Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Aug 2012 11:40:32 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r239494 - stable/9/sys/dev/ata
Message-ID:  <201208211140.q7LBeWIP027703@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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",



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208211140.q7LBeWIP027703>