diff options
author | Madhuranath Iyengar <madhuranath.iyengar@qlogic.com> | 2010-05-04 18:01:28 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-05-16 18:21:56 -0400 |
commit | 4916392b56921b4aaaeaca3ef492135f42fbb5f2 (patch) | |
tree | 6f3a209b1386b74009c197978e677afa04f0d651 /drivers/scsi/qla2xxx/qla_init.c | |
parent | b7d2280c153b33fc60f1a89406d2329137a8b61c (diff) |
[SCSI] qla2xxx: Provide common framework for BSG and IOCB commands.
Currently, BSG and IOCB/Logio commands have a different
framework (srb structs). The purpose of this effort is to
consolidate them into a generalized framework for these
as well as other asynchronous operations in the future.
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 135 |
1 files changed, 78 insertions, 57 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 4e7a3d5493e6..72b4ef270158 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -48,6 +48,7 @@ qla2x00_ctx_sp_timeout(unsigned long __data) | |||
48 | { | 48 | { |
49 | srb_t *sp = (srb_t *)__data; | 49 | srb_t *sp = (srb_t *)__data; |
50 | struct srb_ctx *ctx; | 50 | struct srb_ctx *ctx; |
51 | struct srb_iocb *iocb; | ||
51 | fc_port_t *fcport = sp->fcport; | 52 | fc_port_t *fcport = sp->fcport; |
52 | struct qla_hw_data *ha = fcport->vha->hw; | 53 | struct qla_hw_data *ha = fcport->vha->hw; |
53 | struct req_que *req; | 54 | struct req_que *req; |
@@ -57,17 +58,21 @@ qla2x00_ctx_sp_timeout(unsigned long __data) | |||
57 | req = ha->req_q_map[0]; | 58 | req = ha->req_q_map[0]; |
58 | req->outstanding_cmds[sp->handle] = NULL; | 59 | req->outstanding_cmds[sp->handle] = NULL; |
59 | ctx = sp->ctx; | 60 | ctx = sp->ctx; |
60 | ctx->timeout(sp); | 61 | iocb = ctx->u.iocb_cmd; |
62 | iocb->timeout(sp); | ||
61 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 63 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
62 | 64 | ||
63 | ctx->free(sp); | 65 | iocb->free(sp); |
64 | } | 66 | } |
65 | 67 | ||
66 | void | 68 | void |
67 | qla2x00_ctx_sp_free(srb_t *sp) | 69 | qla2x00_ctx_sp_free(srb_t *sp) |
68 | { | 70 | { |
69 | struct srb_ctx *ctx = sp->ctx; | 71 | struct srb_ctx *ctx = sp->ctx; |
72 | struct srb_iocb *iocb = ctx->u.iocb_cmd; | ||
70 | 73 | ||
74 | del_timer_sync(&iocb->timer); | ||
75 | kfree(iocb); | ||
71 | kfree(ctx); | 76 | kfree(ctx); |
72 | mempool_free(sp, sp->fcport->vha->hw->srb_mempool); | 77 | mempool_free(sp, sp->fcport->vha->hw->srb_mempool); |
73 | } | 78 | } |
@@ -79,6 +84,7 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, | |||
79 | srb_t *sp; | 84 | srb_t *sp; |
80 | struct qla_hw_data *ha = vha->hw; | 85 | struct qla_hw_data *ha = vha->hw; |
81 | struct srb_ctx *ctx; | 86 | struct srb_ctx *ctx; |
87 | struct srb_iocb *iocb; | ||
82 | 88 | ||
83 | sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL); | 89 | sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL); |
84 | if (!sp) | 90 | if (!sp) |
@@ -86,21 +92,30 @@ qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size, | |||
86 | ctx = kzalloc(size, GFP_KERNEL); | 92 | ctx = kzalloc(size, GFP_KERNEL); |
87 | if (!ctx) { | 93 | if (!ctx) { |
88 | mempool_free(sp, ha->srb_mempool); | 94 | mempool_free(sp, ha->srb_mempool); |
95 | sp = NULL; | ||
96 | goto done; | ||
97 | } | ||
98 | iocb = kzalloc(sizeof(struct srb_iocb), GFP_KERNEL); | ||
99 | if (!iocb) { | ||
100 | mempool_free(sp, ha->srb_mempool); | ||
101 | sp = NULL; | ||
102 | kfree(ctx); | ||
89 | goto done; | 103 | goto done; |
90 | } | 104 | } |
91 | 105 | ||
92 | memset(sp, 0, sizeof(*sp)); | 106 | memset(sp, 0, sizeof(*sp)); |
93 | sp->fcport = fcport; | 107 | sp->fcport = fcport; |
94 | sp->ctx = ctx; | 108 | sp->ctx = ctx; |
95 | ctx->free = qla2x00_ctx_sp_free; | 109 | ctx->u.iocb_cmd = iocb; |
110 | iocb->free = qla2x00_ctx_sp_free; | ||
96 | 111 | ||
97 | init_timer(&ctx->timer); | 112 | init_timer(&iocb->timer); |
98 | if (!tmo) | 113 | if (!tmo) |
99 | goto done; | 114 | goto done; |
100 | ctx->timer.expires = jiffies + tmo * HZ; | 115 | iocb->timer.expires = jiffies + tmo * HZ; |
101 | ctx->timer.data = (unsigned long)sp; | 116 | iocb->timer.data = (unsigned long)sp; |
102 | ctx->timer.function = qla2x00_ctx_sp_timeout; | 117 | iocb->timer.function = qla2x00_ctx_sp_timeout; |
103 | add_timer(&ctx->timer); | 118 | add_timer(&iocb->timer); |
104 | done: | 119 | done: |
105 | return sp; | 120 | return sp; |
106 | } | 121 | } |
@@ -113,25 +128,26 @@ static void | |||
113 | qla2x00_async_logio_timeout(srb_t *sp) | 128 | qla2x00_async_logio_timeout(srb_t *sp) |
114 | { | 129 | { |
115 | fc_port_t *fcport = sp->fcport; | 130 | fc_port_t *fcport = sp->fcport; |
116 | struct srb_logio *lio = sp->ctx; | 131 | struct srb_ctx *ctx = sp->ctx; |
117 | 132 | ||
118 | DEBUG2(printk(KERN_WARNING | 133 | DEBUG2(printk(KERN_WARNING |
119 | "scsi(%ld:%x): Async-%s timeout.\n", | 134 | "scsi(%ld:%x): Async-%s timeout.\n", |
120 | fcport->vha->host_no, sp->handle, lio->ctx.name)); | 135 | fcport->vha->host_no, sp->handle, ctx->name)); |
121 | 136 | ||
122 | fcport->flags &= ~FCF_ASYNC_SENT; | 137 | fcport->flags &= ~FCF_ASYNC_SENT; |
123 | if (lio->ctx.type == SRB_LOGIN_CMD) | 138 | if (ctx->type == SRB_LOGIN_CMD) |
124 | qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); | 139 | qla2x00_post_async_logout_work(fcport->vha, fcport, NULL); |
125 | } | 140 | } |
126 | 141 | ||
127 | static void | 142 | static void |
128 | qla2x00_async_login_ctx_done(srb_t *sp) | 143 | qla2x00_async_login_ctx_done(srb_t *sp) |
129 | { | 144 | { |
130 | struct srb_logio *lio = sp->ctx; | 145 | struct srb_ctx *ctx = sp->ctx; |
146 | struct srb_iocb *lio = ctx->u.iocb_cmd; | ||
131 | 147 | ||
132 | qla2x00_post_async_login_done_work(sp->fcport->vha, sp->fcport, | 148 | qla2x00_post_async_login_done_work(sp->fcport->vha, sp->fcport, |
133 | lio->data); | 149 | lio->u.logio.data); |
134 | lio->ctx.free(sp); | 150 | lio->free(sp); |
135 | } | 151 | } |
136 | 152 | ||
137 | int | 153 | int |
@@ -140,23 +156,25 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
140 | { | 156 | { |
141 | struct qla_hw_data *ha = vha->hw; | 157 | struct qla_hw_data *ha = vha->hw; |
142 | srb_t *sp; | 158 | srb_t *sp; |
143 | struct srb_logio *lio; | 159 | struct srb_ctx *ctx; |
160 | struct srb_iocb *lio; | ||
144 | int rval; | 161 | int rval; |
145 | 162 | ||
146 | rval = QLA_FUNCTION_FAILED; | 163 | rval = QLA_FUNCTION_FAILED; |
147 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio), | 164 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), |
148 | ELS_TMO_2_RATOV(ha) + 2); | 165 | ELS_TMO_2_RATOV(ha) + 2); |
149 | if (!sp) | 166 | if (!sp) |
150 | goto done; | 167 | goto done; |
151 | 168 | ||
152 | lio = sp->ctx; | 169 | ctx = sp->ctx; |
153 | lio->ctx.type = SRB_LOGIN_CMD; | 170 | ctx->type = SRB_LOGIN_CMD; |
154 | lio->ctx.name = "login"; | 171 | ctx->name = "login"; |
155 | lio->ctx.timeout = qla2x00_async_logio_timeout; | 172 | lio = ctx->u.iocb_cmd; |
156 | lio->ctx.done = qla2x00_async_login_ctx_done; | 173 | lio->timeout = qla2x00_async_logio_timeout; |
157 | lio->flags |= SRB_LOGIN_COND_PLOGI; | 174 | lio->done = qla2x00_async_login_ctx_done; |
175 | lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; | ||
158 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | 176 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) |
159 | lio->flags |= SRB_LOGIN_RETRIED; | 177 | lio->u.logio.flags |= SRB_LOGIN_RETRIED; |
160 | rval = qla2x00_start_sp(sp); | 178 | rval = qla2x00_start_sp(sp); |
161 | if (rval != QLA_SUCCESS) | 179 | if (rval != QLA_SUCCESS) |
162 | goto done_free_sp; | 180 | goto done_free_sp; |
@@ -169,8 +187,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
169 | return rval; | 187 | return rval; |
170 | 188 | ||
171 | done_free_sp: | 189 | done_free_sp: |
172 | del_timer_sync(&lio->ctx.timer); | 190 | lio->free(sp); |
173 | lio->ctx.free(sp); | ||
174 | done: | 191 | done: |
175 | return rval; | 192 | return rval; |
176 | } | 193 | } |
@@ -178,11 +195,12 @@ done: | |||
178 | static void | 195 | static void |
179 | qla2x00_async_logout_ctx_done(srb_t *sp) | 196 | qla2x00_async_logout_ctx_done(srb_t *sp) |
180 | { | 197 | { |
181 | struct srb_logio *lio = sp->ctx; | 198 | struct srb_ctx *ctx = sp->ctx; |
199 | struct srb_iocb *lio = ctx->u.iocb_cmd; | ||
182 | 200 | ||
183 | qla2x00_post_async_logout_done_work(sp->fcport->vha, sp->fcport, | 201 | qla2x00_post_async_logout_done_work(sp->fcport->vha, sp->fcport, |
184 | lio->data); | 202 | lio->u.logio.data); |
185 | lio->ctx.free(sp); | 203 | lio->free(sp); |
186 | } | 204 | } |
187 | 205 | ||
188 | int | 206 | int |
@@ -190,20 +208,22 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
190 | { | 208 | { |
191 | struct qla_hw_data *ha = vha->hw; | 209 | struct qla_hw_data *ha = vha->hw; |
192 | srb_t *sp; | 210 | srb_t *sp; |
193 | struct srb_logio *lio; | 211 | struct srb_ctx *ctx; |
212 | struct srb_iocb *lio; | ||
194 | int rval; | 213 | int rval; |
195 | 214 | ||
196 | rval = QLA_FUNCTION_FAILED; | 215 | rval = QLA_FUNCTION_FAILED; |
197 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio), | 216 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), |
198 | ELS_TMO_2_RATOV(ha) + 2); | 217 | ELS_TMO_2_RATOV(ha) + 2); |
199 | if (!sp) | 218 | if (!sp) |
200 | goto done; | 219 | goto done; |
201 | 220 | ||
202 | lio = sp->ctx; | 221 | ctx = sp->ctx; |
203 | lio->ctx.type = SRB_LOGOUT_CMD; | 222 | ctx->type = SRB_LOGOUT_CMD; |
204 | lio->ctx.name = "logout"; | 223 | ctx->name = "logout"; |
205 | lio->ctx.timeout = qla2x00_async_logio_timeout; | 224 | lio = ctx->u.iocb_cmd; |
206 | lio->ctx.done = qla2x00_async_logout_ctx_done; | 225 | lio->timeout = qla2x00_async_logio_timeout; |
226 | lio->done = qla2x00_async_logout_ctx_done; | ||
207 | rval = qla2x00_start_sp(sp); | 227 | rval = qla2x00_start_sp(sp); |
208 | if (rval != QLA_SUCCESS) | 228 | if (rval != QLA_SUCCESS) |
209 | goto done_free_sp; | 229 | goto done_free_sp; |
@@ -215,8 +235,7 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
215 | return rval; | 235 | return rval; |
216 | 236 | ||
217 | done_free_sp: | 237 | done_free_sp: |
218 | del_timer_sync(&lio->ctx.timer); | 238 | lio->free(sp); |
219 | lio->ctx.free(sp); | ||
220 | done: | 239 | done: |
221 | return rval; | 240 | return rval; |
222 | } | 241 | } |
@@ -224,11 +243,12 @@ done: | |||
224 | static void | 243 | static void |
225 | qla2x00_async_adisc_ctx_done(srb_t *sp) | 244 | qla2x00_async_adisc_ctx_done(srb_t *sp) |
226 | { | 245 | { |
227 | struct srb_logio *lio = sp->ctx; | 246 | struct srb_ctx *ctx = sp->ctx; |
247 | struct srb_iocb *lio = ctx->u.iocb_cmd; | ||
228 | 248 | ||
229 | qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport, | 249 | qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport, |
230 | lio->data); | 250 | lio->u.logio.data); |
231 | lio->ctx.free(sp); | 251 | lio->free(sp); |
232 | } | 252 | } |
233 | 253 | ||
234 | int | 254 | int |
@@ -237,22 +257,24 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
237 | { | 257 | { |
238 | struct qla_hw_data *ha = vha->hw; | 258 | struct qla_hw_data *ha = vha->hw; |
239 | srb_t *sp; | 259 | srb_t *sp; |
240 | struct srb_logio *lio; | 260 | struct srb_ctx *ctx; |
261 | struct srb_iocb *lio; | ||
241 | int rval; | 262 | int rval; |
242 | 263 | ||
243 | rval = QLA_FUNCTION_FAILED; | 264 | rval = QLA_FUNCTION_FAILED; |
244 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio), | 265 | sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx), |
245 | ELS_TMO_2_RATOV(ha) + 2); | 266 | ELS_TMO_2_RATOV(ha) + 2); |
246 | if (!sp) | 267 | if (!sp) |
247 | goto done; | 268 | goto done; |
248 | 269 | ||
249 | lio = sp->ctx; | 270 | ctx = sp->ctx; |
250 | lio->ctx.type = SRB_ADISC_CMD; | 271 | ctx->type = SRB_ADISC_CMD; |
251 | lio->ctx.name = "adisc"; | 272 | ctx->name = "adisc"; |
252 | lio->ctx.timeout = qla2x00_async_logio_timeout; | 273 | lio = ctx->u.iocb_cmd; |
253 | lio->ctx.done = qla2x00_async_adisc_ctx_done; | 274 | lio->timeout = qla2x00_async_logio_timeout; |
275 | lio->done = qla2x00_async_adisc_ctx_done; | ||
254 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | 276 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) |
255 | lio->flags |= SRB_LOGIN_RETRIED; | 277 | lio->u.logio.flags |= SRB_LOGIN_RETRIED; |
256 | rval = qla2x00_start_sp(sp); | 278 | rval = qla2x00_start_sp(sp); |
257 | if (rval != QLA_SUCCESS) | 279 | if (rval != QLA_SUCCESS) |
258 | goto done_free_sp; | 280 | goto done_free_sp; |
@@ -265,13 +287,12 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
265 | return rval; | 287 | return rval; |
266 | 288 | ||
267 | done_free_sp: | 289 | done_free_sp: |
268 | del_timer_sync(&lio->ctx.timer); | 290 | lio->free(sp); |
269 | lio->ctx.free(sp); | ||
270 | done: | 291 | done: |
271 | return rval; | 292 | return rval; |
272 | } | 293 | } |
273 | 294 | ||
274 | int | 295 | void |
275 | qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 296 | qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
276 | uint16_t *data) | 297 | uint16_t *data) |
277 | { | 298 | { |
@@ -308,25 +329,25 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
308 | qla2x00_post_async_login_work(vha, fcport, NULL); | 329 | qla2x00_post_async_login_work(vha, fcport, NULL); |
309 | break; | 330 | break; |
310 | } | 331 | } |
311 | return QLA_SUCCESS; | 332 | return; |
312 | } | 333 | } |
313 | 334 | ||
314 | int | 335 | void |
315 | qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 336 | qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
316 | uint16_t *data) | 337 | uint16_t *data) |
317 | { | 338 | { |
318 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 339 | qla2x00_mark_device_lost(vha, fcport, 1, 0); |
319 | return QLA_SUCCESS; | 340 | return; |
320 | } | 341 | } |
321 | 342 | ||
322 | int | 343 | void |
323 | qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 344 | qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
324 | uint16_t *data) | 345 | uint16_t *data) |
325 | { | 346 | { |
326 | if (data[0] == MBS_COMMAND_COMPLETE) { | 347 | if (data[0] == MBS_COMMAND_COMPLETE) { |
327 | qla2x00_update_fcport(vha, fcport); | 348 | qla2x00_update_fcport(vha, fcport); |
328 | 349 | ||
329 | return QLA_SUCCESS; | 350 | return; |
330 | } | 351 | } |
331 | 352 | ||
332 | /* Retry login. */ | 353 | /* Retry login. */ |
@@ -336,7 +357,7 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
336 | else | 357 | else |
337 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 358 | qla2x00_mark_device_lost(vha, fcport, 1, 0); |
338 | 359 | ||
339 | return QLA_SUCCESS; | 360 | return; |
340 | } | 361 | } |
341 | 362 | ||
342 | /****************************************************************************/ | 363 | /****************************************************************************/ |