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

📄 ide-tape.c

📁 Linux环境下java编程的经典书籍
💻 C
📖 第 1 页 / 共 5 页
字号:
	switch (idetape_command_key) {		case IDETAPE_TEST_UNIT_READY_CMD:	return("TEST_UNIT_READY_CMD");		case IDETAPE_REWIND_CMD:		return("REWIND_CMD");		case IDETAPE_REQUEST_SENSE_CMD:		return("REQUEST_SENSE_CMD");		case IDETAPE_READ_CMD:			return("READ_CMD");		case IDETAPE_WRITE_CMD:			return("WRITE_CMD");		case IDETAPE_WRITE_FILEMARK_CMD:	return("WRITE_FILEMARK_CMD");		case IDETAPE_SPACE_CMD:			return("SPACE_CMD");		case IDETAPE_INQUIRY_CMD:		return("INQUIRY_CMD");		case IDETAPE_ERASE_CMD:			return("ERASE_CMD");		case IDETAPE_MODE_SENSE_CMD:		return("MODE_SENSE_CMD");		case IDETAPE_MODE_SELECT_CMD:		return("MODE_SELECT_CMD");		case IDETAPE_LOAD_UNLOAD_CMD:		return("LOAD_UNLOAD_CMD");		case IDETAPE_PREVENT_CMD:		return("PREVENT_CMD");		case IDETAPE_LOCATE_CMD:		return("LOCATE_CMD");		case IDETAPE_READ_POSITION_CMD:		return("READ_POSITION_CMD");		case IDETAPE_READ_BUFFER_CMD:		return("READ_BUFFER_CMD");		case IDETAPE_SET_SPEED_CMD:		return("SET_SPEED_CMD");		default: {				char buf[20];				sprintf(buf, "CMD (0x%02x)", idetape_command_key);				return(buf);			}	}}#endif /* IDETAPE_DEBUG_LOG_VERBOSE *//* *      Function declarations * */static void idetape_onstream_mode_sense_tape_parameter_page(ide_drive_t *drive, int debug);static int idetape_chrdev_release (struct inode *inode, struct file *filp);static void idetape_write_release (struct inode *inode);/* *	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--)		IN_BYTE (IDE_DATA_REG);}static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigned int bcount){	struct buffer_head *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 = IDE_MIN (bh->b_size - atomic_read(&bh->b_count), bcount);		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 buffer_head *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 = IDE_MIN (pc->b_count, bcount);		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);			}		}	}}#ifdef CONFIG_BLK_DEV_IDEDMAstatic void idetape_update_buffers (idetape_pc_t *pc){	struct buffer_head *bh = pc->bh;	int count, 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 = IDE_MIN (bh->b_size, 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;}#endif /* CONFIG_BLK_DEV_IDEDMA *//* *	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;	pc->buffer = pc->pc_buffer;	pc->buffer_size = IDETAPE_PC_BUFFER_SIZE;	pc->bh = NULL;	pc->b_data = NULL;}/* *	idetape_analyze_error is called on each failed packet command retry *	to analyze the request sense. We currently do not utilize this *	information. */static void idetape_analyze_error (ide_drive_t *drive, idetape_request_sense_result_t *result){	idetape_tape_t *tape = drive->driver_data;	idetape_pc_t *pc = tape->failed_pc;	tape->sense     = *result;	tape->sense_key = result->sense_key;	tape->asc       = result->asc;	tape->ascq      = result->ascq;#if IDETAPE_DEBUG_LOG	/*	 *	Without debugging, we only log an error if we decided to	 *	give up retrying.	 */	if (tape->debug_level >= 1)		printk (KERN_INFO "ide-tape: pc = %x, sense key = %x, asc = %x, ascq = %x\n",				pc->c[0], result->sense_key, result->asc, result->ascq);#if IDETAPE_DEBUG_LOG_VERBOSE	if (tape->debug_level >= 1)		printk (KERN_INFO "ide-tape: pc = %s, sense key = %x, asc = %x, ascq = %x\n",			idetape_command_key_verbose((byte) pc->c[0]),			result->sense_key,			result->asc,			result->ascq);#endif /* IDETAPE_DEBUG_LOG_VERBOSE */#endif /* IDETAPE_DEBUG_LOG */	if (tape->onstream && result->sense_key == 2 && result->asc == 0x53 && result->ascq == 2) {		clear_bit(PC_DMA_ERROR, &pc->flags);		ide_stall_queue(drive, HZ / 2);		return;	}#ifdef CONFIG_BLK_DEV_IDEDMA	/*	 *	Correct pc->actually_transferred by asking the tape.	 */	if (test_bit (PC_DMA_ERROR, &pc->flags)) {		pc->actually_transferred = pc->request_transfer - tape->tape_block_size * ntohl (get_unaligned (&result->information));		idetape_update_buffers (pc);	}#endif /* CONFIG_BLK_DEV_IDEDMA */	if (pc->c[0] == IDETAPE_READ_CMD && result->filemark) {		pc->error = IDETAPE_ERROR_FILEMARK;		set_bit (PC_ABORT, &pc->flags);	}	if (pc->c[0] == IDETAPE_WRITE_CMD) {		if (result->eom || (result->sense_key == 0xd && result->asc == 0x0 && result->ascq == 0x2)) {			pc->error = IDETAPE_ERROR_EOD;			set_bit (PC_ABORT, &pc->flags);		}	}	if (pc->c[0] == IDETAPE_READ_CMD || pc->c[0] == IDETAPE_WRITE_CMD) {		if (result->sense_key == 8) {			pc->error = IDETAPE_ERROR_EOD;			set_bit (PC_ABORT, &pc->flags);		}		if (!test_bit (PC_ABORT, &pc->flags) && (tape->onstream || pc->actually_transferred))			pc->retries = IDETAPE_MAX_PC_RETRIES + 1;	}}static void idetape_abort_pipeline (ide_drive_t *drive){	idetape_tape_t *tape = drive->driver_data;	idetape_stage_t *stage = tape->next_stage;#if IDETAPE_DEBUG_LOG	if (tape->debug_level >= 4)		printk(KERN_INFO "ide-tape: %s: idetape_abort_pipeline called\n", tape->name);#endif	while (stage) {		if (stage->rq.cmd == IDETAPE_WRITE_RQ)			stage->rq.cmd = IDETAPE_ABORTED_WRITE_RQ;		else if (stage->rq.cmd == IDETAPE_READ_RQ)			stage->rq.cmd = IDETAPE_ABORTED_READ_RQ;		stage = stage->next;	}}/* *	idetape_active_next_stage will declare the next stage as "active". */static void idetape_active_next_stage (ide_drive_t *drive){	idetape_tape_t *tape = drive->driver_data;	idetape_stage_t *stage = tape->next_stage;	struct request *rq = &stage->rq;#if IDETAPE_DEBUG_LOG	if (tape->debug_level >= 4)		printk (KERN_INFO "ide-tape: Reached idetape_active_next_stage\n");#endif /* IDETAPE_DEBUG_LOG */#if IDETAPE_DEBUG_BUGS	if (stage == NULL) {		printk (KERN_ERR "ide-tape: bug: Trying to activate a non existing stage\n");		return;	}#endif /* IDETAPE_DEBUG_BUGS */		rq->buffer = NULL;	rq->bh = stage->bh;	tape->active_data_request = rq;	tape->active_stage = stage;	tape->next_stage = stage->next;}/* *	idetape_increase_max_pipeline_stages is a part of the feedback *	loop which tries to find the optimum number of stages. In the *	feedback loop, we are starting from a minimum maximum number of *	stages, and if we sense that the pipeline is empty, we try to *	increase it, until we reach the user compile time memory limit. */static void idetape_increase_max_pipeline_stages (ide_drive_t *drive){	idetape_tape_t *tape = drive->driver_data;	int increase = (tape->max_pipeline - tape->min_pipeline) / 10;	#if IDETAPE_DEBUG_LOG	if (tape->debug_level >= 4)		printk (KERN_INFO "ide-tape: Reached idetape_increase_max_pipeline_stages\n");#endif /* IDETAPE_DEBUG_LOG */	tape->max_stages += increase;	tape->max_stages = IDE_MAX(tape->max_stages, tape->min_pipeline);	tape->max_stages = IDE_MIN(tape->max_stages, tape->max_pipeline);}/* *	idetape_kfree_stage calls kfree to completely free a stage, along with *	its related buffers. */static void __idetape_kfree_stage (idetape_stage_t *stage){	struct buffer_head *prev_bh, *bh = stage->bh;	int size;	while (bh != NULL) {		if (bh->b_data != NULL) {			size = (int) bh->b_size;			while (size > 0) {				free_page ((unsigned long) bh->b_data);				size -= PAGE_SIZE;				bh->b_data += PAGE_SIZE;			}		}		prev_bh = bh;		bh = bh->b_reqnext;		kfree (prev_bh);	}	kfree (stage);}static void idetape_kfree_stage (idetape_tape_t *tape, idetape_stage_t *stage){	__idetape_kfree_stage (stage);}/* *	idetape_remove_stage_head removes tape->first_stage from the pipeline. *	The caller should avoid race conditions. */static void idetape_remove_stage_head (ide_drive_t *drive){	idetape_tape_t *tape = drive->driver_data;	idetape_stage_t *stage;	#if IDETAPE_DEBUG_LOG	if (tape->

⌨️ 快捷键说明

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