1/* 2 * pata_sch.c - Intel SCH PATA controllers 3 * 4 * Copyright (c) 2008 Alek Du <alek.du@intel.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License 2 as published 8 * by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; see the file COPYING. If not, write to 17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 18 * 19 */ 20 21/* 22 * Supports: 23 * Intel SCH (AF82US15W, AF82US15L, AF82UL11L) chipsets -- see spec at: 24 * http://download.intel.com/design/chipsets/embedded/datashts/319537.pdf 25 */ 26 27#include <linux/kernel.h> 28#include <linux/module.h> 29#include <linux/pci.h> 30#include <linux/blkdev.h> 31#include <linux/delay.h> 32#include <linux/device.h> 33#include <scsi/scsi_host.h> 34#include <linux/libata.h> 35#include <linux/dmi.h> 36 37#define DRV_NAME "pata_sch" 38#define DRV_VERSION "0.2" 39 40/* see SCH datasheet page 351 */ 41enum { 42 D0TIM = 0x80, /* Device 0 Timing Register */ 43 D1TIM = 0x84, /* Device 1 Timing Register */ 44 PM = 0x07, /* PIO Mode Bit Mask */ 45 MDM = (0x03 << 8), /* Multi-word DMA Mode Bit Mask */ 46 UDM = (0x07 << 16), /* Ultra DMA Mode Bit Mask */ 47 PPE = (1 << 30), /* Prefetch/Post Enable */ 48 USD = (1 << 31), /* Use Synchronous DMA */ 49}; 50 51static int sch_init_one(struct pci_dev *pdev, 52 const struct pci_device_id *ent); 53static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev); 54static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev); 55 56static const struct pci_device_id sch_pci_tbl[] = { 57 /* Intel SCH PATA Controller */ 58 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_IDE), 0 }, 59 { } /* terminate list */ 60}; 61 62static struct pci_driver sch_pci_driver = { 63 .name = DRV_NAME, 64 .id_table = sch_pci_tbl, 65 .probe = sch_init_one, 66 .remove = ata_pci_remove_one, 67#ifdef CONFIG_PM_SLEEP 68 .suspend = ata_pci_device_suspend, 69 .resume = ata_pci_device_resume, 70#endif 71}; 72 73static struct scsi_host_template sch_sht = { 74 ATA_BMDMA_SHT(DRV_NAME), 75}; 76 77static struct ata_port_operations sch_pata_ops = { 78 .inherits = &ata_bmdma_port_ops, 79 .cable_detect = ata_cable_unknown, 80 .set_piomode = sch_set_piomode, 81 .set_dmamode = sch_set_dmamode, 82}; 83 84static struct ata_port_info sch_port_info = { 85 .flags = ATA_FLAG_SLAVE_POSS, 86 .pio_mask = ATA_PIO4, 87 .mwdma_mask = ATA_MWDMA2, 88 .udma_mask = ATA_UDMA5, 89 .port_ops = &sch_pata_ops, 90}; 91 92MODULE_AUTHOR("Alek Du <alek.du@intel.com>"); 93MODULE_DESCRIPTION("SCSI low-level driver for Intel SCH PATA controllers"); 94MODULE_LICENSE("GPL"); 95MODULE_DEVICE_TABLE(pci, sch_pci_tbl); 96MODULE_VERSION(DRV_VERSION); 97 98/** 99 * sch_set_piomode - Initialize host controller PATA PIO timings 100 * @ap: Port whose timings we are configuring 101 * @adev: ATA device 102 * 103 * Set PIO mode for device, in host controller PCI config space. 104 * 105 * LOCKING: 106 * None (inherited from caller). 107 */ 108 109static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev) 110{ 111 unsigned int pio = adev->pio_mode - XFER_PIO_0; 112 struct pci_dev *dev = to_pci_dev(ap->host->dev); 113 unsigned int port = adev->devno ? D1TIM : D0TIM; 114 unsigned int data; 115 116 pci_read_config_dword(dev, port, &data); 117 /* see SCH datasheet page 351 */ 118 /* set PIO mode */ 119 data &= ~(PM | PPE); 120 data |= pio; 121 /* enable PPE for block device */ 122 if (adev->class == ATA_DEV_ATA) 123 data |= PPE; 124 pci_write_config_dword(dev, port, data); 125} 126 127/** 128 * sch_set_dmamode - Initialize host controller PATA DMA timings 129 * @ap: Port whose timings we are configuring 130 * @adev: ATA device 131 * 132 * Set MW/UDMA mode for device, in host controller PCI config space. 133 * 134 * LOCKING: 135 * None (inherited from caller). 136 */ 137 138static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev) 139{ 140 unsigned int dma_mode = adev->dma_mode; 141 struct pci_dev *dev = to_pci_dev(ap->host->dev); 142 unsigned int port = adev->devno ? D1TIM : D0TIM; 143 unsigned int data; 144 145 pci_read_config_dword(dev, port, &data); 146 /* see SCH datasheet page 351 */ 147 if (dma_mode >= XFER_UDMA_0) { 148 /* enable Synchronous DMA mode */ 149 data |= USD; 150 data &= ~UDM; 151 data |= (dma_mode - XFER_UDMA_0) << 16; 152 } else { /* must be MWDMA mode, since we masked SWDMA already */ 153 data &= ~(USD | MDM); 154 data |= (dma_mode - XFER_MW_DMA_0) << 8; 155 } 156 pci_write_config_dword(dev, port, data); 157} 158 159/** 160 * sch_init_one - Register SCH ATA PCI device with kernel services 161 * @pdev: PCI device to register 162 * @ent: Entry in sch_pci_tbl matching with @pdev 163 * 164 * LOCKING: 165 * Inherited from PCI layer (may sleep). 166 * 167 * RETURNS: 168 * Zero on success, or -ERRNO value. 169 */ 170 171static int sch_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 172{ 173 const struct ata_port_info *ppi[] = { &sch_port_info, NULL }; 174 175 ata_print_version_once(&pdev->dev, DRV_VERSION); 176 177 return ata_pci_bmdma_init_one(pdev, ppi, &sch_sht, NULL, 0); 178} 179 180module_pci_driver(sch_pci_driver); 181