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

📄 err_handling.c

📁 newos is new operation system
💻 C
字号:
/* ** Copyright 2002, Thomas Kurschel. All rights reserved.** Distributed under the terms of the NewOS License.*/#include "scsi_periph_int.h"#include <kernel/dev/blkman.h>#include <kernel/debug.h>static err_res check_sense( scsi_device_info *device, CCB_SCSIIO *request ){	scsi_sense *sense = (scsi_sense *)request->cam_sense_ptr;		if( (request->cam_ch.cam_status & CAM_AUTOSNS_VALID) == 0 ) {		// shouldn't happen (cam_status should be CAM_AUTOSENSE_FAIL		// as we asked for autosense)		return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );	}	if( request->cam_sense_len - request->cam_sense_resid < 		(int)offsetof( scsi_sense, add_sense_length ) + 1 ) 	{		// that's a bit too short		return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );	}		if( !sense->valid ) {		// error code not conforming to standard - too bad		return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );	}	switch( sense->error_code ) {	case SCSIS_DEFERRED_ERROR:		// we are f**ked - some previous request turned out to have failed		// we neither know which one nor can we resubmit it				dprintf( "SCSI: encountered DEFERRED ERROR - bye, bye\n" );		return MK_ERROR( err_act_ok, NO_ERROR );			case SCSIS_CURR_ERROR:		// we start with very specific and finish very general error infos		switch( (sense->asc << 8) | sense->ascq ) {		case SCSIS_ASC_AUDIO_PLAYING:			// we need something like "busy"			return MK_ERROR( err_act_fail, ERR_NOT_ALLOWED );					case SCSIS_ASC_LUN_NEED_INIT:			// XXX at first glance, this looks like a good "medium changed"			// indicator, but I've read somewhere that there are drives that			// send this message if they are idle and spun down			return MK_ERROR( err_act_start, ERR_DEV_NOT_READY );					case SCSIS_ASC_LUN_NEED_MANUAL_HELP:			return MK_ERROR( err_act_fail, ERR_DEV_NOT_READY );					case SCSIS_ASC_LUN_FORMATTING:			// we could wait, but as formatting normally takes quite long,			// we give up without any further retries			return MK_ERROR( err_act_fail, ERR_DEV_NOT_READY );					case SCSIS_ASC_MEDIUM_CHANGED:			media_changed( device, &request->cam_ch );			return MK_ERROR( err_act_fail, ERR_DEV_MEDIA_CHANGED );					case SCSIS_ASC_WRITE_ERR_AUTOREALLOC:			dprintf( "Recovered write error - block got reallocated automatically\n" );			return MK_ERROR( err_act_ok, NO_ERROR );		case SCSIS_ASC_ID_RECOV:			dprintf( "Recovered ID with ECC\n" );			return MK_ERROR( err_act_ok, NO_ERROR );					case SCSIS_ASC_REMOVAL_REQUESTED:			dprintf( "Removal requested" );			mutex_lock( &device->mutex );			device->removal_requested = true;			mutex_unlock( &device->mutex );						return MK_ERROR( err_act_retry, ERR_DEV_GENERAL );					}				switch( sense->asc ) {		case SCSIS_ASC_DATA_RECOV_NO_ERR_CORR >> 8:		case SCSIS_ASC_DATA_RECOV_WITH_CORR >> 8:			// these are the groups of recovered data with or without correction			// we should print at least a warning here			dprintf( "Recovered data, asc=0x%2x, ascq=0x%2x\n", 				sense->asc, sense->ascq );			return MK_ERROR( err_act_ok, NO_ERROR );				case SCSIS_ASC_WRITE_PROTECTED >> 8:			// isn't there any proper "write protected" error code?			return MK_ERROR( err_act_fail, ERR_DEV_WRITE_ERROR );					case SCSIS_ASC_NO_MEDIUM >> 8:			return MK_ERROR( err_act_fail, ERR_DEV_NO_MEDIA );					}					switch( sense->sense_key ) {		case SCSIS_KEY_NO_SENSE:			// we thought there was an error, huh?			return MK_ERROR( err_act_ok, NO_ERROR );		case SCSIS_KEY_RECOVERED_ERROR:			// we should probably tell about that; perhaps tomorrow			return MK_ERROR( err_act_ok, NO_ERROR );				case SCSIS_KEY_NOT_READY:			return MK_ERROR( err_act_tur, ERR_DEV_NOT_READY );		case SCSIS_KEY_MEDIUM_ERROR:			return MK_ERROR( err_act_retry, ERR_DEV_READ_ERROR );					case SCSIS_KEY_HARDWARE_ERROR:			return MK_ERROR( err_act_retry, ERR_DEV_READ_ERROR );		case SCSIS_KEY_ILLEGAL_REQUEST:			return MK_ERROR( err_act_invalid_req, ERR_DEV_GENERAL );		case SCSIS_KEY_UNIT_ATTENTION:			return MK_ERROR( err_act_tur, ERR_DEV_NOT_READY );		case SCSIS_KEY_DATA_PROTECT:			// we could set "permission denied", but that's probably			// irritating to the user			return MK_ERROR( err_act_fail, ERR_NOT_ALLOWED );		case SCSIS_KEY_BLANK_CHECK:			return MK_ERROR( err_act_fail, ERR_DEV_UNREADABLE );					case SCSIS_KEY_VENDOR_SPECIFIC:			return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );		case SCSIS_KEY_COPY_ABORTED:			// we don't use copy, so this is really wrong			return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );		case SCSIS_KEY_ABORTED_COMMAND:			// proper error code?			return MK_ERROR( err_act_retry, ERR_DEV_GENERAL );		case SCSIS_KEY_EQUAL:		case SCSIS_KEY_MISCOMPARE:			// we don't search, so this is really wrong			return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );		case SCSIS_KEY_VOLUME_OVERFLOW:			// not the best return code, but this error doesn't apply			// to devices we currently support			return MK_ERROR( err_act_fail, ERR_DEV_SEEK_ERROR );				case SCSIS_KEY_RESERVED:		default:			return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );		}			default:		// shouldn't happen - there are only 2 error codes defined		return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );	}}static err_res check_scsi_status( scsi_device_info *device, CCB_SCSIIO *request ){	switch( request->cam_scsi_status & SCSI_STATUS_MASK ) {	case SCSI_STATUS_GOOD:		// shouldn't happen (cam_status should be CAM_REQ_CMP)		return MK_ERROR( err_act_ok, NO_ERROR );			case SCSI_STATUS_CHECK_CONDITION:		return check_sense( device, request );					case SCSI_STATUS_QUEUE_FULL:		// SIM should have automatically requeued request, fall through			case SCSI_STATUS_BUSY:		// take deep breath and try again		thread_snooze( 1000000 );		return MK_ERROR( err_act_retry, ERR_DEV_TIMEOUT );			case SCSI_STATUS_COMMAND_TERMINATED:		return MK_ERROR( err_act_retry, ERR_DEV_GENERAL );			default:		return MK_ERROR( err_act_retry, ERR_DEV_GENERAL );		}}err_res check_error( scsi_device_info *device, CCB_SCSIIO *request ){	switch( request->cam_ch.cam_status & CAM_STATUS_MASK ) {	// everything is ok	case CAM_REQ_CMP:		return MK_ERROR( err_act_ok, NO_ERROR );		// no device	case CAM_LUN_INVALID:	case CAM_TID_INVALID:	case CAM_PATH_INVALID:	case CAM_DEV_NOT_THERE:	case CAM_NO_HBA:		return MK_ERROR( err_act_fail, ERR_DEV_BAD_DRIVE_NUM );			// device temporary unavailable	case CAM_SEL_TIMEOUT:	case CAM_BUSY:	case CAM_SCSI_BUSY:	case CAM_HBA_ERR:	case CAM_MSG_REJECT_REC:	case CAM_NO_NEXUS:	case CAM_FUNC_NOTAVAIL:	case CAM_RESRC_UNAVAIL:		// take a deep breath and hope device becomes ready		thread_snooze( 1000000 );		return MK_ERROR( err_act_retry, ERR_DEV_TIMEOUT );	// data transmission went wrong	case CAM_DATA_RUN_ERR:	case CAM_UNCOR_PARITY:		// retry immediately		return MK_ERROR( err_act_retry, ERR_DEV_READ_ERROR );		// request broken	case CAM_REQ_INVALID:	case CAM_CCB_LEN_ERR:		return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );		// request aborted	case CAM_REQ_ABORTED:	case CAM_SCSI_BUS_RESET:	case CAM_REQ_TERMIO:	case CAM_UNEXP_BUSFREE:	case CAM_BDR_SENT:	case CAM_CMD_TIMEOUT:	case CAM_IID_INVALID:	case CAM_UNACKED_EVENT:	case CAM_IDE:		// take a small breath and retry		thread_snooze( 100000 );		return MK_ERROR( err_act_retry, ERR_DEV_TIMEOUT );	// device error	case CAM_REQ_CMP_ERR:		return check_scsi_status( device, request );		// device error, but we don't know what happened	case CAM_AUTOSENSE_FAIL:		return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );			// should not happen, give up	case CAM_BUS_RESET_DENIED:	case CAM_PROVIDE_FAIL:	case CAM_UA_TERMIO:	case CAM_CDB_RECVD:	case CAM_LUN_ALLREADY_ENAB:			default:		return MK_ERROR( err_act_fail, ERR_DEV_GENERAL );	}}

⌨️ 快捷键说明

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