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

📄 pdc202xx_old.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -