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

📄 ide.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
EXPORT_SYMBOL(system_bus_clock);/* *	Locking is badly broken here - since way back.  That sucker is * root-only, but that's not an excuse...  The real question is what * exclusion rules do we want here. */int ide_replace_subdriver (ide_drive_t *drive, const char *driver){	if (!drive->present || drive->usage || drive->dead)		goto abort;	if (DRIVER(drive)->cleanup(drive))		goto abort;	strlcpy(drive->driver_req, driver, sizeof(drive->driver_req));	if (ata_attach(drive)) {		spin_lock(&drives_lock);		list_del_init(&drive->list);		spin_unlock(&drives_lock);		drive->driver_req[0] = 0;		ata_attach(drive);	} else {		drive->driver_req[0] = 0;	}	if (DRIVER(drive)!= &idedefault_driver && !strcmp(DRIVER(drive)->name, driver))		return 0;abort:	return 1;}/** *	ata_attach		-	attach an ATA/ATAPI device *	@drive: drive to attach * *	Takes a drive that is as yet not assigned to any midlayer IDE *	driver (or is assigned to the default driver) and figures out *	which driver would like to own it. If nobody claims the drive *	then it is automatically attached to the default driver used for *	unclaimed objects. * *	A return of zero indicates attachment to a driver, of one *	attachment to the default driver. * *	Takes drivers_lock. */int ata_attach(ide_drive_t *drive){	struct list_head *p;	spin_lock(&drivers_lock);	list_for_each(p, &drivers) {		ide_driver_t *driver = list_entry(p, ide_driver_t, drivers);		if (!try_module_get(driver->owner))			continue;		spin_unlock(&drivers_lock);		if (driver->attach(drive) == 0) {			module_put(driver->owner);			drive->gendev.driver = &driver->gen_driver;			return 0;		}		spin_lock(&drivers_lock);		module_put(driver->owner);	}	drive->gendev.driver = &idedefault_driver.gen_driver;	spin_unlock(&drivers_lock);	if(idedefault_driver.attach(drive) != 0)		panic("ide: default attach failed");	return 1;}static int generic_ide_suspend(struct device *dev, u32 state){	ide_drive_t *drive = dev->driver_data;	struct request rq;	struct request_pm_state rqpm;	ide_task_t args;	memset(&rq, 0, sizeof(rq));	memset(&rqpm, 0, sizeof(rqpm));	memset(&args, 0, sizeof(args));	rq.flags = REQ_PM_SUSPEND;	rq.special = &args;	rq.pm = &rqpm;	rqpm.pm_step = ide_pm_state_start_suspend;	rqpm.pm_state = state;	return ide_do_drive_cmd(drive, &rq, ide_wait);}static int generic_ide_resume(struct device *dev){	ide_drive_t *drive = dev->driver_data;	struct request rq;	struct request_pm_state rqpm;	ide_task_t args;	memset(&rq, 0, sizeof(rq));	memset(&rqpm, 0, sizeof(rqpm));	memset(&args, 0, sizeof(args));	rq.flags = REQ_PM_RESUME;	rq.special = &args;	rq.pm = &rqpm;	rqpm.pm_step = ide_pm_state_start_resume;	rqpm.pm_state = 0;	return ide_do_drive_cmd(drive, &rq, ide_head_wait);}int generic_ide_ioctl(struct file *file, struct block_device *bdev,			unsigned int cmd, unsigned long arg){	ide_drive_t *drive = bdev->bd_disk->private_data;	ide_settings_t *setting;	int err = 0;	void __user *p = (void __user *)arg;	down(&ide_setting_sem);	if ((setting = ide_find_setting_by_ioctl(drive, cmd)) != NULL) {		if (cmd == setting->read_ioctl) {			err = ide_read_setting(drive, setting);			up(&ide_setting_sem);			return err >= 0 ? put_user(err, (long __user *)arg) : err;		} else {			if (bdev != bdev->bd_contains)				err = -EINVAL;			else				err = ide_write_setting(drive, setting, arg);			up(&ide_setting_sem);			return err;		}	}	up(&ide_setting_sem);	switch (cmd) {		case HDIO_GETGEO:		{			struct hd_geometry geom;			if (!p || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL;			geom.heads = drive->bios_head;			geom.sectors = drive->bios_sect;			geom.cylinders = (u16)drive->bios_cyl; /* truncate */			geom.start = get_start_sect(bdev);			if (copy_to_user(p, &geom, sizeof(struct hd_geometry)))				return -EFAULT;			return 0;		}		case HDIO_OBSOLETE_IDENTITY:		case HDIO_GET_IDENTITY:			if (bdev != bdev->bd_contains)				return -EINVAL;			if (drive->id_read == 0)				return -ENOMSG;			if (copy_to_user(p, drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))				return -EFAULT;			return 0;		case HDIO_GET_NICE:			return put_user(drive->dsc_overlap	<<	IDE_NICE_DSC_OVERLAP	|					drive->atapi_overlap	<<	IDE_NICE_ATAPI_OVERLAP	|					drive->nice0		<< 	IDE_NICE_0		|					drive->nice1		<<	IDE_NICE_1		|					drive->nice2		<<	IDE_NICE_2,					(long __user *) arg);#ifdef CONFIG_IDE_TASK_IOCTL		case HDIO_DRIVE_TASKFILE:		        if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))				return -EACCES;			switch(drive->media) {				case ide_disk:					return ide_taskfile_ioctl(drive, cmd, arg);				default:					return -ENOMSG;			}#endif /* CONFIG_IDE_TASK_IOCTL */		case HDIO_DRIVE_CMD:			if (!capable(CAP_SYS_RAWIO))				return -EACCES;			return ide_cmd_ioctl(drive, cmd, arg);		case HDIO_DRIVE_TASK:			if (!capable(CAP_SYS_RAWIO))				return -EACCES;			return ide_task_ioctl(drive, cmd, arg);		case HDIO_SCAN_HWIF:		{			hw_regs_t hw;			int args[3];			if (!capable(CAP_SYS_RAWIO)) return -EACCES;			if (copy_from_user(args, p, 3 * sizeof(int)))				return -EFAULT;			memset(&hw, 0, sizeof(hw));			ide_init_hwif_ports(&hw, (unsigned long) args[0],					    (unsigned long) args[1], NULL);			hw.irq = args[2];			if (ide_register_hw(&hw, NULL) == -1)				return -EIO;			return 0;		}	        case HDIO_UNREGISTER_HWIF:			if (!capable(CAP_SYS_RAWIO)) return -EACCES;			/* (arg > MAX_HWIFS) checked in function */			ide_unregister(arg);			return 0;		case HDIO_SET_NICE:			if (!capable(CAP_SYS_ADMIN)) return -EACCES;			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))				return -EPERM;			drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;			if (drive->dsc_overlap && !DRIVER(drive)->supports_dsc_overlap) {				drive->dsc_overlap = 0;				return -EPERM;			}			drive->nice1 = (arg >> IDE_NICE_1) & 1;			return 0;		case HDIO_DRIVE_RESET:		{			unsigned long flags;			if (!capable(CAP_SYS_ADMIN)) return -EACCES;						/*			 *	Abort the current command on the			 *	group if there is one, taking			 *	care not to allow anything else			 *	to be queued and to die on the			 *	spot if we miss one somehow			 */			spin_lock_irqsave(&ide_lock, flags);						DRIVER(drive)->abort(drive, "drive reset");			if(HWGROUP(drive)->handler)				BUG();							/* Ensure nothing gets queued after we			   drop the lock. Reset will clear the busy */		   			HWGROUP(drive)->busy = 1;			spin_unlock_irqrestore(&ide_lock, flags);			(void) ide_do_reset(drive);			if (drive->suspend_reset) {/* *				APM WAKE UP todo !! *				int nogoodpower = 1; *				while(nogoodpower) { *					check_power1() or check_power2() *					nogoodpower = 0; *				}  *				HWIF(drive)->multiproc(drive); */				return ioctl_by_bdev(bdev, BLKRRPART, 0);			}			return 0;		}		case CDROMEJECT:		case CDROMCLOSETRAY:			return scsi_cmd_ioctl(file, bdev->bd_disk, cmd, p);		case HDIO_GET_BUSSTATE:			if (!capable(CAP_SYS_ADMIN))				return -EACCES;			if (put_user(HWIF(drive)->bus_state, (long __user *)arg))				return -EFAULT;			return 0;		case HDIO_SET_BUSSTATE:			if (!capable(CAP_SYS_ADMIN))				return -EACCES;			if (HWIF(drive)->busproc)				return HWIF(drive)->busproc(drive, (int)arg);			return -EOPNOTSUPP;		default:			return -EINVAL;	}}EXPORT_SYMBOL(generic_ide_ioctl);/* * stridx() returns the offset of c within s, * or -1 if c is '\0' or not found within s. */static int __init stridx (const char *s, char c){	char *i = strchr(s, c);	return (i && c) ? i - s : -1;}/* * match_parm() does parsing for ide_setup(): * * 1. the first char of s must be '='. * 2. if the remainder matches one of the supplied keywords, *     the index (1 based) of the keyword is negated and returned. * 3. if the remainder is a series of no more than max_vals numbers *     separated by commas, the numbers are saved in vals[] and a *     count of how many were saved is returned.  Base10 is assumed, *     and base16 is allowed when prefixed with "0x". * 4. otherwise, zero is returned. */static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals){	static const char *decimal = "0123456789";	static const char *hex = "0123456789abcdef";	int i, n;	if (*s++ == '=') {		/*		 * Try matching against the supplied keywords,		 * and return -(index+1) if we match one		 */		if (keywords != NULL) {			for (i = 0; *keywords != NULL; ++i) {				if (!strcmp(s, *keywords++))					return -(i+1);			}		}		/*		 * Look for a series of no more than "max_vals"		 * numeric values separated by commas, in base10,		 * or base16 when prefixed with "0x".		 * Return a count of how many were found.		 */		for (n = 0; (i = stridx(decimal, *s)) >= 0;) {			vals[n] = i;			while ((i = stridx(decimal, *++s)) >= 0)				vals[n] = (vals[n] * 10) + i;			if (*s == 'x' && !vals[n]) {				while ((i = stridx(hex, *++s)) >= 0)					vals[n] = (vals[n] * 0x10) + i;			}			if (++n == max_vals)				break;			if (*s == ',' || *s == ';')				++s;		}		if (!*s)			return n;	}	return 0;	/* zero = nothing matched */}#ifdef CONFIG_BLK_DEV_PDC4030static int __initdata probe_pdc4030;#endif#ifdef CONFIG_BLK_DEV_ALI14XXstatic int __initdata probe_ali14xx;extern int ali14xx_init(void);#endif#ifdef CONFIG_BLK_DEV_UMC8672static int __initdata probe_umc8672;extern int umc8672_init(void);#endif#ifdef CONFIG_BLK_DEV_DTC2278static int __initdata probe_dtc2278;extern int dtc2278_init(void);#endif#ifdef CONFIG_BLK_DEV_HT6560Bstatic int __initdata probe_ht6560b;extern int ht6560b_init(void);#endif#ifdef CONFIG_BLK_DEV_QD65XXstatic int __initdata probe_qd65xx;extern int qd65xx_init(void);#endifstatic int __initdata is_chipset_set[MAX_HWIFS];/* * ide_setup() gets called VERY EARLY during initialization, * to handle kernel "command line" strings beginning with "hdx=" or "ide". * * Remember to update Documentation/ide.txt if you change something here. */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("IDE: 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", "stroke", "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;				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 done;			case -7: /* "noautotune" */				drive->autotune = IDE_TUNE_NOAUTO;				goto done;			case -8: /* stroke */				drive->stroke = 1;				goto done;			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;

⌨️ 快捷键说明

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