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

📄 ide.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
		printk("ide: failed opcode was %x\n", opcode);	}out:	local_irq_restore(flags);	return err;}EXPORT_SYMBOL(ide_dump_status);static int ide_open (struct inode * inode, struct file * filp){	return -ENXIO;}/* *	drives_lock protects the list of drives, drivers_lock the *	list of drivers.  Currently nobody takes both at once. */static spinlock_t drives_lock = SPIN_LOCK_UNLOCKED;static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;static LIST_HEAD(drivers);/* Iterator for the driver list. */static void *m_start(struct seq_file *m, loff_t *pos){	struct list_head *p;	loff_t l = *pos;	spin_lock(&drivers_lock);	list_for_each(p, &drivers)		if (!l--)			return list_entry(p, ide_driver_t, drivers);	return NULL;}static void *m_next(struct seq_file *m, void *v, loff_t *pos){	struct list_head *p = ((ide_driver_t *)v)->drivers.next;	(*pos)++;	return p==&drivers ? NULL : list_entry(p, ide_driver_t, drivers);}static void m_stop(struct seq_file *m, void *v){	spin_unlock(&drivers_lock);}static int show_driver(struct seq_file *m, void *v){	ide_driver_t *driver = v;	seq_printf(m, "%s version %s\n", driver->name, driver->version);	return 0;}struct seq_operations ide_drivers_op = {	.start	= m_start,	.next	= m_next,	.stop	= m_stop,	.show	= show_driver};#ifdef CONFIG_PROC_FSstruct proc_dir_entry *proc_ide_root;ide_proc_entry_t generic_subdriver_entries[] = {	{ "capacity",	S_IFREG|S_IRUGO,	proc_ide_read_capacity,	NULL },	{ NULL, 0, NULL, NULL }};#endifstatic struct resource* hwif_request_region(ide_hwif_t *hwif,					    unsigned long addr, int num){	struct resource *res = request_region(addr, num, hwif->name);	if (!res)		printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",				hwif->name, addr, addr+num-1);	return res;}/** *	ide_hwif_request_regions - request resources for IDE *	@hwif: interface to use * *	Requests all the needed resources for an interface. *	Right now core IDE code does this work which is deeply wrong. *	MMIO leaves it to the controller driver, *	PIO will migrate this way over time. */int ide_hwif_request_regions(ide_hwif_t *hwif){	unsigned long addr;	unsigned int i;	if (hwif->mmio == 2)		return 0;	BUG_ON(hwif->mmio == 1);	addr = hwif->io_ports[IDE_CONTROL_OFFSET];	if (addr && !hwif_request_region(hwif, addr, 1))		goto control_region_busy;	hwif->straight8 = 0;	addr = hwif->io_ports[IDE_DATA_OFFSET];	if ((addr | 7) == hwif->io_ports[IDE_STATUS_OFFSET]) {		if (!hwif_request_region(hwif, addr, 8))			goto data_region_busy;		hwif->straight8 = 1;		return 0;	}	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {		addr = hwif->io_ports[i];		if (!hwif_request_region(hwif, addr, 1)) {			while (--i)				release_region(addr, 1);			goto data_region_busy;		}	}	return 0;data_region_busy:	addr = hwif->io_ports[IDE_CONTROL_OFFSET];	if (addr)		release_region(addr, 1);control_region_busy:	/* If any errors are return, we drop the hwif interface. */	return -EBUSY;}/** *	ide_hwif_release_regions - free IDE resources * *	Note that we only release the standard ports, *	and do not even try to handle any extra ports *	allocated for weird IDE interface chipsets. * *	Note also that we don't yet handle mmio resources here. More *	importantly our caller should be doing this so we need to  *	restructure this as a helper function for drivers. */void ide_hwif_release_regions(ide_hwif_t *hwif){	u32 i = 0;	if (hwif->mmio == 2)		return;	if (hwif->io_ports[IDE_CONTROL_OFFSET])		release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);	if (hwif->straight8) {		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])			release_region(hwif->io_ports[i], 1);}/** *	ide_hwif_restore	-	restore hwif to template *	@hwif: hwif to update *	@tmp_hwif: template * *	Restore hwif to a previous state by copying most settngs *	from the template. */static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif){	hwif->hwgroup			= tmp_hwif->hwgroup;	hwif->gendev.parent		= tmp_hwif->gendev.parent;	hwif->proc			= tmp_hwif->proc;	hwif->major			= tmp_hwif->major;	hwif->straight8			= tmp_hwif->straight8;	hwif->bus_state			= tmp_hwif->bus_state;	hwif->atapi_dma			= tmp_hwif->atapi_dma;	hwif->ultra_mask		= tmp_hwif->ultra_mask;	hwif->mwdma_mask		= tmp_hwif->mwdma_mask;	hwif->swdma_mask		= tmp_hwif->swdma_mask;	hwif->chipset			= tmp_hwif->chipset;	hwif->hold			= tmp_hwif->hold;#ifdef CONFIG_BLK_DEV_IDEPCI	hwif->pci_dev			= tmp_hwif->pci_dev;	hwif->cds			= tmp_hwif->cds;#endif	hwif->identify			= tmp_hwif->identify;	hwif->tuneproc			= tmp_hwif->tuneproc;	hwif->speedproc			= tmp_hwif->speedproc;	hwif->selectproc		= tmp_hwif->selectproc;	hwif->reset_poll		= tmp_hwif->reset_poll;	hwif->pre_reset			= tmp_hwif->pre_reset;	hwif->resetproc			= tmp_hwif->resetproc;	hwif->intrproc			= tmp_hwif->intrproc;	hwif->maskproc			= tmp_hwif->maskproc;	hwif->quirkproc			= tmp_hwif->quirkproc;	hwif->busproc			= tmp_hwif->busproc;	hwif->ata_input_data		= tmp_hwif->ata_input_data;	hwif->ata_output_data		= tmp_hwif->ata_output_data;	hwif->atapi_input_bytes		= tmp_hwif->atapi_input_bytes;	hwif->atapi_output_bytes	= tmp_hwif->atapi_output_bytes;	hwif->ide_dma_read		= tmp_hwif->ide_dma_read;	hwif->ide_dma_write		= tmp_hwif->ide_dma_write;	hwif->ide_dma_begin		= tmp_hwif->ide_dma_begin;	hwif->ide_dma_end		= tmp_hwif->ide_dma_end;	hwif->ide_dma_check		= tmp_hwif->ide_dma_check;	hwif->ide_dma_on		= tmp_hwif->ide_dma_on;	hwif->ide_dma_off_quietly	= tmp_hwif->ide_dma_off_quietly;	hwif->ide_dma_test_irq		= tmp_hwif->ide_dma_test_irq;	hwif->ide_dma_host_on		= tmp_hwif->ide_dma_host_on;	hwif->ide_dma_host_off		= tmp_hwif->ide_dma_host_off;	hwif->ide_dma_verbose		= tmp_hwif->ide_dma_verbose;	hwif->ide_dma_lostirq		= tmp_hwif->ide_dma_lostirq;	hwif->ide_dma_timeout		= tmp_hwif->ide_dma_timeout;	hwif->OUTB			= tmp_hwif->OUTB;	hwif->OUTBSYNC			= tmp_hwif->OUTBSYNC;	hwif->OUTW			= tmp_hwif->OUTW;	hwif->OUTL			= tmp_hwif->OUTL;	hwif->OUTSW			= tmp_hwif->OUTSW;	hwif->OUTSL			= tmp_hwif->OUTSL;	hwif->INB			= tmp_hwif->INB;	hwif->INW			= tmp_hwif->INW;	hwif->INL			= tmp_hwif->INL;	hwif->INSW			= tmp_hwif->INSW;	hwif->INSL			= tmp_hwif->INSL;	hwif->mmio			= tmp_hwif->mmio;	hwif->rqsize			= tmp_hwif->rqsize;	hwif->no_lba48			= tmp_hwif->no_lba48;#ifndef CONFIG_BLK_DEV_IDECS	hwif->irq			= tmp_hwif->irq;#endif	hwif->dma_base			= tmp_hwif->dma_base;	hwif->dma_master		= tmp_hwif->dma_master;	hwif->dma_command		= tmp_hwif->dma_command;	hwif->dma_vendor1		= tmp_hwif->dma_vendor1;	hwif->dma_status		= tmp_hwif->dma_status;	hwif->dma_vendor3		= tmp_hwif->dma_vendor3;	hwif->dma_prdtable		= tmp_hwif->dma_prdtable;	hwif->dma_extra			= tmp_hwif->dma_extra;	hwif->config_data		= tmp_hwif->config_data;	hwif->select_data		= tmp_hwif->select_data;	hwif->autodma			= tmp_hwif->autodma;	hwif->udma_four			= tmp_hwif->udma_four;	hwif->no_dsc			= tmp_hwif->no_dsc;	hwif->hwif_data			= tmp_hwif->hwif_data;}/** *	ide_unregister		-	free an ide interface *	@index: index of interface (will change soon to a pointer) * *	Perform the final unregister of an IDE interface. At the moment *	we don't refcount interfaces so this will also get split up. * *	Locking: *	The caller must not hold the IDE locks *	The drive present/vanishing is not yet properly locked *	Take care with the callbacks. These have been split to avoid *	deadlocking the IDE layer. The shutdown callback is called *	before we take the lock and free resources. It is up to the *	caller to be sure there is no pending I/O here, and that *	the interfce will not be reopened (present/vanishing locking *	isnt yet done btw). After we commit to the final kill we *	call the cleanup callback with the ide locks held. * *	Unregister restores the hwif structures to the default state. *	This is raving bonkers. */void ide_unregister(unsigned int index){	ide_drive_t *drive;	ide_hwif_t *hwif, *g;	static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */	ide_hwgroup_t *hwgroup;	int irq_count = 0, unit, i;	BUG_ON(index >= MAX_HWIFS);	BUG_ON(in_interrupt());	BUG_ON(irqs_disabled());	down(&ide_cfg_sem);	spin_lock_irq(&ide_lock);	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->usage || DRIVER(drive)->busy)			goto abort;		drive->dead = 1;	}	hwif->present = 0;	spin_unlock_irq(&ide_lock);	for (unit = 0; unit < MAX_DRIVES; ++unit) {		drive = &hwif->drives[unit];		if (!drive->present)			continue;		DRIVER(drive)->cleanup(drive);	}#ifdef CONFIG_PROC_FS	destroy_proc_ide_drives(hwif);#endif	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);	spin_lock_irq(&ide_lock);	/*	 * Note that we only release the standard ports,	 * and do not even try to handle any extra ports	 * allocated for weird IDE interface chipsets.	 */	ide_hwif_release_regions(hwif);	/*	 * Remove us from the hwgroup, and free	 * the hwgroup if we were the only member	 */	for (i = 0; i < MAX_DRIVES; ++i) {		drive = &hwif->drives[i];		if (drive->devfs_name[0] != '\0') {			devfs_remove(drive->devfs_name);			drive->devfs_name[0] = '\0';		}		if (!drive->present)			continue;		if (drive == drive->next) {			/* special case: last drive from hwgroup. */			BUG_ON(hwgroup->drive != drive);			hwgroup->drive = NULL;		} else {			ide_drive_t *walk;			walk = hwgroup->drive;			while (walk->next != drive)				walk = walk->next;			walk->next = drive->next;			if (hwgroup->drive == drive) {				hwgroup->drive = drive->next;				hwgroup->hwif = HWIF(hwgroup->drive);			}		}		BUG_ON(hwgroup->drive == drive);		if (drive->id != NULL) {			kfree(drive->id);			drive->id = NULL;		}		drive->present = 0;		/* Messed up locking ... */		spin_unlock_irq(&ide_lock);		blk_cleanup_queue(drive->queue);		device_unregister(&drive->gendev);		down(&drive->gendev_rel_sem);		spin_lock_irq(&ide_lock);		drive->queue = NULL;	}	if (hwif->next == hwif) {		BUG_ON(hwgroup->hwif != hwif);		kfree(hwgroup);	} else {		/* There is another interface in hwgroup.		 * Unlink us, and set hwgroup->drive and ->hwif to		 * something sane.		 */		g = hwgroup->hwif;		while (g->next != hwif)			g = g->next;		g->next = hwif->next;		if (hwgroup->hwif == hwif) {			/* Chose a random hwif for hwgroup->hwif.			 * It's guaranteed that there are no drives			 * left in the hwgroup.			 */			BUG_ON(hwgroup->drive != NULL);			hwgroup->hwif = g;		}		BUG_ON(hwgroup->hwif == hwif);	}	/* More messed up locking ... */	spin_unlock_irq(&ide_lock);	device_unregister(&hwif->gendev);	down(&hwif->gendev_rel_sem);	/*	 * Remove us from the kernel's knowledge	 */	blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS);	for (i = 0; i < MAX_DRIVES; i++) {		struct gendisk *disk = hwif->drives[i].disk;		hwif->drives[i].disk = NULL;		put_disk(disk);	}	unregister_blkdev(hwif->major, hwif->name);	spin_lock_irq(&ide_lock);	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;	}	/* copy original settings */	tmp_hwif = *hwif;	/* restore hwif data to pristine status */	init_hwif_data(hwif, index);	init_hwif_default(hwif, index);	ide_hwif_restore(hwif, &tmp_hwif);abort:	spin_unlock_irq(&ide_lock);	up(&ide_cfg_sem);}EXPORT_SYMBOL(ide_unregister);/** *	ide_setup_ports 	-	set up IDE interface ports *	@hw: register descriptions *	@base: base register *	@offsets: table of register offsets *	@ctrl: control register *	@ack_irq: IRQ ack *	@irq: interrupt lie * *	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. This is basically a helper * */ void ide_setup_ports (	hw_regs_t *hw,			unsigned long base, int *offsets,			unsigned long ctrl, unsigned long intr,			ide_ack_intr_t *ack_intr,/*

⌨️ 快捷键说明

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