[SCSI] aacraid: Changeable queue depth
authorSalyzyn, Mark <mark_salyzyn@adaptec.com>
Wed, 30 May 2007 14:01:14 +0000 (10:01 -0400)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Fri, 1 Jun 2007 15:39:56 +0000 (11:39 -0400)
Inspired by Brian King's patch to the ibmvscsi driver. Adds support for
a changeable queue depth to the aacraid driver.

Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/aacraid/linit.c

index a270a3f006479f9b5d67ee92d564c4941feee548..6f92d077679f26eb27bfbd44bde62bc63aacf721 100644 (file)
@@ -446,6 +446,43 @@ static int aac_slave_configure(struct scsi_device *sdev)
        return 0;
 }
 
+/**
+ *     aac_change_queue_depth          -       alter queue depths
+ *     @sdev:  SCSI device we are considering
+ *     @depth: desired queue depth
+ *
+ *     Alters queue depths for target device based on the host adapter's
+ *     total capacity and the queue depth supported by the target device.
+ */
+
+static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
+{
+       if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
+           (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
+               struct scsi_device * dev;
+               struct Scsi_Host *host = sdev->host;
+               unsigned num = 0;
+
+               __shost_for_each_device(dev, host) {
+                       if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
+                           (sdev_channel(dev) == CONTAINER_CHANNEL))
+                               ++num;
+                       ++num;
+               }
+               if (num >= host->can_queue)
+                       num = host->can_queue - 1;
+               if (depth > (host->can_queue - num))
+                       depth = host->can_queue - num;
+               if (depth > 256)
+                       depth = 256;
+               else if (depth < 2)
+                       depth = 2;
+               scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
+       } else
+               scsi_adjust_queue_depth(sdev, 0, 1);
+       return sdev->queue_depth;
+}
+
 static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg)
 {
        struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
@@ -844,6 +881,7 @@ static struct scsi_host_template aac_driver_template = {
        .bios_param                     = aac_biosparm, 
        .shost_attrs                    = aac_attrs,
        .slave_configure                = aac_slave_configure,
+       .change_queue_depth             = aac_change_queue_depth,
        .eh_abort_handler               = aac_eh_abort,
        .eh_host_reset_handler          = aac_eh_reset,
        .can_queue                      = AAC_NUM_IO_FIB,