From owner-freebsd-current Wed Jan 5 15:51:56 2000 Delivered-To: freebsd-current@freebsd.org Received: from 1Cust140.tnt1.washington.dc.da.uu.net (localhost [127.0.0.1]) by hub.freebsd.org (Postfix) with ESMTP id A677F151F4; Wed, 5 Jan 2000 15:51:49 -0800 (PST) (envelope-from green@FreeBSD.org) Date: Wed, 5 Jan 2000 18:50:45 -0500 (EST) From: Brian Fundakowski Feldman X-Sender: green@green.dyndns.org To: Soren Schmidt Cc: current@FreeBSD.ORG Subject: Re: ATA atapi-all.c problems/fixes/cleanups In-Reply-To: <200001050835.JAA35344@freebsd.dk> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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! / green@FreeBSD.org `------------------------------' 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; residdevice->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; residbytecount & 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 majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message