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

📄 dasd.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		count++;		tmp = end;	};}/* * dasd_parm_string holds a concatenated version of all 'dasd=' parameters * supplied in the parmline, which is later to be split by * dasd_split_parm_string * FIXME: why first concatenate then split ? */static char dasd_parm_string[1024] __initdata = { 0, };/* * function: dasd_setup * is invoked for any single 'dasd=' parameter supplied in the parmline * it merges all the arguments into dasd_parm_string */void __initdasd_setup (char *str, int *ints){	int len = strlen (dasd_parm_string);	if (len != 0) {		strcat (dasd_parm_string, ",");	}	strcat (dasd_parm_string, str);}/* * function: dasd_call_setup * is the 2.4 version of dasd_setup and * is invoked for any single 'dasd=' parameter supplied in the parmline */int __initdasd_call_setup (char *str){	int dummy;	dasd_setup (str, &dummy);	return 1;}int __initdasd_disciplines_setup (char *str){	return 1;}__setup ("dasd=", dasd_call_setup);__setup ("dasd_disciplines=", dasd_disciplines_setup);#endif				/* MODULE *//* * function: dasd_strtoul * provides a wrapper to simple_strtoul to strip leading '0x' and * interpret any argument to dasd=[range,...] as hexadecimal */static inline intdasd_strtoul (char *str, char **stra, int* features){        char *temp=str;        char *buffer;        int val,i,start;        buffer=(char*)kmalloc((strlen(str)+1)*sizeof(char),GFP_ATOMIC);        if (buffer==NULL) {            printk (KERN_WARNING PRINTK_HEADER                    "can't parse dasd= parameter %s due to low memory\n",                    str);        }        /* remove leading '0x' */        if (*temp == '0') {                temp++;         /* strip leading zero */                if (*temp == 'x')                        temp++; /* strip leading x */        }        /* copy device no to buffer and convert to decimal */        for (i=0; temp[i]!='\0' && temp[i]!='(' &&                   temp[i]!='-'  && temp[i]!=' '; i++){                if (isxdigit(temp[i])) {                        buffer[i]=temp[i];                } else {                        return -EINVAL;                }        }        buffer[i]='\0';        val = simple_strtoul (buffer, &buffer, 16);        /* check for features - e.g. (ro) ; the '\0', ')' and '-' stops check */        *features = DASD_DEFAULT_FEATURES;        if (temp[i]=='(') {                while (temp[i]!='\0' && temp[i]!=')'&&temp[i]!='-') {                         start=++i;                                      /* move next feature to buffer */                        for (;temp[i]!='\0'&&temp[i]!=':'&&temp[i]!=')'&&temp[i]!='-';i++)                                buffer[i-start]=temp[i];                        buffer[i-start]='\0';                        if (strlen(buffer)) {                                 if (!strcmp(buffer,"ro")) { /* handle 'ro' feature */                                        (*features) |= DASD_FEATURE_READONLY;                                        break;                                }                                printk (KERN_WARNING PRINTK_HEADER                                         "unsupported feature: %s, ignoring setting",                                        buffer);                        }                }        }        *stra = temp+i;        return val;}/* * function: dasd_parse * examines the strings given in the string array str and * creates and adds the ranges to the apropriate lists */static intdasd_parse (char **str){	char *temp;	int from, to;        int features;        int rc = 0;	if (*str) {		/* turn off probeonly mode, if any dasd parameter is present */		dasd_probeonly = 0;		dasd_autodetect = 0;	}	while (*str) {		temp = *str;		from = 0;		to = 0;		if (strcmp ("autodetect", *str) == 0) {			dasd_autodetect = 1;			printk (KERN_INFO "turning to autodetection mode\n");			break;		} else if (strcmp ("probeonly", *str) == 0) {			dasd_probeonly = 1;			printk (KERN_INFO "turning to probeonly mode\n");			break;		} else {			/* turn off autodetect mode, if any range is present */			dasd_autodetect = 0;			from = dasd_strtoul (temp, &temp, &features);                        to = from;			if (*temp == '-') {				temp++;				to = dasd_strtoul (temp, &temp, &features);			}                        if (from == -EINVAL ||                            to   == -EINVAL    ) {                                rc = -EINVAL;                                break;                        } else {                                dasd_add_range (from, to ,features);                        }                }		str++;	}        return rc;}/* SECTION: Dealing with devices registered to multiple major numbers */static spinlock_t dasd_major_lock = SPIN_LOCK_UNLOCKED;static major_info_t dasd_major_info[] = {	{	      list:LIST_HEAD_INIT (dasd_major_info[1].list)	 },	{	      list:LIST_HEAD_INIT (dasd_major_info[0].list),	      gendisk:{	  INIT_GENDISK (94, DASD_NAME, DASD_PARTN_BITS, DASD_PER_MAJOR)	  },      flags:DASD_MAJOR_INFO_IS_STATIC}};static major_info_t *get_new_major_info (void){	major_info_t *major_info = NULL;	major_info = kmalloc (sizeof (major_info_t), GFP_KERNEL);	if (major_info) {		static major_info_t temp_major_info = {			gendisk:{				 INIT_GENDISK (0, DASD_NAME, DASD_PARTN_BITS,					       DASD_PER_MAJOR)}		};		memcpy (major_info, &temp_major_info, sizeof (major_info_t));	}	return major_info;}/* * register major number * is called with the 'static' major_info during init of the driver or 'NULL' to * allocate an additional dynamic major. */static intdasd_register_major (major_info_t * major_info){	int rc = 0;	int major;	unsigned long flags;        /* allocate dynamic major */	if (major_info == NULL) {		major_info = get_new_major_info ();		if (!major_info) {			printk (KERN_WARNING PRINTK_HEADER				"Cannot get memory to allocate another major number\n");			return -ENOMEM;		}	}	major = major_info->gendisk.major;        /* init devfs array */	major_info->gendisk.de_arr = (devfs_handle_t *)	    kmalloc (DASD_PER_MAJOR * sizeof (devfs_handle_t), GFP_KERNEL);	if(major_info->gendisk.de_arr == NULL)		goto out_gd_de_arr;	memset (major_info->gendisk.de_arr, 0,		DASD_PER_MAJOR * sizeof (devfs_handle_t));        /* init flags */	major_info->gendisk.flags = (char *)	    kmalloc (DASD_PER_MAJOR * sizeof (char), GFP_KERNEL);	if(major_info->gendisk.flags == NULL)		goto out_gd_flags;	memset (major_info->gendisk.flags, 0, DASD_PER_MAJOR * sizeof (char));        /* register blockdevice */	rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);	if (rc < 0) {		printk (KERN_WARNING PRINTK_HEADER			"Cannot register to major no %d, rc = %d\n",                        major,                         rc);		goto out_reg_blkdev; 	} else {		major_info->flags |= DASD_MAJOR_INFO_REGISTERED;	}	/* Insert the new major info into dasd_major_info if needed (dynamic major) */	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {		spin_lock_irqsave (&dasd_major_lock, flags);		list_add_tail (&major_info->list, &dasd_major_info[0].list);		spin_unlock_irqrestore (&dasd_major_lock, flags);	}	if (major == 0) {		major = rc;		rc = 0;	}        /* init array of devices */	major_info->dasd_device =	    (dasd_device_t **) kmalloc (DASD_PER_MAJOR *					sizeof (dasd_device_t *), GFP_ATOMIC);	if (!major_info->dasd_device)		goto out_devices;	memset (major_info->dasd_device, 0,		DASD_PER_MAJOR * sizeof (dasd_device_t *));        /* init blk_size */	blk_size[major] =	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);	if (!blk_size[major])		goto out_blk_size;	memset (blk_size[major], 0, (1 << MINORBITS) * sizeof (int));        /* init blksize_size */	blksize_size[major] =	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);	if (!blksize_size[major])		goto out_blksize_size;	memset (blksize_size[major], 0, (1 << MINORBITS) * sizeof (int));        /* init_hardsect_size */	hardsect_size[major] =	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);	if (!hardsect_size[major])		goto out_hardsect_size;	memset (hardsect_size[major], 0, (1 << MINORBITS) * sizeof (int));        /* init max_sectors */	max_sectors[major] =	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);	if (!max_sectors[major])		goto out_max_sectors;	memset (max_sectors[major], 0, (1 << MINORBITS) * sizeof (int));	/* finally do the gendisk stuff */	major_info->gendisk.part = kmalloc ((1 << MINORBITS) *					    sizeof (struct hd_struct),					    GFP_ATOMIC);	if (!major_info->gendisk.part)		goto out_gendisk;	memset (major_info->gendisk.part, 0, (1 << MINORBITS) *		sizeof (struct hd_struct));	INIT_BLK_DEV (major, do_dasd_request, dasd_get_queue, NULL);	major_info->gendisk.sizes = blk_size[major];	major_info->gendisk.major = major;	add_gendisk (&major_info->gendisk);	return major;        /* error handling - free the prior allocated memory */        out_gendisk:	kfree (max_sectors[major]);	max_sectors[major] = NULL;      out_max_sectors:	kfree (hardsect_size[major]);	hardsect_size[major] = NULL;      out_hardsect_size:	kfree (blksize_size[major]);	blksize_size[major] = NULL;      out_blksize_size:	kfree (blk_size[major]);	blk_size[major] = NULL;      out_blk_size:	kfree (major_info->dasd_device);      out_devices:	/* Delete the new major info from dasd_major_info list if needed (dynamic) +*/	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {		spin_lock_irqsave (&dasd_major_lock, flags);		list_del (&major_info->list);		spin_unlock_irqrestore (&dasd_major_lock, flags);	}        /* unregister blockdevice */	rc = devfs_unregister_blkdev (major, DASD_NAME);	if (rc < 0) {		printk (KERN_WARNING PRINTK_HEADER			"Unable to unregister from major no %d, rc = %d\n",                         major,			rc);	} else {		major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;	}out_reg_blkdev:	kfree (major_info->gendisk.flags);out_gd_flags:	kfree (major_info->gendisk.de_arr);out_gd_de_arr:	/* Delete the new major info from dasd_major_info if needed */	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {		kfree (major_info);	}	return -ENOMEM;}static intdasd_unregister_major (major_info_t * major_info){	int rc = 0;	int major;	unsigned long flags;	if (major_info == NULL) {		return -EINVAL;	}	major = major_info->gendisk.major;	INIT_BLK_DEV (major, NULL, NULL, NULL);	del_gendisk (&major_info->gendisk);	kfree (major_info->dasd_device);	kfree (major_info->gendisk.part);	kfree (blk_size[major]);	kfree (blksize_size[major]);	kfree (hardsect_size[major]);	kfree (max_sectors[major]);	blk_size[major]      = NULL;	blksize_size[major]  = NULL;	hardsect_size[major] = NULL;	max_sectors[major]   = NULL;	rc = devfs_unregister_blkdev (major, DASD_NAME);	if (rc < 0) {		printk (KERN_WARNING PRINTK_HEADER			"Cannot unregister from major no %d, rc = %d\n",                        major,			rc);		return rc;	} else {		major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;	}	kfree (major_info->gendisk.flags);	kfree (major_info->gendisk.de_arr);	/* Delete the new major info from dasd_major_info if needed */	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {		spin_lock_irqsave (&dasd_major_lock, flags);		list_del (&major_info->list);		spin_unlock_irqrestore (&dasd_major_lock, flags);		kfree (major_info);	}	return rc;}/* * function: dasd_device_from_kdev * finds the device structure corresponding to the kdev supplied as argument * in the major_info structures and returns it or NULL when not found */dasd_device_t *

⌨️ 快捷键说明

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