How about this? It's mostly the changes in your patch, but it also takes
into account non-int{8,16}_t-sizing/alignment. It also takes care of the
truncation problem when you use outsl and insl, as part of that. Please
review it, as I think it should be the right thing to do.
--
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.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 23:37:27
@@ -552,23 +552,39 @@
*buffer = (int8_t *)&request->sense;
if (request->bytecount < length) {
- printf("%s: read data overrun %d/%d\n",
+ printf("%s: read data buffer too small (bs %d > buflen %d)\n",
request->device->devname, length, request->bytecount);
#ifdef ATA_16BIT_ONLY
insw(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+ (void *)*buffer, request->bytecount / sizeof(int16_t));
#else
insl(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int32_t));
+ (void *)*buffer, request->bytecount / sizeof(int32_t));
+ if (request->bytecount & sizeof(int16_t)) {
+ *(int16_t *)(*buffer + request->bytecount -
+ (sizeof(int16_t) + (request->bytecount & sizeof(int8_t)))) =
+ inw(request->device->controller->ioaddr + ATA_DATA);
+ length -= sizeof(int16_t);
+ }
#endif
- for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
- inw(request->device->controller->ioaddr + ATA_DATA);
+ if (request->bytecount & sizeof(int8_t)) {
+ (*buffer)[request->bytecount - sizeof(int8_t)] =
+ inb(request->device->controller->ioaddr + ATA_DATA);
+ (void)inb(request->device->controller->ioaddr + ATA_DATA);
+ length -= sizeof(int8_t);
+ }
+ resid = request->bytecount & ~(sizeof(int16_t) | sizeof(int8_t));
+ for (; resid < length; resid += sizeof(int16_t))
+ (void)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;
+ (void *)*buffer, length / sizeof(int16_t));
+ *buffer += length;
+ request->bytecount -= length;
+ }
}
static void
@@ -581,23 +597,38 @@
*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 (buflen %d < bs %d), padding written\n",
+ request->device->devname, request->bytecount, length);
#ifdef ATA_16BIT_ONLY
outsw(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / sizeof(int16_t));
+ (void *)*buffer, request->bytecount / sizeof(int16_t));
#else
outsl(request->device->controller->ioaddr + ATA_DATA,
- (void *)((uintptr_t)*buffer), length / 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(int16_t) + (request->bytecount & sizeof(int8_t)))));
+ length -= sizeof(int16_t);
+ }
#endif
- for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
+ if (request->bytecount & sizeof(int8_t)) {
+ outb(request->device->controller->ioaddr + ATA_DATA,
+ (*buffer)[request->bytecount]);
+ length -= sizeof(int8_t);
+ }
+ resid = request->bytecount & ~(sizeof(int16_t) | sizeof(int8_t));
+ for (; 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;
+ (void *)*buffer, length / sizeof(int16_t));
+ *buffer += length;
+ request->bytecount -= length;
+ }
}
static void
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message