Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 22051
b: refs/heads/master
c: b1e8f0a
h: refs/heads/master
i:
  22049: a41596b
  22047: 53d5c54
v: v3
  • Loading branch information
David Brownell authored and Greg Kroah-Hartman committed Mar 20, 2006
1 parent d924031 commit 58a0d24
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 50 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1c05ad4447e4ecbd61647c102fb6f2f5a6634ff3
refs/heads/master: b1e8f0a6a8805c971857cd10a65cf8caa4c1a672
104 changes: 55 additions & 49 deletions trunk/drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -823,18 +823,17 @@ static void usb_deregister_bus (struct usb_bus *bus)

/**
* register_root_hub - called by usb_add_hcd() to register a root hub
* @usb_dev: the usb root hub device to be registered.
* @hcd: host controller for this root hub
*
* This function registers the root hub with the USB subsystem. It sets up
* the device properly in the device tree and stores the root_hub pointer
* in the bus structure, then calls usb_new_device() to register the usb
* device. It also assigns the root hub's USB address (always 1).
* the device properly in the device tree and then calls usb_new_device()
* to register the usb device. It also assigns the root hub's USB address
* (always 1).
*/
static int register_root_hub (struct usb_device *usb_dev,
struct usb_hcd *hcd)
static int register_root_hub(struct usb_hcd *hcd)
{
struct device *parent_dev = hcd->self.controller;
struct usb_device *usb_dev = hcd->self.root_hub;
const int devnum = 1;
int retval;

Expand All @@ -846,12 +845,10 @@ static int register_root_hub (struct usb_device *usb_dev,
usb_set_device_state(usb_dev, USB_STATE_ADDRESS);

mutex_lock(&usb_bus_list_lock);
usb_dev->bus->root_hub = usb_dev;

usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64);
retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE);
if (retval != sizeof usb_dev->descriptor) {
usb_dev->bus->root_hub = NULL;
mutex_unlock(&usb_bus_list_lock);
dev_dbg (parent_dev, "can't read %s device descriptor %d\n",
usb_dev->dev.bus_id, retval);
Expand All @@ -860,7 +857,6 @@ static int register_root_hub (struct usb_device *usb_dev,

retval = usb_new_device (usb_dev);
if (retval) {
usb_dev->bus->root_hub = NULL;
dev_err (parent_dev, "can't register root hub for %s, %d\n",
usb_dev->dev.bus_id, retval);
}
Expand Down Expand Up @@ -1772,12 +1768,10 @@ int usb_add_hcd(struct usb_hcd *hcd,

set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);

/* till now HC has been in an indeterminate state ... */
if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
dev_err(hcd->self.controller, "can't reset\n");
return retval;
}

/* HC is in reset state, but accessible. Now do the one-time init,
* bottom up so that hcds can customize the root hubs before khubd
* starts talking to them. (Note, bus id is assigned early too.)
*/
if ((retval = hcd_buffer_create(hcd)) != 0) {
dev_dbg(hcd->self.controller, "pool alloc failed\n");
return retval;
Expand All @@ -1786,6 +1780,42 @@ int usb_add_hcd(struct usb_hcd *hcd,
if ((retval = usb_register_bus(&hcd->self)) < 0)
goto err_register_bus;

if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
dev_err(hcd->self.controller, "unable to allocate root hub\n");
retval = -ENOMEM;
goto err_allocate_root_hub;
}
rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
USB_SPEED_FULL;
hcd->self.root_hub = rhdev;

/* "reset" is misnamed; its role is now one-time init. the controller
* should already have been reset (and boot firmware kicked off etc).
*/
if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
dev_err(hcd->self.controller, "can't setup\n");
goto err_hcd_driver_setup;
}

/* wakeup flag init is in transition; for now we can't rely on PCI to
* initialize these bits properly, so we let reset() override it.
* This init should _precede_ the reset() once PCI behaves.
*/
device_init_wakeup(&rhdev->dev,
device_can_wakeup(hcd->self.controller));

// ... all these hcd->*_wakeup flags will vanish
hcd->can_wakeup = device_can_wakeup(hcd->self.controller);

/* hcd->driver->reset() reported can_wakeup, probably with
* assistance from board's boot firmware.
* NOTE: normal devices won't enable wakeup by default.
*/
if (hcd->can_wakeup)
dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
hcd->remote_wakeup = hcd->can_wakeup;

/* enable irqs just before we start the controller */
if (hcd->driver->irq) {
char buf[8], *bufp = buf;

Expand Down Expand Up @@ -1817,56 +1847,32 @@ int usb_add_hcd(struct usb_hcd *hcd,
(unsigned long long)hcd->rsrc_start);
}

/* Allocate the root hub before calling hcd->driver->start(),
* but don't register it until afterward so that the hardware
* is running.
*/
if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
dev_err(hcd->self.controller, "unable to allocate root hub\n");
retval = -ENOMEM;
goto err_allocate_root_hub;
}

/* Although in principle hcd->driver->start() might need to use rhdev,
* none of the current drivers do.
*/
if ((retval = hcd->driver->start(hcd)) < 0) {
dev_err(hcd->self.controller, "startup error %d\n", retval);
goto err_hcd_driver_start;
}

/* hcd->driver->start() reported can_wakeup, probably with
* assistance from board's boot firmware.
* NOTE: normal devices won't enable wakeup by default.
*/
if (hcd->can_wakeup)
dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
hcd->remote_wakeup = hcd->can_wakeup;

rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
USB_SPEED_FULL;
/* starting here, usbcore will pay attention to this root hub */
rhdev->bus_mA = min(500u, hcd->power_budget);
if ((retval = register_root_hub(rhdev, hcd)) != 0)
if ((retval = register_root_hub(hcd)) != 0)
goto err_register_root_hub;

if (hcd->uses_new_polling && hcd->poll_rh)
usb_hcd_poll_rh_status(hcd);
return retval;

err_register_root_hub:
err_register_root_hub:
hcd->driver->stop(hcd);

err_hcd_driver_start:
usb_put_dev(rhdev);

err_allocate_root_hub:
err_hcd_driver_start:
if (hcd->irq >= 0)
free_irq(irqnum, hcd);

err_request_irq:
err_request_irq:
err_hcd_driver_setup:
hcd->self.root_hub = NULL;
usb_put_dev(rhdev);
err_allocate_root_hub:
usb_deregister_bus(&hcd->self);

err_register_bus:
err_register_bus:
hcd_buffer_destroy(hcd);
return retval;
}
Expand Down

0 comments on commit 58a0d24

Please sign in to comment.