Author: mav
Date: Tue Nov 23 21:20:27 2010
New Revision: 215769
URL: http://svn.freebsd.org/changeset/base/215769

Log:
  MFC r214880:
  Add support for odd-sized PIO transfers, sometimes used by ATAPI.

Modified:
  stable/8/sys/dev/ata/ata-lowlevel.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/dev/ata/ata-lowlevel.c
==============================================================================
--- stable/8/sys/dev/ata/ata-lowlevel.c Tue Nov 23 21:09:42 2010        
(r215768)
+++ stable/8/sys/dev/ata/ata-lowlevel.c Tue Nov 23 21:20:27 2010        
(r215769)
@@ -833,12 +833,18 @@ ata_pio_read(struct ata_request *request
     struct ata_channel *ch = device_get_softc(request->parent);
     int size = min(request->transfersize, length);
     int resid;
+    uint8_t buf[2];
 
-    if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)))
+    if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) {
        ATA_IDX_INSW_STRM(ch, ATA_DATA,
                          (void*)((uintptr_t)request->data+request->donecount),
                          size / sizeof(int16_t));
-    else
+       if (size & 1) {
+           ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)buf, 1);
+           ((uint8_t *)request->data + request->donecount +
+               (size & ~1))[0] = buf[0];
+       }
+    } else
        ATA_IDX_INSL_STRM(ch, ATA_DATA,
                          (void*)((uintptr_t)request->data+request->donecount),
                          size / sizeof(int32_t));
@@ -846,7 +852,7 @@ ata_pio_read(struct ata_request *request
     if (request->transfersize < length) {
        device_printf(request->parent, "WARNING - %s read data overrun %d>%d\n",
                   ata_cmd2str(request), length, request->transfersize);
-       for (resid = request->transfersize; resid < length;
+       for (resid = request->transfersize + (size & 1); resid < length;
             resid += sizeof(int16_t))
            ATA_IDX_INW(ch, ATA_DATA);
     }
@@ -858,12 +864,18 @@ ata_pio_write(struct ata_request *reques
     struct ata_channel *ch = device_get_softc(request->parent);
     int size = min(request->transfersize, length);
     int resid;
+    uint8_t buf[2];
 
-    if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)))
+    if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) {
        ATA_IDX_OUTSW_STRM(ch, ATA_DATA,
                           (void*)((uintptr_t)request->data+request->donecount),
                           size / sizeof(int16_t));
-    else
+       if (size & 1) {
+           buf[0] = ((uint8_t *)request->data + request->donecount +
+               (size & ~1))[0];
+           ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)buf, 1);
+       }
+    } else
        ATA_IDX_OUTSL_STRM(ch, ATA_DATA,
                           (void*)((uintptr_t)request->data+request->donecount),
                           size / sizeof(int32_t));
@@ -871,7 +883,7 @@ ata_pio_write(struct ata_request *reques
     if (request->transfersize < length) {
        device_printf(request->parent, "WARNING - %s write data underrun 
%d>%d\n",
                   ata_cmd2str(request), length, request->transfersize);
-       for (resid = request->transfersize; resid < length;
+       for (resid = request->transfersize + (size & 1); resid < length;
             resid += sizeof(int16_t))
            ATA_IDX_OUTW(ch, ATA_DATA, 0);
     }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to