linux/drivers/ata/pata_cmd640.c
<<
>>
Prefs
   1/*
   2 * pata_cmd640.c        - CMD640 PCI PATA for new ATA layer
   3 *                        (C) 2007 Red Hat Inc
   4 *
   5 * Based upon
   6 *  linux/drivers/ide/pci/cmd640.c              Version 1.02  Sep 01, 1996
   7 *
   8 *  Copyright (C) 1995-1996  Linus Torvalds & authors (see driver)
   9 *
  10 *      This drives only the PCI version of the controller. If you have a
  11 *      VLB one then we have enough docs to support it but you can write
  12 *      your own code.
  13 */
  14
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/pci.h>
  18#include <linux/init.h>
  19#include <linux/blkdev.h>
  20#include <linux/delay.h>
  21#include <linux/gfp.h>
  22#include <scsi/scsi_host.h>
  23#include <linux/libata.h>
  24
  25#define DRV_NAME "pata_cmd640"
  26#define DRV_VERSION "0.0.5"
  27
  28struct cmd640_reg {
  29        int last;
  30        u8 reg58[ATA_MAX_DEVICES];
  31};
  32
  33enum {
  34        CFR = 0x50,
  35        CNTRL = 0x51,
  36        CMDTIM = 0x52,
  37        ARTIM0 = 0x53,
  38        DRWTIM0 = 0x54,
  39        ARTIM23 = 0x57,
  40        DRWTIM23 = 0x58,
  41        BRST = 0x59
  42};
  43
  44/**
  45 *      cmd640_set_piomode      -       set initial PIO mode data
  46 *      @ap: ATA port
  47 *      @adev: ATA device
  48 *
  49 *      Called to do the PIO mode setup.
  50 */
  51
  52static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev)
  53{
  54        struct cmd640_reg *timing = ap->private_data;
  55        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
  56        struct ata_timing t;
  57        const unsigned long T = 1000000 / 33;
  58        const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 };
  59        u8 reg;
  60        int arttim = ARTIM0 + 2 * adev->devno;
  61        struct ata_device *pair = ata_dev_pair(adev);
  62
  63        if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) {
  64                printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
  65                return;
  66        }
  67
  68        /* The second channel has shared timings and the setup timing is
  69           messy to switch to merge it for worst case */
  70        if (ap->port_no && pair) {
  71                struct ata_timing p;
  72                ata_timing_compute(pair, pair->pio_mode, &p, T, 1);
  73                ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP);
  74        }
  75
  76        /* Make the timings fit */
  77        if (t.recover > 16) {
  78                t.active += t.recover - 16;
  79                t.recover = 16;
  80        }
  81        if (t.active > 16)
  82                t.active = 16;
  83
  84        /* Now convert the clocks into values we can actually stuff into
  85           the chip */
  86
  87        if (t.recover > 1)
  88                t.recover--;    /* 640B only */
  89        else
  90                t.recover = 15;
  91
  92        if (t.setup > 4)
  93                t.setup = 0xC0;
  94        else
  95                t.setup = setup_data[t.setup];
  96
  97        if (ap->port_no == 0) {
  98                t.active &= 0x0F;       /* 0 = 16 */
  99
 100                /* Load setup timing */
 101                pci_read_config_byte(pdev, arttim, &reg);
 102                reg &= 0x3F;
 103                reg |= t.setup;
 104                pci_write_config_byte(pdev, arttim, reg);
 105
 106                /* Load active/recovery */
 107                pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | t.recover);
 108        } else {
 109                /* Save the shared timings for channel, they will be loaded
 110                   by qc_issue. Reloading the setup time is expensive so we
 111                   keep a merged one loaded */
 112                pci_read_config_byte(pdev, ARTIM23, &reg);
 113                reg &= 0x3F;
 114                reg |= t.setup;
 115                pci_write_config_byte(pdev, ARTIM23, reg);
 116                timing->reg58[adev->devno] = (t.active << 4) | t.recover;
 117        }
 118}
 119
 120
 121/**
 122 *      cmd640_qc_issue -       command preparation hook
 123 *      @qc: Command to be issued
 124 *
 125 *      Channel 1 has shared timings. We must reprogram the
 126 *      clock each drive 2/3 switch we do.
 127 */
 128
 129static unsigned int cmd640_qc_issue(struct ata_queued_cmd *qc)
 130{
 131        struct ata_port *ap = qc->ap;
 132        struct ata_device *adev = qc->dev;
 133        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 134        struct cmd640_reg *timing = ap->private_data;
 135
 136        if (ap->port_no != 0 && adev->devno != timing->last) {
 137                pci_write_config_byte(pdev, DRWTIM23, timing->reg58[adev->devno]);
 138                timing->last = adev->devno;
 139        }
 140        return ata_sff_qc_issue(qc);
 141}
 142
 143/**
 144 *      cmd640_port_start       -       port setup
 145 *      @ap: ATA port being set up
 146 *
 147 *      The CMD640 needs to maintain private data structures so we
 148 *      allocate space here.
 149 */
 150
 151static int cmd640_port_start(struct ata_port *ap)
 152{
 153        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 154        struct cmd640_reg *timing;
 155
 156        timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL);
 157        if (timing == NULL)
 158                return -ENOMEM;
 159        timing->last = -1;      /* Force a load */
 160        ap->private_data = timing;
 161        return 0;
 162}
 163
 164static bool cmd640_sff_irq_check(struct ata_port *ap)
 165{
 166        struct pci_dev *pdev    = to_pci_dev(ap->host->dev);
 167        int irq_reg             = ap->port_no ? ARTIM23 : CFR;
 168        u8  irq_stat, irq_mask  = ap->port_no ? 0x10 : 0x04;
 169
 170        pci_read_config_byte(pdev, irq_reg, &irq_stat);
 171
 172        return irq_stat & irq_mask;
 173}
 174
 175static struct scsi_host_template cmd640_sht = {
 176        ATA_PIO_SHT(DRV_NAME),
 177};
 178
 179static struct ata_port_operations cmd640_port_ops = {
 180        .inherits       = &ata_sff_port_ops,
 181        /* In theory xfer_noirq is not needed once we kill the prefetcher */
 182        .sff_data_xfer  = ata_sff_data_xfer_noirq,
 183        .sff_irq_check  = cmd640_sff_irq_check,
 184        .qc_issue       = cmd640_qc_issue,
 185        .cable_detect   = ata_cable_40wire,
 186        .set_piomode    = cmd640_set_piomode,
 187        .port_start     = cmd640_port_start,
 188};
 189
 190static void cmd640_hardware_init(struct pci_dev *pdev)
 191{
 192        u8 ctrl;
 193
 194        /* CMD640 detected, commiserations */
 195        pci_write_config_byte(pdev, 0x5B, 0x00);
 196        /* PIO0 command cycles */
 197        pci_write_config_byte(pdev, CMDTIM, 0);
 198        /* 512 byte bursts (sector) */
 199        pci_write_config_byte(pdev, BRST, 0x40);
 200        /*
 201         * A reporter a long time ago
 202         * Had problems with the data fifo
 203         * So don't run the risk
 204         * Of putting crap on the disk
 205         * For its better just to go slow
 206         */
 207        /* Do channel 0 */
 208        pci_read_config_byte(pdev, CNTRL, &ctrl);
 209        pci_write_config_byte(pdev, CNTRL, ctrl | 0xC0);
 210        /* Ditto for channel 1 */
 211        pci_read_config_byte(pdev, ARTIM23, &ctrl);
 212        ctrl |= 0x0C;
 213        pci_write_config_byte(pdev, ARTIM23, ctrl);
 214}
 215
 216static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 217{
 218        static const struct ata_port_info info = {
 219                .flags = ATA_FLAG_SLAVE_POSS,
 220                .pio_mask = ATA_PIO4,
 221                .port_ops = &cmd640_port_ops
 222        };
 223        const struct ata_port_info *ppi[] = { &info, NULL };
 224        int rc;
 225
 226        rc = pcim_enable_device(pdev);
 227        if (rc)
 228                return rc;
 229
 230        cmd640_hardware_init(pdev);
 231
 232        return ata_pci_sff_init_one(pdev, ppi, &cmd640_sht, NULL, 0);
 233}
 234
 235#ifdef CONFIG_PM
 236static int cmd640_reinit_one(struct pci_dev *pdev)
 237{
 238        struct ata_host *host = dev_get_drvdata(&pdev->dev);
 239        int rc;
 240
 241        rc = ata_pci_device_do_resume(pdev);
 242        if (rc)
 243                return rc;
 244        cmd640_hardware_init(pdev);
 245        ata_host_resume(host);
 246        return 0;
 247}
 248#endif
 249
 250static const struct pci_device_id cmd640[] = {
 251        { PCI_VDEVICE(CMD, 0x640), 0 },
 252        { },
 253};
 254
 255static struct pci_driver cmd640_pci_driver = {
 256        .name           = DRV_NAME,
 257        .id_table       = cmd640,
 258        .probe          = cmd640_init_one,
 259        .remove         = ata_pci_remove_one,
 260#ifdef CONFIG_PM
 261        .suspend        = ata_pci_device_suspend,
 262        .resume         = cmd640_reinit_one,
 263#endif
 264};
 265
 266module_pci_driver(cmd640_pci_driver);
 267
 268MODULE_AUTHOR("Alan Cox");
 269MODULE_DESCRIPTION("low-level driver for CMD640 PATA controllers");
 270MODULE_LICENSE("GPL");
 271MODULE_DEVICE_TABLE(pci, cmd640);
 272MODULE_VERSION(DRV_VERSION);
 273
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.