ata-dma.c revision 98428
145095Ssos/*- 289917Ssos * Copyright (c) 1998,1999,2000,2001,2002 S�ren Schmidt <sos@FreeBSD.org> 345095Ssos * All rights reserved. 445095Ssos * 545095Ssos * Redistribution and use in source and binary forms, with or without 645095Ssos * modification, are permitted provided that the following conditions 745095Ssos * are met: 845095Ssos * 1. Redistributions of source code must retain the above copyright 945095Ssos * notice, this list of conditions and the following disclaimer, 1045095Ssos * without modification, immediately at the beginning of the file. 1145095Ssos * 2. Redistributions in binary form must reproduce the above copyright 1245095Ssos * notice, this list of conditions and the following disclaimer in the 1345095Ssos * documentation and/or other materials provided with the distribution. 1445095Ssos * 3. The name of the author may not be used to endorse or promote products 1545095Ssos * derived from this software without specific prior written permission. 1645095Ssos * 1745095Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1845095Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1945095Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2045095Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2145095Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2245095Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2345095Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2445095Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2545095Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2645095Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2745095Ssos * 2850477Speter * $FreeBSD: head/sys/dev/ata/ata-dma.c 98428 2002-06-19 12:26:20Z sos $ 2945095Ssos */ 3045095Ssos 3145095Ssos#include <sys/param.h> 3245095Ssos#include <sys/systm.h> 3374302Ssos#include <sys/ata.h> 3460041Sphk#include <sys/bio.h> 3595533Smike#include <sys/endian.h> 3645095Ssos#include <sys/malloc.h> 3745798Ssos#include <sys/bus.h> 3854270Ssos#include <sys/disk.h> 3954270Ssos#include <sys/devicestat.h> 4045095Ssos#include <pci/pcivar.h> 4166106Ssos#include <machine/bus.h> 4272106Ssos#include <sys/rman.h> 4345095Ssos#include <dev/ata/ata-all.h> 4445095Ssos 4552067Ssos/* prototypes */ 4693882Ssosstatic void ata_dmacreate(struct ata_device *, int, int); 4793882Ssosstatic void ata_dmasetupd_cb(void *, bus_dma_segment_t *, int, int); 4893882Ssosstatic void ata_dmasetupc_cb(void *, bus_dma_segment_t *, int, int); 4993882Ssosstatic void cyrix_timing(struct ata_device *, int, int); 5093882Ssosstatic void promise_timing(struct ata_device *, int, int); 5193882Ssosstatic void hpt_timing(struct ata_device *, int, int); 5293882Ssosstatic int hpt_cable80(struct ata_device *); 5352067Ssos 5452067Ssos/* misc defines */ 5593882Ssos#define ATAPI_DEVICE(atadev) \ 5693882Ssos ((atadev->unit == ATA_MASTER && \ 5793882Ssos atadev->channel->devices & ATA_ATAPI_MASTER) || \ 5893882Ssos (atadev->unit == ATA_SLAVE && \ 5993882Ssos atadev->channel->devices & ATA_ATAPI_SLAVE)) 6045720Speter 6193882Ssos#define MAXSEGSZ PAGE_SIZE 6293882Ssos#define MAXTABSZ PAGE_SIZE 6393882Ssos#define MAXCTLDMASZ (2 * (MAXTABSZ + MAXPHYS)) 6493882Ssos 6593882Ssosstruct ata_dc_cb_args { 6693882Ssos bus_addr_t maddr; 6793882Ssos int error; 6893882Ssos}; 6993882Ssos 7093882Ssosstatic void 7193882Ssosata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 7266070Ssos{ 7393882Ssos struct ata_dc_cb_args *cba = (struct ata_dc_cb_args *)xsc; 7466070Ssos 7593882Ssos if (!(cba->error = error)) 7693882Ssos cba->maddr = segs[0].ds_addr; 7793882Ssos} 7893882Ssos 7993882Ssosint 8093882Ssosata_dmaalloc(struct ata_device *atadev) 8193882Ssos{ 8293882Ssos struct ata_channel *ch; 8393882Ssos struct ata_dc_cb_args ccba; 8493882Ssos struct ata_dmastate *ds; 8593882Ssos int error; 8693882Ssos 8793882Ssos ch = atadev->channel; 8893882Ssos ds = &atadev->dmastate; 8993882Ssos if (!ds->cdmatag) { 9093882Ssos if ((error = bus_dma_tag_create(ch->dmatag, 1, PAGE_SIZE, 9193882Ssos BUS_SPACE_MAXADDR_32BIT, 9293882Ssos BUS_SPACE_MAXADDR, NULL, NULL, 9393882Ssos MAXTABSZ, 1, MAXTABSZ, 9493882Ssos BUS_DMA_ALLOCNOW, &ds->cdmatag))) 9593882Ssos return error; 9693882Ssos } 9793882Ssos if (!ds->ddmatag) { 9893882Ssos if ((error = bus_dma_tag_create(ch->dmatag, ch->alignment + 1, 0, 9993882Ssos BUS_SPACE_MAXADDR_32BIT, 10093882Ssos BUS_SPACE_MAXADDR, NULL, NULL, 10193882Ssos MAXPHYS, ATA_DMA_ENTRIES, MAXSEGSZ, 10293882Ssos BUS_DMA_ALLOCNOW, &ds->ddmatag))) 10393882Ssos return error; 10493882Ssos } 10593882Ssos if (!ds->mdmatab) { 10693882Ssos if ((error = bus_dmamem_alloc(ds->cdmatag, (void **)&ds->dmatab, 0, 10793882Ssos &ds->cdmamap))) 10893882Ssos return error; 10993882Ssos 11093882Ssos if ((error = bus_dmamap_load(ds->cdmatag, ds->cdmamap, ds->dmatab, 11193882Ssos MAXTABSZ, ata_dmasetupc_cb, &ccba, 11293882Ssos 0)) != 0 || ccba.error != 0) { 11393882Ssos bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap); 11493882Ssos return error; 11566070Ssos } 11693882Ssos ds->mdmatab = ccba.maddr; 11766070Ssos } 11893882Ssos if (!ds->ddmamap) { 11993882Ssos if ((error = bus_dmamap_create(ds->ddmatag, 0, &ds->ddmamap)) != 0) 12093882Ssos return error; 12193882Ssos } 12293882Ssos return 0; 12366070Ssos} 12466070Ssos 12556744Ssosvoid 12693882Ssosata_dmafree(struct ata_device *atadev) 12745095Ssos{ 12893882Ssos struct ata_dmastate *ds; 12993882Ssos 13093882Ssos ds = &atadev->dmastate; 13193882Ssos if (ds->mdmatab) { 13293882Ssos bus_dmamap_unload(ds->cdmatag, ds->cdmamap); 13393882Ssos bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap); 13493882Ssos ds->mdmatab = 0; 13593882Ssos ds->cdmamap = NULL; 13693882Ssos ds->dmatab = NULL; 13793882Ssos } 13893882Ssos if (ds->ddmamap) { 13993882Ssos bus_dmamap_destroy(ds->ddmatag, ds->ddmamap); 14093882Ssos ds->ddmamap = NULL; 14193882Ssos } 14293882Ssos if (ds->cdmatag) { 14393882Ssos bus_dma_tag_destroy(ds->cdmatag); 14493882Ssos ds->cdmatag = NULL; 14593882Ssos } 14693882Ssos if (ds->ddmatag) { 14793882Ssos bus_dma_tag_destroy(ds->ddmatag); 14893882Ssos ds->ddmatag = NULL; 14993882Ssos } 15093882Ssos} 15193882Ssos 15293882Ssosvoid 15393882Ssosata_dmafreetags(struct ata_channel *ch) 15493882Ssos{ 15593882Ssos 15693882Ssos if (ch->dmatag) { 15793882Ssos bus_dma_tag_destroy(ch->dmatag); 15893882Ssos ch->dmatag = NULL; 15993882Ssos } 16093882Ssos} 16193882Ssos 16293882Ssosstatic void 16393882Ssosata_dmacreate(struct ata_device *atadev, int apiomode, int mode) 16493882Ssos{ 16593882Ssos 16693882Ssos atadev->mode = mode; 16793882Ssos if (!atadev->channel->dmatag) { 16893882Ssos if (bus_dma_tag_create(NULL, 1, 0, 16993882Ssos BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 17093882Ssos NULL, NULL, MAXCTLDMASZ, ATA_DMA_ENTRIES, 17193882Ssos BUS_SPACE_MAXSIZE_32BIT, 0, 17293882Ssos &atadev->channel->dmatag)) { 17393882Ssos ata_prtdev(atadev, "DMA tag allocation failed, disabling DMA\n"); 17493882Ssos ata_dmainit(atadev, apiomode, -1, -1); 17593882Ssos } 17693882Ssos } 17793882Ssos} 17893882Ssos 17993882Ssosvoid 18093882Ssosata_dmainit(struct ata_device *atadev, int apiomode, int wdmamode, int udmamode) 18193882Ssos{ 18293882Ssos device_t parent = device_get_parent(atadev->channel->dev); 18393882Ssos int chiptype = atadev->channel->chiptype; 18493882Ssos int chiprev = pci_get_revid(parent); 18593882Ssos int channel = atadev->channel->unit; 18693882Ssos int device = ATA_DEV(atadev->unit); 18793882Ssos int devno = (channel << 1) + device; 18864307Ssos int error; 18945095Ssos 19056744Ssos /* set our most pessimistic default mode */ 19190215Ssos atadev->mode = ATA_PIO; 19256744Ssos 19393882Ssos if (!atadev->channel->r_bmio) 19456744Ssos return; 19545095Ssos 19652067Ssos /* if simplex controller, only allow DMA on primary channel */ 19793882Ssos if (channel == 1) { 19893882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMSTAT_PORT, 19993882Ssos ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 20072106Ssos (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE)); 20193882Ssos if (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 20293882Ssos ATA_BMSTAT_DMA_SIMPLEX) { 20390215Ssos ata_prtdev(atadev, "simplex device, DMA on primary only\n"); 20456744Ssos return; 20552067Ssos } 20652067Ssos } 20752067Ssos 20866070Ssos /* DMA engine address alignment is usually 1 word (2 bytes) */ 20993882Ssos atadev->channel->alignment = 0x1; 21045095Ssos 21185345Ssos#if 1 21293882Ssos if (udmamode > 2 && !atadev->param->hwres_cblid) { 21390215Ssos ata_prtdev(atadev,"DMA limited to UDMA33, non-ATA66 cable or device\n"); 21460829Ssos udmamode = 2; 21560829Ssos } 21685345Ssos#endif 21793882Ssos switch (chiptype) { 21845095Ssos 21985352Ssos case 0x248a8086: /* Intel ICH3 mobile */ 22085352Ssos case 0x248b8086: /* Intel ICH3 */ 22175553Ssos case 0x244a8086: /* Intel ICH2 mobile */ 22264307Ssos case 0x244b8086: /* Intel ICH2 */ 22364307Ssos if (udmamode >= 5) { 22464307Ssos int32_t mask48, new48; 22564307Ssos int16_t word54; 22664307Ssos 22764307Ssos word54 = pci_read_config(parent, 0x54, 2); 22864307Ssos if (word54 & (0x10 << devno)) { 22990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 23090215Ssos ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY); 23190215Ssos if (bootverbose) 23290215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Intel chip\n", 23364307Ssos (error) ? "failed" : "success"); 23464307Ssos if (!error) { 23564307Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 23664307Ssos new48 = (1 << devno) + (1 << (16 + (devno << 2))); 23764307Ssos pci_write_config(parent, 0x48, 23864307Ssos (pci_read_config(parent, 0x48, 4) & 23964307Ssos ~mask48) | new48, 4); 24090215Ssos pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2); 24193882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 24264307Ssos return; 24364307Ssos } 24464307Ssos } 24564307Ssos } 24664479Ssos /* make sure eventual ATA100 mode from the BIOS is disabled */ 24764479Ssos pci_write_config(parent, 0x54, 24864479Ssos pci_read_config(parent, 0x54, 2) & ~(0x1000<<devno),2); 24964307Ssos /* FALLTHROUGH */ 25064307Ssos 25190215Ssos case 0x24118086: /* Intel ICH */ 25290215Ssos case 0x76018086: /* Intel ICH */ 25357391Ssos if (udmamode >= 4) { 25457391Ssos int32_t mask48, new48; 25557391Ssos int16_t word54; 25657391Ssos 25757391Ssos word54 = pci_read_config(parent, 0x54, 2); 25857391Ssos if (word54 & (0x10 << devno)) { 25990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 26090215Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 26190215Ssos if (bootverbose) 26290215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Intel chip\n", 26375553Ssos (error) ? "failed" : "success"); 26457391Ssos if (!error) { 26557391Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 26657391Ssos new48 = (1 << devno) + (2 << (16 + (devno << 2))); 26757391Ssos pci_write_config(parent, 0x48, 26857391Ssos (pci_read_config(parent, 0x48, 4) & 26957391Ssos ~mask48) | new48, 4); 27057391Ssos pci_write_config(parent, 0x54, word54 | (1 << devno), 2); 27193882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 27257391Ssos return; 27357391Ssos } 27457391Ssos } 27590215Ssos } 27664479Ssos /* make sure eventual ATA66 mode from the BIOS is disabled */ 27764479Ssos pci_write_config(parent, 0x54, 27864479Ssos pci_read_config(parent, 0x54, 2) & ~(1 << devno), 2); 27957391Ssos /* FALLTHROUGH */ 28057391Ssos 28145095Ssos case 0x71118086: /* Intel PIIX4 */ 28285352Ssos case 0x84CA8086: /* Intel PIIX4 */ 28356138Ssos case 0x71998086: /* Intel PIIX4e */ 28456138Ssos case 0x24218086: /* Intel ICH0 */ 28545095Ssos if (udmamode >= 2) { 28651520Ssos int32_t mask48, new48; 28745095Ssos 28890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 28953029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 29051520Ssos if (bootverbose) 29190215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n", 29275553Ssos (error) ? "failed" : "success"); 29353681Ssos if (!error) { 29453681Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 29553681Ssos new48 = (1 << devno) + (2 << (16 + (devno << 2))); 29657325Ssos pci_write_config(parent, 0x48, 29757325Ssos (pci_read_config(parent, 0x48, 4) & 29853681Ssos ~mask48) | new48, 4); 29993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 30056744Ssos return; 30153681Ssos } 30245095Ssos } 30364479Ssos /* make sure eventual ATA33 mode from the BIOS is disabled */ 30464479Ssos pci_write_config(parent, 0x48, 30564479Ssos pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4); 30645095Ssos /* FALLTHROUGH */ 30745095Ssos 30845095Ssos case 0x70108086: /* Intel PIIX3 */ 30945095Ssos if (wdmamode >= 2 && apiomode >= 4) { 31045095Ssos int32_t mask40, new40, mask44, new44; 31145095Ssos 31245095Ssos /* if SITRE not set doit for both channels */ 31393882Ssos if (!((pci_read_config(parent, 0x40, 4) >> (channel<<8)) & 0x4000)){ 31457325Ssos new40 = pci_read_config(parent, 0x40, 4); 31557325Ssos new44 = pci_read_config(parent, 0x44, 4); 31651520Ssos if (!(new40 & 0x00004000)) { 31751520Ssos new44 &= ~0x0000000f; 31851520Ssos new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8); 31951520Ssos } 32051520Ssos if (!(new40 & 0x40000000)) { 32151520Ssos new44 &= ~0x000000f0; 32251520Ssos new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20); 32351520Ssos } 32451520Ssos new40 |= 0x40004000; 32557325Ssos pci_write_config(parent, 0x40, new40, 4); 32657325Ssos pci_write_config(parent, 0x44, new44, 4); 32745095Ssos } 32890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 32953029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 33051520Ssos if (bootverbose) 33190215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n", 33275553Ssos (error) ? "failed" : "success"); 33353681Ssos if (!error) { 33453681Ssos if (device == ATA_MASTER) { 33553681Ssos mask40 = 0x0000330f; 33653681Ssos new40 = 0x00002307; 33753681Ssos mask44 = 0; 33853681Ssos new44 = 0; 33953681Ssos } 34053681Ssos else { 34153681Ssos mask40 = 0x000000f0; 34253681Ssos new40 = 0x00000070; 34353681Ssos mask44 = 0x0000000f; 34453681Ssos new44 = 0x0000000b; 34553681Ssos } 34693882Ssos if (channel) { 34753681Ssos mask40 <<= 16; 34853681Ssos new40 <<= 16; 34953681Ssos mask44 <<= 4; 35053681Ssos new44 <<= 4; 35153681Ssos } 35257325Ssos pci_write_config(parent, 0x40, 35357325Ssos (pci_read_config(parent, 0x40, 4) & ~mask40)| 35490215Ssos new40, 4); 35557325Ssos pci_write_config(parent, 0x44, 35657325Ssos (pci_read_config(parent, 0x44, 4) & ~mask44)| 35790215Ssos new44, 4); 35893882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 35956744Ssos return; 36045095Ssos } 36151520Ssos } 36253681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 36345095Ssos break; 36445095Ssos 36545095Ssos case 0x12308086: /* Intel PIIX */ 36654544Ssos if (wdmamode >= 2 && apiomode >= 4) { 36754544Ssos int32_t word40; 36854544Ssos 36957325Ssos word40 = pci_read_config(parent, 0x40, 4); 37093882Ssos word40 >>= channel * 16; 37154544Ssos 37254544Ssos /* Check for timing config usable for DMA on controller */ 37354544Ssos if (!((word40 & 0x3300) == 0x2300 && 37493882Ssos ((word40 >> (device ? 4 : 0)) & 1) == 1)) 37554544Ssos break; 37654544Ssos 37790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 37854544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 37954544Ssos if (bootverbose) 38090215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n", 38156558Ssos (error) ? "failed" : "success"); 38254544Ssos if (!error) { 38393882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 38456744Ssos return; 38554544Ssos } 38654544Ssos } 38745095Ssos break; 38845095Ssos 38952067Ssos case 0x522910b9: /* AcerLabs Aladdin IV/V */ 39075271Ssos /* the older Aladdin doesn't support ATAPI DMA on both master & slave */ 39193882Ssos if (chiprev < 0xc2 && 39293882Ssos atadev->channel->devices & ATA_ATAPI_MASTER && 39393882Ssos atadev->channel->devices & ATA_ATAPI_SLAVE) { 39490215Ssos ata_prtdev(atadev, "two atapi devices on this channel, no DMA\n"); 39553029Ssos break; 39652067Ssos } 39793882Ssos pci_write_config(parent, 0x58 + (channel << 2), 0x00310001, 4); 39893882Ssos if (udmamode >= 5 && chiprev >= 0xc4) { 39990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 40075271Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 40175271Ssos if (bootverbose) 40290215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Acer chip\n", 40375271Ssos (error) ? "failed" : "success"); 40475271Ssos if (!error) { 40575271Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 40652067Ssos 40775271Ssos pci_write_config(parent, 0x4b, 40875271Ssos pci_read_config(parent, 0x4b, 1) | 0x01, 1); 40975271Ssos word54 &= ~(0x000f000f << (devno << 2)); 41075271Ssos word54 |= (0x000f0005 << (devno << 2)); 41175271Ssos pci_write_config(parent, 0x54, word54, 4); 41275271Ssos pci_write_config(parent, 0x53, 41375271Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 41493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 41575271Ssos return; 41675271Ssos } 41775271Ssos } 41893882Ssos if (udmamode >= 4 && chiprev >= 0xc2) { 41990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 42075271Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 42175271Ssos if (bootverbose) 42290215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Acer chip\n", 42375271Ssos (error) ? "failed" : "success"); 42475271Ssos if (!error) { 42575271Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 42675271Ssos 42775271Ssos pci_write_config(parent, 0x4b, 42875271Ssos pci_read_config(parent, 0x4b, 1) | 0x01, 1); 42975271Ssos word54 &= ~(0x000f000f << (devno << 2)); 43075271Ssos word54 |= (0x00080005 << (devno << 2)); 43175271Ssos pci_write_config(parent, 0x54, word54, 4); 43275271Ssos pci_write_config(parent, 0x53, 43375271Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 43493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 43575271Ssos return; 43675271Ssos } 43775271Ssos } 43893882Ssos if (udmamode >= 2 && chiprev >= 0x20) { 43990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 44053029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 44151520Ssos if (bootverbose) 44290215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Acer chip\n", 44356558Ssos (error) ? "failed" : "success"); 44453681Ssos if (!error) { 44575271Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 44675271Ssos 44760829Ssos word54 &= ~(0x000f000f << (devno << 2)); 44860829Ssos word54 |= (0x000a0005 << (devno << 2)); 44957325Ssos pci_write_config(parent, 0x54, word54, 4); 45057325Ssos pci_write_config(parent, 0x53, 45157325Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 45293882Ssos atadev->channel->flags |= ATA_ATAPI_DMA_RO; 45393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 45456744Ssos return; 45553681Ssos } 45651520Ssos } 45770186Ssos 45870186Ssos /* make sure eventual UDMA mode from the BIOS is disabled */ 45970752Ssos pci_write_config(parent, 0x56, pci_read_config(parent, 0x56, 2) & 46070752Ssos ~(0x0008 << (devno << 2)), 2); 46170186Ssos 46253681Ssos if (wdmamode >= 2 && apiomode >= 4) { 46390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 46453029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 46552067Ssos if (bootverbose) 46690215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Acer chip\n", 46756558Ssos (error) ? "failed" : "success"); 46853681Ssos if (!error) { 46957325Ssos pci_write_config(parent, 0x53, 47057325Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 47193882Ssos atadev->channel->flags |= ATA_ATAPI_DMA_RO; 47293882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 47356744Ssos return; 47453681Ssos } 47552067Ssos } 47657771Ssos pci_write_config(parent, 0x53, 47757771Ssos (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1); 47893882Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 47993882Ssos ATA_PIO0 + apiomode, 48093882Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 48193882Ssos if (bootverbose) 48293882Ssos ata_prtdev(atadev, "%s setting PIO%d on Acer chip\n", 48393882Ssos (error) ? "failed" : "success", 48493882Ssos (apiomode >= 0) ? apiomode : 0); 48593882Ssos if (!error) { 48693882Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 48793882Ssos int32_t timing; 48893882Ssos 48993882Ssos switch(ATA_PIO0 + apiomode) { 49093882Ssos case ATA_PIO0: timing = 0x006d0003; 49193882Ssos case ATA_PIO1: timing = 0x00580002; 49293882Ssos case ATA_PIO2: timing = 0x00440001; 49393882Ssos case ATA_PIO3: timing = 0x00330001; 49493882Ssos case ATA_PIO4: timing = 0x00310001; 49593882Ssos default: timing = 0x006d0003; 49693882Ssos } 49793882Ssos pci_write_config(parent, 0x58 + (channel << 2), timing, 4); 49893882Ssos word54 &= ~(0x000f000f << (devno << 2)); 49993882Ssos word54 |= (0x00000004 << (devno << 2)); 50093882Ssos pci_write_config(parent, 0x54, word54, 4); 50193882Ssos atadev->mode = ATA_PIO0 + apiomode; 50293882Ssos return; 50393882Ssos } 50452067Ssos break; 50552067Ssos 50694826Ssos case 0x01bc10de: /* nVIDIA nForce */ 50793094Ssos case 0x74411022: /* AMD 768 */ 50876584Ssos case 0x74111022: /* AMD 766 */ 50959103Ssos case 0x74091022: /* AMD 756 */ 51089917Ssos case 0x05711106: /* VIA 82C571, 82C586, 82C596, 82C686 , 8231, 8233 */ 51189917Ssos { 51294826Ssos int via_modes[5][7] = { 51394826Ssos { 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */ 51494826Ssos { 0x00, 0x00, 0xea, 0x00, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */ 51594826Ssos { 0x00, 0x00, 0xf4, 0x00, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */ 51694826Ssos { 0x00, 0x00, 0xf6, 0x00, 0xf2, 0xf1, 0xf0 }, /* VIA ATA133 */ 51794826Ssos { 0x00, 0x00, 0xc0, 0x00, 0xc5, 0xc6, 0x00 }}; /* AMD/nVIDIA */ 51889917Ssos int *reg_val = NULL; 51994826Ssos char *chip = "VIA"; 52089917Ssos 52193674Ssos if (ata_find_dev(parent, 0x31471106, 0)) { /* 8233a */ 52289917Ssos udmamode = imin(udmamode, 6); 52389917Ssos reg_val = via_modes[3]; 52471156Ssos } 52589917Ssos else if (ata_find_dev(parent, 0x06861106, 0x40) || /* 82C686b */ 52689917Ssos ata_find_dev(parent, 0x82311106, 0) || /* 8231 */ 52789917Ssos ata_find_dev(parent, 0x30741106, 0) || /* 8233 */ 52889917Ssos ata_find_dev(parent, 0x31091106, 0)) { /* 8233c */ 52989917Ssos udmamode = imin(udmamode, 5); 53089917Ssos reg_val = via_modes[2]; 53189917Ssos } 53289917Ssos else if (ata_find_dev(parent, 0x06861106, 0x10) || /* 82C686a */ 53389917Ssos ata_find_dev(parent, 0x05961106, 0x12)) { /* 82C596b */ 53489917Ssos udmamode = imin(udmamode, 4); 53589917Ssos reg_val = via_modes[1]; 53689917Ssos } 53793674Ssos else if (ata_find_dev(parent, 0x06861106, 0)) { /* 82C686 */ 53889917Ssos udmamode = imin(udmamode, 2); 53989917Ssos reg_val = via_modes[1]; 54089917Ssos } 54189917Ssos else if (ata_find_dev(parent, 0x05961106, 0) || /* 82C596a */ 54289917Ssos ata_find_dev(parent, 0x05861106, 0x03)) { /* 82C586b */ 54389917Ssos udmamode = imin(udmamode, 2); 54489917Ssos reg_val = via_modes[0]; 54589917Ssos } 54694826Ssos else if (chiptype == 0x74411022 || /* AMD 768 */ 54794826Ssos chiptype == 0x74111022) { /* AMD 766 */ 54894826Ssos udmamode = imin(udmamode, 5); 54994826Ssos reg_val = via_modes[4]; 55094826Ssos chip = "AMD"; 55194826Ssos } 55294826Ssos else if (chiptype == 0x74091022) { /* AMD 756 */ 55394826Ssos udmamode = imin(udmamode, 4); 55494826Ssos reg_val = via_modes[4]; 55594826Ssos chip = "AMD"; 55694826Ssos } 55794826Ssos else if (chiptype == 0x01bc10de) { /* nVIDIA */ 55894826Ssos udmamode = imin(udmamode, 5); 55994826Ssos reg_val = via_modes[4]; 56094826Ssos chip = "nVIDIA"; 56194826Ssos } 56294826Ssos else 56389917Ssos udmamode = 0; 56494826Ssos 56589917Ssos if (udmamode >= 6) { 56690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 56789917Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 56864695Ssos if (bootverbose) 56994826Ssos ata_prtdev(atadev, "%s setting UDMA6 on %s chip\n", 57094826Ssos (error) ? "failed" : "success", chip); 57164695Ssos if (!error) { 57289917Ssos pci_write_config(parent, 0x53 - devno, reg_val[6], 1); 57393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 57471156Ssos return; 57571156Ssos } 57671156Ssos } 57789917Ssos if (udmamode >= 5) { 57890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 57989917Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 58071156Ssos if (bootverbose) 58194826Ssos ata_prtdev(atadev, "%s setting UDMA5 on %s chip\n", 58294826Ssos (error) ? "failed" : "success", chip); 58371156Ssos if (!error) { 58489917Ssos pci_write_config(parent, 0x53 - devno, reg_val[5], 1); 58593882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 58671156Ssos return; 58771156Ssos } 58871156Ssos } 58971156Ssos if (udmamode >= 4) { 59090215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 59171156Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 59271156Ssos if (bootverbose) 59394826Ssos ata_prtdev(atadev, "%s setting UDMA4 on %s chip\n", 59494826Ssos (error) ? "failed" : "success", chip); 59571156Ssos if (!error) { 59689917Ssos pci_write_config(parent, 0x53 - devno, reg_val[4], 1); 59793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 59864695Ssos return; 59964695Ssos } 60056138Ssos } 60164695Ssos if (udmamode >= 2) { 60290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 60364695Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 60464695Ssos if (bootverbose) 60594826Ssos ata_prtdev(atadev, "%s setting UDMA2 on %s chip\n", 60694826Ssos (error) ? "failed" : "success", chip); 60764695Ssos if (!error) { 60889917Ssos pci_write_config(parent, 0x53 - devno, reg_val[2], 1); 60993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 61064695Ssos return; 61164695Ssos } 61256138Ssos } 61394826Ssos if (wdmamode >= 2 && apiomode >= 4) { 61494826Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 61594826Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 61694826Ssos if (bootverbose) 61794826Ssos ata_prtdev(atadev, "%s setting WDMA2 on %s chip\n", 61894826Ssos (error) ? "failed" : "success", chip); 61994826Ssos if (!error) { 62094826Ssos pci_write_config(parent, 0x53 - devno, 0x0b, 1); 62194826Ssos pci_write_config(parent, 0x4b - devno, 0x31, 1); 62294826Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 62394826Ssos return; 62494826Ssos } 62553681Ssos } 62653681Ssos } 62753681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 62853681Ssos break; 62953681Ssos 63054544Ssos case 0x55131039: /* SiS 5591 */ 63190215Ssos if (ata_find_dev(parent, 0x06301039, 0x30) || /* SiS 630 */ 63293674Ssos ata_find_dev(parent, 0x06331039, 0) || /* SiS 633 */ 63393674Ssos ata_find_dev(parent, 0x06351039, 0) || /* SiS 635 */ 63493674Ssos ata_find_dev(parent, 0x06401039, 0) || /* SiS 640 */ 63593674Ssos ata_find_dev(parent, 0x06451039, 0) || /* SiS 645 */ 63693674Ssos ata_find_dev(parent, 0x06501039, 0) || /* SiS 650 */ 63793674Ssos ata_find_dev(parent, 0x07301039, 0) || /* SiS 730 */ 63893674Ssos ata_find_dev(parent, 0x07331039, 0) || /* SiS 733 */ 63993674Ssos ata_find_dev(parent, 0x07351039, 0) || /* SiS 735 */ 64093674Ssos ata_find_dev(parent, 0x07401039, 0) || /* SiS 740 */ 64193674Ssos ata_find_dev(parent, 0x07451039, 0) || /* SiS 745 */ 64293674Ssos ata_find_dev(parent, 0x07501039, 0)) { /* SiS 750 */ 64387198Ssos int8_t reg = 0x40 + (devno << 1); 64487951Ssos int16_t val = pci_read_config(parent, reg, 2) & 0x0fff; 64587198Ssos 64687198Ssos if (udmamode >= 5) { 64790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 64887198Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 64987198Ssos if (bootverbose) 65090215Ssos ata_prtdev(atadev, "%s setting UDMA5 on SiS chip\n", 65187198Ssos (error) ? "failed" : "success"); 65287198Ssos if (!error) { 65387951Ssos pci_write_config(parent, reg, val | 0x8000, 2); 65493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 65587198Ssos return; 65687198Ssos } 65754544Ssos } 65887198Ssos if (udmamode >= 4) { 65990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 66087198Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 66187198Ssos if (bootverbose) 66290215Ssos ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n", 66387198Ssos (error) ? "failed" : "success"); 66487198Ssos if (!error) { 66587951Ssos pci_write_config(parent, reg, val | 0x9000, 2); 66693882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 66787198Ssos return; 66887198Ssos } 66987198Ssos } 67087198Ssos if (udmamode >= 2) { 67190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 67287198Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 67387198Ssos if (bootverbose) 67490215Ssos ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", 67587198Ssos (error) ? "failed" : "success"); 67687198Ssos if (!error) { 67787951Ssos pci_write_config(parent, reg, val | 0xb000, 2); 67893882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 67987198Ssos return; 68087198Ssos } 68187198Ssos } 68287198Ssos } else if (ata_find_dev(parent, 0x05301039, 0) || /* SiS 530 */ 68387198Ssos ata_find_dev(parent, 0x05401039, 0) || /* SiS 540 */ 68487198Ssos ata_find_dev(parent, 0x06201039, 0) || /* SiS 620 */ 68587198Ssos ata_find_dev(parent, 0x06301039, 0)) { /* SiS 630 */ 68687198Ssos int8_t reg = 0x40 + (devno << 1); 68787198Ssos int16_t val = pci_read_config(parent, reg, 2) & 0x0fff; 68887198Ssos 68987198Ssos if (udmamode >= 4) { 69090215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 69187198Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 69287198Ssos if (bootverbose) 69390215Ssos ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n", 69487198Ssos (error) ? "failed" : "success"); 69587198Ssos if (!error) { 69687198Ssos pci_write_config(parent, reg, val | 0x9000, 2); 69793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 69887198Ssos return; 69987198Ssos } 70087198Ssos } 70187198Ssos if (udmamode >= 2) { 70290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 70387198Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 70487198Ssos if (bootverbose) 70590215Ssos ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", 70687198Ssos (error) ? "failed" : "success"); 70787198Ssos if (!error) { 70887951Ssos pci_write_config(parent, reg, val | 0xa000, 2); 70993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 71087198Ssos return; 71187198Ssos } 71287198Ssos } 71393882Ssos } else if (udmamode >= 2 && chiprev > 0xc1) { 71490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 71588478Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 71688478Ssos if (bootverbose) 71790215Ssos ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", 71888478Ssos (error) ? "failed" : "success"); 71988478Ssos if (!error) { 72088478Ssos pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); 72193882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 72288478Ssos return; 72387198Ssos } 72454544Ssos } 72554544Ssos if (wdmamode >=2 && apiomode >= 4) { 72690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 72754544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 72854544Ssos if (bootverbose) 72990215Ssos ata_prtdev(atadev, "%s setting WDMA2 on SiS chip\n", 73056558Ssos (error) ? "failed" : "success"); 73154544Ssos if (!error) { 73257325Ssos pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); 73393882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 73456744Ssos return; 73554544Ssos } 73654544Ssos } 73754544Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 73854544Ssos break; 73954544Ssos 74066583Ssos case 0x06491095: /* CMD 649 ATA100 controller */ 74166583Ssos if (udmamode >= 5) { 74266583Ssos u_int8_t umode; 74366583Ssos 74490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 74566583Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 74666583Ssos if (bootverbose) 74790215Ssos ata_prtdev(atadev, "%s setting UDMA5 on CMD chip\n", 74866583Ssos (error) ? "failed" : "success"); 74966583Ssos if (!error) { 75093882Ssos umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); 75193882Ssos umode &= ~(device ? 0xca : 0x35); 75293882Ssos umode |= (device ? 0x0a : 0x05); 75393882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); 75493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 75566583Ssos return; 75666583Ssos } 75766583Ssos } 75866583Ssos /* FALLTHROUGH */ 75966583Ssos 76066583Ssos case 0x06481095: /* CMD 648 ATA66 controller */ 76166583Ssos if (udmamode >= 4) { 76266583Ssos u_int8_t umode; 76366583Ssos 76490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 76566583Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 76666583Ssos if (bootverbose) 76790215Ssos ata_prtdev(atadev, "%s setting UDMA4 on CMD chip\n", 76866583Ssos (error) ? "failed" : "success"); 76966583Ssos if (!error) { 77093882Ssos umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); 77193882Ssos umode &= ~(device ? 0xca : 0x35); 77293882Ssos umode |= (device ? 0x4a : 0x15); 77393882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); 77493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 77566583Ssos return; 77666583Ssos } 77766583Ssos } 77866583Ssos if (udmamode >= 2) { 77966583Ssos u_int8_t umode; 78066583Ssos 78190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 78266583Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 78366583Ssos if (bootverbose) 78490215Ssos ata_prtdev(atadev, "%s setting UDMA2 on CMD chip\n", 78566583Ssos (error) ? "failed" : "success"); 78666583Ssos if (!error) { 78793882Ssos umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); 78893882Ssos umode &= ~(device ? 0xca : 0x35); 78993882Ssos umode |= (device ? 0x42 : 0x11); 79093882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); 79193882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 79266583Ssos return; 79366583Ssos } 79466583Ssos } 79566583Ssos /* make sure eventual UDMA mode from the BIOS is disabled */ 79693882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, 79793882Ssos pci_read_config(parent, channel ? 0x7b : 0x73, 1) & 79895010Ssos ~(device ? 0xca : 0x53), 1); 79966583Ssos /* FALLTHROUGH */ 80066583Ssos 80157325Ssos case 0x06461095: /* CMD 646 ATA controller */ 80257325Ssos if (wdmamode >= 2 && apiomode >= 4) { 80390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 80457325Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 80557325Ssos if (bootverbose) 80690215Ssos ata_prtdev(atadev, "%s setting WDMA2 on CMD chip\n", 80757325Ssos error ? "failed" : "success"); 80857325Ssos if (!error) { 80957325Ssos int32_t offset = (devno < 3) ? (devno << 1) : 7; 81057325Ssos 81157325Ssos pci_write_config(parent, 0x54 + offset, 0x3f, 1); 81293882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 81357325Ssos return; 81457325Ssos } 81557325Ssos } 81657325Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 81757325Ssos break; 81857325Ssos 81957477Ssos case 0xc6931080: /* Cypress 82c693 ATA controller */ 82057477Ssos if (wdmamode >= 2 && apiomode >= 4) { 82190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 82257477Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 82357477Ssos if (bootverbose) 82490215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Cypress chip\n", 82557477Ssos error ? "failed" : "success"); 82657477Ssos if (!error) { 82793882Ssos pci_write_config(atadev->channel->dev, 82893882Ssos channel ? 0x4e:0x4c, 0x2020, 2); 82993882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 83057477Ssos return; 83157477Ssos } 83257477Ssos } 83357477Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 83457477Ssos break; 83557477Ssos 83666583Ssos case 0x01021078: /* Cyrix 5530 ATA33 controller */ 83793882Ssos atadev->channel->alignment = 0xf; 83866070Ssos if (udmamode >= 2) { 83990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 84066070Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 84166070Ssos if (bootverbose) 84290215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Cyrix chip\n", 84366070Ssos (error) ? "failed" : "success"); 84466070Ssos if (!error) { 84593882Ssos cyrix_timing(atadev, devno, ATA_UDMA2); 84693882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 84766070Ssos return; 84866070Ssos } 84966070Ssos } 85066070Ssos if (wdmamode >= 2 && apiomode >= 4) { 85190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 85266070Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 85366070Ssos if (bootverbose) 85490215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Cyrix chip\n", 85566070Ssos (error) ? "failed" : "success"); 85666070Ssos if (!error) { 85793882Ssos cyrix_timing(atadev, devno, ATA_WDMA2); 85893882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 85966070Ssos return; 86066070Ssos } 86166070Ssos } 86290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 86384584Ssos ATA_PIO0 + apiomode, ATA_C_F_SETXFER, 86466070Ssos ATA_WAIT_READY); 86566070Ssos if (bootverbose) 86690215Ssos ata_prtdev(atadev, "%s setting %s on Cyrix chip\n", 86766070Ssos (error) ? "failed" : "success", 86884584Ssos ata_mode2str(ATA_PIO0 + apiomode)); 86993882Ssos cyrix_timing(atadev, devno, ATA_PIO0 + apiomode); 87090215Ssos atadev->mode = ATA_PIO0 + apiomode; 87166070Ssos return; 87266070Ssos 87392573Ssos case 0x02121166: /* ServerWorks CSB5 ATA66/100 controller */ 87493882Ssos if (udmamode >= 5 && chiprev >= 0x92) { 87592573Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 87692573Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 87792573Ssos if (bootverbose) 87892573Ssos ata_prtdev(atadev, "%s setting UDMA5 on ServerWorks chip\n", 87992573Ssos (error) ? "failed" : "success"); 88092573Ssos if (!error) { 88192573Ssos u_int16_t reg56; 88292573Ssos 88392573Ssos pci_write_config(parent, 0x54, 88492573Ssos pci_read_config(parent, 0x54, 1) | 88592573Ssos (0x01 << devno), 1); 88692573Ssos reg56 = pci_read_config(parent, 0x56, 2); 88792573Ssos reg56 &= ~(0xf << (devno * 4)); 88892573Ssos reg56 |= (0x5 << (devno * 4)); 88992573Ssos pci_write_config(parent, 0x56, reg56, 2); 89093882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 89192573Ssos return; 89292573Ssos } 89392573Ssos } 89492573Ssos if (udmamode >= 4) { 89592573Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 89692573Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 89792573Ssos if (bootverbose) 89892573Ssos ata_prtdev(atadev, "%s setting UDMA4 on ServerWorks chip\n", 89992573Ssos (error) ? "failed" : "success"); 90092573Ssos if (!error) { 90192573Ssos u_int16_t reg56; 90292573Ssos 90392573Ssos pci_write_config(parent, 0x54, 90492573Ssos pci_read_config(parent, 0x54, 1) | 90592573Ssos (0x01 << devno), 1); 90692573Ssos reg56 = pci_read_config(parent, 0x56, 2); 90792573Ssos reg56 &= ~(0xf << (devno * 4)); 90892573Ssos reg56 |= (0x4 << (devno * 4)); 90992573Ssos pci_write_config(parent, 0x56, reg56, 2); 91093882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 91192573Ssos return; 91292573Ssos } 91392573Ssos } 91492573Ssos /* FALLTHROUGH */ 91592573Ssos 91666583Ssos case 0x02111166: /* ServerWorks ROSB4 ATA33 controller */ 91766583Ssos if (udmamode >= 2) { 91890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 91966583Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 92066583Ssos if (bootverbose) 92190215Ssos ata_prtdev(atadev, "%s setting UDMA2 on ServerWorks chip\n", 92266583Ssos (error) ? "failed" : "success"); 92366583Ssos if (!error) { 92470186Ssos u_int16_t reg56; 92570186Ssos 92666583Ssos pci_write_config(parent, 0x54, 92766583Ssos pci_read_config(parent, 0x54, 1) | 92866583Ssos (0x01 << devno), 1); 92966583Ssos reg56 = pci_read_config(parent, 0x56, 2); 93066583Ssos reg56 &= ~(0xf << (devno * 4)); 93166583Ssos reg56 |= (0x2 << (devno * 4)); 93266583Ssos pci_write_config(parent, 0x56, reg56, 2); 93393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 93466583Ssos return; 93566583Ssos } 93666583Ssos } 93766583Ssos if (wdmamode >= 2 && apiomode >= 4) { 93890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 93966583Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 94066583Ssos if (bootverbose) 94190215Ssos ata_prtdev(atadev, "%s setting WDMA2 on ServerWorks chip\n", 94266583Ssos (error) ? "failed" : "success"); 94366583Ssos if (!error) { 94493882Ssos int offset = devno ^ 0x01; 94566583Ssos int word44 = pci_read_config(parent, 0x44, 4); 94666583Ssos 94766583Ssos pci_write_config(parent, 0x54, 94866583Ssos pci_read_config(parent, 0x54, 1) & 94966583Ssos ~(0x01 << devno), 1); 95066583Ssos word44 &= ~(0xff << (offset << 8)); 95166583Ssos word44 |= (0x20 << (offset << 8)); 95266583Ssos pci_write_config(parent, 0x44, 0x20, 4); 95393882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 95466583Ssos return; 95566583Ssos } 95666583Ssos } 95766583Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 95866583Ssos break; 95966583Ssos 96089917Ssos case 0x4d69105a: /* Promise TX2 ATA133 controllers */ 96194037Ssos case 0x5275105a: /* Promise TX2 ATA133 controllers */ 96294426Ssos case 0x6269105a: /* Promise TX2 ATA133 controllers */ 96393882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); 96493882Ssos if (udmamode >= 6 && 96593882Ssos !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { 96690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 96789917Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 96889917Ssos if (bootverbose) 96990215Ssos ata_prtdev(atadev, "%s setting UDMA6 on Promise chip\n", 97089917Ssos (error) ? "failed" : "success"); 97189917Ssos if (!error) { 97293882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 97389917Ssos return; 97489917Ssos } 97589917Ssos } 97689917Ssos /* FALLTHROUGH */ 97789917Ssos 97884413Ssos case 0x4d68105a: /* Promise TX2 ATA100 controllers */ 97988478Ssos case 0x6268105a: /* Promise TX2 ATA100 controllers */ 98093882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); 98193882Ssos if (udmamode >= 5 && 98293882Ssos !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { 98390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 98489917Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 98589917Ssos if (bootverbose) 98690215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", 98789917Ssos (error) ? "failed" : "success"); 98889917Ssos if (!error) { 98993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 99089917Ssos return; 99189917Ssos } 99289917Ssos } 99393882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); 99493882Ssos if (udmamode >= 4 && 99593882Ssos !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { 99690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 99789917Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 99884413Ssos if (bootverbose) 99990215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", 100089917Ssos (error) ? "failed" : "success"); 100184413Ssos if (!error) { 100293882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 100384413Ssos return; 100484413Ssos } 100584413Ssos } 100684413Ssos if (udmamode >= 2) { 100790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 100884413Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 100984413Ssos if (bootverbose) 101090215Ssos ata_prtdev(atadev, "%s setting UDMA on Promise chip\n", 101190215Ssos (error) ? "failed" : "success"); 101284413Ssos if (!error) { 101393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 101484413Ssos return; 101584413Ssos } 101684413Ssos } 101784413Ssos if (wdmamode >= 2 && apiomode >= 4) { 101890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 101984413Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 102084413Ssos if (bootverbose) 102190215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", 102290215Ssos (error) ? "failed" : "success"); 102384413Ssos if (!error) { 102493882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 102584413Ssos return; 102684413Ssos } 102784413Ssos } 102884413Ssos break; 102984413Ssos 103098428Ssos case 0x0d30105a: /* Promise OEM ATA100 controllers */ 103166070Ssos case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */ 103293882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 5 && 103393882Ssos !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) { 103490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 103564307Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 103664307Ssos if (bootverbose) 103790215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", 103864307Ssos (error) ? "failed" : "success"); 103964307Ssos if (!error) { 104093882Ssos promise_timing(atadev, devno, ATA_UDMA5); 104193882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 104264307Ssos return; 104364307Ssos } 104464307Ssos } 104582053Ssos /* FALLTHROUGH */ 104682053Ssos 104798428Ssos case 0x0d38105a: /* Promise FastTrak 66 controllers */ 104882053Ssos case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */ 104993882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 4 && 105093882Ssos !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) { 105190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 105253029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 105352918Ssos if (bootverbose) 105490215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", 105556558Ssos (error) ? "failed" : "success"); 105653681Ssos if (!error) { 105793882Ssos promise_timing(atadev, devno, ATA_UDMA4); 105893882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 105956744Ssos return; 106053681Ssos } 106152918Ssos } 106282053Ssos /* FALLTHROUGH */ 106382053Ssos 106482053Ssos case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */ 106593882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 2) { 106690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 106753029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 106851520Ssos if (bootverbose) 106990215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Promise chip\n", 107056558Ssos (error) ? "failed" : "success"); 107153681Ssos if (!error) { 107293882Ssos promise_timing(atadev, devno, ATA_UDMA2); 107393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 107456744Ssos return; 107553681Ssos } 107645095Ssos } 107793882Ssos if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) { 107890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 107953029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 108051520Ssos if (bootverbose) 108190215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", 108256558Ssos (error) ? "failed" : "success"); 108353681Ssos if (!error) { 108493882Ssos promise_timing(atadev, devno, ATA_WDMA2); 108593882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 108656744Ssos return; 108753681Ssos } 108851520Ssos } 108990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 109084584Ssos ATA_PIO0 + apiomode, 109155333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 109253681Ssos if (bootverbose) 109390215Ssos ata_prtdev(atadev, "%s setting PIO%d on Promise chip\n", 109456558Ssos (error) ? "failed" : "success", 109556558Ssos (apiomode >= 0) ? apiomode : 0); 109693882Ssos promise_timing(atadev, devno, ATA_PIO0 + apiomode); 109790215Ssos atadev->mode = ATA_PIO0 + apiomode; 109856744Ssos return; 109945095Ssos 110085350Ssos case 0x00041103: /* HighPoint HPT366/368/370/372 controllers */ 110190844Ssos case 0x00051103: /* HighPoint HPT372 controllers */ 110290533Ssos case 0x00081103: /* HighPoint HPT374 controllers */ 110393882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 6 && hpt_cable80(atadev) && 110493882Ssos ((chiptype == 0x00041103 && chiprev >= 0x05) || 110593882Ssos (chiptype == 0x00051103 && chiprev >= 0x01) || 110693882Ssos (chiptype == 0x00081103 && chiprev >= 0x07))) { 110790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 110885350Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 110985350Ssos if (bootverbose) 111090215Ssos ata_prtdev(atadev, "%s setting UDMA6 on HighPoint chip\n", 111185350Ssos (error) ? "failed" : "success"); 111285350Ssos if (!error) { 111393882Ssos hpt_timing(atadev, devno, ATA_UDMA6); 111493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 111585350Ssos return; 111685350Ssos } 111785350Ssos } 111893882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 5 && hpt_cable80(atadev) && 111993882Ssos ((chiptype == 0x00041103 && chiprev >= 0x03) || 112093882Ssos (chiptype == 0x00051103 && chiprev >= 0x01) || 112193882Ssos (chiptype == 0x00081103 && chiprev >= 0x07))) { 112290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 112364307Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 112464307Ssos if (bootverbose) 112590215Ssos ata_prtdev(atadev, "%s setting UDMA5 on HighPoint chip\n", 112664307Ssos (error) ? "failed" : "success"); 112764307Ssos if (!error) { 112893882Ssos hpt_timing(atadev, devno, ATA_UDMA5); 112993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 113064307Ssos return; 113164307Ssos } 113264307Ssos } 113393882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 4 && hpt_cable80(atadev)) { 113490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 113553029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 113652067Ssos if (bootverbose) 113790215Ssos ata_prtdev(atadev, "%s setting UDMA4 on HighPoint chip\n", 113856558Ssos (error) ? "failed" : "success"); 113953681Ssos if (!error) { 114093882Ssos hpt_timing(atadev, devno, ATA_UDMA4); 114193882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 114256744Ssos return; 114353681Ssos } 114451520Ssos } 114593882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 2) { 114690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 114753029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 114851520Ssos if (bootverbose) 114990215Ssos ata_prtdev(atadev, "%s setting UDMA2 on HighPoint chip\n", 115056558Ssos (error) ? "failed" : "success"); 115153681Ssos if (!error) { 115293882Ssos hpt_timing(atadev, devno, ATA_UDMA2); 115393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 115456744Ssos return; 115553681Ssos } 115645095Ssos } 115793882Ssos if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) { 115890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 115953029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 116051520Ssos if (bootverbose) 116190215Ssos ata_prtdev(atadev, "%s setting WDMA2 on HighPoint chip\n", 116256558Ssos (error) ? "failed" : "success"); 116353681Ssos if (!error) { 116493882Ssos hpt_timing(atadev, devno, ATA_WDMA2); 116593882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 116656744Ssos return; 116753681Ssos } 116845095Ssos } 116990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 117084584Ssos ATA_PIO0 + apiomode, 117155333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 117253681Ssos if (bootverbose) 117390215Ssos ata_prtdev(atadev, "%s setting PIO%d on HighPoint chip\n", 117456558Ssos (error) ? "failed" : "success", 117556558Ssos (apiomode >= 0) ? apiomode : 0); 117693882Ssos hpt_timing(atadev, devno, ATA_PIO0 + apiomode); 117790215Ssos atadev->mode = ATA_PIO0 + apiomode; 117856744Ssos return; 117945095Ssos 118090572Ssos case 0x000116ca: /* Cenatek Rocket Drive controller */ 118190572Ssos if (wdmamode >= 0 && 118293882Ssos (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 118393882Ssos (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) 118493882Ssos ata_dmacreate(atadev, apiomode, ATA_DMA); 118590572Ssos else 118690572Ssos atadev->mode = ATA_PIO; 118790572Ssos return; 118890572Ssos 118951548Ssos default: /* unknown controller chip */ 119051548Ssos /* better not try generic DMA on ATAPI devices it almost never works */ 119193882Ssos if (ATAPI_DEVICE(atadev)) 119251548Ssos break; 119351548Ssos 119456744Ssos /* if controller says its setup for DMA take the easy way out */ 119556744Ssos /* the downside is we dont know what DMA mode we are in */ 119690572Ssos if ((udmamode >= 0 || wdmamode >= 2) && 119793882Ssos (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 119893882Ssos (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) { 119993882Ssos ata_dmacreate(atadev, apiomode, ATA_DMA); 120056744Ssos return; 120156744Ssos } 120256744Ssos 120351548Ssos /* well, we have no support for this, but try anyways */ 120493882Ssos if ((wdmamode >= 2 && apiomode >= 4) && atadev->channel->r_bmio) { 120590215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 120653029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 120751520Ssos if (bootverbose) 120890215Ssos ata_prtdev(atadev, "%s setting WDMA2 on generic chip\n", 120956558Ssos (error) ? "failed" : "success"); 121053681Ssos if (!error) { 121193882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 121256744Ssos return; 121353681Ssos } 121445095Ssos } 121545095Ssos } 121690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode, 121790572Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 121855333Ssos if (bootverbose) 121990215Ssos ata_prtdev(atadev, "%s setting PIO%d on generic chip\n", 122056988Ssos (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode); 122156988Ssos if (!error) 122290215Ssos atadev->mode = ATA_PIO0 + apiomode; 122357771Ssos else { 122456988Ssos if (bootverbose) 122590215Ssos ata_prtdev(atadev, "using PIO mode set by BIOS\n"); 122690215Ssos atadev->mode = ATA_PIO; 122757771Ssos } 122845095Ssos} 122945095Ssos 123093882Ssosstruct ata_dmasetup_data_cb_args { 123193882Ssos struct ata_dmaentry *dmatab; 123293882Ssos int error; 123393882Ssos}; 123493882Ssos 123593882Ssosstatic void 123693882Ssosata_dmasetupd_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 123793882Ssos{ 123893882Ssos struct ata_dmasetup_data_cb_args *cba = 123993882Ssos (struct ata_dmasetup_data_cb_args *)xsc; 124093882Ssos bus_size_t cnt; 124193882Ssos u_int32_t lastcount; 124293882Ssos int i, j; 124393882Ssos 124493882Ssos cba->error = error; 124593882Ssos if (error != 0) 124693882Ssos return; 124793882Ssos lastcount = j = 0; 124893882Ssos for (i = 0; i < nsegs; i++) { 124993882Ssos /* 125093882Ssos * A maximum segment size was specified for bus_dma_tag_create, but 125193882Ssos * some busdma code does not seem to honor this, so fix up if needed. 125293882Ssos */ 125393882Ssos for (cnt = 0; cnt < segs[i].ds_len; cnt += MAXSEGSZ, j++) { 125493882Ssos cba->dmatab[j].base = htole32(segs[i].ds_addr + cnt); 125593882Ssos lastcount = ulmin(segs[i].ds_len - cnt, MAXSEGSZ) & 0xffff; 125693882Ssos cba->dmatab[j].count = htole32(lastcount); 125793882Ssos } 125893882Ssos } 125993882Ssos cba->dmatab[j - 1].count = htole32(lastcount | ATA_DMA_EOT); 126093882Ssos} 126193882Ssos 126266070Ssosint 126393882Ssosata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count) 126445095Ssos{ 126593882Ssos struct ata_channel *ch = atadev->channel; 126645095Ssos 126790215Ssos if (((uintptr_t)data & ch->alignment) || (count & ch->alignment)) { 126893882Ssos ata_prtdev(atadev, "non aligned DMA transfer attempted\n"); 126945095Ssos return -1; 127066070Ssos } 127145095Ssos 127245095Ssos if (!count) { 127393882Ssos ata_prtdev(atadev, "zero length DMA transfer attempted\n"); 127445095Ssos return -1; 127545095Ssos } 127695010Ssos return 0; 127795010Ssos} 127845095Ssos 127995010Ssosint 128095010Ssosata_dmastart(struct ata_device *atadev, caddr_t data, int32_t count, int dir) 128195010Ssos{ 128295010Ssos struct ata_channel *ch = atadev->channel; 128395010Ssos struct ata_dmastate *ds = &atadev->dmastate; 128495010Ssos struct ata_dmasetup_data_cb_args cba; 128595010Ssos 128695010Ssos if (ds->flags & ATA_DS_ACTIVE) 128795010Ssos panic("ata_dmasetup: transfer active on this device!"); 128895010Ssos 128993882Ssos cba.dmatab = ds->dmatab; 129095010Ssos bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_PREWRITE); 129193882Ssos if (bus_dmamap_load(ds->ddmatag, ds->ddmamap, data, count, 129293882Ssos ata_dmasetupd_cb, &cba, 0) || cba.error) 129395010Ssos return -1; 129493882Ssos 129595010Ssos bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_POSTWRITE); 129693882Ssos bus_dmamap_sync(ds->ddmatag, ds->ddmamap, dir ? BUS_DMASYNC_PREREAD : 129793882Ssos BUS_DMASYNC_PREWRITE); 129895010Ssos 129995010Ssos ch->flags |= ATA_DMA_ACTIVE; 130095010Ssos ds->flags = ATA_DS_ACTIVE; 130193882Ssos if (dir) 130293882Ssos ds->flags |= ATA_DS_READ; 130395010Ssos 130493882Ssos ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, ds->mdmatab); 130590215Ssos ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0); 130690215Ssos ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, 130790215Ssos (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) | 130866070Ssos (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 130990215Ssos ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, 131090215Ssos ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); 131195010Ssos return 0; 131245095Ssos} 131345095Ssos 131466070Ssosint 131593882Ssosata_dmadone(struct ata_device *atadev) 131645095Ssos{ 131793882Ssos struct ata_channel *ch; 131893882Ssos struct ata_dmastate *ds; 131972106Ssos int error; 132072106Ssos 132193882Ssos ch = atadev->channel; 132293882Ssos ds = &atadev->dmastate; 132393882Ssos bus_dmamap_sync(ds->ddmatag, ds->ddmamap, (ds->flags & ATA_DS_READ) != 0 ? 132493882Ssos BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 132593882Ssos bus_dmamap_unload(ds->ddmatag, ds->ddmamap); 132695010Ssos 132790215Ssos ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, 132890215Ssos ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 132990215Ssos error = ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT); 133090215Ssos ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, 133172106Ssos error | ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR); 133295010Ssos ch->flags &= ~ATA_DMA_ACTIVE; 133393882Ssos ds->flags = 0; 133495010Ssos return (error & ATA_BMSTAT_MASK); 133545095Ssos} 133645095Ssos 133766070Ssosint 133890215Ssosata_dmastatus(struct ata_channel *ch) 133945095Ssos{ 134090215Ssos return ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 134145095Ssos} 134245095Ssos 134352067Ssosstatic void 134493882Ssoscyrix_timing(struct ata_device *atadev, int devno, int mode) 134552067Ssos{ 134666070Ssos u_int32_t reg20 = 0x0000e132; 134766070Ssos u_int32_t reg24 = 0x00017771; 134866070Ssos 134966070Ssos switch (mode) { 135066070Ssos case ATA_PIO0: reg20 = 0x0000e132; break; 135166070Ssos case ATA_PIO1: reg20 = 0x00018121; break; 135266070Ssos case ATA_PIO2: reg20 = 0x00024020; break; 135366070Ssos case ATA_PIO3: reg20 = 0x00032010; break; 135466070Ssos case ATA_PIO4: reg20 = 0x00040010; break; 135566070Ssos case ATA_WDMA2: reg24 = 0x00002020; break; 135666070Ssos case ATA_UDMA2: reg24 = 0x00911030; break; 135766070Ssos } 135893882Ssos ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x20, reg20); 135993882Ssos ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x24, reg24); 136066070Ssos} 136189917Ssos 136266070Ssosstatic void 136393882Ssospromise_timing(struct ata_device *atadev, int devno, int mode) 136466070Ssos{ 136556988Ssos u_int32_t timing = 0; 136693882Ssos /* XXX: Endianess */ 136756988Ssos struct promise_timing { 136856988Ssos u_int8_t pa:4; 136956988Ssos u_int8_t prefetch:1; 137056988Ssos u_int8_t iordy:1; 137156988Ssos u_int8_t errdy:1; 137256988Ssos u_int8_t syncin:1; 137356988Ssos u_int8_t pb:5; 137456988Ssos u_int8_t mb:3; 137556988Ssos u_int8_t mc:4; 137656988Ssos u_int8_t dmaw:1; 137756988Ssos u_int8_t dmar:1; 137856988Ssos u_int8_t iordyp:1; 137956988Ssos u_int8_t dmarqp:1; 138056988Ssos u_int8_t reserved:8; 138156988Ssos } *t = (struct promise_timing*)&timing; 138256988Ssos 138356988Ssos t->iordy = 1; t->iordyp = 1; 138456988Ssos if (mode >= ATA_DMA) { 138556988Ssos t->prefetch = 1; t->errdy = 1; t->syncin = 1; 138655333Ssos } 138756988Ssos 138893882Ssos switch (atadev->channel->chiptype) { 138966070Ssos case 0x4d33105a: /* Promise Ultra/Fasttrak 33 */ 139056988Ssos switch (mode) { 139156988Ssos default: 139290215Ssos case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break; 139390215Ssos case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break; 139490215Ssos case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break; 139590215Ssos case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break; 139690215Ssos case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break; 139790215Ssos case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break; 139890215Ssos case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 139956988Ssos } 140056988Ssos break; 140156988Ssos 140298428Ssos case 0x0d38105a: /* Promise Fasttrak 66 */ 140366070Ssos case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */ 140498428Ssos case 0x0d30105a: /* Promise OEM ATA 100 */ 140566070Ssos case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ 140656988Ssos switch (mode) { 140756988Ssos default: 140890215Ssos case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; 140990215Ssos case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break; 141090215Ssos case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break; 141190215Ssos case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break; 141290215Ssos case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break; 141390215Ssos case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; 141490215Ssos case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; 141590215Ssos case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 141690215Ssos case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 141756988Ssos } 141856988Ssos break; 141956988Ssos } 142093882Ssos pci_write_config(device_get_parent(atadev->channel->dev), 142193882Ssos 0x60 + (devno << 2), timing, 4); 142255333Ssos} 142352067Ssos 142455333Ssosstatic void 142593882Ssoshpt_timing(struct ata_device *atadev, int devno, int mode) 142655333Ssos{ 142793882Ssos device_t parent = device_get_parent(atadev->channel->dev); 142893882Ssos u_int32_t chiptype = atadev->channel->chiptype; 142993882Ssos int chiprev = pci_get_revid(parent); 143055333Ssos u_int32_t timing; 143191914Ssos 143293882Ssos if (chiptype == 0x00081103 && chiprev >= 0x07) { 143390844Ssos switch (mode) { /* HPT374 */ 143490533Ssos case ATA_PIO0: timing = 0x0ac1f48a; break; 143590533Ssos case ATA_PIO1: timing = 0x0ac1f465; break; 143690533Ssos case ATA_PIO2: timing = 0x0a81f454; break; 143790533Ssos case ATA_PIO3: timing = 0x0a81f443; break; 143890533Ssos case ATA_PIO4: timing = 0x0a81f442; break; 143991593Ssos case ATA_WDMA2: timing = 0x22808242; break; 144091593Ssos case ATA_UDMA2: timing = 0x120c8242; break; 144191593Ssos case ATA_UDMA4: timing = 0x12ac8242; break; 144291593Ssos case ATA_UDMA5: timing = 0x12848242; break; 144391593Ssos case ATA_UDMA6: timing = 0x12808242; break; 144490533Ssos default: timing = 0x0d029d5e; 144590533Ssos } 144690533Ssos } 144793882Ssos else if ((chiptype == 0x00041103 && chiprev >= 0x05) || 144893882Ssos (chiptype == 0x00051103 && chiprev >= 0x01)) { 144990844Ssos switch (mode) { /* HPT372 */ 145090215Ssos case ATA_PIO0: timing = 0x0d029d5e; break; 145190215Ssos case ATA_PIO1: timing = 0x0d029d26; break; 145290215Ssos case ATA_PIO2: timing = 0x0c829ca6; break; 145390215Ssos case ATA_PIO3: timing = 0x0c829c84; break; 145490215Ssos case ATA_PIO4: timing = 0x0c829c62; break; 145585350Ssos case ATA_WDMA2: timing = 0x2c829262; break; 145690215Ssos case ATA_UDMA2: timing = 0x1c91dc62; break; 145790215Ssos case ATA_UDMA4: timing = 0x1c8ddc62; break; 145890215Ssos case ATA_UDMA5: timing = 0x1c6ddc62; break; 145990215Ssos case ATA_UDMA6: timing = 0x1c81dc62; break; 146085350Ssos default: timing = 0x0d029d5e; 146185350Ssos } 146285350Ssos } 146393882Ssos else if (chiptype == 0x00041103 && chiprev >= 0x03) { 146490844Ssos switch (mode) { /* HPT370 */ 146564307Ssos case ATA_PIO0: timing = 0x06914e57; break; 146664307Ssos case ATA_PIO1: timing = 0x06914e43; break; 146764307Ssos case ATA_PIO2: timing = 0x06514e33; break; 146864307Ssos case ATA_PIO3: timing = 0x06514e22; break; 146964307Ssos case ATA_PIO4: timing = 0x06514e21; break; 147090215Ssos case ATA_WDMA2: timing = 0x26514e21; break; 147190215Ssos case ATA_UDMA2: timing = 0x16494e31; break; 147290215Ssos case ATA_UDMA4: timing = 0x16454e31; break; 147390215Ssos case ATA_UDMA5: timing = 0x16454e31; break; 147464307Ssos default: timing = 0x06514e57; 147552067Ssos } 147664307Ssos pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); 147764307Ssos } 147890844Ssos else { /* HPT36[68] */ 147964307Ssos switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) { 148064307Ssos case 0x85: /* 25Mhz */ 148164307Ssos switch (mode) { 148291914Ssos case ATA_PIO0: timing = 0x40d08585; break; 148391914Ssos case ATA_PIO1: timing = 0x40d08572; break; 148491914Ssos case ATA_PIO2: timing = 0x40ca8542; break; 148591914Ssos case ATA_PIO3: timing = 0x40ca8532; break; 148691914Ssos case ATA_PIO4: timing = 0x40ca8521; break; 148791914Ssos case ATA_WDMA2: timing = 0x20ca8521; break; 148891914Ssos case ATA_UDMA2: timing = 0x10cf8521; break; 148991914Ssos case ATA_UDMA4: timing = 0x10c98521; break; 149064307Ssos default: timing = 0x01208585; 149164307Ssos } 149264307Ssos break; 149364307Ssos default: 149464307Ssos case 0xa7: /* 33MHz */ 149564307Ssos switch (mode) { 149691914Ssos case ATA_PIO0: timing = 0x40d0a7aa; break; 149791914Ssos case ATA_PIO1: timing = 0x40d0a7a3; break; 149891914Ssos case ATA_PIO2: timing = 0x40d0a753; break; 149991914Ssos case ATA_PIO3: timing = 0x40c8a742; break; 150091914Ssos case ATA_PIO4: timing = 0x40c8a731; break; 150191914Ssos case ATA_WDMA2: timing = 0x20c8a731; break; 150291914Ssos case ATA_UDMA2: timing = 0x10caa731; break; 150391914Ssos case ATA_UDMA4: timing = 0x10c9a731; break; 150464307Ssos default: timing = 0x0120a7a7; 150564307Ssos } 150664307Ssos break; 150764307Ssos case 0xd9: /* 40Mhz */ 150864307Ssos switch (mode) { 150991914Ssos case ATA_PIO0: timing = 0x4018d9d9; break; 151091914Ssos case ATA_PIO1: timing = 0x4010d9c7; break; 151191914Ssos case ATA_PIO2: timing = 0x4010d997; break; 151291914Ssos case ATA_PIO3: timing = 0x4010d974; break; 151391914Ssos case ATA_PIO4: timing = 0x4008d963; break; 151491914Ssos case ATA_WDMA2: timing = 0x2008d943; break; 151591914Ssos case ATA_UDMA2: timing = 0x100bd943; break; 151691914Ssos case ATA_UDMA4: timing = 0x100fd943; break; 151764307Ssos default: timing = 0x0120d9d9; 151864307Ssos } 151952067Ssos } 152052067Ssos } 152191914Ssos pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); 152252067Ssos} 152391914Ssos 152491914Ssosstatic int 152593882Ssoshpt_cable80(struct ata_device *atadev) 152691914Ssos{ 152793882Ssos device_t parent = device_get_parent(atadev->channel->dev); 152891914Ssos u_int8_t reg, val, res; 152991914Ssos 153093882Ssos if (atadev->channel->chiptype==0x00081103 && pci_get_function(parent)==1) { 153193882Ssos reg = atadev->channel->unit ? 0x57 : 0x53; 153291914Ssos val = pci_read_config(parent, reg, 1); 153391914Ssos pci_write_config(parent, reg, val | 0x80, 1); 153491914Ssos } 153591914Ssos else { 153691914Ssos reg = 0x5b; 153791914Ssos val = pci_read_config(parent, reg, 1); 153891914Ssos pci_write_config(parent, reg, val & 0xfe, 1); 153991914Ssos } 154093882Ssos res = pci_read_config(parent, 0x5a, 1) & (atadev->channel->unit ? 0x1:0x2); 154191914Ssos pci_write_config(parent, reg, val, 1); 154291914Ssos return !res; 154391914Ssos} 1544