Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  pata_sch.c - Intel SCH PATA controllers
0004  *
0005  *  Copyright (c) 2008 Alek Du <alek.du@intel.com>
0006  */
0007 
0008 /*
0009  *  Supports:
0010  *    Intel SCH (AF82US15W, AF82US15L, AF82UL11L) chipsets -- see spec at:
0011  *    http://download.intel.com/design/chipsets/embedded/datashts/319537.pdf
0012  */
0013 
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/pci.h>
0017 #include <linux/blkdev.h>
0018 #include <linux/delay.h>
0019 #include <linux/device.h>
0020 #include <scsi/scsi_host.h>
0021 #include <linux/libata.h>
0022 #include <linux/dmi.h>
0023 
0024 #define DRV_NAME    "pata_sch"
0025 #define DRV_VERSION "0.2"
0026 
0027 /* see SCH datasheet page 351 */
0028 enum {
0029     D0TIM   = 0x80,     /* Device 0 Timing Register */
0030     D1TIM   = 0x84,     /* Device 1 Timing Register */
0031     PM  = 0x07,     /* PIO Mode Bit Mask */
0032     MDM = (0x03 << 8),  /* Multi-word DMA Mode Bit Mask */
0033     UDM = (0x07 << 16), /* Ultra DMA Mode Bit Mask */
0034     PPE = (1 << 30),    /* Prefetch/Post Enable */
0035     USD = (1 << 31),    /* Use Synchronous DMA */
0036 };
0037 
0038 static int sch_init_one(struct pci_dev *pdev,
0039              const struct pci_device_id *ent);
0040 static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev);
0041 static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev);
0042 
0043 static const struct pci_device_id sch_pci_tbl[] = {
0044     /* Intel SCH PATA Controller */
0045     { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_IDE), 0 },
0046     { } /* terminate list */
0047 };
0048 
0049 static struct pci_driver sch_pci_driver = {
0050     .name           = DRV_NAME,
0051     .id_table       = sch_pci_tbl,
0052     .probe          = sch_init_one,
0053     .remove         = ata_pci_remove_one,
0054 #ifdef CONFIG_PM_SLEEP
0055     .suspend        = ata_pci_device_suspend,
0056     .resume         = ata_pci_device_resume,
0057 #endif
0058 };
0059 
0060 static struct scsi_host_template sch_sht = {
0061     ATA_BMDMA_SHT(DRV_NAME),
0062 };
0063 
0064 static struct ata_port_operations sch_pata_ops = {
0065     .inherits       = &ata_bmdma_port_ops,
0066     .cable_detect       = ata_cable_unknown,
0067     .set_piomode        = sch_set_piomode,
0068     .set_dmamode        = sch_set_dmamode,
0069 };
0070 
0071 static const struct ata_port_info sch_port_info = {
0072     .flags      = ATA_FLAG_SLAVE_POSS,
0073     .pio_mask   = ATA_PIO4,
0074     .mwdma_mask = ATA_MWDMA2,
0075     .udma_mask  = ATA_UDMA5,
0076     .port_ops   = &sch_pata_ops,
0077 };
0078 
0079 MODULE_AUTHOR("Alek Du <alek.du@intel.com>");
0080 MODULE_DESCRIPTION("SCSI low-level driver for Intel SCH PATA controllers");
0081 MODULE_LICENSE("GPL");
0082 MODULE_DEVICE_TABLE(pci, sch_pci_tbl);
0083 MODULE_VERSION(DRV_VERSION);
0084 
0085 /**
0086  *  sch_set_piomode - Initialize host controller PATA PIO timings
0087  *  @ap: Port whose timings we are configuring
0088  *  @adev: ATA device
0089  *
0090  *  Set PIO mode for device, in host controller PCI config space.
0091  *
0092  *  LOCKING:
0093  *  None (inherited from caller).
0094  */
0095 
0096 static void sch_set_piomode(struct ata_port *ap, struct ata_device *adev)
0097 {
0098     unsigned int pio    = adev->pio_mode - XFER_PIO_0;
0099     struct pci_dev *dev = to_pci_dev(ap->host->dev);
0100     unsigned int port   = adev->devno ? D1TIM : D0TIM;
0101     unsigned int data;
0102 
0103     pci_read_config_dword(dev, port, &data);
0104     /* see SCH datasheet page 351 */
0105     /* set PIO mode */
0106     data &= ~(PM | PPE);
0107     data |= pio;
0108     /* enable PPE for block device */
0109     if (adev->class == ATA_DEV_ATA)
0110         data |= PPE;
0111     pci_write_config_dword(dev, port, data);
0112 }
0113 
0114 /**
0115  *  sch_set_dmamode - Initialize host controller PATA DMA timings
0116  *  @ap: Port whose timings we are configuring
0117  *  @adev: ATA device
0118  *
0119  *  Set MW/UDMA mode for device, in host controller PCI config space.
0120  *
0121  *  LOCKING:
0122  *  None (inherited from caller).
0123  */
0124 
0125 static void sch_set_dmamode(struct ata_port *ap, struct ata_device *adev)
0126 {
0127     unsigned int dma_mode   = adev->dma_mode;
0128     struct pci_dev *dev = to_pci_dev(ap->host->dev);
0129     unsigned int port   = adev->devno ? D1TIM : D0TIM;
0130     unsigned int data;
0131 
0132     pci_read_config_dword(dev, port, &data);
0133     /* see SCH datasheet page 351 */
0134     if (dma_mode >= XFER_UDMA_0) {
0135         /* enable Synchronous DMA mode */
0136         data |= USD;
0137         data &= ~UDM;
0138         data |= (dma_mode - XFER_UDMA_0) << 16;
0139     } else { /* must be MWDMA mode, since we masked SWDMA already */
0140         data &= ~(USD | MDM);
0141         data |= (dma_mode - XFER_MW_DMA_0) << 8;
0142     }
0143     pci_write_config_dword(dev, port, data);
0144 }
0145 
0146 /**
0147  *  sch_init_one - Register SCH ATA PCI device with kernel services
0148  *  @pdev: PCI device to register
0149  *  @ent: Entry in sch_pci_tbl matching with @pdev
0150  *
0151  *  LOCKING:
0152  *  Inherited from PCI layer (may sleep).
0153  *
0154  *  RETURNS:
0155  *  Zero on success, or -ERRNO value.
0156  */
0157 
0158 static int sch_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
0159 {
0160     const struct ata_port_info *ppi[] = { &sch_port_info, NULL };
0161 
0162     ata_print_version_once(&pdev->dev, DRV_VERSION);
0163 
0164     return ata_pci_bmdma_init_one(pdev, ppi, &sch_sht, NULL, 0);
0165 }
0166 
0167 module_pci_driver(sch_pci_driver);