linux/drivers/ide/pdc202xx_old.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 1998-2002             Andre Hedrick <andre@linux-ide.org>
   3 *  Copyright (C) 2006-2007             MontaVista Software, Inc.
   4 *  Copyright (C) 2007                  Bartlomiej Zolnierkiewicz
   5 *
   6 *  Portions Copyright (C) 1999 Promise Technology, Inc.
   7 *  Author: Frank Tiernan (frankt@promise.com)
   8 *  Released under terms of General Public License
   9 */
  10
  11#include <linux/types.h>
  12#include <linux/module.h>
  13#include <linux/kernel.h>
  14#include <linux/delay.h>
  15#include <linux/blkdev.h>
  16#include <linux/pci.h>
  17#include <linux/init.h>
  18#include <linux/ide.h>
  19
  20#include <asm/io.h>
  21
  22#define DRV_NAME "pdc202xx_old"
  23
  24#define PDC202XX_DEBUG_DRIVE_INFO       0
  25
  26static const char *pdc_quirk_drives[] = {
  27        "QUANTUM FIREBALLlct08 08",
  28        "QUANTUM FIREBALLP KA6.4",
  29        "QUANTUM FIREBALLP KA9.1",
  30        "QUANTUM FIREBALLP LM20.4",
  31        "QUANTUM FIREBALLP KX13.6",
  32        "QUANTUM FIREBALLP KX20.5",
  33        "QUANTUM FIREBALLP KX27.3",
  34        "QUANTUM FIREBALLP LM20.5",
  35        NULL
  36};
  37
  38static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
  39
  40static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
  41{
  42        ide_hwif_t *hwif        = HWIF(drive);
  43        struct pci_dev *dev     = to_pci_dev(hwif->dev);
  44        u8 drive_pci            = 0x60 + (drive->dn << 2);
  45
  46        u8                      AP = 0, BP = 0, CP = 0;
  47        u8                      TA = 0, TB = 0, TC = 0;
  48
  49#if PDC202XX_DEBUG_DRIVE_INFO
  50        u32                     drive_conf = 0;
  51        pci_read_config_dword(dev, drive_pci, &drive_conf);
  52#endif
  53
  54        /*
  55         * TODO: do this once per channel
  56         */
  57        if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
  58                pdc_old_disable_66MHz_clock(hwif);
  59
  60        pci_read_config_byte(dev, drive_pci,     &AP);
  61        pci_read_config_byte(dev, drive_pci + 1, &BP);
  62        pci_read_config_byte(dev, drive_pci + 2, &CP);
  63
  64        switch(speed) {
  65                case XFER_UDMA_5:
  66                case XFER_UDMA_4:       TB = 0x20; TC = 0x01; break;
  67                case XFER_UDMA_2:       TB = 0x20; TC = 0x01; break;
  68                case XFER_UDMA_3:
  69                case XFER_UDMA_1:       TB = 0x40; TC = 0x02; break;
  70                case XFER_UDMA_0:
  71                case XFER_MW_DMA_2:     TB = 0x60; TC = 0x03; break;
  72                case XFER_MW_DMA_1:     TB = 0x60; TC = 0x04; break;
  73                case XFER_MW_DMA_0:     TB = 0xE0; TC = 0x0F; break;
  74                case XFER_PIO_4:        TA = 0x01; TB = 0x04; break;
  75                case XFER_PIO_3:        TA = 0x02; TB = 0x06; break;
  76                case XFER_PIO_2:        TA = 0x03; TB = 0x08; break;
  77                case XFER_PIO_1:        TA = 0x05; TB = 0x0C; break;
  78                case XFER_PIO_0:
  79                default:                TA = 0x09; TB = 0x13; break;
  80        }
  81
  82        if (speed < XFER_SW_DMA_0) {
  83                /*
  84                 * preserve SYNC_INT / ERDDY_EN bits while clearing
  85                 * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A
  86                 */
  87                AP &= ~0x3f;
  88                if (ata_id_iordy_disable(drive->id))
  89                        AP |= 0x20;     /* set IORDY_EN bit */
  90                if (drive->media == ide_disk)
  91                        AP |= 0x10;     /* set Prefetch_EN bit */
  92                /* clear PB[4:0] bits of register B */
  93                BP &= ~0x1f;
  94                pci_write_config_byte(dev, drive_pci,     AP | TA);
  95                pci_write_config_byte(dev, drive_pci + 1, BP | TB);
  96        } else {
  97                /* clear MB[2:0] bits of register B */
  98                BP &= ~0xe0;
  99                /* clear MC[3:0] bits of register C */
 100                CP &= ~0x0f;
 101                pci_write_config_byte(dev, drive_pci + 1, BP | TB);
 102                pci_write_config_byte(dev, drive_pci + 2, CP | TC);
 103        }
 104
 105#if PDC202XX_DEBUG_DRIVE_INFO
 106        printk(KERN_DEBUG "%s: %s drive%d 0x%08x ",
 107                drive->name, ide_xfer_verbose(speed),
 108                drive->dn, drive_conf);
 109        pci_read_config_dword(dev, drive_pci, &drive_conf);
 110        printk("0x%08x\n", drive_conf);
 111#endif
 112}
 113
 114static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 115{
 116        pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
 117}
 118
 119static u8 pdc2026x_cable_detect(ide_hwif_t *hwif)
 120{
 121        struct pci_dev *dev = to_pci_dev(hwif->dev);
 122        u16 CIS, mask = hwif->channel ? (1 << 11) : (1 << 10);
 123
 124        pci_read_config_word(dev, 0x50, &CIS);
 125
 126        return (CIS & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
 127}
 128
 129/*
 130 * Set the control register to use the 66MHz system
 131 * clock for UDMA 3/4/5 mode operation when necessary.
 132 *
 133 * FIXME: this register is shared by both channels, some locking is needed
 134 *
 135 * It may also be possible to leave the 66MHz clock on
 136 * and readjust the timing parameters.
 137 */
 138static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
 139{
 140        unsigned long clock_reg = hwif->extra_base + 0x01;
 141        u8 clock = inb(clock_reg);
 142
 143        outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
 144}
 145
 146static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
 147{
 148        unsigned long clock_reg = hwif->extra_base + 0x01;
 149        u8 clock = inb(clock_reg);
 150
 151        outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
 152}
 153
 154static void pdc202xx_quirkproc(ide_drive_t *drive)
 155{
 156        const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
 157
 158        for (list = pdc_quirk_drives; *list != NULL; list++)
 159                if (strstr(m, *list) != NULL) {
 160                        drive->quirk_list = 2;
 161                        return;
 162                }
 163
 164        drive->quirk_list = 0;
 165}
 166
 167static void pdc202xx_dma_start(ide_drive_t *drive)
 168{
 169        if (drive->current_speed > XFER_UDMA_2)
 170                pdc_old_enable_66MHz_clock(drive->hwif);
 171        if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) {
 172                struct request *rq      = HWGROUP(drive)->rq;
 173                ide_hwif_t *hwif        = HWIF(drive);
 174                unsigned long high_16   = hwif->extra_base - 16;
 175                unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
 176                u32 word_count  = 0;
 177                u8 clock = inb(high_16 + 0x11);
 178
 179                outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
 180                word_count = (rq->nr_sectors << 8);
 181                word_count = (rq_data_dir(rq) == READ) ?
 182                                        word_count | 0x05000000 :
 183                                        word_count | 0x06000000;
 184                outl(word_count, atapi_reg);
 185        }
 186        ide_dma_start(drive);
 187}
 188
 189static int pdc202xx_dma_end(ide_drive_t *drive)
 190{
 191        if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) {
 192                ide_hwif_t *hwif        = HWIF(drive);
 193                unsigned long high_16   = hwif->extra_base - 16;
 194                unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
 195                u8 clock                = 0;
 196
 197                outl(0, atapi_reg); /* zero out extra */
 198                clock = inb(high_16 + 0x11);
 199                outb(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11);
 200        }
 201        if (drive->current_speed > XFER_UDMA_2)
 202                pdc_old_disable_66MHz_clock(drive->hwif);
 203        return ide_dma_end(drive);
 204}
 205
 206static int pdc202xx_dma_test_irq(ide_drive_t *drive)
 207{
 208        ide_hwif_t *hwif        = HWIF(drive);
 209        unsigned long high_16   = hwif->extra_base - 16;
 210        u8 dma_stat             = inb(hwif->dma_base + ATA_DMA_STATUS);
 211        u8 sc1d                 = inb(high_16 + 0x001d);
 212
 213        if (hwif->channel) {
 214                /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */
 215                if ((sc1d & 0x50) == 0x50)
 216                        goto somebody_else;
 217                else if ((sc1d & 0x40) == 0x40)
 218                        return (dma_stat & 4) == 4;
 219        } else {
 220                /* bit3: Error, bit2: Interrupting, bit1: FIFO Full, bit0: FIFO Empty */
 221                if ((sc1d & 0x05) == 0x05)
 222                        goto somebody_else;
 223                else if ((sc1d & 0x04) == 0x04)
 224                        return (dma_stat & 4) == 4;
 225        }
 226somebody_else:
 227        return (dma_stat & 4) == 4;     /* return 1 if INTR asserted */
 228}
 229
 230static void pdc202xx_reset_host (ide_hwif_t *hwif)
 231{
 232        unsigned long high_16   = hwif->extra_base - 16;
 233        u8 udma_speed_flag      = inb(high_16 | 0x001f);
 234
 235        outb(udma_speed_flag | 0x10, high_16 | 0x001f);
 236        mdelay(100);
 237        outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
 238        mdelay(2000);   /* 2 seconds ?! */
 239
 240        printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
 241                hwif->channel ? "Secondary" : "Primary");
 242}
 243
 244static void pdc202xx_reset (ide_drive_t *drive)
 245{
 246        ide_hwif_t *hwif        = HWIF(drive);
 247        ide_hwif_t *mate        = hwif->mate;
 248
 249        pdc202xx_reset_host(hwif);
 250        pdc202xx_reset_host(mate);
 251
 252        ide_set_max_pio(drive);
 253}
 254
 255static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
 256{
 257        pdc202xx_reset(drive);
 258        ide_dma_lost_irq(drive);
 259}
 260
 261static void pdc202xx_dma_timeout(ide_drive_t *drive)
 262{
 263        pdc202xx_reset(drive);
 264        ide_dma_timeout(drive);
 265}
 266
 267static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
 268{
 269        unsigned long dmabase = pci_resource_start(dev, 4);
 270        u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
 271
 272        if (dmabase == 0)
 273                goto out;
 274
 275        udma_speed_flag = inb(dmabase | 0x1f);
 276        primary_mode    = inb(dmabase | 0x1a);
 277        secondary_mode  = inb(dmabase | 0x1b);
 278        printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \
 279                "Primary %s Mode " \
 280                "Secondary %s Mode.\n", pci_name(dev),
 281                (udma_speed_flag & 1) ? "EN" : "DIS",
 282                (primary_mode & 1) ? "MASTER" : "PCI",
 283                (secondary_mode & 1) ? "MASTER" : "PCI" );
 284
 285        if (!(udma_speed_flag & 1)) {
 286                printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ",
 287                        pci_name(dev), udma_speed_flag,
 288                        (udma_speed_flag|1));
 289                outb(udma_speed_flag | 1, dmabase | 0x1f);
 290                printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
 291        }
 292out:
 293        return dev->irq;
 294}
 295
 296static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
 297                                           const char *name)
 298{
 299        if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
 300                u8 irq = 0, irq2 = 0;
 301                pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 302                /* 0xbc */
 303                pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2);
 304                if (irq != irq2) {
 305                        pci_write_config_byte(dev,
 306                                (PCI_INTERRUPT_LINE)|0x80, irq);     /* 0xbc */
 307                        printk(KERN_INFO "%s %s: PCI config space interrupt "
 308                                "mirror fixed\n", name, pci_name(dev));
 309                }
 310        }
 311}
 312
 313#define IDE_HFLAGS_PDC202XX \
 314        (IDE_HFLAG_ERROR_STOPS_FIFO | \
 315         IDE_HFLAG_OFF_BOARD)
 316
 317static const struct ide_port_ops pdc20246_port_ops = {
 318        .set_pio_mode           = pdc202xx_set_pio_mode,
 319        .set_dma_mode           = pdc202xx_set_mode,
 320        .quirkproc              = pdc202xx_quirkproc,
 321};
 322
 323static const struct ide_port_ops pdc2026x_port_ops = {
 324        .set_pio_mode           = pdc202xx_set_pio_mode,
 325        .set_dma_mode           = pdc202xx_set_mode,
 326        .quirkproc              = pdc202xx_quirkproc,
 327        .resetproc              = pdc202xx_reset,
 328        .cable_detect           = pdc2026x_cable_detect,
 329};
 330
 331static const struct ide_dma_ops pdc20246_dma_ops = {
 332        .dma_host_set           = ide_dma_host_set,
 333        .dma_setup              = ide_dma_setup,
 334        .dma_exec_cmd           = ide_dma_exec_cmd,
 335        .dma_start              = ide_dma_start,
 336        .dma_end                = ide_dma_end,
 337        .dma_test_irq           = pdc202xx_dma_test_irq,
 338        .dma_lost_irq           = pdc202xx_dma_lost_irq,
 339        .dma_timeout            = pdc202xx_dma_timeout,
 340};
 341
 342static const struct ide_dma_ops pdc2026x_dma_ops = {
 343        .dma_host_set           = ide_dma_host_set,
 344        .dma_setup              = ide_dma_setup,
 345        .dma_exec_cmd           = ide_dma_exec_cmd,
 346        .dma_start              = pdc202xx_dma_start,
 347        .dma_end                = pdc202xx_dma_end,
 348        .dma_test_irq           = pdc202xx_dma_test_irq,
 349        .dma_lost_irq           = pdc202xx_dma_lost_irq,
 350        .dma_timeout            = pdc202xx_dma_timeout,
 351};
 352
 353#define DECLARE_PDC2026X_DEV(udma, extra_flags) \
 354        { \
 355                .name           = DRV_NAME, \
 356                .init_chipset   = init_chipset_pdc202xx, \
 357                .port_ops       = &pdc2026x_port_ops, \
 358                .dma_ops        = &pdc2026x_dma_ops, \
 359                .host_flags     = IDE_HFLAGS_PDC202XX | extra_flags, \
 360                .pio_mask       = ATA_PIO4, \
 361                .mwdma_mask     = ATA_MWDMA2, \
 362                .udma_mask      = udma, \
 363        }
 364
 365static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
 366        {       /* 0: PDC20246 */
 367                .name           = DRV_NAME,
 368                .init_chipset   = init_chipset_pdc202xx,
 369                .port_ops       = &pdc20246_port_ops,
 370                .dma_ops        = &pdc20246_dma_ops,
 371                .host_flags     = IDE_HFLAGS_PDC202XX,
 372                .pio_mask       = ATA_PIO4,
 373                .mwdma_mask     = ATA_MWDMA2,
 374                .udma_mask      = ATA_UDMA2,
 375        },
 376
 377        /* 1: PDC2026{2,3} */
 378        DECLARE_PDC2026X_DEV(ATA_UDMA4, 0),
 379        /* 2: PDC2026{5,7} */
 380        DECLARE_PDC2026X_DEV(ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
 381};
 382
 383/**
 384 *      pdc202xx_init_one       -       called when a PDC202xx is found
 385 *      @dev: the pdc202xx device
 386 *      @id: the matching pci id
 387 *
 388 *      Called when the PCI registration layer (or the IDE initialization)
 389 *      finds a device matching our IDE device tables.
 390 */
 391 
 392static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 393{
 394        const struct ide_port_info *d;
 395        u8 idx = id->driver_data;
 396
 397        d = &pdc202xx_chipsets[idx];
 398
 399        if (idx < 2)
 400                pdc202ata4_fixup_irq(dev, d->name);
 401
 402        if (dev->vendor == PCI_DEVICE_ID_PROMISE_20265) {
 403                struct pci_dev *bridge = dev->bus->self;
 404
 405                if (bridge &&
 406                    bridge->vendor == PCI_VENDOR_ID_INTEL &&
 407                    (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
 408                     bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
 409                        printk(KERN_INFO DRV_NAME " %s: skipping Promise "
 410                                "PDC20265 attached to I2O RAID controller\n",
 411                                pci_name(dev));
 412                        return -ENODEV;
 413                }
 414        }
 415
 416        return ide_pci_init_one(dev, d, NULL);
 417}
 418
 419static const struct pci_device_id pdc202xx_pci_tbl[] = {
 420        { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
 421        { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
 422        { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 },
 423        { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20265), 2 },
 424        { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20267), 2 },
 425        { 0, },
 426};
 427MODULE_DEVICE_TABLE(pci, pdc202xx_pci_tbl);
 428
 429static struct pci_driver pdc202xx_pci_driver = {
 430        .name           = "Promise_Old_IDE",
 431        .id_table       = pdc202xx_pci_tbl,
 432        .probe          = pdc202xx_init_one,
 433        .remove         = ide_pci_remove,
 434        .suspend        = ide_pci_suspend,
 435        .resume         = ide_pci_resume,
 436};
 437
 438static int __init pdc202xx_ide_init(void)
 439{
 440        return ide_pci_register_driver(&pdc202xx_pci_driver);
 441}
 442
 443static void __exit pdc202xx_ide_exit(void)
 444{
 445        pci_unregister_driver(&pdc202xx_pci_driver);
 446}
 447
 448module_init(pdc202xx_ide_init);
 449module_exit(pdc202xx_ide_exit);
 450
 451MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
 452MODULE_DESCRIPTION("PCI driver module for older Promise IDE");
 453MODULE_LICENSE("GPL");
 454