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

📄 ide-floppy.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 4 页
字号:
					drive->using_dma ? ", DMA":"");			}			floppy->capacity = *descriptor;			if (!length || length % 512)				printk (KERN_ERR "%s: %d bytes block size not supported\n", drive->name, length);			else {				floppy->blocks = blocks;				floppy->block_size = length;				if ((floppy->bs_factor = length / 512) != 1)					printk (KERN_NOTICE "%s: warning: non 512 bytes block size not fully supported\n", drive->name);				rc = 0;			}		}#if IDEFLOPPY_DEBUG_INFO		if (!i) printk (KERN_INFO "Descriptor 0 Code: %d\n", descriptor->dc);		printk (KERN_INFO "Descriptor %d: %dkB, %d blocks, %d sector size\n", i, blocks * length / 1024, blocks, length);#endif /* IDEFLOPPY_DEBUG_INFO */	}	(void) idefloppy_get_flexible_disk_page (drive);	drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;	return rc;}/* *	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;	if (cmd == CDROMEJECT) {		if (drive->usage > 1)			return -EBUSY;		idefloppy_create_prevent_cmd (&pc, 0);		(void) idefloppy_queue_pc_tail (drive, &pc);		idefloppy_create_start_stop_cmd (&pc, 2);		(void) idefloppy_queue_pc_tail (drive, &pc);		return 0;	} 	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) {		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)) {			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);		idefloppy_create_prevent_cmd (&pc, 1);		(void) idefloppy_queue_pc_tail (drive, &pc);		check_disk_change(inode->i_rdev);	}	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) {		invalidate_buffers (inode->i_rdev);		idefloppy_create_prevent_cmd (&pc, 0);		(void) idefloppy_queue_pc_tail (drive, &pc);	}	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		printk (KERN_INFO "According to the device, fields 64-70 are not valid.\n");#endif /* IDEFLOPPY_DEBUG_INFO */	if (gcw.protocol != 2)		printk (KERN_ERR "ide-floppy: Protocol is not ATAPI\n");	else if (gcw.device_type != 0)		printk (KERN_ERR "ide-floppy: Device type is not set to floppy\n");	else if (!gcw.removable)		printk (KERN_ERR "ide-floppy: The removable flag is not set\n");	else if (gcw.drq_type == 3) {		printk (KERN_ERR "ide-floppy: Sorry, DRQ type %d not supported\n", gcw.drq_type);	} else if (gcw.packet_size != 0) {		printk (KERN_ERR "ide-floppy: Packet size is not 12 bytes long\n");	} else		return 1;	return 0;}static void idefloppy_add_settings(ide_drive_t *drive){	int major = HWIF(drive)->major;	int minor = drive->select.b.unit << PARTN_BITS;	ide_add_setting(drive,	"bios_cyl",		SETTING_RW,					-1,			-1,			TYPE_INT,	0,	1023,				1,	1,	&drive->bios_cyl,		NULL);	ide_add_setting(drive,	"bios_head",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	255,				1,	1,	&drive->bios_head,		NULL);	ide_add_setting(drive,	"bios_sect",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	63,				1,	1,	&drive->bios_sect,		NULL);	ide_add_setting(drive,	"breada_readahead",	SETTING_RW,					BLKRAGET,		BLKRASET,		TYPE_INT,	0,	255,				1,	2,	&read_ahead[major],		NULL);	ide_add_setting(drive,	"file_readahead",	SETTING_RW,					BLKFRAGET,		BLKFRASET,		TYPE_INTA,	0,	INT_MAX,			1,	1024,	&max_readahead[major][minor],	NULL);	ide_add_setting(drive,	"max_kb_per_request",	SETTING_RW,					BLKSECTGET,		BLKSECTSET,		TYPE_INTA,	1,	255,				1,	2,	&max_sectors[major][minor],	NULL);}/* *	Driver initialization. */static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy){	struct idefloppy_id_gcw gcw;	int major = HWIF(drive)->major, i;	int minor = drive->select.b.unit << PARTN_BITS;	*((unsigned short *) &gcw) = drive->id->config;	drive->driver_data = floppy;	drive->ready_stat = 0;	memset (floppy, 0, sizeof (idefloppy_floppy_t));	floppy->drive = drive;	floppy->pc = floppy->pc_stack;	if (gcw.drq_type == 1)		set_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags);	/*	 *	We used to check revisions here. At this point however	 *	I'm giving up. Just assume they are all broken, its easier.	 *	 *	The actual reason for the workarounds was likely	 *	a driver bug after all rather than a firmware bug,	 *	and the workaround below used to hide it. It should	 *	be fixed as of version 1.9, but to be on the safe side	 *	we'll leave the limitation below for the 2.2.x tree.	 */	if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0)	{		for (i = 0; i < 1 << PARTN_BITS; i++)			max_sectors[major][minor + i] = 64;	}	(void) idefloppy_get_capacity (drive);	idefloppy_add_settings(drive);	for (i = 0; i < MAX_DRIVES; ++i) {		ide_hwif_t *hwif = HWIF(drive);		if (drive != &hwif->drives[i]) continue;		hwif->gd->de_arr[i] = drive->de;		if (drive->removable)			hwif->gd->flags[i] |= GENHD_FL_REMOVABLE;		break;	}}static int idefloppy_cleanup (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	if (ide_unregister_subdriver (drive))		return 1;	drive->driver_data = NULL;	kfree (floppy);	return 0;}#ifdef CONFIG_PROC_FSstatic ide_proc_entry_t idefloppy_proc[] = {	{ "geometry",	S_IFREG|S_IRUGO,	proc_ide_read_geometry,	NULL },	{ NULL, 0, NULL, NULL }};#else#define	idefloppy_proc	NULL#endif	/* CONFIG_PROC_FS *//* *	IDE subdriver functions, registered with ide.c */static ide_driver_t idefloppy_driver = {	"ide-floppy",		/* name */	IDEFLOPPY_VERSION,	/* version */	ide_floppy,		/* media */	0,			/* busy */	1,			/* supports_dma */	0,			/* supports_dsc_overlap */	idefloppy_cleanup,	/* cleanup */	idefloppy_do_request,	/* do_request */	idefloppy_end_request,	/* end_request */	idefloppy_ioctl,	/* ioctl */	idefloppy_open,		/* open */	idefloppy_release,	/* release */	idefloppy_media_change,	/* media_change */	idefloppy_revalidate,	/* media_change */	NULL,			/* pre_reset */	idefloppy_capacity,	/* capacity */	NULL,			/* special */	idefloppy_proc		/* proc */};int idefloppy_init (void);static ide_module_t idefloppy_module = {	IDE_DRIVER_MODULE,	idefloppy_init,	&idefloppy_driver,	NULL};/* *	idefloppy_init will register the driver for each floppy. */int idefloppy_init (void){	ide_drive_t *drive;	idefloppy_floppy_t *floppy;	int failed = 0;	MOD_INC_USE_COUNT;	while ((drive = ide_scan_devices (ide_floppy, idefloppy_driver.name, NULL, failed++)) != NULL) {		if (!idefloppy_identify_device (drive, drive->id)) {			printk (KERN_ERR "ide-floppy: %s: not supported by this version of ide-floppy\n", drive->name);			continue;		}		if (drive->scsi) {			printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);			continue;		}		if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {			printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);			continue;		}		if (ide_register_subdriver (drive, &idefloppy_driver, IDE_SUBDRIVER_VERSION)) {			printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name);			kfree (floppy);			continue;		}		idefloppy_setup (drive, floppy);		failed--;	}	ide_register_module(&idefloppy_module);	MOD_DEC_USE_COUNT;	return 0;}#ifdef MODULEint init_module (void){	return idefloppy_init ();}void cleanup_module (void){	ide_drive_t *drive;	int failed = 0;	while ((drive = ide_scan_devices (ide_floppy, idefloppy_driver.name, &idefloppy_driver, failed)) != NULL) {		if (idefloppy_cleanup (drive)) {			printk ("%s: cleanup_module() called while still busy\n", drive->name);			failed++;		}		/* We must remove proc entries defined in this module.		   Otherwise we oops while accessing these entries */		if (drive->proc)			ide_remove_proc_entries(drive->proc, idefloppy_proc);	}	ide_unregister_module(&idefloppy_module);}#endif /* MODULE */

⌨️ 快捷键说明

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