Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Jan 2000 09:35:11 +0100 (CET)
From:      Soren Schmidt <sos@freebsd.dk>
To:        green@FreeBSD.ORG (Brian Fundakowski Feldman)
Cc:        current@FreeBSD.ORG
Subject:   Re: ATA atapi-all.c problems/fixes/cleanups
Message-ID:  <200001050835.JAA35344@freebsd.dk>
In-Reply-To: <Pine.BSF.4.10.10001041832080.15790-100000@green.dyndns.org> from Brian Fundakowski Feldman at "Jan 4, 2000 06:36:44 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
It seems Brian Fundakowski Feldman wrote:
> 
> I used a multiple of the blocksize, and it works fine, except for on
> the very last bit of data.  The very last bit of data is what causes
> an underrun, and the code that's there for overrun/underrun is
> wrong right now.  For underrun, it ends up writing the underlying
> blocksize length from the user buffer of _less_than_that_size_, then
> it writes (blocksize - user buffer size) _more_ zeroed data!  This
> promptly locks up the IDE bus with my CD-R.  That's what the patch was
> about and you didn't say anything about; yes, I know that blocksizes
> should be matched perfectly and padded perfectly to prevent the ATA
> driver from having to handle the underrun/overrun cases, but the
> current handling is/was still broken.

Try this patch instead, it should do the right thing..

Index: atapi-all.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/atapi-all.c,v
retrieving revision 1.29
diff -u -r1.29 atapi-all.c
--- atapi-all.c 2000/01/03 10:26:56     1.29
+++ atapi-all.c 2000/01/05 08:36:49
@@ -563,12 +563,15 @@
 #endif
        for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
             inw(request->device->controller->ioaddr + ATA_DATA);
+       *buffer += request->bytecount;
+       request->bytecount = 0;
     }                  
-    else
+    else {
        insw(request->device->controller->ioaddr + ATA_DATA,
             (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
-    request->bytecount -= length;
-    *buffer += length;
+       *buffer += length;
+       request->bytecount -= length;
+    }
 }
 
 static void
@@ -585,19 +588,22 @@
               request->device->devname, length, request->bytecount);
 #ifdef ATA_16BIT_ONLY
        outsw(request->device->controller->ioaddr + ATA_DATA, 
-             (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+             (void *)((uintptr_t)*buffer), request->bytecount/sizeof(int16_t));
 #else
        outsl(request->device->controller->ioaddr + ATA_DATA, 
-             (void *)((uintptr_t)*buffer), length / sizeof(int32_t));
+             (void *)((uintptr_t)*buffer), request->bytecount/sizeof(int32_t));
 #endif
        for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
             outw(request->device->controller->ioaddr + ATA_DATA, 0);
+        *buffer += request->bytecount;
+       request->bytecount = 0;
     }
-    else
+    else {
        outsw(request->device->controller->ioaddr + ATA_DATA, 
              (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
-    request->bytecount -= length;
-    *buffer += length;
+        *buffer += length;
+       request->bytecount -= length;
+    }
 }
 
 static void 

-Søren


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200001050835.JAA35344>