aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-07-30 17:05:22 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-10-12 17:55:00 -0400
commitbdd016ba64d909329cb4bacacc8443901c00e112 (patch)
treecf20440d7d613377b5e2b4cec9764f2dc9e04928 /drivers
parent5b653c79c04c6b152b8dc7d18f8c8a7f77f4b235 (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.c5
-rw-r--r--drivers/usb/core/hub.c2
-rw-r--r--drivers/usb/core/message.c20
-rw-r--r--drivers/usb/core/usb.c2
-rw-r--r--drivers/usb/core/usb.h2
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 */
1099static void 1101void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
1100usb_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);
9extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); 9extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint);
10 10
11extern void usb_enable_endpoint(struct usb_device *dev,
12 struct usb_host_endpoint *ep);
11extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); 13extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr);
12extern void usb_disable_interface (struct usb_device *dev, 14extern void usb_disable_interface (struct usb_device *dev,
13 struct usb_interface *intf); 15 struct usb_interface *intf);