ata-dma.c revision 70186
190075Sobrien/*- 2117395Skan * Copyright (c) 1998,1999,2000 S�ren Schmidt 352284Sobrien * All rights reserved. 490075Sobrien * 552284Sobrien * Redistribution and use in source and binary forms, with or without 690075Sobrien * modification, are permitted provided that the following conditions 790075Sobrien * are met: 890075Sobrien * 1. Redistributions of source code must retain the above copyright 990075Sobrien * notice, this list of conditions and the following disclaimer, 1052284Sobrien * without modification, immediately at the beginning of the file. 1190075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1290075Sobrien * notice, this list of conditions and the following disclaimer in the 1390075Sobrien * documentation and/or other materials provided with the distribution. 1490075Sobrien * 3. The name of the author may not be used to endorse or promote products 1552284Sobrien * derived from this software without specific prior written permission. 1652284Sobrien * 1790075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1890075Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1990075Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2052284Sobrien * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2152284Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2290075Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2352284Sobrien * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2452284Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2552284Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2652284Sobrien * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2752284Sobrien * 2852284Sobrien * $FreeBSD: head/sys/dev/ata/ata-dma.c 70186 2000-12-19 10:37:03Z sos $ 2952284Sobrien */ 3052284Sobrien 3152284Sobrien#include "pci.h" 3252284Sobrien#include <sys/param.h> 3352284Sobrien#include <sys/systm.h> 3452284Sobrien#include <sys/bio.h> 3552284Sobrien#include <sys/malloc.h> 3652284Sobrien#include <sys/bus.h> 3752284Sobrien#include <sys/disk.h> 3852284Sobrien#include <sys/devicestat.h> 3952284Sobrien#include <vm/vm.h> 4052284Sobrien#include <vm/pmap.h> 4152284Sobrien#if NPCI > 0 4252284Sobrien#include <pci/pcivar.h> 4352284Sobrien#endif 4452284Sobrien#include <machine/bus.h> 4552284Sobrien#include <dev/ata/ata-all.h> 4652284Sobrien 4752284Sobrien#if NPCI > 0 4852284Sobrien 4952284Sobrien/* prototypes */ 5052284Sobrienstatic void cyrix_timing(struct ata_softc *, int, int); 5152284Sobrienstatic void promise_timing(struct ata_softc *, int, int); 5252284Sobrienstatic void hpt_timing(struct ata_softc *, int, int); 5352284Sobrien 5452284Sobrien/* misc defines */ 5552284Sobrien#ifdef __alpha__ 5652284Sobrien#undef vtophys 5752284Sobrien#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) 5852284Sobrien#endif 5952284Sobrien 6052284Sobrienvoid * 6152284Sobrienata_dmaalloc(struct ata_softc *scp, int device) 62117395Skan{ 6390075Sobrien void *dmatab; 6452284Sobrien 6590075Sobrien if ((dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) { 6690075Sobrien if (((uintptr_t)dmatab >> PAGE_SHIFT) ^ 6790075Sobrien (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) { 6852284Sobrien ata_printf(scp, device, "dmatab crosses page boundary, no DMA\n"); 6990075Sobrien free(dmatab, M_DEVBUF); 7090075Sobrien dmatab = NULL; 7190075Sobrien } 7290075Sobrien } 7390075Sobrien return dmatab; 7490075Sobrien} 7590075Sobrien 7690075Sobrienvoid 7790075Sobrienata_dmainit(struct ata_softc *scp, int device, 7890075Sobrien int apiomode, int wdmamode, int udmamode) 7990075Sobrien{ 8090075Sobrien device_t parent = device_get_parent(scp->dev); 8190075Sobrien int devno = (scp->channel << 1) + ATA_DEV(device); 8290075Sobrien int error; 8352284Sobrien 8490075Sobrien /* set our most pessimistic default mode */ 8590075Sobrien scp->mode[ATA_DEV(device)] = ATA_PIO; 8690075Sobrien 8790075Sobrien if (!scp->bmaddr) 8890075Sobrien return; 8990075Sobrien 9090075Sobrien /* if simplex controller, only allow DMA on primary channel */ 9190075Sobrien if (scp->channel == 1) { 9290075Sobrien outb(scp->bmaddr + ATA_BMSTAT_PORT, inb(scp->bmaddr + ATA_BMSTAT_PORT) & 9390075Sobrien (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE)); 9490075Sobrien if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) { 9590075Sobrien ata_printf(scp, device, "simplex device, DMA on primary only\n"); 9690075Sobrien return; 9790075Sobrien } 9852284Sobrien } 9990075Sobrien 10090075Sobrien /* DMA engine address alignment is usually 1 word (2 bytes) */ 10190075Sobrien scp->alignment = 0x1; 10290075Sobrien 10390075Sobrien if (udmamode > 2 && !ATA_PARAM(scp, device)->cblid) { 10490075Sobrien ata_printf(scp, device, 10590075Sobrien "DMA limited to UDMA33, non-ATA66 compliant cable\n"); 10652284Sobrien udmamode = 2; 10790075Sobrien } 10890075Sobrien 10952284Sobrien switch (scp->chiptype) { 110117395Skan 11190075Sobrien case 0x244b8086: /* Intel ICH2 */ 11290075Sobrien if (udmamode >= 5) { 11390075Sobrien int32_t mask48, new48; 11452284Sobrien int16_t word54; 11590075Sobrien 11690075Sobrien word54 = pci_read_config(parent, 0x54, 2); 11790075Sobrien if (word54 & (0x10 << devno)) { 11890075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 11990075Sobrien ATA_UDMA5, ATA_C_F_SETXFER,ATA_WAIT_READY); 12052284Sobrien if (bootverbose) 12190075Sobrien ata_printf(scp, device, 12290075Sobrien "%s setting UDMA5 on ICH2 chip\n", 123117395Skan (error) ? "failed" : "success"); 12452284Sobrien if (!error) { 12590075Sobrien mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 12690075Sobrien new48 = (1 << devno) + (1 << (16 + (devno << 2))); 127117395Skan pci_write_config(parent, 0x48, 12890075Sobrien (pci_read_config(parent, 0x48, 4) & 129117395Skan ~mask48) | new48, 4); 130117395Skan pci_write_config(parent, 0x54, word54 | (0x1000<<devno), 2); 13190075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA5; 13252284Sobrien return; 13390075Sobrien } 13490075Sobrien } 13590075Sobrien } 13652284Sobrien /* make sure eventual ATA100 mode from the BIOS is disabled */ 13790075Sobrien pci_write_config(parent, 0x54, 13890075Sobrien pci_read_config(parent, 0x54, 2) & ~(0x1000<<devno),2); 13990075Sobrien /* FALLTHROUGH */ 14090075Sobrien 14152284Sobrien case 0x24118086: /* Intel ICH */ 14290075Sobrien if (udmamode >= 4) { 14390075Sobrien int32_t mask48, new48; 14490075Sobrien int16_t word54; 14590075Sobrien 146117395Skan word54 = pci_read_config(parent, 0x54, 2); 14790075Sobrien if (word54 & (0x10 << devno)) { 14890075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 14990075Sobrien ATA_UDMA4, ATA_C_F_SETXFER,ATA_WAIT_READY); 150117395Skan if (bootverbose) 15190075Sobrien ata_printf(scp, device, 152117395Skan "%s setting UDMA4 on ICH%s chip\n", 15390075Sobrien (error) ? "failed" : "success", 15490075Sobrien (scp->chiptype == 0x244b8086) ? "2" : ""); 15590075Sobrien if (!error) { 156117395Skan mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 15790075Sobrien new48 = (1 << devno) + (2 << (16 + (devno << 2))); 15890075Sobrien pci_write_config(parent, 0x48, 15990075Sobrien (pci_read_config(parent, 0x48, 4) & 16090075Sobrien ~mask48) | new48, 4); 161117395Skan pci_write_config(parent, 0x54, word54 | (1 << devno), 2); 162117395Skan scp->mode[ATA_DEV(device)] = ATA_UDMA4; 16390075Sobrien return; 16490075Sobrien } 165117395Skan } 166117395Skan } 16790075Sobrien /* make sure eventual ATA66 mode from the BIOS is disabled */ 16890075Sobrien pci_write_config(parent, 0x54, 16990075Sobrien pci_read_config(parent, 0x54, 2) & ~(1 << devno), 2); 170117395Skan /* FALLTHROUGH */ 17190075Sobrien 17290075Sobrien case 0x71118086: /* Intel PIIX4 */ 17390075Sobrien case 0x71998086: /* Intel PIIX4e */ 17490075Sobrien case 0x24218086: /* Intel ICH0 */ 17590075Sobrien if (udmamode >= 2) { 17690075Sobrien int32_t mask48, new48; 177117395Skan 17890075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 17990075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 18090075Sobrien if (bootverbose) 18190075Sobrien ata_printf(scp, device, "%s setting UDMA2 on %s chip\n", 18290075Sobrien (error) ? "failed" : "success", 18390075Sobrien (scp->chiptype == 0x244b8086) ? "ICH2" : 18452284Sobrien (scp->chiptype == 0x24118086) ? "ICH" : 18552284Sobrien (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); 18690075Sobrien if (!error) { 18752284Sobrien mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 18890075Sobrien new48 = (1 << devno) + (2 << (16 + (devno << 2))); 18990075Sobrien pci_write_config(parent, 0x48, 19090075Sobrien (pci_read_config(parent, 0x48, 4) & 19152284Sobrien ~mask48) | new48, 4); 19290075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 19352284Sobrien return; 19490075Sobrien } 19590075Sobrien } 19690075Sobrien /* make sure eventual ATA33 mode from the BIOS is disabled */ 19752284Sobrien pci_write_config(parent, 0x48, 19890075Sobrien pci_read_config(parent, 0x48, 4) & ~(1 << devno), 4); 19952284Sobrien /* FALLTHROUGH */ 20090075Sobrien 20190075Sobrien case 0x70108086: /* Intel PIIX3 */ 20252284Sobrien if (wdmamode >= 2 && apiomode >= 4) { 20390075Sobrien int32_t mask40, new40, mask44, new44; 20490075Sobrien 20590075Sobrien /* if SITRE not set doit for both channels */ 20690075Sobrien if (!((pci_read_config(parent,0x40,4)>>(scp->channel<<8))&0x4000)) { 20790075Sobrien new40 = pci_read_config(parent, 0x40, 4); 20890075Sobrien new44 = pci_read_config(parent, 0x44, 4); 20990075Sobrien if (!(new40 & 0x00004000)) { 210117395Skan new44 &= ~0x0000000f; 211117395Skan new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8); 21290075Sobrien } 21390075Sobrien if (!(new40 & 0x40000000)) { 21490075Sobrien new44 &= ~0x000000f0; 21590075Sobrien new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20); 21690075Sobrien } 21790075Sobrien new40 |= 0x40004000; 21890075Sobrien pci_write_config(parent, 0x40, new40, 4); 21990075Sobrien pci_write_config(parent, 0x44, new44, 4); 22090075Sobrien } 22190075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 22290075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 22352284Sobrien if (bootverbose) 22490075Sobrien ata_printf(scp, device, "%s setting WDMA2 on %s chip\n", 22590075Sobrien (error) ? "failed" : "success", 22690075Sobrien (scp->chiptype == 0x244b8086) ? "ICH2" : 22752284Sobrien (scp->chiptype == 0x24118086) ? "ICH" : 22890075Sobrien (scp->chiptype == 0x24218086) ? "ICH0" : 22990075Sobrien (scp->chiptype == 0x70108086) ? "PIIX3":"PIIX4"); 23052284Sobrien if (!error) { 23190075Sobrien if (device == ATA_MASTER) { 23290075Sobrien mask40 = 0x0000330f; 23390075Sobrien new40 = 0x00002307; 23452284Sobrien mask44 = 0; 23590075Sobrien new44 = 0; 23690075Sobrien } 23790075Sobrien else { 23852284Sobrien mask40 = 0x000000f0; 23990075Sobrien new40 = 0x00000070; 24090075Sobrien mask44 = 0x0000000f; 24190075Sobrien new44 = 0x0000000b; 24290075Sobrien } 24390075Sobrien if (scp->channel) { 24490075Sobrien mask40 <<= 16; 24590075Sobrien new40 <<= 16; 24690075Sobrien mask44 <<= 4; 24790075Sobrien new44 <<= 4; 24890075Sobrien } 24990075Sobrien pci_write_config(parent, 0x40, 25090075Sobrien (pci_read_config(parent, 0x40, 4) & ~mask40)| 25190075Sobrien new40, 4); 25290075Sobrien pci_write_config(parent, 0x44, 25390075Sobrien (pci_read_config(parent, 0x44, 4) & ~mask44)| 25490075Sobrien new44, 4); 25590075Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 25690075Sobrien return; 25752284Sobrien } 25890075Sobrien } 25990075Sobrien /* we could set PIO mode timings, but we assume the BIOS did that */ 26090075Sobrien break; 26152284Sobrien 262117395Skan case 0x12308086: /* Intel PIIX */ 26390075Sobrien if (wdmamode >= 2 && apiomode >= 4) { 264117395Skan int32_t word40; 26590075Sobrien 26652284Sobrien word40 = pci_read_config(parent, 0x40, 4); 26790075Sobrien word40 >>= scp->channel * 16; 26852284Sobrien 26990075Sobrien /* Check for timing config usable for DMA on controller */ 27090075Sobrien if (!((word40 & 0x3300) == 0x2300 && 27190075Sobrien ((word40 >> (device == ATA_MASTER ? 0 : 4)) & 1) == 1)) 27290075Sobrien break; 27390075Sobrien 27452284Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 27590075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 27690075Sobrien if (bootverbose) 27790075Sobrien ata_printf(scp, device, 27890075Sobrien "%s setting WDMA2 on PIIX chip\n", 27990075Sobrien (error) ? "failed" : "success"); 28090075Sobrien if (!error) { 28190075Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 28290075Sobrien return; 28390075Sobrien } 28490075Sobrien } 28590075Sobrien break; 28690075Sobrien 28790075Sobrien case 0x522910b9: /* AcerLabs Aladdin IV/V */ 28890075Sobrien /* the Aladdin doesn't support ATAPI DMA on both master & slave */ 28990075Sobrien if (scp->devices & ATA_ATAPI_MASTER && scp->devices & ATA_ATAPI_SLAVE) { 29090075Sobrien ata_printf(scp, device, 29190075Sobrien "Aladdin: two atapi devices on this channel, no DMA\n"); 29290075Sobrien break; 29390075Sobrien } 29490075Sobrien if (udmamode >= 2 && pci_get_revid(parent) > 0x20) { 29590075Sobrien int32_t word54 = pci_read_config(parent, 0x54, 4); 29690075Sobrien 29790075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 29890075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 29990075Sobrien if (bootverbose) 300117395Skan ata_printf(scp, device, 30152284Sobrien "%s setting UDMA2 on Aladdin chip\n", 302117395Skan (error) ? "failed" : "success"); 303117395Skan if (!error) { 30490075Sobrien word54 &= ~(0x000f000f << (devno << 2)); 30590075Sobrien word54 |= (0x000a0005 << (devno << 2)); 30690075Sobrien pci_write_config(parent, 0x54, word54, 4); 30790075Sobrien pci_write_config(parent, 0x53, 30890075Sobrien pci_read_config(parent, 0x53, 1) | 0x03, 1); 30990075Sobrien scp->flags |= ATA_ATAPI_DMA_RO; 31090075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 31152284Sobrien return; 31290075Sobrien } 31390075Sobrien } 31490075Sobrien 31590075Sobrien /* make sure eventual UDMA mode from the BIOS is disabled */ 316117395Skan pci_write_config(parent, 0x54, 317117395Skan pci_read_config(parent, 0x54, 4) & ~0x88880000, 4); 31890075Sobrien 31990075Sobrien if (wdmamode >= 2 && apiomode >= 4) { 320117395Skan error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 32152284Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 32290075Sobrien if (bootverbose) 323117395Skan ata_printf(scp, device, 324117395Skan "%s setting WDMA2 on Aladdin chip\n", 325117395Skan (error) ? "failed" : "success"); 32652284Sobrien if (!error) { 32790075Sobrien pci_write_config(parent, 0x53, 328117395Skan pci_read_config(parent, 0x53, 1) | 0x03, 1); 329117395Skan scp->flags |= ATA_ATAPI_DMA_RO; 330117395Skan scp->mode[ATA_DEV(device)] = ATA_WDMA2; 331117395Skan return; 332117395Skan } 33390075Sobrien } 33490075Sobrien pci_write_config(parent, 0x53, 33590075Sobrien (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1); 33690075Sobrien /* we could set PIO mode timings, but we assume the BIOS did that */ 33790075Sobrien break; 33890075Sobrien 33990075Sobrien case 0x74091022: /* AMD 756 */ 34090075Sobrien if (udmamode >= 4) { 34190075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 34290075Sobrien ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 34390075Sobrien if (bootverbose) 34452284Sobrien ata_printf(scp, device, 34590075Sobrien "%s setting UDMA4 on AMD chip\n", 34690075Sobrien (error) ? "failed" : "success"); 34790075Sobrien if (!error) { 348117395Skan pci_write_config(parent, 0x53 - devno, 0xc3, 1); 34990075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA4; 350117395Skan return; 351117395Skan } 35290075Sobrien } 35390075Sobrien goto via_82c586; 35490075Sobrien 35590075Sobrien case 0x05711106: /* VIA 82C571, 82C586, 82C596, 82C686 */ 35652284Sobrien if (ata_find_dev(parent, 0x06861106, 0) || /* 82C686a */ 35752284Sobrien ata_find_dev(parent, 0x05961106, 0x12)) { /* 82C596b */ 35890075Sobrien 35952284Sobrien if (udmamode >= 4) { 36090075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 36190075Sobrien ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 36290075Sobrien if (bootverbose) 36390075Sobrien ata_printf(scp, device, 36490075Sobrien "%s setting UDMA4 on VIA chip\n", 36590075Sobrien (error) ? "failed" : "success"); 36690075Sobrien if (!error) { 367117395Skan pci_write_config(parent, 0x53 - devno, 0xe8, 1); 36852284Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA4; 369117395Skan return; 370117395Skan } 37152284Sobrien } 37290075Sobrien if (udmamode >= 2) { 37390075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 37490075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 37590075Sobrien if (bootverbose) 37690075Sobrien ata_printf(scp, device, 377117395Skan "%s setting UDMA2 on VIA chip\n", 37890075Sobrien (error) ? "failed" : "success"); 37990075Sobrien if (!error) { 38090075Sobrien pci_write_config(parent, 0x53 - devno, 0xea, 1); 38190075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 38290075Sobrien return; 38390075Sobrien } 38490075Sobrien } 38590075Sobrien } 38690075Sobrien else if (ata_find_dev(parent, 0x05961106, 0) || /* 82C596a */ 38790075Sobrien ata_find_dev(parent, 0x05861106, 0x02)) { /* 82C586b */ 38890075Sobrienvia_82c586: 38990075Sobrien if (udmamode >= 2) { 39052284Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 39152284Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 39290075Sobrien if (bootverbose) 39390075Sobrien ata_printf(scp, device, "%s setting UDMA2 on %s chip\n", 39490075Sobrien (error) ? "failed" : "success", 39590075Sobrien (scp->chiptype == 0x74091022) ? "AMD" : "VIA"); 39690075Sobrien if (!error) { 39752284Sobrien pci_write_config(parent, 0x53 - devno, 0xc0, 1); 39890075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 39990075Sobrien return; 40090075Sobrien } 40190075Sobrien } 40290075Sobrien } 40352284Sobrien if (wdmamode >= 2 && apiomode >= 4) { 40490075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 40590075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 40652284Sobrien if (bootverbose) 40790075Sobrien ata_printf(scp, device, "%s setting WDMA2 on %s chip\n", 40890075Sobrien (error) ? "failed" : "success", 40990075Sobrien (scp->chiptype == 0x74091022) ? "AMD" : "VIA"); 41090075Sobrien if (!error) { 41190075Sobrien pci_write_config(parent, 0x53 - devno, 0x82, 1); 41290075Sobrien pci_write_config(parent, 0x4b - devno, 0x31, 1); 413117395Skan scp->mode[ATA_DEV(device)] = ATA_WDMA2; 414117395Skan return; 415117395Skan } 416117395Skan } 41790075Sobrien /* we could set PIO mode timings, but we assume the BIOS did that */ 41890075Sobrien break; 41952284Sobrien 42090075Sobrien case 0x55131039: /* SiS 5591 */ 421117395Skan if (udmamode >= 2 && pci_get_revid(parent) > 0xc1) { 422117395Skan error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 42390075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 42490075Sobrien if (bootverbose) 42552284Sobrien ata_printf(scp, device, 42690075Sobrien "%s setting UDMA2 on SiS chip\n", 427117395Skan (error) ? "failed" : "success"); 428117395Skan if (!error) { 42990075Sobrien pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); 43090075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 43190075Sobrien return; 43290075Sobrien } 43352284Sobrien } 434117395Skan if (wdmamode >=2 && apiomode >= 4) { 435117395Skan error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 43690075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 43790075Sobrien if (bootverbose) 43852284Sobrien ata_printf(scp, device, 43990075Sobrien "%s setting WDMA2 on SiS chip\n", 44090075Sobrien (error) ? "failed" : "success"); 44190075Sobrien if (!error) { 44252284Sobrien pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); 44390075Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 44490075Sobrien return; 44590075Sobrien } 44690075Sobrien } 44752284Sobrien /* we could set PIO mode timings, but we assume the BIOS did that */ 44890075Sobrien break; 44990075Sobrien 45090075Sobrien case 0x06491095: /* CMD 649 ATA100 controller */ 45152284Sobrien if (udmamode >= 5) { 45290075Sobrien u_int8_t umode; 45390075Sobrien 45490075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 455117395Skan ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 45690075Sobrien if (bootverbose) 45790075Sobrien ata_printf(scp, device, "%s setting UDMA5 on CMD chip\n", 45890075Sobrien (error) ? "failed" : "success"); 45990075Sobrien if (!error) { 46090075Sobrien umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1); 461117395Skan umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); 46290075Sobrien umode |= (device == ATA_MASTER ? 0x05 : 0x0a); 46352284Sobrien pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1); 46490075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA5; 46552284Sobrien return; 46690075Sobrien } 46752284Sobrien } 46890075Sobrien /* FALLTHROUGH */ 469117395Skan 47090075Sobrien case 0x06481095: /* CMD 648 ATA66 controller */ 47152284Sobrien if (udmamode >= 4) { 47290075Sobrien u_int8_t umode; 47390075Sobrien 47452284Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 47590075Sobrien ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 47690075Sobrien if (bootverbose) 47790075Sobrien ata_printf(scp, device, "%s setting UDMA4 on CMD chip\n", 47890075Sobrien (error) ? "failed" : "success"); 47990075Sobrien if (!error) { 480117395Skan umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1); 48190075Sobrien umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); 48290075Sobrien umode |= (device == ATA_MASTER ? 0x15 : 0x4a); 48390075Sobrien pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1); 48490075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA4; 48590075Sobrien return; 48690075Sobrien } 48790075Sobrien } 48890075Sobrien if (udmamode >= 2) { 48990075Sobrien u_int8_t umode; 49090075Sobrien 49190075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 49290075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 49352284Sobrien if (bootverbose) 49490075Sobrien ata_printf(scp, device, "%s setting UDMA2 on CMD chip\n", 495117395Skan (error) ? "failed" : "success"); 49690075Sobrien if (!error) { 49752284Sobrien umode = pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1); 49890075Sobrien umode &= ~(device == ATA_MASTER ? 0x35 : 0xca); 49990075Sobrien umode |= (device == ATA_MASTER ? 0x11 : 0x42); 50090075Sobrien pci_write_config(parent, scp->channel ? 0x7b : 0x73, umode, 1); 50190075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 50290075Sobrien return; 50352284Sobrien } 50490075Sobrien } 505117395Skan /* make sure eventual UDMA mode from the BIOS is disabled */ 50652284Sobrien pci_write_config(parent, scp->channel ? 0x7b : 0x73, 50790075Sobrien pci_read_config(parent, scp->channel ? 0x7b : 0x73, 1)& 50890075Sobrien ~(device == ATA_MASTER ? 0x35 : 0xca), 1); 509117395Skan /* FALLTHROUGH */ 51052284Sobrien 511117395Skan case 0x06461095: /* CMD 646 ATA controller */ 512117395Skan if (wdmamode >= 2 && apiomode >= 4) { 51390075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 51490075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 51590075Sobrien if (bootverbose) 51690075Sobrien ata_printf(scp, device, "%s setting WDMA2 on CMD chip\n", 51790075Sobrien error ? "failed" : "success"); 51890075Sobrien if (!error) { 51990075Sobrien int32_t offset = (devno < 3) ? (devno << 1) : 7; 52090075Sobrien 52190075Sobrien pci_write_config(parent, 0x54 + offset, 0x3f, 1); 52290075Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 52390075Sobrien return; 52490075Sobrien } 52590075Sobrien } 52690075Sobrien /* we could set PIO mode timings, but we assume the BIOS did that */ 52790075Sobrien break; 528117395Skan 52990075Sobrien case 0xc6931080: /* Cypress 82c693 ATA controller */ 53090075Sobrien if (wdmamode >= 2 && apiomode >= 4) { 53190075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 532117395Skan ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 53390075Sobrien if (bootverbose) 53490075Sobrien ata_printf(scp, device, 53590075Sobrien "%s setting WDMA2 on Cypress chip\n", 53690075Sobrien error ? "failed" : "success"); 537117395Skan if (!error) { 53890075Sobrien pci_write_config(scp->dev, scp->channel ? 0x4e:0x4c, 0x2020, 2); 53990075Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 540117395Skan return; 54190075Sobrien } 54252284Sobrien } 54390075Sobrien /* we could set PIO mode timings, but we assume the BIOS did that */ 54490075Sobrien break; 545117395Skan 546117395Skan case 0x01021078: /* Cyrix 5530 ATA33 controller */ 54790075Sobrien scp->alignment = 0xf; /* DMA engine requires 16 byte alignment */ 54890075Sobrien if (udmamode >= 2) { 549117395Skan error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 55090075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 55190075Sobrien if (bootverbose) 55290075Sobrien ata_printf(scp, device, "%s setting UDMA2 on Cyrix chip\n", 553117395Skan (error) ? "failed" : "success"); 55490075Sobrien if (!error) { 55552284Sobrien cyrix_timing(scp, devno, ATA_UDMA2); 55690075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 55790075Sobrien return; 55890075Sobrien } 55990075Sobrien } 56090075Sobrien if (wdmamode >= 2 && apiomode >= 4) { 561117395Skan error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 56252284Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 56352284Sobrien if (bootverbose) 56452284Sobrien ata_printf(scp, device, "%s setting WDMA2 on Cyrix chip\n", 56590075Sobrien (error) ? "failed" : "success"); 56690075Sobrien if (!error) { 56790075Sobrien cyrix_timing(scp, devno, ATA_WDMA2); 56852284Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 56952284Sobrien return; 57090075Sobrien } 57152284Sobrien } 57252284Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 57390075Sobrien ata_pio2mode(apiomode), ATA_C_F_SETXFER, 57490075Sobrien ATA_WAIT_READY); 57590075Sobrien if (bootverbose) 57652284Sobrien ata_printf(scp, device, "%s setting %s on Cyrix chip\n", 57790075Sobrien (error) ? "failed" : "success", 57852284Sobrien ata_mode2str(ata_pio2mode(apiomode))); 57990075Sobrien cyrix_timing(scp, devno, ata_pio2mode(apiomode)); 58090075Sobrien scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 58190075Sobrien return; 58252284Sobrien 58390075Sobrien case 0x02111166: /* ServerWorks ROSB4 ATA33 controller */ 58490075Sobrien if (udmamode >= 2) { 58590075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 58652284Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 58752284Sobrien if (bootverbose) 58890075Sobrien ata_printf(scp, device, 58952284Sobrien "%s setting UDMA2 on ServerWorks chip\n", 59090075Sobrien (error) ? "failed" : "success"); 59190075Sobrien if (!error) { 59290075Sobrien u_int16_t reg56; 59390075Sobrien 59490075Sobrien pci_write_config(parent, 0x54, 59552284Sobrien pci_read_config(parent, 0x54, 1) | 59690075Sobrien (0x01 << devno), 1); 59790075Sobrien reg56 = pci_read_config(parent, 0x56, 2); 59890075Sobrien reg56 &= ~(0xf << (devno * 4)); 59990075Sobrien reg56 |= (0x2 << (devno * 4)); 60090075Sobrien pci_write_config(parent, 0x56, reg56, 2); 60190075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 60290075Sobrien return; 60390075Sobrien } 60490075Sobrien } 60590075Sobrien if (wdmamode >= 2 && apiomode >= 4) { 60652284Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 60752284Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 60890075Sobrien if (bootverbose) 60990075Sobrien ata_printf(scp, device, 61090075Sobrien "%s setting WDMA2 on ServerWorks chip\n", 61152284Sobrien (error) ? "failed" : "success"); 61252284Sobrien if (!error) { 61390075Sobrien int offset = (scp->channel * 2) + (device == ATA_MASTER); 61452284Sobrien int word44 = pci_read_config(parent, 0x44, 4); 61590075Sobrien 61690075Sobrien pci_write_config(parent, 0x54, 61752284Sobrien pci_read_config(parent, 0x54, 1) & 61852284Sobrien ~(0x01 << devno), 1); 61990075Sobrien word44 &= ~(0xff << (offset << 8)); 62090075Sobrien word44 |= (0x20 << (offset << 8)); 62190075Sobrien pci_write_config(parent, 0x44, 0x20, 4); 62252284Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 623117395Skan return; 62490075Sobrien } 625117395Skan } 62652284Sobrien /* we could set PIO mode timings, but we assume the BIOS did that */ 62790075Sobrien break; 62852284Sobrien 62990075Sobrien case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */ 63090075Sobrien case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */ 63190075Sobrien case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */ 63290075Sobrien case 0x0d30105a: /* Promise OEM ATA100 controllers */ 63390075Sobrien /* the Promise can only do DMA on ATA disks not on ATAPI devices */ 63490075Sobrien if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 63590075Sobrien (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 63690075Sobrien break; 63790075Sobrien 63890075Sobrien if (udmamode >= 5 && 63990075Sobrien (scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) && 64090075Sobrien !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){ 64190075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 64290075Sobrien ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 64390075Sobrien if (bootverbose) 64490075Sobrien ata_printf(scp, device, 64590075Sobrien "%s setting UDMA5 on Promise chip\n", 64690075Sobrien (error) ? "failed" : "success"); 64790075Sobrien if (!error) { 64890075Sobrien promise_timing(scp, devno, ATA_UDMA5); 64990075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA5; 65090075Sobrien return; 65190075Sobrien } 652117395Skan } 65352284Sobrien if (udmamode >= 4 && (scp->chiptype == 0x4d38105a || 654117395Skan scp->chiptype == 0x4d30105a || scp->chiptype == 0x0d30105a) && 655117395Skan !(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){ 65652284Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 65790075Sobrien ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 65890075Sobrien if (bootverbose) 65990075Sobrien ata_printf(scp, device, 66090075Sobrien "%s setting UDMA4 on Promise chip\n", 66190075Sobrien (error) ? "failed" : "success"); 662117395Skan if (!error) { 663117395Skan promise_timing(scp, devno, ATA_UDMA4); 66490075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA4; 66590075Sobrien return; 666117395Skan } 667117395Skan } 668117395Skan if (udmamode >= 2) { 66990075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 67090075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 67190075Sobrien if (bootverbose) 672117395Skan ata_printf(scp, device, 673117395Skan "%s setting UDMA2 on Promise chip\n", 674117395Skan (error) ? "failed" : "success"); 675117395Skan if (!error) { 676117395Skan promise_timing(scp, devno, ATA_UDMA2); 67790075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA2; 67890075Sobrien return; 67990075Sobrien } 68090075Sobrien } 68190075Sobrien if (wdmamode >= 2 && apiomode >= 4) { 68290075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 68390075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 68490075Sobrien if (bootverbose) 68590075Sobrien ata_printf(scp, device, 68690075Sobrien "%s setting WDMA2 on Promise chip\n", 68790075Sobrien (error) ? "failed" : "success"); 68890075Sobrien if (!error) { 689117395Skan promise_timing(scp, devno, ATA_WDMA2); 69090075Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 691117395Skan return; 692117395Skan } 69390075Sobrien } 69490075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 69590075Sobrien ata_pio2mode(apiomode), 69690075Sobrien ATA_C_F_SETXFER, ATA_WAIT_READY); 69752284Sobrien if (bootverbose) 69852284Sobrien ata_printf(scp, device, 69990075Sobrien "%s setting PIO%d on Promise chip\n", 70052284Sobrien (error) ? "failed" : "success", 70152284Sobrien (apiomode >= 0) ? apiomode : 0); 70290075Sobrien promise_timing(scp, devno, ata_pio2mode(apiomode)); 70390075Sobrien scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 70490075Sobrien return; 70590075Sobrien 70652284Sobrien case 0x00041103: /* HighPoint HPT366/368/370 controllers */ 70790075Sobrien /* no ATAPI devices for now */ 708117395Skan if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 70952284Sobrien (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 710117395Skan break; 711117395Skan 71290075Sobrien if (udmamode >=5 && pci_get_revid(parent) >= 0x03 && 71390075Sobrien !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { 71490075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 71590075Sobrien ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY); 71690075Sobrien if (bootverbose) 717117395Skan ata_printf(scp, device, 71890075Sobrien "%s setting UDMA5 on HighPoint chip\n", 71990075Sobrien (error) ? "failed" : "success"); 72090075Sobrien if (!error) { 72152284Sobrien hpt_timing(scp, devno, ATA_UDMA5); 72252284Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA5; 72390075Sobrien return; 72490075Sobrien } 72590075Sobrien } 72690075Sobrien if (udmamode >=4 && 72752284Sobrien !(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) { 72890075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 72990075Sobrien ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 73090075Sobrien if (bootverbose) 73190075Sobrien ata_printf(scp, device, 73252284Sobrien "%s setting UDMA4 on HighPoint chip\n", 73390075Sobrien (error) ? "failed" : "success"); 73490075Sobrien if (!error) { 73590075Sobrien hpt_timing(scp, devno, ATA_UDMA4); 73690075Sobrien scp->mode[ATA_DEV(device)] = ATA_UDMA4; 73790075Sobrien return; 73890075Sobrien } 73952284Sobrien } 74090075Sobrien if (udmamode >= 2) { 74190075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 74290075Sobrien ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 74390075Sobrien if (bootverbose) 74490075Sobrien ata_printf(scp, device, 74552284Sobrien "%s setting UDMA2 on HighPoint chip\n", 74690075Sobrien (error) ? "failed" : "success"); 74790075Sobrien if (!error) { 74852284Sobrien hpt_timing(scp, devno, ATA_UDMA2); 749117395Skan scp->mode[ATA_DEV(device)] = ATA_UDMA2; 750117395Skan return; 751117395Skan } 752117395Skan } 75390075Sobrien if (wdmamode >= 2 && apiomode >= 4) { 75490075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 75590075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 756117395Skan if (bootverbose) 757117395Skan ata_printf(scp, device, 75890075Sobrien "%s setting WDMA2 on HighPoint chip\n", 75990075Sobrien (error) ? "failed" : "success"); 76090075Sobrien if (!error) { 76190075Sobrien hpt_timing(scp, devno, ATA_WDMA2); 76252284Sobrien scp->mode[ATA_DEV(device)] = ATA_WDMA2; 76390075Sobrien return; 76490075Sobrien } 76590075Sobrien } 766117395Skan error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 767117395Skan ata_pio2mode(apiomode), 768117395Skan ATA_C_F_SETXFER, ATA_WAIT_READY); 769117395Skan if (bootverbose) 770117395Skan ata_printf(scp, device, "%s setting PIO%d on HighPoint chip\n", 771117395Skan (error) ? "failed" : "success", 77252284Sobrien (apiomode >= 0) ? apiomode : 0); 77390075Sobrien hpt_timing(scp, devno, ata_pio2mode(apiomode)); 77490075Sobrien scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 77590075Sobrien return; 77690075Sobrien 77790075Sobrien default: /* unknown controller chip */ 778117395Skan /* better not try generic DMA on ATAPI devices it almost never works */ 779117395Skan if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 78090075Sobrien (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 78190075Sobrien break; 78290075Sobrien 78390075Sobrien /* if controller says its setup for DMA take the easy way out */ 78490075Sobrien /* the downside is we dont know what DMA mode we are in */ 78590075Sobrien if ((udmamode >= 0 || wdmamode > 1) && 78690075Sobrien (inb(scp->bmaddr + ATA_BMSTAT_PORT) & 78790075Sobrien ((device==ATA_MASTER) ? 78890075Sobrien ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) { 78990075Sobrien scp->mode[ATA_DEV(device)] = ATA_DMA; 79090075Sobrien return; 79190075Sobrien } 79290075Sobrien 79390075Sobrien /* well, we have no support for this, but try anyways */ 79490075Sobrien if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) { 79590075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 79690075Sobrien ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 79790075Sobrien if (bootverbose) 79890075Sobrien ata_printf(scp, device, 79990075Sobrien "%s setting WDMA2 on generic chip\n", 80090075Sobrien (error) ? "failed" : "success"); 80190075Sobrien if (!error) { 802117395Skan scp->mode[ATA_DEV(device)] = ATA_WDMA2; 80390075Sobrien return; 80490075Sobrien } 80590075Sobrien } 80690075Sobrien } 80790075Sobrien error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 80890075Sobrien ata_pio2mode(apiomode), ATA_C_F_SETXFER,ATA_WAIT_READY); 809117395Skan if (bootverbose) 81090075Sobrien ata_printf(scp, device, "%s setting PIO%d on generic chip\n", 81190075Sobrien (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode); 81290075Sobrien if (!error) 81390075Sobrien scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 81490075Sobrien else { 81590075Sobrien if (bootverbose) 81690075Sobrien ata_printf(scp, device, "using PIO mode set by BIOS\n"); 817117395Skan scp->mode[ATA_DEV(device)] = ATA_PIO; 81890075Sobrien } 81990075Sobrien} 82090075Sobrien 82190075Sobrienint 82290075Sobrienata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, 82390075Sobrien caddr_t data, int32_t count) 82490075Sobrien{ 82590075Sobrien u_int32_t dma_count, dma_base; 82690075Sobrien int i = 0; 82790075Sobrien 82890075Sobrien if (((uintptr_t)data & scp->alignment) || (count & scp->alignment)) { 829117395Skan ata_printf(scp, device, "non aligned DMA transfer attempted\n"); 83090075Sobrien return -1; 83190075Sobrien } 83290075Sobrien 83352284Sobrien if (!count) { 83452284Sobrien ata_printf(scp, device, "zero length DMA transfer attempted\n"); 83590075Sobrien return -1; 83652284Sobrien } 83790075Sobrien 83890075Sobrien dma_base = vtophys(data); 83990075Sobrien dma_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); 84090075Sobrien data += dma_count; 84190075Sobrien count -= dma_count; 84290075Sobrien 84390075Sobrien while (count) { 84490075Sobrien dmatab[i].base = dma_base; 84590075Sobrien dmatab[i].count = (dma_count & 0xffff); 84690075Sobrien i++; 84790075Sobrien if (i >= ATA_DMA_ENTRIES) { 84890075Sobrien ata_printf(scp, device, "too many segments in DMA table\n"); 84990075Sobrien return -1; 85090075Sobrien } 85190075Sobrien dma_base = vtophys(data); 85290075Sobrien dma_count = min(count, PAGE_SIZE); 85390075Sobrien data += min(count, PAGE_SIZE); 85490075Sobrien count -= min(count, PAGE_SIZE); 85590075Sobrien } 85690075Sobrien dmatab[i].base = dma_base; 85790075Sobrien dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; 85890075Sobrien return 0; 85990075Sobrien} 86090075Sobrien 86190075Sobrienvoid 86290075Sobrienata_dmastart(struct ata_softc *scp, int device, 86390075Sobrien struct ata_dmaentry *dmatab, int dir) 86490075Sobrien{ 86590075Sobrien scp->flags |= ATA_DMA_ACTIVE; 86690075Sobrien outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab)); 86790075Sobrien outb(scp->bmaddr + ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0); 86890075Sobrien outb(scp->bmaddr + ATA_BMSTAT_PORT, 86990075Sobrien (inb(scp->bmaddr + ATA_BMSTAT_PORT) | 87090075Sobrien (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 87190075Sobrien outb(scp->bmaddr + ATA_BMCMD_PORT, 87290075Sobrien inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); 87390075Sobrien} 87490075Sobrien 87590075Sobrienint 87690075Sobrienata_dmadone(struct ata_softc *scp) 87790075Sobrien{ 87890075Sobrien outb(scp->bmaddr + ATA_BMCMD_PORT, 87990075Sobrien inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 88090075Sobrien scp->flags &= ~ATA_DMA_ACTIVE; 88190075Sobrien return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 88290075Sobrien} 88390075Sobrien 88490075Sobrienint 88590075Sobrienata_dmastatus(struct ata_softc *scp) 88690075Sobrien{ 88790075Sobrien return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 88890075Sobrien} 88990075Sobrien 89090075Sobrienstatic void 89190075Sobriencyrix_timing(struct ata_softc *scp, int devno, int mode) 89290075Sobrien{ 89390075Sobrien u_int32_t reg20 = 0x0000e132; 89490075Sobrien u_int32_t reg24 = 0x00017771; 89590075Sobrien 89690075Sobrien switch (mode) { 89790075Sobrien case ATA_PIO0: reg20 = 0x0000e132; break; 89890075Sobrien case ATA_PIO1: reg20 = 0x00018121; break; 89990075Sobrien case ATA_PIO2: reg20 = 0x00024020; break; 90090075Sobrien case ATA_PIO3: reg20 = 0x00032010; break; 90190075Sobrien case ATA_PIO4: reg20 = 0x00040010; break; 90290075Sobrien case ATA_WDMA2: reg24 = 0x00002020; break; 90390075Sobrien case ATA_UDMA2: reg24 = 0x00911030; break; 90490075Sobrien } 90590075Sobrien outl(scp->bmaddr + (devno << 3) + 0x20, reg20); 90690075Sobrien outl(scp->bmaddr + (devno << 3) + 0x24, reg24); 90790075Sobrien} 90890075Sobrien 90990075Sobrienstatic void 91090075Sobrienpromise_timing(struct ata_softc *scp, int devno, int mode) 91190075Sobrien{ 91290075Sobrien u_int32_t timing = 0; 91390075Sobrien struct promise_timing { 91490075Sobrien u_int8_t pa:4; 91590075Sobrien u_int8_t prefetch:1; 91690075Sobrien u_int8_t iordy:1; 91790075Sobrien u_int8_t errdy:1; 91890075Sobrien u_int8_t syncin:1; 91990075Sobrien u_int8_t pb:5; 92052284Sobrien u_int8_t mb:3; 92190075Sobrien u_int8_t mc:4; 92290075Sobrien u_int8_t dmaw:1; 92390075Sobrien u_int8_t dmar:1; 92452284Sobrien u_int8_t iordyp:1; 92590075Sobrien u_int8_t dmarqp:1; 92652284Sobrien u_int8_t reserved:8; 92790075Sobrien } *t = (struct promise_timing*)&timing; 92890075Sobrien 92990075Sobrien t->iordy = 1; t->iordyp = 1; 93052284Sobrien if (mode >= ATA_DMA) { 93190075Sobrien t->prefetch = 1; t->errdy = 1; t->syncin = 1; 93290075Sobrien } 933117395Skan 93490075Sobrien switch (scp->chiptype) { 93552284Sobrien case 0x4d33105a: /* Promise Ultra/Fasttrak 33 */ 93652284Sobrien switch (mode) { 93752284Sobrien default: 93890075Sobrien case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break; 93990075Sobrien case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break; 94090075Sobrien case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break; 94190075Sobrien case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break; 94290075Sobrien case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break; 94352284Sobrien case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break; 94452284Sobrien case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 94590075Sobrien } 94690075Sobrien break; 94790075Sobrien 94852284Sobrien case 0x4d38105a: /* Promise Ultra/Fasttrak 66 */ 94990075Sobrien case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */ 95052284Sobrien case 0x0d30105a: /* Promise OEM ATA 100 */ 95190075Sobrien switch (mode) { 95290075Sobrien default: 95390075Sobrien case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; 95452284Sobrien case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break; 95590075Sobrien case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break; 95690075Sobrien case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break; 95752284Sobrien case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break; 95890075Sobrien case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; 95990075Sobrien case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; 96052284Sobrien case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 96190075Sobrien case ATA_UDMA5: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 96252284Sobrien } 96390075Sobrien break; 96490075Sobrien } 96590075Sobrien pci_write_config(device_get_parent(scp->dev), 0x60 + (devno<<2), timing, 4); 96690075Sobrien} 96790075Sobrien 96890075Sobrienstatic void 96990075Sobrienhpt_timing(struct ata_softc *scp, int devno, int mode) 97090075Sobrien{ 97190075Sobrien device_t parent = device_get_parent(scp->dev); 97290075Sobrien u_int32_t timing; 97390075Sobrien 97490075Sobrien if (pci_get_revid(parent) >= 0x03) { /* HPT370 */ 97590075Sobrien switch (mode) { 97690075Sobrien case ATA_PIO0: timing = 0x06914e57; break; 97790075Sobrien case ATA_PIO1: timing = 0x06914e43; break; 97890075Sobrien case ATA_PIO2: timing = 0x06514e33; break; 97990075Sobrien case ATA_PIO3: timing = 0x06514e22; break; 98052284Sobrien case ATA_PIO4: timing = 0x06514e21; break; 98152284Sobrien case ATA_WDMA2: timing = 0x26514e21; break; 98290075Sobrien case ATA_UDMA2: timing = 0x16494e31; break; 98390075Sobrien case ATA_UDMA4: timing = 0x16454e31; break; 98452284Sobrien case ATA_UDMA5: timing = 0x16454e31; break; 98552284Sobrien default: timing = 0x06514e57; 98690075Sobrien } 98790075Sobrien pci_write_config(parent, 0x40 + (devno << 2) , timing, 4); 98890075Sobrien pci_write_config(parent, 0x5b, 0x22, 1); 98990075Sobrien } 99052284Sobrien else { /* HPT36[68] */ 99190075Sobrien switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) { 99252284Sobrien case 0x85: /* 25Mhz */ 99390075Sobrien switch (mode) { 99490075Sobrien case ATA_PIO0: timing = 0xc0d08585; break; 99552284Sobrien case ATA_PIO1: timing = 0xc0d08572; break; 99690075Sobrien case ATA_PIO2: timing = 0xc0ca8542; break; 99790075Sobrien case ATA_PIO3: timing = 0xc0ca8532; break; 99852284Sobrien case ATA_PIO4: timing = 0xc0ca8521; break; 99990075Sobrien case ATA_WDMA2: timing = 0xa0ca8521; break; 100090075Sobrien case ATA_UDMA2: timing = 0x90cf8521; break; 100190075Sobrien case ATA_UDMA4: timing = 0x90c98521; break; 100290075Sobrien default: timing = 0x01208585; 100390075Sobrien } 100490075Sobrien break; 100590075Sobrien default: 100690075Sobrien case 0xa7: /* 33MHz */ 100790075Sobrien switch (mode) { 100890075Sobrien case ATA_PIO0: timing = 0xc0d0a7aa; break; 100990075Sobrien case ATA_PIO1: timing = 0xc0d0a7a3; break; 101090075Sobrien case ATA_PIO2: timing = 0xc0d0a753; break; 101190075Sobrien case ATA_PIO3: timing = 0xc0c8a742; break; 101290075Sobrien case ATA_PIO4: timing = 0xc0c8a731; break; 101390075Sobrien case ATA_WDMA2: timing = 0xa0c8a731; break; 1014117395Skan case ATA_UDMA2: timing = 0x90caa731; break; 1015117395Skan case ATA_UDMA4: timing = 0x90c9a731; break; 101690075Sobrien default: timing = 0x0120a7a7; 101790075Sobrien } 101890075Sobrien break; 101990075Sobrien case 0xd9: /* 40Mhz */ 1020117395Skan switch (mode) { 102190075Sobrien case ATA_PIO0: timing = 0xc018d9d9; break; 102290075Sobrien case ATA_PIO1: timing = 0xc010d9c7; break; 102390075Sobrien case ATA_PIO2: timing = 0xc010d997; break; 102490075Sobrien case ATA_PIO3: timing = 0xc010d974; break; 102590075Sobrien case ATA_PIO4: timing = 0xc008d963; break; 102690075Sobrien case ATA_WDMA2: timing = 0xa008d943; break; 1027117395Skan case ATA_UDMA2: timing = 0x900bd943; break; 102890075Sobrien case ATA_UDMA4: timing = 0x900fd943; break; 1029117395Skan default: timing = 0x0120d9d9; 103090075Sobrien } 103190075Sobrien } 103290075Sobrien pci_write_config(parent, 0x40 + (devno << 2), (timing & ~0x80000000),4); 103390075Sobrien } 1034117395Skan} 1035117395Skan 1036117395Skan#else /* NPCI > 0 */ 1037117395Skan 1038117395Skanvoid * 1039117395Skanata_dmaalloc(struct ata_softc *scp, int device) 1040117395Skan{ 1041117395Skan return 0; 104290075Sobrien} 1043117395Skan 1044117395Skanvoid 104590075Sobrienata_dmainit(struct ata_softc *scp, int device, 104690075Sobrien int piomode, int wdmamode, int udmamode) 104790075Sobrien{ 104890075Sobrien} 104990075Sobrien 105090075Sobrienint 105190075Sobrienata_dmasetup(struct ata_softc *scp, int device, struct ata_dmaentry *dmatab, 105290075Sobrien caddr_t data, int32_t count) 105390075Sobrien{ 1054117395Skan return -1; 1055117395Skan} 1056117395Skan 1057117395Skanvoid 1058117395Skanata_dmastart(struct ata_softc *scp, int device, 1059117395Skan struct ata_dmaentry *dmatab, int dir) 1060117395Skan{ 1061117395Skan} 1062117395Skan 1063117395Skanint 1064117395Skanata_dmadone(struct ata_softc *scp) 1065117395Skan{ 1066117395Skan return -1; 1067117395Skan} 1068117395Skan 1069117395Skanint 1070117395Skanata_dmastatus(struct ata_softc *scp) 1071117395Skan{ 1072117395Skan return -1; 1073117395Skan} 1074117395Skan 107590075Sobrien#endif /* NPCI > 0 */ 107690075Sobrien