[SCSI] qla2xxx: Add dev_loss_tmo_callbk/terminate_rport_io callback support.

Signed-off-by: Seokmann Ju <seokmann.ju@qlogic.com>
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

Seokmann Ju and committed by
James Bottomley
5f3a9a20 bbfb21da

+78 -25
+31
drivers/scsi/qla2xxx/qla_attr.c
··· 994 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 1024 static int 998 1025 qla2x00_issue_lip(struct Scsi_Host *shost) 999 1026 { ··· 1280 1253 .show_rport_dev_loss_tmo = 1, 1281 1254 1282 1255 .issue_fc_host_lip = qla2x00_issue_lip, 1256 + .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, 1257 + .terminate_rport_io = qla2x00_terminate_rport_io, 1283 1258 .get_fc_host_stats = qla2x00_get_fc_host_stats, 1284 1259 1285 1260 .vport_create = qla24xx_vport_create, ··· 1325 1296 .show_rport_dev_loss_tmo = 1, 1326 1297 1327 1298 .issue_fc_host_lip = qla2x00_issue_lip, 1299 + .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, 1300 + .terminate_rport_io = qla2x00_terminate_rport_io, 1328 1301 .get_fc_host_stats = qla2x00_get_fc_host_stats, 1329 1302 }; 1330 1303
-1
drivers/scsi/qla2xxx/qla_def.h
··· 1544 1544 int login_retry; 1545 1545 atomic_t port_down_timer; 1546 1546 1547 - spinlock_t rport_lock; 1548 1547 struct fc_rport *rport, *drport; 1549 1548 u32 supported_classes; 1550 1549
+2
drivers/scsi/qla2xxx/qla_gbl.h
··· 71 71 extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, 72 72 uint16_t, uint16_t); 73 73 74 + extern void qla2x00_abort_fcport_cmds(fc_port_t *); 75 + 74 76 /* 75 77 * Global Functions in qla_mid.c source file. 76 78 */
+5 -11
drivers/scsi/qla2xxx/qla_init.c
··· 1864 1864 { 1865 1865 fc_port_t *fcport = data; 1866 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 1869 rport = fcport->drport; 1871 1870 fcport->drport = NULL; 1872 - spin_unlock_irqrestore(&fcport->rport_lock, flags); 1871 + spin_unlock_irq(fcport->ha->host->host_lock); 1873 1872 if (rport) 1874 1873 fc_remote_port_delete(rport); 1875 1874 } ··· 1897 1898 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1898 1899 fcport->flags = FCF_RLC_SUPPORT; 1899 1900 fcport->supported_classes = FC_COS_UNSPECIFIED; 1900 - spin_lock_init(&fcport->rport_lock); 1901 1901 1902 1902 return fcport; 1903 1903 } ··· 2241 2243 { 2242 2244 struct fc_rport_identifiers rport_ids; 2243 2245 struct fc_rport *rport; 2244 - unsigned long flags; 2245 2246 2246 2247 if (fcport->drport) 2247 2248 qla2x00_rport_del(fcport); 2248 - if (fcport->rport) 2249 - return; 2250 2249 2251 2250 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2252 2251 rport_ids.port_name = wwn_to_u64(fcport->port_name); 2253 2252 rport_ids.port_id = fcport->d_id.b.domain << 16 | 2254 2253 fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; 2255 2254 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2256 - rport = fc_remote_port_add(ha->host, 0, &rport_ids); 2255 + fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); 2257 2256 if (!rport) { 2258 2257 qla_printk(KERN_WARNING, ha, 2259 2258 "Unable to allocate fc remote port!\n"); 2260 2259 return; 2261 2260 } 2262 - spin_lock_irqsave(&fcport->rport_lock, flags); 2263 - fcport->rport = rport; 2261 + spin_lock_irq(fcport->ha->host->host_lock); 2264 2262 *((fc_port_t **)rport->dd_data) = fcport; 2265 - spin_unlock_irqrestore(&fcport->rport_lock, flags); 2263 + spin_unlock_irq(fcport->ha->host->host_lock); 2266 2264 2267 2265 rport->supported_classes = fcport->supported_classes; 2268 2266
+40 -13
drivers/scsi/qla2xxx/qla_os.c
··· 388 388 } 389 389 390 390 /* Close window on fcport/rport state-transitioning. */ 391 - if (!*(fc_port_t **)rport->dd_data) { 391 + if (fcport->drport) { 392 392 cmd->result = DID_IMM_RETRY << 16; 393 393 goto qc_fail_command; 394 394 } ··· 455 455 } 456 456 457 457 /* Close window on fcport/rport state-transitioning. */ 458 - if (!*(fc_port_t **)rport->dd_data) { 458 + if (fcport->drport) { 459 459 cmd->result = DID_IMM_RETRY << 16; 460 460 goto qc24_fail_command; 461 461 } ··· 615 615 } 616 616 } 617 617 return (return_status); 618 + } 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); 618 652 } 619 653 620 654 static void ··· 1847 1813 qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, 1848 1814 int defer) 1849 1815 { 1850 - unsigned long flags; 1851 1816 struct fc_rport *rport; 1852 1817 1853 1818 if (!fcport->rport) ··· 1854 1821 1855 1822 rport = fcport->rport; 1856 1823 if (defer) { 1857 - spin_lock_irqsave(&fcport->rport_lock, flags); 1824 + spin_lock_irq(ha->host->host_lock); 1858 1825 fcport->drport = rport; 1859 - fcport->rport = NULL; 1860 - *(fc_port_t **)rport->dd_data = NULL; 1861 - spin_unlock_irqrestore(&fcport->rport_lock, flags); 1826 + spin_unlock_irq(ha->host->host_lock); 1862 1827 set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); 1863 - } else { 1864 - spin_lock_irqsave(&fcport->rport_lock, flags); 1865 - fcport->rport = NULL; 1866 - *(fc_port_t **)rport->dd_data = NULL; 1867 - spin_unlock_irqrestore(&fcport->rport_lock, flags); 1828 + qla2xxx_wake_dpc(ha); 1829 + } else 1868 1830 fc_remote_port_delete(rport); 1869 - } 1870 1831 } 1871 1832 1872 1833 /*