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

📄 triton.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* Consult the list of known "good" drives */		list = good_dma_drives;		while (*list) {			if (!strcmp(*list++,id->model)) {				drive->using_dma = 1;				return 0;	/* DMA enabled */			}		}	}	return 1;	/* DMA not enabled */}/* * triton_dmaproc() initiates/aborts DMA read/write operations on a drive. * * The caller is assumed to have selected the drive and programmed the drive's * sector address using CHS or LBA.  All that remains is to prepare for DMA * and then issue the actual read/write DMA/PIO command to the drive. * * For ATAPI devices, we just prepare for DMA and return. The caller should * then issue the packet command to the drive and call us again with * ide_dma_begin afterwards. * * Returns 0 if all went well. * Returns 1 if DMA read/write could not be started, in which case * the caller should revert to PIO for the current request. */static int triton_dmaproc (ide_dma_action_t func, ide_drive_t *drive){	unsigned long dma_base = HWIF(drive)->dma_base;	unsigned int reading = (1 << 3);	switch (func) {		case ide_dma_abort:			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */			return 0;		case ide_dma_check:			return config_drive_for_dma (drive);		case ide_dma_write:			reading = 0;		case ide_dma_read:			break;		case ide_dma_status_bad:			return ((inb(dma_base+2) & 7) != 4);	/* verify good DMA status */		case ide_dma_transferred:#if 0			return (number of bytes actually transferred);#else			return (0);#endif		case ide_dma_begin:			outb(inb(dma_base)|1, dma_base);	/* begin DMA */			return 0;		default:			printk("triton_dmaproc: unsupported func: %d\n", func);			return 1;	}	if (build_dmatable (drive))		return 1;	outl(virt_to_bus (HWIF(drive)->dmatable), dma_base + 4); /* PRD table */	outb(reading, dma_base);			/* specify r/w */	outb(inb(dma_base+2)|0x06, dma_base+2);		/* clear status bits */#ifdef CONFIG_BLK_DEV_IDEATAPI	if (drive->media != ide_disk)		return 0;#endif /* CONFIG_BLK_DEV_IDEATAPI */		ide_set_handler(drive, &dma_intr, WAIT_CMD);	/* issue cmd to drive */	OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);	outb(inb(dma_base)|1, dma_base);		/* begin DMA */	return 0;}#ifdef DISPLAY_TRITON_TIMINGS/* * print_triton_drive_flags() displays the currently programmed options * in the i82371 (Triton) for a given drive. * *	If fastDMA  is "no", then slow ISA timings are used for DMA data xfers. *	If fastPIO  is "no", then slow ISA timings are used for PIO data xfers. *	If IORDY    is "no", then IORDY is assumed to always be asserted. *	If PreFetch is "no", then data pre-fetch/post are not used. * * When "fastPIO" and/or "fastDMA" are "yes", then faster PCI timings and * back-to-back 16-bit data transfers are enabled, using the sample_CLKs * and recovery_CLKs (PCI clock cycles) timing parameters for that interface. */static void print_triton_drive_flags (unsigned int unit, byte flags){	printk("         %s ", unit ? "slave :" : "master:");	printk( "fastDMA=%s",	(flags&9)	? "on " : "off");	printk(" PreFetch=%s",	(flags&4)	? "on " : "off");	printk(" IORDY=%s",	(flags&2)	? "on " : "off");	printk(" fastPIO=%s\n",	((flags&9)==1)	? "on " : "off");}#endif /* DISPLAY_TRITON_TIMINGS */static void init_triton_dma (ide_hwif_t *hwif, unsigned short base){	static unsigned long dmatable = 0;	printk("    %s: BM-DMA at 0x%04x-0x%04x", hwif->name, base, base+7);	if (check_region(base, 8)) {		printk(" -- ERROR, PORTS ALREADY IN USE");	} else {		request_region(base, 8, "IDE DMA");		hwif->dma_base = base;		if (!dmatable) {			/*			 * The BM-DMA uses a full 32-bits, so we can			 * safely use __get_free_page() here instead			 * of __get_dma_pages() -- no ISA limitations.			 */			dmatable = __get_free_pages(GFP_KERNEL, 1, 0);		}		if (dmatable) {			hwif->dmatable = (unsigned long *) dmatable;			dmatable += (PRD_ENTRIES * PRD_BYTES);			outl(virt_to_bus(hwif->dmatable), base + 4);			hwif->dmaproc  = &triton_dmaproc;		}	}	printk("\n");}/* * ide_init_triton() prepares the IDE driver for DMA operation. * This routine is called once, from ide.c during driver initialization, * for each triton chipset which is found (unlikely to be more than one). */void ide_init_triton (byte bus, byte fn){	int rc = 0, h;	int dma_enabled = 0;	unsigned short pcicmd;	unsigned int bmiba, timings;	printk("ide: i82371 PIIX (Triton) on PCI bus %d function %d\n", bus, fn);	/*	 * See if IDE and BM-DMA features are enabled:	 */	if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))		goto quit;	if ((pcicmd & 1) == 0)  {		printk("ide: ports are not enabled (BIOS)\n");		goto quit;	}	if ((pcicmd & 4) == 0) {		printk("ide: BM-DMA feature is not enabled (BIOS)\n");	} else {		/*		 * Get the bmiba base address		 */		int try_again = 1;		do {			if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))				goto quit;			bmiba &= 0xfff0;	/* extract port base address */			if (bmiba) {				dma_enabled = 1;				break;			} else {				printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);				if (inb(DEFAULT_BMIBA) != 0xff || !try_again)					break;				printk("ide: setting BM-DMA base register to 0x%04x\n", DEFAULT_BMIBA);				if ((rc = pcibios_write_config_word(bus, fn, 0x04, pcicmd&~1)))					goto quit;				rc = pcibios_write_config_dword(bus, fn, 0x20, DEFAULT_BMIBA|1);				if (pcibios_write_config_word(bus, fn, 0x04, pcicmd|5) || rc)					goto quit;			}		} while (try_again--);	}	/*	 * See if ide port(s) are enabled	 */	if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))		goto quit;	if (!(timings & 0x80008000)) {		printk("ide: neither port is enabled\n");		goto quit;	}	/*	 * Save the dma_base port addr for each interface	 */	for (h = 0; h < MAX_HWIFS; ++h) {#ifdef DISPLAY_TRITON_TIMINGS		byte s_clks, r_clks;		unsigned short devid;#endif /* DISPLAY_TRITON_TIMINGS */		ide_hwif_t *hwif = &ide_hwifs[h];		unsigned short time;		if (hwif->io_base == 0x1f0) {			time = timings & 0xffff;			if ((time & 0x8000) == 0)	/* interface enabled? */				continue;			hwif->chipset = ide_triton;			if (dma_enabled)				init_triton_dma(hwif, bmiba);		} else if (hwif->io_base == 0x170) {			time = timings >> 16;			if ((time & 0x8000) == 0)	/* interface enabled? */				continue;			hwif->chipset = ide_triton;			if (dma_enabled)				init_triton_dma(hwif, bmiba + 8);		} else			continue;#ifdef DISPLAY_TRITON_TIMINGS		s_clks = ((~time >> 12) & 3) + 2;		r_clks = ((~time >>  8) & 3) + 1;		printk("    %s timing: (0x%04x) sample_CLKs=%d, recovery_CLKs=%d\n",		 hwif->name, time, s_clks, r_clks);		if ((time & 0x40) && !pcibios_read_config_word(bus, fn, 0x02, &devid)		 && devid == PCI_DEVICE_ID_INTEL_82371SB_1)		{			byte stime;			if (pcibios_read_config_byte(bus, fn, 0x44, &stime)) {				if (hwif->io_base == 0x1f0) {					s_clks = ~stime >> 6;					r_clks = ~stime >> 4;				} else {					s_clks = ~stime >> 2;					r_clks = ~stime;				}				s_clks = (s_clks & 3) + 2;				r_clks = (r_clks & 3) + 1;				printk("                   slave: sample_CLKs=%d, recovery_CLKs=%d\n",		 			s_clks, r_clks);			}		}		print_triton_drive_flags (0, time & 0xf);		print_triton_drive_flags (1, (time >> 4) & 0xf);#endif /* DISPLAY_TRITON_TIMINGS */	}quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));}void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma){	int rc;	unsigned short pcicmd;	unsigned int bmiba = 0;	printk("ide: Enabling DMA for Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d, port 0x%04x\n", bus, fn, dma);	if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)) || (pcicmd & 1) == 0 || (pcicmd & 4) == 0)		goto abort;	if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))		goto abort;	bmiba &= 0xfff0;	/* extract port base address */	if (bmiba != dma || !bmiba)		goto abort;	hwif0->chipset = ide_promise_udma;	hwif1->chipset = ide_promise_udma;	init_triton_dma(hwif0, bmiba);	init_triton_dma(hwif1, bmiba + 0x08);	return;abort:	printk(KERN_WARNING "ide: Promise/33 not configured correctly (BIOS)\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -