Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Jan 2000 04:21:47 -0500 (EST)
From:      Brian Fundakowski Feldman <green@FreeBSD.org>
To:        Soren Schmidt <sos@freebsd.dk>
Cc:        current@FreeBSD.ORG
Subject:   Re: ATA atapi-all.c problems/fixes/cleanups
Message-ID:  <Pine.BSF.4.10.10001090418110.16693-100000@green.dyndns.org>
In-Reply-To: <200001060904.KAA90935@freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help
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!  /
 green@FreeBSD.org                    `------------------------------'


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 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?Pine.BSF.4.10.10001090418110.16693-100000>