Я работаю с прошивкой для оборудования с интерфейсом USB. Когда устройство подключено к USB-порту, оно перечисляет 2 класса: CD C & MS C.
Для части MS C устройство настраивается пользователем таким образом, что устройство может быть защищено от записи. Таким образом, пользователь может выбрать, будет ли устройство доступно только для чтения или имеет возможность чтения-записи.
Я использую предварительно написанную USB-библиотеку, которая может перечислять устройство с 2 интерфейсами. Часть, с которой я борюсь, это как я могу позволить своей прошивке работать так, как будто устройство доступно только для чтения.
Микроконтроллер относится к серии STM32L4. Большая часть кода генерируется из программного обеспечения STM32CubeMX.
После некоторого исследования я выяснил, что SCSI Write10 вместе с командами SCSI Request Sense может проверить, защищена ли MS C от записи. Текущая реализация выглядит следующим образом:
static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params)
{
USBD_CDC_MSC_HandleTypeDef *hmsc = pdev->pClassData;
uint32_t len;
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
/* case 8 : Hi <> Do */
if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U)
{
SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
return -1;
}
/* Check whether Media is ready */
if(((USBD_CDC_StorageItfTypeDef *)pdev->pUserData)->IsReady(lun) !=0 )
{
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
return -1;
}
/* Check If media is write-protected */
if(((USBD_CDC_StorageItfTypeDef *)pdev->pUserData)->IsWriteProtected(lun) !=0 )
{
SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
return -1;
}
// Other code
}
Я отладил и проверил, что IsWriteProtected()
правильно возвращает ненулевое значение, когда устройство настроено как защищенное от записи. SCSI_SenseCode()
выдвигает код ошибки в круговом списке. Windows должен отправить команду Request Sense SCSI для получения кода ошибки, но я проверил с точкой останова, что Windows никогда не отправлял эту команду!
int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
{
switch (cmd[0])
{
case SCSI_TEST_UNIT_READY:
SCSI_TestUnitReady(pdev, lun, cmd);
break;
case SCSI_REQUEST_SENSE:
SCSI_RequestSense (pdev, lun, cmd); // <<-- This is never reached
break;
case SCSI_INQUIRY:
SCSI_Inquiry(pdev, lun, cmd);
break;
....
Если я настраиваю устройство в режиме записи - В порядке защиты перечисление дисков в P C занимает очень много времени, а File Explorer очень долго занят. После перечисления я могу открыть дисковод и, если я попытаюсь выполнить запись на диск, Windows сообщит, что произошел дисковый ввод-вывод, и запись не удалась. Я ожидал, что Windows сообщит мне, что диск доступен только для чтения.
Если я настрою устройство с разрешением записи, то перечисление диска займет обычное время, как если бы я подключил обычное перо диск.
- Почему Windows никогда не отправлял команду SCSI Request Sense?
- Почему перечисление диска занимает очень много времени, когда возвращается -1 из-за защиты от записи из команды Write10? Мне нужен диск для быстрого перечисления с защитой от записи или без нее.