diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 31 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 53 |
5 files changed, 78 insertions, 25 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 8dd88fc1244a..3112518b0e64 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -994,6 +994,33 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | |||
994 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 994 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; |
995 | } | 995 | } |
996 | 996 | ||
997 | static void | ||
998 | qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) | ||
999 | { | ||
1000 | struct Scsi_Host *host = rport_to_shost(rport); | ||
1001 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; | ||
1002 | |||
1003 | qla2x00_abort_fcport_cmds(fcport); | ||
1004 | |||
1005 | /* | ||
1006 | * Transport has effectively 'deleted' the rport, clear | ||
1007 | * all local references. | ||
1008 | */ | ||
1009 | spin_lock_irq(host->host_lock); | ||
1010 | fcport->rport = NULL; | ||
1011 | *((fc_port_t **)rport->dd_data) = NULL; | ||
1012 | spin_unlock_irq(host->host_lock); | ||
1013 | } | ||
1014 | |||
1015 | static void | ||
1016 | qla2x00_terminate_rport_io(struct fc_rport *rport) | ||
1017 | { | ||
1018 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; | ||
1019 | |||
1020 | qla2x00_abort_fcport_cmds(fcport); | ||
1021 | scsi_target_unblock(&rport->dev); | ||
1022 | } | ||
1023 | |||
997 | static int | 1024 | static int |
998 | qla2x00_issue_lip(struct Scsi_Host *shost) | 1025 | qla2x00_issue_lip(struct Scsi_Host *shost) |
999 | { | 1026 | { |
@@ -1253,6 +1280,8 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
1253 | .show_rport_dev_loss_tmo = 1, | 1280 | .show_rport_dev_loss_tmo = 1, |
1254 | 1281 | ||
1255 | .issue_fc_host_lip = qla2x00_issue_lip, | 1282 | .issue_fc_host_lip = qla2x00_issue_lip, |
1283 | .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, | ||
1284 | .terminate_rport_io = qla2x00_terminate_rport_io, | ||
1256 | .get_fc_host_stats = qla2x00_get_fc_host_stats, | 1285 | .get_fc_host_stats = qla2x00_get_fc_host_stats, |
1257 | 1286 | ||
1258 | .vport_create = qla24xx_vport_create, | 1287 | .vport_create = qla24xx_vport_create, |
@@ -1296,6 +1325,8 @@ struct fc_function_template qla2xxx_transport_vport_functions = { | |||
1296 | .show_rport_dev_loss_tmo = 1, | 1325 | .show_rport_dev_loss_tmo = 1, |
1297 | 1326 | ||
1298 | .issue_fc_host_lip = qla2x00_issue_lip, | 1327 | .issue_fc_host_lip = qla2x00_issue_lip, |
1328 | .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, | ||
1329 | .terminate_rport_io = qla2x00_terminate_rport_io, | ||
1299 | .get_fc_host_stats = qla2x00_get_fc_host_stats, | 1330 | .get_fc_host_stats = qla2x00_get_fc_host_stats, |
1300 | }; | 1331 | }; |
1301 | 1332 | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 8dd600013bd1..7b0ddc83413f 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1544,7 +1544,6 @@ typedef struct fc_port { | |||
1544 | int login_retry; | 1544 | int login_retry; |
1545 | atomic_t port_down_timer; | 1545 | atomic_t port_down_timer; |
1546 | 1546 | ||
1547 | spinlock_t rport_lock; | ||
1548 | struct fc_rport *rport, *drport; | 1547 | struct fc_rport *rport, *drport; |
1549 | u32 supported_classes; | 1548 | u32 supported_classes; |
1550 | 1549 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 9b4bebee6879..5a50fb749728 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -71,6 +71,8 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum | |||
71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, | 71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, |
72 | uint16_t, uint16_t); | 72 | uint16_t, uint16_t); |
73 | 73 | ||
74 | extern void qla2x00_abort_fcport_cmds(fc_port_t *); | ||
75 | |||
74 | /* | 76 | /* |
75 | * Global Functions in qla_mid.c source file. | 77 | * Global Functions in qla_mid.c source file. |
76 | */ | 78 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index bbbc5a632a1d..c7388fadf225 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1864,12 +1864,11 @@ qla2x00_rport_del(void *data) | |||
1864 | { | 1864 | { |
1865 | fc_port_t *fcport = data; | 1865 | fc_port_t *fcport = data; |
1866 | struct fc_rport *rport; | 1866 | struct fc_rport *rport; |
1867 | unsigned long flags; | ||
1868 | 1867 | ||
1869 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1868 | spin_lock_irq(fcport->ha->host->host_lock); |
1870 | rport = fcport->drport; | 1869 | rport = fcport->drport; |
1871 | fcport->drport = NULL; | 1870 | fcport->drport = NULL; |
1872 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1871 | spin_unlock_irq(fcport->ha->host->host_lock); |
1873 | if (rport) | 1872 | if (rport) |
1874 | fc_remote_port_delete(rport); | 1873 | fc_remote_port_delete(rport); |
1875 | } | 1874 | } |
@@ -1898,7 +1897,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | |||
1898 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | 1897 | atomic_set(&fcport->state, FCS_UNCONFIGURED); |
1899 | fcport->flags = FCF_RLC_SUPPORT; | 1898 | fcport->flags = FCF_RLC_SUPPORT; |
1900 | fcport->supported_classes = FC_COS_UNSPECIFIED; | 1899 | fcport->supported_classes = FC_COS_UNSPECIFIED; |
1901 | spin_lock_init(&fcport->rport_lock); | ||
1902 | 1900 | ||
1903 | return fcport; | 1901 | return fcport; |
1904 | } | 1902 | } |
@@ -2243,28 +2241,24 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2243 | { | 2241 | { |
2244 | struct fc_rport_identifiers rport_ids; | 2242 | struct fc_rport_identifiers rport_ids; |
2245 | struct fc_rport *rport; | 2243 | struct fc_rport *rport; |
2246 | unsigned long flags; | ||
2247 | 2244 | ||
2248 | if (fcport->drport) | 2245 | if (fcport->drport) |
2249 | qla2x00_rport_del(fcport); | 2246 | qla2x00_rport_del(fcport); |
2250 | if (fcport->rport) | ||
2251 | return; | ||
2252 | 2247 | ||
2253 | rport_ids.node_name = wwn_to_u64(fcport->node_name); | 2248 | rport_ids.node_name = wwn_to_u64(fcport->node_name); |
2254 | rport_ids.port_name = wwn_to_u64(fcport->port_name); | 2249 | rport_ids.port_name = wwn_to_u64(fcport->port_name); |
2255 | rport_ids.port_id = fcport->d_id.b.domain << 16 | | 2250 | rport_ids.port_id = fcport->d_id.b.domain << 16 | |
2256 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 2251 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
2257 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 2252 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; |
2258 | rport = fc_remote_port_add(ha->host, 0, &rport_ids); | 2253 | fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); |
2259 | if (!rport) { | 2254 | if (!rport) { |
2260 | qla_printk(KERN_WARNING, ha, | 2255 | qla_printk(KERN_WARNING, ha, |
2261 | "Unable to allocate fc remote port!\n"); | 2256 | "Unable to allocate fc remote port!\n"); |
2262 | return; | 2257 | return; |
2263 | } | 2258 | } |
2264 | spin_lock_irqsave(&fcport->rport_lock, flags); | 2259 | spin_lock_irq(fcport->ha->host->host_lock); |
2265 | fcport->rport = rport; | ||
2266 | *((fc_port_t **)rport->dd_data) = fcport; | 2260 | *((fc_port_t **)rport->dd_data) = fcport; |
2267 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 2261 | spin_unlock_irq(fcport->ha->host->host_lock); |
2268 | 2262 | ||
2269 | rport->supported_classes = fcport->supported_classes; | 2263 | rport->supported_classes = fcport->supported_classes; |
2270 | 2264 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 48eaa3bb5433..c5ad858e17e6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -388,7 +388,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
388 | } | 388 | } |
389 | 389 | ||
390 | /* Close window on fcport/rport state-transitioning. */ | 390 | /* Close window on fcport/rport state-transitioning. */ |
391 | if (!*(fc_port_t **)rport->dd_data) { | 391 | if (fcport->drport) { |
392 | cmd->result = DID_IMM_RETRY << 16; | 392 | cmd->result = DID_IMM_RETRY << 16; |
393 | goto qc_fail_command; | 393 | goto qc_fail_command; |
394 | } | 394 | } |
@@ -455,7 +455,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
455 | } | 455 | } |
456 | 456 | ||
457 | /* Close window on fcport/rport state-transitioning. */ | 457 | /* Close window on fcport/rport state-transitioning. */ |
458 | if (!*(fc_port_t **)rport->dd_data) { | 458 | if (fcport->drport) { |
459 | cmd->result = DID_IMM_RETRY << 16; | 459 | cmd->result = DID_IMM_RETRY << 16; |
460 | goto qc24_fail_command; | 460 | goto qc24_fail_command; |
461 | } | 461 | } |
@@ -617,6 +617,40 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) | |||
617 | return (return_status); | 617 | return (return_status); |
618 | } | 618 | } |
619 | 619 | ||
620 | void | ||
621 | qla2x00_abort_fcport_cmds(fc_port_t *fcport) | ||
622 | { | ||
623 | int cnt; | ||
624 | unsigned long flags; | ||
625 | srb_t *sp; | ||
626 | scsi_qla_host_t *ha = fcport->ha; | ||
627 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
628 | |||
629 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
630 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
631 | sp = pha->outstanding_cmds[cnt]; | ||
632 | if (!sp) | ||
633 | continue; | ||
634 | if (sp->fcport != fcport) | ||
635 | continue; | ||
636 | |||
637 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
638 | if (ha->isp_ops->abort_command(ha, sp)) { | ||
639 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
640 | "Abort failed -- %lx\n", sp->cmd->serial_number)); | ||
641 | } else { | ||
642 | if (qla2x00_eh_wait_on_command(ha, sp->cmd) != | ||
643 | QLA_SUCCESS) | ||
644 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
645 | "Abort failed while waiting -- %lx\n", | ||
646 | sp->cmd->serial_number)); | ||
647 | |||
648 | } | ||
649 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
650 | } | ||
651 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
652 | } | ||
653 | |||
620 | static void | 654 | static void |
621 | qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | 655 | qla2x00_block_error_handler(struct scsi_cmnd *cmnd) |
622 | { | 656 | { |
@@ -1813,7 +1847,6 @@ static inline void | |||
1813 | qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, | 1847 | qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, |
1814 | int defer) | 1848 | int defer) |
1815 | { | 1849 | { |
1816 | unsigned long flags; | ||
1817 | struct fc_rport *rport; | 1850 | struct fc_rport *rport; |
1818 | 1851 | ||
1819 | if (!fcport->rport) | 1852 | if (!fcport->rport) |
@@ -1821,19 +1854,13 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, | |||
1821 | 1854 | ||
1822 | rport = fcport->rport; | 1855 | rport = fcport->rport; |
1823 | if (defer) { | 1856 | if (defer) { |
1824 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1857 | spin_lock_irq(ha->host->host_lock); |
1825 | fcport->drport = rport; | 1858 | fcport->drport = rport; |
1826 | fcport->rport = NULL; | 1859 | spin_unlock_irq(ha->host->host_lock); |
1827 | *(fc_port_t **)rport->dd_data = NULL; | ||
1828 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1829 | set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); | 1860 | set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); |
1830 | } else { | 1861 | qla2xxx_wake_dpc(ha); |
1831 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1862 | } else |
1832 | fcport->rport = NULL; | ||
1833 | *(fc_port_t **)rport->dd_data = NULL; | ||
1834 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1835 | fc_remote_port_delete(rport); | 1863 | fc_remote_port_delete(rport); |
1836 | } | ||
1837 | } | 1864 | } |
1838 | 1865 | ||
1839 | /* | 1866 | /* |