spin_unlock_irq(&hcd_root_hub_lock);
        if (status)
                return status;
+       urb->hcpriv = hcd;      /* Indicate it's queued */
 
        cmd = (struct usb_ctrlrequest *) urb->setup_packet;
        typeReq  = (cmd->bRequestType << 8) | cmd->bRequest;
                        hcd->poll_pending = 0;
                        hcd->status_urb = NULL;
                        urb->status = 0;
-                       urb->hcpriv = NULL;
                        urb->actual_length = length;
                        memcpy(urb->transfer_buffer, buffer, length);
 
                        del_timer (&hcd->rh_timer);
                if (urb == hcd->status_urb) {
                        hcd->status_urb = NULL;
-                       urb->hcpriv = NULL;
                        usb_hcd_unlink_urb_from_ep(hcd, urb);
 
                        spin_unlock(&hcd_root_hub_lock);
        if (unlikely(status)) {
                usbmon_urb_submit_error(&hcd->self, urb, status);
                unmap_urb_for_dma(hcd, urb);
+               urb->hcpriv = NULL;
                INIT_LIST_HEAD(&urb->urb_list);
                atomic_dec(&urb->use_count);
                if (urb->reject)
        unmap_urb_for_dma(hcd, urb);
        usbmon_urb_complete (&hcd->self, urb);
        usb_unanchor_urb(urb);
+       urb->hcpriv = NULL;
+       if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
+                       urb->actual_length < urb->transfer_buffer_length &&
+                       !urb->status))
+               urb->status = -EREMOTEIO;
 
        /* pass ownership to the completion handler */
        urb->complete (urb);
 
                 *
                 * partially filling a buffer optionally blocks queue advances
                 * (so completion handlers can clean up the queue) but we don't
-                * need to emulate such data-in-flight.  so we only show part
-                * of the URB_SHORT_NOT_OK effect: completion status.
+                * need to emulate such data-in-flight.
                 */
                if (is_short) {
                        if (host_len == dev_len) {
                                if (dev_len > host_len)
                                        maybe_set_status (urb, -EOVERFLOW);
                                else
-                                       maybe_set_status (urb,
-                                               (urb->transfer_flags
-                                                       & URB_SHORT_NOT_OK)
-                                               ? -EREMOTEIO : 0);
+                                       maybe_set_status (urb, 0);
                        } else if (!to_host) {
                                maybe_set_status (urb, 0);
                                if (host_len > dev_len)
                        continue;
 
 return_urb:
-               urb->hcpriv = NULL;
                list_del (&urbp->urbp_list);
                kfree (urbp);
                if (ep)
 
        }
 
        spin_lock (&urb->lock);
-       urb->hcpriv = NULL;
        switch (urb->status) {
        case -EINPROGRESS:              /* success */
                urb->status = 0;
                /* remove it from the queue */
                spin_lock (&urb->lock);
                qtd_copy_status (ehci, urb, qtd->length, token);
-               do_status = (urb->status == -EREMOTEIO)
-                               && usb_pipecontrol (urb->pipe);
+               if (unlikely(urb->status == -EREMOTEIO)) {
+                       do_status = usb_pipecontrol(urb->pipe);
+                       urb->status = 0;
+               }
                spin_unlock (&urb->lock);
 
                if (stopped && qtd->qtd_list.prev != &qh->qtd_list) {
 
 {
        unsigned i;
 
-       urb->hcpriv = NULL;
        ep->error_count = 0;
 
        if (usb_pipecontrol(urb->pipe))
                        if (PTD_GET_ACTIVE(ptd)
                            || (cc != TD_CC_NOERROR && cc < 0x0E))
                                break;
-                       if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
-                                       urb->actual_length <
-                                               urb->transfer_buffer_length)
-                               status = -EREMOTEIO;
-                       else
-                               status = 0;
+                       status = 0;
                        ep->nextpid = 0;
                        break;
                default:
 
        // ASSERT (urb->hcpriv != 0);
 
        urb_free_priv (ohci, urb->hcpriv);
-       urb->hcpriv = NULL;
 
        spin_lock (&urb->lock);
        if (likely (urb->status == -EINPROGRESS))
                urb->status = 0;
-       /* report short control reads right even though the data TD always
-        * has TD_R set.  (much simpler, but creates the 1-td limit.)
-        */
-       if (unlikely (urb->transfer_flags & URB_SHORT_NOT_OK)
-                       && unlikely (usb_pipecontrol (urb->pipe))
-                       && urb->actual_length < urb->transfer_buffer_length
-                       && usb_pipein (urb->pipe)
-                       && urb->status == 0) {
-               urb->status = -EREMOTEIO;
-       }
        spin_unlock (&urb->lock);
 
        switch (usb_pipetype (urb->pipe)) {
 
 
                if (urb) {
                        urb->status = -ENODEV;
-                       urb->hcpriv = NULL;
                        usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597),
                                        urb);
 
                if (usb_pipeisoc(urb->pipe))
                        urb->start_frame = r8a66597_get_frame(hcd);
 
-               urb->hcpriv = NULL;
                usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb);
 
                spin_unlock(&r8a66597->lock);
                td->zero_packet = 1;
        if (rcv_len < bufsize) {
                td->short_packet = 1;
-               if (urb->transfer_buffer_length != urb->actual_length &&
-                   urb->transfer_flags & URB_SHORT_NOT_OK)
-                       status = -EREMOTEIO;
        }
        if (usb_pipeisoc(urb->pipe)) {
                urb->iso_frame_desc[td->iso_cnt].actual_length = size;
        }
 
        /* check transfer finish */
-       if (check_transfer_finish(td, urb)) {
+       if (finish || check_transfer_finish(td, urb)) {
                pipe_stop(r8a66597, td->pipe);
                pipe_irq_disable(r8a66597, pipenum);
                finish = 1;
 
        spin_lock(&urb->lock);
        if (urb->status == -EINPROGRESS)
                urb->status = status;
-       urb->hcpriv = NULL;
        spin_unlock(&urb->lock);
 
        usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb);
                        sl811_read_buf(sl811, SL811HS_PACKET_BUF(bank == 0),
                                        buf, len);
                        usb_dotoggle(udev, ep->epnum, 0);
-                       if (urb->actual_length == urb->transfer_buffer_length)
+                       if (urb->actual_length == urb->transfer_buffer_length
+                                       || len < ep->maxpacket)
                                urbstat = 0;
-                       else if (len < ep->maxpacket) {
-                               if (urb->transfer_flags & URB_SHORT_NOT_OK)
-                                       urbstat = -EREMOTEIO;
-                               else
-                                       urbstat = 0;
-                       }
-                       if (usb_pipecontrol(urb->pipe)
-                                       && (urbstat == -EREMOTEIO
-                                               || urbstat == 0)) {
+                       if (usb_pipecontrol(urb->pipe) && urbstat == 0) {
 
                                /* NOTE if the status stage STALLs (why?),
                                 * this reports the wrong urb status.
 
         struct usb_hcd *hcd = u132_to_hcd(u132);
         urb->error_count = 0;
         urb->status = status;
-        urb->hcpriv = NULL;
         spin_lock_irqsave(&endp->queue_lock.slock, irqs);
        usb_hcd_unlink_urb_from_ep(hcd, urb);
         endp->queue_next += 1;
         struct usb_hcd *hcd = u132_to_hcd(u132);
         urb->error_count = 0;
         urb->status = status;
-        urb->hcpriv = NULL;
         spin_lock_irqsave(&endp->queue_lock.slock, irqs);
        usb_hcd_unlink_urb_from_ep(hcd, urb);
         endp->queue_next += 1;
                         list_del(scan);
                         endp->queue_size -= 1;
                         urb->error_count = 0;
-                        urb->hcpriv = NULL;
                         usb_hcd_giveback_urb(hcd, urb);
                         return 0;
                 } else
                         endp->edset_flush = 1;
                         u132_endp_queue_work(u132, endp, 0);
                         spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
-                        urb->hcpriv = NULL;
                         return 0;
                 } else {
                         spin_unlock_irqrestore(&endp->queue_lock.slock, irqs);
                                         irqs);
                                 kfree(urbq);
                         } urb->error_count = 0;
-                        urb->hcpriv = NULL;
                         usb_hcd_giveback_urb(hcd, urb);
                         return 0;
                 } else if (list_empty(&endp->urb_more)) {
 
                uhci_free_td(uhci, td);
        }
 
-       urbp->urb->hcpriv = NULL;
        kmem_cache_free(uhci_up_cachep, urbp);
 }
 
                 * unlinked first.  Regardless, don't confuse people with a
                 * negative length. */
                urb->actual_length = max(urb->actual_length, 0);
-
-               /* Report erroneous short transfers */
-               if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
-                               urb->actual_length <
-                                       urb->transfer_buffer_length &&
-                               urb->status == 0))
-                       urb->status = -EREMOTEIO;
        }
 
        /* When giving back the first URB in an Isochronous queue,