Przeglądaj źródła

add scsi start stop unit struct, improve device msc, correctly stall unsupported scsi command

hathach 7 lat temu
rodzic
commit
d2ab4db25e

+ 1 - 1
examples/device/nrf52840/src/msc_device_app.c

@@ -112,7 +112,7 @@ int32_t tud_msc_scsi_cb (uint8_t rhport, uint8_t lun, uint8_t const scsi_cmd[16]
   }
 
   // return len must not larger than bufsize
-  TU_ASSERT( bufsize >= len );
+  if ( len > bufsize ) len = bufsize;
 
   if ( ptr && len )
   {

+ 23 - 0
src/class/msc/msc.h

@@ -298,6 +298,29 @@ typedef struct ATTR_PACKED
 
 VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct");
 
+typedef struct ATTR_PACKED
+{
+  uint8_t cmd_code;
+
+  uint8_t immded : 1;
+  uint8_t        : 7;
+
+  uint8_t TU_RESERVED;
+
+  uint8_t power_condition_mod : 4;
+  uint8_t                     : 4;
+
+  uint8_t start           : 1;
+  uint8_t load_eject      : 1;
+  uint8_t no_flush        : 1;
+  uint8_t                 : 1;
+  uint8_t power_condition : 4;
+
+  uint8_t control;
+} scsi_start_stop_unit_t;
+
+VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct");
+
 //--------------------------------------------------------------------+
 // SCSI MMC
 //--------------------------------------------------------------------+

+ 18 - 9
src/class/msc/msc_device.c

@@ -216,11 +216,14 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u
 
         if ( p_cbw->xfer_bytes == 0)
         {
-          p_msc->data_len = tud_msc_scsi_cb(rhport, p_cbw->lun, p_cbw->command, NULL, 0);
-          p_csw->status   = (p_msc->data_len == 0) ? MSC_CSW_STATUS_PASSED : MSC_CSW_STATUS_FAILED;
+          int32_t const cb_result = tud_msc_scsi_cb(rhport, p_cbw->lun, p_cbw->command, NULL, 0);
+
+          p_csw->status   = (cb_result == 0) ? MSC_CSW_STATUS_PASSED : MSC_CSW_STATUS_FAILED;
+          p_msc->data_len = 0;
           p_msc->stage    = MSC_STAGE_STATUS;
 
-          TU_ASSERT( p_msc->data_len == 0, TUSB_ERROR_INVALID_PARA);
+          // stall request since callback return negative
+          if ( cb_result < 0 ) dcd_edpt_stall(rhport, p_msc->ep_in);
         }
         else if ( !BIT_TEST_(p_cbw->dir, 7) )
         {
@@ -230,7 +233,6 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u
         else
         {
           // IN Transfer
-
           int32_t cb_result;
 
           // TODO refactor later
@@ -282,8 +284,15 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u
             cb_result = tud_msc_scsi_cb(rhport, p_cbw->lun, p_cbw->command, _mscd_buf, p_msc->data_len);
           }
 
-          p_csw->status   = (cb_result >= 0) ? MSC_CSW_STATUS_PASSED : MSC_CSW_STATUS_FAILED;
-          p_msc->data_len = (uint32_t) cb_result;
+          if ( cb_result > 0 )
+          {
+            p_csw->status   = MSC_CSW_STATUS_PASSED;
+            p_msc->data_len = (uint32_t) cb_result;
+          }else
+          {
+            p_csw->status = MSC_CSW_STATUS_FAILED;
+            p_msc->data_len = 0;
+          }
 
           TU_ASSERT( p_cbw->xfer_bytes >= p_msc->data_len, TUSB_ERROR_INVALID_PARA ); // cannot return more than host expect
 
@@ -292,11 +301,11 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u
             TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->data_len), TUSB_ERROR_DCD_EDPT_XFER );
           }else
           {
-            // application does not provide data to response --> possibly unsupported SCSI command
-            dcd_edpt_stall(rhport, p_msc->ep_in);
-
+            // callback does not provide response's data --> possibly unsupported SCSI command
             p_csw->status = MSC_CSW_STATUS_FAILED;
             p_msc->stage  = MSC_STAGE_STATUS;
+
+            dcd_edpt_stall(rhport, p_msc->ep_in);
           }
         }
       }

+ 3 - 0
src/common/tusb_common.h

@@ -101,6 +101,9 @@
 #endif
 
 
+// for declaration of reserved field, make use of _TU_COUNTER_
+#define TU_RESERVED   XSTRING_CONCAT_(reserved, _TU_COUNTER_)
+
 /*------------------------------------------------------------------*/
 /* Count number of arguments of __VA_ARGS__
  * - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s

+ 7 - 7
src/common/tusb_compiler.h

@@ -49,19 +49,19 @@
 #define STRING_CONCAT_(a, b)  a##b                 ///< concat without expand
 #define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) ///< expand then concat
 
+#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
+  #define _TU_COUNTER_ __COUNTER__
+#else
+  #define _TU_COUNTER_ __LINE__
+#endif
+
 //--------------------------------------------------------------------+
 // Compile-time Assert (use VERIFY_STATIC to avoid name conflict)
 //--------------------------------------------------------------------+
 #if defined(__ICCARM__) || (__STDC_VERSION__ >= 201112L )
   #define VERIFY_STATIC   static_assert
 #else
-  #if defined __COUNTER__ && __COUNTER__ != __COUNTER__
-    #define _VERIFY_COUNTER __COUNTER__
-  #else
-    #define _VERIFY_COUNTER __LINE__
-  #endif
-
-  #define VERIFY_STATIC(const_expr, _mess) enum { XSTRING_CONCAT_(_verify_static_, _VERIFY_COUNTER) = 1/(!!(const_expr)) }
+  #define VERIFY_STATIC(const_expr, _mess) enum { XSTRING_CONCAT_(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) }
 #endif
 
 // allow debugger to watch any module-wide variables anywhere