Add functions to execute asynchronous requests and use these from
interrupt context. [I had some feline debugging help here. I noticed that every time Kem, our kitty, jumped onto the USB keyboard the machine crashed.]
This commit is contained in:
parent
f453d02883
commit
a0803787f7
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ukbd.c,v 1.3 1998/07/26 17:42:49 augustss Exp $ */
|
||||
/* $NetBSD: ukbd.c,v 1.4 1998/07/29 20:50:11 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -141,8 +141,6 @@ struct ukbd_softc {
|
|||
struct ukbd_data sc_ndata;
|
||||
struct ukbd_data sc_odata;
|
||||
|
||||
int sc_state;
|
||||
#define UKBD_NEEDCLEAR 0x01 /* needs clearing endpoint stall */
|
||||
int sc_disconnected; /* device is gone */
|
||||
|
||||
int sc_leds;
|
||||
|
@ -308,7 +306,7 @@ ukbd_intr(reqh, addr, status)
|
|||
|
||||
if (status != USBD_NORMAL_COMPLETION) {
|
||||
DPRINTF(("ukbd_intr: status=%d\n", status));
|
||||
sc->sc_state |= UKBD_NEEDCLEAR;
|
||||
usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -391,7 +389,7 @@ ukbd_set_leds(v, leds)
|
|||
res |= NUM_LOCK;
|
||||
if (leds & WSKBD_LED_CAPS)
|
||||
res |= CAPS_LOCK;
|
||||
usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT, 0, &res, 1);
|
||||
usbd_set_report_async(sc->sc_iface, UHID_OUTPUT_REPORT, 0, &res, 1);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -432,7 +430,9 @@ ukbd_cngetc(v, type, data)
|
|||
struct ukbd_softc *sc = v;
|
||||
usbd_lock_token s;
|
||||
extern int usbd_use_polling;
|
||||
int c;
|
||||
|
||||
DPRINTFN(1,("ukbd_cngetc: enter\n"));
|
||||
s = usbd_lock();
|
||||
usbd_use_polling = 1;
|
||||
sc->sc_polling = 1;
|
||||
|
@ -441,9 +441,11 @@ ukbd_cngetc(v, type, data)
|
|||
usbd_dopoll(sc->sc_iface);
|
||||
sc->sc_polling = 0;
|
||||
usbd_use_polling = 0;
|
||||
*type = sc->sc_pollchar&0x80?WSCONS_EVENT_KEY_UP:WSCONS_EVENT_KEY_DOWN;
|
||||
*data = sc->sc_pollchar & 0x7f;
|
||||
c = sc->sc_pollchar;
|
||||
*type = c & 0x80 ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
|
||||
*data = c & 0x7f;
|
||||
usbd_unlock(s);
|
||||
DPRINTFN(1,("ukbd_cngetc: return 0x%02x\n", c));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -451,5 +453,5 @@ ukbd_cnpollc(v, on)
|
|||
void *v;
|
||||
int on;
|
||||
{
|
||||
DPRINTF(("ukbd_cnpollc: sc=%p on=%d\n", v, on));
|
||||
DPRINTFN(1,("ukbd_cnpollc: sc=%p on=%d\n", v, on));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ums.c,v 1.6 1998/07/28 21:21:47 augustss Exp $ */
|
||||
/* $NetBSD: ums.c,v 1.7 1998/07/29 20:50:12 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -91,8 +91,6 @@ struct ums_softc {
|
|||
struct hid_location sc_loc_x, sc_loc_y, sc_loc_z,
|
||||
sc_loc_btn1, sc_loc_btn2, sc_loc_btn3;
|
||||
|
||||
u_char sc_state; /* mouse driver state */
|
||||
#define UMS_NEEDCLEAR 0x04 /* needs clearing endpoint stall */
|
||||
u_char sc_buttons; /* mouse button status */
|
||||
int sc_disconnected; /* device is gone */
|
||||
|
||||
|
@ -294,7 +292,7 @@ ums_intr(reqh, addr, status)
|
|||
|
||||
if (status != USBD_NORMAL_COMPLETION) {
|
||||
DPRINTF(("ums_intr: status=%d\n", status));
|
||||
sc->sc_state |= UMS_NEEDCLEAR;
|
||||
usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: usbdi.c,v 1.6 1998/07/26 17:42:49 augustss Exp $ */
|
||||
/* $NetBSD: usbdi.c,v 1.7 1998/07/29 20:50:12 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -66,6 +66,8 @@ static void usbd_transfer_cb __P((usbd_request_handle reqh));
|
|||
static void usbd_sync_transfer_cb __P((usbd_request_handle reqh));
|
||||
static usbd_status usbd_do_transfer __P((usbd_request_handle reqh));
|
||||
static usbd_status usbd_start __P((usbd_pipe_handle pipe));
|
||||
void usbd_do_request_async_cb
|
||||
__P((usbd_request_handle, usbd_private_handle, usbd_status));
|
||||
|
||||
static SIMPLEQ_HEAD(, usbd_request) usbd_free_requests;
|
||||
|
||||
|
@ -479,7 +481,7 @@ usbd_clear_endpoint_stall(pipe)
|
|||
req.bmRequestType = UT_WRITE_ENDPOINT;
|
||||
req.bRequest = UR_CLEAR_FEATURE;
|
||||
USETW(req.wValue, UF_ENDPOINT_STALL);
|
||||
USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); /* XXX mask/ */
|
||||
USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
|
||||
USETW(req.wLength, 0);
|
||||
r = usbd_do_request(dev, &req, 0);
|
||||
#if 0
|
||||
|
@ -492,6 +494,23 @@ XXX should we do this?
|
|||
return (r);
|
||||
}
|
||||
|
||||
usbd_status
|
||||
usbd_clear_endpoint_stall_async(pipe)
|
||||
usbd_pipe_handle pipe;
|
||||
{
|
||||
usbd_device_handle dev = pipe->device;
|
||||
usb_device_request_t req;
|
||||
usbd_status r;
|
||||
|
||||
req.bmRequestType = UT_WRITE_ENDPOINT;
|
||||
req.bRequest = UR_CLEAR_FEATURE;
|
||||
USETW(req.wValue, UF_ENDPOINT_STALL);
|
||||
USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
|
||||
USETW(req.wLength, 0);
|
||||
r = usbd_do_request_async(dev, &req, 0);
|
||||
return (r);
|
||||
}
|
||||
|
||||
usbd_status
|
||||
usbd_set_pipe_state(pipe, state)
|
||||
usbd_pipe_handle pipe;
|
||||
|
@ -914,6 +933,13 @@ usbd_do_request(dev, req, data)
|
|||
usbd_request_handle reqh;
|
||||
usbd_status r;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (!curproc) {
|
||||
printf("usbd_do_request: not in process context\n");
|
||||
return (USBD_XXX);
|
||||
}
|
||||
#endif
|
||||
|
||||
reqh = usbd_alloc_request();
|
||||
if (reqh == 0)
|
||||
return (USBD_NOMEM);
|
||||
|
@ -938,6 +964,54 @@ usbd_do_request(dev, req, data)
|
|||
return (r);
|
||||
}
|
||||
|
||||
void
|
||||
usbd_do_request_async_cb(reqh, priv, status)
|
||||
usbd_request_handle reqh;
|
||||
usbd_private_handle priv;
|
||||
usbd_status status;
|
||||
{
|
||||
#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
|
||||
if (reqh->actlen > reqh->length)
|
||||
printf("usbd_do_request: overrun addr=%d type=0x%02x req=0x%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
|
||||
reqh->pipe->device->address,
|
||||
reqh->request.bmRequestType,
|
||||
reqh->request.bRequest, UGETW(reqh->request.wValue),
|
||||
UGETW(reqh->request.wIndex),
|
||||
UGETW(reqh->request.wLength),
|
||||
reqh->length, reqh->actlen);
|
||||
#endif
|
||||
usbd_free_request(reqh);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a request without waiting for completion.
|
||||
* Can be used from interrupt context.
|
||||
*/
|
||||
usbd_status
|
||||
usbd_do_request_async(dev, req, data)
|
||||
usbd_device_handle dev;
|
||||
usb_device_request_t *req;
|
||||
void *data;
|
||||
{
|
||||
usbd_request_handle reqh;
|
||||
usbd_status r;
|
||||
|
||||
reqh = usbd_alloc_request();
|
||||
if (reqh == 0)
|
||||
return (USBD_NOMEM);
|
||||
r = usbd_setup_default_request(
|
||||
reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data,
|
||||
UGETW(req->wLength), 0, usbd_do_request_async_cb);
|
||||
if (r != USBD_NORMAL_COMPLETION) {
|
||||
usbd_free_request(reqh);
|
||||
return (r);
|
||||
}
|
||||
r = usbd_transfer(reqh);
|
||||
if (r != USBD_IN_PROGRESS)
|
||||
return (r);
|
||||
return (USBD_NORMAL_COMPLETION);
|
||||
}
|
||||
|
||||
struct usbd_quirks *
|
||||
usbd_get_quirks(dev)
|
||||
usbd_device_handle dev;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: usbdi.h,v 1.3 1998/07/26 17:42:49 augustss Exp $ */
|
||||
/* $NetBSD: usbdi.h,v 1.4 1998/07/29 20:50:12 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -150,6 +150,7 @@ usbd_status usbd_abort_interface __P((usbd_interface_handle iface));
|
|||
usbd_status usbd_reset_pipe __P((usbd_pipe_handle pipe));
|
||||
usbd_status usbd_reset_interface __P((usbd_interface_handle iface));
|
||||
usbd_status usbd_clear_endpoint_stall __P((usbd_pipe_handle pipe));
|
||||
usbd_status usbd_clear_endpoint_stall_async __P((usbd_pipe_handle pipe));
|
||||
usbd_status usbd_set_pipe_state
|
||||
__P((usbd_pipe_handle pipe, usbd_pipe_state state));
|
||||
usbd_status usbd_get_pipe_state
|
||||
|
@ -207,6 +208,8 @@ usbd_status usbd_open_pipe_intr
|
|||
u_int32_t length, usbd_callback));
|
||||
usbd_status usbd_do_request
|
||||
__P((usbd_device_handle pipe, usb_device_request_t *req, void *data));
|
||||
usbd_status usbd_do_request_async
|
||||
__P((usbd_device_handle pipe, usb_device_request_t *req, void *data));
|
||||
usb_interface_descriptor_t *usbd_get_interface_descriptor
|
||||
__P((usbd_interface_handle iface));
|
||||
usb_config_descriptor_t *usbd_get_config_descriptor
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: usbdi_util.c,v 1.2 1998/07/13 10:49:42 augustss Exp $ */
|
||||
/* $NetBSD: usbdi_util.c,v 1.3 1998/07/29 20:50:12 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -258,6 +258,33 @@ usbd_set_report(iface, type, id, data, len)
|
|||
return (usbd_do_request(dev, &req, data));
|
||||
}
|
||||
|
||||
usbd_status
|
||||
usbd_set_report_async(iface, type, id, data, len)
|
||||
usbd_interface_handle iface;
|
||||
int type;
|
||||
int id;
|
||||
void *data;
|
||||
int len;
|
||||
{
|
||||
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
|
||||
usbd_device_handle dev;
|
||||
usb_device_request_t req;
|
||||
usbd_status r;
|
||||
|
||||
DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
|
||||
r = usbd_interface2device_handle(iface, &dev);
|
||||
if (r != USBD_NORMAL_COMPLETION)
|
||||
return (r);
|
||||
if (!ifd)
|
||||
return (USBD_INVAL);
|
||||
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
|
||||
req.bRequest = UR_SET_REPORT;
|
||||
USETW2(req.wValue, type, id);
|
||||
USETW(req.wIndex, ifd->bInterfaceNumber);
|
||||
USETW(req.wLength, len);
|
||||
return (usbd_do_request_async(dev, &req, data));
|
||||
}
|
||||
|
||||
usbd_status
|
||||
usbd_get_report(iface, type, id, data, len)
|
||||
usbd_interface_handle iface;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: usbdi_util.h,v 1.2 1998/07/13 10:49:42 augustss Exp $ */
|
||||
/* $NetBSD: usbdi_util.h,v 1.3 1998/07/29 20:50:12 augustss Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -57,9 +57,11 @@ usbd_status usbd_get_report_descriptor
|
|||
struct usb_hid_descriptor *usbd_get_hid_descriptor
|
||||
__P((usbd_interface_handle ifc));
|
||||
usbd_status usbd_set_report
|
||||
__P((usbd_interface_handle iface, int type, int id, void *data, int len));
|
||||
__P((usbd_interface_handle iface,int type,int id,void *data,int len));
|
||||
usbd_status usbd_set_report_async
|
||||
__P((usbd_interface_handle iface,int type,int id,void *data,int len));
|
||||
usbd_status usbd_get_report
|
||||
__P((usbd_interface_handle iface, int type, int id, void *data, int len));
|
||||
__P((usbd_interface_handle iface,int type,int id,void *data,int len));
|
||||
usbd_status usbd_set_idle
|
||||
__P((usbd_interface_handle iface, int duration, int id));
|
||||
usbd_status usbd_alloc_report_desc
|
||||
|
|
Loading…
Reference in New Issue