diff options
| author | Mike Christie <michaelc@cs.wisc.edu> | 2008-05-21 16:54:06 -0400 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-07-12 09:22:19 -0400 |
| commit | 3e5c28ad0391389959ccae81c938c7533efb3490 (patch) | |
| tree | bcfb02dc14afa91dd21fd59ec7c82f881be065c9 | |
| parent | 052d014485d2ce5bb7fa8dd0df875dafd1db77df (diff) | |
[SCSI] libiscsi: merge iscsi_mgmt_task and iscsi_cmd_task
There is no need to have the mgmt and cmd tasks separate
structs. It used to save a lot of memory when we overprealocated
memory for tasks, but the next patches will set up the
driver so in the future they can use a mempool or some other
common scsi command allocator and common tagging.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
| -rw-r--r-- | drivers/scsi/libiscsi.c | 518 | ||||
| -rw-r--r-- | include/scsi/libiscsi.h | 29 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 41 |
3 files changed, 272 insertions, 316 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 1e605de07cff..ef92b1b0f16e 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -197,7 +197,7 @@ static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask) | |||
| 197 | 197 | ||
| 198 | /** | 198 | /** |
| 199 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu | 199 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu |
| 200 | * @ctask: iscsi cmd task | 200 | * @ctask: iscsi task |
| 201 | * | 201 | * |
| 202 | * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set | 202 | * Prep basic iSCSI PDU fields for a scsi cmd pdu. The LLD should set |
| 203 | * fields like dlength or final based on how much data it sends | 203 | * fields like dlength or final based on how much data it sends |
| @@ -300,31 +300,31 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
| 300 | WARN_ON(hdrlength >= 256); | 300 | WARN_ON(hdrlength >= 256); |
| 301 | hdr->hlength = hdrlength & 0xFF; | 301 | hdr->hlength = hdrlength & 0xFF; |
| 302 | 302 | ||
| 303 | if (conn->session->tt->init_cmd_task && | 303 | if (conn->session->tt->init_task && |
| 304 | conn->session->tt->init_cmd_task(ctask)) | 304 | conn->session->tt->init_task(ctask)) |
| 305 | return -EIO; | 305 | return -EIO; |
| 306 | 306 | ||
| 307 | ctask->state = ISCSI_TASK_RUNNING; | 307 | ctask->state = ISCSI_TASK_RUNNING; |
| 308 | list_move_tail(&ctask->running, &conn->run_list); | 308 | list_move_tail(&ctask->running, &conn->run_list); |
| 309 | 309 | ||
| 310 | conn->scsicmd_pdus_cnt++; | 310 | conn->scsicmd_pdus_cnt++; |
| 311 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x " | 311 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " |
| 312 | "len %d bidi_len %d cmdsn %d win %d]\n", | 312 | "bidi_len %d cmdsn %d win %d]\n", scsi_bidi_cmnd(sc) ? |
| 313 | scsi_bidi_cmnd(sc) ? "bidirectional" : | 313 | "bidirectional" : sc->sc_data_direction == DMA_TO_DEVICE ? |
| 314 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", | 314 | "write" : "read", conn->id, sc, sc->cmnd[0], ctask->itt, |
| 315 | conn->id, sc, sc->cmnd[0], ctask->itt, | 315 | scsi_bufflen(sc), |
| 316 | scsi_bufflen(sc), scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, | 316 | scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, |
| 317 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); | 317 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); |
| 318 | return 0; | 318 | return 0; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | /** | 321 | /** |
| 322 | * iscsi_complete_command - return command back to scsi-ml | 322 | * iscsi_complete_command - finish a task |
| 323 | * @ctask: iscsi cmd task | 323 | * @ctask: iscsi cmd task |
| 324 | * | 324 | * |
| 325 | * Must be called with session lock. | 325 | * Must be called with session lock. |
| 326 | * This function returns the scsi command to scsi-ml and returns | 326 | * This function returns the scsi command to scsi-ml or cleans |
| 327 | * the cmd task to the pool of available cmd tasks. | 327 | * up mgmt tasks then returns the task to the pool. |
| 328 | */ | 328 | */ |
| 329 | static void iscsi_complete_command(struct iscsi_cmd_task *ctask) | 329 | static void iscsi_complete_command(struct iscsi_cmd_task *ctask) |
| 330 | { | 330 | { |
| @@ -332,17 +332,34 @@ static void iscsi_complete_command(struct iscsi_cmd_task *ctask) | |||
| 332 | struct iscsi_session *session = conn->session; | 332 | struct iscsi_session *session = conn->session; |
| 333 | struct scsi_cmnd *sc = ctask->sc; | 333 | struct scsi_cmnd *sc = ctask->sc; |
| 334 | 334 | ||
| 335 | list_del_init(&ctask->running); | ||
| 335 | ctask->state = ISCSI_TASK_COMPLETED; | 336 | ctask->state = ISCSI_TASK_COMPLETED; |
| 336 | ctask->sc = NULL; | 337 | ctask->sc = NULL; |
| 337 | /* SCSI eh reuses commands to verify us */ | 338 | |
| 338 | sc->SCp.ptr = NULL; | ||
| 339 | if (conn->ctask == ctask) | 339 | if (conn->ctask == ctask) |
| 340 | conn->ctask = NULL; | 340 | conn->ctask = NULL; |
| 341 | list_del_init(&ctask->running); | 341 | /* |
| 342 | * login ctask is preallocated so do not free | ||
| 343 | */ | ||
| 344 | if (conn->login_ctask == ctask) | ||
| 345 | return; | ||
| 346 | |||
| 342 | __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); | 347 | __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); |
| 343 | 348 | ||
| 344 | if (sc->scsi_done) | 349 | if (conn->ping_ctask == ctask) |
| 345 | sc->scsi_done(sc); | 350 | conn->ping_ctask = NULL; |
| 351 | |||
| 352 | if (sc) { | ||
| 353 | ctask->sc = NULL; | ||
| 354 | /* SCSI eh reuses commands to verify us */ | ||
| 355 | sc->SCp.ptr = NULL; | ||
| 356 | /* | ||
| 357 | * queue command may call this to free the task, but | ||
| 358 | * not have setup the sc callback | ||
| 359 | */ | ||
| 360 | if (sc->scsi_done) | ||
| 361 | sc->scsi_done(sc); | ||
| 362 | } | ||
| 346 | } | 363 | } |
| 347 | 364 | ||
| 348 | static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask) | 365 | static void __iscsi_get_ctask(struct iscsi_cmd_task *ctask) |
| @@ -356,6 +373,16 @@ static void __iscsi_put_ctask(struct iscsi_cmd_task *ctask) | |||
| 356 | iscsi_complete_command(ctask); | 373 | iscsi_complete_command(ctask); |
| 357 | } | 374 | } |
| 358 | 375 | ||
| 376 | void iscsi_put_ctask(struct iscsi_cmd_task *ctask) | ||
| 377 | { | ||
| 378 | struct iscsi_session *session = ctask->conn->session; | ||
| 379 | |||
| 380 | spin_lock_bh(&session->lock); | ||
| 381 | __iscsi_put_ctask(ctask); | ||
| 382 | spin_unlock_bh(&session->lock); | ||
| 383 | } | ||
| 384 | EXPORT_SYMBOL_GPL(iscsi_put_ctask); | ||
| 385 | |||
| 359 | /* | 386 | /* |
| 360 | * session lock must be held | 387 | * session lock must be held |
| 361 | */ | 388 | */ |
| @@ -375,47 +402,28 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
| 375 | */ | 402 | */ |
| 376 | conn->session->queued_cmdsn--; | 403 | conn->session->queued_cmdsn--; |
| 377 | else | 404 | else |
| 378 | conn->session->tt->cleanup_cmd_task(conn, ctask); | 405 | conn->session->tt->cleanup_task(conn, ctask); |
| 379 | 406 | ||
| 380 | sc->result = err; | 407 | sc->result = err; |
| 408 | |||
| 381 | if (!scsi_bidi_cmnd(sc)) | 409 | if (!scsi_bidi_cmnd(sc)) |
| 382 | scsi_set_resid(sc, scsi_bufflen(sc)); | 410 | scsi_set_resid(sc, scsi_bufflen(sc)); |
| 383 | else { | 411 | else { |
| 384 | scsi_out(sc)->resid = scsi_out(sc)->length; | 412 | scsi_out(sc)->resid = scsi_out(sc)->length; |
| 385 | scsi_in(sc)->resid = scsi_in(sc)->length; | 413 | scsi_in(sc)->resid = scsi_in(sc)->length; |
| 386 | } | 414 | } |
| 415 | |||
| 387 | if (conn->ctask == ctask) | 416 | if (conn->ctask == ctask) |
| 388 | conn->ctask = NULL; | 417 | conn->ctask = NULL; |
| 389 | /* release ref from queuecommand */ | 418 | /* release ref from queuecommand */ |
| 390 | __iscsi_put_ctask(ctask); | 419 | __iscsi_put_ctask(ctask); |
| 391 | } | 420 | } |
| 392 | 421 | ||
| 393 | /** | 422 | static int iscsi_prep_mgmt_task(struct iscsi_conn *conn, |
| 394 | * iscsi_free_mgmt_task - return mgmt task back to pool | 423 | struct iscsi_cmd_task *ctask) |
| 395 | * @conn: iscsi connection | ||
| 396 | * @mtask: mtask | ||
| 397 | * | ||
| 398 | * Must be called with session lock. | ||
| 399 | */ | ||
| 400 | void iscsi_free_mgmt_task(struct iscsi_conn *conn, | ||
| 401 | struct iscsi_mgmt_task *mtask) | ||
| 402 | { | ||
| 403 | list_del_init(&mtask->running); | ||
| 404 | if (conn->login_mtask == mtask) | ||
| 405 | return; | ||
| 406 | |||
| 407 | if (conn->ping_mtask == mtask) | ||
| 408 | conn->ping_mtask = NULL; | ||
| 409 | __kfifo_put(conn->session->mgmtpool.queue, | ||
| 410 | (void*)&mtask, sizeof(void*)); | ||
| 411 | } | ||
| 412 | EXPORT_SYMBOL_GPL(iscsi_free_mgmt_task); | ||
| 413 | |||
| 414 | static int iscsi_prep_mtask(struct iscsi_conn *conn, | ||
| 415 | struct iscsi_mgmt_task *mtask) | ||
| 416 | { | 424 | { |
| 417 | struct iscsi_session *session = conn->session; | 425 | struct iscsi_session *session = conn->session; |
| 418 | struct iscsi_hdr *hdr = mtask->hdr; | 426 | struct iscsi_hdr *hdr = (struct iscsi_hdr *)ctask->hdr; |
| 419 | struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; | 427 | struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; |
| 420 | 428 | ||
| 421 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) | 429 | if (conn->session->state == ISCSI_STATE_LOGGING_OUT) |
| @@ -429,7 +437,7 @@ static int iscsi_prep_mtask(struct iscsi_conn *conn, | |||
| 429 | */ | 437 | */ |
| 430 | nop->cmdsn = cpu_to_be32(session->cmdsn); | 438 | nop->cmdsn = cpu_to_be32(session->cmdsn); |
| 431 | if (hdr->itt != RESERVED_ITT) { | 439 | if (hdr->itt != RESERVED_ITT) { |
| 432 | hdr->itt = build_itt(mtask->itt, session->age); | 440 | hdr->itt = build_itt(ctask->itt, session->age); |
| 433 | /* | 441 | /* |
| 434 | * TODO: We always use immediate, so we never hit this. | 442 | * TODO: We always use immediate, so we never hit this. |
| 435 | * If we start to send tmfs or nops as non-immediate then | 443 | * If we start to send tmfs or nops as non-immediate then |
| @@ -442,25 +450,25 @@ static int iscsi_prep_mtask(struct iscsi_conn *conn, | |||
| 442 | } | 450 | } |
| 443 | } | 451 | } |
| 444 | 452 | ||
| 445 | if (session->tt->init_mgmt_task) | 453 | if (session->tt->init_task) |
| 446 | session->tt->init_mgmt_task(conn, mtask); | 454 | session->tt->init_task(ctask); |
| 447 | 455 | ||
| 448 | if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) | 456 | if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) |
| 449 | session->state = ISCSI_STATE_LOGGING_OUT; | 457 | session->state = ISCSI_STATE_LOGGING_OUT; |
| 450 | 458 | ||
| 451 | list_move_tail(&mtask->running, &conn->mgmt_run_list); | 459 | list_move_tail(&ctask->running, &conn->mgmt_run_list); |
| 452 | debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", | 460 | debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", |
| 453 | hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, | 461 | hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt, |
| 454 | mtask->data_count); | 462 | ctask->data_count); |
| 455 | return 0; | 463 | return 0; |
| 456 | } | 464 | } |
| 457 | 465 | ||
| 458 | static struct iscsi_mgmt_task * | 466 | static struct iscsi_cmd_task * |
| 459 | __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | 467 | __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, |
| 460 | char *data, uint32_t data_size) | 468 | char *data, uint32_t data_size) |
| 461 | { | 469 | { |
| 462 | struct iscsi_session *session = conn->session; | 470 | struct iscsi_session *session = conn->session; |
| 463 | struct iscsi_mgmt_task *mtask; | 471 | struct iscsi_cmd_task *ctask; |
| 464 | 472 | ||
| 465 | if (session->state == ISCSI_STATE_TERMINATE) | 473 | if (session->state == ISCSI_STATE_TERMINATE) |
| 466 | return NULL; | 474 | return NULL; |
| @@ -470,48 +478,56 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 470 | /* | 478 | /* |
| 471 | * Login and Text are sent serially, in | 479 | * Login and Text are sent serially, in |
| 472 | * request-followed-by-response sequence. | 480 | * request-followed-by-response sequence. |
| 473 | * Same mtask can be used. Same ITT must be used. | 481 | * Same task can be used. Same ITT must be used. |
| 474 | * Note that login_mtask is preallocated at conn_create(). | 482 | * Note that login_task is preallocated at conn_create(). |
| 475 | */ | 483 | */ |
| 476 | mtask = conn->login_mtask; | 484 | ctask = conn->login_ctask; |
| 477 | else { | 485 | else { |
| 478 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); | 486 | BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE); |
| 479 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); | 487 | BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED); |
| 480 | 488 | ||
| 481 | if (!__kfifo_get(session->mgmtpool.queue, | 489 | if (!__kfifo_get(session->cmdpool.queue, |
| 482 | (void*)&mtask, sizeof(void*))) | 490 | (void*)&ctask, sizeof(void*))) |
| 483 | return NULL; | 491 | return NULL; |
| 484 | 492 | ||
| 485 | if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) && | 493 | if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) && |
| 486 | hdr->ttt == RESERVED_ITT) { | 494 | hdr->ttt == RESERVED_ITT) { |
| 487 | conn->ping_mtask = mtask; | 495 | conn->ping_ctask = ctask; |
| 488 | conn->last_ping = jiffies; | 496 | conn->last_ping = jiffies; |
| 489 | } | 497 | } |
| 490 | } | 498 | } |
| 499 | /* | ||
| 500 | * released in complete pdu for task we expect a response for, and | ||
| 501 | * released by the lld when it has transmitted the task for | ||
| 502 | * pdus we do not expect a response for. | ||
| 503 | */ | ||
| 504 | atomic_set(&ctask->refcount, 1); | ||
| 505 | ctask->conn = conn; | ||
| 506 | ctask->sc = NULL; | ||
| 491 | 507 | ||
| 492 | if (data_size) { | 508 | if (data_size) { |
| 493 | memcpy(mtask->data, data, data_size); | 509 | memcpy(ctask->data, data, data_size); |
| 494 | mtask->data_count = data_size; | 510 | ctask->data_count = data_size; |
| 495 | } else | 511 | } else |
| 496 | mtask->data_count = 0; | 512 | ctask->data_count = 0; |
| 497 | 513 | ||
| 498 | memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr)); | 514 | memcpy(ctask->hdr, hdr, sizeof(struct iscsi_hdr)); |
| 499 | INIT_LIST_HEAD(&mtask->running); | 515 | INIT_LIST_HEAD(&ctask->running); |
| 500 | list_add_tail(&mtask->running, &conn->mgmtqueue); | 516 | list_add_tail(&ctask->running, &conn->mgmtqueue); |
| 501 | 517 | ||
| 502 | if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) { | 518 | if (session->tt->caps & CAP_DATA_PATH_OFFLOAD) { |
| 503 | if (iscsi_prep_mtask(conn, mtask)) { | 519 | if (iscsi_prep_mgmt_task(conn, ctask)) { |
| 504 | iscsi_free_mgmt_task(conn, mtask); | 520 | __iscsi_put_ctask(ctask); |
| 505 | return NULL; | 521 | return NULL; |
| 506 | } | 522 | } |
| 507 | 523 | ||
| 508 | if (session->tt->xmit_mgmt_task(conn, mtask)) | 524 | if (session->tt->xmit_task(ctask)) |
| 509 | mtask = NULL; | 525 | ctask = NULL; |
| 510 | 526 | ||
| 511 | } else | 527 | } else |
| 512 | scsi_queue_work(conn->session->host, &conn->xmitwork); | 528 | scsi_queue_work(conn->session->host, &conn->xmitwork); |
| 513 | 529 | ||
| 514 | return mtask; | 530 | return ctask; |
| 515 | } | 531 | } |
| 516 | 532 | ||
| 517 | int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, | 533 | int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr, |
| @@ -538,7 +554,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); | |||
| 538 | * @datalen: len of buffer | 554 | * @datalen: len of buffer |
| 539 | * | 555 | * |
| 540 | * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and | 556 | * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and |
| 541 | * then completes the command and task. | 557 | * then completes the command and ctask. |
| 542 | **/ | 558 | **/ |
| 543 | static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | 559 | static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, |
| 544 | struct iscsi_cmd_task *ctask, char *data, | 560 | struct iscsi_cmd_task *ctask, char *data, |
| @@ -634,9 +650,9 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
| 634 | static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) | 650 | static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) |
| 635 | { | 651 | { |
| 636 | struct iscsi_nopout hdr; | 652 | struct iscsi_nopout hdr; |
| 637 | struct iscsi_mgmt_task *mtask; | 653 | struct iscsi_cmd_task *ctask; |
| 638 | 654 | ||
| 639 | if (!rhdr && conn->ping_mtask) | 655 | if (!rhdr && conn->ping_ctask) |
| 640 | return; | 656 | return; |
| 641 | 657 | ||
| 642 | memset(&hdr, 0, sizeof(struct iscsi_nopout)); | 658 | memset(&hdr, 0, sizeof(struct iscsi_nopout)); |
| @@ -650,8 +666,8 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) | |||
| 650 | } else | 666 | } else |
| 651 | hdr.ttt = RESERVED_ITT; | 667 | hdr.ttt = RESERVED_ITT; |
| 652 | 668 | ||
| 653 | mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); | 669 | ctask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); |
| 654 | if (!mtask) | 670 | if (!ctask) |
| 655 | iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); | 671 | iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); |
| 656 | } | 672 | } |
| 657 | 673 | ||
| @@ -697,7 +713,6 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 697 | struct iscsi_session *session = conn->session; | 713 | struct iscsi_session *session = conn->session; |
| 698 | int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0; | 714 | int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0; |
| 699 | struct iscsi_cmd_task *ctask; | 715 | struct iscsi_cmd_task *ctask; |
| 700 | struct iscsi_mgmt_task *mtask; | ||
| 701 | uint32_t itt; | 716 | uint32_t itt; |
| 702 | 717 | ||
| 703 | conn->last_recv = jiffies; | 718 | conn->last_recv = jiffies; |
| @@ -710,93 +725,10 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 710 | else | 725 | else |
| 711 | itt = ~0U; | 726 | itt = ~0U; |
| 712 | 727 | ||
| 713 | if (itt < session->cmds_max) { | 728 | debug_scsi("[op 0x%x cid %d itt 0x%x len %d]\n", |
| 714 | ctask = session->cmds[itt]; | 729 | opcode, conn->id, itt, datalen); |
| 715 | |||
| 716 | debug_scsi("cmdrsp [op 0x%x cid %d itt 0x%x len %d]\n", | ||
| 717 | opcode, conn->id, ctask->itt, datalen); | ||
| 718 | |||
| 719 | switch(opcode) { | ||
| 720 | case ISCSI_OP_SCSI_CMD_RSP: | ||
| 721 | BUG_ON((void*)ctask != ctask->sc->SCp.ptr); | ||
| 722 | iscsi_scsi_cmd_rsp(conn, hdr, ctask, data, | ||
| 723 | datalen); | ||
| 724 | break; | ||
| 725 | case ISCSI_OP_SCSI_DATA_IN: | ||
| 726 | BUG_ON((void*)ctask != ctask->sc->SCp.ptr); | ||
| 727 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { | ||
| 728 | conn->scsirsp_pdus_cnt++; | ||
| 729 | __iscsi_put_ctask(ctask); | ||
| 730 | } | ||
| 731 | break; | ||
| 732 | case ISCSI_OP_R2T: | ||
| 733 | /* LLD handles this for now */ | ||
| 734 | break; | ||
| 735 | default: | ||
| 736 | rc = ISCSI_ERR_BAD_OPCODE; | ||
| 737 | break; | ||
| 738 | } | ||
| 739 | } else if (itt >= ISCSI_MGMT_ITT_OFFSET && | ||
| 740 | itt < ISCSI_MGMT_ITT_OFFSET + session->mgmtpool_max) { | ||
| 741 | mtask = session->mgmt_cmds[itt - ISCSI_MGMT_ITT_OFFSET]; | ||
| 742 | |||
| 743 | debug_scsi("immrsp [op 0x%x cid %d itt 0x%x len %d]\n", | ||
| 744 | opcode, conn->id, mtask->itt, datalen); | ||
| 745 | 730 | ||
| 746 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | 731 | if (itt == ~0U) { |
| 747 | switch(opcode) { | ||
| 748 | case ISCSI_OP_LOGOUT_RSP: | ||
| 749 | if (datalen) { | ||
| 750 | rc = ISCSI_ERR_PROTO; | ||
| 751 | break; | ||
| 752 | } | ||
| 753 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
| 754 | /* fall through */ | ||
| 755 | case ISCSI_OP_LOGIN_RSP: | ||
| 756 | case ISCSI_OP_TEXT_RSP: | ||
| 757 | /* | ||
| 758 | * login related PDU's exp_statsn is handled in | ||
| 759 | * userspace | ||
| 760 | */ | ||
| 761 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) | ||
| 762 | rc = ISCSI_ERR_CONN_FAILED; | ||
| 763 | iscsi_free_mgmt_task(conn, mtask); | ||
| 764 | break; | ||
| 765 | case ISCSI_OP_SCSI_TMFUNC_RSP: | ||
| 766 | if (datalen) { | ||
| 767 | rc = ISCSI_ERR_PROTO; | ||
| 768 | break; | ||
| 769 | } | ||
| 770 | |||
| 771 | iscsi_tmf_rsp(conn, hdr); | ||
| 772 | iscsi_free_mgmt_task(conn, mtask); | ||
| 773 | break; | ||
| 774 | case ISCSI_OP_NOOP_IN: | ||
| 775 | if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || | ||
| 776 | datalen) { | ||
| 777 | rc = ISCSI_ERR_PROTO; | ||
| 778 | break; | ||
| 779 | } | ||
| 780 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
| 781 | |||
| 782 | if (conn->ping_mtask != mtask) { | ||
| 783 | /* | ||
| 784 | * If this is not in response to one of our | ||
| 785 | * nops then it must be from userspace. | ||
| 786 | */ | ||
| 787 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, | ||
| 788 | datalen)) | ||
| 789 | rc = ISCSI_ERR_CONN_FAILED; | ||
| 790 | } else | ||
| 791 | mod_timer(&conn->transport_timer, | ||
| 792 | jiffies + conn->recv_timeout); | ||
| 793 | iscsi_free_mgmt_task(conn, mtask); | ||
| 794 | break; | ||
| 795 | default: | ||
| 796 | rc = ISCSI_ERR_BAD_OPCODE; | ||
| 797 | break; | ||
| 798 | } | ||
| 799 | } else if (itt == ~0U) { | ||
| 800 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | 732 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); |
| 801 | 733 | ||
| 802 | switch(opcode) { | 734 | switch(opcode) { |
| @@ -823,9 +755,88 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
| 823 | rc = ISCSI_ERR_BAD_OPCODE; | 755 | rc = ISCSI_ERR_BAD_OPCODE; |
| 824 | break; | 756 | break; |
| 825 | } | 757 | } |
| 826 | } else | 758 | goto out; |
| 827 | rc = ISCSI_ERR_BAD_ITT; | 759 | } |
| 760 | |||
| 761 | ctask = session->cmds[itt]; | ||
| 762 | switch(opcode) { | ||
| 763 | case ISCSI_OP_SCSI_CMD_RSP: | ||
| 764 | if (!ctask->sc) { | ||
| 765 | rc = ISCSI_ERR_NO_SCSI_CMD; | ||
| 766 | break; | ||
| 767 | } | ||
| 768 | BUG_ON((void*)ctask != ctask->sc->SCp.ptr); | ||
| 769 | iscsi_scsi_cmd_rsp(conn, hdr, ctask, data, datalen); | ||
| 770 | break; | ||
| 771 | case ISCSI_OP_SCSI_DATA_IN: | ||
| 772 | if (!ctask->sc) { | ||
| 773 | rc = ISCSI_ERR_NO_SCSI_CMD; | ||
| 774 | break; | ||
| 775 | } | ||
| 776 | BUG_ON((void*)ctask != ctask->sc->SCp.ptr); | ||
| 777 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { | ||
| 778 | conn->scsirsp_pdus_cnt++; | ||
| 779 | iscsi_update_cmdsn(session, | ||
| 780 | (struct iscsi_nopin*) hdr); | ||
| 781 | __iscsi_put_ctask(ctask); | ||
| 782 | } | ||
| 783 | break; | ||
| 784 | case ISCSI_OP_R2T: | ||
| 785 | /* LLD handles this for now */ | ||
| 786 | break; | ||
| 787 | case ISCSI_OP_LOGOUT_RSP: | ||
| 788 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | ||
| 789 | if (datalen) { | ||
| 790 | rc = ISCSI_ERR_PROTO; | ||
| 791 | break; | ||
| 792 | } | ||
| 793 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
| 794 | goto recv_pdu; | ||
| 795 | case ISCSI_OP_LOGIN_RSP: | ||
| 796 | case ISCSI_OP_TEXT_RSP: | ||
| 797 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | ||
| 798 | /* | ||
| 799 | * login related PDU's exp_statsn is handled in | ||
| 800 | * userspace | ||
| 801 | */ | ||
| 802 | goto recv_pdu; | ||
| 803 | case ISCSI_OP_SCSI_TMFUNC_RSP: | ||
| 804 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | ||
| 805 | if (datalen) { | ||
| 806 | rc = ISCSI_ERR_PROTO; | ||
| 807 | break; | ||
| 808 | } | ||
| 809 | |||
| 810 | iscsi_tmf_rsp(conn, hdr); | ||
| 811 | __iscsi_put_ctask(ctask); | ||
| 812 | break; | ||
| 813 | case ISCSI_OP_NOOP_IN: | ||
| 814 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | ||
| 815 | if (hdr->ttt != cpu_to_be32(ISCSI_RESERVED_TAG) || datalen) { | ||
| 816 | rc = ISCSI_ERR_PROTO; | ||
| 817 | break; | ||
| 818 | } | ||
| 819 | conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; | ||
| 820 | |||
| 821 | if (conn->ping_ctask != ctask) | ||
| 822 | /* | ||
| 823 | * If this is not in response to one of our | ||
| 824 | * nops then it must be from userspace. | ||
| 825 | */ | ||
| 826 | goto recv_pdu; | ||
| 827 | __iscsi_put_ctask(ctask); | ||
| 828 | break; | ||
| 829 | default: | ||
| 830 | rc = ISCSI_ERR_BAD_OPCODE; | ||
| 831 | break; | ||
| 832 | } | ||
| 828 | 833 | ||
| 834 | out: | ||
| 835 | return rc; | ||
| 836 | recv_pdu: | ||
| 837 | if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) | ||
| 838 | rc = ISCSI_ERR_CONN_FAILED; | ||
| 839 | __iscsi_put_ctask(ctask); | ||
| 829 | return rc; | 840 | return rc; |
| 830 | } | 841 | } |
| 831 | 842 | ||
| @@ -845,6 +856,7 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) | |||
| 845 | { | 856 | { |
| 846 | struct iscsi_session *session = conn->session; | 857 | struct iscsi_session *session = conn->session; |
| 847 | struct iscsi_cmd_task *ctask; | 858 | struct iscsi_cmd_task *ctask; |
| 859 | uint32_t i; | ||
| 848 | 860 | ||
| 849 | if (itt == RESERVED_ITT) | 861 | if (itt == RESERVED_ITT) |
| 850 | return 0; | 862 | return 0; |
| @@ -858,25 +870,22 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) | |||
| 858 | return ISCSI_ERR_BAD_ITT; | 870 | return ISCSI_ERR_BAD_ITT; |
| 859 | } | 871 | } |
| 860 | 872 | ||
| 861 | if (itt < session->cmds_max) { | 873 | i = get_itt(itt); |
| 862 | ctask = session->cmds[itt]; | 874 | if (i >= session->cmds_max) { |
| 863 | 875 | iscsi_conn_printk(KERN_ERR, conn, | |
| 864 | if (!ctask->sc) { | 876 | "received invalid itt index %u (max cmds " |
| 865 | iscsi_conn_printk(KERN_INFO, conn, "dropping ctask " | 877 | "%u.\n", i, session->cmds_max); |
| 866 | "with itt 0x%x\n", ctask->itt); | 878 | return ISCSI_ERR_BAD_ITT; |
| 867 | /* force drop */ | ||
| 868 | return ISCSI_ERR_NO_SCSI_CMD; | ||
| 869 | } | ||
| 870 | |||
| 871 | if (ctask->sc->SCp.phase != session->age) { | ||
| 872 | iscsi_conn_printk(KERN_ERR, conn, | ||
| 873 | "iscsi: ctask's session age %d, " | ||
| 874 | "expected %d\n", ctask->sc->SCp.phase, | ||
| 875 | session->age); | ||
| 876 | return ISCSI_ERR_SESSION_FAILED; | ||
| 877 | } | ||
| 878 | } | 879 | } |
| 879 | 880 | ||
| 881 | ctask = session->cmds[i]; | ||
| 882 | if (ctask->sc && ctask->sc->SCp.phase != session->age) { | ||
| 883 | iscsi_conn_printk(KERN_ERR, conn, | ||
| 884 | "iscsi: ctask's session age %d, " | ||
| 885 | "expected %d\n", ctask->sc->SCp.phase, | ||
| 886 | session->age); | ||
| 887 | return ISCSI_ERR_SESSION_FAILED; | ||
| 888 | } | ||
| 880 | return 0; | 889 | return 0; |
| 881 | } | 890 | } |
| 882 | EXPORT_SYMBOL_GPL(iscsi_verify_itt); | 891 | EXPORT_SYMBOL_GPL(iscsi_verify_itt); |
| @@ -929,20 +938,6 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | |||
| 929 | } | 938 | } |
| 930 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); | 939 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); |
| 931 | 940 | ||
| 932 | static int iscsi_xmit_mtask(struct iscsi_conn *conn) | ||
| 933 | { | ||
| 934 | int rc; | ||
| 935 | |||
| 936 | spin_unlock_bh(&conn->session->lock); | ||
| 937 | rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask); | ||
| 938 | spin_lock_bh(&conn->session->lock); | ||
| 939 | if (rc) | ||
| 940 | return rc; | ||
| 941 | /* done with this in-progress mtask */ | ||
| 942 | conn->mtask = NULL; | ||
| 943 | return 0; | ||
| 944 | } | ||
| 945 | |||
| 946 | static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) | 941 | static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) |
| 947 | { | 942 | { |
| 948 | struct iscsi_session *session = conn->session; | 943 | struct iscsi_session *session = conn->session; |
| @@ -967,7 +962,7 @@ static int iscsi_xmit_ctask(struct iscsi_conn *conn) | |||
| 967 | 962 | ||
| 968 | __iscsi_get_ctask(ctask); | 963 | __iscsi_get_ctask(ctask); |
| 969 | spin_unlock_bh(&conn->session->lock); | 964 | spin_unlock_bh(&conn->session->lock); |
| 970 | rc = conn->session->tt->xmit_cmd_task(conn, ctask); | 965 | rc = conn->session->tt->xmit_task(ctask); |
| 971 | spin_lock_bh(&conn->session->lock); | 966 | spin_lock_bh(&conn->session->lock); |
| 972 | __iscsi_put_ctask(ctask); | 967 | __iscsi_put_ctask(ctask); |
| 973 | if (!rc) | 968 | if (!rc) |
| @@ -1015,12 +1010,6 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 1015 | 1010 | ||
| 1016 | if (conn->ctask) { | 1011 | if (conn->ctask) { |
| 1017 | rc = iscsi_xmit_ctask(conn); | 1012 | rc = iscsi_xmit_ctask(conn); |
| 1018 | if (rc) | ||
| 1019 | goto again; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | if (conn->mtask) { | ||
| 1023 | rc = iscsi_xmit_mtask(conn); | ||
| 1024 | if (rc) | 1013 | if (rc) |
| 1025 | goto again; | 1014 | goto again; |
| 1026 | } | 1015 | } |
| @@ -1032,14 +1021,14 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 1032 | */ | 1021 | */ |
| 1033 | check_mgmt: | 1022 | check_mgmt: |
| 1034 | while (!list_empty(&conn->mgmtqueue)) { | 1023 | while (!list_empty(&conn->mgmtqueue)) { |
| 1035 | conn->mtask = list_entry(conn->mgmtqueue.next, | 1024 | conn->ctask = list_entry(conn->mgmtqueue.next, |
| 1036 | struct iscsi_mgmt_task, running); | 1025 | struct iscsi_cmd_task, running); |
| 1037 | if (iscsi_prep_mtask(conn, conn->mtask)) { | 1026 | if (iscsi_prep_mgmt_task(conn, conn->ctask)) { |
| 1038 | iscsi_free_mgmt_task(conn, conn->mtask); | 1027 | __iscsi_put_ctask(conn->ctask); |
| 1039 | conn->mtask = NULL; | 1028 | conn->ctask = NULL; |
| 1040 | continue; | 1029 | continue; |
| 1041 | } | 1030 | } |
| 1042 | rc = iscsi_xmit_mtask(conn); | 1031 | rc = iscsi_xmit_ctask(conn); |
| 1043 | if (rc) | 1032 | if (rc) |
| 1044 | goto again; | 1033 | goto again; |
| 1045 | } | 1034 | } |
| @@ -1224,7 +1213,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
| 1224 | iscsi_complete_command(ctask); | 1213 | iscsi_complete_command(ctask); |
| 1225 | goto fault; | 1214 | goto fault; |
| 1226 | } | 1215 | } |
| 1227 | if (session->tt->xmit_cmd_task(conn, ctask)) { | 1216 | if (session->tt->xmit_task(ctask)) { |
| 1228 | sc->scsi_done = NULL; | 1217 | sc->scsi_done = NULL; |
| 1229 | iscsi_complete_command(ctask); | 1218 | iscsi_complete_command(ctask); |
| 1230 | reason = FAILURE_SESSION_NOT_READY; | 1219 | reason = FAILURE_SESSION_NOT_READY; |
| @@ -1347,16 +1336,16 @@ static void iscsi_tmf_timedout(unsigned long data) | |||
| 1347 | spin_unlock(&session->lock); | 1336 | spin_unlock(&session->lock); |
| 1348 | } | 1337 | } |
| 1349 | 1338 | ||
| 1350 | static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, | 1339 | static int iscsi_exec_ctask_mgmt_fn(struct iscsi_conn *conn, |
| 1351 | struct iscsi_tm *hdr, int age, | 1340 | struct iscsi_tm *hdr, int age, |
| 1352 | int timeout) | 1341 | int timeout) |
| 1353 | { | 1342 | { |
| 1354 | struct iscsi_session *session = conn->session; | 1343 | struct iscsi_session *session = conn->session; |
| 1355 | struct iscsi_mgmt_task *mtask; | 1344 | struct iscsi_cmd_task *ctask; |
| 1356 | 1345 | ||
| 1357 | mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, | 1346 | ctask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, |
| 1358 | NULL, 0); | 1347 | NULL, 0); |
| 1359 | if (!mtask) { | 1348 | if (!ctask) { |
| 1360 | spin_unlock_bh(&session->lock); | 1349 | spin_unlock_bh(&session->lock); |
| 1361 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 1350 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
| 1362 | spin_lock_bh(&session->lock); | 1351 | spin_lock_bh(&session->lock); |
| @@ -1390,7 +1379,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, | |||
| 1390 | 1379 | ||
| 1391 | mutex_lock(&session->eh_mutex); | 1380 | mutex_lock(&session->eh_mutex); |
| 1392 | spin_lock_bh(&session->lock); | 1381 | spin_lock_bh(&session->lock); |
| 1393 | /* if the session drops it will clean up the mtask */ | 1382 | /* if the session drops it will clean up the ctask */ |
| 1394 | if (age != session->age || | 1383 | if (age != session->age || |
| 1395 | session->state != ISCSI_STATE_LOGGED_IN) | 1384 | session->state != ISCSI_STATE_LOGGED_IN) |
| 1396 | return -ENOTCONN; | 1385 | return -ENOTCONN; |
| @@ -1497,7 +1486,7 @@ static enum scsi_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *scmd) | |||
| 1497 | jiffies)) | 1486 | jiffies)) |
| 1498 | rc = EH_RESET_TIMER; | 1487 | rc = EH_RESET_TIMER; |
| 1499 | /* if in the middle of checking the transport then give us more time */ | 1488 | /* if in the middle of checking the transport then give us more time */ |
| 1500 | if (conn->ping_mtask) | 1489 | if (conn->ping_ctask) |
| 1501 | rc = EH_RESET_TIMER; | 1490 | rc = EH_RESET_TIMER; |
| 1502 | done: | 1491 | done: |
| 1503 | spin_unlock(&session->lock); | 1492 | spin_unlock(&session->lock); |
| @@ -1521,7 +1510,7 @@ static void iscsi_check_transport_timeouts(unsigned long data) | |||
| 1521 | 1510 | ||
| 1522 | recv_timeout *= HZ; | 1511 | recv_timeout *= HZ; |
| 1523 | last_recv = conn->last_recv; | 1512 | last_recv = conn->last_recv; |
| 1524 | if (conn->ping_mtask && | 1513 | if (conn->ping_ctask && |
| 1525 | time_before_eq(conn->last_ping + (conn->ping_timeout * HZ), | 1514 | time_before_eq(conn->last_ping + (conn->ping_timeout * HZ), |
| 1526 | jiffies)) { | 1515 | jiffies)) { |
| 1527 | iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs " | 1516 | iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs " |
| @@ -1547,7 +1536,7 @@ done: | |||
| 1547 | spin_unlock(&session->lock); | 1536 | spin_unlock(&session->lock); |
| 1548 | } | 1537 | } |
| 1549 | 1538 | ||
| 1550 | static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask, | 1539 | static void iscsi_prep_abort_ctask_pdu(struct iscsi_cmd_task *ctask, |
| 1551 | struct iscsi_tm *hdr) | 1540 | struct iscsi_tm *hdr) |
| 1552 | { | 1541 | { |
| 1553 | memset(hdr, 0, sizeof(*hdr)); | 1542 | memset(hdr, 0, sizeof(*hdr)); |
| @@ -1619,9 +1608,9 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 1619 | conn->tmf_state = TMF_QUEUED; | 1608 | conn->tmf_state = TMF_QUEUED; |
| 1620 | 1609 | ||
| 1621 | hdr = &conn->tmhdr; | 1610 | hdr = &conn->tmhdr; |
| 1622 | iscsi_prep_abort_task_pdu(ctask, hdr); | 1611 | iscsi_prep_abort_ctask_pdu(ctask, hdr); |
| 1623 | 1612 | ||
| 1624 | if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) { | 1613 | if (iscsi_exec_ctask_mgmt_fn(conn, hdr, age, session->abort_timeout)) { |
| 1625 | rc = FAILED; | 1614 | rc = FAILED; |
| 1626 | goto failed; | 1615 | goto failed; |
| 1627 | } | 1616 | } |
| @@ -1631,7 +1620,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 1631 | spin_unlock_bh(&session->lock); | 1620 | spin_unlock_bh(&session->lock); |
| 1632 | iscsi_suspend_tx(conn); | 1621 | iscsi_suspend_tx(conn); |
| 1633 | /* | 1622 | /* |
| 1634 | * clean up task if aborted. grab the recv lock as a writer | 1623 | * clean up ctask if aborted. grab the recv lock as a writer |
| 1635 | */ | 1624 | */ |
| 1636 | write_lock_bh(conn->recv_lock); | 1625 | write_lock_bh(conn->recv_lock); |
| 1637 | spin_lock(&session->lock); | 1626 | spin_lock(&session->lock); |
| @@ -1716,7 +1705,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) | |||
| 1716 | hdr = &conn->tmhdr; | 1705 | hdr = &conn->tmhdr; |
| 1717 | iscsi_prep_lun_reset_pdu(sc, hdr); | 1706 | iscsi_prep_lun_reset_pdu(sc, hdr); |
| 1718 | 1707 | ||
| 1719 | if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, | 1708 | if (iscsi_exec_ctask_mgmt_fn(conn, hdr, session->age, |
| 1720 | session->lu_reset_timeout)) { | 1709 | session->lu_reset_timeout)) { |
| 1721 | rc = FAILED; | 1710 | rc = FAILED; |
| 1722 | goto unlock; | 1711 | goto unlock; |
| @@ -1897,8 +1886,7 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); | |||
| 1897 | * @iscsit: iscsi transport template | 1886 | * @iscsit: iscsi transport template |
| 1898 | * @shost: scsi host | 1887 | * @shost: scsi host |
| 1899 | * @cmds_max: session can queue | 1888 | * @cmds_max: session can queue |
| 1900 | * @cmd_task_size: LLD ctask private data size | 1889 | * @cmd_ctask_size: LLD ctask private data size |
| 1901 | * @mgmt_task_size: LLD mtask private data size | ||
| 1902 | * @initial_cmdsn: initial CmdSN | 1890 | * @initial_cmdsn: initial CmdSN |
| 1903 | * | 1891 | * |
| 1904 | * This can be used by software iscsi_transports that allocate | 1892 | * This can be used by software iscsi_transports that allocate |
| @@ -1906,22 +1894,26 @@ EXPORT_SYMBOL_GPL(iscsi_host_free); | |||
| 1906 | */ | 1894 | */ |
| 1907 | struct iscsi_cls_session * | 1895 | struct iscsi_cls_session * |
| 1908 | iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | 1896 | iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, |
| 1909 | uint16_t cmds_max, int cmd_task_size, int mgmt_task_size, | 1897 | uint16_t scsi_cmds_max, int cmd_ctask_size, |
| 1910 | uint32_t initial_cmdsn) | 1898 | uint32_t initial_cmdsn) |
| 1911 | { | 1899 | { |
| 1912 | struct iscsi_session *session; | 1900 | struct iscsi_session *session; |
| 1913 | struct iscsi_cls_session *cls_session; | 1901 | struct iscsi_cls_session *cls_session; |
| 1914 | int cmd_i; | 1902 | int cmd_i, cmds_max; |
| 1915 | 1903 | ||
| 1916 | if (!is_power_of_2(cmds_max) || cmds_max >= ISCSI_MGMT_ITT_OFFSET || | 1904 | /* |
| 1917 | cmds_max < 2) { | 1905 | * The iscsi layer needs some ctasks for nop handling and tmfs. |
| 1918 | if (cmds_max != 0) | 1906 | */ |
| 1919 | printk(KERN_ERR "iscsi: invalid can_queue of %d. " | 1907 | if (scsi_cmds_max < 1) |
| 1920 | "can_queue must be a power of 2 and between " | 1908 | scsi_cmds_max = ISCSI_MGMT_CMDS_MAX; |
| 1921 | "2 and %d - setting to %d.\n", cmds_max, | 1909 | if ((scsi_cmds_max + ISCSI_MGMT_CMDS_MAX) >= ISCSI_MGMT_ITT_OFFSET) { |
| 1922 | ISCSI_MGMT_ITT_OFFSET, ISCSI_DEF_XMIT_CMDS_MAX); | 1910 | printk(KERN_ERR "iscsi: invalid can_queue of %d. " |
| 1923 | cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; | 1911 | "can_queue must be less than %d.\n", |
| 1912 | scsi_cmds_max, | ||
| 1913 | ISCSI_MGMT_ITT_OFFSET - ISCSI_MGMT_CMDS_MAX); | ||
| 1914 | scsi_cmds_max = ISCSI_DEF_XMIT_CMDS_MAX; | ||
| 1924 | } | 1915 | } |
| 1916 | cmds_max = roundup_pow_of_two(scsi_cmds_max + ISCSI_MGMT_CMDS_MAX); | ||
| 1925 | 1917 | ||
| 1926 | cls_session = iscsi_alloc_session(shost, iscsit, | 1918 | cls_session = iscsi_alloc_session(shost, iscsit, |
| 1927 | sizeof(struct iscsi_session)); | 1919 | sizeof(struct iscsi_session)); |
| @@ -1934,7 +1926,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | |||
| 1934 | session->fast_abort = 1; | 1926 | session->fast_abort = 1; |
| 1935 | session->lu_reset_timeout = 15; | 1927 | session->lu_reset_timeout = 15; |
| 1936 | session->abort_timeout = 10; | 1928 | session->abort_timeout = 10; |
| 1937 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; | 1929 | session->scsi_cmds_max = scsi_cmds_max; |
| 1938 | session->cmds_max = cmds_max; | 1930 | session->cmds_max = cmds_max; |
| 1939 | session->queued_cmdsn = session->cmdsn = initial_cmdsn; | 1931 | session->queued_cmdsn = session->cmdsn = initial_cmdsn; |
| 1940 | session->exp_cmdsn = initial_cmdsn + 1; | 1932 | session->exp_cmdsn = initial_cmdsn + 1; |
| @@ -1947,36 +1939,19 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | |||
| 1947 | /* initialize SCSI PDU commands pool */ | 1939 | /* initialize SCSI PDU commands pool */ |
| 1948 | if (iscsi_pool_init(&session->cmdpool, session->cmds_max, | 1940 | if (iscsi_pool_init(&session->cmdpool, session->cmds_max, |
| 1949 | (void***)&session->cmds, | 1941 | (void***)&session->cmds, |
| 1950 | cmd_task_size + sizeof(struct iscsi_cmd_task))) | 1942 | cmd_ctask_size + sizeof(struct iscsi_cmd_task))) |
| 1951 | goto cmdpool_alloc_fail; | 1943 | goto cmdpool_alloc_fail; |
| 1952 | 1944 | ||
| 1953 | /* pre-format cmds pool with ITT */ | 1945 | /* pre-format cmds pool with ITT */ |
| 1954 | for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { | 1946 | for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { |
| 1955 | struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; | 1947 | struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; |
| 1956 | 1948 | ||
| 1957 | if (cmd_task_size) | 1949 | if (cmd_ctask_size) |
| 1958 | ctask->dd_data = &ctask[1]; | 1950 | ctask->dd_data = &ctask[1]; |
| 1959 | ctask->itt = cmd_i; | 1951 | ctask->itt = cmd_i; |
| 1960 | INIT_LIST_HEAD(&ctask->running); | 1952 | INIT_LIST_HEAD(&ctask->running); |
| 1961 | } | 1953 | } |
| 1962 | 1954 | ||
| 1963 | /* initialize immediate command pool */ | ||
| 1964 | if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, | ||
| 1965 | (void***)&session->mgmt_cmds, | ||
| 1966 | mgmt_task_size + sizeof(struct iscsi_mgmt_task))) | ||
| 1967 | goto mgmtpool_alloc_fail; | ||
| 1968 | |||
| 1969 | |||
| 1970 | /* pre-format immediate cmds pool with ITT */ | ||
| 1971 | for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) { | ||
| 1972 | struct iscsi_mgmt_task *mtask = session->mgmt_cmds[cmd_i]; | ||
| 1973 | |||
| 1974 | if (mgmt_task_size) | ||
| 1975 | mtask->dd_data = &mtask[1]; | ||
| 1976 | mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; | ||
| 1977 | INIT_LIST_HEAD(&mtask->running); | ||
| 1978 | } | ||
| 1979 | |||
| 1980 | if (!try_module_get(iscsit->owner)) | 1955 | if (!try_module_get(iscsit->owner)) |
| 1981 | goto module_get_fail; | 1956 | goto module_get_fail; |
| 1982 | 1957 | ||
| @@ -1987,8 +1962,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | |||
| 1987 | cls_session_fail: | 1962 | cls_session_fail: |
| 1988 | module_put(iscsit->owner); | 1963 | module_put(iscsit->owner); |
| 1989 | module_get_fail: | 1964 | module_get_fail: |
| 1990 | iscsi_pool_free(&session->mgmtpool); | ||
| 1991 | mgmtpool_alloc_fail: | ||
| 1992 | iscsi_pool_free(&session->cmdpool); | 1965 | iscsi_pool_free(&session->cmdpool); |
| 1993 | cmdpool_alloc_fail: | 1966 | cmdpool_alloc_fail: |
| 1994 | iscsi_free_session(cls_session); | 1967 | iscsi_free_session(cls_session); |
| @@ -2008,7 +1981,6 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
| 2008 | struct iscsi_session *session = cls_session->dd_data; | 1981 | struct iscsi_session *session = cls_session->dd_data; |
| 2009 | struct module *owner = cls_session->transport->owner; | 1982 | struct module *owner = cls_session->transport->owner; |
| 2010 | 1983 | ||
| 2011 | iscsi_pool_free(&session->mgmtpool); | ||
| 2012 | iscsi_pool_free(&session->cmdpool); | 1984 | iscsi_pool_free(&session->cmdpool); |
| 2013 | 1985 | ||
| 2014 | kfree(session->password); | 1986 | kfree(session->password); |
| @@ -2063,30 +2035,30 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, | |||
| 2063 | INIT_LIST_HEAD(&conn->requeue); | 2035 | INIT_LIST_HEAD(&conn->requeue); |
| 2064 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker); | 2036 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker); |
| 2065 | 2037 | ||
| 2066 | /* allocate login_mtask used for the login/text sequences */ | 2038 | /* allocate login_ctask used for the login/text sequences */ |
| 2067 | spin_lock_bh(&session->lock); | 2039 | spin_lock_bh(&session->lock); |
| 2068 | if (!__kfifo_get(session->mgmtpool.queue, | 2040 | if (!__kfifo_get(session->cmdpool.queue, |
| 2069 | (void*)&conn->login_mtask, | 2041 | (void*)&conn->login_ctask, |
| 2070 | sizeof(void*))) { | 2042 | sizeof(void*))) { |
| 2071 | spin_unlock_bh(&session->lock); | 2043 | spin_unlock_bh(&session->lock); |
| 2072 | goto login_mtask_alloc_fail; | 2044 | goto login_ctask_alloc_fail; |
| 2073 | } | 2045 | } |
| 2074 | spin_unlock_bh(&session->lock); | 2046 | spin_unlock_bh(&session->lock); |
| 2075 | 2047 | ||
| 2076 | data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL); | 2048 | data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL); |
| 2077 | if (!data) | 2049 | if (!data) |
| 2078 | goto login_mtask_data_alloc_fail; | 2050 | goto login_ctask_data_alloc_fail; |
| 2079 | conn->login_mtask->data = conn->data = data; | 2051 | conn->login_ctask->data = conn->data = data; |
| 2080 | 2052 | ||
| 2081 | init_timer(&conn->tmf_timer); | 2053 | init_timer(&conn->tmf_timer); |
| 2082 | init_waitqueue_head(&conn->ehwait); | 2054 | init_waitqueue_head(&conn->ehwait); |
| 2083 | 2055 | ||
| 2084 | return cls_conn; | 2056 | return cls_conn; |
| 2085 | 2057 | ||
| 2086 | login_mtask_data_alloc_fail: | 2058 | login_ctask_data_alloc_fail: |
| 2087 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, | 2059 | __kfifo_put(session->cmdpool.queue, (void*)&conn->login_ctask, |
| 2088 | sizeof(void*)); | 2060 | sizeof(void*)); |
| 2089 | login_mtask_alloc_fail: | 2061 | login_ctask_alloc_fail: |
| 2090 | iscsi_destroy_conn(cls_conn); | 2062 | iscsi_destroy_conn(cls_conn); |
| 2091 | return NULL; | 2063 | return NULL; |
| 2092 | } | 2064 | } |
| @@ -2146,7 +2118,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
| 2146 | spin_lock_bh(&session->lock); | 2118 | spin_lock_bh(&session->lock); |
| 2147 | kfree(conn->data); | 2119 | kfree(conn->data); |
| 2148 | kfree(conn->persistent_address); | 2120 | kfree(conn->persistent_address); |
| 2149 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, | 2121 | __kfifo_put(session->cmdpool.queue, (void*)&conn->login_ctask, |
| 2150 | sizeof(void*)); | 2122 | sizeof(void*)); |
| 2151 | if (session->leadconn == conn) | 2123 | if (session->leadconn == conn) |
| 2152 | session->leadconn = NULL; | 2124 | session->leadconn = NULL; |
| @@ -2227,21 +2199,23 @@ EXPORT_SYMBOL_GPL(iscsi_conn_start); | |||
| 2227 | static void | 2199 | static void |
| 2228 | flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn) | 2200 | flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn) |
| 2229 | { | 2201 | { |
| 2230 | struct iscsi_mgmt_task *mtask, *tmp; | 2202 | struct iscsi_cmd_task *ctask, *tmp; |
| 2231 | 2203 | ||
| 2232 | /* handle pending */ | 2204 | /* handle pending */ |
| 2233 | list_for_each_entry_safe(mtask, tmp, &conn->mgmtqueue, running) { | 2205 | list_for_each_entry_safe(ctask, tmp, &conn->mgmtqueue, running) { |
| 2234 | debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt); | 2206 | debug_scsi("flushing pending mgmt ctask itt 0x%x\n", ctask->itt); |
| 2235 | iscsi_free_mgmt_task(conn, mtask); | 2207 | /* release ref from prep ctask */ |
| 2208 | __iscsi_put_ctask(ctask); | ||
| 2236 | } | 2209 | } |
| 2237 | 2210 | ||
| 2238 | /* handle running */ | 2211 | /* handle running */ |
| 2239 | list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) { | 2212 | list_for_each_entry_safe(ctask, tmp, &conn->mgmt_run_list, running) { |
| 2240 | debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt); | 2213 | debug_scsi("flushing running mgmt ctask itt 0x%x\n", ctask->itt); |
| 2241 | iscsi_free_mgmt_task(conn, mtask); | 2214 | /* release ref from prep ctask */ |
| 2215 | __iscsi_put_ctask(ctask); | ||
| 2242 | } | 2216 | } |
| 2243 | 2217 | ||
| 2244 | conn->mtask = NULL; | 2218 | conn->ctask = NULL; |
| 2245 | } | 2219 | } |
| 2246 | 2220 | ||
| 2247 | static void iscsi_start_session_recovery(struct iscsi_session *session, | 2221 | static void iscsi_start_session_recovery(struct iscsi_session *session, |
| @@ -2272,7 +2246,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
| 2272 | 2246 | ||
| 2273 | /* | 2247 | /* |
| 2274 | * When this is called for the in_login state, we only want to clean | 2248 | * When this is called for the in_login state, we only want to clean |
| 2275 | * up the login task and connection. We do not need to block and set | 2249 | * up the login ctask and connection. We do not need to block and set |
| 2276 | * the recovery state again | 2250 | * the recovery state again |
| 2277 | */ | 2251 | */ |
| 2278 | if (flag == STOP_CONN_TERM) | 2252 | if (flag == STOP_CONN_TERM) |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 9be6a70faff5..d1c36759b350 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
| @@ -85,18 +85,6 @@ enum { | |||
| 85 | ISCSI_DIGEST_SIZE = sizeof(__u32), | 85 | ISCSI_DIGEST_SIZE = sizeof(__u32), |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | struct iscsi_mgmt_task { | ||
| 89 | /* | ||
| 90 | * Becuae LLDs allocate their hdr differently, this is a pointer to | ||
| 91 | * that storage. It must be setup at session creation time. | ||
| 92 | */ | ||
| 93 | struct iscsi_hdr *hdr; | ||
| 94 | char *data; /* mgmt payload */ | ||
| 95 | unsigned data_count; /* counts data to be sent */ | ||
| 96 | uint32_t itt; /* this ITT */ | ||
| 97 | void *dd_data; /* driver/transport data */ | ||
| 98 | struct list_head running; | ||
| 99 | }; | ||
| 100 | 88 | ||
| 101 | enum { | 89 | enum { |
| 102 | ISCSI_TASK_COMPLETED, | 90 | ISCSI_TASK_COMPLETED, |
| @@ -121,6 +109,7 @@ struct iscsi_cmd_task { | |||
| 121 | /* offset in unsolicited stream (bytes); */ | 109 | /* offset in unsolicited stream (bytes); */ |
| 122 | unsigned unsol_offset; | 110 | unsigned unsol_offset; |
| 123 | unsigned data_count; /* remaining Data-Out */ | 111 | unsigned data_count; /* remaining Data-Out */ |
| 112 | char *data; /* mgmt payload */ | ||
| 124 | struct scsi_cmnd *sc; /* associated SCSI cmd*/ | 113 | struct scsi_cmnd *sc; /* associated SCSI cmd*/ |
| 125 | struct iscsi_conn *conn; /* used connection */ | 114 | struct iscsi_conn *conn; /* used connection */ |
| 126 | 115 | ||
| @@ -162,7 +151,7 @@ struct iscsi_conn { | |||
| 162 | unsigned long last_ping; | 151 | unsigned long last_ping; |
| 163 | int ping_timeout; | 152 | int ping_timeout; |
| 164 | int recv_timeout; | 153 | int recv_timeout; |
| 165 | struct iscsi_mgmt_task *ping_mtask; | 154 | struct iscsi_cmd_task *ping_ctask; |
| 166 | 155 | ||
| 167 | /* iSCSI connection-wide sequencing */ | 156 | /* iSCSI connection-wide sequencing */ |
| 168 | uint32_t exp_statsn; | 157 | uint32_t exp_statsn; |
| @@ -178,9 +167,8 @@ struct iscsi_conn { | |||
| 178 | * should always fit in this buffer | 167 | * should always fit in this buffer |
| 179 | */ | 168 | */ |
| 180 | char *data; | 169 | char *data; |
| 181 | struct iscsi_mgmt_task *login_mtask; /* mtask used for login/text */ | 170 | struct iscsi_cmd_task *login_ctask; /* mtask used for login/text */ |
| 182 | struct iscsi_mgmt_task *mtask; /* xmit mtask in progress */ | 171 | struct iscsi_cmd_task *ctask; /* xmit task in progress */ |
| 183 | struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ | ||
| 184 | 172 | ||
| 185 | /* xmit */ | 173 | /* xmit */ |
| 186 | struct list_head mgmtqueue; /* mgmt (control) xmit queue */ | 174 | struct list_head mgmtqueue; /* mgmt (control) xmit queue */ |
| @@ -295,12 +283,10 @@ struct iscsi_session { | |||
| 295 | int state; /* session state */ | 283 | int state; /* session state */ |
| 296 | int age; /* counts session re-opens */ | 284 | int age; /* counts session re-opens */ |
| 297 | 285 | ||
| 286 | int scsi_cmds_max; /* max scsi commands */ | ||
| 298 | int cmds_max; /* size of cmds array */ | 287 | int cmds_max; /* size of cmds array */ |
| 299 | struct iscsi_cmd_task **cmds; /* Original Cmds arr */ | 288 | struct iscsi_cmd_task **cmds; /* Original Cmds arr */ |
| 300 | struct iscsi_pool cmdpool; /* PDU's pool */ | 289 | struct iscsi_pool cmdpool; /* PDU's pool */ |
| 301 | int mgmtpool_max; /* size of mgmt array */ | ||
| 302 | struct iscsi_mgmt_task **mgmt_cmds; /* Original mgmt arr */ | ||
| 303 | struct iscsi_pool mgmtpool; /* Mgmt PDU's pool */ | ||
| 304 | }; | 290 | }; |
| 305 | 291 | ||
| 306 | struct iscsi_host { | 292 | struct iscsi_host { |
| @@ -345,7 +331,7 @@ extern void iscsi_host_free(struct Scsi_Host *shost); | |||
| 345 | */ | 331 | */ |
| 346 | extern struct iscsi_cls_session * | 332 | extern struct iscsi_cls_session * |
| 347 | iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, | 333 | iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, |
| 348 | uint16_t, int, int, uint32_t); | 334 | uint16_t, int, uint32_t); |
| 349 | extern void iscsi_session_teardown(struct iscsi_cls_session *); | 335 | extern void iscsi_session_teardown(struct iscsi_cls_session *); |
| 350 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); | 336 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); |
| 351 | extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | 337 | extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, |
| @@ -388,8 +374,7 @@ extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, | |||
| 388 | extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); | 374 | extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); |
| 389 | extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); | 375 | extern struct iscsi_cmd_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); |
| 390 | extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); | 376 | extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); |
| 391 | extern void iscsi_free_mgmt_task(struct iscsi_conn *conn, | 377 | extern void iscsi_put_ctask(struct iscsi_cmd_task *ctask); |
| 392 | struct iscsi_mgmt_task *mtask); | ||
| 393 | 378 | ||
| 394 | /* | 379 | /* |
| 395 | * generic helpers | 380 | * generic helpers |
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 4028f121d548..3f24503dfdf9 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
| @@ -34,7 +34,6 @@ struct Scsi_Host; | |||
| 34 | struct iscsi_cls_conn; | 34 | struct iscsi_cls_conn; |
| 35 | struct iscsi_conn; | 35 | struct iscsi_conn; |
| 36 | struct iscsi_cmd_task; | 36 | struct iscsi_cmd_task; |
| 37 | struct iscsi_mgmt_task; | ||
| 38 | struct sockaddr; | 37 | struct sockaddr; |
| 39 | 38 | ||
| 40 | /** | 39 | /** |
| @@ -58,19 +57,22 @@ struct sockaddr; | |||
| 58 | * @stop_conn: suspend/recover/terminate connection | 57 | * @stop_conn: suspend/recover/terminate connection |
| 59 | * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. | 58 | * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. |
| 60 | * @session_recovery_timedout: notify LLD a block during recovery timed out | 59 | * @session_recovery_timedout: notify LLD a block during recovery timed out |
| 61 | * @init_cmd_task: Initialize a iscsi_cmd_task and any internal structs. | 60 | * @init_task: Initialize a iscsi_task and any internal structs. |
| 62 | * Called from queuecommand with session lock held. | 61 | * When offloading the data path, this is called from |
| 63 | * @init_mgmt_task: Initialize a iscsi_mgmt_task and any internal structs. | 62 | * queuecommand with the session lock, or from the |
| 64 | * Called from iscsi_conn_send_generic with xmitmutex. | 63 | * iscsi_conn_send_pdu context with the session lock. |
| 65 | * @xmit_cmd_task: Requests LLD to transfer cmd task. Returns 0 or the | 64 | * When not offloading the data path, this is called |
| 65 | * from the scsi work queue without the session lock. | ||
| 66 | * @xmit_task Requests LLD to transfer cmd task. Returns 0 or the | ||
| 66 | * the number of bytes transferred on success, and -Exyz | 67 | * the number of bytes transferred on success, and -Exyz |
| 67 | * value on error. | 68 | * value on error. When offloading the data path, this |
| 68 | * @xmit_mgmt_task: Requests LLD to transfer mgmt task. Returns 0 or the | 69 | * is called from queuecommand with the session lock, or |
| 69 | * the number of bytes transferred on success, and -Exyz | 70 | * from the iscsi_conn_send_pdu context with the session |
| 70 | * value on error. | 71 | * lock. When not offloading the data path, this is called |
| 71 | * @cleanup_cmd_task: requests LLD to fail cmd task. Called with xmitmutex | 72 | * from the scsi work queue without the session lock. |
| 72 | * and session->lock after the connection has been | 73 | * @cleanup_task: requests LLD to fail task. Called with session lock |
| 73 | * suspended and terminated during recovery. If called | 74 | * and after the connection has been suspended and |
| 75 | * terminated during recovery. If called | ||
| 74 | * from abort task then connection is not suspended | 76 | * from abort task then connection is not suspended |
| 75 | * or terminated but sk_callback_lock is held | 77 | * or terminated but sk_callback_lock is held |
| 76 | * | 78 | * |
| @@ -110,15 +112,10 @@ struct iscsi_transport { | |||
| 110 | char *data, uint32_t data_size); | 112 | char *data, uint32_t data_size); |
| 111 | void (*get_stats) (struct iscsi_cls_conn *conn, | 113 | void (*get_stats) (struct iscsi_cls_conn *conn, |
| 112 | struct iscsi_stats *stats); | 114 | struct iscsi_stats *stats); |
| 113 | int (*init_cmd_task) (struct iscsi_cmd_task *ctask); | 115 | int (*init_task) (struct iscsi_cmd_task *task); |
| 114 | void (*init_mgmt_task) (struct iscsi_conn *conn, | 116 | int (*xmit_task) (struct iscsi_cmd_task *task); |
| 115 | struct iscsi_mgmt_task *mtask); | 117 | void (*cleanup_task) (struct iscsi_conn *conn, |
| 116 | int (*xmit_cmd_task) (struct iscsi_conn *conn, | 118 | struct iscsi_cmd_task *task); |
| 117 | struct iscsi_cmd_task *ctask); | ||
| 118 | void (*cleanup_cmd_task) (struct iscsi_conn *conn, | ||
| 119 | struct iscsi_cmd_task *ctask); | ||
| 120 | int (*xmit_mgmt_task) (struct iscsi_conn *conn, | ||
| 121 | struct iscsi_mgmt_task *mtask); | ||
| 122 | void (*session_recovery_timedout) (struct iscsi_cls_session *session); | 119 | void (*session_recovery_timedout) (struct iscsi_cls_session *session); |
| 123 | int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking, | 120 | int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking, |
| 124 | uint64_t *ep_handle); | 121 | uint64_t *ep_handle); |
