ata-dma.c revision 57771
145095Ssos/*- 255333Ssos * Copyright (c) 1998,1999,2000 S�ren Schmidt 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 57771 2000-03-05 16:52:26Z sos $ 2945095Ssos */ 3045095Ssos 3145150Ssos#include "pci.h" 3245095Ssos#include <sys/param.h> 3345095Ssos#include <sys/systm.h> 3445095Ssos#include <sys/buf.h> 3545095Ssos#include <sys/malloc.h> 3645798Ssos#include <sys/bus.h> 3754270Ssos#include <sys/disk.h> 3854270Ssos#include <sys/devicestat.h> 3951520Ssos#include <vm/vm.h> 4045095Ssos#include <vm/pmap.h> 4147272Ssos#if NPCI > 0 4245095Ssos#include <pci/pcivar.h> 4347272Ssos#endif 4445095Ssos#include <dev/ata/ata-all.h> 4554270Ssos#include <dev/ata/ata-disk.h> 4645095Ssos 4756754Ssos#if NPCI > 0 4856754Ssos 4952067Ssos/* prototypes */ 5055333Ssosstatic void promise_timing(struct ata_softc *, int32_t, int32_t); 5152067Ssosstatic void hpt366_timing(struct ata_softc *, int32_t, int32_t); 5252067Ssos 5352067Ssos/* misc defines */ 5445720Speter#ifdef __alpha__ 5545720Speter#undef vtophys 5651520Ssos#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) 5745720Speter#endif 5845720Speter 5956744Ssosvoid 6045095Ssosata_dmainit(struct ata_softc *scp, int32_t device, 6145095Ssos int32_t apiomode, int32_t wdmamode, int32_t udmamode) 6245095Ssos{ 6357325Ssos device_t parent = device_get_parent(scp->dev); 6456558Ssos int32_t devno = (scp->unit << 1) + ATA_DEV(device); 6555333Ssos int32_t error; 6645095Ssos 6756744Ssos /* set our most pessimistic default mode */ 6856744Ssos scp->mode[ATA_DEV(device)] = ATA_PIO; 6956744Ssos 7045095Ssos if (!scp->bmaddr) 7156744Ssos return; 7245095Ssos 7352067Ssos /* if simplex controller, only allow DMA on primary channel */ 7452067Ssos if (scp->unit == 1) { 7552067Ssos outb(scp->bmaddr + ATA_BMSTAT_PORT, inb(scp->bmaddr + ATA_BMSTAT_PORT) & 7652067Ssos (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE)); 7752067Ssos if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) { 7856558Ssos ata_printf(scp, device, "simplex device, DMA on primary only\n"); 7956744Ssos return; 8052067Ssos } 8152067Ssos } 8252067Ssos 8356558Ssos if (!scp->dmatab[ATA_DEV(device)]) { 8456558Ssos void *dmatab; 8545095Ssos 8656558Ssos if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) 8756744Ssos return; 8856558Ssos if (((uintptr_t)dmatab >> PAGE_SHIFT) ^ 8956558Ssos (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) { 9056558Ssos ata_printf(scp, device, "dmatab crosses page boundary, no DMA\n"); 9156558Ssos free(dmatab, M_DEVBUF); 9256744Ssos return; 9356558Ssos } 9456558Ssos scp->dmatab[ATA_DEV(device)] = dmatab; 9545095Ssos } 9645095Ssos 9755333Ssos switch (scp->chiptype) { 9845095Ssos 9957391Ssos case 0x24118086: /* Intel ICH */ 10057391Ssos if (udmamode >= 4) { 10157391Ssos int32_t mask48, new48; 10257391Ssos int16_t word54; 10357391Ssos 10457391Ssos word54 = pci_read_config(parent, 0x54, 2); 10557391Ssos if (word54 & (0x10 << devno)) { 10657391Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 10757391Ssos ATA_UDMA4, ATA_C_F_SETXFER,ATA_WAIT_READY); 10857391Ssos if (bootverbose) 10957391Ssos ata_printf(scp, device, 11057391Ssos "%s setting up UDMA4 mode on ICH chip\n", 11157391Ssos (error) ? "failed" : "success"); 11257391Ssos if (!error) { 11357391Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 11457391Ssos new48 = (1 << devno) + (2 << (16 + (devno << 2))); 11557391Ssos pci_write_config(parent, 0x48, 11657391Ssos (pci_read_config(parent, 0x48, 4) & 11757391Ssos ~mask48) | new48, 4); 11857391Ssos pci_write_config(parent, 0x54, word54 | (1 << devno), 2); 11957391Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 12057391Ssos return; 12157391Ssos } 12257391Ssos } 12357391Ssos } 12457391Ssos /* FALLTHROUGH */ 12557391Ssos 12645095Ssos case 0x71118086: /* Intel PIIX4 */ 12756138Ssos case 0x71998086: /* Intel PIIX4e */ 12856138Ssos case 0x24218086: /* Intel ICH0 */ 12945095Ssos if (udmamode >= 2) { 13051520Ssos int32_t mask48, new48; 13145095Ssos 13245095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 13353029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 13451520Ssos if (bootverbose) 13556558Ssos ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n", 13656558Ssos (error) ? "failed" : "success", 13756558Ssos (scp->chiptype == 0x24118086) ? "ICH" : 13856558Ssos (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); 13953681Ssos if (!error) { 14053681Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 14153681Ssos new48 = (1 << devno) + (2 << (16 + (devno << 2))); 14257325Ssos pci_write_config(parent, 0x48, 14357325Ssos (pci_read_config(parent, 0x48, 4) & 14453681Ssos ~mask48) | new48, 4); 14556558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 14656744Ssos return; 14753681Ssos } 14845095Ssos } 14945095Ssos /* FALLTHROUGH */ 15045095Ssos 15145095Ssos case 0x70108086: /* Intel PIIX3 */ 15245095Ssos if (wdmamode >= 2 && apiomode >= 4) { 15345095Ssos int32_t mask40, new40, mask44, new44; 15445095Ssos 15545095Ssos /* if SITRE not set doit for both channels */ 15657325Ssos if (!((pci_read_config(parent, 0x40, 4)>>(scp->unit<<8))&0x4000)){ 15757325Ssos new40 = pci_read_config(parent, 0x40, 4); 15857325Ssos new44 = pci_read_config(parent, 0x44, 4); 15951520Ssos if (!(new40 & 0x00004000)) { 16051520Ssos new44 &= ~0x0000000f; 16151520Ssos new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8); 16251520Ssos } 16351520Ssos if (!(new40 & 0x40000000)) { 16451520Ssos new44 &= ~0x000000f0; 16551520Ssos new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20); 16651520Ssos } 16751520Ssos new40 |= 0x40004000; 16857325Ssos pci_write_config(parent, 0x40, new40, 4); 16957325Ssos pci_write_config(parent, 0x44, new44, 4); 17045095Ssos } 17145095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 17253029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 17351520Ssos if (bootverbose) 17456558Ssos ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n", 17556558Ssos (error) ? "failed" : "success", 17656558Ssos (scp->chiptype == 0x70108086) ? "PIIX3" : 17756558Ssos (scp->chiptype == 0x24118086) ? "ICH" : 17856558Ssos (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); 17953681Ssos if (!error) { 18053681Ssos if (device == ATA_MASTER) { 18153681Ssos mask40 = 0x0000330f; 18253681Ssos new40 = 0x00002307; 18353681Ssos mask44 = 0; 18453681Ssos new44 = 0; 18553681Ssos } 18653681Ssos else { 18753681Ssos mask40 = 0x000000f0; 18853681Ssos new40 = 0x00000070; 18953681Ssos mask44 = 0x0000000f; 19053681Ssos new44 = 0x0000000b; 19153681Ssos } 19253681Ssos if (scp->unit) { 19353681Ssos mask40 <<= 16; 19453681Ssos new40 <<= 16; 19553681Ssos mask44 <<= 4; 19653681Ssos new44 <<= 4; 19753681Ssos } 19857325Ssos pci_write_config(parent, 0x40, 19957325Ssos (pci_read_config(parent, 0x40, 4) & ~mask40)| 20053681Ssos new40, 4); 20157325Ssos pci_write_config(parent, 0x44, 20257325Ssos (pci_read_config(parent, 0x44, 4) & ~mask44)| 20353681Ssos new44, 4); 20456558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 20556744Ssos return; 20645095Ssos } 20751520Ssos } 20853681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 20945095Ssos break; 21045095Ssos 21145095Ssos case 0x12308086: /* Intel PIIX */ 21254544Ssos if (wdmamode >= 2 && apiomode >= 4) { 21354544Ssos int32_t word40; 21454544Ssos 21557325Ssos word40 = pci_read_config(parent, 0x40, 4); 21654544Ssos word40 >>= scp->unit * 16; 21754544Ssos 21854544Ssos /* Check for timing config usable for DMA on controller */ 21954544Ssos if (!((word40 & 0x3300) == 0x2300 && 22054544Ssos ((word40 >> (device == ATA_MASTER ? 0 : 4)) & 1) == 1)) 22154544Ssos break; 22254544Ssos 22354544Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 22454544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 22554544Ssos if (bootverbose) 22656558Ssos ata_printf(scp, device, 22756558Ssos "%s setting up WDMA2 mode on PIIX chip\n", 22856558Ssos (error) ? "failed" : "success"); 22954544Ssos if (!error) { 23056558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 23156744Ssos return; 23254544Ssos } 23354544Ssos } 23445095Ssos break; 23545095Ssos 23652067Ssos case 0x522910b9: /* AcerLabs Aladdin IV/V */ 23753029Ssos /* the Aladdin doesn't support ATAPI DMA on both master & slave */ 23853029Ssos if (scp->devices & ATA_ATAPI_MASTER && scp->devices & ATA_ATAPI_SLAVE) { 23956558Ssos ata_printf(scp, device, 24056558Ssos "Aladdin: two atapi devices on this channel, no DMA\n"); 24153029Ssos break; 24252067Ssos } 24353681Ssos if (udmamode >= 2) { 24457325Ssos int32_t word54 = pci_read_config(parent, 0x54, 4); 24552067Ssos 24651520Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 24753029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 24851520Ssos if (bootverbose) 24956558Ssos ata_printf(scp, device, 25056558Ssos "%s setting up UDMA2 mode on Aladdin chip\n", 25156558Ssos (error) ? "failed" : "success"); 25253681Ssos if (!error) { 25353681Ssos word54 |= 0x5555; 25453681Ssos word54 |= (0x0a << (16 + (scp->unit << 3) + (device << 2))); 25557325Ssos pci_write_config(parent, 0x54, word54, 4); 25657325Ssos pci_write_config(parent, 0x53, 25757325Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 25853681Ssos scp->flags |= ATA_ATAPI_DMA_RO; 25956558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 26056744Ssos return; 26153681Ssos } 26251520Ssos } 26353681Ssos if (wdmamode >= 2 && apiomode >= 4) { 26452067Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 26553029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 26652067Ssos if (bootverbose) 26756558Ssos ata_printf(scp, device, 26856558Ssos "%s setting up WDMA2 mode on Aladdin chip\n", 26956558Ssos (error) ? "failed" : "success"); 27053681Ssos if (!error) { 27157325Ssos pci_write_config(parent, 0x53, 27257325Ssos pci_read_config(parent, 0x53, 1) | 0x03, 1); 27353681Ssos scp->flags |= ATA_ATAPI_DMA_RO; 27456558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 27556744Ssos return; 27653681Ssos } 27752067Ssos } 27857771Ssos pci_write_config(parent, 0x53, 27957771Ssos (pci_read_config(parent, 0x53, 1) & ~0x01) | 0x02, 1); 28053681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 28152067Ssos break; 28252067Ssos 28356988Ssos case 0x06861106: /* VIA 82C686 */ 28456988Ssos if (udmamode >= 4) { 28556988Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 28656988Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 28756988Ssos if (bootverbose) 28856988Ssos ata_printf(scp, device, 28956988Ssos "%s setting up UDMA4 mode on VIA chip\n", 29056988Ssos (error) ? "failed" : "success"); 29156988Ssos if (!error) { 29257325Ssos pci_write_config(parent, 0x53 - devno, 0xe8, 1); 29356988Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 29456988Ssos return; 29556138Ssos } 29656988Ssos } 29756988Ssos if (udmamode >= 2) { 29856988Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 29956988Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 30056988Ssos if (bootverbose) 30156988Ssos ata_printf(scp, device, 30256988Ssos "%s setting up UDMA2 mode on VIA chip\n", 30356988Ssos (error) ? "failed" : "success"); 30456988Ssos if (!error) { 30557325Ssos pci_write_config(parent, 0x53 - devno, 0xea, 1); 30656988Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 30756988Ssos return; 30856138Ssos } 30956138Ssos } 31056988Ssos goto via_generic; 31156138Ssos 31256988Ssos case 0x74091022: /* AMD 756 */ 31356988Ssos if (udmamode >= 4) { 31454270Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 31556138Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 31654270Ssos if (bootverbose) 31756558Ssos ata_printf(scp, device, 31856558Ssos "%s setting up UDMA4 mode on AMD chip\n", 31956558Ssos (error) ? "failed" : "success"); 32054270Ssos if (!error) { 32157325Ssos pci_write_config(parent, 0x53 - devno, 0xc3, 1); 32256558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 32356744Ssos return; 32453681Ssos } 32554270Ssos } 32656988Ssos /* FALLTHROUGH */ 32754270Ssos 32856988Ssos case 0x05961106: /* VIA 82C596 */ 32956988Ssos case 0x05861106: /* VIA 82C586 */ 33056988Ssos 33156138Ssos /* UDMA2 mode only on 82C586 > rev1, 82C596, AMD 756 */ 33256988Ssos if ((udmamode >= 2 && scp->chiptype == 0x05861106 && 33355333Ssos pci_read_config(scp->dev, 0x08, 1) >= 0x01) || 33456988Ssos (udmamode >= 2 && scp->chiptype == 0x05961106) || 33555333Ssos (udmamode >= 2 && scp->chiptype == 0x74091022)) { 33653681Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 33753681Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 33853681Ssos if (bootverbose) 33956558Ssos ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n", 34056558Ssos (error) ? "failed" : "success", 34156558Ssos (scp->chiptype == 0x74091022) ? "AMD" : "VIA"); 34253681Ssos if (!error) { 34357325Ssos pci_write_config(parent, 0x53 - devno, 0xc0, 1); 34456558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 34556744Ssos return; 34653681Ssos } 34753681Ssos } 34856988Ssos /* FALLTHROUGH */ 34956988Ssos 35056988Ssos case 0x05711106: /* VIA 82C571 */ 35156988Ssosvia_generic: 35253681Ssos if (wdmamode >= 2 && apiomode >= 4) { 35353681Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 35453681Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 35553681Ssos if (bootverbose) 35656558Ssos ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n", 35756558Ssos (error) ? "failed" : "success", 35856558Ssos (scp->chiptype == 0x74091022) ? "AMD" : "VIA"); 35953681Ssos if (!error) { 36057325Ssos pci_write_config(parent, 0x53 - devno, 0x82, 1); 36157325Ssos pci_write_config(parent, 0x4b - devno, 0x31, 1); 36256558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 36356744Ssos return; 36453681Ssos } 36553681Ssos } 36653681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 36753681Ssos break; 36853681Ssos 36954544Ssos case 0x55131039: /* SiS 5591 */ 37054544Ssos if (udmamode >= 2) { 37154544Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 37254544Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 37354544Ssos if (bootverbose) 37456558Ssos ata_printf(scp, device, 37556558Ssos "%s setting up UDMA2 mode on SiS chip\n", 37656558Ssos (error) ? "failed" : "success"); 37754544Ssos if (!error) { 37857325Ssos pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2); 37956558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 38056744Ssos return; 38154544Ssos } 38254544Ssos } 38354544Ssos if (wdmamode >=2 && apiomode >= 4) { 38454544Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 38554544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 38654544Ssos if (bootverbose) 38756558Ssos ata_printf(scp, device, 38856558Ssos "%s setting up WDMA2 mode on SiS chip\n", 38956558Ssos (error) ? "failed" : "success"); 39054544Ssos if (!error) { 39157325Ssos pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2); 39256558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 39356744Ssos return; 39454544Ssos } 39554544Ssos } 39654544Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 39754544Ssos break; 39854544Ssos 39957325Ssos case 0x06461095: /* CMD 646 ATA controller */ 40057325Ssos if (wdmamode >= 2 && apiomode >= 4) { 40157325Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 40257325Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 40357325Ssos if (bootverbose) 40457325Ssos ata_printf(scp, device, 40557325Ssos "%s setting up WDMA2 mode on CMD646 chip\n", 40657325Ssos error ? "failed" : "success"); 40757325Ssos if (!error) { 40857325Ssos int32_t offset = (devno < 3) ? (devno << 1) : 7; 40957325Ssos 41057325Ssos pci_write_config(parent, 0x54 + offset, 0x3f, 1); 41157325Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 41257325Ssos return; 41357325Ssos } 41457325Ssos } 41557325Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 41657325Ssos break; 41757325Ssos 41857477Ssos case 0xc6931080: /* Cypress 82c693 ATA controller */ 41957477Ssos if (wdmamode >= 2 && apiomode >= 4) { 42057477Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 42157477Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 42257477Ssos if (bootverbose) 42357477Ssos ata_printf(scp, device, 42457477Ssos "%s setting up WDMA2 mode on Cypress chip\n", 42557477Ssos error ? "failed" : "success"); 42657477Ssos if (!error) { 42757477Ssos pci_write_config(scp->dev, scp->unit ? 0x4e : 0x4c, 0x2020, 2); 42857477Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 42957477Ssos return; 43057477Ssos } 43157477Ssos } 43257477Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 43357477Ssos break; 43457477Ssos 43552067Ssos case 0x4d33105a: /* Promise Ultra33 / FastTrak33 controllers */ 43652067Ssos case 0x4d38105a: /* Promise Ultra66 / FastTrak66 controllers */ 43752067Ssos /* the Promise can only do DMA on ATA disks not on ATAPI devices */ 43852067Ssos if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 43952067Ssos (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 44052067Ssos break; 44152067Ssos 44255333Ssos if (udmamode >=4 && scp->chiptype == 0x4d38105a && 44357325Ssos !(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) { 44452918Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 44553029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 44652918Ssos if (bootverbose) 44756558Ssos ata_printf(scp, device, 44856558Ssos "%s setting up UDMA4 mode on Promise chip\n", 44956558Ssos (error) ? "failed" : "success"); 45053681Ssos if (!error) { 45155333Ssos promise_timing(scp, devno, ATA_UDMA4); 45256558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 45356744Ssos return; 45453681Ssos } 45552918Ssos } 45653681Ssos if (udmamode >= 2) { 45745095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 45853029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 45951520Ssos if (bootverbose) 46056558Ssos ata_printf(scp, device, 46156558Ssos "%s setting up UDMA2 mode on Promise chip\n", 46256558Ssos (error) ? "failed" : "success"); 46353681Ssos if (!error) { 46455333Ssos promise_timing(scp, devno, ATA_UDMA2); 46556558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 46656744Ssos return; 46753681Ssos } 46845095Ssos } 46953681Ssos if (wdmamode >= 2 && apiomode >= 4) { 47045095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 47153029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 47251520Ssos if (bootverbose) 47356558Ssos ata_printf(scp, device, 47456558Ssos "%s setting up WDMA2 mode on Promise chip\n", 47556558Ssos (error) ? "failed" : "success"); 47653681Ssos if (!error) { 47755333Ssos promise_timing(scp, devno, ATA_WDMA2); 47856558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 47956744Ssos return; 48053681Ssos } 48151520Ssos } 48255333Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 48355333Ssos ata_pio2mode(apiomode), 48455333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 48553681Ssos if (bootverbose) 48656558Ssos ata_printf(scp, device, 48756558Ssos "%s setting up PIO%d mode on Promise chip\n", 48856558Ssos (error) ? "failed" : "success", 48956558Ssos (apiomode >= 0) ? apiomode : 0); 49056686Ssos promise_timing(scp, devno, ata_pio2mode(apiomode)); 49156686Ssos scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 49256744Ssos return; 49345095Ssos 49454270Ssos case 0x00041103: /* HighPoint HPT366 controller */ 49553681Ssos /* no ATAPI devices for now */ 49651520Ssos if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 49752067Ssos (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 49852067Ssos break; 49951520Ssos 50057325Ssos if (udmamode >=4 && !(pci_read_config(parent, 0x5a, 1) & 0x2)) { 50152067Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 50253029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 50352067Ssos if (bootverbose) 50456558Ssos ata_printf(scp, device, 50556558Ssos "%s setting up UDMA4 mode on HPT366 chip\n", 50656558Ssos (error) ? "failed" : "success"); 50753681Ssos if (!error) { 50855333Ssos hpt366_timing(scp, devno, ATA_UDMA4); 50956558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 51056744Ssos return; 51153681Ssos } 51251520Ssos } 51353681Ssos if (udmamode >= 2) { 51452067Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 51553029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 51651520Ssos if (bootverbose) 51756558Ssos ata_printf(scp, device, 51856558Ssos "%s setting up UDMA2 mode on HPT366 chip\n", 51956558Ssos (error) ? "failed" : "success"); 52053681Ssos if (!error) { 52155333Ssos hpt366_timing(scp, devno, ATA_UDMA2); 52256558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 52356744Ssos return; 52453681Ssos } 52545095Ssos } 52653681Ssos if (wdmamode >= 2 && apiomode >= 4) { 52745095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 52853029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 52951520Ssos if (bootverbose) 53056558Ssos ata_printf(scp, device, 53156558Ssos "%s setting up WDMA2 mode on HPT366 chip\n", 53256558Ssos (error) ? "failed" : "success"); 53353681Ssos if (!error) { 53455333Ssos hpt366_timing(scp, devno, ATA_WDMA2); 53556558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 53656744Ssos return; 53753681Ssos } 53845095Ssos } 53955333Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 54055333Ssos ata_pio2mode(apiomode), 54155333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 54253681Ssos if (bootverbose) 54356558Ssos ata_printf(scp, device, "%s setting up PIO%d mode on HPT366 chip\n", 54456558Ssos (error) ? "failed" : "success", 54556558Ssos (apiomode >= 0) ? apiomode : 0); 54656686Ssos hpt366_timing(scp, devno, ata_pio2mode(apiomode)); 54756686Ssos scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 54856744Ssos return; 54945095Ssos 55051548Ssos default: /* unknown controller chip */ 55151548Ssos /* better not try generic DMA on ATAPI devices it almost never works */ 55251548Ssos if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 55351548Ssos (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 55451548Ssos break; 55551548Ssos 55656744Ssos /* if controller says its setup for DMA take the easy way out */ 55756744Ssos /* the downside is we dont know what DMA mode we are in */ 55856744Ssos if ((udmamode >= 0 || wdmamode > 1) && 55956744Ssos (inb(scp->bmaddr + ATA_BMSTAT_PORT) & 56056744Ssos ((device==ATA_MASTER) ? 56156744Ssos ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) { 56256744Ssos scp->mode[ATA_DEV(device)] = ATA_DMA; 56356744Ssos return; 56456744Ssos } 56556744Ssos 56651548Ssos /* well, we have no support for this, but try anyways */ 56754594Ssos if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) { 56845095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 56953029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 57051520Ssos if (bootverbose) 57156558Ssos ata_printf(scp, device, 57256558Ssos "%s setting up WDMA2 mode on generic chip\n", 57356558Ssos (error) ? "failed" : "success"); 57453681Ssos if (!error) { 57556558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 57656744Ssos return; 57753681Ssos } 57845095Ssos } 57945095Ssos } 58056988Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 58156988Ssos ata_pio2mode(apiomode), ATA_C_F_SETXFER,ATA_WAIT_READY); 58255333Ssos if (bootverbose) 58356988Ssos ata_printf(scp, device, "%s setting up PIO%d mode on generic chip\n", 58456988Ssos (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode); 58556988Ssos if (!error) 58656988Ssos scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 58757771Ssos else { 58856988Ssos if (bootverbose) 58956988Ssos ata_printf(scp, device, "using PIO mode set by BIOS\n"); 59057771Ssos scp->mode[ATA_DEV(device)] = ATA_PIO; 59157771Ssos } 59245095Ssos} 59345095Ssos 59445095Ssosint32_t 59545095Ssosata_dmasetup(struct ata_softc *scp, int32_t device, 59645095Ssos int8_t *data, int32_t count, int32_t flags) 59745095Ssos{ 59845095Ssos struct ata_dmaentry *dmatab; 59945095Ssos u_int32_t dma_count, dma_base; 60045095Ssos int32_t i = 0; 60145095Ssos 60245720Speter if (((uintptr_t)data & 1) || (count & 1)) 60345095Ssos return -1; 60445095Ssos 60545095Ssos if (!count) { 60656558Ssos ata_printf(scp, device, "zero length DMA transfer attempted\n"); 60745095Ssos return -1; 60845095Ssos } 60945095Ssos 61056558Ssos dmatab = scp->dmatab[ATA_DEV(device)]; 61145095Ssos dma_base = vtophys(data); 61256558Ssos dma_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); 61345095Ssos data += dma_count; 61445095Ssos count -= dma_count; 61545095Ssos 61645095Ssos while (count) { 61745095Ssos dmatab[i].base = dma_base; 61845095Ssos dmatab[i].count = (dma_count & 0xffff); 61945095Ssos i++; 62045095Ssos if (i >= ATA_DMA_ENTRIES) { 62156558Ssos ata_printf(scp, device, "too many segments in DMA table\n"); 62245095Ssos return -1; 62345095Ssos } 62445095Ssos dma_base = vtophys(data); 62556558Ssos dma_count = min(count, PAGE_SIZE); 62656558Ssos data += min(count, PAGE_SIZE); 62756558Ssos count -= min(count, PAGE_SIZE); 62845095Ssos } 62945095Ssos dmatab[i].base = dma_base; 63045095Ssos dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; 63145095Ssos outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab)); 63245095Ssos outb(scp->bmaddr + ATA_BMCMD_PORT, flags ? ATA_BMCMD_WRITE_READ:0); 63345095Ssos outb(scp->bmaddr + ATA_BMSTAT_PORT, (inb(scp->bmaddr + ATA_BMSTAT_PORT) | 63445095Ssos (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 63545095Ssos return 0; 63645095Ssos} 63745095Ssos 63845095Ssosvoid 63952067Ssosata_dmastart(struct ata_softc *scp) 64045095Ssos{ 64152067Ssos scp->flags |= ATA_DMA_ACTIVE; 64245095Ssos outb(scp->bmaddr + ATA_BMCMD_PORT, 64345095Ssos inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); 64445095Ssos} 64545095Ssos 64645095Ssosint32_t 64752067Ssosata_dmadone(struct ata_softc *scp) 64845095Ssos{ 64945095Ssos outb(scp->bmaddr + ATA_BMCMD_PORT, 65045095Ssos inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 65152067Ssos scp->flags &= ~ATA_DMA_ACTIVE; 65245095Ssos return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 65345095Ssos} 65445095Ssos 65545095Ssosint32_t 65652067Ssosata_dmastatus(struct ata_softc *scp) 65745095Ssos{ 65845095Ssos return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 65945095Ssos} 66045095Ssos 66152067Ssosstatic void 66255333Ssospromise_timing(struct ata_softc *scp, int32_t devno, int32_t mode) 66352067Ssos{ 66456988Ssos u_int32_t timing = 0; 66556988Ssos struct promise_timing { 66656988Ssos u_int8_t pa:4; 66756988Ssos u_int8_t prefetch:1; 66856988Ssos u_int8_t iordy:1; 66956988Ssos u_int8_t errdy:1; 67056988Ssos u_int8_t syncin:1; 67156988Ssos u_int8_t pb:5; 67256988Ssos u_int8_t mb:3; 67356988Ssos u_int8_t mc:4; 67456988Ssos u_int8_t dmaw:1; 67556988Ssos u_int8_t dmar:1; 67656988Ssos u_int8_t iordyp:1; 67756988Ssos u_int8_t dmarqp:1; 67856988Ssos u_int8_t reserved:8; 67956988Ssos } *t = (struct promise_timing*)&timing; 68056988Ssos 68156988Ssos t->iordy = 1; t->iordyp = 1; 68256988Ssos if (mode >= ATA_DMA) { 68356988Ssos t->prefetch = 1; t->errdy = 1; t->syncin = 1; 68455333Ssos } 68556988Ssos 68656988Ssos switch (scp->chiptype) { 68756988Ssos case 0x4d33105a: /* Promise 33's */ 68856988Ssos switch (mode) { 68956988Ssos default: 69056988Ssos case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break; 69156988Ssos case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break; 69256988Ssos case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break; 69356988Ssos case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break; 69456988Ssos case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break; 69556988Ssos case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break; 69656988Ssos case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 69756988Ssos } 69856988Ssos break; 69956988Ssos 70056988Ssos case 0x4d38105a: /* Promise 66's */ 70156988Ssos switch (mode) { 70256988Ssos default: 70356988Ssos case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; 70456988Ssos case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break; 70556988Ssos case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break; 70656988Ssos case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break; 70756988Ssos case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break; 70856988Ssos case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; 70956988Ssos case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; 71056988Ssos case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 71156988Ssos } 71256988Ssos break; 71356988Ssos } 71457325Ssos pci_write_config(device_get_parent(scp->dev), 0x60 + (devno<<2), timing, 4); 71555333Ssos} 71652067Ssos 71755333Ssosstatic void 71855333Ssoshpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode) 71955333Ssos{ 72057325Ssos device_t parent = device_get_parent(scp->dev); 72155333Ssos u_int32_t timing; 72255333Ssos 72357325Ssos switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) { 72452067Ssos case 0x85: /* 25Mhz */ 72552067Ssos switch (mode) { 72655333Ssos case ATA_PIO0: timing = 0xc0d08585; break; 72755333Ssos case ATA_PIO1: timing = 0xc0d08572; break; 72855333Ssos case ATA_PIO2: timing = 0xc0ca8542; break; 72955333Ssos case ATA_PIO3: timing = 0xc0ca8532; break; 73055333Ssos case ATA_PIO4: timing = 0xc0ca8521; break; 73155333Ssos case ATA_WDMA2: timing = 0xa0ca8521; break; 73255333Ssos case ATA_UDMA2: timing = 0x90cf8521; break; 73355333Ssos case ATA_UDMA4: timing = 0x90c98521; break; 73455333Ssos default: timing = 0x01208585; 73552067Ssos } 73652067Ssos break; 73752067Ssos default: 73852067Ssos case 0xa7: /* 33MHz */ 73952067Ssos switch (mode) { 74055333Ssos case ATA_PIO0: timing = 0xc0d0a7aa; break; 74155333Ssos case ATA_PIO1: timing = 0xc0d0a7a3; break; 74255333Ssos case ATA_PIO2: timing = 0xc0d0a753; break; 74355333Ssos case ATA_PIO3: timing = 0xc0c8a742; break; 74455333Ssos case ATA_PIO4: timing = 0xc0c8a731; break; 74555333Ssos case ATA_WDMA2: timing = 0xa0c8a731; break; 74655333Ssos case ATA_UDMA2: timing = 0x90caa731; break; 74755333Ssos case ATA_UDMA4: timing = 0x90c9a731; break; 74855333Ssos default: timing = 0x0120a7a7; 74952067Ssos } 75052067Ssos break; 75152067Ssos case 0xd9: /* 40Mhz */ 75252067Ssos switch (mode) { 75355333Ssos case ATA_PIO0: timing = 0xc018d9d9; break; 75455333Ssos case ATA_PIO1: timing = 0xc010d9c7; break; 75555333Ssos case ATA_PIO2: timing = 0xc010d997; break; 75655333Ssos case ATA_PIO3: timing = 0xc010d974; break; 75755333Ssos case ATA_PIO4: timing = 0xc008d963; break; 75855333Ssos case ATA_WDMA2: timing = 0xa008d943; break; 75955333Ssos case ATA_UDMA2: timing = 0x900bd943; break; 76055333Ssos case ATA_UDMA4: timing = 0x900fd943; break; 76155333Ssos default: timing = 0x0120d9d9; 76252067Ssos } 76352067Ssos } 76457325Ssos pci_write_config(parent, 0x40 + (devno << 2) , (timing & ~0x80000000), 4); 76552067Ssos} 76652067Ssos 76745095Ssos#else /* NPCI > 0 */ 76845095Ssos 76956754Ssosvoid 77045095Ssosata_dmainit(struct ata_softc *scp, int32_t device, 77151520Ssos int32_t piomode, int32_t wdmamode, int32_t udmamode) 77245095Ssos{ 77345095Ssos} 77445095Ssos 77545095Ssosint32_t 77645095Ssosata_dmasetup(struct ata_softc *scp, int32_t device, 77751520Ssos int8_t *data, int32_t count, int32_t flags) 77845095Ssos{ 77945095Ssos return -1; 78045095Ssos} 78145095Ssos 78245095Ssosvoid 78352067Ssosata_dmastart(struct ata_softc *scp) 78445095Ssos{ 78545095Ssos} 78645095Ssos 78745095Ssosint32_t 78852067Ssosata_dmadone(struct ata_softc *scp) 78945095Ssos{ 79045095Ssos return -1; 79145095Ssos} 79245095Ssos 79345095Ssosint32_t 79452067Ssosata_dmastatus(struct ata_softc *scp) 79545095Ssos{ 79645095Ssos return -1; 79745095Ssos} 79845095Ssos 79945095Ssos#endif /* NPCI > 0 */ 800