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

Reply via email to