From 5b653c79c04c6b152b8dc7d18f8c8a7f77f4b235 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 30 Jul 2007 17:04:37 -0400 Subject: USB: add urb->ep This patch (as943) prepares the way for eliminating urb->pipe by introducing an endpoint pointer into struct urb. For now urb->ep is set by usb_submit_urb() from the pipe value; eventually drivers will set it themselves and we will remove urb->pipe completely. The patch also adds new inline routines to retrieve an endpoint descriptor's number and transfer type, essentially as replacements for usb_pipeendpoint and usb_pipetype. usb_submit_urb(), usb_hcd_submit_urb(), and usb_hcd_unlink_urb() are converted to use the new field and new routines. Other parts of usbcore will be converted in later patches. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 4f33a58fa9d1..105e3e9362d0 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -554,6 +554,29 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, /*-------------------------------------------------------------------------*/ +/** + * usb_endpoint_num - get the endpoint's number + * @epd: endpoint to be checked + * + * Returns @epd's number: 0 to 15. + */ +static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd) +{ + return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; +} + +/** + * usb_endpoint_type - get the endpoint's transfer type + * @epd: endpoint to be checked + * + * Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according + * to @epd's transfer type. + */ +static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd) +{ + return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; +} + /** * usb_endpoint_dir_in - check if the endpoint has IN direction * @epd: endpoint to be checked @@ -1037,6 +1060,8 @@ typedef void (*usb_complete_t)(struct urb *); * @urb_list: For use by current owner of the URB. * @anchor_list: membership in the list of an anchor * @anchor: to anchor URBs to a common mooring + * @ep: Points to the endpoint's data structure. Will eventually + * replace @pipe. * @pipe: Holds endpoint number, direction, type, and more. * Create these values with the eight macros available; * usb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is "ctrl" @@ -1212,6 +1237,7 @@ struct urb struct list_head anchor_list; /* the URB may be anchored by the driver */ struct usb_anchor *anchor; struct usb_device *dev; /* (in) pointer to associated device */ + struct usb_host_endpoint *ep; /* (internal) pointer to endpoint struct */ unsigned int pipe; /* (in) pipe information */ int status; /* (return) non-ISO status */ unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/ -- cgit v1.2.3 From bdd016ba64d909329cb4bacacc8443901c00e112 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 30 Jul 2007 17:05:22 -0400 Subject: USB: add ep->enable This patch (as944) adds an explicit "enabled" field to the usb_host_endpoint structure and uses it in place of the current mechanism. This is merely a time-space tradeoff; it makes checking whether URBs may be submitted to an endpoint simpler. The existing mechanism is efficient when converting urb->pipe to an endpoint pointer, but it's not so efficient when urb->ep is used instead. As a side effect, the procedure for enabling an endpoint is now a little more complicated. The ad-hoc inline code in usb.c and hub.c for enabling ep0 is now replaced with calls to usb_enable_endpoint, which is no longer static. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 105e3e9362d0..818a1b4f737a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -52,6 +52,7 @@ struct ep_device; * @ep_dev: ep_device for sysfs info * @extra: descriptors following this endpoint in the configuration * @extralen: how many bytes of "extra" are valid + * @enabled: URBs may be submitted to this endpoint * * USB requests are always queued to a given endpoint, identified by a * descriptor within an active interface in a given USB configuration. @@ -64,6 +65,7 @@ struct usb_host_endpoint { unsigned char *extra; /* Extra descriptors */ int extralen; + int enabled; }; /* host-side wrapper for one interface setting's parsed descriptors */ -- cgit v1.2.3 From fea3409112a93581db18da4c4332c8bf8d68af6b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 30 Jul 2007 17:06:16 -0400 Subject: USB: add direction bit to urb->transfer_flags This patch (as945) adds a bit to urb->transfer_flags for recording the direction of the URB. The bit is set/cleared automatically in usb_submit_urb() so drivers don't have to worry about it (although as a result, it isn't valid until the URB has been submitted). Inline routines are added for easily checking an URB's direction. They replace calls to usb_pipein in the DMA-mapping parts of hcd.c. For non-control endpoints, the direction is determined directly from the endpoint descriptor. However control endpoints are bi-directional; for them the direction is determined from the bRequestType byte and the wLength value in the setup packet. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 818a1b4f737a..9d08f5a5ba76 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1021,6 +1021,8 @@ extern int usb_disabled(void); /* * urb->transfer_flags: + * + * Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb(). */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ #define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame @@ -1033,6 +1035,10 @@ extern int usb_disabled(void); * needed */ #define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */ +#define URB_DIR_IN 0x0200 /* Transfer from device to host */ +#define URB_DIR_OUT 0 +#define URB_DIR_MASK URB_DIR_IN + struct usb_iso_packet_descriptor { unsigned int offset; unsigned int length; /* expected length */ @@ -1380,6 +1386,30 @@ extern void usb_unanchor_urb(struct urb *urb); extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, unsigned int timeout); +/** + * usb_urb_dir_in - check if an URB describes an IN transfer + * @urb: URB to be checked + * + * Returns 1 if @urb describes an IN transfer (device-to-host), + * otherwise 0. + */ +static inline int usb_urb_dir_in(struct urb *urb) +{ + return (urb->transfer_flags & URB_DIR_MASK) != URB_DIR_OUT; +} + +/** + * usb_urb_dir_out - check if an URB describes an OUT transfer + * @urb: URB to be checked + * + * Returns 1 if @urb describes an OUT transfer (host-to-device), + * otherwise 0. + */ +static inline int usb_urb_dir_out(struct urb *urb) +{ + return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT; +} + void *usb_buffer_alloc (struct usb_device *dev, size_t size, gfp_t mem_flags, dma_addr_t *dma); void usb_buffer_free (struct usb_device *dev, size_t size, -- cgit v1.2.3 From 5e60a16139c2a48b9876b0ff910671eee5fb32ec Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 30 Jul 2007 17:07:21 -0400 Subject: USB: avoid using urb->pipe in usbcore This patch (as946) eliminates many of the uses of urb->pipe in usbcore. Unfortunately there will have to be a significant API change, affecting all USB drivers, before we can remove it entirely. This patch contents itself with changing only the interface to usb_buffer_map_sg() and friends: The pipe argument is replaced with a direction flag. That can be done easily because those routines get used in only one place. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 9d08f5a5ba76..019ae963a9fe 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1422,13 +1422,13 @@ void usb_buffer_unmap (struct urb *urb); #endif struct scatterlist; -int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, +int usb_buffer_map_sg(const struct usb_device *dev, int is_in, struct scatterlist *sg, int nents); #if 0 -void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, +void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, struct scatterlist *sg, int n_hw_ents); #endif -void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, +void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, struct scatterlist *sg, int n_hw_ents); /*-------------------------------------------------------------------* -- cgit v1.2.3 From d617bc83ff48ebf0df253605529d8b3bef15773a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 2 Aug 2007 15:04:52 -0400 Subject: USB: cleanup for previous patches This patch (as951) cleans up a few loose ends from earlier patches. Redundant checks for non-NULL urb->dev are removed, as are checks of urb->dev->bus (which can never be NULL). Conversely, a check for non-NULL urb->ep is added to the unlink paths. A homegrown round-down-to-power-of-2 loop is simplified by using the ilog2 routine. The comparison in usb_urb_dir_in() is made more transparent. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 019ae963a9fe..a51f34e80572 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1395,7 +1395,7 @@ extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, */ static inline int usb_urb_dir_in(struct urb *urb) { - return (urb->transfer_flags & URB_DIR_MASK) != URB_DIR_OUT; + return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_IN; } /** -- cgit v1.2.3 From da04b7a42711c1d1d8d9fbc2565cdd83efcfee40 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Tue, 31 Jul 2007 20:33:57 -0700 Subject: usb: introduce usb_device authorization bits This just modifies 'struct usb_device' to contain the 'authorized' bit. It also adds a 'wusb' bit. This is needed because nonauthorized (and thus non-authenticated) wusb devices will fail certain kind of simple requests (such as string descriptors). By knowing the device is WUSB, we just avoid them. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index a51f34e80572..92d63c6b6fc6 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -346,6 +346,11 @@ struct usb_tt; * * Usbcore drivers should not set usbdev->state directly. Instead use * usb_set_device_state(). + * + * @authorized: (user space) policy determines if we authorize this + * device to be used or not. By default, wired USB + * devices are authorized. WUSB devices are not, until we + * authorize them from user space. FIXME -- complete doc */ struct usb_device { int devnum; /* Address on USB bus */ @@ -380,6 +385,8 @@ struct usb_device { unsigned discon_suspended:1; /* Disconnected while suspended */ unsigned have_langid:1; /* whether string_langid is valid */ + unsigned authorized:1; /* Policy has determined we can use it */ + unsigned wusb:1; /* Device is Wireless USB */ int string_langid; /* language ID for strings */ /* static strings from the device */ -- cgit v1.2.3 From eb23105462304fd35571fd0cab1de7aec79a9ec5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 21 Aug 2007 15:40:36 -0400 Subject: USB: add urb->unlinked field This patch (as970) adds a new urb->unlinked field, which is used to store the status of unlinked URBs since we can't use urb->status for that purpose any more. To help simplify the HCDs, usbcore will check urb->unlinked before calling the completion handler; if the value is set it will automatically override the status reported by the HCD. Signed-off-by: Alan Stern CC: David Brownell CC: Olav Kongas CC: Yoshihiro Shimoda CC: Tony Olech Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 92d63c6b6fc6..5c7b79088add 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1245,6 +1245,7 @@ struct urb void *hcpriv; /* private data for host controller */ atomic_t use_count; /* concurrent submissions counter */ u8 reject; /* submissions will fail */ + int unlinked; /* unlink error code */ /* public: documented fields in the urb that can be used by drivers */ struct list_head urb_list; /* list head for use by the urb's -- cgit v1.2.3 From 1431d2a44ccf68a547094976f363f94177ab00c6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 24 Aug 2007 15:42:39 -0400 Subject: USB: get rid of urb->lock Now that urb->status isn't used, urb->lock doesn't protect anything. This patch (as980) removes it and replaces it with a private mutex in the one remaining place it was still used: usb_kill_urb. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 5c7b79088add..5b14b4c81fd6 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1241,7 +1241,6 @@ struct urb { /* private: usb core and host controller only fields in the urb */ struct kref kref; /* reference count of the URB */ - spinlock_t lock; /* lock for the URB */ void *hcpriv; /* private data for host controller */ atomic_t use_count; /* concurrent submissions counter */ u8 reject; /* submissions will fail */ @@ -1299,7 +1298,6 @@ static inline void usb_fill_control_urb (struct urb *urb, usb_complete_t complete_fn, void *context) { - spin_lock_init(&urb->lock); urb->dev = dev; urb->pipe = pipe; urb->setup_packet = setup_packet; @@ -1330,7 +1328,6 @@ static inline void usb_fill_bulk_urb (struct urb *urb, usb_complete_t complete_fn, void *context) { - spin_lock_init(&urb->lock); urb->dev = dev; urb->pipe = pipe; urb->transfer_buffer = transfer_buffer; @@ -1366,7 +1363,6 @@ static inline void usb_fill_int_urb (struct urb *urb, void *context, int interval) { - spin_lock_init(&urb->lock); urb->dev = dev; urb->pipe = pipe; urb->transfer_buffer = transfer_buffer; -- cgit v1.2.3 From 6840d2555afd66290be7a39b400b5e66a840b82d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 10 Sep 2007 11:34:26 -0400 Subject: USB: flush outstanding URBs when suspending This patch (as989) makes usbcore flush all outstanding URBs for each device as the device is suspended. This will be true even when CONFIG_USB_SUSPEND is not enabled. In addition, an extra can_submit flag is added to the usb_device structure. That flag will be turned off whenever a suspend request has been received for the device, even if the device isn't actually suspended because CONFIG_USB_SUSPEND isn't set. It's no longer necessary to check for the device state being equal to USB_STATE_SUSPENDED during URB submission; that check can be replaced by a check of the can_submit flag. This also permits us to remove some questionable references to the deprecated power.power_state field. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 5b14b4c81fd6..e5b35e0dca23 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -383,6 +383,7 @@ struct usb_device { u8 portnum; /* Parent port number (origin 1) */ u8 level; /* Number of USB hub ancestors */ + unsigned can_submit:1; /* URBs may be submitted */ unsigned discon_suspended:1; /* Disconnected while suspended */ unsigned have_langid:1; /* whether string_langid is valid */ unsigned authorized:1; /* Policy has determined we can use it */ -- cgit v1.2.3 From 4d59d8a11383ebf0e0260ee481a4e766959fd7d9 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 3 Oct 2007 14:56:03 -0700 Subject: USB: Export URB statistics for powertop powertop currently tracks interrupts generated by uhci, ehci, and ohci, but it has no way of telling which USB device to blame USB bus activity on. This patch exports the number of URBs that are submitted for a given device. Cat the file 'urbnum' in /sys/bus/usb/devices/.../ Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index e5b35e0dca23..c10935fdc03a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -415,6 +415,7 @@ struct usb_device { int pm_usage_cnt; /* usage counter for autosuspend */ u32 quirks; /* quirks of the whole device */ + atomic_t urbnum; /* number of URBs submitted for the whole device */ #ifdef CONFIG_PM struct delayed_work autosuspend; /* for delayed autosuspends */ -- cgit v1.2.3 From 271f9e68f3450ac8d1ff3bda36581f1ec0d0cc1f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 10 Oct 2007 16:30:12 -0400 Subject: USB: skip autosuspended devices during system resume System suspends and hibernation are supposed to be as transparent as possible. By this reasoning, if a USB device is already autosuspended before the system sleep begins then it should remain autosuspended after the system wakes up. This patch (as1001) adds a skip_sys_resume flag to the usb_device structure and uses it to avoid waking up devices which were suspended when a system sleep began. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index c10935fdc03a..c5c8f169d3cf 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -430,6 +430,7 @@ struct usb_device { unsigned persist_enabled:1; /* USB_PERSIST enabled for this dev */ unsigned autosuspend_disabled:1; /* autosuspend and autoresume */ unsigned autoresume_disabled:1; /* disabled by the user */ + unsigned skip_sys_resume:1; /* skip the next system resume */ #endif }; #define to_usb_device(d) container_of(d, struct usb_device, dev) -- cgit v1.2.3