ata-dma.c revision 56988
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 56988 2000-02-04 10:20:22Z sos $ 2945095Ssos */ 3045095Ssos 3145150Ssos#include "pci.h" 3251520Ssos#include "apm.h" 3345095Ssos#include <sys/param.h> 3445095Ssos#include <sys/systm.h> 3545095Ssos#include <sys/buf.h> 3645095Ssos#include <sys/malloc.h> 3745798Ssos#include <sys/bus.h> 3854270Ssos#include <sys/disk.h> 3954270Ssos#include <sys/devicestat.h> 4051520Ssos#include <vm/vm.h> 4145095Ssos#include <vm/pmap.h> 4247272Ssos#if NPCI > 0 4345095Ssos#include <pci/pcivar.h> 4447272Ssos#endif 4551520Ssos#if NAPM > 0 4651520Ssos#include <machine/apm_bios.h> 4751520Ssos#endif 4845095Ssos#include <dev/ata/ata-all.h> 4954270Ssos#include <dev/ata/ata-disk.h> 5045095Ssos 5156754Ssos#if NPCI > 0 5256754Ssos 5352067Ssos/* prototypes */ 5455333Ssosstatic void promise_timing(struct ata_softc *, int32_t, int32_t); 5552067Ssosstatic void hpt366_timing(struct ata_softc *, int32_t, int32_t); 5652067Ssos 5752067Ssos/* misc defines */ 5845720Speter#ifdef __alpha__ 5945720Speter#undef vtophys 6051520Ssos#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va) 6145720Speter#endif 6245720Speter 6356744Ssosvoid 6445095Ssosata_dmainit(struct ata_softc *scp, int32_t device, 6545095Ssos int32_t apiomode, int32_t wdmamode, int32_t udmamode) 6645095Ssos{ 6756558Ssos int32_t devno = (scp->unit << 1) + ATA_DEV(device); 6855333Ssos int32_t error; 6945095Ssos 7056744Ssos /* set our most pessimistic default mode */ 7156744Ssos scp->mode[ATA_DEV(device)] = ATA_PIO; 7256744Ssos 7345095Ssos if (!scp->bmaddr) 7456744Ssos return; 7545095Ssos 7652067Ssos /* if simplex controller, only allow DMA on primary channel */ 7752067Ssos if (scp->unit == 1) { 7852067Ssos outb(scp->bmaddr + ATA_BMSTAT_PORT, inb(scp->bmaddr + ATA_BMSTAT_PORT) & 7952067Ssos (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE)); 8052067Ssos if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) { 8156558Ssos ata_printf(scp, device, "simplex device, DMA on primary only\n"); 8256744Ssos return; 8352067Ssos } 8452067Ssos } 8552067Ssos 8656558Ssos if (!scp->dmatab[ATA_DEV(device)]) { 8756558Ssos void *dmatab; 8845095Ssos 8956558Ssos if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT))) 9056744Ssos return; 9156558Ssos if (((uintptr_t)dmatab >> PAGE_SHIFT) ^ 9256558Ssos (((uintptr_t)dmatab + PAGE_SIZE - 1) >> PAGE_SHIFT)) { 9356558Ssos ata_printf(scp, device, "dmatab crosses page boundary, no DMA\n"); 9456558Ssos free(dmatab, M_DEVBUF); 9556744Ssos return; 9656558Ssos } 9756558Ssos scp->dmatab[ATA_DEV(device)] = dmatab; 9845095Ssos } 9945095Ssos 10055333Ssos switch (scp->chiptype) { 10145095Ssos 10245095Ssos case 0x71118086: /* Intel PIIX4 */ 10356138Ssos case 0x71998086: /* Intel PIIX4e */ 10456138Ssos case 0x24118086: /* Intel ICH */ 10556138Ssos case 0x24218086: /* Intel ICH0 */ 10645095Ssos if (udmamode >= 2) { 10751520Ssos int32_t mask48, new48; 10845095Ssos 10945095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 11053029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 11151520Ssos if (bootverbose) 11256558Ssos ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n", 11356558Ssos (error) ? "failed" : "success", 11456558Ssos (scp->chiptype == 0x24118086) ? "ICH" : 11556558Ssos (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); 11653681Ssos if (!error) { 11753681Ssos mask48 = (1 << devno) + (3 << (16 + (devno << 2))); 11853681Ssos new48 = (1 << devno) + (2 << (16 + (devno << 2))); 11953681Ssos pci_write_config(scp->dev, 0x48, 12053681Ssos (pci_read_config(scp->dev, 0x48, 4) & 12153681Ssos ~mask48) | new48, 4); 12256558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 12356744Ssos return; 12453681Ssos } 12545095Ssos } 12645095Ssos /* FALLTHROUGH */ 12745095Ssos 12845095Ssos case 0x70108086: /* Intel PIIX3 */ 12945095Ssos if (wdmamode >= 2 && apiomode >= 4) { 13045095Ssos int32_t mask40, new40, mask44, new44; 13145095Ssos 13245095Ssos /* if SITRE not set doit for both channels */ 13345798Ssos if (!((pci_read_config(scp->dev, 0x40, 4)>>(scp->unit<<8))&0x4000)){ 13451520Ssos new40 = pci_read_config(scp->dev, 0x40, 4); 13551520Ssos new44 = pci_read_config(scp->dev, 0x44, 4); 13651520Ssos if (!(new40 & 0x00004000)) { 13751520Ssos new44 &= ~0x0000000f; 13851520Ssos new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8); 13951520Ssos } 14051520Ssos if (!(new40 & 0x40000000)) { 14151520Ssos new44 &= ~0x000000f0; 14251520Ssos new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20); 14351520Ssos } 14451520Ssos new40 |= 0x40004000; 14551520Ssos pci_write_config(scp->dev, 0x40, new40, 4); 14651520Ssos pci_write_config(scp->dev, 0x44, new44, 4); 14745095Ssos } 14845095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 14953029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 15051520Ssos if (bootverbose) 15156558Ssos ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n", 15256558Ssos (error) ? "failed" : "success", 15356558Ssos (scp->chiptype == 0x70108086) ? "PIIX3" : 15456558Ssos (scp->chiptype == 0x24118086) ? "ICH" : 15556558Ssos (scp->chiptype == 0x24218086) ? "ICH0" :"PIIX4"); 15653681Ssos if (!error) { 15753681Ssos if (device == ATA_MASTER) { 15853681Ssos mask40 = 0x0000330f; 15953681Ssos new40 = 0x00002307; 16053681Ssos mask44 = 0; 16153681Ssos new44 = 0; 16253681Ssos } 16353681Ssos else { 16453681Ssos mask40 = 0x000000f0; 16553681Ssos new40 = 0x00000070; 16653681Ssos mask44 = 0x0000000f; 16753681Ssos new44 = 0x0000000b; 16853681Ssos } 16953681Ssos if (scp->unit) { 17053681Ssos mask40 <<= 16; 17153681Ssos new40 <<= 16; 17253681Ssos mask44 <<= 4; 17353681Ssos new44 <<= 4; 17453681Ssos } 17553681Ssos pci_write_config(scp->dev, 0x40, 17653681Ssos (pci_read_config(scp->dev, 0x40, 4) & ~mask40)| 17753681Ssos new40, 4); 17853681Ssos pci_write_config(scp->dev, 0x44, 17953681Ssos (pci_read_config(scp->dev, 0x44, 4) & ~mask44)| 18053681Ssos new44, 4); 18156558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 18256744Ssos return; 18345095Ssos } 18451520Ssos } 18553681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 18645095Ssos break; 18745095Ssos 18845095Ssos case 0x12308086: /* Intel PIIX */ 18954544Ssos if (wdmamode >= 2 && apiomode >= 4) { 19054544Ssos int32_t word40; 19154544Ssos 19254544Ssos word40 = pci_read_config(scp->dev, 0x40, 4); 19354544Ssos word40 >>= scp->unit * 16; 19454544Ssos 19554544Ssos /* Check for timing config usable for DMA on controller */ 19654544Ssos if (!((word40 & 0x3300) == 0x2300 && 19754544Ssos ((word40 >> (device == ATA_MASTER ? 0 : 4)) & 1) == 1)) 19854544Ssos break; 19954544Ssos 20054544Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 20154544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 20254544Ssos if (bootverbose) 20356558Ssos ata_printf(scp, device, 20456558Ssos "%s setting up WDMA2 mode on PIIX chip\n", 20556558Ssos (error) ? "failed" : "success"); 20654544Ssos if (!error) { 20756558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 20856744Ssos return; 20954544Ssos } 21054544Ssos } 21145095Ssos break; 21245095Ssos 21352067Ssos case 0x522910b9: /* AcerLabs Aladdin IV/V */ 21453029Ssos /* the Aladdin doesn't support ATAPI DMA on both master & slave */ 21553029Ssos if (scp->devices & ATA_ATAPI_MASTER && scp->devices & ATA_ATAPI_SLAVE) { 21656558Ssos ata_printf(scp, device, 21756558Ssos "Aladdin: two atapi devices on this channel, no DMA\n"); 21853029Ssos break; 21952067Ssos } 22053681Ssos if (udmamode >= 2) { 22152067Ssos int32_t word54 = pci_read_config(scp->dev, 0x54, 4); 22252067Ssos 22351520Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 22453029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 22551520Ssos if (bootverbose) 22656558Ssos ata_printf(scp, device, 22756558Ssos "%s setting up UDMA2 mode on Aladdin chip\n", 22856558Ssos (error) ? "failed" : "success"); 22953681Ssos if (!error) { 23053681Ssos word54 |= 0x5555; 23153681Ssos word54 |= (0x0a << (16 + (scp->unit << 3) + (device << 2))); 23253681Ssos pci_write_config(scp->dev, 0x54, word54, 4); 23353681Ssos pci_write_config(scp->dev, 0x53, 23453681Ssos pci_read_config(scp->dev, 0x53, 1) | 0x03, 1); 23553681Ssos scp->flags |= ATA_ATAPI_DMA_RO; 23656558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 23756744Ssos return; 23853681Ssos } 23951520Ssos } 24053681Ssos if (wdmamode >= 2 && apiomode >= 4) { 24152067Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 24253029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 24352067Ssos if (bootverbose) 24456558Ssos ata_printf(scp, device, 24556558Ssos "%s setting up WDMA2 mode on Aladdin chip\n", 24656558Ssos (error) ? "failed" : "success"); 24753681Ssos if (!error) { 24853681Ssos pci_write_config(scp->dev, 0x53, 24953681Ssos pci_read_config(scp->dev, 0x53, 1) | 0x03, 1); 25053681Ssos scp->flags |= ATA_ATAPI_DMA_RO; 25156558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 25256744Ssos return; 25353681Ssos } 25452067Ssos } 25553681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 25652067Ssos break; 25752067Ssos 25856988Ssos case 0x06861106: /* VIA 82C686 */ 25956988Ssos if (udmamode >= 4) { 26056988Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 26156988Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 26256988Ssos if (bootverbose) 26356988Ssos ata_printf(scp, device, 26456988Ssos "%s setting up UDMA4 mode on VIA chip\n", 26556988Ssos (error) ? "failed" : "success"); 26656988Ssos if (!error) { 26756988Ssos pci_write_config(scp->dev, 0x53 - devno, 0xe8, 1); 26856988Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 26956988Ssos return; 27056138Ssos } 27156988Ssos } 27256988Ssos if (udmamode >= 2) { 27356988Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 27456988Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 27556988Ssos if (bootverbose) 27656988Ssos ata_printf(scp, device, 27756988Ssos "%s setting up UDMA2 mode on VIA chip\n", 27856988Ssos (error) ? "failed" : "success"); 27956988Ssos if (!error) { 28056988Ssos pci_write_config(scp->dev, 0x53 - devno, 0xea, 1); 28156988Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 28256988Ssos return; 28356138Ssos } 28456138Ssos } 28556988Ssos goto via_generic; 28656138Ssos 28756988Ssos case 0x74091022: /* AMD 756 */ 28856988Ssos if (udmamode >= 4) { 28954270Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 29056138Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 29154270Ssos if (bootverbose) 29256558Ssos ata_printf(scp, device, 29356558Ssos "%s setting up UDMA4 mode on AMD chip\n", 29456558Ssos (error) ? "failed" : "success"); 29554270Ssos if (!error) { 29654969Ssos pci_write_config(scp->dev, 0x53 - devno, 0xc3, 1); 29756558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 29856744Ssos return; 29953681Ssos } 30054270Ssos } 30156988Ssos /* FALLTHROUGH */ 30254270Ssos 30356988Ssos case 0x05961106: /* VIA 82C596 */ 30456988Ssos case 0x05861106: /* VIA 82C586 */ 30556988Ssos 30656138Ssos /* UDMA2 mode only on 82C586 > rev1, 82C596, AMD 756 */ 30756988Ssos if ((udmamode >= 2 && scp->chiptype == 0x05861106 && 30855333Ssos pci_read_config(scp->dev, 0x08, 1) >= 0x01) || 30956988Ssos (udmamode >= 2 && scp->chiptype == 0x05961106) || 31055333Ssos (udmamode >= 2 && scp->chiptype == 0x74091022)) { 31153681Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 31253681Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 31353681Ssos if (bootverbose) 31456558Ssos ata_printf(scp, device, "%s setting up UDMA2 mode on %s chip\n", 31556558Ssos (error) ? "failed" : "success", 31656558Ssos (scp->chiptype == 0x74091022) ? "AMD" : "VIA"); 31753681Ssos if (!error) { 31854969Ssos pci_write_config(scp->dev, 0x53 - devno, 0xc0, 1); 31956558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 32056744Ssos return; 32153681Ssos } 32253681Ssos } 32356988Ssos /* FALLTHROUGH */ 32456988Ssos 32556988Ssos case 0x05711106: /* VIA 82C571 */ 32656988Ssosvia_generic: 32753681Ssos if (wdmamode >= 2 && apiomode >= 4) { 32853681Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 32953681Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 33053681Ssos if (bootverbose) 33156558Ssos ata_printf(scp, device, "%s setting up WDMA2 mode on %s chip\n", 33256558Ssos (error) ? "failed" : "success", 33356558Ssos (scp->chiptype == 0x74091022) ? "AMD" : "VIA"); 33453681Ssos if (!error) { 33554969Ssos pci_write_config(scp->dev, 0x53 - devno, 0x82, 1); 33654969Ssos pci_write_config(scp->dev, 0x4b - devno, 0x31, 1); 33756558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 33856744Ssos return; 33953681Ssos } 34053681Ssos } 34153681Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 34253681Ssos break; 34353681Ssos 34454544Ssos case 0x55131039: /* SiS 5591 */ 34554544Ssos if (udmamode >= 2) { 34654544Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 34754544Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 34854544Ssos if (bootverbose) 34956558Ssos ata_printf(scp, device, 35056558Ssos "%s setting up UDMA2 mode on SiS chip\n", 35156558Ssos (error) ? "failed" : "success"); 35254544Ssos if (!error) { 35354544Ssos pci_write_config(scp->dev, 0x40 + (devno << 1), 0xa301, 2); 35456558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 35556744Ssos return; 35654544Ssos } 35754544Ssos } 35854544Ssos if (wdmamode >=2 && apiomode >= 4) { 35954544Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 36054544Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 36154544Ssos if (bootverbose) 36256558Ssos ata_printf(scp, device, 36356558Ssos "%s setting up WDMA2 mode on SiS chip\n", 36456558Ssos (error) ? "failed" : "success"); 36554544Ssos if (!error) { 36654544Ssos pci_write_config(scp->dev, 0x40 + (devno << 1), 0x0301, 2); 36756558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 36856744Ssos return; 36954544Ssos } 37054544Ssos } 37154544Ssos /* we could set PIO mode timings, but we assume the BIOS did that */ 37254544Ssos break; 37354544Ssos 37452067Ssos case 0x4d33105a: /* Promise Ultra33 / FastTrak33 controllers */ 37552067Ssos case 0x4d38105a: /* Promise Ultra66 / FastTrak66 controllers */ 37652067Ssos /* the Promise can only do DMA on ATA disks not on ATAPI devices */ 37752067Ssos if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 37852067Ssos (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 37952067Ssos break; 38052067Ssos 38155333Ssos if (udmamode >=4 && scp->chiptype == 0x4d38105a && 38252918Ssos !(pci_read_config(scp->dev, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) { 38352918Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 38453029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 38552918Ssos if (bootverbose) 38656558Ssos ata_printf(scp, device, 38756558Ssos "%s setting up UDMA4 mode on Promise chip\n", 38856558Ssos (error) ? "failed" : "success"); 38953681Ssos if (!error) { 39055333Ssos promise_timing(scp, devno, ATA_UDMA4); 39156558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 39256744Ssos return; 39353681Ssos } 39452918Ssos } 39553681Ssos if (udmamode >= 2) { 39645095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 39753029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 39851520Ssos if (bootverbose) 39956558Ssos ata_printf(scp, device, 40056558Ssos "%s setting up UDMA2 mode on Promise chip\n", 40156558Ssos (error) ? "failed" : "success"); 40253681Ssos if (!error) { 40355333Ssos promise_timing(scp, devno, ATA_UDMA2); 40456558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 40556744Ssos return; 40653681Ssos } 40745095Ssos } 40853681Ssos if (wdmamode >= 2 && apiomode >= 4) { 40945095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 41053029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 41151520Ssos if (bootverbose) 41256558Ssos ata_printf(scp, device, 41356558Ssos "%s setting up WDMA2 mode on Promise chip\n", 41456558Ssos (error) ? "failed" : "success"); 41553681Ssos if (!error) { 41655333Ssos promise_timing(scp, devno, ATA_WDMA2); 41756558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 41856744Ssos return; 41953681Ssos } 42051520Ssos } 42155333Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 42255333Ssos ata_pio2mode(apiomode), 42355333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 42453681Ssos if (bootverbose) 42556558Ssos ata_printf(scp, device, 42656558Ssos "%s setting up PIO%d mode on Promise chip\n", 42756558Ssos (error) ? "failed" : "success", 42856558Ssos (apiomode >= 0) ? apiomode : 0); 42956686Ssos promise_timing(scp, devno, ata_pio2mode(apiomode)); 43056686Ssos scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 43156744Ssos return; 43245095Ssos 43354270Ssos case 0x00041103: /* HighPoint HPT366 controller */ 43453681Ssos /* no ATAPI devices for now */ 43551520Ssos if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 43652067Ssos (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 43752067Ssos break; 43851520Ssos 43952067Ssos if (udmamode >=4 && !(pci_read_config(scp->dev, 0x5a, 1) & 0x2)) { 44052067Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 44153029Ssos ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY); 44252067Ssos if (bootverbose) 44356558Ssos ata_printf(scp, device, 44456558Ssos "%s setting up UDMA4 mode on HPT366 chip\n", 44556558Ssos (error) ? "failed" : "success"); 44653681Ssos if (!error) { 44755333Ssos hpt366_timing(scp, devno, ATA_UDMA4); 44856558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA4; 44956744Ssos return; 45053681Ssos } 45151520Ssos } 45253681Ssos if (udmamode >= 2) { 45352067Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 45453029Ssos ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 45551520Ssos if (bootverbose) 45656558Ssos ata_printf(scp, device, 45756558Ssos "%s setting up UDMA2 mode on HPT366 chip\n", 45856558Ssos (error) ? "failed" : "success"); 45953681Ssos if (!error) { 46055333Ssos hpt366_timing(scp, devno, ATA_UDMA2); 46156558Ssos scp->mode[ATA_DEV(device)] = ATA_UDMA2; 46256744Ssos return; 46353681Ssos } 46445095Ssos } 46553681Ssos if (wdmamode >= 2 && apiomode >= 4) { 46645095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 46753029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 46851520Ssos if (bootverbose) 46956558Ssos ata_printf(scp, device, 47056558Ssos "%s setting up WDMA2 mode on HPT366 chip\n", 47156558Ssos (error) ? "failed" : "success"); 47253681Ssos if (!error) { 47355333Ssos hpt366_timing(scp, devno, ATA_WDMA2); 47456558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 47556744Ssos return; 47653681Ssos } 47745095Ssos } 47855333Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 47955333Ssos ata_pio2mode(apiomode), 48055333Ssos ATA_C_F_SETXFER, ATA_WAIT_READY); 48153681Ssos if (bootverbose) 48256558Ssos ata_printf(scp, device, "%s setting up PIO%d mode on HPT366 chip\n", 48356558Ssos (error) ? "failed" : "success", 48456558Ssos (apiomode >= 0) ? apiomode : 0); 48556686Ssos hpt366_timing(scp, devno, ata_pio2mode(apiomode)); 48656686Ssos scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 48756744Ssos return; 48845095Ssos 48951548Ssos default: /* unknown controller chip */ 49051548Ssos /* better not try generic DMA on ATAPI devices it almost never works */ 49151548Ssos if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || 49251548Ssos (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE)) 49351548Ssos break; 49451548Ssos 49556744Ssos /* if controller says its setup for DMA take the easy way out */ 49656744Ssos /* the downside is we dont know what DMA mode we are in */ 49756744Ssos if ((udmamode >= 0 || wdmamode > 1) && 49856744Ssos (inb(scp->bmaddr + ATA_BMSTAT_PORT) & 49956744Ssos ((device==ATA_MASTER) ? 50056744Ssos ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) { 50156744Ssos scp->mode[ATA_DEV(device)] = ATA_DMA; 50256744Ssos return; 50356744Ssos } 50456744Ssos 50551548Ssos /* well, we have no support for this, but try anyways */ 50654594Ssos if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) { 50745095Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 50853029Ssos ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY); 50951520Ssos if (bootverbose) 51056558Ssos ata_printf(scp, device, 51156558Ssos "%s setting up WDMA2 mode on generic chip\n", 51256558Ssos (error) ? "failed" : "success"); 51353681Ssos if (!error) { 51456558Ssos scp->mode[ATA_DEV(device)] = ATA_WDMA2; 51556744Ssos return; 51653681Ssos } 51745095Ssos } 51845095Ssos } 51956988Ssos error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0, 52056988Ssos ata_pio2mode(apiomode), ATA_C_F_SETXFER,ATA_WAIT_READY); 52155333Ssos if (bootverbose) 52256988Ssos ata_printf(scp, device, "%s setting up PIO%d mode on generic chip\n", 52356988Ssos (error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode); 52456988Ssos if (!error) 52556988Ssos scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode); 52656988Ssos else 52756988Ssos if (bootverbose) 52856988Ssos ata_printf(scp, device, "using PIO mode set by BIOS\n"); 52945095Ssos} 53045095Ssos 53145095Ssosint32_t 53245095Ssosata_dmasetup(struct ata_softc *scp, int32_t device, 53345095Ssos int8_t *data, int32_t count, int32_t flags) 53445095Ssos{ 53545095Ssos struct ata_dmaentry *dmatab; 53645095Ssos u_int32_t dma_count, dma_base; 53745095Ssos int32_t i = 0; 53845095Ssos 53945720Speter if (((uintptr_t)data & 1) || (count & 1)) 54045095Ssos return -1; 54145095Ssos 54245095Ssos if (!count) { 54356558Ssos ata_printf(scp, device, "zero length DMA transfer attempted\n"); 54445095Ssos return -1; 54545095Ssos } 54645095Ssos 54756558Ssos dmatab = scp->dmatab[ATA_DEV(device)]; 54845095Ssos dma_base = vtophys(data); 54956558Ssos dma_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); 55045095Ssos data += dma_count; 55145095Ssos count -= dma_count; 55245095Ssos 55345095Ssos while (count) { 55445095Ssos dmatab[i].base = dma_base; 55545095Ssos dmatab[i].count = (dma_count & 0xffff); 55645095Ssos i++; 55745095Ssos if (i >= ATA_DMA_ENTRIES) { 55856558Ssos ata_printf(scp, device, "too many segments in DMA table\n"); 55945095Ssos return -1; 56045095Ssos } 56145095Ssos dma_base = vtophys(data); 56256558Ssos dma_count = min(count, PAGE_SIZE); 56356558Ssos data += min(count, PAGE_SIZE); 56456558Ssos count -= min(count, PAGE_SIZE); 56545095Ssos } 56645095Ssos dmatab[i].base = dma_base; 56745095Ssos dmatab[i].count = (dma_count & 0xffff) | ATA_DMA_EOT; 56845095Ssos outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab)); 56945095Ssos outb(scp->bmaddr + ATA_BMCMD_PORT, flags ? ATA_BMCMD_WRITE_READ:0); 57045095Ssos outb(scp->bmaddr + ATA_BMSTAT_PORT, (inb(scp->bmaddr + ATA_BMSTAT_PORT) | 57145095Ssos (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR))); 57245095Ssos return 0; 57345095Ssos} 57445095Ssos 57545095Ssosvoid 57652067Ssosata_dmastart(struct ata_softc *scp) 57745095Ssos{ 57852067Ssos scp->flags |= ATA_DMA_ACTIVE; 57945095Ssos outb(scp->bmaddr + ATA_BMCMD_PORT, 58045095Ssos inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP); 58145095Ssos} 58245095Ssos 58345095Ssosint32_t 58452067Ssosata_dmadone(struct ata_softc *scp) 58545095Ssos{ 58645095Ssos outb(scp->bmaddr + ATA_BMCMD_PORT, 58745095Ssos inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP); 58852067Ssos scp->flags &= ~ATA_DMA_ACTIVE; 58945095Ssos return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 59045095Ssos} 59145095Ssos 59245095Ssosint32_t 59352067Ssosata_dmastatus(struct ata_softc *scp) 59445095Ssos{ 59545095Ssos return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK; 59645095Ssos} 59745095Ssos 59852067Ssosstatic void 59955333Ssospromise_timing(struct ata_softc *scp, int32_t devno, int32_t mode) 60052067Ssos{ 60156988Ssos u_int32_t timing = 0; 60256988Ssos struct promise_timing { 60356988Ssos u_int8_t pa:4; 60456988Ssos u_int8_t prefetch:1; 60556988Ssos u_int8_t iordy:1; 60656988Ssos u_int8_t errdy:1; 60756988Ssos u_int8_t syncin:1; 60856988Ssos u_int8_t pb:5; 60956988Ssos u_int8_t mb:3; 61056988Ssos u_int8_t mc:4; 61156988Ssos u_int8_t dmaw:1; 61256988Ssos u_int8_t dmar:1; 61356988Ssos u_int8_t iordyp:1; 61456988Ssos u_int8_t dmarqp:1; 61556988Ssos u_int8_t reserved:8; 61656988Ssos } *t = (struct promise_timing*)&timing; 61756988Ssos 61856988Ssos t->iordy = 1; t->iordyp = 1; 61956988Ssos if (mode >= ATA_DMA) { 62056988Ssos t->prefetch = 1; t->errdy = 1; t->syncin = 1; 62155333Ssos } 62256988Ssos 62356988Ssos switch (scp->chiptype) { 62456988Ssos case 0x4d33105a: /* Promise 33's */ 62556988Ssos switch (mode) { 62656988Ssos default: 62756988Ssos case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break; 62856988Ssos case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break; 62956988Ssos case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break; 63056988Ssos case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break; 63156988Ssos case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break; 63256988Ssos case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break; 63356988Ssos case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 63456988Ssos } 63556988Ssos break; 63656988Ssos 63756988Ssos case 0x4d38105a: /* Promise 66's */ 63856988Ssos switch (mode) { 63956988Ssos default: 64056988Ssos case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break; 64156988Ssos case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break; 64256988Ssos case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break; 64356988Ssos case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break; 64456988Ssos case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break; 64556988Ssos case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break; 64656988Ssos case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break; 64756988Ssos case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break; 64856988Ssos } 64956988Ssos break; 65056988Ssos } 65155333Ssos pci_write_config(scp->dev, 0x60 + (devno << 2), timing, 4); 65255333Ssos} 65352067Ssos 65455333Ssosstatic void 65555333Ssoshpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode) 65655333Ssos{ 65755333Ssos u_int32_t timing; 65855333Ssos 65955333Ssos switch (pci_read_config(scp->dev, 0x41 + (devno << 2), 1)) { 66052067Ssos case 0x85: /* 25Mhz */ 66152067Ssos switch (mode) { 66255333Ssos case ATA_PIO0: timing = 0xc0d08585; break; 66355333Ssos case ATA_PIO1: timing = 0xc0d08572; break; 66455333Ssos case ATA_PIO2: timing = 0xc0ca8542; break; 66555333Ssos case ATA_PIO3: timing = 0xc0ca8532; break; 66655333Ssos case ATA_PIO4: timing = 0xc0ca8521; break; 66755333Ssos case ATA_WDMA2: timing = 0xa0ca8521; break; 66855333Ssos case ATA_UDMA2: timing = 0x90cf8521; break; 66955333Ssos case ATA_UDMA4: timing = 0x90c98521; break; 67055333Ssos default: timing = 0x01208585; 67152067Ssos } 67252067Ssos break; 67352067Ssos default: 67452067Ssos case 0xa7: /* 33MHz */ 67552067Ssos switch (mode) { 67655333Ssos case ATA_PIO0: timing = 0xc0d0a7aa; break; 67755333Ssos case ATA_PIO1: timing = 0xc0d0a7a3; break; 67855333Ssos case ATA_PIO2: timing = 0xc0d0a753; break; 67955333Ssos case ATA_PIO3: timing = 0xc0c8a742; break; 68055333Ssos case ATA_PIO4: timing = 0xc0c8a731; break; 68155333Ssos case ATA_WDMA2: timing = 0xa0c8a731; break; 68255333Ssos case ATA_UDMA2: timing = 0x90caa731; break; 68355333Ssos case ATA_UDMA4: timing = 0x90c9a731; break; 68455333Ssos default: timing = 0x0120a7a7; 68552067Ssos } 68652067Ssos break; 68752067Ssos case 0xd9: /* 40Mhz */ 68852067Ssos switch (mode) { 68955333Ssos case ATA_PIO0: timing = 0xc018d9d9; break; 69055333Ssos case ATA_PIO1: timing = 0xc010d9c7; break; 69155333Ssos case ATA_PIO2: timing = 0xc010d997; break; 69255333Ssos case ATA_PIO3: timing = 0xc010d974; break; 69355333Ssos case ATA_PIO4: timing = 0xc008d963; break; 69455333Ssos case ATA_WDMA2: timing = 0xa008d943; break; 69555333Ssos case ATA_UDMA2: timing = 0x900bd943; break; 69655333Ssos case ATA_UDMA4: timing = 0x900fd943; break; 69755333Ssos default: timing = 0x0120d9d9; 69852067Ssos } 69952067Ssos } 70056988Ssos pci_write_config(scp->dev, 0x40 + (devno << 2) , (timing & ~0x80000000), 4); 70152067Ssos} 70252067Ssos 70345095Ssos#else /* NPCI > 0 */ 70445095Ssos 70556754Ssosvoid 70645095Ssosata_dmainit(struct ata_softc *scp, int32_t device, 70751520Ssos int32_t piomode, int32_t wdmamode, int32_t udmamode) 70845095Ssos{ 70945095Ssos} 71045095Ssos 71145095Ssosint32_t 71245095Ssosata_dmasetup(struct ata_softc *scp, int32_t device, 71351520Ssos int8_t *data, int32_t count, int32_t flags) 71445095Ssos{ 71545095Ssos return -1; 71645095Ssos} 71745095Ssos 71845095Ssosvoid 71952067Ssosata_dmastart(struct ata_softc *scp) 72045095Ssos{ 72145095Ssos} 72245095Ssos 72345095Ssosint32_t 72452067Ssosata_dmadone(struct ata_softc *scp) 72545095Ssos{ 72645095Ssos return -1; 72745095Ssos} 72845095Ssos 72945095Ssosint32_t 73052067Ssosata_dmastatus(struct ata_softc *scp) 73145095Ssos{ 73245095Ssos return -1; 73345095Ssos} 73445095Ssos 73545095Ssos#endif /* NPCI > 0 */ 736