summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--stmhal/usbd_msc_storage.c25
-rw-r--r--stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h1
-rw-r--r--stmhal/usbdev/class/cdc_msc_hid/src/usbd_cdc_msc_hid.c16
-rw-r--r--stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c32
4 files changed, 71 insertions, 3 deletions
diff --git a/stmhal/usbd_msc_storage.c b/stmhal/usbd_msc_storage.c
index f3ecd023d1..0225a2a23c 100644
--- a/stmhal/usbd_msc_storage.c
+++ b/stmhal/usbd_msc_storage.c
@@ -35,6 +35,11 @@
#include "diskio.h"
#include "sdcard.h"
+// These are needed to support removal of the medium, so that the USB drive
+// can be unmounted, and won't be remounted automatically.
+static uint8_t flash_removed = 0;
+static uint8_t sdcard_removed = 0;
+
/******************************************************************************/
// Callback functions for when the internal flash is the mass storage device
@@ -83,6 +88,9 @@ int8_t FLASH_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *blo
* @retval Status
*/
int8_t FLASH_STORAGE_IsReady(uint8_t lun) {
+ if (flash_removed) {
+ return -1;
+ }
return 0;
}
@@ -95,6 +103,12 @@ int8_t FLASH_STORAGE_IsWriteProtected(uint8_t lun) {
return 0;
}
+// Remove the lun
+int8_t FLASH_STORAGE_StopUnit(uint8_t lun) {
+ flash_removed = 1;
+ return 0;
+}
+
/**
* @brief Read data from the medium
* @param lun : logical unit number
@@ -150,6 +164,7 @@ const USBD_StorageTypeDef USBD_FLASH_STORAGE_fops = {
FLASH_STORAGE_GetCapacity,
FLASH_STORAGE_IsReady,
FLASH_STORAGE_IsWriteProtected,
+ FLASH_STORAGE_StopUnit,
FLASH_STORAGE_Read,
FLASH_STORAGE_Write,
FLASH_STORAGE_GetMaxLun,
@@ -236,6 +251,9 @@ int8_t SDCARD_STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *bl
* @retval Status
*/
int8_t SDCARD_STORAGE_IsReady(uint8_t lun) {
+ if (sdcard_removed) {
+ return -1;
+ }
/*
#ifndef USE_STM3210C_EVAL
@@ -271,6 +289,12 @@ int8_t SDCARD_STORAGE_IsWriteProtected(uint8_t lun) {
return 0;
}
+// Remove the lun
+int8_t SDCARD_STORAGE_StopUnit(uint8_t lun) {
+ sdcard_removed = 1;
+ return 0;
+}
+
/**
* @brief Read data from the medium
* @param lun : logical unit number
@@ -315,6 +339,7 @@ const USBD_StorageTypeDef USBD_SDCARD_STORAGE_fops = {
SDCARD_STORAGE_GetCapacity,
SDCARD_STORAGE_IsReady,
SDCARD_STORAGE_IsWriteProtected,
+ SDCARD_STORAGE_StopUnit,
SDCARD_STORAGE_Read,
SDCARD_STORAGE_Write,
SDCARD_STORAGE_GetMaxLun,
diff --git a/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h
index 8423ad7759..9343994931 100644
--- a/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h
+++ b/stmhal/usbdev/class/cdc_msc_hid/inc/usbd_cdc_msc_hid.h
@@ -53,6 +53,7 @@ typedef struct _USBD_STORAGE {
int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint16_t *block_size);
int8_t (* IsReady) (uint8_t lun);
int8_t (* IsWriteProtected) (uint8_t lun);
+ int8_t (* StopUnit)(uint8_t lun);
int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_t (* GetMaxLun)(void);
diff --git a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_cdc_msc_hid.c b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_cdc_msc_hid.c
index 6cb15ba210..6dc0af0e65 100644
--- a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_cdc_msc_hid.c
+++ b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_cdc_msc_hid.c
@@ -583,11 +583,18 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp
/*
printf("SU: %x %x %x %x\n", req->bmRequest, req->bRequest, req->wValue, req->wIndex);
+
This is what we get when MSC is IFACE=0 and CDC is IFACE=1,2:
SU: 21 22 0 1 -- USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; CDC_SET_CONTROL_LINE_STATE
SU: 21 20 0 1 -- USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; CDC_SET_LINE_CODING
SU: a1 fe 0 0 -- 0x80 | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; BOT_GET_MAX_LUN; 0; 0
SU: 21 22 3 1 -- USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE; CDC_SET_CONTROL_LINE_STATE
+
+ On a Mac OS X, with MSC then CDC:
+ SU: a1 fe 0 0
+ SU: 21 22 2 1
+ SU: 21 22 3 1
+ SU: 21 20 0 1
*/
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
@@ -723,6 +730,11 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp
return USBD_OK;
}
+/* unused
+static uint8_t EP0_TxSent(USBD_HandleTypeDef *pdev) {
+}
+*/
+
static uint8_t USBD_CDC_MSC_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) {
if((CDC_fops != NULL) && (CDC_ClassData.CmdOpCode != 0xFF)) {
CDC_fops->Control(CDC_ClassData.CmdOpCode, (uint8_t *)CDC_ClassData.data, CDC_ClassData.CmdLength);
@@ -902,8 +914,8 @@ USBD_ClassTypeDef USBD_CDC_MSC_HID = {
USBD_CDC_MSC_HID_DataIn,
USBD_CDC_MSC_HID_DataOut,
NULL, // SOF
- NULL,
- NULL,
+ NULL, // IsoINIncomplete
+ NULL, // IsoOUTIncomplete
USBD_CDC_MSC_HID_GetCfgDesc,
USBD_CDC_MSC_HID_GetCfgDesc,
USBD_CDC_MSC_HID_GetCfgDesc,
diff --git a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c
index af3818d373..b00d1ae2ce 100644
--- a/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c
+++ b/stmhal/usbdev/class/cdc_msc_hid/src/usbd_msc_scsi.c
@@ -86,6 +86,7 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, ui
static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_RequestSense (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
+static int8_t SCSI_AllowMediumRemoval(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params);
@@ -122,6 +123,11 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
uint8_t lun,
uint8_t *params)
{
+ /*
+ if (params[0] != SCSI_READ10 && params[0] != SCSI_WRITE10) {
+ printf("SCSI_ProcessCmd(lun=%d, params=%x, %x)\n", lun, params[0], params[1]);
+ }
+ */
switch (params[0])
{
@@ -137,7 +143,7 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
return SCSI_StartStopUnit(pdev, lun, params);
case SCSI_ALLOW_MEDIUM_REMOVAL:
- return SCSI_StartStopUnit(pdev, lun, params);
+ return SCSI_AllowMediumRemoval(pdev, lun, params);
case SCSI_MODE_SENSE6:
return SCSI_ModeSense6 (pdev, lun, params);
@@ -442,6 +448,30 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
{
USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
hmsc->bot_data_length = 0;
+
+ // On Mac OS X, when the device is ejected a SCSI_START_STOP_UNIT command is sent.
+ // params[1]==0 means stop, param[1]==1 seems to be something else (happens after the
+ // device is plugged in and mounted for some time, probably a keep alive).
+ // If we get a stop, we must really stop the device so that the Mac does not
+ // automatically remount it.
+ if (params[1] == 0) {
+ ((USBD_StorageTypeDef *)pdev->pUserData)->StopUnit(lun);
+ }
+
+ return 0;
+}
+
+/**
+* @brief SCSI_AllowMediumRemoval
+* Process Allow Medium Removal command
+* @param lun: Logical unit number
+* @param params: Command parameters
+* @retval status
+*/
+static int8_t SCSI_AllowMediumRemoval(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
+{
+ USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData;
+ hmsc->bot_data_length = 0;
return 0;
}