?? pdc202xx_old.c
字號:
if (id && (id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (__ide_dma_bad_drive(drive)) goto fast_ata_pio; if (id->field_valid & 4) { if (id->dma_ultra & hwif->ultra_mask) { /* Force if Capable UltraDMA */ int dma = config_chipset_for_dma(drive); if ((id->field_valid & 2) && !dma) goto try_dma_modes; } } else if (id->field_valid & 2) {try_dma_modes: if ((id->dma_mword & hwif->mwdma_mask) || (id->dma_1word & hwif->swdma_mask)) { /* Force if Capable regular DMA modes */ if (!config_chipset_for_dma(drive)) goto no_dma_set; } } else if (__ide_dma_good_drive(drive) && (id->eide_dma_time < 150)) { goto no_dma_set; /* Consult the list of known "good" drives */ if (!config_chipset_for_dma(drive)) goto no_dma_set; } else { goto fast_ata_pio; } return hwif->ide_dma_on(drive); } else if ((id->capability & 8) || (id->field_valid & 2)) {fast_ata_pio:no_dma_set: hwif->tuneproc(drive, 5); return hwif->ide_dma_off_quietly(drive); } /* IORDY not supported */ return 0;}static int pdc202xx_quirkproc (ide_drive_t *drive){ return ((int) check_in_drive_lists(drive, pdc_quirk_drives));}static int pdc202xx_old_ide_dma_begin(ide_drive_t *drive){ if (drive->current_speed > XFER_UDMA_2) pdc_old_enable_66MHz_clock(drive->hwif); if (drive->addressing == 1) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive);// struct pci_dev *dev = hwif->pci_dev;// unsgned long high_16 = pci_resource_start(dev, 4); unsigned long high_16 = hwif->dma_master; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); u32 word_count = 0; u8 clock = hwif->INB(high_16 + 0x11); hwif->OUTB(clock|(hwif->channel ? 0x08 : 0x02), high_16+0x11); word_count = (rq->nr_sectors << 8); word_count = (rq_data_dir(rq) == READ) ? word_count | 0x05000000 : word_count | 0x06000000; hwif->OUTL(word_count, atapi_reg); } return __ide_dma_begin(drive);}static int pdc202xx_old_ide_dma_end(ide_drive_t *drive){ if (drive->addressing == 1) { ide_hwif_t *hwif = HWIF(drive);// unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4); unsigned long high_16 = hwif->dma_master; unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); u8 clock = 0; hwif->OUTL(0, atapi_reg); /* zero out extra */ clock = hwif->INB(high_16 + 0x11); hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11); } 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) { if ((sc1d & 0x50) == 0x50) goto somebody_else; else if ((sc1d & 0x40) == 0x40) return (dma_stat & 4) == 4; } else { 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");}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); }#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) pdc202_devs[n_pdc202_devs++] = dev; if (!pdc202xx_proc) { pdc202xx_proc = 1; ide_pci_create_host_proc("pdc202xx", pdc202xx_get_info); }#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */ /* * 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_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->ide_dma_begin = &pdc202xx_old_ide_dma_begin; 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 void __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 ide_setup_pci_device(dev, d);}static void __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; }#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 ide_setup_pci_device(dev, d);}static void __devinit init_setup_pdc202xx(struct pci_dev *dev, ide_pci_device_t *d){ ide_setup_pci_device(dev, d);}/** * 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]; d->init_setup(dev, d); return 0;}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 + -