[EMAIL PROTECTED] wrote:
> 
> Hi Eric,
> 
> thanks for your quick reply...
> 
> You're right: I failed to mention that I use the Adaptec 2940 (aic7xxx)
> driver. Sorry! Probably he's resetting the TCQ queue depth...
> 
> Is anybody using a different SCSI-driver (**NOT** aic7xxx) experiencing
> this, too? All machines I have access to have Adaptec (aic7xxx)
> controllers...
> 
Michael,
There is a bug in scsi_build_commandblocks() that could be related.
During add-single-device it gets called _before_ the low level driver
has been asked to calculate the queue_depth of the device so it has its
initialization value of 0. In that situation scsi_build_commandblocks()
uses the "cpl" variable (commands per lun) which is often 1 and in one
case that bites me, 0 (advansys). A queue length of 0 is useless
(hangs on any attempt to use the device) and a queue length of 1
doesn't permit any tagged queuing.

Could you try the attached (it is against 2.3.99-pre3 and will
probably work against pre2 even though scsi.c was changed) and
report back if it cures your problem.

Looking at the aic7xxx source it sets cpl to 3. Perhaps you could
also try a little program to call the SCSI_IOCTL_TAGGED_ENABLE
ioctl() supplied by the midlevel. Something like:

    fd = open("/dev/sda", O_RDWR);
    ioctl(fd, SCSI_IOCTL_TAGGED_ENABLE, &any_int);
    close(fd);

and see if that helps.


Doug Gilbert
--- linux/drivers/scsi/scsi.c   Fri Mar 24 09:20:43 2000
+++ linux/drivers/scsi/scsi.c_asd       Fri Mar 24 10:17:49 2000
@@ -1413,7 +1413,11 @@
        spin_lock_irqsave(&device_request_lock, flags);
 
        if (SDpnt->queue_depth == 0)
+       {
                SDpnt->queue_depth = host->cmd_per_lun;
+               if (SDpnt->queue_depth == 0)
+                       SDpnt->queue_depth = 1; /* live to fight another day */
+       }
        SDpnt->device_queue = NULL;
 
        for (j = 0; j < SDpnt->queue_depth; j++) {
@@ -1804,8 +1808,9 @@
                /* FIXME (DB) This assumes that the queue_depth routines can be used
                   in this context as well, while they were all designed to be
                   called only once after the detect routine. (DB) */
-               if (HBA_ptr->select_queue_depths != NULL)
-                       (HBA_ptr->select_queue_depths) (HBA_ptr, HBA_ptr->host_queue);
+
+               /* queue_depth routine moved to inside scan_scsis(,1,,,) so
+                  it is called before build_commandblocks() */
 
                err = length;
                goto out;
--- linux/drivers/scsi/scsi_scan.c      Fri Mar 24 10:32:30 2000
+++ linux/drivers/scsi/scsi_scan.c_asd  Fri Mar 24 10:10:23 2000
@@ -347,6 +347,12 @@
                if (SDpnt != oldSDpnt) {
 
                        /* it could happen the blockdevice hasn't yet been inited */
+                       /* queue_depth() moved from scsi_proc_info() so that
+                          it is called before scsi_build_commandblocks() */
+                       if (shpnt->select_queue_depths != NULL)
+                           (shpnt->select_queue_depths)(shpnt,
+                                                        shpnt->host_queue);
+
                        for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
                                if (sdtpnt->init && sdtpnt->dev_noticed)
                                        (*sdtpnt->init) ();

Reply via email to