From owner-svn-src-stable@FreeBSD.ORG Sat Mar 2 17:32:21 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 32594B9A; Sat, 2 Mar 2013 17:32:21 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 15ED2937; Sat, 2 Mar 2013 17:32:21 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r22HWKSU076905; Sat, 2 Mar 2013 17:32:20 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r22HWKa6076903; Sat, 2 Mar 2013 17:32:20 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201303021732.r22HWKa6076903@svn.freebsd.org> From: Marius Strobl Date: Sat, 2 Mar 2013 17:32:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r247653 - stable/8/sys/dev/ata X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Mar 2013 17:32:21 -0000 Author: marius Date: Sat Mar 2 17:32:20 2013 New Revision: 247653 URL: http://svnweb.freebsd.org/changeset/base/247653 Log: MFC: r246257 Improve r238673 (MFC'ed to stable/8 in r239495) to additionally allow for odd-aligned buffers as passed in by smartd of smartmontools. While at it, hint the compiler that 32-bit PIO is the most likely case (idea from Linux) and use bus_{read,write}_stream_2(9) instead of bus_{read,write}_multi_stream_2(9) for single count reads/writes. Modified: stable/8/sys/dev/ata/ata-all.h stable/8/sys/dev/ata/ata-lowlevel.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/dev/ (props changed) stable/8/sys/dev/ata/ (props changed) Modified: stable/8/sys/dev/ata/ata-all.h ============================================================================== --- stable/8/sys/dev/ata/ata-all.h Sat Mar 2 17:32:15 2013 (r247652) +++ stable/8/sys/dev/ata/ata-all.h Sat Mar 2 17:32:20 2013 (r247653) @@ -698,6 +698,8 @@ MALLOC_DECLARE(M_ATA); #define ATA_INW(res, offset) \ bus_read_2((res), (offset)) +#define ATA_INW_STRM(res, offset) \ + bus_read_stream_2((res), (offset)) #define ATA_INL(res, offset) \ bus_read_4((res), (offset)) #define ATA_INSW(res, offset, addr, count) \ @@ -712,6 +714,8 @@ MALLOC_DECLARE(M_ATA); bus_write_1((res), (offset), (value)) #define ATA_OUTW(res, offset, value) \ bus_write_2((res), (offset), (value)) +#define ATA_OUTW_STRM(res, offset, value) \ + bus_write_stream_2((res), (offset), (value)) #define ATA_OUTL(res, offset, value) \ bus_write_4((res), (offset), (value)) #define ATA_OUTSW(res, offset, addr, count) \ @@ -729,6 +733,9 @@ MALLOC_DECLARE(M_ATA); #define ATA_IDX_INW(ch, idx) \ ATA_INW(ch->r_io[idx].res, ch->r_io[idx].offset) +#define ATA_IDX_INW_STRM(ch, idx) \ + ATA_INW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset) + #define ATA_IDX_INL(ch, idx) \ ATA_INL(ch->r_io[idx].res, ch->r_io[idx].offset) @@ -750,6 +757,9 @@ MALLOC_DECLARE(M_ATA); #define ATA_IDX_OUTW(ch, idx, value) \ ATA_OUTW(ch->r_io[idx].res, ch->r_io[idx].offset, value) +#define ATA_IDX_OUTW_STRM(ch, idx, value) \ + ATA_OUTW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, value) + #define ATA_IDX_OUTL(ch, idx, value) \ ATA_OUTL(ch->r_io[idx].res, ch->r_io[idx].offset, value) Modified: stable/8/sys/dev/ata/ata-lowlevel.c ============================================================================== --- stable/8/sys/dev/ata/ata-lowlevel.c Sat Mar 2 17:32:15 2013 (r247652) +++ stable/8/sys/dev/ata/ata-lowlevel.c Sat Mar 2 17:32:20 2013 (r247653) @@ -847,14 +847,28 @@ ata_pio_read(struct ata_request *request uint8_t *addr; int size = min(request->transfersize, length); int resid; - uint8_t buf[2]; + uint8_t buf[2] __aligned(sizeof(int16_t)); +#ifndef __NO_STRICT_ALIGNMENT + int i; +#endif 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 (__predict_false(ch->flags & ATA_USE_16BIT || + (size % sizeof(int32_t)) || ((uintptr_t)addr % sizeof(int32_t)))) { +#ifndef __NO_STRICT_ALIGNMENT + if (__predict_false((uintptr_t)addr % sizeof(int16_t))) { + for (i = 0, resid = size & ~1; resid > 0; resid -= + sizeof(int16_t)) { + *(uint16_t *)&buf = ATA_IDX_INW_STRM(ch, ATA_DATA); + addr[i++] = buf[0]; + addr[i++] = buf[1]; + } + } else +#endif + 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); + *(uint16_t *)&buf = ATA_IDX_INW_STRM(ch, ATA_DATA); (addr + (size & ~1))[0] = buf[0]; } } else @@ -876,15 +890,30 @@ ata_pio_write(struct ata_request *reques uint8_t *addr; int size = min(request->transfersize, length); int resid; - uint8_t buf[2]; + uint8_t buf[2] __aligned(sizeof(int16_t)); +#ifndef __NO_STRICT_ALIGNMENT + int i; +#endif + size = min(request->transfersize, length); 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 (__predict_false(ch->flags & ATA_USE_16BIT || + (size % sizeof(int32_t)) || ((uintptr_t)addr % sizeof(int32_t)))) { +#ifndef __NO_STRICT_ALIGNMENT + if (__predict_false((uintptr_t)addr % sizeof(int16_t))) { + for (i = 0, resid = size & ~1; resid > 0; resid -= + sizeof(int16_t)) { + buf[0] = addr[i++]; + buf[1] = addr[i++]; + ATA_IDX_OUTW_STRM(ch, ATA_DATA, *(uint16_t *)&buf); + } + } else +#endif + ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)addr, size / + sizeof(int16_t)); if (size & 1) { buf[0] = (addr + (size & ~1))[0]; - ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)buf, 1); + ATA_IDX_OUTW_STRM(ch, ATA_DATA, *(uint16_t *)&buf); } } else ATA_IDX_OUTSL_STRM(ch, ATA_DATA, (void*)addr, size / sizeof(int32_t));