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

📄 ide.c

📁 ep9315平台下硬盘驱动的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * If we are revalidating a disk because of a media change, then we * enter with usage == 0.  If we are using an ioctl, we automatically have * usage == 1 (we need an open channel to use an ioctl :-), so this * is our limit. */int ide_revalidate_disk (kdev_t i_rdev){	ide_drive_t *drive;	ide_hwgroup_t *hwgroup;	unsigned int p, major, minor;	unsigned long flags;	if ((drive = get_info_ptr(i_rdev)) == NULL)		return -ENODEV;	major = MAJOR(i_rdev);	minor = drive->select.b.unit << PARTN_BITS;	hwgroup = HWGROUP(drive);	spin_lock_irqsave(&io_request_lock, flags);	if (drive->busy || (drive->usage > 1)) {		spin_unlock_irqrestore(&io_request_lock, flags);		return -EBUSY;	};	drive->busy = 1;	MOD_INC_USE_COUNT;	spin_unlock_irqrestore(&io_request_lock, flags);	for (p = 0; p < (1<<PARTN_BITS); ++p) {		if (drive->part[p].nr_sects > 0) {			kdev_t devp = MKDEV(major, minor+p);			invalidate_device(devp, 1);		}		drive->part[p].start_sect = 0;		drive->part[p].nr_sects   = 0;	};	if (DRIVER(drive)->revalidate)		DRIVER(drive)->revalidate(drive);	drive->busy = 0;	wake_up(&drive->wqueue);	MOD_DEC_USE_COUNT;	return 0;}EXPORT_SYMBOL(ide_revalidate_disk);static void revalidate_drives (int revaldiate){	ide_hwif_t *hwif;	ide_drive_t *drive;	int index, unit;	for (index = 0; index < MAX_HWIFS; ++index) {		hwif = &ide_hwifs[index];		for (unit = 0; unit < MAX_DRIVES; ++unit) {			drive = &ide_hwifs[index].drives[unit];			if (drive->revalidate) {				drive->revalidate = 0;				if ((!initializing) && (revaldiate))					(void) ide_revalidate_disk(MKDEV(hwif->major, unit<<PARTN_BITS));			}		}	}}void ide_probe_module (int revaldiate){	if (!ide_probe) {#if  defined(CONFIG_BLK_DEV_IDE_MODULE)		(void) request_module("ide-probe-mod");#endif	} else {		(void) ide_probe->init();	}	revalidate_drives(revaldiate);}EXPORT_SYMBOL(ide_probe_module);void ide_driver_module (int revaldiate){	int index;	ide_module_t *module = ide_modules;	for (index = 0; index < MAX_HWIFS; ++index)		if (ide_hwifs[index].present)			goto search;	ide_probe_module(revaldiate);search:	while (module) {		(void) module->init();		module = module->next;	}	revalidate_drives(revaldiate);}EXPORT_SYMBOL(ide_driver_module);static int ide_open (struct inode * inode, struct file * filp){	ide_drive_t *drive;	if ((drive = get_info_ptr(inode->i_rdev)) == NULL)		return -ENXIO;	if (drive->driver == &idedefault_driver)		ide_driver_module(1);	if (drive->driver == &idedefault_driver) {		if (drive->media == ide_disk)			(void) request_module("ide-disk");		if (drive->scsi)			(void) request_module("ide-scsi");		if (drive->media == ide_cdrom)			(void) request_module("ide-cd");		if (drive->media == ide_tape)			(void) request_module("ide-tape");		if (drive->media == ide_floppy)			(void) request_module("ide-floppy");	}		/* The locking here isnt enough, but this is hard to fix	   in the 2.4 cases */	while (drive->busy)		sleep_on(&drive->wqueue);	drive->usage++;	if (!drive->dead)		return DRIVER(drive)->open(inode, filp, drive);	printk(KERN_WARNING "%s: driver not present\n", drive->name);	drive->usage--;	return -ENXIO;}/* * Releasing a block device means we sync() it, so that it can safely * be forgotten about... */static int ide_release (struct inode * inode, struct file * file){	ide_drive_t *drive;	if ((drive = get_info_ptr(inode->i_rdev)) != NULL) {		drive->usage--;		DRIVER(drive)->release(inode, file, drive);	}	return 0;}#ifdef CONFIG_PROC_FSide_proc_entry_t generic_subdriver_entries[] = {	{ "capacity",	S_IFREG|S_IRUGO,	proc_ide_read_capacity,	NULL },	{ NULL, 0, NULL, NULL }};#endif#define hwif_release_region(addr, num) \	((hwif->mmio) ? release_mem_region((addr),(num)) : release_region((addr),(num)))/* * Note that we only release the standard ports, * and do not even try to handle any extra ports * allocated for weird IDE interface chipsets. */void hwif_unregister (ide_hwif_t *hwif){	u32 i = 0;	if (hwif->mmio == 2)		return;	if (hwif->io_ports[IDE_CONTROL_OFFSET])		hwif_release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)	if (hwif->io_ports[IDE_IRQ_OFFSET])		hwif_release_region(hwif->io_ports[IDE_IRQ_OFFSET], 1);#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */	if (hwif->straight8) {		hwif_release_region(hwif->io_ports[IDE_DATA_OFFSET], 8);		return;	}	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {		if (hwif->io_ports[i]) {			hwif_release_region(hwif->io_ports[i], 1);		}	}}EXPORT_SYMBOL(hwif_unregister);extern void init_hwif_data(unsigned int index);int ide_unregister (unsigned int index){	struct gendisk *gd;	ide_drive_t *drive, *d;	ide_hwif_t *hwif, *g;	ide_hwgroup_t *hwgroup;	int irq_count = 0, unit, i;	unsigned long flags;	unsigned int p, minor;	ide_hwif_t old_hwif;	if (index >= MAX_HWIFS)		BUG();			spin_lock_irqsave(&io_request_lock, flags);	hwif = &ide_hwifs[index];	if (!hwif->present)		goto abort;	for (unit = 0; unit < MAX_DRIVES; ++unit) {		drive = &hwif->drives[unit];		if (!drive->present)			continue;		if (drive->busy || drive->usage)			goto abort;		if (DRIVER(drive)->shutdown(drive))			goto abort;	}	hwif->present = 0;		/*	 * All clear?  Then blow away the buffer cache	 */	spin_unlock_irqrestore(&io_request_lock, flags);	for (unit = 0; unit < MAX_DRIVES; ++unit) {		drive = &hwif->drives[unit];		if (!drive->present)			continue;		DRIVER(drive)->cleanup(drive);		minor = drive->select.b.unit << PARTN_BITS;		for (p = 0; p < (1<<PARTN_BITS); ++p) {			if (drive->part[p].nr_sects > 0) {				kdev_t devp = MKDEV(hwif->major, minor+p);				invalidate_device(devp, 0);			}		}#ifdef CONFIG_PROC_FS		destroy_proc_ide_drives(hwif);#endif	}	spin_lock_irqsave(&io_request_lock, flags);	hwgroup = hwif->hwgroup;	/*	 * free the irq if we were the only hwif using it	 */	g = hwgroup->hwif;	do {		if (g->irq == hwif->irq)			++irq_count;		g = g->next;	} while (g != hwgroup->hwif);	if (irq_count == 1)		free_irq(hwif->irq, hwgroup);	/*	 * Note that we only release the standard ports,	 * and do not even try to handle any extra ports	 * allocated for weird IDE interface chipsets.	 */	hwif_unregister(hwif);	/*	 * Remove us from the hwgroup, and free	 * the hwgroup if we were the only member	 */	d = hwgroup->drive;	for (i = 0; i < MAX_DRIVES; ++i) {		drive = &hwif->drives[i];		if (drive->de) {			devfs_unregister(drive->de);			drive->de = NULL;		}		if (!drive->present)			continue;		while (hwgroup->drive->next != drive)			hwgroup->drive = hwgroup->drive->next;		hwgroup->drive->next = drive->next;		if (hwgroup->drive == drive)			hwgroup->drive = NULL;		if (drive->id != NULL) {			kfree(drive->id);			drive->id = NULL;		}		drive->present = 0;		blk_cleanup_queue(&drive->queue);	}	if (d->present)		hwgroup->drive = d;	while (hwgroup->hwif->next != hwif)		hwgroup->hwif = hwgroup->hwif->next;	hwgroup->hwif->next = hwif->next;	if (hwgroup->hwif == hwif)		kfree(hwgroup);	else		hwgroup->hwif = HWIF(hwgroup->drive);#if !defined(CONFIG_DMA_NONPCI)	if (hwif->dma_base) {		(void) ide_release_dma(hwif);		hwif->dma_base = 0;		hwif->dma_master = 0;		hwif->dma_command = 0;		hwif->dma_vendor1 = 0;		hwif->dma_status = 0;		hwif->dma_vendor3 = 0;		hwif->dma_prdtable = 0;	}#endif /* !(CONFIG_DMA_NONPCI) */	/*	 * Remove us from the kernel's knowledge	 */	unregister_blkdev(hwif->major, hwif->name);	kfree(blksize_size[hwif->major]);	kfree(max_sectors[hwif->major]);	kfree(max_readahead[hwif->major]);	blk_dev[hwif->major].data = NULL;	blk_dev[hwif->major].queue = NULL;	blksize_size[hwif->major] = NULL;	gd = hwif->gd;	if (gd) {		del_gendisk(gd);		kfree(gd->sizes);		kfree(gd->part);		if (gd->de_arr)			kfree(gd->de_arr);		if (gd->flags)			kfree(gd->flags);		kfree(gd);		hwif->gd = NULL;	}	old_hwif			= *hwif;	init_hwif_data(index);	/* restore hwif data to pristine status */	hwif->hwgroup			= old_hwif.hwgroup;	hwif->proc			= old_hwif.proc;	hwif->major			= old_hwif.major;//	hwif->index			= old_hwif.index;//	hwif->channel			= old_hwif.channel;	hwif->straight8			= old_hwif.straight8;	hwif->bus_state			= old_hwif.bus_state;	hwif->atapi_dma			= old_hwif.atapi_dma;	hwif->ultra_mask		= old_hwif.ultra_mask;	hwif->mwdma_mask		= old_hwif.mwdma_mask;	hwif->swdma_mask		= old_hwif.swdma_mask;	hwif->chipset			= old_hwif.chipset;#ifdef CONFIG_BLK_DEV_IDEPCI	hwif->pci_dev			= old_hwif.pci_dev;	hwif->cds			= old_hwif.cds;#endif /* CONFIG_BLK_DEV_IDEPCI */#if 0	hwif->hwifops			= old_hwif.hwifops;#else	hwif->identify			= old_hwif.identify;	hwif->tuneproc			= old_hwif.tuneproc;	hwif->speedproc			= old_hwif.speedproc;	hwif->selectproc		= old_hwif.selectproc;	hwif->reset_poll		= old_hwif.reset_poll;	hwif->pre_reset			= old_hwif.pre_reset;	hwif->resetproc			= old_hwif.resetproc;	hwif->intrproc			= old_hwif.intrproc;	hwif->maskproc			= old_hwif.maskproc;	hwif->quirkproc			= old_hwif.quirkproc;	hwif->busproc			= old_hwif.busproc;#endif#if 0	hwif->pioops			= old_hwif.pioops;#else	hwif->ata_input_data		= old_hwif.ata_input_data;	hwif->ata_output_data		= old_hwif.ata_output_data;	hwif->atapi_input_bytes		= old_hwif.atapi_input_bytes;	hwif->atapi_output_bytes	= old_hwif.atapi_output_bytes;#endif#if 0	hwif->dmaops			= old_hwif.dmaops;#else	hwif->ide_dma_read		= old_hwif.ide_dma_read;	hwif->ide_dma_write		= old_hwif.ide_dma_write;	hwif->ide_dma_begin		= old_hwif.ide_dma_begin;	hwif->ide_dma_end		= old_hwif.ide_dma_end;	hwif->ide_dma_check		= old_hwif.ide_dma_check;	hwif->ide_dma_on		= old_hwif.ide_dma_on;	hwif->ide_dma_off		= old_hwif.ide_dma_off;	hwif->ide_dma_off_quietly	= old_hwif.ide_dma_off_quietly;	hwif->ide_dma_test_irq		= old_hwif.ide_dma_test_irq;	hwif->ide_dma_host_on		= old_hwif.ide_dma_host_on;	hwif->ide_dma_host_off		= old_hwif.ide_dma_host_off;	hwif->ide_dma_bad_drive		= old_hwif.ide_dma_bad_drive;	hwif->ide_dma_good_drive	= old_hwif.ide_dma_good_drive;	hwif->ide_dma_count		= old_hwif.ide_dma_count;	hwif->ide_dma_verbose		= old_hwif.ide_dma_verbose;	hwif->ide_dma_retune		= old_hwif.ide_dma_retune;	hwif->ide_dma_lostirq		= old_hwif.ide_dma_lostirq;	hwif->ide_dma_timeout		= old_hwif.ide_dma_timeout;#endif#if 0	hwif->iops			= old_hwif.iops;#else	hwif->OUTB		= old_hwif.OUTB;	hwif->OUTBSYNC		= old_hwif.OUTBSYNC;	hwif->OUTW		= old_hwif.OUTW;	hwif->OUTL		= old_hwif.OUTL;	hwif->OUTSW		= old_hwif.OUTSW;	hwif->OUTSL		= old_hwif.OUTSL;	hwif->INB		= old_hwif.INB;	hwif->INW		= old_hwif.INW;	hwif->INL		= old_hwif.INL;	hwif->INSW		= old_hwif.INSW;	hwif->INSL		= old_hwif.INSL;#endif	hwif->mmio			= old_hwif.mmio;	hwif->rqsize			= old_hwif.rqsize;	hwif->addressing		= old_hwif.addressing;#ifndef CONFIG_BLK_DEV_IDECS	hwif->irq			= old_hwif.irq;#endif /* CONFIG_BLK_DEV_IDECS */	hwif->initializing		= old_hwif.initializing;	hwif->dma_base			= old_hwif.dma_base;	hwif->dma_master		= old_hwif.dma_master;	hwif->dma_command		= old_hwif.dma_command;	hwif->dma_vendor1		= old_hwif.dma_vendor1;	hwif->dma_status		= old_hwif.dma_status;	hwif->dma_vendor3		= old_hwif.dma_vendor3;	hwif->dma_prdtable		= old_hwif.dma_prdtable;	hwif->dma_extra			= old_hwif.dma_extra;	hwif->config_data		= old_hwif.config_data;	hwif->select_data		= old_hwif.select_data;	hwif->autodma			= old_hwif.autodma;	hwif->udma_four			= old_hwif.udma_four;	hwif->no_dsc			= old_hwif.no_dsc;	hwif->hwif_data			= old_hwif.hwif_data;	spin_unlock_irqrestore(&io_request_lock, flags);	return 0;abort:	spin_unlock_irqrestore(&io_request_lock, flags);	return 1;	}EXPORT_SYMBOL(ide_unregister);/* * Setup hw_regs_t structure described by parameters.  You * may set up the hw structure yourself OR use this routine to * do it for you.

⌨️ 快捷键说明

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