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

📄 ide-probe.c

📁 Linux环境下java编程的经典书籍
💻 C
📖 第 1 页 / 共 2 页
字号:
		ide_request_region(hwif->io_ports[IDE_NSECTOR_OFFSET], 1, hwif->name);	if (hwif->io_ports[IDE_SECTOR_OFFSET])		ide_request_region(hwif->io_ports[IDE_SECTOR_OFFSET], 1, hwif->name);	if (hwif->io_ports[IDE_LCYL_OFFSET])		ide_request_region(hwif->io_ports[IDE_LCYL_OFFSET], 1, hwif->name);	if (hwif->io_ports[IDE_HCYL_OFFSET])		ide_request_region(hwif->io_ports[IDE_HCYL_OFFSET], 1, hwif->name);	if (hwif->io_ports[IDE_SELECT_OFFSET])		ide_request_region(hwif->io_ports[IDE_SELECT_OFFSET], 1, hwif->name);	if (hwif->io_ports[IDE_STATUS_OFFSET])		ide_request_region(hwif->io_ports[IDE_STATUS_OFFSET], 1, hwif->name);jump_straight8:	if (hwif->io_ports[IDE_CONTROL_OFFSET])		ide_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name);#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC)	if (hwif->io_ports[IDE_IRQ_OFFSET])		ide_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name);#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */}/* * This routine only knows how to look for drive units 0 and 1 * on an interface, so any setting of MAX_DRIVES > 2 won't work here. */static void probe_hwif (ide_hwif_t *hwif){	unsigned int unit;	unsigned long flags;	if (hwif->noprobe)		return;#ifdef CONFIG_BLK_DEV_IDE	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {		extern void probe_cmos_for_drives(ide_hwif_t *);		probe_cmos_for_drives (hwif);	}#endif	if ((hwif->chipset != ide_4drives || !hwif->mate->present) &&#if CONFIG_BLK_DEV_PDC4030	    (hwif->chipset != ide_pdc4030 || hwif->channel == 0) &&#endif /* CONFIG_BLK_DEV_PDC4030 */	    (hwif_check_regions(hwif))) {		int msgout = 0;		for (unit = 0; unit < MAX_DRIVES; ++unit) {			ide_drive_t *drive = &hwif->drives[unit];			if (drive->present) {				drive->present = 0;				printk("%s: ERROR, PORTS ALREADY IN USE\n", drive->name);				msgout = 1;			}		}		if (!msgout)			printk("%s: ports already in use, skipping probe\n", hwif->name);		return;		}	__save_flags(flags);	/* local CPU only */	__sti();		/* local CPU only; needed for jiffies and irq probing */	/*	 * Second drive should only exist if first drive was found,	 * but a lot of cdrom drives are configured as single slaves.	 */	for (unit = 0; unit < MAX_DRIVES; ++unit) {		ide_drive_t *drive = &hwif->drives[unit];		(void) probe_for_drive (drive);		if (drive->present && !hwif->present) {			hwif->present = 1;			if (hwif->chipset != ide_4drives || !hwif->mate->present) {				hwif_register(hwif);			}		}	}	if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {		unsigned long timeout = jiffies + WAIT_WORSTCASE;		byte stat;		printk("%s: reset\n", hwif->name);		OUT_BYTE(12, hwif->io_ports[IDE_CONTROL_OFFSET]);		udelay(10);		OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]);		do {			ide_delay_50ms();			stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);		} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));	}	__restore_flags(flags);	/* local CPU only */	for (unit = 0; unit < MAX_DRIVES; ++unit) {		ide_drive_t *drive = &hwif->drives[unit];		if (drive->present) {			ide_tuneproc_t *tuneproc = HWIF(drive)->tuneproc;			if (tuneproc != NULL && drive->autotune == 1)				tuneproc(drive, 255);	/* auto-tune PIO mode */		}	}}#if MAX_HWIFS > 1/* * save_match() is used to simplify logic in init_irq() below. * * A loophole here is that we may not know about a particular * hwif's irq until after that hwif is actually probed/initialized.. * This could be a problem for the case where an hwif is on a * dual interface that requires serialization (eg. cmd640) and another * hwif using one of the same irqs is initialized beforehand. * * This routine detects and reports such situations, but does not fix them. */static void save_match (ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match){	ide_hwif_t *m = *match;	if (m && m->hwgroup && m->hwgroup != new->hwgroup) {		if (!new->hwgroup)			return;		printk("%s: potential irq problem with %s and %s\n", hwif->name, new->name, m->name);	}	if (!m || m->irq != hwif->irq) /* don't undo a prior perfect match */		*match = new;}#endif /* MAX_HWIFS > 1 *//* * init request queue */static void ide_init_queue(ide_drive_t *drive){	request_queue_t *q = &drive->queue;	q->queuedata = HWGROUP(drive);	blk_init_queue(q, do_ide_request);}/* * This routine sets up the irq for an ide interface, and creates a new * hwgroup for the irq/hwif if none was previously assigned. * * Much of the code is for correctly detecting/handling irq sharing * and irq serialization situations.  This is somewhat complex because * it handles static as well as dynamic (PCMCIA) IDE interfaces. * * The SA_INTERRUPT in sa_flags means ide_intr() is always entered with * interrupts completely disabled.  This can be bad for interrupt latency, * but anything else has led to problems on some machines.  We re-enable * interrupts as much as we can safely do in most places. */static int init_irq (ide_hwif_t *hwif){	unsigned long flags;	unsigned int index;	ide_hwgroup_t *hwgroup, *new_hwgroup;	ide_hwif_t *match = NULL;		/* Allocate the buffer and potentially sleep first */		new_hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);		save_flags(flags);	/* all CPUs */	cli();			/* all CPUs */	hwif->hwgroup = NULL;#if MAX_HWIFS > 1	/*	 * Group up with any other hwifs that share our irq(s).	 */	for (index = 0; index < MAX_HWIFS; index++) {		ide_hwif_t *h = &ide_hwifs[index];		if (h->hwgroup) {  /* scan only initialized hwif's */			if (hwif->irq == h->irq) {				hwif->sharing_irq = h->sharing_irq = 1;				if (hwif->chipset != ide_pci || h->chipset != ide_pci) {					save_match(hwif, h, &match);				}			}			if (hwif->serialized) {				if (hwif->mate && hwif->mate->irq == h->irq)					save_match(hwif, h, &match);			}			if (h->serialized) {				if (h->mate && hwif->irq == h->mate->irq)					save_match(hwif, h, &match);			}		}	}#endif /* MAX_HWIFS > 1 */	/*	 * If we are still without a hwgroup, then form a new one	 */	if (match) {		hwgroup = match->hwgroup;		if(new_hwgroup)			kfree(new_hwgroup);	} else {		hwgroup = new_hwgroup;		if (!hwgroup) {			restore_flags(flags);	/* all CPUs */			return 1;		}		memset(hwgroup, 0, sizeof(ide_hwgroup_t));		hwgroup->hwif     = hwif->next = hwif;		hwgroup->rq       = NULL;		hwgroup->handler  = NULL;		hwgroup->drive    = NULL;		hwgroup->busy     = 0;		init_timer(&hwgroup->timer);		hwgroup->timer.function = &ide_timer_expiry;		hwgroup->timer.data = (unsigned long) hwgroup;	}	/*	 * Allocate the irq, if not already obtained for another hwif	 */	if (!match || match->irq != hwif->irq) {#ifdef CONFIG_IDEPCI_SHARE_IRQ		int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_SHIRQ : SA_INTERRUPT;#else /* !CONFIG_IDEPCI_SHARE_IRQ */		int sa = IDE_CHIPSET_IS_PCI(hwif->chipset) ? SA_INTERRUPT|SA_SHIRQ : SA_INTERRUPT;#endif /* CONFIG_IDEPCI_SHARE_IRQ */		if (ide_request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwgroup)) {			if (!match)				kfree(hwgroup);			restore_flags(flags);	/* all CPUs */			return 1;		}	}	/*	 * Everything is okay, so link us into the hwgroup	 */	hwif->hwgroup = hwgroup;	hwif->next = hwgroup->hwif->next;	hwgroup->hwif->next = hwif;	for (index = 0; index < MAX_DRIVES; ++index) {		ide_drive_t *drive = &hwif->drives[index];		if (!drive->present)			continue;		if (!hwgroup->drive)			hwgroup->drive = drive;		drive->next = hwgroup->drive->next;		hwgroup->drive->next = drive;		ide_init_queue(drive);	}	if (!hwgroup->hwif) {		hwgroup->hwif = HWIF(hwgroup->drive);#ifdef DEBUG		printk("%s : Adding missed hwif to hwgroup!!\n", hwif->name);#endif	}	restore_flags(flags);	/* all CPUs; safe now that hwif->hwgroup is set up */#if !defined(__mc68000__) && !defined(CONFIG_APUS) && !defined(__sparc__)	printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,		hwif->io_ports[IDE_DATA_OFFSET],		hwif->io_ports[IDE_DATA_OFFSET]+7,		hwif->io_ports[IDE_CONTROL_OFFSET], hwif->irq);#elif defined(__sparc__)	printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %s", hwif->name,		hwif->io_ports[IDE_DATA_OFFSET],		hwif->io_ports[IDE_DATA_OFFSET]+7,		hwif->io_ports[IDE_CONTROL_OFFSET], __irq_itoa(hwif->irq));#else	printk("%s at %p on irq 0x%08x", hwif->name,		hwif->io_ports[IDE_DATA_OFFSET], hwif->irq);#endif /* __mc68000__ && CONFIG_APUS */	if (match)		printk(" (%sed with %s)",			hwif->sharing_irq ? "shar" : "serializ", match->name);	printk("\n");	return 0;}/* * init_gendisk() (as opposed to ide_geninit) is called for each major device, * after probing for drives, to allocate partition tables and other data * structures needed for the routines in genhd.c.  ide_geninit() gets called * somewhat later, during the partition check. */static void init_gendisk (ide_hwif_t *hwif){	struct gendisk *gd;	unsigned int unit, units, minors;	int *bs, *max_sect, *max_ra;	extern devfs_handle_t ide_devfs_handle;	/* figure out maximum drive number on the interface */	for (units = MAX_DRIVES; units > 0; --units) {		if (hwif->drives[units-1].present)			break;	}	minors    = units * (1<<PARTN_BITS);	gd        = kmalloc (sizeof(struct gendisk), GFP_KERNEL);	gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);	gd->part  = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);	bs        = kmalloc (minors*sizeof(int), GFP_KERNEL);	max_sect  = kmalloc (minors*sizeof(int), GFP_KERNEL);	max_ra    = kmalloc (minors*sizeof(int), GFP_KERNEL);	memset(gd->part, 0, minors * sizeof(struct hd_struct));	/* cdroms and msdos f/s are examples of non-1024 blocksizes */	blksize_size[hwif->major] = bs;	max_sectors[hwif->major] = max_sect;	max_readahead[hwif->major] = max_ra;	for (unit = 0; unit < minors; ++unit) {		*bs++ = BLOCK_SIZE;#ifdef CONFIG_BLK_DEV_PDC4030		*max_sect++ = ((hwif->chipset == ide_pdc4030) ? 127 : 255);#else		/* IDE can do up to 128K per request. */		*max_sect++ = 255;#endif		*max_ra++ = vm_max_readahead;	}	for (unit = 0; unit < units; ++unit)		hwif->drives[unit].part = &gd->part[unit << PARTN_BITS];	gd->major	= hwif->major;		/* our major device number */	gd->major_name	= IDE_MAJOR_NAME;	/* treated special in genhd.c */	gd->minor_shift	= PARTN_BITS;		/* num bits for partitions */	gd->max_p	= 1<<PARTN_BITS;	/* 1 + max partitions / drive */	gd->nr_real	= units;		/* current num real drives */	gd->real_devices= hwif;			/* ptr to internal data */	gd->next	= NULL;			/* linked list of major devs */	gd->fops        = ide_fops;             /* file operations */	gd->de_arr	= kmalloc (sizeof *gd->de_arr * units, GFP_KERNEL);	gd->flags	= kmalloc (sizeof *gd->flags * units, GFP_KERNEL);	if (gd->de_arr)		memset (gd->de_arr, 0, sizeof *gd->de_arr * units);	if (gd->flags)		memset (gd->flags, 0, sizeof *gd->flags * units);	hwif->gd = gd;	add_gendisk(gd);	for (unit = 0; unit < units; ++unit) {		if (hwif->drives[unit].present) {			char name[64];			ide_add_generic_settings(hwif->drives + unit);			hwif->drives[unit].dn = ((hwif->channel ? 2 : 0) + unit);			sprintf (name, "host%d/bus%d/target%d/lun%d",				 (hwif->channel && hwif->mate) ? hwif->mate->index : hwif->index,				 hwif->channel, unit, hwif->drives[unit].lun);			hwif->drives[unit].de =				devfs_mk_dir (ide_devfs_handle, name, NULL);		}	}}static int hwif_init (ide_hwif_t *hwif){	if (!hwif->present)		return 0;	if (!hwif->irq) {		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET])))		{			printk("%s: DISABLED, NO IRQ\n", hwif->name);			return (hwif->present = 0);		}	}#ifdef CONFIG_BLK_DEV_HD	if (hwif->irq == HD_IRQ && hwif->io_ports[IDE_DATA_OFFSET] != HD_DATA) {		printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name);		return (hwif->present = 0);	}#endif /* CONFIG_BLK_DEV_HD */		hwif->present = 0; /* we set it back to 1 if all is ok below */	if (devfs_register_blkdev (hwif->major, hwif->name, ide_fops)) {		printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major);		return (hwif->present = 0);	}	if (init_irq(hwif)) {		int i = hwif->irq;		/*		 *	It failed to initialise. Find the default IRQ for		 *	this port and try that.		 */		if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {			printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, i);			(void) unregister_blkdev (hwif->major, hwif->name);			return (hwif->present = 0);		}		if (init_irq(hwif)) {			printk("%s: probed IRQ %d and default IRQ %d failed.\n",				hwif->name, i, hwif->irq);			(void) unregister_blkdev (hwif->major, hwif->name);			return (hwif->present = 0);		}		printk("%s: probed IRQ %d failed, using default.\n",			hwif->name, hwif->irq);	}	init_gendisk(hwif);	blk_dev[hwif->major].data = hwif;	blk_dev[hwif->major].queue = ide_get_queue;	read_ahead[hwif->major] = 8;	/* (4kB) */	hwif->present = 1;	/* success */#if (DEBUG_SPINLOCK > 0){	static int done = 0;	if (!done++)		printk("io_request_lock is %p\n", &io_request_lock);    /* FIXME */}#endif	return hwif->present;}int ideprobe_init (void);static ide_module_t ideprobe_module = {	IDE_PROBE_MODULE,	ideprobe_init,	NULL};int ideprobe_init (void){	unsigned int index;	int probe[MAX_HWIFS];		MOD_INC_USE_COUNT;	memset(probe, 0, MAX_HWIFS * sizeof(int));	for (index = 0; index < MAX_HWIFS; ++index)		probe[index] = !ide_hwifs[index].present;	/*	 * Probe for drives in the usual way.. CMOS/BIOS, then poke at ports	 */	for (index = 0; index < MAX_HWIFS; ++index)		if (probe[index])			probe_hwif(&ide_hwifs[index]);	for (index = 0; index < MAX_HWIFS; ++index)		if (probe[index])			hwif_init(&ide_hwifs[index]);	if (!ide_probe)		ide_probe = &ideprobe_module;	MOD_DEC_USE_COUNT;	return 0;}#ifdef MODULEint init_module (void){	unsigned int index;		for (index = 0; index < MAX_HWIFS; ++index)		ide_unregister(index);	ideprobe_init();	create_proc_ide_interfaces();	return 0;}void cleanup_module (void){	ide_probe = NULL;}MODULE_LICENSE("GPL");#endif /* MODULE */

⌨️ 快捷键说明

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