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

📄 xpram.c

📁 ARM S3C2410 linux2.4 内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	} else return 0;#endif}/* *   expanded memory operations *//*--------------------------------------------------------------------*//* Copy expanded memory page (4kB) into main memory                   *//* Arguments                                                          *//*           page_addr:    address of target page                     *//*           xpage_index:  index of expandeded memory page            *//* Return value                                                       *//*           0:            if operation succeeds                      *//*           non-0:       otherwise                                   *//*--------------------------------------------------------------------*/long xpram_page_in (unsigned long page_addr, unsigned long xpage_index){	int cc=0;	unsigned long real_page_addr = __pa(page_addr);#ifndef CONFIG_ARCH_S390X	__asm__ __volatile__ (		"   lr  1,%1         \n"   /* r1 = real_page_addr            */		"   lr  2,%2         \n"   /* r2 = xpage_index               */		"   .long 0xb22e0012 \n"   /* pgin r1,r2                     */		/* copy page from expanded memory */		"0: ipm  %0          \n"   /* save status (cc & program mask */		"   srl  %0,28       \n"   /* cc into least significant bits */                "1:                  \n"   /* we are done                    */                ".section .fixup,\"ax\"\n" /* start of fix up section        */                "2: lhi    %0,2      \n"   /* return unused condition code 2 */                "   bras 1,3f        \n"   /* safe label 1: in r1 and goto 3 */                "   .long 1b         \n"   /* literal containing label 1     */                "3: l    1,0(1)      \n"   /* load label 1 address into r1   */                "   br   1           \n"   /* goto label 1 (across sections) */                ".previous           \n"   /* back in text section           */                ".section __ex_table,\"a\"\n" /* start __extable             */                "   .align 4         \n"                "   .long 0b,2b      \n"   /* failure point 0, fixup code 2  */                ".previous           \n"		: "=d" (cc) : "d" (real_page_addr), "d" (xpage_index) : "cc", "1", "2"		);#else /* CONFIG_ARCH_S390X */	__asm__ __volatile__ (		"   lgr  1,%1        \n"   /* r1 = real_page_addr            */		"   lgr  2,%2        \n"   /* r2 = xpage_index               */		"   .long 0xb22e0012 \n"   /* pgin r1,r2                     */		/* copy page from expanded memory */		"0: ipm  %0          \n"   /* save status (cc & program mask */		"   srl  %0,28       \n"   /* cc into least significant bits */                "1:                  \n"   /* we are done                    */                ".section .fixup,\"ax\"\n" /* start of fix up section        */                "2: lghi %0,2        \n"   /* return unused condition code 2 */                "   jg   1b          \n"   /* goto label 1 above             */                ".previous           \n"   /* back in text section           */                ".section __ex_table,\"a\"\n" /* start __extable             */                "   .align 8         \n"                "   .quad 0b,2b      \n"   /* failure point 0, fixup code 2  */                ".previous           \n"		: "=d" (cc) : "d" (real_page_addr), "d" (xpage_index) : "cc", "1", "2"		);#endif /* CONFIG_ARCH_S390X */	switch (cc) {	case 0: return 0;	case 1: return -EIO;        case 2: return -ENXIO;	case 3: return -ENXIO;	default: return -EIO;  /* should not happen */	};}/*--------------------------------------------------------------------*//* Copy a 4kB page of main memory to an expanded memory page          *//* Arguments                                                          *//*           page_addr:    address of source page                     *//*           xpage_index:  index of expandeded memory page            *//* Return value                                                       *//*           0:            if operation succeeds                      *//*           non-0:        otherwise                                  *//*--------------------------------------------------------------------*/long xpram_page_out (unsigned long page_addr, unsigned long xpage_index){	int cc=0;	unsigned long real_page_addr = __pa(page_addr);#ifndef CONFIG_ARCH_S390X	__asm__ __volatile__ (		"  lr  1,%1        \n"   /* r1 = mem_page                  */		"  lr  2,%2        \n"   /* r2 = rpi                       */		" .long 0xb22f0012 \n"   /* pgout r1,r2                    */                                /* copy page from expanded memory */		"0: ipm  %0        \n"   /* save status (cc & program mask */                " srl  %0,28       \n"   /* cc into least significant bits */                "1:                  \n"   /* we are done                    */                ".section .fixup,\"ax\"\n" /* start of fix up section        */                "2: lhi   %0,2       \n"   /* return unused condition code 2 */                "   bras 1,3f        \n"   /* safe label 1: in r1 and goto 3 */                "   .long 1b         \n"   /* literal containing label 1     */                "3: l    1,0(1)      \n"   /* load label 1 address into r1   */                "   br   1           \n"   /* goto label 1 (across sections) */                ".previous           \n"   /* back in text section           */                ".section __ex_table,\"a\"\n" /* start __extable             */                "   .align 4         \n"                "   .long 0b,2b      \n"   /* failure point 0, fixup code 2  */                ".previous           \n"		: "=d" (cc) : "d" (real_page_addr), "d" (xpage_index) : "cc", "1", "2"		);#else /* CONFIG_ARCH_S390X */	__asm__ __volatile__ (		"  lgr  1,%1       \n"   /* r1 = mem_page                  */		"  lgr  2,%2       \n"   /* r2 = rpi                       */		" .long 0xb22f0012 \n"   /* pgout r1,r2                    */                                         /* copy page from expanded memory */		"0: ipm  %0        \n"   /* save status (cc & program mask */                "  srl  %0,28      \n"   /* cc into least significant bits */                "1:                \n"   /* we are done                    */                ".section .fixup,\"ax\"\n" /* start of fix up section      */                "2: lghi %0,2      \n"   /* return unused condition code 2 */                "   jg   1b        \n"   /* goto label 1 above             */                ".previous         \n"   /* back in text section           */                ".section __ex_table,\"a\"\n" /* start __extable           */                "   .align 8       \n"                "   .quad 0b,2b    \n"   /* failure point 0, fixup code 2  */                ".previous         \n"		: "=d" (cc) : "d" (real_page_addr), "d" (xpage_index) : "cc", "1", "2"		);#endif  /* CONFIG_ARCH_S390X */	switch (cc) {	case 0: return 0;	case 1: return -EIO;        case 2: { PRINT_ERR("expanded storage lost!\n"); return -ENXIO; }	case 3: return -ENXIO;	default: return -EIO;  /* should not happen */        }}/*--------------------------------------------------------------------*//* Measure expanded memory                                            *//* Return value                                                       *//*           size of expanded memory in kB (must be a multipe of 4)   *//*--------------------------------------------------------------------*/int xpram_size(void){	int cc=0;          unsigned long base=0;	unsigned long po, pi, rpi;   /* page index order, page index */	unsigned long mem_page = __get_free_page(GFP_KERNEL);	/* for po=0,1,2,... try to move in page number base+(2^po)-1 */	pi=1;   	for (po=0; po <= 32; po++) { /* pi = 2^po */		cc=xpram_page_in(mem_page,base+pi-1);		if ( cc ) break;		pi <<= 1;  	}	if ( cc && (po < 31 ) ) {                pi >>=1;		base += pi;		pi >>=1;		for ( ; pi > 0; pi >>= 1) {			rpi = pi - 1;			cc=xpram_page_in(mem_page,base+rpi);			if ( !cc ) base += pi;		}	}		free_page (mem_page);	if ( cc && (po < 31) ) 		return (XPRAM_KB_IN_PG * base);	else          /* return maximal value possible */		return INT_MAX;}/* * Open and close */int xpram_open (struct inode *inode, struct file *filp){	Xpram_Dev *dev; /* device information */	int num = MINOR(inode->i_rdev);	if (num >= xpram_devs) return -ENODEV;	dev = xpram_devices + num;	PRINT_DEBUG("calling xpram_open for device %d\n",num);        PRINT_DEBUG("  size %dkB, name %s, usage: %d\n",                      dev->size,dev->device_name, atomic_read(&(dev->usage)));	atomic_inc(&(dev->usage));	return 0;          /* success */}int xpram_release (struct inode *inode, struct file *filp){	Xpram_Dev *dev = xpram_devices + MINOR(inode->i_rdev);	PRINT_DEBUG("calling xpram_release for device %d (size %dkB, usage: %d)\n",MINOR(inode->i_rdev) ,dev->size,atomic_read(&(dev->usage)));	/*	 * If the device is closed for the last time, start a timer	 * to release RAM in half a minute. The function and argument	 * for the timer have been setup in init_module()	 */	if (!atomic_dec_return(&(dev->usage))) {		/* but flush it right now */		/* Everything is already flushed by caller -- AV */	}	return(0);}/* * The ioctl() implementation */int xpram_ioctl (struct inode *inode, struct file *filp,		 unsigned int cmd, unsigned long arg){	int err, size;	struct hd_geometry *geo = (struct hd_geometry *)arg;	PRINT_DEBUG("ioctl 0x%x 0x%lx\n", cmd, arg);	switch(cmd) {	case BLKGETSIZE:  /* 0x1260 */		/* Return the device size, expressed in sectors */		return put_user( 1024* xpram_sizes[MINOR(inode->i_rdev)]                           / XPRAM_SOFTSECT,			   (unsigned long *) arg);	case BLKGETSIZE64:		return put_user( (u64)(1024* xpram_sizes[MINOR(inode->i_rdev)]                           / XPRAM_SOFTSECT) << 9,			   (u64 *) arg);	case BLKFLSBUF: /* flush, 0x1261 */		fsync_dev(inode->i_rdev);		if ( capable(CAP_SYS_ADMIN) )invalidate_buffers(inode->i_rdev);		return 0;	case BLKRAGET: /* return the readahead value, 0x1263 */		if (!arg)  return -EINVAL;		err = 0; /* verify_area_20(VERIFY_WRITE, (long *) arg, sizeof(long));		          * if (err) return err;                          */		put_user(read_ahead[MAJOR(inode->i_rdev)], (long *)arg);		return 0;	case BLKRASET: /* set the readahead value, 0x1262 */		if (!capable(CAP_SYS_ADMIN)) return -EACCES;		if (arg > 0xff) return -EINVAL; /* limit it */		read_ahead[MAJOR(inode->i_rdev)] = arg;                atomic_eieio();		return 0;	case BLKRRPART: /* re-read partition table: can't do it, 0x1259 */		return -EINVAL;#if (XPRAM_VERSION == 22)		RO_IOCTLS(inode->i_rdev, arg); /* the default RO operations                                                 * BLKROSET						* BLKROGET                                                */#endif /* V22 */	case HDIO_GETGEO:		/*		 * get geometry: we have to fake one...  trim the size to a		 * multiple of 64 (32k): tell we have 16 sectors, 4 heads,		 * whatever cylinders. Tell also that data starts at sector. 4.		 */		size = xpram_mem_avail * 1024 / XPRAM_SOFTSECT;		/* size = xpram_mem_avail * 1024 / xpram_hardsect; */		size &= ~0x3f; /* multiple of 64 */		if (geo==NULL) return -EINVAL;                /*                  * err=verify_area_20(VERIFY_WRITE, geo, sizeof(*geo));		 * if (err) return err;                 */		put_user(size >> 6, &geo->cylinders);		put_user(        4, &geo->heads);		put_user(       16, &geo->sectors);		put_user(        4, &geo->start);		return 0;	}	return -EINVAL; /* unknown command */}/* * The file operations */#if (XPRAM_VERSION == 22)struct file_operations xpram_fops = {	NULL,          /* lseek: default */	block_read,	block_write,	NULL,          /* xpram_readdir */	NULL,          /* xpram_select */	xpram_ioctl,	NULL,          /* xpram_mmap */	xpram_open,	NULL,          /* flush */	xpram_release,	block_fsync,	NULL,          /* xpram_fasync */        NULL,        NULL};#endif /* V22 */#if (XPRAM_VERSION == 24)struct block_device_operations xpram_devops ={	owner:   THIS_MODULE,	ioctl:   xpram_ioctl,	open:    xpram_open,	release: xpram_release,};#endif /* V24 *//* * Block-driver specific functions */void xpram_request(request_queue_t * queue){	Xpram_Dev *device;	/*     u8 *ptr;          */	/*    int size;          */	unsigned long page_no;         /* expanded memory page number */	unsigned long sects_to_copy;   /* number of sectors to be copied */        char * buffer;                 /* local pointer into buffer cache */	int dev_no;                    /* device number of request */	int fault;                     /* faulty access to expanded memory */#if ( XPRAM_VERSION == 24 )	        struct request * current_req;      /* working request */#else #       define current_req CURRENT#endif /* V24 */	while(1) {		INIT_REQUEST;		fault=0;#if ( XPRAM_VERSION == 24 )		current_req = blkdev_entry_next_request (&queue->queue_head);#endif /* V24 */		dev_no = DEVICE_NR(current_req->rq_dev); 		/* Check if the minor number is in range */		if ( dev_no > xpram_devs ) {			static int count = 0;			if (count++ < 5) /* print the message at most five times */				PRINT_WARN(" request for unknown device\n");			end_request(0);			continue;		}		/* pointer to device structure, from the global array */		device = xpram_devices + dev_no;   		sects_to_copy = current_req->current_nr_sectors;                /* does request exceed size of device ? */		if ( XPRAM_SEC2KB(sects_to_copy) > xpram_sizes[dev_no] ) {			PRINT_WARN(" request past end of device\n");			end_request(0);			continue;		}                /* Does request start at page boundery? -- paranoia */#if 0		PRINT_DEBUG(" req %lx, sect %lx, to copy %lx, buf addr %lx\n", (unsigned long) current_req, current_req->sector, sects_to_copy, (unsigned long) current_req->buffer);#endif                buffer = current_req->buffer;#if XPRAM_SEC_IN_PG != 1                /* Does request start at an expanded storage page boundery? */                if ( current_req->sector &  (XPRAM_SEC_IN_PG - 1) ) {			PRINT_WARN(" request does not start at an expanded storage page boundery\n");			PRINT_WARN(" referenced sector: %ld\n",current_req->sector);			end_request(0);			continue;		}		/* Does request refere to partial expanded storage pages? */                if ( sects_to_copy & (XPRAM_SEC_IN_PG - 1) ) {			PRINT_WARN(" request referes to a partial expanded storage page\n");			end_request(0);			continue;		}#endif /*  XPRAM_SEC_IN_PG != 1 */		/* Is request buffer aligned with kernel pages? */		if ( ((unsigned long)buffer) & (XPRAM_PGSIZE-1) ) {			PRINT_WARN(" request buffer is not aligned with kernel pages\n");			end_request(0);			continue;		}                /* which page of expanded storage is affected first? */		page_no = (xpram_offsets[dev_no] >> XPRAM_KB_IN_PG_ORDER)			+ (current_req->sector >> XPRAM_SEC_IN_PG_ORDER); #if 0 		PRINT_DEBUG("request: %d ( dev %d, copy %d sectors, at page %d ) \n", current_req->cmd,dev_no,sects_to_copy,page_no);#endif

⌨️ 快捷键说明

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