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

📄 ata.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
				device->no_reconnect_timeout = false;								access_finished( bus, device );				return;			}		} 				start_dma( device, qrequest );			} else {		if( qrequest->is_write ) {			xpt->schedule_dpc( bus->xpt_cookie, bus->irq_dpc, ide_dpc, bus );		}	}		return;	err_setup:	abort_dma( device, qrequest );	finish_checksense( qrequest );	return;	err_send:	abort_dma( device, qrequest );	finish_reset_queue( qrequest );	return;}bool check_rw_error( ide_device_info *device, ide_qrequest *qrequest ){	ide_bus_info *bus = device->bus;	int status;		status = bus->controller->get_altstatus( bus->channel );	if( (status & ide_status_err) != 0 ) {		int error;				if( bus->controller->read_command_block_regs( bus->channel, 			&device->tf, ide_mask_error ) != NO_ERROR )		{			set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE );			return false;		}				error = device->tf.read.error;		if( (error & ide_error_icrc) != 0 ) {			set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC );			return false;		}				if( qrequest->is_write ) {			if( (error & ide_error_wp) != 0 ) {				set_sense( device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED );				return false;			}		} else {			if( (error & ide_error_unc) != 0 ) {				set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR );				return false;			}		}				if( (error & ide_error_mc) != 0 ) {			set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED );			return false;		}				if( (error & ide_error_idnf) != 0 ) {			// ID not found - invalid CHS mapping (was: seek error?)			set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR );			return false;		}				if( (error & ide_error_mcr) != 0 ) {			// XXX proper sense key?			// for TUR this case is not defined !?			set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED );			return false;		}				if( (error & ide_error_nm) != 0 ) {			set_sense( device, SCSIS_KEY_NOT_READY, SCSIS_ASC_NO_MEDIUM );			return false;		}				if( (error & ide_error_abrt) != 0 ) {			set_sense( device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE );			return false;		}		set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE );		return false;	}		return true;}bool check_output( ide_device_info *device, bool drdy_required,	int error_mask, bool is_write ){	ide_bus_info *bus = device->bus;	int status;		if( bus->sync_wait_timeout ) {		bus->sync_wait_timeout = false;		set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT );		return false;	}		status = bus->controller->get_altstatus( bus->channel );		if( (status & ide_status_bsy) != 0 ) {		set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_TIMEOUT );		return false;	}		if( drdy_required && ((status & ide_status_drdy) == 0) ) {		set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE );		return false;	}	if( (status & ide_status_err) != 0 ) {		int error;				if( bus->controller->read_command_block_regs( bus->channel, 			&device->tf, ide_mask_error ) != NO_ERROR )		{			set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE );			return false;		}				error = device->tf.read.error & error_mask;				if( (error & ide_error_icrc) != 0 ) {			set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC );			return false;		}				if( is_write ) {			if( (error & ide_error_wp) != 0 ) {				set_sense( device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED );				return false;			}		} else {			if( (error & ide_error_unc) != 0 ) {				set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR );				return false;			}		}				if( (error & ide_error_mc) != 0 ) {			// XXX what are the additional sense data for "medium changed" ?			set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_NO_SENSE );			return false;		}				if( (error & ide_error_idnf) != 0 ) {			// XXX strange error code, don't really know what it means			set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR );			return false;		}				if( (error & ide_error_mcr) != 0 ) {			// XXX proper sense key?			set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED );			return false;		}				if( (error & ide_error_nm) != 0 ) {			set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM );			return false;		}				if( (error & ide_error_abrt) != 0 ) {			set_sense( device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE );			return false;		}		set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE );		return false;	}		return true;}// set subcommand before callingstatic bool device_set_feature( ide_device_info *device, int feature ){	device->tf_param_mask = ide_mask_features;		device->tf.write.features = feature;	device->tf.write.command = IDE_CMD_SET_FEATURES;		if( !send_command( device, true, 1000000, ide_state_sync_waiting ))		return false;	sem_acquire( device->bus->sync_wait_sem, 1 );		return check_output( device, true, ide_error_abrt, false );}static bool configure_rmsn( ide_device_info *device ){	ide_bus_info *bus = device->bus;	int i;		if( !device->infoblock.RMSN_supported ||		device->infoblock._127_RMSN_support != 1 )		return true;	if( !device_set_feature( device, IDE_CMD_SET_FEATURES_ENABLE_MSN ))		return false;	bus->controller->read_command_block_regs( bus->channel, &device->tf, 		ide_mask_LBA_mid | ide_mask_LBA_high );	for( i = 0; i < 5; ++i ) {		// don't use TUR as it checks not ide_error_mcr | ide_error_mc | ide_error_wp		// but: we don't check wp as well		device->combined_sense = 0;				device->tf_param_mask = 0;		device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS;				if( !send_command( device, true, 15000000, ide_state_sync_waiting )) 			continue;			if( check_output( device, true, 			ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc,			true )			|| decode_sense_asc_ascq( device->combined_sense ) == SCSIS_ASC_NO_MEDIUM )			return true;	}	return false;}static bool configure_CQ( ide_device_info *device ){	device->CQ_enabled = device->CQ_supported = false;		if( !device->bus->controller_params.can_CQ ||		!device->infoblock.DMA_QUEUED_supported ) 		return initialize_qreq_array( device, 1 );			// seems like the following functions always fail	if( !device_set_feature( device, IDE_CMD_SET_FEATURES_DISABLE_REL_INT )) {		dprintf( "Cannot disable release int\n" );	}			if( !device_set_feature( device, IDE_CMD_SET_FEATURES_DISABLE_SERV_INT )) {		dprintf( "Cannot disable release int\n" );	}		device->CQ_enabled = device->CQ_supported = true;		// official IBM docs talk about 31 queue entries, though 	// their disks report 32; let's hope their docs are wrong	return initialize_qreq_array( device, device->infoblock.queue_depth + 1 );}bool prep_ata( ide_device_info *device ){	ide_device_infoblock *infoblock = &device->infoblock;	uint32 chs_capacity;		SHOW_FLOW0( 3, "" );		device->is_atapi = false;	device->exec_io = ata_exec_io;		// warning: ata == 0 means "this is ata"...	if( infoblock->_0.ata.ATA != 0 ) {		// CF has either magic header or CFA bit set		// we merge it to "CFA bit set" for easier (later) testing		if( *(uint16 *)infoblock == 0x848a )			infoblock->CFA_supported = true;		else			return false;	}		SHOW_FLOW0( 3, "1" );	if( !infoblock->_54_58_valid ) {		// normally, current_xxx contains active CHS mapping,		// but if BIOS didn't call INITIALIZE DEVICE PARAMETERS		// the default mapping is used		infoblock->current_sectors = infoblock->sectors;		infoblock->current_cylinders = infoblock->cylinders;		infoblock->current_heads = infoblock->heads;	} 		// just in case capacity_xxx isn't initialized - calculate it manually	// (seems that this information is really redundant; hopefully)	chs_capacity = infoblock->current_sectors * infoblock->current_cylinders * 		infoblock->current_heads;			infoblock->capacity_low = chs_capacity & 0xff;	infoblock->capacity_high = chs_capacity >> 8;		// checking LBA_supported flag should be sufficient, but it seems	// that checking LBA_total_sectors is a good idea	device->use_LBA = infoblock->LBA_supported && infoblock->LBA_total_sectors != 0;		if( device->use_LBA ) {		device->total_sectors = infoblock->LBA_total_sectors;		device->tf.lba.mode = ide_mode_lba;	} else {		device->total_sectors = chs_capacity;		device->tf.chs.mode = ide_mode_chs;	}			device->use_48bits = infoblock->_48_bit_addresses_supported;		if( device->use_48bits )		device->total_sectors = infoblock->LBA48_total_sectors;			SHOW_FLOW0( 3, "2" );	if( !configure_DMA( device ) ||		!configure_CQ( device ) ||		!configure_rmsn( device ))		return false;			SHOW_FLOW0( 3, "3" );			return true;}void enable_CQ( ide_device_info *device, bool enable ){}

⌨️ 快捷键说明

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