svn commit: r214880 - head/sys/dev/ata

Alexander Motin mav at FreeBSD.org
Sat Nov 6 14:22:51 UTC 2010


Author: mav
Date: Sat Nov  6 14:22:50 2010
New Revision: 214880
URL: http://svn.freebsd.org/changeset/base/214880

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

Modified:
  head/sys/dev/ata/ata-lowlevel.c

Modified: head/sys/dev/ata/ata-lowlevel.c
==============================================================================
--- head/sys/dev/ata/ata-lowlevel.c	Sat Nov  6 13:58:24 2010	(r214879)
+++ head/sys/dev/ata/ata-lowlevel.c	Sat Nov  6 14:22:50 2010	(r214880)
@@ -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);
     }


More information about the svn-src-head mailing list