if (keyboard_pipe)
// XXX - this enables the first found keyboard (could be random)
return -1;
- dprintf(2, "usb_keyboard_setup %x\n", pipe->endp);
+ dprintf(2, "usb_keyboard_setup %p\n", pipe);
// Find intr in endpoint.
struct usb_endpoint_descriptor *epdesc = findEndPointDesc(
if (ret)
return -1;
- u32 inendp = mkendpFromDesc(pipe, epdesc);
- keyboard_pipe = alloc_intr_pipe(inendp, epdesc->bInterval);
+ keyboard_pipe = alloc_intr_pipe(pipe, epdesc);
if (!keyboard_pipe)
return -1;
struct usbhub_s hub;
memset(&hub, 0, sizeof(hub));
hub.pipe = pipe;
- hub.cntl = endp2cntl(pipe->endp);
+ hub.cntl = pipe->cntl;
hub.powerwait = desc.bPwrOn2PwrGood * 2;
// Launch a thread for every port.
iface, imax, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT);
if (!indesc || !outdesc)
goto fail;
- u32 inendp = mkendpFromDesc(pipe, indesc);
- struct usb_pipe *bulkin = alloc_bulk_pipe(inendp);
- u32 outendp = mkendpFromDesc(pipe, outdesc);
- struct usb_pipe *bulkout = alloc_bulk_pipe(outendp);
+ struct usb_pipe *bulkin = alloc_bulk_pipe(pipe, indesc);
+ struct usb_pipe *bulkout = alloc_bulk_pipe(pipe, outdesc);
if (!bulkin || !bulkout)
goto fail;
{
if (! CONFIG_USB_OHCI)
return;
+ dprintf(7, "ohci_free_pipe %p\n", p);
struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe);
- u32 endp = pipe->pipe.endp;
- dprintf(7, "ohci_free_pipe %x\n", endp);
- struct usb_s *cntl = endp2cntl(endp);
+ struct usb_s *cntl = pipe->pipe.cntl;
u32 *pos = &cntl->ohci.regs->ed_controlhead;
for (;;) {
}
struct usb_pipe *
-ohci_alloc_control_pipe(u32 endp)
+ohci_alloc_control_pipe(struct usb_pipe *dummy)
{
if (! CONFIG_USB_OHCI)
return NULL;
- struct usb_s *cntl = endp2cntl(endp);
- dprintf(7, "ohci_alloc_control_pipe %x\n", endp);
+ struct usb_s *cntl = dummy->cntl;
+ dprintf(7, "ohci_alloc_control_pipe %p\n", cntl);
// Allocate a queue head.
struct ohci_pipe *pipe = malloc_tmphigh(sizeof(*pipe));
}
memset(pipe, 0, sizeof(*pipe));
pipe->ed.hwINFO = ED_SKIP;
- pipe->pipe.endp = endp;
+ memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
// Add queue head to controller list.
pipe->ed.hwNextED = cntl->ohci.regs->ed_controlhead;
{
if (! CONFIG_USB_OHCI)
return -1;
+ dprintf(5, "ohci_control %p\n", p);
if (datasize > 4096) {
// XXX - should support larger sizes.
warn_noalloc();
return -1;
}
struct ohci_pipe *pipe = container_of(p, struct ohci_pipe, pipe);
- u32 endp = pipe->pipe.endp;
- dprintf(5, "ohci_control %x\n", endp);
- struct usb_s *cntl = endp2cntl(endp);
- int maxpacket = endp2maxsize(endp);
- int lowspeed = endp2speed(endp);
- int devaddr = endp2devaddr(endp) | (endp2ep(endp) << 7);
+ struct usb_s *cntl = pipe->pipe.cntl;
+ int maxpacket = pipe->pipe.maxpacket;
+ int lowspeed = pipe->pipe.lowspeed;
+ int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
// Setup transfer descriptors
struct ohci_td *tds = malloc_tmphigh(sizeof(*tds) * 3);
}
struct usb_pipe *
-ohci_alloc_intr_pipe(u32 endp, int frameexp)
+ohci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp)
{
if (! CONFIG_USB_OHCI)
return NULL;
+ struct usb_s *cntl = dummy->cntl;
+ dprintf(7, "ohci_alloc_intr_pipe %p %d\n", cntl, frameexp);
- dprintf(7, "ohci_alloc_intr_pipe %x %d\n", endp, frameexp);
if (frameexp > 5)
frameexp = 5;
- struct usb_s *cntl = endp2cntl(endp);
- int maxpacket = endp2maxsize(endp);
- int lowspeed = endp2speed(endp);
- int devaddr = endp2devaddr(endp) | (endp2ep(endp) << 7);
+ int maxpacket = dummy->maxpacket;
+ int lowspeed = dummy->lowspeed;
+ int devaddr = dummy->devaddr | (dummy->ep << 7);
// Determine number of entries needed for 2 timer ticks.
int ms = 1<<frameexp;
int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
pipe->data = data;
pipe->count = count;
pipe->tds = tds;
- pipe->pipe.endp = endp;
+ memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
return &pipe->pipe;
err:
// XXX - check for errors.
// Copy data.
- u32 endp = GET_FLATPTR(pipe->pipe.endp);
- int maxpacket = endp2maxsize(endp);
+ int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket);
void *pipedata = GET_FLATPTR(pipe->data);
void *intrdata = pipedata + maxpacket * pos;
memcpy_far(GET_SEG(SS), data
void ohci_init(void *data);
struct usb_pipe;
void ohci_free_pipe(struct usb_pipe *p);
-struct usb_pipe *ohci_alloc_control_pipe(u32 endp);
+struct usb_pipe *ohci_alloc_control_pipe(struct usb_pipe *dummy);
int ohci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
, void *data, int datasize);
-struct usb_pipe *ohci_alloc_intr_pipe(u32 endp, int frameexp);
-int ohci_poll_intr(struct usb_pipe *pipe, void *data);
+struct usb_pipe *ohci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp);
+int ohci_poll_intr(struct usb_pipe *p, void *data);
/****************************************************************
{
if (! CONFIG_USB_UHCI)
return;
+ dprintf(7, "uhci_free_pipe %p\n", p);
struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe);
- u32 endp = pipe->pipe.endp;
- dprintf(7, "uhci_free_pipe %x\n", endp);
- struct usb_s *cntl = endp2cntl(endp);
+ struct usb_s *cntl = pipe->pipe.cntl;
struct uhci_framelist *fl = cntl->uhci.framelist;
struct uhci_qh *pos = (void*)(fl->links[0] & ~UHCI_PTR_BITS);
}
struct usb_pipe *
-uhci_alloc_control_pipe(u32 endp)
+uhci_alloc_control_pipe(struct usb_pipe *dummy)
{
if (! CONFIG_USB_UHCI)
return NULL;
- struct usb_s *cntl = endp2cntl(endp);
- dprintf(7, "uhci_alloc_control_pipe %x\n", endp);
+ struct usb_s *cntl = dummy->cntl;
+ dprintf(7, "uhci_alloc_control_pipe %p\n", cntl);
// Allocate a queue head.
struct uhci_pipe *pipe = malloc_tmphigh(sizeof(*pipe));
warn_noalloc();
return NULL;
}
+ memset(pipe, 0, sizeof(*pipe));
pipe->qh.element = UHCI_PTR_TERM;
- pipe->next_td = 0;
- pipe->pipe.endp = endp;
+ memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
// Add queue head to controller list.
struct uhci_qh *control_qh = cntl->uhci.control_qh;
ASSERT32FLAT();
if (! CONFIG_USB_UHCI)
return -1;
+ dprintf(5, "uhci_control %p\n", p);
struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe);
- u32 endp = pipe->pipe.endp;
- dprintf(5, "uhci_control %x\n", endp);
- struct usb_s *cntl = endp2cntl(endp);
- int maxpacket = endp2maxsize(endp);
- int lowspeed = endp2speed(endp);
- int devaddr = endp2devaddr(endp) | (endp2ep(endp) << 7);
+ struct usb_s *cntl = pipe->pipe.cntl;
+ int maxpacket = pipe->pipe.maxpacket;
+ int lowspeed = pipe->pipe.lowspeed;
+ int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
// Setup transfer descriptors
int count = 2 + DIV_ROUND_UP(datasize, maxpacket);
}
struct usb_pipe *
-uhci_alloc_bulk_pipe(u32 endp)
+uhci_alloc_bulk_pipe(struct usb_pipe *dummy)
{
if (! CONFIG_USB_UHCI)
return NULL;
- struct usb_s *cntl = endp2cntl(endp);
- dprintf(7, "uhci_alloc_bulk_pipe %x\n", endp);
+ struct usb_s *cntl = dummy->cntl;
+ dprintf(7, "uhci_alloc_bulk_pipe %p\n", cntl);
// Allocate a queue head.
struct uhci_pipe *pipe = malloc_low(sizeof(*pipe));
warn_noalloc();
return NULL;
}
+ memset(pipe, 0, sizeof(*pipe));
pipe->qh.element = UHCI_PTR_TERM;
- pipe->next_td = 0;
- pipe->pipe.endp = endp;
+ memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
// Add queue head to controller list.
struct uhci_qh *bulk_qh = cntl->uhci.bulk_qh;
uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
{
struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe);
- u32 endp = GET_FLATPTR(pipe->pipe.endp);
- dprintf(7, "uhci_send_bulk qh=%p endp=%x dir=%d data=%p size=%d\n"
- , &pipe->qh, endp, dir, data, datasize);
- int maxpacket = endp2maxsize(endp);
- int lowspeed = endp2speed(endp);
- int devaddr = endp2devaddr(endp) | (endp2ep(endp) << 7);
- int toggle = (u32)GET_FLATPTR(pipe->next_td); // XXX
+ dprintf(7, "uhci_send_bulk qh=%p dir=%d data=%p size=%d\n"
+ , &pipe->qh, dir, data, datasize);
+ int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket);
+ int lowspeed = GET_FLATPTR(pipe->pipe.lowspeed);
+ int devaddr = (GET_FLATPTR(pipe->pipe.devaddr)
+ | (GET_FLATPTR(pipe->pipe.ep) << 7));
+ int toggle = GET_FLATPTR(pipe->pipe.toggle) ? TD_TOKEN_TOGGLE : 0;
// Allocate 4 tds on stack (16byte aligned)
u8 tdsbuf[sizeof(struct uhci_td) * STACKTDS + TDALIGN - 1];
goto fail;
}
- SET_FLATPTR(pipe->next_td, (void*)toggle); // XXX
+ SET_FLATPTR(pipe->pipe.toggle, !!toggle);
return 0;
fail:
dprintf(1, "uhci_send_bulk failed\n");
SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM);
- uhci_waittick(endp2cntl(endp));
+ uhci_waittick(GET_FLATPTR(pipe->pipe.cntl));
return -1;
}
struct usb_pipe *
-uhci_alloc_intr_pipe(u32 endp, int frameexp)
+uhci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp)
{
if (! CONFIG_USB_UHCI)
return NULL;
+ struct usb_s *cntl = dummy->cntl;
+ dprintf(7, "uhci_alloc_intr_pipe %p %d\n", cntl, frameexp);
- dprintf(7, "uhci_alloc_intr_pipe %x %d\n", endp, frameexp);
if (frameexp > 10)
frameexp = 10;
- struct usb_s *cntl = endp2cntl(endp);
- int maxpacket = endp2maxsize(endp);
- int lowspeed = endp2speed(endp);
- int devaddr = endp2devaddr(endp) | (endp2ep(endp) << 7);
+ int maxpacket = dummy->maxpacket;
+ int lowspeed = dummy->lowspeed;
+ int devaddr = dummy->devaddr | (dummy->ep << 7);
// Determine number of entries needed for 2 timer ticks.
int ms = 1<<frameexp;
int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
}
if (maxpacket > sizeof(tds[0].data))
goto fail;
+ memset(pipe, 0, sizeof(*pipe));
pipe->qh.element = (u32)tds;
+ pipe->next_td = &tds[0];
+ memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
+
int toggle = 0;
int i;
for (i=0; i<count; i++) {
toggle ^= TD_TOKEN_TOGGLE;
}
- pipe->next_td = &tds[0];
- pipe->pipe.endp = endp;
-
// Add to interrupt schedule.
struct uhci_framelist *fl = cntl->uhci.framelist;
if (frameexp == 0) {
// usb-uhci.c
void uhci_init(void *data);
struct usb_pipe;
-void uhci_free_pipe(struct usb_pipe *pipe);
-struct usb_pipe *uhci_alloc_control_pipe(u32 endp);
-int uhci_control(struct usb_pipe *pipe, int dir, const void *cmd, int cmdsize
+void uhci_free_pipe(struct usb_pipe *p);
+struct usb_pipe *uhci_alloc_control_pipe(struct usb_pipe *dummy);
+int uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
, void *data, int datasize);
-struct usb_pipe *uhci_alloc_bulk_pipe(u32 endp);
-int uhci_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize);
-struct usb_pipe *uhci_alloc_intr_pipe(u32 endp, int frameexp);
-int uhci_poll_intr(struct usb_pipe *pipe, void *data);
+struct usb_pipe *uhci_alloc_bulk_pipe(struct usb_pipe *dummy);
+int uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize);
+struct usb_pipe *uhci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp);
+int uhci_poll_intr(struct usb_pipe *p, void *data);
/****************************************************************
ASSERT32FLAT();
if (!pipe)
return;
- struct usb_s *cntl = endp2cntl(pipe->endp);
- switch (cntl->type) {
+ switch (pipe->type) {
default:
case USB_TYPE_UHCI:
return uhci_free_pipe(pipe);
}
}
-// Allocate a control pipe (which can only be used by 32bit code)
+// Allocate a control pipe to a default endpoint (which can only be
+// used by 32bit code)
static struct usb_pipe *
-alloc_control_pipe(u32 endp)
+alloc_default_control_pipe(struct usb_pipe *dummy)
{
- struct usb_s *cntl = endp2cntl(endp);
- switch (cntl->type) {
+ switch (dummy->type) {
default:
case USB_TYPE_UHCI:
- return uhci_alloc_control_pipe(endp);
+ return uhci_alloc_control_pipe(dummy);
case USB_TYPE_OHCI:
- return ohci_alloc_control_pipe(endp);
+ return ohci_alloc_control_pipe(dummy);
}
}
, void *data, int datasize)
{
ASSERT32FLAT();
- struct usb_s *cntl = endp2cntl(pipe->endp);
- switch (cntl->type) {
+ switch (pipe->type) {
default:
case USB_TYPE_UHCI:
return uhci_control(pipe, dir, cmd, cmdsize, data, datasize);
}
}
+// Fill "pipe" endpoint info from an endpoint descriptor.
+static void
+desc2pipe(struct usb_pipe *newpipe, struct usb_pipe *origpipe
+ , struct usb_endpoint_descriptor *epdesc)
+{
+ memcpy(newpipe, origpipe, sizeof(*newpipe));
+ newpipe->ep = epdesc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ newpipe->maxpacket = epdesc->wMaxPacketSize;
+}
+
struct usb_pipe *
-alloc_bulk_pipe(u32 endp)
+alloc_bulk_pipe(struct usb_pipe *pipe, struct usb_endpoint_descriptor *epdesc)
{
- struct usb_s *cntl = endp2cntl(endp);
- switch (cntl->type) {
+ struct usb_pipe dummy;
+ desc2pipe(&dummy, pipe, epdesc);
+ switch (pipe->type) {
default:
case USB_TYPE_UHCI:
- return uhci_alloc_bulk_pipe(endp);
+ return uhci_alloc_bulk_pipe(&dummy);
case USB_TYPE_OHCI:
return NULL;
}
}
int
-usb_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize)
+usb_send_bulk(struct usb_pipe *pipe_fl, int dir, void *data, int datasize)
{
- u32 endp = GET_FLATPTR(pipe->endp);
- struct usb_s *cntl = endp2cntl(endp);
- switch (cntl->type) {
+ switch (GET_FLATPTR(pipe_fl->type)) {
default:
case USB_TYPE_UHCI:
- return uhci_send_bulk(pipe, dir, data, datasize);
+ return uhci_send_bulk(pipe_fl, dir, data, datasize);
case USB_TYPE_OHCI:
return -1;
}
}
struct usb_pipe *
-alloc_intr_pipe(u32 endp, int period)
+alloc_intr_pipe(struct usb_pipe *pipe, struct usb_endpoint_descriptor *epdesc)
{
- struct usb_s *cntl = endp2cntl(endp);
+ struct usb_pipe dummy;
+ desc2pipe(&dummy, pipe, epdesc);
// Find the exponential period of the requested time.
+ int period = epdesc->bInterval;
if (period <= 0)
period = 1;
int frameexp = __fls(period);
- switch (cntl->type) {
+ switch (pipe->type) {
default:
case USB_TYPE_UHCI:
- return uhci_alloc_intr_pipe(endp, frameexp);
+ return uhci_alloc_intr_pipe(&dummy, frameexp);
case USB_TYPE_OHCI:
- return ohci_alloc_intr_pipe(endp, frameexp);
+ return ohci_alloc_intr_pipe(&dummy, frameexp);
}
}
int noinline
-usb_poll_intr(struct usb_pipe *pipe, void *data)
+usb_poll_intr(struct usb_pipe *pipe_fl, void *data)
{
- u32 endp = GET_FLATPTR(pipe->endp);
- struct usb_s *cntl = endp2cntl(endp);
- switch (GET_GLOBAL(cntl->type)) {
+ switch (GET_FLATPTR(pipe_fl->type)) {
default:
case USB_TYPE_UHCI:
- return uhci_poll_intr(pipe, data);
+ return uhci_poll_intr(pipe_fl, data);
case USB_TYPE_OHCI:
- return ohci_poll_intr(pipe, data);
+ return ohci_poll_intr(pipe_fl, data);
}
}
}
}
-// Change endpoint characteristics of the default control pipe.
-static void
-usb_alter_control(struct usb_pipe *pipe, u32 endp)
-{
- pipe->endp = endp;
-}
-
-// Build an encoded "endp" from an endpoint descriptor.
-u32
-mkendpFromDesc(struct usb_pipe *pipe, struct usb_endpoint_descriptor *epdesc)
-{
- u32 endp = pipe->endp;
- return mkendp(endp2cntl(endp), endp2devaddr(endp)
- , epdesc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK
- , endp2speed(endp), epdesc->wMaxPacketSize);
-}
-
// Send a message to the default control pipe of a device.
int
send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *req
return NULL;
struct usb_pipe *defpipe = cntl->defaultpipe;
- u32 endp = mkendp(cntl, 0, 0, lowspeed, 8);
if (!defpipe) {
- cntl->defaultpipe = defpipe = alloc_control_pipe(endp);
+ // Create a pipe for the default address.
+ struct usb_pipe dummy;
+ memset(&dummy, 0, sizeof(dummy));
+ dummy.cntl = cntl;
+ dummy.type = cntl->type;
+ dummy.maxpacket = 8;
+ cntl->defaultpipe = defpipe = alloc_default_control_pipe(&dummy);
if (!defpipe)
return NULL;
}
- usb_alter_control(defpipe, endp);
+ defpipe->lowspeed = lowspeed;
msleep(USB_TIME_RSTRCY);
msleep(USB_TIME_SETADDR_RECOVERY);
cntl->maxaddr++;
- endp = mkendp(cntl, cntl->maxaddr, 0, lowspeed, 8);
- return alloc_control_pipe(endp);
+ defpipe->devaddr = cntl->maxaddr;
+ struct usb_pipe *pipe = alloc_default_control_pipe(defpipe);
+ defpipe->devaddr = 0;
+ return pipe;
}
// Called for every found device - see if a driver is available for
configure_usb_device(struct usb_pipe *pipe)
{
ASSERT32FLAT();
- struct usb_s *cntl = endp2cntl(pipe->endp);
- dprintf(3, "config_usb: %p\n", cntl);
+ dprintf(3, "config_usb: %p\n", pipe);
// Set the max packet size for endpoint 0 of this device.
struct usb_device_descriptor dinfo;
, dinfo.bDeviceProtocol, dinfo.bMaxPacketSize0);
if (dinfo.bMaxPacketSize0 < 8 || dinfo.bMaxPacketSize0 > 64)
return 0;
- u32 endp = mkendp(cntl, endp2devaddr(pipe->endp), 0
- , endp2speed(pipe->endp), dinfo.bMaxPacketSize0);
- usb_alter_control(pipe, endp);
+ pipe->maxpacket = dinfo.bMaxPacketSize0;
// Get configuration
struct usb_config_descriptor *config = get_device_config(pipe);
#include "util.h" // struct mutex_s
struct usb_pipe {
- u32 endp;
+ struct usb_s *cntl;
+ u8 type;
+ u8 ep;
+ u8 devaddr;
+ u8 lowspeed;
+ u16 maxpacket;
+ u8 toggle;
};
// Local information for a usb controller.
#define USB_MAXADDR 127
-// usb.c
-void usb_setup(void);
-struct usb_pipe *usb_set_address(struct usb_s *cntl, int lowspeed);
-int configure_usb_device(struct usb_pipe *pipe);
-struct usb_ctrlrequest;
-int send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *req
- , void *data);
-int usb_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize);
-void free_pipe(struct usb_pipe *pipe);
-struct usb_pipe *alloc_bulk_pipe(u32 endp);
-struct usb_pipe *alloc_intr_pipe(u32 endp, int period);
-int usb_poll_intr(struct usb_pipe *pipe, void *data);
-struct usb_interface_descriptor;
-struct usb_endpoint_descriptor *findEndPointDesc(
- struct usb_interface_descriptor *iface, int imax, int type, int dir);
-u32 mkendpFromDesc(struct usb_pipe *pipe
- , struct usb_endpoint_descriptor *epdesc);
-
-
-/****************************************************************
- * endpoint definition
- ****************************************************************/
-
-static inline u32
-mkendp(struct usb_s *cntl, u8 devaddr, u8 ep, u8 lowspeed, u8 maxsize)
-{
- u8 bus = cntl-USBControllers;
- u8 size = __ffs(maxsize);
- return (size<<25) | (lowspeed<<24) | (bus<<16) | (devaddr<<8) | ep;
-}
-
-static inline u8 endp2ep(u32 endp) {
- return endp;
-}
-static inline u8 endp2devaddr(u32 endp) {
- return endp>>8;
-}
-static inline struct usb_s *endp2cntl(u32 endp) {
- u8 bus = endp>>16;
- return &USBControllers[bus];
-}
-static inline u8 endp2speed(u32 endp) {
- return (endp>>24) & 1;
-}
-static inline u8 endp2maxsize(u32 endp) {
- return 1 << (endp>>25);
-}
-
/****************************************************************
* usb structs and flags
#define USB_ENDPOINT_XFER_INT 3
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
+
+/****************************************************************
+ * function defs
+ ****************************************************************/
+
+// usb.c
+void usb_setup(void);
+struct usb_pipe *usb_set_address(struct usb_s *cntl, int lowspeed);
+int configure_usb_device(struct usb_pipe *pipe);
+int send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *req
+ , void *data);
+int usb_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize);
+void free_pipe(struct usb_pipe *pipe);
+struct usb_pipe *alloc_bulk_pipe(struct usb_pipe *pipe
+ , struct usb_endpoint_descriptor *epdesc);
+struct usb_pipe *alloc_intr_pipe(struct usb_pipe *pipe
+ , struct usb_endpoint_descriptor *epdesc);
+int usb_poll_intr(struct usb_pipe *pipe, void *data);
+struct usb_endpoint_descriptor *findEndPointDesc(
+ struct usb_interface_descriptor *iface, int imax, int type, int dir);
+u32 mkendpFromDesc(struct usb_pipe *pipe
+ , struct usb_endpoint_descriptor *epdesc);
+
#endif // usb.h