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

📄 ide-floppy.c

📁 em85xx的大硬盘修正代码包
💻 C
📖 第 1 页 / 共 5 页
字号:
{	idefloppy_init_pc(pc);	pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;}static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector){	int block = sector / floppy->bs_factor;	int blocks = rq->nr_sectors / floppy->bs_factor;	#if IDEFLOPPY_DEBUG_LOG	printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",		2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags), block, blocks);#endif /* IDEFLOPPY_DEBUG_LOG */	idefloppy_init_pc (pc);	if (test_bit (IDEFLOPPY_USE_READ12, &floppy->flags)) {		pc->c[0] = rq->cmd == READ ? IDEFLOPPY_READ12_CMD : IDEFLOPPY_WRITE12_CMD;		put_unaligned (htonl (blocks), (unsigned int *) &pc->c[6]);	} else {		pc->c[0] = rq->cmd == READ ? IDEFLOPPY_READ10_CMD : IDEFLOPPY_WRITE10_CMD;		put_unaligned (htons (blocks), (unsigned short *) &pc->c[7]);	}	put_unaligned (htonl (block), (unsigned int *) &pc->c[2]);	pc->callback = &idefloppy_rw_callback;	pc->rq = rq;	pc->b_data = rq->buffer;	pc->b_count = rq->cmd == READ ? 0 : rq->bh->b_size;	if (rq->cmd == WRITE)		set_bit (PC_WRITING, &pc->flags);	pc->buffer = NULL;	pc->request_transfer = pc->buffer_size = blocks * floppy->block_size;	set_bit (PC_DMA_RECOMMENDED, &pc->flags);}/* *	idefloppy_do_request is our request handling function.	 */static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request *rq, unsigned long block){	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_pc_t *pc;#if IDEFLOPPY_DEBUG_LOG	printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);	printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %ld\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);#endif /* IDEFLOPPY_DEBUG_LOG */	if (rq->errors >= ERROR_MAX) {		if (floppy->failed_pc != NULL)			printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",				drive->name, floppy->failed_pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);		else			printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name);		idefloppy_end_request (0, HWGROUP(drive));		return ide_stopped;	}	switch (rq->cmd) {		case READ:		case WRITE:			if (rq->sector % floppy->bs_factor || rq->nr_sectors % floppy->bs_factor) {				printk ("%s: unsupported r/w request size\n", drive->name);				idefloppy_end_request (0, HWGROUP(drive));				return ide_stopped;			}			pc = idefloppy_next_pc_storage (drive);			idefloppy_create_rw_cmd (floppy, pc, rq, block);			break;		case IDEFLOPPY_PC_RQ:			pc = (idefloppy_pc_t *) rq->buffer;			break;		default:			printk (KERN_ERR "ide-floppy: unsupported command %x in request queue\n", rq->cmd);			idefloppy_end_request (0,HWGROUP (drive));			return ide_stopped;	}	pc->rq = rq;	return idefloppy_issue_pc (drive, pc);}/* *	idefloppy_queue_pc_tail adds a special packet command request to the *	tail of the request queue, and waits for it to be serviced. */static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc){	struct request rq;	ide_init_drive_cmd (&rq);	rq.buffer = (char *) pc;	rq.cmd = IDEFLOPPY_PC_RQ;	return ide_do_drive_cmd (drive, &rq, ide_wait);}/* *	Look at the flexible disk page parameters. We will ignore the CHS *	capacity parameters and use the LBA parameters instead. */static int idefloppy_get_flexible_disk_page (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_pc_t pc;	idefloppy_mode_parameter_header_t *header;	idefloppy_flexible_disk_page_t *page;	int capacity, lba_capacity;	idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE, MODE_SENSE_CURRENT);	if (idefloppy_queue_pc_tail (drive,&pc)) {		printk (KERN_ERR "ide-floppy: Can't get flexible disk page parameters\n");		return 1;	}	header = (idefloppy_mode_parameter_header_t *) pc.buffer;	floppy->wp = header->wp;	page = (idefloppy_flexible_disk_page_t *) (header + 1);	page->transfer_rate = ntohs (page->transfer_rate);	page->sector_size = ntohs (page->sector_size);	page->cyls = ntohs (page->cyls);	page->rpm = ntohs (page->rpm);	capacity = page->cyls * page->heads * page->sectors * page->sector_size;	if (memcmp (page, &floppy->flexible_disk_page, sizeof (idefloppy_flexible_disk_page_t)))		printk (KERN_INFO "%s: %dkB, %d/%d/%d CHS, %d kBps, %d sector size, %d rpm\n",			drive->name, capacity / 1024, page->cyls, page->heads, page->sectors,			page->transfer_rate / 8, page->sector_size, page->rpm);	floppy->flexible_disk_page = *page;	drive->bios_cyl = page->cyls;	drive->bios_head = page->heads;	drive->bios_sect = page->sectors;	lba_capacity = floppy->blocks * floppy->block_size;	if (capacity < lba_capacity) {		printk (KERN_NOTICE "%s: The disk reports a capacity of %d bytes, "			"but the drive only handles %d\n",			drive->name, lba_capacity, capacity);		floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0;	}	return 0;}static int idefloppy_get_capability_page(ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_pc_t pc;	idefloppy_mode_parameter_header_t *header;	idefloppy_capabilities_page_t *page;	floppy->srfp=0;	idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE,						 MODE_SENSE_CURRENT);	set_bit(PC_SUPPRESS_ERROR, &pc.flags);	if (idefloppy_queue_pc_tail (drive,&pc)) {		return 1;	}	header = (idefloppy_mode_parameter_header_t *) pc.buffer;	page= (idefloppy_capabilities_page_t *)(header+1);	floppy->srfp=page->srfp;	return (0);}/* *	Determine if a media is present in the floppy drive, and if so, *	its LBA capacity. */static int idefloppy_get_capacity (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_pc_t pc;	idefloppy_capacity_header_t *header;	idefloppy_capacity_descriptor_t *descriptor;	int i, descriptors, rc = 1, blocks, length;		drive->bios_cyl = 0;	drive->bios_head = drive->bios_sect = 0;	floppy->blocks = floppy->bs_factor = 0;	drive->part[0].nr_sects = 0;	idefloppy_create_read_capacity_cmd (&pc);	if (idefloppy_queue_pc_tail (drive, &pc)) {		printk (KERN_ERR "ide-floppy: Can't get floppy parameters\n");		return 1;	}	header = (idefloppy_capacity_header_t *) pc.buffer;	descriptors = header->length / sizeof (idefloppy_capacity_descriptor_t);	descriptor = (idefloppy_capacity_descriptor_t *) (header + 1);	for (i = 0; i < descriptors; i++, descriptor++) {                blocks = descriptor->blocks = ntohl (descriptor->blocks);                length = descriptor->length = ntohs (descriptor->length);		if (!i) 		{          	switch (descriptor->dc) {                case CAPACITY_UNFORMATTED: /* Clik! drive returns this instead of CAPACITY_CURRENT */                        if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))                                break; /* If it is not a clik drive, break out (maintains previous driver behaviour) */                case CAPACITY_CURRENT: /* Normal Zip/LS-120 disks */                        if (memcmp (descriptor, &floppy->capacity, sizeof (idefloppy_capacity_descriptor_t)))                                printk (KERN_INFO "%s: %dkB, %d blocks, %d sector size\n", drive->name, blocks * length / 1024, blocks, length);                        floppy->capacity = *descriptor;                        if (!length || length % 512)                                printk (KERN_NOTICE "%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;                        }                        break;                case CAPACITY_NO_CARTRIDGE:                        /* This is a KERN_ERR so it appears on screen for the user to see */                        printk (KERN_ERR "%s: No disk in drive\n", drive->name);                                        break;                case CAPACITY_INVALID:                        printk (KERN_ERR "%s: Invalid capacity for disk in drive\n", drive->name);                                        break;		}		}		if (!i) {		IDEFLOPPY_DEBUG( "Descriptor 0 Code: %d\n", descriptor->dc);		}		IDEFLOPPY_DEBUG( "Descriptor %d: %dkB, %d blocks, %d sector size\n", i, blocks * length / 1024, blocks, length);	}	/* Clik! disk does not support get_flexible_disk_page */        if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))	{		(void) idefloppy_get_flexible_disk_page (drive);	}	drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;	return rc;}/*** Obtain the list of formattable capacities.** Very similar to idefloppy_get_capacity, except that we push the capacity** descriptors to userland, instead of our own structures.**** Userland gives us the following structure:**** struct idefloppy_format_capacities {**        int nformats;**        struct {**                int nblocks;**                int blocksize;**                } formats[];**        } ;**** userland initializes nformats to the number of allocated formats[]** records.  On exit we set nformats to the number of records we've** actually initialized.***/static int idefloppy_get_format_capacities (ide_drive_t *drive,					    struct inode *inode,					    struct file *file,					    int *arg)	/* Cheater */{        idefloppy_pc_t pc;	idefloppy_capacity_header_t *header;        idefloppy_capacity_descriptor_t *descriptor;	int i, descriptors, blocks, length;	int u_array_size;	int u_index;	int *argp;	if (get_user(u_array_size, arg))		return (-EFAULT);	if (u_array_size <= 0)		return (-EINVAL);	idefloppy_create_read_capacity_cmd (&pc);	if (idefloppy_queue_pc_tail (drive, &pc)) {		printk (KERN_ERR "ide-floppy: Can't get floppy parameters\n");                return (-EIO);        }        header = (idefloppy_capacity_header_t *) pc.buffer;        descriptors = header->length /		sizeof (idefloppy_capacity_descriptor_t);	descriptor = (idefloppy_capacity_descriptor_t *) (header + 1);	u_index=0;	argp=arg+1;	/*	** We always skip the first capacity descriptor.  That's the	** current capacity.  We are interested in the remaining descriptors,	** the formattable capacities.	*/	for (i=0; i<descriptors; i++, descriptor++)	{		if (u_index >= u_array_size)			break;	/* User-supplied buffer too small */		if (i == 0)			continue;	/* Skip the first descriptor */		blocks = ntohl (descriptor->blocks);		length = ntohs (descriptor->length);		if (put_user(blocks, argp))			return (-EFAULT);		++argp;		if (put_user(length, argp))			return (-EFAULT);		++argp;		++u_index;	}	if (put_user(u_index, arg))		return (-EFAULT);	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;		}

⌨️ 快捷键说明

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