diff options
Diffstat (limited to 'drivers/scsi/libiscsi.c')
| -rw-r--r-- | drivers/scsi/libiscsi.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 256b87a85978..2673a11a9495 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -513,10 +513,11 @@ EXPORT_SYMBOL_GPL(iscsi_conn_failure); | |||
| 513 | static int iscsi_data_xmit(struct iscsi_conn *conn) | 513 | static int iscsi_data_xmit(struct iscsi_conn *conn) |
| 514 | { | 514 | { |
| 515 | struct iscsi_transport *tt; | 515 | struct iscsi_transport *tt; |
| 516 | int rc = 0; | ||
| 516 | 517 | ||
| 517 | if (unlikely(conn->suspend_tx)) { | 518 | if (unlikely(conn->suspend_tx)) { |
| 518 | debug_scsi("conn %d Tx suspended!\n", conn->id); | 519 | debug_scsi("conn %d Tx suspended!\n", conn->id); |
| 519 | return 0; | 520 | return -ENODATA; |
| 520 | } | 521 | } |
| 521 | tt = conn->session->tt; | 522 | tt = conn->session->tt; |
| 522 | 523 | ||
| @@ -536,13 +537,15 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 536 | BUG_ON(conn->ctask && conn->mtask); | 537 | BUG_ON(conn->ctask && conn->mtask); |
| 537 | 538 | ||
| 538 | if (conn->ctask) { | 539 | if (conn->ctask) { |
| 539 | if (tt->xmit_cmd_task(conn, conn->ctask)) | 540 | rc = tt->xmit_cmd_task(conn, conn->ctask); |
| 541 | if (rc) | ||
| 540 | goto again; | 542 | goto again; |
| 541 | /* done with this in-progress ctask */ | 543 | /* done with this in-progress ctask */ |
| 542 | conn->ctask = NULL; | 544 | conn->ctask = NULL; |
| 543 | } | 545 | } |
| 544 | if (conn->mtask) { | 546 | if (conn->mtask) { |
| 545 | if (tt->xmit_mgmt_task(conn, conn->mtask)) | 547 | rc = tt->xmit_mgmt_task(conn, conn->mtask); |
| 548 | if (rc) | ||
| 546 | goto again; | 549 | goto again; |
| 547 | /* done with this in-progress mtask */ | 550 | /* done with this in-progress mtask */ |
| 548 | conn->mtask = NULL; | 551 | conn->mtask = NULL; |
| @@ -556,7 +559,8 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 556 | list_add_tail(&conn->mtask->running, | 559 | list_add_tail(&conn->mtask->running, |
| 557 | &conn->mgmt_run_list); | 560 | &conn->mgmt_run_list); |
| 558 | spin_unlock_bh(&conn->session->lock); | 561 | spin_unlock_bh(&conn->session->lock); |
| 559 | if (tt->xmit_mgmt_task(conn, conn->mtask)) | 562 | rc = tt->xmit_mgmt_task(conn, conn->mtask); |
| 563 | if (rc) | ||
| 560 | goto again; | 564 | goto again; |
| 561 | } | 565 | } |
| 562 | /* done with this mtask */ | 566 | /* done with this mtask */ |
| @@ -574,7 +578,8 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 574 | if (list_empty(&conn->ctask->running)) | 578 | if (list_empty(&conn->ctask->running)) |
| 575 | list_add_tail(&conn->ctask->running, &conn->run_list); | 579 | list_add_tail(&conn->ctask->running, &conn->run_list); |
| 576 | spin_unlock_bh(&conn->session->lock); | 580 | spin_unlock_bh(&conn->session->lock); |
| 577 | if (tt->xmit_cmd_task(conn, conn->ctask)) | 581 | rc = tt->xmit_cmd_task(conn, conn->ctask); |
| 582 | if (rc) | ||
| 578 | goto again; | 583 | goto again; |
| 579 | } | 584 | } |
| 580 | /* done with this ctask */ | 585 | /* done with this ctask */ |
| @@ -588,32 +593,34 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 588 | list_add_tail(&conn->mtask->running, | 593 | list_add_tail(&conn->mtask->running, |
| 589 | &conn->mgmt_run_list); | 594 | &conn->mgmt_run_list); |
| 590 | spin_unlock_bh(&conn->session->lock); | 595 | spin_unlock_bh(&conn->session->lock); |
| 591 | if (tt->xmit_mgmt_task(conn, conn->mtask)) | 596 | rc = tt->xmit_mgmt_task(conn, conn->mtask); |
| 597 | if (rc) | ||
| 592 | goto again; | 598 | goto again; |
| 593 | } | 599 | } |
| 594 | /* done with this mtask */ | 600 | /* done with this mtask */ |
| 595 | conn->mtask = NULL; | 601 | conn->mtask = NULL; |
| 596 | } | 602 | } |
| 597 | 603 | ||
| 598 | return 0; | 604 | return -ENODATA; |
| 599 | 605 | ||
| 600 | again: | 606 | again: |
| 601 | if (unlikely(conn->suspend_tx)) | 607 | if (unlikely(conn->suspend_tx)) |
| 602 | return 0; | 608 | return -ENODATA; |
| 603 | 609 | ||
| 604 | return -EAGAIN; | 610 | return rc; |
| 605 | } | 611 | } |
| 606 | 612 | ||
| 607 | static void iscsi_xmitworker(void *data) | 613 | static void iscsi_xmitworker(void *data) |
| 608 | { | 614 | { |
| 609 | struct iscsi_conn *conn = data; | 615 | struct iscsi_conn *conn = data; |
| 610 | 616 | int rc; | |
| 611 | /* | 617 | /* |
| 612 | * serialize Xmit worker on a per-connection basis. | 618 | * serialize Xmit worker on a per-connection basis. |
| 613 | */ | 619 | */ |
| 614 | mutex_lock(&conn->xmitmutex); | 620 | mutex_lock(&conn->xmitmutex); |
| 615 | if (iscsi_data_xmit(conn)) | 621 | do { |
| 616 | scsi_queue_work(conn->session->host, &conn->xmitwork); | 622 | rc = iscsi_data_xmit(conn); |
| 623 | } while (rc >= 0 || rc == -EAGAIN); | ||
| 617 | mutex_unlock(&conn->xmitmutex); | 624 | mutex_unlock(&conn->xmitmutex); |
| 618 | } | 625 | } |
| 619 | 626 | ||
