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

📄 ataflop.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
{	int drive, type;	kdev_t device;	struct atari_format_descr fmt_desc;	struct atari_disk_type *dtp;	struct floppy_struct getprm;	int settype;	struct floppy_struct setprm;	device = inode->i_rdev;	switch (cmd) {		case BLKROSET:		case BLKROGET:		case BLKRASET:		case BLKRAGET:		case BLKFLSBUF:			return blk_ioctl(device, cmd, param);	}	drive = MINOR (device);	type  = drive >> 2;	drive &= 3;	switch (cmd) {	case FDGETPRM:	case BLKGETSIZE:		if (type) {			if (--type >= NUM_DISK_MINORS)				return -ENODEV;			if (minor2disktype[type].drive_types > DriveType)				return -ENODEV;			type = minor2disktype[type].index;			dtp = &disk_type[type];			if (UD.flags & FTD_MSG)			    printk (KERN_ERR "floppy%d: found dtp %p name %s!\n",			        drive, dtp, dtp->name);		}		else {			if (!UDT)				return -ENXIO;			else				dtp = UDT;		}		if (cmd == BLKGETSIZE)			return put_user(dtp->blocks, (unsigned long *)param);		memset((void *)&getprm, 0, sizeof(getprm));		getprm.size = dtp->blocks;		getprm.sect = dtp->spt;		getprm.head = 2;		getprm.track = dtp->blocks/dtp->spt/2;		getprm.stretch = dtp->stretch;		if (copy_to_user((void *)param, &getprm, sizeof(getprm)))			return -EFAULT;		return 0;	}	switch (cmd) {	case FDSETPRM:	case FDDEFPRM:	        /* 		 * MSch 7/96: simple 'set geometry' case: just set the		 * 'default' device params (minor == 0).		 * Currently, the drive geometry is cleared after each		 * disk change and subsequent revalidate()! simple		 * implementation of FDDEFPRM: save geometry from a		 * FDDEFPRM call and restore it in floppy_revalidate() !		 */		/* get the parameters from user space */		if (fd_ref[drive] != 1 && fd_ref[drive] != -1)			return -EBUSY;		if (copy_from_user(&setprm, (void *) param, sizeof(setprm)))			return -EFAULT;		/* 		 * first of all: check for floppy change and revalidate, 		 * or the next access will revalidate - and clear UDT :-(		 */		if (check_floppy_change(device))		        floppy_revalidate(device);		if (UD.flags & FTD_MSG)		    printk (KERN_INFO "floppy%d: setting size %d spt %d str %d!\n",			drive, setprm.size, setprm.sect, setprm.stretch);		/* what if type > 0 here? Overwrite specified entry ? */		if (type) {		        /* refuse to re-set a predefined type for now */			redo_fd_request();			return -EINVAL;		}		/* 		 * type == 0: first look for a matching entry in the type list,		 * and set the UD.disktype field to use the perdefined entry.		 * TODO: add user-defined format to head of autoprobe list ? 		 * Useful to include the user-type for future autodetection!		 */		for (settype = 0; settype < NUM_DISK_MINORS; settype++) {			int setidx = 0;			if (minor2disktype[settype].drive_types > DriveType) {				/* skip this one, invalid for drive ... */				continue;			}			setidx = minor2disktype[settype].index;			dtp = &disk_type[setidx];			/* found matching entry ?? */			if (   dtp->blocks  == setprm.size 			    && dtp->spt     == setprm.sect			    && dtp->stretch == setprm.stretch ) {				if (UD.flags & FTD_MSG)				    printk (KERN_INFO "floppy%d: setting %s %p!\n",				        drive, dtp->name, dtp);				UDT = dtp;				floppy_sizes[drive] = UDT->blocks >> 1;				if (cmd == FDDEFPRM) {				  /* save settings as permanent default type */				  default_params[drive].name    = dtp->name;				  default_params[drive].spt     = dtp->spt;				  default_params[drive].blocks  = dtp->blocks;				  default_params[drive].fdc_speed = dtp->fdc_speed;				  default_params[drive].stretch = dtp->stretch;				}								return 0;			}		}		/* no matching disk type found above - setting user_params */	       	if (cmd == FDDEFPRM) {			/* set permanent type */			dtp = &default_params[drive];		} else			/* set user type (reset by disk change!) */			dtp = &user_params[drive];		dtp->name   = "user format";		dtp->blocks = setprm.size;		dtp->spt    = setprm.sect;		if (setprm.sect > 14) 			dtp->fdc_speed = 3;		else			dtp->fdc_speed = 0;		dtp->stretch = setprm.stretch;		if (UD.flags & FTD_MSG)			printk (KERN_INFO "floppy%d: blk %d spt %d str %d!\n",				drive, dtp->blocks, dtp->spt, dtp->stretch);		/* sanity check */		if (!dtp || setprm.track != dtp->blocks/dtp->spt/2 ||		    setprm.head != 2) {			redo_fd_request();			return -EINVAL;		}		UDT = dtp;		floppy_sizes[drive] = UDT->blocks >> 1;		return 0;	case FDMSGON:		UD.flags |= FTD_MSG;		return 0;	case FDMSGOFF:		UD.flags &= ~FTD_MSG;		return 0;	case FDSETEMSGTRESH:		return -EINVAL;	case FDFMTBEG:		return 0;	case FDFMTTRK:		if (fd_ref[drive] != 1 && fd_ref[drive] != -1)			return -EBUSY;		if (copy_from_user(&fmt_desc, (void *) param, sizeof(fmt_desc)))			return -EFAULT;		return do_format(device, &fmt_desc);	case FDCLRPRM:		UDT = NULL;		/* MSch: invalidate default_params */		default_params[drive].blocks  = 0;		floppy_sizes[drive] = MAX_DISK_SIZE;		return invalidate_drive (device);	case FDFMTEND:	case FDFLUSH:		return invalidate_drive(device);	}	return -EINVAL;}/* Initialize the 'unit' variable for drive 'drive' */static void __init fd_probe( int drive ){	UD.connected = 0;	UDT  = NULL;	if (!fd_test_drive_present( drive ))		return;	UD.connected = 1;	UD.track     = 0;	switch( UserSteprate[drive] ) {	case 2:		UD.steprate = FDCSTEP_2;		break;	case 3:		UD.steprate = FDCSTEP_3;		break;	case 6:		UD.steprate = FDCSTEP_6;		break;	case 12:		UD.steprate = FDCSTEP_12;		break;	default: /* should be -1 for "not set by user" */		if (ATARIHW_PRESENT( FDCSPEED ) || MACH_IS_MEDUSA)			UD.steprate = FDCSTEP_3;		else			UD.steprate = FDCSTEP_6;		break;	}	MotorOn = 1;	/* from probe restore operation! */}/* This function tests the physical presence of a floppy drive (not * whether a disk is inserted). This is done by issuing a restore * command, waiting max. 2 seconds (that should be enough to move the * head across the whole disk) and looking at the state of the "TR00" * signal. This should now be raised if there is a drive connected * (and there is no hardware failure :-) Otherwise, the drive is * declared absent. */static int __init fd_test_drive_present( int drive ){	unsigned long timeout;	unsigned char status;	int ok;		if (drive >= (MACH_IS_FALCON ? 1 : 2)) return( 0 );	fd_select_drive( drive );	/* disable interrupt temporarily */	atari_turnoff_irq( IRQ_MFP_FDC );	FDC_WRITE (FDCREG_TRACK, 0xff00);	FDC_WRITE( FDCREG_CMD, FDCCMD_RESTORE | FDCCMDADD_H | FDCSTEP_6 );	timeout = jiffies + 2*HZ+HZ/2;	while (time_before(jiffies, timeout))		if (!(mfp.par_dt_reg & 0x20))			break;	status = FDC_READ( FDCREG_STATUS );	ok = (status & FDCSTAT_TR00) != 0;	/* force interrupt to abort restore operation (FDC would try	 * about 50 seconds!) */	FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );	udelay(500);	status = FDC_READ( FDCREG_STATUS );	udelay(20);	if (ok) {		/* dummy seek command to make WP bit accessible */		FDC_WRITE( FDCREG_DATA, 0 );		FDC_WRITE( FDCREG_CMD, FDCCMD_SEEK );		while( mfp.par_dt_reg & 0x20 )			;		status = FDC_READ( FDCREG_STATUS );	}	atari_turnon_irq( IRQ_MFP_FDC );	return( ok );}/* Look how many and which kind of drives are connected. If there are * floppies, additionally start the disk-change and motor-off timers. */static void __init config_types( void ){	int drive, cnt = 0;	/* for probing drives, set the FDC speed to 8 MHz */	if (ATARIHW_PRESENT(FDCSPEED))		dma_wd.fdc_speed = 0;	printk(KERN_INFO "Probing floppy drive(s):\n");	for( drive = 0; drive < FD_MAX_UNITS; drive++ ) {		fd_probe( drive );		if (UD.connected) {			printk(KERN_INFO "fd%d\n", drive);			++cnt;		}	}	if (FDC_READ( FDCREG_STATUS ) & FDCSTAT_BUSY) {		/* If FDC is still busy from probing, give it another FORCI		 * command to abort the operation. If this isn't done, the FDC		 * will interrupt later and its IRQ line stays low, because		 * the status register isn't read. And this will block any		 * interrupts on this IRQ line :-(		 */		FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );		udelay(500);		FDC_READ( FDCREG_STATUS );		udelay(20);	}		if (cnt > 0) {		start_motor_off_timer();		if (cnt == 1) fd_select_drive( 0 );		start_check_change_timer();	}}/* * 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, type;	int old_dev;	if (!filp) {		DPRINT (("Weird, open called with filp=0\n"));		return -EIO;	}	drive = MINOR(inode->i_rdev) & 3;	type  = MINOR(inode->i_rdev) >> 2;	DPRINT(("fd_open: type=%d\n",type));	if (drive >= FD_MAX_UNITS || type > NUM_DISK_MINORS)		return -ENXIO;	old_dev = fd_device[drive];	if (fd_ref[drive] && old_dev != MINOR(inode->i_rdev))		return -EBUSY;	if (fd_ref[drive] == -1 || (fd_ref[drive] && filp->f_flags & O_EXCL))		return -EBUSY;	if (filp->f_flags & O_EXCL)		fd_ref[drive] = -1;	else		fd_ref[drive]++;	fd_device[drive] = MINOR(inode->i_rdev);	if (old_dev && old_dev != MINOR(inode->i_rdev))		invalidate_buffers(MKDEV(FLOPPY_MAJOR, old_dev));	if (filp->f_flags & O_NDELAY)		return 0;	if (filp->f_mode & 3) {		check_disk_change(inode->i_rdev);		if (filp->f_mode & 2) {			if (UD.wpstat) {				floppy_release(inode, filp);				return -EROFS;			}		}	}	return 0;}static int floppy_release( struct inode * inode, struct file * filp ){	int drive = MINOR(inode->i_rdev) & 3;	if (fd_ref[drive] < 0)		fd_ref[drive] = 0;	else if (!fd_ref[drive]--) {		printk(KERN_ERR "floppy_release with fd_ref == 0");		fd_ref[drive] = 0;	}	return 0;}static struct block_device_operations floppy_fops = {	owner:			THIS_MODULE,	open:			floppy_open,	release:		floppy_release,	ioctl:			fd_ioctl,	check_media_change:	check_floppy_change,	revalidate:		floppy_revalidate,};int __init atari_floppy_init (void){	int i;	if (!MACH_IS_ATARI)		/* Amiga, Mac, ... don't have Atari-compatible floppy :-) */		return -ENXIO;	if (MACH_IS_HADES)		/* Hades doesn't have Atari-compatible floppy */		return -ENXIO;	if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {		printk(KERN_ERR "Unable to get major %d for floppy\n",MAJOR_NR);		return -EBUSY;	}	if (UseTrackbuffer < 0)		/* not set by user -> use default: for now, we turn		   track buffering off for all Medusas, though it		   could be used with ones that have a counter		   card. But the test is too hard :-( */		UseTrackbuffer = !MACH_IS_MEDUSA;	/* initialize variables */	SelectedDrive = -1;	BufferDrive = -1;	DMABuffer = atari_stram_alloc(BUFFER_SIZE+512, "ataflop");	if (!DMABuffer) {		printk(KERN_ERR "atari_floppy_init: cannot get dma buffer\n");		unregister_blkdev(MAJOR_NR, "fd");		return -ENOMEM;	}	TrackBuffer = DMABuffer + 512;	PhysDMABuffer = virt_to_phys(DMABuffer);	PhysTrackBuffer = virt_to_phys(TrackBuffer);	BufferDrive = BufferSide = BufferTrack = -1;	for (i = 0; i < FD_MAX_UNITS; i++) {		unit[i].track = -1;		unit[i].flags = 0;	}	for (i = 0; i < 256; i++)		if ((i >> 2) > 0 && (i >> 2) <= NUM_DISK_MINORS) {			int type = minor2disktype[(i >> 2) - 1].index;			floppy_sizes[i] = disk_type[type].blocks >> 1;		} else			floppy_sizes[i] = MAX_DISK_SIZE;	blk_size[MAJOR_NR] = floppy_sizes;	blksize_size[MAJOR_NR] = floppy_blocksizes;	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);	printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n",	       DriveType == 0 ? 'D' : DriveType == 1 ? 'H' : 'E',	       UseTrackbuffer ? "" : "no ");	config_types();	(void)do_floppy; /* avoid warning about unused variable */	return 0;}void __init atari_floppy_setup( char *str, int *ints ){	int i;		if (ints[0] < 1) {		printk(KERN_ERR "ataflop_setup: no arguments!\n" );		return;	}	else if (ints[0] > 2+FD_MAX_UNITS) {		printk(KERN_ERR "ataflop_setup: too many arguments\n" );	}	if (ints[1] < 0 || ints[1] > 2)		printk(KERN_ERR "ataflop_setup: bad drive type\n" );	else		DriveType = ints[1];	if (ints[0] >= 2)		UseTrackbuffer = (ints[2] > 0);	for( i = 3; i <= ints[0] && i-3 < FD_MAX_UNITS; ++i ) {		if (ints[i] != 2 && ints[i] != 3 && ints[i] != 6 && ints[i] != 12)			printk(KERN_ERR "ataflop_setup: bad steprate\n" );		else			UserSteprate[i-3] = ints[i];	}}#ifdef MODULEMODULE_LICENSE("GPL");int init_module (void){	if (!MACH_IS_ATARI)		return -ENXIO;	return atari_floppy_init ();}void cleanup_module (void){	unregister_blkdev(MAJOR_NR, "fd");	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));	del_timer_sync(&fd_timer);	atari_stram_free( DMABuffer );}#endif

⌨️ 快捷键说明

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