linux/drivers/ata/pata_sl82c105.c
<<
>>
Prefs
   1/*
   2 * pata_sl82c105.c      - SL82C105 PATA for new ATA layer
   3 *                        (C) 2005 Red Hat Inc
   4 *                        (C) 2011 Bartlomiej Zolnierkiewicz
   5 *
   6 * Based in part on linux/drivers/ide/pci/sl82c105.c
   7 *              SL82C105/Winbond 553 IDE driver
   8 *
   9 * and in part on the documentation and errata sheet
  10 *
  11 *
  12 * Note: The controller like many controllers has shared timings for
  13 * PIO and DMA. We thus flip to the DMA timings in dma_start and flip back
  14 * in the dma_stop function. Thus we actually don't need a set_dmamode
  15 * method as the PIO method is always called and will set the right PIO
  16 * timing parameters.
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/pci.h>
  22#include <linux/init.h>
  23#include <linux/blkdev.h>
  24#include <linux/delay.h>
  25#include <scsi/scsi_host.h>
  26#include <linux/libata.h>
  27
  28#define DRV_NAME "pata_sl82c105"
  29#define DRV_VERSION "0.3.3"
  30
  31enum {
  32        /*
  33         * SL82C105 PCI config register 0x40 bits.
  34         */
  35        CTRL_IDE_IRQB   =       (1 << 30),
  36        CTRL_IDE_IRQA   =       (1 << 28),
  37        CTRL_LEGIRQ     =       (1 << 11),
  38        CTRL_P1F16      =       (1 << 5),
  39        CTRL_P1EN       =       (1 << 4),
  40        CTRL_P0F16      =       (1 << 1),
  41        CTRL_P0EN       =       (1 << 0)
  42};
  43
  44/**
  45 *      sl82c105_pre_reset              -       probe begin
  46 *      @link: ATA link
  47 *      @deadline: deadline jiffies for the operation
  48 *
  49 *      Set up cable type and use generic probe init
  50 */
  51
  52static int sl82c105_pre_reset(struct ata_link *link, unsigned long deadline)
  53{
  54        static const struct pci_bits sl82c105_enable_bits[] = {
  55                { 0x40, 1, 0x01, 0x01 },
  56                { 0x40, 1, 0x10, 0x10 }
  57        };
  58        struct ata_port *ap = link->ap;
  59        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  60
  61        if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
  62                return -ENOENT;
  63        return ata_sff_prereset(link, deadline);
  64}
  65
  66
  67/**
  68 *      sl82c105_configure_piomode      -       set chip PIO timing
  69 *      @ap: ATA interface
  70 *      @adev: ATA device
  71 *      @pio: PIO mode
  72 *
  73 *      Called to do the PIO mode setup. Our timing registers are shared
  74 *      so a configure_dmamode call will undo any work we do here and vice
  75 *      versa
  76 */
  77
  78static void sl82c105_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
  79{
  80        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  81        static u16 pio_timing[5] = {
  82                0x50D, 0x407, 0x304, 0x242, 0x240
  83        };
  84        u16 dummy;
  85        int timing = 0x44 + (8 * ap->port_no) + (4 * adev->devno);
  86
  87        pci_write_config_word(pdev, timing, pio_timing[pio]);
  88        /* Can we lose this oddity of the old driver */
  89        pci_read_config_word(pdev, timing, &dummy);
  90}
  91
  92/**
  93 *      sl82c105_set_piomode    -       set initial PIO mode data
  94 *      @ap: ATA interface
  95 *      @adev: ATA device
  96 *
  97 *      Called to do the PIO mode setup. Our timing registers are shared
  98 *      but we want to set the PIO timing by default.
  99 */
 100
 101static void sl82c105_set_piomode(struct ata_port *ap, struct ata_device *adev)
 102{
 103        sl82c105_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
 104}
 105
 106/**
 107 *      sl82c105_configure_dmamode      -       set DMA mode in chip
 108 *      @ap: ATA interface
 109 *      @adev: ATA device
 110 *
 111 *      Load DMA cycle times into the chip ready for a DMA transfer
 112 *      to occur.
 113 */
 114
 115static void sl82c105_configure_dmamode(struct ata_port *ap, struct ata_device *adev)
 116{
 117        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 118        static u16 dma_timing[3] = {
 119                0x707, 0x201, 0x200
 120        };
 121        u16 dummy;
 122        int timing = 0x44 + (8 * ap->port_no) + (4 * adev->devno);
 123        int dma = adev->dma_mode - XFER_MW_DMA_0;
 124
 125        pci_write_config_word(pdev, timing, dma_timing[dma]);
 126        /* Can we lose this oddity of the old driver */
 127        pci_read_config_word(pdev, timing, &dummy);
 128}
 129
 130/**
 131 *      sl82c105_reset_engine   -       Reset the DMA engine
 132 *      @ap: ATA interface
 133 *
 134 *      The sl82c105 has some serious problems with the DMA engine
 135 *      when transfers don't run as expected or ATAPI is used. The
 136 *      recommended fix is to reset the engine each use using a chip
 137 *      test register.
 138 */
 139
 140static void sl82c105_reset_engine(struct ata_port *ap)
 141{
 142        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 143        u16 val;
 144
 145        pci_read_config_word(pdev, 0x7E, &val);
 146        pci_write_config_word(pdev, 0x7E, val | 4);
 147        pci_write_config_word(pdev, 0x7E, val & ~4);
 148}
 149
 150/**
 151 *      sl82c105_bmdma_start            -       DMA engine begin
 152 *      @qc: ATA command
 153 *
 154 *      Reset the DMA engine each use as recommended by the errata
 155 *      document.
 156 *
 157 *      FIXME: if we switch clock at BMDMA start/end we might get better
 158 *      PIO performance on DMA capable devices.
 159 */
 160
 161static void sl82c105_bmdma_start(struct ata_queued_cmd *qc)
 162{
 163        struct ata_port *ap = qc->ap;
 164
 165        udelay(100);
 166        sl82c105_reset_engine(ap);
 167        udelay(100);
 168
 169        /* Set the clocks for DMA */
 170        sl82c105_configure_dmamode(ap, qc->dev);
 171        /* Activate DMA */
 172        ata_bmdma_start(qc);
 173}
 174
 175/**
 176 *      sl82c105_bmdma_end              -       DMA engine stop
 177 *      @qc: ATA command
 178 *
 179 *      Reset the DMA engine each use as recommended by the errata
 180 *      document.
 181 *
 182 *      This function is also called to turn off DMA when a timeout occurs
 183 *      during DMA operation. In both cases we need to reset the engine,
 184 *      so no actual eng_timeout handler is required.
 185 *
 186 *      We assume bmdma_stop is always called if bmdma_start as called. If
 187 *      not then we may need to wrap qc_issue.
 188 */
 189
 190static void sl82c105_bmdma_stop(struct ata_queued_cmd *qc)
 191{
 192        struct ata_port *ap = qc->ap;
 193
 194        ata_bmdma_stop(qc);
 195        sl82c105_reset_engine(ap);
 196        udelay(100);
 197
 198        /* This will redo the initial setup of the DMA device to matching
 199           PIO timings */
 200        sl82c105_set_piomode(ap, qc->dev);
 201}
 202
 203/**
 204 *      sl82c105_qc_defer       -       implement serialization
 205 *      @qc: command
 206 *
 207 *      We must issue one command per host not per channel because
 208 *      of the reset bug.
 209 *
 210 *      Q: is the scsi host lock sufficient ?
 211 */
 212
 213static int sl82c105_qc_defer(struct ata_queued_cmd *qc)
 214{
 215        struct ata_host *host = qc->ap->host;
 216        struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
 217        int rc;
 218
 219        /* First apply the usual rules */
 220        rc = ata_std_qc_defer(qc);
 221        if (rc != 0)
 222                return rc;
 223
 224        /* Now apply serialization rules. Only allow a command if the
 225           other channel state machine is idle */
 226        if (alt && alt->qc_active)
 227                return  ATA_DEFER_PORT;
 228        return 0;
 229}
 230
 231static bool sl82c105_sff_irq_check(struct ata_port *ap)
 232{
 233        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
 234        u32 val, mask           = ap->port_no ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
 235
 236        pci_read_config_dword(pdev, 0x40, &val);
 237
 238        return val & mask;
 239}
 240
 241static struct scsi_host_template sl82c105_sht = {
 242        ATA_BMDMA_SHT(DRV_NAME),
 243};
 244
 245static struct ata_port_operations sl82c105_port_ops = {
 246        .inherits       = &ata_bmdma_port_ops,
 247        .qc_defer       = sl82c105_qc_defer,
 248        .bmdma_start    = sl82c105_bmdma_start,
 249        .bmdma_stop     = sl82c105_bmdma_stop,
 250        .cable_detect   = ata_cable_40wire,
 251        .set_piomode    = sl82c105_set_piomode,
 252        .prereset       = sl82c105_pre_reset,
 253        .sff_irq_check  = sl82c105_sff_irq_check,
 254};
 255
 256/**
 257 *      sl82c105_bridge_revision        -       find bridge version
 258 *      @pdev: PCI device for the ATA function
 259 *
 260 *      Locates the PCI bridge associated with the ATA function and
 261 *      providing it is a Winbond 553 reports the revision. If it cannot
 262 *      find a revision or the right device it returns -1
 263 */
 264
 265static int sl82c105_bridge_revision(struct pci_dev *pdev)
 266{
 267        struct pci_dev *bridge;
 268
 269        /*
 270         * The bridge should be part of the same device, but function 0.
 271         */
 272        bridge = pci_get_slot(pdev->bus,
 273                               PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
 274        if (!bridge)
 275                return -1;
 276
 277        /*
 278         * Make sure it is a Winbond 553 and is an ISA bridge.
 279         */
 280        if (bridge->vendor != PCI_VENDOR_ID_WINBOND ||
 281            bridge->device != PCI_DEVICE_ID_WINBOND_83C553 ||
 282            bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) {
 283                pci_dev_put(bridge);
 284                return -1;
 285        }
 286        /*
 287         * We need to find function 0's revision, not function 1
 288         */
 289        pci_dev_put(bridge);
 290        return bridge->revision;
 291}
 292
 293static void sl82c105_fixup(struct pci_dev *pdev)
 294{
 295        u32 val;
 296
 297        pci_read_config_dword(pdev, 0x40, &val);
 298        val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
 299        pci_write_config_dword(pdev, 0x40, val);
 300}
 301
 302static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 303{
 304        static const struct ata_port_info info_dma = {
 305                .flags = ATA_FLAG_SLAVE_POSS,
 306                .pio_mask = ATA_PIO4,
 307                .mwdma_mask = ATA_MWDMA2,
 308                .port_ops = &sl82c105_port_ops
 309        };
 310        static const struct ata_port_info info_early = {
 311                .flags = ATA_FLAG_SLAVE_POSS,
 312                .pio_mask = ATA_PIO4,
 313                .port_ops = &sl82c105_port_ops
 314        };
 315        /* for now use only the first port */
 316        const struct ata_port_info *ppi[] = { &info_early,
 317                                               NULL };
 318        int rev;
 319        int rc;
 320
 321        rc = pcim_enable_device(dev);
 322        if (rc)
 323                return rc;
 324
 325        rev = sl82c105_bridge_revision(dev);
 326
 327        if (rev == -1)
 328                dev_warn(&dev->dev,
 329                         "pata_sl82c105: Unable to find bridge, disabling DMA\n");
 330        else if (rev <= 5)
 331                dev_warn(&dev->dev,
 332                         "pata_sl82c105: Early bridge revision, no DMA available\n");
 333        else
 334                ppi[0] = &info_dma;
 335
 336        sl82c105_fixup(dev);
 337
 338        return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0);
 339}
 340
 341#ifdef CONFIG_PM
 342static int sl82c105_reinit_one(struct pci_dev *pdev)
 343{
 344        struct ata_host *host = dev_get_drvdata(&pdev->dev);
 345        int rc;
 346
 347        rc = ata_pci_device_do_resume(pdev);
 348        if (rc)
 349                return rc;
 350
 351        sl82c105_fixup(pdev);
 352
 353        ata_host_resume(host);
 354        return 0;
 355}
 356#endif
 357
 358static const struct pci_device_id sl82c105[] = {
 359        { PCI_VDEVICE(WINBOND, PCI_DEVICE_ID_WINBOND_82C105), },
 360
 361        { },
 362};
 363
 364static struct pci_driver sl82c105_pci_driver = {
 365        .name           = DRV_NAME,
 366        .id_table       = sl82c105,
 367        .probe          = sl82c105_init_one,
 368        .remove         = ata_pci_remove_one,
 369#ifdef CONFIG_PM
 370        .suspend        = ata_pci_device_suspend,
 371        .resume         = sl82c105_reinit_one,
 372#endif
 373};
 374
 375module_pci_driver(sl82c105_pci_driver);
 376
 377MODULE_AUTHOR("Alan Cox");
 378MODULE_DESCRIPTION("low-level driver for Sl82c105");
 379MODULE_LICENSE("GPL");
 380MODULE_DEVICE_TABLE(pci, sl82c105);
 381MODULE_VERSION(DRV_VERSION);
 382
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.