aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/drivers/usb/uhci_rh.c
diff options
context:
space:
mode:
authorStefan Reinauer <stepan@coresystems.de>2010-03-25 22:17:36 +0000
committerStefan Reinauer <stepan@openbios.org>2010-03-25 22:17:36 +0000
commitb56f2d0ad4bfc81e7ef5ffd406c652f2c3bd954a (patch)
treeec2bbc0918ee3e1f2ee66491c7b87da204e607da /payloads/libpayload/drivers/usb/uhci_rh.c
parente5d30b78b7720ba3e511819b7fc51c11d642153b (diff)
USB updates from our internal tree
- support MMC2 devices - make usb stack more solid - drop some unused functions - fix lowspeed/speed naming - add support for "quirks" - improve usbhid driver Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Joseph Smith <joe@settoplinux.org> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5299 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'payloads/libpayload/drivers/usb/uhci_rh.c')
-rw-r--r--payloads/libpayload/drivers/usb/uhci_rh.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/payloads/libpayload/drivers/usb/uhci_rh.c b/payloads/libpayload/drivers/usb/uhci_rh.c
index 2f4c7d839c..3957275bf0 100644
--- a/payloads/libpayload/drivers/usb/uhci_rh.c
+++ b/payloads/libpayload/drivers/usb/uhci_rh.c
@@ -1,7 +1,7 @@
/*
* This file is part of the libpayload project.
*
- * Copyright (C) 2008 coresystems GmbH
+ * Copyright (C) 2008-2010 coresystems GmbH
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,8 @@
* SUCH DAMAGE.
*/
+//#define USB_DEBUG
+
#include <libpayload.h>
#include "uhci.h"
@@ -43,8 +45,13 @@ uhci_rh_enable_port (usbdev_t *dev, int port)
hci_t *controller = dev->controller;
if (port == 1)
port = PORTSC1;
- else
+ else if (port == 2)
port = PORTSC2;
+ else {
+ printf("Invalid port %d\n", port);
+ return;
+ }
+
uhci_reg_mask16 (controller, port, ~(1 << 12), 0); /* wakeup */
uhci_reg_mask16 (controller, port, ~0, 1 << 9); /* reset */
@@ -85,8 +92,10 @@ uhci_rh_scanport (usbdev_t *dev, int port)
} else if (port == 2) {
portsc = PORTSC2;
offset = 1;
- } else
+ } else {
+ printf("Invalid port %d\n", port);
return;
+ }
int devno = RH_INST (dev)->port[offset];
if ((dev->controller->devices[devno] != 0) && (devno != -1)) {
usb_detach_device(dev->controller, devno);
@@ -94,16 +103,17 @@ uhci_rh_scanport (usbdev_t *dev, int port)
}
uhci_reg_mask16 (dev->controller, portsc, ~0, (1 << 3) | (1 << 2)); // clear port state change, enable port
+ mdelay(100); // wait for signal to stabilize
+
if ((uhci_reg_read16 (dev->controller, portsc) & 1) != 0) {
// device attached
uhci_rh_disable_port (dev, port);
uhci_rh_enable_port (dev, port);
- int lowspeed =
- (uhci_reg_read16 (dev->controller, portsc) >> 8) & 1;
+ int speed = ((uhci_reg_read16 (dev->controller, portsc) >> 8) & 1);
- RH_INST (dev)->port[offset] = usb_attach_device(dev->controller, dev->address, portsc, lowspeed);
+ RH_INST (dev)->port[offset] = usb_attach_device(dev->controller, dev->address, portsc, speed);
}
}
@@ -114,21 +124,30 @@ uhci_rh_report_port_changes (usbdev_t *dev)
stored = (RH_INST (dev)->port[0] == -1);
real = ((uhci_reg_read16 (dev->controller, PORTSC1) & 1) == 0);
- if (stored != real)
+ if (stored != real) {
+ debug("change on port 1\n");
return 1;
+ }
stored = (RH_INST (dev)->port[1] == -1);
real = ((uhci_reg_read16 (dev->controller, PORTSC2) & 1) == 0);
- if (stored != real)
+ if (stored != real) {
+ debug("change on port 2\n");
return 2;
+ }
+
+ // maybe detach+attach happened between two scans?
-// maybe detach+attach happened between two scans?
- if ((uhci_reg_read16 (dev->controller, PORTSC1) & 2) > 0)
+ if ((uhci_reg_read16 (dev->controller, PORTSC1) & 2) > 0) {
+ debug("possibly re-attached on port 1\n");
return 1;
- if ((uhci_reg_read16 (dev->controller, PORTSC2) & 2) > 0)
+ }
+ if ((uhci_reg_read16 (dev->controller, PORTSC2) & 2) > 0) {
+ debug("possibly re-attached on port 2\n");
return 2;
+ }
-// no change
+ // no change
return -1;
}