summaryrefslogtreecommitdiff
path: root/usb_1.1.0/host/class/usb_host_msd_ufi.c
diff options
context:
space:
mode:
Diffstat (limited to 'usb_1.1.0/host/class/usb_host_msd_ufi.c')
-rw-r--r--usb_1.1.0/host/class/usb_host_msd_ufi.c473
1 files changed, 473 insertions, 0 deletions
diff --git a/usb_1.1.0/host/class/usb_host_msd_ufi.c b/usb_1.1.0/host/class/usb_host_msd_ufi.c
new file mode 100644
index 0000000..0e47e79
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_msd_ufi.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_MSD) && (USB_HOST_CONFIG_MSD))
+#include "usb_host.h"
+#include "usb_host_msd.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* UFI command code */
+#define UFI_FORMAT_UNIT (0x04U)
+#define UFI_INQUIRY (0x12U)
+#define UFI_START_STOP (0x1BU)
+#define UFI_MODE_SELECT (0x55U)
+#define UFI_MODE_SENSE (0x5AU)
+#define UFI_MEDIUM_REMOVAL (0x1EU)
+#define UFI_READ10 (0x28U)
+#define UFI_READ12 (0xA8U)
+#define UFI_READ_CAPACITY (0x25U)
+#define UFI_READ_FORMAT_CAPACITY (0x23U)
+#define UFI_REQUEST_SENSE (0x03U)
+#define UFI_REZERO_UINT (0x01U)
+#define UFI_SEEK (0x2BU)
+#define UFI_SEND_DIAGNOSTIC (0x1DU)
+#define UFI_TEST_UNIT_READY (0x00U)
+#define UFI_VERIFY (0x2FU)
+#define UFI_WRITE10 (0x2AU)
+#define UFI_WRITE12 (0xAAU)
+#define UFI_WRITE_VERIFY (0x2EU)
+
+#define GET_BYTE_FROM_LE_LONG(b, n) \
+ ((uint8_t)((USB_LONG_TO_LITTLE_ENDIAN(b)) >> (n * 8))) /* get the byte from the long value */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+extern usb_status_t USB_HostMsdCommand(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam,
+ uint8_t direction,
+ uint8_t byteValues[10]);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+usb_status_t USB_HostMsdRead10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ10,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdRead12(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ12,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 3),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 2),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdWrite10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_WRITE10,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdWrite12(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_WRITE12,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 3),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 2),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdReadCapacity(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ_CAPACITY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdTestUnitReady(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_TEST_UNIT_READY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdRequestSense(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_REQUEST_SENSE,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ (uint8_t)bufferLength,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdModeSelect(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_MODE_SELECT,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdModeSense(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t pageControl,
+ uint8_t pageCode,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_MODE_SENSE, (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ (uint8_t)(((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CONTROL_SHIFT) |
+ ((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CODE_SHIFT)),
+ 0x00, 0x00, 0x00, 0x00, GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0), 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdInquiry(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_INQUIRY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ (uint8_t)bufferLength,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdReadFormatCapacities(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ_FORMAT_CAPACITY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdFormatUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t trackNumber,
+ uint16_t interLeave,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_FORMAT_UNIT,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ trackNumber,
+ GET_BYTE_FROM_LE_LONG(interLeave, 1),
+ GET_BYTE_FROM_LE_LONG(interLeave, 0),
+ 0x00,
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdPreventAllowRemoval(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t prevent,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_MEDIUM_REMOVAL,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ prevent,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdWriteAndVerify(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_WRITE_VERIFY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdStartStopUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t loadEject,
+ uint8_t start,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_START_STOP, (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION), 0x00, 0x00,
+ (uint8_t)(((uint32_t)loadEject << USB_HOST_UFI_START_STOP_UNIT_LOEJ_SHIFT) |
+ ((uint32_t)start << USB_HOST_UFI_START_STOP_UNIT_START_SHIFT)),
+ 0x00, 0x00, 0x00, 0x00, 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdVerify(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint16_t verificationLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_VERIFY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(verificationLength, 1),
+ GET_BYTE_FROM_LE_LONG(verificationLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdRezeroUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_REZERO_UINT,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdSeek10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_SEEK,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdSendDiagnostic(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t selfTest,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_REZERO_UINT,
+ (uint8_t)(((uint32_t)logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION) |
+ ((uint32_t)selfTest << USB_HOST_UFI_SEND_DIAGNOSTIC_SELF_TEST_SHIFT)),
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+#endif /* USB_HOST_CONFIG_MSD */