aboutsummaryrefslogtreecommitdiff
path: root/src/usb-hub.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2010-02-26 08:57:13 -0500
committerKevin O'Connor <kevin@koconnor.net>2010-02-28 17:26:25 -0500
commit357bdfa26a681d614f04e842f85850fe5848f6fe (patch)
tree3b992d2b421d990cf3fe41ed5401826e3015bdf1 /src/usb-hub.c
parent7fb8ba866e112491feb64b2cf82b762fd9071f89 (diff)
downloadseabios-hppa-357bdfa26a681d614f04e842f85850fe5848f6fe.zip
seabios-hppa-357bdfa26a681d614f04e842f85850fe5848f6fe.tar.gz
seabios-hppa-357bdfa26a681d614f04e842f85850fe5848f6fe.tar.bz2
Prefer passing a USB "pipe" structure over a USB endp encoding.
Instead of passing the "u32 endp" encoding of the usb endpoint, allocate a "struct usb_pipe" for each end point and pass that. Allocate a control pipe for every device found. Support freeing the pipes after they are done. Implement pipe allocation and freeing for both UHCI and OHCI controllers. Also, don't define every UHCI qh to include a pipe - create a separate structure "struct uhci_pipe". Also, be sure to clear the USBControllers on reset. Also, convert usb_hub_init to return 0 on success. Also, cleanup some of the USB debug messages to make them more consistent.
Diffstat (limited to 'src/usb-hub.c')
-rw-r--r--src/usb-hub.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/usb-hub.c b/src/usb-hub.c
index ce9326b..b301f1c 100644
--- a/src/usb-hub.c
+++ b/src/usb-hub.c
@@ -10,7 +10,7 @@
#include "usb.h" // struct usb_s
static int
-get_hub_desc(struct usb_hub_descriptor *desc, u32 endp)
+get_hub_desc(struct usb_pipe *pipe, struct usb_hub_descriptor *desc)
{
struct usb_ctrlrequest req;
req.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE;
@@ -18,11 +18,11 @@ get_hub_desc(struct usb_hub_descriptor *desc, u32 endp)
req.wValue = USB_DT_HUB<<8;
req.wIndex = 0;
req.wLength = sizeof(*desc);
- return send_default_control(endp, &req, desc);
+ return send_default_control(pipe, &req, desc);
}
static int
-set_port_feature(int port, int feature, u32 endp)
+set_port_feature(struct usb_pipe *pipe, int port, int feature)
{
struct usb_ctrlrequest req;
req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER;
@@ -30,11 +30,11 @@ set_port_feature(int port, int feature, u32 endp)
req.wValue = feature;
req.wIndex = port;
req.wLength = 0;
- return send_default_control(endp, &req, NULL);
+ return send_default_control(pipe, &req, NULL);
}
static int
-clear_port_feature(int port, int feature, u32 endp)
+clear_port_feature(struct usb_pipe *pipe, int port, int feature)
{
struct usb_ctrlrequest req;
req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER;
@@ -42,11 +42,11 @@ clear_port_feature(int port, int feature, u32 endp)
req.wValue = feature;
req.wIndex = port;
req.wLength = 0;
- return send_default_control(endp, &req, NULL);
+ return send_default_control(pipe, &req, NULL);
}
static int
-get_port_status(int port, struct usb_port_status *sts, u32 endp)
+get_port_status(struct usb_pipe *pipe, int port, struct usb_port_status *sts)
{
struct usb_ctrlrequest req;
req.bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER;
@@ -54,25 +54,25 @@ get_port_status(int port, struct usb_port_status *sts, u32 endp)
req.wValue = 0;
req.wIndex = port;
req.wLength = sizeof(*sts);
- return send_default_control(endp, &req, sts);
+ return send_default_control(pipe, &req, sts);
}
// Configure a usb hub and then find devices connected to it.
int
-usb_hub_init(u32 endp)
+usb_hub_init(struct usb_pipe *pipe)
{
if (!CONFIG_USB_HUB)
- return 0;
+ return -1;
struct usb_hub_descriptor desc;
- int ret = get_hub_desc(&desc, endp);
+ int ret = get_hub_desc(pipe, &desc);
if (ret)
return ret;
// Turn on power to all ports.
int i;
for (i=1; i<=desc.bNbrPorts; i++) {
- ret = set_port_feature(i, USB_PORT_FEAT_POWER, endp);
+ ret = set_port_feature(pipe, i, USB_PORT_FEAT_POWER);
if (ret)
goto fail;
}
@@ -83,11 +83,11 @@ usb_hub_init(u32 endp)
// possibly wait USB_TIME_ATTDB.
// Detect down stream devices.
- struct usb_s *cntl = endp2cntl(endp);
+ struct usb_s *cntl = endp2cntl(pipe->endp);
int totalcount = 0;
for (i=1; i<=desc.bNbrPorts; i++) {
struct usb_port_status sts;
- ret = get_port_status(i, &sts, endp);
+ ret = get_port_status(pipe, i, &sts);
if (ret)
goto fail;
if (!(sts.wPortStatus & USB_PORT_STAT_CONNECTION))
@@ -95,14 +95,14 @@ usb_hub_init(u32 endp)
continue;
// Reset port.
- ret = set_port_feature(i, USB_PORT_FEAT_RESET, endp);
+ ret = set_port_feature(pipe, i, USB_PORT_FEAT_RESET);
if (ret)
goto fail;
// Wait for reset to complete.
u64 end = calc_future_tsc(USB_TIME_DRST * 2);
for (;;) {
- ret = get_port_status(i, &sts, endp);
+ ret = get_port_status(pipe, i, &sts);
if (ret)
goto fail;
if (!(sts.wPortStatus & USB_PORT_STAT_RESET))
@@ -123,16 +123,19 @@ usb_hub_init(u32 endp)
cntl, !!(sts.wPortStatus & USB_PORT_STAT_LOW_SPEED));
if (! count) {
// Shutdown port
- ret = clear_port_feature(i, USB_PORT_FEAT_ENABLE, endp);
+ ret = clear_port_feature(pipe, i, USB_PORT_FEAT_ENABLE);
if (ret)
goto fail;
}
totalcount += count;
}
- return totalcount;
+ dprintf(1, "Initialized USB HUB (%d ports used)\n", totalcount);
+ if (totalcount)
+ return 0;
+ return -1;
fail:
dprintf(1, "Failure on hub setup\n");
- return 0;
+ return -1;
}