aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c149
2 files changed, 73 insertions, 77 deletions
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index ac3d418e3990..9c7fbd4da9b8 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -220,7 +220,6 @@ extern void qla24xx_sched_upd_fcport(fc_port_t *);
220void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, 220void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
221 uint16_t *); 221 uint16_t *);
222int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *); 222int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
223int qla24xx_async_abort_cmd(srb_t *, bool);
224int qla24xx_post_relogin_work(struct scsi_qla_host *vha); 223int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
225void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *); 224void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
226 225
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 241ff5ae26f0..8945278ff0be 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -95,6 +95,79 @@ qla2x00_get_async_timeout(struct scsi_qla_host *vha)
95 return tmo; 95 return tmo;
96} 96}
97 97
98static void qla24xx_abort_iocb_timeout(void *data)
99{
100 srb_t *sp = data;
101 struct srb_iocb *abt = &sp->u.iocb_cmd;
102
103 abt->u.abt.comp_status = CS_TIMEOUT;
104 sp->done(sp, QLA_FUNCTION_TIMEOUT);
105}
106
107static void qla24xx_abort_sp_done(void *ptr, int res)
108{
109 srb_t *sp = ptr;
110 struct srb_iocb *abt = &sp->u.iocb_cmd;
111
112 if (del_timer(&sp->u.iocb_cmd.timer)) {
113 if (sp->flags & SRB_WAKEUP_ON_COMP)
114 complete(&abt->u.abt.comp);
115 else
116 sp->free(sp);
117 }
118}
119
120static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
121{
122 scsi_qla_host_t *vha = cmd_sp->vha;
123 struct srb_iocb *abt_iocb;
124 srb_t *sp;
125 int rval = QLA_FUNCTION_FAILED;
126
127 sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
128 GFP_ATOMIC);
129 if (!sp)
130 goto done;
131
132 abt_iocb = &sp->u.iocb_cmd;
133 sp->type = SRB_ABT_CMD;
134 sp->name = "abort";
135 sp->qpair = cmd_sp->qpair;
136 if (wait)
137 sp->flags = SRB_WAKEUP_ON_COMP;
138
139 abt_iocb->timeout = qla24xx_abort_iocb_timeout;
140 init_completion(&abt_iocb->u.abt.comp);
141 /* FW can send 2 x ABTS's timeout/20s */
142 qla2x00_init_timer(sp, 42);
143
144 abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
145 abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id);
146
147 sp->done = qla24xx_abort_sp_done;
148
149 ql_dbg(ql_dbg_async, vha, 0x507c,
150 "Abort command issued - hdl=%x, type=%x\n", cmd_sp->handle,
151 cmd_sp->type);
152
153 rval = qla2x00_start_sp(sp);
154 if (rval != QLA_SUCCESS)
155 goto done_free_sp;
156
157 if (wait) {
158 wait_for_completion(&abt_iocb->u.abt.comp);
159 rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
160 QLA_SUCCESS : QLA_FUNCTION_FAILED;
161 } else {
162 goto done;
163 }
164
165done_free_sp:
166 sp->free(sp);
167done:
168 return rval;
169}
170
98void 171void
99qla2x00_async_iocb_timeout(void *data) 172qla2x00_async_iocb_timeout(void *data)
100{ 173{
@@ -1785,82 +1858,6 @@ done:
1785 return rval; 1858 return rval;
1786} 1859}
1787 1860
1788static void
1789qla24xx_abort_iocb_timeout(void *data)
1790{
1791 srb_t *sp = data;
1792 struct srb_iocb *abt = &sp->u.iocb_cmd;
1793
1794 abt->u.abt.comp_status = CS_TIMEOUT;
1795 sp->done(sp, QLA_FUNCTION_TIMEOUT);
1796}
1797
1798static void
1799qla24xx_abort_sp_done(void *ptr, int res)
1800{
1801 srb_t *sp = ptr;
1802 struct srb_iocb *abt = &sp->u.iocb_cmd;
1803
1804 if (del_timer(&sp->u.iocb_cmd.timer)) {
1805 if (sp->flags & SRB_WAKEUP_ON_COMP)
1806 complete(&abt->u.abt.comp);
1807 else
1808 sp->free(sp);
1809 }
1810}
1811
1812int
1813qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
1814{
1815 scsi_qla_host_t *vha = cmd_sp->vha;
1816 struct srb_iocb *abt_iocb;
1817 srb_t *sp;
1818 int rval = QLA_FUNCTION_FAILED;
1819
1820 sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
1821 GFP_ATOMIC);
1822 if (!sp)
1823 goto done;
1824
1825 abt_iocb = &sp->u.iocb_cmd;
1826 sp->type = SRB_ABT_CMD;
1827 sp->name = "abort";
1828 sp->qpair = cmd_sp->qpair;
1829 if (wait)
1830 sp->flags = SRB_WAKEUP_ON_COMP;
1831
1832 abt_iocb->timeout = qla24xx_abort_iocb_timeout;
1833 init_completion(&abt_iocb->u.abt.comp);
1834 /* FW can send 2 x ABTS's timeout/20s */
1835 qla2x00_init_timer(sp, 42);
1836
1837 abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
1838 abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id);
1839
1840 sp->done = qla24xx_abort_sp_done;
1841
1842 ql_dbg(ql_dbg_async, vha, 0x507c,
1843 "Abort command issued - hdl=%x, type=%x\n",
1844 cmd_sp->handle, cmd_sp->type);
1845
1846 rval = qla2x00_start_sp(sp);
1847 if (rval != QLA_SUCCESS)
1848 goto done_free_sp;
1849
1850 if (wait) {
1851 wait_for_completion(&abt_iocb->u.abt.comp);
1852 rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
1853 QLA_SUCCESS : QLA_FUNCTION_FAILED;
1854 } else {
1855 goto done;
1856 }
1857
1858done_free_sp:
1859 sp->free(sp);
1860done:
1861 return rval;
1862}
1863
1864int 1861int
1865qla24xx_async_abort_command(srb_t *sp) 1862qla24xx_async_abort_command(srb_t *sp)
1866{ 1863{