diff options
author | Tatyana Brokhman <tlinder@codeaurora.org> | 2011-06-29 09:41:51 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-01 17:27:05 -0400 |
commit | cdfcbd2c4a9e866c19bf8fe2b4e011a12441c32a (patch) | |
tree | c6a5de9847676fb6f55a6925ac92b0690a134055 /drivers/usb/gadget | |
parent | bdb64d727216b49a18c2b8337658adc6b2db82ea (diff) |
usb: gadget: dummy_hcd: use the shared_hcd infrastructure
This patch is a preparation for adding SuperSpeed
support to dummy hcd.
It takes the master side fields out of the struct
dummy to a separate structure. The init process
was also modified to resemble the way it is
done by xHCI.
Signed-off-by: Tatyana Brokhman <tlinder@codeaurora.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 507 |
1 files changed, 270 insertions, 237 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index cbcb4c7fd26c..fcbff1cd180c 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -152,6 +152,22 @@ enum dummy_rh_state { | |||
152 | DUMMY_RH_RUNNING | 152 | DUMMY_RH_RUNNING |
153 | }; | 153 | }; |
154 | 154 | ||
155 | struct dummy_hcd { | ||
156 | struct dummy *dum; | ||
157 | enum dummy_rh_state rh_state; | ||
158 | struct timer_list timer; | ||
159 | u32 port_status; | ||
160 | u32 old_status; | ||
161 | unsigned long re_timeout; | ||
162 | |||
163 | struct usb_device *udev; | ||
164 | struct list_head urbp_list; | ||
165 | |||
166 | unsigned active:1; | ||
167 | unsigned old_active:1; | ||
168 | unsigned resuming:1; | ||
169 | }; | ||
170 | |||
155 | struct dummy { | 171 | struct dummy { |
156 | spinlock_t lock; | 172 | spinlock_t lock; |
157 | 173 | ||
@@ -167,36 +183,26 @@ struct dummy { | |||
167 | u16 devstatus; | 183 | u16 devstatus; |
168 | unsigned udc_suspended:1; | 184 | unsigned udc_suspended:1; |
169 | unsigned pullup:1; | 185 | unsigned pullup:1; |
170 | unsigned active:1; | ||
171 | unsigned old_active:1; | ||
172 | 186 | ||
173 | /* | 187 | /* |
174 | * MASTER/HOST side support | 188 | * MASTER/HOST side support |
175 | */ | 189 | */ |
176 | enum dummy_rh_state rh_state; | 190 | struct dummy_hcd *hs_hcd; |
177 | struct timer_list timer; | ||
178 | u32 port_status; | ||
179 | u32 old_status; | ||
180 | unsigned resuming:1; | ||
181 | unsigned long re_timeout; | ||
182 | |||
183 | struct usb_device *udev; | ||
184 | struct list_head urbp_list; | ||
185 | }; | 191 | }; |
186 | 192 | ||
187 | static inline struct dummy *hcd_to_dummy (struct usb_hcd *hcd) | 193 | static inline struct dummy_hcd *hcd_to_dummy_hcd(struct usb_hcd *hcd) |
188 | { | 194 | { |
189 | return (struct dummy *) (hcd->hcd_priv); | 195 | return (struct dummy_hcd *) (hcd->hcd_priv); |
190 | } | 196 | } |
191 | 197 | ||
192 | static inline struct usb_hcd *dummy_to_hcd (struct dummy *dum) | 198 | static inline struct usb_hcd *dummy_hcd_to_hcd(struct dummy_hcd *dum) |
193 | { | 199 | { |
194 | return container_of((void *) dum, struct usb_hcd, hcd_priv); | 200 | return container_of((void *) dum, struct usb_hcd, hcd_priv); |
195 | } | 201 | } |
196 | 202 | ||
197 | static inline struct device *dummy_dev (struct dummy *dum) | 203 | static inline struct device *dummy_dev(struct dummy_hcd *dum) |
198 | { | 204 | { |
199 | return dummy_to_hcd(dum)->self.controller; | 205 | return dummy_hcd_to_hcd(dum)->self.controller; |
200 | } | 206 | } |
201 | 207 | ||
202 | static inline struct device *udc_dev (struct dummy *dum) | 208 | static inline struct device *udc_dev (struct dummy *dum) |
@@ -209,9 +215,10 @@ static inline struct dummy *ep_to_dummy (struct dummy_ep *ep) | |||
209 | return container_of (ep->gadget, struct dummy, gadget); | 215 | return container_of (ep->gadget, struct dummy, gadget); |
210 | } | 216 | } |
211 | 217 | ||
212 | static inline struct dummy *gadget_to_dummy (struct usb_gadget *gadget) | 218 | static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) |
213 | { | 219 | { |
214 | return container_of (gadget, struct dummy, gadget); | 220 | struct dummy *dum = container_of(gadget, struct dummy, gadget); |
221 | return dum->hs_hcd; | ||
215 | } | 222 | } |
216 | 223 | ||
217 | static inline struct dummy *gadget_dev_to_dummy (struct device *dev) | 224 | static inline struct dummy *gadget_dev_to_dummy (struct device *dev) |
@@ -219,7 +226,7 @@ static inline struct dummy *gadget_dev_to_dummy (struct device *dev) | |||
219 | return container_of (dev, struct dummy, gadget.dev); | 226 | return container_of (dev, struct dummy, gadget.dev); |
220 | } | 227 | } |
221 | 228 | ||
222 | static struct dummy *the_controller; | 229 | static struct dummy the_controller; |
223 | 230 | ||
224 | /*-------------------------------------------------------------------------*/ | 231 | /*-------------------------------------------------------------------------*/ |
225 | 232 | ||
@@ -260,60 +267,64 @@ stop_activity (struct dummy *dum) | |||
260 | } | 267 | } |
261 | 268 | ||
262 | /* caller must hold lock */ | 269 | /* caller must hold lock */ |
263 | static void | 270 | static void set_link_state(struct dummy_hcd *dum_hcd) |
264 | set_link_state (struct dummy *dum) | ||
265 | { | 271 | { |
266 | dum->active = 0; | 272 | struct dummy *dum = dum_hcd->dum; |
267 | if ((dum->port_status & USB_PORT_STAT_POWER) == 0) | 273 | |
268 | dum->port_status = 0; | 274 | dum_hcd->active = 0; |
275 | if ((dum_hcd->port_status & USB_PORT_STAT_POWER) == 0) | ||
276 | dum_hcd->port_status = 0; | ||
269 | 277 | ||
270 | /* UDC suspend must cause a disconnect */ | 278 | /* UDC suspend must cause a disconnect */ |
271 | else if (!dum->pullup || dum->udc_suspended) { | 279 | else if (!dum->pullup || dum->udc_suspended) { |
272 | dum->port_status &= ~(USB_PORT_STAT_CONNECTION | | 280 | dum_hcd->port_status &= ~(USB_PORT_STAT_CONNECTION | |
273 | USB_PORT_STAT_ENABLE | | 281 | USB_PORT_STAT_ENABLE | |
274 | USB_PORT_STAT_LOW_SPEED | | 282 | USB_PORT_STAT_LOW_SPEED | |
275 | USB_PORT_STAT_HIGH_SPEED | | 283 | USB_PORT_STAT_HIGH_SPEED | |
276 | USB_PORT_STAT_SUSPEND); | 284 | USB_PORT_STAT_SUSPEND); |
277 | if ((dum->old_status & USB_PORT_STAT_CONNECTION) != 0) | 285 | if ((dum_hcd->old_status & USB_PORT_STAT_CONNECTION) != 0) |
278 | dum->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); | 286 | dum_hcd->port_status |= |
287 | (USB_PORT_STAT_C_CONNECTION << 16); | ||
279 | } else { | 288 | } else { |
280 | dum->port_status |= USB_PORT_STAT_CONNECTION; | 289 | dum_hcd->port_status |= USB_PORT_STAT_CONNECTION; |
281 | if ((dum->old_status & USB_PORT_STAT_CONNECTION) == 0) | 290 | if ((dum_hcd->old_status & USB_PORT_STAT_CONNECTION) == 0) |
282 | dum->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); | 291 | dum_hcd->port_status |= |
283 | if ((dum->port_status & USB_PORT_STAT_ENABLE) == 0) | 292 | (USB_PORT_STAT_C_CONNECTION << 16); |
284 | dum->port_status &= ~USB_PORT_STAT_SUSPEND; | 293 | if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0) |
285 | else if ((dum->port_status & USB_PORT_STAT_SUSPEND) == 0 && | 294 | dum_hcd->port_status &= ~USB_PORT_STAT_SUSPEND; |
286 | dum->rh_state != DUMMY_RH_SUSPENDED) | 295 | else if ((dum_hcd->port_status & USB_PORT_STAT_SUSPEND) == 0 && |
287 | dum->active = 1; | 296 | dum_hcd->rh_state != DUMMY_RH_SUSPENDED) |
297 | dum_hcd->active = 1; | ||
288 | } | 298 | } |
289 | 299 | ||
290 | if ((dum->port_status & USB_PORT_STAT_ENABLE) == 0 || dum->active) | 300 | if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || |
291 | dum->resuming = 0; | 301 | dum_hcd->active) |
302 | dum_hcd->resuming = 0; | ||
292 | 303 | ||
293 | if ((dum->port_status & USB_PORT_STAT_CONNECTION) == 0 || | 304 | if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || |
294 | (dum->port_status & USB_PORT_STAT_RESET) != 0) { | 305 | (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { |
295 | if ((dum->old_status & USB_PORT_STAT_CONNECTION) != 0 && | 306 | if ((dum_hcd->old_status & USB_PORT_STAT_CONNECTION) != 0 && |
296 | (dum->old_status & USB_PORT_STAT_RESET) == 0 && | 307 | (dum_hcd->old_status & USB_PORT_STAT_RESET) == 0 && |
297 | dum->driver) { | 308 | dum->driver) { |
298 | stop_activity (dum); | 309 | stop_activity (dum); |
299 | spin_unlock (&dum->lock); | 310 | spin_unlock (&dum->lock); |
300 | dum->driver->disconnect (&dum->gadget); | 311 | dum->driver->disconnect (&dum->gadget); |
301 | spin_lock (&dum->lock); | 312 | spin_lock (&dum->lock); |
302 | } | 313 | } |
303 | } else if (dum->active != dum->old_active) { | 314 | } else if (dum_hcd->active != dum_hcd->old_active) { |
304 | if (dum->old_active && dum->driver->suspend) { | 315 | if (dum_hcd->old_active && dum->driver->suspend) { |
305 | spin_unlock (&dum->lock); | 316 | spin_unlock (&dum->lock); |
306 | dum->driver->suspend (&dum->gadget); | 317 | dum->driver->suspend (&dum->gadget); |
307 | spin_lock (&dum->lock); | 318 | spin_lock (&dum->lock); |
308 | } else if (!dum->old_active && dum->driver->resume) { | 319 | } else if (!dum_hcd->old_active && dum->driver->resume) { |
309 | spin_unlock (&dum->lock); | 320 | spin_unlock (&dum->lock); |
310 | dum->driver->resume (&dum->gadget); | 321 | dum->driver->resume (&dum->gadget); |
311 | spin_lock (&dum->lock); | 322 | spin_lock (&dum->lock); |
312 | } | 323 | } |
313 | } | 324 | } |
314 | 325 | ||
315 | dum->old_status = dum->port_status; | 326 | dum_hcd->old_status = dum_hcd->port_status; |
316 | dum->old_active = dum->active; | 327 | dum_hcd->old_active = dum_hcd->active; |
317 | } | 328 | } |
318 | 329 | ||
319 | /*-------------------------------------------------------------------------*/ | 330 | /*-------------------------------------------------------------------------*/ |
@@ -332,6 +343,7 @@ static int | |||
332 | dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | 343 | dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) |
333 | { | 344 | { |
334 | struct dummy *dum; | 345 | struct dummy *dum; |
346 | struct dummy_hcd *dum_hcd; | ||
335 | struct dummy_ep *ep; | 347 | struct dummy_ep *ep; |
336 | unsigned max; | 348 | unsigned max; |
337 | int retval; | 349 | int retval; |
@@ -341,9 +353,17 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
341 | || desc->bDescriptorType != USB_DT_ENDPOINT) | 353 | || desc->bDescriptorType != USB_DT_ENDPOINT) |
342 | return -EINVAL; | 354 | return -EINVAL; |
343 | dum = ep_to_dummy (ep); | 355 | dum = ep_to_dummy (ep); |
344 | if (!dum->driver || !is_enabled (dum)) | 356 | if (!dum->driver) |
357 | return -ESHUTDOWN; | ||
358 | dum_hcd = dum->hs_hcd; | ||
359 | if (!is_enabled(dum_hcd)) | ||
345 | return -ESHUTDOWN; | 360 | return -ESHUTDOWN; |
346 | max = le16_to_cpu(desc->wMaxPacketSize) & 0x3ff; | 361 | |
362 | /* | ||
363 | * For HS/FS devices only bits 0..10 of the wMaxPacketSize represent the | ||
364 | * maximum packet size. | ||
365 | */ | ||
366 | max = le16_to_cpu(desc->wMaxPacketSize) & 0x7ff; | ||
347 | 367 | ||
348 | /* drivers must not request bad settings, since lower levels | 368 | /* drivers must not request bad settings, since lower levels |
349 | * (hardware or its drivers) may not check. some endpoints | 369 | * (hardware or its drivers) may not check. some endpoints |
@@ -515,6 +535,7 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, | |||
515 | struct dummy_ep *ep; | 535 | struct dummy_ep *ep; |
516 | struct dummy_request *req; | 536 | struct dummy_request *req; |
517 | struct dummy *dum; | 537 | struct dummy *dum; |
538 | struct dummy_hcd *dum_hcd; | ||
518 | unsigned long flags; | 539 | unsigned long flags; |
519 | 540 | ||
520 | req = usb_request_to_dummy_request (_req); | 541 | req = usb_request_to_dummy_request (_req); |
@@ -526,7 +547,8 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, | |||
526 | return -EINVAL; | 547 | return -EINVAL; |
527 | 548 | ||
528 | dum = ep_to_dummy (ep); | 549 | dum = ep_to_dummy (ep); |
529 | if (!dum->driver || !is_enabled (dum)) | 550 | dum_hcd = dum->hs_hcd; |
551 | if (!dum->driver || !is_enabled(dum_hcd)) | ||
530 | return -ESHUTDOWN; | 552 | return -ESHUTDOWN; |
531 | 553 | ||
532 | #if 0 | 554 | #if 0 |
@@ -670,24 +692,24 @@ static int dummy_g_get_frame (struct usb_gadget *_gadget) | |||
670 | 692 | ||
671 | static int dummy_wakeup (struct usb_gadget *_gadget) | 693 | static int dummy_wakeup (struct usb_gadget *_gadget) |
672 | { | 694 | { |
673 | struct dummy *dum; | 695 | struct dummy_hcd *dum_hcd; |
674 | 696 | ||
675 | dum = gadget_to_dummy (_gadget); | 697 | dum_hcd = gadget_to_dummy_hcd(_gadget); |
676 | if (!(dum->devstatus & ( (1 << USB_DEVICE_B_HNP_ENABLE) | 698 | if (!(dum_hcd->dum->devstatus & ((1 << USB_DEVICE_B_HNP_ENABLE) |
677 | | (1 << USB_DEVICE_REMOTE_WAKEUP)))) | 699 | | (1 << USB_DEVICE_REMOTE_WAKEUP)))) |
678 | return -EINVAL; | 700 | return -EINVAL; |
679 | if ((dum->port_status & USB_PORT_STAT_CONNECTION) == 0) | 701 | if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0) |
680 | return -ENOLINK; | 702 | return -ENOLINK; |
681 | if ((dum->port_status & USB_PORT_STAT_SUSPEND) == 0 && | 703 | if ((dum_hcd->port_status & USB_PORT_STAT_SUSPEND) == 0 && |
682 | dum->rh_state != DUMMY_RH_SUSPENDED) | 704 | dum_hcd->rh_state != DUMMY_RH_SUSPENDED) |
683 | return -EIO; | 705 | return -EIO; |
684 | 706 | ||
685 | /* FIXME: What if the root hub is suspended but the port isn't? */ | 707 | /* FIXME: What if the root hub is suspended but the port isn't? */ |
686 | 708 | ||
687 | /* hub notices our request, issues downstream resume, etc */ | 709 | /* hub notices our request, issues downstream resume, etc */ |
688 | dum->resuming = 1; | 710 | dum_hcd->resuming = 1; |
689 | dum->re_timeout = jiffies + msecs_to_jiffies(20); | 711 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(20); |
690 | mod_timer (&dummy_to_hcd (dum)->rh_timer, dum->re_timeout); | 712 | mod_timer(&dummy_hcd_to_hcd(dum_hcd)->rh_timer, dum_hcd->re_timeout); |
691 | return 0; | 713 | return 0; |
692 | } | 714 | } |
693 | 715 | ||
@@ -695,7 +717,7 @@ static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) | |||
695 | { | 717 | { |
696 | struct dummy *dum; | 718 | struct dummy *dum; |
697 | 719 | ||
698 | dum = gadget_to_dummy (_gadget); | 720 | dum = (gadget_to_dummy_hcd(_gadget))->dum; |
699 | if (value) | 721 | if (value) |
700 | dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); | 722 | dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); |
701 | else | 723 | else |
@@ -708,13 +730,12 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) | |||
708 | struct dummy *dum; | 730 | struct dummy *dum; |
709 | unsigned long flags; | 731 | unsigned long flags; |
710 | 732 | ||
711 | dum = gadget_to_dummy (_gadget); | 733 | dum = gadget_to_dummy_hcd(_gadget)->dum; |
712 | spin_lock_irqsave (&dum->lock, flags); | 734 | spin_lock_irqsave (&dum->lock, flags); |
713 | dum->pullup = (value != 0); | 735 | dum->pullup = (value != 0); |
714 | set_link_state (dum); | 736 | set_link_state(dum->hs_hcd); |
715 | spin_unlock_irqrestore (&dum->lock, flags); | 737 | spin_unlock_irqrestore (&dum->lock, flags); |
716 | 738 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum->hs_hcd)); | |
717 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | ||
718 | return 0; | 739 | return 0; |
719 | } | 740 | } |
720 | 741 | ||
@@ -764,7 +785,7 @@ static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); | |||
764 | static int dummy_udc_start(struct usb_gadget_driver *driver, | 785 | static int dummy_udc_start(struct usb_gadget_driver *driver, |
765 | int (*bind)(struct usb_gadget *)) | 786 | int (*bind)(struct usb_gadget *)) |
766 | { | 787 | { |
767 | struct dummy *dum = the_controller; | 788 | struct dummy *dum = &the_controller; |
768 | int retval, i; | 789 | int retval, i; |
769 | 790 | ||
770 | if (!dum) | 791 | if (!dum) |
@@ -800,7 +821,8 @@ static int dummy_udc_start(struct usb_gadget_driver *driver, | |||
800 | } | 821 | } |
801 | 822 | ||
802 | dum->gadget.ep0 = &dum->ep [0].ep; | 823 | dum->gadget.ep0 = &dum->ep [0].ep; |
803 | dum->ep [0].ep.maxpacket = 64; | 824 | dum->gadget.speed = min((u8)driver->speed, (u8)USB_SPEED_HIGH) ; |
825 | dum->ep[0].ep.maxpacket = 64; | ||
804 | list_del_init (&dum->ep [0].ep.ep_list); | 826 | list_del_init (&dum->ep [0].ep.ep_list); |
805 | INIT_LIST_HEAD(&dum->fifo_req.queue); | 827 | INIT_LIST_HEAD(&dum->fifo_req.queue); |
806 | 828 | ||
@@ -819,16 +841,18 @@ static int dummy_udc_start(struct usb_gadget_driver *driver, | |||
819 | /* khubd will enumerate this in a while */ | 841 | /* khubd will enumerate this in a while */ |
820 | spin_lock_irq (&dum->lock); | 842 | spin_lock_irq (&dum->lock); |
821 | dum->pullup = 1; | 843 | dum->pullup = 1; |
822 | set_link_state (dum); | 844 | dum->gadget.is_otg = |
845 | (dummy_hcd_to_hcd(dum->hs_hcd)->self.otg_port != 0); | ||
846 | set_link_state(dum->hs_hcd); | ||
823 | spin_unlock_irq (&dum->lock); | 847 | spin_unlock_irq (&dum->lock); |
824 | 848 | ||
825 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 849 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum->hs_hcd)); |
826 | return 0; | 850 | return 0; |
827 | } | 851 | } |
828 | 852 | ||
829 | static int dummy_udc_stop(struct usb_gadget_driver *driver) | 853 | static int dummy_udc_stop(struct usb_gadget_driver *driver) |
830 | { | 854 | { |
831 | struct dummy *dum = the_controller; | 855 | struct dummy *dum = &the_controller; |
832 | unsigned long flags; | 856 | unsigned long flags; |
833 | 857 | ||
834 | if (!dum) | 858 | if (!dum) |
@@ -841,7 +865,7 @@ static int dummy_udc_stop(struct usb_gadget_driver *driver) | |||
841 | 865 | ||
842 | spin_lock_irqsave (&dum->lock, flags); | 866 | spin_lock_irqsave (&dum->lock, flags); |
843 | dum->pullup = 0; | 867 | dum->pullup = 0; |
844 | set_link_state (dum); | 868 | set_link_state(dum->hs_hcd); |
845 | spin_unlock_irqrestore (&dum->lock, flags); | 869 | spin_unlock_irqrestore (&dum->lock, flags); |
846 | 870 | ||
847 | driver->unbind (&dum->gadget); | 871 | driver->unbind (&dum->gadget); |
@@ -850,10 +874,9 @@ static int dummy_udc_stop(struct usb_gadget_driver *driver) | |||
850 | 874 | ||
851 | spin_lock_irqsave (&dum->lock, flags); | 875 | spin_lock_irqsave (&dum->lock, flags); |
852 | dum->pullup = 0; | 876 | dum->pullup = 0; |
853 | set_link_state (dum); | 877 | set_link_state(dum->hs_hcd); |
854 | spin_unlock_irqrestore (&dum->lock, flags); | 878 | spin_unlock_irqrestore (&dum->lock, flags); |
855 | 879 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum->hs_hcd)); | |
856 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | ||
857 | return 0; | 880 | return 0; |
858 | } | 881 | } |
859 | 882 | ||
@@ -874,25 +897,18 @@ EXPORT_SYMBOL (net2280_set_fifo_mode); | |||
874 | static void | 897 | static void |
875 | dummy_gadget_release (struct device *dev) | 898 | dummy_gadget_release (struct device *dev) |
876 | { | 899 | { |
877 | struct dummy *dum = gadget_dev_to_dummy (dev); | 900 | return; |
878 | |||
879 | usb_put_hcd (dummy_to_hcd (dum)); | ||
880 | } | 901 | } |
881 | 902 | ||
882 | static int dummy_udc_probe (struct platform_device *pdev) | 903 | static int dummy_udc_probe (struct platform_device *pdev) |
883 | { | 904 | { |
884 | struct dummy *dum = the_controller; | 905 | struct dummy *dum = &the_controller; |
885 | int rc; | 906 | int rc; |
886 | 907 | ||
887 | usb_get_hcd(dummy_to_hcd(dum)); | ||
888 | |||
889 | dum->gadget.name = gadget_name; | 908 | dum->gadget.name = gadget_name; |
890 | dum->gadget.ops = &dummy_ops; | 909 | dum->gadget.ops = &dummy_ops; |
891 | dum->gadget.is_dualspeed = 1; | 910 | dum->gadget.is_dualspeed = 1; |
892 | 911 | ||
893 | /* maybe claim OTG support, though we won't complete HNP */ | ||
894 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); | ||
895 | |||
896 | dev_set_name(&dum->gadget.dev, "gadget"); | 912 | dev_set_name(&dum->gadget.dev, "gadget"); |
897 | dum->gadget.dev.parent = &pdev->dev; | 913 | dum->gadget.dev.parent = &pdev->dev; |
898 | dum->gadget.dev.release = dummy_gadget_release; | 914 | dum->gadget.dev.release = dummy_gadget_release; |
@@ -937,10 +953,10 @@ static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state) | |||
937 | dev_dbg (&pdev->dev, "%s\n", __func__); | 953 | dev_dbg (&pdev->dev, "%s\n", __func__); |
938 | spin_lock_irq (&dum->lock); | 954 | spin_lock_irq (&dum->lock); |
939 | dum->udc_suspended = 1; | 955 | dum->udc_suspended = 1; |
940 | set_link_state (dum); | 956 | set_link_state(dum->hs_hcd); |
941 | spin_unlock_irq (&dum->lock); | 957 | spin_unlock_irq (&dum->lock); |
942 | 958 | ||
943 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 959 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum->hs_hcd)); |
944 | return 0; | 960 | return 0; |
945 | } | 961 | } |
946 | 962 | ||
@@ -951,10 +967,10 @@ static int dummy_udc_resume (struct platform_device *pdev) | |||
951 | dev_dbg (&pdev->dev, "%s\n", __func__); | 967 | dev_dbg (&pdev->dev, "%s\n", __func__); |
952 | spin_lock_irq (&dum->lock); | 968 | spin_lock_irq (&dum->lock); |
953 | dum->udc_suspended = 0; | 969 | dum->udc_suspended = 0; |
954 | set_link_state (dum); | 970 | set_link_state(dum->hs_hcd); |
955 | spin_unlock_irq (&dum->lock); | 971 | spin_unlock_irq (&dum->lock); |
956 | 972 | ||
957 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 973 | usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum->hs_hcd)); |
958 | return 0; | 974 | return 0; |
959 | } | 975 | } |
960 | 976 | ||
@@ -988,7 +1004,7 @@ static int dummy_urb_enqueue ( | |||
988 | struct urb *urb, | 1004 | struct urb *urb, |
989 | gfp_t mem_flags | 1005 | gfp_t mem_flags |
990 | ) { | 1006 | ) { |
991 | struct dummy *dum; | 1007 | struct dummy_hcd *dum_hcd; |
992 | struct urbp *urbp; | 1008 | struct urbp *urbp; |
993 | unsigned long flags; | 1009 | unsigned long flags; |
994 | int rc; | 1010 | int rc; |
@@ -1001,51 +1017,51 @@ static int dummy_urb_enqueue ( | |||
1001 | return -ENOMEM; | 1017 | return -ENOMEM; |
1002 | urbp->urb = urb; | 1018 | urbp->urb = urb; |
1003 | 1019 | ||
1004 | dum = hcd_to_dummy (hcd); | 1020 | dum_hcd = hcd_to_dummy_hcd(hcd); |
1005 | spin_lock_irqsave (&dum->lock, flags); | 1021 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
1006 | rc = usb_hcd_link_urb_to_ep(hcd, urb); | 1022 | rc = usb_hcd_link_urb_to_ep(hcd, urb); |
1007 | if (rc) { | 1023 | if (rc) { |
1008 | kfree(urbp); | 1024 | kfree(urbp); |
1009 | goto done; | 1025 | goto done; |
1010 | } | 1026 | } |
1011 | 1027 | ||
1012 | if (!dum->udev) { | 1028 | if (!dum_hcd->udev) { |
1013 | dum->udev = urb->dev; | 1029 | dum_hcd->udev = urb->dev; |
1014 | usb_get_dev (dum->udev); | 1030 | usb_get_dev(dum_hcd->udev); |
1015 | } else if (unlikely (dum->udev != urb->dev)) | 1031 | } else if (unlikely(dum_hcd->udev != urb->dev)) |
1016 | dev_err (dummy_dev(dum), "usb_device address has changed!\n"); | 1032 | dev_err(dummy_dev(dum_hcd), "usb_device address has changed!\n"); |
1017 | 1033 | ||
1018 | list_add_tail (&urbp->urbp_list, &dum->urbp_list); | 1034 | list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); |
1019 | urb->hcpriv = urbp; | 1035 | urb->hcpriv = urbp; |
1020 | if (usb_pipetype (urb->pipe) == PIPE_CONTROL) | 1036 | if (usb_pipetype (urb->pipe) == PIPE_CONTROL) |
1021 | urb->error_count = 1; /* mark as a new urb */ | 1037 | urb->error_count = 1; /* mark as a new urb */ |
1022 | 1038 | ||
1023 | /* kick the scheduler, it'll do the rest */ | 1039 | /* kick the scheduler, it'll do the rest */ |
1024 | if (!timer_pending (&dum->timer)) | 1040 | if (!timer_pending(&dum_hcd->timer)) |
1025 | mod_timer (&dum->timer, jiffies + 1); | 1041 | mod_timer(&dum_hcd->timer, jiffies + 1); |
1026 | 1042 | ||
1027 | done: | 1043 | done: |
1028 | spin_unlock_irqrestore(&dum->lock, flags); | 1044 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
1029 | return rc; | 1045 | return rc; |
1030 | } | 1046 | } |
1031 | 1047 | ||
1032 | static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | 1048 | static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
1033 | { | 1049 | { |
1034 | struct dummy *dum; | 1050 | struct dummy_hcd *dum_hcd; |
1035 | unsigned long flags; | 1051 | unsigned long flags; |
1036 | int rc; | 1052 | int rc; |
1037 | 1053 | ||
1038 | /* giveback happens automatically in timer callback, | 1054 | /* giveback happens automatically in timer callback, |
1039 | * so make sure the callback happens */ | 1055 | * so make sure the callback happens */ |
1040 | dum = hcd_to_dummy (hcd); | 1056 | dum_hcd = hcd_to_dummy_hcd(hcd); |
1041 | spin_lock_irqsave (&dum->lock, flags); | 1057 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
1042 | 1058 | ||
1043 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | 1059 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
1044 | if (!rc && dum->rh_state != DUMMY_RH_RUNNING && | 1060 | if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && |
1045 | !list_empty(&dum->urbp_list)) | 1061 | !list_empty(&dum_hcd->urbp_list)) |
1046 | mod_timer (&dum->timer, jiffies); | 1062 | mod_timer(&dum_hcd->timer, jiffies); |
1047 | 1063 | ||
1048 | spin_unlock_irqrestore (&dum->lock, flags); | 1064 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
1049 | return rc; | 1065 | return rc; |
1050 | } | 1066 | } |
1051 | 1067 | ||
@@ -1185,7 +1201,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) | |||
1185 | return limit; | 1201 | return limit; |
1186 | } | 1202 | } |
1187 | 1203 | ||
1188 | #define is_active(dum) ((dum->port_status & \ | 1204 | #define is_active(dum_hcd) ((dum_hcd->port_status & \ |
1189 | (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \ | 1205 | (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \ |
1190 | USB_PORT_STAT_SUSPEND)) \ | 1206 | USB_PORT_STAT_SUSPEND)) \ |
1191 | == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) | 1207 | == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) |
@@ -1194,7 +1210,7 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) | |||
1194 | { | 1210 | { |
1195 | int i; | 1211 | int i; |
1196 | 1212 | ||
1197 | if (!is_active (dum)) | 1213 | if (!is_active(dum->hs_hcd)) |
1198 | return NULL; | 1214 | return NULL; |
1199 | if ((address & ~USB_DIR_IN) == 0) | 1215 | if ((address & ~USB_DIR_IN) == 0) |
1200 | return &dum->ep [0]; | 1216 | return &dum->ep [0]; |
@@ -1231,11 +1247,12 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) | |||
1231 | * 1 - if the request wasn't handles | 1247 | * 1 - if the request wasn't handles |
1232 | * error code on error | 1248 | * error code on error |
1233 | */ | 1249 | */ |
1234 | static int handle_control_request(struct dummy *dum, struct urb *urb, | 1250 | static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb, |
1235 | struct usb_ctrlrequest *setup, | 1251 | struct usb_ctrlrequest *setup, |
1236 | int *status) | 1252 | int *status) |
1237 | { | 1253 | { |
1238 | struct dummy_ep *ep2; | 1254 | struct dummy_ep *ep2; |
1255 | struct dummy *dum = dum_hcd->dum; | ||
1239 | int ret_val = 1; | 1256 | int ret_val = 1; |
1240 | unsigned w_index; | 1257 | unsigned w_index; |
1241 | unsigned w_value; | 1258 | unsigned w_value; |
@@ -1354,9 +1371,10 @@ static int handle_control_request(struct dummy *dum, struct urb *urb, | |||
1354 | /* drive both sides of the transfers; looks like irq handlers to | 1371 | /* drive both sides of the transfers; looks like irq handlers to |
1355 | * both drivers except the callbacks aren't in_irq(). | 1372 | * both drivers except the callbacks aren't in_irq(). |
1356 | */ | 1373 | */ |
1357 | static void dummy_timer (unsigned long _dum) | 1374 | static void dummy_timer(unsigned long _dum_hcd) |
1358 | { | 1375 | { |
1359 | struct dummy *dum = (struct dummy *) _dum; | 1376 | struct dummy_hcd *dum_hcd = (struct dummy_hcd *) _dum_hcd; |
1377 | struct dummy *dum = dum_hcd->dum; | ||
1360 | struct urbp *urbp, *tmp; | 1378 | struct urbp *urbp, *tmp; |
1361 | unsigned long flags; | 1379 | unsigned long flags; |
1362 | int limit, total; | 1380 | int limit, total; |
@@ -1374,7 +1392,7 @@ static void dummy_timer (unsigned long _dum) | |||
1374 | total = 512/*bytes*/ * 13/*packets*/ * 8/*uframes*/; | 1392 | total = 512/*bytes*/ * 13/*packets*/ * 8/*uframes*/; |
1375 | break; | 1393 | break; |
1376 | default: | 1394 | default: |
1377 | dev_err (dummy_dev(dum), "bogus device speed\n"); | 1395 | dev_err(dummy_dev(dum_hcd), "bogus device speed\n"); |
1378 | return; | 1396 | return; |
1379 | } | 1397 | } |
1380 | 1398 | ||
@@ -1383,8 +1401,8 @@ static void dummy_timer (unsigned long _dum) | |||
1383 | /* look at each urb queued by the host side driver */ | 1401 | /* look at each urb queued by the host side driver */ |
1384 | spin_lock_irqsave (&dum->lock, flags); | 1402 | spin_lock_irqsave (&dum->lock, flags); |
1385 | 1403 | ||
1386 | if (!dum->udev) { | 1404 | if (!dum_hcd->udev) { |
1387 | dev_err (dummy_dev(dum), | 1405 | dev_err(dummy_dev(dum_hcd), |
1388 | "timer fired with no URBs pending?\n"); | 1406 | "timer fired with no URBs pending?\n"); |
1389 | spin_unlock_irqrestore (&dum->lock, flags); | 1407 | spin_unlock_irqrestore (&dum->lock, flags); |
1390 | return; | 1408 | return; |
@@ -1397,7 +1415,7 @@ static void dummy_timer (unsigned long _dum) | |||
1397 | } | 1415 | } |
1398 | 1416 | ||
1399 | restart: | 1417 | restart: |
1400 | list_for_each_entry_safe (urbp, tmp, &dum->urbp_list, urbp_list) { | 1418 | list_for_each_entry_safe(urbp, tmp, &dum_hcd->urbp_list, urbp_list) { |
1401 | struct urb *urb; | 1419 | struct urb *urb; |
1402 | struct dummy_request *req; | 1420 | struct dummy_request *req; |
1403 | u8 address; | 1421 | u8 address; |
@@ -1408,7 +1426,7 @@ restart: | |||
1408 | urb = urbp->urb; | 1426 | urb = urbp->urb; |
1409 | if (urb->unlinked) | 1427 | if (urb->unlinked) |
1410 | goto return_urb; | 1428 | goto return_urb; |
1411 | else if (dum->rh_state != DUMMY_RH_RUNNING) | 1429 | else if (dum_hcd->rh_state != DUMMY_RH_RUNNING) |
1412 | continue; | 1430 | continue; |
1413 | type = usb_pipetype (urb->pipe); | 1431 | type = usb_pipetype (urb->pipe); |
1414 | 1432 | ||
@@ -1426,7 +1444,7 @@ restart: | |||
1426 | ep = find_endpoint(dum, address); | 1444 | ep = find_endpoint(dum, address); |
1427 | if (!ep) { | 1445 | if (!ep) { |
1428 | /* set_configuration() disagreement */ | 1446 | /* set_configuration() disagreement */ |
1429 | dev_dbg (dummy_dev(dum), | 1447 | dev_dbg(dummy_dev(dum_hcd), |
1430 | "no ep configured for urb %p\n", | 1448 | "no ep configured for urb %p\n", |
1431 | urb); | 1449 | urb); |
1432 | status = -EPROTO; | 1450 | status = -EPROTO; |
@@ -1442,7 +1460,7 @@ restart: | |||
1442 | } | 1460 | } |
1443 | if (ep->halted && !ep->setup_stage) { | 1461 | if (ep->halted && !ep->setup_stage) { |
1444 | /* NOTE: must not be iso! */ | 1462 | /* NOTE: must not be iso! */ |
1445 | dev_dbg (dummy_dev(dum), "ep %s halted, urb %p\n", | 1463 | dev_dbg(dummy_dev(dum_hcd), "ep %s halted, urb %p\n", |
1446 | ep->ep.name, urb); | 1464 | ep->ep.name, urb); |
1447 | status = -EPIPE; | 1465 | status = -EPIPE; |
1448 | goto return_urb; | 1466 | goto return_urb; |
@@ -1477,7 +1495,7 @@ restart: | |||
1477 | ep->setup_stage = 0; | 1495 | ep->setup_stage = 0; |
1478 | ep->halted = 0; | 1496 | ep->halted = 0; |
1479 | 1497 | ||
1480 | value = handle_control_request(dum, urb, &setup, | 1498 | value = handle_control_request(dum_hcd, urb, &setup, |
1481 | &status); | 1499 | &status); |
1482 | 1500 | ||
1483 | /* gadget driver handles all other requests. block | 1501 | /* gadget driver handles all other requests. block |
@@ -1547,20 +1565,20 @@ return_urb: | |||
1547 | if (ep) | 1565 | if (ep) |
1548 | ep->already_seen = ep->setup_stage = 0; | 1566 | ep->already_seen = ep->setup_stage = 0; |
1549 | 1567 | ||
1550 | usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb); | 1568 | usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb); |
1551 | spin_unlock (&dum->lock); | 1569 | spin_unlock (&dum->lock); |
1552 | usb_hcd_giveback_urb(dummy_to_hcd(dum), urb, status); | 1570 | usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status); |
1553 | spin_lock (&dum->lock); | 1571 | spin_lock (&dum->lock); |
1554 | 1572 | ||
1555 | goto restart; | 1573 | goto restart; |
1556 | } | 1574 | } |
1557 | 1575 | ||
1558 | if (list_empty (&dum->urbp_list)) { | 1576 | if (list_empty(&dum_hcd->urbp_list)) { |
1559 | usb_put_dev (dum->udev); | 1577 | usb_put_dev(dum_hcd->udev); |
1560 | dum->udev = NULL; | 1578 | dum_hcd->udev = NULL; |
1561 | } else if (dum->rh_state == DUMMY_RH_RUNNING) { | 1579 | } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { |
1562 | /* want a 1 msec delay here */ | 1580 | /* want a 1 msec delay here */ |
1563 | mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1)); | 1581 | mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1)); |
1564 | } | 1582 | } |
1565 | 1583 | ||
1566 | spin_unlock_irqrestore (&dum->lock, flags); | 1584 | spin_unlock_irqrestore (&dum->lock, flags); |
@@ -1577,32 +1595,32 @@ return_urb: | |||
1577 | 1595 | ||
1578 | static int dummy_hub_status (struct usb_hcd *hcd, char *buf) | 1596 | static int dummy_hub_status (struct usb_hcd *hcd, char *buf) |
1579 | { | 1597 | { |
1580 | struct dummy *dum; | 1598 | struct dummy_hcd *dum_hcd; |
1581 | unsigned long flags; | 1599 | unsigned long flags; |
1582 | int retval = 0; | 1600 | int retval = 0; |
1583 | 1601 | ||
1584 | dum = hcd_to_dummy (hcd); | 1602 | dum_hcd = hcd_to_dummy_hcd(hcd); |
1585 | 1603 | ||
1586 | spin_lock_irqsave (&dum->lock, flags); | 1604 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
1587 | if (!HCD_HW_ACCESSIBLE(hcd)) | 1605 | if (!HCD_HW_ACCESSIBLE(hcd)) |
1588 | goto done; | 1606 | goto done; |
1589 | 1607 | ||
1590 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { | 1608 | if (dum_hcd->resuming && time_after_eq(jiffies, dum_hcd->re_timeout)) { |
1591 | dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16); | 1609 | dum_hcd->port_status |= (USB_PORT_STAT_C_SUSPEND << 16); |
1592 | dum->port_status &= ~USB_PORT_STAT_SUSPEND; | 1610 | dum_hcd->port_status &= ~USB_PORT_STAT_SUSPEND; |
1593 | set_link_state (dum); | 1611 | set_link_state(dum_hcd); |
1594 | } | 1612 | } |
1595 | 1613 | ||
1596 | if ((dum->port_status & PORT_C_MASK) != 0) { | 1614 | if ((dum_hcd->port_status & PORT_C_MASK) != 0) { |
1597 | *buf = (1 << 1); | 1615 | *buf = (1 << 1); |
1598 | dev_dbg (dummy_dev(dum), "port status 0x%08x has changes\n", | 1616 | dev_dbg(dummy_dev(dum_hcd), "port status 0x%08x has changes\n", |
1599 | dum->port_status); | 1617 | dum_hcd->port_status); |
1600 | retval = 1; | 1618 | retval = 1; |
1601 | if (dum->rh_state == DUMMY_RH_SUSPENDED) | 1619 | if (dum_hcd->rh_state == DUMMY_RH_SUSPENDED) |
1602 | usb_hcd_resume_root_hub (hcd); | 1620 | usb_hcd_resume_root_hub (hcd); |
1603 | } | 1621 | } |
1604 | done: | 1622 | done: |
1605 | spin_unlock_irqrestore (&dum->lock, flags); | 1623 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
1606 | return retval; | 1624 | return retval; |
1607 | } | 1625 | } |
1608 | 1626 | ||
@@ -1626,39 +1644,40 @@ static int dummy_hub_control ( | |||
1626 | char *buf, | 1644 | char *buf, |
1627 | u16 wLength | 1645 | u16 wLength |
1628 | ) { | 1646 | ) { |
1629 | struct dummy *dum; | 1647 | struct dummy_hcd *dum_hcd; |
1630 | int retval = 0; | 1648 | int retval = 0; |
1631 | unsigned long flags; | 1649 | unsigned long flags; |
1632 | 1650 | ||
1633 | if (!HCD_HW_ACCESSIBLE(hcd)) | 1651 | if (!HCD_HW_ACCESSIBLE(hcd)) |
1634 | return -ETIMEDOUT; | 1652 | return -ETIMEDOUT; |
1635 | 1653 | ||
1636 | dum = hcd_to_dummy (hcd); | 1654 | dum_hcd = hcd_to_dummy_hcd(hcd); |
1637 | spin_lock_irqsave (&dum->lock, flags); | 1655 | |
1656 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); | ||
1638 | switch (typeReq) { | 1657 | switch (typeReq) { |
1639 | case ClearHubFeature: | 1658 | case ClearHubFeature: |
1640 | break; | 1659 | break; |
1641 | case ClearPortFeature: | 1660 | case ClearPortFeature: |
1642 | switch (wValue) { | 1661 | switch (wValue) { |
1643 | case USB_PORT_FEAT_SUSPEND: | 1662 | case USB_PORT_FEAT_SUSPEND: |
1644 | if (dum->port_status & USB_PORT_STAT_SUSPEND) { | 1663 | if (dum_hcd->port_status & USB_PORT_STAT_SUSPEND) { |
1645 | /* 20msec resume signaling */ | 1664 | /* 20msec resume signaling */ |
1646 | dum->resuming = 1; | 1665 | dum_hcd->resuming = 1; |
1647 | dum->re_timeout = jiffies + | 1666 | dum_hcd->re_timeout = jiffies + |
1648 | msecs_to_jiffies(20); | 1667 | msecs_to_jiffies(20); |
1649 | } | 1668 | } |
1650 | break; | 1669 | break; |
1651 | case USB_PORT_FEAT_POWER: | 1670 | case USB_PORT_FEAT_POWER: |
1652 | if (dum->port_status & USB_PORT_STAT_POWER) | 1671 | if (dum_hcd->port_status & USB_PORT_STAT_POWER) |
1653 | dev_dbg (dummy_dev(dum), "power-off\n"); | 1672 | dev_dbg(dummy_dev(dum_hcd), "power-off\n"); |
1654 | /* FALLS THROUGH */ | 1673 | /* FALLS THROUGH */ |
1655 | default: | 1674 | default: |
1656 | dum->port_status &= ~(1 << wValue); | 1675 | dum_hcd->port_status &= ~(1 << wValue); |
1657 | set_link_state (dum); | 1676 | set_link_state(dum_hcd); |
1658 | } | 1677 | } |
1659 | break; | 1678 | break; |
1660 | case GetHubDescriptor: | 1679 | case GetHubDescriptor: |
1661 | hub_descriptor ((struct usb_hub_descriptor *) buf); | 1680 | hub_descriptor((struct usb_hub_descriptor *) buf); |
1662 | break; | 1681 | break; |
1663 | case GetHubStatus: | 1682 | case GetHubStatus: |
1664 | *(__le32 *) buf = cpu_to_le32 (0); | 1683 | *(__le32 *) buf = cpu_to_le32 (0); |
@@ -1670,39 +1689,38 @@ static int dummy_hub_control ( | |||
1670 | /* whoever resets or resumes must GetPortStatus to | 1689 | /* whoever resets or resumes must GetPortStatus to |
1671 | * complete it!! | 1690 | * complete it!! |
1672 | */ | 1691 | */ |
1673 | if (dum->resuming && | 1692 | if (dum_hcd->resuming && |
1674 | time_after_eq (jiffies, dum->re_timeout)) { | 1693 | time_after_eq(jiffies, dum_hcd->re_timeout)) { |
1675 | dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16); | 1694 | dum_hcd->port_status |= (USB_PORT_STAT_C_SUSPEND << 16); |
1676 | dum->port_status &= ~USB_PORT_STAT_SUSPEND; | 1695 | dum_hcd->port_status &= ~USB_PORT_STAT_SUSPEND; |
1677 | } | 1696 | } |
1678 | if ((dum->port_status & USB_PORT_STAT_RESET) != 0 && | 1697 | if ((dum_hcd->port_status & USB_PORT_STAT_RESET) != 0 && |
1679 | time_after_eq (jiffies, dum->re_timeout)) { | 1698 | time_after_eq(jiffies, dum_hcd->re_timeout)) { |
1680 | dum->port_status |= (USB_PORT_STAT_C_RESET << 16); | 1699 | dum_hcd->port_status |= (USB_PORT_STAT_C_RESET << 16); |
1681 | dum->port_status &= ~USB_PORT_STAT_RESET; | 1700 | dum_hcd->port_status &= ~USB_PORT_STAT_RESET; |
1682 | if (dum->pullup) { | 1701 | if (dum_hcd->dum->pullup) { |
1683 | dum->port_status |= USB_PORT_STAT_ENABLE; | 1702 | dum_hcd->port_status |= USB_PORT_STAT_ENABLE; |
1684 | /* give it the best speed we agree on */ | 1703 | switch (dum_hcd->dum->gadget.speed) { |
1685 | dum->gadget.speed = dum->driver->speed; | ||
1686 | dum->gadget.ep0->maxpacket = 64; | ||
1687 | switch (dum->gadget.speed) { | ||
1688 | case USB_SPEED_HIGH: | 1704 | case USB_SPEED_HIGH: |
1689 | dum->port_status |= | 1705 | dum_hcd->port_status |= |
1690 | USB_PORT_STAT_HIGH_SPEED; | 1706 | USB_PORT_STAT_HIGH_SPEED; |
1691 | break; | 1707 | break; |
1692 | case USB_SPEED_LOW: | 1708 | case USB_SPEED_LOW: |
1693 | dum->gadget.ep0->maxpacket = 8; | 1709 | dum_hcd->dum->gadget.ep0-> |
1694 | dum->port_status |= | 1710 | maxpacket = 8; |
1711 | dum_hcd->port_status |= | ||
1695 | USB_PORT_STAT_LOW_SPEED; | 1712 | USB_PORT_STAT_LOW_SPEED; |
1696 | break; | 1713 | break; |
1697 | default: | 1714 | default: |
1698 | dum->gadget.speed = USB_SPEED_FULL; | 1715 | dum_hcd->dum->gadget.speed = |
1716 | USB_SPEED_FULL; | ||
1699 | break; | 1717 | break; |
1700 | } | 1718 | } |
1701 | } | 1719 | } |
1702 | } | 1720 | } |
1703 | set_link_state (dum); | 1721 | set_link_state(dum_hcd); |
1704 | ((__le16 *) buf)[0] = cpu_to_le16 (dum->port_status); | 1722 | ((__le16 *) buf)[0] = cpu_to_le16 (dum_hcd->port_status); |
1705 | ((__le16 *) buf)[1] = cpu_to_le16 (dum->port_status >> 16); | 1723 | ((__le16 *) buf)[1] = cpu_to_le16 (dum_hcd->port_status >> 16); |
1706 | break; | 1724 | break; |
1707 | case SetHubFeature: | 1725 | case SetHubFeature: |
1708 | retval = -EPIPE; | 1726 | retval = -EPIPE; |
@@ -1710,87 +1728,91 @@ static int dummy_hub_control ( | |||
1710 | case SetPortFeature: | 1728 | case SetPortFeature: |
1711 | switch (wValue) { | 1729 | switch (wValue) { |
1712 | case USB_PORT_FEAT_SUSPEND: | 1730 | case USB_PORT_FEAT_SUSPEND: |
1713 | if (dum->active) { | 1731 | if (dum_hcd->active) { |
1714 | dum->port_status |= USB_PORT_STAT_SUSPEND; | 1732 | dum_hcd->port_status |= USB_PORT_STAT_SUSPEND; |
1715 | 1733 | ||
1716 | /* HNP would happen here; for now we | 1734 | /* HNP would happen here; for now we |
1717 | * assume b_bus_req is always true. | 1735 | * assume b_bus_req is always true. |
1718 | */ | 1736 | */ |
1719 | set_link_state (dum); | 1737 | set_link_state(dum_hcd); |
1720 | if (((1 << USB_DEVICE_B_HNP_ENABLE) | 1738 | if (((1 << USB_DEVICE_B_HNP_ENABLE) |
1721 | & dum->devstatus) != 0) | 1739 | & dum_hcd->dum->devstatus) != 0) |
1722 | dev_dbg (dummy_dev(dum), | 1740 | dev_dbg(dummy_dev(dum_hcd), |
1723 | "no HNP yet!\n"); | 1741 | "no HNP yet!\n"); |
1724 | } | 1742 | } |
1725 | break; | 1743 | break; |
1726 | case USB_PORT_FEAT_POWER: | 1744 | case USB_PORT_FEAT_POWER: |
1727 | dum->port_status |= USB_PORT_STAT_POWER; | 1745 | dum_hcd->port_status |= USB_PORT_STAT_POWER; |
1728 | set_link_state (dum); | 1746 | set_link_state(dum_hcd); |
1729 | break; | 1747 | break; |
1730 | case USB_PORT_FEAT_RESET: | 1748 | case USB_PORT_FEAT_RESET: |
1731 | /* if it's already enabled, disable */ | 1749 | /* if it's already enabled, disable */ |
1732 | dum->port_status &= ~(USB_PORT_STAT_ENABLE | 1750 | dum_hcd->port_status &= ~(USB_PORT_STAT_ENABLE |
1733 | | USB_PORT_STAT_LOW_SPEED | 1751 | | USB_PORT_STAT_LOW_SPEED |
1734 | | USB_PORT_STAT_HIGH_SPEED); | 1752 | | USB_PORT_STAT_HIGH_SPEED); |
1735 | dum->devstatus = 0; | 1753 | /* |
1736 | /* 50msec reset signaling */ | 1754 | * We want to reset device status. All but the |
1737 | dum->re_timeout = jiffies + msecs_to_jiffies(50); | 1755 | * Self powered feature |
1756 | */ | ||
1757 | dum_hcd->dum->devstatus &= | ||
1758 | (1 << USB_DEVICE_SELF_POWERED); | ||
1759 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); | ||
1738 | /* FALLS THROUGH */ | 1760 | /* FALLS THROUGH */ |
1739 | default: | 1761 | default: |
1740 | if ((dum->port_status & USB_PORT_STAT_POWER) != 0) { | 1762 | if ((dum_hcd->port_status & |
1741 | dum->port_status |= (1 << wValue); | 1763 | USB_PORT_STAT_POWER) != 0) { |
1742 | set_link_state (dum); | 1764 | dum_hcd->port_status |= (1 << wValue); |
1765 | set_link_state(dum_hcd); | ||
1743 | } | 1766 | } |
1744 | } | 1767 | } |
1745 | break; | 1768 | break; |
1746 | 1769 | ||
1747 | default: | 1770 | default: |
1748 | dev_dbg (dummy_dev(dum), | 1771 | dev_dbg(dummy_dev(dum_hcd), |
1749 | "hub control req%04x v%04x i%04x l%d\n", | 1772 | "hub control req%04x v%04x i%04x l%d\n", |
1750 | typeReq, wValue, wIndex, wLength); | 1773 | typeReq, wValue, wIndex, wLength); |
1751 | |||
1752 | /* "protocol stall" on error */ | 1774 | /* "protocol stall" on error */ |
1753 | retval = -EPIPE; | 1775 | retval = -EPIPE; |
1754 | } | 1776 | } |
1755 | spin_unlock_irqrestore (&dum->lock, flags); | 1777 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
1756 | 1778 | ||
1757 | if ((dum->port_status & PORT_C_MASK) != 0) | 1779 | if ((dum_hcd->port_status & PORT_C_MASK) != 0) |
1758 | usb_hcd_poll_rh_status (hcd); | 1780 | usb_hcd_poll_rh_status (hcd); |
1759 | return retval; | 1781 | return retval; |
1760 | } | 1782 | } |
1761 | 1783 | ||
1762 | static int dummy_bus_suspend (struct usb_hcd *hcd) | 1784 | static int dummy_bus_suspend (struct usb_hcd *hcd) |
1763 | { | 1785 | { |
1764 | struct dummy *dum = hcd_to_dummy (hcd); | 1786 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
1765 | 1787 | ||
1766 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); | 1788 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); |
1767 | 1789 | ||
1768 | spin_lock_irq (&dum->lock); | 1790 | spin_lock_irq(&dum_hcd->dum->lock); |
1769 | dum->rh_state = DUMMY_RH_SUSPENDED; | 1791 | dum_hcd->rh_state = DUMMY_RH_SUSPENDED; |
1770 | set_link_state (dum); | 1792 | set_link_state(dum_hcd); |
1771 | hcd->state = HC_STATE_SUSPENDED; | 1793 | hcd->state = HC_STATE_SUSPENDED; |
1772 | spin_unlock_irq (&dum->lock); | 1794 | spin_unlock_irq(&dum_hcd->dum->lock); |
1773 | return 0; | 1795 | return 0; |
1774 | } | 1796 | } |
1775 | 1797 | ||
1776 | static int dummy_bus_resume (struct usb_hcd *hcd) | 1798 | static int dummy_bus_resume (struct usb_hcd *hcd) |
1777 | { | 1799 | { |
1778 | struct dummy *dum = hcd_to_dummy (hcd); | 1800 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
1779 | int rc = 0; | 1801 | int rc = 0; |
1780 | 1802 | ||
1781 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); | 1803 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); |
1782 | 1804 | ||
1783 | spin_lock_irq (&dum->lock); | 1805 | spin_lock_irq(&dum_hcd->dum->lock); |
1784 | if (!HCD_HW_ACCESSIBLE(hcd)) { | 1806 | if (!HCD_HW_ACCESSIBLE(hcd)) { |
1785 | rc = -ESHUTDOWN; | 1807 | rc = -ESHUTDOWN; |
1786 | } else { | 1808 | } else { |
1787 | dum->rh_state = DUMMY_RH_RUNNING; | 1809 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
1788 | set_link_state (dum); | 1810 | set_link_state(dum_hcd); |
1789 | if (!list_empty(&dum->urbp_list)) | 1811 | if (!list_empty(&dum_hcd->urbp_list)) |
1790 | mod_timer (&dum->timer, jiffies); | 1812 | mod_timer(&dum_hcd->timer, jiffies); |
1791 | hcd->state = HC_STATE_RUNNING; | 1813 | hcd->state = HC_STATE_RUNNING; |
1792 | } | 1814 | } |
1793 | spin_unlock_irq (&dum->lock); | 1815 | spin_unlock_irq(&dum_hcd->dum->lock); |
1794 | return rc; | 1816 | return rc; |
1795 | } | 1817 | } |
1796 | 1818 | ||
@@ -1842,43 +1864,41 @@ static ssize_t | |||
1842 | show_urbs (struct device *dev, struct device_attribute *attr, char *buf) | 1864 | show_urbs (struct device *dev, struct device_attribute *attr, char *buf) |
1843 | { | 1865 | { |
1844 | struct usb_hcd *hcd = dev_get_drvdata (dev); | 1866 | struct usb_hcd *hcd = dev_get_drvdata (dev); |
1845 | struct dummy *dum = hcd_to_dummy (hcd); | 1867 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
1846 | struct urbp *urbp; | 1868 | struct urbp *urbp; |
1847 | size_t size = 0; | 1869 | size_t size = 0; |
1848 | unsigned long flags; | 1870 | unsigned long flags; |
1849 | 1871 | ||
1850 | spin_lock_irqsave (&dum->lock, flags); | 1872 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
1851 | list_for_each_entry (urbp, &dum->urbp_list, urbp_list) { | 1873 | list_for_each_entry(urbp, &dum_hcd->urbp_list, urbp_list) { |
1852 | size_t temp; | 1874 | size_t temp; |
1853 | 1875 | ||
1854 | temp = show_urb (buf, PAGE_SIZE - size, urbp->urb); | 1876 | temp = show_urb (buf, PAGE_SIZE - size, urbp->urb); |
1855 | buf += temp; | 1877 | buf += temp; |
1856 | size += temp; | 1878 | size += temp; |
1857 | } | 1879 | } |
1858 | spin_unlock_irqrestore (&dum->lock, flags); | 1880 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
1859 | 1881 | ||
1860 | return size; | 1882 | return size; |
1861 | } | 1883 | } |
1862 | static DEVICE_ATTR (urbs, S_IRUGO, show_urbs, NULL); | 1884 | static DEVICE_ATTR (urbs, S_IRUGO, show_urbs, NULL); |
1863 | 1885 | ||
1864 | static int dummy_start (struct usb_hcd *hcd) | 1886 | static int dummy_start(struct usb_hcd *hcd) |
1865 | { | 1887 | { |
1866 | struct dummy *dum; | 1888 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
1867 | |||
1868 | dum = hcd_to_dummy (hcd); | ||
1869 | 1889 | ||
1870 | /* | 1890 | /* |
1871 | * MASTER side init ... we emulate a root hub that'll only ever | 1891 | * MASTER side init ... we emulate a root hub that'll only ever |
1872 | * talk to one device (the slave side). Also appears in sysfs, | 1892 | * talk to one device (the slave side). Also appears in sysfs, |
1873 | * just like more familiar pci-based HCDs. | 1893 | * just like more familiar pci-based HCDs. |
1874 | */ | 1894 | */ |
1875 | spin_lock_init (&dum->lock); | 1895 | spin_lock_init(&dum_hcd->dum->lock); |
1876 | init_timer (&dum->timer); | 1896 | init_timer(&dum_hcd->timer); |
1877 | dum->timer.function = dummy_timer; | 1897 | dum_hcd->timer.function = dummy_timer; |
1878 | dum->timer.data = (unsigned long) dum; | 1898 | dum_hcd->timer.data = (unsigned long)dum_hcd; |
1879 | dum->rh_state = DUMMY_RH_RUNNING; | 1899 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
1880 | 1900 | ||
1881 | INIT_LIST_HEAD (&dum->urbp_list); | 1901 | INIT_LIST_HEAD(&dum_hcd->urbp_list); |
1882 | 1902 | ||
1883 | hcd->power_budget = POWER_BUDGET; | 1903 | hcd->power_budget = POWER_BUDGET; |
1884 | hcd->state = HC_STATE_RUNNING; | 1904 | hcd->state = HC_STATE_RUNNING; |
@@ -1889,17 +1909,17 @@ static int dummy_start (struct usb_hcd *hcd) | |||
1889 | #endif | 1909 | #endif |
1890 | 1910 | ||
1891 | /* FIXME 'urbs' should be a per-device thing, maybe in usbcore */ | 1911 | /* FIXME 'urbs' should be a per-device thing, maybe in usbcore */ |
1892 | return device_create_file (dummy_dev(dum), &dev_attr_urbs); | 1912 | return device_create_file(dummy_dev(dum_hcd), &dev_attr_urbs); |
1893 | } | 1913 | } |
1894 | 1914 | ||
1895 | static void dummy_stop (struct usb_hcd *hcd) | 1915 | static void dummy_stop (struct usb_hcd *hcd) |
1896 | { | 1916 | { |
1897 | struct dummy *dum; | 1917 | struct dummy *dum; |
1898 | 1918 | ||
1899 | dum = hcd_to_dummy (hcd); | 1919 | dum = (hcd_to_dummy_hcd(hcd))->dum; |
1900 | 1920 | device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); | |
1901 | device_remove_file (dummy_dev(dum), &dev_attr_urbs); | 1921 | usb_gadget_unregister_driver(dum->driver); |
1902 | dev_info (dummy_dev(dum), "stopped\n"); | 1922 | dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); |
1903 | } | 1923 | } |
1904 | 1924 | ||
1905 | /*-------------------------------------------------------------------------*/ | 1925 | /*-------------------------------------------------------------------------*/ |
@@ -1909,13 +1929,26 @@ static int dummy_h_get_frame (struct usb_hcd *hcd) | |||
1909 | return dummy_g_get_frame (NULL); | 1929 | return dummy_g_get_frame (NULL); |
1910 | } | 1930 | } |
1911 | 1931 | ||
1932 | static int dummy_setup(struct usb_hcd *hcd) | ||
1933 | { | ||
1934 | if (usb_hcd_is_primary_hcd(hcd)) { | ||
1935 | the_controller.hs_hcd = hcd_to_dummy_hcd(hcd); | ||
1936 | the_controller.hs_hcd->dum = &the_controller; | ||
1937 | /* Mark the first roothub as being USB 2.0. */ | ||
1938 | hcd->speed = HCD_USB2; | ||
1939 | hcd->self.root_hub->speed = USB_SPEED_HIGH; | ||
1940 | } | ||
1941 | return 0; | ||
1942 | } | ||
1943 | |||
1912 | static const struct hc_driver dummy_hcd = { | 1944 | static const struct hc_driver dummy_hcd = { |
1913 | .description = (char *) driver_name, | 1945 | .description = (char *) driver_name, |
1914 | .product_desc = "Dummy host controller", | 1946 | .product_desc = "Dummy host controller", |
1915 | .hcd_priv_size = sizeof(struct dummy), | 1947 | .hcd_priv_size = sizeof(struct dummy_hcd), |
1916 | 1948 | ||
1917 | .flags = HCD_USB2, | 1949 | .flags = HCD_USB2, |
1918 | 1950 | ||
1951 | .reset = dummy_setup, | ||
1919 | .start = dummy_start, | 1952 | .start = dummy_start, |
1920 | .stop = dummy_stop, | 1953 | .stop = dummy_stop, |
1921 | 1954 | ||
@@ -1932,47 +1965,47 @@ static const struct hc_driver dummy_hcd = { | |||
1932 | 1965 | ||
1933 | static int dummy_hcd_probe(struct platform_device *pdev) | 1966 | static int dummy_hcd_probe(struct platform_device *pdev) |
1934 | { | 1967 | { |
1935 | struct usb_hcd *hcd; | 1968 | struct usb_hcd *hs_hcd; |
1936 | int retval; | 1969 | int retval; |
1937 | 1970 | ||
1938 | dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); | 1971 | dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); |
1939 | 1972 | ||
1940 | hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); | 1973 | hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); |
1941 | if (!hcd) | 1974 | if (!hs_hcd) |
1942 | return -ENOMEM; | 1975 | return -ENOMEM; |
1943 | the_controller = hcd_to_dummy (hcd); | 1976 | hs_hcd->has_tt = 1; |
1944 | hcd->has_tt = 1; | ||
1945 | 1977 | ||
1946 | retval = usb_add_hcd(hcd, 0, 0); | 1978 | retval = usb_add_hcd(hs_hcd, 0, 0); |
1947 | if (retval != 0) { | 1979 | if (retval != 0) { |
1948 | usb_put_hcd (hcd); | 1980 | usb_put_hcd(hs_hcd); |
1949 | the_controller = NULL; | 1981 | the_controller.hs_hcd = NULL; |
1950 | } | 1982 | } |
1951 | return retval; | 1983 | return retval; |
1952 | } | 1984 | } |
1953 | 1985 | ||
1954 | static int dummy_hcd_remove (struct platform_device *pdev) | 1986 | static int dummy_hcd_remove(struct platform_device *pdev) |
1955 | { | 1987 | { |
1956 | struct usb_hcd *hcd; | 1988 | struct dummy *dum; |
1989 | |||
1990 | dum = (hcd_to_dummy_hcd(platform_get_drvdata(pdev)))->dum; | ||
1991 | usb_remove_hcd(dummy_hcd_to_hcd(dum->hs_hcd)); | ||
1992 | usb_put_hcd(dummy_hcd_to_hcd(dum->hs_hcd)); | ||
1993 | the_controller.hs_hcd = NULL; | ||
1957 | 1994 | ||
1958 | hcd = platform_get_drvdata (pdev); | ||
1959 | usb_remove_hcd (hcd); | ||
1960 | usb_put_hcd (hcd); | ||
1961 | the_controller = NULL; | ||
1962 | return 0; | 1995 | return 0; |
1963 | } | 1996 | } |
1964 | 1997 | ||
1965 | static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) | 1998 | static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) |
1966 | { | 1999 | { |
1967 | struct usb_hcd *hcd; | 2000 | struct usb_hcd *hcd; |
1968 | struct dummy *dum; | 2001 | struct dummy_hcd *dum_hcd; |
1969 | int rc = 0; | 2002 | int rc = 0; |
1970 | 2003 | ||
1971 | dev_dbg (&pdev->dev, "%s\n", __func__); | 2004 | dev_dbg (&pdev->dev, "%s\n", __func__); |
1972 | 2005 | ||
1973 | hcd = platform_get_drvdata (pdev); | 2006 | hcd = platform_get_drvdata (pdev); |
1974 | dum = hcd_to_dummy (hcd); | 2007 | dum_hcd = hcd_to_dummy_hcd(hcd); |
1975 | if (dum->rh_state == DUMMY_RH_RUNNING) { | 2008 | if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { |
1976 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); | 2009 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); |
1977 | rc = -EBUSY; | 2010 | rc = -EBUSY; |
1978 | } else | 2011 | } else |
@@ -2032,7 +2065,7 @@ static int __init init (void) | |||
2032 | retval = platform_device_add(the_hcd_pdev); | 2065 | retval = platform_device_add(the_hcd_pdev); |
2033 | if (retval < 0) | 2066 | if (retval < 0) |
2034 | goto err_add_hcd; | 2067 | goto err_add_hcd; |
2035 | if (!the_controller) { | 2068 | if (!the_controller.hs_hcd) { |
2036 | /* | 2069 | /* |
2037 | * The hcd was added successfully but its probe function failed | 2070 | * The hcd was added successfully but its probe function failed |
2038 | * for some reason. | 2071 | * for some reason. |