{"id":385576,"date":"2024-06-29T06:11:48","date_gmt":"2024-06-29T06:11:48","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=385576"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=385576","title":{"rendered":"<span>USB Mass Storage BOT \u0447\u0438\u043d\u0438\u043c multi LUN \u0443 STM32<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u043e\u043f\u0430\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e USB \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0438\u043a\u0438\u0434\u044b\u0432\u0430\u043b\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0434\u0438\u0441\u043a\u043e\u0432\u044b\u043c\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0434\u043b\u044f MicroSD, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 EEPROM \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u0435\u043a \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438. \u0420\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043f\u043e\u0439\u0442\u0438 \u043f\u043e \u043f\u0443\u0442\u0438 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0433\u043e \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0432 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u0442\u043e \u0447\u0442\u043e ST \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0432 \u0441\u0432\u043e\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435. \u0420\u0430\u0431\u043e\u0442\u0430 c USB \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u0443 \u043d\u0438\u0445 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438: \u0434\u0440\u0430\u0439\u0432\u0435\u0440 + MiddleWare:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2f2\/877\/436\/2f28774362d6a409d18ea361a7304c62.png\" alt=\"USB \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 STM32\" title=\"USB \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 STM32\" width=\"690\" height=\"599\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2f2\/877\/436\/2f28774362d6a409d18ea361a7304c62.png\"\/><figcaption>USB \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 STM32<\/figcaption><\/figure>\n<p>\u041e\u0448\u0438\u0431\u043a\u0438 \u0443 \u043d\u0430\u0441 \u0437\u0430\u043a\u0440\u0430\u043b\u0438\u0441\u044c MiddleWare \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0442\u043e\u043c\u0443, \u0447\u0442\u043e MiddleWare \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d \u043e\u0442 \u0436\u0435\u043b\u0435\u0437\u0430, \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u043a\u0430\u043c\u0438 \u043a\u043e\u0434\u0430. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 MiddleWare \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u043e \u0443 ST \u0432 UM1717, UM0424, UM1021, UM1720.<\/p>\n<h2>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 (\u0432 \u0447\u0438\u0441\u0442\u043e\u043c \u0432\u0438\u0434\u0435, \u0447\u0442\u043e ST \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b)<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u043a\u0443\u0431\u0435 \u043f\u0440\u043e\u0435\u043a\u0442, \u0437\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c USB \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0432 MiddleWare Class For FS IP: Mass Storage Class \u0438 \u043f\u0440\u0430\u0432\u0438\u043c \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u044b. \u0417\u0430\u0442\u0435\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 USB_DEVICE->App->usbd_storage_if.c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 LUN. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0444\u0430\u0439\u043b\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0430\u0439\u043b USB_DEVICE->App->usbd_storage_if.c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* USER CODE BEGIN PRIVATE_TYPES *\/  typedef enum LUN_NUM{ LUN_NUM_MICROSD =0, LUN_NUM_EEPROM, LUN_NUM_SYSTEM, LUN_NUM_TEST } lun_num_t;  \/* USER CODE END PRIVATE_TYPES *\/  \/* USER CODE BEGIN PRIVATE_DEFINES *\/  #define STORAGE_LUNS0x8  #define EEPROM_BLOCK_SIZE 512 #define EEPROM_BLOCKS   64  \/* USER CODE END PRIVATE_DEFINES *\/  \/** USB Mass storage Standard Inquiry Data. *\/ const int8_t STORAGE_Inquirydata_FS[] = {\/* 36 *\/    \/* LUN 0 *\/   0x00,   0x00, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80   0x02,   0x02,   (STANDARD_INQUIRY_DATA_LEN - 5),   0x00,   0x00,   0x00,   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/   'M', 'i', 'c', 'r', 'o', 'S', 'D', ' ', \/* Product      : 16 Bytes *\/   'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',   '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/    \/* LUN 1 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'E', 'E', 'P', 'R', 'O', 'M', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/    \/* LUN 2 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'S', 'y', 's', 't', 'e', 'm', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 3 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'T', 'e', 's', 't', ' ', ' ', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 4 *\/   0x00,   0x00, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80   0x02,   0x02,   (STANDARD_INQUIRY_DATA_LEN - 5),   0x00,   0x00,   0x00,   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/   'M', 'i', 'c', 'r', 'o', 'S', 'D', '2', \/* Product      : 16 Bytes *\/   'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',   '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/    \/* LUN 5 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'E', 'E', 'P', 'R', 'O', 'M', '2', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/    \/* LUN 6 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reseForrved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'S', 'y', 's', 't', 'e', 'm', '2', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 7 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'T', 'e', 's', 't', '2', ' ', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/   }; \/* USER CODE END INQUIRY_DATA_FS *\/  int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size) {   \/* USER CODE BEGIN 3 *\/   switch(lun){     case LUN_NUM_MICROSD:     *block_num  = sd_card_glb->data.size_kb &lt;&lt; 1;     *block_size = sd_card_glb->data.block_size;     break;     case LUN_NUM_EEPROM:       *block_num  = EEPROM_BLOCKS;       *block_size = EEPROM_BLOCK_SIZE;       break;     case LUN_NUM_SYSTEM:       *block_num  = EEPROM_BLOCKS &lt;&lt; 2;       *block_size = EEPROM_BLOCK_SIZE;       break;     case LUN_NUM_TEST:       *block_num  = EEPROM_BLOCKS &lt;&lt; 4;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x04:       *block_num  = EEPROM_BLOCKS &lt;&lt; 5;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x05:       *block_num  = EEPROM_BLOCKS &lt;&lt; 6;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x06:       *block_num  = EEPROM_BLOCKS &lt;&lt; 7;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x07:       *block_num  = EEPROM_BLOCKS &lt;&lt; 8;       *block_size = EEPROM_BLOCK_SIZE;       break;   }     return (USBD_OK);   \/* USER CODE END 3 *\/ }  int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {   \/* USER CODE BEGIN 6 *\/    switch(lun){     case LUN_NUM_MICROSD:     sd_card_read_single_block(sd_card_glb, blk_addr, buf); \/*for (int i =0 ; i&lt;512; i++){   buf[i] = blk_addr; }*\/   break;   case LUN_NUM_EEPROM:   for (int i =0 ; i&lt;512; i++){   buf[i] = i;   }   break;   case LUN_NUM_SYSTEM:       for (int i =0 ; i&lt;512; i++){   buf[i] = blk_addr;   }       break;     case LUN_NUM_TEST:       for (int i =0 ; i&lt;512; i++){   buf[i] = lun;   }       break;   }     return (USBD_OK);   \/* USER CODE END 6 *\/ }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 8 LUN \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e 2, \u0434\u0430 \u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u0435\u0441\u043b\u0438 \u0432  STORAGE_GetCapacity_FS \u0432\u044b\u0434\u0430\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 LUN, \u0434\u0430 \u0435\u0449\u0451 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u0435\u0440\u0435\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f&#8230;<\/p>\n<details class=\"spoiler\">\n<summary>\u0412 kernel log:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">usb 1-1: new full-speed USB device number 10 using xhci_hcd usb 1-1: New USB device found, idVendor=0483, idProduct=572a, bcdDevice= 2.00 usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-1: Product: Test MASS Storage usb 1-1: Manufacturer: Developer usb 1-1: SerialNumber: 2062369C5950 usb-storage 1-1:1.0: USB Mass Storage device detected scsi host4: usb-storage 1-1:1.0 scsi 4:0:0:0: Direct-Access     STM      MicroSD Device   0.01 PQ: 0 ANSI: 2 scsi 4:0:0:1: Direct-Access     STM      EEPROM           0.01 PQ: 0 ANSI: 2 scsi 4:0:0:0: Attached scsi generic sg1 type 0 scsi 4:0:0:1: Attached scsi generic sg2 type 0 sd 4:0:0:0: [sdb] 1030144 512-byte logical blocks: (527 MB\/503 MiB) sd 4:0:0:1: [sdc] 64 512-byte logical blocks: (32.8 kB\/32.0 KiB) sd 4:0:0:1: [sdc] Write Protect is off sd 4:0:0:1: [sdc] Mode Sense: 22 0 0 0 sd 4:0:0:1: [sdc] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA  sdb: sdb1 sdb2 sdb3 usb 1-1: reset full-speed USB device number 10 using xhci_hcd sd 4:0:0:0: [sdb] Attached SCSI disk usb 1-1: reset full-speed USB device number 10 using xhci_hcd usb 1-1: reset full-speed USB device number 10 using xhci_hcd sd 4:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE cmd_age=0s sd 4:0:0:0: [sdb] tag#0 Sense Key : Illegal Request [current] sd 4:0:0:0: [sdb] tag#0 Add. Sense: Logical block address out of range sd 4:0:0:0: [sdb] tag#0 CDB: Read(10) 28 0 0 0f b7 f8 0 0 1 0 blk_update_request: critical target error, dev sdb, sector 1030136 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0 sd 4:0:0:1: [sdc] Attached SCSI disk sd 4:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE cmd_age=0s sd 4:0:0:0: [sdb] tag#0 Sense Key : Illegal Request [current] sd 4:0:0:0: [sdb] tag#0 Add. Sense: Logical block address out of range sd 4:0:0:0: [sdb] tag#0 CDB: Read(10) 28 0 0 0f b7 f8 0 0 1 0 blk_update_request: critical target error, dev sdb, sector 1030136 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0 buffer_io_error: 1 callbacks suppressed Buffer I\/O error on dev sdb, logical block 128767 async page read<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u043b\u043e\u0433\u0435 USB, \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u043c Wireshark:<\/p>\n<p>\u0437\u0430\u043f\u0440\u043e\u0441 USBMS 64  GET MAX LUN &#8212; \u043e\u0442\u0434\u0430\u0451\u0442  7 (LUN \u043d\u0443\u043c\u0435\u0440\u0443\u044e\u0442\u0441\u044f \u0441 0 \u0438 \u043e\u0442\u0434\u0430\u0451\u0442\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440), \u0430 LUN 2 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 &#8212; \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f<\/p>\n<p>\u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b SCSI: Data In LUN:  (Mode Sense(6)  &#8212; \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0430 \u044d\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e LUN, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0434\u0435\u043b\u0430\u044e\u0449\u0438\u0435 \u0438\u0445 readonly<\/p>\n<p> \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 USBMS 95  SCSI Command: 0xa1 LUN:0x00 &#8212; \u043a\u043e\u043c\u0430\u043d\u0434\u0430 ATA Command Pass-Through, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0434\u0451\u0442 \u043f\u0435\u0440\u0435\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e \u0448\u0438\u043d\u0435 c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>WireShark log:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">386 4.538519  1.10.1  host  USBMS 77  SCSI: Response LUN: 0x00 (Read Capacity(10)) (Good) 387 4.538572  host  1.10.1  USBMS 95  SCSI Command: 0xa1 LUN:0x00 388 4.538641  1.10.1  host  USB 64  URB_BULK out 389 4.538657  host  1.10.1  USB 64  URB_BULK in 390 4.538711  1.10.1  host  USB 64  URB_BULK in 391 4.538726  host  1.10.0  USB 64  CLEAR FEATURE Request 392 4.538810  1.10.0  host  USB 64  CLEAR FEATURE Response 393 4.538824  host  1.10.1  USB 64  URB_BULK in 394 4.538925  1.10.1  host  USB 64  URB_BULK in 395 4.538937  host  1.10.0  USB 64  CLEAR FEATURE Request 396 4.539014  1.10.0  host  USB 64  CLEAR FEATURE Response 397 4.539067  host  1.10.1  USB 64  URB_BULK in 398 4.539125  1.10.1  host  USB 64  URB_BULK in 399 4.539169  host  1.10.0  USB 64  CLEAR FEATURE Request 400 4.539254  1.10.0  host  USB 64  CLEAR FEATURE Response 415 4.815078  host  1.10.0  USB 64  GET DESCRIPTOR Request DEVICE 416 4.815289  1.10.0  host  USB 82  GET DESCRIPTOR Response DEVICE 417 4.815371  host  1.10.0  USB 64  GET DESCRIPTOR Request BOS 418 4.815507  1.10.0  host  USB 69  GET DESCRIPTOR Response BOS 419 4.815584  host  1.10.0  USB 64  GET DESCRIPTOR Request BOS 420 4.815802  1.10.0  host  USB 76  GET DESCRIPTOR Response BOS 421 4.815898  host  1.10.0  USB 64  GET DESCRIPTOR Request CONFIGURATION 422 4.816161  1.10.0  host  USB 96  GET DESCRIPTOR Response CONFIGURATION 423 4.816257  host  1.10.0  USB 64  GET DESCRIPTOR Request CONFIGURATION 424 4.816527  1.10.0  host  USB 96  GET DESCRIPTOR Response CONFIGURATION 425 4.816616  host  1.10.0  USB 64  GET DESCRIPTOR Request CONFIGURATION 426 4.816874  1.10.0  host  USB 96  GET DESCRIPTOR Response CONFIGURATION 427 4.816959  host  1.10.0  USB 64  GET DESCRIPTOR Request CONFIGURATION 428 4.817224  1.10.0  host  USB 96  GET DESCRIPTOR Response CONFIGURATION 429 4.817309  host  1.10.0  USB 64  GET DESCRIPTOR Request STRING 430 4.817470  1.10.0  host  USB 90  GET DESCRIPTOR Response STRING 431 4.818177  host  1.10.0  USB 64  SET CONFIGURATION Request 432 4.818338  1.10.0  host  USB 64  SET CONFIGURATION Response 433 4.818507  host  1.10.1  USBMS 95  SCSI: Read(10) LUN: 0x03 (LBA: 0x00000008, Len: 8)<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 LUN, \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u043f\u0440\u0438 \u043e\u0434\u043d\u043e\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u0438 \u0443 \u043d\u0430\u0441 \u0442\u043e\u043b\u044c\u043a\u043e 2 LUN \u0438 \u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0440\u0430\u0432\u043d\u044b. \u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b:<\/p>\n<ol>\n<li>\n<p>\u041d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043c\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e LUN \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043d\u0430 call back \u0444\u0443\u043d\u043a\u0446\u0438\u044e int8_t STORAGE_GetMaxLun_FS(void) &#8212; \u043e\u0442\u0434\u0430\u0451\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0432\u043e LUN, \u043d\u043e LUN \u0431\u043e\u043b\u044c\u0448\u0435 1 &#8212; \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 LUN\u044b \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 &#8212; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043c\u0435\u043d\u044c\u0448\u0438\u043c \u0438\u0437 \u043d\u0438\u0445, \u0438\u043d\u0430\u0447\u0435, \u0441\u0443\u0434\u044f \u043f\u043e \u043b\u043e\u0433\u0430\u043c &#8212; \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043d\u043e\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0439 \u0441\u0431\u0440\u043e\u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e \u0448\u0438\u043d\u0435 \u0438\u0437-\u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 SCSI 0xa1 ATA Command Pass-Through<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435 \u0434\u0435\u043b\u0430\u0442\u044c, \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 Mass Storage \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c BOT<\/p>\n<h2>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b USB Mass Storage BOT<\/h2>\n<p>\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b BOT \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a Bulk Only Transfer, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0449\u0451 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 BBB, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 3 \u0444\u0430\u0437\u044b \u043e\u0431\u043c\u0435\u043d\u0430 (\u043a\u043e\u043c\u0430\u043d\u0434\/\u0434\u0430\u043d\u043d\u044b\u0445\/\u0441\u0442\u0430\u0442\u0443\u0441\u0430) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f\u0430 bulk. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0435\u0449\u0451 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b CBI, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u044e\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0443\u0436\u0435 3 \u0442\u0438\u043f\u043e\u0432: Control Bulk Interrupt, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439\u0441\u044f, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c, \u0434\u043b\u044f full-speed floppy \u0434\u0438\u0441\u043a\u043e\u0432\u043e\u0434\u043e\u0432.<\/p>\n<p>\u041d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043e\u043c\u0430\u043d\u0434, \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 BOT. \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 CBW \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043f\u0430\u043a\u0435\u0442, \u0434\u043b\u0438\u043d\u043e\u0439 31 \u0431\u0430\u0439\u0442. CBW \u0438 \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b CSW \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044e\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0430\u043a\u0435\u0442. \u0415\u0449\u0451 \u043e\u0434\u043d\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u044d\u0442\u043e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 CBW &#8212; little-endian \u0441 LSB (0 \u0431\u0430\u0439\u0442 \u0438\u0434\u0451\u0442 \u043f\u0435\u0440\u0432\u044b\u043c).<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/722\/efd\/8c7\/722efd8c7df605b10447a6d52dcf61aa.png\" alt=\"\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\/\u0434\u0430\u043d\u043d\u044b\u0445\/\u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 BOT \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\" title=\"\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\/\u0434\u0430\u043d\u043d\u044b\u0445\/\u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 BOT \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\" width=\"397\" height=\"641\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/722\/efd\/8c7\/722efd8c7df605b10447a6d52dcf61aa.png\"\/><figcaption>\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\/\u0434\u0430\u043d\u043d\u044b\u0445\/\u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 BOT \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441<\/figcaption><\/figure>\n<p>\u0412 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 BOT \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0442 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b SCSI (<em>Small Computer System Interface<\/em>), \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0439 \u0435\u0449\u0451 \u0432 1978 \u0433\u043e\u0434\u0443 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0434\u0430\u0447\u043d\u044b\u043c, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0431\u043b\u043e\u0447\u043d\u044b\u043c\u0438 \u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044f\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u0420\u0430\u0431\u043e\u0442\u0430 \u043f\u043e SCSI \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ol>\n<li>\n<p>\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443 \u0445\u043e\u0441\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438: SCSI:  [\u043a\u043e\u043c\u0430\u043d\u0434\u0430 + \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b]<\/p>\n<\/li>\n<li>\n<p>\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043e\u0442\u0434\u0430\u0451\u0442 \u0445\u043e\u0441\u0442\u0443 \u0434\u0430\u043d\u043d\u044b\u0435: SCSI Payload (Inquiry Response Data)<\/p>\n<\/li>\n<li>\n<p>\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043e\u0442\u0434\u0430\u0451\u0442 \u0445\u043e\u0441\u0442\u0443 \u0441\u0442\u0430\u0442\u0443\u0441: SCSI: Response (Inquiry) [\u0441\u0442\u0430\u0442\u0443\u0441]<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/344\/eac\/946\/344eac946574e3c8b627dd3283f36f02.jpg\" alt=\"\u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445\" title=\"\u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445\" width=\"1078\" height=\"621\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/344\/eac\/946\/344eac946574e3c8b627dd3283f36f02.jpg\" data-blurred=\"true\"\/><figcaption>\u0427\u0442\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/figcaption><\/figure>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/2b6\/5a8\/7e2\/2b65a87e29b2a4c12ccf3df50a192a90.jpg\" alt=\"\u0417\u0430\u043f\u0438\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0445\" title=\"\u0417\u0430\u043f\u0438\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0445\" width=\"1067\" height=\"632\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2b6\/5a8\/7e2\/2b65a87e29b2a4c12ccf3df50a192a90.jpg\" data-blurred=\"true\"\/><figcaption>\u0417\u0430\u043f\u0438\u0441\u044c \u0434\u0430\u043d\u043d\u044b\u0445<\/figcaption><\/figure>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0431\u043e\u0440 \u043a\u043e\u043c\u0430\u043d\u0434 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439. \u041a\u043e\u043c\u0430\u043d\u0434\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043d\u0430\u0448\u0438\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043f\u043e USB \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>\u041f\u0440\u0442\u043e\u043a\u043e\u043b<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>\u041d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430<\/p>\n<\/td>\n<td>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>USB<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>-><\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430<\/p>\n<\/td>\n<td>\n<p>\u0422\u0438\u043f \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>USB<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>&lt;-<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>DESCRIPTOR Request<\/p>\n<\/td>\n<td>\n<p>\u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>USBMS<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>-><\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u043e\u043c\u0435\u0440\u0430 LUN<\/p>\n<\/td>\n<td>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>USBMS<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>&lt;-<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>GET MAX LUN Response<\/p>\n<\/td>\n<td>\n<p>\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>-><\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b LUN<\/p>\n<\/td>\n<td>\n<p>\u043d\u043e\u043c\u0435\u0440 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>&lt;-<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>SCSI: Data In LUN: 0xyy (Inquiry Response Data)<\/p>\n<\/td>\n<td>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>-><\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u042e\u043d\u0438\u0442 \u0442\u0435\u0441\u0442 LUN<\/p>\n<\/td>\n<td>\n<p>\u041d\u043e\u043c\u0435\u0440 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>&lt;-<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>SCSI: Response LUN: 0xyy (Test Unit Ready)<\/p>\n<\/td>\n<td>\n<p>\u0441\u0442\u0430\u0442\u0443\u0441 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>-><\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0451\u043c\u043a\u043e\u0441\u0442\u0438 LUN: \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043b\u043e\u043a\u043e\u0432<\/p>\n<\/td>\n<td>\n<p>\u043d\u043e\u043c\u0435\u0440 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>&lt;-<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>SCSI: Data In LUN: 0x01 (Read Capacity(10) Response Data)<\/p>\n<\/td>\n<td>\n<p>\u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043b\u043e\u043a\u043e\u0432 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>-><\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0440\u0435\u0436\u0438\u043c\u043e\u0432<\/p>\n<\/td>\n<td>\n<p>\u043d\u043e\u043c\u0435\u0440 LUN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>&lt;-<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>SCSI: Data In LUN: 0x01 (Mode Sense(6) Response Data)<\/p>\n<\/td>\n<td>\n<p>\u0420\u0435\u0436\u0438\u043c\u044b LUN, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 read-only<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>-><\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>\u0427\u0442\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430<\/p>\n<\/td>\n<td>\n<p>\u043d\u043e\u043c\u0435\u0440 LUN, \u043d\u043e\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u043e\u0432, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043b\u043e\u043a\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"184\" width=\"184\">\n<p>SCSI<\/p>\n<\/td>\n<td data-colwidth=\"130\" width=\"130\">\n<p>&lt;-<\/p>\n<\/td>\n<td data-colwidth=\"185\" width=\"185\">\n<p>SCSI: Read(10) LUN: 0x03 (LBA: 0x00000000, Len: 8)<\/p>\n<\/td>\n<td>\n<p>\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u0438\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432, \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 LUN \u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0451\u043c\u043a\u043e\u0441\u0442\u0438, \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u043e\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0447\u0442\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u043e\u0432: \u0432\u044b\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432 (MBR \u0438\u043b\u0438 GPT), \u0437\u0430\u0442\u0435\u043c \u0441\u0430\u043c\u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u044b \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0438 \u0438\u0437 \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0451\u043c\u043a\u043e\u0441\u0442\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u0442\u0435\u043f\u0435\u0440\u044c \u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a ST:<\/p>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>\u0424\u0430\u0439\u043b<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>USB_DEVICE->App->usb_device.c<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 USB, \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>USB_DEVICE->App->usbd_desk.c<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 DEVICE DESCRIPTOR (VID\/PID), \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u0435. \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 USBD_FS_DeviceDescUSBD_FS_DeviceDesc<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>Middlewares->ST->STM32_USB_Device_Library->Class->MSC->Src->usbd_msc.c<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0442\u043e\u0447\u0435\u043a MassStorage \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 USBD_MSC_CfgFSDesc<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>Middlewares->ST->STM32_USB_Device_Library->Class->MSC->Src->usbd_msc_bot.c<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 BOT<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>Middlewares->ST->STM32_USB_Device_Library->Class->MSC->Src->usbd_msc_data.c<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b SCSI, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 MODE_SENSE6 \u0438 MSC_Mode_Sense10<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>Middlewares->ST->STM32_USB_Device_Library->Class->MSC->Src->usbd_msc_scsi.c<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 SCSI \u043a\u043e\u043c\u0430\u043d\u0434 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"294\" width=\"294\">\n<p>USB_DEVICE->App->usbd_storage_if.\u0441<\/p>\n<\/td>\n<td colspan=\"2\" data-colwidth=\"351,128\" width=\"351\">\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 LUN \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043d\u0438\u043c\u0438 \u0438 \u0441 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u043a\u0430\u043a \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0441 \u0447\u0435\u043c \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u0434\u0435\u043b\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a \u043f\u043e\u0447\u0438\u043d\u043a\u0435.<\/p>\n<h2>1. \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 2 LUN<\/h2>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 BOT, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 LUN \u0440\u0430\u0432\u043d\u043e 15 \u0438\u043b\u0438 0x0f, \u0432\u0438\u0434\u0438\u043c\u043e, \u0431\u043e\u043b\u044c\u0448\u0435 \u0431\u0438\u0442 \u0436\u0430\u043b\u043a\u043e \u0431\u044b\u043b\u043e, \u0434\u0430 \u0438 \u0437\u0430\u0434\u0430\u0447 \u0441\u0435\u0431\u0435 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441 15-\u044e \u0434\u0438\u0441\u043a\u0430\u043c\u0438, \u0445\u043e\u0442\u044f&#8230; \u0435\u0441\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043d\u044b\u043c \u0438 \u043d\u0430\u0432\u0435\u0441\u0438\u0442\u044c \u0435\u0449\u0451 1 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438. <\/p>\n<p>\u0414\u0440\u0430\u0439\u0432\u0435\u0440\u0430\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c \u0447\u0442\u043e Linux, \u0447\u0442\u043e Windows, \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 8 LUN \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u043e\u0441\u044c. \u0421\u0443\u0434\u044f \u043f\u043e \u0430\u043d\u0430\u0434\u0438\u0437\u0443 \u0442\u0440\u0430\u0444\u0438\u043a\u0430 USB \u0437\u0430\u043f\u0440\u043e\u0441 GET MAX LUN \u0431\u043e\u043b\u044c\u0448\u0435 7 \u0441\u044a\u0435\u0434\u0430\u0435\u0442, \u0432 \u043b\u043e\u0433\u0438 \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043d\u0435 \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f, \u043d\u043e 8-\u043e\u0435 \u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0440\u0448\u0435\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f&#8230;<\/p>\n<p>\u041d\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 ST \u043d\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b \u0438 \u0432\u0438\u0434\u0438\u043c\u043e \u043d\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0434\u043e\u043b\u0436\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430. \u0422\u0430\u043a\u043e\u0435 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u0438\u0434\u044f\u0442 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u044b, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0442, \u0443\u0431\u0435\u0434\u0438\u0432\u0448\u0438\u0441\u044c, \u0447\u0442\u043e \u0440\u0430\u0437 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 &#8212; \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043e\u0439\u0434\u0435\u0442. \u0422\u0430\u043a \u0438 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0441 1 LUN \u0438 \u0443\u0441\u043f\u043e\u043a\u043e\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u044d\u0442\u043e\u043c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441 2-\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043a\u0440\u0438\u0432\u043e \u043f\u0440\u0438 \u0440\u0430\u0432\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u0445, \u0430 \u0431\u043e\u043b\u044c\u0448\u0435\u043c &#8212; \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u043a\u0430\u043a. \u041d\u0443 \u0447\u0442\u043e \u0436\u0435 \u0434\u0435\u043b\u0430\u0442\u044c, \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430\u043c \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438\u043c\u0435\u044e\u0449\u0435\u0435\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>\u0422\u043a \u0443 \u043d\u0430\u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0442\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 SCSI \u043a\u043e\u043c\u0430\u043d\u0434 \u0434\u043b\u044f LUN, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 2 \u0438 \u0431\u043e\u043b\u0435\u0435, \u0438\u0449\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e<\/p>\n<pre><code class=\"cpp\">static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)<\/code><\/pre>\n<p> \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f SCSI \u043a\u043e\u043c\u0430\u043d\u0434 Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_bot.c \u0438 \u0432\u0438\u0434\u0438\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u043c\u0435\u0440\u0430 LUN \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439 1U! \u041f\u0440\u0430\u0432\u0438\u043c, \u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435, \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u043c\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e LUN hmsc->max_lun:<\/p>\n<pre><code class=\"cpp\">@@ -255,7 +255,7 @@ static void  MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)    if ((USBD_LL_GetRxDataSize(pdev, MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) ||        (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) || -      (hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength &lt; 1U) || +      (hmsc->cbw.bLUN > hmsc->max_lun) || (hmsc->cbw.bCBLength &lt; 1U) ||        (hmsc->cbw.bCBLength > 16U))    {   SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);<\/code><\/pre>\n<p>\u041d\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u0443 \u043d\u0430\u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e 0x0f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e LUN \u044d\u0442\u0438\u043c \u0447\u0438\u0441\u043b\u043e\u043c, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u0432 \u0444\u0430\u0439\u043b Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Inc\/usbd_msc.h:<\/p>\n<pre><code>@@ -55,6 +55,7 @@ extern \"C\" {  #define BOT_RESET                    0xFF  #define USB_MSC_CONFIG_DESC_SIZ      32   +#define MSC_BOT_MAX_LUN              0x10    #define MSC_EPIN_ADDR                0x81U  #define MSC_EPOUT_ADDR               0x01U @@ -82,25 +83,31 @@ typedef struct _USBD_STORAGE<\/code><\/pre>\n<p>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c hmsc->max_lun, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u043e\u0435 \u0438\u0437 CALLBACK<\/p>\n<pre><code class=\"cpp\">int8_t STORAGE_GetMaxLun_FS(void) {   \/* USER CODE BEGIN 8 *\/   return (STORAGE_LUNS - 1);   \/* USER CODE END 8 *\/ }<\/code><\/pre>\n<p>\u0444\u0430\u0439\u043b\u0430 USB_DEVICE->App->usbd_storage_if.c<\/p>\n<p>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 CALLBACK \u0432 \u0444\u0430\u0439\u043b\u0435 Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc.c<\/p>\n<pre><code class=\"cpp\">@@ -390,6 +390,7 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)                ((req->bmRequest &amp; 0x80U) == 0x80U))            {              hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); +            hmsc->max_lun = (hmsc->max_lun > MSC_BOT_MAX_LUN) ? MSC_BOT_MAX_LUN : hmsc->max_lun;              (void)USBD_CtlSendData(pdev, (uint8_t *)&amp;hmsc->max_lun, 1U);            }            else<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043d\u0430 \u0445\u043e\u0441\u0442 \u0441\u0442\u0430\u043b\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u0435 \u043e\u0442 \u0432\u0441\u0435\u0445 8 LUN, \u043d\u043e \u0440\u0430\u0434\u043e\u0432\u0442\u044c\u0441\u044f \u0435\u0449\u0451 \u0440\u0430\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 LUN \u0440\u0430\u0437\u043d\u044b\u0439 &#8212; \u0431\u043b\u043e\u043a \u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0435 \u0432\u044b\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f  \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u0440\u0451\u0441\u0442\u043d\u043e\u043c \u043e\u043f\u0440\u043e\u0441\u0435 LUN.<\/p>\n<h2>2. \u0427\u0438\u043d\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 LUN c \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430\u043c\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u0438 \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c<\/h2>\n<p>\u041e\u0448\u0438\u0431\u043a\u0430 \u043e \u0432\u044b\u043b\u0435\u0442\u0435 \u0438\u0437 \u0430\u0434\u0440\u0435\u0441\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u043d\u043e\u043c\u0435\u0440\u0430 \u0431\u043b\u043e\u043a\u0430 \u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u043e\u0432<\/p>\n<pre><code class=\"cpp\">static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,                                      uint32_t blk_offset, uint32_t blk_nbr) {   USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;    if (hmsc == NULL)   {     return -1;   }    if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr)   {     SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);     return -1;   }    return 0; }<\/code><\/pre>\n<p>\u0444\u0430\u0439\u043b\u0430 Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_scsi.c. \u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0441\u043c\u043e\u0442\u0440\u0435\u0432\u0448\u0438\u0441\u044c, \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043d\u043e\u043c\u0435\u0440 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e \u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u043c \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0431\u043b\u043e\u043a\u043e\u0432 hmsc->scsi_blk_nbr. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0443 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 SCSI, \u0445\u043e\u0441\u0442 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u043d \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u043b\u043e\u043a\u043e\u0432 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0433\u043e\/\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e LUN \u0438, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0442\u0430\u043c \u043c\u043e\u0433\u0443\u0442 \u043e\u0441\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u0440\u0443\u0433\u043e\u0433\u043e LUN, \u0447\u0442\u043e \u043c\u044b \u0438 \u0432\u0438\u0434\u0438\u043c. \u0412\u043e\u0442 \u043a\u0430\u043a \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u043e\u0432  LUN \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 SCSI_ReadCapacity16, \u0434\u043b\u044f SCSI_ReadCapacity10 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e:<\/p>\n<pre><code class=\"cpp\">static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) {   UNUSED(params);   uint8_t idx;   int8_t ret;   USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;    if (hmsc == NULL)   {     return -1;   }    ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &amp;hmsc->scsi_blk_nbr, &amp;hmsc->scsi_blk_size);    if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))   {     SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);     return -1;   }    hmsc->bot_data_length = ((uint32_t)params[10] &lt;&lt; 24) |                           ((uint32_t)params[11] &lt;&lt; 16) |                           ((uint32_t)params[12] &lt;&lt;  8) |                           (uint32_t)params[13];    for (idx = 0U; idx &lt; hmsc->bot_data_length; idx++)   {     hmsc->bot_data[idx] = 0U;   }    hmsc->bot_data[4] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24);   hmsc->bot_data[5] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16);   hmsc->bot_data[6] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >>  8);   hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_nbr - 1U);    hmsc->bot_data[8] = (uint8_t)(hmsc->scsi_blk_size >>  24);   hmsc->bot_data[9] = (uint8_t)(hmsc->scsi_blk_size >>  16);   hmsc->bot_data[10] = (uint8_t)(hmsc->scsi_blk_size >>  8);   hmsc->bot_data[11] = (uint8_t)(hmsc->scsi_blk_size);    hmsc->bot_data_length = ((uint32_t)params[10] &lt;&lt; 24) |                           ((uint32_t)params[11] &lt;&lt; 16) |                           ((uint32_t)params[12] &lt;&lt;  8) |                           (uint32_t)params[13];    return 0; }<\/code><\/pre>\n<p>\u0422\u0435 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443! \u041a\u0430\u043a \u043d\u0435 \u0442\u0440\u0443\u0434\u043d\u043e \u0434\u043e\u0433\u0430\u0434\u0430\u0442\u044c\u0441\u044f, \u0434\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e LUN \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u0438\u0441\u044c \u0438\u043d\u0434\u0438\u0432\u0438\u0434\u0443\u0430\u043b\u044c\u043d\u043e, \u0442\u0435 \u043c\u0430\u0441\u0441\u0438\u0432. PS: \u041e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u044b\u043b\u043e-\u0431\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c CALLBACK STORAGE_GetMaxLun_FS \u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0432\u0441\u0435\u0445 LUN, \u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u043d\u0435\u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0433\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e, \u044d\u0442\u043e \u043a\u0430\u043f\u043b\u044f \u0432 \u043c\u043e\u0440\u0435, \u0442\u043a \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043c \u043d\u0430\u0434\u043e \u043c\u043d\u043e\u0433\u043e\u0435&#8230;<\/p>\n<p>\u0414\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0438\u0441\u043f\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Inc\/usbd_msc.h \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u0442\u0443\u0440\u0443 USBD_LUN_BLK_HandleTypeDef \u0438 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e USBD_LUN_BLK_HandleTypeDef:<\/p>\n<pre><code class=\"cpp\">typedef struct {   uint32_t                 max_lun;   uint32_t                 interface;   uint8_t                  bot_state;   uint8_t                  bot_status;   uint32_t                 bot_data_length;   uint8_t                  bot_data[MSC_MEDIA_PACKET];   USBD_MSC_BOT_CBWTypeDef  cbw;   USBD_MSC_BOT_CSWTypeDef  csw;    USBD_SCSI_SenseTypeDef   scsi_sense [SENSE_LIST_DEEPTH];   uint8_t                  scsi_sense_head;   uint8_t                  scsi_sense_tail;   uint8_t                  scsi_medium_state;    uint16_t                 scsi_blk_size;   uint32_t                 scsi_blk_nbr;    uint32_t                 scsi_blk_addr;   uint32_t                 scsi_blk_len; } USBD_MSC_BOT_HandleTypeDef;<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">typedef struct { uint16_tsize; uint32_tnbr; uint32_taddr; uint32_tlen; } USBD_LUN_BLK_HandleTypeDef;  typedef struct {   uint32_t                    max_lun;   uint32_t                    interface;   uint8_t                     bot_state;   uint8_t                     bot_status;   uint32_t                    bot_data_length;   uint8_t                     bot_data[MSC_MEDIA_PACKET];   USBD_MSC_BOT_CBWTypeDef     cbw;   USBD_MSC_BOT_CSWTypeDef     csw;    USBD_SCSI_SenseTypeDef      scsi_sense [SENSE_LIST_DEEPTH];   uint8_t                     scsi_sense_head;   uint8_t                     scsi_sense_tail;   uint8_t                     scsi_medium_state;    USBD_LUN_BLK_HandleTypeDef  scsi_blk[MSC_BOT_MAX_LUN];  } USBD_MSC_BOT_HandleTypeDef;<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 SCSI \u0432 \u0444\u0430\u0439\u043b\u0435 Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_scsi.c:<\/p>\n<details class=\"spoiler\">\n<summary>diff \u0444\u0430\u0439\u043b\u0430: usbd_msc_scsi.c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">@@ -317,13 +317,14 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t    UNUSED(params);    int8_t ret;    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];      if (hmsc == NULL)    {      return -1;    }   -  ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &amp;hmsc->scsi_blk_nbr, &amp;hmsc->scsi_blk_size); +  ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &amp;hlun->nbr, &amp;hlun->size);      if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))    { @@ -331,15 +332,15 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t      return -1;    }   -  hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); -  hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); -  hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >>  8); -  hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); +  hmsc->bot_data[0] = (uint8_t)((hlun->nbr - 1U) >> 24); +  hmsc->bot_data[1] = (uint8_t)((hlun->nbr - 1U) >> 16); +  hmsc->bot_data[2] = (uint8_t)((hlun->nbr - 1U) >>  8); +  hmsc->bot_data[3] = (uint8_t)(hlun->nbr - 1U);   -  hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >>  24); -  hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >>  16); -  hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >>  8); -  hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size); +  hmsc->bot_data[4] = (uint8_t)(hlun->size >>  24); +  hmsc->bot_data[5] = (uint8_t)(hlun->size >>  16); +  hmsc->bot_data[6] = (uint8_t)(hlun->size >>  8); +  hmsc->bot_data[7] = (uint8_t)(hlun->size);      hmsc->bot_data_length = 8U;   @@ -361,13 +362,14 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t    uint8_t idx;    int8_t ret;    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];      if (hmsc == NULL)    {      return -1;    }   -  ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &amp;hmsc->scsi_blk_nbr, &amp;hmsc->scsi_blk_size); +  ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &amp;hlun->nbr, &amp;hlun->size);      if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED))    { @@ -385,15 +387,15 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t      hmsc->bot_data[idx] = 0U;    }   -  hmsc->bot_data[4] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 24); -  hmsc->bot_data[5] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >> 16); -  hmsc->bot_data[6] = (uint8_t)((hmsc->scsi_blk_nbr - 1U) >>  8); -  hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_nbr - 1U); +  hmsc->bot_data[4] = (uint8_t)((hlun->nbr - 1U) >> 24); +  hmsc->bot_data[5] = (uint8_t)((hlun->nbr - 1U) >> 16); +  hmsc->bot_data[6] = (uint8_t)((hlun->nbr - 1U) >>  8); +  hmsc->bot_data[7] = (uint8_t)(hlun->nbr - 1U);   -  hmsc->bot_data[8] = (uint8_t)(hmsc->scsi_blk_size >>  24); -  hmsc->bot_data[9] = (uint8_t)(hmsc->scsi_blk_size >>  16); -  hmsc->bot_data[10] = (uint8_t)(hmsc->scsi_blk_size >>  8); -  hmsc->bot_data[11] = (uint8_t)(hmsc->scsi_blk_size); +  hmsc->bot_data[8] = (uint8_t)(hlun->size >>  24); +  hmsc->bot_data[9] = (uint8_t)(hlun->size >>  16); +  hmsc->bot_data[10] = (uint8_t)(hlun->size >>  8); +  hmsc->bot_data[11] = (uint8_t)(hlun->size);      hmsc->bot_data_length = ((uint32_t)params[10] &lt;&lt; 24) |                            ((uint32_t)params[11] &lt;&lt; 16) | @@ -472,6 +474,12 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa    {      return -1;    } +   +  \/* Check If media is write-protected *\/ +  if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) == 1) +  { +    MSC_Mode_Sense6_data[2] |= 0x80; +  }      if (params[4] &lt;= len)    { @@ -502,6 +510,12 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p      return -1;    }   +  \/* Check If media is write-protected *\/ +  if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) == 1) +  { +    MSC_Mode_Sense10_data[2] |= 0x80; +  } +    if (params[8] &lt;= len)    {      len = params[8]; @@ -688,6 +702,7 @@ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun,  static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];      if (hmsc == NULL)    { @@ -716,21 +731,20 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params        return -1;      }   -    hmsc->scsi_blk_addr = ((uint32_t)params[2] &lt;&lt; 24) | -                          ((uint32_t)params[3] &lt;&lt; 16) | -                          ((uint32_t)params[4] &lt;&lt;  8) | -                          (uint32_t)params[5]; +    hlun->addr = ((uint32_t)params[2] &lt;&lt; 24) | +                 ((uint32_t)params[3] &lt;&lt; 16) | +                 ((uint32_t)params[4] &lt;&lt;  8) | +                  (uint32_t)params[5];   -    hmsc->scsi_blk_len = ((uint32_t)params[7] &lt;&lt;  8) | (uint32_t)params[8]; +    hlun->len = ((uint32_t)params[7] &lt;&lt;  8) | (uint32_t)params[8];   -    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, -                               hmsc->scsi_blk_len) &lt; 0) +    if (SCSI_CheckAddressRange(pdev, lun, hlun->addr, hlun->len) &lt; 0)      {        return -1; \/* error *\/      }        \/* cases 4,5 : Hi &lt;> Dn *\/ -    if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) +    if (hmsc->cbw.dDataLength != (hlun->len * hlun->size))      {        SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);        return -1; @@ -754,6 +768,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params  static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];      if (hmsc == NULL)    { @@ -781,24 +796,23 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params        return -1;      }   -    hmsc->scsi_blk_addr = ((uint32_t)params[2] &lt;&lt; 24) | -                          ((uint32_t)params[3] &lt;&lt; 16) | -                          ((uint32_t)params[4] &lt;&lt;  8) | -                          (uint32_t)params[5]; +    hlun->addr = ((uint32_t)params[2] &lt;&lt; 24) | +                 ((uint32_t)params[3] &lt;&lt; 16) | +                 ((uint32_t)params[4] &lt;&lt;  8) | +                  (uint32_t)params[5];   -    hmsc->scsi_blk_len = ((uint32_t)params[6] &lt;&lt; 24) | -                         ((uint32_t)params[7] &lt;&lt; 16) | -                         ((uint32_t)params[8] &lt;&lt; 8) | -                         (uint32_t)params[9]; +    hlun->len = ((uint32_t)params[6] &lt;&lt; 24) | +                ((uint32_t)params[7] &lt;&lt; 16) | +                ((uint32_t)params[8] &lt;&lt; 8) | +                 (uint32_t)params[9];   -    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, -                               hmsc->scsi_blk_len) &lt; 0) +    if (SCSI_CheckAddressRange(pdev, lun, hlun->addr, hlun->len) &lt; 0)      {        return -1; \/* error *\/      }        \/* cases 4,5 : Hi &lt;> Dn *\/ -    if (hmsc->cbw.dDataLength != (hmsc->scsi_blk_len * hmsc->scsi_blk_size)) +    if (hmsc->cbw.dDataLength != (hlun->len * hlun->size))      {        SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);        return -1; @@ -822,6 +836,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params  static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];    uint32_t len;      if (hmsc == NULL) @@ -858,22 +873,21 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param        return -1;      }   -    hmsc->scsi_blk_addr = ((uint32_t)params[2] &lt;&lt; 24) | -                          ((uint32_t)params[3] &lt;&lt; 16) | -                          ((uint32_t)params[4] &lt;&lt; 8) | -                          (uint32_t)params[5]; +    hlun->addr = ((uint32_t)params[2] &lt;&lt; 24) | +                 ((uint32_t)params[3] &lt;&lt; 16) | +                 ((uint32_t)params[4] &lt;&lt; 8) | +                  (uint32_t)params[5];   -    hmsc->scsi_blk_len = ((uint32_t)params[7] &lt;&lt; 8) | -                         (uint32_t)params[8]; +    hlun->len = ((uint32_t)params[7] &lt;&lt; 8) | +                 (uint32_t)params[8];        \/* check if LBA address is in the right range *\/ -    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, -                               hmsc->scsi_blk_len) &lt; 0) +    if (SCSI_CheckAddressRange(pdev, lun, hlun->addr, hlun->len) &lt; 0)      {        return -1; \/* error *\/      }   -    len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; +    len = hlun->len * hlun->size;        \/* cases 3,11,13 : Hn,Ho &lt;> D0 *\/      if (hmsc->cbw.dDataLength != len) @@ -907,6 +921,7 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param  static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];    uint32_t len;      if (hmsc == NULL) @@ -945,24 +960,23 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param        return -1;      }   -    hmsc->scsi_blk_addr = ((uint32_t)params[2] &lt;&lt; 24) | -                          ((uint32_t)params[3] &lt;&lt; 16) | -                          ((uint32_t)params[4] &lt;&lt; 8) | -                          (uint32_t)params[5]; +    hlun->addr = ((uint32_t)params[2] &lt;&lt; 24) | +                 ((uint32_t)params[3] &lt;&lt; 16) | +                 ((uint32_t)params[4] &lt;&lt; 8) | +                  (uint32_t)params[5];   -    hmsc->scsi_blk_len = ((uint32_t)params[6] &lt;&lt; 24) | -                         ((uint32_t)params[7] &lt;&lt; 16) | -                         ((uint32_t)params[8] &lt;&lt; 8) | -                         (uint32_t)params[9]; +    hlun->len = ((uint32_t)params[6] &lt;&lt; 24) | +                ((uint32_t)params[7] &lt;&lt; 16) | +                ((uint32_t)params[8] &lt;&lt; 8) | +                 (uint32_t)params[9];        \/* check if LBA address is in the right range *\/ -    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, -                               hmsc->scsi_blk_len) &lt; 0) +    if (SCSI_CheckAddressRange(pdev, lun, hlun->addr, hlun->len) &lt; 0)      {        return -1; \/* error *\/      }   -    len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; +    len = hlun->len * hlun->size;        \/* cases 3,11,13 : Hn,Ho &lt;> D0 *\/      if (hmsc->cbw.dDataLength != len) @@ -996,6 +1010,7 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param  static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];      if (hmsc == NULL)    { @@ -1008,7 +1023,7 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para      return -1; \/* Error, Verify Mode Not supported*\/    }   -  if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) &lt; 0) +  if (SCSI_CheckAddressRange(pdev, lun, hlun->addr, hlun->len) &lt; 0)    {      return -1; \/* error *\/    } @@ -1026,22 +1041,23 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para    * @param  blk_nbr: number of block to be processed    * @retval status    *\/ -static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, +__attribute__((optimize(0))) static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,                                       uint32_t blk_offset, uint32_t blk_nbr)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];     if (hmsc == NULL)    {      return -1;    }   -  if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr) +  if ((blk_offset + blk_nbr) > hlun->nbr)    {      SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);      return -1;    }      return 0;  }   @@ -1054,7 +1070,8 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,  static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; -  uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun]; +  uint32_t len = hlun->len * hlun->size;      if (hmsc == NULL)    { @@ -1064,8 +1081,8 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)    len = MIN(len, MSC_MEDIA_PACKET);      if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, hmsc->bot_data, -                                                     hmsc->scsi_blk_addr, -                                                     (len \/ hmsc->scsi_blk_size)) &lt; 0) +                                             hlun->addr, +                                                     (len \/ hlun->size)) &lt; 0)    {      SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, UNRECOVERED_READ_ERROR);      return -1; @@ -1073,13 +1090,13 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)      (void)USBD_LL_Transmit(pdev, MSC_EPIN_ADDR, hmsc->bot_data, len);   -  hmsc->scsi_blk_addr += (len \/ hmsc->scsi_blk_size); -  hmsc->scsi_blk_len -= (len \/ hmsc->scsi_blk_size); +  hlun->addr += (len \/ hlun->size); +  hlun->len -= (len \/ hlun->size);      \/* case 6 : Hi = Di *\/    hmsc->csw.dDataResidue -= len;   -  if (hmsc->scsi_blk_len == 0U) +  if (hlun->len == 0U)    {      hmsc->bot_state = USBD_BOT_LAST_DATA_IN;    } @@ -1096,7 +1113,8 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)  static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; -  uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; +  USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun]; +  uint32_t len = hlun->len * hlun->size;      if (hmsc == NULL)    { @@ -1106,26 +1124,26 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)    len = MIN(len, MSC_MEDIA_PACKET);      if (((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun, hmsc->bot_data, -                                                      hmsc->scsi_blk_addr, -                                                      (len \/ hmsc->scsi_blk_size)) &lt; 0) +                                              hlun->addr, +                                                      (len \/ hlun->size)) &lt; 0)    {      SCSI_SenseCode(pdev, lun, HARDWARE_ERROR, WRITE_FAULT);      return -1;    }   -  hmsc->scsi_blk_addr += (len \/ hmsc->scsi_blk_size); -  hmsc->scsi_blk_len -= (len \/ hmsc->scsi_blk_size); +  hlun->addr += (len \/ hlun->size); +  hlun->len -= (len \/ hlun->size);      \/* case 12 : Ho = Do *\/    hmsc->csw.dDataResidue -= len;   -  if (hmsc->scsi_blk_len == 0U) +  if (hlun->len == 0U)    {      MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);    }    else    { -    len = MIN((hmsc->scsi_blk_len * hmsc->scsi_blk_size), MSC_MEDIA_PACKET); +    len = MIN((hlun->len * hlun->size), MSC_MEDIA_PACKET);        \/* Prepare EP to Receive next packet *\/      (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, hmsc->bot_data, len);<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>3. \u0427\u0438\u043d\u0438\u043c SCSI Mode Sense \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0435\u0436\u0438\u043c Read Only (Write Protect)<\/h2>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u0435 \u0441 ST \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u043c\u0435\u043d\u044f \u043e\u0447\u0435\u043d\u044c \u043e\u0431\u0440\u0430\u0434\u043e\u0432\u0430\u043b\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432 USB_DEVICE->App->usbd_storage_if.\u0441 CALLBACK <\/p>\n<pre><code class=\"cpp\">int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);<\/code><\/pre>\n<p>\u041d\u043e \u043f\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044e \u043a\u043e\u0434\u0430 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043e\u043d \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u043f\u0440\u0438\u0433\u043e\u0434\u0435\u043d \u0434\u043b\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u043e\u043c USBD_FAIL, \u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 USBD_OK, \u0442\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 SCSI Write. \u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u043e \u0447\u0451\u043c \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u044f\u0434\u0440\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c (\u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438):<\/p>\n<pre><code class=\"bash\">sd 4:0:0:2: [sdd] Write Protect is off sd 4:0:0:2: [sdd] Mode Sense: 22 0 0 0<\/code><\/pre>\n<p>\u0417\u0430 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 Write Protect \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 SCSI \u0437\u0430\u043f\u0440\u043e\u0441 Mode Sense, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 4 \u0431\u0430\u0439\u0442\u0430 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043f\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 SCSI. \u041d\u043e \u043f\u0438\u0441\u0430\u0432\u0448\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432 ST \u044f\u0432\u043d\u043e \u0447\u0435\u043c-\u0442\u043e \u043c\u044f\u0433\u043a\u0438\u043c \u043d\u0430\u043f\u0440\u044b\u0433\u0430\u043b\u0438 \u043d\u0430 \u0430\u0436 23 \u0431\u0430\u0439\u0442\u0430, \u0438\u0431\u043e 0x22 \u044d\u0442\u043e \u0434\u043b\u0438\u043d\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u044d\u0442\u043e 34! \u041d\u0430 \u044d\u0442\u043e \u043f\u0430\u043a\u0435\u0442 WireShark \u043e\u0440\u0451\u0442 \u0431\u043b\u0430\u0433\u0438\u043c \u043c\u0430\u0442\u043e\u043c, \u0442\u043e\u043b\u044c\u043a\u043e \u0438 \u0432 \u043b\u043e\u0433 \u044f\u0434\u0440\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0447\u0430\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u0431\u0435\u0437\u043e\u0431\u0440\u0430\u0437\u0438\u044f. \u041d\u0443 \u0447\u0442\u043e \u0436\u0435, \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043c \u044d\u0442\u043e \u043d\u0435\u0434\u043e\u0440\u0430\u0437\u0443\u043c\u0435\u043d\u0438\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435  Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_data.c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439:<\/p>\n<pre><code class=\"cpp\">\/* USB Mass storage sense 6 Data *\/ uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = {   0x03,     \/* MODE DATA LENGTH. The number of bytes that follow. *\/   0x00,     \/* MEDIUM TYPE. 00h for SBC devices. *\/   0x00,     \/* DEVICE-SPECIFIC PARAMETER. For SBC devices:               *   bit 7: WP. Set to 1 if the media is write-protected.              *   bits 6..4: reserved              *   bit 4: DPOFUA. Set to 1 if the device supports the DPO and FUA bits (used in caching)              *   bits 3..0: reserved*\/   0x00      \/* Put Product Serial number *\/ };   \/* USB Mass storage sense 10  Data *\/ uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = {   0x07,     \/* MODE DATA LENGTH. The number of bytes that follow. *\/   0x00,     \/* MEDIUM TYPE. 00h for SBC devices. *\/   0x00,     \/* DEVICE-SPECIFIC PARAMETER. For SBC devices:               *   bit 7: WP. Set to 1 if the media is write-protected.              *   bits 6..4: reserved              *   bit 4: DPOFUA. Set to 1 if the device supports the DPO and FUA bits (used in caching)              *   bits 3..0: reserved*\/   0x00,     \/* Reserved *\/   0x00,     \/* Reserved *\/   0x00,     \/* Reserved *\/   0x00,     \/* Reserved *\/   0x00      \/* BLOCK DESCRIPTOR LENGTH. The length in bytes of all block descriptors in the              *   mode parameter list. *\/ };<\/code><\/pre>\n<p>\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u044f \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u043b\u0438\u043d\u0443 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0444\u0430\u0439\u043b\u0435 Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Inc\/usbd_msc_data.h<\/p>\n<pre><code class=\"cpp\">@@ -40,8 +40,8 @@ extern \"C\" {  \/** @defgroup USB_INFO_Exported_Defines    * @{    *\/ -#define MODE_SENSE6_LEN                    0x17U -#define MODE_SENSE10_LEN                   0x1BU +#define MODE_SENSE6_LEN                    0x04U +#define MODE_SENSE10_LEN                   0x08U  #define LENGTH_INQUIRY_PAGE00              0x06U  #define LENGTH_INQUIRY_PAGE80              0x08U<\/code><\/pre>\n<p>\u042d\u0442\u0438\u043c \u043c\u044b \u0443\u0441\u043f\u043e\u043a\u043e\u0438\u043b\u0438 WireShak, \u043d\u043e \u043c\u044b \u0436\u0435 \u0445\u043e\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c ReadOnly. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0434\u0438\u0441\u043a\u043e\u0432 &#8212; \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e \u0443\u043c\u043e\u0447\u0430\u043d\u0438\u044e \u043f\u0440\u044f\u043c\u043e \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u043d\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 LUN. \u0414\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 CALLBACK <code>STORAGE_IsWriteProtected_FS(uint8_t lun);<\/code> , \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0432 \u0435\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u041f\u0443\u0441\u0442\u044c \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0435 USBD_BUSY \u043e\u043d \u0434\u0435\u043b\u0430\u0435\u0442 \u0434\u0438\u0441\u043a WriteProtect \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_scsi.c \u043f\u0440\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 SCSI \u043a\u043e\u043c\u0430\u043d\u0434\u044b SCSI_ModeSense 6 \u0438 10:<\/p>\n<pre><code class=\"cpp\">@@ -472,6 +472,12 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa    {      return -1;    } +   +  \/* Check If media is write-protected *\/ +  if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) == 1) +  { +    MSC_Mode_Sense6_data[2] |= 0x80; +  }      if (params[4] &lt;= len)    { @@ -502,6 +508,12 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p      return -1;    }   +  \/* Check If media is write-protected *\/ +  if (((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) == 1) +  { +    MSC_Mode_Sense6_data[2] |= 0x80; +  } +    if (params[8] &lt;= len)    {      len = params[8];<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u0440\u0438 \u0432\u043e\u0437\u0440\u0430\u0442\u0435 CALLBACK<\/p>\n<pre><code class=\"cpp\">int8_t STORAGE_IsWriteProtected_FS(uint8_t lun) {   \/* USER CODE BEGIN 5 *\/   switch(lun){     case LUN_NUM_MICROSD:   return (USBD_OK);   case LUN_NUM_EEPROM: return (USBD_BUSY); break;   case LUN_NUM_SYSTEM:     return (USBD_BUSY);     break;     case LUN_NUM_TEST:     return (USBD_BUSY);     break;     default: return (USBD_FAIL);   }     \/* USER CODE END 5 *\/ }<\/code><\/pre>\n<p>\u041f\u043e\u043b\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043b\u044f:<\/p>\n<p>LUN_NUM_MICROSD &#8212; \u0417\u0430\u043f\u0438\u0441\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0430<\/p>\n<p>LUN_NUM_EEPROM, LUN_NUM_SYSTEM, LUN_NUM_TEST &#8212; \u0417\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0438\u0441\u043a\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439<\/p>\n<p>\u0414\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 &#8212; \u0417\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 SCSI Write<\/p>\n<p>\u0412 \u043b\u043e\u0433\u0435 linux \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"bash\">sd 4:0:0:0: [sdb] Write Protect is off sd 4:0:0:0: [sdb] Mode Sense: 03 00 00 00  sd 4:0:0:1: [sdc] Write Protect is on sd 4:0:0:1: [sdc] Mode Sense: 03 00 80 00  sd 4:0:0:2: [sdd] Write Protect is on sd 4:0:0:2: [sdd] Mode Sense: 03 00 80 00  sd 4:0:0:3: [sde] Write Protect is on sd 4:0:0:3: [sde] Mode Sense: 03 00 80 00  sd 4:0:0:4: [sdf] Write Protect is off sd 4:0:0:4: [sdf] Mode Sense: 03 00 00 00  sd 4:0:0:5: [sdg] Write Protect is off sd 4:0:0:5: [sdg] Mode Sense: 03 00 00 00  sd 4:0:0:7: [sdi] Write Protect is off sd 4:0:0:7: [sdi] Mode Sense: 03 00 00 00  sd 4:0:0:6: [sdh] Write Protect is off sd 4:0:0:6: [sdh] Mode Sense: 03 00 00 00<\/code><\/pre>\n<h2>4. \u0427\u0438\u043d\u0438\u043c \u0441\u0431\u0440\u043e\u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0445 SCSI \u043a\u043e\u043c\u0430\u043d\u0434<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0441\u0435\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435. \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0432\u0440\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043d\u043e \u0432 \u043b\u043e\u0433\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u044f\u0434\u0440\u0430 linux \u043f\u0440\u043e\u0441\u043a\u0430\u043a\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u0447\u043a\u0430 \u043e \u0441\u0431\u0440\u043e\u0441\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430:<\/p>\n<pre><code class=\"bash\">usb 1-1: reset full-speed USB device number 10 using xhci_hcd<\/code><\/pre>\n<p>\u0410 \u0432 WireShark \u0432\u0438\u0434\u0435\u043d \u0441\u0431\u0440\u043e\u0441 \u0441 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u043e\u0432. \u042d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u044b. \u0414\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0443\u0441\u0442\u044b\u0435, \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b: SCSI_REPORT_LUNS12, SCSI_LOG_SENSE10, SCSI_RECEIVE_DIAGNOSTIC8, SCSI_ATA_PASSTHROUGH12<\/p>\n<p>\u0414\u043b\u044f SCSI_REPORT_LUNS12 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u043c\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 \u0444\u0430\u0439\u043b Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Inc\/usbd_msc_scsi.h:<\/p>\n<pre><code class=\"cpp\">@ -74,6 +74,8 @@ extern \"C\" {  #define SCSI_SEND_DIAGNOSTIC                        0x1DU  #define SCSI_READ_FORMAT_CAPACITIES                 0x23U   +#define SCSI_REPORT_LUNS12                          0xA0U +<\/code><\/pre>\n<p>\u0418 \u0435\u0451 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u0444\u0430\u0439\u043b Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_scsi.c:<\/p>\n<details class=\"spoiler\">\n<summary>diff \u0444\u0430\u0439\u043b\u0430: usbd_msc_scsi.c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">@@ -100,6 +100,9 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun);    static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,                                   uint8_t *pBuff, uint16_t length); + +static int8_t SCSI_ReportLuns12(USBD_HandleTypeDef *pdev, uint8_t lun, +                                 uint8_t *params);  \/**    * @}    *\/ @@ -190,6 +193,10 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)        ret = SCSI_Verify10(pdev, lun, cmd);        break;   +    case SCSI_REPORT_LUNS12: +      ret = SCSI_ReportLuns12(pdev, lun, cmd); +      break; +      default:        SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);        hmsc->bot_status = USBD_BOT_STATUS_ERROR; @@ -1041,12 +1048,12 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para    * @param  blk_nbr: number of block to be processed    * @retval status    *\/  static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,                                       uint32_t blk_offset, uint32_t blk_nbr)  {    USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData;    USBD_LUN_BLK_HandleTypeDef *hlun = &amp;hmsc->scsi_blk[lun];  +    if (hmsc == NULL)    {      return -1; @@ -1057,7 +1064,7 @@ __attribute__((optimize(0))) static int8_t SCSI_CheckAddressRange(USBD_HandleTyp      SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);      return -1;    } +    return 0;  }   @@ -1181,6 +1188,41 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,      return 0;  } + + +\/** +  * @brief  SCSI_Write12 +  *         Process Write12 command +  * @param  lun: Logical unit number +  * @param  params: Command parameters +  * @retval status +  *\/ +static int8_t SCSI_ReportLuns12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ +  USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + +  uint16_t lun_i; + +  static uint64_t report_luns[MSC_BOT_MAX_LUN + 1]; + +  if (hmsc == NULL) +  { +    return -1; +  } + + +  report_luns[0] = 0; +  ((uint8_t *)report_luns)[3] = sizeof(uint64_t)*(hmsc->max_lun + 1); + +  for (lun_i = 0; lun_i &lt;= hmsc->max_lun; lun_i++){ +  report_luns[lun_i + 1] = lun_i &lt;&lt; 8; +  } + +  (void)SCSI_UpdateBotData(hmsc, (uint8_t *)report_luns, sizeof(uint64_t)*(hmsc->max_lun + 2) ); + +  return 0; +} +  \/**@@ -75,6 +75,7 @@ extern \"C\" {  #define SCSI_READ_FORMAT_CAPACITIES                 0x23U    #define SCSI_REPORT_LUNS12                          0xA0U +#define SCSI_LOG_SENSE10                            0x4DU<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f SCSI_LOG_SENSE10 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u043c\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 \u0444\u0430\u0439\u043b Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Inc\/usbd_msc_scsi.h:<\/p>\n<pre><code class=\"cpp\">@@ -75,6 +75,7 @@ extern \"C\" {  #define SCSI_READ_FORMAT_CAPACITIES                 0x23U    #define SCSI_REPORT_LUNS12                          0xA0U +#define SCSI_LOG_SENSE10                            0x4DU<\/code><\/pre>\n<p>\u0418 \u0435\u0451 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u0444\u0430\u0439\u043b Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_scsi.c:<\/p>\n<details class=\"spoiler\">\n<summary>diff \u0444\u0430\u0439\u043b\u0430: usbd_msc_scsi.c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">@@ -103,6 +103,8 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc,    static int8_t SCSI_ReportLuns12(USBD_HandleTypeDef *pdev, uint8_t lun,                                   uint8_t *params); +static int8_t SCSI_Log_Sense10(USBD_HandleTypeDef *pdev, uint8_t lun, +uint8_t *params);  \/**    * @}    *\/ @@ -197,6 +199,10 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)        ret = SCSI_ReportLuns12(pdev, lun, cmd);        break;   +    case SCSI_LOG_SENSE10: +      ret = SCSI_Log_Sense10(pdev, lun, cmd); SCSI_RECEIVE_DIAGNOSTIC8+      break; +      default:        SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);        hmsc->bot_status = USBD_BOT_STATUS_ERROR;                                              @@ -1238,7 +1251,7 @@ static int8_t SCSI_ReportLuns12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *    * @param  params: Command parameters    * @retval status    *\/       \/**   * @brief  SCSI_Write12   *         Process Write12 command   * @param  lun: Logical unit number   * @param  params: Command parameters   * @retval status   *\/ +static int8_t SCSI_Log_Sense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ +  USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + +  static uint8_t log_sense[] = {0x00, 0x00, 0x00, 0x00};  +  if (hmsc == NULL) +  { +    return -1; +  }  +  (void)SCSI_UpdateBotData(hmsc, log_sense, sizeof(log_sense) );  +  return 0; +}                                                     <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f SCSI_RECEIVE_DIAGNOSTIC8, SCSI_ATA_PASSTHROUGH12 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u043c\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0432 \u0444\u0430\u0439\u043b Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Inc\/usbd_msc_scsi.h:<\/p>\n<pre><code class=\"cpp\">@@ -76,6 +76,8 @@ extern \"C\" {    #define SCSI_REPORT_LUNS12                          0xA0U  #define SCSI_LOG_SENSE10                            0x4DU +#define SCSI_RECEIVE_DIAGNOSTIC8                    0x1CU +#define SCSI_ATA_PASSTHROUGH12                      0xA1U<\/code><\/pre>\n<p>\u0418 \u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u0444\u0430\u0439\u043b Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC\/Src\/usbd_msc_scsi.c:<\/p>\n<details class=\"spoiler\">\n<summary>diff \u0444\u0430\u0439\u043b\u0430: usbd_msc_scsi.c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">@@ -105,6 +105,11 @@ static int8_t SCSI_ReportLuns12(USBD_HandleTypeDef *pdev, uint8_t lun,                                   uint8_t *params);  static int8_t SCSI_Log_Sense10(USBD_HandleTypeDef *pdev, uint8_t lun,  uint8_t *params); +static int8_t SCSI_Recive_Diagnostic8(USBD_HandleTypeDef *pdev, uint8_t lun, +uint8_t *params); +static int8_t SCSI_Ata_PassThrough12(USBD_HandleTypeDef *pdev, uint8_t lun, +uint8_t *params); +  \/**    * @}    *\/ @@ -203,6 +208,14 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)        ret = SCSI_Log_Sense10(pdev, lun, cmd);        break;   +    case SCSI_RECEIVE_DIAGNOSTIC8: +      ret = SCSI_Recive_Diagnostic8(pdev, lun, cmd); +      break; + +    case SCSI_ATA_PASSTHROUGH12: +      ret = SCSI_Ata_PassThrough12(pdev, lun, cmd); +      break; +      default:        SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);        hmsc->bot_status = USBD_BOT_STATUS_ERROR;  @@ -1254,6 +1267,37 @@ __attribute__((optimize(0))) static int8_t SCSI_Log_Sense10(USBD_HandleTypeDef *    return 0;  }   + + +\/** +  * @brief  SCSI_Write12 +  *         Process Write12 command +  * @param  lun: Logical unit number +  * @param  params: Command parameters +  * @retval status +  *\/ +static int8_t SCSI_Recive_Diagnostic8(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + +  return SCSI_Log_Sense10(pdev, lun, params); +} + + + +\/** +  * @brief  SCSI_Write12 +  *         Process Write12 command +  * @param  lun: Logical unit number +  * @param  params: Command parameters +  * @retval status +  *\/ +static int8_t SCSI_Ata_PassThrough12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + +  return SCSI_Log_Sense10(pdev, lun, params); +} + +  \/**<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0438\u043c \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u043b\u043e\u0433 \u0438 \u0440\u0430\u0434\u0443\u0435\u043c\u0441\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u043c\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443:<\/p>\n<details class=\"spoiler\">\n<summary>Log \u044f\u0434\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">kernel: [15712.126112] usb 1-1: new full-speed USB device number 73 using xhci_hcd      kernel: [15712.277413] usb 1-1: New USB device found, idVendor=0483, idProduct=572a, bcdDevice= 2.00      kernel: [15712.277419] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3       kernel: [15712.277420] usb 1-1: Product: Test MASS Storage          kernel: [15712.277421] usb 1-1: Manufacturer: Developer            kernel: [15712.277422] usb 1-1: SerialNumber: 2062369C5950            kernel: [15712.279576] usb-storage 1-1:1.0: USB Mass Storage device detected         kernel: [15712.279965] scsi host4: usb-storage 1-1:1.0            mtp-probe: checking bus 1 device 73:00:00 \/sys\/devices\/pci0000:00\/0000:00:14.0\/usb1\/1-1           mtp-probe: bus: 1 device: 73 was not an MTP device        mtp-probe: checking bus 1 device 73:00:00 \/sys\/devices\/pci0000:00\/0000:00:14.0\/usb1\/1-1           mtp-probe: bus: 1 device: 73 was not an MTP device        kernel: [15713.287207] scsi 4:0:0:0: Direct-Access STM MicroSD Device 0.01 PQ: 0 ANSI: 2     kernel: [15713.287882] scsi 4:0:0:1: Direct-Access STM EEPROM 0.01 PQ: 0 ANSI: 2      kernel: [15713.288253] scsi 4:0:0:2: Direct-Access STM System 0.01 PQ: 0 ANSI: 2      kernel: [15713.288611] scsi 4:0:0:3: Direct-Access STM Test 0.01 PQ: 0 ANSI: 2      kernel: [15713.288991] scsi 4:0:0:4: Direct-Access STM MicroSD2Device 0.01 PQ: 0 ANSI: 2      kernel: [15713.289293] scsi 4:0:0:5: Direct-Access STM EEPROM2 0.01 PQ: 0 ANSI: 2      kernel: [15713.289593] scsi 4:0:0:6: Direct-Access STM System2 0.01 PQ: 0 ANSI: 2      kernel: [15713.290194] scsi 4:0:0:7: Direct-Access STM Test2 0.01 PQ: 0 ANSI: 2      kernel: [15713.290496] sd 4:0:0:0: Attached scsi generic sg1 type 0        kernel: [15713.290708] sd 4:0:0:1: Attached scsi generic sg2 type 0        kernel: [15713.290748] sd 4:0:0:0: [sdb] 1030144 512-byte logical blocks: (527 MB\/503 MiB)      kernel: [15713.290937] sd 4:0:0:0: [sdb] Write Protect is on         kernel: [15713.290939] sd 4:0:0:2: Attached scsi generic sg3 type 0        kernel: [15713.290939] sd 4:0:0:0: [sdb] Mode Sense: 3 0 80 0       kernel: [15713.291048] sd 4:0:0:3: Attached scsi generic sg4 type 0        kernel: [15713.291117] scsi 4:0:0:4: Attached scsi generic sg5 type 0        kernel: [15713.291147] sd 4:0:0:0: [sdb] No Caching mode page found        kernel: [15713.291149] sd 4:0:0:0: [sdb] Assuming drive cache: write through        kernel: [15713.291194] sd 4:0:0:5: Attached scsi generic sg6kernel: [15712.126112] usb 1-1: new full-speed USB device number 73 using xhci_hcd      kernel: [15712.277413] usb 1-1: New USB device found, idVendor=0483, idProduct=572a, bcdDevice= 2.00      kernel: [15712.277419] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3       kernel: [15712.277420] usb 1-1: Product: Test MASS Storage          kernel: [15712.277421] usb 1-1: Manufacturer: Developer            kernel: [15712.277422] usb 1-1: SerialNumber: 2062369C5950            kernel: [15712.279576] usb-storage 1-1:1.0: USB Mass Storage device detected         kernel: [15712.279965] scsi host4: usb-storage 1-1:1.0            mtp-probe: checking bus 1 device 73:00:00 \/sys\/devices\/pci0000:00\/0000:00:14.0\/usb1\/1-1           mtp-probe: bus: 1 device: 73 was not an MTP device        mtp-probe: checking bus 1 device 73:00:00 \/sys\/devices\/pci0000:00\/0000:00:14.0\/usb1\/1-1           mtp-probe: bus: 1 device: 73 was not an MTP device        kernel: [15713.287207] scsi 4:0:0:0: Direct-Access STM MicroSD Device 0.01 PQ: 0 ANSI: 2     kernel: [15713.287882] scsi 4:0:0:1: Direct-Access STM EEPROM 0.01 PQ: 0 ANSI: 2      kernel: [15713.288253] scsi 4:0:0:2: Direct-Access STM System 0.01 PQ: 0 ANSI: 2      kernel: [15713.288611] scsi 4:0:0:3: Direct-Access STM Test 0.01 PQ: 0 ANSI: 2      kernel: [15713.288991] scsi 4:0:0:4: Direct-Access STM MicroSD2Device 0.01 PQ: 0 ANSI: 2      kernel: [15713.289293] scsi 4:0:0:5: Direct-Access STM EEPROM2 0.01 PQ: 0 ANSI: 2      kernel: [15713.289593] scsi 4:0:0:6: Direct-Access STM System2 0.01 PQ: 0 ANSI: 2      kernel: [15713.290194] scsi 4:0:0:7: Direct-Access STM Test2 0.01 PQ: 0 ANSI: 2      kernel: [15713.290496] sd 4:0:0:0: Attached scsi generic sg1 type 0        kernel: [15713.290708] sd 4:0:0:1: Attached scsi generic sg2 type 0        kernel: [15713.290748] sd 4:0:0:0: [sdb] 1030144 512-byte logical blocks: (527 MB\/503 MiB)      kernel: [15713.290937] sd 4:0:0:0: [sdb] Write Protect is on         kernel: [15713.290939] sd 4:0:0:2: Attached scsi generic sg3 type 0        kernel: [15713.290939] sd 4:0:0:0: [sdb] Mode Sense: 3 0 80 0       kernel: [15713.291048] sd 4:0:0:3: Attached scsi generic sg4 type 0        kernel: [15713.291117] scsi 4:0:0:4: Attached scsi generic sg5 type 0        kernel: [15713.291147] sd 4:0:0:0: [sdb] No Caching mode page found        kernel: [15713.291149] sd 4:0:0:0: [sdb] Assuming drive cache: write through        kernel: [15713.291194] sd 4:0:0:5: Attached scsi generic sg6 type 0        kernel: [15713.291274] sd 4:0:0:6: Attached scsi generic sg7 type 0        kernel: [15713.291334] scsi 4:0:0:7: Attached scsi generic sg8 type 0        kernel: [15713.291486] sd 4:0:0:1: [sdc] 64 512-byte logical blocks: (32.8 kB\/32.0 KiB)      kernel: [15713.291777] sd 4:0:0:2: [sdd] 256 512-byte logical blocks: (131 kB\/128 KiB)      kernel: [15713.291913] sd 4:0:0:1: [sdc] Write Protect is on         kernel: [15713.291915] sd 4:0:0:1: [sdc] Mode Sense: 3 0 80 0       kernel: [15713.292154] sd 4:0:0:3: [sde] 1024 512-byte logical blocks: (524 kB\/512 KiB)      kernel: [15713.292299] sd 4:0:0:2: [sdd] Write Protect is on         kernel: [15713.292302] sd 4:0:0:2: [sdd] Mode Sense: 3 0 80 0       kernel: [15713.292444] sd 4:0:0:1: [sdc] No Caching mode page found        kernel: [15713.292446] sd 4:0:0:1: [sdc] Assuming drive cache: write through        kernel: [15713.292792] sd 4:0:0:4: [sdf] 2048 512-byte logical blocks: (1.05 MB\/1.00 MiB)      kernel: [15713.292934] sd 4:0:0:3: [sde] Write Protect is on         kernel: [15713.292936] sd 4:0:0:3: [sde] Mode Sense: 3 0 80 0       kernel: [15713.293081] sd 4:0:0:2: [sdd] No Caching mode page found        kernel: [15713.293084] sd 4:0:0:2: [sdd] Assuming drive cache: write through        kernel: [15713.293338] sd 4:0:0:5: [sdg] 4096 512-byte logical blocks: (2.10 MB\/2.00 MiB)      kernel: [15713.293483] sd 4:0:0:4: [sdf] Write Protect is on         kernel: [15713.293486] sd 4:0:0:4: [sdf] Mode Sense: 3 0 80 0       kernel: [15713.293642] sd 4:0:0:4: [sdf] No Caching mode page found        kernel: [15713.293644] sd 4:0:0:4: [sdf] Assuming drive cache: write through        kernel: [15713.293794] sd 4:0:0:3: [sde] No Caching mode page found        kernel: [15713.293796] sd 4:0:0:3: [sde] Assuming drive cache: write through        kernel: [15713.294146] sd 4:0:0:6: [sdh] 8192 512-byte logical blocks: (4.19 MB\/4.00 MiB)      kernel: [15713.294482] sd 4:0:0:5: [sdg] Write Protect is on         kernel: [15713.294485] sd 4:0:0:5: [sdg] Mode Sense: 3 0 80 0       kernel: [15713.297058] sd 4:0:0:7: [sdi] 16384 512-byte logical blocks: (8.39 MB\/8.00 MiB)      kernel: [15713.297215] sd 4:0:0:7: [sdi] Write Protect is on         kernel: [15713.297218] sd 4:0:0:7: [sdi] Mode Sense: 3 0 80 0       kernel: [15713.297374] sd 4:0:0:7: [sdi] No Caching mode page found        kernel: [15713.297376] sd 4:0:0:7: [sdi] Assuming drive cache: write through        kernel: [15713.297550] sd 4:0:0:5: [sdg] No Caching mode page found        kernel: [15713.297553] sd 4:0:0:5: [sdg] Assuming drive cache: write through        kernel: [15713.297788] sd 4:0:0:6: [sdh] Write Protect is on         kernel: [15713.297790] sd 4:0:0:6: [sdh] Mode Sense: 3 0 80 0       kernel: [15713.297972] sd 4:0:0:6: [sdh] No Caching mode page found        kernel: [15713.297974] sd 4:0:0:6: [sdh] Assuming drive cache: write through        kernel: [15713.318373] sdb: sdb1 sdb2 sdb3            kernel: [15713.400473] sd 4:0:0:0: [sdb] Attached SCSI disk          kernel: [15713.461585] sd 4:0:0:2: [sdd] Attached SCSI disk          kernel: [15713.462133] sd 4:0:0:6: [sdh] Attached SCSI disk          kernel: [15713.463092] sd 4:0:0:7: [sdi] Attached SCSI disk          kernel: [15713.486541] sd 4:0:0:3: [sde] Attached SCSI disk          kernel: [15713.494895] sd 4:0:0:4: [sdf] Attached SCSI disk          kernel: [15713.501634] sd 4:0:0:1: [sdc] Attached SCSI disk          kernel: [15713.537123] sd 4:0:0:5: [sdg] Attached SCSI disk          systemd[1]: Finished Clean the \/media\/user\/REC_ROM mount point.           udisksd[1611]: Mounted \/dev\/sdb2 at \/media\/user\/REC_ROM on behalf of uid 1001        systemd[1788]: Starting Tracker metadata database store and lookup manager...  dbus-daemon[1810]: [session uid=1001 pid=1810] Successfully activated service 'org.freedesktop.Tracker1'  systemd[1788]: Started Tracker metadata database store and lookup manager.  systemd[1]: Finished Clean the \/media\/user\/LAST_ROMS mount point.  udisksd[1611]: Mounted \/dev\/sdb3 at \/media\/user\/LAST_ROMS on behalf of uid 1001  type 0        kernel: [15713.291274] sd 4:0:0:6: Attached scsi generic sg7 type 0        kernel: [15713.291334] scsi 4:0:0:7: Attached scsi generic sg8 type 0        kernel: [15713.291486] sd 4:0:0:1: [sdc] 64 512-byte logical blocks: (32.8 kB\/32.0 KiB)      kernel: [15713.291777] sd 4:0:0:2: [sdd] 256 512-byte logical blocks: (131 kB\/128 KiB)      kernel: [15713.291913] sd 4:0:0:1: [sdc] Write Protect is on         kernel: [15713.291915] sd 4:0:0:1: [sdc] Mode Sense: 3 0 80 0       kernel: [15713.292154] sd 4:0:0:3: [sde] 1024 512-byte logical blocks: (524 kB\/512 KiB)      kernel: [15713.292299] sd 4:0:0:2: [sdd] Write Protect is on         kernel: [15713.292302] sd 4:0:0:2: [sdd] Mode Sense: 3 0 80 0       kernel: [15713.292444] sd 4:0:0:1: [sdc] No Caching mode page found        kernel: [15713.292446] sd 4:0:0:1: [sdc] Assuming drive cache: write through        kernel: [15713.292792] sd 4:0:0:4: [sdf] 2048 512-byte logical blocks: (1.05 MB\/1.00 MiB)      kernel: [15713.292934] sd 4:0:0:3: [sde] Write Protect is on         kernel: [15713.292936] sd 4:0:0:3: [sde] Mode Sense: 3 0 80 0       kernel: [15713.293081] sd 4:0:0:2: [sdd] No Caching mode page found        kernel: [15713.293084] sd 4:0:0:2: [sdd] Assuming drive cache: write through        kernel: [15713.293338] sd 4:0:0:5: [sdg] 4096 512-byte logical blocks: (2.10 MB\/2.00 MiB)      kernel: [15713.293483] sd 4:0:0:4: [sdf] Write Protect is on         kernel: [15713.293486] sd 4:0:0:4: [sdf] Mode Sense: 3 0 80 0       kernel: [15713.293642] sd 4:0:0:4: [sdf] No Caching mode page found        kernel: [15713.293644] sd 4:0:0:4: [sdf] Assuming drive cache: write through        kernel: [15713.293794] sd 4:0:0:3: [sde] No Caching mode page found        kernel: [15713.293796] sd 4:0:0:3: [sde] Assuming drive cache: write through        kernel: [15713.294146] sd 4:0:0:6: [sdh] 8192 512-byte logical blocks: (4.19 MB\/4.00 MiB)      kernel: [15713.294482] sd 4:0:0:5: [sdg] Write Protect is on         kernel: [15713.294485] sd 4:0:0:5: [sdg] Mode Sense: 3 0 80 0       kernel: [15713.297058] sd 4:0:0:7: [sdi] 16384 512-byte logical blocks: (8.39 MB\/8.00 MiB)      kernel: [15713.297215] sd 4:0:0:7: [sdi] Write Protect is on         kernel: [15713.297218] sd 4:0:0:7: [sdi] Mode Sense: 3 0 80 0       kernel: [15713.297374] sd 4:0:0:7: [sdi] No Caching mode page found        kernel: [15713.297376] sd 4:0:0:7: [sdi] Assuming drive cache: write through        kernel: [15713.297550] sd 4:0:0:5: [sdg] No Caching mode page found        kernel: [15713.297553] sd 4:0:0:5: [sdg] Assuming drive cache: write through        kernel: [15713.297788] sd 4:0:0:6: [sdh] Write Protect is on         kernel: [15713.297790] sd 4:0:0:6: [sdh] Mode Sense: 3 0 80 0       kernel: [15713.297972] sd 4:0:0:6: [sdh] No Caching mode page found        kernel: [15713.297974] sd 4:0:0:6: [sdh] Assuming drive cache: write through        kernel: [15713.318373] sdb: sdb1 sdb2 sdb3            kernel: [15713.400473] sd 4:0:0:0: [sdb] Attached SCSI disk          kernel: [15713.461585] sd 4:0:0:2: [sdd] Attached SCSI disk          kernel: [15713.462133] sd 4:0:0:6: [sdh] Attached SCSI disk          kernel: [15713.463092] sd 4:0:0:7: [sdi] Attached SCSI disk          kernel: [15713.486541] sd 4:0:0:3: [sde] Attached SCSI disk          kernel: [15713.494895] sd 4:0:0:4: [sdf] Attached SCSI disk          kernel: [15713.501634] sd 4:0:0:1: [sdc] Attached SCSI disk          kernel: [15713.537123] sd 4:0:0:5: [sdg] Attached SCSI disk          systemd[1]: Finished Clean the \/media\/user\/REC_ROM mount point.           udisksd[1611]: Mounted \/dev\/sdb2 at \/media\/user\/REC_ROM on behalf of uid 1001        systemd[1788]: Starting Tracker metadata database store and lookup manager...  dbus-daemon[1810]: [session uid=1001 pid=1810] Successfully activated service 'org.freedesktop.Tracker1'  systemd[1788]: Started Tracker metadata database store and lookup manager.  systemd[1]: Finished Clean the \/media\/user\/LAST_ROMS mount point.  udisksd[1611]: Mounted \/dev\/sdb3 at \/media\/user\/LAST_ROMS on behalf of uid 1001 <\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e LUN<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0412\u044b\u0432\u0435\u0434\u0435\u043c \u0432\u0441\u0435 SCSI \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430:<\/p>\n<pre><code class=\"bash\"># sg_map -x \/dev\/sg0  0 0 0 0  0  \/dev\/sda \/dev\/sg1  4 0 0 0  0  \/dev\/sdb \/dev\/sg2  4 0 0 1  0  \/dev\/sdc \/dev\/sg3  4 0 0 2  0  \/dev\/sdd \/dev\/sg4  4 0 0 3  0  \/dev\/sde \/dev\/sg5  4 0 0 4  0  \/dev\/sdf \/dev\/sg6  4 0 0 5  0  \/dev\/sdg \/dev\/sg7  4 0 0 6  0  \/dev\/sdh \/dev\/sg8  4 0 0 7  0  \/dev\/sdi<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u043c \u0451\u043c\u043a\u043e\u0441\u0442\u044c:<\/p>\n<pre><code class=\"bash\"># sg_readcap \/dev\/sg1 Read Capacity results:    Last LBA=1030143 (0xfb7ff), Number of logical blocks=1030144    Logical block length=512 bytes Hence:    Device size: 527433728 bytes, 503.0 MiB, 0.53 GB  # sg_readcap \/dev\/sg2 Read Capacity results:    Last LBA=63 (0x3f), Number of logical blocks=64    Logical block length=512 bytes Hence:    Device size: 32768 bytes, 0.0 MiB, 0.00 GB  # sg_readcap \/dev\/sg3 Read Capacity results:    Last LBA=255 (0xff), Number of logical blocks=256    Logical block length=512 bytes Hence:    Device size: 131072 bytes, 0.1 MiB, 0.00 GB  # sg_readcap \/dev\/sg4 Read Capacity results:    Last LBA=1023 (0x3ff), Number of logical blocks=1024    Logical block length=512 bytes Hence:    Device size: 524288 bytes, 0.5 MiB, 0.00 GB  # sg_readcap \/dev\/sg5 Read Capacity results:    Last LBA=2047 (0x7ff), Number of logical blocks=2048    Logical block length=512 bytes Hence:    Device size: 1048576 bytes, 1.0 MiB, 0.00 GB  # sg_readcap \/dev\/sg6 Read Capacity results:    Last LBA=4095 (0xfff), Number of logical blocks=4096    Logical block length=512 bytes Hence:    Device size: 2097152 bytes, 2.0 MiB, 0.00 GB  # sg_readcap \/dev\/sg7 Read Capacity results:    Last LBA=8191 (0x1fff), Number of logical blocks=8192    Logical block length=512 bytes Hence:    Device size: 4194304 bytes, 4.0 MiB, 0.00 GB  # sg_readcap \/dev\/sg8 Read Capacity results:    Last LBA=16383 (0x3fff), Number of logical blocks=16384    Logical block length=512 bytes Hence:    Device size: 8388608 bytes, 8.0 MiB, 0.01 GB<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c \u043c\u0435\u0442\u043a\u0438:<\/p>\n<pre><code class=\"bash\"># sg_raw -r 1k \/dev\/sg1 12 00 00 00 60 00 SCSI Status: Good  Received 36 bytes of data:  00     00 00 02 02 1f 00 00 00  53 54 4d 20 20 20 20 20    ........STM  10     4d 69 63 72 6f 53 44 20  44 65 76 69 63 65 20 20    MicroSD Device  20     30 2e 30 31                                         0.01  # sg_raw -r 1k \/dev\/sg2 12 00 00 00 60 00 SCSI Status: Good  Received 36 bytes of data:  00     00 00 02 02 1f 00 00 00  53 54 4d 20 20 20 20 20    ........STM  10     45 45 50 52 4f 4d 20 20  20 20 20 20 20 20 20 20    EEPROM  20     30 2e 30 31                                         0.01  # sg_raw -r 1k \/dev\/sg3 12 00 00 00 60 00 SCSI Status: Good  Received 36 bytes of data:  00     00 00 02 02 1f 00 00 00  53 54 4d 20 20 20 20 20    ........STM  10     53 79 73 74 65 6d 20 20  20 20 20 20 20 20 20 20    System  20     30 2e 30 31                                         0.01  # sg_raw -r 1k \/dev\/sg4 12 00 00 00 60 00 SCSI Status: Good  Received 36 bytes of data:  00     00 00 02 02 1f 00 00 00  53 54 4d 20 20 20 20 20    ........STM  10     54 65 73 74 20 20 20 20  20 20 20 20 20 20 20 20    Test  20     30 2e 30 31<\/code><\/pre>\n<p>\u0412\u044b\u0432\u0435\u0434\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0432\u0441\u0435 LUN \u0432 \u0443\u0437\u043b\u0435:<\/p>\n<pre><code class=\"bash\"># sg_luns \/dev\/sg3 Lun list length = 64 which imples 8 lun entries Report luns [select_report=0x0]:     0000000000000000     0001000000000000     0002000000000000     0003000000000000     0004000000000000     0005000000000000     0006000000000000     0007000000000000 <\/code><\/pre>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u043c \u043b\u043e\u0433\u0438 LUN:<\/p>\n<pre><code class=\"cpp\"># sg_logs \/dev\/sg1     STM       MicroSD Device    0.01  # sg_logs \/dev\/sg2     STM       EEPROM            0.01  # sg_logs \/dev\/sg3     STM       System            0.01  # sg_logs \/dev\/sg4     STM       Test              0.01  # sg_logs \/dev\/sg5     STM       MicroSD2Device    0.01  # sg_logs \/dev\/sg6     STM       EEPROM2           0.01  # sg_logs \/dev\/sg7     STM       System2           0.01  # sg_logs \/dev\/sg8     STM       Test2             0.01<\/code><\/pre>\n<p>\u041f\u043e\u0447\u0438\u0442\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<pre><code>#xxd -l   0x200  -s 0x200  \/dev\/sdb 00000200: ebfe 904d 5344 4f53 352e 3000 0201 0100  ...MSDOS5.0..... 00000210: 0140 0010 02f8 0200 3f00 ff00 0100 0000  .@......?....... 00000220: 0000 0000 8001 29ba 97e1 524e 4f20 4e41  ......)...RNO NA 00000230: 4d45 2020 2020 4641 5420 2020 2020 0000  ME    FAT     .. 00000240: 0000 0000 0000 0000 0000 0000 0000 0000  ................ ................................................................... 000003e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................ 000003f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.   #xxd -l   0x100  -s 0x800  \/dev\/sdc 00000800: 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f  ................ 00000810: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f  ................ 00000820: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f   !\"#$%&amp;'()*+,-.\/ 00000830: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f  0123456789:;&lt;=>? 00000840: 4041 4243 4445 4647 4849 4a4b 4c4d 4e4f  @ABCDEFGHIJKLMNO 00000850: 5051 5253 5455 5657 5859 5a5b 5c5d 5e5f  PQRSTUVWXYZ[\\]^_ 00000860: 6061 6263 6465 6667 6869 6a6b 6c6d 6e6f  `abcdefghijklmno 00000870: 7071 7273 7475 7677 7879 7a7b 7c7d 7e7f  pqrstuvwxyz{|}~. 00000880: 8081 8283 8485 8687 8889 8a8b 8c8d 8e8f  ................ 00000890: 9091 9293 9495 9697 9899 9a9b 9c9d 9e9f  ................ 000008a0: a0a1 a2a3 a4a5 a6a7 a8a9 aaab acad aeaf  ................ 000008b0: b0b1 b2b3 b4b5 b6b7 b8b9 babb bcbd bebf  ................ 000008c0: c0c1 c2c3 c4c5 c6c7 c8c9 cacb cccd cecf  ................ 000008d0: d0d1 d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf  ................ 000008e0: e0e1 e2e3 e4e5 e6e7 e8e9 eaeb eced eeef  ................ 000008f0: f0f1 f2f3 f4f5 f6f7 f8f9 fafb fcfd feff  ................  # xxd -l   0x20  -s 0x800  \/dev\/sdd 00000800: 0404 0404 0404 0404 0404 0404 0404 0404  ................ 00000810: 0404 0404 0404 0404 0404 0404 0404 0404  ................<\/code><\/pre>\n<\/div>\n<\/details>\n<p>Update:<\/p>\n<p>\u0412 Windows 7 \u0438 10  \u0432\u0438\u0434\u0438\u0442 8 LUN \u0438 16, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0438 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u044c \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 10 \u0441\u0435\u043a\u0443\u043d\u0434 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442.<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u043e\u0432\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f 16 LUNs (\u0444\u0430\u0439\u043b usbd_storage_if.c)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* USER CODE BEGIN PRIVATE_TYPES *\/  typedef enum LUN_NUM{ LUN_NUM_MICROSD =0, LUN_NUM_EEPROM, LUN_NUM_SYSTEM, LUN_NUM_TEST, LUN_NUM_CD } lun_num_t;  \/* USER CODE END PRIVATE_TYPES *\/  \/**   * @}   *\/  \/** @defgroup USBD_STORAGE_Private_Defines   * @brief Private defines.   * @{   *\/  #define STORAGE_LUN_NBR                  1 #define STORAGE_BLK_NBR                  0x10000 #define STORAGE_BLK_SIZ                  0x200  \/* USER CODE BEGIN PRIVATE_DEFINES *\/  #define STORAGE_LUNS0x10  #define EEPROM_BLOCK_SIZE 512 #define EEPROM_BLOCKS   64  \/* USER CODE END PRIVATE_DEFINES *\/  \/**   * @}   *\/  \/** @defgroup USBD_STORAGE_Private_Macros   * @brief Private macros.   * @{   *\/  \/* USER CODE BEGIN PRIVATE_MACRO *\/  \/* USER CODE END PRIVATE_MACRO *\/  \/**   * @}   *\/  \/** @defgroup USBD_STORAGE_Private_Variables   * @brief Private variables.   * @{   *\/  \/* USER CODE BEGIN INQUIRY_DATA_FS *\/ \/** USB Mass storage Standard Inquiry Data. *\/ const int8_t STORAGE_Inquirydata_FS[] = {\/* 36 *\/    \/* LUN 0 *\/   0x00,   0x00, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80   0x02,   0x02,   (STANDARD_INQUIRY_DATA_LEN - 5),   0x00,   0x00,   0x00,   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/   'M', 'i', 'c', 'r', 'o', 'S', 'D', ' ', \/* Product      : 16 Bytes *\/   'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',   '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/    \/* LUN 1 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'E', 'E', 'P', 'R', 'O', 'M', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/    \/* LUN 2 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'S', 'y', 's', 't', 'e', 'm', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 3 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'T', 'e', 's', 't', ' ', ' ', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 4 *\/   0x00, \/\/ Set CDROM type   0x80, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80   0x02,   0x02,   (STANDARD_INQUIRY_DATA_LEN - 5),   0x00,   0x00,   0x00,   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/   'D', 'A', 'T', 'A', '0', ' ', ' ', ' ', \/* Product      : 16 Bytes *\/   'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',   '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/    \/* LUN 5 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'E', 'E', 'P', 'R', 'O', 'M', '2', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/    \/* LUN 6 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'S', 'y', 's', 't', 'e', 'm', '2', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 7 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'T', 'e', 's', 't', '2', ' ', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/    \/* LUN 8 *\/     0x00,     0x00, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80     0x02,     0x02,     (STANDARD_INQUIRY_DATA_LEN - 5),     0x00,     0x00,     0x00,     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/     'M', 'i', 'c', 'r', 'o', 'S', 'D', '3', \/* Product      : 16 Bytes *\/     'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',     '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/      \/* LUN 9 *\/     0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved     0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)     0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version     0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved     (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.     0x00, \/\/ reserved     0x00, \/\/ reserved     0x00, \/\/ reserved     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/     'E', 'E', 'P', 'R', 'O', 'M', '3', ' ', \/* Product : 16 Bytes *\/     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',     '0', '.', '0', '1', \/* Version : 4 Bytes *\/      \/* LUN 10 *\/     0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved     0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)     0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version     0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved     (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.     0x00, \/\/ reserved     0x00, \/\/ reserved     0x00, \/\/ reserved     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/     'S', 'y', 's', 't', 'e', 'm', '3', ' ', \/* Product : 16 Bytes *\/     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',     '0', '.', '0', '1', \/* Version : 4 Bytes *\/       \/* LUN 11 *\/     0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved     0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)     0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version     0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved     (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.     0x00, \/\/ reserved     0x00, \/\/ reserved     0x00, \/\/ reserved     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/     'T', 'e', 's', 't', '3', ' ', ' ', ' ', \/* Product : 16 Bytes *\/     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',     '0', '.', '0', '1', \/* Version : 4 Bytes *\/       \/* LUN 12 *\/     0x00, \/\/ Set CDROM type     0x80, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80     0x02,     0x02,     (STANDARD_INQUIRY_DATA_LEN - 5),     0x00,     0x00,     0x00,     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/     'D', 'A', 'T', 'A', '4', ' ', ' ', ' ', \/* Product      : 16 Bytes *\/     'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',     '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/      \/* LUN 13 *\/     0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved     0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)     0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version     0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved     (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.     0x00, \/\/ reserved     0x00, \/\/ reserved     0x00, \/\/ reserved     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/     'E', 'E', 'P', 'R', 'O', 'M', '4', ' ', \/* Product : 16 Bytes *\/     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',     '0', '.', '0', '1', \/* Version : 4 Bytes *\/      \/* LUN 14 *\/     0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved     0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)     0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version     0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved     (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.     0x00, \/\/ reserved     0x00, \/\/ reserved     0x00, \/\/ reserved     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/     'S', 'y', 's', 't', 'e', 'm', '4', ' ', \/* Product : 16 Bytes *\/     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',     '0', '.', '0', '1', \/* Version : 4 Bytes *\/       \/* LUN 15 *\/     0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved     0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)     0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version     0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved     (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.     0x00, \/\/ reserved     0x00, \/\/ reserved     0x00, \/\/ reserved     'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/     'T', 'e', 's', 't', '4', ' ', ' ', ' ', \/* Product : 16 Bytes *\/     ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',     '0', '.', '0', '1', \/* Version : 4 Bytes *\/   }; \/* USER CODE END INQUIRY_DATA_FS *\/  \/* USER CODE BEGIN PRIVATE_VARIABLES *\/  \/* USER CODE END PRIVATE_VARIABLES *\/  \/**   * @}   *\/  \/** @defgroup USBD_STORAGE_Exported_Variables   * @brief Public variables.   * @{   *\/  extern USBD_HandleTypeDef hUsbDeviceFS;  \/* USER CODE BEGIN EXPORTED_VARIABLES *\/  \/* USER CODE END EXPORTED_VARIABLES *\/  \/**   * @}   *\/  \/** @defgroup USBD_STORAGE_Private_FunctionPrototypes   * @brief Private functions declaration.   * @{   *\/  static int8_t STORAGE_Init_FS(uint8_t lun); static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size); static int8_t STORAGE_IsReady_FS(uint8_t lun); static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun); static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); static int8_t STORAGE_GetMaxLun_FS(void);  \/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION *\/  \/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION *\/  \/**   * @}   *\/  USBD_StorageTypeDef USBD_Storage_Interface_fops_FS = {   STORAGE_Init_FS,   STORAGE_GetCapacity_FS,   STORAGE_IsReady_FS,   STORAGE_IsWriteProtected_FS,   STORAGE_Read_FS,   STORAGE_Write_FS,   STORAGE_GetMaxLun_FS,   (int8_t *)STORAGE_Inquirydata_FS };  \/* Private functions ---------------------------------------------------------*\/ \/**   * @brief  Initializes over USB FS IP   * @param  lun:   * @retval USBD_OK if all operations are OK else USBD_FAIL   *\/ int8_t STORAGE_Init_FS(uint8_t lun) {   \/* USER CODE BEGIN 2 *\/   return (USBD_OK);   \/* USER CODE END 2 *\/ }  \/**   * @brief  .   * @param  lun: .   * @param  block_num: .   * @param  block_size: .   * @retval USBD_OK if all operations are OK else USBD_FAIL   *\/ int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size) {   \/* USER CODE BEGIN 3 *\/ \/*   static uint64_t counter = 0;   static lun_num_t prev_lun = LUN_NUM_MICROSD;    if ((counter > STORAGE_LUN_NBR )&amp;&amp;(counter &lt; STORAGE_LUN_NBR*2)){   lun = LUN_NUM_MICROSD;   }    if (prev_lun != lun){   counter++;   } *\/     switch(lun){     case LUN_NUM_MICROSD:     *block_num  = sd_card_glb->data.size_kb &lt;&lt; 1;     *block_size = sd_card_glb->data.block_size;     break;     case LUN_NUM_EEPROM:       *block_num  = EEPROM_BLOCKS;       *block_size = EEPROM_BLOCK_SIZE;       break;     case LUN_NUM_SYSTEM:       *block_num  = EEPROM_BLOCKS &lt;&lt; 2;       *block_size = EEPROM_BLOCK_SIZE;       break;     case LUN_NUM_TEST:       *block_num  = EEPROM_BLOCKS &lt;&lt; 4;       *block_size = EEPROM_BLOCK_SIZE;       break;     case LUN_NUM_CD:       *block_num  = EEPROM_BLOCKS &lt;&lt; 5;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x05:       *block_num  = EEPROM_BLOCKS &lt;&lt; 6;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x06:       *block_num  = EEPROM_BLOCKS &lt;&lt; 7;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x07:       *block_num  = EEPROM_BLOCKS &lt;&lt; 8;       *block_size = EEPROM_BLOCK_SIZE;       break;   }     return (USBD_OK);   \/* USER CODE END 3 *\/ }  \/**   * @brief  .   * @param  lun: .   * @retval USBD_OK if all operations are OK else USBD_FAIL   *\/ int8_t STORAGE_IsReady_FS(uint8_t lun) {   \/* USER CODE BEGIN 4 *\/    return (USBD_OK);   \/* USER CODE END 4 *\/ }  \/**   * @brief  .   * @param  lun: .   * @retval USBD_OK if all operations are OK else USBD_FAIL   *\/ int8_t STORAGE_IsWriteProtected_FS(uint8_t lun) {   \/* USER CODE BEGIN 5 *\/   return (USBD_BUSY);   \/* USER CODE END 5 *\/ }  \/**   * @brief  .   * @param  lun: .   * @retval USBD_OK if all operations are OK else USBD_FAIL   *\/ int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {   \/* USER CODE BEGIN 6 *\/    switch(lun){     case LUN_NUM_MICROSD:     sd_card_read_single_block(sd_card_glb, blk_addr, buf); \/*for (int i =0 ; i&lt;512; i++){   buf[i] = blk_addr; }*\/   break;   case LUN_NUM_EEPROM:   for (int i =0 ; i&lt;512; i++){   buf[i] = i;   }   break;   case LUN_NUM_SYSTEM:       for (int i =0 ; i&lt;512; i++){   buf[i] = blk_addr;   }       break;     case LUN_NUM_TEST:       for (int i =0 ; i&lt;512; i++){   buf[i] = lun;   }       break;     case LUN_NUM_CD:        for (int i =0 ; i&lt;512; i++){     buf[i] = blk_addr;     }     break;   }     return (USBD_OK);   \/* USER CODE END 6 *\/ }  \/**   * @brief  .   * @param  lun: .   * @retval USBD_OK if all operations are OK else USBD_FAIL   *\/ int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {   \/* USER CODE BEGIN 7 *\/   return USBD_FAIL;   \/\/return (USBD_OK);   \/* USER CODE END 7 *\/ }  \/**   * @brief  .   * @param  None   * @retval .   *\/ int8_t STORAGE_GetMaxLun_FS(void) {   \/* USER CODE BEGIN 8 *\/   return (STORAGE_LUNS - 1);   \/* USER CODE END 8 *\/ }<\/code><\/pre>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>LUNS \u0432 Windows<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6c4\/2e9\/0ee\/6c42e90ee3276886303986009837c687.png\" alt=\"16 LUNs \u0432 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0435 \u0437\u0430\u0434\u0430\u0447 Windows 7\" title=\"16 LUNs \u0432 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0435 \u0437\u0430\u0434\u0430\u0447 Windows 7\" width=\"241\" height=\"321\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6c4\/2e9\/0ee\/6c42e90ee3276886303986009837c687.png\"\/><figcaption>16 LUNs \u0432 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0435 \u0437\u0430\u0434\u0430\u0447 Windows 7<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/522\/8c6\/abd\/5228c6abd6959e29e853b386a304b9db.png\" alt=\"D: E: F: - \u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043c\u0430 LUN 0, G: Removeble LUN 4, H: Removeble LUN 12 \" title=\"D: E: F: - \u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043c\u0430 LUN 0, G: Removeble LUN 4, H: Removeble LUN 12 \" width=\"524\" height=\"230\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/522\/8c6\/abd\/5228c6abd6959e29e853b386a304b9db.png\"\/><figcaption>D: E: F: &#8212; \u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043c\u0430 LUN 0, G: Removeble LUN 4, H: Removeble LUN 12 <\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/268\/511\/82b\/26851182bc2cae20cedcc5387a4f26cd.png\" alt=\"LUNs \u0432 Astra32\" title=\"LUNs \u0432 Astra32\" width=\"607\" height=\"419\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/268\/511\/82b\/26851182bc2cae20cedcc5387a4f26cd.png\"\/><figcaption>LUNs \u0432 Astra32<\/figcaption><\/figure>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/91f\/9c9\/abe\/91f9c9abe50d5e394d893e6944090835.png\" alt=\"\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435 LUN 0, Astra32\" title=\"\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435 LUN 0, Astra32\" width=\"475\" height=\"247\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/91f\/9c9\/abe\/91f9c9abe50d5e394d893e6944090835.png\"\/><figcaption>\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0435 LUN 0, Astra32<\/figcaption><\/figure>\n<\/div>\n<\/details>\n<h2>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 CubeMX \/ STM32CubeIDE<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u0441\u0435\u0445 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439, \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u0443\u0431\u043e\u043c, \u0442\u043e \u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u043a\u0438, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c USB_DEVICE->*** \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043a\u0430\u0442\u0430\u043d\u044b \u043a \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e \u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0431\u0440\u0430\u043b\u0438\u0441\u044c \u0443\u0436\u0435 \u0438\u0441\u043f\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0438, \u043d\u043e \u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u043e\u0442\u043a\u0443\u0434\u0430 \u0438\u0445 \u0431\u0435\u0440\u0451\u0442 Cube. \u0412 Linux \u044d\u0442\u043e \u043f\u0430\u043f\u043a\u0430 ~\/STM32Cube\/Repository\/STM32Cube_FW_L4_V1.17.0\/Middlewares\/ST\/STM32_USB_Device_Library\/Class\/MSC.<\/p>\n<p>\u0418 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043d\u0430 GitHub: <a href=\"https:\/\/github.com\/Igorbunow\/STM32CubeL4\/tree\/testing\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Igorbunow\/STM32CubeL4\/tree\/testing<\/a> \u0432\u0435\u0442\u043a\u0430 testing!!!<\/p>\n<p>\u041f\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u043c \u043e\u0448\u0438\u0431\u043a\u0430\u043c \u0441\u0434\u0435\u043b\u0430\u043d Pull Request \u0432 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 ST, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u043d\u0438 \u043f\u043e\u043f\u0440\u0430\u0432\u044f\u0442 \u0443 \u0441\u0435\u0431\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0432\u0435\u0442\u043e\u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e L4. \u0414\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432 \u043d\u0435 \u0441\u043c\u043e\u0442\u0440\u0435\u043b, \u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0438\u044f \u0432 \u043f\u0440\u0430\u0432\u043a\u0430\u0445 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b:<\/p>\n<p>[1] Jan Axelson USB Mass Storage Designing and Programming Devices and Embedded Hosts <\/p>\n<p>[2] Microchip AN2554 <a href=\"https:\/\/www.microchip.com\/content\/dam\/mchp\/documents\/OTH\/ApplicationNotes\/ApplicationNotes\/00002554A.pdf\" rel=\"noopener noreferrer nofollow\">https:\/\/www.microchip.com\/content\/dam\/mchp\/documents\/OTH\/ApplicationNotes\/ApplicationNotes\/00002554A.pdf<\/a><\/p>\n<p>[3] Microchip AN1169 <a href=\"http:\/\/www.t-es-t.hu\/download\/microchip\/an1169a.pdf\" rel=\"noopener noreferrer nofollow\">http:\/\/www.t-es-t.hu\/download\/microchip\/an1169a.pdf<\/a><\/p>\n<p>[4] ST UM1717, UM0424, UM1021, UM1720<\/p>\n<p>[5] Universal Serial Bus Mass Storage Class Bulk-Only Transport <a href=\"https:\/\/www.usb.org\/sites\/default\/files\/usbmassbulk_10.pdf\" rel=\"noopener noreferrer nofollow\">https:\/\/www.usb.org\/sites\/default\/files\/usbmassbulk_10.pdf<\/a><\/p>\n<p>[6] SCSI Commands Reference Manual Seagate <a href=\"https:\/\/www.seagate.com\/files\/staticfiles\/support\/docs\/manual\/Interface%20manuals\/100293068j.pdf\" rel=\"noopener noreferrer nofollow\">https:\/\/www.seagate.com\/files\/staticfiles\/support\/docs\/manual\/Interface%20manuals\/100293068j.pdf<\/a><\/p>\n<p>[7] <a href=\"https:\/\/habr.com\/ru\/post\/549016\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/post\/549016\/<\/a><\/p>\n<p>[8] <a href=\"https:\/\/habr.com\/ru\/post\/335018\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/post\/335018\/<\/a><\/p>\n<p>[9] <a href=\"https:\/\/habr.com\/ru\/post\/336968\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/post\/336968\/<\/a><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/571704\/\"> https:\/\/habr.com\/ru\/articles\/571704\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u043e\u043f\u0430\u043b\u0430\u0441\u044c \u0437\u0430\u0434\u0430\u0447\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e USB \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0438\u043a\u0438\u0434\u044b\u0432\u0430\u043b\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0434\u0438\u0441\u043a\u043e\u0432\u044b\u043c\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0434\u043b\u044f MicroSD, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 EEPROM \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u0435\u043a \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438. \u0420\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u043f\u043e\u0439\u0442\u0438 \u043f\u043e \u043f\u0443\u0442\u0438 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0433\u043e \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0432 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438, \u0442\u043e \u0447\u0442\u043e ST \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0432 \u0441\u0432\u043e\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435. \u0420\u0430\u0431\u043e\u0442\u0430 c USB \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0430 \u0443 \u043d\u0438\u0445 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438: \u0434\u0440\u0430\u0439\u0432\u0435\u0440 + MiddleWare:<\/p>\n<figure class=\"full-width\"><figcaption>USB \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 STM32<\/figcaption><\/figure>\n<p>\u041e\u0448\u0438\u0431\u043a\u0438 \u0443 \u043d\u0430\u0441 \u0437\u0430\u043a\u0440\u0430\u043b\u0438\u0441\u044c MiddleWare \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0442\u043e\u043c\u0443, \u0447\u0442\u043e MiddleWare \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d \u043e\u0442 \u0436\u0435\u043b\u0435\u0437\u0430, \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u043c\u0435\u0439\u0441\u0442\u0432 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u043a\u0430\u043c\u0438 \u043a\u043e\u0434\u0430. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 MiddleWare \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u043e \u0443 ST \u0432 UM1717, UM0424, UM1021, UM1720.<\/p>\n<h2>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 (\u0432 \u0447\u0438\u0441\u0442\u043e\u043c \u0432\u0438\u0434\u0435, \u0447\u0442\u043e ST \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b)<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0432 \u043a\u0443\u0431\u0435 \u043f\u0440\u043e\u0435\u043a\u0442, \u0437\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c USB \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0432 MiddleWare Class For FS IP: Mass Storage Class \u0438 \u043f\u0440\u0430\u0432\u0438\u043c \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u044b. \u0417\u0430\u0442\u0435\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 USB_DEVICE->App->usbd_storage_if.c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 LUN. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0444\u0430\u0439\u043b\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0430\u0439\u043b USB_DEVICE->App->usbd_storage_if.c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/* USER CODE BEGIN PRIVATE_TYPES *\/  typedef enum LUN_NUM{ LUN_NUM_MICROSD =0, LUN_NUM_EEPROM, LUN_NUM_SYSTEM, LUN_NUM_TEST } lun_num_t;  \/* USER CODE END PRIVATE_TYPES *\/  \/* USER CODE BEGIN PRIVATE_DEFINES *\/  #define STORAGE_LUNS0x8  #define EEPROM_BLOCK_SIZE 512 #define EEPROM_BLOCKS   64  \/* USER CODE END PRIVATE_DEFINES *\/  \/** USB Mass storage Standard Inquiry Data. *\/ const int8_t STORAGE_Inquirydata_FS[] = {\/* 36 *\/    \/* LUN 0 *\/   0x00,   0x00, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80   0x02,   0x02,   (STANDARD_INQUIRY_DATA_LEN - 5),   0x00,   0x00,   0x00,   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/   'M', 'i', 'c', 'r', 'o', 'S', 'D', ' ', \/* Product      : 16 Bytes *\/   'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',   '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/    \/* LUN 1 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'E', 'E', 'P', 'R', 'O', 'M', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/    \/* LUN 2 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'S', 'y', 's', 't', 'e', 'm', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 3 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'T', 'e', 's', 't', ' ', ' ', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 4 *\/   0x00,   0x00, \/\/ Disable MSB bit - for multipartishion recognize in windows, removeble device = 0x80   0x02,   0x02,   (STANDARD_INQUIRY_DATA_LEN - 5),   0x00,   0x00,   0x00,   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer : 8 bytes *\/   'M', 'i', 'c', 'r', 'o', 'S', 'D', '2', \/* Product      : 16 Bytes *\/   'D', 'e', 'v', 'i', 'c', 'e', ' ', ' ',   '0', '.', '0' ,'1',                      \/* Version      : 4 Bytes *\/    \/* LUN 5 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'E', 'E', 'P', 'R', 'O', 'M', '2', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/    \/* LUN 6 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reseForrved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'S', 'y', 's', 't', 'e', 'm', '2', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/     \/* LUN 7 *\/   0x00, \/\/ bit4:0 - peripheral device type, bit7:5 - reserved   0x00, \/\/ bit6:0 - reserved, bit7 - removable media bit (set to 1 to indicate removable media)   0x02, \/\/ bit2:0 - ANSI version, bit5:3 - ECMA version, bit7:6 - ISO version   0x02, \/\/ bit3:0 - Response data format, bit7:4 - reserved   (STANDARD_INQUIRY_DATA_LEN - 5), \/\/ additional length - specify the length in bytes of the parameters.   0x00, \/\/ reserved   0x00, \/\/ reserved   0x00, \/\/ reserved   'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', \/* Manufacturer: 8 bytes *\/   'T', 'e', 's', 't', '2', ' ', ' ', ' ', \/* Product : 16 Bytes *\/   ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',   '0', '.', '0', '1', \/* Version : 4 Bytes *\/   }; \/* USER CODE END INQUIRY_DATA_FS *\/  int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size) {   \/* USER CODE BEGIN 3 *\/   switch(lun){     case LUN_NUM_MICROSD:     *block_num  = sd_card_glb->data.size_kb &lt;&lt; 1;     *block_size = sd_card_glb->data.block_size;     break;     case LUN_NUM_EEPROM:       *block_num  = EEPROM_BLOCKS;       *block_size = EEPROM_BLOCK_SIZE;       break;     case LUN_NUM_SYSTEM:       *block_num  = EEPROM_BLOCKS &lt;&lt; 2;       *block_size = EEPROM_BLOCK_SIZE;       break;     case LUN_NUM_TEST:       *block_num  = EEPROM_BLOCKS &lt;&lt; 4;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x04:       *block_num  = EEPROM_BLOCKS &lt;&lt; 5;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x05:       *block_num  = EEPROM_BLOCKS &lt;&lt; 6;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x06:       *block_num  = EEPROM_BLOCKS &lt;&lt; 7;       *block_size = EEPROM_BLOCK_SIZE;       break;     case 0x07:       *block_num  = EEPROM_BLOCKS &lt;&lt; 8;       *block_size = EEPROM_BLOCK_SIZE;       break;   }     return (USBD_OK);   \/* USER CODE END 3 *\/ }  int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) {   \/* USER CODE BEGIN 6 *\/    switch(lun){     case LUN_NUM_MICROSD:     sd_card_read_single_block(sd_card_glb, blk_addr, buf); \/*for (int i =0 ; i&lt;512; i++){   buf[i] = blk_addr; }*\/   break;   case LUN_NUM_EEPROM:   for (int i =0 ; i&lt;512; i++){   buf[i] = i;   }   break;   case LUN_NUM_SYSTEM:       for (int i =0 ; i&lt;512; i++){   buf[i] = blk_addr;   }       break;     case LUN_NUM_TEST:       for (int i =0 ; i&lt;512; i++){   buf[i] = lun;   }       break;   }     return (USBD_OK);   \/* USER CODE END 6 *\/ }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 8 LUN \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e 2, \u0434\u0430 \u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442, \u0435\u0441\u043b\u0438 \u0432  STORAGE_GetCapacity_FS \u0432\u044b\u0434\u0430\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 LUN, \u0434\u0430 \u0435\u0449\u0451 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u0435\u0440\u0435\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f&#8230;<\/p>\n<details class=\"spoiler\">\n<summary>\u0412 kernel log:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">usb 1-1: new full-speed USB device number 10 using xhci_hcd usb 1-1: New USB device found, idVendor=0483, idProduct=572a, bcdDevice= 2.00 usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-1: Product: Test MASS Storage usb 1-1: Manufacturer: Developer usb 1-1: SerialNumber: 2062369C5950 usb-storage 1-1:1.0: USB Mass Storage device detected scsi host4: usb-storage 1-1:1.0 scsi 4:0:0:0: Direct-Access     STM      MicroSD Device   0.01 PQ: 0 ANSI: 2 scsi 4:0:0:1: Direct-Access     STM      EEPROM           0.01 PQ: 0 ANSI: 2 scsi 4:0:0:0: Attached scsi generic sg1 type 0 scsi 4:0:0:1: Attached scsi generic sg2 type 0 sd 4:0:0:0: [sdb] 1030144 512-byte logical blocks: (527 MB\/503 MiB) sd 4:0:0:1: [sdc] 64 512-byte logical blocks: (32.8 kB\/32.0 KiB) sd 4:0:0:1: [sdc] Write Protect is off sd 4:0:0:1: [sdc] Mode Sense: 22 0 0 0 sd 4:0:0:1: [sdc] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA  sdb: sdb1 sdb2 sdb3 usb 1-1: reset full-speed USB device number 10 using xhci_hcd sd 4:0:0:0: [sdb] Attached SCSI disk usb 1-1: reset full-speed USB device number 10 using xhci_hcd usb 1-1: reset full-speed USB device number 10 using xhci_hcd sd 4:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE cmd_age=0s sd 4:0:0:0: [sdb] tag#0 Sense Key : Illegal Request [current] sd 4:0:0:0: [sdb] tag#0 Add. Sense: Logical block<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-385576","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/385576","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=385576"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/385576\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=385576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=385576"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=385576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}