?? pdc202xx_old.c
字號:
if (drive->current_speed > XFER_UDMA_2) pdc_old_disable_66MHz_clock(drive->hwif); return __ide_dma_end(drive);}static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive);// struct pci_dev *dev = hwif->pci_dev;// unsigned long high_16 = pci_resource_start(dev, 4); unsigned long high_16 = hwif->dma_master; u8 dma_stat = hwif->INB(hwif->dma_status); u8 sc1d = hwif->INB((high_16 + 0x001d)); if (hwif->channel) { /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */ if ((sc1d & 0x50) == 0x50) goto somebody_else; else if ((sc1d & 0x40) == 0x40) return (dma_stat & 4) == 4; } else { /* bit3: Error, bit2: Interrupting, bit1: FIFO Full, bit0: FIFO Empty */ if ((sc1d & 0x05) == 0x05) goto somebody_else; else if ((sc1d & 0x04) == 0x04) return (dma_stat & 4) == 4; }somebody_else: return (dma_stat & 4) == 4; /* return 1 if INTR asserted */}static int pdc202xx_ide_dma_lostirq(ide_drive_t *drive){ if (HWIF(drive)->resetproc != NULL) HWIF(drive)->resetproc(drive); return __ide_dma_lostirq(drive);}static int pdc202xx_ide_dma_timeout(ide_drive_t *drive){ if (HWIF(drive)->resetproc != NULL) HWIF(drive)->resetproc(drive); return __ide_dma_timeout(drive);}static void pdc202xx_reset_host (ide_hwif_t *hwif){#ifdef CONFIG_BLK_DEV_IDEDMA// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel)); unsigned long high_16 = hwif->dma_master;#else /* !CONFIG_BLK_DEV_IDEDMA */ unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4);#endif /* CONFIG_BLK_DEV_IDEDMA */ u8 udma_speed_flag = hwif->INB(high_16|0x001f); hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f)); mdelay(100); hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f)); mdelay(2000); /* 2 seconds ?! */ printk(KERN_WARNING "PDC202XX: %s channel reset.\n", hwif->channel ? "Secondary" : "Primary");}static void pdc202xx_reset (ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *mate = hwif->mate; pdc202xx_reset_host(hwif); pdc202xx_reset_host(mate);#if 0 /* * FIXME: Have to kick all the drives again :-/ * What a pain in the ACE! */ if (hwif->present) { u16 hunit = 0; for (hunit = 0; hunit < MAX_DRIVES; ++hunit) { ide_drive_t *hdrive = &hwif->drives[hunit]; if (hdrive->present) { if (hwif->ide_dma_check) hwif->ide_dma_check(hdrive); else hwif->tuneproc(hdrive, 5); } } } if (mate->present) { u16 munit = 0; for (munit = 0; munit < MAX_DRIVES; ++munit) { ide_drive_t *mdrive = &mate->drives[munit]; if (mdrive->present) { if (mate->ide_dma_check) mate->ide_dma_check(mdrive); else mate->tuneproc(mdrive, 5); } } }#else hwif->tuneproc(drive, 5);#endif}/* * Since SUN Cobalt is attempting to do this operation, I should disclose * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date * HOTSWAP ATA Infrastructure. */static int pdc202xx_tristate (ide_drive_t * drive, int state){ ide_hwif_t *hwif = HWIF(drive);// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel)); unsigned long high_16 = hwif->dma_master; u8 sc1f = hwif->INB(high_16|0x001f); if (!hwif) return -EINVAL;// hwif->bus_state = state; if (state) { hwif->OUTB(sc1f | 0x08, (high_16|0x001f)); } else { hwif->OUTB(sc1f & ~0x08, (high_16|0x001f)); } return 0;}static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name){ if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); } /* * software reset - this is required because the bios * will set UDMA timing on if the hdd supports it. The * user may want to turn udma off. A bug in the pdc20262 * is that it cannot handle a downgrade in timing from * UDMA to DMA. Disk accesses after issuing a set * feature command will result in errors. A software * reset leaves the timing registers intact, * but resets the drives. */#if 0 if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || (dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20263) || (dev->device == PCI_DEVICE_ID_PROMISE_20262)) { unsigned long high_16 = pci_resource_start(dev, 4); byte udma_speed_flag = inb(high_16 + 0x001f); outb(udma_speed_flag | 0x10, high_16 + 0x001f); mdelay(100); outb(udma_speed_flag & ~0x10, high_16 + 0x001f); mdelay(2000); /* 2 seconds ?! */ }#endif return dev->irq;}static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif){ struct pci_dev *dev = hwif->pci_dev; /* PDC20265 has problems with large LBA48 requests */ if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || (dev->device == PCI_DEVICE_ID_PROMISE_20265)) hwif->rqsize = 256; hwif->autodma = 0; hwif->tuneproc = &config_chipset_for_pio; hwif->quirkproc = &pdc202xx_quirkproc; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { hwif->busproc = &pdc202xx_tristate; hwif->resetproc = &pdc202xx_reset; } hwif->speedproc = &pdc202xx_tune_chipset; hwif->drives[0].autotune = hwif->drives[1].autotune = 1; hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { if (!(hwif->udma_four)) hwif->udma_four = (pdc202xx_old_cable_detect(hwif)) ? 0 : 1; hwif->dma_start = &pdc202xx_old_ide_dma_start; hwif->ide_dma_end = &pdc202xx_old_ide_dma_end; } hwif->ide_dma_test_irq = &pdc202xx_old_ide_dma_test_irq; if (!noautodma) hwif->autodma = 1; hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma;#if PDC202_DEBUG_CABLE printk(KERN_DEBUG "%s: %s-pin cable\n", hwif->name, hwif->udma_four ? "80" : "40");#endif /* PDC202_DEBUG_CABLE */ }static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase){ u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0; if (hwif->channel) { ide_setup_dma(hwif, dmabase, 8); return; } udma_speed_flag = hwif->INB((dmabase|0x1f)); primary_mode = hwif->INB((dmabase|0x1a)); secondary_mode = hwif->INB((dmabase|0x1b)); printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \ "Primary %s Mode " \ "Secondary %s Mode.\n", hwif->cds->name, (udma_speed_flag & 1) ? "EN" : "DIS", (primary_mode & 1) ? "MASTER" : "PCI", (secondary_mode & 1) ? "MASTER" : "PCI" );#ifdef CONFIG_PDC202XX_BURST if (!(udma_speed_flag & 1)) { printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ", hwif->cds->name, udma_speed_flag, (udma_speed_flag|1)); hwif->OUTB(udma_speed_flag|1,(dmabase|0x1f)); printk("%sACTIVE\n", (hwif->INB(dmabase|0x1f)&1) ? "":"IN"); }#endif /* CONFIG_PDC202XX_BURST */#ifdef CONFIG_PDC202XX_MASTER if (!(primary_mode & 1)) { printk(KERN_INFO "%s: FORCING PRIMARY MODE BIT " "0x%02x -> 0x%02x ", hwif->cds->name, primary_mode, (primary_mode|1)); hwif->OUTB(primary_mode|1, (dmabase|0x1a)); printk("%s\n", (hwif->INB((dmabase|0x1a)) & 1) ? "MASTER" : "PCI"); } if (!(secondary_mode & 1)) { printk(KERN_INFO "%s: FORCING SECONDARY MODE BIT " "0x%02x -> 0x%02x ", hwif->cds->name, secondary_mode, (secondary_mode|1)); hwif->OUTB(secondary_mode|1, (dmabase|0x1b)); printk("%s\n", (hwif->INB((dmabase|0x1b)) & 1) ? "MASTER" : "PCI"); }#endif /* CONFIG_PDC202XX_MASTER */ ide_setup_dma(hwif, dmabase, 8);}static int __devinit init_setup_pdc202ata4(struct pci_dev *dev, ide_pci_device_t *d){ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { u8 irq = 0, irq2 = 0; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); /* 0xbc */ pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); if (irq != irq2) { pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ printk(KERN_INFO "%s: pci-config space interrupt " "mirror fixed.\n", d->name); } }#if 0 if (dev->device == PCI_DEVICE_ID_PROMISE_20262) if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val)) if (d->enablebits[0].reg != d->enablebits[1].reg) { d->enablebits[0].reg = d->enablebits[1].reg; d->enablebits[0].mask = d->enablebits[1].mask; d->enablebits[0].val = d->enablebits[1].val; }#endif return ide_setup_pci_device(dev, d);}static int __devinit init_setup_pdc20265(struct pci_dev *dev, ide_pci_device_t *d){ if ((dev->bus->self) && (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) && ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) || (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) { printk(KERN_INFO "ide: Skipping Promise PDC20265 " "attached to I2O RAID controller.\n"); return -ENODEV; }#if 0 { u8 pri = 0, sec = 0; if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val)) if (d->enablebits[0].reg != d->enablebits[1].reg) { d->enablebits[0].reg = d->enablebits[1].reg; d->enablebits[0].mask = d->enablebits[1].mask; d->enablebits[0].val = d->enablebits[1].val; } }#endif return ide_setup_pci_device(dev, d);}static int __devinit init_setup_pdc202xx(struct pci_dev *dev, ide_pci_device_t *d){ return ide_setup_pci_device(dev, d);}static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { { /* 0 */ .name = "PDC20246", .init_setup = init_setup_pdc202ata4, .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, .channels = 2, .autodma = AUTODMA,#ifndef CONFIG_PDC202XX_FORCE .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},#endif .bootable = OFF_BOARD, .extra = 16, },{ /* 1 */ .name = "PDC20262", .init_setup = init_setup_pdc202ata4, .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, .channels = 2, .autodma = AUTODMA,#ifndef CONFIG_PDC202XX_FORCE .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},#endif .bootable = OFF_BOARD, .extra = 48, .flags = IDEPCI_FLAG_FORCE_PDC, },{ /* 2 */ .name = "PDC20263", .init_setup = init_setup_pdc202ata4, .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, .channels = 2, .autodma = AUTODMA,#ifndef CONFIG_PDC202XX_FORCE .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},#endif .bootable = OFF_BOARD, .extra = 48, },{ /* 3 */ .name = "PDC20265", .init_setup = init_setup_pdc20265, .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, .channels = 2, .autodma = AUTODMA,#ifndef CONFIG_PDC202XX_FORCE .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},#endif .bootable = OFF_BOARD, .extra = 48, .flags = IDEPCI_FLAG_FORCE_PDC, },{ /* 4 */ .name = "PDC20267", .init_setup = init_setup_pdc202xx, .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, .channels = 2, .autodma = AUTODMA,#ifndef CONFIG_PDC202XX_FORCE .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},#endif .bootable = OFF_BOARD, .extra = 48, }};/** * pdc202xx_init_one - called when a PDC202xx is found * @dev: the pdc202xx device * @id: the matching pci id * * Called when the PCI registration layer (or the IDE initialization) * finds a device matching our IDE device tables. */ static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id){ ide_pci_device_t *d = &pdc202xx_chipsets[id->driver_data]; return d->init_setup(dev, d);}static struct pci_device_id pdc202xx_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, { 0, },};MODULE_DEVICE_TABLE(pci, pdc202xx_pci_tbl);static struct pci_driver driver = { .name = "Promise_Old_IDE", .id_table = pdc202xx_pci_tbl, .probe = pdc202xx_init_one,};static int pdc202xx_ide_init(void){ return ide_pci_register_driver(&driver);}module_init(pdc202xx_ide_init);MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");MODULE_DESCRIPTION("PCI driver module for older Promise IDE");MODULE_LICENSE("GPL");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -