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

📄 jsflash.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#if 0	/*	 * This code is ok, except that counter based timeout	 * has no place in this world. Let's just drop timeouts...	 */	{		int i;		__u32 x;		for (i = 0; i < 1000000; i++) {			x = jsf_inl(p);			if ((x & 0x80808080) == 0x80808080) break;		}		if ((x & 0x80808080) != 0x80808080) {			printk("jsf0: erase timeout with 0x%08x\n", x);		} else {			printk("jsf0: erase done with 0x%08x\n", x);		}	}#else	jsf_wait(p);#endif	return 0;}/* * Program a block of flash. * Very simple because we can do it byte by byte anyway. */static int jsf_ioctl_program(unsigned long arg){	struct jsflash_program_arg abuf;	char *uptr;	unsigned long p;	unsigned int togo;	union {		unsigned int n;		char s[4];	} b;	if (verify_area(VERIFY_READ, (void *)arg, JSFPRGSZ))		return -EFAULT; 	copy_from_user(&abuf, (char *)arg, JSFPRGSZ);	p = abuf.off;	togo = abuf.size;	if ((togo & 3) || (p & 3)) return -EINVAL;	uptr = (char *) (unsigned long) abuf.data;	if (verify_area(VERIFY_READ, uptr, togo))		return -EFAULT;	while (togo != 0) {		togo -= 4;		copy_from_user(&b.s[0], uptr, 4);		jsf_write4(p, b.n);		p += 4;		uptr += 4;	}	return 0;}static int jsf_ioctl(struct inode *inode, struct file *f, unsigned int cmd,    unsigned long arg){	int error = -ENOTTY;	if (!capable(CAP_SYS_ADMIN))		return -EPERM;	switch (cmd) {	case JSFLASH_IDENT:		if (verify_area(VERIFY_WRITE, (void *)arg, JSFIDSZ))			return -EFAULT; 		copy_to_user(arg, &jsf0.id, JSFIDSZ);		error = 0;		break;	case JSFLASH_ERASE:		error = jsf_ioctl_erase(arg);		break;	case JSFLASH_PROGRAM:		error = jsf_ioctl_program(arg);		break;	}	return error;}static int jsfd_ioctl(struct inode *inode, struct file *file,    unsigned int cmd, unsigned long arg){	int dev;	if (!capable(CAP_SYS_ADMIN))		return -EPERM;	if (!inode)		return -EINVAL;	if ((dev = MINOR(inode->i_rdev)) >= JSF_MAX) return -ENODEV;	switch (cmd) {	case BLKGETSIZE:		return put_user(jsfd_bytesizes[dev] >> 9, (long *) arg);#if 0	case BLKROSET:	case BLKROGET:	case BLKSSZGET:		return blk_ioctl(inode->i_rdev, cmd, arg);#endif	/* case BLKFLSBUF: */	/* Program, then read, what happens? Stale? */	default: ;	}	return -ENOTTY;}static int jsf_mmap(struct file * file, struct vm_area_struct * vma){	return -ENXIO;}static int jsf_open(struct inode * inode, struct file * filp){	if (jsf0.base == 0) return -ENXIO;	if (test_and_set_bit(0, (void *)&jsf0.busy) != 0)		return -EBUSY;	return 0;	/* XXX What security? */}static int jsfd_open(struct inode *inode, struct file *file){	struct jsfd_part *jdp;	int dev;	if (!inode)		return -EINVAL;	dev = MINOR(inode->i_rdev);	if (dev >= JSF_MAX || (dev & JSF_PART_MASK) >= JSF_NPART) {		printk(KERN_ALERT "jsfd_open: illegal minor %d\n", dev);		return -ENODEV;	}	jdp = &jsf0.dv[dev];	jdp->refcnt++;	MOD_INC_USE_COUNT;	return 0;}static int jsf_release(struct inode *inode, struct file *file){	lock_kernel();	jsf0.busy = 0;	unlock_kernel();	return 0;}static int jsfd_release(struct inode *inode, struct file *file){	struct jsfd_part *jdp;	int dev;	if (!inode)		return -ENODEV;	dev = MINOR(inode->i_rdev);	if (dev >= JSF_MAX || (dev & JSF_PART_MASK) >= JSF_NPART) {		printk(KERN_ALERT "jsfd_release: illegal minor %d\n", dev);		return -ENODEV;	}	jdp = &jsf0.dv[dev];	if (jdp->refcnt <= 0) {		printk(KERN_ALERT "jsfd_release: bad ref on minor %d\n", dev);	} else {		--jdp->refcnt;	}	/* N.B. Doesn't lo->file need an fput?? */	MOD_DEC_USE_COUNT;	return 0;}static struct file_operations jsf_fops = {	owner:		THIS_MODULE,	llseek:		jsf_lseek,	read:		jsf_read,	write:		jsf_write,	ioctl:		jsf_ioctl,	mmap:		jsf_mmap,	open:		jsf_open,	release:	jsf_release,};static struct miscdevice jsf_dev = { JSF_MINOR, "jsflash", &jsf_fops };static struct block_device_operations jsfd_fops = {	open:		jsfd_open,	release:	jsfd_release,	ioctl:		jsfd_ioctl,};EXPORT_NO_SYMBOLS;int jsflash_init(void){	int rc;	struct jsflash *jsf;	int node;	char banner[128];	struct linux_prom_registers reg0;	node = prom_getchild(prom_root_node);	node = prom_searchsiblings(node, "flash-memory");	if (node != 0 && node != -1) {		if (prom_getproperty(node, "reg",		    (char *)&reg0, sizeof(reg0)) == -1) {			printk("jsflash: no \"reg\" property\n");			return -ENXIO;		}		if (reg0.which_io != 0) {			printk("jsflash: bus number nonzero: 0x%x:%x\n",			    reg0.which_io, reg0.phys_addr);			return -ENXIO;		}		/*		 * Flash may be somewhere else, for instance on Ebus.		 * So, don't do the following check for IIep flash space.		 */#if 0		if ((reg0.phys_addr >> 24) != 0x20) {			printk("jsflash: suspicious address: 0x%x:%x\n",			    reg0.which_io, reg0.phys_addr);			return -ENXIO;		}#endif		if ((int)reg0.reg_size <= 0) {			printk("jsflash: bad size 0x%x\n", (int)reg0.reg_size);			return -ENXIO;		}	} else {		/* XXX Remove this code once PROLL ID12 got widespread */		printk("jsflash: no /flash-memory node, use PROLL >= 12\n");		prom_getproperty(prom_root_node, "banner-name", banner, 128);		if (strcmp (banner, "JavaStation-NC") != 0 &&		    strcmp (banner, "JavaStation-E") != 0) {			return -ENXIO;		}		reg0.which_io = 0;		reg0.phys_addr = 0x20400000;		reg0.reg_size  = 0x00800000;	}	/* Let us be really paranoid for modifications to probing code. */	/* extern enum sparc_cpu sparc_cpu_model; */ /* in <asm/system.h> */	if (sparc_cpu_model != sun4m) {		/* We must be on sun4m because we use MMU Bypass ASI. */		return -ENXIO;	}	if (jsf0.base == 0) {		jsf = &jsf0;		jsf->base = reg0.phys_addr;		jsf->size = reg0.reg_size;		/* XXX Redo the userland interface. */		jsf->id.off = JSF_BASE_ALL;		jsf->id.size = 0x01000000;	/* 16M - all segments */		strcpy(jsf->id.name, "Krups_all");		jsf->dv[0].dbase = jsf->base;		jsf->dv[0].dsize = jsf->size;		jsf->dv[1].dbase = jsf->base + 1024;		jsf->dv[1].dsize = jsf->size - 1024;		jsf->dv[2].dbase = JSF_BASE_ALL;		jsf->dv[2].dsize = 0x01000000;		printk("Espresso Flash @0x%lx [%d MB]\n", jsf->base,		    (int) (jsf->size / (1024*1024)));	}	if ((rc = misc_register(&jsf_dev)) != 0) {		printk(KERN_ERR "jsf: unable to get misc minor %d\n",		    JSF_MINOR);		jsf0.base = 0;		return rc;	}	return 0;}int jsfd_init(void) {	struct jsflash *jsf;	struct jsfd_part *jdp;	int i;	if (jsf0.base == 0) {		return -ENXIO;	}	if (register_blkdev(JSFD_MAJOR, "jsfd", &jsfd_fops)) {		printk("jsfd_init: unable to get major number %d\n",		    JSFD_MAJOR);		return -EIO;	}	blksize_size[JSFD_MAJOR] = jsfd_blksizes;	blk_size[JSFD_MAJOR] = jsfd_sizes;	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);	/* blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0); */	for (i = 0; i < JSF_MAX; i++) {		if ((i & JSF_PART_MASK) >= JSF_NPART) continue;		jsf = &jsf0;	/* actually, &jsfv[i >> JSF_PART_BITS] */		jdp = &jsf->dv[i&JSF_PART_MASK];		jdp->refcnt = 0;		jsfd_blksizes[i] = 1024;		jsfd_bytesizes[i] = jdp->dsize;		jsfd_sizes[i] = jsfd_bytesizes[i] >> 10;		register_disk(NULL, MKDEV(JSFD_MAJOR, i), 1, &jsfd_fops,				jsfd_bytesizes[i] >> 9);		set_device_ro(MKDEV(JSFD_MAJOR, i), 1);	}	return 0;}#ifdef MODULEint init_module(void) {	int rc;	if ((rc = jsflash_init()) == 0) {		jsfd_init();		return 0;	}	return rc;}void cleanup_module(void) {	/* for (all probed units) {  } */	if (jsf0.busy)		printk("jsf0: cleaning busy unit\n");	jsf0.base = 0;	jsf0.busy = 0;	misc_deregister(&jsf_dev);	if (unregister_blkdev(JSFD_MAJOR, "jsfd") != 0)		printk("jsfd: cleanup_module failed\n");	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));}#endif

⌨️ 快捷键说明

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