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

📄 xpram.c

📁 ARM S3C2410 linux2.4 内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		switch(current_req->cmd) {		case READ:			do {				if ( (fault=xpram_page_in((unsigned long)buffer,page_no)) ) {					PRINT_WARN("xpram(dev %d): page in failed for page %ld.\n",dev_no,page_no);					break;				}				sects_to_copy -= XPRAM_SEC_IN_PG;                                buffer += XPRAM_PGSIZE;				page_no++;			} while ( sects_to_copy > 0 );			break;		case WRITE:			do {				if ( (fault=xpram_page_out((unsigned long)buffer,page_no)) 					) {					PRINT_WARN("xpram(dev %d): page out failed for page %ld.\n",dev_no,page_no);					break;				}				sects_to_copy -= XPRAM_SEC_IN_PG;				buffer += XPRAM_PGSIZE;				page_no++;			} while ( sects_to_copy > 0 );			break;		default:			/* can't happen */			end_request(0);			continue;		}		if ( fault ) end_request(0);		else end_request(1); /* success */	}}/* *    Kernel interfaces *//* * Parses the kernel parameters given in the kernel parameter line. * The expected format is  *           <number_of_partitions>[","<partition_size>]* * where  *           devices is a positive integer that initializes xpram_devs *           each size is a non-negative integer possibly followed by a *           magnitude (k,K,m,M,g,G), the list of sizes initialises  *           xpram_sizes * * Arguments *           str: substring of kernel parameter line that contains xprams *                kernel parameters.  *           ints: not used -- not in Version > 2.3 any more * * Result    0 on success, -EINVAl else -- only for Version > 2.3 * * Side effects *           the global variabls devs is set to the value of  *           <number_of_partitions> and sizes[i] is set to the i-th *           partition size (if provided). A parsing error of a value *           results in this value being set to -EINVAL. */#if (XPRAM_VERSION == 22)void xpram_setup (char *str, int *ints)#else int xpram_setup (char *str)#endif /* V22 */{	devs = xpram_read_int(&str);	if ( devs != -EINVAL ) 	  if ( xpram_read_size_list_tail(&str,devs,sizes) < 0 ) {			PRINT_ERR("error while reading xpram parameters.\n");#if (XPRAM_VERSION == 24)			return -EINVAL;#endif /* V24 */			  }#if (XPRAM_VERSION == 24)	  else return 0;	else return -EINVAL;#elif (XPRAM_VERSION == 22)	return; #endif /* V24/V22 */}/* * initialize xpram device driver * * Result: 0 ok *         negative number: negative error code */int xpram_init(void){	int result, i;	int mem_usable;       /* net size of expanded memory */	int mem_needed=0;     /* size of expanded memory needed to fullfill			       * requirements of non-zero parameters in sizes			       */	int mem_auto_no=0;    /* number of (implicit) zero parameters in sizes */	int mem_auto;         /* automatically determined device size          */#if (XPRAM_VERSION == 24)	int minor_length;     /* store the length of a minor (w/o '\0') */        int minor_thresh;     /* threshhold for minor lenght            */        request_queue_t *q;   /* request queue */#endif /* V24 */				/*				 * Copy the (static) cfg variables to public prefixed ones to allow				 * snoozing with a debugger.				 */	xpram_rahead   = rahead;	xpram_blksize  = blksize;	xpram_hardsect = hardsect;	PRINT_INFO("initializing: %s\n","");				/* check arguments */	xpram_major    = major;	if ( (devs <= 0) || (devs > XPRAM_MAX_DEVS) ) {		PRINT_ERR("invalid number %d of devices\n",devs);                PRINT_ERR("Giving up xpram\n");		return -EINVAL;	}	xpram_devs     = devs;	for (i=0; i < xpram_devs; i++) {		if ( sizes[i] < 0 ) {			PRINT_ERR("Invalid partition size %d kB\n",xpram_sizes[i]);                        PRINT_ERR("Giving up xpram\n");			return -EINVAL;		} else {		  xpram_sizes[i] = NEXT4(sizes[i]);  /* page align */			if ( sizes[i] ) mem_needed += xpram_sizes[i];			else mem_auto_no++;		}	}	PRINT_DEBUG("  major %d \n", xpram_major);	PRINT_INFO("  number of devices (partitions): %d \n", xpram_devs);	for (i=0; i < xpram_devs; i++) {		if ( sizes[i] )			PRINT_INFO("  size of partition %d: %d kB\n", i, xpram_sizes[i]);		else			PRINT_INFO("  size of partition %d to be set automatically\n",i);	}	PRINT_DEBUG("  memory needed (for sized partitions): %d kB\n", mem_needed);	PRINT_DEBUG("  partitions to be sized automatically: %d\n", mem_auto_no);#if 0				/* Hardsect can't be changed :( */                                /* I try it any way. Yet I must distinguish                                 * between hardsects (to be changed to 4096)                                 * and soft sectors, hard-coded for buffer                                  * sizes within the requests                                 */	if (hardsect != 512) {		PRINT_ERR("Can't change hardsect size\n");		hardsect = xpram_hardsect = 512;	}#endif        PRINT_INFO("  hardsector size: %dB \n",xpram_hardsect);	/*	 * Register your major, and accept a dynamic number	 */#if (XPRAM_VERSION == 22)	result = register_blkdev(xpram_major, "xpram", &xpram_fops);#elif (XPRAM_VERSION == 24)	result = devfs_register_blkdev(xpram_major, "xpram", &xpram_devops);#endif /* V22/V24 */	if (result < 0) {		PRINT_ERR("Can't get major %d\n",xpram_major);                PRINT_ERR("Giving up xpram\n");		return result;	}#if (XPRAM_VERSION == 24)	xpram_devfs_handle = devfs_mk_dir (NULL, "slram", NULL);	devfs_register_series (xpram_devfs_handle, "%u", XPRAM_MAX_DEVS,			       DEVFS_FL_DEFAULT, XPRAM_MAJOR, 0,			       S_IFBLK | S_IRUSR | S_IWUSR,			       &xpram_devops, NULL);#endif /* V22/V24 */	if (xpram_major == 0) xpram_major = result; /* dynamic */	major = xpram_major; /* Use `major' later on to save typing */	result = -ENOMEM; /* for the possible errors */	/* 	 * measure expanded memory	 */	xpram_mem_avail = xpram_size();	if (!xpram_mem_avail) {		PRINT_ERR("No or not enough expanded memory available\n");                PRINT_ERR("Giving up xpram\n");		result = -ENODEV;		goto fail_malloc;	}	PRINT_INFO("  %d kB expanded memory found.\n",xpram_mem_avail );	/*	 * Assign the other needed values: request, rahead, size, blksize,	 * hardsect. All the minor devices feature the same value.	 * Note that `xpram' defines all of them to allow testing non-default	 * values. A real device could well avoid setting values in global	 * arrays if it uses the default values.	 */#if (XPRAM_VERSION == 22)	blk_dev[major].request_fn = xpram_request;#elif (XPRAM_VERSION == 24)	q = BLK_DEFAULT_QUEUE (major);	blk_init_queue (q, xpram_request);	blk_queue_headactive (BLK_DEFAULT_QUEUE (major), 0);#endif /* V22/V24 */	read_ahead[major] = xpram_rahead;	/* we want to have XPRAM_UNUSED blocks security buffer between devices */	mem_usable=xpram_mem_avail-(XPRAM_UNUSED*(xpram_devs-1));	if ( mem_needed > mem_usable ) {		PRINT_ERR("Not enough expanded memory available\n");                PRINT_ERR("Giving up xpram\n");		goto fail_malloc;	}	/*	 * partitioning:	 * xpram_sizes[i] != 0; partition i has size xpram_sizes[i] kB	 * else:             ; all partitions i with xpram_sizesxpram_size[i] 	 *                     partition equally the remaining space	 */	if ( mem_auto_no ) {		mem_auto=LAST4((mem_usable-mem_needed)/mem_auto_no);		PRINT_INFO("  automatically determined partition size: %d kB\n", mem_auto);		for (i=0; i < xpram_devs; i++) 			if (xpram_sizes[i] == 0) xpram_sizes[i] = mem_auto;	}	blk_size[major]=xpram_sizes;	xpram_offsets = kmalloc(xpram_devs * sizeof(int), GFP_KERNEL);	if (!xpram_offsets) {		PRINT_ERR("Not enough memory for xpram_offsets\n");                PRINT_ERR("Giving up xpram\n");		goto fail_malloc;	}	xpram_offsets[0] = 0;	for (i=1; i < xpram_devs; i++) 		xpram_offsets[i] = xpram_offsets[i-1] + xpram_sizes[i-1] + XPRAM_UNUSED;#if 0	for (i=0; i < xpram_devs; i++)		PRINT_DEBUG(" device(%d) offset = %d kB, size = %d kB\n",i, xpram_offsets[i], xpram_sizes[i]);#endif	xpram_blksizes = kmalloc(xpram_devs * sizeof(int), GFP_KERNEL);	if (!xpram_blksizes) {		PRINT_ERR("Not enough memory for xpram_blksizes\n");                PRINT_ERR("Giving up xpram\n");		goto fail_malloc_blksizes;	}	for (i=0; i < xpram_devs; i++) /* all the same blocksize */		xpram_blksizes[i] = xpram_blksize;	blksize_size[major]=xpram_blksizes;	xpram_hardsects = kmalloc(xpram_devs * sizeof(int), GFP_KERNEL);	if (!xpram_hardsects) {		PRINT_ERR("Not enough memory for xpram_hardsects\n");                PRINT_ERR("Giving up xpram\n");		goto fail_malloc_hardsects;	}	for (i=0; i < xpram_devs; i++) /* all the same hardsect */		xpram_hardsects[i] = xpram_hardsect;	hardsect_size[major]=xpram_hardsects;   	/* 	 * allocate the devices -- we can't have them static, as the number	 * can be specified at load time	 */	xpram_devices = kmalloc(xpram_devs * sizeof (Xpram_Dev), GFP_KERNEL);	if (!xpram_devices) {		PRINT_ERR("Not enough memory for xpram_devices\n");                PRINT_ERR("Giving up xpram\n");		goto fail_malloc_devices;	}	memset(xpram_devices, 0, xpram_devs * sizeof (Xpram_Dev));#if (XPRAM_VERSION == 24)        minor_length = 1;        minor_thresh = 10;#endif /* V24 */	for (i=0; i < xpram_devs; i++) {		/* data and usage remain zeroed */		xpram_devices[i].size = xpram_sizes[i];  /* size in kB not in bytes */		atomic_set(&(xpram_devices[i].usage),0);#if (XPRAM_VERSION == 24)                if (i == minor_thresh) {		  minor_length++;		  minor_thresh *= 10;		}                xpram_devices[i].device_name =                   kmalloc(1 + strlen(XPRAM_DEVICE_NAME_PREFIX) + minor_length,GFP_KERNEL);		if ( xpram_devices[i].device_name == NULL ) {		  PRINT_ERR("Not enough memory for xpram_devices[%d].device_name\n",i);                  PRINT_ERR("Giving up xpram\n");		  goto fail_devfs_register;		}                sprintf(xpram_devices[i].device_name,XPRAM_DEVICE_NAME_PREFIX "%d",i);	PRINT_DEBUG("initializing xpram_open for device %d\n",i);        PRINT_DEBUG("  size %dkB, name %s, usage: %d\n",                      xpram_devices[i].size,xpram_devices[i].device_name, atomic_read(&(xpram_devices[i].usage)));#if 0  /* WHY? */                xpram_devices[i].devfs_entry =		  devfs_register(NULL /* devfs root dir */,                                 xpram_devices[i].device_name, 0,                                 0 /* flags */,				 XPRAM_MAJOR,i,                                 0755 /* access mode */,				 0 /* uid */, 0 /* gid */,                                 &xpram_devops,				 (void *) &(xpram_devices[i])				 );		if ( xpram_devices[i].devfs_entry == NULL ) {		  PRINT_ERR("devfs system registry failed\n");		  PRINT_ERR("Giving up xpram\n");		  goto fail_devfs_register;		}#endif  /* WHY? */#endif /* V24 */				 	}	return 0; /* succeed */	/* clean up memory in case of failures */#if (XPRAM_VERSION == 24) fail_devfs_register:        for (i=0; i < xpram_devs; i++) {	  if ( xpram_devices[i].device_name )	    kfree(xpram_devices[i].device_name);	}	kfree(xpram_devices);#endif /* V24 */ fail_malloc_blksizes:	kfree (xpram_offsets); fail_malloc_hardsects:	kfree (xpram_blksizes);	blksize_size[major] = NULL; fail_malloc_devices:	kfree(xpram_hardsects);	hardsect_size[major] = NULL; fail_malloc:	read_ahead[major] = 0;#if (XPRAM_VERSION == 22)	blk_dev[major].request_fn = NULL;#endif /* V22 */	/* ???	unregister_chrdev(major, "xpram"); */	unregister_blkdev(major, "xpram");	return result;}/* * Finally, the module stuff */int init_module(void){	int rc = 0;	PRINT_INFO ("trying to load module\n");	rc = xpram_init ();	if (rc == 0) {		PRINT_INFO ("Module loaded successfully\n");	} else {		PRINT_WARN ("Module load returned rc=%d\n", rc);	}	return rc;}void cleanup_module(void){	int i;				/* first of all, flush it all and reset all the data structures */	for (i=0; i<xpram_devs; i++)		fsync_dev(MKDEV(xpram_major, i)); /* flush the devices */#if (XPRAM_VERSION == 22)	blk_dev[major].request_fn = NULL;#endif /* V22 */	read_ahead[major] = 0;	blk_size[major] = NULL;	kfree(blksize_size[major]);	blksize_size[major] = NULL;	kfree(hardsect_size[major]);	hardsect_size[major] = NULL;	kfree(xpram_offsets);				/* finally, the usual cleanup */#if (XPRAM_VERSION == 22)	unregister_blkdev(major, "xpram");#elif (XPRAM_VERSION == 24)	devfs_unregister(xpram_devfs_handle);	if (devfs_unregister_blkdev(MAJOR_NR, "xpram"))		printk(KERN_WARNING "xpram: cannot unregister blkdev\n");#endif /* V22/V24 */	kfree(xpram_devices);}

⌨️ 快捷键说明

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