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 [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to