svn commit: r215769 - stable/8/sys/dev/ata
Alexander Motin
mav at FreeBSD.org
Tue Nov 23 21:20:27 UTC 2010
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);
}
More information about the svn-src-all
mailing list