[SCSI] zfcp: Update dbf calls
[safe/jmp/linux-2.6] / drivers / s390 / scsi / zfcp_fc.c
index 538c68d..309f1df 100644 (file)
@@ -25,14 +25,6 @@ static u32 rscn_range_mask[] = {
        [RSCN_FABRIC_ADDRESS]           = 0x000000,
 };
 
-struct ct_iu_gpn_ft_req {
-       struct ct_hdr header;
-       u8 flags;
-       u8 domain_id_scope;
-       u8 area_id_scope;
-       u8 fc4_type;
-} __attribute__ ((packed));
-
 struct gpn_ft_resp_acc {
        u8 control;
        u8 port_id[3];
@@ -79,11 +71,9 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)
 
        mutex_unlock(&wka_port->mutex);
 
-       wait_event_timeout(
-               wka_port->completion_wq,
-               wka_port->status == ZFCP_WKA_PORT_ONLINE ||
-               wka_port->status == ZFCP_WKA_PORT_OFFLINE,
-               HZ >> 1);
+       wait_event(wka_port->completion_wq,
+                  wka_port->status == ZFCP_WKA_PORT_ONLINE ||
+                  wka_port->status == ZFCP_WKA_PORT_OFFLINE);
 
        if (wka_port->status == ZFCP_WKA_PORT_ONLINE) {
                atomic_inc(&wka_port->refcount);
@@ -116,7 +106,7 @@ static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port)
 {
        if (atomic_dec_return(&wka_port->refcount) != 0)
                return;
-       /* wait 10 miliseconds, other reqs might pop in */
+       /* wait 10 milliseconds, other reqs might pop in */
        schedule_delayed_work(&wka_port->work, HZ / 100);
 }
 
@@ -134,7 +124,7 @@ static void zfcp_fc_wka_port_init(struct zfcp_wka_port *wka_port, u32 d_id,
        INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline);
 }
 
-void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
+static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
 {
        cancel_delayed_work_sync(&wka->work);
        mutex_lock(&wka->mutex);
@@ -142,6 +132,15 @@ void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
        mutex_unlock(&wka->mutex);
 }
 
+void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
+{
+       zfcp_fc_wka_port_force_offline(&gs->ms);
+       zfcp_fc_wka_port_force_offline(&gs->ts);
+       zfcp_fc_wka_port_force_offline(&gs->ds);
+       zfcp_fc_wka_port_force_offline(&gs->as);
+       zfcp_fc_wka_port_force_offline(&gs->ks);
+}
+
 void zfcp_fc_wka_ports_init(struct zfcp_adapter *adapter)
 {
        struct zfcp_wka_ports *gs = adapter->gs;
@@ -243,7 +242,7 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
                (struct fsf_status_read_buffer *) fsf_req->data;
        unsigned int els_type = status_buffer->payload.data[0];
 
-       zfcp_san_dbf_event_incoming_els(fsf_req);
+       zfcp_dbf_san_incoming_els(fsf_req);
        if (els_type == LS_PLOGI)
                zfcp_fc_incoming_plogi(fsf_req);
        else if (els_type == LS_LOGO)
@@ -283,15 +282,15 @@ static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
        port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
 }
 
-int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
+static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
                                     struct zfcp_gid_pn_data *gid_pn)
 {
-       struct zfcp_adapter *adapter = erp_action->adapter;
+       struct zfcp_adapter *adapter = port->adapter;
        struct zfcp_fc_ns_handler_data compl_rec;
        int ret;
 
        /* setup parameters for send generic command */
-       gid_pn->port = erp_action->port;
+       gid_pn->port = port;
        gid_pn->ct.wka_port = &adapter->gs->ds;
        gid_pn->ct.handler = zfcp_fc_ns_handler;
        gid_pn->ct.handler_data = (unsigned long) &compl_rec;
@@ -310,13 +309,12 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
        gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS;
        gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN;
        gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4;
-       gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn;
+       gid_pn->ct_iu_req.wwpn = port->wwpn;
 
        init_completion(&compl_rec.done);
        compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
        compl_rec.handler_data = (unsigned long) gid_pn;
-       ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp,
-                              erp_action);
+       ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.gid_pn_req);
        if (!ret)
                wait_for_completion(&compl_rec.done);
        return ret;
@@ -324,16 +322,16 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
 
 /**
  * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request
- * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed
+ * @port: port where GID_PN request is needed
  * return: -ENOMEM on error, 0 otherwise
  */
-int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
+static int zfcp_fc_ns_gid_pn(struct zfcp_port *port)
 {
        int ret;
        struct zfcp_gid_pn_data *gid_pn;
-       struct zfcp_adapter *adapter = erp_action->adapter;
+       struct zfcp_adapter *adapter = port->adapter;
 
-       gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC);
+       gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC);
        if (!gid_pn)
                return -ENOMEM;
 
@@ -343,14 +341,37 @@ int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
        if (ret)
                goto out;
 
-       ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn);
+       ret = zfcp_fc_ns_gid_pn_request(port, gid_pn);
 
        zfcp_wka_port_put(&adapter->gs->ds);
 out:
-       mempool_free(gid_pn, adapter->pool.data_gid_pn);
+       mempool_free(gid_pn, adapter->pool.gid_pn_data);
        return ret;
 }
 
+void zfcp_fc_port_did_lookup(struct work_struct *work)
+{
+       int ret;
+       struct zfcp_port *port = container_of(work, struct zfcp_port,
+                                             gid_pn_work);
+
+       ret = zfcp_fc_ns_gid_pn(port);
+       if (ret) {
+               /* could not issue gid_pn for some reason */
+               zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1", NULL);
+               goto out;
+       }
+
+       if (!port->d_id) {
+               zfcp_erp_port_failed(port, "fcgpn_2", NULL);
+               goto out;
+       }
+
+       zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
+out:
+       zfcp_port_put(port);
+}
+
 /**
  * zfcp_fc_plogi_evaluate - evaluate PLOGI playload
  * @port: zfcp_port structure
@@ -406,6 +427,7 @@ static void zfcp_fc_adisc_handler(unsigned long data)
        /* port is good, unblock rport without going through erp */
        zfcp_scsi_schedule_rport_register(port);
  out:
+       atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
        zfcp_port_put(port);
        kfree(adisc);
 }
@@ -452,13 +474,21 @@ void zfcp_fc_link_test_work(struct work_struct *work)
        port->rport_task = RPORT_DEL;
        zfcp_scsi_rport_work(&port->rport_work);
 
+       /* only issue one test command at one time per port */
+       if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST)
+               goto out;
+
+       atomic_set_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
+
        retval = zfcp_fc_adisc(port);
        if (retval == 0)
                return;
 
        /* send of ADISC was not possible */
+       atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
        zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
 
+out:
        zfcp_port_put(port);
 }
 
@@ -473,7 +503,7 @@ void zfcp_fc_link_test_work(struct work_struct *work)
 void zfcp_test_link(struct zfcp_port *port)
 {
        zfcp_port_get(port);
-       if (!queue_work(zfcp_data.work_queue, &port->test_link_work))
+       if (!queue_work(port->adapter->work_queue, &port->test_link_work))
                zfcp_port_put(port);
 }
 
@@ -481,7 +511,7 @@ static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
 {
        struct scatterlist *sg = &gpn_ft->sg_req;
 
-       kfree(sg_virt(sg)); /* free request buffer */
+       kmem_cache_free(zfcp_data.gpn_ft_cache, sg_virt(sg));
        zfcp_sg_free_table(gpn_ft->sg_resp, buf_num);
 
        kfree(gpn_ft);
@@ -496,7 +526,7 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num)
        if (!gpn_ft)
                return NULL;
 
-       req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL);
+       req = kmem_cache_alloc(zfcp_data.gpn_ft_cache, GFP_KERNEL);
        if (!req) {
                kfree(gpn_ft);
                gpn_ft = NULL;
@@ -544,7 +574,7 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
 
        init_completion(&compl_rec.done);
        compl_rec.handler = NULL;
-       ret = zfcp_fsf_send_ct(ct, NULL, NULL);
+       ret = zfcp_fsf_send_ct(ct, NULL);
        if (!ret)
                wait_for_completion(&compl_rec.done);
        return ret;
@@ -833,7 +863,7 @@ int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job)
        ct_fc_job->ct.completion = NULL;
        ct_fc_job->job = job;
 
-       ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL, NULL);
+       ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL);
        if (ret) {
                kfree(ct_fc_job);
                zfcp_wka_port_put(ct_fc_job->ct.wka_port);