⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide-pci.c

📁 at91rm9200处理器ide接口驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	#ifdef CONFIG_PDC202XX_FORCE	if (dev->class >> 8 == PCI_CLASS_STORAGE_RAID) {		/*		 * By rights we want to ignore Promise FastTrak and SuperTrak		 * series here, those use own driver.		 */		if (dev->vendor == PCI_VENDOR_ID_PROMISE) {			printk(KERN_INFO "ide: Skipping Promise RAID controller.\n");			return;		}	}#endif /* CONFIG_PDC202XX_FORCE */	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 (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDCADMA))			goto bypass_legacy_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_PDC20270) ||		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20269) ||		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20275) ||		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20276) ||		    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_CMD680) ||		    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_legacy_dma: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 pdc20270_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d){	struct pci_dev *dev2 = NULL, *findev;	ide_pci_device_t *d2;	if ((dev->bus->self &&	     dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&	    (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) {		if (PCI_SLOT(dev->devfn) & 2) {			return;		}		d->extra = 0;		pci_for_each_dev(findev) {			if ((findev->vendor == dev->vendor) &&			    (findev->device == dev->device) &&			    (PCI_SLOT(findev->devfn) & 2)) {				byte irq = 0, irq2 = 0;				dev2 = findev;				pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);				pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2);                                if (irq != irq2) {					dev2->irq = dev->irq;                                        pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, irq);                                }			}		}	}	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);}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", "HPT372"};	if (PCI_FUNC(dev->devfn) & 1)		return;	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);	class_rev &= 0xff;	if (class_rev > 5)		class_rev = 5;		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, DEVID_PDC20270))		pdc20270_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 + -