rem: return;	}  default: set_sense( device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE );
add: case SCSI_OP_PREVENT_ALLOW: { scsi_cmd_prevent_allow *cmd = (scsi_cmd_prevent_allow *)request->cdb;  ata_prevent_allow(device, cmd->prevent); break; }  case SCSI_OP_READ_CAPACITY: read_capacity(device, qrequest); break;  case SCSI_OP_VERIFY:   set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); break;  case SCSI_OP_SYNCHRONIZE_CACHE:  ata_flush_cache(device, qrequest); break;    case SCSI_OP_READ_6: case SCSI_OP_WRITE_6: { scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb; uint32 pos; size_t length;  pos = ((uint32)cmd->high_LBA << 16) | ((uint32)cmd->mid_LBA << 8) | (uint32)cmd->low_LBA;  length = cmd->length != 0 ? cmd->length : 256;  SHOW_FLOW(3, "READ6/WRITE6 pos=%lx, length=%lx", pos, length);  ata_send_rw(device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_6); return; }  case SCSI_OP_READ_10: case SCSI_OP_WRITE_10: { scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb; uint32 pos; size_t length;  pos = ((uint32)cmd->top_LBA << 24) | ((uint32)cmd->high_LBA << 16) | ((uint32)cmd->mid_LBA << 8) | (uint32)cmd->low_LBA;  length = ((uint32)cmd->high_length << 8) | cmd->low_length;  if (length != 0) { ata_send_rw(device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_10); } else {  finish_request(qrequest, false); } return; }  default: set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE);
context: ata_exec_io(ide_device_info *device, ide_qrequest *qrequest){	scsi_ccb *request = qrequest->request;		SHOW_FLOW( 3, "command=%x", request->cdb[0] );			// ATA devices have one LUN only	if( request->target_lun != 0 ) {		request->subsys_status = SCSI_SEL_TIMEOUT;		finish_request( qrequest, false );		return;	}		// starting a request means deleting sense, so don't do it if	// the command wants to read it	if( request->cdb[0] != SCSI_OP_REQUEST_SENSE )			start_request( device, qrequest );		switch( request->cdb[0] ) {	case SCSI_OP_TUR:		ata_tur( device, qrequest );		break;	case SCSI_OP_REQUEST_SENSE:		ide_request_sense( device, qrequest );		return;			case SCSI_OP_FORMAT: /* FORMAT UNIT */		// we could forward request to disk, but modern disks cannot		// be formatted anyway, so we just refuse request		// (exceptions are removable media devices, but to my knowledge		// they don't have to be formatted as well)		set_sense( device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE );		break;	case SCSI_OP_INQUIRY: 		ata_inquiry( device, qrequest );		break;	case SCSI_OP_MODE_SELECT_10:		ata_mode_select_10( device, qrequest );		break;				case SCSI_OP_MODE_SENSE_10:		ata_mode_sense_10( device, qrequest );		break;		case SCSI_OP_MODE_SELECT_6:	case SCSI_OP_MODE_SENSE_6:		// we've told SCSI bus manager to emulates these commands		set_sense( device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE );		break;			case SCSI_OP_RESERVE:	case SCSI_OP_RELEASE:		// though mandatory, this doesn't make much sense in a		// single initiator environment; so what		set_sense( device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE );		break;			case SCSI_OP_START_STOP: {		scsi_cmd_ssu *cmd = (scsi_cmd_ssu *)request->cdb;				// with no LoEj bit set, we should only allow/deny further access		// we ignore that (unsupported for ATA)		// with LoEj bit set, we should additionally either load or eject the medium		// (start = 0 - eject; start = 1 - load)				if( !cmd->start )			// we must always flush cache if start = 0			ata_flush_cache( device, qrequest );				if( cmd->LoEj )			ata_load_eject( device, qrequest, cmd->start );					break; }			case SCSI_OP_PREVENT_ALLOW: {		scsi_cmd_prevent_allow *cmd = (scsi_cmd_prevent_allow *)request->cdb;				ata_prevent_allow( device, cmd->prevent );		break; }		case SCSI_OP_READ_CAPACITY:		read_capacity( device, qrequest );		break;				case SCSI_OP_VERIFY:		// does anyone uses this function?		// effectly, it does a read-and-compare, which IDE doesn't support		set_sense( device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE );		break;		case SCSI_OP_SYNCHRONIZE_CACHE:		// we ignore range and immediate bit, we always immediately flush everything 		ata_flush_cache( device, qrequest );		break;		// sadly, there are two possible read/write operation codes;	// at least, the third one, read/write(12), is not valid for DAS	case SCSI_OP_READ_6:	case SCSI_OP_WRITE_6: {		scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb;		uint32 pos;		size_t length;				pos = ((uint32)cmd->high_LBA << 16) | ((uint32)cmd->mid_LBA << 8)			| (uint32)cmd->low_LBA;					length = cmd->length != 0 ? cmd->length : 256;				SHOW_FLOW( 3, "READ6/WRITE6 pos=%ux, length=%ux", (uint)pos, (uint)length );				ata_send_rw( device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_6 );				return; }			case SCSI_OP_READ_10:	case SCSI_OP_WRITE_10: {		scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb;		uint32 pos;		size_t length;				pos = ((uint32)cmd->top_LBA << 24) | ((uint32)cmd->high_LBA << 16) 			| ((uint32)cmd->mid_LBA << 8) | (uint32)cmd->low_LBA;					length = ((uint32)cmd->high_length << 8) | cmd->low_length;				if( length != 0 ) {			ata_send_rw( device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_10 );		} else {			// we cannot transfer zero blocks (apart from LBA48)			finish_request( qrequest, false );		}		return;	}			default:		set_sense( device, 			SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE );	}		finish_checksense( qrequest );}