From owner-freebsd-current@FreeBSD.ORG Mon Jan 7 22:28:13 2008 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 77E5116A419 for ; Mon, 7 Jan 2008 22:28:13 +0000 (UTC) (envelope-from delphij@delphij.net) Received: from tarsier.delphij.net (delphij-pt.tunnel.tserv2.fmt.ipv6.he.net [IPv6:2001:470:1f03:2c9::2]) by mx1.freebsd.org (Postfix) with ESMTP id 4A7AD13C45B for ; Mon, 7 Jan 2008 22:28:12 +0000 (UTC) (envelope-from delphij@delphij.net) Received: from tarsier.geekcn.org (unknown [202.108.54.204]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by tarsier.delphij.net (Postfix) with ESMTP id 839AA28448 for ; Tue, 8 Jan 2008 06:28:11 +0800 (CST) Received: from localhost (unknown [202.108.54.204]) by tarsier.geekcn.org (Postfix) with ESMTP id 45907EB1014; Tue, 8 Jan 2008 06:28:11 +0800 (CST) X-Virus-Scanned: amavisd-new at geekcn.org Received: from tarsier.geekcn.org ([202.108.54.204]) by localhost (mail.geekcn.org [202.108.54.204]) (amavisd-new, port 10024) with ESMTP id MYcIT3VAg7or; Tue, 8 Jan 2008 06:28:00 +0800 (CST) Received: from charlie.delphij.net (adsl-76-237-33-62.dsl.pltn13.sbcglobal.net [76.237.33.62]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by tarsier.geekcn.org (Postfix) with ESMTP id D0332EB0FB4; Tue, 8 Jan 2008 06:27:56 +0800 (CST) DomainKey-Signature: a=rsa-sha1; s=default; d=delphij.net; c=nofws; q=dns; h=message-id:date:from:reply-to:organization:user-agent: mime-version:to:cc:subject:references:in-reply-to: x-enigmail-version:openpgp:content-type; b=YPclmQYflOW9HGPwABKR6pkXuRzbhbOeKKOriC5kv+xINfVa8wSOJlyS6Wzu1Ma6Z 1+4+uHskAaI+LJZKcNnFQ== Message-ID: <4782A768.3020304@delphij.net> Date: Mon, 07 Jan 2008 14:27:52 -0800 From: Xin LI Organization: The FreeBSD Project User-Agent: Thunderbird 2.0.0.9 (X11/20071125) MIME-Version: 1.0 To: Travis Mikalson References: <1497D115-2534-4799-9D8E-18A267DF0B62@mipster.net> <9A374150-DC2A-439D-A205-E8867B663C5A@mipster.net> <477B0B07.8080703@terranova.net> <477CAF30.7020703@terranova.net> In-Reply-To: <477CAF30.7020703@terranova.net> X-Enigmail-Version: 0.95.5 OpenPGP: id=18EDEBA0; url=http://www.delphij.net/delphij.asc Content-Type: multipart/mixed; boundary="------------000605020808010702070506" Cc: freebsd-current@freebsd.org Subject: Re: ServerWorks/Broadcom HT1000 chipset errata saga X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: d@delphij.net List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Jan 2008 22:28:13 -0000 This is a multi-part message in MIME format. --------------000605020808010702070506 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Travis Mikalson wrote: > Nick Pope wrote: >> I csup'ed to latest RELENG_7_0 (RC1) and built the GENERIC kernel. >> I'm assuming Soren's patch has made it into RC1 because, without >> commenting out the rr232x driver, the kernel mis-detects my Supermicro >> PCI-X SATA controller (MV88SX6081 chipset) as an rr232x. > > No, Søren's HT1000/Marvell fixing stuff is still in HEAD only according > to cvsweb. Did not make it to RELENG_7 or RELENG_7_0 yet. > > I think your problem is unrelated to this patchset. > > It wasn't making any sense that any of this code that was touched would > have any effect on detection of your Marvell device anyway... Here is a patch that brings the HT1000 changeset back to RELENG_7 and RELENG_7_0. Newer change by phk@ seems to be harmless, but it does not have effect for HT1000 either. Cheers, - -- Xin LI http://www.delphij.net/ FreeBSD - The Power to Serve! -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4 (FreeBSD) iD8DBQFHgqdoi+vbBBjt66ARAj/8AKCn6Ar4gxVbEvKPXVmLVnwEV6QWJgCgpRef TJhBZGIJqvuvkZoifOkTcXs= =2gRs -----END PGP SIGNATURE----- --------------000605020808010702070506 Content-Type: text/plain; name="ata-ht1000.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ata-ht1000.diff" Index: ata-all.h =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-all.h,v retrieving revision 1.124.2.1 diff -u -p -r1.124.2.1 ata-all.h --- ata-all.h 21 Nov 2007 21:15:00 -0000 1.124.2.1 +++ ata-all.h 7 Jan 2008 22:17:41 -0000 @@ -464,6 +464,8 @@ struct ata_lowlevel { int (*begin_transaction)(struct ata_request *request); int (*end_transaction)(struct ata_request *request); int (*command)(struct ata_request *request); + void (*tf_read)(struct ata_request *request); + void (*tf_write)(struct ata_request *request); }; /* structure holding resources for an ATA channel */ Index: ata-chipset.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-chipset.c,v retrieving revision 1.202.2.5 diff -u -p -r1.202.2.5 ata-chipset.c --- ata-chipset.c 9 Dec 2007 19:26:56 -0000 1.202.2.5 +++ ata-chipset.c 7 Jan 2008 22:17:56 -0000 @@ -99,7 +99,7 @@ static void ata_intel_new_setmode(device static void ata_intel_sata_setmode(device_t dev, int mode); static int ata_intel_31244_allocate(device_t dev); static int ata_intel_31244_status(device_t dev); -static int ata_intel_31244_command(struct ata_request *request); +static void ata_intel_31244_tf_write(struct ata_request *request); static void ata_intel_31244_reset(device_t dev); static int ata_ite_chipinit(device_t dev); static void ata_ite_setmode(device_t dev, int mode); @@ -152,6 +152,8 @@ static void ata_promise_queue_hpkt(struc static void ata_promise_next_hpkt(struct ata_pci_controller *ctlr); static int ata_serverworks_chipinit(device_t dev); static int ata_serverworks_allocate(device_t dev); +static void ata_serverworks_tf_read(struct ata_request *request); +static void ata_serverworks_tf_write(struct ata_request *request); static void ata_serverworks_setmode(device_t dev, int mode); static int ata_sii_chipinit(device_t dev); static int ata_cmd_allocate(device_t dev); @@ -2093,7 +2095,7 @@ ata_intel_31244_allocate(device_t dev) ch->flags |= ATA_NO_SLAVE; ata_pci_hw(dev); ch->hw.status = ata_intel_31244_status; - ch->hw.command = ata_intel_31244_command; + ch->hw.tf_write = ata_intel_31244_tf_write; /* enable PHY state change interrupt */ ATA_OUTL(ctlr->r_res2, 0x4, @@ -2111,32 +2113,55 @@ ata_intel_31244_status(device_t dev) return ata_pci_status(dev); } -static int -ata_intel_31244_command(struct ata_request *request) +static void +ata_intel_31244_tf_write(struct ata_request *request) { struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); struct ata_device *atadev = device_get_softc(request->dev); - u_int64_t lba; - - if (!(atadev->flags & ATA_D_48BIT_ACTIVE)) - return (ata_generic_command(request)); - - lba = request->u.ata.lba; - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | atadev->unit); - /* enable interrupt */ - ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); - ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); - ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); - ATA_IDX_OUTW(ch, ATA_SECTOR, ((lba >> 16) & 0xff00) | (lba & 0x00ff)); - ATA_IDX_OUTW(ch, ATA_CYL_LSB, ((lba >> 24) & 0xff00) | - ((lba >> 8) & 0x00ff)); - ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((lba >> 32) & 0xff00) | - ((lba >> 16) & 0x00ff)); - /* issue command to controller */ - ATA_IDX_OUTB(ch, ATA_COMMAND, request->u.ata.command); - - return 0; + if (atadev->flags & ATA_D_48BIT_ACTIVE) { + ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); + ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); + ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) | + (request->u.ata.lba & 0x00ff)); + ATA_IDX_OUTW(ch, ATA_CYL_LSB, ((request->u.ata.lba >> 24) & 0xff00) | + ((request->u.ata.lba >> 8) & 0x00ff)); + ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) | + ((request->u.ata.lba >> 16) & 0x00ff)); + ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | atadev->unit); + } + else { + ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); + ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); + if (atadev->flags & ATA_D_USE_CHS) { + int heads, sectors; + + if (atadev->param.atavalid & ATA_FLAG_54_58) { + heads = atadev->param.current_heads; + sectors = atadev->param.current_sectors; + } + else { + heads = atadev->param.heads; + sectors = atadev->param.sectors; + } + ATA_IDX_OUTB(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, + (request->u.ata.lba / (sectors * heads))); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, + (request->u.ata.lba / (sectors * heads)) >> 8); + ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | + (((request->u.ata.lba% (sectors * heads)) / + sectors) & 0xf)); + } + else { + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); + ATA_IDX_OUTB(ch, ATA_DRIVE, + ATA_D_IBM | ATA_D_LBA | atadev->unit | + ((request->u.ata.lba >> 24) & 0x0f)); + } + } } static void @@ -2849,8 +2874,12 @@ ata_marvell_edma_dmainit(device_t dev) /* note start and stop are not used here */ ch->dma->setprd = ata_marvell_edma_dmasetprd; + /* if 64bit support present adjust max address used */ if (ATA_INL(ctlr->r_res1, 0x00d00) & 0x00000004) ch->dma->max_address = BUS_SPACE_MAXADDR; + + /* chip does not reliably do 64K DMA transfers */ + ch->dma->max_iosize = 126 * DEV_BSIZE; } } @@ -4248,10 +4277,97 @@ ata_serverworks_allocate(device_t dev) ch->flags |= ATA_NO_SLAVE; ata_pci_hw(dev); + ch->hw.tf_read = ata_serverworks_tf_read; + ch->hw.tf_write = ata_serverworks_tf_write; + + /* chip does not reliably do 64K DMA transfers */ + if (ch->dma) + ch->dma->max_iosize = 126 * DEV_BSIZE; + return 0; } static void +ata_serverworks_tf_read(struct ata_request *request) +{ + struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); + struct ata_device *atadev = device_get_softc(request->dev); + + if (atadev->flags & ATA_D_48BIT_ACTIVE) { + u_int16_t temp; + + request->u.ata.count = ATA_IDX_INW(ch, ATA_COUNT); + temp = ATA_IDX_INW(ch, ATA_SECTOR); + request->u.ata.lba = (u_int64_t)(temp & 0x00ff) | + ((u_int64_t)(temp & 0xff00) << 24); + temp = ATA_IDX_INW(ch, ATA_CYL_LSB); + request->u.ata.lba |= ((u_int64_t)(temp & 0x00ff) << 8) | + ((u_int64_t)(temp & 0xff00) << 32); + temp = ATA_IDX_INW(ch, ATA_CYL_MSB); + request->u.ata.lba |= ((u_int64_t)(temp & 0x00ff) << 16) | + ((u_int64_t)(temp & 0xff00) << 40); + } + else { + request->u.ata.count = ATA_IDX_INW(ch, ATA_COUNT) & 0x00ff; + request->u.ata.lba = (ATA_IDX_INW(ch, ATA_SECTOR) & 0x00ff) | + ((ATA_IDX_INW(ch, ATA_CYL_LSB) & 0x00ff) << 8) | + ((ATA_IDX_INW(ch, ATA_CYL_MSB) & 0x00ff) << 16) | + ((ATA_IDX_INW(ch, ATA_DRIVE) & 0xf) << 24); + } +} + +static void +ata_serverworks_tf_write(struct ata_request *request) +{ + struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); + struct ata_device *atadev = device_get_softc(request->dev); + + if (atadev->flags & ATA_D_48BIT_ACTIVE) { + ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); + ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); + ATA_IDX_OUTW(ch, ATA_SECTOR, ((request->u.ata.lba >> 16) & 0xff00) | + (request->u.ata.lba & 0x00ff)); + ATA_IDX_OUTW(ch, ATA_CYL_LSB, ((request->u.ata.lba >> 24) & 0xff00) | + ((request->u.ata.lba >> 8) & 0x00ff)); + ATA_IDX_OUTW(ch, ATA_CYL_MSB, ((request->u.ata.lba >> 32) & 0xff00) | + ((request->u.ata.lba >> 16) & 0x00ff)); + ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_LBA | atadev->unit); + } + else { + ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature); + ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count); + if (atadev->flags & ATA_D_USE_CHS) { + int heads, sectors; + + if (atadev->param.atavalid & ATA_FLAG_54_58) { + heads = atadev->param.current_heads; + sectors = atadev->param.current_sectors; + } + else { + heads = atadev->param.heads; + sectors = atadev->param.sectors; + } + ATA_IDX_OUTW(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); + ATA_IDX_OUTW(ch, ATA_CYL_LSB, + (request->u.ata.lba / (sectors * heads))); + ATA_IDX_OUTW(ch, ATA_CYL_MSB, + (request->u.ata.lba / (sectors * heads)) >> 8); + ATA_IDX_OUTW(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | + (((request->u.ata.lba% (sectors * heads)) / + sectors) & 0xf)); + } + else { + ATA_IDX_OUTW(ch, ATA_SECTOR, request->u.ata.lba); + ATA_IDX_OUTW(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); + ATA_IDX_OUTW(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); + ATA_IDX_OUTW(ch, ATA_DRIVE, + ATA_D_IBM | ATA_D_LBA | atadev->unit | + ((request->u.ata.lba >> 24) & 0x0f)); + } + } +} + +static void ata_serverworks_setmode(device_t dev, int mode) { device_t gparent = GRANDPARENT(dev); @@ -4562,7 +4678,7 @@ ata_sii_allocate(device_t dev) if ((ctlr->chip->cfg2 & SIIBUG) && ch->dma) { /* work around errata in early chips */ - ch->dma->boundary = 16 * DEV_BSIZE; + ch->dma->boundary = 8192; ch->dma->segsize = 15 * DEV_BSIZE; } Index: ata-dma.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-dma.c,v retrieving revision 1.147.2.1 diff -u -p -r1.147.2.1 ata-dma.c --- ata-dma.c 21 Nov 2007 21:15:00 -0000 1.147.2.1 +++ ata-dma.c 7 Jan 2008 22:18:10 -0000 @@ -75,7 +75,7 @@ ata_dmainit(device_t dev) ch->dma->load = ata_dmaload; ch->dma->unload = ata_dmaunload; ch->dma->alignment = 2; - ch->dma->boundary = 128 * DEV_BSIZE; + ch->dma->boundary = 65536; ch->dma->segsize = 128 * DEV_BSIZE; ch->dma->max_iosize = 128 * DEV_BSIZE; ch->dma->max_address = BUS_SPACE_MAXADDR_32BIT; Index: ata-lowlevel.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ata/ata-lowlevel.c,v retrieving revision 1.79 diff -u -p -r1.79 ata-lowlevel.c --- ata-lowlevel.c 6 Apr 2007 16:18:59 -0000 1.79 +++ ata-lowlevel.c 7 Jan 2008 22:18:25 -0000 @@ -50,6 +50,8 @@ static int ata_generic_status(device_t d static int ata_wait(struct ata_channel *ch, struct ata_device *, u_int8_t); static void ata_pio_read(struct ata_request *, int); static void ata_pio_write(struct ata_request *, int); +static void ata_tf_read(struct ata_request *); +static void ata_tf_write(struct ata_request *); /* * low level ATA functions @@ -63,6 +65,8 @@ ata_generic_hw(device_t dev) ch->hw.end_transaction = ata_end_transaction; ch->hw.status = ata_generic_status; ch->hw.command = ata_generic_command; + ch->hw.tf_read = ata_tf_read; + ch->hw.tf_write = ata_tf_write; } /* must be called with ATA channel locked and state_mtx held */ @@ -244,28 +248,7 @@ ata_end_transaction(struct ata_request * /* on control commands read back registers to the request struct */ if (request->flags & ATA_R_CONTROL) { - if (atadev->flags & ATA_D_48BIT_ACTIVE) { - ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT | ATA_A_HOB); - request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8); - request->u.ata.lba = - ((u_int64_t)(ATA_IDX_INB(ch, ATA_SECTOR)) << 24) | - ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_LSB)) << 32) | - ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_MSB)) << 40); - - ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); - request->u.ata.count |= ATA_IDX_INB(ch, ATA_COUNT); - request->u.ata.lba |= - (ATA_IDX_INB(ch, ATA_SECTOR) | - (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | - (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16)); - } - else { - request->u.ata.count = ATA_IDX_INB(ch, ATA_COUNT); - request->u.ata.lba = ATA_IDX_INB(ch, ATA_SECTOR) | - (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | - (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16) | - ((ATA_IDX_INB(ch, ATA_DRIVE) & 0xf) << 24); - } + ch->hw.tf_read(request); } /* if we got an error we are done with the HW */ @@ -734,57 +717,96 @@ ata_generic_command(struct ata_request * ATA_PROTO_ATAPI_12 ? 6 : 8); } else { - if (atadev->flags & ATA_D_48BIT_ACTIVE) { - ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8); - ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); - ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count >> 8); - ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); - ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba >> 24); - ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 32); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 40); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | atadev->unit); - } - else { - ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); - ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); - if (atadev->flags & ATA_D_USE_CHS) { - int heads, sectors; + ch->hw.tf_write(request); + + /* issue command to controller */ + ATA_IDX_OUTB(ch, ATA_COMMAND, request->u.ata.command); + } + return 0; +} + +static void +ata_tf_read(struct ata_request *request) +{ + struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); + struct ata_device *atadev = device_get_softc(request->dev); + + if (atadev->flags & ATA_D_48BIT_ACTIVE) { + ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT | ATA_A_HOB); + request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8); + request->u.ata.lba = + ((u_int64_t)(ATA_IDX_INB(ch, ATA_SECTOR)) << 24) | + ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_LSB)) << 32) | + ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_MSB)) << 40); + + ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); + request->u.ata.count |= ATA_IDX_INB(ch, ATA_COUNT); + request->u.ata.lba |= + (ATA_IDX_INB(ch, ATA_SECTOR) | + (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | + (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16)); + } + else { + request->u.ata.count = ATA_IDX_INB(ch, ATA_COUNT); + request->u.ata.lba = ATA_IDX_INB(ch, ATA_SECTOR) | + (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | + (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16) | + ((ATA_IDX_INB(ch, ATA_DRIVE) & 0xf) << 24); + } +} + +static void +ata_tf_write(struct ata_request *request) +{ + struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); + struct ata_device *atadev = device_get_softc(request->dev); + + if (atadev->flags & ATA_D_48BIT_ACTIVE) { + ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature >> 8); + ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); + ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count >> 8); + ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba >> 24); + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 32); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 40); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); + ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_LBA | atadev->unit); + } + else { + ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature); + ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count); + if (atadev->flags & ATA_D_USE_CHS) { + int heads, sectors; - if (atadev->param.atavalid & ATA_FLAG_54_58) { - heads = atadev->param.current_heads; - sectors = atadev->param.current_sectors; - } - else { - heads = atadev->param.heads; - sectors = atadev->param.sectors; - } - ATA_IDX_OUTB(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, - (request->u.ata.lba / (sectors * heads))); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, - (request->u.ata.lba / (sectors * heads)) >> 8); - ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | - (((request->u.ata.lba% (sectors * heads)) / - sectors) & 0xf)); + if (atadev->param.atavalid & ATA_FLAG_54_58) { + heads = atadev->param.current_heads; + sectors = atadev->param.current_sectors; } else { - ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); - ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); - ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); - ATA_IDX_OUTB(ch, ATA_DRIVE, - ATA_D_IBM | ATA_D_LBA | atadev->unit | - ((request->u.ata.lba >> 24) & 0x0f)); + heads = atadev->param.heads; + sectors = atadev->param.sectors; } - } - /* issue command to controller */ - ATA_IDX_OUTB(ch, ATA_COMMAND, request->u.ata.command); + ATA_IDX_OUTB(ch, ATA_SECTOR, (request->u.ata.lba % sectors)+1); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, + (request->u.ata.lba / (sectors * heads))); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, + (request->u.ata.lba / (sectors * heads)) >> 8); + ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | atadev->unit | + (((request->u.ata.lba% (sectors * heads)) / + sectors) & 0xf)); + } + else { + ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba); + ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8); + ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16); + ATA_IDX_OUTB(ch, ATA_DRIVE, + ATA_D_IBM | ATA_D_LBA | atadev->unit | + ((request->u.ata.lba >> 24) & 0x0f)); + } } - - return 0; } static void --------------000605020808010702070506--