On Thu, 6 Jan 2000, Soren Schmidt wrote:
> You should respect the blocksize when talking to a device with a
> fixed blocklength, dont write ! % blocksize blocks to the device..
>
By the way, I think I've redone this enough times that it's all correct.
It's 32-bit support _outside_ of the overrun/underrun loops in atapi-all,
a bugfix for atapi-cd, and the full support for weird overrun/underrun
sizes. The drive is still not working, but I know this has nothing to
do with it. Think you might use this at all? I think it's important
for stability if the driver handles overruns and underruns well, and
this makes everything full-block-size-sized.
> -Søren
--
Brian Fundakowski Feldman \ FreeBSD: The Power to Serve! /
[EMAIL PROTECTED] `------------------------------'
Index: atapi-all.c
===================================================================
RCS file: /usr2/ncvs/src/sys/dev/ata/atapi-all.c,v
retrieving revision 1.33
diff -u -r1.33 atapi-all.c
--- atapi-all.c 2000/01/07 15:51:45 1.33
+++ atapi-all.c 2000/01/08 23:50:08
@@ -558,23 +558,44 @@
*buffer = (int8_t *)&request->sense;
if (request->bytecount < length) {
- printf("%s: read data overrun %d/%d\n",
- request->device->devname, length, request->bytecount);
+ printf("%s: read data overrun (%d buffer < %d bs), some data ignored\n",
+ request->device->devname, request->bytecount, length);
#ifdef ATA_16BIT_ONLY
insw(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), request->bytecount/sizeof(int16_t));
+ (void *)*buffer, request->bytecount / sizeof(int16_t));
#else
insl(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), request->bytecount/sizeof(int32_t));
+ (void *)*buffer, request->bytecount / sizeof(int32_t));
+ if (request->bytecount & sizeof(int16_t))
+ ((int16_t *)*buffer)[(request->bytecount % sizeof(int32_t)) /
+ sizeof(int16_t)] =
+ inw(request->device->controller->ioaddr + ATA_DATA);
#endif
+ if (request->bytecount & sizeof(int8_t)) {
+ int16_t sixteen;
+
+ sixteen = inw(request->device->controller->ioaddr + ATA_DATA);
+ (*buffer)[request->bytecount - sizeof(int8_t)] =
+ *(int8_t *)&sixteen;
+ length -= sizeof(int16_t);
+ }
for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
- inw(request->device->controller->ioaddr + ATA_DATA);
+ (void)inw(request->device->controller->ioaddr + ATA_DATA);
*buffer += request->bytecount;
request->bytecount = 0;
}
else {
+#ifdef ATA_16BIT_ONLY
insw(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+ (void *)*buffer, length / sizeof(int16_t));
+#else
+ insl(request->device->controller->ioaddr + ATA_DATA,
+ (void *)*buffer, length / sizeof(int32_t));
+ if (length & sizeof(int16_t))
+ ((int16_t *)*buffer)[(length - (length % sizeof(int32_t))) /
+ sizeof(int16_t)] =
+ inw(request->device->controller->ioaddr + ATA_DATA);
+#endif
*buffer += length;
request->bytecount -= length;
}
@@ -590,24 +611,46 @@
*buffer = (int8_t *)&request->sense;
if (request->bytecount < length) {
- printf("%s: write data underrun %d/%d\n",
- request->device->devname, length, request->bytecount);
+ printf("%s: write data underrun (%d buffer < %d bs), padding\n",
+ request->device->devname, request->bytecount, length);
#ifdef ATA_16BIT_ONLY
outsw(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), request->bytecount/sizeof(int16_t));
+ (void *)*buffer, request->bytecount / sizeof(int16_t));
#else
outsl(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), request->bytecount/sizeof(int32_t));
+ (void *)*buffer, request->bytecount / sizeof(int32_t));
+ if (request->bytecount & sizeof(int16_t))
+ outw(request->device->controller->ioaddr + ATA_DATA,
+ ((int16_t *)*buffer)[(request->bytecount % sizeof(int32_t)) /
+ sizeof(int16_t)]);
#endif
+ if (request->bytecount & sizeof(int8_t)) {
+ int16_t sixteen;
+
+ sixteen = 0;
+ *(int8_t *)&sixteen =
+ (*buffer)[request->bytecount - sizeof(int8_t)];
+ outw(request->device->controller->ioaddr + ATA_DATA, sixteen);
+ length -= sizeof(int16_t);
+ }
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 {
- outsw(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
- *buffer += length;
+#ifdef ATA_16BIT_ONLY
+ outsw(request->device->controller->ioaddr + ATA_DATA,
+ (void *)*buffer, length / sizeof(int16_t));
+#else
+ outsl(request->device->controller->ioaddr + ATA_DATA,
+ (void *)*buffer, length / sizeof(int32_t));
+ if (length & sizeof(int16_t))
+ outw(request->device->controller->ioaddr + ATA_DATA,
+ ((int16_t *)*buffer)[(length - (length % sizeof(int32_t))) /
+ sizeof(int16_t)]);
+#endif
+ *buffer += length;
request->bytecount -= length;
}
}
Index: atapi-cd.c
===================================================================
RCS file: /usr2/ncvs/src/sys/dev/ata/atapi-cd.c,v
retrieving revision 1.33
diff -u -r1.33 atapi-cd.c
--- atapi-cd.c 2000/01/07 12:01:00 1.33
+++ atapi-cd.c 2000/01/08 18:50:42
@@ -966,9 +966,12 @@
break;
case CDRIOCCLOSEDISK:
- if (!(cdp->flags & F_WRITTEN) || !(cdp->flags & F_DISK_OPEN)) {
+ if (!(cdp->flags & F_DISK_OPEN)) {
error = EINVAL;
printf("acd%d: sequence error (nothing to close)\n", cdp->lun);
+ }
+ else if (!(cdp->flags & F_WRITTEN)) {
+ cdp->flags &= ~(F_DISK_OPEN | F_TRACK_OPEN);
}
else {
error = acd_close_disk(cdp);
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message