diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-07-30 17:05:22 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:00 -0400 |
commit | bdd016ba64d909329cb4bacacc8443901c00e112 (patch) | |
tree | cf20440d7d613377b5e2b4cec9764f2dc9e04928 /drivers | |
parent | 5b653c79c04c6b152b8dc7d18f8c8a7f77f4b235 (diff) |
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 <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/hcd.c | 5 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 20 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 2 |
5 files changed, 15 insertions, 16 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index fb82c500caf4..cc5b1d3c3680 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -943,7 +943,6 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
943 | { | 943 | { |
944 | int status; | 944 | int status; |
945 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); | 945 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); |
946 | struct usb_host_endpoint *ep; | ||
947 | unsigned long flags; | 946 | unsigned long flags; |
948 | 947 | ||
949 | if (!hcd) | 948 | if (!hcd) |
@@ -960,9 +959,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
960 | // FIXME: verify that quiescing hc works right (RH cleans up) | 959 | // FIXME: verify that quiescing hc works right (RH cleans up) |
961 | 960 | ||
962 | spin_lock_irqsave(&hcd_urb_list_lock, flags); | 961 | spin_lock_irqsave(&hcd_urb_list_lock, flags); |
963 | ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) | 962 | if (unlikely(!urb->ep->enabled)) |
964 | [usb_pipeendpoint(urb->pipe)]; | ||
965 | if (unlikely(ep != urb->ep)) | ||
966 | status = -ENOENT; | 963 | status = -ENOENT; |
967 | else if (unlikely (urb->reject)) | 964 | else if (unlikely (urb->reject)) |
968 | status = -EPERM; | 965 | status = -EPERM; |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index f7b337feb3ea..c8a01f66df70 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1999,7 +1999,7 @@ static void ep0_reinit(struct usb_device *udev) | |||
1999 | { | 1999 | { |
2000 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); | 2000 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); |
2001 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); | 2001 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); |
2002 | udev->ep_in[0] = udev->ep_out[0] = &udev->ep0; | 2002 | usb_enable_endpoint(udev, &udev->ep0); |
2003 | } | 2003 | } |
2004 | 2004 | ||
2005 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) | 2005 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d8f7b089a8f0..0d618647758e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1013,8 +1013,10 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | |||
1013 | ep = dev->ep_in[epnum]; | 1013 | ep = dev->ep_in[epnum]; |
1014 | dev->ep_in[epnum] = NULL; | 1014 | dev->ep_in[epnum] = NULL; |
1015 | } | 1015 | } |
1016 | if (ep && dev->bus) | 1016 | if (ep) { |
1017 | ep->enabled = 0; | ||
1017 | usb_hcd_endpoint_disable(dev, ep); | 1018 | usb_hcd_endpoint_disable(dev, ep); |
1019 | } | ||
1018 | } | 1020 | } |
1019 | 1021 | ||
1020 | /** | 1022 | /** |
@@ -1096,23 +1098,21 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1096 | * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. | 1098 | * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. |
1097 | * For control endpoints, both the input and output sides are handled. | 1099 | * For control endpoints, both the input and output sides are handled. |
1098 | */ | 1100 | */ |
1099 | static void | 1101 | void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) |
1100 | usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) | ||
1101 | { | 1102 | { |
1102 | unsigned int epaddr = ep->desc.bEndpointAddress; | 1103 | int epnum = usb_endpoint_num(&ep->desc); |
1103 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; | 1104 | int is_out = usb_endpoint_dir_out(&ep->desc); |
1104 | int is_control; | 1105 | int is_control = usb_endpoint_xfer_control(&ep->desc); |
1105 | 1106 | ||
1106 | is_control = ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1107 | if (is_out || is_control) { |
1107 | == USB_ENDPOINT_XFER_CONTROL); | ||
1108 | if (usb_endpoint_out(epaddr) || is_control) { | ||
1109 | usb_settoggle(dev, epnum, 1, 0); | 1108 | usb_settoggle(dev, epnum, 1, 0); |
1110 | dev->ep_out[epnum] = ep; | 1109 | dev->ep_out[epnum] = ep; |
1111 | } | 1110 | } |
1112 | if (!usb_endpoint_out(epaddr) || is_control) { | 1111 | if (!is_out || is_control) { |
1113 | usb_settoggle(dev, epnum, 0, 0); | 1112 | usb_settoggle(dev, epnum, 0, 0); |
1114 | dev->ep_in[epnum] = ep; | 1113 | dev->ep_in[epnum] = ep; |
1115 | } | 1114 | } |
1115 | ep->enabled = 1; | ||
1116 | } | 1116 | } |
1117 | 1117 | ||
1118 | /* | 1118 | /* |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0fee5c66fd64..d3c68d8eafb2 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -260,7 +260,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
260 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; | 260 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; |
261 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; | 261 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; |
262 | /* ep0 maxpacket comes later, from device descriptor */ | 262 | /* ep0 maxpacket comes later, from device descriptor */ |
263 | dev->ep_in[0] = dev->ep_out[0] = &dev->ep0; | 263 | usb_enable_endpoint(dev, &dev->ep0); |
264 | 264 | ||
265 | /* Save readable and stable topology id, distinguishing devices | 265 | /* Save readable and stable topology id, distinguishing devices |
266 | * by location for diagnostics, tools, driver model, etc. The | 266 | * by location for diagnostics, tools, driver model, etc. The |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index ad5fa0338f49..cde6e52b84fe 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -8,6 +8,8 @@ extern int usb_create_ep_files(struct device *parent, struct usb_host_endpoint * | |||
8 | struct usb_device *udev); | 8 | struct usb_device *udev); |
9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); | 9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); |
10 | 10 | ||
11 | extern void usb_enable_endpoint(struct usb_device *dev, | ||
12 | struct usb_host_endpoint *ep); | ||
11 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); | 13 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); |
12 | extern void usb_disable_interface (struct usb_device *dev, | 14 | extern void usb_disable_interface (struct usb_device *dev, |
13 | struct usb_interface *intf); | 15 | struct usb_interface *intf); |