* unlink pending urbs so they won't rx/tx bad data.
*/
for (i = 0, found = 0; i < io->entries; i++) {
- if (!io->urbs [i])
+ if (!io->urbs [i] || !io->urbs [i]->dev)
continue;
if (found) {
status = usb_unlink_urb (io->urbs [i]);
if (io->entries <= 0)
return io->entries;
- io->count = 0;
+ io->count = io->entries;
io->urbs = kmalloc (io->entries * sizeof *io->urbs, mem_flags);
if (!io->urbs)
goto nomem;
if (usb_pipein (pipe))
urb_flags |= URB_SHORT_NOT_OK;
- for (i = 0; i < io->entries; i++, io->count = i) {
+ for (i = 0; i < io->entries; i++) {
unsigned len;
io->urbs [i] = usb_alloc_urb (0, mem_flags);
/* fail any uncompleted urbs */
default:
- spin_lock_irq (&io->lock);
- io->count -= entries - i;
- if (io->status == -EINPROGRESS)
- io->status = retval;
- if (io->count == 0)
- complete (&io->complete);
- spin_unlock_irq (&io->lock);
-
- io->urbs[i]->dev = NULL;
+ io->urbs [i]->dev = NULL;
io->urbs [i]->status = retval;
dev_dbg (&io->dev->dev, "%s, submit --> %d\n",
__FUNCTION__, retval);
usb_sg_cancel (io);
}
spin_lock_irq (&io->lock);
- if (retval && io->status == -ECONNRESET)
+ if (retval && (io->status == 0 || io->status == -ECONNRESET))
io->status = retval;
}
+ io->count -= entries - i;
+ if (io->count == 0)
+ complete (&io->complete);
spin_unlock_irq (&io->lock);
/* OK, yes, this could be packaged as non-blocking.
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
HZ * USB_CTRL_GET_TIMEOUT);
- if (!(result == 0 || result == -EPIPE))
- break;
+ if (result == 0 || result == -EPIPE)
+ continue;
+ if (result > 1 && ((u8 *)buf)[1] != type) {
+ result = -EPROTO;
+ continue;
+ }
+ break;
}
return result;
}
* the copy in usb-storage, for as long as we need two copies.
*/
- /* toggle was reset by the clear, then ep was reactivated */
+ /* toggle was reset by the clear */
usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
- usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
return 0;
}
* Deallocates hcd/hardware state for this endpoint ... and nukes all
* pending urbs.
*
- * If the HCD hasn't registered a disable() function, this marks the
- * endpoint as halted and sets its maxpacket size to 0 to prevent
- * further submissions.
+ * If the HCD hasn't registered a disable() function, this sets the
+ * endpoint's maxpacket size to 0 to prevent further submissions.
*/
void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
{
else {
unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
- if (usb_endpoint_out(epaddr)) {
- usb_endpoint_halt(dev, epnum, 1);
+ if (usb_endpoint_out(epaddr))
dev->epmaxpacketout[epnum] = 0;
- } else {
- usb_endpoint_halt(dev, epnum, 0);
+ else
dev->epmaxpacketin[epnum] = 0;
- }
}
}
usb_disable_endpoint(dev, i + USB_DIR_IN);
}
dev->toggle[0] = dev->toggle[1] = 0;
- dev->halted[0] = dev->halted[1] = 0;
/* getting rid of interfaces will disconnect
* any drivers bound to them (a key side effect)
* @dev: the device whose interface is being enabled
* @epd: pointer to the endpoint descriptor
*
- * Marks the endpoint as running, resets its toggle, and stores
- * its maxpacket value. For control endpoints, both the input
- * and output sides are handled.
+ * Resets the endpoint toggle and stores its maxpacket value.
+ * For control endpoints, both the input and output sides are handled.
*/
void usb_enable_endpoint(struct usb_device *dev,
struct usb_endpoint_descriptor *epd)
USB_ENDPOINT_XFER_CONTROL);
if (usb_endpoint_out(epaddr) || is_control) {
- usb_endpoint_running(dev, epnum, 1);
usb_settoggle(dev, epnum, 1, 0);
dev->epmaxpacketout[epnum] = maxsize;
}
if (!usb_endpoint_out(epaddr) || is_control) {
- usb_endpoint_running(dev, epnum, 0);
usb_settoggle(dev, epnum, 0, 0);
dev->epmaxpacketin[epnum] = maxsize;
}
int ret;
int manual = 0;
+ if (dev->state == USB_STATE_SUSPENDED)
+ return -EHOSTUNREACH;
+
iface = usb_ifnum_to_if(dev, interface);
if (!iface) {
dev_dbg(&dev->dev, "selecting invalid interface %d\n",
int i, retval;
struct usb_host_config *config;
+ if (dev->state == USB_STATE_SUSPENDED)
+ return -EHOSTUNREACH;
+
/* caller must own dev->serialize (config won't change)
* and the usb bus readlock (so driver bindings are stable);
* so calls during probe() are fine
}
dev->toggle[0] = dev->toggle[1] = 0;
- dev->halted[0] = dev->halted[1] = 0;
/* re-init hc/hcd interface/endpoint state */
for (i = 0; i < config->desc.bNumInterfaces; i++) {
struct usb_interface_cache *intfc =
altsetting_to_usb_interface_cache(intf->altsetting);
- kref_put(&intfc->ref);
+ kref_put(&intfc->ref, usb_release_interface_cache);
kfree(intf);
}
if (cp && configuration == 0)
dev_warn(&dev->dev, "config 0 descriptor??\n");
+ if (dev->state == USB_STATE_SUSPENDED)
+ return -EHOSTUNREACH;
+
/* Allocate memory for new interfaces before doing anything else,
* so that if we run out then nothing will have changed. */
n = nintf = 0;