]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/s390/scsi/zfcp_qdio.c
Merge branch 'master' into tk71
[mv-sheeva.git] / drivers / s390 / scsi / zfcp_qdio.c
index b2635759721cd81db28c4de2dfe6097568836d6f..8da5ed644c2b4314a4cc362f874e22efa02c4e52 100644 (file)
@@ -41,7 +41,7 @@ static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
                zfcp_qdio_siosl(adapter);
        zfcp_erp_adapter_reopen(adapter,
                                ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
-                               ZFCP_STATUS_COMMON_ERP_FAILED, id, NULL);
+                               ZFCP_STATUS_COMMON_ERP_FAILED, id);
 }
 
 static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
@@ -60,13 +60,11 @@ static inline void zfcp_qdio_account(struct zfcp_qdio *qdio)
        unsigned long long now, span;
        int used;
 
-       spin_lock(&qdio->stat_lock);
        now = get_clock_monotonic();
        span = (now - qdio->req_q_time) >> 12;
        used = QDIO_MAX_BUFFERS_PER_Q - atomic_read(&qdio->req_q_free);
        qdio->req_q_util += used * span;
        qdio->req_q_time = now;
-       spin_unlock(&qdio->stat_lock);
 }
 
 static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
@@ -76,7 +74,6 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
        struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
 
        if (unlikely(qdio_err)) {
-               zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
                zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err);
                return;
        }
@@ -84,7 +81,9 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
        /* cleanup all SBALs being program-owned now */
        zfcp_qdio_zero_sbals(qdio->req_q, idx, count);
 
+       spin_lock_irq(&qdio->stat_lock);
        zfcp_qdio_account(qdio);
+       spin_unlock_irq(&qdio->stat_lock);
        atomic_add(count, &qdio->req_q_free);
        wake_up(&qdio->req_q_wq);
 }
@@ -97,7 +96,6 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
        int sbal_idx, sbal_no;
 
        if (unlikely(qdio_err)) {
-               zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count);
                zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
                return;
        }
@@ -116,7 +114,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
         * put SBALs back to response queue
         */
        if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count))
-               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2", NULL);
+               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
 }
 
 static struct qdio_buffer_element *
@@ -201,11 +199,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
 
 static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio)
 {
-       spin_lock_bh(&qdio->req_q_lock);
+       spin_lock_irq(&qdio->req_q_lock);
        if (atomic_read(&qdio->req_q_free) ||
            !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
                return 1;
-       spin_unlock_bh(&qdio->req_q_lock);
+       spin_unlock_irq(&qdio->req_q_lock);
        return 0;
 }
 
@@ -223,7 +221,7 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
 {
        long ret;
 
-       spin_unlock_bh(&qdio->req_q_lock);
+       spin_unlock_irq(&qdio->req_q_lock);
        ret = wait_event_interruptible_timeout(qdio->req_q_wq,
                               zfcp_qdio_sbal_check(qdio), 5 * HZ);
 
@@ -236,10 +234,10 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio)
        if (!ret) {
                atomic_inc(&qdio->req_q_full);
                /* assume hanging outbound queue, try queue recovery */
-               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1", NULL);
+               zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1");
        }
 
-       spin_lock_bh(&qdio->req_q_lock);
+       spin_lock_irq(&qdio->req_q_lock);
        return -EIO;
 }
 
@@ -254,7 +252,9 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
        int retval;
        u8 sbal_number = q_req->sbal_number;
 
+       spin_lock(&qdio->stat_lock);
        zfcp_qdio_account(qdio);
+       spin_unlock(&qdio->stat_lock);
 
        retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
                         q_req->sbal_first, sbal_number);
@@ -277,16 +277,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
 static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
                                      struct zfcp_qdio *qdio)
 {
-
+       memset(id, 0, sizeof(*id));
        id->cdev = qdio->adapter->ccw_device;
        id->q_format = QDIO_ZFCP_QFMT;
        memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
        ASCEBC(id->adapter_name, 8);
        id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV;
-       id->qib_param_field_format = 0;
-       id->qib_param_field = NULL;
-       id->input_slib_elements = NULL;
-       id->output_slib_elements = NULL;
        id->no_input_qs = 1;
        id->no_output_qs = 1;
        id->input_handler = zfcp_qdio_int_resp;
@@ -294,6 +290,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
        id->int_parm = (unsigned long) qdio;
        id->input_sbal_addr_array = (void **) (qdio->res_q);
        id->output_sbal_addr_array = (void **) (qdio->req_q);
+       id->scan_threshold =
+               QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2;
 }
 
 /**
@@ -311,6 +309,7 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
                return -ENOMEM;
 
        zfcp_qdio_setup_init_data(&init_data, qdio);
+       init_waitqueue_head(&qdio->req_q_wq);
 
        return qdio_allocate(&init_data);
 }
@@ -328,9 +327,9 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio)
                return;
 
        /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
-       spin_lock_bh(&qdio->req_q_lock);
+       spin_lock_irq(&qdio->req_q_lock);
        atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-       spin_unlock_bh(&qdio->req_q_lock);
+       spin_unlock_irq(&qdio->req_q_lock);
 
        wake_up(&qdio->req_q_wq);
 
@@ -395,6 +394,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
        /* set index of first avalable SBALS / number of available SBALS */
        qdio->req_q_idx = 0;
        atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q);
+       atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
 
        return 0;