static rtems_status_code rtems_bsd_scsi_inquiry(union ccb *ccb, struct scsi_inquiry_data *inq_data) { memset(inq_data, 0, sizeof(*inq_data)); scsi_inquiry( &ccb->csio, BSD_SCSI_RETRIES, rtems_bsd_ccb_callback, BSD_SCSI_TAG, (u_int8_t *) inq_data, sizeof(*inq_data) - 1, FALSE, 0, SSD_MIN_SIZE, BSD_SCSI_TIMEOUT ); return rtems_bsd_ccb_action(ccb); }
int scsi_get_info(struct scsi_info *info, unsigned int lun, struct scsi_transport *tr, void *priv) { int rc; u32 *cap; unsigned char __cacheline_aligned buf[64]; struct scsi_request srb; if (!info || !tr || !tr->transport) { return VMM_EINVALID; } memset(info, 0, sizeof(*info)); INIT_SCSI_REQUEST(&srb, lun, &buf, sizeof(buf)); rc = scsi_inquiry(&srb, tr, priv); if (rc) { return rc; } info->lun = lun; info->perph_qualifier = (buf[0] & 0xE0) >> 5; info->perph_type = buf[0] & 0x1F; info->removable = (buf[1] & 0x80) ? TRUE : FALSE; memcpy(&info->vendor[0], (const void *)&buf[8], 8); memcpy(&info->product[0], (const void *)&buf[16], 16); memcpy(&info->revision[0], (const void *)&buf[32], 4); info->vendor[8] = 0; info->product[16] = 0; info->revision[4] = 0; INIT_SCSI_REQUEST(&srb, lun, NULL, 0); rc = scsi_test_unit_ready(&srb, tr, priv); if (rc) { return rc; } INIT_SCSI_REQUEST(&srb, lun, buf, sizeof(buf)); rc = scsi_read_capacity(&srb, tr, priv); if (rc) { return rc; } cap = (u32 *)buf; cap[0] = vmm_cpu_to_be32(cap[0]); cap[1] = vmm_cpu_to_be32(cap[1]); info->capacity = cap[0] + 1; info->blksz = cap[1]; info->readonly = TRUE; switch (info->perph_type) { case 0x00: case 0x0C: case 0x0E: case 0x0F: info->readonly = FALSE; break; default: break; }; if (tr->info_fixup) { tr->info_fixup(info, tr, priv); } return VMM_OK; }
bool usbhmsdLUNConnect(USBHMassStorageLUNDriver *lunp) { osalDbgCheck(lunp != NULL); osalDbgCheck(lunp->msdp != NULL); msd_result_t res; chSemWait(&lunp->sem); osalDbgAssert((lunp->state == BLK_READY) || (lunp->state == BLK_ACTIVE), "invalid state"); if (lunp->state == BLK_READY) { chSemSignal(&lunp->sem); return HAL_SUCCESS; } lunp->state = BLK_CONNECTING; { USBH_DEFINE_BUFFER(scsi_inquiry_response_t inq); uinfo("INQUIRY..."); res = scsi_inquiry(lunp, &inq); if (res == MSD_RESULT_DISCONNECTED) { goto failed; } else if (res == MSD_RESULT_TRANSPORT_ERROR) { //retry? goto failed; } else if (res == MSD_RESULT_FAILED) { //retry? goto failed; } uinfof("\tPDT=%02x", inq.peripheral & 0x1f); if (inq.peripheral != 0) { uerr("\tUnsupported PDT"); goto failed; } } // Test if unit ready uint8_t i; for (i = 0; i < 10; i++) { uinfo("TEST UNIT READY..."); res = scsi_testunitready(lunp); if (res == MSD_RESULT_DISCONNECTED) { goto failed; } else if (res == MSD_RESULT_TRANSPORT_ERROR) { //retry? goto failed; } else if (res == MSD_RESULT_FAILED) { uinfo("\tTEST UNIT READY: Command Failed, retry"); osalThreadSleepMilliseconds(200); continue; } uinfo("\tReady."); break; } if (i == 10) goto failed; { USBH_DEFINE_BUFFER(scsi_readcapacity10_response_t cap); // Read capacity uinfo("READ CAPACITY(10)..."); res = scsi_readcapacity10(lunp, &cap); if (res == MSD_RESULT_DISCONNECTED) { goto failed; } else if (res == MSD_RESULT_TRANSPORT_ERROR) { //retry? goto failed; } else if (res == MSD_RESULT_FAILED) { //retry? goto failed; } lunp->info.blk_size = __REV(cap.block_size); lunp->info.blk_num = __REV(cap.last_block_addr) + 1; } uinfof("\tBlock size=%dbytes, blocks=%u (~%u MB)", lunp->info.blk_size, lunp->info.blk_num, (uint32_t)(((uint64_t)lunp->info.blk_size * lunp->info.blk_num) / (1024UL * 1024UL))); uinfo("MSD Connected."); lunp->state = BLK_READY; chSemSignal(&lunp->sem); return HAL_SUCCESS; /* Connection failed, state reset to BLK_ACTIVE.*/ failed: uinfo("MSD Connect failed."); lunp->state = BLK_ACTIVE; chSemSignal(&lunp->sem); return HAL_FAILED; }
int scsi_parse(uint8_t *block, uint8_t in_len) { /* set new operation */ if (state == USB_MS_SCSI_STATE_IDLE) { state = USB_MS_SCSI_STATE_PARSE; op = block[0]; } /* skip operation if sending reply */ if (state != USB_MS_SCSI_STATE_REPLY) { switch (op) { case SCSI_INQUIRY: scsi_inquiry(block, in_len); break; case SCSI_MODE_SENSE6: scsi_mode_sense6(block, in_len); break; case SCSI_READ10: scsi_read10(block, in_len); break; case SCSI_READ_CAPACITY10: scsi_read_capacity10(block, in_len); break; case SCSI_READ_FORMAT_CAPACITIES: scsi_read_format_capacities(block, in_len); break; case SCSI_REPORT_LUNS: scsi_report_luns(block, in_len); break; case SCSI_REQUEST_SENSE: scsi_request_sense(block, in_len); break; case SCSI_START_STOP_UNIT: scsi_start_stop_unit(block, in_len); break; case SCSI_SYNCHRONIZE_CACHE10: scsi_synchronize_cache10(block, in_len); break; case SCSI_TEST_UNIT_READY: scsi_test_unit_ready(block, in_len); break; case SCSI_WRITE10: scsi_write10(block, in_len); break; default: state = USB_MS_SCSI_STATE_REPLY; scsi_sense_code(SCSI_SENSE_ILLEGAL_REQUEST, SCSI_SENSE_CODE_INVALID_COMMAND_OPERATION_CODE); break; } } /* error during data rx/tx */ if (((state == USB_MS_SCSI_STATE_DATA_OUT) || (state == USB_MS_SCSI_STATE_DATA_IN)) && scsi_sense_data.key) { btable_ep[USB_EP_MS_TX].tx_count = 0; state = USB_MS_SCSI_STATE_REPLY; return SCSI_STATUS_CONTINUE; } /* done sending data */ if (state == USB_MS_SCSI_STATE_REPLY) { state = USB_MS_SCSI_STATE_IDLE; return scsi_sense_data.key; } /* still sending/receiving data and no error has occurred */ return SCSI_STATUS_CONTINUE; }
void scsi_proc(void) { if (USBD_ep_buffer_full(BOMS_EP_DATA_OUT)) { if (sizeof(BOMSCmd) == USBD_transfer(BOMS_EP_DATA_OUT, (uint8_t *)&BOMSCmd, sizeof(BOMSCmd))) { if (BOMSCmd.dCBWSignature == BOMS_USBC) { if (BOMSCmd.CBWCB.unit_ready.op_code == BOMS_SCSI_TEST_UNIT_READY) // SCSI Test Unit Ready { scsi_test_unit_ready(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_READ) // SCSI Read { scsi_read(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_WRITE) // SCSI Write { scsi_write(&BOMSCmd); } else if (BOMSCmd.CBWCB.inquiry.op_code == BOMS_SCSI_INQUIRY) // SCSI Inquiry { scsi_inquiry(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_REQUEST_SENSE) // SCSI Request Sense { scsi_request_sense(&BOMSCmd); } else if (BOMSCmd.CBWCB.read_capacity.op_code == BOMS_SCSI_READ_CAPACITY) // SCSI Read Capacity (10) { scsi_read_capacity(&BOMSCmd); } else if (BOMSCmd.CBWCB.read_capacity.op_code == BOMS_SCSI_READ_FORMAT_CAPACITY) // SCSI Read Format Capacity (10) { scsi_read_format_capacity(&BOMSCmd); } else if (BOMSCmd.CBWCB.mode_sense.op_code == BOMS_SCSI_MODE_SENSE) // SCSI Mode Sense { scsi_mode_sense(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_READ_CAPACITY_16) // SCSI Read Capacity (16) { scsi_read_capacity(&BOMSCmd); } else if (BOMSCmd.CBWCB.request_sense.op_code == BOMS_SCSI_PREVENT_ALLOW_REMOVAL) // SCSI Prevent Allow Removal { scsi_prevent_allow_removal(&BOMSCmd); } else { // Send IN a zero length packet. if (BOMSCmd.dCBWDataTransferLength) { USBD_stall_endpoint(BOMS_EP_DATA_IN); } boms_send_status(BOMS_STATUS_COMMAND_FAILED, &BOMSCmd); scsi_sense_illegal_request_command(); } } else { // Was not a USBC signature. boms_send_status(BOMS_STATUS_PHASE_ERROR, &BOMSCmd); scsi_sense_illegal_request_cdb(); } }else{ // Wrong command size. boms_send_status(BOMS_STATUS_COMMAND_FAILED, &BOMSCmd); scsi_sense_illegal_request_parm(); } } }