]> git.hungrycats.org Git - linux/commitdiff
[PATCH] tcq fixes for the issue on linux-kernel
authorDoug Ledford <dledford@redhat.com>
Fri, 11 Oct 2002 07:01:28 +0000 (00:01 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Fri, 11 Oct 2002 07:01:28 +0000 (00:01 -0700)
This does 4 things.  Fixes the oversight James found about cmd_per_lun.
Makes scsi_adjust_queue_depth() implement the usage of tagged that I
described in my email to linux-scsi.  Updates some comments to highlight
things that are going to go away shortly.  Removes the call to
host->select_queue_depths() entirely since drivers that implement this
will try to set SDptr->queue_depth to the desired depth, which in reality
will do nothing but confuse the mid layer since that is now the actual
allocated command counter, so it won't make the mid layer allocate more
commands, it will make the mid layer think more commands have been
allocated.

drivers/scsi/scsi.c
drivers/scsi/scsi.h
drivers/scsi/scsi_ioctl.c
drivers/scsi/scsi_scan.c

index 524fbbc3ad0a8090046b9002a67927a0b0b3f2ca..61c5c407b53144b1600774799408ba8aaa88b047 100644 (file)
@@ -1624,11 +1624,40 @@ void scsi_adjust_queue_depth(Scsi_Device *SDpnt, int tagged, int tags)
        /*
         * refuse to set tagged depth to an unworkable size
         */
-       if(tags == 0)
+       if(tags <= 0)
                return;
+       /*
+        * Limit max queue depth on a single lun to 256 for now.  Remember,
+        * we allocate a struct scsi_command for each of these and keep it
+        * around forever.  Too deep of a depth just wastes memory.
+        */
+       if(tags > 256)
+               return;
+
        spin_lock_irqsave(&device_request_lock, flags);
        SDpnt->new_queue_depth = tags;
-       SDpnt->tagged_queue = tagged;
+       switch(tagged) {
+               case MSG_ORDERED_TAG:
+                       SDpnt->ordered_tags = 1;
+                       SDpnt->simple_tags = 1;
+                       break;
+               case MSG_SIMPLE_TAG:
+                       SDpnt->ordered_tags = 0;
+                       SDpnt->simple_tags = 1;
+                       break;
+               default:
+                       printk(KERN_WARNING "(scsi%d:%d:%d:%d) "
+                               "scsi_adjust_queue_depth, bad queue type, "
+                               "disabled\n", SDpnt->host->host_no,
+                               SDpnt->channel, SDpnt->id, SDpnt->lun, tagged); 
+               case 0:
+                       SDpnt->ordered_tags = SDpnt->simple_tags = 0;
+                       if(SDpnt->host->cmd_per_lun)
+                               SDpnt->new_queue_depth = SDpnt->host->cmd_per_lun;
+                       else
+                               SDpnt->new_queue_depth = 1;
+                       break;
+       }
        spin_unlock_irqrestore(&device_request_lock, flags);
        if(SDpnt->queue_depth == 0)
        {
index cee04225732d289e936c2e7c5c17bf950695cb0d..128b1e5e73357825ddef211177b2a25cb8744e6d 100644 (file)
@@ -605,9 +605,10 @@ struct scsi_device {
        unsigned wdtr:1;        /* Device supports WDTR messages */
        unsigned ppr:1;         /* Device supports PPR messages */
        unsigned tagged_supported:1;    /* Supports SCSI-II tagged queuing */
-       unsigned tagged_queue:1;        /* SCSI-II tagged queuing enabled */
-       unsigned simple_tags:1; /* Device supports simple queue tag messages */
-       unsigned ordered_tags:1;/* Device supports ordered queue tag messages */
+       unsigned tagged_queue:1;/* This is going away!!!!  Look at simple_tags
+                                  instead!!!  Please fix your driver now!! */
+       unsigned simple_tags:1; /* simple queue tag messages are enabled */
+       unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
        unsigned single_lun:1;  /* Indicates we should only allow I/O to
                                 * one of the luns for the device at a 
                                 * time. */
index 40ba88d6f0e094e28b281868879dd6a429e79de9..80f23e46a9e4ff8005a73fee12c0848deb1a7276 100644 (file)
@@ -424,6 +424,14 @@ int scsi_ioctl(Scsi_Device * dev, int cmd, void *arg)
                return 0;
        case SCSI_IOCTL_GET_BUS_NUMBER:
                return put_user(dev->host->host_no, (int *) arg);
+       /*
+        * The next two ioctls either need to go or need to be changed to
+        * pass tagged queueing changes through the low level drivers.
+        * Simply enabling or disabling tagged queueing without the knowledge
+        * of the low level driver is a *BAD* thing.
+        *
+        * Oct. 10, 2002 - Doug Ledford <dledford@redhat.com>
+        */
        case SCSI_IOCTL_TAGGED_ENABLE:
                if (!capable(CAP_SYS_ADMIN))
                        return -EACCES;
index 6f01e8029adf485fcb39743f5427e5116bf9eb1d..0f52ed55b2102ca8a5c7db7b2c3770e556b34084 100644 (file)
@@ -1477,11 +1477,14 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
                if (sdt->detect)
                        sdev->attached += (*sdt->detect) (sdev);
 
-       if (sdev->host->hostt->slave_attach != NULL)
+       if (sdev->host->hostt->slave_attach != NULL) {
                if (sdev->host->hostt->slave_attach(sdev) != 0) {
-                       printk(KERN_INFO "scsi_add_lun: failed low level driver attach, setting device offline");
+                       printk(KERN_INFO "%s: scsi_add_lun: failed low level driver attach, setting device offline", devname);
                        sdev->online = FALSE;
                }
+       } else if(sdev->host->cmd_per_lun) {
+               scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
+       }
 
        if (sdevnew != NULL)
                *sdevnew = sdev;
@@ -2017,21 +2020,6 @@ static void scsi_scan_selected_lun(struct Scsi_Host *shost, uint channel,
        scsi_free_sdev(sdevscan);
        if (res == SCSI_SCAN_LUN_PRESENT) {
                BUG_ON(sdev == NULL);
-               /*
-                * FIXME calling select_queue_depths is wrong for adapters
-                * that modify queue depths of all scsi devices - the
-                * adapter might change a queue depth (not for this sdev),
-                * but the mid-layer will not change the queue depth. This
-                * does not cause an oops, but queue_depth will not match
-                * the actual queue depth used.
-                *
-                * Perhaps use a default queue depth, and allow them to be
-                * modified at boot/insmod time, and/or via sysctl/ioctl/proc;
-                * plus have dynamic queue depth adjustment like the
-                * aic7xxx driver.
-                */
-               if (shost->select_queue_depths != NULL)
-                       (shost->select_queue_depths) (shost, shost->host_queue);
 
                for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
                        if (sdt->init && sdt->dev_noticed)