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

📄 siimage.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/drivers/ide/pci/siimage.c		Version 1.02	Jan 30, 2003 * * Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org> */#include <linux/config.h>#include <linux/types.h>#include <linux/module.h>#include <linux/pci.h>#include <linux/delay.h>#include <linux/hdreg.h>#include <linux/ide.h>#include <linux/init.h>#include <asm/io.h>#include "ide_modes.h"#include "siimage.h"#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS)#include <linux/stat.h>#include <linux/proc_fs.h>static u8 siimage_proc = 0;#define SIIMAGE_MAX_DEVS		5static struct pci_dev *siimage_devs[SIIMAGE_MAX_DEVS];static int n_siimage_devs;static char * print_siimage_get_info (char *buf, struct pci_dev *dev, int index){	char *p		= buf;	u8 mmio		= (pci_get_drvdata(dev) != NULL) ? 1 : 0;	unsigned long bmdma	= (mmio) ? ((unsigned long) pci_get_drvdata(dev)) :				    (pci_resource_start(dev, 4));	p += sprintf(p, "\nController: %d\n", index);	p += sprintf(p, "SiI%x Chipset.\n", dev->device);	if (mmio)		p += sprintf(p, "MMIO Base 0x%lx\n", bmdma);	p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma);	p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma+8);	p += sprintf(p, "--------------- Primary Channel "			"---------------- Secondary Channel "			"-------------\n");	p += sprintf(p, "--------------- drive0 --------- drive1 "			"-------- drive0 ---------- drive1 ------\n");	p += sprintf(p, "PIO Mode:       %s                %s"			"               %s                 %s\n",			"?", "?", "?", "?");	return (char *)p;}static int siimage_get_info (char *buffer, char **addr, off_t offset, int count){	char *p = buffer;	u16 i;	p += sprintf(p, "\n");	for (i = 0; i < n_siimage_devs; i++) {		struct pci_dev *dev	= siimage_devs[i];		p = print_siimage_get_info(p, dev, i);	}	return p-buffer;	/* => must be less than 4k! */}#endif	/* defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) */static byte siimage_ratemask (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	u8 mode	= 0, scsc = 0;	if (hwif->mmio)		scsc = hwif->INB(HWIFADDR(0x4A));	else		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);	switch(hwif->pci_dev->device) {		case PCI_DEVICE_ID_SII_3112:			return 4;		case PCI_DEVICE_ID_SII_680:			if ((scsc & 0x10) == 0x10)	/* 133 */				mode = 4;			else if ((scsc & 0x30) == 0x00)	/* 100 */				mode = 3;			else if ((scsc & 0x20) == 0x20)	/* 66 eek */				BUG();	// mode = 2;			break;		default:	return 0;	}	if (!eighty_ninty_three(drive))		mode = min(mode, (u8)1);	return mode;}static byte siimage_taskfile_timing (ide_hwif_t *hwif){	u16 timing	= 0x328a;	if (hwif->mmio)		timing = hwif->INW(SELADDR(2));	else		pci_read_config_word(hwif->pci_dev, SELREG(2), &timing);	switch (timing) {		case 0x10c1:	return 4;		case 0x10c3:	return 3;		case 0x1281:	return 2;		case 0x2283:	return 1;		case 0x328a:		default:	return 0;	}}static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted){	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	u16 speedt		= 0;	u8 unit			= drive->select.b.unit;	if (hwif->mmio)		speedt = hwif->INW(SELADDR(0x04|(unit<<unit)));	else		pci_read_config_word(dev, SELADDR(0x04|(unit<<unit)), &speedt);	/* cheat for now and use the docs *///	switch(siimage_taskfile_timing(hwif)) {	switch(mode_wanted) {		case 4:		speedt = 0x10c1; break;		case 3:		speedt = 0x10C3; break;		case 2:		speedt = 0x1104; break;		case 1:		speedt = 0x2283; break;		case 0:		default:	speedt = 0x328A; break;	}	if (hwif->mmio)		hwif->OUTW(speedt, SELADDR(0x04|(unit<<unit)));	else		pci_write_config_word(dev, SELADDR(0x04|(unit<<unit)), speedt);}static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed){	u8 channel_timings	= siimage_taskfile_timing(HWIF(drive));	u8 speed = 0, set_pio	= ide_get_best_pio_mode(drive, 4, 5, NULL);	/* WARNING PIO timing mess is going to happen b/w devices, argh */	if ((channel_timings != set_pio) && (set_pio > channel_timings))		set_pio = channel_timings;	siimage_tuneproc(drive, set_pio);	speed = XFER_PIO_0 + set_pio;	if (set_speed)		(void) ide_config_drive_speed(drive, speed);}static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed){	config_siimage_chipset_for_pio(drive, set_speed);}static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed){	u8 ultra6[]		= { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };	u8 ultra5[]		= { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };	u16 dma[]		= { 0x2208, 0x10C2, 0x10C1 };	ide_hwif_t *hwif	= HWIF(drive);	u16 ultra = 0, multi	= 0;	u8 mode = 0, unit	= drive->select.b.unit;	u8 speed	= ide_rate_filter(siimage_ratemask(drive), xferspeed);	u8 scsc = 0, addr_mask	= ((hwif->channel) ?				    ((hwif->mmio) ? 0xF4 : 0x84) :				    ((hwif->mmio) ? 0xB4 : 0x80));	if (hwif->mmio) {		scsc = hwif->INB(HWIFADDR(0x4A));		mode = hwif->INB(HWIFADDR(addr_mask));		multi = hwif->INW(SELADDR(0x08|(unit<<unit)));		ultra = hwif->INW(SELADDR(0x0C|(unit<<unit)));	} else {		pci_read_config_byte(hwif->pci_dev, HWIFADDR(0x8A), &scsc);		pci_read_config_byte(hwif->pci_dev, addr_mask, &mode);		pci_read_config_word(hwif->pci_dev,				SELREG(0x08|(unit<<unit)), &multi);		pci_read_config_word(hwif->pci_dev,				SELREG(0x0C|(unit<<unit)), &ultra);	}	mode &= ~((unit) ? 0x30 : 0x03);	ultra &= ~0x3F;	scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;	scsc = (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) ? 1 : scsc;	switch(speed) {		case XFER_PIO_4:		case XFER_PIO_3:		case XFER_PIO_2:		case XFER_PIO_1:		case XFER_PIO_0:			siimage_tuneproc(drive, (speed - XFER_PIO_0));			mode |= ((unit) ? 0x10 : 0x01);			break;		case XFER_MW_DMA_2:		case XFER_MW_DMA_1:		case XFER_MW_DMA_0:			multi = dma[speed - XFER_MW_DMA_0];			mode |= ((unit) ? 0x20 : 0x02);			config_siimage_chipset_for_pio(drive, 0);			break;		case XFER_UDMA_6:		case XFER_UDMA_5:		case XFER_UDMA_4:		case XFER_UDMA_3:		case XFER_UDMA_2:		case XFER_UDMA_1:		case XFER_UDMA_0:			multi = dma[2];			ultra |= ((scsc) ? (ultra5[speed - XFER_UDMA_0]) :					   (ultra6[speed - XFER_UDMA_0]));			mode |= ((unit) ? 0x30 : 0x03);			config_siimage_chipset_for_pio(drive, 0);			break;		default:			return 1;	}	if (hwif->mmio) {		hwif->OUTB(mode, HWIFADDR(addr_mask));		hwif->OUTW(multi, SELADDR(0x08|(unit<<unit)));		hwif->OUTW(ultra, SELADDR(0x0C|(unit<<unit)));	} else {		pci_write_config_byte(hwif->pci_dev, addr_mask, mode);		pci_write_config_word(hwif->pci_dev,				SELREG(0x08|(unit<<unit)), multi);		pci_write_config_word(hwif->pci_dev,				SELREG(0x0C|(unit<<unit)), ultra);	}	return (ide_config_drive_speed(drive, speed));}static int config_chipset_for_dma (ide_drive_t *drive){	u8 speed	= ide_dma_speed(drive, siimage_ratemask(drive));	config_chipset_for_pio(drive, !speed);	if (!speed)		return 0;	if (ide_set_xfer_rate(drive, speed))		return 0;	if (!drive->init_speed)		drive->init_speed = speed;	return ide_dma_enable(drive);}static int siimage_config_drive_for_dma (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	struct hd_driveid *id	= drive->id;	if (id != NULL && (id->capability & 1) != 0 && drive->autodma) {		if (!(hwif->atapi_dma))			goto fast_ata_pio;		/* Consult the list of known "bad" drives */		if (hwif->ide_dma_bad_drive(drive))			goto fast_ata_pio;		if ((id->field_valid & 4) && siimage_ratemask(drive)) {			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 (hwif->ide_dma_good_drive(drive) &&			   (id->eide_dma_time < 150)) {			/* Consult the list of known "good" drives */			if (!config_chipset_for_dma(drive))				goto no_dma_set;		} else {			goto fast_ata_pio;		}	} else if ((id->capability & 8) || (id->field_valid & 2)) {fast_ata_pio:no_dma_set:		config_chipset_for_pio(drive, 1);		return hwif->ide_dma_off_quietly(drive);	}	return hwif->ide_dma_on(drive);}/* returns 1 if dma irq issued, 0 otherwise */static int siimage_io_ide_dma_test_irq (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	u8 dma_altstat		= 0;	/* return 1 if INTR asserted */	if ((hwif->INB(hwif->dma_status) & 4) == 4)		return 1;	/* return 1 if Device INTR asserted */	pci_read_config_byte(hwif->pci_dev, SELREG(1), &dma_altstat);	if (dma_altstat & 8)		return 0;	//return 1;	return 0;}static int siimage_mmio_ide_dma_count (ide_drive_t *drive){#ifdef SIIMAGE_VIRTUAL_DMAPIO	struct request *rq	= HWGROUP(drive)->rq;	ide_hwif_t *hwif	= HWIF(drive);	u32 count		= (rq->nr_sectors * SECTOR_SIZE);	u32 rcount		= 0;	hwif->OUTL(count, SELADDR(0x1C));	rcount = hwif->INL(SELADDR(0x1C));	printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n",		drive->name, count, rcount, rq->nr_sectors);#endif /* SIIMAGE_VIRTUAL_DMAPIO */	return __ide_dma_count(drive);}/* returns 1 if dma irq issued, 0 otherwise */static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	if (SATA_ERROR_REG) {		u32 ext_stat = hwif->INL(HWIFADDR(0x10));		u8 watchdog = 0;		if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {			u32 sata_error = hwif->INL(SATA_ERROR_REG);			hwif->OUTL(sata_error, SATA_ERROR_REG);			watchdog = (sata_error & 0x00680000) ? 1 : 0;#if 1			printk(KERN_WARNING "%s: sata_error = 0x%08x, "				"watchdog = %d, %s\n",				drive->name, sata_error, watchdog,				__FUNCTION__);#endif		} else {			watchdog = (ext_stat & 0x8000) ? 1 : 0;		}		ext_stat >>= 16;		if (!(ext_stat & 0x0404) && !watchdog)			return 0;	}	/* return 1 if INTR asserted */	if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04)		return 1;	/* return 1 if Device INTR asserted */	if ((hwif->INB(SELADDR(1)) & 8) == 8)		return 0;	//return 1;	return 0;}static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive){	int temp = __ide_dma_verbose(drive);#if 0	drive->using_dma = 0;#endif	return temp;}static int siimage_busproc (ide_drive_t * drive, int state){	ide_hwif_t *hwif	= HWIF(drive);	u32 stat_config		= 0;	if (hwif->mmio) {		stat_config = hwif->INL(SELADDR(0));	} else		pci_read_config_dword(hwif->pci_dev, SELREG(0), &stat_config);	switch (state) {		case BUSSTATE_ON:			hwif->drives[0].failures = 0;			hwif->drives[1].failures = 0;			break;		case BUSSTATE_OFF:			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;			break;		case BUSSTATE_TRISTATE:			hwif->drives[0].failures = hwif->drives[0].max_failures + 1;			hwif->drives[1].failures = hwif->drives[1].max_failures + 1;			break;		default:			return 0;	}	hwif->bus_state = state;	return 0;}static int siimage_reset_poll (ide_drive_t *drive){	if (SATA_STATUS_REG) {		ide_hwif_t *hwif	= HWIF(drive);		if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {

⌨️ 快捷键说明

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