Hello,
I dont want to disconnect the USB. I want to tell the usb host that no medium is present. How ever I got it to work.
I modified the USB_DeviceMscProcessUfiCommand function to set the sensekey.
According to the USB UFI Spec the ASC is 0x3A.
=> #define USB_DEVICE_MSC_UFI_MEDIUM_NOT_PRESENT 0x3AU
If found also a vilolation of the UFI Spec in MSC examples from NXP.
The USB_DEVICE_MSC_UFI_ADDITIONAL_LENGTH was set to 0x20 but should 0x1F according to the UFI Spec.
http://www.usb.org/developers/docs/devclass_docs/usbmass-ufi10.pdf Page 20.
The Additional Length field shall specify the length in bytes of the parameters. If the Allocation Length of the Command Packet is too small to transfer all of the parameters, the Additional Length shall not be adjusted to reflect the truncation. The UFI device shall set this field to 1Fh.
However I have not discovered any effect or impact of this violation.
usb_status_t USB_DeviceMscProcessUfiCommand(usb_device_msc_struct_t *mscHandle)
{
usb_status_t error = kStatus_USB_Error;
usb_device_msc_ufi_struct_t *ufi = NULL;
ufi = &mscHandle->g_mscUfi;
ufi->requestSense.senseKey = USB_DEVICE_MSC_UFI_NO_SENSE;
ufi->requestSense.additionalSenseCode = USB_DEVICE_MSC_UFI_NO_SENSE;
ufi->requestSense.additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE;
ufi->thirteenCase.hostExpectedDataLength = mscHandle->g_mscCbw.dataTransferLength;
ufi->thirteenCase.hostExpectedDirection =
(uint8_t)(mscHandle->g_mscCbw.flags >> USB_DEVICE_MSC_CBW_DIRECTION_SHIFT);
switch (mscHandle->g_mscCbw.cbwcb[0])
{
case USB_DEVICE_MSC_INQUIRY_COMMAND:
error = USB_DeviceMscUfiInquiryCommand(mscHandle);
break;
case USB_DEVICE_MSC_READ_10_COMMAND:
case USB_DEVICE_MSC_READ_12_COMMAND:
error = USB_DeviceMscUfiReadCommand(mscHandle);
break;
case USB_DEVICE_MSC_REQUEST_SENSE_COMMAND:
error = USB_DeviceMscUfiRequestSenseCommand(mscHandle);
break;
case USB_DEVICE_MSC_TEST_UNIT_READY_COMMAND:
error = USB_DeviceMscUfiTestUnitReadyCommand(mscHandle);
if (mscHandle->g_mscCsw.cswStatus != USB_DEVICE_MSC_PHASE_ERROR)
{
if ((not_ready_flg))
{
mscHandle->g_mscCsw.cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
}
}
break;
case USB_DEVICE_MSC_WRITE_10_COMMAND:
case USB_DEVICE_MSC_WRITE_12_COMMAND:
error = USB_DeviceMscUfiWriteCommand(mscHandle);
break;
case USB_DEVICE_MSC_PREVENT_ALLOW_MEDIUM_REM_COMMAND:
error = USB_DeviceMscUfiPreventAllowMediumCommand(mscHandle);
break;
case USB_DEVICE_MSC_FORMAT_UNIT_COMMAND:
error = USB_DeviceMscUfiFormatUnitCommand(mscHandle);
break;
case USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND:
case USB_DEVICE_MSC_READ_CAPACITY_16_COMMAND:
error = USB_DeviceMscUfiReadCapacityCommand(mscHandle);
break;
case USB_DEVICE_MSC_MODE_SENSE_10_COMMAND:
case USB_DEVICE_MSC_MODE_SENSE_6_COMMAND:
error = USB_DeviceMscUfiModeSenseCommand(mscHandle);
break;
case USB_DEVICE_MSC_MODE_SELECT_10_COMMAND:
case USB_DEVICE_MSC_MODE_SELECT_6_COMMAND:
error = USB_DeviceMscUfiModeSelectCommand(mscHandle);
break;
case USB_DEVICE_MSC_READ_FORMAT_CAPACITIES_COMMAND:
error = USB_DeviceMscUfiReadFormatCapacityCommand(mscHandle);
break;
case USB_DEVICE_MSC_SEND_DIAGNOSTIC_COMMAND:
error = USB_DeviceMscUfiSendDiagnosticCommand(mscHandle);
break;
case USB_DEVICE_MSC_VERIFY_COMMAND:
error = USB_DeviceMscUfiVerifyCommand(mscHandle);
break;
case USB_DEVICE_MSC_START_STOP_UNIT_COMMAND:
error = USB_DeviceMscUfiStartStopUnitCommand(mscHandle);
break;
default:
error = USB_DeviceMscUfiUnsupportCommand(mscHandle);
mscHandle->dataOutFlag = 0;
mscHandle->dataInFlag = 0;
mscHandle->outEndpointStallFlag = 0;
mscHandle->inEndpointStallFlag = 0;
mscHandle->needOutStallFlag = 0;
mscHandle->needInStallFlag = 0;
break;
}
if (mscHandle->g_mscCsw.cswStatus != USB_DEVICE_MSC_PHASE_ERROR)
{
if ((not_ready_flg))
{
ufi->requestSense.senseKey = USB_DEVICE_MSC_UFI_NOT_READY;
ufi->requestSense.additionalSenseCode = USB_DEVICE_MSC_UFI_MEDIUM_NOT_PRESENT;
ufi->requestSense.additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE;
}
}
return error;
}