qla2xxx: Disable laser for ISP2031 while unloading driver.
authorHimanshu Madhani <himanshu.madhani@qlogic.com>
Thu, 25 Sep 2014 09:16:55 +0000 (05:16 -0400)
committerChristoph Hellwig <hch@lst.de>
Thu, 25 Sep 2014 12:25:04 +0000 (14:25 +0200)
Nameserver data on FC switch is not refreshed when
qla2xxx driver is unloaded. Disabling laser for
ISP2031 will force FC switch to rescan ports and
clear fdmi entries from Nameserver.

Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_os.c

index 2d5610be2d70f6abe42bc5a58498f5fe3295c655..b21adb3d5e6708383f43888165f0d0645c9eacab 100644 (file)
@@ -11,7 +11,7 @@
  * ----------------------------------------------------------------------
  * |             Level            |   Last Value Used  |     Holes     |
  * ----------------------------------------------------------------------
- * | Module Init and Probe        |       0x017d       | 0x004b,0x0141 |
+ * | Module Init and Probe        |       0x017d       | 0x0141                |
  * |                              |                    | 0x0144,0x0146 |
  * |                              |                    | 0x015b-0x0160 |
  * |                              |                    | 0x016e-0x0170 |
index c29f4653db1811eb9979363e8fd21d716b208f7f..d9daad7db6cef79ab31f9a4de95ca6510c729065 100644 (file)
                                             * reset-recovery completion is
                                             * second
                                             */
+/* ISP2031: Values for laser on/off */
+#define PORT_0_2031    0x00201340
+#define PORT_1_2031    0x00201350
+#define LASER_ON_2031  0x01800100
+#define LASER_OFF_2031 0x01800180
 
 /*
  * The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an
index 72b94f9ca637410020e39c6a464499f136601fe6..e742890d5d1b6cecff1dc0c97a0f8c4945430d24 100644 (file)
@@ -240,6 +240,7 @@ static int qla2x00_change_queue_depth(struct scsi_device *, int, int);
 static int qla2x00_change_queue_type(struct scsi_device *, int);
 static void qla2x00_clear_drv_active(struct qla_hw_data *);
 static void qla2x00_free_device(scsi_qla_host_t *);
+static void qla83xx_disable_laser(scsi_qla_host_t *vha);
 
 struct scsi_host_template qla2xxx_driver_template = {
        .module                 = THIS_MODULE,
@@ -3177,6 +3178,10 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
        qla84xx_put_chip(base_vha);
 
+       /* Laser should be disabled only for ISP2031 */
+       if (IS_QLA2031(ha))
+               qla83xx_disable_laser(base_vha);
+
        /* Disable timer */
        if (base_vha->timer_active)
                qla2x00_stop_timer(base_vha);
@@ -5701,6 +5706,32 @@ qla2xxx_pci_resume(struct pci_dev *pdev)
        ha->flags.eeh_busy = 0;
 }
 
+static void
+qla83xx_disable_laser(scsi_qla_host_t *vha)
+{
+       uint32_t reg, data, fn;
+       struct qla_hw_data *ha = vha->hw;
+       struct device_reg_24xx __iomem *isp_reg = &ha->iobase->isp24;
+
+       /* pci func #/port # */
+       ql_dbg(ql_dbg_init, vha, 0x004b,
+           "Disabling Laser for hba: %p\n", vha);
+
+       fn = (RD_REG_DWORD(&isp_reg->ctrl_status) &
+               (BIT_15|BIT_14|BIT_13|BIT_12));
+
+       fn = (fn >> 12);
+
+       if (fn & 1)
+               reg = PORT_1_2031;
+       else
+               reg = PORT_0_2031;
+
+       data = LASER_OFF_2031;
+
+       qla83xx_wr_reg(vha, reg, data);
+}
+
 static const struct pci_error_handlers qla2xxx_err_handler = {
        .error_detected = qla2xxx_pci_error_detected,
        .mmio_enabled = qla2xxx_pci_mmio_enabled,