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

📄 amiflop.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef DEBUG		printk("access to track %d, sector %d, with buffer at "		       "0x%08lx\n", track, sector, data);#endif		if ((CURRENT->cmd != READ) && (CURRENT->cmd != WRITE)) {			printk(KERN_WARNING "do_fd_request: unknown command\n");			end_request(0);			goto repeat;		}		if (get_track(drive, track) == -1) {			end_request(0);			goto repeat;		}		switch (CURRENT->cmd) {		case READ:			memcpy(data, unit[drive].trackbuf + sector * 512, 512);			break;		case WRITE:			memcpy(unit[drive].trackbuf + sector * 512, data, 512);			/* keep the drive spinning while writes are scheduled */			if (!fd_motor_on(drive)) {				end_request(0);				goto repeat;			}			/*			 * setup a callback to write the track buffer			 * after a short (1 tick) delay.			 */			save_flags (flags);			cli();			unit[drive].dirty = 1;		        /* reset the timer */		        del_timer (flush_track_timer + drive);			    			flush_track_timer[drive].expires = jiffies + 1;			add_timer (flush_track_timer + drive);			restore_flags (flags);			break;		}	}	CURRENT->nr_sectors -= CURRENT->current_nr_sectors;	CURRENT->sector += CURRENT->current_nr_sectors;	end_request(1);	goto repeat;}static void do_fd_request(request_queue_t * q){	redo_fd_request();}static int fd_ioctl(struct inode *inode, struct file *filp,		    unsigned int cmd, unsigned long param){	int drive = inode->i_rdev & 3;	static struct floppy_struct getprm;	struct super_block * sb;	switch(cmd){	case HDIO_GETGEO:	{		struct hd_geometry loc;		loc.heads = unit[drive].type->heads;		loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;		loc.cylinders = unit[drive].type->tracks;		loc.start = 0;		if (copy_to_user((void *)param, (void *)&loc,				 sizeof(struct hd_geometry)))			return -EFAULT;		break;	}	case FDFMTBEG:		get_fdc(drive);		if (fd_ref[drive] > 1) {			rel_fdc();			return -EBUSY;		}		fsync_dev(inode->i_rdev);		if (fd_motor_on(drive) == 0) {			rel_fdc();			return -ENODEV;		}		if (fd_calibrate(drive) == 0) {			rel_fdc();			return -ENXIO;		}		floppy_off(drive);		rel_fdc();		break;	case FDFMTTRK:		if (param < unit[drive].type->tracks * unit[drive].type->heads)		{			get_fdc(drive);			if (fd_seek(drive,param) != 0){				memset(unit[drive].trackbuf, FD_FILL_BYTE,				       unit[drive].dtype->sects * unit[drive].type->sect_mult * 512);				non_int_flush_track(drive);			}			floppy_off(drive);			rel_fdc();		}		else			return -EINVAL;		break;	case FDFMTEND:		floppy_off(drive);		invalidate_device(inode->i_rdev, 0);		break;	case FDGETPRM:		memset((void *)&getprm, 0, sizeof (getprm));		getprm.track=unit[drive].type->tracks;		getprm.head=unit[drive].type->heads;		getprm.sect=unit[drive].dtype->sects * unit[drive].type->sect_mult;		getprm.size=unit[drive].blocks;		if (copy_to_user((void *)param,				 (void *)&getprm,				 sizeof(struct floppy_struct)))			return -EFAULT;		break;	case BLKGETSIZE:		return put_user(unit[drive].blocks,(unsigned long *)param);		break;	case BLKGETSIZE64:		return put_user((u64)unit[drive].blocks << 9, (u64 *)param);		break;	case FDSETPRM:	case FDDEFPRM:		return -EINVAL;	case FDFLUSH: /* unconditionally, even if not needed */		del_timer (flush_track_timer + drive);		non_int_flush_track(drive);		break;#ifdef RAW_IOCTL	case IOCTL_RAW_TRACK:		if (copy_to_user((void *)param, raw_buf,				 unit[drive].type->read_size))			return -EFAULT;		else			return unit[drive].type->read_size;#endif	default:		printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",		       cmd, drive);		return -ENOSYS;	}	return 0;}static void fd_probe(int dev){	unsigned long code;	int type;	int drive;	drive = dev & 3;	code = fd_get_drive_id(drive);	/* get drive type */	for (type = 0; type < num_dr_types; type++)		if (drive_types[type].code == code)			break;	if (type >= num_dr_types) {		printk(KERN_WARNING "fd_probe: unsupported drive type "		       "%08lx found\n", code);		unit[drive].type = &drive_types[num_dr_types-1]; /* FD_NODRIVE */		return;	}	unit[drive].type = drive_types + type;	unit[drive].track = -1;	unit[drive].disk = -1;	unit[drive].motor = 0;	unit[drive].busy = 0;	unit[drive].status = -1;}/* * floppy_open check for aliasing (/dev/fd0 can be the same as * /dev/PS0 etc), and disallows simultaneous access to the same * drive with different device numbers. */static int floppy_open(struct inode *inode, struct file *filp){	int drive;	int old_dev;	int system;	unsigned long flags;	drive = MINOR(inode->i_rdev) & 3;	old_dev = fd_device[drive];	if (fd_ref[drive])		if (old_dev != inode->i_rdev)			return -EBUSY;	if (unit[drive].type->code == FD_NODRIVE)		return -ENODEV;	if (filp && filp->f_mode & 3) {		check_disk_change(inode->i_rdev);		if (filp->f_mode & 2 ) {			int wrprot;			get_fdc(drive);			fd_select (drive);			wrprot = !(ciaa.pra & DSKPROT);			fd_deselect (drive);			rel_fdc();			if (wrprot)				return -EROFS;		}	}	save_flags(flags);	cli();	fd_ref[drive]++;	fd_device[drive] = inode->i_rdev;#ifdef MODULE	if (unit[drive].motor == 0)		MOD_INC_USE_COUNT;#endif	restore_flags(flags);	if (old_dev && old_dev != inode->i_rdev)		invalidate_buffers(old_dev);	system=(inode->i_rdev & 4)>>2;	unit[drive].dtype=&data_types[system];	unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*		data_types[system].sects*unit[drive].type->sect_mult;	floppy_sizes[MINOR(inode->i_rdev)] = unit[drive].blocks >> 1;	printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive,	       unit[drive].type->name, data_types[system].name);	return 0;}static int floppy_release(struct inode * inode, struct file * filp){#ifdef DEBUG	struct super_block * sb;#endif	int drive = MINOR(inode->i_rdev) & 3;	if (unit[drive].dirty == 1) {		del_timer (flush_track_timer + drive);		non_int_flush_track (drive);	}  	if (!fd_ref[drive]--) {		printk(KERN_CRIT "floppy_release with fd_ref == 0");		fd_ref[drive] = 0;	}#ifdef MODULE/* the mod_use counter is handled this way */	floppy_off (drive | 0x40000000);#endif	return 0;}/* * floppy-change is never called from an interrupt, so we can relax a bit * here, sleep etc. Note that floppy-on tries to set current_DOR to point * to the desired drive, but it will probably not survive the sleep if * several floppies are used at the same time: thus the loop. */static int amiga_floppy_change(kdev_t dev){	int drive = MINOR(dev) & 3;	int changed;	static int first_time = 1;	if (MAJOR(dev) != MAJOR_NR) {		printk(KERN_CRIT "floppy_change: not a floppy\n");		return 0;	}	if (first_time)		changed = first_time--;	else {		get_fdc(drive);		fd_select (drive);		changed = !(ciaa.pra & DSKCHANGE);		fd_deselect (drive);		rel_fdc();	}	if (changed) {		fd_probe(drive);		unit[drive].track = -1;		unit[drive].dirty = 0;		writepending = 0; /* if this was true before, too bad! */		writefromint = 0;		return 1;	}	return 0;}static struct block_device_operations floppy_fops = {	owner:			THIS_MODULE,	open:			floppy_open,	release:		floppy_release,	ioctl:			fd_ioctl,	check_media_change:	amiga_floppy_change,};void __init amiga_floppy_setup (char *str, int *ints){	printk (KERN_INFO "amiflop: Setting default df0 to %x\n", ints[1]);	fd_def_df0 = ints[1];}static int __init fd_probe_drives(void){	int drive,drives,nomem;	printk(KERN_INFO "FD: probing units\n" KERN_INFO "found ");	drives=0;	nomem=0;	for(drive=0;drive<FD_MAX_UNITS;drive++) {		fd_probe(drive);		if (unit[drive].type->code != FD_NODRIVE) {			drives++;			if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) {				printk("no mem for ");				unit[drive].type = &drive_types[num_dr_types - 1]; /* FD_NODRIVE */				drives--;				nomem = 1;			}			printk("fd%d ",drive);		}	}	if ((drives > 0) || (nomem == 0)) {		if (drives == 0)			printk("no drives");		printk("\n");		return drives;	}	printk("\n");	return -ENOMEM;}int __init amiga_floppy_init(void){	int i;	if (!AMIGAHW_PRESENT(AMI_FLOPPY))		return -ENXIO;	if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {		printk("fd: Unable to get major %d for floppy\n",MAJOR_NR);		return -EBUSY;	}	/*	 *  We request DSKPTR, DSKLEN and DSKDATA only, because the other	 *  floppy registers are too spreaded over the custom register space	 */	if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) {		printk("fd: cannot get floppy registers\n");		unregister_blkdev(MAJOR_NR,"fd");		return -EBUSY;	}	if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==	    NULL) {		printk("fd: cannot get chip mem buffer\n");		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);		unregister_blkdev(MAJOR_NR,"fd");		return -ENOMEM;	}	if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {		printk("fd: cannot get irq for dma\n");		amiga_chip_free(raw_buf);		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);		unregister_blkdev(MAJOR_NR,"fd");		return -EBUSY;	}	if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) {		printk("fd: cannot get irq for timer\n");		free_irq(IRQ_AMIGA_DSKBLK, NULL);		amiga_chip_free(raw_buf);		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);		unregister_blkdev(MAJOR_NR,"fd");		return -EBUSY;	}	if (fd_probe_drives() < 1) { /* No usable drives */		free_irq(IRQ_AMIGA_CIAA_TB, NULL);		free_irq(IRQ_AMIGA_DSKBLK, NULL);		amiga_chip_free(raw_buf);		release_mem_region(CUSTOM_PHYSADDR+0x20, 8);		unregister_blkdev(MAJOR_NR,"fd");		return -ENXIO;	}	/* initialize variables */	init_timer(&motor_on_timer);	motor_on_timer.expires = 0;	motor_on_timer.data = 0;	motor_on_timer.function = motor_on_callback;	for (i = 0; i < FD_MAX_UNITS; i++) {		init_timer(&motor_off_timer[i]);		motor_off_timer[i].expires = 0;		motor_off_timer[i].data = i|0x80000000;		motor_off_timer[i].function = fd_motor_off;		init_timer(&flush_track_timer[i]);		flush_track_timer[i].expires = 0;		flush_track_timer[i].data = i;		flush_track_timer[i].function = flush_track_callback;		unit[i].track = -1;	}	init_timer(&post_write_timer);	post_write_timer.expires = 0;	post_write_timer.data = 0;	post_write_timer.function = post_write;  	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);	blksize_size[MAJOR_NR] = floppy_blocksizes;	blk_size[MAJOR_NR] = floppy_sizes;	for (i = 0; i < 128; i++)		mfmdecode[i]=255;	for (i = 0; i < 16; i++)		mfmdecode[mfmencode[i]]=i;	/* make sure that disk DMA is enabled */	custom.dmacon = DMAF_SETCLR | DMAF_DISK;	/* init ms timer */	ciaa.crb = 8; /* one-shot, stop */	(void)do_floppy; /* avoid warning about unused variable */	return 0;}#ifdef MODULE#include <linux/version.h>int init_module(void){	if (!MACH_IS_AMIGA)		return -ENXIO;	return amiga_floppy_init();}void cleanup_module(void){	int i;	for( i = 0; i < FD_MAX_UNITS; i++)		if (unit[i].type->code != FD_NODRIVE)			kfree(unit[i].trackbuf);	free_irq(IRQ_AMIGA_CIAA_TB, NULL);	free_irq(IRQ_AMIGA_DSKBLK, NULL);	custom.dmacon = DMAF_DISK; /* disable DMA */	amiga_chip_free(raw_buf);	blk_size[MAJOR_NR] = NULL;	blksize_size[MAJOR_NR] = NULL;	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));	release_mem_region(CUSTOM_PHYSADDR+0x20, 8);	unregister_blkdev(MAJOR_NR, "fd");}#endif

⌨️ 快捷键说明

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