diff options
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r-- | drivers/usb/core/usb.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0fee5c66fd6..c99938d5f78 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -223,6 +223,15 @@ static void ksuspend_usb_cleanup(void) | |||
223 | 223 | ||
224 | #endif /* CONFIG_PM */ | 224 | #endif /* CONFIG_PM */ |
225 | 225 | ||
226 | |||
227 | /* Returns 1 if @usb_bus is WUSB, 0 otherwise */ | ||
228 | static unsigned usb_bus_is_wusb(struct usb_bus *bus) | ||
229 | { | ||
230 | struct usb_hcd *hcd = container_of(bus, struct usb_hcd, self); | ||
231 | return hcd->wireless; | ||
232 | } | ||
233 | |||
234 | |||
226 | /** | 235 | /** |
227 | * usb_alloc_dev - usb device constructor (usbcore-internal) | 236 | * usb_alloc_dev - usb device constructor (usbcore-internal) |
228 | * @parent: hub to which device is connected; null to allocate a root hub | 237 | * @parent: hub to which device is connected; null to allocate a root hub |
@@ -239,6 +248,8 @@ struct usb_device * | |||
239 | usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | 248 | usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) |
240 | { | 249 | { |
241 | struct usb_device *dev; | 250 | struct usb_device *dev; |
251 | struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); | ||
252 | unsigned root_hub = 0; | ||
242 | 253 | ||
243 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 254 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
244 | if (!dev) | 255 | if (!dev) |
@@ -255,12 +266,14 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
255 | dev->dev.dma_mask = bus->controller->dma_mask; | 266 | dev->dev.dma_mask = bus->controller->dma_mask; |
256 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); | 267 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); |
257 | dev->state = USB_STATE_ATTACHED; | 268 | dev->state = USB_STATE_ATTACHED; |
269 | atomic_set(&dev->urbnum, 0); | ||
258 | 270 | ||
259 | INIT_LIST_HEAD(&dev->ep0.urb_list); | 271 | INIT_LIST_HEAD(&dev->ep0.urb_list); |
260 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; | 272 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; |
261 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; | 273 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; |
262 | /* ep0 maxpacket comes later, from device descriptor */ | 274 | /* ep0 maxpacket comes later, from device descriptor */ |
263 | dev->ep_in[0] = dev->ep_out[0] = &dev->ep0; | 275 | usb_enable_endpoint(dev, &dev->ep0); |
276 | dev->can_submit = 1; | ||
264 | 277 | ||
265 | /* Save readable and stable topology id, distinguishing devices | 278 | /* Save readable and stable topology id, distinguishing devices |
266 | * by location for diagnostics, tools, driver model, etc. The | 279 | * by location for diagnostics, tools, driver model, etc. The |
@@ -275,6 +288,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
275 | 288 | ||
276 | dev->dev.parent = bus->controller; | 289 | dev->dev.parent = bus->controller; |
277 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); | 290 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); |
291 | root_hub = 1; | ||
278 | } else { | 292 | } else { |
279 | /* match any labeling on the hubs; it's one-based */ | 293 | /* match any labeling on the hubs; it's one-based */ |
280 | if (parent->devpath[0] == '0') | 294 | if (parent->devpath[0] == '0') |
@@ -301,6 +315,12 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
301 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); | 315 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); |
302 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; | 316 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; |
303 | #endif | 317 | #endif |
318 | if (root_hub) /* Root hub always ok [and always wired] */ | ||
319 | dev->authorized = 1; | ||
320 | else { | ||
321 | dev->authorized = usb_hcd->authorized_default; | ||
322 | dev->wusb = usb_bus_is_wusb(bus)? 1 : 0; | ||
323 | } | ||
304 | return dev; | 324 | return dev; |
305 | } | 325 | } |
306 | 326 | ||
@@ -748,7 +768,7 @@ void usb_buffer_unmap(struct urb *urb) | |||
748 | /** | 768 | /** |
749 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint | 769 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint |
750 | * @dev: device to which the scatterlist will be mapped | 770 | * @dev: device to which the scatterlist will be mapped |
751 | * @pipe: endpoint defining the mapping direction | 771 | * @is_in: mapping transfer direction |
752 | * @sg: the scatterlist to map | 772 | * @sg: the scatterlist to map |
753 | * @nents: the number of entries in the scatterlist | 773 | * @nents: the number of entries in the scatterlist |
754 | * | 774 | * |
@@ -771,14 +791,13 @@ void usb_buffer_unmap(struct urb *urb) | |||
771 | * | 791 | * |
772 | * Reverse the effect of this call with usb_buffer_unmap_sg(). | 792 | * Reverse the effect of this call with usb_buffer_unmap_sg(). |
773 | */ | 793 | */ |
774 | int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | 794 | int usb_buffer_map_sg(const struct usb_device *dev, int is_in, |
775 | struct scatterlist *sg, int nents) | 795 | struct scatterlist *sg, int nents) |
776 | { | 796 | { |
777 | struct usb_bus *bus; | 797 | struct usb_bus *bus; |
778 | struct device *controller; | 798 | struct device *controller; |
779 | 799 | ||
780 | if (!dev | 800 | if (!dev |
781 | || usb_pipecontrol(pipe) | ||
782 | || !(bus = dev->bus) | 801 | || !(bus = dev->bus) |
783 | || !(controller = bus->controller) | 802 | || !(controller = bus->controller) |
784 | || !controller->dma_mask) | 803 | || !controller->dma_mask) |
@@ -786,7 +805,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
786 | 805 | ||
787 | // FIXME generic api broken like pci, can't report errors | 806 | // FIXME generic api broken like pci, can't report errors |
788 | return dma_map_sg(controller, sg, nents, | 807 | return dma_map_sg(controller, sg, nents, |
789 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 808 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
790 | } | 809 | } |
791 | 810 | ||
792 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 811 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
@@ -799,14 +818,14 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
799 | /** | 818 | /** |
800 | * usb_buffer_dmasync_sg - synchronize DMA and CPU view of scatterlist buffer(s) | 819 | * usb_buffer_dmasync_sg - synchronize DMA and CPU view of scatterlist buffer(s) |
801 | * @dev: device to which the scatterlist will be mapped | 820 | * @dev: device to which the scatterlist will be mapped |
802 | * @pipe: endpoint defining the mapping direction | 821 | * @is_in: mapping transfer direction |
803 | * @sg: the scatterlist to synchronize | 822 | * @sg: the scatterlist to synchronize |
804 | * @n_hw_ents: the positive return value from usb_buffer_map_sg | 823 | * @n_hw_ents: the positive return value from usb_buffer_map_sg |
805 | * | 824 | * |
806 | * Use this when you are re-using a scatterlist's data buffers for | 825 | * Use this when you are re-using a scatterlist's data buffers for |
807 | * another USB request. | 826 | * another USB request. |
808 | */ | 827 | */ |
809 | void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | 828 | void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, |
810 | struct scatterlist *sg, int n_hw_ents) | 829 | struct scatterlist *sg, int n_hw_ents) |
811 | { | 830 | { |
812 | struct usb_bus *bus; | 831 | struct usb_bus *bus; |
@@ -819,20 +838,20 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | |||
819 | return; | 838 | return; |
820 | 839 | ||
821 | dma_sync_sg(controller, sg, n_hw_ents, | 840 | dma_sync_sg(controller, sg, n_hw_ents, |
822 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 841 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
823 | } | 842 | } |
824 | #endif | 843 | #endif |
825 | 844 | ||
826 | /** | 845 | /** |
827 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist | 846 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist |
828 | * @dev: device to which the scatterlist will be mapped | 847 | * @dev: device to which the scatterlist will be mapped |
829 | * @pipe: endpoint defining the mapping direction | 848 | * @is_in: mapping transfer direction |
830 | * @sg: the scatterlist to unmap | 849 | * @sg: the scatterlist to unmap |
831 | * @n_hw_ents: the positive return value from usb_buffer_map_sg | 850 | * @n_hw_ents: the positive return value from usb_buffer_map_sg |
832 | * | 851 | * |
833 | * Reverses the effect of usb_buffer_map_sg(). | 852 | * Reverses the effect of usb_buffer_map_sg(). |
834 | */ | 853 | */ |
835 | void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | 854 | void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, |
836 | struct scatterlist *sg, int n_hw_ents) | 855 | struct scatterlist *sg, int n_hw_ents) |
837 | { | 856 | { |
838 | struct usb_bus *bus; | 857 | struct usb_bus *bus; |
@@ -845,7 +864,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | |||
845 | return; | 864 | return; |
846 | 865 | ||
847 | dma_unmap_sg(controller, sg, n_hw_ents, | 866 | dma_unmap_sg(controller, sg, n_hw_ents, |
848 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 867 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
849 | } | 868 | } |
850 | 869 | ||
851 | /* format to disable USB on kernel command line is: nousb */ | 870 | /* format to disable USB on kernel command line is: nousb */ |