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

📄 ide-floppy.c

📁 at91rm9200处理器ide接口驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return (0);}/*** Send ATAPI_FORMAT_UNIT to the drive.**** Userland gives us the following structure:**** struct idefloppy_format_command {**        int nblocks;**        int blocksize;**        int flags;**        } ;**** flags is a bitmask, currently, the only defined flag is:****        0x01 - verify media after format.*/static int idefloppy_begin_format(ide_drive_t *drive,				  struct inode *inode,				  struct file *file,				  int *arg){	int blocks;	int length;	int flags;	idefloppy_pc_t pc;	if (get_user(blocks, arg)	    || get_user(length, arg+1)	    || get_user(flags, arg+2))	{		return (-EFAULT);	}	(void) idefloppy_get_capability_page (drive);	/* Get the SFRP bit */	idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);	if (idefloppy_queue_pc_tail (drive, &pc))	{                return (-EIO);        }	return (0);}/*** Get ATAPI_FORMAT_UNIT progress indication.**** Userland gives a pointer to an int.  The int is set to a progresss** indicator 0-65536, with 65536=100%.**** If the drive does not support format progress indication, we just check** the dsc bit, and return either 0 or 65536.*/static int idefloppy_get_format_progress(ide_drive_t *drive,					 struct inode *inode,					 struct file *file,					 int *arg){	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_pc_t pc;	int progress_indication=0x10000;	if (floppy->srfp)	{		idefloppy_create_request_sense_cmd(&pc);		if (idefloppy_queue_pc_tail (drive, &pc))		{			return (-EIO);		}		if (floppy->sense_key == 2 && floppy->asc == 4 &&		    floppy->ascq == 4)		{			progress_indication=floppy->progress_indication;		}		/* Else assume format_unit has finished, and we're		** at 0x10000 */	}	else	{		idefloppy_status_reg_t status;		unsigned long flags;		__save_flags(flags);		__cli();		status.all=GET_STAT();		__restore_flags(flags);		progress_indication= !status.b.dsc ? 0:0x10000;	}	if (put_user(progress_indication, arg))		return (-EFAULT);	return (0);}/* *	Our special ide-floppy ioctl's. * *	Currently there aren't any ioctl's. */static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,				 unsigned int cmd, unsigned long arg){	idefloppy_pc_t pc;	idefloppy_floppy_t *floppy = drive->driver_data;	int prevent = (arg) ? 1 : 0;	switch (cmd) {	case CDROMEJECT:		prevent = 0;		/* fall through */	case CDROM_LOCKDOOR:		if (drive->usage > 1)			return -EBUSY;		/* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */                if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {			idefloppy_create_prevent_cmd (&pc, prevent);			(void) idefloppy_queue_pc_tail (drive, &pc);		}		if (cmd == CDROMEJECT) {			idefloppy_create_start_stop_cmd (&pc, 2);			(void) idefloppy_queue_pc_tail (drive, &pc);		}		return 0;	case IDEFLOPPY_IOCTL_FORMAT_SUPPORTED:		return (0);	case IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY:		return (idefloppy_get_format_capacities(drive, inode, file,							(int *)arg));	case IDEFLOPPY_IOCTL_FORMAT_START:		if (!(file->f_mode & 2))			return (-EPERM);		{			idefloppy_floppy_t *floppy = drive->driver_data;			if (drive->usage > 1)			{				/* Don't format if someone is using the disk */				clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,					  &floppy->flags);				return -EBUSY;			}			else			{				int rc;				set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,					&floppy->flags);				rc=idefloppy_begin_format(drive, inode,							      file,							      (int *)arg);				if (rc)					clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,						  &floppy->flags);				return (rc);			/*			** Note, the bit will be cleared when the device is			** closed.  This is the cleanest way to handle the			** situation where the drive does not support			** format progress reporting.			*/			}		}	case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:		return (idefloppy_get_format_progress(drive, inode, file,						      (int *)arg));	} 	return -EIO;}/* *	Our open/release functions */static int idefloppy_open (struct inode *inode, struct file *filp, ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_pc_t pc;	#if IDEFLOPPY_DEBUG_LOG	printk (KERN_INFO "Reached idefloppy_open\n");#endif /* IDEFLOPPY_DEBUG_LOG */	MOD_INC_USE_COUNT;	if (drive->usage == 1) {		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);		/* Just in case */		idefloppy_create_test_unit_ready_cmd(&pc);		if (idefloppy_queue_pc_tail(drive, &pc)) {			idefloppy_create_start_stop_cmd (&pc, 1);			(void) idefloppy_queue_pc_tail (drive, &pc);		}		if (idefloppy_get_capacity (drive)		   && (filp->f_flags & O_NDELAY) == 0		    /*		    ** Allow O_NDELAY to open a drive without a disk, or with		    ** an unreadable disk, so that we can get the format		    ** capacity of the drive or begin the format - Sam		    */		    ) {			drive->usage--;			MOD_DEC_USE_COUNT;			return -EIO;		}		if (floppy->wp && (filp->f_mode & 2)) {			drive->usage--;			MOD_DEC_USE_COUNT;			return -EROFS;		}				set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);		/* IOMEGA Clik! drives do not support lock/unlock commands */                if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {			idefloppy_create_prevent_cmd (&pc, 1);			(void) idefloppy_queue_pc_tail (drive, &pc);		}		check_disk_change(inode->i_rdev);	}	else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags))	{		drive->usage--;		MOD_DEC_USE_COUNT;		return -EBUSY;	}	return 0;}static void idefloppy_release (struct inode *inode, struct file *filp, ide_drive_t *drive){	idefloppy_pc_t pc;	#if IDEFLOPPY_DEBUG_LOG	printk (KERN_INFO "Reached idefloppy_release\n");#endif /* IDEFLOPPY_DEBUG_LOG */	if (!drive->usage) {		idefloppy_floppy_t *floppy = drive->driver_data;		invalidate_bdev (inode->i_bdev, 0);		/* IOMEGA Clik! drives do not support lock/unlock commands */                if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {			idefloppy_create_prevent_cmd (&pc, 0);			(void) idefloppy_queue_pc_tail (drive, &pc);		}		clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);	}	MOD_DEC_USE_COUNT;}/* *	Check media change. Use a simple algorithm for now. */static int idefloppy_media_change (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;		return test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);}/* *	Revalidate the new media. Should set blk_size[] */static void idefloppy_revalidate (ide_drive_t *drive){	grok_partitions(HWIF(drive)->gd, drive->select.b.unit,			1<<PARTN_BITS,			current_capacity(drive));}/* *	Return the current floppy capacity to ide.c. */static unsigned long idefloppy_capacity (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	unsigned long capacity = floppy->blocks * floppy->bs_factor;	return capacity;}/* *	idefloppy_identify_device checks if we can support a drive, *	based on the ATAPI IDENTIFY command results. */static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id){	struct idefloppy_id_gcw gcw;#if IDEFLOPPY_DEBUG_INFO	unsigned short mask,i;	char buffer[80];#endif /* IDEFLOPPY_DEBUG_INFO */	*((unsigned short *) &gcw) = id->config;#ifdef CONFIG_PPC	/* kludge for Apple PowerBook internal zip */	if ((gcw.device_type == 5) && !strstr(id->model, "CD-ROM")	    && strstr(id->model, "ZIP"))		gcw.device_type = 0;			#endif#if IDEFLOPPY_DEBUG_INFO	printk (KERN_INFO "Dumping ATAPI Identify Device floppy parameters\n");	switch (gcw.protocol) {		case 0: case 1: sprintf (buffer, "ATA");break;		case 2:	sprintf (buffer, "ATAPI");break;		case 3: sprintf (buffer, "Reserved (Unknown to ide-floppy)");break;	}	printk (KERN_INFO "Protocol Type: %s\n", buffer);	switch (gcw.device_type) {		case 0: sprintf (buffer, "Direct-access Device");break;		case 1: sprintf (buffer, "Streaming Tape Device");break;		case 2: case 3: case 4: sprintf (buffer, "Reserved");break;		case 5: sprintf (buffer, "CD-ROM Device");break;		case 6: sprintf (buffer, "Reserved");		case 7: sprintf (buffer, "Optical memory Device");break;		case 0x1f: sprintf (buffer, "Unknown or no Device type");break;		default: sprintf (buffer, "Reserved");	}	printk (KERN_INFO "Device Type: %x - %s\n", gcw.device_type, buffer);	printk (KERN_INFO "Removable: %s\n",gcw.removable ? "Yes":"No");		switch (gcw.drq_type) {		case 0: sprintf (buffer, "Microprocessor DRQ");break;		case 1: sprintf (buffer, "Interrupt DRQ");break;		case 2: sprintf (buffer, "Accelerated DRQ");break;		case 3: sprintf (buffer, "Reserved");break;	}	printk (KERN_INFO "Command Packet DRQ Type: %s\n", buffer);	switch (gcw.packet_size) {		case 0: sprintf (buffer, "12 bytes");break;		case 1: sprintf (buffer, "16 bytes");break;		default: sprintf (buffer, "Reserved");break;	}	printk (KERN_INFO "Command Packet Size: %s\n", buffer);	printk (KERN_INFO "Model: %.40s\n",id->model);	printk (KERN_INFO "Firmware Revision: %.8s\n",id->fw_rev);	printk (KERN_INFO "Serial Number: %.20s\n",id->serial_no);	printk (KERN_INFO "Write buffer size(?): %d bytes\n",id->buf_size*512);	printk (KERN_INFO "DMA: %s",id->capability & 0x01 ? "Yes\n":"No\n");	printk (KERN_INFO "LBA: %s",id->capability & 0x02 ? "Yes\n":"No\n");	printk (KERN_INFO "IORDY can be disabled: %s",id->capability & 0x04 ? "Yes\n":"No\n");	printk (KERN_INFO "IORDY supported: %s",id->capability & 0x08 ? "Yes\n":"Unknown\n");	printk (KERN_INFO "ATAPI overlap supported: %s",id->capability & 0x20 ? "Yes\n":"No\n");	printk (KERN_INFO "PIO Cycle Timing Category: %d\n",id->tPIO);	printk (KERN_INFO "DMA Cycle Timing Category: %d\n",id->tDMA);	printk (KERN_INFO "Single Word DMA supported modes:\n");	for (i=0,mask=1;i<8;i++,mask=mask << 1) {		if (id->dma_1word & mask)			printk (KERN_INFO "   Mode %d%s\n", i, (id->dma_1word & (mask << 8)) ? " (active)" : "");	}	printk (KERN_INFO "Multi Word DMA supported modes:\n");	for (i=0,mask=1;i<8;i++,mask=mask << 1) {		if (id->dma_mword & mask)			printk (KERN_INFO "   Mode %d%s\n", i, (id->dma_mword & (mask << 8)) ? " (active)" : "");	}	if (id->field_valid & 0x0002) {		printk (KERN_INFO "Enhanced PIO Modes: %s\n",id->eide_pio_modes & 1 ? "Mode 3":"None");		if (id->eide_dma_min == 0)			sprintf (buffer, "Not supported");		else			sprintf (buffer, "%d ns",id->eide_dma_min);		printk (KERN_INFO "Minimum Multi-word DMA cycle per word: %s\n", buffer);		if (id->eide_dma_time == 0)			sprintf (buffer, "Not supported");		else			sprintf (buffer, "%d ns",id->eide_dma_time);		printk (KERN_INFO "Manufacturer\'s Recommended Multi-word cycle: %s\n", buffer);		if (id->eide_pio == 0)			sprintf (buffer, "Not supported");		else			sprintf (buffer, "%d ns",id->eide_pio);		printk (KERN_INFO "Minimum PIO cycle without IORDY: %s\n", buffer);		if (id->eide_pio_iordy == 0)			sprintf (buffer, "Not supported");		else			sprintf (buffer, "%d ns",id->eide_pio_iordy);		printk (KERN_INFO "Minimum PIO cycle with IORDY: %s\n", buffer);	} else		pr

⌨️ 快捷键说明

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