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

📄 ide-tape.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *	Some defines for the SPACE command */#define IDETAPE_SPACE_OVER_FILEMARK	1#define IDETAPE_SPACE_TO_EOD		3/* *	Some defines for the LOAD UNLOAD command */#define IDETAPE_LU_LOAD_MASK		1#define IDETAPE_LU_RETENSION_MASK	2#define IDETAPE_LU_EOT_MASK		4/* *	Special requests for our block device strategy routine. * *	In order to service a character device command, we add special *	requests to the tail of our block device request queue and wait *	for their completion. */enum {	REQ_IDETAPE_PC1		= (1 << 0), /* packet command (first stage) */	REQ_IDETAPE_PC2		= (1 << 1), /* packet command (second stage) */	REQ_IDETAPE_READ	= (1 << 2),	REQ_IDETAPE_WRITE	= (1 << 3),	REQ_IDETAPE_READ_BUFFER	= (1 << 4),};/* *	Error codes which are returned in rq->errors to the higher part *	of the driver. */#define	IDETAPE_ERROR_GENERAL		101#define	IDETAPE_ERROR_FILEMARK		102#define	IDETAPE_ERROR_EOD		103/* *	The following is used to format the general configuration word of *	the ATAPI IDENTIFY DEVICE command. */struct idetape_id_gcw {		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 */};/* *	INQUIRY packet command - Data Format (From Table 6-8 of QIC-157C) */typedef struct {	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 */	__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 */} idetape_inquiry_result_t;/* *	READ POSITION packet command - Data Format (From Table 6-57) */typedef struct {	unsigned	reserved0_10	:2;	/* Reserved */	unsigned	bpu		:1;	/* Block Position Unknown */		unsigned	reserved0_543	:3;	/* Reserved */	unsigned	eop		:1;	/* End Of Partition */	unsigned	bop		:1;	/* Beginning Of Partition */	u8		partition;		/* Partition Number */	u8		reserved2, reserved3;	/* Reserved */	u32		first_block;		/* First Block Location */	u32		last_block;		/* Last Block Location (Optional) */	u8		reserved12;		/* Reserved */	u8		blocks_in_buffer[3];	/* Blocks In Buffer - (Optional) */	u32		bytes_in_buffer;	/* Bytes In Buffer (Optional) */} idetape_read_position_result_t;/* *	Follows structures which are related to the SELECT SENSE / MODE SENSE *	packet commands. Those packet commands are still not supported *	by ide-tape. */#define IDETAPE_BLOCK_DESCRIPTOR	0#define	IDETAPE_CAPABILITIES_PAGE	0x2a#define IDETAPE_PARAMTR_PAGE		0x2b   /* Onstream DI-x0 only */#define IDETAPE_BLOCK_SIZE_PAGE		0x30#define IDETAPE_BUFFER_FILLING_PAGE	0x33/* *	Mode Parameter Header for the MODE SENSE packet command */typedef struct {	__u8	mode_data_length;	/* Length of the following data transfer */	__u8	medium_type;		/* Medium Type */	__u8	dsp;			/* Device Specific Parameter */	__u8	bdl;			/* Block Descriptor Length */#if 0	/* data transfer page */	__u8	page_code	:6;	__u8	reserved0_6	:1;	__u8	ps		:1;	/* parameters saveable */	__u8	page_length;		/* page Length == 0x02 */	__u8	reserved2;	__u8	read32k		:1;	/* 32k blk size (data only) */	__u8	read32k5	:1;	/* 32.5k blk size (data&AUX) */	__u8	reserved3_23	:2;	__u8	write32k	:1;	/* 32k blk size (data only) */	__u8	write32k5	:1;	/* 32.5k blk size (data&AUX) */	__u8	reserved3_6	:1;	__u8	streaming	:1;	/* streaming mode enable */#endif} idetape_mode_parameter_header_t;/* *	Mode Parameter Block Descriptor the MODE SENSE packet command * *	Support for block descriptors is optional. */typedef struct {	__u8		density_code;		/* Medium density code */	__u8		blocks[3];		/* Number of blocks */	__u8		reserved4;		/* Reserved */	__u8		length[3];		/* Block Length */} idetape_parameter_block_descriptor_t;/* *	The Data Compression Page, as returned by the MODE SENSE packet command. */typedef struct {	unsigned	page_code	:6;	/* Page Code - Should be 0xf */	unsigned	reserved0	:1;	/* Reserved */	unsigned	ps		:1;	__u8		page_length;		/* Page Length - Should be 14 */	unsigned	reserved2	:6;	/* Reserved */	unsigned	dcc		:1;	/* Data Compression Capable */	unsigned	dce		:1;	/* Data Compression Enable */	unsigned	reserved3	:5;	/* Reserved */	unsigned	red		:2;	/* Report Exception on Decompression */	unsigned	dde		:1;	/* Data Decompression Enable */	__u32		ca;			/* Compression Algorithm */	__u32		da;			/* Decompression Algorithm */	__u8		reserved[4];		/* Reserved */} idetape_data_compression_page_t;/* *	The Medium Partition Page, as returned by the MODE SENSE packet command. */typedef struct {	unsigned	page_code	:6;	/* Page Code - Should be 0x11 */	unsigned	reserved1_6	:1;	/* Reserved */	unsigned	ps		:1;	__u8		page_length;		/* Page Length - Should be 6 */	__u8		map;			/* Maximum Additional Partitions - Should be 0 */	__u8		apd;			/* Additional Partitions Defined - Should be 0 */	unsigned	reserved4_012	:3;	/* Reserved */	unsigned	psum		:2;	/* Should be 0 */	unsigned	idp		:1;	/* Should be 0 */	unsigned	sdp		:1;	/* Should be 0 */	unsigned	fdp		:1;	/* Fixed Data Partitions */	__u8		mfr;			/* Medium Format Recognition */	__u8		reserved[2];		/* Reserved */} idetape_medium_partition_page_t;/* *	Run time configurable parameters. */typedef struct {	int	dsc_rw_frequency;	int	dsc_media_access_frequency;	int	nr_stages;} idetape_config_t;/* *	The variables below are used for the character device interface. *	Additional state variables are defined in our ide_drive_t structure. */static struct ide_tape_obj * idetape_devs[MAX_HWIFS * MAX_DRIVES];#define ide_tape_f(file) ((file)->private_data)static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i){	struct ide_tape_obj *tape = NULL;	mutex_lock(&idetape_ref_mutex);	tape = idetape_devs[i];	if (tape)		kref_get(&tape->kref);	mutex_unlock(&idetape_ref_mutex);	return tape;}/* *      Function declarations * */static int idetape_chrdev_release (struct inode *inode, struct file *filp);static void idetape_write_release (ide_drive_t *drive, unsigned int minor);/* * Too bad. The drive wants to send us data which we are not ready to accept. * Just throw it away. */static void idetape_discard_data (ide_drive_t *drive, unsigned int bcount){	while (bcount--)		(void) HWIF(drive)->INB(IDE_DATA_REG);}static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigned int bcount){	struct idetape_bh *bh = pc->bh;	int count;	while (bcount) {#if IDETAPE_DEBUG_BUGS		if (bh == NULL) {			printk(KERN_ERR "ide-tape: bh == NULL in "				"idetape_input_buffers\n");			idetape_discard_data(drive, bcount);			return;		}#endif /* IDETAPE_DEBUG_BUGS */		count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount);		HWIF(drive)->atapi_input_bytes(drive, bh->b_data + atomic_read(&bh->b_count), count);		bcount -= count;		atomic_add(count, &bh->b_count);		if (atomic_read(&bh->b_count) == bh->b_size) {			bh = bh->b_reqnext;			if (bh)				atomic_set(&bh->b_count, 0);		}	}	pc->bh = bh;}static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigned int bcount){	struct idetape_bh *bh = pc->bh;	int count;	while (bcount) {#if IDETAPE_DEBUG_BUGS		if (bh == NULL) {			printk(KERN_ERR "ide-tape: bh == NULL in "				"idetape_output_buffers\n");			return;		}#endif /* IDETAPE_DEBUG_BUGS */		count = min((unsigned int)pc->b_count, (unsigned int)bcount);		HWIF(drive)->atapi_output_bytes(drive, pc->b_data, count);		bcount -= count;		pc->b_data += count;		pc->b_count -= count;		if (!pc->b_count) {			pc->bh = bh = bh->b_reqnext;			if (bh) {				pc->b_data = bh->b_data;				pc->b_count = atomic_read(&bh->b_count);			}		}	}}static void idetape_update_buffers (idetape_pc_t *pc){	struct idetape_bh *bh = pc->bh;	int count;	unsigned int bcount = pc->actually_transferred;	if (test_bit(PC_WRITING, &pc->flags))		return;	while (bcount) {#if IDETAPE_DEBUG_BUGS		if (bh == NULL) {			printk(KERN_ERR "ide-tape: bh == NULL in "				"idetape_update_buffers\n");			return;		}#endif /* IDETAPE_DEBUG_BUGS */		count = min((unsigned int)bh->b_size, (unsigned int)bcount);		atomic_set(&bh->b_count, count);		if (atomic_read(&bh->b_count) == bh->b_size)			bh = bh->b_reqnext;		bcount -= count;	}	pc->bh = bh;}/* *	idetape_next_pc_storage returns a pointer to a place in which we can *	safely store a packet command, even though we intend to leave the *	driver. A storage space for a maximum of IDETAPE_PC_STACK packet *	commands is allocated at initialization time. */static idetape_pc_t *idetape_next_pc_storage (ide_drive_t *drive){	idetape_tape_t *tape = drive->driver_data;#if IDETAPE_DEBUG_LOG	if (tape->debug_level >= 5)		printk(KERN_INFO "ide-tape: pc_stack_index=%d\n",			tape->pc_stack_index);#endif /* IDETAPE_DEBUG_LOG */	if (tape->pc_stack_index == IDETAPE_PC_STACK)		tape->pc_stack_index=0;	return (&tape->pc_stack[tape->pc_stack_index++]);}/* *	idetape_next_rq_storage is used along with idetape_next_pc_storage. *	Since we queue packet commands in the request queue, we need to *	allocate a request, along with the allocation of a packet command. */ /************************************************************** *                                                            * *  This should get fixed to use kmalloc(.., GFP_ATOMIC)      * *  followed later on by kfree().   -ml                       * *                                                            * **************************************************************/ static struct request *idetape_next_rq_storage (ide_drive_t *drive){	idetape_tape_t *tape = drive->driver_data;#if IDETAPE_DEBUG_LOG	if (tape->debug_level >= 5)		printk(KERN_INFO "ide-tape: rq_stack_index=%d\n",			tape->rq_stack_index);#endif /* IDETAPE_DEBUG_LOG */	if (tape->rq_stack_index == IDETAPE_PC_STACK)		tape->rq_stack_index=0;	return (&tape->rq_stack[tape->rq_stack_index++]);}/* *	idetape_init_pc initializes a packet command. */static void idetape_init_pc (idetape_pc_t *pc){	memset(pc->c, 0, 12);	pc->retries = 0;	pc->flags = 0;	pc->request_transfer = 0;

⌨️ 快捷键说明

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