aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorMadhuranath Iyengar <madhuranath.iyengar@qlogic.com>2010-05-04 18:01:28 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-16 18:21:56 -0400
commit4916392b56921b4aaaeaca3ef492135f42fbb5f2 (patch)
tree6f3a209b1386b74009c197978e677afa04f0d651 /drivers/scsi/qla2xxx/qla_init.c
parentb7d2280c153b33fc60f1a89406d2329137a8b61c (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.c135
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
66void 68void
67qla2x00_ctx_sp_free(srb_t *sp) 69qla2x00_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);
104done: 119done:
105 return sp; 120 return sp;
106} 121}
@@ -113,25 +128,26 @@ static void
113qla2x00_async_logio_timeout(srb_t *sp) 128qla2x00_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
127static void 142static void
128qla2x00_async_login_ctx_done(srb_t *sp) 143qla2x00_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
137int 153int
@@ -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
171done_free_sp: 189done_free_sp:
172 del_timer_sync(&lio->ctx.timer); 190 lio->free(sp);
173 lio->ctx.free(sp);
174done: 191done:
175 return rval; 192 return rval;
176} 193}
@@ -178,11 +195,12 @@ done:
178static void 195static void
179qla2x00_async_logout_ctx_done(srb_t *sp) 196qla2x00_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
188int 206int
@@ -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
217done_free_sp: 237done_free_sp:
218 del_timer_sync(&lio->ctx.timer); 238 lio->free(sp);
219 lio->ctx.free(sp);
220done: 239done:
221 return rval; 240 return rval;
222} 241}
@@ -224,11 +243,12 @@ done:
224static void 243static void
225qla2x00_async_adisc_ctx_done(srb_t *sp) 244qla2x00_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
234int 254int
@@ -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
267done_free_sp: 289done_free_sp:
268 del_timer_sync(&lio->ctx.timer); 290 lio->free(sp);
269 lio->ctx.free(sp);
270done: 291done:
271 return rval; 292 return rval;
272} 293}
273 294
274int 295void
275qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, 296qla2x00_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
314int 335void
315qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, 336qla2x00_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
322int 343void
323qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, 344qla2x00_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/****************************************************************************/