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