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

📄 ataflop.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
}static void fd_rwsec_done( int status ){	DPRINT(("fd_rwsec_done()\n"));	if (read_track) {		del_timer(&readtrack_timer);		if (!MultReadInProgress)			return;		MultReadInProgress = 0;	}	fd_rwsec_done1(status);}static void fd_rwsec_done1(int status){	unsigned int track;	stop_timeout();		/* Correct the track if stretch != 0 */	if (SUDT->stretch) {		track = FDC_READ( FDCREG_TRACK);		MFPDELAY();		FDC_WRITE( FDCREG_TRACK, track << SUDT->stretch);	}	if (!UseTrackbuffer) {		dma_wd.dma_mode_status = 0x90;		MFPDELAY();		if (!(dma_wd.dma_mode_status & 0x01)) {			printk(KERN_ERR "fd%d: DMA error\n", SelectedDrive );			goto err_end;		}	}	MFPDELAY();	if (ReqCmd == WRITE && (status & FDCSTAT_WPROT)) {		printk(KERN_NOTICE "fd%d: is write protected\n", SelectedDrive );		goto err_end;	}		if ((status & FDCSTAT_RECNF) &&	    /* RECNF is no error after a multiple read when the FDC	       searched for a non-existent sector! */	    !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) {		if (Probing) {			if (SUDT > disk_type) {			    if (SUDT[-1].blocks > ReqBlock) {				/* try another disk type */				SUDT--;				floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;			    } else				Probing = 0;			}			else {				if (SUD.flags & FTD_MSG)					printk(KERN_INFO "fd%d: Auto-detected floppy type %s\n",					       SelectedDrive, SUDT->name );				Probing=0;			}		} else {	/* record not found, but not probing. Maybe stretch wrong ? Restart probing */			if (SUD.autoprobe) {				SUDT = disk_type + StartDiskType[DriveType];				floppy_sizes[SelectedDrive] = SUDT->blocks >> 1;				Probing = 1;			}		}		if (Probing) {			if (ATARIHW_PRESENT(FDCSPEED)) {				dma_wd.fdc_speed = SUDT->fdc_speed;				MFPDELAY();			}			setup_req_params( SelectedDrive );			BufferDrive = -1;			do_fd_action( SelectedDrive );			return;		}		printk(KERN_ERR "fd%d: sector %d not found (side %d, track %d)\n",		       SelectedDrive, FDC_READ (FDCREG_SECTOR), ReqSide, ReqTrack );		goto err_end;	}	if (status & FDCSTAT_CRC) {		printk(KERN_ERR "fd%d: CRC error (side %d, track %d, sector %d)\n",		       SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );		goto err_end;	}	if (status & FDCSTAT_LOST) {		printk(KERN_ERR "fd%d: lost data (side %d, track %d, sector %d)\n",		       SelectedDrive, ReqSide, ReqTrack, FDC_READ (FDCREG_SECTOR) );		goto err_end;	}	Probing = 0;		if (ReqCmd == READ) {		if (!read_track) {			void *addr;			addr = ATARIHW_PRESENT( EXTD_DMA ) ? ReqData : DMABuffer;			dma_cache_maintenance( virt_to_phys(addr), 512, 0 );			if (!ATARIHW_PRESENT( EXTD_DMA ))				copy_buffer (addr, ReqData);		} else {			dma_cache_maintenance( PhysTrackBuffer, MaxSectors[DriveType] * 512, 0 );			BufferDrive = SelectedDrive;			BufferSide  = ReqSide;			BufferTrack = ReqTrack;			copy_buffer (SECTOR_BUFFER (ReqSector), ReqData);		}	}  	if (++ReqCnt < CURRENT->current_nr_sectors) {		/* read next sector */		setup_req_params( SelectedDrive );		do_fd_action( SelectedDrive );	}	else {		/* all sectors finished */		CURRENT->nr_sectors -= CURRENT->current_nr_sectors;		CURRENT->sector += CURRENT->current_nr_sectors;		end_request( 1 );		redo_fd_request();	}	return;    err_end:	BufferDrive = -1;	fd_error();}static void fd_writetrack( void ){	unsigned long paddr, flags;	unsigned int track;		DPRINT(("fd_writetrack() Tr=%d Si=%d\n", ReqTrack, ReqSide ));	paddr = PhysTrackBuffer;	dma_cache_maintenance( paddr, BUFFER_SIZE, 1 );	fd_select_side( ReqSide );  	/* Cheat for track if stretch != 0 */	if (SUDT->stretch) {		track = FDC_READ( FDCREG_TRACK);		MFPDELAY();		FDC_WRITE(FDCREG_TRACK,track >> SUDT->stretch);	}	udelay(40);  	/* Setup DMA */	save_flags(flags);  	cli();	dma_wd.dma_lo = (unsigned char)paddr;	MFPDELAY();	paddr >>= 8;	dma_wd.dma_md = (unsigned char)paddr;	MFPDELAY();	paddr >>= 8;	if (ATARIHW_PRESENT( EXTD_DMA ))		st_dma_ext_dmahi = (unsigned short)paddr;	else		dma_wd.dma_hi = (unsigned char)paddr;	MFPDELAY();	restore_flags(flags);  	/* Clear FIFO and switch DMA to correct mode */  	dma_wd.dma_mode_status = 0x190;  	MFPDELAY();	dma_wd.dma_mode_status = 0x90;  	MFPDELAY();	dma_wd.dma_mode_status = 0x190;	MFPDELAY();  	/* How many sectors for DMA */	dma_wd.fdc_acces_seccount = BUFFER_SIZE/512;	udelay(40);    	/* Start operation */	dma_wd.dma_mode_status = FDCSELREG_STP | 0x100;	udelay(40);	SET_IRQ_HANDLER( fd_writetrack_done );	dma_wd.fdc_acces_seccount = FDCCMD_WRTRA | get_head_settle_flag(); 	MotorOn = 1;	start_timeout();	/* wait for interrupt */}static void fd_writetrack_done( int status ){	DPRINT(("fd_writetrack_done()\n"));	stop_timeout();	if (status & FDCSTAT_WPROT) {		printk(KERN_NOTICE "fd%d: is write protected\n", SelectedDrive );		goto err_end;	}		if (status & FDCSTAT_LOST) {		printk(KERN_ERR "fd%d: lost data (side %d, track %d)\n",				SelectedDrive, ReqSide, ReqTrack );		goto err_end;	}	wake_up( &format_wait );	return;  err_end:	fd_error();}static void fd_times_out( unsigned long dummy ){	atari_disable_irq( IRQ_MFP_FDC );	if (!FloppyIRQHandler) goto end; /* int occurred after timer was fired, but					  * before we came here... */	SET_IRQ_HANDLER( NULL );	/* If the timeout occurred while the readtrack_check timer was	 * active, we need to cancel it, else bad things will happen */	if (UseTrackbuffer)		del_timer( &readtrack_timer );	FDC_WRITE( FDCREG_CMD, FDCCMD_FORCI );	udelay( 25 );		printk(KERN_ERR "floppy timeout\n" );	fd_error();  end:	atari_enable_irq( IRQ_MFP_FDC );}/* The (noop) seek operation here is needed to make the WP bit in the * FDC status register accessible for check_change. If the last disk * operation would have been a RDSEC, this bit would always read as 0 * no matter what :-( To save time, the seek goes to the track we're * already on. */static void finish_fdc( void ){	if (!NeedSeek) {		finish_fdc_done( 0 );	}	else {		DPRINT(("finish_fdc: dummy seek started\n"));		FDC_WRITE (FDCREG_DATA, SUD.track);		SET_IRQ_HANDLER( finish_fdc_done );		FDC_WRITE (FDCREG_CMD, FDCCMD_SEEK);		MotorOn = 1;		start_timeout();		/* we must wait for the IRQ here, because the ST-DMA		   is released immediately afterwards and the interrupt		   may be delivered to the wrong driver. */	  }}static void finish_fdc_done( int dummy ){	unsigned long flags;	DPRINT(("finish_fdc_done entered\n"));	stop_timeout();	NeedSeek = 0;	if (timer_pending(&fd_timer) && time_before(fd_timer.expires, jiffies + 5))		/* If the check for a disk change is done too early after this		 * last seek command, the WP bit still reads wrong :-((		 */		mod_timer(&fd_timer, jiffies + 5);	else		start_check_change_timer();	start_motor_off_timer();	save_flags(flags);	cli();	stdma_release();	fdc_busy = 0;	wake_up( &fdc_wait );	restore_flags(flags);	DPRINT(("finish_fdc() finished\n"));}/* Prevent "aliased" accesses. */static int fd_ref[4] = { 0,0,0,0 };static int fd_device[4] = { 0,0,0,0 };/* * Current device number. Taken either from the block header or from the * format request descriptor. */#define CURRENT_DEVICE (CURRENT->rq_dev)/* Current error count. */#define CURRENT_ERRORS (CURRENT->errors)/* dummy for blk.h */static void floppy_off( unsigned int nr) {}/* The detection of disk changes is a dark chapter in Atari history :-( * Because the "Drive ready" signal isn't present in the Atari * hardware, one has to rely on the "Write Protect". This works fine, * as long as no write protected disks are used. TOS solves this * problem by introducing tri-state logic ("maybe changed") and * looking at the serial number in block 0. This isn't possible for * Linux, since the floppy driver can't make assumptions about the * filesystem used on the disk and thus the contents of block 0. I've * chosen the method to always say "The disk was changed" if it is * unsure whether it was. This implies that every open or mount * invalidates the disk buffers if you work with write protected * disks. But at least this is better than working with incorrect data * due to unrecognised disk changes. */static int check_floppy_change (kdev_t dev){	unsigned int drive = MINOR(dev) & 0x03;	if (MAJOR(dev) != MAJOR_NR) {		printk(KERN_ERR "floppy_changed: not a floppy\n");		return 0;	}		if (test_bit (drive, &fake_change)) {		/* simulated change (e.g. after formatting) */		return 1;	}	if (test_bit (drive, &changed_floppies)) {		/* surely changed (the WP signal changed at least once) */		return 1;	}	if (UD.wpstat) {		/* WP is on -> could be changed: to be sure, buffers should be		 * invalidated...		 */		return 1;	}	return 0;}static int floppy_revalidate (kdev_t dev){	int drive = MINOR(dev) & 3;	if (test_bit(drive, &changed_floppies) ||	    test_bit(drive, &fake_change) ||	    unit[drive].disktype == 0) {		if (UD.flags & FTD_MSG)			printk(KERN_ERR "floppy: clear format %p!\n", UDT);		BufferDrive = -1;		clear_bit(drive, &fake_change);		clear_bit(drive, &changed_floppies);		/* MSch: clearing geometry makes sense only for autoprobe		   formats, for 'permanent user-defined' parameter:		   restore default_params[] here if flagged valid! */		if (default_params[drive].blocks == 0)			UDT = 0;		else			UDT = &default_params[drive];	}	return 0;}static __inline__ void copy_buffer(void *from, void *to){	ulong	*p1 = (ulong *)from, *p2 = (ulong *)to;	int		cnt;	for( cnt = 512/4; cnt; cnt-- )		*p2++ = *p1++;}/* This sets up the global variables describing the current request. */static void setup_req_params( int drive ){	int block = ReqBlock + ReqCnt;	ReqTrack = block / UDT->spt;	ReqSector = block - ReqTrack * UDT->spt + 1;	ReqSide = ReqTrack & 1;	ReqTrack >>= 1;	ReqData = ReqBuffer + 512 * ReqCnt;	if (UseTrackbuffer)		read_track = (ReqCmd == READ && CURRENT_ERRORS == 0);	else		read_track = 0;	DPRINT(("Request params: Si=%d Tr=%d Se=%d Data=%08lx\n",ReqSide,			ReqTrack, ReqSector, (unsigned long)ReqData ));}static void redo_fd_request(void){	int device, drive, type;  	DPRINT(("redo_fd_request: CURRENT=%08lx CURRENT->dev=%04x CURRENT->sector=%ld\n",		(unsigned long)CURRENT, !QUEUE_EMPTY ? CURRENT->rq_dev : 0,		!QUEUE_EMPTY ? CURRENT->sector : 0 ));	IsFormatting = 0;	if (!QUEUE_EMPTY && CURRENT->rq_status == RQ_INACTIVE){		return;	}repeat:    	if (QUEUE_EMPTY)		goto the_end;	if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)		panic(DEVICE_NAME ": request list destroyed");	if (CURRENT->bh && !buffer_locked(CURRENT->bh))		panic(DEVICE_NAME ": block not locked");	device = MINOR(CURRENT_DEVICE);	drive = device & 3;	type = device >> 2;		if (!UD.connected) {		/* drive not connected */		printk(KERN_ERR "Unknown Device: fd%d\n", drive );		end_request(0);		goto repeat;	}			if (type == 0) {		if (!UDT) {			Probing = 1;			UDT = disk_type + StartDiskType[DriveType];			floppy_sizes[drive] = UDT->blocks >> 1;			UD.autoprobe = 1;		}	} 	else {		/* user supplied disk type */		if (--type >= NUM_DISK_MINORS) {			printk(KERN_WARNING "fd%d: invalid disk format", drive );			end_request( 0 );			goto repeat;		}		if (minor2disktype[type].drive_types > DriveType)  {			printk(KERN_WARNING "fd%d: unsupported disk format", drive );			end_request( 0 );			goto repeat;		}		type = minor2disktype[type].index;		UDT = &disk_type[type];		floppy_sizes[drive] = UDT->blocks >> 1;		UD.autoprobe = 0;	}		if (CURRENT->sector + 1 > UDT->blocks) {		end_request(0);		goto repeat;	}	/* stop deselect timer */	del_timer( &motor_off_timer );			ReqCnt = 0;	ReqCmd = CURRENT->cmd;	ReqBlock = CURRENT->sector;	ReqBuffer = CURRENT->buffer;	setup_req_params( drive );	do_fd_action( drive );	return;  the_end:	finish_fdc();}void do_fd_request(request_queue_t * q){ 	unsigned long flags;	DPRINT(("do_fd_request for pid %d\n",current->pid));	while( fdc_busy ) sleep_on( &fdc_wait );	fdc_busy = 1;	stdma_lock(floppy_irq, NULL);	atari_disable_irq( IRQ_MFP_FDC );	save_flags(flags);	/* The request function is called with ints	sti();				 * disabled... so must save the IPL for later */ 	redo_fd_request();	restore_flags(flags);	atari_enable_irq( IRQ_MFP_FDC );}static int invalidate_drive(kdev_t rdev){	/* invalidate the buffer track to force a reread */	BufferDrive = -1;	set_bit(MINOR(rdev) & 3, &fake_change);	check_disk_change(rdev);	return 0;}static int fd_ioctl(struct inode *inode, struct file *filp,		    unsigned int cmd, unsigned long param)

⌨️ 快捷键说明

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