]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/qla2xxx/qla_init.c
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6-omap-h63xx.git] / drivers / scsi / qla2xxx / qla_init.c
index 7d973bd9022bb84773a11aa490ed39df1608133a..634ee174bff2a315e95fc29dd6fc41a72145480f 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
-#include <scsi/scsi_transport_fc.h>
 
 #include "qla_devtbl.h"
 
@@ -32,7 +31,6 @@ static int qla2x00_fw_ready(scsi_qla_host_t *);
 static int qla2x00_configure_hba(scsi_qla_host_t *);
 static int qla2x00_configure_loop(scsi_qla_host_t *);
 static int qla2x00_configure_local_loop(scsi_qla_host_t *);
-static void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
 static int qla2x00_configure_fabric(scsi_qla_host_t *);
 static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *);
 static int qla2x00_device_resync(scsi_qla_host_t *);
@@ -1014,11 +1012,13 @@ qla24xx_update_fw_options(scsi_qla_host_t *ha)
        int rval;
 
        /* Update Serial Link options. */
-       if ((ha->fw_seriallink_options24[0] & BIT_0) == 0)
+       if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
                return;
 
-       rval = qla2x00_set_serdes_params(ha, ha->fw_seriallink_options24[1],
-           ha->fw_seriallink_options24[2], ha->fw_seriallink_options24[3]);
+       rval = qla2x00_set_serdes_params(ha,
+           le16_to_cpu(ha->fw_seriallink_options24[1]),
+           le16_to_cpu(ha->fw_seriallink_options24[2]),
+           le16_to_cpu(ha->fw_seriallink_options24[3]));
        if (rval != QLA_SUCCESS) {
                qla_printk(KERN_WARNING, ha,
                    "Unable to update Serial Link options (%x).\n", rval);
@@ -1686,10 +1686,16 @@ static void
 qla2x00_rport_del(void *data)
 {
        fc_port_t *fcport = data;
+       struct fc_rport *rport;
+       unsigned long flags;
+
+       spin_lock_irqsave(&fcport->rport_lock, flags);
+       rport = fcport->drport;
+       fcport->drport = NULL;
+       spin_unlock_irqrestore(&fcport->rport_lock, flags);
+       if (rport)
+               fc_remote_port_delete(rport);
 
-       if (fcport->rport)
-               fc_remote_port_delete(fcport->rport);
-       fcport->rport = NULL;
 }
 
 /**
@@ -1717,6 +1723,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
        atomic_set(&fcport->state, FCS_UNCONFIGURED);
        fcport->flags = FCF_RLC_SUPPORT;
        fcport->supported_classes = FC_COS_UNSPECIFIED;
+       spin_lock_init(&fcport->rport_lock);
        INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
        INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
 
@@ -1939,6 +1946,9 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
                            "information -- get_port_database=%x, "
                            "loop_id=0x%04x\n",
                            ha->host_no, rval2, new_fcport->loop_id));
+                       DEBUG2(printk("scsi(%ld): Scheduling resync...\n",
+                           ha->host_no));
+                       set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
                        continue;
                }
 
@@ -2003,7 +2013,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
 {
        fc_port_t       *fcport;
 
-       qla2x00_mark_all_devices_lost(ha);
+       qla2x00_mark_all_devices_lost(ha, 0);
        list_for_each_entry(fcport, &ha->fcports, list) {
                if (fcport->port_type != FCT_TARGET)
                        continue;
@@ -2027,13 +2037,9 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
  * Context:
  *     Kernel context.
  */
-static void
+void
 qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
 {
-       uint16_t        index;
-       unsigned long flags;
-       srb_t *sp;
-
        fcport->ha = ha;
        fcport->login_retry = 0;
        fcport->port_login_retry_count = ha->port_down_retry_count *
@@ -2042,28 +2048,6 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
            PORT_RETRY_TIME);
        fcport->flags &= ~FCF_LOGIN_NEEDED;
 
-       /*
-        * Check for outstanding cmd on tape Bypass LUN discovery if active
-        * command on tape.
-        */
-       if (fcport->flags & FCF_TAPE_PRESENT) {
-               spin_lock_irqsave(&ha->hardware_lock, flags);
-               for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
-                       fc_port_t *sfcp;
-
-                       if ((sp = ha->outstanding_cmds[index]) != 0) {
-                               sfcp = sp->fcport;
-                               if (sfcp == fcport) {
-                                       atomic_set(&fcport->state, FCS_ONLINE);
-                                       spin_unlock_irqrestore(
-                                           &ha->hardware_lock, flags);
-                                       return;
-                               }
-                       }
-               }
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
-       }
-
        if (fcport->port_type == FCT_INITIATOR ||
            fcport->port_type == FCT_BROADCAST)
                fcport->device_type = TYPE_PROCESSOR;
@@ -2079,24 +2063,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
 {
        struct fc_rport_identifiers rport_ids;
        struct fc_rport *rport;
+       unsigned long flags;
 
-       if (fcport->rport) {
-               fc_remote_port_delete(fcport->rport);
-               fcport->rport = NULL;
-       }
+       if (fcport->drport)
+               qla2x00_rport_del(fcport);
+       if (fcport->rport)
+               return;
 
        rport_ids.node_name = wwn_to_u64(fcport->node_name);
        rport_ids.port_name = wwn_to_u64(fcport->port_name);
        rport_ids.port_id = fcport->d_id.b.domain << 16 |
            fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
        rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-       fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
+       rport = fc_remote_port_add(ha->host, 0, &rport_ids);
        if (!rport) {
                qla_printk(KERN_WARNING, ha,
                    "Unable to allocate fc remote port!\n");
                return;
        }
+       spin_lock_irqsave(&fcport->rport_lock, flags);
+       fcport->rport = rport;
        *((fc_port_t **)rport->dd_data) = fcport;
+       spin_unlock_irqrestore(&fcport->rport_lock, flags);
+
        rport->supported_classes = fcport->supported_classes;
 
        rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
@@ -2212,12 +2201,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
 
                        if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
                                qla2x00_mark_device_lost(ha, fcport,
-                                   ql2xplogiabsentdevice);
+                                   ql2xplogiabsentdevice, 0);
                                if (fcport->loop_id != FC_NO_LOOP_ID &&
                                    (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
                                    fcport->port_type != FCT_INITIATOR &&
                                    fcport->port_type != FCT_BROADCAST) {
-
                                        ha->isp_ops.fabric_logout(ha,
                                            fcport->loop_id,
                                            fcport->d_id.b.domain,
@@ -2648,7 +2636,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
 
                switch (format) {
                case 0:
-                       if (!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
+                       if (ql2xprocessrscn &&
+                           !IS_QLA2100(ha) && !IS_QLA2200(ha) &&
                            !IS_QLA6312(ha) && !IS_QLA6322(ha) &&
                            !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
                            ha->flags.init_done) {
@@ -2688,7 +2677,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
                        if (atomic_read(&fcport->state) == FCS_ONLINE) {
                                if (format != 3 ||
                                    fcport->port_type != FCT_INITIATOR) {
-                                       qla2x00_mark_device_lost(ha, fcport, 0);
+                                       qla2x00_mark_device_lost(ha, fcport,
+                                           0, 0);
                                }
                        }
                        fcport->flags &= ~FCF_FARP_DONE;
@@ -2735,8 +2725,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport,
                        ha->isp_ops.fabric_logout(ha, fcport->loop_id,
                            fcport->d_id.b.domain, fcport->d_id.b.area,
                            fcport->d_id.b.al_pa);
-                       qla2x00_mark_device_lost(ha, fcport, 1);
-
+                       qla2x00_mark_device_lost(ha, fcport, 1, 0);
                } else {
                        qla2x00_update_fcport(ha, fcport);
                }
@@ -2849,7 +2838,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
                        ha->isp_ops.fabric_logout(ha, fcport->loop_id,
                            fcport->d_id.b.domain, fcport->d_id.b.area,
                            fcport->d_id.b.al_pa);
-                       qla2x00_mark_device_lost(ha, fcport, 1);
+                       qla2x00_mark_device_lost(ha, fcport, 1, 0);
 
                        rval = 1;
                        break;
@@ -2984,6 +2973,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *ha)
        qla2x00_probe_for_all_luns(ha);
 }
 
+void
+qla2x00_update_fcports(scsi_qla_host_t *ha)
+{
+       fc_port_t *fcport;
+
+       /* Go with deferred removal of rport references. */
+       list_for_each_entry(fcport, &ha->fcports, list)
+               if (fcport->drport)
+                       qla2x00_rport_del(fcport);
+}
+
 /*
 *  qla2x00_abort_isp
 *      Resets ISP and aborts all outstanding commands.
@@ -3013,7 +3013,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
                        atomic_set(&ha->loop_state, LOOP_DOWN);
-                       qla2x00_mark_all_devices_lost(ha);
+                       qla2x00_mark_all_devices_lost(ha, 0);
                } else {
                        if (!atomic_read(&ha->loop_down_timer))
                                atomic_set(&ha->loop_down_timer,
@@ -3402,6 +3402,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
        ha->node_name = icb->node_name;
        ha->port_name = icb->port_name;
 
+       icb->execution_throttle = __constant_cpu_to_le16(0xFFFF);
+
        ha->retry_count = le16_to_cpu(nv->login_retry_count);
 
        /* Set minimum login_timeout to 4 seconds. */
@@ -3667,8 +3669,8 @@ qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
                        for (i = 0; i < dlen; i++)
                                dcode[i] = swab32(dcode[i]);
 
-                       rval = qla2x00_load_ram_ext(ha, ha->request_dma,
-                           risc_addr, dlen);
+                       rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+                           dlen);
                        if (rval) {
                                DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
                                    "segment %d of firmware\n", ha->host_no,
@@ -3868,8 +3870,8 @@ qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
                        for (i = 0; i < dlen; i++)
                                dcode[i] = swab32(fwcode[i]);
 
-                       rval = qla2x00_load_ram_ext(ha, ha->request_dma,
-                           risc_addr, dlen);
+                       rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+                           dlen);
                        if (rval) {
                                DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
                                    "segment %d of firmware\n", ha->host_no,