ide.c

来自「2410的硬盘块设备源码」· C语言 代码 · 共 2,013 行 · 第 1/4 页

C
2,013
字号
 */static int __init ide_setup(char *s){	int i, vals[3];	ide_hwif_t *hwif;	ide_drive_t *drive;	unsigned int hw, unit;	const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);	const char max_hwif  = '0' + (MAX_HWIFS - 1);		if (strncmp(s,"hd",2) == 0 && s[2] == '=')	/* hd= is for hd.c   */		return 0;				/* driver and not us */	if (strncmp(s,"ide",3) && strncmp(s,"idebus",6) && strncmp(s,"hd",2))		return 0;	printk(KERN_INFO "ide_setup: %s", s);	init_ide_data ();#ifdef CONFIG_BLK_DEV_IDEDOUBLER	if (!strcmp(s, "ide=doubler")) {		extern int ide_doubler;		printk(" : Enabled support for IDE doublers\n");		ide_doubler = 1;		return 1;	}#endif /* CONFIG_BLK_DEV_IDEDOUBLER */	if (!strcmp(s, "ide=nodma")) {		printk(" : Prevented DMA\n");		noautodma = 1;		return 1;	}#ifdef CONFIG_BLK_DEV_IDEPCI	if (!strcmp(s, "ide=reverse")) {		ide_scan_direction = 1;		printk(" : Enabled support for IDE inverse scan order.\n");		return 1;	}#endif /* CONFIG_BLK_DEV_IDEPCI */	/*	 * Look for drive options:  "hdx="	 */	if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {		const char *hd_words[] = {			"none", "noprobe", "nowerr", "cdrom", "serialize",			"autotune", "noautotune", "minus8", "swapdata", "bswap",			"minus11", "remap", "remap63", "scsi", NULL };		unit = s[2] - 'a';		hw   = unit / MAX_DRIVES;		unit = unit % MAX_DRIVES;		hwif = &ide_hwifs[hw];		drive = &hwif->drives[unit];		if (strncmp(s + 4, "ide-", 4) == 0) {			strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req));			goto done;		}		switch (match_parm(&s[3], hd_words, vals, 3)) {			case -1: /* "none" */			case -2: /* "noprobe" */				drive->noprobe = 1;				goto done;			case -3: /* "nowerr" */				drive->bad_wstat = BAD_R_STAT;				hwif->noprobe = 0;				goto done;			case -4: /* "cdrom" */				drive->present = 1;				drive->media = ide_cdrom;				/* an ATAPI device ignores DRDY */				drive->ready_stat = 0;				hwif->noprobe = 0;				goto done;			case -5: /* "serialize" */				printk(" -- USE \"ide%d=serialize\" INSTEAD", hw);				goto do_serialize;			case -6: /* "autotune" */				drive->autotune = IDE_TUNE_AUTO;				goto obsolete_option;			case -7: /* "noautotune" */				drive->autotune = IDE_TUNE_NOAUTO;				goto obsolete_option;			case -9: /* "swapdata" */			case -10: /* "bswap" */				drive->bswap = 1;				goto done;			case -12: /* "remap" */				drive->remap_0_to_1 = 1;				goto done;			case -13: /* "remap63" */				drive->sect0 = 63;				goto done;			case -14: /* "scsi" */				drive->scsi = 1;				goto done;			case 3: /* cyl,head,sect */				drive->media	= ide_disk;				drive->ready_stat = READY_STAT;				drive->cyl	= drive->bios_cyl  = vals[0];				drive->head	= drive->bios_head = vals[1];				drive->sect	= drive->bios_sect = vals[2];				drive->present	= 1;				drive->forced_geom = 1;				hwif->noprobe = 0;				goto done;			default:				goto bad_option;		}	}	if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e')		goto bad_option;	/*	 * Look for bus speed option:  "idebus="	 */	if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') {		if (match_parm(&s[6], NULL, vals, 1) != 1)			goto bad_option;		if (vals[0] >= 20 && vals[0] <= 66) {			idebus_parameter = vals[0];		} else			printk(" -- BAD BUS SPEED! Expected value from 20 to 66");		goto done;	}	/*	 * Look for interface options:  "idex="	 */	if (s[3] >= '0' && s[3] <= max_hwif) {		/*		 * Be VERY CAREFUL changing this: note hardcoded indexes below		 * (-8, -9, -10) are reserved to ease the hardcoding.		 */		static const char *ide_words[] = {			"noprobe", "serialize", "autotune", "noautotune", 			"reset", "dma", "ata66", "minus8", "minus9",			"minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",			"dtc2278", "umc8672", "ali14xx", NULL };		hw = s[3] - '0';		hwif = &ide_hwifs[hw];		i = match_parm(&s[4], ide_words, vals, 3);		/*		 * Cryptic check to ensure chipset not already set for hwif.		 * Note: we can't depend on hwif->chipset here.		 */		if ((i >= -18 && i <= -11) || (i > 0 && i <= 3)) {			/* chipset already specified */			if (is_chipset_set[hw])				goto bad_option;			if (i > -18 && i <= -11) {				/* these drivers are for "ide0=" only */				if (hw != 0)					goto bad_hwif;				/* chipset already specified for 2nd port */				if (is_chipset_set[hw+1])					goto bad_option;			}			is_chipset_set[hw] = 1;			printk("\n");		}		switch (i) {#ifdef CONFIG_BLK_DEV_ALI14XX			case -17: /* "ali14xx" */				probe_ali14xx = 1;				goto done;#endif#ifdef CONFIG_BLK_DEV_UMC8672			case -16: /* "umc8672" */				probe_umc8672 = 1;				goto done;#endif#ifdef CONFIG_BLK_DEV_DTC2278			case -15: /* "dtc2278" */				probe_dtc2278 = 1;				goto done;#endif#ifdef CONFIG_BLK_DEV_CMD640			case -14: /* "cmd640_vlb" */			{				extern int cmd640_vlb; /* flag for cmd640.c */				cmd640_vlb = 1;				goto done;			}#endif#ifdef CONFIG_BLK_DEV_HT6560B			case -13: /* "ht6560b" */				probe_ht6560b = 1;				goto done;#endif#ifdef CONFIG_BLK_DEV_QD65XX			case -12: /* "qd65xx" */				probe_qd65xx = 1;				goto done;#endif#ifdef CONFIG_BLK_DEV_4DRIVES			case -11: /* "four" drives on one set of ports */			{				ide_hwif_t *mate = &ide_hwifs[hw^1];				mate->drives[0].select.all ^= 0x20;				mate->drives[1].select.all ^= 0x20;				hwif->chipset = mate->chipset = ide_4drives;				mate->irq = hwif->irq;				memcpy(mate->io_ports, hwif->io_ports, sizeof(hwif->io_ports));				goto do_serialize;			}#endif /* CONFIG_BLK_DEV_4DRIVES */			case -10: /* minus10 */			case -9: /* minus9 */			case -8: /* minus8 */				goto bad_option;			case -7: /* ata66 */#ifdef CONFIG_BLK_DEV_IDEPCI				hwif->udma_four = 1;				goto obsolete_option;#else				goto bad_hwif;#endif			case -6: /* dma */				hwif->autodma = 1;				goto obsolete_option;			case -5: /* "reset" */				hwif->reset = 1;				goto obsolete_option;			case -4: /* "noautotune" */				hwif->drives[0].autotune = IDE_TUNE_NOAUTO;				hwif->drives[1].autotune = IDE_TUNE_NOAUTO;				goto obsolete_option;			case -3: /* "autotune" */				hwif->drives[0].autotune = IDE_TUNE_AUTO;				hwif->drives[1].autotune = IDE_TUNE_AUTO;				goto obsolete_option;			case -2: /* "serialize" */			do_serialize:				hwif->mate = &ide_hwifs[hw^1];				hwif->mate->mate = hwif;				hwif->serialized = hwif->mate->serialized = 1;				goto obsolete_option;			case -1: /* "noprobe" */				hwif->noprobe = 1;				goto done;			case 1:	/* base */				vals[1] = vals[0] + 0x206; /* default ctl */			case 2: /* base,ctl */				vals[2] = 0;	/* default irq = probe for it */			case 3: /* base,ctl,irq */				hwif->hw.irq = vals[2];				ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq);				memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));				hwif->irq      = vals[2];				hwif->noprobe  = 0;				hwif->chipset  = ide_forced;				goto obsolete_option;			case 0: goto bad_option;			default:				printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n");				return 1;		}	}bad_option:	printk(" -- BAD OPTION\n");	return 1;obsolete_option:	printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n");	return 1;bad_hwif:	printk("-- NOT SUPPORTED ON ide%d", hw);done:	printk("\n");	return 1;}extern void pnpide_init(void);extern void h8300_ide_init(void);/* * probe_for_hwifs() finds/initializes "known" IDE interfaces */static void __init probe_for_hwifs (void){#ifdef CONFIG_BLK_DEV_IDEPCI	ide_scan_pcibus(ide_scan_direction);#endif /* CONFIG_BLK_DEV_IDEPCI */#ifdef CONFIG_ETRAX_IDE	{		extern void init_e100_ide(void);		init_e100_ide();	}#endif /* CONFIG_ETRAX_IDE */#ifdef CONFIG_BLK_DEV_CMD640	{		extern void ide_probe_for_cmd640x(void);		ide_probe_for_cmd640x();	}#endif /* CONFIG_BLK_DEV_CMD640 */#ifdef CONFIG_BLK_DEV_IDE_PMAC	{		extern void pmac_ide_probe(void);		pmac_ide_probe();	}#endif /* CONFIG_BLK_DEV_IDE_PMAC */#ifdef CONFIG_BLK_DEV_GAYLE	{		extern void gayle_init(void);		gayle_init();	}#endif /* CONFIG_BLK_DEV_GAYLE */#ifdef CONFIG_BLK_DEV_FALCON_IDE	{		extern void falconide_init(void);		falconide_init();	}#endif /* CONFIG_BLK_DEV_FALCON_IDE */#ifdef CONFIG_BLK_DEV_MAC_IDE	{		extern void macide_init(void);		macide_init();	}#endif /* CONFIG_BLK_DEV_MAC_IDE */#ifdef CONFIG_BLK_DEV_Q40IDE	{		extern void q40ide_init(void);		q40ide_init();	}#endif /* CONFIG_BLK_DEV_Q40IDE */#ifdef CONFIG_BLK_DEV_BUDDHA	{		extern void buddha_init(void);		buddha_init();	}#endif /* CONFIG_BLK_DEV_BUDDHA */#ifdef CONFIG_BLK_DEV_IDEPNP	pnpide_init();#endif#ifdef CONFIG_H8300	h8300_ide_init();#endif}void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver){#ifdef CONFIG_PROC_FS	ide_add_proc_entries(drive->proc, driver->proc, drive);#endif}EXPORT_SYMBOL(ide_register_subdriver);/** *	ide_unregister_subdriver	-	disconnect drive from driver *	@drive: drive to unplug *	@driver: driver * *	Disconnect a drive from the driver it was attached to and then *	clean up the various proc files and other objects attached to it. * *	Takes ide_setting_sem and ide_lock. *	Caller must hold none of the locks. */void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver){	unsigned long flags;		down(&ide_setting_sem);	spin_lock_irqsave(&ide_lock, flags);#ifdef CONFIG_PROC_FS	ide_remove_proc_entries(drive->proc, driver->proc);#endif	auto_remove_settings(drive);	spin_unlock_irqrestore(&ide_lock, flags);	up(&ide_setting_sem);}EXPORT_SYMBOL(ide_unregister_subdriver);/* * Probe module */EXPORT_SYMBOL(ide_lock);static int ide_bus_match(struct device *dev, struct device_driver *drv){	return 1;}struct bus_type ide_bus_type = {	.name		= "ide",	.match		= ide_bus_match,	.suspend	= generic_ide_suspend,	.resume		= generic_ide_resume,};EXPORT_SYMBOL_GPL(ide_bus_type);/* * This is gets invoked once during initialization, to set *everything* up */static int __init ide_init(void){	printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");	devfs_mk_dir("ide");	system_bus_speed = ide_system_bus_speed();	bus_register(&ide_bus_type);	init_ide_data();#ifdef CONFIG_PROC_FS	proc_ide_root = proc_mkdir("ide", NULL);#endif#ifdef CONFIG_BLK_DEV_ALI14XX	if (probe_ali14xx)		(void)ali14xx_init();#endif#ifdef CONFIG_BLK_DEV_UMC8672	if (probe_umc8672)		(void)umc8672_init();#endif#ifdef CONFIG_BLK_DEV_DTC2278	if (probe_dtc2278)		(void)dtc2278_init();#endif#ifdef CONFIG_BLK_DEV_HT6560B	if (probe_ht6560b)		(void)ht6560b_init();#endif#ifdef CONFIG_BLK_DEV_QD65XX	if (probe_qd65xx)		(void)qd65xx_init();#endif	initializing = 1;	/* Probe for special PCI and other "known" interface chipsets. */	probe_for_hwifs();	initializing = 0;#ifdef CONFIG_PROC_FS	proc_ide_create();#endif	return 0;}#ifdef MODULEstatic char *options = NULL;module_param(options, charp, 0);MODULE_LICENSE("GPL");static void __init parse_options (char *line){	char *next = line;	if (line == NULL || !*line)		return;	while ((line = next) != NULL) { 		if ((next = strchr(line,' ')) != NULL)			*next++ = 0;		if (!ide_setup(line))			printk (KERN_INFO "Unknown option '%s'\n", line);	}}int init_module (void){	parse_options(options);	return ide_init();}void cleanup_module (void){	int index;	for (index = 0; index < MAX_HWIFS; ++index)		ide_unregister(index);#ifdef CONFIG_PROC_FS	proc_ide_destroy();#endif	devfs_remove("ide");	bus_unregister(&ide_bus_type);}#else /* !MODULE */__setup("", ide_setup);module_init(ide_init);#endif /* MODULE */

⌨️ 快捷键说明

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