This is a slightly cleaned up version of that earlier patch:

- Makes both copies of the clear_halt() logic know that
  usb_pipein() returns boolean (zero/not) not integer (0/1).
  This resolves a problem folk have had with usb-storage.
  (I looked at kernel uses of usb_pipein and it really was
  only the clear_halt logic that cares.)

- Removes some code from the "standard" version; no point
  in Linux expecting devices to do something neither Microsoft
  nor Apple will test for.

Please merge.

- Dave





--- ./drivers-dist/usb/core/message.c   Fri Oct 18 09:48:17 2002
+++ ./drivers/usb/core/message.c        Sun Oct 20 18:15:14 2002
@@ -687,6 +687,7 @@
  * sometimes referred to as being "stalled".  Such endpoints are unable
  * to transmit or receive data until the halt status is cleared.  Any URBs
- * queued queued for such an endpoint should normally be unlinked before
- * clearing the halt condition.
+ * queued for such an endpoint should normally be unlinked by the driver
+ * before clearing the halt condition, as described in sections 5.7.5
+ * and 5.8.5 of the USB 2.0 spec.
  *
  * Note that control and isochronous endpoints don't halt, although control
@@ -702,46 +703,32 @@
 {
        int result;
-       __u16 status;
-       unsigned char *buffer;
-       int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
-
-/*
-       if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))
-               return 0;
-*/
-
+       int endp = usb_pipeendpoint(pipe);
+       
+       if (usb_pipein (pipe))
+               endp |= USB_DIR_IN;
+
+       /* we don't care if it wasn't halted first. in fact some devices
+        * (like some ibmcam model 1 units) seem to expect hosts to make
+        * this request for iso endpoints, which can't halt!
+        */
        result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0,
                HZ * USB_CTRL_SET_TIMEOUT);
 
-       /* don't clear if failed */
-       if (result < 0)
-               return result;
-
-       buffer = kmalloc(sizeof(status), GFP_KERNEL);
-       if (!buffer) {
-               err("unable to allocate memory for configuration descriptors");
-               return -ENOMEM;
-       }
-
-       result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-               USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
-               // FIXME USB_CTRL_GET_TIMEOUT, yes?  why not usb_get_status() ?
-               buffer, sizeof(status), HZ * USB_CTRL_SET_TIMEOUT);
-
-       memcpy(&status, buffer, sizeof(status));
-       kfree(buffer);
-
+       /* don't un-halt or force to DATA0 except on success */
        if (result < 0)
                return result;
 
-       if (le16_to_cpu(status) & 1)
-               return -EPIPE;          /* still halted */
-
-       usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
-
-       /* toggle is reset on clear */
+       /* NOTE:  seems like Microsoft and Apple don't bother verifying
+        * the clear "took", so some devices could lock up if you check...
+        * such as the Hagiwara FlashGate DUAL.  So we won't bother.
+        *
+        * NOTE:  make sure the logic here doesn't diverge much from
+        * the copy in usb-storage, for as long as we need two copies.
+        */
 
+       /* toggle was reset by the clear, then ep was reactivated */
        usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
+       usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
 
        return 0;
--- ./drivers-dist/usb/storage/transport.c      Wed Oct 16 14:02:11 2002
+++ ./drivers/usb/storage/transport.c   Fri Oct 18 14:29:25 2002
@@ -519,5 +519,8 @@
 {
        int result;
-       int endp = usb_pipeendpoint(pipe) | (usb_pipein(pipe) << 7);
+       int endp = usb_pipeendpoint(pipe);
+
+       if (usb_pipein (pipe))
+               endp |= USB_DIR_IN;
 
        result = usb_stor_control_msg(us, us->send_ctrl_pipe,

Reply via email to