]> Zhao Yanbai Git Server - minix.git/commitdiff
USB bulk only transport 'reset recovery' added
authorWojciech Zajac <wzajac@jpembedded.eu>
Wed, 25 Jun 2014 08:09:20 +0000 (10:09 +0200)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:05:55 +0000 (17:05 +0200)
Control URB formatting for mass storage driver was also fixed.

drivers/usb_storage/usb_storage.c

index ca7b0cf793ccf8fda3ed9aa72bfd5a26bf108960..c455554e8b24c83425dc73f0e6a06f60e0f25781 100755 (executable)
@@ -46,7 +46,9 @@ static int mass_storage_send_scsi_data_out(void *, unsigned int);
 static int mass_storage_send_scsi_csw_in(void);
 
 /* Bulk only URB related prototypes */
+static int mass_storage_reset_recovery(void);
 static int mass_storage_send_bulk_reset(void);
+static int mass_storage_send_clear_feature(int, int);
 
 /* SEF related functions */
 static int mass_storage_sef_hdlr(int, sef_init_info_t *);
@@ -330,6 +332,43 @@ mass_storage_send_scsi_csw_in(void)
        return EXIT_SUCCESS;
 }
 
+
+/*===========================================================================*
+ *    mass_storage_reset_recovery                                            *
+ *===========================================================================*/
+static int
+mass_storage_reset_recovery(void)
+{
+       MASS_DEBUG_DUMP;
+
+       /* Bulk-Only Mass Storage Reset */
+       if (mass_storage_send_bulk_reset()) {
+               MASS_MSG("Bulk-only mass storage reset failed");
+               return EIO;
+       }
+
+       /* Clear Feature HALT to the Bulk-In endpoint */
+       if (URB_INVALID_EP != driver_state.cur_periph->ep_in.ep_num)
+               if (mass_storage_send_clear_feature(
+                                       driver_state.cur_periph->ep_in.ep_num,
+                                       DDEKIT_USB_IN)) {
+                       MASS_MSG("Resetting IN EP failed");
+                       return EIO;
+               }
+
+       /* Clear Feature HALT to the Bulk-Out endpoint */
+       if (URB_INVALID_EP != driver_state.cur_periph->ep_out.ep_num)
+               if (mass_storage_send_clear_feature(
+                                       driver_state.cur_periph->ep_out.ep_num,
+                                       DDEKIT_USB_OUT)) {
+                       MASS_MSG("Resetting OUT EP failed");
+                       return EIO;
+               }
+
+       return EXIT_SUCCESS;
+}
+
+
 /*===========================================================================*
  *    mass_storage_send_bulk_reset                                           *
  *===========================================================================*/
@@ -351,6 +390,8 @@ mass_storage_send_bulk_reset(void)
        ep_conf.ep_num = 0;
        ep_conf.direction = DDEKIT_USB_OUT;
        ep_conf.type = DDEKIT_USB_TRANSFER_CTL;
+       ep_conf.max_packet_size = 0;
+       ep_conf.interval = 0;
 
        /* Reset URB and assign given values */
        init_urb(&urb, driver_state.cur_periph->dev, &ep_conf);
@@ -378,6 +419,61 @@ mass_storage_send_bulk_reset(void)
 }
 
 
+/*===========================================================================*
+ *    mass_storage_send_clear_feature                                        *
+ *===========================================================================*/
+static int
+mass_storage_send_clear_feature(int ep_num, int direction)
+{
+       /* URB to be send */
+       struct ddekit_usb_urb urb;
+
+       /* Setup buffer to be send */
+       struct usb_ctrlrequest bulk_setup;
+
+       /* Control EP configuration */
+       urb_ep_config ep_conf;
+
+       MASS_DEBUG_DUMP;
+
+       assert((ep_num >= 0) && (ep_num < 16));
+       assert((DDEKIT_USB_OUT == direction) || (DDEKIT_USB_IN == direction));
+
+       /* Initialize EP configuration */
+       ep_conf.ep_num = 0;
+       ep_conf.direction = DDEKIT_USB_OUT;
+       ep_conf.type = DDEKIT_USB_TRANSFER_CTL;
+       ep_conf.max_packet_size = 0;
+       ep_conf.interval = 0;
+
+       /* Reset URB and assign given values */
+       init_urb(&urb, driver_state.cur_periph->dev, &ep_conf);
+
+       /* Clear setup data */
+       memset(&bulk_setup, 0, sizeof(bulk_setup));
+
+       /* For explanation of these values see usbmassbulk_10.pdf */
+       /* 3.1 Bulk-Only Mass Storage Reset */
+       bulk_setup.bRequestType = 0x02; /* Standard, Endpoint, host to device */
+       bulk_setup.bRequest = 0x01; /* CLEAR_FEATURE */
+       bulk_setup.wValue = 0x00; /* Endpoint */
+       bulk_setup.wIndex = ep_num; /* Endpoint number... */
+       if (DDEKIT_USB_IN == direction)
+               bulk_setup.wIndex |= UE_DIR_IN; /* ...and direction bit */
+       bulk_setup.wLength = 0x00;
+
+       /* Attach request to URB */
+       attach_urb_data(&urb, URB_BUF_TYPE_SETUP,
+                       &bulk_setup, sizeof(bulk_setup));
+
+       /* Send and wait for response */
+       if (blocking_urb_submit(&urb, mass_storage_sem, URB_SUBMIT_CHECK_LEN))
+               return EXIT_FAILURE;
+
+       return EXIT_SUCCESS;
+}
+
+
 /*===========================================================================*
  *    mass_storage_sef_hdlr                                                  *
  *===========================================================================*/
@@ -910,7 +1006,7 @@ mass_storage_open(devminor_t minor, int UNUSED(access))
        d = driver_state.cur_drive;
 
        /* In case of previous CBW mismatch */
-       if (mass_storage_send_bulk_reset()) {
+       if (mass_storage_reset_recovery()) {
                MASS_MSG("Resetting mass storage device failed");
                return EIO;
        }
@@ -1339,6 +1435,8 @@ mass_storage_get_endpoints(urb_ep_config * ep_in, urb_ep_config * ep_out)
        ep_conf.ep_num = 0;
        ep_conf.direction = DDEKIT_USB_IN;
        ep_conf.type = DDEKIT_USB_TRANSFER_CTL;
+       ep_conf.max_packet_size = 0;
+       ep_conf.interval = 0;
 
        /* Reset URB and assign given values */
        init_urb(&urb, driver_state.cur_periph->dev, &ep_conf);