Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[sfrench/cifs-2.6.git] / drivers / scsi / qla2xxx / qla_os.c
index 3eb4cd2cbc7838baef9dc3ee199528f269451d1d..d6445ae841ba965896c8993fce3ab38ae899f0e4 100644 (file)
@@ -24,7 +24,7 @@ char qla2x00_version_str[40];
 /*
  * SRB allocation cache
  */
-static kmem_cache_t *srb_cachep;
+static struct kmem_cache *srb_cachep;
 
 /*
  * Ioctl related information.
@@ -95,6 +95,8 @@ MODULE_PARM_DESC(ql2xqfullrampup,
  */
 static int qla2xxx_slave_configure(struct scsi_device * device);
 static int qla2xxx_slave_alloc(struct scsi_device *);
+static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
+static void qla2xxx_scan_start(struct Scsi_Host *);
 static void qla2xxx_slave_destroy(struct scsi_device *);
 static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
                void (*fn)(struct scsi_cmnd *));
@@ -124,6 +126,8 @@ static struct scsi_host_template qla2x00_driver_template = {
 
        .slave_alloc            = qla2xxx_slave_alloc,
        .slave_destroy          = qla2xxx_slave_destroy,
+       .scan_finished          = qla2xxx_scan_finished,
+       .scan_start             = qla2xxx_scan_start,
        .change_queue_depth     = qla2x00_change_queue_depth,
        .change_queue_type      = qla2x00_change_queue_type,
        .this_id                = -1,
@@ -1033,48 +1037,49 @@ eh_host_reset_lock:
 static int
 qla2x00_loop_reset(scsi_qla_host_t *ha)
 {
-       int status = QLA_SUCCESS;
+       int ret;
        struct fc_port *fcport;
 
+       if (ha->flags.enable_lip_full_login) {
+               ret = qla2x00_full_login_lip(ha);
+               if (ret != QLA_SUCCESS) {
+                       DEBUG2_3(printk("%s(%ld): bus_reset failed: "
+                           "full_login_lip=%d.\n", __func__, ha->host_no,
+                           ret));
+               }
+               atomic_set(&ha->loop_state, LOOP_DOWN);
+               atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
+               qla2x00_mark_all_devices_lost(ha, 0);
+               qla2x00_wait_for_loop_ready(ha);
+       }
+
        if (ha->flags.enable_lip_reset) {
-               status = qla2x00_lip_reset(ha);
+               ret = qla2x00_lip_reset(ha);
+               if (ret != QLA_SUCCESS) {
+                       DEBUG2_3(printk("%s(%ld): bus_reset failed: "
+                           "lip_reset=%d.\n", __func__, ha->host_no, ret));
+               }
+               qla2x00_wait_for_loop_ready(ha);
        }
 
-       if (status == QLA_SUCCESS && ha->flags.enable_target_reset) {
+       if (ha->flags.enable_target_reset) {
                list_for_each_entry(fcport, &ha->fcports, list) {
                        if (fcport->port_type != FCT_TARGET)
                                continue;
 
-                       status = qla2x00_device_reset(ha, fcport);
-                       if (status != QLA_SUCCESS)
-                               break;
+                       ret = qla2x00_device_reset(ha, fcport);
+                       if (ret != QLA_SUCCESS) {
+                               DEBUG2_3(printk("%s(%ld): bus_reset failed: "
+                                   "target_reset=%d d_id=%x.\n", __func__,
+                                   ha->host_no, ret, fcport->d_id.b24));
+                       }
                }
        }
 
-       if (status == QLA_SUCCESS &&
-               ((!ha->flags.enable_target_reset &&
-                 !ha->flags.enable_lip_reset) ||
-               ha->flags.enable_lip_full_login)) {
-
-               status = qla2x00_full_login_lip(ha);
-       }
-
        /* Issue marker command only when we are going to start the I/O */
        ha->marker_needed = 1;
 
-       if (status) {
-               /* Empty */
-               DEBUG2_3(printk("%s(%ld): **** FAILED ****\n",
-                               __func__,
-                               ha->host_no));
-       } else {
-               /* Empty */
-               DEBUG3(printk("%s(%ld): exiting normally.\n",
-                               __func__,
-                               ha->host_no));
-       }
-
-       return(status);
+       return QLA_SUCCESS;
 }
 
 /*
@@ -1366,6 +1371,29 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha)
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
+static void
+qla2xxx_scan_start(struct Scsi_Host *shost)
+{
+       scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata;
+
+       set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
+       set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
+       set_bit(RSCN_UPDATE, &ha->dpc_flags);
+}
+
+static int
+qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+       scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata;
+
+       if (!ha->host)
+               return 1;
+       if (time > ha->loop_reset_delay * HZ)
+               return 1;
+
+       return atomic_read(&ha->loop_state) == LOOP_READY;
+}
+
 /*
  * PCI driver interface
  */
@@ -1377,10 +1405,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        struct Scsi_Host *host;
        scsi_qla_host_t *ha;
        unsigned long   flags = 0;
-       unsigned long   wait_switch = 0;
        char pci_info[20];
        char fw_str[30];
-       fc_port_t *fcport;
        struct scsi_host_template *sht;
 
        if (pci_enable_device(pdev))
@@ -1388,7 +1414,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        sht = &qla2x00_driver_template;
        if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
-           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432)
                sht = &qla24xx_driver_template;
        host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
        if (host == NULL) {
@@ -1631,30 +1659,19 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
        ha->isp_ops.enable_intrs(ha);
 
-       /* v2.19.5b6 */
-       /*
-        * Wait around max loop_reset_delay secs for the devices to come
-        * on-line. We don't want Linux scanning before we are ready.
-        *
-        */
-       for (wait_switch = jiffies + (ha->loop_reset_delay * HZ);
-           time_before(jiffies,wait_switch) &&
-            !(ha->device_flags & (DFLG_NO_CABLE | DFLG_FABRIC_DEVICES))
-            && (ha->device_flags & SWITCH_FOUND) ;) {
-
-               qla2x00_check_fabric_devices(ha);
-
-               msleep(10);
-       }
-
        pci_set_drvdata(pdev, ha);
+
        ha->flags.init_done = 1;
+       ha->flags.online = 1;
+
        num_hosts++;
 
        ret = scsi_add_host(host, &pdev->dev);
        if (ret)
                goto probe_failed;
 
+       scsi_scan_host(host);
+
        qla2x00_alloc_sysfs_attr(ha);
 
        qla2x00_init_host_attr(ha);
@@ -1669,10 +1686,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
            ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
            ha->isp_ops.fw_version_str(ha, fw_str));
 
-       /* Go with fc_rport registration. */
-       list_for_each_entry(fcport, &ha->fcports, list)
-               qla2x00_reg_remote_port(ha, fcport);
-
        return 0;
 
 probe_failed: