ata-dma.c revision 109529
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 109529 2003-01-19 11:47:32Z sos $ 2945095Ssos */ 3045095Ssos 3145095Ssos#include <sys/param.h> 3245095Ssos#include <sys/systm.h> 3374302Ssos#include <sys/ata.h> 3495533Smike#include <sys/endian.h> 3545095Ssos#include <sys/malloc.h> 3645798Ssos#include <sys/bus.h> 3745095Ssos#include <pci/pcivar.h> 3866106Ssos#include <machine/bus.h> 3972106Ssos#include <sys/rman.h> 4045095Ssos#include <dev/ata/ata-all.h> 4145095Ssos 4252067Ssos/* prototypes */ 4393882Ssosstatic void ata_dmacreate(struct ata_device *, int, int); 4493882Ssosstatic void ata_dmasetupd_cb(void *, bus_dma_segment_t *, int, int); 4593882Ssosstatic void ata_dmasetupc_cb(void *, bus_dma_segment_t *, int, int); 4693882Ssosstatic void cyrix_timing(struct ata_device *, int, int); 4793882Ssosstatic void promise_timing(struct ata_device *, int, int); 4893882Ssosstatic void hpt_timing(struct ata_device *, int, int); 4993882Ssosstatic int hpt_cable80(struct ata_device *); 5052067Ssos 5152067Ssos/* misc defines */ 5293882Ssos#define ATAPI_DEVICE(atadev) \ 5393882Ssos ((atadev->unit == ATA_MASTER && \ 5493882Ssos atadev->channel->devices & ATA_ATAPI_MASTER) || \ 5593882Ssos (atadev->unit == ATA_SLAVE && \ 5693882Ssos atadev->channel->devices & ATA_ATAPI_SLAVE)) 5745720Speter 5893882Ssos#define MAXSEGSZ PAGE_SIZE 5993882Ssos#define MAXTABSZ PAGE_SIZE 6093882Ssos#define MAXCTLDMASZ (2 * (MAXTABSZ + MAXPHYS)) 6193882Ssos 6293882Ssosstruct ata_dc_cb_args { 6393882Ssos bus_addr_t maddr; 6493882Ssos int error; 6593882Ssos}; 6693882Ssos 6793882Ssosstatic void 6893882Ssosata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 6966070Ssos{ 7093882Ssos struct ata_dc_cb_args *cba = (struct ata_dc_cb_args *)xsc; 7166070Ssos 7293882Ssos if (!(cba->error = error)) 7393882Ssos cba->maddr = segs[0].ds_addr; 7493882Ssos} 7593882Ssos 7693882Ssosint 7793882Ssosata_dmaalloc(struct ata_device *atadev) 7893882Ssos{ 7993882Ssos struct ata_channel *ch; 8093882Ssos struct ata_dc_cb_args ccba; 8193882Ssos struct ata_dmastate *ds; 8293882Ssos int error; 8393882Ssos 8493882Ssos ch = atadev->channel; 8593882Ssos ds = &atadev->dmastate; 8693882Ssos if (!ds->cdmatag) { 8793882Ssos if ((error = bus_dma_tag_create(ch->dmatag, 1, PAGE_SIZE, 8893882Ssos BUS_SPACE_MAXADDR_32BIT, 8993882Ssos BUS_SPACE_MAXADDR, NULL, NULL, 9093882Ssos MAXTABSZ, 1, MAXTABSZ, 9193882Ssos BUS_DMA_ALLOCNOW, &ds->cdmatag))) 9293882Ssos return error; 9393882Ssos } 9493882Ssos if (!ds->ddmatag) { 9593882Ssos if ((error = bus_dma_tag_create(ch->dmatag, ch->alignment + 1, 0, 9693882Ssos BUS_SPACE_MAXADDR_32BIT, 9793882Ssos BUS_SPACE_MAXADDR, NULL, NULL, 9893882Ssos MAXPHYS, ATA_DMA_ENTRIES, MAXSEGSZ, 9993882Ssos BUS_DMA_ALLOCNOW, &ds->ddmatag))) 10093882Ssos return error; 10193882Ssos } 10293882Ssos if (!ds->mdmatab) { 10393882Ssos if ((error = bus_dmamem_alloc(ds->cdmatag, (void **)&ds->dmatab, 0, 10493882Ssos &ds->cdmamap))) 10593882Ssos return error; 10693882Ssos 10793882Ssos if ((error = bus_dmamap_load(ds->cdmatag, ds->cdmamap, ds->dmatab, 10893882Ssos MAXTABSZ, ata_dmasetupc_cb, &ccba, 10993882Ssos 0)) != 0 || ccba.error != 0) { 11093882Ssos bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap); 11193882Ssos return error; 11266070Ssos } 11393882Ssos ds->mdmatab = ccba.maddr; 11466070Ssos } 11593882Ssos if (!ds->ddmamap) { 11693882Ssos if ((error = bus_dmamap_create(ds->ddmatag, 0, &ds->ddmamap)) != 0) 11793882Ssos return error; 11893882Ssos } 11993882Ssos return 0; 12066070Ssos} 12166070Ssos 12256744Ssosvoid 12393882Ssosata_dmafree(struct ata_device *atadev) 12445095Ssos{ 12593882Ssos struct ata_dmastate *ds; 12693882Ssos 12793882Ssos ds = &atadev->dmastate; 12893882Ssos if (ds->mdmatab) { 12993882Ssos bus_dmamap_unload(ds->cdmatag, ds->cdmamap); 13093882Ssos bus_dmamem_free(ds->cdmatag, ds->dmatab, ds->cdmamap); 13193882Ssos ds->mdmatab = 0; 13293882Ssos ds->cdmamap = NULL; 13393882Ssos ds->dmatab = NULL; 13493882Ssos } 13593882Ssos if (ds->ddmamap) { 13693882Ssos bus_dmamap_destroy(ds->ddmatag, ds->ddmamap); 13793882Ssos ds->ddmamap = NULL; 13893882Ssos } 13993882Ssos if (ds->cdmatag) { 14093882Ssos bus_dma_tag_destroy(ds->cdmatag); 14193882Ssos ds->cdmatag = NULL; 14293882Ssos } 14393882Ssos if (ds->ddmatag) { 14493882Ssos bus_dma_tag_destroy(ds->ddmatag); 14593882Ssos ds->ddmatag = NULL; 14693882Ssos } 14793882Ssos} 14893882Ssos 14993882Ssosvoid 15093882Ssosata_dmafreetags(struct ata_channel *ch) 15193882Ssos{ 15293882Ssos 15393882Ssos if (ch->dmatag) { 15493882Ssos bus_dma_tag_destroy(ch->dmatag); 15593882Ssos ch->dmatag = NULL; 15693882Ssos } 15793882Ssos} 15893882Ssos 15993882Ssosstatic void 16093882Ssosata_dmacreate(struct ata_device *atadev, int apiomode, int mode) 16193882Ssos{ 16293882Ssos 16393882Ssos atadev->mode = mode; 16493882Ssos if (!atadev->channel->dmatag) { 16593882Ssos if (bus_dma_tag_create(NULL, 1, 0, 16693882Ssos BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 16793882Ssos NULL, NULL, MAXCTLDMASZ, ATA_DMA_ENTRIES, 16893882Ssos BUS_SPACE_MAXSIZE_32BIT, 0, 16993882Ssos &atadev->channel->dmatag)) { 17093882Ssos ata_prtdev(atadev, "DMA tag allocation failed, disabling DMA\n"); 17193882Ssos ata_dmainit(atadev, apiomode, -1, -1); 17293882Ssos } 17393882Ssos } 17493882Ssos} 17593882Ssos 17693882Ssosvoid 17793882Ssosata_dmainit(struct ata_device *atadev, int apiomode, int wdmamode, int udmamode) 17893882Ssos{ 17993882Ssos device_t parent = device_get_parent(atadev->channel->dev); 18093882Ssos int chiptype = atadev->channel->chiptype; 18193882Ssos int chiprev = pci_get_revid(parent); 18293882Ssos int channel = atadev->channel->unit; 18393882Ssos int device = ATA_DEV(atadev->unit); 18493882Ssos int devno = (channel << 1) + device; 18564307Ssos int error; 18645095Ssos 18756744Ssos /* set our most pessimistic default mode */ 18890215Ssos atadev->mode = ATA_PIO; 18956744Ssos 19093882Ssos if (!atadev->channel->r_bmio) 19156744Ssos return; 19245095Ssos 19352067Ssos /* if simplex controller, only allow DMA on primary channel */ 19493882Ssos if (channel == 1) { 19593882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMSTAT_PORT, 19693882Ssos ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 19772106Ssos (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE)); 19893882Ssos if (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 19993882Ssos ATA_BMSTAT_DMA_SIMPLEX) { 20090215Ssos ata_prtdev(atadev, "simplex device, DMA on primary only\n"); 20156744Ssos return; 20252067Ssos } 20352067Ssos } 20452067Ssos 20566070Ssos /* DMA engine address alignment is usually 1 word (2 bytes) */ 20693882Ssos atadev->channel->alignment = 0x1; 20745095Ssos 20885345Ssos#if 1 20993882Ssos if (udmamode > 2 && !atadev->param->hwres_cblid) { 21090215Ssos ata_prtdev(atadev,"DMA limited to UDMA33, non-ATA66 cable or device\n"); 21160829Ssos udmamode = 2; 21260829Ssos } 21385345Ssos#endif 21493882Ssos switch (chiptype) { 21545095Ssos 216100380Sjhb case 0x24cb8086: /* Intel ICH4 */ 21785352Ssos case 0x248a8086: /* Intel ICH3 mobile */ 21885352Ssos case 0x248b8086: /* Intel ICH3 */ 21975553Ssos case 0x244a8086: /* Intel ICH2 mobile */ 22064307Ssos case 0x244b8086: /* Intel ICH2 */ 22164307Ssos if (udmamode >= 5) { 22264307Ssos int32_t mask48, new48; 22364307Ssos int16_t word54; 22464307Ssos 22564307Ssos word54 = pci_read_config(parent, 0x54, 2); 22664307Ssos if (word54 & (0x10 << devno)) { 22790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 22890215Ssos ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY); 22990215Ssos if (bootverbose) 23090215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Intel chip\n", 23164307Ssos (error) ? "failed" : "success"); 23264307Ssos if (!error) { 23364307Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 23464307Ssos new48 = (1 << devno) + (1 << (16 + (devno << 2))); 23564307Ssos pci_write_config(parent, 0x48, 23664307Ssos (pci_read_config(parent, 0x48, 4) & 23764307Ssos ~mask48) | new48, 4); 23890215Ssos pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2); 23993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 24064307Ssos return; 24164307Ssos } 24264307Ssos } 24364307Ssos } 24464479Ssos /* make sure eventual ATA100 mode from the BIOS is disabled */ 24564479Ssos pci_write_config(parent, 0x54, 24664479Ssos pci_read_config(parent, 0x54, 2) & ~(0x1000<<devno),2); 24764307Ssos /* FALLTHROUGH */ 24864307Ssos 24990215Ssos case 0x24118086: /* Intel ICH */ 25090215Ssos case 0x76018086: /* Intel ICH */ 25157391Ssos if (udmamode >= 4) { 25257391Ssos int32_t mask48, new48; 25357391Ssos int16_t word54; 25457391Ssos 25557391Ssos word54 = pci_read_config(parent, 0x54, 2); 25657391Ssos if (word54 & (0x10 << devno)) { 25790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 25890215Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 25990215Ssos if (bootverbose) 26090215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Intel chip\n", 26175553Ssos (error) ? "failed" : "success"); 26257391Ssos if (!error) { 26357391Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 26457391Ssos new48 = (1 << devno) + (2 << (16 + (devno << 2))); 26557391Ssos pci_write_config(parent, 0x48, 26657391Ssos (pci_read_config(parent, 0x48, 4) & 26757391Ssos ~mask48) | new48, 4); 26857391Ssos pci_write_config(parent, 0x54, word54 | (1 << devno), 2); 26993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 27057391Ssos return; 27157391Ssos } 27257391Ssos } 27390215Ssos } 27464479Ssos /* make sure eventual ATA66 mode from the BIOS is disabled */ 27564479Ssos pci_write_config(parent, 0x54, 27664479Ssos pci_read_config(parent, 0x54, 2) & ~(1 << devno), 2); 27757391Ssos /* FALLTHROUGH */ 27857391Ssos 27945095Ssos case 0x71118086: /* Intel PIIX4 */ 28085352Ssos case 0x84CA8086: /* Intel PIIX4 */ 28156138Ssos case 0x71998086: /* Intel PIIX4e */ 28256138Ssos case 0x24218086: /* Intel ICH0 */ 28345095Ssos if (udmamode >= 2) { 28451520Ssos int32_t mask48, new48; 28545095Ssos 28690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 28753029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 28851520Ssos if (bootverbose) 28990215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Intel chip\n", 29075553Ssos (error) ? "failed" : "success"); 29153681Ssos if (!error) { 29253681Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 29353681Ssos new48 = (1 << devno) + (2 << (16 + (devno << 2))); 29457325Ssos pci_write_config(parent, 0x48, 29557325Ssos (pci_read_config(parent, 0x48, 4) & 29653681Ssos ~mask48) | new48, 4); 29793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 29856744Ssos return; 29953681Ssos } 30045095Ssos } 30164479Ssos /* make sure eventual ATA33 mode from the BIOS is disabled */ 30264479Ssos pci_write_config(parent, 0x48, 30364479Ssos pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4); 30445095Ssos /* FALLTHROUGH */ 30545095Ssos 30645095Ssos case 0x70108086: /* Intel PIIX3 */ 30745095Ssos if (wdmamode >= 2 && apiomode >= 4) { 30845095Ssos int32_t mask40, new40, mask44, new44; 30945095Ssos 31045095Ssos /* if SITRE not set doit for both channels */ 31193882Ssos if (!((pci_read_config(parent, 0x40, 4) >> (channel<<8)) & 0x4000)){ 31257325Ssos new40 = pci_read_config(parent, 0x40, 4); 31357325Ssos new44 = pci_read_config(parent, 0x44, 4); 31451520Ssos if (!(new40 & 0x00004000)) { 31551520Ssos new44 &= ~0x0000000f; 31651520Ssos new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8); 31751520Ssos } 31851520Ssos if (!(new40 & 0x40000000)) { 31951520Ssos new44 &= ~0x000000f0; 32051520Ssos new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20); 32151520Ssos } 32251520Ssos new40 |= 0x40004000; 32357325Ssos pci_write_config(parent, 0x40, new40, 4); 32457325Ssos pci_write_config(parent, 0x44, new44, 4); 32545095Ssos } 32690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 32753029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 32851520Ssos if (bootverbose) 32990215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n", 33075553Ssos (error) ? "failed" : "success"); 33153681Ssos if (!error) { 33253681Ssos if (device == ATA_MASTER) { 33353681Ssos mask40 = 0x0000330f; 33453681Ssos new40 = 0x00002307; 33553681Ssos mask44 = 0; 33653681Ssos new44 = 0; 33753681Ssos } 33853681Ssos else { 33953681Ssos mask40 = 0x000000f0; 34053681Ssos new40 = 0x00000070; 34153681Ssos mask44 = 0x0000000f; 34253681Ssos new44 = 0x0000000b; 34353681Ssos } 34493882Ssos if (channel) { 34553681Ssos mask40 <<= 16; 34653681Ssos new40 <<= 16; 34753681Ssos mask44 <<= 4; 34853681Ssos new44 <<= 4; 34953681Ssos } 35057325Ssos pci_write_config(parent, 0x40, 35157325Ssos (pci_read_config(parent, 0x40, 4) & ~mask40)| 35290215Ssos new40, 4); 35357325Ssos pci_write_config(parent, 0x44, 35457325Ssos (pci_read_config(parent, 0x44, 4) & ~mask44)| 35590215Ssos new44, 4); 35693882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 35756744Ssos return; 35845095Ssos } 35951520Ssos } 36053681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 36145095Ssos break; 36245095Ssos 36345095Ssos case 0x12308086: /* Intel PIIX */ 36454544Ssos if (wdmamode >= 2 && apiomode >= 4) { 36554544Ssos int32_t word40; 36654544Ssos 36757325Ssos word40 = pci_read_config(parent, 0x40, 4); 36893882Ssos word40 >>= channel * 16; 36954544Ssos 37054544Ssos /* Check for timing config usable for DMA on controller */ 37154544Ssos if (!((word40 & 0x3300) == 0x2300 && 37293882Ssos ((word40 >> (device ? 4 : 0)) & 1) == 1)) 37354544Ssos break; 37454544Ssos 37590215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 37654544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 37754544Ssos if (bootverbose) 37890215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Intel chip\n", 37956558Ssos (error) ? "failed" : "success"); 38054544Ssos if (!error) { 38193882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 38256744Ssos return; 38354544Ssos } 38454544Ssos } 38545095Ssos break; 38645095Ssos 38752067Ssos case 0x522910b9: /* AcerLabs Aladdin IV/V */ 38875271Ssos /* the older Aladdin doesn't support ATAPI DMA on both master & slave */ 38993882Ssos if (chiprev < 0xc2 && 39093882Ssos atadev->channel->devices & ATA_ATAPI_MASTER && 39193882Ssos atadev->channel->devices & ATA_ATAPI_SLAVE) { 39290215Ssos ata_prtdev(atadev, "two atapi devices on this channel, no DMA\n"); 39353029Ssos break; 39452067Ssos } 39593882Ssos pci_write_config(parent, 0x58 + (channel << 2), 0x00310001, 4); 39693882Ssos if (udmamode >= 5 && chiprev >= 0xc4) { 39790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 39875271Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 39975271Ssos if (bootverbose) 40090215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Acer chip\n", 40175271Ssos (error) ? "failed" : "success"); 40275271Ssos if (!error) { 40375271Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 40452067Ssos 40575271Ssos pci_write_config(parent, 0x4b, 40675271Ssos pci_read_config(parent, 0x4b, 1) | 0x01, 1); 40775271Ssos word54 &= ~(0x000f000f << (devno << 2)); 40875271Ssos word54 |= (0x000f0005 << (devno << 2)); 40975271Ssos pci_write_config(parent, 0x54, word54, 4); 41075271Ssos pci_write_config(parent, 0x53, 41175271Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 41293882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 41375271Ssos return; 41475271Ssos } 41575271Ssos } 41693882Ssos if (udmamode >= 4 && chiprev >= 0xc2) { 41790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 41875271Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 41975271Ssos if (bootverbose) 42090215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Acer chip\n", 42175271Ssos (error) ? "failed" : "success"); 42275271Ssos if (!error) { 42375271Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 42475271Ssos 42575271Ssos pci_write_config(parent, 0x4b, 42675271Ssos pci_read_config(parent, 0x4b, 1) | 0x01, 1); 42775271Ssos word54 &= ~(0x000f000f << (devno << 2)); 42875271Ssos word54 |= (0x00080005 << (devno << 2)); 42975271Ssos pci_write_config(parent, 0x54, word54, 4); 43075271Ssos pci_write_config(parent, 0x53, 43175271Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 43293882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 43375271Ssos return; 43475271Ssos } 43575271Ssos } 43693882Ssos if (udmamode >= 2 && chiprev >= 0x20) { 43790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 43853029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 43951520Ssos if (bootverbose) 44090215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Acer chip\n", 44156558Ssos (error) ? "failed" : "success"); 44253681Ssos if (!error) { 44375271Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 44475271Ssos 44560829Ssos word54 &= ~(0x000f000f << (devno << 2)); 44660829Ssos word54 |= (0x000a0005 << (devno << 2)); 44757325Ssos pci_write_config(parent, 0x54, word54, 4); 44857325Ssos pci_write_config(parent, 0x53, 44957325Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 45093882Ssos atadev->channel->flags |= ATA_ATAPI_DMA_RO; 45193882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 45256744Ssos return; 45353681Ssos } 45451520Ssos } 45570186Ssos 45670186Ssos /* make sure eventual UDMA mode from the BIOS is disabled */ 45770752Ssos pci_write_config(parent, 0x56, pci_read_config(parent, 0x56, 2) & 45870752Ssos ~(0x0008 << (devno << 2)), 2); 45970186Ssos 46053681Ssos if (wdmamode >= 2 && apiomode >= 4) { 46190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 46253029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 46352067Ssos if (bootverbose) 46490215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Acer chip\n", 46556558Ssos (error) ? "failed" : "success"); 46653681Ssos if (!error) { 46757325Ssos pci_write_config(parent, 0x53, 46857325Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 46993882Ssos atadev->channel->flags |= ATA_ATAPI_DMA_RO; 47093882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 47156744Ssos return; 47253681Ssos } 47352067Ssos } 47457771Ssos pci_write_config(parent, 0x53, 47557771Ssos (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1); 47693882Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 47793882Ssos ATA_PIO0 + apiomode, 47893882Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 47993882Ssos if (bootverbose) 48093882Ssos ata_prtdev(atadev, "%s setting PIO%d on Acer chip\n", 48193882Ssos (error) ? "failed" : "success", 48293882Ssos (apiomode >= 0) ? apiomode : 0); 48393882Ssos if (!error) { 48493882Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 48593882Ssos int32_t timing; 48693882Ssos 48793882Ssos switch(ATA_PIO0 + apiomode) { 48893882Ssos case ATA_PIO0: timing = 0x006d0003; 48993882Ssos case ATA_PIO1: timing = 0x00580002; 49093882Ssos case ATA_PIO2: timing = 0x00440001; 49193882Ssos case ATA_PIO3: timing = 0x00330001; 49293882Ssos case ATA_PIO4: timing = 0x00310001; 49393882Ssos default: timing = 0x006d0003; 49493882Ssos } 49593882Ssos pci_write_config(parent, 0x58 + (channel << 2), timing, 4); 49693882Ssos word54 &= ~(0x000f000f << (devno << 2)); 49793882Ssos word54 |= (0x00000004 << (devno << 2)); 49893882Ssos pci_write_config(parent, 0x54, word54, 4); 49993882Ssos atadev->mode = ATA_PIO0 + apiomode; 50093882Ssos return; 50193882Ssos } 50252067Ssos break; 50352067Ssos 50494826Ssos case 0x01bc10de: /* nVIDIA nForce */ 505108949Ssos case 0x006510de: /* nVIDIA nForce2 */ 50693094Ssos case 0x74411022: /* AMD 768 */ 50776584Ssos case 0x74111022: /* AMD 766 */ 50859103Ssos case 0x74091022: /* AMD 756 */ 509103535Ssos case 0x05711106: /* VIA 82C571, 82C586, 82C596, 82C686, 8231,8233,8235 */ 51089917Ssos { 51194826Ssos int via_modes[5][7] = { 51294826Ssos { 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */ 51394826Ssos { 0x00, 0x00, 0xea, 0x00, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */ 51494826Ssos { 0x00, 0x00, 0xf4, 0x00, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */ 51594826Ssos { 0x00, 0x00, 0xf6, 0x00, 0xf2, 0xf1, 0xf0 }, /* VIA ATA133 */ 516108949Ssos { 0x00, 0x00, 0xc0, 0x00, 0xc5, 0xc6, 0xc7 }}; /* AMD/nVIDIA */ 517108949Ssos int reg = 0x53 - devno; 51889917Ssos int *reg_val = NULL; 51994826Ssos char *chip = "VIA"; 52089917Ssos 521103535Ssos if (ata_find_dev(parent, 0x31471106, 0) || /* 8233a */ 522103535Ssos ata_find_dev(parent, 0x31771106, 0)) { /* 8235 */ 52389917Ssos udmamode = imin(udmamode, 6); 52489917Ssos reg_val = via_modes[3]; 52571156Ssos } 52689917Ssos else if (ata_find_dev(parent, 0x06861106, 0x40) || /* 82C686b */ 52789917Ssos ata_find_dev(parent, 0x82311106, 0) || /* 8231 */ 52889917Ssos ata_find_dev(parent, 0x30741106, 0) || /* 8233 */ 52989917Ssos ata_find_dev(parent, 0x31091106, 0)) { /* 8233c */ 53089917Ssos udmamode = imin(udmamode, 5); 53189917Ssos reg_val = via_modes[2]; 53289917Ssos } 53389917Ssos else if (ata_find_dev(parent, 0x06861106, 0x10) || /* 82C686a */ 53489917Ssos ata_find_dev(parent, 0x05961106, 0x12)) { /* 82C596b */ 53589917Ssos udmamode = imin(udmamode, 4); 53689917Ssos reg_val = via_modes[1]; 53789917Ssos } 53893674Ssos else if (ata_find_dev(parent, 0x06861106, 0)) { /* 82C686 */ 53989917Ssos udmamode = imin(udmamode, 2); 54089917Ssos reg_val = via_modes[1]; 54189917Ssos } 54289917Ssos else if (ata_find_dev(parent, 0x05961106, 0) || /* 82C596a */ 54389917Ssos ata_find_dev(parent, 0x05861106, 0x03)) { /* 82C586b */ 54489917Ssos udmamode = imin(udmamode, 2); 54589917Ssos reg_val = via_modes[0]; 54689917Ssos } 54794826Ssos else if (chiptype == 0x74411022 || /* AMD 768 */ 54894826Ssos chiptype == 0x74111022) { /* AMD 766 */ 54994826Ssos udmamode = imin(udmamode, 5); 55094826Ssos reg_val = via_modes[4]; 55194826Ssos chip = "AMD"; 55294826Ssos } 55394826Ssos else if (chiptype == 0x74091022) { /* AMD 756 */ 55494826Ssos udmamode = imin(udmamode, 4); 55594826Ssos reg_val = via_modes[4]; 55694826Ssos chip = "AMD"; 55794826Ssos } 558108949Ssos else if (chiptype == 0x006510de) { /* nForce2 */ 559108949Ssos udmamode = imin(udmamode, 6); 560108949Ssos reg += 0x10; 561108949Ssos reg_val = via_modes[4]; 562108949Ssos chip = "nVidia"; 563108949Ssos } 564108949Ssos else if (chiptype == 0x01bc10de) { /* nForce */ 56594826Ssos udmamode = imin(udmamode, 5); 566108949Ssos reg += 0x10; 56794826Ssos reg_val = via_modes[4]; 568108949Ssos chip = "nVidia"; 56994826Ssos } 57094826Ssos else 57189917Ssos udmamode = 0; 57294826Ssos 573108949Ssos if (udmamode || wdmamode) 574108949Ssos pci_write_config(parent, reg - 0x08, 0x20, 1); 575108949Ssos 57689917Ssos if (udmamode >= 6) { 57790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 57889917Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 57964695Ssos if (bootverbose) 58094826Ssos ata_prtdev(atadev, "%s setting UDMA6 on %s chip\n", 58194826Ssos (error) ? "failed" : "success", chip); 58264695Ssos if (!error) { 583108949Ssos pci_write_config(parent, reg, reg_val[6], 1); 58493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 58571156Ssos return; 58671156Ssos } 58771156Ssos } 58889917Ssos if (udmamode >= 5) { 58990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 59089917Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 59171156Ssos if (bootverbose) 59294826Ssos ata_prtdev(atadev, "%s setting UDMA5 on %s chip\n", 59394826Ssos (error) ? "failed" : "success", chip); 59471156Ssos if (!error) { 595108949Ssos pci_write_config(parent, reg, reg_val[5], 1); 59693882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 59771156Ssos return; 59871156Ssos } 59971156Ssos } 60071156Ssos if (udmamode >= 4) { 60190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 60271156Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 60371156Ssos if (bootverbose) 60494826Ssos ata_prtdev(atadev, "%s setting UDMA4 on %s chip\n", 60594826Ssos (error) ? "failed" : "success", chip); 60671156Ssos if (!error) { 607108949Ssos pci_write_config(parent, reg, reg_val[4], 1); 60893882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 60964695Ssos return; 61064695Ssos } 61156138Ssos } 61264695Ssos if (udmamode >= 2) { 61390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 61464695Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 61564695Ssos if (bootverbose) 61694826Ssos ata_prtdev(atadev, "%s setting UDMA2 on %s chip\n", 61794826Ssos (error) ? "failed" : "success", chip); 61864695Ssos if (!error) { 619108949Ssos pci_write_config(parent, reg, reg_val[2], 1); 62093882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 62164695Ssos return; 62264695Ssos } 62356138Ssos } 62494826Ssos if (wdmamode >= 2 && apiomode >= 4) { 62594826Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 62694826Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 62794826Ssos if (bootverbose) 62894826Ssos ata_prtdev(atadev, "%s setting WDMA2 on %s chip\n", 62994826Ssos (error) ? "failed" : "success", chip); 63094826Ssos if (!error) { 631108949Ssos pci_write_config(parent, reg, 0x0b, 1); 632108949Ssos pci_write_config(parent, reg - 0x08, 0x31, 1); 63394826Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 63494826Ssos return; 63594826Ssos } 63653681Ssos } 63753681Ssos } 63853681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 63953681Ssos break; 64053681Ssos 64154544Ssos case 0x55131039: /* SiS 5591 */ 64290215Ssos if (ata_find_dev(parent, 0x06301039, 0x30) || /* SiS 630 */ 64393674Ssos ata_find_dev(parent, 0x06331039, 0) || /* SiS 633 */ 64493674Ssos ata_find_dev(parent, 0x06351039, 0) || /* SiS 635 */ 64593674Ssos ata_find_dev(parent, 0x06401039, 0) || /* SiS 640 */ 64693674Ssos ata_find_dev(parent, 0x06451039, 0) || /* SiS 645 */ 64793674Ssos ata_find_dev(parent, 0x06501039, 0) || /* SiS 650 */ 64893674Ssos ata_find_dev(parent, 0x07301039, 0) || /* SiS 730 */ 64993674Ssos ata_find_dev(parent, 0x07331039, 0) || /* SiS 733 */ 65093674Ssos ata_find_dev(parent, 0x07351039, 0) || /* SiS 735 */ 65193674Ssos ata_find_dev(parent, 0x07401039, 0) || /* SiS 740 */ 65293674Ssos ata_find_dev(parent, 0x07451039, 0) || /* SiS 745 */ 65393674Ssos ata_find_dev(parent, 0x07501039, 0)) { /* SiS 750 */ 65487198Ssos int8_t reg = 0x40 + (devno << 1); 65587951Ssos int16_t val = pci_read_config(parent, reg, 2) & 0x0fff; 65687198Ssos 65787198Ssos if (udmamode >= 5) { 65890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 65987198Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 66087198Ssos if (bootverbose) 66190215Ssos ata_prtdev(atadev, "%s setting UDMA5 on SiS chip\n", 66287198Ssos (error) ? "failed" : "success"); 66387198Ssos if (!error) { 66487951Ssos pci_write_config(parent, reg, val | 0x8000, 2); 66593882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 66687198Ssos return; 66787198Ssos } 66854544Ssos } 66987198Ssos if (udmamode >= 4) { 67090215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 67187198Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 67287198Ssos if (bootverbose) 67390215Ssos ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n", 67487198Ssos (error) ? "failed" : "success"); 67587198Ssos if (!error) { 67687951Ssos pci_write_config(parent, reg, val | 0x9000, 2); 67793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 67887198Ssos return; 67987198Ssos } 68087198Ssos } 68187198Ssos if (udmamode >= 2) { 68290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 68387198Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 68487198Ssos if (bootverbose) 68590215Ssos ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", 68687198Ssos (error) ? "failed" : "success"); 68787198Ssos if (!error) { 68887951Ssos pci_write_config(parent, reg, val | 0xb000, 2); 68993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 69087198Ssos return; 69187198Ssos } 69287198Ssos } 69387198Ssos } else if (ata_find_dev(parent, 0x05301039, 0) || /* SiS 530 */ 69487198Ssos ata_find_dev(parent, 0x05401039, 0) || /* SiS 540 */ 69587198Ssos ata_find_dev(parent, 0x06201039, 0) || /* SiS 620 */ 69687198Ssos ata_find_dev(parent, 0x06301039, 0)) { /* SiS 630 */ 69787198Ssos int8_t reg = 0x40 + (devno << 1); 69887198Ssos int16_t val = pci_read_config(parent, reg, 2) & 0x0fff; 69987198Ssos 70087198Ssos if (udmamode >= 4) { 70190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 70287198Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 70387198Ssos if (bootverbose) 70490215Ssos ata_prtdev(atadev, "%s setting UDMA4 on SiS chip\n", 70587198Ssos (error) ? "failed" : "success"); 70687198Ssos if (!error) { 70787198Ssos pci_write_config(parent, reg, val | 0x9000, 2); 70893882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 70987198Ssos return; 71087198Ssos } 71187198Ssos } 71287198Ssos if (udmamode >= 2) { 71390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 71487198Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 71587198Ssos if (bootverbose) 71690215Ssos ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", 71787198Ssos (error) ? "failed" : "success"); 71887198Ssos if (!error) { 71987951Ssos pci_write_config(parent, reg, val | 0xa000, 2); 72093882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 72187198Ssos return; 72287198Ssos } 72387198Ssos } 72493882Ssos } else if (udmamode >= 2 && chiprev > 0xc1) { 72590215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 72688478Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 72788478Ssos if (bootverbose) 72890215Ssos ata_prtdev(atadev, "%s setting UDMA2 on SiS chip\n", 72988478Ssos (error) ? "failed" : "success"); 73088478Ssos if (!error) { 73188478Ssos pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); 73293882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 73388478Ssos return; 73487198Ssos } 73554544Ssos } 73654544Ssos if (wdmamode >=2 && apiomode >= 4) { 73790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 73854544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 73954544Ssos if (bootverbose) 74090215Ssos ata_prtdev(atadev, "%s setting WDMA2 on SiS chip\n", 74156558Ssos (error) ? "failed" : "success"); 74254544Ssos if (!error) { 74357325Ssos pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); 74493882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 74556744Ssos return; 74654544Ssos } 74754544Ssos } 74854544Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 74954544Ssos break; 75054544Ssos 751103255Ssos case 0x06801095: /* Sil 0680 ATA133 controller */ 752103255Ssos { 753103255Ssos u_int8_t ureg = 0xac + (device * 0x02) + (channel * 0x10); 754103255Ssos u_int8_t uval = pci_read_config(parent, ureg, 1); 755103255Ssos u_int8_t mreg = channel ? 0x84 : 0x80; 756103255Ssos u_int8_t mask = device ? 0x30 : 0x03; 757103255Ssos u_int8_t mode = pci_read_config(parent, mreg, 1); 758103255Ssos 759103255Ssos /* enable UDMA mode */ 760103255Ssos pci_write_config(parent, mreg, 761103255Ssos (mode & ~mask) | (device ? 0x30 : 0x03), 1); 762103255Ssos if (udmamode >= 6) { 763103255Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 764103255Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 765103255Ssos if (bootverbose) 766103255Ssos ata_prtdev(atadev, "%s setting UDMA6 on Sil chip\n", 767103255Ssos (error) ? "failed" : "success"); 768103255Ssos if (!error) { 769103255Ssos pci_write_config(parent, ureg, (uval & 0x3f) | 0x01, 1); 770103255Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 771103255Ssos return; 772103255Ssos } 773103255Ssos } 774103255Ssos if (udmamode >= 5) { 775103255Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 776103255Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 777103255Ssos if (bootverbose) 778103255Ssos ata_prtdev(atadev, "%s setting UDMA5 on Sil chip\n", 779103255Ssos (error) ? "failed" : "success"); 780103255Ssos if (!error) { 781103255Ssos pci_write_config(parent, ureg, (uval & 0x3f) | 0x02, 1); 782103255Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 783103255Ssos return; 784103255Ssos } 785103255Ssos } 786103255Ssos if (udmamode >= 4) { 787103255Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 788103255Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 789103255Ssos if (bootverbose) 790103255Ssos ata_prtdev(atadev, "%s setting UDMA4 on Sil chip\n", 791103255Ssos (error) ? "failed" : "success"); 792103255Ssos if (!error) { 793103255Ssos pci_write_config(parent, ureg, (uval & 0x3f) | 0x03, 1); 794103255Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 795103255Ssos return; 796103255Ssos } 797103255Ssos } 798103255Ssos if (udmamode >= 2) { 799103255Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 800103255Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 801103255Ssos if (bootverbose) 802103255Ssos ata_prtdev(atadev, "%s setting UDMA2 on Sil chip\n", 803103255Ssos (error) ? "failed" : "success"); 804103255Ssos if (!error) { 805103255Ssos pci_write_config(parent, ureg, (uval & 0x3f) | 0x07, 1); 806103255Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 807103255Ssos return; 808103255Ssos } 809103255Ssos } 810103255Ssos 811103255Ssos /* disable UDMA mode and enable WDMA mode */ 812103255Ssos pci_write_config(parent, mreg, 813103255Ssos (mode & ~mask) | (device ? 0x20 : 0x02), 1); 814103255Ssos if (wdmamode >= 2 && apiomode >= 4) { 815103255Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 816103255Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 817103255Ssos if (bootverbose) 818103255Ssos ata_prtdev(atadev, "%s setting WDMA2 on Sil chip\n", 819103255Ssos (error) ? "failed" : "success"); 820103255Ssos if (!error) { 821103255Ssos pci_write_config(parent, ureg - 0x4, 0x10c1, 2); 822103255Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 823103255Ssos return; 824103255Ssos } 825103255Ssos } 826103255Ssos 827103255Ssos /* restore PIO mode */ 828103255Ssos pci_write_config(parent, mreg, mode, 1); 829103255Ssos } 830103255Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 831103255Ssos break; 832103255Ssos 83366583Ssos case 0x06491095: /* CMD 649 ATA100 controller */ 83466583Ssos if (udmamode >= 5) { 83566583Ssos u_int8_t umode; 83666583Ssos 83790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 83866583Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 83966583Ssos if (bootverbose) 84090215Ssos ata_prtdev(atadev, "%s setting UDMA5 on CMD chip\n", 84166583Ssos (error) ? "failed" : "success"); 84266583Ssos if (!error) { 84393882Ssos umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); 84493882Ssos umode &= ~(device ? 0xca : 0x35); 84593882Ssos umode |= (device ? 0x0a : 0x05); 84693882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); 84793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 84866583Ssos return; 84966583Ssos } 85066583Ssos } 85166583Ssos /* FALLTHROUGH */ 85266583Ssos 85366583Ssos case 0x06481095: /* CMD 648 ATA66 controller */ 85466583Ssos if (udmamode >= 4) { 85566583Ssos u_int8_t umode; 85666583Ssos 85790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 85866583Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 85966583Ssos if (bootverbose) 86090215Ssos ata_prtdev(atadev, "%s setting UDMA4 on CMD chip\n", 86166583Ssos (error) ? "failed" : "success"); 86266583Ssos if (!error) { 86393882Ssos umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); 86493882Ssos umode &= ~(device ? 0xca : 0x35); 86593882Ssos umode |= (device ? 0x4a : 0x15); 86693882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); 86793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 86866583Ssos return; 86966583Ssos } 87066583Ssos } 87166583Ssos if (udmamode >= 2) { 87266583Ssos u_int8_t umode; 87366583Ssos 87490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 87566583Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 87666583Ssos if (bootverbose) 87790215Ssos ata_prtdev(atadev, "%s setting UDMA2 on CMD chip\n", 87866583Ssos (error) ? "failed" : "success"); 87966583Ssos if (!error) { 88093882Ssos umode = pci_read_config(parent, channel ? 0x7b : 0x73, 1); 88193882Ssos umode &= ~(device ? 0xca : 0x35); 88293882Ssos umode |= (device ? 0x42 : 0x11); 88393882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, umode, 1); 88493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 88566583Ssos return; 88666583Ssos } 88766583Ssos } 88866583Ssos /* make sure eventual UDMA mode from the BIOS is disabled */ 88993882Ssos pci_write_config(parent, channel ? 0x7b : 0x73, 89093882Ssos pci_read_config(parent, channel ? 0x7b : 0x73, 1) & 89195010Ssos ~(device ? 0xca : 0x53), 1); 89266583Ssos /* FALLTHROUGH */ 89366583Ssos 89457325Ssos case 0x06461095: /* CMD 646 ATA controller */ 89557325Ssos if (wdmamode >= 2 && apiomode >= 4) { 89690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 89757325Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 89857325Ssos if (bootverbose) 89990215Ssos ata_prtdev(atadev, "%s setting WDMA2 on CMD chip\n", 90057325Ssos error ? "failed" : "success"); 90157325Ssos if (!error) { 90257325Ssos int32_t offset = (devno < 3) ? (devno << 1) : 7; 90357325Ssos 90457325Ssos pci_write_config(parent, 0x54 + offset, 0x3f, 1); 90593882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 90657325Ssos return; 90757325Ssos } 90857325Ssos } 90957325Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 91057325Ssos break; 91157325Ssos 91257477Ssos case 0xc6931080: /* Cypress 82c693 ATA controller */ 91357477Ssos if (wdmamode >= 2 && apiomode >= 4) { 91490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 91557477Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 91657477Ssos if (bootverbose) 91790215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Cypress chip\n", 91857477Ssos error ? "failed" : "success"); 91957477Ssos if (!error) { 92093882Ssos pci_write_config(atadev->channel->dev, 92193882Ssos channel ? 0x4e:0x4c, 0x2020, 2); 92293882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 92357477Ssos return; 92457477Ssos } 92557477Ssos } 92657477Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 92757477Ssos break; 92857477Ssos 92966583Ssos case 0x01021078: /* Cyrix 5530 ATA33 controller */ 93093882Ssos atadev->channel->alignment = 0xf; 93166070Ssos if (udmamode >= 2) { 93290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 93366070Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 93466070Ssos if (bootverbose) 93590215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Cyrix chip\n", 93666070Ssos (error) ? "failed" : "success"); 93766070Ssos if (!error) { 93893882Ssos cyrix_timing(atadev, devno, ATA_UDMA2); 93993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 94066070Ssos return; 94166070Ssos } 94266070Ssos } 94366070Ssos if (wdmamode >= 2 && apiomode >= 4) { 94490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 94566070Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 94666070Ssos if (bootverbose) 94790215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Cyrix chip\n", 94866070Ssos (error) ? "failed" : "success"); 94966070Ssos if (!error) { 95093882Ssos cyrix_timing(atadev, devno, ATA_WDMA2); 95193882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 95266070Ssos return; 95366070Ssos } 95466070Ssos } 95590215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 95684584Ssos ATA_PIO0 + apiomode, ATA_C_F_SETXFER, 95766070Ssos ATA_WAIT_READY); 95866070Ssos if (bootverbose) 95990215Ssos ata_prtdev(atadev, "%s setting %s on Cyrix chip\n", 96066070Ssos (error) ? "failed" : "success", 96184584Ssos ata_mode2str(ATA_PIO0 + apiomode)); 96293882Ssos cyrix_timing(atadev, devno, ATA_PIO0 + apiomode); 96390215Ssos atadev->mode = ATA_PIO0 + apiomode; 96466070Ssos return; 96566070Ssos 96692573Ssos case 0x02121166: /* ServerWorks CSB5 ATA66/100 controller */ 96793882Ssos if (udmamode >= 5 && chiprev >= 0x92) { 96892573Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 96992573Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 97092573Ssos if (bootverbose) 97192573Ssos ata_prtdev(atadev, "%s setting UDMA5 on ServerWorks chip\n", 97292573Ssos (error) ? "failed" : "success"); 97392573Ssos if (!error) { 97492573Ssos u_int16_t reg56; 97592573Ssos 97692573Ssos pci_write_config(parent, 0x54, 97792573Ssos pci_read_config(parent, 0x54, 1) | 97892573Ssos (0x01 << devno), 1); 97992573Ssos reg56 = pci_read_config(parent, 0x56, 2); 98092573Ssos reg56 &= ~(0xf << (devno * 4)); 98192573Ssos reg56 |= (0x5 << (devno * 4)); 98292573Ssos pci_write_config(parent, 0x56, reg56, 2); 98393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 98492573Ssos return; 98592573Ssos } 98692573Ssos } 98792573Ssos if (udmamode >= 4) { 98892573Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 98992573Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 99092573Ssos if (bootverbose) 99192573Ssos ata_prtdev(atadev, "%s setting UDMA4 on ServerWorks chip\n", 99292573Ssos (error) ? "failed" : "success"); 99392573Ssos if (!error) { 99492573Ssos u_int16_t reg56; 99592573Ssos 99692573Ssos pci_write_config(parent, 0x54, 99792573Ssos pci_read_config(parent, 0x54, 1) | 99892573Ssos (0x01 << devno), 1); 99992573Ssos reg56 = pci_read_config(parent, 0x56, 2); 100092573Ssos reg56 &= ~(0xf << (devno * 4)); 100192573Ssos reg56 |= (0x4 << (devno * 4)); 100292573Ssos pci_write_config(parent, 0x56, reg56, 2); 100393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 100492573Ssos return; 100592573Ssos } 100692573Ssos } 100792573Ssos /* FALLTHROUGH */ 100892573Ssos 100966583Ssos case 0x02111166: /* ServerWorks ROSB4 ATA33 controller */ 101066583Ssos if (udmamode >= 2) { 101190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 101266583Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 101366583Ssos if (bootverbose) 101490215Ssos ata_prtdev(atadev, "%s setting UDMA2 on ServerWorks chip\n", 101566583Ssos (error) ? "failed" : "success"); 101666583Ssos if (!error) { 101770186Ssos u_int16_t reg56; 101870186Ssos 101966583Ssos pci_write_config(parent, 0x54, 102066583Ssos pci_read_config(parent, 0x54, 1) | 102166583Ssos (0x01 << devno), 1); 102266583Ssos reg56 = pci_read_config(parent, 0x56, 2); 102366583Ssos reg56 &= ~(0xf << (devno * 4)); 102466583Ssos reg56 |= (0x2 << (devno * 4)); 102566583Ssos pci_write_config(parent, 0x56, reg56, 2); 102693882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 102766583Ssos return; 102866583Ssos } 102966583Ssos } 103066583Ssos if (wdmamode >= 2 && apiomode >= 4) { 103190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 103266583Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 103366583Ssos if (bootverbose) 103490215Ssos ata_prtdev(atadev, "%s setting WDMA2 on ServerWorks chip\n", 103566583Ssos (error) ? "failed" : "success"); 103666583Ssos if (!error) { 103793882Ssos int offset = devno ^ 0x01; 103866583Ssos int word44 = pci_read_config(parent, 0x44, 4); 103966583Ssos 104066583Ssos pci_write_config(parent, 0x54, 104166583Ssos pci_read_config(parent, 0x54, 1) & 104266583Ssos ~(0x01 << devno), 1); 104366583Ssos word44 &= ~(0xff << (offset << 8)); 104466583Ssos word44 |= (0x20 << (offset << 8)); 104566583Ssos pci_write_config(parent, 0x44, 0x20, 4); 104693882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 104766583Ssos return; 104866583Ssos } 104966583Ssos } 105066583Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 105166583Ssos break; 105266583Ssos 105389917Ssos case 0x4d69105a: /* Promise TX2 ATA133 controllers */ 1054109529Ssos case 0x6269105a: /* Promise TX2 ATA133 controllers */ 1055109529Ssos case 0x1275105a: /* Promise TX2 ATA133 controllers */ 105694037Ssos case 0x5275105a: /* Promise TX2 ATA133 controllers */ 1057104298Ssos case 0x7275105a: /* Promise TX2 ATA133 controllers */ 105893882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); 105993882Ssos if (udmamode >= 6 && 106093882Ssos !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { 106190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 106289917Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 106389917Ssos if (bootverbose) 106490215Ssos ata_prtdev(atadev, "%s setting UDMA6 on Promise chip\n", 106589917Ssos (error) ? "failed" : "success"); 106689917Ssos if (!error) { 106793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 106889917Ssos return; 106989917Ssos } 107089917Ssos } 107189917Ssos /* FALLTHROUGH */ 107289917Ssos 107384413Ssos case 0x4d68105a: /* Promise TX2 ATA100 controllers */ 107488478Ssos case 0x6268105a: /* Promise TX2 ATA100 controllers */ 107593882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); 107693882Ssos if (udmamode >= 5 && 107793882Ssos !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { 107890215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 107989917Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 108089917Ssos if (bootverbose) 108190215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", 108289917Ssos (error) ? "failed" : "success"); 108389917Ssos if (!error) { 108493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 108589917Ssos return; 108689917Ssos } 108789917Ssos } 108893882Ssos ATA_OUTB(atadev->channel->r_bmio, ATA_BMDEVSPEC_0, 0x0b); 108993882Ssos if (udmamode >= 4 && 109093882Ssos !(ATA_INB(atadev->channel->r_bmio, ATA_BMDEVSPEC_1) & 0x04)) { 109190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 109289917Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 109384413Ssos if (bootverbose) 109490215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", 109589917Ssos (error) ? "failed" : "success"); 109684413Ssos if (!error) { 109793882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 109884413Ssos return; 109984413Ssos } 110084413Ssos } 110184413Ssos if (udmamode >= 2) { 110290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 110384413Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 110484413Ssos if (bootverbose) 110590215Ssos ata_prtdev(atadev, "%s setting UDMA on Promise chip\n", 110690215Ssos (error) ? "failed" : "success"); 110784413Ssos if (!error) { 110893882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 110984413Ssos return; 111084413Ssos } 111184413Ssos } 111284413Ssos if (wdmamode >= 2 && apiomode >= 4) { 111390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 111484413Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 111584413Ssos if (bootverbose) 111690215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", 111790215Ssos (error) ? "failed" : "success"); 111884413Ssos if (!error) { 111993882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 112084413Ssos return; 112184413Ssos } 112284413Ssos } 112384413Ssos break; 112484413Ssos 112598428Ssos case 0x0d30105a: /* Promise OEM ATA100 controllers */ 112666070Ssos case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */ 112793882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 5 && 112893882Ssos !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) { 112990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 113064307Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 113164307Ssos if (bootverbose) 113290215Ssos ata_prtdev(atadev, "%s setting UDMA5 on Promise chip\n", 113364307Ssos (error) ? "failed" : "success"); 113464307Ssos if (!error) { 113593882Ssos promise_timing(atadev, devno, ATA_UDMA5); 113693882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 113764307Ssos return; 113864307Ssos } 113964307Ssos } 114082053Ssos /* FALLTHROUGH */ 114182053Ssos 114298428Ssos case 0x0d38105a: /* Promise FastTrak 66 controllers */ 114382053Ssos case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */ 114493882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 4 && 114593882Ssos !(pci_read_config(parent, 0x50, 2) & (channel ? 1<<11 : 1<<10))) { 114690215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 114753029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 114852918Ssos if (bootverbose) 114990215Ssos ata_prtdev(atadev, "%s setting UDMA4 on Promise chip\n", 115056558Ssos (error) ? "failed" : "success"); 115153681Ssos if (!error) { 115293882Ssos promise_timing(atadev, devno, ATA_UDMA4); 115393882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 115456744Ssos return; 115553681Ssos } 115652918Ssos } 115782053Ssos /* FALLTHROUGH */ 115882053Ssos 115982053Ssos case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */ 116093882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 2) { 116190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 116253029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 116351520Ssos if (bootverbose) 116490215Ssos ata_prtdev(atadev, "%s setting UDMA2 on Promise chip\n", 116556558Ssos (error) ? "failed" : "success"); 116653681Ssos if (!error) { 116793882Ssos promise_timing(atadev, devno, ATA_UDMA2); 116893882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 116956744Ssos return; 117053681Ssos } 117145095Ssos } 117293882Ssos if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) { 117390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 117453029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 117551520Ssos if (bootverbose) 117690215Ssos ata_prtdev(atadev, "%s setting WDMA2 on Promise chip\n", 117756558Ssos (error) ? "failed" : "success"); 117853681Ssos if (!error) { 117993882Ssos promise_timing(atadev, devno, ATA_WDMA2); 118093882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 118156744Ssos return; 118253681Ssos } 118351520Ssos } 118490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 118584584Ssos ATA_PIO0 + apiomode, 118655333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 118753681Ssos if (bootverbose) 118890215Ssos ata_prtdev(atadev, "%s setting PIO%d on Promise chip\n", 118956558Ssos (error) ? "failed" : "success", 119056558Ssos (apiomode >= 0) ? apiomode : 0); 119193882Ssos promise_timing(atadev, devno, ATA_PIO0 + apiomode); 119290215Ssos atadev->mode = ATA_PIO0 + apiomode; 119356744Ssos return; 119445095Ssos 119585350Ssos case 0x00041103: /* HighPoint HPT366/368/370/372 controllers */ 119690844Ssos case 0x00051103: /* HighPoint HPT372 controllers */ 119790533Ssos case 0x00081103: /* HighPoint HPT374 controllers */ 119893882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 6 && hpt_cable80(atadev) && 119993882Ssos ((chiptype == 0x00041103 && chiprev >= 0x05) || 120093882Ssos (chiptype == 0x00051103 && chiprev >= 0x01) || 120193882Ssos (chiptype == 0x00081103 && chiprev >= 0x07))) { 120290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 120385350Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 120485350Ssos if (bootverbose) 120590215Ssos ata_prtdev(atadev, "%s setting UDMA6 on HighPoint chip\n", 120685350Ssos (error) ? "failed" : "success"); 120785350Ssos if (!error) { 120893882Ssos hpt_timing(atadev, devno, ATA_UDMA6); 120993882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 121085350Ssos return; 121185350Ssos } 121285350Ssos } 121393882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 5 && hpt_cable80(atadev) && 121493882Ssos ((chiptype == 0x00041103 && chiprev >= 0x03) || 121593882Ssos (chiptype == 0x00051103 && chiprev >= 0x01) || 121693882Ssos (chiptype == 0x00081103 && chiprev >= 0x07))) { 121790215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 121864307Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 121964307Ssos if (bootverbose) 122090215Ssos ata_prtdev(atadev, "%s setting UDMA5 on HighPoint chip\n", 122164307Ssos (error) ? "failed" : "success"); 122264307Ssos if (!error) { 122393882Ssos hpt_timing(atadev, devno, ATA_UDMA5); 122493882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 122564307Ssos return; 122664307Ssos } 122764307Ssos } 122893882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 4 && hpt_cable80(atadev)) { 122990215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 123053029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 123152067Ssos if (bootverbose) 123290215Ssos ata_prtdev(atadev, "%s setting UDMA4 on HighPoint chip\n", 123356558Ssos (error) ? "failed" : "success"); 123453681Ssos if (!error) { 123593882Ssos hpt_timing(atadev, devno, ATA_UDMA4); 123693882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 123756744Ssos return; 123853681Ssos } 123951520Ssos } 124093882Ssos if (!ATAPI_DEVICE(atadev) && udmamode >= 2) { 124190215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 124253029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 124351520Ssos if (bootverbose) 124490215Ssos ata_prtdev(atadev, "%s setting UDMA2 on HighPoint chip\n", 124556558Ssos (error) ? "failed" : "success"); 124653681Ssos if (!error) { 124793882Ssos hpt_timing(atadev, devno, ATA_UDMA2); 124893882Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 124956744Ssos return; 125053681Ssos } 125145095Ssos } 125293882Ssos if (!ATAPI_DEVICE(atadev) && wdmamode >= 2 && apiomode >= 4) { 125390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 125453029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 125551520Ssos if (bootverbose) 125690215Ssos ata_prtdev(atadev, "%s setting WDMA2 on HighPoint chip\n", 125756558Ssos (error) ? "failed" : "success"); 125853681Ssos if (!error) { 125993882Ssos hpt_timing(atadev, devno, ATA_WDMA2); 126093882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 126156744Ssos return; 126253681Ssos } 126345095Ssos } 126490215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 126584584Ssos ATA_PIO0 + apiomode, 126655333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 126753681Ssos if (bootverbose) 126890215Ssos ata_prtdev(atadev, "%s setting PIO%d on HighPoint chip\n", 126956558Ssos (error) ? "failed" : "success", 127056558Ssos (apiomode >= 0) ? apiomode : 0); 127193882Ssos hpt_timing(atadev, devno, ATA_PIO0 + apiomode); 127290215Ssos atadev->mode = ATA_PIO0 + apiomode; 127356744Ssos return; 127445095Ssos 1275107562Ssos case 0x00091191: /* Acard ATP865R controller */ 1276107562Ssos case 0x00081191: /* Acard ATP865 controller */ 1277107562Ssos if (ATAPI_DEVICE(atadev)) 1278107562Ssos break; 1279107562Ssos if (udmamode >= 6) { 1280107562Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 1281107562Ssos ATA_UDMA6, ATA_C_F_SETXFER, ATA_WAIT_READY); 1282107562Ssos if (bootverbose) 1283107562Ssos ata_prtdev(atadev, "%s setting up UDMA6 mode on Acard chip\n", 1284107562Ssos (error) ? "failed" : "success"); 1285107562Ssos if (!error) { 1286107562Ssos u_int16_t reg44 = pci_read_config(parent, 0x44, 2); 1287107562Ssos 1288107562Ssos reg44 &= ~(0x000f << (devno << 2)); 1289107562Ssos reg44 |= (0x0007 << (devno << 2)); 1290107562Ssos pci_write_config(parent, 0x44, reg44, 2); 1291107562Ssos pci_write_config(parent, 0x4a, 0xa6, 1); 1292107562Ssos pci_write_config(parent, 0x40 + devno, 0x031, 1); 1293107562Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA6); 1294107562Ssos return; 1295107562Ssos } 1296107562Ssos } 1297107562Ssos if (udmamode >= 5) { 1298107562Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 1299107562Ssos ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 1300107562Ssos if (bootverbose) 1301107562Ssos ata_prtdev(atadev, "%s setting up UDMA5 mode on Acard chip\n", 1302107562Ssos (error) ? "failed" : "success"); 1303107562Ssos if (!error) { 1304107562Ssos u_int16_t reg44 = pci_read_config(parent, 0x44, 2); 1305107562Ssos 1306107562Ssos reg44 &= ~(0x000f << (devno << 2)); 1307107562Ssos reg44 |= (0x0006 << (devno << 2)); 1308107562Ssos pci_write_config(parent, 0x44, reg44, 2); 1309107562Ssos pci_write_config(parent, 0x4a, 0xa6, 1); 1310107562Ssos pci_write_config(parent, 0x40 + devno, 0x031, 1); 1311107562Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA5); 1312107562Ssos return; 1313107562Ssos } 1314107562Ssos } 1315107562Ssos /* FALLTHROUGH */ 1316107562Ssos 1317107562Ssos case 0x00071191: /* Acard ATP860R controller */ 1318107562Ssos case 0x00061191: /* Acard ATP860 controller */ 1319107562Ssos if (ATAPI_DEVICE(atadev)) 1320107562Ssos break; 1321107562Ssos if (udmamode >= 4) { 1322107562Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 1323107562Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 1324107562Ssos if (bootverbose) 1325107562Ssos ata_prtdev(atadev, "%s setting up UDMA4 mode on Acard chip\n", 1326107562Ssos (error) ? "failed" : "success"); 1327107562Ssos if (!error) { 1328107562Ssos u_int16_t reg44 = pci_read_config(parent, 0x44, 2); 1329107562Ssos 1330107562Ssos reg44 &= ~(0x000f << (devno << 2)); 1331107562Ssos reg44 |= (0x0005 << (devno << 2)); 1332107562Ssos pci_write_config(parent, 0x44, reg44, 2); 1333107562Ssos pci_write_config(parent, 0x4a, 0xa6, 1); 1334107562Ssos pci_write_config(parent, 0x40 + devno, 0x031, 1); 1335107562Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA4); 1336107562Ssos return; 1337107562Ssos } 1338107562Ssos } 1339107562Ssos if (udmamode >= 2) { 1340107562Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 1341109010Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 1342107562Ssos if (bootverbose) 1343107562Ssos ata_prtdev(atadev, "%s setting up UDMA2 mode on Acard chip\n", 1344107562Ssos (error) ? "failed" : "success"); 1345107562Ssos if (!error) { 1346107562Ssos u_int16_t reg44 = pci_read_config(parent, 0x44, 2); 1347107562Ssos 1348107562Ssos reg44 &= ~(0x000f << (devno << 2)); 1349107562Ssos reg44 |= (0x0003 << (devno << 2)); 1350107562Ssos pci_write_config(parent, 0x44, reg44, 2); 1351107562Ssos pci_write_config(parent, 0x4a, 0xa6, 1); 1352107562Ssos pci_write_config(parent, 0x40 + devno, 0x031, 1); 1353107562Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 1354107562Ssos return; 1355107562Ssos } 1356107562Ssos } 1357107562Ssos if (wdmamode >= 2 && apiomode >= 4) { 1358107562Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 1359107562Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 1360107562Ssos if (bootverbose) 1361107562Ssos ata_prtdev(atadev, "%s setting up WDMA2 mode on Acard chip\n", 1362107562Ssos (error) ? "failed" : "success"); 1363107562Ssos if (!error) { 1364107562Ssos u_int16_t reg44 = pci_read_config(parent, 0x44, 2); 1365107562Ssos 1366107562Ssos reg44 &= ~(0x000f << (devno << 2)); 1367107562Ssos pci_write_config(parent, 0x44, reg44, 2); 1368107562Ssos pci_write_config(parent, 0x4a, 0xa6, 1); 1369107562Ssos pci_write_config(parent, 0x40 + devno, 0x031, 1); 1370107562Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 1371107562Ssos return; 1372107562Ssos } 1373107562Ssos } 1374107562Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 1375107562Ssos break; 1376107562Ssos 1377107562Ssos case 0x00051191: /* Acard ATP850UF controller */ 1378107562Ssos if (ATAPI_DEVICE(atadev)) 1379107562Ssos break; 1380107562Ssos if (udmamode >= 2) { 1381107562Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 1382107562Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 1383107562Ssos if (bootverbose) 1384107562Ssos ata_prtdev(atadev, "%s setting up UDMA2 mode on Acard chip\n", 1385107562Ssos (error) ? "failed" : "success"); 1386107562Ssos if (!error) { 1387107562Ssos u_int8_t reg54 = pci_read_config(parent, 0x54, 1); 1388107562Ssos 1389107562Ssos reg54 |= (0x03 << (devno << 1)); 1390107562Ssos pci_write_config(parent, 0x54, reg54, 1); 1391107562Ssos pci_write_config(parent, 0x4a, 0xa6, 1); 1392107562Ssos pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); 1393107562Ssos ata_dmacreate(atadev, apiomode, ATA_UDMA2); 1394107562Ssos return; 1395107562Ssos } 1396107562Ssos } 1397107562Ssos if (wdmamode >= 2 && apiomode >= 4) { 1398107562Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 1399107562Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 1400107562Ssos if (bootverbose) 1401107562Ssos ata_prtdev(atadev, "%s setting up WDMA2 mode on Acard chip\n", 1402107562Ssos (error) ? "failed" : "success"); 1403107562Ssos if (!error) { 1404107562Ssos u_int8_t reg54 = pci_read_config(parent, 0x54, 1); 1405107562Ssos 1406107562Ssos reg54 &= ~(0x03 << (devno << 1)); 1407107562Ssos pci_write_config(parent, 0x54, reg54, 1); 1408107562Ssos pci_write_config(parent, 0x4a, 0xa6, 1); 1409107562Ssos pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); 1410107562Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 1411107562Ssos return; 1412107562Ssos } 1413107562Ssos } 1414107562Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 1415107562Ssos break; 1416107562Ssos 141790572Ssos case 0x000116ca: /* Cenatek Rocket Drive controller */ 141890572Ssos if (wdmamode >= 0 && 141993882Ssos (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 142093882Ssos (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) 142193882Ssos ata_dmacreate(atadev, apiomode, ATA_DMA); 142290572Ssos else 142390572Ssos atadev->mode = ATA_PIO; 142490572Ssos return; 142590572Ssos 142651548Ssos default: /* unknown controller chip */ 142751548Ssos /* better not try generic DMA on ATAPI devices it almost never works */ 142893882Ssos if (ATAPI_DEVICE(atadev)) 142951548Ssos break; 143051548Ssos 143156744Ssos /* if controller says its setup for DMA take the easy way out */ 143256744Ssos /* the downside is we dont know what DMA mode we are in */ 143390572Ssos if ((udmamode >= 0 || wdmamode >= 2) && 143493882Ssos (ATA_INB(atadev->channel->r_bmio, ATA_BMSTAT_PORT) & 143593882Ssos (device ? ATA_BMSTAT_DMA_SLAVE : ATA_BMSTAT_DMA_MASTER))) { 143693882Ssos ata_dmacreate(atadev, apiomode, ATA_DMA); 143756744Ssos return; 143856744Ssos } 143956744Ssos 144051548Ssos /* well, we have no support for this, but try anyways */ 144193882Ssos if ((wdmamode >= 2 && apiomode >= 4) && atadev->channel->r_bmio) { 144290215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, 144353029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 144451520Ssos if (bootverbose) 144590215Ssos ata_prtdev(atadev, "%s setting WDMA2 on generic chip\n", 144656558Ssos (error) ? "failed" : "success"); 144753681Ssos if (!error) { 144893882Ssos ata_dmacreate(atadev, apiomode, ATA_WDMA2); 144956744Ssos return; 145053681Ssos } 145145095Ssos } 145245095Ssos } 145390215Ssos error = ata_command(atadev, ATA_C_SETFEATURES, 0, ATA_PIO0 + apiomode, 145490572Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 145555333Ssos if (bootverbose) 145690215Ssos ata_prtdev(atadev, "%s setting PIO%d on generic chip\n", 145756988Ssos (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode); 145856988Ssos if (!error) 145990215Ssos atadev->mode = ATA_PIO0 + apiomode; 146057771Ssos else { 146156988Ssos if (bootverbose) 146290215Ssos ata_prtdev(atadev, "using PIO mode set by BIOS\n"); 146390215Ssos atadev->mode = ATA_PIO; 146457771Ssos } 146545095Ssos} 146645095Ssos 146793882Ssosstruct ata_dmasetup_data_cb_args { 146893882Ssos struct ata_dmaentry *dmatab; 146993882Ssos int error; 147093882Ssos}; 147193882Ssos 147293882Ssosstatic void 147393882Ssosata_dmasetupd_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 147493882Ssos{ 147593882Ssos struct ata_dmasetup_data_cb_args *cba = 147693882Ssos (struct ata_dmasetup_data_cb_args *)xsc; 147793882Ssos bus_size_t cnt; 147893882Ssos u_int32_t lastcount; 147993882Ssos int i, j; 148093882Ssos 148193882Ssos cba->error = error; 148293882Ssos if (error != 0) 148393882Ssos return; 148493882Ssos lastcount = j = 0; 148593882Ssos for (i = 0; i < nsegs; i++) { 148693882Ssos /* 148793882Ssos * A maximum segment size was specified for bus_dma_tag_create, but 148893882Ssos * some busdma code does not seem to honor this, so fix up if needed. 148993882Ssos */ 149093882Ssos for (cnt = 0; cnt < segs[i].ds_len; cnt += MAXSEGSZ, j++) { 149193882Ssos cba->dmatab[j].base = htole32(segs[i].ds_addr + cnt); 149293882Ssos lastcount = ulmin(segs[i].ds_len - cnt, MAXSEGSZ) & 0xffff; 149393882Ssos cba->dmatab[j].count = htole32(lastcount); 149493882Ssos } 149593882Ssos } 149693882Ssos cba->dmatab[j - 1].count = htole32(lastcount | ATA_DMA_EOT); 149793882Ssos} 149893882Ssos 149966070Ssosint 150093882Ssosata_dmasetup(struct ata_device *atadev, caddr_t data, int32_t count) 150145095Ssos{ 150293882Ssos struct ata_channel *ch = atadev->channel; 150345095Ssos 150490215Ssos if (((uintptr_t)data & ch->alignment) || (count & ch->alignment)) { 150593882Ssos ata_prtdev(atadev, "non aligned DMA transfer attempted\n"); 150645095Ssos return -1; 150766070Ssos } 150845095Ssos 150945095Ssos if (!count) { 151093882Ssos ata_prtdev(atadev, "zero length DMA transfer attempted\n"); 151145095Ssos return -1; 151245095Ssos } 151395010Ssos return 0; 151495010Ssos} 151545095Ssos 151695010Ssosint 151795010Ssosata_dmastart(struct ata_device *atadev, caddr_t data, int32_t count, int dir) 151895010Ssos{ 151995010Ssos struct ata_channel *ch = atadev->channel; 152095010Ssos struct ata_dmastate *ds = &atadev->dmastate; 152195010Ssos struct ata_dmasetup_data_cb_args cba; 152295010Ssos 152395010Ssos if (ds->flags & ATA_DS_ACTIVE) 152495010Ssos panic("ata_dmasetup: transfer active on this device!"); 152595010Ssos 1526108931Ssos switch(ch->chiptype) { 1527108931Ssos case 0x0d38105a: /* Promise Fasttrak 66 */ 1528108931Ssos case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */ 1529108931Ssos case 0x0d30105a: /* Promise OEM ATA 100 */ 1530108931Ssos case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ 1531109529Ssos if (ch->flags & ATA_48BIT_ACTIVE) { 1532109529Ssos ATA_OUTB(ch->r_bmio, (ch->unit ? 0x09 : 0x11), 1533109529Ssos ATA_INB(ch->r_bmio, (ch->unit ? 0x09 : 0x11)) | 1534109529Ssos (ch->unit ? 0x08 : 0x02)); 1535109529Ssos ATA_OUTL(ch->r_bmio, (ch->unit ? 0x1c : 0x20), 1536108931Ssos (dir ? 0x05000000 : 0x06000000) | (count >> 1)); 1537109529Ssos } 1538108931Ssos } 1539108931Ssos 154093882Ssos cba.dmatab = ds->dmatab; 154195010Ssos bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_PREWRITE); 154293882Ssos if (bus_dmamap_load(ds->ddmatag, ds->ddmamap, data, count, 154393882Ssos ata_dmasetupd_cb, &cba, 0) || cba.error) 154495010Ssos return -1; 154593882Ssos 154695010Ssos bus_dmamap_sync(ds->cdmatag, ds->cdmamap, BUS_DMASYNC_POSTWRITE); 154793882Ssos bus_dmamap_sync(ds->ddmatag, ds->ddmamap, dir ? BUS_DMASYNC_PREREAD : 154893882Ssos BUS_DMASYNC_PREWRITE); 154995010Ssos 155095010Ssos ch->flags |= ATA_DMA_ACTIVE; 1551108931Ssos ds->flags = dir ? (ATA_DS_ACTIVE | ATA_DS_READ) : ATA_DS_ACTIVE; 155295010Ssos 155393882Ssos ATA_OUTL(ch->r_bmio, ATA_BMDTP_PORT, ds->mdmatab); 155490215Ssos ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0); 155590215Ssos ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT, 1556108931Ssos (ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) | 1557108931Ssos (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 155890215Ssos ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, 1559108931Ssos ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); 156095010Ssos return 0; 156145095Ssos} 156245095Ssos 156366070Ssosint 156493882Ssosata_dmadone(struct ata_device *atadev) 156545095Ssos{ 1566108931Ssos struct ata_channel *ch = atadev->channel; 1567108931Ssos struct ata_dmastate *ds = &atadev->dmastate; 156872106Ssos int error; 156972106Ssos 1570108931Ssos switch(ch->chiptype) { 1571108931Ssos case 0x0d38105a: /* Promise Fasttrak 66 */ 1572108931Ssos case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */ 1573108931Ssos case 0x0d30105a: /* Promise OEM ATA 100 */ 1574108931Ssos case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ 1575109529Ssos if (ch->flags & ATA_48BIT_ACTIVE) { 1576109529Ssos ATA_OUTB(ch->r_bmio, (ch->unit ? 0x09 : 0x11), 1577109529Ssos ATA_INB(ch->r_bmio, (ch->unit ? 0x09 : 0x11)) & 1578109529Ssos ~(ch->unit ? 0x08 : 0x02)); 1579109529Ssos ATA_OUTL(ch->r_bmio, (ch->unit ? 0x1c : 0x20), 0); 1580109529Ssos ch->flags &= ~ATA_48BIT_ACTIVE; 1581109529Ssos } 1582108931Ssos } 1583108931Ssos 1584109529Ssos error = ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT); 1585109529Ssos ATA_OUTB(ch->r_bmio, ATA_BMCMD_PORT, 1586109529Ssos ATA_INB(ch->r_bmio, ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 1587109529Ssos ATA_OUTB(ch->r_bmio, ATA_BMSTAT_PORT,ATA_BMSTAT_INTERRUPT|ATA_BMSTAT_ERROR); 1588109529Ssos 158993882Ssos bus_dmamap_sync(ds->ddmatag, ds->ddmamap, (ds->flags & ATA_DS_READ) != 0 ? 159093882Ssos BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 159193882Ssos bus_dmamap_unload(ds->ddmatag, ds->ddmamap); 1592109529Ssos 159395010Ssos ch->flags &= ~ATA_DMA_ACTIVE; 159493882Ssos ds->flags = 0; 159595010Ssos return (error & ATA_BMSTAT_MASK); 159645095Ssos} 159745095Ssos 159866070Ssosint 159990215Ssosata_dmastatus(struct ata_channel *ch) 160045095Ssos{ 160190215Ssos return ATA_INB(ch->r_bmio, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 160245095Ssos} 160345095Ssos 160452067Ssosstatic void 160593882Ssoscyrix_timing(struct ata_device *atadev, int devno, int mode) 160652067Ssos{ 160766070Ssos u_int32_t reg20 = 0x0000e132; 160866070Ssos u_int32_t reg24 = 0x00017771; 160966070Ssos 161066070Ssos switch (mode) { 161166070Ssos case ATA_PIO0: reg20 = 0x0000e132; break; 161266070Ssos case ATA_PIO1: reg20 = 0x00018121; break; 161366070Ssos case ATA_PIO2: reg20 = 0x00024020; break; 161466070Ssos case ATA_PIO3: reg20 = 0x00032010; break; 161566070Ssos case ATA_PIO4: reg20 = 0x00040010; break; 161666070Ssos case ATA_WDMA2: reg24 = 0x00002020; break; 161766070Ssos case ATA_UDMA2: reg24 = 0x00911030; break; 161866070Ssos } 161993882Ssos ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x20, reg20); 162093882Ssos ATA_OUTL(atadev->channel->r_bmio, (devno << 3) + 0x24, reg24); 162166070Ssos} 162289917Ssos 162366070Ssosstatic void 162493882Ssospromise_timing(struct ata_device *atadev, int devno, int mode) 162566070Ssos{ 162656988Ssos u_int32_t timing = 0; 162793882Ssos /* XXX: Endianess */ 162856988Ssos struct promise_timing { 162956988Ssos u_int8_t pa:4; 163056988Ssos u_int8_t prefetch:1; 163156988Ssos u_int8_t iordy:1; 163256988Ssos u_int8_t errdy:1; 163356988Ssos u_int8_t syncin:1; 163456988Ssos u_int8_t pb:5; 163556988Ssos u_int8_t mb:3; 163656988Ssos u_int8_t mc:4; 163756988Ssos u_int8_t dmaw:1; 163856988Ssos u_int8_t dmar:1; 163956988Ssos u_int8_t iordyp:1; 164056988Ssos u_int8_t dmarqp:1; 164156988Ssos u_int8_t reserved:8; 164256988Ssos } *t = (struct promise_timing*)&timing; 164356988Ssos 164456988Ssos t->iordy = 1; t->iordyp = 1; 164556988Ssos if (mode >= ATA_DMA) { 164656988Ssos t->prefetch = 1; t->errdy = 1; t->syncin = 1; 164755333Ssos } 164856988Ssos 164993882Ssos switch (atadev->channel->chiptype) { 165066070Ssos case 0x4d33105a: /* Promise Ultra/Fasttrak 33 */ 165156988Ssos switch (mode) { 165256988Ssos default: 165390215Ssos case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break; 165490215Ssos case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break; 165590215Ssos case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break; 165690215Ssos case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break; 165790215Ssos case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break; 165890215Ssos case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break; 165990215Ssos case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 166056988Ssos } 166156988Ssos break; 166256988Ssos 166398428Ssos case 0x0d38105a: /* Promise Fasttrak 66 */ 166466070Ssos case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */ 166598428Ssos case 0x0d30105a: /* Promise OEM ATA 100 */ 166666070Ssos case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ 166756988Ssos switch (mode) { 166856988Ssos default: 166990215Ssos case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; 167090215Ssos case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break; 167190215Ssos case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break; 167290215Ssos case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break; 167390215Ssos case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break; 167490215Ssos case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; 167590215Ssos case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; 167690215Ssos case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 167790215Ssos case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 167856988Ssos } 167956988Ssos break; 168056988Ssos } 168193882Ssos pci_write_config(device_get_parent(atadev->channel->dev), 168293882Ssos 0x60 + (devno << 2), timing, 4); 168355333Ssos} 168452067Ssos 168555333Ssosstatic void 168693882Ssoshpt_timing(struct ata_device *atadev, int devno, int mode) 168755333Ssos{ 168893882Ssos device_t parent = device_get_parent(atadev->channel->dev); 168993882Ssos u_int32_t chiptype = atadev->channel->chiptype; 169093882Ssos int chiprev = pci_get_revid(parent); 169155333Ssos u_int32_t timing; 169291914Ssos 169393882Ssos if (chiptype == 0x00081103 && chiprev >= 0x07) { 169490844Ssos switch (mode) { /* HPT374 */ 169590533Ssos case ATA_PIO0: timing = 0x0ac1f48a; break; 169690533Ssos case ATA_PIO1: timing = 0x0ac1f465; break; 169790533Ssos case ATA_PIO2: timing = 0x0a81f454; break; 169890533Ssos case ATA_PIO3: timing = 0x0a81f443; break; 169990533Ssos case ATA_PIO4: timing = 0x0a81f442; break; 170091593Ssos case ATA_WDMA2: timing = 0x22808242; break; 170191593Ssos case ATA_UDMA2: timing = 0x120c8242; break; 170291593Ssos case ATA_UDMA4: timing = 0x12ac8242; break; 170391593Ssos case ATA_UDMA5: timing = 0x12848242; break; 170491593Ssos case ATA_UDMA6: timing = 0x12808242; break; 170590533Ssos default: timing = 0x0d029d5e; 170690533Ssos } 170790533Ssos } 170893882Ssos else if ((chiptype == 0x00041103 && chiprev >= 0x05) || 170993882Ssos (chiptype == 0x00051103 && chiprev >= 0x01)) { 171090844Ssos switch (mode) { /* HPT372 */ 171190215Ssos case ATA_PIO0: timing = 0x0d029d5e; break; 171290215Ssos case ATA_PIO1: timing = 0x0d029d26; break; 171390215Ssos case ATA_PIO2: timing = 0x0c829ca6; break; 171490215Ssos case ATA_PIO3: timing = 0x0c829c84; break; 171590215Ssos case ATA_PIO4: timing = 0x0c829c62; break; 171685350Ssos case ATA_WDMA2: timing = 0x2c829262; break; 171790215Ssos case ATA_UDMA2: timing = 0x1c91dc62; break; 171890215Ssos case ATA_UDMA4: timing = 0x1c8ddc62; break; 171990215Ssos case ATA_UDMA5: timing = 0x1c6ddc62; break; 172090215Ssos case ATA_UDMA6: timing = 0x1c81dc62; break; 172185350Ssos default: timing = 0x0d029d5e; 172285350Ssos } 172385350Ssos } 172493882Ssos else if (chiptype == 0x00041103 && chiprev >= 0x03) { 172590844Ssos switch (mode) { /* HPT370 */ 172664307Ssos case ATA_PIO0: timing = 0x06914e57; break; 172764307Ssos case ATA_PIO1: timing = 0x06914e43; break; 172864307Ssos case ATA_PIO2: timing = 0x06514e33; break; 172964307Ssos case ATA_PIO3: timing = 0x06514e22; break; 173064307Ssos case ATA_PIO4: timing = 0x06514e21; break; 173190215Ssos case ATA_WDMA2: timing = 0x26514e21; break; 173290215Ssos case ATA_UDMA2: timing = 0x16494e31; break; 173390215Ssos case ATA_UDMA4: timing = 0x16454e31; break; 173490215Ssos case ATA_UDMA5: timing = 0x16454e31; break; 173564307Ssos default: timing = 0x06514e57; 173652067Ssos } 173764307Ssos pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); 173864307Ssos } 173990844Ssos else { /* HPT36[68] */ 174064307Ssos switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) { 174164307Ssos case 0x85: /* 25Mhz */ 174264307Ssos switch (mode) { 174391914Ssos case ATA_PIO0: timing = 0x40d08585; break; 174491914Ssos case ATA_PIO1: timing = 0x40d08572; break; 174591914Ssos case ATA_PIO2: timing = 0x40ca8542; break; 174691914Ssos case ATA_PIO3: timing = 0x40ca8532; break; 174791914Ssos case ATA_PIO4: timing = 0x40ca8521; break; 174891914Ssos case ATA_WDMA2: timing = 0x20ca8521; break; 174991914Ssos case ATA_UDMA2: timing = 0x10cf8521; break; 175091914Ssos case ATA_UDMA4: timing = 0x10c98521; break; 175164307Ssos default: timing = 0x01208585; 175264307Ssos } 175364307Ssos break; 175464307Ssos default: 175564307Ssos case 0xa7: /* 33MHz */ 175664307Ssos switch (mode) { 175791914Ssos case ATA_PIO0: timing = 0x40d0a7aa; break; 175891914Ssos case ATA_PIO1: timing = 0x40d0a7a3; break; 175991914Ssos case ATA_PIO2: timing = 0x40d0a753; break; 176091914Ssos case ATA_PIO3: timing = 0x40c8a742; break; 176191914Ssos case ATA_PIO4: timing = 0x40c8a731; break; 176291914Ssos case ATA_WDMA2: timing = 0x20c8a731; break; 176391914Ssos case ATA_UDMA2: timing = 0x10caa731; break; 176491914Ssos case ATA_UDMA4: timing = 0x10c9a731; break; 176564307Ssos default: timing = 0x0120a7a7; 176664307Ssos } 176764307Ssos break; 176864307Ssos case 0xd9: /* 40Mhz */ 176964307Ssos switch (mode) { 177091914Ssos case ATA_PIO0: timing = 0x4018d9d9; break; 177191914Ssos case ATA_PIO1: timing = 0x4010d9c7; break; 177291914Ssos case ATA_PIO2: timing = 0x4010d997; break; 177391914Ssos case ATA_PIO3: timing = 0x4010d974; break; 177491914Ssos case ATA_PIO4: timing = 0x4008d963; break; 177591914Ssos case ATA_WDMA2: timing = 0x2008d943; break; 177691914Ssos case ATA_UDMA2: timing = 0x100bd943; break; 177791914Ssos case ATA_UDMA4: timing = 0x100fd943; break; 177864307Ssos default: timing = 0x0120d9d9; 177964307Ssos } 178052067Ssos } 178152067Ssos } 178291914Ssos pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); 178352067Ssos} 178491914Ssos 178591914Ssosstatic int 178693882Ssoshpt_cable80(struct ata_device *atadev) 178791914Ssos{ 178893882Ssos device_t parent = device_get_parent(atadev->channel->dev); 178991914Ssos u_int8_t reg, val, res; 179091914Ssos 179193882Ssos if (atadev->channel->chiptype==0x00081103 && pci_get_function(parent)==1) { 179293882Ssos reg = atadev->channel->unit ? 0x57 : 0x53; 179391914Ssos val = pci_read_config(parent, reg, 1); 179491914Ssos pci_write_config(parent, reg, val | 0x80, 1); 179591914Ssos } 179691914Ssos else { 179791914Ssos reg = 0x5b; 179891914Ssos val = pci_read_config(parent, reg, 1); 179991914Ssos pci_write_config(parent, reg, val & 0xfe, 1); 180091914Ssos } 180193882Ssos res = pci_read_config(parent, 0x5a, 1) & (atadev->channel->unit ? 0x1:0x2); 180291914Ssos pci_write_config(parent, reg, val, 1); 180391914Ssos return !res; 180491914Ssos} 1805