From: "Eric Youngdale" <[EMAIL PROTECTED]>

        Sigh.  It sounds like some of the queueing code doesn't have sanity
    checking.  I guess I will have to dust off the 1542 in my test machine and
    see if I can reproduce it.  I am hoping that this won't be *too* hard to
    reproduce and find.

Also on one of my machines I get a panic with aha1542 after
upgrading (downgrading?) to linux-2.3.99pre3.

At first sight it looks like all checks in scsi_merge
are combined in the wrong way - like
        if (sth > max1 && sth_else > max2) error;
with && where I would expect ||.

Without investigating any further I made the patch below,
and after applying it the panic was gone.

[Don't apply it blindly - I wrote it without any attempt
to understand the code.]

Andries

----------------------------------------------------------
--- /g1/linux/linux-2.3.99p3/linux/drivers/scsi/scsi_merge.c    Fri Mar 17 18:17:26 
2000
+++ scsi_merge.c        Sun Apr  9 16:01:47 2000
@@ -282,7 +282,7 @@
  *             This can come up if you get a MEDIUM_ERROR, for example,
  *             as we will have "completed" all of the sectors up to and
  *             including the bad sector, and the leftover bit is what
- *             we have to do now.  This tends to be a rare occurence, so
+ *             we have to do now.  This tends to be a rare occurrence, so
  *             we aren't busting our butts to instantiate separate versions
  *             of this function for the 4 different flag values.  We
  *             probably should, however.
@@ -320,7 +320,7 @@
         * scsi.c allocates for this purpose
         * min(64,sg_tablesize) entries.
         */
-       if (req->nr_segments >= max_segments &&
+       if (req->nr_segments >= max_segments ||
            req->nr_segments >= SHpnt->sg_tablesize)
                return 0;
        req->nr_segments++;
@@ -339,7 +339,7 @@
         * check if things fit into sg_tablesize.
         */
        if (req->nr_hw_segments >= SHpnt->sg_tablesize ||
-           (req->nr_segments >= max_segments &&
+           (req->nr_segments >= max_segments ||
             req->nr_segments >= SHpnt->sg_tablesize))
                return 0;
        if (req->nr_segments >= max_segments)
@@ -609,7 +609,7 @@
        /* If it would not fit into prepared memory space for sg chain,
         * then don't allow the merge.
         */
-       if (req->nr_segments + next->nr_segments - 1 > max_segments &&
+       if (req->nr_segments + next->nr_segments - 1 > max_segments ||
            req->nr_segments + next->nr_segments - 1 > SHpnt->sg_tablesize) {
                return 0;
        }
@@ -674,7 +674,7 @@
        }
       dont_combine:
 #ifdef DMA_CHUNK_SIZE
-       if (req->nr_segments + next->nr_segments > max_segments &&
+       if (req->nr_segments + next->nr_segments > max_segments ||
            req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) {
                return 0;
        }
@@ -697,7 +697,7 @@
         * Make sure we can fix something that is the sum of the two.
         * A slightly stricter test than we had above.
         */
-       if (req->nr_segments + next->nr_segments > max_segments &&
+       if (req->nr_segments + next->nr_segments > max_segments ||
            req->nr_segments + next->nr_segments > SHpnt->sg_tablesize) {
                return 0;
        } else {

-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]

Reply via email to