/*! Emulate REQUEST SENSE */ void ide_request_sense(ide_device_info *device, ide_qrequest *qrequest) { scsi_ccb *request = qrequest->request; scsi_cmd_request_sense *cmd = (scsi_cmd_request_sense *)request->cdb; scsi_sense sense; uint32 transferSize; // cannot use finish_checksense here, as data is not copied into autosense buffer // but into normal data buffer, SCSI result is GOOD and CAM status is REQ_CMP if (device->combined_sense) create_sense(device, &sense); else memset(&sense, 0, sizeof(sense)); copy_sg_data(request, 0, cmd->allocation_length, &sense, sizeof(sense), false); // reset sense information on read device->combined_sense = 0; transferSize = min_c(sizeof(sense), cmd->allocation_length); transferSize = min_c(transferSize, request->data_length); request->data_resid = request->data_length - transferSize; // normally, all flags are set to "success", but for Request Sense // this would have overwritten the sense we want to read device->subsys_status = SCSI_REQ_CMP; request->device_status = SCSI_STATUS_GOOD; }
void notify_sense( ide_qrequest *qrequest ) { CCB_SCSIIO *request = qrequest->request; ide_device_info *device = qrequest->device; if( request->cam_ch.cam_status == CAM_REQ_CMP ) { request->cam_ch.cam_status = CAM_REQ_CMP_ERR; request->cam_scsi_status = SCSI_STATUS_CHECK_CONDITION; if( (request->cam_ch.cam_flags & CAM_DIS_AUTOSENSE) == 0 ) { scsi_sense sense; int sense_len; create_sense( device, &sense ); sense_len = min( request->cam_sense_len, sizeof( sense )); if( request->cam_sense_ptr != NULL ) { memcpy( request->cam_sense_ptr, &sense, sense_len ); request->cam_sense_resid = request->cam_sense_len - sense_len; request->cam_sense_len = sense_len; } request->cam_ch.cam_status |= CAM_AUTOSNS_VALID; device->combined_sense = 0; } } else // we destroyed old sense data anyway, so there's no way // to restore them if this request went seriously wrong device->combined_sense = 0; }