]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/s390/scsi/zfcp_fc.c
Merge commit 'v2.6.27-rc7' into x86/microcode
[linux-2.6-omap-h63xx.git] / drivers / s390 / scsi / zfcp_fc.c
index 34c9b20ce4939e3918597f523887a4d9e8533bc0..56196c98c07b417f060e44dfb6c8a2dce2543e89 100644 (file)
@@ -71,8 +71,8 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
        u16 no_entries;
        u32 range_mask;
 
-       fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload;
-       fcp_rscn_element = (struct fcp_rscn_element *) status_buffer->payload;
+       fcp_rscn_head = (struct fcp_rscn_head *) status_buffer->payload.data;
+       fcp_rscn_element = (struct fcp_rscn_element *) fcp_rscn_head;
 
        /* see FC-FS */
        no_entries = fcp_rscn_head->payload_len /
@@ -123,7 +123,7 @@ static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req)
        struct fsf_status_read_buffer *status_buffer =
                (struct fsf_status_read_buffer *)req->data;
        struct fsf_plogi *els_plogi =
-               (struct fsf_plogi *) status_buffer->payload;
+               (struct fsf_plogi *) status_buffer->payload.data;
 
        zfcp_fc_incoming_wwpn(req, els_plogi->serv_param.wwpn);
 }
@@ -132,7 +132,8 @@ static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req)
 {
        struct fsf_status_read_buffer *status_buffer =
                (struct fsf_status_read_buffer *)req->data;
-       struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload;
+       struct fcp_logo *els_logo =
+               (struct fcp_logo *) status_buffer->payload.data;
 
        zfcp_fc_incoming_wwpn(req, els_logo->nport_wwpn);
 }
@@ -145,7 +146,7 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
 {
        struct fsf_status_read_buffer *status_buffer =
                (struct fsf_status_read_buffer *) fsf_req->data;
-       unsigned int els_type = status_buffer->payload[0];
+       unsigned int els_type = status_buffer->payload.data[0];
 
        zfcp_san_dbf_event_incoming_els(fsf_req);
        if (els_type == LS_PLOGI)
@@ -263,7 +264,7 @@ static void zfcp_fc_adisc_handler(unsigned long data)
        struct zfcp_port *port = adisc->els.port;
        struct zfcp_ls_adisc_acc *ls_adisc = &adisc->ls_adisc_acc;
 
-       if (!adisc->els.status) {
+       if (adisc->els.status) {
                /* request rejected or timed out */
                zfcp_erp_port_forced_reopen(port, 0, 63, NULL);
                goto out;
@@ -328,12 +329,13 @@ void zfcp_test_link(struct zfcp_port *port)
 
        zfcp_port_get(port);
        retval = zfcp_fc_adisc(port);
-       if (retval == 0 || retval == -EBUSY)
+       if (retval == 0)
                return;
 
        /* send of ADISC was not possible */
        zfcp_port_put(port);
-       zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
+       if (retval != -EBUSY)
+               zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
 }
 
 static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
@@ -350,7 +352,6 @@ static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
                if (ret)
                        return ret;
                zfcp_erp_wait(adapter);
-               zfcp_port_put(adapter->nameserver_port);
        }
        return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
                                  &adapter->nameserver_port->status);
@@ -462,7 +463,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
        struct zfcp_adapter *adapter = ct->port->adapter;
        struct zfcp_port *port, *tmp;
        u32 d_id;
-       int ret = 0, x;
+       int ret = 0, x, last = 0;
 
        if (ct->status)
                return -EIO;
@@ -479,29 +480,32 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
        down(&zfcp_data.config_sema);
 
        /* first entry is the header */
-       for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) {
+       for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) {
                if (x % (ZFCP_GPN_FT_ENTRIES + 1))
                        acc++;
                else
                        acc = sg_virt(++sg);
 
+               last = acc->control & 0x80;
                d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
                       acc->port_id[2];
 
                /* skip the adapter's port and known remote ports */
-               if (acc->wwpn == fc_host_port_name(adapter->scsi_host) ||
-                    zfcp_get_port_by_did(adapter, d_id))
+               if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
                        continue;
+               port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
+               if (port) {
+                       zfcp_port_get(port);
+                       continue;
+               }
 
                port = zfcp_port_enqueue(adapter, acc->wwpn,
                                         ZFCP_STATUS_PORT_DID_DID |
                                         ZFCP_STATUS_COMMON_NOESC, d_id);
-               if (port)
-                       zfcp_erp_port_reopen(port, 0, 149, NULL);
+               if (IS_ERR(port))
+                       ret = PTR_ERR(port);
                else
-                       ret = -ENOMEM;
-               if (acc->control & 0x80) /* last entry */
-                       break;
+                       zfcp_erp_port_reopen(port, 0, 149, NULL);
        }
 
        zfcp_erp_wait(adapter);