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