Date: Wed, 5 Jan 2000 09:35:11 +0100 (CET) From: Soren Schmidt <sos@freebsd.dk> To: green@FreeBSD.ORG (Brian Fundakowski Feldman) Cc: current@FreeBSD.ORG Subject: Re: ATA atapi-all.c problems/fixes/cleanups Message-ID: <200001050835.JAA35344@freebsd.dk> In-Reply-To: <Pine.BSF.4.10.10001041832080.15790-100000@green.dyndns.org> from Brian Fundakowski Feldman at "Jan 4, 2000 06:36:44 pm"
next in thread | previous in thread | raw e-mail | index | archive | help
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 majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200001050835.JAA35344>