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

📄 ide-floppy.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 4 页
字号:
		unsigned reserved3	:1;	/* Reserved */		unsigned drv		:1;	/* The responding drive will be drive 0 (0) or drive 1 (1) */		unsigned one5		:1;	/* Should be set to 1 */		unsigned reserved6	:1;	/* Reserved */		unsigned one7		:1;	/* Should be set to 1 */#elif defined(__BIG_ENDIAN_BITFIELD)		unsigned one7		:1;	/* Should be set to 1 */		unsigned reserved6	:1;	/* Reserved */		unsigned one5		:1;	/* Should be set to 1 */		unsigned drv		:1;	/* The responding drive will be drive 0 (0) or drive 1 (1) */		unsigned reserved3	:1;	/* Reserved */		unsigned sam_lun	:3;	/* Logical unit number */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif	} b;} idefloppy_drivesel_reg_t;/* *	ATAPI Device Control Register */typedef union {				unsigned all			:8;	struct {#if defined(__LITTLE_ENDIAN_BITFIELD)		unsigned zero0		:1;	/* Should be set to zero */		unsigned nien		:1;	/* Device interrupt is disabled (1) or enabled (0) */		unsigned srst		:1;	/* ATA software reset. ATAPI devices should use the new ATAPI srst. */		unsigned one3		:1;	/* Should be set to 1 */		unsigned reserved4567	:4;	/* Reserved */#elif defined(__BIG_ENDIAN_BITFIELD)		unsigned reserved4567	:4;	/* Reserved */		unsigned one3		:1;	/* Should be set to 1 */		unsigned srst		:1;	/* ATA software reset. ATAPI devices should use the new ATAPI srst. */		unsigned nien		:1;	/* Device interrupt is disabled (1) or enabled (0) */		unsigned zero0		:1;	/* Should be set to zero */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif	} b;} idefloppy_control_reg_t;/* *	The following is used to format the general configuration word of *	the ATAPI IDENTIFY DEVICE command. */struct idefloppy_id_gcw {	#if defined(__LITTLE_ENDIAN_BITFIELD)	unsigned packet_size		:2;	/* Packet Size */	unsigned reserved234		:3;	/* Reserved */	unsigned drq_type		:2;	/* Command packet DRQ type */	unsigned removable		:1;	/* Removable media */	unsigned device_type		:5;	/* Device type */	unsigned reserved13		:1;	/* Reserved */	unsigned protocol		:2;	/* Protocol type */#elif defined(__BIG_ENDIAN_BITFIELD)	unsigned protocol		:2;	/* Protocol type */	unsigned reserved13		:1;	/* Reserved */	unsigned device_type		:5;	/* Device type */	unsigned removable		:1;	/* Removable media */	unsigned drq_type		:2;	/* Command packet DRQ type */	unsigned reserved234		:3;	/* Reserved */	unsigned packet_size		:2;	/* Packet Size */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif};/* *	INQUIRY packet command - Data Format */typedef struct {#if defined(__LITTLE_ENDIAN_BITFIELD)	unsigned	device_type	:5;	/* Peripheral Device Type */	unsigned	reserved0_765	:3;	/* Peripheral Qualifier - Reserved */	unsigned	reserved1_6t0	:7;	/* Reserved */	unsigned	rmb		:1;	/* Removable Medium Bit */	unsigned	ansi_version	:3;	/* ANSI Version */	unsigned	ecma_version	:3;	/* ECMA Version */	unsigned	iso_version	:2;	/* ISO Version */	unsigned	response_format :4;	/* Response Data Format */	unsigned	reserved3_45	:2;	/* Reserved */	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */	unsigned	reserved3_7	:1;	/* AENC - Reserved */#elif defined(__BIG_ENDIAN_BITFIELD)	unsigned	reserved0_765	:3;	/* Peripheral Qualifier - Reserved */	unsigned	device_type	:5;	/* Peripheral Device Type */	unsigned	rmb		:1;	/* Removable Medium Bit */	unsigned	reserved1_6t0	:7;	/* Reserved */	unsigned	iso_version	:2;	/* ISO Version */	unsigned	ecma_version	:3;	/* ECMA Version */	unsigned	ansi_version	:3;	/* ANSI Version */	unsigned	reserved3_7	:1;	/* AENC - Reserved */	unsigned	reserved3_6	:1;	/* TrmIOP - Reserved */	unsigned	reserved3_45	:2;	/* Reserved */	unsigned	response_format :4;	/* Response Data Format */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif	u8		additional_length;	/* Additional Length (total_length-4) */	u8		rsv5, rsv6, rsv7;	/* Reserved */	u8		vendor_id[8];		/* Vendor Identification */	u8		product_id[16];		/* Product Identification */	u8		revision_level[4];	/* Revision Level */	u8		vendor_specific[20];	/* Vendor Specific - Optional */	u8		reserved56t95[40];	/* Reserved - Optional */						/* Additional information may be returned */} idefloppy_inquiry_result_t;/* *	REQUEST SENSE packet command result - Data Format. */typedef struct {#if defined(__LITTLE_ENDIAN_BITFIELD)	unsigned	error_code	:7;	/* Current error (0x70) */	unsigned	valid		:1;	/* The information field conforms to SFF-8070i */	u8		reserved1	:8;	/* Reserved */	unsigned	sense_key	:4;	/* Sense Key */	unsigned	reserved2_4	:1;	/* Reserved */	unsigned	ili		:1;	/* Incorrect Length Indicator */	unsigned	reserved2_67	:2;#elif defined(__BIG_ENDIAN_BITFIELD)	unsigned	valid		:1;	/* The information field conforms to SFF-8070i */	unsigned	error_code	:7;	/* Current error (0x70) */	u8		reserved1	:8;	/* Reserved */	unsigned	reserved2_67	:2;	unsigned	ili		:1;	/* Incorrect Length Indicator */	unsigned	reserved2_4	:1;	/* Reserved */	unsigned	sense_key	:4;	/* Sense Key */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif	u32		information __attribute__ ((packed));	u8		asl;			/* Additional sense length (n-7) */	u32		command_specific;	/* Additional command specific information */	u8		asc;			/* Additional Sense Code */	u8		ascq;			/* Additional Sense Code Qualifier */	u8		replaceable_unit_code;	/* Field Replaceable Unit Code */	u8		reserved[3];	u8		pad[2];			/* Padding to 20 bytes */} idefloppy_request_sense_result_t;/* *	Pages of the SELECT SENSE / MODE SENSE packet commands. */#define	IDEFLOPPY_CAPABILITIES_PAGE	0x1b#define IDEFLOPPY_FLEXIBLE_DISK_PAGE	0x05/* *	Mode Parameter Header for the MODE SENSE packet command */typedef struct {	u16		mode_data_length;	/* Length of the following data transfer */	u8		medium_type;		/* Medium Type */#if defined(__LITTLE_ENDIAN_BITFIELD)	unsigned	reserved3	:7;	unsigned	wp		:1;	/* Write protect */#elif defined(__BIG_ENDIAN_BITFIELD)	unsigned	wp		:1;	/* Write protect */	unsigned	reserved3	:7;#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif	u8		reserved[4];} idefloppy_mode_parameter_header_t;#define IDEFLOPPY_MIN(a,b)	((a)<(b) ? (a):(b))#define	IDEFLOPPY_MAX(a,b)	((a)>(b) ? (a):(b))/* *	Too bad. The drive wants to send us data which we are not ready to accept. *	Just throw it away. */static void idefloppy_discard_data (ide_drive_t *drive, unsigned int bcount){	while (bcount--)		IN_BYTE (IDE_DATA_REG);}#if IDEFLOPPY_DEBUG_BUGSstatic void idefloppy_write_zeros (ide_drive_t *drive, unsigned int bcount){	while (bcount--)		OUT_BYTE (0, IDE_DATA_REG);}#endif /* IDEFLOPPY_DEBUG_BUGS *//* *	idefloppy_end_request is used to finish servicing a request. * *	For read/write requests, we will call ide_end_request to pass to the *	next buffer. */static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup){	ide_drive_t *drive = hwgroup->drive;	idefloppy_floppy_t *floppy = drive->driver_data;	struct request *rq = hwgroup->rq;	int error;#if IDEFLOPPY_DEBUG_LOG	printk (KERN_INFO "Reached idefloppy_end_request\n");#endif /* IDEFLOPPY_DEBUG_LOG */	switch (uptodate) {		case 0: error = IDEFLOPPY_ERROR_GENERAL; break;		case 1: error = 0; break;		default: error = uptodate;	}	if (error)		floppy->failed_pc = NULL;	/* Why does this happen? */	if (!rq)		return;	if (!IDEFLOPPY_RQ_CMD (rq->cmd)) {		ide_end_request (uptodate, hwgroup);		return;	}	rq->errors = error;	ide_end_drive_cmd (drive, 0, 0);}static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount){	struct request *rq = pc->rq;	struct buffer_head *bh = rq->bh;	int count;	while (bcount) {		if (pc->b_count == bh->b_size) {			rq->sector += rq->current_nr_sectors;			rq->nr_sectors -= rq->current_nr_sectors;			idefloppy_end_request (1, HWGROUP(drive));			if ((bh = rq->bh) != NULL)				pc->b_count = 0;		}		if (bh == NULL) {			printk (KERN_ERR "%s: bh == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount);			idefloppy_discard_data (drive, bcount);			return;		}		count = IDEFLOPPY_MIN (bh->b_size - pc->b_count, bcount);		atapi_input_bytes (drive, bh->b_data + pc->b_count, count);		bcount -= count; pc->b_count += count;	}}static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount){	struct request *rq = pc->rq;	struct buffer_head *bh = rq->bh;	int count;		while (bcount) {		if (!pc->b_count) {			rq->sector += rq->current_nr_sectors;			rq->nr_sectors -= rq->current_nr_sectors;			idefloppy_end_request (1, HWGROUP(drive));			if ((bh = rq->bh) != NULL) {				pc->b_data = bh->b_data;				pc->b_count = bh->b_size;			}		}		if (bh == NULL) {			printk (KERN_ERR "%s: bh == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);			idefloppy_write_zeros (drive, bcount);			return;		}		count = IDEFLOPPY_MIN (pc->b_count, bcount);		atapi_output_bytes (drive, pc->b_data, count);		bcount -= count; pc->b_data += count; pc->b_count -= count;	}}#ifdef CONFIG_BLK_DEV_IDEDMAstatic void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc){	struct request *rq = pc->rq;	struct buffer_head *bh = rq->bh;	while ((bh = rq->bh) != NULL)		idefloppy_end_request (1, HWGROUP(drive));}#endif /* CONFIG_BLK_DEV_IDEDMA *//* *	idefloppy_queue_pc_head generates a new packet command request in front *	of the request queue, before the current request, so that it will be *	processed immediately, on the next pass through the driver. */static void idefloppy_queue_pc_head (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;	(void) ide_do_drive_cmd (drive, rq, ide_preempt);}static idefloppy_pc_t *idefloppy_next_pc_storage (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	if (floppy->pc_stack_index==IDEFLOPPY_PC_STACK)		floppy->pc_stack_index=0;	return (&floppy->pc_stack[floppy->pc_stack_index++]);}static struct request *idefloppy_next_rq_storage (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	if (floppy->rq_stack_index==IDEFLOPPY_PC_STACK)		floppy->rq_stack_index=0;	return (&floppy->rq_stack[floppy->rq_stack_index++]);}/* *	idefloppy_analyze_error is called on each failed packet command retry *	to analyze the request sense. */static void idefloppy_analyze_error (ide_drive_t *drive,idefloppy_request_sense_result_t *result){	idefloppy_floppy_t *floppy = drive->driver_data;	floppy->sense_key = result->sense_key; floppy->asc = result->asc; floppy->ascq = result->ascq;#if IDEFLOPPY_DEBUG_LOG	if (floppy->failed_pc)		printk (KERN_INFO "ide-floppy: pc = %x, sense key = %x, asc = %x, ascq = %x\n",floppy->failed_pc->c[0],result->sense_key,result->asc,result->ascq);	else		printk (KERN_INFO "ide-floppy: sense key = %x, asc = %x, ascq = %x\n",result->sense_key,result->asc,result->ascq);#endif /* IDEFLOPPY_DEBUG_LOG */}static void idefloppy_request_sense_callback (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;#if IDEFLOPPY_DEBUG_LOG	printk (KERN_INFO "ide-floppy: Reached idefloppy_request_sense_callback\n");#endif /* IDEFLOPPY_DEBUG_LOG */	if (!floppy->pc->error) {		idefloppy_analyze_error (drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer);		idefloppy_end_request (1,HWGROUP (drive));	} else {		printk (KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n");		idefloppy_end_request (0,HWGROUP (drive));	}}/* *	General packet command callback function. */static void idefloppy_pc_callback (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	#if IDEFLOPPY_DEBUG_LOG	printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_callback\n");#endif /* IDEFLOPPY_DEBUG_LOG */	idefloppy_end_request (floppy->pc->error ? 0:1, HWGROUP(drive));}/* *	idefloppy_init_pc initializes a packet command. */static void idefloppy_init_pc (idefloppy_pc_t *pc){	memset (pc->c, 0, 12);	pc->retries = 0;	pc->flags = 0;	pc->request_transfer = 0;	pc->buffer = pc->pc_buffer;	pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE;	pc->b_data = NULL;	pc->callback = &idefloppy_pc_callback;}static void idefloppy_create_request_sense_cmd (idefloppy_pc_t *pc){	idefloppy_init_pc (pc);		pc->c[0] = IDEFLOPPY_REQUEST_SENSE_CMD;	pc->c[4] = 255;	pc->request_transfer = 18;	pc->callback = &idefloppy_request_sense_callback;}/* *	idefloppy_retry_pc is called when an error was detected during the *	last packet command. We queue a request sense packet command in *	the head of the request list. */static void idefloppy_retry_pc (ide_drive_t *drive){	idefloppy_pc_t *pc;	struct request *rq;	idefloppy_error_reg_t error;	error.all = IN_BYTE (IDE_ERROR_REG);	pc = idefloppy_next_pc_storage (drive);	rq = idefloppy_next_rq_storage (drive);	idefloppy_create_request_sense_cmd (pc);	idefloppy_queue_pc_head (drive, pc, rq);}/* *	idefloppy_pc_intr is the usual interrupt handler which will be called *	during a packet command. */static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive){	idefloppy_floppy_t *floppy = drive->driver_data;	idefloppy_status_reg_t status;	idefloppy_bcount_reg_t bcount;	idefloppy_ireason_reg_t ireason;	idefloppy_pc_t *pc=floppy->pc;	struct request *rq = pc->rq;	unsigned int temp;#if IDEFLOPPY_DEBUG_LOG	printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_intr interrupt handler\n");#endif /* IDEFLOPPY_DEBUG_LOG */	

⌨️ 快捷键说明

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