if (status == 0) {
if (timeout > 0) {
init_timer(&timer);
- timer.expires = jiffies + timeout;
+ timer.expires = jiffies + msecs_to_jiffies(timeout);
timer.data = (unsigned long)urb;
timer.function = timeout_kill;
/* grr. timeout _should_ include submit delays. */
status = urb->status;
/* note: HCDs return ETIMEDOUT for other reasons too */
if (status == -ECONNRESET) {
- dev_warn(&urb->dev->dev,
- "%s timed out on ep%d%s\n",
+ dev_dbg(&urb->dev->dev,
+ "%s timed out on ep%d%s len=%d/%d\n",
current->comm,
usb_pipeendpoint(urb->pipe),
- usb_pipein(urb->pipe) ? "in" : "out");
- status = -ETIMEDOUT;
+ usb_pipein(urb->pipe) ? "in" : "out",
+ urb->actual_length,
+ urb->transfer_buffer_length
+ );
+ if (urb->actual_length > 0)
+ status = 0;
+ else
+ status = -ETIMEDOUT;
}
if (timeout > 0)
del_timer_sync(&timer);
/*-------------------------------------------------------------------*/
// returns status (negative) or length (positive)
-int usb_internal_control_msg(struct usb_device *usb_dev, unsigned int pipe,
- struct usb_ctrlrequest *cmd, void *data, int len, int timeout)
+static int usb_internal_control_msg(struct usb_device *usb_dev,
+ unsigned int pipe,
+ struct usb_ctrlrequest *cmd,
+ void *data, int len, int timeout)
{
struct urb *urb;
int retv;
* @index: USB message index value
* @data: pointer to the data to send
* @size: length in bytes of the data to send
- * @timeout: time in jiffies to wait for the message to complete before
+ * @timeout: time in msecs to wait for the message to complete before
* timing out (if 0 the wait is forever)
* Context: !in_interrupt ()
*
* @data: pointer to the data to send
* @len: length in bytes of the data to send
* @actual_length: pointer to a location to put the actual length transferred in bytes
- * @timeout: time in jiffies to wait for the message to complete before
+ * @timeout: time in msecs to wait for the message to complete before
* timing out (if 0 the wait is forever)
* Context: !in_interrupt ()
*
usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
usb_api_blocking_completion, NULL);
- return usb_start_wait_urb(urb,timeout,actual_length);
+ return usb_start_wait_urb(urb, timeout, actual_length);
}
/*-------------------------------------------------------------------*/
kfree (io->urbs);
io->urbs = NULL;
}
- if (io->dev->dev.dma_mask != 0)
+ if (io->dev->dev.dma_mask != NULL)
usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
io->dev = NULL;
}
/* not all host controllers use DMA (like the mainstream pci ones);
* they can use PIO (sl811) or be software over another transport.
*/
- dma = (dev->dev.dma_mask != 0);
+ dma = (dev->dev.dma_mask != NULL);
if (dma)
io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
else
* (2) error, where io->status is a negative errno value. The number
* of io->bytes transferred before the error is usually less
* than requested, and can be nonzero.
- * (3) cancelation, a type of error with status -ECONNRESET that
+ * (3) cancellation, a type of error with status -ECONNRESET that
* is initiated by usb_sg_cancel().
*
* When this function returns, all memory allocated through usb_sg_init() or
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);
+ USB_CTRL_GET_TIMEOUT);
if (result == 0 || result == -EPIPE)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
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);
+ USB_CTRL_GET_TIMEOUT);
if (!(result == 0 || result == -EPIPE))
break;
}
return -ENOMEM;
ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);
- if (ret >= 0) {
- le16_to_cpus(&desc->bcdUSB);
- le16_to_cpus(&desc->idVendor);
- le16_to_cpus(&desc->idProduct);
- le16_to_cpus(&desc->bcdDevice);
+ if (ret >= 0)
memcpy(&dev->descriptor, desc, size);
- }
kfree(desc);
return ret;
}
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, status,
- sizeof(*status), HZ * USB_CTRL_GET_TIMEOUT);
+ sizeof(*status), USB_CTRL_GET_TIMEOUT);
*(u16 *)data = *status;
kfree(status);
result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
USB_ENDPOINT_HALT, endp, NULL, 0,
- HZ * USB_CTRL_SET_TIMEOUT);
+ USB_CTRL_SET_TIMEOUT);
/* don't un-halt or force to DATA0 except on success */
if (result < 0)
*/
void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr)
{
- if (dev && dev->bus && dev->bus->op && dev->bus->op->disable)
- dev->bus->op->disable(dev, epaddr);
- else {
- unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
+ unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
+ struct usb_host_endpoint *ep;
- if (usb_endpoint_out(epaddr))
- dev->epmaxpacketout[epnum] = 0;
- else
- dev->epmaxpacketin[epnum] = 0;
+ if (!dev)
+ return;
+
+ if (usb_endpoint_out(epaddr)) {
+ ep = dev->ep_out[epnum];
+ dev->ep_out[epnum] = NULL;
+ } else {
+ ep = dev->ep_in[epnum];
+ dev->ep_in[epnum] = NULL;
}
+ if (ep && dev->bus && dev->bus->op && dev->bus->op->disable)
+ dev->bus->op->disable(dev, ep);
}
/**
dev_dbg (&dev->dev, "unregistering interface %s\n",
interface->dev.bus_id);
usb_remove_sysfs_intf_files(interface);
+ kfree(interface->cur_altsetting->string);
+ interface->cur_altsetting->string = NULL;
device_del (&interface->dev);
}
/*
* usb_enable_endpoint - Enable an endpoint for USB communications
* @dev: the device whose interface is being enabled
- * @epd: pointer to the endpoint descriptor
+ * @ep: the endpoint
*
- * Resets the endpoint toggle and stores its maxpacket value.
+ * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers.
* For control endpoints, both the input and output sides are handled.
*/
-void usb_enable_endpoint(struct usb_device *dev,
- struct usb_endpoint_descriptor *epd)
+static void
+usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
{
- int maxsize = epd->wMaxPacketSize;
- unsigned int epaddr = epd->bEndpointAddress;
+ unsigned int epaddr = ep->desc.bEndpointAddress;
unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK;
- int is_control = ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_CONTROL);
+ int is_control;
+ is_control = ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_CONTROL);
if (usb_endpoint_out(epaddr) || is_control) {
usb_settoggle(dev, epnum, 1, 0);
- dev->epmaxpacketout[epnum] = maxsize;
+ dev->ep_out[epnum] = ep;
}
if (!usb_endpoint_out(epaddr) || is_control) {
usb_settoggle(dev, epnum, 0, 0);
- dev->epmaxpacketin[epnum] = maxsize;
+ dev->ep_in[epnum] = ep;
}
}
*
* Enables all the endpoints for the interface's current altsetting.
*/
-void usb_enable_interface(struct usb_device *dev,
- struct usb_interface *intf)
+static void usb_enable_interface(struct usb_device *dev,
+ struct usb_interface *intf)
{
struct usb_host_interface *alt = intf->cur_altsetting;
int i;
for (i = 0; i < alt->desc.bNumEndpoints; ++i)
- usb_enable_endpoint(dev, &alt->endpoint[i].desc);
+ usb_enable_endpoint(dev, &alt->endpoint[i]);
}
/**
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
- alternate, interface, NULL, 0, HZ * 5);
+ alternate, interface, NULL, 0, 5000);
/* 9.4.10 says devices don't need this and are free to STALL the
* request if the interface only has one alternate setting.
*
* Because this affects multiple interfaces, avoid using this with composite
* (multi-interface) devices. Instead, the driver for each interface may
- * use usb_set_interface() on the interfaces it claims. Resetting the whole
+ * use usb_set_interface() on the interfaces it claims. Be careful though;
+ * some devices don't support the SET_INTERFACE request, and others won't
+ * reset all the interface state (notably data toggles). Resetting the whole
* configuration would affect other drivers' interfaces.
*
* The caller must own the device lock.
retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0,
config->desc.bConfigurationValue, 0,
- NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
+ NULL, 0, USB_CTRL_SET_TIMEOUT);
if (retval < 0) {
usb_set_device_state(dev, USB_STATE_ADDRESS);
return retval;
* bus rwsem; usb device driver probe() methods cannot use this routine.
*
* Returns zero on success, or else the status code returned by the
- * underlying call that failed. On succesful completion, each interface
+ * underlying call that failed. On successful completion, each interface
* in the original device configuration has been destroyed, and each one
* in the new configuration has been probed by all relevant usb device
* drivers currently known to the kernel.
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
- NULL, 0, HZ * USB_CTRL_SET_TIMEOUT)) < 0)
+ NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0)
goto free_interfaces;
dev->actconfig = cp;
}
kfree(new_interfaces);
+ if ((cp->desc.iConfiguration) &&
+ (cp->string == NULL)) {
+ cp->string = kmalloc(256, GFP_KERNEL);
+ if (cp->string)
+ usb_string(dev, cp->desc.iConfiguration, cp->string, 256);
+ }
+
/* Now that all the interfaces are set up, register them
* to trigger binding of drivers to interfaces. probe()
* routines may install different altsettings and may
ret);
continue;
}
+ if ((intf->cur_altsetting->desc.iInterface) &&
+ (intf->cur_altsetting->string == NULL)) {
+ intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL);
+ if (intf->cur_altsetting->string)
+ usb_string(dev, intf->cur_altsetting->desc.iInterface,
+ intf->cur_altsetting->string, 256);
+ }
usb_create_sysfs_intf_files (intf);
}
}