1669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/* 2669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer 3669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * (C) 2005 Red Hat Inc 4ab77163008c596aad9624ceab190d840c0143fa8Alan Cox * Alan Cox <alan@lxorguk.ukuu.org.uk> 5a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz * (C) 2007,2009,2010 Bartlomiej Zolnierkiewicz 6669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 7669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Based in part on linux/drivers/ide/pci/pdc202xx_old.c 8669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 9669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * First cut with LBA48/ATAPI 10669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 11669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * TODO: 1206b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox * Channel interlock/reset on both required ? 13669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 1485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 15669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/kernel.h> 16669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/module.h> 17669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/pci.h> 18669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/init.h> 19669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/blkdev.h> 20669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/delay.h> 21669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <scsi/scsi_host.h> 22669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#include <linux/libata.h> 23669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 24669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik#define DRV_NAME "pata_pdc202xx_old" 2506b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox#define DRV_VERSION "0.4.3" 26669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 27a0fcdc0259e98d1c16d96baea9ba8a8603e41791Jeff Garzikstatic int pdc2026x_cable_detect(struct ata_port *ap) 28669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 29669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 30669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u16 cis; 3185cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 32669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_word(pdev, 0x50, &cis); 33669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (cis & (1 << (10 + ap->port_no))) 34a0ac38f16045f90dbbcd265b638cd7254c53aa65Alan Cox return ATA_CBL_PATA40; 35a0ac38f16045f90dbbcd265b638cd7254c53aa65Alan Cox return ATA_CBL_PATA80; 36669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 37669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 38750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewiczstatic void pdc202xx_exec_command(struct ata_port *ap, 39a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz const struct ata_taskfile *tf) 40a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz{ 41a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); 42a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz 43a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz iowrite8(tf->command, ap->ioaddr.command_addr); 44a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz ndelay(400); 45a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz} 46a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz 47606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyovstatic bool pdc202xx_irq_check(struct ata_port *ap) 48606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov{ 49606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov struct pci_dev *pdev = to_pci_dev(ap->host->dev); 50606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov unsigned long master = pci_resource_start(pdev, 4); 51606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov u8 sc1d = inb(master + 0x1d); 52606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov 53606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov if (ap->port_no) { 54606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov /* 55606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov * bit 7: error, bit 6: interrupting, 56606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov * bit 5: FIFO full, bit 4: FIFO empty 57606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov */ 58606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov return sc1d & 0x40; 59606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov } else { 60606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov /* 61606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov * bit 3: error, bit 2: interrupting, 62606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov * bit 1: FIFO full, bit 0: FIFO empty 63606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov */ 64606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov return sc1d & 0x04; 65606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov } 66606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov} 67606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov 68669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 69ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox * pdc202xx_configure_piomode - set chip PIO timing 70669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @ap: ATA interface 71669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @adev: ATA device 72669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @pio: PIO mode 73669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 74669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Called to do the PIO mode setup. Our timing registers are shared 75669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * so a configure_dmamode call will undo any work we do here and vice 76669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * versa 77669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 7885cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 79ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio) 80669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 81669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 8263ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz int port = 0x60 + 8 * ap->port_no + 4 * adev->devno; 83669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik static u16 pio_timing[5] = { 84669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 0x0913, 0x050C , 0x0308, 0x0206, 0x0104 85669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik }; 86669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u8 r_ap, r_bp; 87669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 88669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_byte(pdev, port, &r_ap); 89669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_byte(pdev, port + 1, &r_bp); 90669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_ap &= ~0x3F; /* Preserve ERRDY_EN, SYNC_IN */ 9163ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz r_bp &= ~0x1F; 92669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_ap |= (pio_timing[pio] >> 8); 93669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_bp |= (pio_timing[pio] & 0xFF); 9485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 95669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (ata_pio_need_iordy(adev)) 96669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_ap |= 0x20; /* IORDY enable */ 97669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (adev->class == ATA_DEV_ATA) 98669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_ap |= 0x10; /* FIFO enable */ 99669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_write_config_byte(pdev, port, r_ap); 100669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_write_config_byte(pdev, port + 1, r_bp); 101669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 102669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 103669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 104ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox * pdc202xx_set_piomode - set initial PIO mode data 105669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @ap: ATA interface 106669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @adev: ATA device 107669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 108669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Called to do the PIO mode setup. Our timing registers are shared 109669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * but we want to set the PIO timing by default. 110669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 11185cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 112ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void pdc202xx_set_piomode(struct ata_port *ap, struct ata_device *adev) 113669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 114ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox pdc202xx_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); 115669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 116669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 117669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 118ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox * pdc202xx_configure_dmamode - set DMA mode in chip 119669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @ap: ATA interface 120669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @adev: ATA device 121669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 122669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Load DMA cycle times into the chip ready for a DMA transfer 123669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * to occur. 124669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 12585cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 126ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev) 127669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 128669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct pci_dev *pdev = to_pci_dev(ap->host->dev); 12963ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz int port = 0x60 + 8 * ap->port_no + 4 * adev->devno; 130669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik static u8 udma_timing[6][2] = { 131669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0x60, 0x03 }, /* 33 Mhz Clock */ 132669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0x40, 0x02 }, 133669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0x20, 0x01 }, 134669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0x40, 0x02 }, /* 66 Mhz Clock */ 135669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 0x20, 0x01 }, 13685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik { 0x20, 0x01 } 137669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik }; 13863ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz static u8 mdma_timing[3][2] = { 13963ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz { 0xe0, 0x0f }, 14006b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox { 0x60, 0x04 }, 14106b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox { 0x60, 0x03 }, 14263ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz }; 143669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u8 r_bp, r_cp; 14485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 145669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_byte(pdev, port + 1, &r_bp); 146669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_read_config_byte(pdev, port + 2, &r_cp); 14785cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 14863ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz r_bp &= ~0xE0; 149669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_cp &= ~0x0F; 15085cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 151669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (adev->dma_mode >= XFER_UDMA_0) { 152669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik int speed = adev->dma_mode - XFER_UDMA_0; 153669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_bp |= udma_timing[speed][0]; 154669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik r_cp |= udma_timing[speed][1]; 15585cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 156669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } else { 157669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik int speed = adev->dma_mode - XFER_MW_DMA_0; 15863ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz r_bp |= mdma_timing[speed][0]; 15963ed71019c4437caef65fca1f83c990ae729024fBartlomiej Zolnierkiewicz r_cp |= mdma_timing[speed][1]; 160669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 161669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_write_config_byte(pdev, port + 1, r_bp); 162669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik pci_write_config_byte(pdev, port + 2, r_cp); 16385cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 164669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 165669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 166669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 167669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * pdc2026x_bmdma_start - DMA engine begin 168669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @qc: ATA command 169669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 170669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * In UDMA3 or higher we have to clock switch for the duration of the 171669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * DMA transfer sequence. 17206b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox * 17306b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox * Note: The host lock held by the libata layer protects 17406b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox * us from two channels both trying to set DMA bits at once 175669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 17685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 177669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic void pdc2026x_bmdma_start(struct ata_queued_cmd *qc) 178669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 179669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct ata_port *ap = qc->ap; 180669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct ata_device *adev = qc->dev; 181669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct ata_taskfile *tf = &qc->tf; 182669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik int sel66 = ap->port_no ? 0x08: 0x02; 183669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 1840d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr; 1850d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo void __iomem *clock = master + 0x11; 1860d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no); 18785cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 188669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik u32 len; 18985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 190669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Check we keep host level locking here */ 1916ad58b245a543461bd55d51b8303f555419687b2Bartlomiej Zolnierkiewicz if (adev->dma_mode > XFER_UDMA_2) 1920d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo iowrite8(ioread8(clock) | sel66, clock); 193669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik else 1940d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo iowrite8(ioread8(clock) & ~sel66, clock); 195669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 19685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik /* The DMA clocks may have been trashed by a reset. FIXME: make conditional 197669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik and move to qc_issue ? */ 198ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox pdc202xx_set_dmamode(ap, qc->dev); 199669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 200669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Cases the state machine will not complete correctly without help */ 2010dc36888d4422140f9eaf50f24953ec109f750a3Tejun Heo if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATAPI_PROT_DMA) { 2025e5188108bcf9ab2e6f87b4b54924354040b0aa7Alan Cox len = qc->nbytes / 2; 20385cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 204669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (tf->flags & ATA_TFLAG_WRITE) 205669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik len |= 0x06000000; 206669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik else 207669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik len |= 0x05000000; 20885cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 2090d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo iowrite32(len, atapi_reg); 210669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 21185cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 21285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik /* Activate DMA */ 213669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik ata_bmdma_start(qc); 214669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 215669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 216669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 217669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * pdc2026x_bmdma_end - DMA engine stop 218669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @qc: ATA command 219669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 220669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * After a DMA completes we need to put the clock back to 33MHz for 221669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * PIO timings. 22206b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox * 22306b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox * Note: The host lock held by the libata layer protects 22406b74dd28fa607249c5e41e5f1f6dd1885fe0a0dAlan Cox * us from two channels both trying to set DMA bits at once 225669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 22685cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 227669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc) 228669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 229669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct ata_port *ap = qc->ap; 230669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct ata_device *adev = qc->dev; 231669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct ata_taskfile *tf = &qc->tf; 23285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 233669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik int sel66 = ap->port_no ? 0x08: 0x02; 234669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* The clock bits are in the same register for both channels */ 2350d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr; 2360d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo void __iomem *clock = master + 0x11; 2370d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no); 23885cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 239669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Cases the state machine will not complete correctly */ 2400dc36888d4422140f9eaf50f24953ec109f750a3Tejun Heo if (tf->protocol == ATAPI_PROT_DMA || (tf->flags & ATA_TFLAG_LBA48)) { 2410d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo iowrite32(0, atapi_reg); 2420d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo iowrite8(ioread8(clock) & ~sel66, clock); 243669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 244669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Flip back to 33Mhz for PIO */ 2456ad58b245a543461bd55d51b8303f555419687b2Bartlomiej Zolnierkiewicz if (adev->dma_mode > XFER_UDMA_2) 2460d5ff566779f894ca9937231a181eb31e4adff0eTejun Heo iowrite8(ioread8(clock) & ~sel66, clock); 247669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik ata_bmdma_stop(qc); 24836906d9beab941452cad406cc03f05cc78671256Alan Cox pdc202xx_set_piomode(ap, adev); 249669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 250669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 251669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik/** 252669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * pdc2026x_dev_config - device setup hook 253669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * @adev: newly found device 254669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * 255669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * Perform chip specific early setup. We need to lock the transfer 256669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * sizes to 8bit to avoid making the state engine on the 2026x cards 257669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik * barf. 258669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik */ 25985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 260cd0d3bbcdd650651b7ccfaf55d107e3fc237d95aAlan Coxstatic void pdc2026x_dev_config(struct ata_device *adev) 261669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 262669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik adev->max_sectors = 256; 263669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 264669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 26536906d9beab941452cad406cc03f05cc78671256Alan Coxstatic int pdc2026x_port_start(struct ata_port *ap) 26636906d9beab941452cad406cc03f05cc78671256Alan Cox{ 26736906d9beab941452cad406cc03f05cc78671256Alan Cox void __iomem *bmdma = ap->ioaddr.bmdma_addr; 26836906d9beab941452cad406cc03f05cc78671256Alan Cox if (bmdma) { 26936906d9beab941452cad406cc03f05cc78671256Alan Cox /* Enable burst mode */ 27036906d9beab941452cad406cc03f05cc78671256Alan Cox u8 burst = ioread8(bmdma + 0x1f); 27136906d9beab941452cad406cc03f05cc78671256Alan Cox iowrite8(burst | 0x01, bmdma + 0x1f); 27236906d9beab941452cad406cc03f05cc78671256Alan Cox } 273c7087652e1890a3feef35b30ee1d4be68e1932cdTejun Heo return ata_bmdma_port_start(ap); 27436906d9beab941452cad406cc03f05cc78671256Alan Cox} 27536906d9beab941452cad406cc03f05cc78671256Alan Cox 276aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox/** 277aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * pdc2026x_check_atapi_dma - Check whether ATAPI DMA can be supported for this command 278aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * @qc: Metadata associated with taskfile to check 279aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * 280aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * Just say no - not supported on older Promise. 281aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * 282aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * LOCKING: 283aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * None (inherited from caller). 284aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * 285aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * RETURNS: 0 when ATAPI DMA can be used 286aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox * 1 otherwise 287aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox */ 288aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox 289aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Coxstatic int pdc2026x_check_atapi_dma(struct ata_queued_cmd *qc) 290aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox{ 291aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox return 1; 292aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox} 293aa8f2371c564fc9b289dab3a8ecd93212d021fd2Alan Cox 294ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic struct scsi_host_template pdc202xx_sht = { 29568d1d07b510bb57a504588adc2bd2758adea0965Tejun Heo ATA_BMDMA_SHT(DRV_NAME), 296669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 297669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 298669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic struct ata_port_operations pdc2024x_port_ops = { 299029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .inherits = &ata_bmdma_port_ops, 300029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo 301029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .cable_detect = ata_cable_40wire, 302029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .set_piomode = pdc202xx_set_piomode, 303029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .set_dmamode = pdc202xx_set_dmamode, 304a75032e8772d13dab5e3501413d7e14a148281b4Bartlomiej Zolnierkiewicz 305750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewicz .sff_exec_command = pdc202xx_exec_command, 306606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov .sff_irq_check = pdc202xx_irq_check, 30785cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik}; 308669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 309669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzikstatic struct ata_port_operations pdc2026x_port_ops = { 310029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .inherits = &pdc2024x_port_ops, 311029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo 312029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .check_atapi_dma = pdc2026x_check_atapi_dma, 313029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .bmdma_start = pdc2026x_bmdma_start, 314029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .bmdma_stop = pdc2026x_bmdma_stop, 315029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo 316029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .cable_detect = pdc2026x_cable_detect, 317029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .dev_config = pdc2026x_dev_config, 318029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo 319029cfd6b74fc5c517865fad78cf4a3ea8d9b664aTejun Heo .port_start = pdc2026x_port_start, 320750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewicz 321750e519da7b3f470fe1b5b55c8d8f52d6d6371e4Bartlomiej Zolnierkiewicz .sff_exec_command = pdc202xx_exec_command, 322606254e3c1faeb091203c58c2da8e3e4433aae6dSergei Shtylyov .sff_irq_check = pdc202xx_irq_check, 32385cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik}; 324669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 325ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) 326669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 3271626aeb881236c8cb022b5e4ca594146a951d669Tejun Heo static const struct ata_port_info info[3] = { 328669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 3291d2808fd3d2d5d2c0483796a0f443d1cb3f11367Jeff Garzik .flags = ATA_FLAG_SLAVE_POSS, 33014bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .pio_mask = ATA_PIO4, 33114bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .mwdma_mask = ATA_MWDMA2, 332669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .udma_mask = ATA_UDMA2, 333669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .port_ops = &pdc2024x_port_ops 33485cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik }, 335669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 3361d2808fd3d2d5d2c0483796a0f443d1cb3f11367Jeff Garzik .flags = ATA_FLAG_SLAVE_POSS, 33714bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .pio_mask = ATA_PIO4, 33814bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .mwdma_mask = ATA_MWDMA2, 339669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .udma_mask = ATA_UDMA4, 340669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .port_ops = &pdc2026x_port_ops 341669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik }, 342669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik { 3431d2808fd3d2d5d2c0483796a0f443d1cb3f11367Jeff Garzik .flags = ATA_FLAG_SLAVE_POSS, 34414bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .pio_mask = ATA_PIO4, 34514bdef982caeda19afe34010482867c18217c641Erik Inge Bolsø .mwdma_mask = ATA_MWDMA2, 346669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .udma_mask = ATA_UDMA5, 347669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik .port_ops = &pdc2026x_port_ops 348669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 34985cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 350669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik }; 3511626aeb881236c8cb022b5e4ca594146a951d669Tejun Heo const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL }; 35285cd7251b9112e3dabeac9fd3b175601ca607241Jeff Garzik 353669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (dev->device == PCI_DEVICE_ID_PROMISE_20265) { 354669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik struct pci_dev *bridge = dev->bus->self; 355669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik /* Don't grab anything behind a Promise I2O RAID */ 356669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik if (bridge && bridge->vendor == PCI_VENDOR_ID_INTEL) { 357b447916e2b8c80f37aa88512ea39a05d5d11507dJeff Garzik if (bridge->device == PCI_DEVICE_ID_INTEL_I960) 358669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik return -ENODEV; 359b447916e2b8c80f37aa88512ea39a05d5d11507dJeff Garzik if (bridge->device == PCI_DEVICE_ID_INTEL_I960RM) 360669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik return -ENODEV; 361669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 362669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik } 3631c5afdf7a629d2e77de8dd043b97a33dcd7e6dfaTejun Heo return ata_pci_bmdma_init_one(dev, ppi, &pdc202xx_sht, NULL, 0); 364669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 365669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 366ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic const struct pci_device_id pdc202xx[] = { 3672d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 }, 3682d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 }, 3692d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 }, 3702d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2 }, 3712d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2 }, 3722d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik 3732d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik { }, 374669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 375669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 376ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic struct pci_driver pdc202xx_pci_driver = { 3772d2744fc8be620a2dc469cf48349e3e704119f1bJeff Garzik .name = DRV_NAME, 378ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox .id_table = pdc202xx, 379ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox .probe = pdc202xx_init_one, 38062d64ae0ec76360736c9dc4ca2067ae8de0ba9f2Alan Cox .remove = ata_pci_remove_one, 381438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#ifdef CONFIG_PM 38262d64ae0ec76360736c9dc4ca2067ae8de0ba9f2Alan Cox .suspend = ata_pci_device_suspend, 38362d64ae0ec76360736c9dc4ca2067ae8de0ba9f2Alan Cox .resume = ata_pci_device_resume, 384438ac6d5e3f8106a6bd1a5682c508d660294a85dTejun Heo#endif 385669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik}; 386669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 387ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic int __init pdc202xx_init(void) 388669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 389ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox return pci_register_driver(&pdc202xx_pci_driver); 390669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 391669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 392ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxstatic void __exit pdc202xx_exit(void) 393669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik{ 394ada406c8246b0792afe4d7f8ae7606093052de87Alan Cox pci_unregister_driver(&pdc202xx_pci_driver); 395669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik} 396669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 397669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_AUTHOR("Alan Cox"); 398669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267"); 399669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_LICENSE("GPL"); 400ada406c8246b0792afe4d7f8ae7606093052de87Alan CoxMODULE_DEVICE_TABLE(pci, pdc202xx); 401669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff GarzikMODULE_VERSION(DRV_VERSION); 402669a5db411d85a14f86cd92bc16bf7ab5b8aa235Jeff Garzik 403ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxmodule_init(pdc202xx_init); 404ada406c8246b0792afe4d7f8ae7606093052de87Alan Coxmodule_exit(pdc202xx_exit); 405