diff options
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 1091 |
1 files changed, 713 insertions, 378 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 8b57af5baaec..553168ae44f1 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/kfifo.h> | 25 | #include <linux/kfifo.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/log2.h> | ||
27 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
28 | #include <net/tcp.h> | 29 | #include <net/tcp.h> |
29 | #include <scsi/scsi_cmnd.h> | 30 | #include <scsi/scsi_cmnd.h> |
@@ -86,7 +87,7 @@ iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) | |||
86 | * xmit thread | 87 | * xmit thread |
87 | */ | 88 | */ |
88 | if (!list_empty(&session->leadconn->xmitqueue) || | 89 | if (!list_empty(&session->leadconn->xmitqueue) || |
89 | __kfifo_len(session->leadconn->mgmtqueue)) | 90 | !list_empty(&session->leadconn->mgmtqueue)) |
90 | scsi_queue_work(session->host, | 91 | scsi_queue_work(session->host, |
91 | &session->leadconn->xmitwork); | 92 | &session->leadconn->xmitwork); |
92 | } | 93 | } |
@@ -122,6 +123,20 @@ void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, | |||
122 | } | 123 | } |
123 | EXPORT_SYMBOL_GPL(iscsi_prep_unsolicit_data_pdu); | 124 | EXPORT_SYMBOL_GPL(iscsi_prep_unsolicit_data_pdu); |
124 | 125 | ||
126 | static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len) | ||
127 | { | ||
128 | unsigned exp_len = ctask->hdr_len + len; | ||
129 | |||
130 | if (exp_len > ctask->hdr_max) { | ||
131 | WARN_ON(1); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | WARN_ON(len & (ISCSI_PAD_LEN - 1)); /* caller must pad the AHS */ | ||
136 | ctask->hdr_len = exp_len; | ||
137 | return 0; | ||
138 | } | ||
139 | |||
125 | /** | 140 | /** |
126 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu | 141 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu |
127 | * @ctask: iscsi cmd task | 142 | * @ctask: iscsi cmd task |
@@ -129,27 +144,32 @@ EXPORT_SYMBOL_GPL(iscsi_prep_unsolicit_data_pdu); | |||
129 | * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set | 144 | * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set |
130 | * fields like dlength or final based on how much data it sends | 145 | * fields like dlength or final based on how much data it sends |
131 | */ | 146 | */ |
132 | static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | 147 | static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) |
133 | { | 148 | { |
134 | struct iscsi_conn *conn = ctask->conn; | 149 | struct iscsi_conn *conn = ctask->conn; |
135 | struct iscsi_session *session = conn->session; | 150 | struct iscsi_session *session = conn->session; |
136 | struct iscsi_cmd *hdr = ctask->hdr; | 151 | struct iscsi_cmd *hdr = ctask->hdr; |
137 | struct scsi_cmnd *sc = ctask->sc; | 152 | struct scsi_cmnd *sc = ctask->sc; |
153 | unsigned hdrlength; | ||
154 | int rc; | ||
138 | 155 | ||
139 | hdr->opcode = ISCSI_OP_SCSI_CMD; | 156 | ctask->hdr_len = 0; |
140 | hdr->flags = ISCSI_ATTR_SIMPLE; | 157 | rc = iscsi_add_hdr(ctask, sizeof(*hdr)); |
141 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); | 158 | if (rc) |
142 | hdr->itt = build_itt(ctask->itt, conn->id, session->age); | 159 | return rc; |
143 | hdr->data_length = cpu_to_be32(scsi_bufflen(sc)); | 160 | hdr->opcode = ISCSI_OP_SCSI_CMD; |
144 | hdr->cmdsn = cpu_to_be32(session->cmdsn); | 161 | hdr->flags = ISCSI_ATTR_SIMPLE; |
145 | session->cmdsn++; | 162 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); |
146 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); | 163 | hdr->itt = build_itt(ctask->itt, conn->id, session->age); |
147 | memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); | 164 | hdr->data_length = cpu_to_be32(scsi_bufflen(sc)); |
165 | hdr->cmdsn = cpu_to_be32(session->cmdsn); | ||
166 | session->cmdsn++; | ||
167 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); | ||
168 | memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); | ||
148 | if (sc->cmd_len < MAX_COMMAND_SIZE) | 169 | if (sc->cmd_len < MAX_COMMAND_SIZE) |
149 | memset(&hdr->cdb[sc->cmd_len], 0, | 170 | memset(&hdr->cdb[sc->cmd_len], 0, |
150 | MAX_COMMAND_SIZE - sc->cmd_len); | 171 | MAX_COMMAND_SIZE - sc->cmd_len); |
151 | 172 | ||
152 | ctask->data_count = 0; | ||
153 | ctask->imm_count = 0; | 173 | ctask->imm_count = 0; |
154 | if (sc->sc_data_direction == DMA_TO_DEVICE) { | 174 | if (sc->sc_data_direction == DMA_TO_DEVICE) { |
155 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; | 175 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; |
@@ -178,9 +198,9 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
178 | else | 198 | else |
179 | ctask->imm_count = min(scsi_bufflen(sc), | 199 | ctask->imm_count = min(scsi_bufflen(sc), |
180 | conn->max_xmit_dlength); | 200 | conn->max_xmit_dlength); |
181 | hton24(ctask->hdr->dlength, ctask->imm_count); | 201 | hton24(hdr->dlength, ctask->imm_count); |
182 | } else | 202 | } else |
183 | zero_data(ctask->hdr->dlength); | 203 | zero_data(hdr->dlength); |
184 | 204 | ||
185 | if (!session->initial_r2t_en) { | 205 | if (!session->initial_r2t_en) { |
186 | ctask->unsol_count = min((session->first_burst), | 206 | ctask->unsol_count = min((session->first_burst), |
@@ -190,7 +210,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
190 | 210 | ||
191 | if (!ctask->unsol_count) | 211 | if (!ctask->unsol_count) |
192 | /* No unsolicit Data-Out's */ | 212 | /* No unsolicit Data-Out's */ |
193 | ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 213 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
194 | } else { | 214 | } else { |
195 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 215 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
196 | zero_data(hdr->dlength); | 216 | zero_data(hdr->dlength); |
@@ -199,13 +219,25 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
199 | hdr->flags |= ISCSI_FLAG_CMD_READ; | 219 | hdr->flags |= ISCSI_FLAG_CMD_READ; |
200 | } | 220 | } |
201 | 221 | ||
202 | conn->scsicmd_pdus_cnt++; | 222 | /* calculate size of additional header segments (AHSs) */ |
223 | hdrlength = ctask->hdr_len - sizeof(*hdr); | ||
224 | |||
225 | WARN_ON(hdrlength & (ISCSI_PAD_LEN-1)); | ||
226 | hdrlength /= ISCSI_PAD_LEN; | ||
227 | |||
228 | WARN_ON(hdrlength >= 256); | ||
229 | hdr->hlength = hdrlength & 0xFF; | ||
230 | |||
231 | if (conn->session->tt->init_cmd_task(conn->ctask)) | ||
232 | return EIO; | ||
203 | 233 | ||
204 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " | 234 | conn->scsicmd_pdus_cnt++; |
235 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " | ||
205 | "cmdsn %d win %d]\n", | 236 | "cmdsn %d win %d]\n", |
206 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", | 237 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", |
207 | conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc), | 238 | conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc), |
208 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); | 239 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); |
240 | return 0; | ||
209 | } | 241 | } |
210 | 242 | ||
211 | /** | 243 | /** |
@@ -218,13 +250,16 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
218 | */ | 250 | */ |
219 | static void iscsi_complete_command(struct iscsi_cmd_task *ctask) | 251 | static void iscsi_complete_command(struct iscsi_cmd_task *ctask) |
220 | { | 252 | { |
221 | struct iscsi_session *session = ctask->conn->session; | 253 | struct iscsi_conn *conn = ctask->conn; |
254 | struct iscsi_session *session = conn->session; | ||
222 | struct scsi_cmnd *sc = ctask->sc; | 255 | struct scsi_cmnd *sc = ctask->sc; |
223 | 256 | ||
224 | ctask->state = ISCSI_TASK_COMPLETED; | 257 | ctask->state = ISCSI_TASK_COMPLETED; |
225 | ctask->sc = NULL; | 258 | ctask->sc = NULL; |
226 | /* SCSI eh reuses commands to verify us */ | 259 | /* SCSI eh reuses commands to verify us */ |
227 | sc->SCp.ptr = NULL; | 260 | sc->SCp.ptr = NULL; |
261 | if (conn->ctask == ctask) | ||
262 | conn->ctask = NULL; | ||
228 | list_del_init(&ctask->running); | 263 | list_del_init(&ctask->running); |
229 | __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); | 264 | __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); |
230 | sc->scsi_done(sc); | 265 | sc->scsi_done(sc); |
@@ -241,6 +276,112 @@ static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask) | |||
241 | iscsi_complete_command(ctask); | 276 | iscsi_complete_command(ctask); |
242 | } | 277 | } |
243 | 278 | ||
279 | /* | ||
280 | * session lock must be held | ||
281 | */ | ||
282 | static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | ||
283 | int err) | ||
284 | { | ||
285 | struct scsi_cmnd *sc; | ||
286 | |||
287 | sc = ctask->sc; | ||
288 | if (!sc) | ||
289 | return; | ||
290 | |||
291 | if (ctask->state == ISCSI_TASK_PENDING) | ||
292 | /* | ||
293 | * cmd never made it to the xmit thread, so we should not count | ||
294 | * the cmd in the sequencing | ||
295 | */ | ||
296 | conn->session->queued_cmdsn--; | ||
297 | else | ||
298 | conn->session->tt->cleanup_cmd_task(conn, ctask); | ||
299 | |||
300 | sc->result = err; | ||
301 | scsi_set_resid(sc, scsi_bufflen(sc)); | ||
302 | if (conn->ctask == ctask) | ||
303 | conn->ctask = NULL; | ||
304 | /* release ref from queuecommand */ | ||
305 | __iscsi_put_ctask(ctask); | ||
306 | } | ||
307 | |||
308 | /** | ||
309 | * iscsi_free_mgmt_task - return mgmt task back to pool | ||
310 | * @conn: iscsi connection | ||
311 | * @mtask: mtask | ||
312 | * | ||
313 | * Must be called with session lock. | ||
314 | */ | ||
315 | void iscsi_free_mgmt_task(struct iscsi_conn *conn, | ||
316 | struct iscsi_mgmt_task *mtask) | ||
317 | { | ||
318 | list_del_init(&mtask->running); | ||
319 | if (conn->login_mtask == mtask) | ||
320 | return; | ||
321 | |||
322 | if (conn->ping_mtask == mtask) | ||
323 | conn->ping_mtask = NULL; | ||
324 | __kfifo_put(conn->session->mgmtpool.queue, | ||
325 | (void*)&mtask, sizeof(void*)); | ||
326 | } | ||
327 | EXPORT_SYMBOL_GPL(iscsi_free_mgmt_task); | ||
328 | |||
329 | static struct iscsi_mgmt_task * | ||
330 | __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | ||
331 | char *data, uint32_t data_size) | ||
332 | { | ||
333 | struct iscsi_session *session = conn->session; | ||
334 | struct iscsi_mgmt_task *mtask; | ||
335 | |||
336 | if (session->state == ISCSI_STATE_TERMINATE) | ||
337 | return NULL; | ||
338 | |||
339 | if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || | ||
340 | hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) | ||
341 | /* | ||
342 | * Login and Text are sent serially, in | ||
343 | * request-followed-by-response sequence. | ||
344 | * Same mtask can be used. Same ITT must be used. | ||
345 | * Note that login_mtask is preallocated at conn_create(). | ||
346 | */ | ||
347 | mtask = conn->login_mtask; | ||
348 | else { | ||
349 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); | ||
350 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); | ||
351 | |||
352 | if (!__kfifo_get(session->mgmtpool.queue, | ||
353 | (void*)&mtask, sizeof(void*))) | ||
354 | return NULL; | ||
355 | } | ||
356 | |||
357 | if (data_size) { | ||
358 | memcpy(mtask->data, data, data_size); | ||
359 | mtask->data_count = data_size; | ||
360 | } else | ||
361 | mtask->data_count = 0; | ||
362 | |||
363 | memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr)); | ||
364 | INIT_LIST_HEAD(&mtask->running); | ||
365 | list_add_tail(&mtask->running, &conn->mgmtqueue); | ||
366 | return mtask; | ||
367 | } | ||
368 | |||
369 | int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, | ||
370 | char *data, uint32_t data_size) | ||
371 | { | ||
372 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
373 | struct iscsi_session *session = conn->session; | ||
374 | int err = 0; | ||
375 | |||
376 | spin_lock_bh(&session->lock); | ||
377 | if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size)) | ||
378 | err = -EPERM; | ||
379 | spin_unlock_bh(&session->lock); | ||
380 | scsi_queue_work(session->host, &conn->xmitwork); | ||
381 | return err; | ||
382 | } | ||
383 | EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); | ||
384 | |||
244 | /** | 385 | /** |
245 | * iscsi_cmd_rsp - SCSI Command Response processing | 386 | * iscsi_cmd_rsp - SCSI Command Response processing |
246 | * @conn: iscsi connection | 387 | * @conn: iscsi connection |
@@ -291,17 +432,19 @@ invalid_datalen: | |||
291 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); | 432 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); |
292 | } | 433 | } |
293 | 434 | ||
294 | if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { | 435 | if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW | |
436 | ISCSI_FLAG_CMD_OVERFLOW)) { | ||
295 | int res_count = be32_to_cpu(rhdr->residual_count); | 437 | int res_count = be32_to_cpu(rhdr->residual_count); |
296 | 438 | ||
297 | if (res_count > 0 && res_count <= scsi_bufflen(sc)) | 439 | if (res_count > 0 && |
440 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || | ||
441 | res_count <= scsi_bufflen(sc))) | ||
298 | scsi_set_resid(sc, res_count); | 442 | scsi_set_resid(sc, res_count); |
299 | else | 443 | else |
300 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | 444 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; |
301 | } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) | 445 | } else if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW | |
446 | ISCSI_FLAG_CMD_BIDI_OVERFLOW)) | ||
302 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | 447 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; |
303 | else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) | ||
304 | scsi_set_resid(sc, be32_to_cpu(rhdr->residual_count)); | ||
305 | 448 | ||
306 | out: | 449 | out: |
307 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", | 450 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", |
@@ -318,18 +461,51 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
318 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | 461 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; |
319 | conn->tmfrsp_pdus_cnt++; | 462 | conn->tmfrsp_pdus_cnt++; |
320 | 463 | ||
321 | if (conn->tmabort_state != TMABORT_INITIAL) | 464 | if (conn->tmf_state != TMF_QUEUED) |
322 | return; | 465 | return; |
323 | 466 | ||
324 | if (tmf->response == ISCSI_TMF_RSP_COMPLETE) | 467 | if (tmf->response == ISCSI_TMF_RSP_COMPLETE) |
325 | conn->tmabort_state = TMABORT_SUCCESS; | 468 | conn->tmf_state = TMF_SUCCESS; |
326 | else if (tmf->response == ISCSI_TMF_RSP_NO_TASK) | 469 | else if (tmf->response == ISCSI_TMF_RSP_NO_TASK) |
327 | conn->tmabort_state = TMABORT_NOT_FOUND; | 470 | conn->tmf_state = TMF_NOT_FOUND; |
328 | else | 471 | else |
329 | conn->tmabort_state = TMABORT_FAILED; | 472 | conn->tmf_state = TMF_FAILED; |
330 | wake_up(&conn->ehwait); | 473 | wake_up(&conn->ehwait); |
331 | } | 474 | } |
332 | 475 | ||
476 | static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) | ||
477 | { | ||
478 | struct iscsi_nopout hdr; | ||
479 | struct iscsi_mgmt_task *mtask; | ||
480 | |||
481 | if (!rhdr && conn->ping_mtask) | ||
482 | return; | ||
483 | |||
484 | memset(&hdr, 0, sizeof(struct iscsi_nopout)); | ||
485 | hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE; | ||
486 | hdr.flags = ISCSI_FLAG_CMD_FINAL; | ||
487 | |||
488 | if (rhdr) { | ||
489 | memcpy(hdr.lun, rhdr->lun, 8); | ||
490 | hdr.ttt = rhdr->ttt; | ||
491 | hdr.itt = RESERVED_ITT; | ||
492 | } else | ||
493 | hdr.ttt = RESERVED_ITT; | ||
494 | |||
495 | mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); | ||
496 | if (!mtask) { | ||
497 | printk(KERN_ERR "Could not send nopout\n"); | ||
498 | return; | ||
499 | } | ||
500 | |||
501 | /* only track our nops */ | ||
502 | if (!rhdr) { | ||
503 | conn->ping_mtask = mtask; | ||
504 | conn->last_ping = jiffies; | ||
505 | } | ||
506 | scsi_queue_work(conn->session->host, &conn->xmitwork); | ||
507 | } | ||
508 | |||
333 | static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | 509 | static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, |
334 | char *data, int datalen) | 510 | char *data, int datalen) |
335 | { | 511 | { |
@@ -374,6 +550,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
374 | struct iscsi_mgmt_task *mtask; | 550 | struct iscsi_mgmt_task *mtask; |
375 | uint32_t itt; | 551 | uint32_t itt; |
376 | 552 | ||
553 | conn->last_recv = jiffies; | ||
377 | if (hdr->itt != RESERVED_ITT) | 554 | if (hdr->itt != RESERVED_ITT) |
378 | itt = get_itt(hdr->itt); | 555 | itt = get_itt(hdr->itt); |
379 | else | 556 | else |
@@ -429,10 +606,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
429 | */ | 606 | */ |
430 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) | 607 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) |
431 | rc = ISCSI_ERR_CONN_FAILED; | 608 | rc = ISCSI_ERR_CONN_FAILED; |
432 | list_del(&mtask->running); | 609 | iscsi_free_mgmt_task(conn, mtask); |
433 | if (conn->login_mtask != mtask) | ||
434 | __kfifo_put(session->mgmtpool.queue, | ||
435 | (void*)&mtask, sizeof(void*)); | ||
436 | break; | 610 | break; |
437 | case ISCSI_OP_SCSI_TMFUNC_RSP: | 611 | case ISCSI_OP_SCSI_TMFUNC_RSP: |
438 | if (datalen) { | 612 | if (datalen) { |
@@ -441,20 +615,26 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
441 | } | 615 | } |
442 | 616 | ||
443 | iscsi_tmf_rsp(conn, hdr); | 617 | iscsi_tmf_rsp(conn, hdr); |
618 | iscsi_free_mgmt_task(conn, mtask); | ||
444 | break; | 619 | break; |
445 | case ISCSI_OP_NOOP_IN: | 620 | case ISCSI_OP_NOOP_IN: |
446 | if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || datalen) { | 621 | if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || |
622 | datalen) { | ||
447 | rc = ISCSI_ERR_PROTO; | 623 | rc = ISCSI_ERR_PROTO; |
448 | break; | 624 | break; |
449 | } | 625 | } |
450 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | 626 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; |
451 | 627 | ||
452 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) | 628 | if (conn->ping_mtask != mtask) { |
453 | rc = ISCSI_ERR_CONN_FAILED; | 629 | /* |
454 | list_del(&mtask->running); | 630 | * If this is not in response to one of our |
455 | if (conn->login_mtask != mtask) | 631 | * nops then it must be from userspace. |
456 | __kfifo_put(session->mgmtpool.queue, | 632 | */ |
457 | (void*)&mtask, sizeof(void*)); | 633 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, |
634 | datalen)) | ||
635 | rc = ISCSI_ERR_CONN_FAILED; | ||
636 | } | ||
637 | iscsi_free_mgmt_task(conn, mtask); | ||
458 | break; | 638 | break; |
459 | default: | 639 | default: |
460 | rc = ISCSI_ERR_BAD_OPCODE; | 640 | rc = ISCSI_ERR_BAD_OPCODE; |
@@ -473,8 +653,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
473 | if (hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) | 653 | if (hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) |
474 | break; | 654 | break; |
475 | 655 | ||
476 | if (iscsi_recv_pdu(conn->cls_conn, hdr, NULL, 0)) | 656 | iscsi_send_nopout(conn, (struct iscsi_nopin*)hdr); |
477 | rc = ISCSI_ERR_CONN_FAILED; | ||
478 | break; | 657 | break; |
479 | case ISCSI_OP_REJECT: | 658 | case ISCSI_OP_REJECT: |
480 | rc = iscsi_handle_reject(conn, hdr, data, datalen); | 659 | rc = iscsi_handle_reject(conn, hdr, data, datalen); |
@@ -609,20 +788,19 @@ static void iscsi_prep_mtask(struct iscsi_conn *conn, | |||
609 | session->tt->init_mgmt_task(conn, mtask); | 788 | session->tt->init_mgmt_task(conn, mtask); |
610 | 789 | ||
611 | debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", | 790 | debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", |
612 | hdr->opcode, hdr->itt, mtask->data_count); | 791 | hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, |
792 | mtask->data_count); | ||
613 | } | 793 | } |
614 | 794 | ||
615 | static int iscsi_xmit_mtask(struct iscsi_conn *conn) | 795 | static int iscsi_xmit_mtask(struct iscsi_conn *conn) |
616 | { | 796 | { |
617 | struct iscsi_hdr *hdr = conn->mtask->hdr; | 797 | struct iscsi_hdr *hdr = conn->mtask->hdr; |
618 | int rc, was_logout = 0; | 798 | int rc; |
619 | 799 | ||
800 | if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) | ||
801 | conn->session->state = ISCSI_STATE_LOGGING_OUT; | ||
620 | spin_unlock_bh(&conn->session->lock); | 802 | spin_unlock_bh(&conn->session->lock); |
621 | if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) { | 803 | |
622 | conn->session->state = ISCSI_STATE_IN_RECOVERY; | ||
623 | iscsi_block_session(session_to_cls(conn->session)); | ||
624 | was_logout = 1; | ||
625 | } | ||
626 | rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); | 804 | rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); |
627 | spin_lock_bh(&conn->session->lock); | 805 | spin_lock_bh(&conn->session->lock); |
628 | if (rc) | 806 | if (rc) |
@@ -630,11 +808,6 @@ static int iscsi_xmit_mtask(struct iscsi_conn *conn) | |||
630 | 808 | ||
631 | /* done with this in-progress mtask */ | 809 | /* done with this in-progress mtask */ |
632 | conn->mtask = NULL; | 810 | conn->mtask = NULL; |
633 | |||
634 | if (was_logout) { | ||
635 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
636 | return -ENODATA; | ||
637 | } | ||
638 | return 0; | 811 | return 0; |
639 | } | 812 | } |
640 | 813 | ||
@@ -658,21 +831,13 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) | |||
658 | static int iscsi_xmit_ctask(struct iscsi_conn *conn) | 831 | static int iscsi_xmit_ctask(struct iscsi_conn *conn) |
659 | { | 832 | { |
660 | struct iscsi_cmd_task *ctask = conn->ctask; | 833 | struct iscsi_cmd_task *ctask = conn->ctask; |
661 | int rc = 0; | 834 | int rc; |
662 | |||
663 | /* | ||
664 | * serialize with TMF AbortTask | ||
665 | */ | ||
666 | if (ctask->state == ISCSI_TASK_ABORTING) | ||
667 | goto done; | ||
668 | 835 | ||
669 | __iscsi_get_ctask(ctask); | 836 | __iscsi_get_ctask(ctask); |
670 | spin_unlock_bh(&conn->session->lock); | 837 | spin_unlock_bh(&conn->session->lock); |
671 | rc = conn->session->tt->xmit_cmd_task(conn, ctask); | 838 | rc = conn->session->tt->xmit_cmd_task(conn, ctask); |
672 | spin_lock_bh(&conn->session->lock); | 839 | spin_lock_bh(&conn->session->lock); |
673 | __iscsi_put_ctask(ctask); | 840 | __iscsi_put_ctask(ctask); |
674 | |||
675 | done: | ||
676 | if (!rc) | 841 | if (!rc) |
677 | /* done with this ctask */ | 842 | /* done with this ctask */ |
678 | conn->ctask = NULL; | 843 | conn->ctask = NULL; |
@@ -680,6 +845,22 @@ done: | |||
680 | } | 845 | } |
681 | 846 | ||
682 | /** | 847 | /** |
848 | * iscsi_requeue_ctask - requeue ctask to run from session workqueue | ||
849 | * @ctask: ctask to requeue | ||
850 | * | ||
851 | * LLDs that need to run a ctask from the session workqueue should call | ||
852 | * this. The session lock must be held. | ||
853 | */ | ||
854 | void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask) | ||
855 | { | ||
856 | struct iscsi_conn *conn = ctask->conn; | ||
857 | |||
858 | list_move_tail(&ctask->running, &conn->requeue); | ||
859 | scsi_queue_work(conn->session->host, &conn->xmitwork); | ||
860 | } | ||
861 | EXPORT_SYMBOL_GPL(iscsi_requeue_ctask); | ||
862 | |||
863 | /** | ||
683 | * iscsi_data_xmit - xmit any command into the scheduled connection | 864 | * iscsi_data_xmit - xmit any command into the scheduled connection |
684 | * @conn: iscsi connection | 865 | * @conn: iscsi connection |
685 | * | 866 | * |
@@ -717,36 +898,40 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
717 | * overflow us with nop-ins | 898 | * overflow us with nop-ins |
718 | */ | 899 | */ |
719 | check_mgmt: | 900 | check_mgmt: |
720 | while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask, | 901 | while (!list_empty(&conn->mgmtqueue)) { |
721 | sizeof(void*))) { | 902 | conn->mtask = list_entry(conn->mgmtqueue.next, |
903 | struct iscsi_mgmt_task, running); | ||
904 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { | ||
905 | iscsi_free_mgmt_task(conn, conn->mtask); | ||
906 | conn->mtask = NULL; | ||
907 | continue; | ||
908 | } | ||
909 | |||
722 | iscsi_prep_mtask(conn, conn->mtask); | 910 | iscsi_prep_mtask(conn, conn->mtask); |
723 | list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); | 911 | list_move_tail(conn->mgmtqueue.next, &conn->mgmt_run_list); |
724 | rc = iscsi_xmit_mtask(conn); | 912 | rc = iscsi_xmit_mtask(conn); |
725 | if (rc) | 913 | if (rc) |
726 | goto again; | 914 | goto again; |
727 | } | 915 | } |
728 | 916 | ||
729 | /* process command queue */ | 917 | /* process pending command queue */ |
730 | while (!list_empty(&conn->xmitqueue)) { | 918 | while (!list_empty(&conn->xmitqueue)) { |
731 | /* | 919 | if (conn->tmf_state == TMF_QUEUED) |
732 | * iscsi tcp may readd the task to the xmitqueue to send | 920 | break; |
733 | * write data | 921 | |
734 | */ | ||
735 | conn->ctask = list_entry(conn->xmitqueue.next, | 922 | conn->ctask = list_entry(conn->xmitqueue.next, |
736 | struct iscsi_cmd_task, running); | 923 | struct iscsi_cmd_task, running); |
737 | switch (conn->ctask->state) { | 924 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { |
738 | case ISCSI_TASK_ABORTING: | 925 | fail_command(conn, conn->ctask, DID_IMM_RETRY << 16); |
739 | break; | 926 | continue; |
740 | case ISCSI_TASK_PENDING: | 927 | } |
741 | iscsi_prep_scsi_cmd_pdu(conn->ctask); | 928 | if (iscsi_prep_scsi_cmd_pdu(conn->ctask)) { |
742 | conn->session->tt->init_cmd_task(conn->ctask); | 929 | fail_command(conn, conn->ctask, DID_ABORT << 16); |
743 | /* fall through */ | 930 | continue; |
744 | default: | ||
745 | conn->ctask->state = ISCSI_TASK_RUNNING; | ||
746 | break; | ||
747 | } | 931 | } |
748 | list_move_tail(conn->xmitqueue.next, &conn->run_list); | ||
749 | 932 | ||
933 | conn->ctask->state = ISCSI_TASK_RUNNING; | ||
934 | list_move_tail(conn->xmitqueue.next, &conn->run_list); | ||
750 | rc = iscsi_xmit_ctask(conn); | 935 | rc = iscsi_xmit_ctask(conn); |
751 | if (rc) | 936 | if (rc) |
752 | goto again; | 937 | goto again; |
@@ -755,7 +940,28 @@ check_mgmt: | |||
755 | * we need to check the mgmt queue for nops that need to | 940 | * we need to check the mgmt queue for nops that need to |
756 | * be sent to aviod starvation | 941 | * be sent to aviod starvation |
757 | */ | 942 | */ |
758 | if (__kfifo_len(conn->mgmtqueue)) | 943 | if (!list_empty(&conn->mgmtqueue)) |
944 | goto check_mgmt; | ||
945 | } | ||
946 | |||
947 | while (!list_empty(&conn->requeue)) { | ||
948 | if (conn->session->fast_abort && conn->tmf_state != TMF_INITIAL) | ||
949 | break; | ||
950 | |||
951 | /* | ||
952 | * we always do fastlogout - conn stop code will clean up. | ||
953 | */ | ||
954 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) | ||
955 | break; | ||
956 | |||
957 | conn->ctask = list_entry(conn->requeue.next, | ||
958 | struct iscsi_cmd_task, running); | ||
959 | conn->ctask->state = ISCSI_TASK_RUNNING; | ||
960 | list_move_tail(conn->requeue.next, &conn->run_list); | ||
961 | rc = iscsi_xmit_ctask(conn); | ||
962 | if (rc) | ||
963 | goto again; | ||
964 | if (!list_empty(&conn->mgmtqueue)) | ||
759 | goto check_mgmt; | 965 | goto check_mgmt; |
760 | } | 966 | } |
761 | spin_unlock_bh(&conn->session->lock); | 967 | spin_unlock_bh(&conn->session->lock); |
@@ -790,6 +996,7 @@ enum { | |||
790 | FAILURE_SESSION_TERMINATE, | 996 | FAILURE_SESSION_TERMINATE, |
791 | FAILURE_SESSION_IN_RECOVERY, | 997 | FAILURE_SESSION_IN_RECOVERY, |
792 | FAILURE_SESSION_RECOVERY_TIMEOUT, | 998 | FAILURE_SESSION_RECOVERY_TIMEOUT, |
999 | FAILURE_SESSION_LOGGING_OUT, | ||
793 | }; | 1000 | }; |
794 | 1001 | ||
795 | int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | 1002 | int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) |
@@ -805,8 +1012,9 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
805 | sc->SCp.ptr = NULL; | 1012 | sc->SCp.ptr = NULL; |
806 | 1013 | ||
807 | host = sc->device->host; | 1014 | host = sc->device->host; |
808 | session = iscsi_hostdata(host->hostdata); | 1015 | spin_unlock(host->host_lock); |
809 | 1016 | ||
1017 | session = iscsi_hostdata(host->hostdata); | ||
810 | spin_lock(&session->lock); | 1018 | spin_lock(&session->lock); |
811 | 1019 | ||
812 | /* | 1020 | /* |
@@ -822,17 +1030,22 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
822 | * be entering our queuecommand while a block is starting | 1030 | * be entering our queuecommand while a block is starting |
823 | * up because the block code is not locked) | 1031 | * up because the block code is not locked) |
824 | */ | 1032 | */ |
825 | if (session->state == ISCSI_STATE_IN_RECOVERY) { | 1033 | switch (session->state) { |
1034 | case ISCSI_STATE_IN_RECOVERY: | ||
826 | reason = FAILURE_SESSION_IN_RECOVERY; | 1035 | reason = FAILURE_SESSION_IN_RECOVERY; |
827 | goto reject; | 1036 | goto reject; |
828 | } | 1037 | case ISCSI_STATE_LOGGING_OUT: |
829 | 1038 | reason = FAILURE_SESSION_LOGGING_OUT; | |
830 | if (session->state == ISCSI_STATE_RECOVERY_FAILED) | 1039 | goto reject; |
1040 | case ISCSI_STATE_RECOVERY_FAILED: | ||
831 | reason = FAILURE_SESSION_RECOVERY_TIMEOUT; | 1041 | reason = FAILURE_SESSION_RECOVERY_TIMEOUT; |
832 | else if (session->state == ISCSI_STATE_TERMINATE) | 1042 | break; |
1043 | case ISCSI_STATE_TERMINATE: | ||
833 | reason = FAILURE_SESSION_TERMINATE; | 1044 | reason = FAILURE_SESSION_TERMINATE; |
834 | else | 1045 | break; |
1046 | default: | ||
835 | reason = FAILURE_SESSION_FREED; | 1047 | reason = FAILURE_SESSION_FREED; |
1048 | } | ||
836 | goto fault; | 1049 | goto fault; |
837 | } | 1050 | } |
838 | 1051 | ||
@@ -859,7 +1072,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
859 | 1072 | ||
860 | atomic_set(&ctask->refcount, 1); | 1073 | atomic_set(&ctask->refcount, 1); |
861 | ctask->state = ISCSI_TASK_PENDING; | 1074 | ctask->state = ISCSI_TASK_PENDING; |
862 | ctask->mtask = NULL; | ||
863 | ctask->conn = conn; | 1075 | ctask->conn = conn; |
864 | ctask->sc = sc; | 1076 | ctask->sc = sc; |
865 | INIT_LIST_HEAD(&ctask->running); | 1077 | INIT_LIST_HEAD(&ctask->running); |
@@ -868,11 +1080,13 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
868 | spin_unlock(&session->lock); | 1080 | spin_unlock(&session->lock); |
869 | 1081 | ||
870 | scsi_queue_work(host, &conn->xmitwork); | 1082 | scsi_queue_work(host, &conn->xmitwork); |
1083 | spin_lock(host->host_lock); | ||
871 | return 0; | 1084 | return 0; |
872 | 1085 | ||
873 | reject: | 1086 | reject: |
874 | spin_unlock(&session->lock); | 1087 | spin_unlock(&session->lock); |
875 | debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); | 1088 | debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); |
1089 | spin_lock(host->host_lock); | ||
876 | return SCSI_MLQUEUE_HOST_BUSY; | 1090 | return SCSI_MLQUEUE_HOST_BUSY; |
877 | 1091 | ||
878 | fault: | 1092 | fault: |
@@ -882,6 +1096,7 @@ fault: | |||
882 | sc->result = (DID_NO_CONNECT << 16); | 1096 | sc->result = (DID_NO_CONNECT << 16); |
883 | scsi_set_resid(sc, scsi_bufflen(sc)); | 1097 | scsi_set_resid(sc, scsi_bufflen(sc)); |
884 | sc->scsi_done(sc); | 1098 | sc->scsi_done(sc); |
1099 | spin_lock(host->host_lock); | ||
885 | return 0; | 1100 | return 0; |
886 | } | 1101 | } |
887 | EXPORT_SYMBOL_GPL(iscsi_queuecommand); | 1102 | EXPORT_SYMBOL_GPL(iscsi_queuecommand); |
@@ -895,72 +1110,15 @@ int iscsi_change_queue_depth(struct scsi_device *sdev, int depth) | |||
895 | } | 1110 | } |
896 | EXPORT_SYMBOL_GPL(iscsi_change_queue_depth); | 1111 | EXPORT_SYMBOL_GPL(iscsi_change_queue_depth); |
897 | 1112 | ||
898 | static struct iscsi_mgmt_task * | ||
899 | __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | ||
900 | char *data, uint32_t data_size) | ||
901 | { | ||
902 | struct iscsi_session *session = conn->session; | ||
903 | struct iscsi_mgmt_task *mtask; | ||
904 | |||
905 | if (session->state == ISCSI_STATE_TERMINATE) | ||
906 | return NULL; | ||
907 | |||
908 | if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || | ||
909 | hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE)) | ||
910 | /* | ||
911 | * Login and Text are sent serially, in | ||
912 | * request-followed-by-response sequence. | ||
913 | * Same mtask can be used. Same ITT must be used. | ||
914 | * Note that login_mtask is preallocated at conn_create(). | ||
915 | */ | ||
916 | mtask = conn->login_mtask; | ||
917 | else { | ||
918 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); | ||
919 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); | ||
920 | |||
921 | if (!__kfifo_get(session->mgmtpool.queue, | ||
922 | (void*)&mtask, sizeof(void*))) | ||
923 | return NULL; | ||
924 | } | ||
925 | |||
926 | if (data_size) { | ||
927 | memcpy(mtask->data, data, data_size); | ||
928 | mtask->data_count = data_size; | ||
929 | } else | ||
930 | mtask->data_count = 0; | ||
931 | |||
932 | INIT_LIST_HEAD(&mtask->running); | ||
933 | memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr)); | ||
934 | __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); | ||
935 | return mtask; | ||
936 | } | ||
937 | |||
938 | int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, | ||
939 | char *data, uint32_t data_size) | ||
940 | { | ||
941 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
942 | struct iscsi_session *session = conn->session; | ||
943 | int err = 0; | ||
944 | |||
945 | spin_lock_bh(&session->lock); | ||
946 | if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size)) | ||
947 | err = -EPERM; | ||
948 | spin_unlock_bh(&session->lock); | ||
949 | scsi_queue_work(session->host, &conn->xmitwork); | ||
950 | return err; | ||
951 | } | ||
952 | EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); | ||
953 | |||
954 | void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) | 1113 | void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) |
955 | { | 1114 | { |
956 | struct iscsi_session *session = class_to_transport_session(cls_session); | 1115 | struct iscsi_session *session = class_to_transport_session(cls_session); |
957 | struct iscsi_conn *conn = session->leadconn; | ||
958 | 1116 | ||
959 | spin_lock_bh(&session->lock); | 1117 | spin_lock_bh(&session->lock); |
960 | if (session->state != ISCSI_STATE_LOGGED_IN) { | 1118 | if (session->state != ISCSI_STATE_LOGGED_IN) { |
961 | session->state = ISCSI_STATE_RECOVERY_FAILED; | 1119 | session->state = ISCSI_STATE_RECOVERY_FAILED; |
962 | if (conn) | 1120 | if (session->leadconn) |
963 | wake_up(&conn->ehwait); | 1121 | wake_up(&session->leadconn->ehwait); |
964 | } | 1122 | } |
965 | spin_unlock_bh(&session->lock); | 1123 | spin_unlock_bh(&session->lock); |
966 | } | 1124 | } |
@@ -971,30 +1129,25 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc) | |||
971 | struct Scsi_Host *host = sc->device->host; | 1129 | struct Scsi_Host *host = sc->device->host; |
972 | struct iscsi_session *session = iscsi_hostdata(host->hostdata); | 1130 | struct iscsi_session *session = iscsi_hostdata(host->hostdata); |
973 | struct iscsi_conn *conn = session->leadconn; | 1131 | struct iscsi_conn *conn = session->leadconn; |
974 | int fail_session = 0; | ||
975 | 1132 | ||
1133 | mutex_lock(&session->eh_mutex); | ||
976 | spin_lock_bh(&session->lock); | 1134 | spin_lock_bh(&session->lock); |
977 | if (session->state == ISCSI_STATE_TERMINATE) { | 1135 | if (session->state == ISCSI_STATE_TERMINATE) { |
978 | failed: | 1136 | failed: |
979 | debug_scsi("failing host reset: session terminated " | 1137 | debug_scsi("failing host reset: session terminated " |
980 | "[CID %d age %d]\n", conn->id, session->age); | 1138 | "[CID %d age %d]\n", conn->id, session->age); |
981 | spin_unlock_bh(&session->lock); | 1139 | spin_unlock_bh(&session->lock); |
1140 | mutex_unlock(&session->eh_mutex); | ||
982 | return FAILED; | 1141 | return FAILED; |
983 | } | 1142 | } |
984 | 1143 | ||
985 | if (sc->SCp.phase == session->age) { | ||
986 | debug_scsi("failing connection CID %d due to SCSI host reset\n", | ||
987 | conn->id); | ||
988 | fail_session = 1; | ||
989 | } | ||
990 | spin_unlock_bh(&session->lock); | 1144 | spin_unlock_bh(&session->lock); |
991 | 1145 | mutex_unlock(&session->eh_mutex); | |
992 | /* | 1146 | /* |
993 | * we drop the lock here but the leadconn cannot be destoyed while | 1147 | * we drop the lock here but the leadconn cannot be destoyed while |
994 | * we are in the scsi eh | 1148 | * we are in the scsi eh |
995 | */ | 1149 | */ |
996 | if (fail_session) | 1150 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
997 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
998 | 1151 | ||
999 | debug_scsi("iscsi_eh_host_reset wait for relogin\n"); | 1152 | debug_scsi("iscsi_eh_host_reset wait for relogin\n"); |
1000 | wait_event_interruptible(conn->ehwait, | 1153 | wait_event_interruptible(conn->ehwait, |
@@ -1004,73 +1157,56 @@ failed: | |||
1004 | if (signal_pending(current)) | 1157 | if (signal_pending(current)) |
1005 | flush_signals(current); | 1158 | flush_signals(current); |
1006 | 1159 | ||
1160 | mutex_lock(&session->eh_mutex); | ||
1007 | spin_lock_bh(&session->lock); | 1161 | spin_lock_bh(&session->lock); |
1008 | if (session->state == ISCSI_STATE_LOGGED_IN) | 1162 | if (session->state == ISCSI_STATE_LOGGED_IN) |
1009 | printk(KERN_INFO "iscsi: host reset succeeded\n"); | 1163 | printk(KERN_INFO "iscsi: host reset succeeded\n"); |
1010 | else | 1164 | else |
1011 | goto failed; | 1165 | goto failed; |
1012 | spin_unlock_bh(&session->lock); | 1166 | spin_unlock_bh(&session->lock); |
1013 | 1167 | mutex_unlock(&session->eh_mutex); | |
1014 | return SUCCESS; | 1168 | return SUCCESS; |
1015 | } | 1169 | } |
1016 | EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); | 1170 | EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); |
1017 | 1171 | ||
1018 | static void iscsi_tmabort_timedout(unsigned long data) | 1172 | static void iscsi_tmf_timedout(unsigned long data) |
1019 | { | 1173 | { |
1020 | struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data; | 1174 | struct iscsi_conn *conn = (struct iscsi_conn *)data; |
1021 | struct iscsi_conn *conn = ctask->conn; | ||
1022 | struct iscsi_session *session = conn->session; | 1175 | struct iscsi_session *session = conn->session; |
1023 | 1176 | ||
1024 | spin_lock(&session->lock); | 1177 | spin_lock(&session->lock); |
1025 | if (conn->tmabort_state == TMABORT_INITIAL) { | 1178 | if (conn->tmf_state == TMF_QUEUED) { |
1026 | conn->tmabort_state = TMABORT_TIMEDOUT; | 1179 | conn->tmf_state = TMF_TIMEDOUT; |
1027 | debug_scsi("tmabort timedout [sc %p itt 0x%x]\n", | 1180 | debug_scsi("tmf timedout\n"); |
1028 | ctask->sc, ctask->itt); | ||
1029 | /* unblock eh_abort() */ | 1181 | /* unblock eh_abort() */ |
1030 | wake_up(&conn->ehwait); | 1182 | wake_up(&conn->ehwait); |
1031 | } | 1183 | } |
1032 | spin_unlock(&session->lock); | 1184 | spin_unlock(&session->lock); |
1033 | } | 1185 | } |
1034 | 1186 | ||
1035 | static int iscsi_exec_abort_task(struct scsi_cmnd *sc, | 1187 | static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, |
1036 | struct iscsi_cmd_task *ctask) | 1188 | struct iscsi_tm *hdr, int age, |
1189 | int timeout) | ||
1037 | { | 1190 | { |
1038 | struct iscsi_conn *conn = ctask->conn; | ||
1039 | struct iscsi_session *session = conn->session; | 1191 | struct iscsi_session *session = conn->session; |
1040 | struct iscsi_tm *hdr = &conn->tmhdr; | 1192 | struct iscsi_mgmt_task *mtask; |
1041 | |||
1042 | /* | ||
1043 | * ctask timed out but session is OK requests must be serialized. | ||
1044 | */ | ||
1045 | memset(hdr, 0, sizeof(struct iscsi_tm)); | ||
1046 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; | ||
1047 | hdr->flags = ISCSI_TM_FUNC_ABORT_TASK; | ||
1048 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | ||
1049 | memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); | ||
1050 | hdr->rtt = ctask->hdr->itt; | ||
1051 | hdr->refcmdsn = ctask->hdr->cmdsn; | ||
1052 | 1193 | ||
1053 | ctask->mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, | 1194 | mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, |
1054 | NULL, 0); | 1195 | NULL, 0); |
1055 | if (!ctask->mtask) { | 1196 | if (!mtask) { |
1056 | spin_unlock_bh(&session->lock); | 1197 | spin_unlock_bh(&session->lock); |
1057 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 1198 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
1058 | spin_lock_bh(&session->lock) | 1199 | spin_lock_bh(&session->lock); |
1059 | debug_scsi("abort sent failure [itt 0x%x]\n", ctask->itt); | 1200 | debug_scsi("tmf exec failure\n"); |
1060 | return -EPERM; | 1201 | return -EPERM; |
1061 | } | 1202 | } |
1062 | ctask->state = ISCSI_TASK_ABORTING; | 1203 | conn->tmfcmd_pdus_cnt++; |
1204 | conn->tmf_timer.expires = timeout * HZ + jiffies; | ||
1205 | conn->tmf_timer.function = iscsi_tmf_timedout; | ||
1206 | conn->tmf_timer.data = (unsigned long)conn; | ||
1207 | add_timer(&conn->tmf_timer); | ||
1208 | debug_scsi("tmf set timeout\n"); | ||
1063 | 1209 | ||
1064 | debug_scsi("abort sent [itt 0x%x]\n", ctask->itt); | ||
1065 | |||
1066 | if (conn->tmabort_state == TMABORT_INITIAL) { | ||
1067 | conn->tmfcmd_pdus_cnt++; | ||
1068 | conn->tmabort_timer.expires = 20*HZ + jiffies; | ||
1069 | conn->tmabort_timer.function = iscsi_tmabort_timedout; | ||
1070 | conn->tmabort_timer.data = (unsigned long)ctask; | ||
1071 | add_timer(&conn->tmabort_timer); | ||
1072 | debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt); | ||
1073 | } | ||
1074 | spin_unlock_bh(&session->lock); | 1210 | spin_unlock_bh(&session->lock); |
1075 | mutex_unlock(&session->eh_mutex); | 1211 | mutex_unlock(&session->eh_mutex); |
1076 | scsi_queue_work(session->host, &conn->xmitwork); | 1212 | scsi_queue_work(session->host, &conn->xmitwork); |
@@ -1078,113 +1214,197 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc, | |||
1078 | /* | 1214 | /* |
1079 | * block eh thread until: | 1215 | * block eh thread until: |
1080 | * | 1216 | * |
1081 | * 1) abort response | 1217 | * 1) tmf response |
1082 | * 2) abort timeout | 1218 | * 2) tmf timeout |
1083 | * 3) session is terminated or restarted or userspace has | 1219 | * 3) session is terminated or restarted or userspace has |
1084 | * given up on recovery | 1220 | * given up on recovery |
1085 | */ | 1221 | */ |
1086 | wait_event_interruptible(conn->ehwait, | 1222 | wait_event_interruptible(conn->ehwait, age != session->age || |
1087 | sc->SCp.phase != session->age || | ||
1088 | session->state != ISCSI_STATE_LOGGED_IN || | 1223 | session->state != ISCSI_STATE_LOGGED_IN || |
1089 | conn->tmabort_state != TMABORT_INITIAL); | 1224 | conn->tmf_state != TMF_QUEUED); |
1090 | if (signal_pending(current)) | 1225 | if (signal_pending(current)) |
1091 | flush_signals(current); | 1226 | flush_signals(current); |
1092 | del_timer_sync(&conn->tmabort_timer); | 1227 | del_timer_sync(&conn->tmf_timer); |
1228 | |||
1093 | mutex_lock(&session->eh_mutex); | 1229 | mutex_lock(&session->eh_mutex); |
1094 | spin_lock_bh(&session->lock); | 1230 | spin_lock_bh(&session->lock); |
1231 | /* if the session drops it will clean up the mtask */ | ||
1232 | if (age != session->age || | ||
1233 | session->state != ISCSI_STATE_LOGGED_IN) | ||
1234 | return -ENOTCONN; | ||
1095 | return 0; | 1235 | return 0; |
1096 | } | 1236 | } |
1097 | 1237 | ||
1098 | /* | 1238 | /* |
1099 | * session lock must be held | 1239 | * Fail commands. session lock held and recv side suspended and xmit |
1240 | * thread flushed | ||
1100 | */ | 1241 | */ |
1101 | static struct iscsi_mgmt_task * | 1242 | static void fail_all_commands(struct iscsi_conn *conn, unsigned lun) |
1102 | iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt) | ||
1103 | { | 1243 | { |
1104 | int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*); | 1244 | struct iscsi_cmd_task *ctask, *tmp; |
1105 | struct iscsi_mgmt_task *task; | ||
1106 | 1245 | ||
1107 | debug_scsi("searching %d tasks\n", nr_tasks); | 1246 | if (conn->ctask && (conn->ctask->sc->device->lun == lun || lun == -1)) |
1247 | conn->ctask = NULL; | ||
1108 | 1248 | ||
1109 | for (i = 0; i < nr_tasks; i++) { | 1249 | /* flush pending */ |
1110 | __kfifo_get(fifo, (void*)&task, sizeof(void*)); | 1250 | list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) { |
1111 | debug_scsi("check task %u\n", task->itt); | 1251 | if (lun == ctask->sc->device->lun || lun == -1) { |
1252 | debug_scsi("failing pending sc %p itt 0x%x\n", | ||
1253 | ctask->sc, ctask->itt); | ||
1254 | fail_command(conn, ctask, DID_BUS_BUSY << 16); | ||
1255 | } | ||
1256 | } | ||
1112 | 1257 | ||
1113 | if (task->itt == itt) { | 1258 | list_for_each_entry_safe(ctask, tmp, &conn->requeue, running) { |
1114 | debug_scsi("matched task\n"); | 1259 | if (lun == ctask->sc->device->lun || lun == -1) { |
1115 | return task; | 1260 | debug_scsi("failing requeued sc %p itt 0x%x\n", |
1261 | ctask->sc, ctask->itt); | ||
1262 | fail_command(conn, ctask, DID_BUS_BUSY << 16); | ||
1116 | } | 1263 | } |
1264 | } | ||
1117 | 1265 | ||
1118 | __kfifo_put(fifo, (void*)&task, sizeof(void*)); | 1266 | /* fail all other running */ |
1267 | list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) { | ||
1268 | if (lun == ctask->sc->device->lun || lun == -1) { | ||
1269 | debug_scsi("failing in progress sc %p itt 0x%x\n", | ||
1270 | ctask->sc, ctask->itt); | ||
1271 | fail_command(conn, ctask, DID_BUS_BUSY << 16); | ||
1272 | } | ||
1119 | } | 1273 | } |
1120 | return NULL; | ||
1121 | } | 1274 | } |
1122 | 1275 | ||
1123 | static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask) | 1276 | static void iscsi_suspend_tx(struct iscsi_conn *conn) |
1124 | { | 1277 | { |
1125 | struct iscsi_conn *conn = ctask->conn; | 1278 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); |
1126 | struct iscsi_session *session = conn->session; | 1279 | scsi_flush_work(conn->session->host); |
1127 | 1280 | } | |
1128 | if (!ctask->mtask) | ||
1129 | return -EINVAL; | ||
1130 | 1281 | ||
1131 | if (!iscsi_remove_mgmt_task(conn->mgmtqueue, ctask->mtask->itt)) | 1282 | static void iscsi_start_tx(struct iscsi_conn *conn) |
1132 | list_del(&ctask->mtask->running); | 1283 | { |
1133 | __kfifo_put(session->mgmtpool.queue, (void*)&ctask->mtask, | 1284 | clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); |
1134 | sizeof(void*)); | 1285 | scsi_queue_work(conn->session->host, &conn->xmitwork); |
1135 | ctask->mtask = NULL; | ||
1136 | return 0; | ||
1137 | } | 1286 | } |
1138 | 1287 | ||
1139 | /* | 1288 | static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) |
1140 | * session lock must be held | ||
1141 | */ | ||
1142 | static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | ||
1143 | int err) | ||
1144 | { | 1289 | { |
1145 | struct scsi_cmnd *sc; | 1290 | struct iscsi_cls_session *cls_session; |
1291 | struct iscsi_session *session; | ||
1292 | struct iscsi_conn *conn; | ||
1293 | enum scsi_eh_timer_return rc = EH_NOT_HANDLED; | ||
1146 | 1294 | ||
1147 | sc = ctask->sc; | 1295 | cls_session = starget_to_session(scsi_target(scmd->device)); |
1148 | if (!sc) | 1296 | session = class_to_transport_session(cls_session); |
1149 | return; | ||
1150 | 1297 | ||
1151 | if (ctask->state == ISCSI_TASK_PENDING) | 1298 | debug_scsi("scsi cmd %p timedout\n", scmd); |
1299 | |||
1300 | spin_lock(&session->lock); | ||
1301 | if (session->state != ISCSI_STATE_LOGGED_IN) { | ||
1152 | /* | 1302 | /* |
1153 | * cmd never made it to the xmit thread, so we should not count | 1303 | * We are probably in the middle of iscsi recovery so let |
1154 | * the cmd in the sequencing | 1304 | * that complete and handle the error. |
1155 | */ | 1305 | */ |
1156 | conn->session->queued_cmdsn--; | 1306 | rc = EH_RESET_TIMER; |
1157 | else | 1307 | goto done; |
1158 | conn->session->tt->cleanup_cmd_task(conn, ctask); | 1308 | } |
1159 | iscsi_ctask_mtask_cleanup(ctask); | ||
1160 | 1309 | ||
1161 | sc->result = err; | 1310 | conn = session->leadconn; |
1162 | scsi_set_resid(sc, scsi_bufflen(sc)); | 1311 | if (!conn) { |
1163 | if (conn->ctask == ctask) | 1312 | /* In the middle of shuting down */ |
1164 | conn->ctask = NULL; | 1313 | rc = EH_RESET_TIMER; |
1165 | /* release ref from queuecommand */ | 1314 | goto done; |
1166 | __iscsi_put_ctask(ctask); | 1315 | } |
1316 | |||
1317 | if (!conn->recv_timeout && !conn->ping_timeout) | ||
1318 | goto done; | ||
1319 | /* | ||
1320 | * if the ping timedout then we are in the middle of cleaning up | ||
1321 | * and can let the iscsi eh handle it | ||
1322 | */ | ||
1323 | if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + | ||
1324 | (conn->ping_timeout * HZ), jiffies)) | ||
1325 | rc = EH_RESET_TIMER; | ||
1326 | /* | ||
1327 | * if we are about to check the transport then give the command | ||
1328 | * more time | ||
1329 | */ | ||
1330 | if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ), | ||
1331 | jiffies)) | ||
1332 | rc = EH_RESET_TIMER; | ||
1333 | /* if in the middle of checking the transport then give us more time */ | ||
1334 | if (conn->ping_mtask) | ||
1335 | rc = EH_RESET_TIMER; | ||
1336 | done: | ||
1337 | spin_unlock(&session->lock); | ||
1338 | debug_scsi("return %s\n", rc == EH_RESET_TIMER ? "timer reset" : "nh"); | ||
1339 | return rc; | ||
1167 | } | 1340 | } |
1168 | 1341 | ||
1169 | static void iscsi_suspend_tx(struct iscsi_conn *conn) | 1342 | static void iscsi_check_transport_timeouts(unsigned long data) |
1170 | { | 1343 | { |
1171 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | 1344 | struct iscsi_conn *conn = (struct iscsi_conn *)data; |
1172 | scsi_flush_work(conn->session->host); | 1345 | struct iscsi_session *session = conn->session; |
1346 | unsigned long timeout, next_timeout = 0, last_recv; | ||
1347 | |||
1348 | spin_lock(&session->lock); | ||
1349 | if (session->state != ISCSI_STATE_LOGGED_IN) | ||
1350 | goto done; | ||
1351 | |||
1352 | timeout = conn->recv_timeout; | ||
1353 | if (!timeout) | ||
1354 | goto done; | ||
1355 | |||
1356 | timeout *= HZ; | ||
1357 | last_recv = conn->last_recv; | ||
1358 | if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ), | ||
1359 | jiffies)) { | ||
1360 | printk(KERN_ERR "ping timeout of %d secs expired, " | ||
1361 | "last rx %lu, last ping %lu, now %lu\n", | ||
1362 | conn->ping_timeout, last_recv, | ||
1363 | conn->last_ping, jiffies); | ||
1364 | spin_unlock(&session->lock); | ||
1365 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
1366 | return; | ||
1367 | } | ||
1368 | |||
1369 | if (time_before_eq(last_recv + timeout, jiffies)) { | ||
1370 | if (time_before_eq(conn->last_ping, last_recv)) { | ||
1371 | /* send a ping to try to provoke some traffic */ | ||
1372 | debug_scsi("Sending nopout as ping on conn %p\n", conn); | ||
1373 | iscsi_send_nopout(conn, NULL); | ||
1374 | } | ||
1375 | next_timeout = last_recv + timeout + (conn->ping_timeout * HZ); | ||
1376 | } else { | ||
1377 | next_timeout = last_recv + timeout; | ||
1378 | } | ||
1379 | |||
1380 | if (next_timeout) { | ||
1381 | debug_scsi("Setting next tmo %lu\n", next_timeout); | ||
1382 | mod_timer(&conn->transport_timer, next_timeout); | ||
1383 | } | ||
1384 | done: | ||
1385 | spin_unlock(&session->lock); | ||
1173 | } | 1386 | } |
1174 | 1387 | ||
1175 | static void iscsi_start_tx(struct iscsi_conn *conn) | 1388 | static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask, |
1389 | struct iscsi_tm *hdr) | ||
1176 | { | 1390 | { |
1177 | clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | 1391 | memset(hdr, 0, sizeof(*hdr)); |
1178 | scsi_queue_work(conn->session->host, &conn->xmitwork); | 1392 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; |
1393 | hdr->flags = ISCSI_TM_FUNC_ABORT_TASK & ISCSI_FLAG_TM_FUNC_MASK; | ||
1394 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | ||
1395 | memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun)); | ||
1396 | hdr->rtt = ctask->hdr->itt; | ||
1397 | hdr->refcmdsn = ctask->hdr->cmdsn; | ||
1179 | } | 1398 | } |
1180 | 1399 | ||
1181 | int iscsi_eh_abort(struct scsi_cmnd *sc) | 1400 | int iscsi_eh_abort(struct scsi_cmnd *sc) |
1182 | { | 1401 | { |
1183 | struct Scsi_Host *host = sc->device->host; | 1402 | struct Scsi_Host *host = sc->device->host; |
1184 | struct iscsi_session *session = iscsi_hostdata(host->hostdata); | 1403 | struct iscsi_session *session = iscsi_hostdata(host->hostdata); |
1185 | struct iscsi_cmd_task *ctask; | ||
1186 | struct iscsi_conn *conn; | 1404 | struct iscsi_conn *conn; |
1187 | int rc; | 1405 | struct iscsi_cmd_task *ctask; |
1406 | struct iscsi_tm *hdr; | ||
1407 | int rc, age; | ||
1188 | 1408 | ||
1189 | mutex_lock(&session->eh_mutex); | 1409 | mutex_lock(&session->eh_mutex); |
1190 | spin_lock_bh(&session->lock); | 1410 | spin_lock_bh(&session->lock); |
@@ -1199,19 +1419,23 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
1199 | return SUCCESS; | 1419 | return SUCCESS; |
1200 | } | 1420 | } |
1201 | 1421 | ||
1202 | ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; | ||
1203 | conn = ctask->conn; | ||
1204 | |||
1205 | conn->eh_abort_cnt++; | ||
1206 | debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt); | ||
1207 | |||
1208 | /* | 1422 | /* |
1209 | * If we are not logged in or we have started a new session | 1423 | * If we are not logged in or we have started a new session |
1210 | * then let the host reset code handle this | 1424 | * then let the host reset code handle this |
1211 | */ | 1425 | */ |
1212 | if (session->state != ISCSI_STATE_LOGGED_IN || | 1426 | if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN || |
1213 | sc->SCp.phase != session->age) | 1427 | sc->SCp.phase != session->age) { |
1214 | goto failed; | 1428 | spin_unlock_bh(&session->lock); |
1429 | mutex_unlock(&session->eh_mutex); | ||
1430 | return FAILED; | ||
1431 | } | ||
1432 | |||
1433 | conn = session->leadconn; | ||
1434 | conn->eh_abort_cnt++; | ||
1435 | age = session->age; | ||
1436 | |||
1437 | ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; | ||
1438 | debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt); | ||
1215 | 1439 | ||
1216 | /* ctask completed before time out */ | 1440 | /* ctask completed before time out */ |
1217 | if (!ctask->sc) { | 1441 | if (!ctask->sc) { |
@@ -1219,27 +1443,26 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
1219 | goto success; | 1443 | goto success; |
1220 | } | 1444 | } |
1221 | 1445 | ||
1222 | /* what should we do here ? */ | ||
1223 | if (conn->ctask == ctask) { | ||
1224 | printk(KERN_INFO "iscsi: sc %p itt 0x%x partially sent. " | ||
1225 | "Failing abort\n", sc, ctask->itt); | ||
1226 | goto failed; | ||
1227 | } | ||
1228 | |||
1229 | if (ctask->state == ISCSI_TASK_PENDING) { | 1446 | if (ctask->state == ISCSI_TASK_PENDING) { |
1230 | fail_command(conn, ctask, DID_ABORT << 16); | 1447 | fail_command(conn, ctask, DID_ABORT << 16); |
1231 | goto success; | 1448 | goto success; |
1232 | } | 1449 | } |
1233 | 1450 | ||
1234 | conn->tmabort_state = TMABORT_INITIAL; | 1451 | /* only have one tmf outstanding at a time */ |
1235 | rc = iscsi_exec_abort_task(sc, ctask); | 1452 | if (conn->tmf_state != TMF_INITIAL) |
1236 | if (rc || sc->SCp.phase != session->age || | 1453 | goto failed; |
1237 | session->state != ISCSI_STATE_LOGGED_IN) | 1454 | conn->tmf_state = TMF_QUEUED; |
1455 | |||
1456 | hdr = &conn->tmhdr; | ||
1457 | iscsi_prep_abort_task_pdu(ctask, hdr); | ||
1458 | |||
1459 | if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) { | ||
1460 | rc = FAILED; | ||
1238 | goto failed; | 1461 | goto failed; |
1239 | iscsi_ctask_mtask_cleanup(ctask); | 1462 | } |
1240 | 1463 | ||
1241 | switch (conn->tmabort_state) { | 1464 | switch (conn->tmf_state) { |
1242 | case TMABORT_SUCCESS: | 1465 | case TMF_SUCCESS: |
1243 | spin_unlock_bh(&session->lock); | 1466 | spin_unlock_bh(&session->lock); |
1244 | iscsi_suspend_tx(conn); | 1467 | iscsi_suspend_tx(conn); |
1245 | /* | 1468 | /* |
@@ -1248,22 +1471,26 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
1248 | write_lock_bh(conn->recv_lock); | 1471 | write_lock_bh(conn->recv_lock); |
1249 | spin_lock(&session->lock); | 1472 | spin_lock(&session->lock); |
1250 | fail_command(conn, ctask, DID_ABORT << 16); | 1473 | fail_command(conn, ctask, DID_ABORT << 16); |
1474 | conn->tmf_state = TMF_INITIAL; | ||
1251 | spin_unlock(&session->lock); | 1475 | spin_unlock(&session->lock); |
1252 | write_unlock_bh(conn->recv_lock); | 1476 | write_unlock_bh(conn->recv_lock); |
1253 | iscsi_start_tx(conn); | 1477 | iscsi_start_tx(conn); |
1254 | goto success_unlocked; | 1478 | goto success_unlocked; |
1255 | case TMABORT_NOT_FOUND: | 1479 | case TMF_TIMEDOUT: |
1256 | if (!ctask->sc) { | 1480 | spin_unlock_bh(&session->lock); |
1481 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
1482 | goto failed_unlocked; | ||
1483 | case TMF_NOT_FOUND: | ||
1484 | if (!sc->SCp.ptr) { | ||
1485 | conn->tmf_state = TMF_INITIAL; | ||
1257 | /* ctask completed before tmf abort response */ | 1486 | /* ctask completed before tmf abort response */ |
1258 | debug_scsi("sc completed while abort in progress\n"); | 1487 | debug_scsi("sc completed while abort in progress\n"); |
1259 | goto success; | 1488 | goto success; |
1260 | } | 1489 | } |
1261 | /* fall through */ | 1490 | /* fall through */ |
1262 | default: | 1491 | default: |
1263 | /* timedout or failed */ | 1492 | conn->tmf_state = TMF_INITIAL; |
1264 | spin_unlock_bh(&session->lock); | 1493 | goto failed; |
1265 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
1266 | goto failed_unlocked; | ||
1267 | } | 1494 | } |
1268 | 1495 | ||
1269 | success: | 1496 | success: |
@@ -1276,65 +1503,152 @@ success_unlocked: | |||
1276 | failed: | 1503 | failed: |
1277 | spin_unlock_bh(&session->lock); | 1504 | spin_unlock_bh(&session->lock); |
1278 | failed_unlocked: | 1505 | failed_unlocked: |
1279 | debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); | 1506 | debug_scsi("abort failed [sc %p itt 0x%x]\n", sc, |
1507 | ctask ? ctask->itt : 0); | ||
1280 | mutex_unlock(&session->eh_mutex); | 1508 | mutex_unlock(&session->eh_mutex); |
1281 | return FAILED; | 1509 | return FAILED; |
1282 | } | 1510 | } |
1283 | EXPORT_SYMBOL_GPL(iscsi_eh_abort); | 1511 | EXPORT_SYMBOL_GPL(iscsi_eh_abort); |
1284 | 1512 | ||
1513 | static void iscsi_prep_lun_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr) | ||
1514 | { | ||
1515 | memset(hdr, 0, sizeof(*hdr)); | ||
1516 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE; | ||
1517 | hdr->flags = ISCSI_TM_FUNC_LOGICAL_UNIT_RESET & ISCSI_FLAG_TM_FUNC_MASK; | ||
1518 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | ||
1519 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); | ||
1520 | hdr->rtt = RESERVED_ITT; | ||
1521 | } | ||
1522 | |||
1523 | int iscsi_eh_device_reset(struct scsi_cmnd *sc) | ||
1524 | { | ||
1525 | struct Scsi_Host *host = sc->device->host; | ||
1526 | struct iscsi_session *session = iscsi_hostdata(host->hostdata); | ||
1527 | struct iscsi_conn *conn; | ||
1528 | struct iscsi_tm *hdr; | ||
1529 | int rc = FAILED; | ||
1530 | |||
1531 | debug_scsi("LU Reset [sc %p lun %u]\n", sc, sc->device->lun); | ||
1532 | |||
1533 | mutex_lock(&session->eh_mutex); | ||
1534 | spin_lock_bh(&session->lock); | ||
1535 | /* | ||
1536 | * Just check if we are not logged in. We cannot check for | ||
1537 | * the phase because the reset could come from a ioctl. | ||
1538 | */ | ||
1539 | if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN) | ||
1540 | goto unlock; | ||
1541 | conn = session->leadconn; | ||
1542 | |||
1543 | /* only have one tmf outstanding at a time */ | ||
1544 | if (conn->tmf_state != TMF_INITIAL) | ||
1545 | goto unlock; | ||
1546 | conn->tmf_state = TMF_QUEUED; | ||
1547 | |||
1548 | hdr = &conn->tmhdr; | ||
1549 | iscsi_prep_lun_reset_pdu(sc, hdr); | ||
1550 | |||
1551 | if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, | ||
1552 | session->lu_reset_timeout)) { | ||
1553 | rc = FAILED; | ||
1554 | goto unlock; | ||
1555 | } | ||
1556 | |||
1557 | switch (conn->tmf_state) { | ||
1558 | case TMF_SUCCESS: | ||
1559 | break; | ||
1560 | case TMF_TIMEDOUT: | ||
1561 | spin_unlock_bh(&session->lock); | ||
1562 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
1563 | goto done; | ||
1564 | default: | ||
1565 | conn->tmf_state = TMF_INITIAL; | ||
1566 | goto unlock; | ||
1567 | } | ||
1568 | |||
1569 | rc = SUCCESS; | ||
1570 | spin_unlock_bh(&session->lock); | ||
1571 | |||
1572 | iscsi_suspend_tx(conn); | ||
1573 | /* need to grab the recv lock then session lock */ | ||
1574 | write_lock_bh(conn->recv_lock); | ||
1575 | spin_lock(&session->lock); | ||
1576 | fail_all_commands(conn, sc->device->lun); | ||
1577 | conn->tmf_state = TMF_INITIAL; | ||
1578 | spin_unlock(&session->lock); | ||
1579 | write_unlock_bh(conn->recv_lock); | ||
1580 | |||
1581 | iscsi_start_tx(conn); | ||
1582 | goto done; | ||
1583 | |||
1584 | unlock: | ||
1585 | spin_unlock_bh(&session->lock); | ||
1586 | done: | ||
1587 | debug_scsi("iscsi_eh_device_reset %s\n", | ||
1588 | rc == SUCCESS ? "SUCCESS" : "FAILED"); | ||
1589 | mutex_unlock(&session->eh_mutex); | ||
1590 | return rc; | ||
1591 | } | ||
1592 | EXPORT_SYMBOL_GPL(iscsi_eh_device_reset); | ||
1593 | |||
1594 | /* | ||
1595 | * Pre-allocate a pool of @max items of @item_size. By default, the pool | ||
1596 | * should be accessed via kfifo_{get,put} on q->queue. | ||
1597 | * Optionally, the caller can obtain the array of object pointers | ||
1598 | * by passing in a non-NULL @items pointer | ||
1599 | */ | ||
1285 | int | 1600 | int |
1286 | iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) | 1601 | iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size) |
1287 | { | 1602 | { |
1288 | int i; | 1603 | int i, num_arrays = 1; |
1289 | 1604 | ||
1290 | *items = kmalloc(max * sizeof(void*), GFP_KERNEL); | 1605 | memset(q, 0, sizeof(*q)); |
1291 | if (*items == NULL) | ||
1292 | return -ENOMEM; | ||
1293 | 1606 | ||
1294 | q->max = max; | 1607 | q->max = max; |
1295 | q->pool = kmalloc(max * sizeof(void*), GFP_KERNEL); | 1608 | |
1296 | if (q->pool == NULL) { | 1609 | /* If the user passed an items pointer, he wants a copy of |
1297 | kfree(*items); | 1610 | * the array. */ |
1298 | return -ENOMEM; | 1611 | if (items) |
1299 | } | 1612 | num_arrays++; |
1613 | q->pool = kzalloc(num_arrays * max * sizeof(void*), GFP_KERNEL); | ||
1614 | if (q->pool == NULL) | ||
1615 | goto enomem; | ||
1300 | 1616 | ||
1301 | q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), | 1617 | q->queue = kfifo_init((void*)q->pool, max * sizeof(void*), |
1302 | GFP_KERNEL, NULL); | 1618 | GFP_KERNEL, NULL); |
1303 | if (q->queue == ERR_PTR(-ENOMEM)) { | 1619 | if (q->queue == ERR_PTR(-ENOMEM)) |
1304 | kfree(q->pool); | 1620 | goto enomem; |
1305 | kfree(*items); | ||
1306 | return -ENOMEM; | ||
1307 | } | ||
1308 | 1621 | ||
1309 | for (i = 0; i < max; i++) { | 1622 | for (i = 0; i < max; i++) { |
1310 | q->pool[i] = kmalloc(item_size, GFP_KERNEL); | 1623 | q->pool[i] = kzalloc(item_size, GFP_KERNEL); |
1311 | if (q->pool[i] == NULL) { | 1624 | if (q->pool[i] == NULL) { |
1312 | int j; | 1625 | q->max = i; |
1313 | 1626 | goto enomem; | |
1314 | for (j = 0; j < i; j++) | ||
1315 | kfree(q->pool[j]); | ||
1316 | |||
1317 | kfifo_free(q->queue); | ||
1318 | kfree(q->pool); | ||
1319 | kfree(*items); | ||
1320 | return -ENOMEM; | ||
1321 | } | 1627 | } |
1322 | memset(q->pool[i], 0, item_size); | ||
1323 | (*items)[i] = q->pool[i]; | ||
1324 | __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); | 1628 | __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*)); |
1325 | } | 1629 | } |
1630 | |||
1631 | if (items) { | ||
1632 | *items = q->pool + max; | ||
1633 | memcpy(*items, q->pool, max * sizeof(void *)); | ||
1634 | } | ||
1635 | |||
1326 | return 0; | 1636 | return 0; |
1637 | |||
1638 | enomem: | ||
1639 | iscsi_pool_free(q); | ||
1640 | return -ENOMEM; | ||
1327 | } | 1641 | } |
1328 | EXPORT_SYMBOL_GPL(iscsi_pool_init); | 1642 | EXPORT_SYMBOL_GPL(iscsi_pool_init); |
1329 | 1643 | ||
1330 | void iscsi_pool_free(struct iscsi_queue *q, void **items) | 1644 | void iscsi_pool_free(struct iscsi_pool *q) |
1331 | { | 1645 | { |
1332 | int i; | 1646 | int i; |
1333 | 1647 | ||
1334 | for (i = 0; i < q->max; i++) | 1648 | for (i = 0; i < q->max; i++) |
1335 | kfree(items[i]); | 1649 | kfree(q->pool[i]); |
1336 | kfree(q->pool); | 1650 | if (q->pool) |
1337 | kfree(items); | 1651 | kfree(q->pool); |
1338 | } | 1652 | } |
1339 | EXPORT_SYMBOL_GPL(iscsi_pool_free); | 1653 | EXPORT_SYMBOL_GPL(iscsi_pool_free); |
1340 | 1654 | ||
@@ -1387,7 +1701,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
1387 | qdepth = ISCSI_DEF_CMD_PER_LUN; | 1701 | qdepth = ISCSI_DEF_CMD_PER_LUN; |
1388 | } | 1702 | } |
1389 | 1703 | ||
1390 | if (cmds_max < 2 || (cmds_max & (cmds_max - 1)) || | 1704 | if (!is_power_of_2(cmds_max) || |
1391 | cmds_max >= ISCSI_MGMT_ITT_OFFSET) { | 1705 | cmds_max >= ISCSI_MGMT_ITT_OFFSET) { |
1392 | if (cmds_max != 0) | 1706 | if (cmds_max != 0) |
1393 | printk(KERN_ERR "iscsi: invalid can_queue of %d. " | 1707 | printk(KERN_ERR "iscsi: invalid can_queue of %d. " |
@@ -1411,12 +1725,16 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
1411 | shost->max_cmd_len = iscsit->max_cmd_len; | 1725 | shost->max_cmd_len = iscsit->max_cmd_len; |
1412 | shost->transportt = scsit; | 1726 | shost->transportt = scsit; |
1413 | shost->transportt->create_work_queue = 1; | 1727 | shost->transportt->create_work_queue = 1; |
1728 | shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out; | ||
1414 | *hostno = shost->host_no; | 1729 | *hostno = shost->host_no; |
1415 | 1730 | ||
1416 | session = iscsi_hostdata(shost->hostdata); | 1731 | session = iscsi_hostdata(shost->hostdata); |
1417 | memset(session, 0, sizeof(struct iscsi_session)); | 1732 | memset(session, 0, sizeof(struct iscsi_session)); |
1418 | session->host = shost; | 1733 | session->host = shost; |
1419 | session->state = ISCSI_STATE_FREE; | 1734 | session->state = ISCSI_STATE_FREE; |
1735 | session->fast_abort = 1; | ||
1736 | session->lu_reset_timeout = 15; | ||
1737 | session->abort_timeout = 10; | ||
1420 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; | 1738 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; |
1421 | session->cmds_max = cmds_max; | 1739 | session->cmds_max = cmds_max; |
1422 | session->queued_cmdsn = session->cmdsn = initial_cmdsn; | 1740 | session->queued_cmdsn = session->cmdsn = initial_cmdsn; |
@@ -1479,9 +1797,9 @@ module_put: | |||
1479 | cls_session_fail: | 1797 | cls_session_fail: |
1480 | scsi_remove_host(shost); | 1798 | scsi_remove_host(shost); |
1481 | add_host_fail: | 1799 | add_host_fail: |
1482 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | 1800 | iscsi_pool_free(&session->mgmtpool); |
1483 | mgmtpool_alloc_fail: | 1801 | mgmtpool_alloc_fail: |
1484 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 1802 | iscsi_pool_free(&session->cmdpool); |
1485 | cmdpool_alloc_fail: | 1803 | cmdpool_alloc_fail: |
1486 | scsi_host_put(shost); | 1804 | scsi_host_put(shost); |
1487 | return NULL; | 1805 | return NULL; |
@@ -1501,11 +1819,11 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
1501 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | 1819 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
1502 | struct module *owner = cls_session->transport->owner; | 1820 | struct module *owner = cls_session->transport->owner; |
1503 | 1821 | ||
1504 | iscsi_unblock_session(cls_session); | 1822 | iscsi_remove_session(cls_session); |
1505 | scsi_remove_host(shost); | 1823 | scsi_remove_host(shost); |
1506 | 1824 | ||
1507 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | 1825 | iscsi_pool_free(&session->mgmtpool); |
1508 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 1826 | iscsi_pool_free(&session->cmdpool); |
1509 | 1827 | ||
1510 | kfree(session->password); | 1828 | kfree(session->password); |
1511 | kfree(session->password_in); | 1829 | kfree(session->password_in); |
@@ -1516,7 +1834,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
1516 | kfree(session->hwaddress); | 1834 | kfree(session->hwaddress); |
1517 | kfree(session->initiatorname); | 1835 | kfree(session->initiatorname); |
1518 | 1836 | ||
1519 | iscsi_destroy_session(cls_session); | 1837 | iscsi_free_session(cls_session); |
1520 | scsi_host_put(shost); | 1838 | scsi_host_put(shost); |
1521 | module_put(owner); | 1839 | module_put(owner); |
1522 | } | 1840 | } |
@@ -1546,17 +1864,17 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) | |||
1546 | conn->c_stage = ISCSI_CONN_INITIAL_STAGE; | 1864 | conn->c_stage = ISCSI_CONN_INITIAL_STAGE; |
1547 | conn->id = conn_idx; | 1865 | conn->id = conn_idx; |
1548 | conn->exp_statsn = 0; | 1866 | conn->exp_statsn = 0; |
1549 | conn->tmabort_state = TMABORT_INITIAL; | 1867 | conn->tmf_state = TMF_INITIAL; |
1868 | |||
1869 | init_timer(&conn->transport_timer); | ||
1870 | conn->transport_timer.data = (unsigned long)conn; | ||
1871 | conn->transport_timer.function = iscsi_check_transport_timeouts; | ||
1872 | |||
1550 | INIT_LIST_HEAD(&conn->run_list); | 1873 | INIT_LIST_HEAD(&conn->run_list); |
1551 | INIT_LIST_HEAD(&conn->mgmt_run_list); | 1874 | INIT_LIST_HEAD(&conn->mgmt_run_list); |
1875 | INIT_LIST_HEAD(&conn->mgmtqueue); | ||
1552 | INIT_LIST_HEAD(&conn->xmitqueue); | 1876 | INIT_LIST_HEAD(&conn->xmitqueue); |
1553 | 1877 | INIT_LIST_HEAD(&conn->requeue); | |
1554 | /* initialize general immediate & non-immediate PDU commands queue */ | ||
1555 | conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), | ||
1556 | GFP_KERNEL, NULL); | ||
1557 | if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) | ||
1558 | goto mgmtqueue_alloc_fail; | ||
1559 | |||
1560 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker); | 1878 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker); |
1561 | 1879 | ||
1562 | /* allocate login_mtask used for the login/text sequences */ | 1880 | /* allocate login_mtask used for the login/text sequences */ |
@@ -1574,7 +1892,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) | |||
1574 | goto login_mtask_data_alloc_fail; | 1892 | goto login_mtask_data_alloc_fail; |
1575 | conn->login_mtask->data = conn->data = data; | 1893 | conn->login_mtask->data = conn->data = data; |
1576 | 1894 | ||
1577 | init_timer(&conn->tmabort_timer); | 1895 | init_timer(&conn->tmf_timer); |
1578 | init_waitqueue_head(&conn->ehwait); | 1896 | init_waitqueue_head(&conn->ehwait); |
1579 | 1897 | ||
1580 | return cls_conn; | 1898 | return cls_conn; |
@@ -1583,8 +1901,6 @@ login_mtask_data_alloc_fail: | |||
1583 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, | 1901 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, |
1584 | sizeof(void*)); | 1902 | sizeof(void*)); |
1585 | login_mtask_alloc_fail: | 1903 | login_mtask_alloc_fail: |
1586 | kfifo_free(conn->mgmtqueue); | ||
1587 | mgmtqueue_alloc_fail: | ||
1588 | iscsi_destroy_conn(cls_conn); | 1904 | iscsi_destroy_conn(cls_conn); |
1589 | return NULL; | 1905 | return NULL; |
1590 | } | 1906 | } |
@@ -1603,8 +1919,9 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
1603 | struct iscsi_session *session = conn->session; | 1919 | struct iscsi_session *session = conn->session; |
1604 | unsigned long flags; | 1920 | unsigned long flags; |
1605 | 1921 | ||
1922 | del_timer_sync(&conn->transport_timer); | ||
1923 | |||
1606 | spin_lock_bh(&session->lock); | 1924 | spin_lock_bh(&session->lock); |
1607 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
1608 | conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; | 1925 | conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; |
1609 | if (session->leadconn == conn) { | 1926 | if (session->leadconn == conn) { |
1610 | /* | 1927 | /* |
@@ -1637,7 +1954,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
1637 | } | 1954 | } |
1638 | 1955 | ||
1639 | /* flush queued up work because we free the connection below */ | 1956 | /* flush queued up work because we free the connection below */ |
1640 | scsi_flush_work(session->host); | 1957 | iscsi_suspend_tx(conn); |
1641 | 1958 | ||
1642 | spin_lock_bh(&session->lock); | 1959 | spin_lock_bh(&session->lock); |
1643 | kfree(conn->data); | 1960 | kfree(conn->data); |
@@ -1648,8 +1965,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
1648 | session->leadconn = NULL; | 1965 | session->leadconn = NULL; |
1649 | spin_unlock_bh(&session->lock); | 1966 | spin_unlock_bh(&session->lock); |
1650 | 1967 | ||
1651 | kfifo_free(conn->mgmtqueue); | ||
1652 | |||
1653 | iscsi_destroy_conn(cls_conn); | 1968 | iscsi_destroy_conn(cls_conn); |
1654 | } | 1969 | } |
1655 | EXPORT_SYMBOL_GPL(iscsi_conn_teardown); | 1970 | EXPORT_SYMBOL_GPL(iscsi_conn_teardown); |
@@ -1672,11 +1987,29 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1672 | return -EINVAL; | 1987 | return -EINVAL; |
1673 | } | 1988 | } |
1674 | 1989 | ||
1990 | if (conn->ping_timeout && !conn->recv_timeout) { | ||
1991 | printk(KERN_ERR "iscsi: invalid recv timeout of zero " | ||
1992 | "Using 5 seconds\n."); | ||
1993 | conn->recv_timeout = 5; | ||
1994 | } | ||
1995 | |||
1996 | if (conn->recv_timeout && !conn->ping_timeout) { | ||
1997 | printk(KERN_ERR "iscsi: invalid ping timeout of zero " | ||
1998 | "Using 5 seconds.\n"); | ||
1999 | conn->ping_timeout = 5; | ||
2000 | } | ||
2001 | |||
1675 | spin_lock_bh(&session->lock); | 2002 | spin_lock_bh(&session->lock); |
1676 | conn->c_stage = ISCSI_CONN_STARTED; | 2003 | conn->c_stage = ISCSI_CONN_STARTED; |
1677 | session->state = ISCSI_STATE_LOGGED_IN; | 2004 | session->state = ISCSI_STATE_LOGGED_IN; |
1678 | session->queued_cmdsn = session->cmdsn; | 2005 | session->queued_cmdsn = session->cmdsn; |
1679 | 2006 | ||
2007 | conn->last_recv = jiffies; | ||
2008 | conn->last_ping = jiffies; | ||
2009 | if (conn->recv_timeout && conn->ping_timeout) | ||
2010 | mod_timer(&conn->transport_timer, | ||
2011 | jiffies + (conn->recv_timeout * HZ)); | ||
2012 | |||
1680 | switch(conn->stop_stage) { | 2013 | switch(conn->stop_stage) { |
1681 | case STOP_CONN_RECOVER: | 2014 | case STOP_CONN_RECOVER: |
1682 | /* | 2015 | /* |
@@ -1684,7 +2017,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1684 | * commands after successful recovery | 2017 | * commands after successful recovery |
1685 | */ | 2018 | */ |
1686 | conn->stop_stage = 0; | 2019 | conn->stop_stage = 0; |
1687 | conn->tmabort_state = TMABORT_INITIAL; | 2020 | conn->tmf_state = TMF_INITIAL; |
1688 | session->age++; | 2021 | session->age++; |
1689 | spin_unlock_bh(&session->lock); | 2022 | spin_unlock_bh(&session->lock); |
1690 | 2023 | ||
@@ -1709,55 +2042,27 @@ flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn) | |||
1709 | struct iscsi_mgmt_task *mtask, *tmp; | 2042 | struct iscsi_mgmt_task *mtask, *tmp; |
1710 | 2043 | ||
1711 | /* handle pending */ | 2044 | /* handle pending */ |
1712 | while (__kfifo_get(conn->mgmtqueue, (void*)&mtask, sizeof(void*))) { | 2045 | list_for_each_entry_safe(mtask, tmp, &conn->mgmtqueue, running) { |
1713 | if (mtask == conn->login_mtask) | ||
1714 | continue; | ||
1715 | debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt); | 2046 | debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt); |
1716 | __kfifo_put(session->mgmtpool.queue, (void*)&mtask, | 2047 | iscsi_free_mgmt_task(conn, mtask); |
1717 | sizeof(void*)); | ||
1718 | } | 2048 | } |
1719 | 2049 | ||
1720 | /* handle running */ | 2050 | /* handle running */ |
1721 | list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) { | 2051 | list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) { |
1722 | debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt); | 2052 | debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt); |
1723 | list_del(&mtask->running); | 2053 | iscsi_free_mgmt_task(conn, mtask); |
1724 | |||
1725 | if (mtask == conn->login_mtask) | ||
1726 | continue; | ||
1727 | __kfifo_put(session->mgmtpool.queue, (void*)&mtask, | ||
1728 | sizeof(void*)); | ||
1729 | } | 2054 | } |
1730 | 2055 | ||
1731 | conn->mtask = NULL; | 2056 | conn->mtask = NULL; |
1732 | } | 2057 | } |
1733 | 2058 | ||
1734 | /* Fail commands. Mutex and session lock held and recv side suspended */ | ||
1735 | static void fail_all_commands(struct iscsi_conn *conn) | ||
1736 | { | ||
1737 | struct iscsi_cmd_task *ctask, *tmp; | ||
1738 | |||
1739 | /* flush pending */ | ||
1740 | list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) { | ||
1741 | debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc, | ||
1742 | ctask->itt); | ||
1743 | fail_command(conn, ctask, DID_BUS_BUSY << 16); | ||
1744 | } | ||
1745 | |||
1746 | /* fail all other running */ | ||
1747 | list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) { | ||
1748 | debug_scsi("failing in progress sc %p itt 0x%x\n", | ||
1749 | ctask->sc, ctask->itt); | ||
1750 | fail_command(conn, ctask, DID_BUS_BUSY << 16); | ||
1751 | } | ||
1752 | |||
1753 | conn->ctask = NULL; | ||
1754 | } | ||
1755 | |||
1756 | static void iscsi_start_session_recovery(struct iscsi_session *session, | 2059 | static void iscsi_start_session_recovery(struct iscsi_session *session, |
1757 | struct iscsi_conn *conn, int flag) | 2060 | struct iscsi_conn *conn, int flag) |
1758 | { | 2061 | { |
1759 | int old_stop_stage; | 2062 | int old_stop_stage; |
1760 | 2063 | ||
2064 | del_timer_sync(&conn->transport_timer); | ||
2065 | |||
1761 | mutex_lock(&session->eh_mutex); | 2066 | mutex_lock(&session->eh_mutex); |
1762 | spin_lock_bh(&session->lock); | 2067 | spin_lock_bh(&session->lock); |
1763 | if (conn->stop_stage == STOP_CONN_TERM) { | 2068 | if (conn->stop_stage == STOP_CONN_TERM) { |
@@ -1818,7 +2123,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
1818 | * flush queues. | 2123 | * flush queues. |
1819 | */ | 2124 | */ |
1820 | spin_lock_bh(&session->lock); | 2125 | spin_lock_bh(&session->lock); |
1821 | fail_all_commands(conn); | 2126 | fail_all_commands(conn, -1); |
1822 | flush_control_queues(session, conn); | 2127 | flush_control_queues(session, conn); |
1823 | spin_unlock_bh(&session->lock); | 2128 | spin_unlock_bh(&session->lock); |
1824 | mutex_unlock(&session->eh_mutex); | 2129 | mutex_unlock(&session->eh_mutex); |
@@ -1869,6 +2174,21 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | |||
1869 | uint32_t value; | 2174 | uint32_t value; |
1870 | 2175 | ||
1871 | switch(param) { | 2176 | switch(param) { |
2177 | case ISCSI_PARAM_FAST_ABORT: | ||
2178 | sscanf(buf, "%d", &session->fast_abort); | ||
2179 | break; | ||
2180 | case ISCSI_PARAM_ABORT_TMO: | ||
2181 | sscanf(buf, "%d", &session->abort_timeout); | ||
2182 | break; | ||
2183 | case ISCSI_PARAM_LU_RESET_TMO: | ||
2184 | sscanf(buf, "%d", &session->lu_reset_timeout); | ||
2185 | break; | ||
2186 | case ISCSI_PARAM_PING_TMO: | ||
2187 | sscanf(buf, "%d", &conn->ping_timeout); | ||
2188 | break; | ||
2189 | case ISCSI_PARAM_RECV_TMO: | ||
2190 | sscanf(buf, "%d", &conn->recv_timeout); | ||
2191 | break; | ||
1872 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | 2192 | case ISCSI_PARAM_MAX_RECV_DLENGTH: |
1873 | sscanf(buf, "%d", &conn->max_recv_dlength); | 2193 | sscanf(buf, "%d", &conn->max_recv_dlength); |
1874 | break; | 2194 | break; |
@@ -1983,6 +2303,15 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | |||
1983 | int len; | 2303 | int len; |
1984 | 2304 | ||
1985 | switch(param) { | 2305 | switch(param) { |
2306 | case ISCSI_PARAM_FAST_ABORT: | ||
2307 | len = sprintf(buf, "%d\n", session->fast_abort); | ||
2308 | break; | ||
2309 | case ISCSI_PARAM_ABORT_TMO: | ||
2310 | len = sprintf(buf, "%d\n", session->abort_timeout); | ||
2311 | break; | ||
2312 | case ISCSI_PARAM_LU_RESET_TMO: | ||
2313 | len = sprintf(buf, "%d\n", session->lu_reset_timeout); | ||
2314 | break; | ||
1986 | case ISCSI_PARAM_INITIAL_R2T_EN: | 2315 | case ISCSI_PARAM_INITIAL_R2T_EN: |
1987 | len = sprintf(buf, "%d\n", session->initial_r2t_en); | 2316 | len = sprintf(buf, "%d\n", session->initial_r2t_en); |
1988 | break; | 2317 | break; |
@@ -2040,6 +2369,12 @@ int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
2040 | int len; | 2369 | int len; |
2041 | 2370 | ||
2042 | switch(param) { | 2371 | switch(param) { |
2372 | case ISCSI_PARAM_PING_TMO: | ||
2373 | len = sprintf(buf, "%u\n", conn->ping_timeout); | ||
2374 | break; | ||
2375 | case ISCSI_PARAM_RECV_TMO: | ||
2376 | len = sprintf(buf, "%u\n", conn->recv_timeout); | ||
2377 | break; | ||
2043 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | 2378 | case ISCSI_PARAM_MAX_RECV_DLENGTH: |
2044 | len = sprintf(buf, "%u\n", conn->max_recv_dlength); | 2379 | len = sprintf(buf, "%u\n", conn->max_recv_dlength); |
2045 | break; | 2380 | break; |