svn commit: r239494 - stable/9/sys/dev/ata
Alexander Motin
mav at FreeBSD.org
Tue Aug 21 11:40:32 UTC 2012
Author: mav
Date: Tue Aug 21 11:40:31 2012
New Revision: 239494
URL: http://svn.freebsd.org/changeset/base/239494
Log:
MFC r238673:
Use 16bit PIO instead of 32bit in case of misaligned buffer.
It fixes kernel panic during CD write with cdrecord on sparc64.
Modified:
stable/9/sys/dev/ata/ata-lowlevel.c
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/sys/dev/ata/ata-lowlevel.c
==============================================================================
--- stable/9/sys/dev/ata/ata-lowlevel.c Tue Aug 21 11:35:54 2012 (r239493)
+++ stable/9/sys/dev/ata/ata-lowlevel.c Tue Aug 21 11:40:31 2012 (r239494)
@@ -836,23 +836,21 @@ static void
ata_pio_read(struct ata_request *request, int length)
{
struct ata_channel *ch = device_get_softc(request->parent);
+ uint8_t *addr;
int size = min(request->transfersize, length);
int resid;
uint8_t buf[2];
- 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));
+ addr = (uint8_t *)request->data + request->donecount;
+ if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)) ||
+ ((uintptr_t)addr % sizeof(int32_t))) {
+ ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)addr, size / sizeof(int16_t));
if (size & 1) {
ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)buf, 1);
- ((uint8_t *)request->data + request->donecount +
- (size & ~1))[0] = buf[0];
+ (addr + (size & ~1))[0] = buf[0];
}
} else
- ATA_IDX_INSL_STRM(ch, ATA_DATA,
- (void*)((uintptr_t)request->data+request->donecount),
- size / sizeof(int32_t));
+ ATA_IDX_INSL_STRM(ch, ATA_DATA, (void*)addr, size / sizeof(int32_t));
if (request->transfersize < length) {
device_printf(request->parent, "WARNING - %s read data overrun %d>%d\n",
@@ -867,23 +865,21 @@ static void
ata_pio_write(struct ata_request *request, int length)
{
struct ata_channel *ch = device_get_softc(request->parent);
+ uint8_t *addr;
int size = min(request->transfersize, length);
int resid;
uint8_t buf[2];
- 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));
+ addr = (uint8_t *)request->data + request->donecount;
+ if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t)) ||
+ ((uintptr_t)addr % sizeof(int32_t))) {
+ ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)addr, size / sizeof(int16_t));
if (size & 1) {
- buf[0] = ((uint8_t *)request->data + request->donecount +
- (size & ~1))[0];
+ buf[0] = (addr + (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));
+ ATA_IDX_OUTSL_STRM(ch, ATA_DATA, (void*)addr, size / sizeof(int32_t));
if (request->transfersize < length) {
device_printf(request->parent, "WARNING - %s write data underrun %d>%d\n",
More information about the svn-src-stable
mailing list