aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmvscsi
diff options
context:
space:
mode:
authorRobert Jennings <rcjenn@us.ibm.com>2007-03-28 13:45:46 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-04-01 11:36:39 -0400
commita897ff2a6386ac4368ba41db18b626afd903f9d8 (patch)
treeb88472fc877f6f85d76fe89d9d92b737e675dc6b /drivers/scsi/ibmvscsi
parenta45c863f02c808107172b4b2975e1130c7da66d6 (diff)
[SCSI] ibmvscsi: allow for dynamic adjustment of server request_limit
The request limit calculations used previously on the client failed to mirror the state of the server. Additionally, when a value < 3 was provided there could be problems setting can_queue and handling abort and reset commands. Signed-off-by: "Robert Jennings" <rcj@linux.vnet.ibm.com> Signed-off-by: Santiago Leon <santil@us.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c58
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.h2
2 files changed, 40 insertions, 20 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index fbc1d5c3b0a7..383f5948ba06 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -85,7 +85,7 @@
85static int max_id = 64; 85static int max_id = 64;
86static int max_channel = 3; 86static int max_channel = 3;
87static int init_timeout = 5; 87static int init_timeout = 5;
88static int max_requests = 50; 88static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT;
89 89
90#define IBMVSCSI_VERSION "1.5.8" 90#define IBMVSCSI_VERSION "1.5.8"
91 91
@@ -538,7 +538,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
538 int request_status; 538 int request_status;
539 int rc; 539 int rc;
540 540
541 /* If we have exhausted our request limit, just fail this request. 541 /* If we have exhausted our request limit, just fail this request,
542 * unless it is for a reset or abort.
542 * Note that there are rare cases involving driver generated requests 543 * Note that there are rare cases involving driver generated requests
543 * (such as task management requests) that the mid layer may think we 544 * (such as task management requests) that the mid layer may think we
544 * can handle more requests (can_queue) when we actually can't 545 * can handle more requests (can_queue) when we actually can't
@@ -551,9 +552,30 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
551 */ 552 */
552 if (request_status < -1) 553 if (request_status < -1)
553 goto send_error; 554 goto send_error;
554 /* Otherwise, if we have run out of requests */ 555 /* Otherwise, we may have run out of requests. */
555 else if (request_status < 0) 556 /* Abort and reset calls should make it through.
556 goto send_busy; 557 * Nothing except abort and reset should use the last two
558 * slots unless we had two or less to begin with.
559 */
560 else if (request_status < 2 &&
561 evt_struct->iu.srp.cmd.opcode != SRP_TSK_MGMT) {
562 /* In the case that we have less than two requests
563 * available, check the server limit as a combination
564 * of the request limit and the number of requests
565 * in-flight (the size of the send list). If the
566 * server limit is greater than 2, return busy so
567 * that the last two are reserved for reset and abort.
568 */
569 int server_limit = request_status;
570 struct srp_event_struct *tmp_evt;
571
572 list_for_each_entry(tmp_evt, &hostdata->sent, list) {
573 server_limit++;
574 }
575
576 if (server_limit > 2)
577 goto send_busy;
578 }
557 } 579 }
558 580
559 /* Copy the IU into the transfer area */ 581 /* Copy the IU into the transfer area */
@@ -572,6 +594,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
572 594
573 printk(KERN_ERR "ibmvscsi: send error %d\n", 595 printk(KERN_ERR "ibmvscsi: send error %d\n",
574 rc); 596 rc);
597 atomic_inc(&hostdata->request_limit);
575 goto send_error; 598 goto send_error;
576 } 599 }
577 600
@@ -581,7 +604,8 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
581 unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); 604 unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
582 605
583 free_event_struct(&hostdata->pool, evt_struct); 606 free_event_struct(&hostdata->pool, evt_struct);
584 return SCSI_MLQUEUE_HOST_BUSY; 607 atomic_inc(&hostdata->request_limit);
608 return SCSI_MLQUEUE_HOST_BUSY;
585 609
586 send_error: 610 send_error:
587 unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); 611 unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev);
@@ -831,23 +855,16 @@ static void login_rsp(struct srp_event_struct *evt_struct)
831 855
832 printk(KERN_INFO "ibmvscsi: SRP_LOGIN succeeded\n"); 856 printk(KERN_INFO "ibmvscsi: SRP_LOGIN succeeded\n");
833 857
834 if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta > 858 if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta < 0)
835 (max_requests - 2)) 859 printk(KERN_ERR "ibmvscsi: Invalid request_limit.\n");
836 evt_struct->xfer_iu->srp.login_rsp.req_lim_delta =
837 max_requests - 2;
838 860
839 /* Now we know what the real request-limit is */ 861 /* Now we know what the real request-limit is.
862 * This value is set rather than added to request_limit because
863 * request_limit could have been set to -1 by this client.
864 */
840 atomic_set(&hostdata->request_limit, 865 atomic_set(&hostdata->request_limit,
841 evt_struct->xfer_iu->srp.login_rsp.req_lim_delta); 866 evt_struct->xfer_iu->srp.login_rsp.req_lim_delta);
842 867
843 hostdata->host->can_queue =
844 evt_struct->xfer_iu->srp.login_rsp.req_lim_delta - 2;
845
846 if (hostdata->host->can_queue < 1) {
847 printk(KERN_ERR "ibmvscsi: Invalid request_limit_delta\n");
848 return;
849 }
850
851 /* If we had any pending I/Os, kick them */ 868 /* If we had any pending I/Os, kick them */
852 scsi_unblock_requests(hostdata->host); 869 scsi_unblock_requests(hostdata->host);
853 870
@@ -1483,7 +1500,7 @@ static struct scsi_host_template driver_template = {
1483 .eh_abort_handler = ibmvscsi_eh_abort_handler, 1500 .eh_abort_handler = ibmvscsi_eh_abort_handler,
1484 .eh_device_reset_handler = ibmvscsi_eh_device_reset_handler, 1501 .eh_device_reset_handler = ibmvscsi_eh_device_reset_handler,
1485 .cmd_per_lun = 16, 1502 .cmd_per_lun = 16,
1486 .can_queue = 1, /* Updated after SRP_LOGIN */ 1503 .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT,
1487 .this_id = -1, 1504 .this_id = -1,
1488 .sg_tablesize = SG_ALL, 1505 .sg_tablesize = SG_ALL,
1489 .use_clustering = ENABLE_CLUSTERING, 1506 .use_clustering = ENABLE_CLUSTERING,
@@ -1503,6 +1520,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1503 1520
1504 vdev->dev.driver_data = NULL; 1521 vdev->dev.driver_data = NULL;
1505 1522
1523 driver_template.can_queue = max_requests;
1506 host = scsi_host_alloc(&driver_template, sizeof(*hostdata)); 1524 host = scsi_host_alloc(&driver_template, sizeof(*hostdata));
1507 if (!host) { 1525 if (!host) {
1508 printk(KERN_ERR "ibmvscsi: couldn't allocate host data\n"); 1526 printk(KERN_ERR "ibmvscsi: couldn't allocate host data\n");
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index 5c6d93582929..77cc1d40f5bb 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -44,6 +44,8 @@ struct Scsi_Host;
44 */ 44 */
45#define MAX_INDIRECT_BUFS 10 45#define MAX_INDIRECT_BUFS 10
46 46
47#define IBMVSCSI_MAX_REQUESTS_DEFAULT 100
48
47/* ------------------------------------------------------------ 49/* ------------------------------------------------------------
48 * Data Structures 50 * Data Structures
49 */ 51 */