?? ide-pci.c
字號:
printk("%s: device enabled (Linux)\n", d->name); pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) { /* see comments in hpt34x.c on why..... */ char *chipset_names[] = {"HPT343", "HPT345"}; strcpy(d->name, chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]); d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; } printk("%s: chipset revision %d\n", d->name, class_rev); /* * Can we trust the reported IRQ? */ pciirq = dev->irq; if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) { /* By rights we want to ignore these, but the Promise Fastrak people have some strange ideas about proprietary so we have to act otherwise on those. The supertrak however we need to skip */ if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) { printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n"); if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL && dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) { printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n"); return; } } /* Its attached to something else, just a random bridge. Suspect a fastrak and fall through */ } if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) { printk("%s: not 100%% native mode: will probe irqs later\n", d->name); /* * This allows offboard ide-pci cards the enable a BIOS, * verify interrupt settings of split-mirror pci-config * space, place chipset into init-mode, and/or preserve * an interrupt if the card is not native ide support. */ pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : ide_special_settings(dev, d->name); } else if (tried_config) { printk("%s: will probe irqs later\n", d->name); pciirq = 0; } else if (!pciirq) { printk("%s: bad irq (%d): will probe later\n", d->name, pciirq); pciirq = 0; } else { if (d->init_chipset) (void) d->init_chipset(dev, d->name);#ifdef __sparc__ printk("%s: 100%% native mode on irq %s\n", d->name, __irq_itoa(pciirq));#else printk("%s: 100%% native mode on irq %d\n", d->name, pciirq);#endif } /* * Set up the IDE ports */ for (port = 0; port <= 1; ++port) { unsigned long base = 0, ctl = 0; ide_pci_enablebit_t *e = &(d->enablebits[port]); /* * If this is a Promise FakeRaid controller, the 2nd controller will be marked as * disabled while it is actually there and enabled by the bios for raid purposes. * Skip the normal "is it enabled" test for those. */ if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265)) && (secondpdc++==1) && (port==1) ) goto controller_ok; if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262)) && (secondpdc++==1) && (port==1) ) goto controller_ok; if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val)) continue; /* port not enabled */controller_ok: if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev < 0x03)) return; if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE || (dev->class & (port ? 4 : 1)) != 0) { ctl = dev->resource[(2*port)+1].start; base = dev->resource[2*port].start; if (!(ctl & PCI_BASE_ADDRESS_IO_MASK) || !(base & PCI_BASE_ADDRESS_IO_MASK)) { printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@linux-ide.org>.\n", d->name);#if 0 /* FIXME! This really should check that it really gets the IO/MEM part right! */ continue;#endif } } if ((ctl && !base) || (base && !ctl)) { printk("%s: inconsistent baseregs (BIOS) for port %d, skipping\n", d->name, port); continue; } if (!ctl) ctl = port ? 0x374 : 0x3f4; /* use default value */ if (!base) base = port ? 0x170 : 0x1f0; /* use default value */ if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL) continue; /* no room in ide_hwifs[] */ if (hwif->io_ports[IDE_DATA_OFFSET] != base) { ide_init_hwif_ports(&hwif->hw, base, (ctl | 2), NULL); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; } hwif->chipset = ide_pci; hwif->pci_dev = dev; hwif->pci_devid = d->devid; hwif->channel = port; if (!hwif->irq) hwif->irq = pciirq; if (mate) { hwif->mate = mate; mate->mate = hwif; if (IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210)) { hwif->serialized = 1; mate->serialized = 1; } } if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) || IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886BF) || IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8673F)) { hwif->irq = hwif->channel ? 15 : 14; goto bypass_umc_dma; } if (IDE_PCI_DEVID_EQ(d->devid, DEVID_MPIIX)) goto bypass_piix_dma; if (hwif->udma_four) { printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name); } else { hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0; }#ifdef CONFIG_BLK_DEV_IDEDMA if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PIIX4NX) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) || IDE_PCI_DEVID_EQ(d->devid, DEVID_VIA_IDE) || IDE_PCI_DEVID_EQ(d->devid, DEVID_MR_IDE) || IDE_PCI_DEVID_EQ(d->devid, DEVID_VP_IDE)) autodma = 0; if (autodma) hwif->autodma = 1; if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) || IDE_PCI_DEVID_EQ(d->devid, DEVID_OSB4) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name); if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { /* * Set up BM-DMA capability (PnP BIOS should have done this) */ if (!IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530)) hwif->autodma = 0; /* default DMA off if we had to configure it here */ (void) pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_MASTER); if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) { printk("%s: %s error updating PCICMD\n", hwif->name, d->name); dma_base = 0; } } if (dma_base) { if (d->dma_init) { d->dma_init(hwif, dma_base); } else { ide_setup_dma(hwif, dma_base, 8); } } else { printk("%s: %s Bus-Master DMA disabled (BIOS)\n", hwif->name, d->name); } }#endif /* CONFIG_BLK_DEV_IDEDMA */bypass_piix_dma:bypass_umc_dma: if (d->init_hwif) /* Call chipset-specific routine for each enabled hwif */ d->init_hwif(hwif); mate = hwif; at_least_one_hwif_enabled = 1; } if (!at_least_one_hwif_enabled) printk("%s: neither IDE port enabled (BIOS)\n", d->name);}static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d){ struct pci_dev *dev2 = NULL, *findev; ide_pci_device_t *d2; unsigned char pin1 = 0, pin2 = 0; unsigned int class_rev; char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"}; if (PCI_FUNC(dev->devfn) & 1) return; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; strcpy(d->name, chipset_names[class_rev]); switch(class_rev) { case 4: case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); ide_setup_pci_device(dev, d); return; default: break; } pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); pci_for_each_dev(findev) { if ((findev->vendor == dev->vendor) && (findev->device == dev->device) && ((findev->devfn - dev->devfn) == 1) && (PCI_FUNC(findev->devfn) & 1)) { dev2 = findev; pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2); hpt363_shared_pin = (pin1 != pin2) ? 1 : 0; hpt363_shared_irq = (dev->irq == dev2->irq) ? 1 : 0; if (hpt363_shared_pin && hpt363_shared_irq) { d->bootable = ON_BOARD; printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", d->name, pin1, pin2);#if 0 /* I forgot why I did this once, but it fixed something. */ pci_write_config_byte(dev2, PCI_INTERRUPT_PIN, dev->irq); printk("PCI: %s: Fixing interrupt %d pin %d to ZERO \n", d->name, dev2->irq, pin2); pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, 0);#endif } break; } } printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); ide_setup_pci_device(dev, d); if (!dev2) return; d2 = d; printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn); ide_setup_pci_device(dev2, d2);}/* * ide_scan_pcibus() gets invoked at boot time from ide.c. * It finds all PCI IDE controllers and calls ide_setup_pci_device for them. */void __init ide_scan_pcidev (struct pci_dev *dev){ ide_pci_devid_t devid; ide_pci_device_t *d; devid.vid = dev->vendor; devid.did = dev->device; for (d = ide_pci_chipsets; d->devid.vid && !IDE_PCI_DEVID_EQ(d->devid, devid); ++d); if (d->init_hwif == IDE_IGNORE) printk("%s: ignored by ide_scan_pci_device() (uses own driver)\n", d->name); else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_OPTI621V) && !(PCI_FUNC(dev->devfn) & 1)) return; else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) return; /* CY82C693 is more than only a IDE controller */ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_ITE8172G) && (!(PCI_FUNC(dev->devfn) & 1) || !((dev->class >> 8) == PCI_CLASS_STORAGE_IDE))) return; /* IT8172G is also more than only an IDE controller */ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_UM8886A) && !(PCI_FUNC(dev->devfn) & 1)) return; /* UM8886A/BF pair */ else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366)) hpt366_device_order_fixup(dev, d); else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { if (IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL)) printk("%s: unknown IDE controller on PCI bus %02x device %02x, VID=%04x, DID=%04x\n", d->name, dev->bus->number, dev->devfn, devid.vid, devid.did); else printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); ide_setup_pci_device(dev, d); }}void __init ide_scan_pcibus (int scan_direction){ struct pci_dev *dev; if (!scan_direction) { pci_for_each_dev(dev) { ide_scan_pcidev(dev); } } else { pci_for_each_dev_reverse(dev) { ide_scan_pcidev(dev); } }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -