if (!urb)
return -ENOMEM;
- usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char*)cmd, data, len,
- usb_api_blocking_completion, 0);
+ usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
+ len, usb_api_blocking_completion, NULL);
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return -ENOMEM;
usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
- usb_api_blocking_completion, 0);
+ usb_api_blocking_completion, NULL);
return usb_start_wait_urb(urb,timeout,actual_length);
}
while (io->entries--)
usb_free_urb (io->urbs [io->entries]);
kfree (io->urbs);
- io->urbs = 0;
+ io->urbs = NULL;
}
if (io->dev->dev.dma_mask != 0)
usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
- io->dev = 0;
+ io->dev = NULL;
}
static void sg_complete (struct urb *urb, struct pt_regs *regs)
* 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]);
found = 1;
}
}
- urb->dev = 0;
+ urb->dev = NULL;
/* on the last completion, signal usb_sg_wait() */
io->bytes += urb->actual_length;
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);
goto nomem;
}
- io->urbs [i]->dev = 0;
+ io->urbs [i]->dev = NULL;
io->urbs [i]->pipe = pipe;
io->urbs [i]->interval = period;
io->urbs [i]->transfer_flags = urb_flags;
case -ENXIO: // hc didn't queue this one
case -EAGAIN:
case -ENOMEM:
- io->urbs [i]->dev = 0;
+ io->urbs[i]->dev = NULL;
retval = 0;
i--;
yield ();
/* 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 = 0;
+ 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.
*/
int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
{
- int i = 5;
+ int i;
int result;
memset(buf,0,size); // Make sure we parse really received data
- while (i--) {
+ for (i = 0; i < 3; ++i) {
/* retry on length 0 or stall; some devices are flakey */
- if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
- (type << 8) + index, 0, buf, size,
- HZ * USB_CTRL_GET_TIMEOUT)) > 0
- || result != -EPIPE)
- break;
-
- dev_dbg (&dev->dev, "RETRY descriptor, result %d\n", result);
- result = -ENOMSG;
+ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (type << 8) + index, 0, buf, size,
+ HZ * USB_CTRL_GET_TIMEOUT);
+ if (result == 0 || result == -EPIPE)
+ continue;
+ if (result > 1 && ((u8 *)buf)[1] != type) {
+ result = -EPROTO;
+ continue;
+ }
+ break;
}
return result;
}
* Returns the number of bytes received on success, or else the status code
* returned by the underlying usb_control_msg() call.
*/
-int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
+int usb_get_string(struct usb_device *dev, unsigned short langid,
+ unsigned char index, void *buf, int size)
{
- return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
- (USB_DT_STRING << 8) + index, langid, buf, size,
- HZ * USB_CTRL_GET_TIMEOUT);
+ int i;
+ int result;
+
+ for (i = 0; i < 3; ++i) {
+ /* retry on length 0 or stall; some devices are flakey */
+ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (USB_DT_STRING << 8) + index, langid, buf, size,
+ HZ * USB_CTRL_GET_TIMEOUT);
+ if (!(result == 0 || result == -EPIPE))
+ break;
+ }
+ return result;
+}
+
+static int usb_string_sub(struct usb_device *dev, unsigned int langid,
+ unsigned int index, unsigned char *buf)
+{
+ int rc;
+
+ /* Try to read the string descriptor by asking for the maximum
+ * possible number of bytes */
+ rc = usb_get_string(dev, langid, index, buf, 255);
+
+ /* If that failed try to read the descriptor length, then
+ * ask for just that many bytes */
+ if (rc < 0) {
+ rc = usb_get_string(dev, langid, index, buf, 2);
+ if (rc == 2)
+ rc = usb_get_string(dev, langid, index, buf, buf[0]);
+ }
+
+ if (rc >= 0) {
+ /* There might be extra junk at the end of the descriptor */
+ if (buf[0] < rc)
+ rc = buf[0];
+ if (rc < 2)
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+/**
+ * usb_string - returns ISO 8859-1 version of a string descriptor
+ * @dev: the device whose string descriptor is being retrieved
+ * @index: the number of the descriptor
+ * @buf: where to put the string
+ * @size: how big is "buf"?
+ * Context: !in_interrupt ()
+ *
+ * This converts the UTF-16LE encoded strings returned by devices, from
+ * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones
+ * that are more usable in most kernel contexts. Note that all characters
+ * in the chosen descriptor that can't be encoded using ISO-8859-1
+ * are converted to the question mark ("?") character, and this function
+ * chooses strings in the first language supported by the device.
+ *
+ * The ASCII (or, redundantly, "US-ASCII") character set is the seven-bit
+ * subset of ISO 8859-1. ISO-8859-1 is the eight-bit subset of Unicode,
+ * and is appropriate for use many uses of English and several other
+ * Western European languages. (But it doesn't include the "Euro" symbol.)
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Returns length of the string (>= 0) or usb_control_msg status (< 0).
+ */
+int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
+{
+ unsigned char *tbuf;
+ int err;
+ unsigned int u, idx;
+
+ if (size <= 0 || !buf || !index)
+ return -EINVAL;
+ buf[0] = 0;
+ tbuf = kmalloc(256, GFP_KERNEL);
+ if (!tbuf)
+ return -ENOMEM;
+
+ /* get langid for strings if it's not yet known */
+ if (!dev->have_langid) {
+ err = usb_string_sub(dev, 0, 0, tbuf);
+ if (err < 0) {
+ dev_err (&dev->dev,
+ "string descriptor 0 read error: %d\n",
+ err);
+ goto errout;
+ } else if (err < 4) {
+ dev_err (&dev->dev, "string descriptor 0 too short\n");
+ err = -EINVAL;
+ goto errout;
+ } else {
+ dev->have_langid = -1;
+ dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
+ /* always use the first langid listed */
+ dev_dbg (&dev->dev, "default language 0x%04x\n",
+ dev->string_langid);
+ }
+ }
+
+ err = usb_string_sub(dev, dev->string_langid, index, tbuf);
+ if (err < 0)
+ goto errout;
+
+ size--; /* leave room for trailing NULL char in output buffer */
+ for (idx = 0, u = 2; u < err; u += 2) {
+ if (idx >= size)
+ break;
+ if (tbuf[u+1]) /* high byte */
+ buf[idx++] = '?'; /* non ISO-8859-1 character */
+ else
+ buf[idx++] = tbuf[u];
+ }
+ buf[idx] = 0;
+ err = idx;
+
+ errout:
+ kfree(tbuf);
+ return err;
}
/**
* 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)
interface = dev->actconfig->interface[i];
dev_dbg (&dev->dev, "unregistering interface %s\n",
interface->dev.bus_id);
+ usb_remove_sysfs_intf_files(interface);
device_del (&interface->dev);
}
put_device (&dev->actconfig->interface[i]->dev);
dev->actconfig->interface[i] = NULL;
}
- dev->actconfig = 0;
+ dev->actconfig = NULL;
if (dev->state == USB_STATE_CONFIGURED)
- dev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(dev, USB_STATE_ADDRESS);
}
}
* @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
config->desc.bConfigurationValue, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
if (retval < 0) {
- dev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(dev, USB_STATE_ADDRESS);
return retval;
}
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;
dev->actconfig = cp;
if (!cp)
- dev->state = USB_STATE_ADDRESS;
+ usb_set_device_state(dev, USB_STATE_ADDRESS);
else {
- dev->state = USB_STATE_CONFIGURED;
+ usb_set_device_state(dev, USB_STATE_CONFIGURED);
/* Initialize the new interface structures and the
* hc/hcd/usbcore interface/endpoint state.
return ret;
}
-/**
- * usb_string - returns ISO 8859-1 version of a string descriptor
- * @dev: the device whose string descriptor is being retrieved
- * @index: the number of the descriptor
- * @buf: where to put the string
- * @size: how big is "buf"?
- * Context: !in_interrupt ()
- *
- * This converts the UTF-16LE encoded strings returned by devices, from
- * usb_get_string_descriptor(), to null-terminated ISO-8859-1 encoded ones
- * that are more usable in most kernel contexts. Note that all characters
- * in the chosen descriptor that can't be encoded using ISO-8859-1
- * are converted to the question mark ("?") character, and this function
- * chooses strings in the first language supported by the device.
- *
- * The ASCII (or, redundantly, "US-ASCII") character set is the seven-bit
- * subset of ISO 8859-1. ISO-8859-1 is the eight-bit subset of Unicode,
- * and is appropriate for use many uses of English and several other
- * Western European languages. (But it doesn't include the "Euro" symbol.)
- *
- * This call is synchronous, and may not be used in an interrupt context.
- *
- * Returns length of the string (>= 0) or usb_control_msg status (< 0).
- */
-int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
-{
- unsigned char *tbuf;
- int err, len;
- unsigned int u, idx;
-
- if (size <= 0 || !buf || !index)
- return -EINVAL;
- buf[0] = 0;
- tbuf = kmalloc(256, GFP_KERNEL);
- if (!tbuf)
- return -ENOMEM;
-
- /* get langid for strings if it's not yet known */
- if (!dev->have_langid) {
- err = usb_get_descriptor(dev, USB_DT_STRING, 0, tbuf, 4);
- if (err < 0) {
- dev_err (&dev->dev,
- "string descriptor 0 read error: %d\n",
- err);
- goto errout;
- } else if (err < 4 || tbuf[0] < 4) {
- dev_err (&dev->dev, "string descriptor 0 too short\n");
- err = -EINVAL;
- goto errout;
- } else {
- dev->have_langid = -1;
- dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
- /* always use the first langid listed */
- dev_dbg (&dev->dev, "default language 0x%04x\n",
- dev->string_langid);
- }
- }
-
- /*
- * ask for the length of the string
- */
-
- err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
- if (err == -EPIPE) {
- dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, 2);
- err = usb_get_string(dev, dev->string_langid, index, tbuf, 2);
- }
- if(err<2)
- goto errout;
- len=tbuf[0];
-
- err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
- if (err == -EPIPE) {
- dev_dbg(&dev->dev, "RETRY string %d read/%d\n", index, len);
- err = usb_get_string(dev, dev->string_langid, index, tbuf, len);
- }
- if (err < 0)
- goto errout;
-
- size--; /* leave room for trailing NULL char in output buffer */
- for (idx = 0, u = 2; u < err; u += 2) {
- if (idx >= size)
- break;
- if (tbuf[u+1]) /* high byte */
- buf[idx++] = '?'; /* non ISO-8859-1 character */
- else
- buf[idx++] = tbuf[u];
- }
- buf[idx] = 0;
- err = idx;
-
- errout:
- kfree(tbuf);
- return err;
-}
-
// synchronous request completion model
EXPORT_SYMBOL(usb_control_msg);
EXPORT_SYMBOL(usb_bulk_msg);