diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 16:24:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 16:24:49 -0400 |
commit | 22eb5aa6c7940861f9603581665b9d9a1c60be30 (patch) | |
tree | 22890bcebae5647bcc1a29e7b544a1c5de2b1f8b /drivers/scsi/qla2xxx/qla_os.c | |
parent | d7ca6f8cdffa5765e486edb3dada9121fba8e6aa (diff) | |
parent | 015640edb1f346e0b2eda703587c4cd1c310ec1d (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (74 commits)
[SCSI] sg: fix q->queue_lock on scsi_error_handler path
[SCSI] replace __inline with inline
[SCSI] a2091: make 2 functions static
[SCSI] a3000: make 2 functions static
[SCSI] ses: #if 0 the unused ses_match_host()
[SCSI] use kmem_cache_zalloc instead of kmem_cache_alloc/memset
[SCSI] sg: fix iovec bugs introduced by the block layer conversion
[SCSI] qlogicpti: use request_firmware
[SCSI] advansys: use request_firmware
[SCSI] qla1280: use request_firmware
[SCSI] libiscsi: fix iscsi pool error path
[SCSI] cxgb3i: call ddp release function directly
[SCSI] cxgb3i: merge cxgb3i_ddp into cxgb3i module
[SCSI] cxgb3i: close all tcp connections upon chip reset
[SCSI] cxgb3i: re-read ddp settings information after chip reset
[SCSI] cxgb3i: re-initialize ddp settings after chip reset
[SCSI] cxgb3i: subscribe to error notification from cxgb3 driver
[SCSI] aacraid driver update
[SCSI] mptsas: remove unneeded check
[SCSI] config: Make need for SCSI_CDROM clearer
...
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 258 |
1 files changed, 100 insertions, 158 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3ddfa889e949..efe29924e058 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -104,9 +104,7 @@ static int qla2xxx_slave_alloc(struct scsi_device *); | |||
104 | static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time); | 104 | static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time); |
105 | static void qla2xxx_scan_start(struct Scsi_Host *); | 105 | static void qla2xxx_scan_start(struct Scsi_Host *); |
106 | static void qla2xxx_slave_destroy(struct scsi_device *); | 106 | static void qla2xxx_slave_destroy(struct scsi_device *); |
107 | static int qla2x00_queuecommand(struct scsi_cmnd *cmd, | 107 | static int qla2xxx_queuecommand(struct scsi_cmnd *cmd, |
108 | void (*fn)(struct scsi_cmnd *)); | ||
109 | static int qla24xx_queuecommand(struct scsi_cmnd *cmd, | ||
110 | void (*fn)(struct scsi_cmnd *)); | 108 | void (*fn)(struct scsi_cmnd *)); |
111 | static int qla2xxx_eh_abort(struct scsi_cmnd *); | 109 | static int qla2xxx_eh_abort(struct scsi_cmnd *); |
112 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); | 110 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); |
@@ -117,42 +115,10 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *); | |||
117 | static int qla2x00_change_queue_depth(struct scsi_device *, int); | 115 | static int qla2x00_change_queue_depth(struct scsi_device *, int); |
118 | static int qla2x00_change_queue_type(struct scsi_device *, int); | 116 | static int qla2x00_change_queue_type(struct scsi_device *, int); |
119 | 117 | ||
120 | static struct scsi_host_template qla2x00_driver_template = { | 118 | struct scsi_host_template qla2xxx_driver_template = { |
121 | .module = THIS_MODULE, | 119 | .module = THIS_MODULE, |
122 | .name = QLA2XXX_DRIVER_NAME, | 120 | .name = QLA2XXX_DRIVER_NAME, |
123 | .queuecommand = qla2x00_queuecommand, | 121 | .queuecommand = qla2xxx_queuecommand, |
124 | |||
125 | .eh_abort_handler = qla2xxx_eh_abort, | ||
126 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | ||
127 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
128 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | ||
129 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | ||
130 | |||
131 | .slave_configure = qla2xxx_slave_configure, | ||
132 | |||
133 | .slave_alloc = qla2xxx_slave_alloc, | ||
134 | .slave_destroy = qla2xxx_slave_destroy, | ||
135 | .scan_finished = qla2xxx_scan_finished, | ||
136 | .scan_start = qla2xxx_scan_start, | ||
137 | .change_queue_depth = qla2x00_change_queue_depth, | ||
138 | .change_queue_type = qla2x00_change_queue_type, | ||
139 | .this_id = -1, | ||
140 | .cmd_per_lun = 3, | ||
141 | .use_clustering = ENABLE_CLUSTERING, | ||
142 | .sg_tablesize = SG_ALL, | ||
143 | |||
144 | /* | ||
145 | * The RISC allows for each command to transfer (2^32-1) bytes of data, | ||
146 | * which equates to 0x800000 sectors. | ||
147 | */ | ||
148 | .max_sectors = 0xFFFF, | ||
149 | .shost_attrs = qla2x00_host_attrs, | ||
150 | }; | ||
151 | |||
152 | struct scsi_host_template qla24xx_driver_template = { | ||
153 | .module = THIS_MODULE, | ||
154 | .name = QLA2XXX_DRIVER_NAME, | ||
155 | .queuecommand = qla24xx_queuecommand, | ||
156 | 122 | ||
157 | .eh_abort_handler = qla2xxx_eh_abort, | 123 | .eh_abort_handler = qla2xxx_eh_abort, |
158 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | 124 | .eh_device_reset_handler = qla2xxx_eh_device_reset, |
@@ -430,73 +396,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
430 | } | 396 | } |
431 | 397 | ||
432 | static int | 398 | static int |
433 | qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 399 | qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
434 | { | ||
435 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | ||
436 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | ||
437 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); | ||
438 | struct qla_hw_data *ha = vha->hw; | ||
439 | srb_t *sp; | ||
440 | int rval; | ||
441 | |||
442 | if (unlikely(pci_channel_offline(ha->pdev))) { | ||
443 | cmd->result = DID_REQUEUE << 16; | ||
444 | goto qc_fail_command; | ||
445 | } | ||
446 | |||
447 | rval = fc_remote_port_chkready(rport); | ||
448 | if (rval) { | ||
449 | cmd->result = rval; | ||
450 | goto qc_fail_command; | ||
451 | } | ||
452 | |||
453 | /* Close window on fcport/rport state-transitioning. */ | ||
454 | if (fcport->drport) | ||
455 | goto qc_target_busy; | ||
456 | |||
457 | if (atomic_read(&fcport->state) != FCS_ONLINE) { | ||
458 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || | ||
459 | atomic_read(&vha->loop_state) == LOOP_DEAD) { | ||
460 | cmd->result = DID_NO_CONNECT << 16; | ||
461 | goto qc_fail_command; | ||
462 | } | ||
463 | goto qc_target_busy; | ||
464 | } | ||
465 | |||
466 | spin_unlock_irq(vha->host->host_lock); | ||
467 | |||
468 | sp = qla2x00_get_new_sp(vha, fcport, cmd, done); | ||
469 | if (!sp) | ||
470 | goto qc_host_busy_lock; | ||
471 | |||
472 | rval = ha->isp_ops->start_scsi(sp); | ||
473 | if (rval != QLA_SUCCESS) | ||
474 | goto qc_host_busy_free_sp; | ||
475 | |||
476 | spin_lock_irq(vha->host->host_lock); | ||
477 | |||
478 | return 0; | ||
479 | |||
480 | qc_host_busy_free_sp: | ||
481 | qla2x00_sp_free_dma(sp); | ||
482 | mempool_free(sp, ha->srb_mempool); | ||
483 | |||
484 | qc_host_busy_lock: | ||
485 | spin_lock_irq(vha->host->host_lock); | ||
486 | return SCSI_MLQUEUE_HOST_BUSY; | ||
487 | |||
488 | qc_target_busy: | ||
489 | return SCSI_MLQUEUE_TARGET_BUSY; | ||
490 | |||
491 | qc_fail_command: | ||
492 | done(cmd); | ||
493 | |||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | |||
498 | static int | ||
499 | qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | ||
500 | { | 400 | { |
501 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 401 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
502 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 402 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
@@ -507,7 +407,10 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
507 | int rval; | 407 | int rval; |
508 | 408 | ||
509 | if (unlikely(pci_channel_offline(ha->pdev))) { | 409 | if (unlikely(pci_channel_offline(ha->pdev))) { |
510 | cmd->result = DID_REQUEUE << 16; | 410 | if (ha->pdev->error_state == pci_channel_io_frozen) |
411 | cmd->result = DID_REQUEUE << 16; | ||
412 | else | ||
413 | cmd->result = DID_NO_CONNECT << 16; | ||
511 | goto qc24_fail_command; | 414 | goto qc24_fail_command; |
512 | } | 415 | } |
513 | 416 | ||
@@ -635,6 +538,34 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha) | |||
635 | return (return_status); | 538 | return (return_status); |
636 | } | 539 | } |
637 | 540 | ||
541 | int | ||
542 | qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) | ||
543 | { | ||
544 | int return_status; | ||
545 | unsigned long wait_reset; | ||
546 | struct qla_hw_data *ha = vha->hw; | ||
547 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | ||
548 | |||
549 | wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ); | ||
550 | while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) || | ||
551 | test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || | ||
552 | test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || | ||
553 | ha->dpc_active) && time_before(jiffies, wait_reset)) { | ||
554 | |||
555 | msleep(1000); | ||
556 | |||
557 | if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) && | ||
558 | ha->flags.chip_reset_done) | ||
559 | break; | ||
560 | } | ||
561 | if (ha->flags.chip_reset_done) | ||
562 | return_status = QLA_SUCCESS; | ||
563 | else | ||
564 | return_status = QLA_FUNCTION_FAILED; | ||
565 | |||
566 | return return_status; | ||
567 | } | ||
568 | |||
638 | /* | 569 | /* |
639 | * qla2x00_wait_for_loop_ready | 570 | * qla2x00_wait_for_loop_ready |
640 | * Wait for MAX_LOOP_TIMEOUT(5 min) value for loop | 571 | * Wait for MAX_LOOP_TIMEOUT(5 min) value for loop |
@@ -1163,7 +1094,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) | |||
1163 | continue; | 1094 | continue; |
1164 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | 1095 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { |
1165 | sp = req->outstanding_cmds[cnt]; | 1096 | sp = req->outstanding_cmds[cnt]; |
1166 | if (sp && sp->fcport->vha == vha) { | 1097 | if (sp) { |
1167 | req->outstanding_cmds[cnt] = NULL; | 1098 | req->outstanding_cmds[cnt] = NULL; |
1168 | sp->cmd->result = res; | 1099 | sp->cmd->result = res; |
1169 | qla2x00_sp_compl(ha, sp); | 1100 | qla2x00_sp_compl(ha, sp); |
@@ -1351,9 +1282,6 @@ static struct isp_operations qla2100_isp_ops = { | |||
1351 | .write_optrom = qla2x00_write_optrom_data, | 1282 | .write_optrom = qla2x00_write_optrom_data, |
1352 | .get_flash_version = qla2x00_get_flash_version, | 1283 | .get_flash_version = qla2x00_get_flash_version, |
1353 | .start_scsi = qla2x00_start_scsi, | 1284 | .start_scsi = qla2x00_start_scsi, |
1354 | .wrt_req_reg = NULL, | ||
1355 | .wrt_rsp_reg = NULL, | ||
1356 | .rd_req_reg = NULL, | ||
1357 | }; | 1285 | }; |
1358 | 1286 | ||
1359 | static struct isp_operations qla2300_isp_ops = { | 1287 | static struct isp_operations qla2300_isp_ops = { |
@@ -1389,9 +1317,6 @@ static struct isp_operations qla2300_isp_ops = { | |||
1389 | .write_optrom = qla2x00_write_optrom_data, | 1317 | .write_optrom = qla2x00_write_optrom_data, |
1390 | .get_flash_version = qla2x00_get_flash_version, | 1318 | .get_flash_version = qla2x00_get_flash_version, |
1391 | .start_scsi = qla2x00_start_scsi, | 1319 | .start_scsi = qla2x00_start_scsi, |
1392 | .wrt_req_reg = NULL, | ||
1393 | .wrt_rsp_reg = NULL, | ||
1394 | .rd_req_reg = NULL, | ||
1395 | }; | 1320 | }; |
1396 | 1321 | ||
1397 | static struct isp_operations qla24xx_isp_ops = { | 1322 | static struct isp_operations qla24xx_isp_ops = { |
@@ -1427,9 +1352,6 @@ static struct isp_operations qla24xx_isp_ops = { | |||
1427 | .write_optrom = qla24xx_write_optrom_data, | 1352 | .write_optrom = qla24xx_write_optrom_data, |
1428 | .get_flash_version = qla24xx_get_flash_version, | 1353 | .get_flash_version = qla24xx_get_flash_version, |
1429 | .start_scsi = qla24xx_start_scsi, | 1354 | .start_scsi = qla24xx_start_scsi, |
1430 | .wrt_req_reg = qla24xx_wrt_req_reg, | ||
1431 | .wrt_rsp_reg = qla24xx_wrt_rsp_reg, | ||
1432 | .rd_req_reg = qla24xx_rd_req_reg, | ||
1433 | }; | 1355 | }; |
1434 | 1356 | ||
1435 | static struct isp_operations qla25xx_isp_ops = { | 1357 | static struct isp_operations qla25xx_isp_ops = { |
@@ -1465,9 +1387,6 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1465 | .write_optrom = qla24xx_write_optrom_data, | 1387 | .write_optrom = qla24xx_write_optrom_data, |
1466 | .get_flash_version = qla24xx_get_flash_version, | 1388 | .get_flash_version = qla24xx_get_flash_version, |
1467 | .start_scsi = qla24xx_start_scsi, | 1389 | .start_scsi = qla24xx_start_scsi, |
1468 | .wrt_req_reg = qla24xx_wrt_req_reg, | ||
1469 | .wrt_rsp_reg = qla24xx_wrt_rsp_reg, | ||
1470 | .rd_req_reg = qla24xx_rd_req_reg, | ||
1471 | }; | 1390 | }; |
1472 | 1391 | ||
1473 | static struct isp_operations qla81xx_isp_ops = { | 1392 | static struct isp_operations qla81xx_isp_ops = { |
@@ -1493,8 +1412,8 @@ static struct isp_operations qla81xx_isp_ops = { | |||
1493 | .build_iocbs = NULL, | 1412 | .build_iocbs = NULL, |
1494 | .prep_ms_iocb = qla24xx_prep_ms_iocb, | 1413 | .prep_ms_iocb = qla24xx_prep_ms_iocb, |
1495 | .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, | 1414 | .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb, |
1496 | .read_nvram = qla25xx_read_nvram_data, | 1415 | .read_nvram = NULL, |
1497 | .write_nvram = qla25xx_write_nvram_data, | 1416 | .write_nvram = NULL, |
1498 | .fw_dump = qla81xx_fw_dump, | 1417 | .fw_dump = qla81xx_fw_dump, |
1499 | .beacon_on = qla24xx_beacon_on, | 1418 | .beacon_on = qla24xx_beacon_on, |
1500 | .beacon_off = qla24xx_beacon_off, | 1419 | .beacon_off = qla24xx_beacon_off, |
@@ -1503,9 +1422,6 @@ static struct isp_operations qla81xx_isp_ops = { | |||
1503 | .write_optrom = qla24xx_write_optrom_data, | 1422 | .write_optrom = qla24xx_write_optrom_data, |
1504 | .get_flash_version = qla24xx_get_flash_version, | 1423 | .get_flash_version = qla24xx_get_flash_version, |
1505 | .start_scsi = qla24xx_start_scsi, | 1424 | .start_scsi = qla24xx_start_scsi, |
1506 | .wrt_req_reg = qla24xx_wrt_req_reg, | ||
1507 | .wrt_rsp_reg = qla24xx_wrt_rsp_reg, | ||
1508 | .rd_req_reg = qla24xx_rd_req_reg, | ||
1509 | }; | 1425 | }; |
1510 | 1426 | ||
1511 | static inline void | 1427 | static inline void |
@@ -1727,7 +1643,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1727 | struct rsp_que *rsp = NULL; | 1643 | struct rsp_que *rsp = NULL; |
1728 | 1644 | ||
1729 | bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); | 1645 | bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); |
1730 | sht = &qla2x00_driver_template; | 1646 | sht = &qla2xxx_driver_template; |
1731 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || | 1647 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1732 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || | 1648 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || |
1733 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 || | 1649 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 || |
@@ -1736,7 +1652,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1736 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 || | 1652 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 || |
1737 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001) { | 1653 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001) { |
1738 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 1654 | bars = pci_select_bars(pdev, IORESOURCE_MEM); |
1739 | sht = &qla24xx_driver_template; | ||
1740 | mem_only = 1; | 1655 | mem_only = 1; |
1741 | } | 1656 | } |
1742 | 1657 | ||
@@ -1927,10 +1842,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1927 | ha->rsp_q_map[0] = rsp; | 1842 | ha->rsp_q_map[0] = rsp; |
1928 | ha->req_q_map[0] = req; | 1843 | ha->req_q_map[0] = req; |
1929 | 1844 | ||
1845 | /* FWI2-capable only. */ | ||
1846 | req->req_q_in = &ha->iobase->isp24.req_q_in; | ||
1847 | req->req_q_out = &ha->iobase->isp24.req_q_out; | ||
1848 | rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in; | ||
1849 | rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out; | ||
1930 | if (ha->mqenable) { | 1850 | if (ha->mqenable) { |
1931 | ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg; | 1851 | req->req_q_in = &ha->mqiobase->isp25mq.req_q_in; |
1932 | ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg; | 1852 | req->req_q_out = &ha->mqiobase->isp25mq.req_q_out; |
1933 | ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg; | 1853 | rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in; |
1854 | rsp->rsp_q_out = &ha->mqiobase->isp25mq.rsp_q_out; | ||
1934 | } | 1855 | } |
1935 | 1856 | ||
1936 | if (qla2x00_initialize_adapter(base_vha)) { | 1857 | if (qla2x00_initialize_adapter(base_vha)) { |
@@ -2000,6 +1921,16 @@ probe_init_failed: | |||
2000 | ha->max_queues = 0; | 1921 | ha->max_queues = 0; |
2001 | 1922 | ||
2002 | probe_failed: | 1923 | probe_failed: |
1924 | if (base_vha->timer_active) | ||
1925 | qla2x00_stop_timer(base_vha); | ||
1926 | base_vha->flags.online = 0; | ||
1927 | if (ha->dpc_thread) { | ||
1928 | struct task_struct *t = ha->dpc_thread; | ||
1929 | |||
1930 | ha->dpc_thread = NULL; | ||
1931 | kthread_stop(t); | ||
1932 | } | ||
1933 | |||
2003 | qla2x00_free_device(base_vha); | 1934 | qla2x00_free_device(base_vha); |
2004 | 1935 | ||
2005 | scsi_host_put(base_vha->host); | 1936 | scsi_host_put(base_vha->host); |
@@ -2033,10 +1964,30 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
2033 | 1964 | ||
2034 | set_bit(UNLOADING, &base_vha->dpc_flags); | 1965 | set_bit(UNLOADING, &base_vha->dpc_flags); |
2035 | 1966 | ||
1967 | qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); | ||
1968 | |||
2036 | qla2x00_dfs_remove(base_vha); | 1969 | qla2x00_dfs_remove(base_vha); |
2037 | 1970 | ||
2038 | qla84xx_put_chip(base_vha); | 1971 | qla84xx_put_chip(base_vha); |
2039 | 1972 | ||
1973 | /* Disable timer */ | ||
1974 | if (base_vha->timer_active) | ||
1975 | qla2x00_stop_timer(base_vha); | ||
1976 | |||
1977 | base_vha->flags.online = 0; | ||
1978 | |||
1979 | /* Kill the kernel thread for this host */ | ||
1980 | if (ha->dpc_thread) { | ||
1981 | struct task_struct *t = ha->dpc_thread; | ||
1982 | |||
1983 | /* | ||
1984 | * qla2xxx_wake_dpc checks for ->dpc_thread | ||
1985 | * so we need to zero it out. | ||
1986 | */ | ||
1987 | ha->dpc_thread = NULL; | ||
1988 | kthread_stop(t); | ||
1989 | } | ||
1990 | |||
2040 | qla2x00_free_sysfs_attr(base_vha); | 1991 | qla2x00_free_sysfs_attr(base_vha); |
2041 | 1992 | ||
2042 | fc_remove_host(base_vha->host); | 1993 | fc_remove_host(base_vha->host); |
@@ -2065,25 +2016,6 @@ static void | |||
2065 | qla2x00_free_device(scsi_qla_host_t *vha) | 2016 | qla2x00_free_device(scsi_qla_host_t *vha) |
2066 | { | 2017 | { |
2067 | struct qla_hw_data *ha = vha->hw; | 2018 | struct qla_hw_data *ha = vha->hw; |
2068 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
2069 | |||
2070 | /* Disable timer */ | ||
2071 | if (vha->timer_active) | ||
2072 | qla2x00_stop_timer(vha); | ||
2073 | |||
2074 | vha->flags.online = 0; | ||
2075 | |||
2076 | /* Kill the kernel thread for this host */ | ||
2077 | if (ha->dpc_thread) { | ||
2078 | struct task_struct *t = ha->dpc_thread; | ||
2079 | |||
2080 | /* | ||
2081 | * qla2xxx_wake_dpc checks for ->dpc_thread | ||
2082 | * so we need to zero it out. | ||
2083 | */ | ||
2084 | ha->dpc_thread = NULL; | ||
2085 | kthread_stop(t); | ||
2086 | } | ||
2087 | 2019 | ||
2088 | if (ha->flags.fce_enabled) | 2020 | if (ha->flags.fce_enabled) |
2089 | qla2x00_disable_fce_trace(vha, NULL, NULL); | 2021 | qla2x00_disable_fce_trace(vha, NULL, NULL); |
@@ -2313,9 +2245,19 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, | |||
2313 | } else | 2245 | } else |
2314 | ha->npiv_info = NULL; | 2246 | ha->npiv_info = NULL; |
2315 | 2247 | ||
2248 | /* Get consistent memory allocated for EX-INIT-CB. */ | ||
2249 | if (IS_QLA81XX(ha)) { | ||
2250 | ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, | ||
2251 | &ha->ex_init_cb_dma); | ||
2252 | if (!ha->ex_init_cb) | ||
2253 | goto fail_ex_init_cb; | ||
2254 | } | ||
2255 | |||
2316 | INIT_LIST_HEAD(&ha->vp_list); | 2256 | INIT_LIST_HEAD(&ha->vp_list); |
2317 | return 1; | 2257 | return 1; |
2318 | 2258 | ||
2259 | fail_ex_init_cb: | ||
2260 | kfree(ha->npiv_info); | ||
2319 | fail_npiv_info: | 2261 | fail_npiv_info: |
2320 | dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) * | 2262 | dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) * |
2321 | sizeof(response_t), (*rsp)->ring, (*rsp)->dma); | 2263 | sizeof(response_t), (*rsp)->ring, (*rsp)->dma); |
@@ -2398,18 +2340,22 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
2398 | if (ha->sfp_data) | 2340 | if (ha->sfp_data) |
2399 | dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); | 2341 | dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); |
2400 | 2342 | ||
2343 | if (ha->edc_data) | ||
2344 | dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma); | ||
2345 | |||
2401 | if (ha->ms_iocb) | 2346 | if (ha->ms_iocb) |
2402 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); | 2347 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
2403 | 2348 | ||
2349 | if (ha->ex_init_cb) | ||
2350 | dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); | ||
2351 | |||
2404 | if (ha->s_dma_pool) | 2352 | if (ha->s_dma_pool) |
2405 | dma_pool_destroy(ha->s_dma_pool); | 2353 | dma_pool_destroy(ha->s_dma_pool); |
2406 | 2354 | ||
2407 | |||
2408 | if (ha->gid_list) | 2355 | if (ha->gid_list) |
2409 | dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, | 2356 | dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list, |
2410 | ha->gid_list_dma); | 2357 | ha->gid_list_dma); |
2411 | 2358 | ||
2412 | |||
2413 | if (ha->init_cb) | 2359 | if (ha->init_cb) |
2414 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, | 2360 | dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, |
2415 | ha->init_cb, ha->init_cb_dma); | 2361 | ha->init_cb, ha->init_cb_dma); |
@@ -2428,6 +2374,8 @@ qla2x00_mem_free(struct qla_hw_data *ha) | |||
2428 | ha->ms_iocb_dma = 0; | 2374 | ha->ms_iocb_dma = 0; |
2429 | ha->init_cb = NULL; | 2375 | ha->init_cb = NULL; |
2430 | ha->init_cb_dma = 0; | 2376 | ha->init_cb_dma = 0; |
2377 | ha->ex_init_cb = NULL; | ||
2378 | ha->ex_init_cb_dma = 0; | ||
2431 | 2379 | ||
2432 | ha->s_dma_pool = NULL; | 2380 | ha->s_dma_pool = NULL; |
2433 | 2381 | ||
@@ -2914,19 +2862,11 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
2914 | spin_unlock_irqrestore(&ha->hardware_lock, | 2862 | spin_unlock_irqrestore(&ha->hardware_lock, |
2915 | cpu_flags); | 2863 | cpu_flags); |
2916 | } | 2864 | } |
2917 | set_bit(ABORT_QUEUES_NEEDED, &vha->dpc_flags); | ||
2918 | start_dpc++; | 2865 | start_dpc++; |
2919 | } | 2866 | } |
2920 | 2867 | ||
2921 | /* if the loop has been down for 4 minutes, reinit adapter */ | 2868 | /* if the loop has been down for 4 minutes, reinit adapter */ |
2922 | if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { | 2869 | if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { |
2923 | DEBUG(printk("scsi(%ld): Loop down exceed 4 mins - " | ||
2924 | "restarting queues.\n", | ||
2925 | vha->host_no)); | ||
2926 | |||
2927 | set_bit(RESTART_QUEUES_NEEDED, &vha->dpc_flags); | ||
2928 | start_dpc++; | ||
2929 | |||
2930 | if (!(vha->device_flags & DFLG_NO_CABLE) && | 2870 | if (!(vha->device_flags & DFLG_NO_CABLE) && |
2931 | !vha->vp_idx) { | 2871 | !vha->vp_idx) { |
2932 | DEBUG(printk("scsi(%ld): Loop down - " | 2872 | DEBUG(printk("scsi(%ld): Loop down - " |
@@ -3053,6 +2993,8 @@ qla2x00_release_firmware(void) | |||
3053 | static pci_ers_result_t | 2993 | static pci_ers_result_t |
3054 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | 2994 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
3055 | { | 2995 | { |
2996 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); | ||
2997 | |||
3056 | switch (state) { | 2998 | switch (state) { |
3057 | case pci_channel_io_normal: | 2999 | case pci_channel_io_normal: |
3058 | return PCI_ERS_RESULT_CAN_RECOVER; | 3000 | return PCI_ERS_RESULT_CAN_RECOVER; |
@@ -3060,7 +3002,7 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | |||
3060 | pci_disable_device(pdev); | 3002 | pci_disable_device(pdev); |
3061 | return PCI_ERS_RESULT_NEED_RESET; | 3003 | return PCI_ERS_RESULT_NEED_RESET; |
3062 | case pci_channel_io_perm_failure: | 3004 | case pci_channel_io_perm_failure: |
3063 | qla2x00_remove_one(pdev); | 3005 | qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); |
3064 | return PCI_ERS_RESULT_DISCONNECT; | 3006 | return PCI_ERS_RESULT_DISCONNECT; |
3065 | } | 3007 | } |
3066 | return PCI_ERS_RESULT_NEED_RESET; | 3008 | return PCI_ERS_RESULT_NEED_RESET; |