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