1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-13 14:40:22 +00:00

Synchronisation with NetBSD as of 1999/11/16:

Cleaning up the code:
- Declare many functions static
- Change variable names to make them more self explanatory
- Change usbd_request_handle -> usbd_xfer_handle
- Syntactical changes
- Remove some unused code
- Other KNF changes

Interrupt context handling
- Change delay to usbd_delay_ms were possible (takes polling mode into
  account)
- Change detection mechanism for interrupt context

Add support for pre-allocation DMA-able memory by device driver

Add preliminary support for isochronous to the UHCI driver (not for OHCI
yet).

usb.c, uhci.c, ohci.c
- Initial attempt at detachable USB host controllers
- Handle the use_polling flag with a lttle more care and only set it if
we are cold booting.

usb.c, uhci.c ohci.c, usbdi.c usbdi_util.c usb_subr.c
- Make sure an aborted pipe is marked as not running.
- Start queued request in the right order.
- Insert some more DIAGNOSTIC sanity checks.
- Remove (almost) unused definitions USBD_XFER_OUT and USBD_XFER_IN.

usb.c, usb_subr.c
- Add an event mechanism so that a userland process can watch devices
  come and go.

ohci.c
- Handle the case when a USB transfer is so long that it crosses two
  page (4K) boundaries.  OHCI cannot do that with a single TD so we make
  a chain.

ulpt.c
- Use a bigger buffer when transferring data.
- Pre-allocate the DMA buffer.  This makes the driver slightly more
  efficient.
- Comment out the GET_DEVICE_ID code, because for some unknown reason it
  causes printing to fail sometimes.

usb.h
- Add a macro to extract the isoc type.
- Add a macro to check whether the routine has been entered after splusb
  and if not, complain.

usbdi.c
- Fix a glitch in dequeueing and aborting requests on interrupt pipes.
- Add a flag in the request to determine if the data copying is done by
  the driver or the usbdi layer.
This commit is contained in:
Nick Hibma 1999-11-17 22:33:51 +00:00
parent 6a54425c86
commit 3241be7550
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=53313
30 changed files with 2905 additions and 2163 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: hid.c,v 1.8 1999/08/14 14:49:31 augustss Exp $ */
/* $NetBSD: hid.c,v 1.9 1999/10/13 08:10:55 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -111,7 +111,7 @@ void
hid_end_parse(s)
struct hid_data *s;
{
while (s->cur.next) {
while (s->cur.next != NULL) {
struct hid_item *hi = s->cur.next->next;
free(s->cur.next, M_TEMP);
s->cur.next = hi;
@ -133,7 +133,7 @@ hid_get_item(s, h)
int i;
top:
if (s->multimax) {
if (s->multimax != 0) {
if (s->multi < s->multimax) {
c->usage = s->usages[min(s->multi, s->nu-1)];
s->multi++;
@ -380,11 +380,11 @@ hid_report_size(buf, len, k, idp)
id = 0;
for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); )
if (h.report_ID)
if (h.report_ID != 0)
id = h.report_ID;
hid_end_parse(d);
size = h.loc.pos;
if (id) {
if (id != 0) {
size += 8;
*idp = id; /* XXX wrong */
} else
@ -406,9 +406,9 @@ hid_locate(desc, size, u, k, loc, flags)
for (d = hid_start_parse(desc, size, 1<<k); hid_get_item(d, &h); ) {
if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) {
if (loc)
if (loc != NULL)
*loc = h.loc;
if (flags)
if (flags != NULL)
*flags = h.flags;
hid_end_parse(d);
return (1);
@ -456,15 +456,15 @@ hid_is_collection(desc, size, usage)
{
struct hid_data *hd;
struct hid_item hi;
int r;
int err;
hd = hid_start_parse(desc, size, hid_input);
if (!hd)
if (hd == NULL)
return (0);
r = hid_get_item(hd, &hi) &&
err = hid_get_item(hd, &hi) &&
hi.kind == hid_collection &&
hi.usage == usage;
hid_end_parse(hd);
return (r);
return (err);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: hid.h,v 1.3 1998/11/25 22:32:04 augustss Exp $ */
/* $NetBSD: hid.h,v 1.2 1998/07/24 20:57:46 augustss Exp $ */
/* $FreeBSD$ */
/*

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/* $NetBSD: ohcireg.h,v 1.8 1999/08/22 23:41:00 augustss Exp $ */
/* $FreeBSD$ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -140,6 +141,9 @@ struct ohci_hcca {
#define OHCI_HCCA_SIZE 256
#define OHCI_HCCA_ALIGN 256
#define OHCI_PAGE_SIZE 0x1000
#define OHCI_PAGE(x) ((x) &~ 0xfff)
typedef struct {
u_int32_t ed_flags;
#define OHCI_ED_GET_FA(s) ((s) & 0x7f)

View File

@ -1,5 +1,5 @@
/* $NetBSD: ohcivar.h,v 1.8 1999/08/22 23:41:00 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: ohcivar.h,v 1.13 1999/10/13 08:10:55 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -52,11 +52,11 @@ typedef struct ohci_soft_td {
struct ohci_soft_td *dnext; /* next in done list */
ohci_physaddr_t physaddr;
LIST_ENTRY(ohci_soft_td) hnext;
usbd_request_handle reqh;
usbd_xfer_handle xfer;
u_int16_t len;
u_int16_t flags;
#define OHCI_CALL_DONE 0x0001
#define OHCI_SET_LEN 0x0002
#define OHCI_ADD_LEN 0x0002
} ohci_soft_td_t;
#define OHCI_STD_SIZE ((sizeof (struct ohci_soft_td) + OHCI_TD_ALIGN - 1) / OHCI_TD_ALIGN * OHCI_TD_ALIGN)
#define OHCI_STD_CHUNK 128
@ -69,12 +69,6 @@ typedef struct ohci_softc {
struct usbd_bus sc_bus; /* base device */
bus_space_tag_t iot;
bus_space_handle_t ioh;
#if defined(__NetBSD__) || defined(__OpenBSD__)
void *sc_ih; /* interrupt vectoring */
bus_dma_tag_t sc_dmatag; /* DMA tag */
/* XXX should keep track of all DMA memory */
#endif /* __NetBSD__ || defined(__OpenBSD__) */
usb_dma_t sc_hccadma;
struct ohci_hcca *sc_hcca;
@ -94,15 +88,20 @@ typedef struct ohci_softc {
ohci_soft_ed_t *sc_freeeds;
ohci_soft_td_t *sc_freetds;
usbd_request_handle sc_intrreqh;
int sc_intrs;
usbd_xfer_handle sc_intrxfer;
char sc_vendor[16];
int sc_id_vendor;
void *sc_powerhook;
device_ptr_t sc_child;
} ohci_softc_t;
usbd_status ohci_init __P((ohci_softc_t *));
int ohci_intr __P((void *));
#if defined(__NetBSD__) || defined(__OpenBSD__)
int ohci_detach __P((ohci_softc_t *, int));
int ohci_activate __P((device_ptr_t, enum devact));
#endif
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ugen.c,v 1.23 1999/09/09 12:26:44 augustss Exp $ */
/* $NetBSD: ugen.c,v 1.27 1999/10/28 12:08:38 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -97,7 +97,7 @@ struct ugen_softc {
USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_udev;
char sc_is_open[USB_MAX_ENDPOINTS][2];
char sc_is_open[USB_MAX_ENDPOINTS];
struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
#define OUT 0
#define IN 1
@ -136,18 +136,18 @@ static struct cdevsw ugen_cdevsw = {
};
#endif
void ugenintr __P((usbd_request_handle reqh, usbd_private_handle addr,
usbd_status status));
static void ugenintr __P((usbd_xfer_handle xfer, usbd_private_handle addr,
usbd_status status));
int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int));
int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int));
int ugen_do_ioctl __P((struct ugen_softc *, int, u_long,
caddr_t, int, struct proc *));
int ugen_set_config __P((struct ugen_softc *sc, int configno));
usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, int index,
int *lenp));
usbd_status ugen_set_interface __P((struct ugen_softc *, int, int));
int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx));
static int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int));
static int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int));
static int ugen_do_ioctl __P((struct ugen_softc *, int, u_long,
caddr_t, int, struct proc *));
static int ugen_set_config __P((struct ugen_softc *sc, int configno));
static usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc,
int index, int *lenp));
static usbd_status ugen_set_interface __P((struct ugen_softc *, int, int));
static int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx));
#define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
#define UGENENDPOINT(n) (minor(n) & 0xf)
@ -169,7 +169,7 @@ USB_ATTACH(ugen)
{
USB_ATTACH_START(ugen, sc, uaa);
char devinfo[1024];
usbd_status r;
usbd_status err;
int conf;
usbd_devinfo(uaa->device, 0, devinfo);
@ -178,8 +178,8 @@ USB_ATTACH(ugen)
sc->sc_udev = uaa->device;
conf = 1; /* XXX should not hard code 1 */
r = ugen_set_config(sc, conf);
if (r != USBD_NORMAL_COMPLETION) {
err = ugen_set_config(sc, conf);
if (err) {
printf("%s: setting configuration %d failed\n",
USBDEVNAME(sc->sc_dev), conf);
sc->sc_dying = 1;
@ -195,10 +195,11 @@ USB_ATTACH(ugen)
}
}
#endif
USB_ATTACH_SUCCESS_RETURN;
}
int
static int
ugen_set_config(sc, configno)
struct ugen_softc *sc;
int configno;
@ -209,30 +210,30 @@ ugen_set_config(sc, configno)
struct ugen_endpoint *sce;
u_int8_t niface, nendpt;
int ifaceno, endptno, endpt;
usbd_status r;
usbd_status err;
int dir;
DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
USBDEVNAME(sc->sc_dev), configno, sc));
if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
/* Avoid setting the current value. */
r = usbd_set_config_no(dev, configno, 0);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_set_config_no(dev, configno, 0);
if (err)
return (err);
}
r = usbd_interface_count(dev, &niface);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_interface_count(dev, &niface);
if (err)
return (err);
memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
for (ifaceno = 0; ifaceno < niface; ifaceno++) {
DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
r = usbd_device2interface_handle(dev, ifaceno, &iface);
if (r != USBD_NORMAL_COMPLETION)
return (r);
r = usbd_endpoint_count(iface, &nendpt);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_device2interface_handle(dev, ifaceno, &iface);
if (err)
return (err);
err = usbd_endpoint_count(iface, &nendpt);
if (err)
return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@ -257,29 +258,31 @@ ugenopen(dev, flag, mode, p)
int mode;
struct proc *p;
{
struct ugen_softc *sc;
int unit = UGENUNIT(dev);
int endpt = UGENENDPOINT(dev);
usb_endpoint_descriptor_t *edesc;
struct ugen_endpoint *sce;
int dir, isize;
usbd_status r;
usbd_status err;
USB_GET_SC_OPEN(ugen, unit, sc);
DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
flag, mode, unit, endpt));
if (!sc || sc->sc_dying)
if (sc == NULL || sc->sc_dying)
return (ENXIO);
if (sc->sc_is_open[endpt])
return (EBUSY);
if (endpt == USB_CONTROL_ENDPOINT) {
sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 1;
sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
return (0);
}
/* Make sure there are pipes for all directions. */
for (dir = OUT; dir <= IN; dir++) {
if (sc->sc_is_open[endpt][dir])
return (EBUSY);
if (flag & (dir == OUT ? FWRITE : FREAD)) {
sce = &sc->sc_endpoints[endpt][dir];
if (sce == 0 || sce->edesc == 0)
@ -298,8 +301,6 @@ ugenopen(dev, flag, mode, p)
DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
sc, endpt, dir, sce));
edesc = sce->edesc;
if (!edesc)
return (ENXIO);
switch (edesc->bmAttributes & UE_XFERTYPE) {
case UE_INTERRUPT:
isize = UGETW(edesc->wMaxPacketSize);
@ -308,40 +309,31 @@ ugenopen(dev, flag, mode, p)
sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
endpt, isize));
#if defined(__NetBSD__) || defined(__OpenBSD__)
if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
return (ENOMEM);
#elif defined(__FreeBSD__)
clist_alloc_cblocks(&sce->q, UGEN_IBSIZE, 0);
#endif
r = usbd_open_pipe_intr(sce->iface,
if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
return (ENOMEM);
err = usbd_open_pipe_intr(sce->iface,
edesc->bEndpointAddress,
USBD_SHORT_XFER_OK, &sce->pipeh, sce,
sce->ibuf, isize, ugenintr);
if (r != USBD_NORMAL_COMPLETION) {
if (err) {
free(sce->ibuf, M_USBDEV);
#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sce->q);
#elif defined(__FreeBSD__)
clist_free_cblocks(&sce->q);
#endif
return (EIO);
}
DPRINTFN(5, ("ugenopen: interrupt open done\n"));
break;
case UE_BULK:
r = usbd_open_pipe(sce->iface,
edesc->bEndpointAddress, 0,
&sce->pipeh);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_open_pipe(sce->iface,
edesc->bEndpointAddress, 0, &sce->pipeh);
if (err)
return (EIO);
break;
case UE_CONTROL:
case UE_ISOCHRONOUS:
return (EINVAL);
}
sc->sc_is_open[endpt][dir] = 1;
}
sc->sc_is_open[endpt] = 1;
return (0);
}
@ -352,16 +344,18 @@ ugenclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
struct ugen_softc *sc;
struct ugen_endpoint *sce;
int dir;
USB_GET_SC(ugen, UGENUNIT(dev), sc);
DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
flag, mode, UGENUNIT(dev), endpt));
#ifdef DIAGNOSTIC
if (!sc->sc_is_open[endpt][IN] || !sc->sc_is_open[endpt][OUT] ) {
if (!sc->sc_is_open[endpt]) {
printf("ugenclose: not open\n");
return (EINVAL);
}
@ -369,7 +363,7 @@ ugenclose(dev, flag, mode, p)
if (endpt == USB_CONTROL_ENDPOINT) {
DPRINTFN(5, ("ugenclose: close control\n"));
sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 0;
sc->sc_is_open[endpt] = 0;
return (0);
}
@ -377,31 +371,28 @@ ugenclose(dev, flag, mode, p)
if (!(flag & (dir == OUT ? FWRITE : FREAD)))
continue;
sce = &sc->sc_endpoints[endpt][dir];
if (!sce || !sce->pipeh)
if (sce == NULL || sce->pipeh == NULL)
continue;
DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
endpt, dir, sce));
usbd_abort_pipe(sce->pipeh);
usbd_close_pipe(sce->pipeh);
sce->pipeh = 0;
sce->pipeh = NULL;
if (sce->ibuf) {
if (sce->ibuf != NULL) {
free(sce->ibuf, M_USBDEV);
sce->ibuf = 0;
#if defined(__NetBSD__) || defined(__OpenBSD__)
sce->ibuf = NULL;
clfree(&sce->q);
#elif defined(__FreeBSD__)
clist_free_cblocks(&sce->q);
#endif
}
sc->sc_is_open[endpt][dir] = 0;
}
sc->sc_is_open[endpt] = 0;
return (0);
}
int
static int
ugen_do_read(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
@ -411,8 +402,8 @@ ugen_do_read(sc, endpt, uio, flag)
struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
u_int32_t n, tn;
char buf[UGEN_BBSIZE];
usbd_request_handle reqh;
usbd_status r;
usbd_xfer_handle xfer;
usbd_status err;
int s;
int error = 0;
u_char buffer[UGEN_CHUNK];
@ -420,15 +411,19 @@ ugen_do_read(sc, endpt, uio, flag)
#ifdef __NetBSD__
DPRINTFN(5, ("ugenread: %d:%d\n", sc->sc_dev.dv_unit, endpt));
#endif
if (sc->sc_dying)
return (EIO);
if (endpt == USB_CONTROL_ENDPOINT)
return (ENODEV);
#ifdef DIAGNOSTIC
if (!sce->edesc) {
if (sce->edesc == NULL) {
printf("ugenread: no edesc\n");
return (EIO);
}
if (!sce->pipeh) {
if (sce->pipeh == NULL) {
printf("ugenread: no pipe\n");
return (EIO);
}
@ -473,21 +468,21 @@ ugen_do_read(sc, endpt, uio, flag)
}
break;
case UE_BULK:
reqh = usbd_alloc_request(sc->sc_udev);
if (reqh == 0)
xfer = usbd_alloc_request(sc->sc_udev);
if (xfer == 0)
return (ENOMEM);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
tn = n;
r = usbd_bulk_transfer(
reqh, sce->pipeh,
err = usbd_bulk_transfer(
xfer, sce->pipeh,
sce->state & UGEN_SHORT_OK ?
USBD_SHORT_XFER_OK : 0,
sce->timeout, buf, &tn, "ugenrb");
if (r != USBD_NORMAL_COMPLETION) {
if (r == USBD_INTERRUPTED)
if (err) {
if (err == USBD_INTERRUPTED)
error = EINTR;
else if (r == USBD_TIMEOUT)
else if (err == USBD_TIMEOUT)
error = ETIMEDOUT;
else
error = EIO;
@ -498,7 +493,7 @@ ugen_do_read(sc, endpt, uio, flag)
if (error || tn < n)
break;
}
usbd_free_request(reqh);
usbd_free_request(xfer);
break;
default:
return (ENXIO);
@ -512,10 +507,12 @@ ugenread(dev, uio, flag)
struct uio *uio;
int flag;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
struct ugen_softc *sc;
int error;
USB_GET_SC(ugen, UGENUNIT(dev), sc);
sc->sc_refcnt++;
error = ugen_do_read(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
@ -523,7 +520,7 @@ ugenread(dev, uio, flag)
return (error);
}
int
static int
ugen_do_write(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
@ -534,45 +531,49 @@ ugen_do_write(sc, endpt, uio, flag)
u_int32_t n;
int error = 0;
char buf[UGEN_BBSIZE];
usbd_request_handle reqh;
usbd_status r;
usbd_xfer_handle xfer;
usbd_status err;
DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt));
if (sc->sc_dying)
return (EIO);
if (endpt == USB_CONTROL_ENDPOINT)
return (ENODEV);
#ifdef DIAGNOSTIC
if (!sce->edesc) {
if (sce->edesc == NULL) {
printf("ugenwrite: no edesc\n");
return (EIO);
}
if (!sce->pipeh) {
if (sce->pipeh == NULL) {
printf("ugenwrite: no pipe\n");
return (EIO);
}
#endif
DPRINTF(("ugenwrite\n"));
switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
case UE_BULK:
reqh = usbd_alloc_request(sc->sc_udev);
if (reqh == 0)
xfer = usbd_alloc_request(sc->sc_udev);
if (xfer == 0)
return (EIO);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
error = uiomove(buf, n, uio);
if (error)
break;
DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
r = usbd_bulk_transfer(reqh, sce->pipeh, 0,
sce->timeout, buf, &n,"ugenwb");
if (r != USBD_NORMAL_COMPLETION) {
if (r == USBD_INTERRUPTED)
err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
sce->timeout, buf, &n,"ugenwb");
if (err) {
if (err == USBD_INTERRUPTED)
error = EINTR;
else
error = EIO;
break;
}
}
usbd_free_request(reqh);
usbd_free_request(xfer);
break;
default:
return (ENXIO);
@ -586,10 +587,12 @@ ugenwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
struct ugen_softc *sc;
int error;
USB_GET_SC(ugen, UGENUNIT(dev), sc);
sc->sc_refcnt++;
error = ugen_do_write(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
@ -597,7 +600,6 @@ ugenwrite(dev, uio, flag)
return (error);
}
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
ugen_activate(self, act)
@ -669,9 +671,9 @@ USB_DETACH(ugen)
return (0);
}
void
ugenintr(reqh, addr, status)
usbd_request_handle reqh;
static void
ugenintr(xfer, addr, status)
usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
@ -689,11 +691,11 @@ ugenintr(reqh, addr, status)
return;
}
usbd_get_request_status(reqh, 0, 0, &count, 0);
usbd_get_request_status(xfer, 0, 0, &count, 0);
ibuf = sce->ibuf;
DPRINTFN(5, ("ugenintr: reqh=%p status=%d count=%d\n",
reqh, status, count));
DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
xfer, status, count));
DPRINTFN(5, (" data = %02x %02x %02x\n",
ibuf[0], ibuf[1], ibuf[2]));
@ -707,32 +709,32 @@ ugenintr(reqh, addr, status)
selwakeup(&sce->rsel);
}
usbd_status
static usbd_status
ugen_set_interface(sc, ifaceidx, altno)
struct ugen_softc *sc;
int ifaceidx, altno;
{
usbd_interface_handle iface;
usb_endpoint_descriptor_t *ed;
usbd_status r;
usbd_status err;
struct ugen_endpoint *sce;
u_int8_t niface, nendpt, endptno, endpt;
int dir;
DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
r = usbd_interface_count(sc->sc_udev, &niface);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_interface_count(sc->sc_udev, &niface);
if (err)
return (err);
if (ifaceidx < 0 || ifaceidx >= niface)
return (USBD_INVAL);
r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
if (r != USBD_NORMAL_COMPLETION)
return (r);
r = usbd_endpoint_count(iface, &nendpt);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
if (err)
return (err);
err = usbd_endpoint_count(iface, &nendpt);
if (err)
return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@ -744,13 +746,13 @@ ugen_set_interface(sc, ifaceidx, altno)
}
/* change setting */
r = usbd_set_interface(iface, altno);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_set_interface(iface, altno);
if (err)
return (err);
r = usbd_endpoint_count(iface, &nendpt);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_endpoint_count(iface, &nendpt);
if (err)
return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@ -764,7 +766,7 @@ ugen_set_interface(sc, ifaceidx, altno)
}
/* Retrieve a complete descriptor for a certain device and index. */
usb_config_descriptor_t *
static usb_config_descriptor_t *
ugen_get_cdesc(sc, index, lenp)
struct ugen_softc *sc;
int index;
@ -772,7 +774,7 @@ ugen_get_cdesc(sc, index, lenp)
{
usb_config_descriptor_t *cdesc, *tdesc, cdescr;
int len;
usbd_status r;
usbd_status err;
if (index == USB_CURRENT_CONFIG_INDEX) {
tdesc = usbd_get_config_descriptor(sc->sc_udev);
@ -783,16 +785,16 @@ ugen_get_cdesc(sc, index, lenp)
memcpy(cdesc, tdesc, len);
DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
} else {
r = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
if (err)
return (0);
len = UGETW(cdescr.wTotalLength);
DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
if (lenp)
*lenp = len;
cdesc = malloc(len, M_TEMP, M_WAITOK);
r = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
if (err) {
free(cdesc, M_TEMP);
return (0);
}
@ -800,21 +802,21 @@ ugen_get_cdesc(sc, index, lenp)
return (cdesc);
}
int
static int
ugen_get_alt_index(sc, ifaceidx)
struct ugen_softc *sc;
int ifaceidx;
{
usbd_interface_handle iface;
usbd_status r;
usbd_status err;
r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
if (err)
return (-1);
return (usbd_get_interface_altindex(iface));
}
int
static int
ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct ugen_softc *sc;
int endpt;
@ -824,7 +826,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct proc *p;
{
struct ugen_endpoint *sce;
usbd_status r;
usbd_status err;
usbd_interface_handle iface;
struct usb_config_desc *cd;
usb_config_descriptor_t *cdesc;
@ -849,8 +851,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
if (endpt == USB_CONTROL_ENDPOINT)
return (EINVAL);
sce = &sc->sc_endpoints[endpt][IN];
if (sce == NULL)
return (EINVAL);
#ifdef DIAGNOSTIC
if (!sce->pipeh) {
if (sce->pipeh == NULL) {
printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
return (EIO);
}
@ -862,8 +866,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
return (0);
case USB_SET_TIMEOUT:
sce = &sc->sc_endpoints[endpt][IN];
if (sce == NULL)
return (EINVAL);
#ifdef DIAGNOSTIC
if (!sce->pipeh) {
if (sce->pipeh == NULL) {
printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n");
return (EIO);
}
@ -884,26 +890,26 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
break;
#endif
case USB_GET_CONFIG:
r = usbd_get_config(sc->sc_udev, &conf);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_get_config(sc->sc_udev, &conf);
if (err)
return (EIO);
*(int *)addr = conf;
break;
case USB_SET_CONFIG:
if (!(flag & FWRITE))
return (EPERM);
r = ugen_set_config(sc, *(int *)addr);
if (r != USBD_NORMAL_COMPLETION)
err = ugen_set_config(sc, *(int *)addr);
if (err)
return (EIO);
break;
case USB_GET_ALTINTERFACE:
ai = (struct usb_alt_interface *)addr;
r = usbd_device2interface_handle(sc->sc_udev,
ai->interface_index, &iface);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_device2interface_handle(sc->sc_udev,
ai->interface_index, &iface);
if (err)
return (EINVAL);
idesc = usbd_get_interface_descriptor(iface);
if (!idesc)
if (idesc == NULL)
return (EIO);
ai->alt_no = idesc->bAlternateSetting;
break;
@ -911,21 +917,21 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
if (!(flag & FWRITE))
return (EPERM);
ai = (struct usb_alt_interface *)addr;
r = usbd_device2interface_handle(sc->sc_udev,
ai->interface_index, &iface);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_device2interface_handle(sc->sc_udev,
ai->interface_index, &iface);
if (err)
return (EINVAL);
r = ugen_set_interface(sc, ai->interface_index, ai->alt_no);
if (r != USBD_NORMAL_COMPLETION)
err = ugen_set_interface(sc, ai->interface_index, ai->alt_no);
if (err)
return (EINVAL);
break;
case USB_GET_NO_ALT:
ai = (struct usb_alt_interface *)addr;
cdesc = ugen_get_cdesc(sc, ai->config_index, 0);
if (!cdesc)
if (cdesc == NULL)
return (EINVAL);
idesc = usbd_find_idesc(cdesc, ai->interface_index, 0);
if (!idesc) {
if (idesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@ -939,7 +945,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_CONFIG_DESC:
cd = (struct usb_config_desc *)addr;
cdesc = ugen_get_cdesc(sc, cd->config_index, 0);
if (!cdesc)
if (cdesc == NULL)
return (EINVAL);
cd->desc = *cdesc;
free(cdesc, M_TEMP);
@ -947,7 +953,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_INTERFACE_DESC:
id = (struct usb_interface_desc *)addr;
cdesc = ugen_get_cdesc(sc, id->config_index, 0);
if (!cdesc)
if (cdesc == NULL)
return (EINVAL);
if (id->config_index == USB_CURRENT_CONFIG_INDEX &&
id->alt_index == USB_CURRENT_ALT_INDEX)
@ -955,7 +961,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
else
alt = id->alt_index;
idesc = usbd_find_idesc(cdesc, id->interface_index, alt);
if (!idesc) {
if (idesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@ -965,7 +971,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_ENDPOINT_DESC:
ed = (struct usb_endpoint_desc *)addr;
cdesc = ugen_get_cdesc(sc, ed->config_index, 0);
if (!cdesc)
if (cdesc == NULL)
return (EINVAL);
if (ed->config_index == USB_CURRENT_CONFIG_INDEX &&
ed->alt_index == USB_CURRENT_ALT_INDEX)
@ -974,7 +980,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
alt = ed->alt_index;
edesc = usbd_find_edesc(cdesc, ed->interface_index,
alt, ed->endpoint_index);
if (!edesc) {
if (edesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@ -1011,9 +1017,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
}
case USB_GET_STRING_DESC:
si = (struct usb_string_desc *)addr;
r = usbd_get_string_desc(sc->sc_udev, si->string_index,
si->language_id, &si->desc);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_get_string_desc(sc->sc_udev, si->string_index,
si->language_id, &si->desc);
if (err)
return (EINVAL);
break;
case USB_DO_REQUEST:
@ -1023,7 +1029,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct iovec iov;
struct uio uio;
void *ptr = 0;
usbd_status r;
usbd_status err;
int error = 0;
if (!(flag & FWRITE))
@ -1058,9 +1064,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
goto ret;
}
}
r = usbd_do_request_flags(sc->sc_udev, &ur->request,
ptr, ur->flags, &ur->actlen);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_do_request_flags(sc->sc_udev, &ur->request,
ptr, ur->flags, &ur->actlen);
if (err) {
error = EIO;
goto ret;
}
@ -1078,7 +1084,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
}
case USB_GET_DEVICEINFO:
usbd_fill_deviceinfo(sc->sc_udev,
(struct usb_device_info *)addr);
(struct usb_device_info *)addr);
break;
default:
return (EINVAL);
@ -1094,10 +1100,12 @@ ugenioctl(dev, cmd, addr, flag, p)
int flag;
struct proc *p;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
struct ugen_softc *sc;
int error;
USB_GET_SC(ugen, UGENUNIT(dev), sc);
sc->sc_refcnt++;
error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
@ -1111,16 +1119,20 @@ ugenpoll(dev, events, p)
int events;
struct proc *p;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
struct ugen_softc *sc;
struct ugen_endpoint *sce;
int revents = 0;
int s;
USB_GET_SC(ugen, UGENUNIT(dev), sc);
if (sc->sc_dying)
return (EIO);
/* XXX always IN */
sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
if (sce == NULL)
return (EINVAL);
#ifdef DIAGNOSTIC
if (!sce->edesc) {
printf("ugenwrite: no edesc\n");

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhcireg.h,v 1.7 1999/08/22 23:19:57 augustss Exp $ */
/* $NetBSD: uhcireg.h,v 1.6 1999/04/03 19:01:20 augustss Exp $ */
/* $FreeBSD$ */
/*

View File

@ -1,5 +1,5 @@
/* $NetBSD: uhcivar.h,v 1.12 1999/08/22 23:41:00 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: uhcivar.h,v 1.16 1999/10/13 08:10:56 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -70,7 +70,7 @@ typedef union {
*/
typedef struct uhci_intr_info {
struct uhci_softc *sc;
usbd_request_handle reqh;
usbd_xfer_handle xfer;
uhci_soft_td_t *stdstart;
uhci_soft_td_t *stdend;
LIST_ENTRY(uhci_intr_info) list;
@ -130,12 +130,6 @@ typedef struct uhci_softc {
struct usbd_bus sc_bus; /* base device */
bus_space_tag_t iot;
bus_space_handle_t ioh;
#if defined(__NetBSD__) || defined(__OpenBSD__)
void *sc_ih; /* interrupt vectoring */
bus_dma_tag_t sc_dmatag; /* DMA tag */
/* XXX should keep track of all DMA memory */
#endif /* defined(__FreeBSD__) */
uhci_physaddr_t *sc_pframes;
usb_dma_t sc_dma;
@ -154,12 +148,9 @@ typedef struct uhci_softc {
char sc_isreset;
#if defined(__NetBSD__)
char sc_suspend;
#endif
usbd_request_handle sc_has_timo;
usbd_xfer_handle sc_has_timo;
int sc_intrs;
LIST_HEAD(, uhci_intr_info) sc_intrhead;
/* Info for the root hub interrupt channel. */
@ -171,11 +162,15 @@ typedef struct uhci_softc {
char sc_vendor[16];
int sc_id_vendor;
void *sc_powerhook;
device_ptr_t sc_child;
} uhci_softc_t;
usbd_status uhci_init __P((uhci_softc_t *));
int uhci_intr __P((void *));
#if 0
void uhci_reset __P((void *));
#if defined(__NetBSD__) || defined(__OpenBSD__)
int uhci_detach __P((uhci_softc_t *, int));
int uhci_activate __P((device_ptr_t, enum devact));
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhid.c,v 1.24 1999/09/05 19:32:18 augustss Exp $ */
/* $NetBSD: uhid.c,v 1.26 1999/10/13 08:10:56 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -146,11 +146,13 @@ static struct cdevsw uhid_cdevsw = {
};
#endif
void uhid_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
static void uhid_intr __P((usbd_xfer_handle, usbd_private_handle,
usbd_status));
int uhid_do_read __P((struct uhid_softc *, struct uio *uio, int));
int uhid_do_write __P((struct uhid_softc *, struct uio *uio, int));
int uhid_do_ioctl __P((struct uhid_softc *, u_long, caddr_t, int, struct proc *));
static int uhid_do_read __P((struct uhid_softc *, struct uio *uio, int));
static int uhid_do_write __P((struct uhid_softc *, struct uio *uio, int));
static int uhid_do_ioctl __P((struct uhid_softc *, u_long, caddr_t, int,
struct proc *));
USB_DECLARE_DRIVER(uhid);
@ -159,10 +161,10 @@ USB_MATCH(uhid)
USB_MATCH_START(uhid, uaa);
usb_interface_descriptor_t *id;
if (!uaa->iface)
if (uaa->iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa->iface);
if (!id || id->bInterfaceClass != UCLASS_HID)
if (id == NULL || id->bInterfaceClass != UCLASS_HID)
return (UMATCH_NONE);
return (UMATCH_IFACECLASS_GENERIC);
}
@ -175,7 +177,7 @@ USB_ATTACH(uhid)
usb_endpoint_descriptor_t *ed;
int size;
void *desc;
usbd_status r;
usbd_status err;
char devinfo[1024];
sc->sc_iface = iface;
@ -186,7 +188,7 @@ USB_ATTACH(uhid)
devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
ed = usbd_interface2endpoint_descriptor(iface, 0);
if (!ed) {
if (ed == NULL) {
printf("%s: could not read endpoint descriptor\n",
USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
@ -212,11 +214,11 @@ USB_ATTACH(uhid)
sc->sc_ep_addr = ed->bEndpointAddress;
desc = 0;
r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USBDEV);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USBDEV);
if (err) {
printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
if (desc)
if (desc != NULL)
free(desc, M_USBDEV);
USB_ATTACH_ERROR_RETURN;
}
@ -272,12 +274,12 @@ USB_DETACH(uhid)
int maj, mn;
DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
#else
DPRINTF(("uhid_detach: sc=%p\n", sc));
#endif
sc->sc_dying = 1;
if (sc->sc_intrpipe)
if (sc->sc_intrpipe != NULL)
usbd_abort_pipe(sc->sc_intrpipe);
if (sc->sc_state & UHID_OPEN) {
@ -310,8 +312,8 @@ USB_DETACH(uhid)
}
void
uhid_intr(reqh, addr, status)
usbd_request_handle reqh;
uhid_intr(xfer, addr, status)
usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
@ -347,7 +349,9 @@ uhidopen(dev, flag, mode, p)
int mode;
struct proc *p;
{
usbd_status r;
struct uhid_softc *sc;
usbd_status err;
USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);
DPRINTF(("uhidopen: sc=%p\n", sc));
@ -359,26 +363,21 @@ uhidopen(dev, flag, mode, p)
return (EBUSY);
sc->sc_state |= UHID_OPEN;
#if defined(__NetBSD__) || defined(__OpenBSD__)
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) {
sc->sc_state &= ~UHID_OPEN;
return (ENOMEM);
}
#elif defined(__FreeBSD__)
clist_alloc_cblocks(&sc->sc_q, UHID_BSIZE, 0);
#endif
sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
/* Set up interrupt pipe. */
r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
USBD_SHORT_XFER_OK,
&sc->sc_intrpipe, sc, sc->sc_ibuf,
sc->sc_isize, uhid_intr);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf,
sc->sc_isize, uhid_intr);
if (err) {
DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
"error=%d\n",r));
"error=%d\n",err));
free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
sc->sc_state &= ~UHID_OPEN;
@ -397,6 +396,8 @@ uhidclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
struct uhid_softc *sc;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
DPRINTF(("uhidclose: sc=%p\n", sc));
@ -406,11 +407,7 @@ uhidclose(dev, flag, mode, p)
usbd_close_pipe(sc->sc_intrpipe);
sc->sc_intrpipe = 0;
#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sc->sc_q);
#elif defined(__FreeBSD__)
clist_free_cblocks(&sc->sc_q);
#endif
free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
@ -430,15 +427,15 @@ uhid_do_read(sc, uio, flag)
int error = 0;
size_t length;
u_char buffer[UHID_CHUNK];
usbd_status r;
usbd_status err;
DPRINTFN(1, ("uhidread\n"));
if (sc->sc_state & UHID_IMMED) {
DPRINTFN(1, ("uhidread immed\n"));
r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
sc->sc_iid, buffer, sc->sc_isize);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
sc->sc_iid, buffer, sc->sc_isize);
if (err)
return (EIO);
return (uiomove(buffer, sc->sc_isize, uio));
}
@ -491,9 +488,11 @@ uhidread(dev, uio, flag)
struct uio *uio;
int flag;
{
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
struct uhid_softc *sc;
int error;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
sc->sc_refcnt++;
error = uhid_do_read(sc, uio, flag);
if (--sc->sc_refcnt < 0)
@ -509,7 +508,7 @@ uhid_do_write(sc, uio, flag)
{
int error;
int size;
usbd_status r;
usbd_status err;
DPRINTFN(1, ("uhidwrite\n"));
@ -523,15 +522,13 @@ uhid_do_write(sc, uio, flag)
error = uiomove(sc->sc_obuf, size, uio);
if (!error) {
if (sc->sc_oid)
r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
sc->sc_obuf[0],
sc->sc_obuf+1, size-1);
err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
sc->sc_obuf[0], sc->sc_obuf+1, size-1);
else
r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
0, sc->sc_obuf, size);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
0, sc->sc_obuf, size);
if (err)
error = EIO;
}
}
return (error);
@ -543,9 +540,11 @@ uhidwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
struct uhid_softc *sc;
int error;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
sc->sc_refcnt++;
error = uhid_do_write(sc, uio, flag);
if (--sc->sc_refcnt < 0)
@ -564,7 +563,7 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
struct usb_ctl_report_desc *rd;
struct usb_ctl_report *re;
int size, id;
usbd_status r;
usbd_status err;
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
@ -585,11 +584,10 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
case USB_SET_IMMED:
if (*(int *)addr) {
/* XXX should read into ibuf, but does it matter */
r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
sc->sc_iid, sc->sc_ibuf,
sc->sc_isize);
if (r != USBD_NORMAL_COMPLETION)
/* XXX should read into ibuf, but does it matter? */
err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
sc->sc_iid, sc->sc_ibuf, sc->sc_isize);
if (err)
return (EOPNOTSUPP);
sc->sc_state |= UHID_IMMED;
@ -615,9 +613,9 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
default:
return (EINVAL);
}
r = usbd_get_report(sc->sc_iface, re->report, id,
re->data, size);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_get_report(sc->sc_iface, re->report, id, re->data,
size);
if (err)
return (EIO);
break;
@ -635,9 +633,11 @@ uhidioctl(dev, cmd, addr, flag, p)
int flag;
struct proc *p;
{
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
struct uhid_softc *sc;
int error;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
sc->sc_refcnt++;
error = uhid_do_ioctl(sc, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
@ -651,8 +651,10 @@ uhidpoll(dev, events, p)
int events;
struct proc *p;
{
struct uhid_softc *sc;
int revents = 0;
int s;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_dying)

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhub.c,v 1.26 1999/09/05 19:32:18 augustss Exp $ */
/* $NetBSD: uhub.c,v 1.32 1999/10/13 08:10:56 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -52,9 +52,10 @@
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
#include "bus_if.h"
#endif
#include "bus_if.h"
#include <machine/bus.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@ -78,22 +79,23 @@ struct uhub_softc {
u_char sc_running;
};
usbd_status uhub_init_port __P((struct usbd_port *));
void uhub_disconnect_port __P((struct usbd_port *up));
usbd_status uhub_explore __P((usbd_device_handle hub));
void uhub_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
static usbd_status uhub_init_port __P((struct usbd_port *));
static usbd_status uhub_explore __P((usbd_device_handle hub));
static void uhub_intr __P((usbd_xfer_handle, usbd_private_handle, usbd_status));
#if defined(__FreeBSD__)
static bus_child_detached_t uhub_child_detached;
#endif
/* We need two attachment points:
/*
* We need two attachment points:
* hub to usb and hub to hub
* Every other driver only connects to hubs
*/
#if defined(__NetBSD__) || defined(__OpenBSD__)
USB_DECLARE_DRIVER(uhub);
USB_DECLARE_DRIVER(uhub)
/* Create the driver instance for the hub connected to hub case */
struct cfattach uhub_uhub_ca = {
@ -101,8 +103,9 @@ struct cfattach uhub_uhub_ca = {
uhub_detach, uhub_activate
};
#elif defined(__FreeBSD__)
USB_DECLARE_DRIVER_INIT(uhub, DEVMETHOD(bus_child_detached, uhub_child_detached));
USB_DECLARE_DRIVER_INIT(uhub,
DEVMETHOD(bus_child_detached, uhub_child_detached));
/* Create the driver instance for the hub connected to usb case. */
devclass_t uhubroot_devclass;
@ -121,7 +124,6 @@ static driver_t uhubroot_driver = {
};
#endif
USB_MATCH(uhub)
{
USB_MATCH_START(uhub, uaa);
@ -132,7 +134,7 @@ USB_MATCH(uhub)
* The subclass for hubs seems to be 0 for some and 1 for others,
* so we just ignore the subclass.
*/
if (uaa->iface == 0 && dd->bDeviceClass == UCLASS_HUB)
if (uaa->iface == NULL && dd->bDeviceClass == UCLASS_HUB)
return (UMATCH_DEVCLASS_DEVSUBCLASS);
return (UMATCH_NONE);
}
@ -142,7 +144,7 @@ USB_ATTACH(uhub)
USB_ATTACH_START(uhub, sc, uaa);
usbd_device_handle dev = uaa->device;
char devinfo[1024];
usbd_status r;
usbd_status err;
struct usbd_hub *hub;
usb_device_request_t req;
usb_hub_descriptor_t hubdesc;
@ -156,10 +158,10 @@ USB_ATTACH(uhub)
USB_ATTACH_SETUP;
printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
r = usbd_set_config_index(dev, 0, 1);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_set_config_index(dev, 0, 1);
if (err) {
DPRINTF(("%s: configuration failed, error=%s\n",
USBDEVNAME(sc->sc_dev), usbd_errstr(r)));
USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
USB_ATTACH_ERROR_RETURN;
}
@ -176,15 +178,15 @@ USB_ATTACH(uhub)
USETW(req.wIndex, 0);
USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
DPRINTFN(1,("usb_init_hub: getting hub descriptor\n"));
r = usbd_do_request(dev, &req, &hubdesc);
err = usbd_do_request(dev, &req, &hubdesc);
nports = hubdesc.bNbrPorts;
if (r == USBD_NORMAL_COMPLETION && nports > 7) {
if (!err && nports > 7) {
USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8);
r = usbd_do_request(dev, &req, &hubdesc);
err = usbd_do_request(dev, &req, &hubdesc);
}
if (r != USBD_NORMAL_COMPLETION) {
if (err) {
DPRINTF(("%s: getting hub descriptor failed, error=%s\n",
USBDEVNAME(sc->sc_dev), usbd_errstr(r)));
USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
USB_ATTACH_ERROR_RETURN;
}
@ -194,11 +196,10 @@ USB_ATTACH(uhub)
printf("%s: %d port%s with %d removable, %s powered\n",
USBDEVNAME(sc->sc_dev), nports, nports != 1 ? "s" : "",
nremov, dev->self_powered ? "self" : "bus");
hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port),
M_USBDEV, M_NOWAIT);
if (hub == 0)
if (hub == NULL)
USB_ATTACH_ERROR_RETURN;
dev->hub = hub;
dev->hub->hubsoftc = sc;
@ -211,7 +212,7 @@ USB_ATTACH(uhub)
dev->powersrc->parent ?
dev->powersrc->parent->self_powered : 0));
if (!dev->self_powered && dev->powersrc->parent &&
if (!dev->self_powered && dev->powersrc->parent != NULL &&
!dev->powersrc->parent->self_powered) {
printf("%s: bus powered hub connected to bus powered hub, "
"ignored\n", USBDEVNAME(sc->sc_dev));
@ -219,13 +220,13 @@ USB_ATTACH(uhub)
}
/* Set up interrupt pipe. */
r = usbd_device2interface_handle(dev, 0, &iface);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_device2interface_handle(dev, 0, &iface);
if (err) {
printf("%s: no interface handle\n", USBDEVNAME(sc->sc_dev));
goto bad;
}
ed = usbd_interface2endpoint_descriptor(iface, 0);
if (ed == 0) {
if (ed == NULL) {
printf("%s: no endpoint descriptor\n", USBDEVNAME(sc->sc_dev));
goto bad;
}
@ -234,11 +235,10 @@ USB_ATTACH(uhub)
goto bad;
}
r = usbd_open_pipe_intr(iface, ed->bEndpointAddress,USBD_SHORT_XFER_OK,
&sc->sc_ipipe, sc, sc->sc_status,
sizeof(sc->sc_status),
uhub_intr);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_open_pipe_intr(iface, ed->bEndpointAddress,
USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status,
sizeof(sc->sc_status), uhub_intr);
if (err) {
printf("%s: cannot open interrupt pipe\n",
USBDEVNAME(sc->sc_dev));
goto bad;
@ -252,16 +252,16 @@ USB_ATTACH(uhub)
up->device = 0;
up->parent = dev;
up->portno = p+1;
r = uhub_init_port(up);
if (r != USBD_NORMAL_COMPLETION)
err = uhub_init_port(up);
if (err)
printf("%s: init of port %d failed\n",
USBDEVNAME(sc->sc_dev), up->portno);
USBDEVNAME(sc->sc_dev), up->portno);
}
sc->sc_running = 1;
USB_ATTACH_SUCCESS_RETURN;
bad:
bad:
free(hub, M_USBDEV);
dev->hub = 0;
USB_ATTACH_ERROR_RETURN;
@ -273,12 +273,12 @@ uhub_init_port(up)
{
int port = up->portno;
usbd_device_handle dev = up->parent;
usbd_status r;
usbd_status err;
u_int16_t pstatus;
r = usbd_get_port_status(dev, port, &up->status);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_get_port_status(dev, port, &up->status);
if (err)
return (err);
pstatus = UGETW(up->status.wPortStatus);
DPRINTF(("usbd_init_port: adding hub port=%d status=0x%04x "
"change=0x%04x\n",
@ -295,9 +295,9 @@ usbd_clear_port_feature(dev, port, UHF_C_PORT_OVER_CURRENT);
#endif
/* then turn the power on. */
r = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
if (err)
return (err);
DPRINTF(("usb_init_port: turn on port %d power status=0x%04x "
"change=0x%04x\n",
port, UGETW(up->status.wPortStatus),
@ -306,9 +306,9 @@ usbd_clear_port_feature(dev, port, UHF_C_PORT_OVER_CURRENT);
usbd_delay_ms(dev, dev->hub->hubdesc.bPwrOn2PwrGood *
UHD_PWRON_FACTOR);
/* Get the port status again. */
r = usbd_get_port_status(dev, port, &up->status);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_get_port_status(dev, port, &up->status);
if (err)
return (err);
DPRINTF(("usb_init_port: after power on status=0x%04x "
"change=0x%04x\n",
UGETW(up->status.wPortStatus),
@ -341,7 +341,7 @@ uhub_explore(dev)
usb_hub_descriptor_t *hd = &dev->hub->hubdesc;
struct uhub_softc *sc = dev->hub->hubsoftc;
struct usbd_port *up;
usbd_status r;
usbd_status err;
int port;
int change, status;
@ -356,11 +356,10 @@ uhub_explore(dev)
for(port = 1; port <= hd->bNbrPorts; port++) {
up = &dev->hub->ports[port-1];
r = usbd_get_port_status(dev, port, &up->status);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_get_port_status(dev, port, &up->status);
if (err) {
DPRINTF(("uhub_explore: get port status failed, "
"error=%s\n",
usbd_errstr(r)));
"error=%s\n", usbd_errstr(err)));
continue;
}
status = UGETW(up->status.wPortStatus);
@ -404,13 +403,11 @@ uhub_explore(dev)
* the disconnect.
*/
disco:
if (up->device) {
if (up->device != NULL) {
/* Disconnected */
DPRINTF(("uhub_explore: device %d disappeared "
"on port %d\n",
up->device->address, port));
uhub_disconnect_port(up);
"on port %d\n", up->device->address, port));
usb_disconnect_port(up, USBDEV(sc->sc_dev));
usbd_clear_port_feature(dev, port,
UHF_C_PORT_CONNECTION);
}
@ -429,32 +426,26 @@ uhub_explore(dev)
continue;
/* Get device info and set its address. */
r = usbd_new_device(USBDEV(sc->sc_dev), dev->bus,
dev->depth + 1, status & UPS_LOW_SPEED,
port, up);
err = usbd_new_device(USBDEV(sc->sc_dev), dev->bus,
dev->depth + 1, status & UPS_LOW_SPEED,
port, up);
/* XXX retry a few times? */
if (r != USBD_NORMAL_COMPLETION) {
if (err) {
DPRINTFN(-1,("uhub_explore: usb_new_device failed, "
"error=%s\n", usbd_errstr(r)));
"error=%s\n", usbd_errstr(err)));
/* Avoid addressing problems by disabling. */
/* usbd_reset_port(dev, port, &up->status); */
/* XXX
* What should we do. The device may or may not be at its
* assigned address. In any case we'd like to ignore it.
*/
if (r == USBD_SET_ADDR_FAILED || 1) {/* XXX */
/* The unit refused to accept a new
* address, and since we cannot leave
* at 0 we have to disable the port
* instead. */
printf("%s: device problem, disabling "
"port %d\n",
USBDEVNAME(sc->sc_dev), port);
usbd_clear_port_feature(dev, port,
UHF_PORT_ENABLE);
/* Make sure we don't try to restart it. */
up->restartcnt = USBD_RESTART_MAX;
}
/*
* The unit refused to accept a new address, or had
* some other serious problem. Since we cannot leave
* at 0 we have to disable the port instead.
*/
printf("%s: device problem, disabling port %d\n",
USBDEVNAME(sc->sc_dev), port);
usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE);
/* Make sure we don't try to restart it infinitely. */
up->restartcnt = USBD_RESTART_MAX;
} else {
if (up->device->hub)
up->device->hub->explore(up->device);
@ -463,112 +454,31 @@ uhub_explore(dev)
return (USBD_NORMAL_COMPLETION);
}
/*
* The general mechanism for detaching drivers works as follows: Each
* driver is responsible for maintaining a reference count on the
* number of outstanding references to its softc (e.g. from
* processing hanging in a read or write). The detach method of the
* driver decrements this counter and flags in the softc that the
* driver is dying and then wakes any sleepers. It then sleeps on the
* softc. Each place that can sleep must maintain the reference
* count. When the reference count drops to -1 (0 is the normal value
* of the reference count) the a wakeup on the softc is performed
* signaling to the detach waiter that all references are gone.
*/
/*
* Called from process context when we discover that a port has
* been disconnected.
*/
void
uhub_disconnect_port(up)
struct usbd_port *up;
{
usbd_device_handle dev = up->device;
int i;
DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
up, dev, up->portno));
if (!dev) /* not even generic device was attached */
return;
if (!dev->cdesc) {
/* Partially attached device, just drop it. */
dev->bus->devices[dev->address] = 0;
up->device = 0;
return;
}
if (dev->subdevs) {
for (i = 0; dev->subdevs[i]; i++) {
if (!dev->subdevs[i]) /* skip empty elements */
continue;
printf("%s: at %s port %d (addr %d) disconnected\n",
USBDEVPTRNAME(dev->subdevs[i]),
USBDEVPTRNAME(up->parent->subdevs[0]),
up->portno, dev->address);
#if defined(__NetBSD__) || defined(__OpenBSD__)
config_detach(dev->subdevs[i], DETACH_FORCE);
#elif defined(__FreeBSD__)
device_delete_child(device_get_parent(dev->subdevs[i]),
dev->subdevs[i]);
#endif
}
}
dev->bus->devices[dev->address] = 0;
up->device = 0;
usb_free_device(dev);
}
#if defined(__FreeBSD__)
/* Called when a device has been detached from it */
static void
uhub_child_detached(self, child)
device_t self;
device_t child;
{
struct uhub_softc *sc = device_get_softc(self);
usbd_device_handle dev = sc->sc_hub;
struct usbd_port *up;
int nports;
int port;
int i;
if (!dev->hub)
/* should never happen; children are only created after init */
panic("hub not fully initialised, but child deleted?");
nports = dev->hub->hubdesc.bNbrPorts;
for (port = 0; port < nports; port++) {
up = &dev->hub->ports[port];
if (up->device && up->device->subdevs) {
for (i = 0; up->device->subdevs[i]; i++) {
if (up->device->subdevs[i] == child) {
up->device->subdevs[i] = NULL;
return;
}
}
}
}
}
#endif
#if defined(__NetBSD__)
int
uhub_activate(self, act)
device_ptr_t self;
enum devact act;
{
struct uhub_softc *sc = (struct uhub_softc *)self;
usbd_device_handle devhub = sc->sc_hub;
usbd_device_handle dev;
int nports, port, i;
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
nports = devhub->hub->hubdesc.bNbrPorts;
for(port = 0; port < nports; port++) {
dev = devhub->hub->ports[port].device;
if (dev != NULL) {
for (i = 0; dev->subdevs[i]; i++)
config_deactivate(dev->subdevs[i]);
}
}
break;
}
return (0);
@ -583,16 +493,16 @@ USB_DETACH(uhub)
{
USB_DETACH_START(uhub, sc);
usbd_device_handle dev = sc->sc_hub;
struct usbd_port *up;
struct usbd_port *rup;
int port, nports;
#if defined(__NetBSD__) || defined(__OpenBSD__)
DPRINTF(("uhub_detach: sc=%port flags=%d\n", sc, flags));
DPRINTF(("uhub_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("uhub_detach: sc=%port\n", sc));
#endif
if (!dev->hub) /* Must be partially working */
if (dev->hub == NULL) /* Must be partially working */
return (0);
usbd_abort_pipe(sc->sc_ipipe);
@ -600,21 +510,51 @@ USB_DETACH(uhub)
nports = dev->hub->hubdesc.bNbrPorts;
for(port = 0; port < nports; port++) {
up = &dev->hub->ports[port];
if (up->device) {
DPRINTF(("uhub_detach: device %d disappeared "
"on port %d\n",
up->device->address, port));
uhub_disconnect_port(up);
}
rup = &dev->hub->ports[port];
if (rup->device)
usb_disconnect_port(rup, self);
}
free(dev->hub, M_USBDEV);
dev->hub = 0;
dev->hub = NULL;
return (0);
}
#if defined(__FreeBSD__)
/* Called when a device has been detached from it */
static void
uhub_child_detached(self, child)
device_t self;
device_t child;
{
struct uhub_softc *sc = device_get_softc(self);
usbd_device_handle devhub = sc->sc_hub;
usbd_device_handle dev;
int nports;
int port;
int i;
if (!devhub->hub)
/* should never happen; children are only created after init */
panic("hub not fully initialised, but child deleted?");
nports = devhub->hub->hubdesc.bNbrPorts;
for (port = 0; port < nports; port++) {
dev = devhub->hub->ports[port].device;
if (dev && dev->subdevs) {
for (i = 0; dev->subdevs[i]; i++) {
if (dev->subdevs[i] == child) {
dev->subdevs[i] = NULL;
return;
}
}
}
}
}
#endif
/*
* Hub interrupt.
* This an indication that some port has changed status.
@ -622,8 +562,8 @@ USB_DETACH(uhub)
* to be explored again.
*/
void
uhub_intr(reqh, addr, status)
usbd_request_handle reqh;
uhub_intr(xfer, addr, status)
usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{

View File

@ -1,4 +1,3 @@
/* $NetBSD: ukbd.c,v 1.22 1999/01/09 12:10:36 drochner Exp $ */
/* $FreeBSD$ */
/*
@ -112,7 +111,7 @@ typedef struct ukbd_softc {
#define UKBD_CHUNK 128 /* chunk size for read */
#define UKBD_BSIZE 1020 /* buffer size */
typedef void usbd_intr_t(usbd_request_handle, usbd_private_handle, usbd_status);
typedef void usbd_intr_t(usbd_xfer_handle, usbd_private_handle, usbd_status);
typedef void usbd_disco_t(void *);
static usbd_intr_t ukbd_intr;
@ -209,7 +208,7 @@ ukbd_detach(device_t self)
}
void
ukbd_intr(usbd_request_handle reqh, usbd_private_handle addr, usbd_status status)
ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
{
keyboard_t *kbd = (keyboard_t *)addr;
@ -582,7 +581,7 @@ static int
ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
{
ukbd_state_t *state = (ukbd_state_t *)kbd->kb_data;
usbd_status r;
usbd_status err;
if (on) {
/* Set up interrupt pipe. */
@ -590,12 +589,12 @@ ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
return EBUSY;
state->ks_ifstate |= INTRENABLED;
r = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
USBD_SHORT_XFER_OK,
&state->ks_intrpipe, kbd,
&state->ks_ndata,
sizeof(state->ks_ndata), func);
if (r != USBD_NORMAL_COMPLETION)
if (err)
return (EIO);
} else {
/* Disable interrupts. */
@ -1333,7 +1332,7 @@ static int
init_keyboard(ukbd_state_t *state, int *type, int flags)
{
usb_endpoint_descriptor_t *ed;
usbd_status r;
usbd_status err;
*type = KB_OTHER;
@ -1360,9 +1359,9 @@ bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketS
}
if ((usbd_get_quirks(state->ks_uaa->device)->uq_flags & UQ_NO_SET_PROTO) == 0) {
r = usbd_set_protocol(state->ks_iface, 0);
err = usbd_set_protocol(state->ks_iface, 0);
DPRINTFN(5, ("ukbd:init_keyboard: protocol set\n"));
if (r != USBD_NORMAL_COMPLETION) {
if (err) {
printf("ukbd: set protocol failed\n");
return EIO;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulpt.c,v 1.23 1999/09/11 10:40:07 augustss Exp $ */
/* $NetBSD: ulpt.c,v 1.27 1999/10/13 08:10:57 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -71,7 +71,7 @@
#define STEP hz/4
#define LPTPRI (PZERO+8)
#define ULPT_BSIZE 1024
#define ULPT_BSIZE 16384
#ifdef ULPT_DEBUG
#define DPRINTF(x) if (ulptdebug) logprintf x
@ -118,10 +118,7 @@ struct ulpt_softc {
};
#if defined(__NetBSD__) || defined(__OpenBSD__)
int ulptopen __P((dev_t, int, int, struct proc *));
int ulptclose __P((dev_t, int, int, struct proc *p));
int ulptwrite __P((dev_t, struct uio *uio, int));
int ulptioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
cdev_decl(ulpt);
#elif defined(__FreeBSD__)
static d_open_t ulptopen;
static d_close_t ulptclose;
@ -169,10 +166,10 @@ USB_MATCH(ulpt)
usb_interface_descriptor_t *id;
DPRINTFN(10,("ulpt_match\n"));
if (!uaa->iface)
if (uaa->iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa->iface);
if (id &&
if (id != NULL &&
id->bInterfaceClass == UCLASS_PRINTER &&
id->bInterfaceSubClass == USUBCLASS_PRINTER &&
(id->bInterfaceProtocol == UPROTO_PRINTER_UNI ||
@ -189,7 +186,7 @@ USB_ATTACH(ulpt)
usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
char devinfo[1024];
usb_endpoint_descriptor_t *ed;
usbd_status r;
usbd_status err;
DPRINTFN(10,("ulpt_attach: sc=%p\n", sc));
usbd_devinfo(dev, 0, devinfo);
@ -199,13 +196,13 @@ USB_ATTACH(ulpt)
/* Figure out which endpoint is the bulk out endpoint. */
ed = usbd_interface2endpoint_descriptor(iface, 0);
if (!ed)
if (ed == NULL)
goto nobulk;
if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT ||
(ed->bmAttributes & UE_XFERTYPE) != UE_BULK) {
/* In case we are using a bidir protocol... */
ed = usbd_interface2endpoint_descriptor(iface, 1);
if (!ed)
if (ed == NULL)
goto nobulk;
if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT ||
(ed->bmAttributes & UE_XFERTYPE) != UE_BULK)
@ -215,8 +212,8 @@ USB_ATTACH(ulpt)
DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_bulk));
sc->sc_iface = iface;
r = usbd_interface2device_handle(iface, &sc->sc_udev);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_interface2device_handle(iface, &sc->sc_udev);
if (err) {
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
@ -238,8 +235,9 @@ USB_ATTACH(ulpt)
USETW(req.wValue, cd->bConfigurationValue);
USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting);
USETW(req.wLength, sizeof devinfo - 1);
r = usbd_do_request_flags(dev, &req, devinfo,USBD_SHORT_XFER_OK,&alen);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_do_request_flags(dev, &req, devinfo, USBD_SHORT_XFER_OK,
&alen);
if (err) {
printf("%s: cannot get device id\n", USBDEVNAME(sc->sc_dev));
} else if (alen <= 2) {
printf("%s: empty device id, no printer connected?\n",
@ -307,7 +305,7 @@ USB_DETACH(ulpt)
#endif
sc->sc_dying = 1;
if (sc->sc_bulkpipe)
if (sc->sc_bulkpipe != NULL)
usbd_abort_pipe(sc->sc_bulkpipe);
s = splusb();
@ -342,7 +340,7 @@ ulpt_status(sc)
struct ulpt_softc *sc;
{
usb_device_request_t req;
usbd_status r;
usbd_status err;
u_char status;
req.bmRequestType = UT_READ_CLASS_INTERFACE;
@ -350,9 +348,9 @@ ulpt_status(sc)
USETW(req.wValue, 0);
USETW(req.wIndex, sc->sc_ifaceno);
USETW(req.wLength, 1);
r = usbd_do_request(sc->sc_udev, &req, &status);
DPRINTFN(1, ("ulpt_status: status=0x%02x r=%d\n", status, r));
if (r == USBD_NORMAL_COMPLETION)
err = usbd_do_request(sc->sc_udev, &req, &status);
DPRINTFN(1, ("ulpt_status: status=0x%02x err=%d\n", status, err));
if (!err)
return (status);
else
return (0);
@ -384,11 +382,13 @@ ulptopen(dev, flag, mode, p)
struct proc *p;
{
u_char flags = ULPTFLAGS(dev);
usbd_status r;
struct ulpt_softc *sc;
usbd_status err;
int spin, error;
USB_GET_SC_OPEN(ulpt, ULPTUNIT(dev), sc);
if (!sc || !sc->sc_iface || sc->sc_dying)
if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying)
return (ENXIO);
if (sc->sc_state)
@ -423,8 +423,8 @@ ulptopen(dev, flag, mode, p)
}
}
r = usbd_open_pipe(sc->sc_iface, sc->sc_bulk, 0, &sc->sc_bulkpipe);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_open_pipe(sc->sc_iface, sc->sc_bulk, 0, &sc->sc_bulkpipe);
if (err) {
sc->sc_state = 0;
return (EIO);
}
@ -463,6 +463,8 @@ ulptclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
struct ulpt_softc *sc;
USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
if (sc->sc_state != ULPT_OPEN)
@ -487,16 +489,16 @@ ulpt_do_write(sc, uio, flags)
u_int32_t n;
int error = 0;
void *bufp;
usbd_request_handle reqh;
usbd_status r;
usbd_xfer_handle xfer;
usbd_status err;
DPRINTF(("ulptwrite\n"));
reqh = usbd_alloc_request(sc->sc_udev);
if (reqh == 0)
xfer = usbd_alloc_request(sc->sc_udev);
if (xfer == NULL)
return (ENOMEM);
bufp = usbd_alloc_buffer(reqh, ULPT_BSIZE);
if (bufp == 0) {
usbd_free_request(reqh);
bufp = usbd_alloc_buffer(xfer, ULPT_BSIZE);
if (bufp == NULL) {
usbd_free_request(xfer);
return (ENOMEM);
}
while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
@ -505,15 +507,15 @@ ulpt_do_write(sc, uio, flags)
if (error)
break;
DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n));
r = usbd_bulk_transfer(reqh, sc->sc_bulkpipe, 0,
USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
if (r != USBD_NORMAL_COMPLETION) {
DPRINTF(("ulptwrite: error=%d\n", r));
err = usbd_bulk_transfer(xfer, sc->sc_bulkpipe, USBD_NO_COPY,
USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
if (err) {
DPRINTF(("ulptwrite: error=%d\n", err));
error = EIO;
break;
}
}
usbd_free_request(reqh);
usbd_free_request(xfer);
return (error);
}
@ -524,9 +526,11 @@ ulptwrite(dev, uio, flags)
struct uio *uio;
int flags;
{
USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
struct ulpt_softc *sc;
int error;
USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
if (sc->sc_dying)
return (EIO);

View File

@ -288,7 +288,7 @@ umass_usb_transfer(usbd_interface_handle iface, usbd_pipe_handle pipe,
void *buf, int buflen, int flags, int *xfer_size)
{
usbd_device_handle dev;
usbd_request_handle reqh;
usbd_xfer_handle xfer;
usbd_private_handle priv;
void *buffer;
int size;
@ -300,28 +300,28 @@ umass_usb_transfer(usbd_interface_handle iface, usbd_pipe_handle pipe,
usbd_interface2device_handle(iface, &dev);
reqh = usbd_alloc_request(dev);
if (!reqh) {
xfer = usbd_alloc_request(dev);
if (!xfer) {
DPRINTF(UDMASS_USB, ("Not enough memory\n"));
return USBD_NOMEM;
}
(void) usbd_setup_request(reqh, pipe, 0, buf, buflen,
(void) usbd_setup_request(xfer, pipe, 0, buf, buflen,
flags, 3000 /*ms*/, NULL);
err = usbd_sync_transfer(reqh);
err = usbd_sync_transfer(xfer);
if (err) {
DPRINTF(UDMASS_USB, ("transfer failed, %s\n",
usbd_errstr(err)));
usbd_free_request(reqh);
usbd_free_request(xfer);
return(err);
}
usbd_get_request_status(reqh, &priv, &buffer, &size, &err);
usbd_get_request_status(xfer, &priv, &buffer, &size, &err);
if (xfer_size)
*xfer_size = size;
usbd_free_request(reqh);
usbd_free_request(xfer);
return(USBD_NORMAL_COMPLETION);
}

View File

@ -123,7 +123,7 @@ struct ums_softc {
#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
#define MOUSE_FLAGS (HIO_RELATIVE)
static void ums_intr __P((usbd_request_handle reqh,
static void ums_intr __P((usbd_xfer_handle xfer,
usbd_private_handle priv, usbd_status status));
static void ums_add_to_queue __P((struct ums_softc *sc,
@ -166,7 +166,7 @@ USB_MATCH(ums)
usb_interface_descriptor_t *id;
int size, ret;
void *desc;
usbd_status r;
usbd_status err;
if (!uaa->iface)
return (UMATCH_NONE);
@ -174,8 +174,8 @@ USB_MATCH(ums)
if (!id || id->bInterfaceClass != UCLASS_HID)
return (UMATCH_NONE);
r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
if (err)
return (UMATCH_NONE);
if (hid_is_collection(desc, size,
@ -196,7 +196,7 @@ USB_ATTACH(ums)
usb_endpoint_descriptor_t *ed;
int size;
void *desc;
usbd_status r;
usbd_status err;
char devinfo[1024];
u_int32_t flags;
int i;
@ -232,8 +232,8 @@ USB_ATTACH(ums)
USB_ATTACH_ERROR_RETURN;
}
r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
if (err)
USB_ATTACH_ERROR_RETURN;
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
@ -395,8 +395,8 @@ ums_detach(device_t self)
}
void
ums_intr(reqh, addr, status)
usbd_request_handle reqh;
ums_intr(xfer, addr, status)
usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
@ -444,6 +444,12 @@ ums_intr(reqh, addr, status)
sc->status.dy += dy;
sc->status.dz += dz;
/* Discard data in case of full buffer */
if (sc->qcount == sizeof(sc->qbuf)) {
DPRINTF(("Buffer full, discarded packet"));
return;
}
/*
* The Qtronix keyboard has a built in PS/2 port for a mouse.
* The firmware once in a while posts a spurious button up
@ -528,7 +534,7 @@ ums_enable(v)
{
struct ums_softc *sc = v;
usbd_status r;
usbd_status err;
if (sc->sc_enabled)
return EBUSY;
@ -543,12 +549,12 @@ ums_enable(v)
callout_handle_init(&sc->timeout_handle);
/* Set up interrupt pipe. */
r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,
sc->sc_ibuf, sc->sc_isize, ums_intr);
if (r != USBD_NORMAL_COMPLETION) {
if (err) {
DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n",
r));
err));
sc->sc_enabled = 0;
return (EIO);
}
@ -576,6 +582,8 @@ ums_disable(priv)
static int
ums_open(dev_t dev, int flag, int fmt, struct proc *p)
{
struct ums_softc *sc;
USB_GET_SC_OPEN(ums, UMSUNIT(dev), sc);
return ums_enable(sc);
@ -584,6 +592,8 @@ ums_open(dev_t dev, int flag, int fmt, struct proc *p)
static int
ums_close(dev_t dev, int flag, int fmt, struct proc *p)
{
struct ums_softc *sc;
USB_GET_SC(ums, UMSUNIT(dev), sc);
if (!sc)
@ -598,12 +608,14 @@ ums_close(dev_t dev, int flag, int fmt, struct proc *p)
static int
ums_read(dev_t dev, struct uio *uio, int flag)
{
USB_GET_SC(ums, UMSUNIT(dev), sc);
struct ums_softc *sc;
int s;
char buf[sizeof(sc->qbuf)];
int l = 0;
int error;
USB_GET_SC(ums, UMSUNIT(dev), sc);
s = splusb();
if (!sc) {
splx(s);
@ -666,10 +678,12 @@ ums_read(dev_t dev, struct uio *uio, int flag)
static int
ums_poll(dev_t dev, int events, struct proc *p)
{
USB_GET_SC(ums, UMSUNIT(dev), sc);
struct ums_softc *sc;
int revents = 0;
int s;
USB_GET_SC(ums, UMSUNIT(dev), sc);
if (!sc)
return 0;
@ -690,11 +704,13 @@ ums_poll(dev_t dev, int events, struct proc *p)
int
ums_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
USB_GET_SC(ums, UMSUNIT(dev), sc);
struct ums_softc *sc;
int error = 0;
int s;
mousemode_t mode;
USB_GET_SC(ums, UMSUNIT(dev), sc);
if (!sc)
return EIO;

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb.c,v 1.19 1999/09/05 19:32:19 augustss Exp $ */
/* $NetBSD: usb.c,v 1.28 1999/10/13 08:10:57 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -55,17 +55,21 @@
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/ioccom.h>
#include <sys/filio.h>
#include <sys/uio.h>
#include <sys/conf.h>
#endif
#include <sys/conf.h>
#include <sys/poll.h>
#include <sys/select.h>
#include <sys/vnode.h>
#include <sys/signalvar.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#define USB_DEV_MINOR 255
#if defined(__FreeBSD__)
MALLOC_DEFINE(M_USB, "USB", "USB");
MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
@ -74,6 +78,8 @@ MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
#include "usb_if.h"
#endif /* defined(__FreeBSD__) */
#include <machine/bus.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_quirks.h>
@ -81,35 +87,39 @@ MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
#define DPRINTF(x) if (usbdebug) logprintf x
#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
int usbdebug = 0;
extern int uhcidebug;
extern int ohcidebug;
#ifdef UHCI_DEBUG
extern int uhcidebug;
#endif
#ifdef OHCI_DEBUG
extern int ohcidebug;
#endif
int usb_noexplore = 0;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
#endif
#define USBUNIT(dev) (minor(dev))
struct usb_softc {
USBBASEDEVICE sc_dev; /* base device */
USBBASEDEVICE sc_dev; /* base device */
usbd_bus_handle sc_bus; /* USB controller */
struct usbd_port sc_port; /* dummy port for root hub */
char sc_running;
char sc_exploring;
struct selinfo sc_consel; /* waiting for connect change */
int shutdown;
struct proc *event_thread;
#if defined(__FreeBSD__)
/* This part should be deleted when kthreads is available */
struct selinfo sc_consel; /* waiting for connect change */
#else
struct proc *sc_event_thread;
#endif
char sc_dying;
};
#if defined(__NetBSD__) || defined(__OpenBSD__)
int usbopen __P((dev_t, int, int, struct proc *));
int usbclose __P((dev_t, int, int, struct proc *));
int usbioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
int usbpoll __P((dev_t, int, struct proc *));
cdev_decl(usb);
#elif defined(__FreeBSD__)
d_open_t usbopen;
d_close_t usbclose;
d_read_t usbread;
d_ioctl_t usbioctl;
int usbpoll __P((dev_t, int, struct proc *));
@ -131,9 +141,28 @@ struct cdevsw usb_cdevsw = {
};
#endif
usbd_status usb_discover __P((struct usb_softc *));
void usb_create_event_thread __P((void *));
void usb_event_thread __P((void *));
static usbd_status usb_discover __P((struct usb_softc *));
static void usb_create_event_thread __P((void *));
static void usb_event_thread __P((void *));
#define USB_MAX_EVENTS 50
struct usb_event_q {
struct usb_event ue;
SIMPLEQ_ENTRY(usb_event_q) next;
};
static SIMPLEQ_HEAD(, usb_event_q) usb_events =
SIMPLEQ_HEAD_INITIALIZER(usb_events);
static int usb_nevents = 0;
static struct selinfo usb_selevent;
static struct proc *usb_async_proc; /* process who wants USB SIGIO */
static int usb_dev_open = 0;
static int usb_get_next_event __P((struct usb_event *));
#if defined(__NetBSD__) || defined(__OpenBSD__)
/* Flag to see if we are in the cold boot process. */
extern int cold;
#endif
USB_DECLARE_DRIVER(usb);
@ -152,7 +181,7 @@ USB_ATTACH(usb)
void *aux = device_get_ivars(self);
#endif
usbd_device_handle dev;
usbd_status r;
usbd_status err;
#if defined(__NetBSD__) || defined(__OpenBSD__)
printf("\n");
@ -161,38 +190,45 @@ USB_ATTACH(usb)
#endif
DPRINTF(("usbd_attach\n"));
usbd_init();
sc->sc_bus = aux;
sc->sc_bus->usbctl = sc;
sc->sc_running = 1;
sc->sc_bus->use_polling = 1;
sc->sc_port.power = USB_MAX_POWER;
r = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0,0,0, &sc->sc_port);
err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0,
&sc->sc_port);
if (r == USBD_NORMAL_COMPLETION) {
if (!err) {
dev = sc->sc_port.device;
if (!dev->hub) {
sc->sc_running = 0;
if (dev->hub == NULL) {
sc->sc_dying = 1;
printf("%s: root device is not a hub\n",
USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
sc->sc_bus->root_hub = dev;
dev->hub->explore(sc->sc_bus->root_hub);
#if 1
/*
* Turning this code off will delay attachment of USB devices
* until the USB event thread is running, which means that
* the keyboard will not work until after cold boot.
*/
if (cold) {
sc->sc_bus->use_polling++;
dev->hub->explore(sc->sc_bus->root_hub);
sc->sc_bus->use_polling--;
}
#endif
} else {
printf("%s: root hub problem, error=%d\n",
USBDEVNAME(sc->sc_dev), r);
sc->sc_running = 0;
USBDEVNAME(sc->sc_dev), err);
sc->sc_dying = 1;
}
sc->sc_bus->use_polling = 0;
#if defined(__NetBSD__) || defined(__OpenBSD__)
kthread_create(usb_create_event_thread, sc);
#endif
#if defined(__FreeBSD__)
make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR,
0644, "usb%d", device_get_unit(self));
0644, "usb%d", device_get_unit(self));
#endif
USB_ATTACH_SUCCESS_RETURN;
@ -205,7 +241,7 @@ usb_create_event_thread(arg)
{
struct usb_softc *sc = arg;
if (kthread_create1(usb_event_thread, sc, &sc->event_thread,
if (kthread_create1(usb_event_thread, sc, &sc->sc_event_thread,
"%s", sc->sc_dev.dv_xname)) {
printf("%s: unable to create event thread for\n",
sc->sc_dev.dv_xname);
@ -219,17 +255,23 @@ usb_event_thread(arg)
{
struct usb_softc *sc = arg;
while (!sc->shutdown) {
(void)tsleep(&sc->sc_bus->needs_explore,
PWAIT, "usbevt", hz*30);
DPRINTFN(2,("usb_event_thread: woke up\n"));
DPRINTF(("usb_event_thread: start\n"));
while (!sc->sc_dying) {
#ifdef USB_DEBUG
if (!usb_noexplore)
#endif
usb_discover(sc);
(void)tsleep(&sc->sc_bus->needs_explore,
PWAIT, "usbevt", hz*60);
DPRINTFN(2,("usb_event_thread: woke up\n"));
}
sc->event_thread = 0;
sc->sc_event_thread = 0;
/* In case parent is waiting for us to exit. */
wakeup(sc);
DPRINTF(("usb_event_thread: exit\n"));
kthread_exit(0);
}
@ -244,7 +286,7 @@ usbctlprint(aux, pnp)
return (UNCONF);
}
#endif /* NetBSD && OpenBSD */
#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
int
usbopen(dev, flag, mode, p)
@ -252,20 +294,74 @@ usbopen(dev, flag, mode, p)
int flag, mode;
struct proc *p;
{
USB_GET_SC_OPEN(usb, USBUNIT(dev), sc);
int unit = minor(dev);
struct usb_softc *sc;
if (sc == 0 || !sc->sc_running)
return (ENXIO);
if (unit == USB_DEV_MINOR) {
if (usb_dev_open)
return (EBUSY);
usb_dev_open = 1;
usb_async_proc = 0;
return (0);
}
USB_GET_SC_OPEN(usb, unit, sc);
if (sc->sc_dying)
return (EIO);
return (0);
}
int
usbread(dev, uio, flag)
dev_t dev;
struct uio *uio;
int flag;
{
struct usb_event ue;
int s, error, n;
if (minor(dev) != USB_DEV_MINOR)
return (ENXIO);
if (uio->uio_resid != sizeof(struct usb_event))
return (EINVAL);
error = 0;
s = splusb();
for (;;) {
n = usb_get_next_event(&ue);
if (n != 0)
break;
if (flag & IO_NDELAY) {
error = EWOULDBLOCK;
break;
}
error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
if (error)
break;
}
splx(s);
if (!error)
error = uiomove((void *)&ue, uio->uio_resid, uio);
return (error);
}
int
usbclose(dev, flag, mode, p)
dev_t dev;
int flag, mode;
struct proc *p;
{
int unit = minor(dev);
if (unit == USB_DEV_MINOR) {
usb_async_proc = 0;
usb_dev_open = 0;
}
return (0);
}
@ -277,19 +373,48 @@ usbioctl(devt, cmd, data, flag, p)
int flag;
struct proc *p;
{
USB_GET_SC(usb, USBUNIT(devt), sc);
struct usb_softc *sc;
int unit = minor(devt);
if (unit == USB_DEV_MINOR) {
switch (cmd) {
case FIONBIO:
/* All handled in the upper FS layer. */
return (0);
case FIOASYNC:
if (*(int *)data)
usb_async_proc = p;
else
usb_async_proc = 0;
return (0);
default:
return (EINVAL);
}
}
USB_GET_SC(usb, unit, sc);
if (sc->sc_dying)
return (EIO);
if (sc == 0 || !sc->sc_running)
return (ENXIO);
switch (cmd) {
#if defined(__FreeBSD__)
/* This part should be deleted when kthreads is available */
case USB_DISCOVER:
usb_discover(sc);
break;
#endif
#ifdef USB_DEBUG
case USB_SETDEBUG:
usbdebug = uhcidebug = ohcidebug = *(int *)data;
break;
usbdebug = ((*(int *)data) & 0x000000ff);
#ifdef UHCI_DEBUG
uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8;
#endif
#ifdef OHCI_DEBUG
ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16;
#endif
#if defined(__FreeBSD__)
case USB_DISCOVER:
usb_discover(sc);
break;
#endif
case USB_REQUEST:
@ -300,7 +425,7 @@ usbioctl(devt, cmd, data, flag, p)
struct uio uio;
void *ptr = 0;
int addr = ur->addr;
usbd_status r;
usbd_status err;
int error = 0;
DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
@ -328,10 +453,9 @@ usbioctl(devt, cmd, data, flag, p)
goto ret;
}
}
r = usbd_do_request_flags(sc->sc_bus->devices[addr],
&ur->request, ptr,
ur->flags, &ur->actlen);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_do_request_flags(sc->sc_bus->devices[addr],
&ur->request, ptr, ur->flags, &ur->actlen);
if (err) {
error = EIO;
goto ret;
}
@ -368,7 +492,7 @@ usbioctl(devt, cmd, data, flag, p)
break;
default:
return (ENXIO);
return (EINVAL);
}
return (0);
}
@ -379,79 +503,77 @@ usbpoll(dev, events, p)
int events;
struct proc *p;
{
int revents, s;
USB_GET_SC(usb, USBUNIT(dev), sc);
int revents, mask, s;
DPRINTFN(15, ("usbpoll: sc=%p events=0x%x\n", sc, events));
s = splusb();
revents = 0;
if (events & (POLLOUT | POLLWRNORM))
if (sc->sc_bus->needs_explore)
revents |= events & (POLLOUT | POLLWRNORM);
DPRINTFN(15, ("usbpoll: revents=0x%x\n", revents));
if (revents == 0) {
if (events & (POLLOUT | POLLWRNORM)) {
DPRINTFN(2, ("usbpoll: selrecord\n"));
if (minor(dev) == USB_DEV_MINOR) {
revents = 0;
mask = POLLIN | POLLRDNORM;
s = splusb();
if (events & mask && usb_nevents > 0)
revents |= events & mask;
if (revents == 0 && events & mask)
selrecord(p, &usb_selevent);
splx(s);
return (revents);
} else {
#if defined(__FreeBSD__)
/* This part should be deleted when kthreads is available */
struct usb_softc *sc;
int unit = minor(dev);
USB_GET_SC(usb, unit, sc);
revents = 0;
mask = POLLOUT | POLLRDNORM;
s = splusb();
if (events & mask && sc->sc_bus->needs_explore)
revents |= events & mask;
if (revents == 0 && events & mask)
selrecord(p, &sc->sc_consel);
}
splx(s);
return (revents);
#else
return (ENXIO);
#endif
}
splx(s);
return (revents);
}
#if 0
int
usb_bus_count()
{
int i, n;
for (i = n = 0; i < usb_cd.cd_ndevs; i++)
if (usb_cd.cd_devs[i])
n++;
return (n);
}
#endif
#if 0
usbd_status
usb_get_bus_handle(n, h)
int n;
usbd_bus_handle *h;
{
int i;
for (i = 0; i < usb_cd.cd_ndevs; i++)
if (usb_cd.cd_devs[i] && n-- == 0) {
*h = usb_cd.cd_devs[i];
return (USBD_NORMAL_COMPLETION);
}
return (USBD_INVAL);
}
#endif
/* Explore device tree from the root. */
usbd_status
usb_discover(sc)
struct usb_softc *sc;
{
#if defined(__FreeBSD__)
/* The splxxx parts should be deleted when kthreads is available */
int s;
#endif
/* Explore device tree from the root */
/* We need mutual exclusion while traversing the device tree. */
do {
s = splusb();
while (sc->sc_exploring)
tsleep(&sc->sc_exploring, PRIBIO, "usbdis", 0);
sc->sc_exploring = 1;
/*
* We need mutual exclusion while traversing the device tree,
* but this is guaranteed since this function is only called
* from the event thread for the controller.
*/
#if defined(__FreeBSD__)
s = splusb();
#endif
while (sc->sc_bus->needs_explore && !sc->sc_dying) {
sc->sc_bus->needs_explore = 0;
#if defined(__FreeBSD__)
splx(s);
#endif
sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
#if defined(__FreeBSD__)
s = splusb();
sc->sc_exploring = 0;
wakeup(&sc->sc_exploring);
splx(s);
} while (sc->sc_bus->needs_explore);
#endif
}
#if defined(__FreeBSD__)
splx(s);
#endif
return (USBD_NORMAL_COMPLETION);
}
@ -460,18 +582,90 @@ usb_needs_explore(bus)
usbd_bus_handle bus;
{
bus->needs_explore = 1;
#if defined(__FreeBSD__)
/* This part should be deleted when kthreads is available */
selwakeup(&bus->usbctl->sc_consel);
#endif
wakeup(&bus->needs_explore);
}
/* Called at splusb() */
int
usb_get_next_event(ue)
struct usb_event *ue;
{
struct usb_event_q *ueq;
if (usb_nevents <= 0)
return (0);
ueq = SIMPLEQ_FIRST(&usb_events);
*ue = ueq->ue;
SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next);
free(ueq, M_USBDEV);
usb_nevents--;
return (1);
}
void
usbd_add_event(type, dev)
int type;
usbd_device_handle dev;
{
struct usb_event_q *ueq;
struct usb_event ue;
struct timeval thetime;
int s;
s = splusb();
if (++usb_nevents >= USB_MAX_EVENTS) {
/* Too many queued events, drop an old one. */
DPRINTFN(-1,("usb: event dropped\n"));
(void)usb_get_next_event(&ue);
}
/* Don't want to wait here inside splusb() */
ueq = malloc(sizeof *ueq, M_USBDEV, M_NOWAIT);
if (ueq == NULL) {
printf("usb: no memory, event dropped\n");
splx(s);
return;
}
ueq->ue.ue_type = type;
ueq->ue.ue_cookie = dev->cookie;
usbd_fill_deviceinfo(dev, &ueq->ue.ue_device);
microtime(&thetime);
TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next);
wakeup(&usb_events);
selwakeup(&usb_selevent);
if (usb_async_proc != NULL)
psignal(usb_async_proc, SIGIO);
splx(s);
}
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
usb_activate(self, act)
device_ptr_t self;
enum devact act;
{
panic("usb_activate\n");
return (0);
struct usb_softc *sc = (struct usb_softc *)self;
usbd_device_handle dev = sc->sc_port.device;
int i, rv = 0;
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
if (dev && dev->cdesc && dev->subdevs) {
for (i = 0; dev->subdevs[i]; i++)
rv |= config_deactivate(dev->subdevs[i]);
}
break;
}
return (rv);
}
int
@ -479,7 +673,26 @@ usb_detach(self, flags)
device_ptr_t self;
int flags;
{
panic("usb_detach\n");
struct usb_softc *sc = (struct usb_softc *)self;
DPRINTF(("usb_detach: start\n"));
sc->sc_dying = 1;
/* Make all devices disconnect. */
if (sc->sc_port.device)
usb_disconnect_port(&sc->sc_port, self);
/* Kill off event thread. */
if (sc->sc_event_thread) {
wakeup(&sc->sc_bus->needs_explore);
if (tsleep(sc, PWAIT, "usbdet", hz * 60))
printf("%s: event thread didn't die\n",
USBDEVNAME(sc->sc_dev));
DPRINTF(("usb_detach: event thread dead\n"));
}
usbd_finish();
return (0);
}
#elif defined(__FreeBSD__)

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb.h,v 1.33 1999/09/11 08:19:27 augustss Exp $ */
/* $NetBSD: usb.h,v 1.37 1999/10/13 18:52:54 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -43,6 +43,7 @@
#define _USB_H_
#include <sys/types.h>
#include <sys/time.h>
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/ioctl.h>
@ -244,6 +245,7 @@ typedef struct {
#define UE_ISO_ASYNC 0x04
#define UE_ISO_ADAPT 0x08
#define UE_ISO_SYNC 0x0c
#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE)
uWord wMaxPacketSize;
uByte bInterval;
} usb_endpoint_descriptor_t;
@ -339,13 +341,13 @@ typedef struct {
#define USUBCLASS_AUDIOSTREAM 2
#define USUBCLASS_MIDISTREAM 3
#define UCLASS_CDC 2 /* communication */
#define USUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
#define USUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
#define USUBCLASS_ABSTRACT_CONTROL_MODEL 2
#define USUBCLASS_TELEPHONE_CONTROL_MODEL 3
#define USUBCLASS_MULTICHANNEL_CONTROL_MODEL 4
#define USUBCLASS_CAPI_CONTROLMODEL 5
#define USUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
#define USUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
#define USUBCLASS_TELEPHONE_CONTROL_MODEL 3
#define USUBCLASS_MULTICHANNEL_CONTROL_MODEL 4
#define USUBCLASS_CAPI_CONTROLMODEL 5
#define USUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
#define USUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
#define UPROTO_CDC_AT 1
#define UCLASS_HID 3
#define USUBCLASS_BOOT 1
@ -379,7 +381,7 @@ typedef struct {
#define UPROTO_DATA_V120 0x92 /* V.24 rate adaption */
#define UPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */
#define UPROTO_DATA_HOST_BASED 0xfd /* Host based driver */
#define UPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc. */
#define UPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/
#define UPROTO_DATA_VENDOR 0xff /* Vendor specific */
@ -494,7 +496,7 @@ struct usb_device_info {
};
struct usb_ctl_report {
int report;
int report;
u_char data[1024]; /* filled data size will vary */
};
@ -502,6 +504,17 @@ struct usb_device_stats {
u_long requests[4]; /* indexed by transfer type UE_* */
};
typedef struct { u_int32_t cookie; } usb_event_cookie_t;
/* Events that can be read from /dev/usb */
struct usb_event {
int ue_type;
#define USB_EVENT_ATTACH 1
#define USB_EVENT_DETACH 2
struct usb_device_info ue_device;
struct timespec ue_time;
usb_event_cookie_t ue_cookie;
};
/* USB controller */
#define USB_REQUEST _IOWR('U', 1, struct usb_ctl_request)
#define USB_SETDEBUG _IOW ('U', 2, int)

View File

@ -1,5 +1,5 @@
/* $NetBSD: usb_mem.h,v 1.7 1999/09/09 12:26:47 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: usb_mem.h,v 1.9 1999/10/13 08:10:58 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -54,8 +54,8 @@ typedef struct usb_dma_block {
#define DMAADDR(dma) ((dma)->block->segs[0].ds_addr + (dma)->offs)
#define KERNADDR(dma) ((void *)((dma)->block->kaddr + (dma)->offs))
usbd_status usb_allocmem __P((bus_dma_tag_t, size_t, size_t, usb_dma_t *));
void usb_freemem __P((bus_dma_tag_t, usb_dma_t *));
usbd_status usb_allocmem __P((usbd_bus_handle,size_t,size_t, usb_dma_t *));
void usb_freemem __P((usbd_bus_handle, usb_dma_t *));
#elif defined(__FreeBSD__)

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_port.h,v 1.11 1999/09/11 08:19:27 augustss Exp $ */
/* $NetBSD: usb_port.h,v 1.13 1999/10/13 08:10:58 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -50,6 +50,16 @@
#include "opt_usbverbose.h"
#ifdef USB_DEBUG
#define UHID_DEBUG 1
#define OHCI_DEBUG 1
#define UGEN_DEBUG 1
#define UHCI_DEBUG 1
#define UHUB_DEBUG 1
#define ULPT_DEBUG 1
#define UAUDIO_DEBUG 1
#endif
typedef struct device *device_ptr_t;
#define USBBASEDEVICE struct device
#define USBDEV(bdev) (&(bdev))
@ -123,7 +133,6 @@ __CONCAT(dname,_detach)(self, flags) \
(struct __CONCAT(dname,_softc) *)self
#define USB_GET_SC_OPEN(dname, unit, sc) \
struct __CONCAT(dname,_softc) *sc; \
if (unit >= __CONCAT(dname,_cd).cd_ndevs) \
return (ENXIO); \
sc = __CONCAT(dname,_cd).cd_devs[unit]; \
@ -131,7 +140,7 @@ __CONCAT(dname,_detach)(self, flags) \
return (ENXIO)
#define USB_GET_SC(dname, unit, sc) \
struct __CONCAT(dname,_softc) *sc = __CONCAT(dname,_cd).cd_devs[unit]
sc = __CONCAT(dname,_cd).cd_devs[unit]
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(config_found_sm(parent, args, print, sub))
@ -140,6 +149,15 @@ __CONCAT(dname,_detach)(self, flags) \
/*
* OpenBSD
*/
#ifdef USB_DEBUG
#define UHID_DEBUG 1
#define OHCI_DEBUG 1
#define UGEN_DEBUG 1
#define UHCI_DEBUG 1
#define UHUB_DEBUG 1
#define ULPT_DEBUG 1
#endif
#define memcpy(d, s, l) bcopy((s),(d),(l))
#define memset(d, v, l) bzero((d),(l))
#define bswap32(x) swap32(x)
@ -150,6 +168,10 @@ __CONCAT(dname,_detach)(self, flags) \
#define uhidpoll uhidselect
#define ugenpoll ugenselect
#define powerhook_establish(fn, sc) 0
#define powerhook_disestablish(hdl)
#define PWR_RESUME 0
typedef struct device device_ptr_t;
#define USBBASEDEVICE struct device
#define USBDEV(bdev) (&(bdev))
@ -223,7 +245,6 @@ __CONCAT(dname,_detach)(self, flags) \
(struct __CONCAT(dname,_softc) *)self
#define USB_GET_SC_OPEN(dname, unit, sc) \
struct __CONCAT(dname,_softc) *sc; \
if (unit >= __CONCAT(dname,_cd).cd_ndevs) \
return (ENXIO); \
sc = __CONCAT(dname,_cd).cd_devs[unit]; \
@ -231,7 +252,7 @@ __CONCAT(dname,_detach)(self, flags) \
return (ENXIO)
#define USB_GET_SC(dname, unit, sc) \
struct __CONCAT(dname,_softc) *sc = __CONCAT(dname,_cd).cd_devs[unit]
sc = __CONCAT(dname,_cd).cd_devs[unit]
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(config_found_sm(parent, args, print, sub))
@ -257,15 +278,22 @@ __CONCAT(dname,_detach)(self, flags) \
*/
#define memcpy(d, s, l) bcopy((s),(d),(l))
#define memset(d, v, l) bzero((d),(l))
#define bswap32(x) swap32(x) /* XXX not available in FreeBSD */
#define kthread_create1
#define kthread_create
#define bswap32(x) swap32(x)
#define kthread_create1(function, sc, priv, string, name)
#define kthread_create(create_function, sc)
#define kthread_exit(err)
#define usb_timeout(f, d, t, h) ((h) = timeout((f), (d), (t)))
#define usb_untimeout(f, d, h) untimeout((f), (d), (h))
#define USB_DECLARE_DRIVER_INIT(dname, init...) \
#define clalloc(p, s, x) (clist_alloc_cblocks((p), (s), (x)), 0)
#define clfree(p) clist_free_cblocks((p))
#define powerhook_establish(fn, sc) 0
#define powerhook_disestablish(hdl)
#define PWR_RESUME 0
#define USB_DECLARE_DRIVER_INIT(dname, init) \
static device_probe_t __CONCAT(dname,_match); \
static device_attach_t __CONCAT(dname,_attach); \
static device_detach_t __CONCAT(dname,_detach); \
@ -288,6 +316,7 @@ static driver_t __CONCAT(dname,_driver) = { \
#define METHODS_NONE {0,0}
#define USB_DECLARE_DRIVER(dname) USB_DECLARE_DRIVER_INIT(dname, METHODS_NONE)
#define USB_MATCH(dname) \
static int \
__CONCAT(dname,_match)(device_t self)
@ -319,14 +348,12 @@ __CONCAT(dname,_detach)(device_t self)
struct __CONCAT(dname,_softc) *sc = device_get_softc(self)
#define USB_GET_SC_OPEN(dname, unit, sc) \
struct __CONCAT(dname,_softc) *sc = \
devclass_get_softc(__CONCAT(dname,_devclass), unit); \
sc = devclass_get_softc(__CONCAT(dname,_devclass), unit); \
if (!sc) \
return (ENXIO)
#define USB_GET_SC(dname, unit, sc) \
struct __CONCAT(dname,_softc) *sc = \
devclass_get_softc(__CONCAT(dname,_devclass), unit)
sc = devclass_get_softc(__CONCAT(dname,_devclass), unit)
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(device_probe_and_attach((bdev)) == 0 ? (bdev) : 0)
@ -355,7 +382,3 @@ __CONCAT(dname,_detach)(device_t self)
#define logprintf printf
#endif /* __FreeBSD__ */
#if defined(__NetBSD__) || defined(__OpenBSD__)
#elif defined(__FreeBSD__)
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_quirks.c,v 1.13 1999/09/15 12:30:59 augustss Exp $ */
/* $NetBSD: usb_quirks.c,v 1.14 1999/09/15 13:57:09 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -50,12 +50,12 @@
extern int usbdebug;
#endif
struct usbd_quirk_entry {
static struct usbd_quirk_entry {
u_int16_t idVendor;
u_int16_t idProduct;
u_int16_t bcdDevice;
struct usbd_quirks quirks;
} quirks[] = {
} usb_quirks[] = {
{ USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, 0x100, { UQ_NO_SET_PROTO}},
{ USB_VENDOR_INSIDEOUT,USB_PRODUCT_INSIDEOUT_EDGEPORT4,
0x094, { UQ_SWAP_UNICODE}},
@ -76,7 +76,7 @@ usbd_find_quirk(d)
{
struct usbd_quirk_entry *t;
for (t = quirks; t->idVendor != 0; t++) {
for (t = usb_quirks; t->idVendor != 0; t++) {
if (t->idVendor == UGETW(d->idVendor) &&
t->idProduct == UGETW(d->idProduct) &&
t->bcdDevice == UGETW(d->bcdDevice))

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_subr.c,v 1.45 1999/09/09 12:26:47 augustss Exp $ */
/* $NetBSD: usb_subr.c,v 1.52 1999/10/13 08:10:58 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -51,6 +51,8 @@
#endif
#include <sys/proc.h>
#include <machine/bus.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@ -74,19 +76,20 @@ extern int usbdebug;
#endif
static usbd_status usbd_set_config __P((usbd_device_handle, int));
char *usbd_get_string __P((usbd_device_handle, int, char *));
int usbd_getnewaddr __P((usbd_bus_handle bus));
int usbd_print __P((void *aux, const char *pnp));
static char *usbd_get_string __P((usbd_device_handle, int, char *));
static int usbd_getnewaddr __P((usbd_bus_handle bus));
#if defined(__NetBSD__)
int usbd_submatch __P((device_ptr_t, struct cfdata *cf, void *));
static int usbd_print __P((void *aux, const char *pnp));
static int usbd_submatch __P((device_ptr_t, struct cfdata *cf, void *));
#elif defined(__OpenBSD__)
int usbd_submatch __P((device_ptr_t, void *, void *));
static int usbd_submatch __P((device_ptr_t, void *, void *));
#endif
void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno));
void usbd_kill_pipe __P((usbd_pipe_handle));
usbd_status usbd_probe_and_attach
static void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno));
static void usbd_kill_pipe __P((usbd_pipe_handle));
static usbd_status usbd_probe_and_attach
__P((device_ptr_t parent, usbd_device_handle dev, int port, int addr));
static u_int32_t usb_cookie_no = 0;
#ifdef USBVERBOSE
typedef u_int16_t usb_vendor_id_t;
@ -104,9 +107,9 @@ struct usb_knowndev {
#define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
#include <dev/usb/usbdevs_data.h>
#endif
#endif /* USBVERBOSE */
const char *usbd_error_strs[] = {
static const char *usbd_error_strs[] = {
"NORMAL_COMPLETION",
"IN_PROGRESS",
"PENDING_REQUESTS",
@ -151,16 +154,16 @@ usbd_get_string_desc(dev, sindex, langid, sdesc)
usb_string_descriptor_t *sdesc;
{
usb_device_request_t req;
usbd_status r;
usbd_status err;
req.bmRequestType = UT_READ_DEVICE;
req.bRequest = UR_GET_DESCRIPTOR;
USETW2(req.wValue, UDESC_STRING, sindex);
USETW(req.wIndex, langid);
USETW(req.wLength, 1); /* only size byte first */
r = usbd_do_request(dev, &req, sdesc);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_do_request(dev, &req, sdesc);
if (err)
return (err);
USETW(req.wLength, sdesc->bLength); /* the whole string */
return (usbd_do_request(dev, &req, sdesc));
}
@ -176,7 +179,7 @@ usbd_get_string(dev, si, buf)
char *s;
int i, n;
u_int16_t c;
usbd_status r;
usbd_status err;
if (si == 0)
return (0);
@ -184,16 +187,16 @@ usbd_get_string(dev, si, buf)
return (0);
if (dev->langid == USBD_NOLANG) {
/* Set up default language */
r = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us);
if (r != USBD_NORMAL_COMPLETION || us.bLength < 4) {
err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us);
if (err || us.bLength < 4) {
dev->langid = 0; /* Well, just pick English then */
} else {
/* Pick the first language as the default. */
dev->langid = UGETW(us.bString[0]);
}
}
r = usbd_get_string_desc(dev, si, dev->langid, &us);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_get_string_desc(dev, si, dev->langid, &us);
if (err)
return (0);
s = buf;
n = us.bLength / 2 - 1;
@ -208,7 +211,7 @@ usbd_get_string(dev, si, buf)
*s++ = '?';
}
*s++ = 0;
return buf;
return (buf);
}
void
@ -222,7 +225,7 @@ usbd_devinfo_vp(dev, v, p)
struct usb_knowndev *kdp;
#endif
if (!dev) {
if (dev == NULL) {
v[0] = p[0] = '\0';
return;
}
@ -230,7 +233,7 @@ usbd_devinfo_vp(dev, v, p)
vendor = usbd_get_string(dev, udd->iManufacturer, v);
product = usbd_get_string(dev, udd->iProduct, p);
#ifdef USBVERBOSE
if (!vendor) {
if (vendor == NULL) {
for(kdp = usb_knowndevs;
kdp->vendorname != NULL;
kdp++) {
@ -248,12 +251,11 @@ usbd_devinfo_vp(dev, v, p)
}
}
#endif
if (vendor)
if (vendor != NULL)
strcpy(v, vendor);
else
sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
if (product)
if (product != NULL)
strcpy(p, product);
else
sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
@ -322,7 +324,7 @@ usbd_reset_port(dev, port, ps)
usb_port_status_t *ps;
{
usb_device_request_t req;
usbd_status r;
usbd_status err;
int n;
req.bmRequestType = UT_WRITE_CLASS_OTHER;
@ -330,34 +332,36 @@ usbd_reset_port(dev, port, ps)
USETW(req.wValue, UHF_PORT_RESET);
USETW(req.wIndex, port);
USETW(req.wLength, 0);
r = usbd_do_request(dev, &req, 0);
err = usbd_do_request(dev, &req, 0);
DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
port, usbd_errstr(r)));
if (r != USBD_NORMAL_COMPLETION)
return (r);
port, usbd_errstr(err)));
if (err)
return (err);
n = 10;
do {
/* Wait for device to recover from reset. */
usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
r = usbd_get_port_status(dev, port, ps);
if (r != USBD_NORMAL_COMPLETION) {
DPRINTF(("usbd_reset_port: get status failed %d\n",r));
return (r);
err = usbd_get_port_status(dev, port, ps);
if (err) {
DPRINTF(("usbd_reset_port: get status failed %d\n",
err));
return (err);
}
} while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
if (n == 0) {
printf("usbd_reset_port: timeout\n");
return (USBD_IOERROR);
}
r = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
#ifdef USB_DEBUG
if (r != USBD_NORMAL_COMPLETION)
DPRINTF(("usbd_reset_port: clear port feature failed %d\n",r));
if (err)
DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
err));
#endif
/* Wait for the device to recover from reset. */
usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
return (r);
return (err);
}
usb_interface_descriptor_t *
@ -408,7 +412,7 @@ usbd_find_edesc(cd, ifaceidx, altidx, endptidx)
int curidx;
d = usbd_find_idesc(cd, ifaceidx, altidx);
if (!d)
if (d == NULL)
return (0);
if (endptidx >= d->bNumEndpoints) /* quick exit */
return (0);
@ -524,14 +528,14 @@ usbd_set_config_no(dev, no, msg)
{
int index;
usb_config_descriptor_t cd;
usbd_status r;
usbd_status err;
DPRINTFN(5,("usbd_set_config_no: %d\n", no));
/* Figure out what config index to use. */
for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
r = usbd_get_config_desc(dev, index, &cd);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_get_config_desc(dev, index, &cd);
if (err)
return (err);
if (cd.bConfigurationValue == no)
return (usbd_set_config_index(dev, index, msg));
}
@ -546,7 +550,7 @@ usbd_set_config_index(dev, index, msg)
{
usb_status_t ds;
usb_config_descriptor_t cd, *cdp;
usbd_status r;
usbd_status err;
int ifcidx, nifc, len, selfpowered, power;
DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
@ -566,34 +570,34 @@ usbd_set_config_index(dev, index, msg)
}
/* Figure out what config number to use. */
r = usbd_get_config_desc(dev, index, &cd);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_get_config_desc(dev, index, &cd);
if (err)
return (err);
len = UGETW(cd.wTotalLength);
cdp = malloc(len, M_USB, M_NOWAIT);
if (cdp == 0)
if (cdp == NULL)
return (USBD_NOMEM);
r = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
if (err)
goto bad;
if (cdp->bDescriptorType != UDESC_CONFIG) {
DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
cdp->bDescriptorType));
r = USBD_INVAL;
err = USBD_INVAL;
goto bad;
}
selfpowered = 0;
if (cdp->bmAttributes & UC_SELF_POWERED) {
if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
cdp->bmAttributes & UC_SELF_POWERED) {
/* May be self powered. */
if (cdp->bmAttributes & UC_BUS_POWERED) {
/* Must ask device. */
r = usbd_get_device_status(dev, &ds);
if (r == USBD_NORMAL_COMPLETION &&
(UGETW(ds.wStatus) & UDS_SELF_POWERED))
err = usbd_get_device_status(dev, &ds);
if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
selfpowered = 1;
DPRINTF(("usbd_set_config_index: status=0x%04x, "
"error=%s\n",
UGETW(ds.wStatus), usbd_errstr(r)));
UGETW(ds.wStatus), usbd_errstr(err)));
} else
selfpowered = 1;
}
@ -602,7 +606,7 @@ usbd_set_config_index(dev, index, msg)
dev->address, cdp->bmAttributes,
selfpowered, cdp->bMaxPower * 2));
#ifdef USB_DEBUG
if (!dev->powersrc) {
if (dev->powersrc == NULL) {
DPRINTF(("usbd_set_config_index: No power source?\n"));
return (USBD_IOERROR);
}
@ -616,7 +620,7 @@ usbd_set_config_index(dev, index, msg)
USBDEVNAME(dev->bus->bdev), dev->address,
cdp->bConfigurationValue,
power, dev->powersrc->power);
r = USBD_NO_POWER;
err = USBD_NO_POWER;
goto bad;
}
dev->power = power;
@ -624,11 +628,11 @@ usbd_set_config_index(dev, index, msg)
DPRINTF(("usbd_set_config_index: set config %d\n",
cdp->bConfigurationValue));
r = usbd_set_config(dev, cdp->bConfigurationValue);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_set_config(dev, cdp->bConfigurationValue);
if (err) {
DPRINTF(("usbd_set_config_index: setting config=%d failed, "
"error=%s\n",
cdp->bConfigurationValue, usbd_errstr(r)));
cdp->bConfigurationValue, usbd_errstr(err)));
goto bad;
}
DPRINTF(("usbd_set_config_index: setting new config %d\n",
@ -637,15 +641,15 @@ usbd_set_config_index(dev, index, msg)
dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
M_USB, M_NOWAIT);
if (dev->ifaces == 0) {
r = USBD_NOMEM;
err = USBD_NOMEM;
goto bad;
}
DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
dev->cdesc = cdp;
dev->config = cdp->bConfigurationValue;
for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
r = usbd_fill_iface_data(dev, ifcidx, 0);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_fill_iface_data(dev, ifcidx, 0);
if (err) {
while (--ifcidx >= 0)
usbd_free_iface_data(dev, ifcidx);
goto bad;
@ -656,7 +660,7 @@ usbd_set_config_index(dev, index, msg)
bad:
free(cdp, M_USB);
return (r);
return (err);
}
/* XXX add function for alternate settings */
@ -669,29 +673,29 @@ usbd_setup_pipe(dev, iface, ep, pipe)
usbd_pipe_handle *pipe;
{
usbd_pipe_handle p;
usbd_status r;
usbd_status err;
DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
dev, iface, ep, pipe));
p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
if (p == 0)
if (p == NULL)
return (USBD_NOMEM);
p->device = dev;
p->iface = iface;
p->endpoint = ep;
ep->refcnt++;
p->refcnt = 1;
p->intrreqh = 0;
p->intrxfer = 0;
p->running = 0;
p->repeat = 0;
SIMPLEQ_INIT(&p->queue);
r = dev->bus->methods->open_pipe(p);
if (r != USBD_NORMAL_COMPLETION) {
err = dev->bus->methods->open_pipe(p);
if (err) {
DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
"%s\n",
ep->edesc->bEndpointAddress, usbd_errstr(r)));
ep->edesc->bEndpointAddress, usbd_errstr(err)));
free(p, M_USB);
return (r);
return (err);
}
/* Clear any stall and make sure DATA0 toggle will be used next. */
if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT)
@ -732,7 +736,8 @@ usbd_probe_and_attach(parent, dev, port, addr)
{
struct usb_attach_arg uaa;
usb_device_descriptor_t *dd = &dev->ddesc;
int r, found, i, confi, nifaces;
int found, i, confi, nifaces;
usbd_status err;
device_ptr_t dv;
usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
@ -779,12 +784,12 @@ usbd_probe_and_attach(parent, dev, port, addr)
for (confi = 0; confi < dd->bNumConfigurations; confi++) {
DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
confi));
r = usbd_set_config_index(dev, confi, 1);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_set_config_index(dev, confi, 1);
if (err) {
#ifdef USB_DEBUG
DPRINTF(("%s: port %d, set config at addr %d failed, "
"error=%s\n", USBDEVPTRNAME(parent), port,
addr, usbd_errstr(r)));
addr, usbd_errstr(err)));
#else
printf("%s: port %d, set config at addr %d failed\n",
USBDEVPTRNAME(parent), port, addr);
@ -792,8 +797,8 @@ usbd_probe_and_attach(parent, dev, port, addr)
#if defined(__FreeBSD__)
device_delete_child(parent, bdev);
#endif
return (r);
return (err);
}
nifaces = dev->cdesc->bNumInterface;
uaa.configno = dev->cdesc->bConfigurationValue;
@ -801,7 +806,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
ifaces[i] = &dev->ifaces[i];
uaa.ifaces = ifaces;
uaa.nifaces = nifaces;
dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB,M_NOWAIT);
if (dev->subdevs == 0) {
#if defined(__FreeBSD__)
@ -812,21 +816,20 @@ usbd_probe_and_attach(parent, dev, port, addr)
found = 0;
for (i = 0; i < nifaces; i++) {
if (!ifaces[i])
if (ifaces[i] == NULL)
continue; /* interface already claimed */
uaa.iface = ifaces[i];
uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
usbd_submatch);
if (dv) {
if (dv != NULL) {
dev->subdevs[found++] = dv;
dev->subdevs[found] = 0;
ifaces[i] = 0; /* consumed */
#if defined(__FreeBSD__)
/* create another child for the next iface */
bdev = device_add_child(parent, NULL, -1, &uaa);
bdev = device_add_child(parent, NULL, -1,&uaa);
if (!bdev) {
printf("%s: Device creation failed\n",
USBDEVNAME(dev->bus->bdev));
@ -836,7 +839,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
#endif
}
}
if (found != 0) {
#if defined(__FreeBSD__)
/* remove the last created child again; it is unused */
@ -844,7 +846,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
#endif
return (USBD_NORMAL_COMPLETION);
}
free(dev->subdevs, M_USB);
dev->subdevs = 0;
}
@ -864,7 +865,7 @@ usbd_probe_and_attach(parent, dev, port, addr)
uaa.product = UHUB_UNK_PRODUCT;
uaa.release = UHUB_UNK_RELEASE;
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
if (dv) {
if (dv != NULL) {
dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
if (dev->subdevs == 0)
return (USBD_NOMEM);
@ -886,7 +887,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
}
/*
* Called when a new device has been put in the powered state,
* but not yet in the addressed state.
@ -904,7 +904,7 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
{
usbd_device_handle dev;
usb_device_descriptor_t *dd;
usbd_status r;
usbd_status err;
int addr;
int i;
@ -918,7 +918,7 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
}
dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
if (dev == 0)
if (dev == NULL)
return (USBD_NOMEM);
memset(dev, 0, sizeof(*dev));
@ -942,30 +942,31 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
dev->depth = depth;
dev->powersrc = up;
dev->langid = USBD_NOLANG;
dev->cookie.cookie = ++usb_cookie_no;
/* Establish the the default pipe. */
r = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe);
if (err) {
usbd_remove_device(dev, up);
return (r);
return (err);
}
up->device = dev;
dd = &dev->ddesc;
/* Try a few times in case the device is slow (i.e. outside specs.) */
for (i = 0; i < 5; i++) {
/* for (i = 0; i < 5; i++) { */
for (i = 0; i < 3; i++) {
/* Get the first 8 bytes of the device descriptor. */
r = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
if (r == USBD_NORMAL_COMPLETION)
err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
if (!err)
break;
usbd_delay_ms(dev, 200);
}
if (r != USBD_NORMAL_COMPLETION) {
if (err) {
DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
"failed\n",
addr));
"failed\n", addr));
usbd_remove_device(dev, up);
return (r);
return (err);
}
DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
@ -991,24 +992,24 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
/* Get the full device descriptor. */
r = usbd_get_device_desc(dev, dd);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_get_device_desc(dev, dd);
if (err) {
DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
"failed\n", addr));
usbd_remove_device(dev, up);
return (r);
return (err);
}
/* Figure out what's wrong with this device. */
dev->quirks = usbd_find_quirk(dd);
/* Set the address */
r = usbd_set_address(dev, addr);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_set_address(dev, addr);
if (err) {
DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr));
r = USBD_SET_ADDR_FAILED;
err = USBD_SET_ADDR_FAILED;
usbd_remove_device(dev, up);
return (r);
return (err);
}
/* Allow device time to set new address */
usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
@ -1023,12 +1024,13 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
addr, dev, parent));
r = usbd_probe_and_attach(parent, dev, port, addr);
if (r != USBD_NORMAL_COMPLETION) {
err = usbd_probe_and_attach(parent, dev, port, addr);
if (err) {
usbd_remove_device(dev, up);
return (r);
return (err);
}
usbd_add_event(USB_EVENT_ATTACH, dev);
return (USBD_NORMAL_COMPLETION);
}
@ -1039,7 +1041,7 @@ usbd_remove_device(dev, up)
{
DPRINTF(("usbd_remove_device: %p\n", dev));
if (dev->default_pipe)
if (dev->default_pipe != NULL)
usbd_kill_pipe(dev->default_pipe);
up->device = 0;
dev->bus->devices[dev->address] = 0;
@ -1134,7 +1136,7 @@ usbd_fill_deviceinfo(dev, di)
struct usb_device_info *di;
{
struct usbd_port *p;
int i, r, s;
int i, err, s;
di->config = dev->config;
usbd_devinfo_vp(dev, di->vendor, di->product);
@ -1152,19 +1154,19 @@ usbd_fill_deviceinfo(dev, di)
i++) {
p = &dev->hub->ports[i];
if (p->device)
r = p->device->address;
err = p->device->address;
else {
s = UGETW(p->status.wPortStatus);
if (s & UPS_PORT_ENABLED)
r = USB_PORT_ENABLED;
err = USB_PORT_ENABLED;
else if (s & UPS_SUSPEND)
r = USB_PORT_SUSPENDED;
err = USB_PORT_SUSPENDED;
else if (s & UPS_PORT_POWER)
r = USB_PORT_POWERED;
err = USB_PORT_POWERED;
else
r = USB_PORT_DISABLED;
err = USB_PORT_DISABLED;
}
di->ports[i] = r;
di->ports[i] = err;
}
di->nports = dev->hub->hubdesc.bNbrPorts;
} else
@ -1177,17 +1179,87 @@ usb_free_device(dev)
{
int ifcidx, nifc;
if (dev->default_pipe)
if (dev->default_pipe != NULL)
usbd_kill_pipe(dev->default_pipe);
if (dev->ifaces) {
if (dev->ifaces != NULL) {
nifc = dev->cdesc->bNumInterface;
for (ifcidx = 0; ifcidx < nifc; ifcidx++)
usbd_free_iface_data(dev, ifcidx);
free(dev->ifaces, M_USB);
}
if (dev->cdesc)
if (dev->cdesc != NULL)
free(dev->cdesc, M_USB);
if (dev->subdevs)
if (dev->subdevs != NULL)
free(dev->subdevs, M_USB);
free(dev, M_USB);
}
/*
* The general mechanism for detaching drivers works as follows: Each
* driver is responsible for maintaining a reference count on the
* number of outstanding references to its softc (e.g. from
* processing hanging in a read or write). The detach method of the
* driver decrements this counter and flags in the softc that the
* driver is dying and then wakes any sleepers. It then sleeps on the
* softc. Each place that can sleep must maintain the reference
* count. When the reference count drops to -1 (0 is the normal value
* of the reference count) the a wakeup on the softc is performed
* signaling to the detach waiter that all references are gone.
*/
/*
* Called from process context when we discover that a port has
* been disconnected.
*/
void
usb_disconnect_port(up, parent)
struct usbd_port *up;
device_ptr_t parent;
{
usbd_device_handle dev = up->device;
char *hubname = USBDEVPTRNAME(parent);
int i;
DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
up, dev, up->portno));
#ifdef DIAGNOSTIC
if (!dev) {
printf("usb_disconnect_port: no device\n");
return;
}
#endif
if (!dev->cdesc) {
/* Partially attached device, just drop it. */
dev->bus->devices[dev->address] = 0;
up->device = 0;
return;
}
if (dev->subdevs != NULL) {
for (i = 0; dev->subdevs[i]; i++) {
if (!dev->subdevs[i]) /* skip empty elements */
continue;
printf("%s: at %s", USBDEVPTRNAME(dev->subdevs[i]),
hubname);
if (up->portno != 0)
printf(" port %d", up->portno);
printf(" (addr %d) disconnected\n", dev->address);
#if defined(__NetBSD__) || defined(__OpenBSD__)
config_detach(dev->subdevs[i], DETACH_FORCE);
#elif defined(__FreeBSD__)
device_delete_child(device_get_parent(dev->subdevs[i]),
dev->subdevs[i]);
#endif
}
}
usbd_add_event(USB_EVENT_DETACH, dev);
dev->bus->devices[dev->address] = 0;
up->device = 0;
usb_free_device(dev);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbcdc.h,v 1.4 1999/08/16 20:20:19 augustss Exp $ */
/* $NetBSD: usbcdc.h,v 1.3 1999/01/03 01:09:18 augustss Exp $ */
/* $FreeBSD$ */
/*

View File

@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
* NetBSD: usbdevs,v 1.58 1999/11/10 15:55:51 matt Exp
* NetBSD: usbdevs,v 1.59 1999/11/10 19:46:40 augustss Exp
*/
/*
@ -99,6 +99,7 @@
#define USB_VENDOR_INSYSTEM 0x05ab /* In-System Design */
#define USB_VENDOR_APPLE 0x05ac /* Apple Computer */
#define USB_VENDOR_QTRONIX 0x05c7 /* Qtronix Corp */
#define USB_VENDOR_ELSA 0x05cc /* ELSA Gmbh */
#define USB_VENDOR_EIZONANAO 0x05e7 /* EIZO Nanao */
#define USB_VENDOR_PIENGINEERING 0x05f3 /* P.I. Engineering */
#define USB_VENDOR_CHIC 0x05fe /* Chic Technology */
@ -135,6 +136,7 @@
/* CATC products */
#define USB_PRODUCT_CATC_ANDROMEDA 0x1237 /* Andromeda hub */
#define USB_PRODUCT_CATC_CHIEF 0x000d /* USB Chief Bus & Protocol Analyzer */
/* Gravis products */
#define USB_PRODUCT_GRAVIS_GAMEPADPRO 0x4001 /* GamePad Pro */
@ -276,6 +278,9 @@
/* Qtronix products */
#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */
/* Elsa products */
#define USB_PRODUCT_ELSA_MODEM1 0x2265 /* ELSA Modem Board */
/* Logitech products */
#define USB_PRODUCT_LOGITECH_M2452 0x0203 /* M2452 keyboard */
#define USB_PRODUCT_LOGITECH_M4848 0x0301 /* M4848 mouse */

View File

@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
* NetBSD: usbdevs,v 1.58 1999/11/10 15:55:51 matt Exp
* NetBSD: usbdevs,v 1.59 1999/11/10 19:46:40 augustss Exp
*/
/*
@ -93,6 +93,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Computer Access Technology Corp.",
"Andromeda hub",
},
{
USB_VENDOR_CATC, USB_PRODUCT_CATC_CHIEF,
0,
"Computer Access Technology Corp.",
"USB Chief Bus & Protocol Analyzer",
},
{
USB_VENDOR_GRAVIS, USB_PRODUCT_GRAVIS_GAMEPADPRO,
0,
@ -417,6 +423,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Qtronix Corp",
"Scorpion-980N keyboard",
},
{
USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1,
0,
"ELSA Gmbh",
"ELSA Modem Board",
},
{
USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M2452,
0,
@ -903,6 +915,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Qtronix Corp",
NULL,
},
{
USB_VENDOR_ELSA, 0,
USB_KNOWNDEV_NOPROD,
"ELSA Gmbh",
NULL,
},
{
USB_VENDOR_EIZONANAO, 0,
USB_KNOWNDEV_NOPROD,

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi.h,v 1.28 1999/09/11 08:19:27 augustss Exp $ */
/* $NetBSD: usbdi.h,v 1.31 1999/10/13 08:10:58 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -42,11 +42,11 @@ typedef struct usbd_bus *usbd_bus_handle;
typedef struct usbd_device *usbd_device_handle;
typedef struct usbd_interface *usbd_interface_handle;
typedef struct usbd_pipe *usbd_pipe_handle;
typedef struct usbd_request *usbd_request_handle;
typedef struct usbd_xfer *usbd_xfer_handle;
typedef void *usbd_private_handle;
typedef enum { /* keep in sync with usbd_status_msgs */
USBD_NORMAL_COMPLETION = 0, /* must be 0 */
typedef enum { /* keep in sync with usbd_status_msgs */
USBD_NORMAL_COMPLETION = 0, /* must be 0 */
USBD_IN_PROGRESS,
/* errors */
USBD_PENDING_REQUESTS,
@ -72,15 +72,16 @@ typedef enum { /* keep in sync with usbd_status_msgs */
typedef int usbd_lock_token;
typedef void (*usbd_callback) __P((usbd_request_handle, usbd_private_handle,
typedef void (*usbd_callback) __P((usbd_xfer_handle, usbd_private_handle,
usbd_status));
/* Open flags */
#define USBD_EXCLUSIVE_USE 0x01
/* Request flags */
#define USBD_NO_COPY 0x01 /* do not copy data to DMA buffer */
#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
#define USBD_SYNCHRONOUS 0x08 /* wait for completion */
#define USBD_NO_TIMEOUT 0
#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
@ -93,25 +94,25 @@ usbd_status usbd_open_pipe
__P((usbd_interface_handle iface, u_int8_t address,
u_int8_t flags, usbd_pipe_handle *pipe));
usbd_status usbd_close_pipe __P((usbd_pipe_handle pipe));
usbd_status usbd_transfer __P((usbd_request_handle req));
usbd_request_handle usbd_alloc_request __P((usbd_device_handle));
usbd_status usbd_free_request __P((usbd_request_handle reqh));
usbd_status usbd_transfer __P((usbd_xfer_handle req));
usbd_xfer_handle usbd_alloc_request __P((usbd_device_handle));
usbd_status usbd_free_request __P((usbd_xfer_handle xfer));
void usbd_setup_request
__P((usbd_request_handle reqh, usbd_pipe_handle pipe,
__P((usbd_xfer_handle xfer, usbd_pipe_handle pipe,
usbd_private_handle priv, void *buffer,
u_int32_t length, u_int16_t flags, u_int32_t timeout,
usbd_callback));
void usbd_setup_default_request
__P((usbd_request_handle reqh, usbd_device_handle dev,
__P((usbd_xfer_handle xfer, usbd_device_handle dev,
usbd_private_handle priv, u_int32_t timeout,
usb_device_request_t *req, void *buffer,
u_int32_t length, u_int16_t flags, usbd_callback));
void usbd_setup_isoc_request
__P((usbd_request_handle reqh, usbd_pipe_handle pipe,
__P((usbd_xfer_handle xfer, usbd_pipe_handle pipe,
usbd_private_handle priv, u_int16_t *frlengths,
u_int32_t nframes, usbd_callback));
u_int32_t nframes, u_int16_t flags, usbd_callback));
void usbd_get_request_status
__P((usbd_request_handle reqh, usbd_private_handle *priv,
__P((usbd_xfer_handle xfer, usbd_private_handle *priv,
void **buffer, u_int32_t *count, usbd_status *status));
usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
__P((usbd_interface_handle iface, u_int8_t address));
@ -128,9 +129,10 @@ usbd_status usbd_device2interface_handle
__P((usbd_device_handle dev, u_int8_t ifaceno, usbd_interface_handle *iface));
usbd_device_handle usbd_pipe2device_handle __P((usbd_pipe_handle));
void *usbd_alloc_buffer __P((usbd_request_handle req, u_int32_t size));
void usbd_free_buffer __P((usbd_request_handle req));
usbd_status usbd_sync_transfer __P((usbd_request_handle req));
void *usbd_alloc_buffer __P((usbd_xfer_handle req, u_int32_t size));
void usbd_free_buffer __P((usbd_xfer_handle req));
void *usbd_get_buffer __P((usbd_xfer_handle xfer));
usbd_status usbd_sync_transfer __P((usbd_xfer_handle req));
usbd_status usbd_open_pipe_intr
__P((usbd_interface_handle iface, u_int8_t address,
u_int8_t flags, usbd_pipe_handle *pipe,
@ -166,6 +168,10 @@ usb_endpoint_descriptor_t *usbd_find_edesc
void usbd_dopoll __P((usbd_interface_handle));
void usbd_set_polling __P((usbd_interface_handle iface, int on));
const char *usbd_errstr __P((usbd_status err));
void usbd_add_event __P((int, usbd_device_handle));
/* NetBSD attachment information */
/* Attach data */
@ -229,8 +235,6 @@ void usbd_devinfo __P((usbd_device_handle, int, char *));
struct usbd_quirks *usbd_get_quirks __P((usbd_device_handle));
usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor
__P((usbd_interface_handle iface, u_int8_t address));
const char *usbd_errstr __P((usbd_status));
#if defined(__FreeBSD__)
int usbd_driver_load __P((module_t mod, int what, void *arg));

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi_util.c,v 1.21 1999/09/09 12:26:48 augustss Exp $ */
/* $NetBSD: usbdi_util.c,v 1.22 1999/10/13 08:10:59 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -87,13 +87,13 @@ usbd_get_config_desc(dev, conf, d)
int conf;
usb_config_descriptor_t *d;
{
usbd_status r;
usbd_status err;
DPRINTFN(3,("usbd_get_config_desc: conf=%d\n", conf));
r = usbd_get_desc(dev, UDESC_CONFIG, conf,
err = usbd_get_desc(dev, UDESC_CONFIG, conf,
USB_CONFIG_DESCRIPTOR_SIZE, d);
if (r != USBD_NORMAL_COMPLETION)
return (r);
if (err)
return (err);
if (d->bDescriptorType != UDESC_CONFIG) {
DPRINTFN(-1,("usbd_get_config_desc: conf %d, bad desc %d\n",
conf, d->bDescriptorType));
@ -253,17 +253,15 @@ usbd_set_protocol(iface, report)
usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
usbd_status r;
usbd_status err;
DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
iface, report, id->bInterfaceNumber));
if (!id)
if (id == NULL)
return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
if (!id)
return (USBD_INVAL);
err = usbd_interface2device_handle(iface, &dev);
if (err)
return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_PROTOCOL;
USETW(req.wValue, report);
@ -283,16 +281,14 @@ usbd_set_report(iface, type, id, data, len)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
usbd_status r;
usbd_status err;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
if (!ifd)
if (ifd == NULL)
return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
if (!ifd)
return (USBD_INVAL);
err = usbd_interface2device_handle(iface, &dev);
if (err)
return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_REPORT;
USETW2(req.wValue, type, id);
@ -312,16 +308,14 @@ usbd_set_report_async(iface, type, id, data, len)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
usbd_status r;
usbd_status err;
DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
if (!ifd)
if (ifd == NULL)
return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
if (!ifd)
return (USBD_INVAL);
err = usbd_interface2device_handle(iface, &dev);
if (err)
return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_REPORT;
USETW2(req.wValue, type, id);
@ -341,16 +335,14 @@ usbd_get_report(iface, type, id, data, len)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
usbd_status r;
usbd_status err;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
if (!id)
if (id == NULL)
return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
if (!ifd)
return (USBD_INVAL);
err = usbd_interface2device_handle(iface, &dev);
if (err)
return (err);
req.bmRequestType = UT_READ_CLASS_INTERFACE;
req.bRequest = UR_GET_REPORT;
USETW2(req.wValue, type, id);
@ -368,16 +360,14 @@ usbd_set_idle(iface, duration, id)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
usbd_status r;
usbd_status err;
DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
if (!ifd)
if (ifd == NULL)
return (USBD_IOERROR);
r = usbd_interface2device_handle(iface, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
if (!ifd)
return (USBD_INVAL);
err = usbd_interface2device_handle(iface, &dev);
if (err)
return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_IDLE;
USETW2(req.wValue, duration, id);
@ -413,12 +403,12 @@ usbd_get_hid_descriptor(ifc)
usb_config_descriptor_t *cdesc;
usb_hid_descriptor_t *hd;
char *p, *end;
usbd_status r;
usbd_status err;
if (!idesc)
if (idesc == NULL)
return (0);
r = usbd_interface2device_handle(ifc, &dev);
if (r != USBD_NORMAL_COMPLETION)
err = usbd_interface2device_handle(ifc, &dev);
if (err)
return (0);
cdesc = usbd_get_config_descriptor(dev);
@ -450,27 +440,27 @@ usbd_alloc_report_desc(ifc, descp, sizep, mem)
usb_interface_descriptor_t *id;
usb_hid_descriptor_t *hid;
usbd_device_handle dev;
usbd_status r;
usbd_status err;
r = usbd_interface2device_handle(ifc, &dev);
if (r != USBD_NORMAL_COMPLETION)
return (r);
err = usbd_interface2device_handle(ifc, &dev);
if (err)
return (err);
id = usbd_get_interface_descriptor(ifc);
if (!id)
if (id == NULL)
return (USBD_INVAL);
hid = usbd_get_hid_descriptor(ifc);
if (!hid)
if (hid == NULL)
return (USBD_IOERROR);
*sizep = UGETW(hid->descrs[0].wDescriptorLength);
*descp = malloc(*sizep, mem, M_NOWAIT);
if (!*descp)
if (*descp == NULL)
return (USBD_NOMEM);
/* XXX should not use 0 Report ID */
r = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0,
err = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0,
*sizep, *descp);
if (r != USBD_NORMAL_COMPLETION) {
if (err) {
free(*descp, mem);
return (r);
return (err);
}
return (USBD_NORMAL_COMPLETION);
}
@ -490,20 +480,20 @@ usbd_get_config(dev, conf)
return (usbd_do_request(dev, &req, conf));
}
static void usbd_bulk_transfer_cb __P((usbd_request_handle reqh,
static void usbd_bulk_transfer_cb __P((usbd_xfer_handle xfer,
usbd_private_handle priv, usbd_status status));
static void
usbd_bulk_transfer_cb(reqh, priv, status)
usbd_request_handle reqh;
usbd_bulk_transfer_cb(xfer, priv, status)
usbd_xfer_handle xfer;
usbd_private_handle priv;
usbd_status status;
{
wakeup(reqh);
wakeup(xfer);
}
usbd_status
usbd_bulk_transfer(reqh, pipe, flags, timeout, buf, size, lbl)
usbd_request_handle reqh;
usbd_bulk_transfer(xfer, pipe, flags, timeout, buf, size, lbl)
usbd_xfer_handle xfer;
usbd_pipe_handle pipe;
u_int16_t flags;
u_int32_t timeout;
@ -511,32 +501,32 @@ usbd_bulk_transfer(reqh, pipe, flags, timeout, buf, size, lbl)
u_int32_t *size;
char *lbl;
{
usbd_status r;
usbd_status err;
int s, error;
usbd_setup_request(reqh, pipe, 0, buf, *size,
usbd_setup_request(xfer, pipe, 0, buf, *size,
flags, timeout, usbd_bulk_transfer_cb);
DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
s = splusb(); /* don't want callback until tsleep() */
r = usbd_transfer(reqh);
if (r != USBD_IN_PROGRESS) {
err = usbd_transfer(xfer);
if (err != USBD_IN_PROGRESS) {
splx(s);
return (r);
return (err);
}
error = tsleep((caddr_t)reqh, PZERO | PCATCH, lbl, 0);
error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
splx(s);
if (error) {
DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
usbd_abort_pipe(pipe);
return (USBD_INTERRUPTED);
}
usbd_get_request_status(reqh, 0, 0, size, &r);
usbd_get_request_status(xfer, 0, 0, size, &err);
DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
if (r != USBD_NORMAL_COMPLETION) {
DPRINTF(("usbd_bulk_transfer: error=%d\n", r));
if (err) {
DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
usbd_clear_endpoint_stall(pipe);
}
return (r);
return (err);
}
void

View File

@ -90,7 +90,7 @@ usbd_status usbd_set_config_index
__P((usbd_device_handle dev, int index, int msg));
usbd_status usbd_bulk_transfer
__P((usbd_request_handle reqh, usbd_pipe_handle pipe, u_int16_t flags,
__P((usbd_xfer_handle xfer, usbd_pipe_handle pipe, u_int16_t flags,
u_int32_t timeout, void *buf, u_int32_t *size, char *lbl));
void usb_detach_wait __P((device_ptr_t));

View File

@ -1,5 +1,5 @@
/* $NetBSD: usbdivar.h,v 1.30 1999/09/11 08:19:27 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: usbdivar.h,v 1.39 1999/11/10 04:19:59 mycroft Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
/* From usb_mem.h */
DECLARE_USB_DMA_T;
struct usbd_request;
struct usbd_xfer;
struct usbd_pipe;
struct usbd_endpoint {
@ -58,12 +58,12 @@ struct usbd_bus_methods {
};
struct usbd_pipe_methods {
usbd_status (*transfer)__P((usbd_request_handle reqh));
usbd_status (*start)__P((usbd_request_handle reqh));
void (*abort)__P((usbd_request_handle reqh));
usbd_status (*transfer)__P((usbd_xfer_handle xfer));
usbd_status (*start)__P((usbd_xfer_handle xfer));
void (*abort)__P((usbd_xfer_handle xfer));
void (*close)__P((usbd_pipe_handle pipe));
void (*cleartoggle)__P((usbd_pipe_handle pipe));
void (*done)__P((usbd_request_handle reqh));
void (*done)__P((usbd_xfer_handle xfer));
};
struct usbd_port {
@ -99,6 +99,11 @@ struct usbd_bus {
char use_polling;
struct usb_softc *usbctl;
struct usb_device_stats stats;
int intr_context;
u_int no_intrs;
#if defined(__NetBSD__) || defined(__OpenBSD__)
bus_dma_tag_t dmatag; /* DMA tag */
#endif
};
struct usbd_device {
@ -112,6 +117,7 @@ struct usbd_device {
int config;
int langid; /* language to use for strings */
#define USBD_NOLANG (-1)
usb_event_cookie_t cookie; /* unique connection id */
struct usbd_port *powersrc;
struct usbd_endpoint def_ep; /* for pipe 0 */
usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */
@ -139,17 +145,17 @@ struct usbd_pipe {
struct usbd_endpoint *endpoint;
int refcnt;
char running;
SIMPLEQ_HEAD(, usbd_request) queue;
SIMPLEQ_HEAD(, usbd_xfer) queue;
LIST_ENTRY(usbd_pipe) next;
usbd_request_handle intrreqh; /* used for repeating requests */
usbd_xfer_handle intrxfer; /* used for repeating requests */
char repeat;
/* Filled by HC driver. */
struct usbd_pipe_methods *methods;
};
struct usbd_request {
struct usbd_xfer {
struct usbd_pipe *pipe;
void *priv;
void *buffer;
@ -177,7 +183,7 @@ struct usbd_request {
#define URQ_AUTO_DMABUF 0x10
#define URQ_DEV_DMABUF 0x20
SIMPLEQ_ENTRY(usbd_request) next;
SIMPLEQ_ENTRY(usbd_xfer) next;
void *hcpriv; /* private use by the HC driver */
int hcprivint; /* ditto */
@ -187,6 +193,9 @@ struct usbd_request {
#endif
};
void usbd_init __P((void));
void usbd_finish __P((void));
/* Routines from usb_subr.c */
int usbctlprint __P((void *, const char *));
void usb_delay_ms __P((usbd_bus_handle, u_int));
@ -208,13 +217,26 @@ usbd_status usbd_fill_iface_data __P((usbd_device_handle dev,
int i, int a));
void usb_free_device __P((usbd_device_handle));
usbd_status usb_insert_transfer __P((usbd_request_handle reqh));
void usb_transfer_complete __P((usbd_request_handle reqh));
usbd_status usb_insert_transfer __P((usbd_xfer_handle xfer));
void usb_transfer_complete __P((usbd_xfer_handle xfer));
void usb_disconnect_port __P((struct usbd_port *up, device_ptr_t));
/* Routines from usb.c */
int usb_bus_count __P((void));
void usb_needs_explore __P((usbd_bus_handle));
#ifdef DIAGNOSTIC
#define SPLUSBCHECK \
do { int _s = splusb(), _su = splusb(); \
extern int cold; \
if (!cold && _s != _su) printf("SPLUSBCHECK failed 0x%x!=0x%x, %s:%d\n", \
_s, _su, __FILE__, __LINE__); \
splx(_s); \
} while (0)
#else
#define SPLUSBCHECK
#endif
/* Locator stuff. */
#if defined(__NetBSD__)

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbhid.h,v 1.5 1999/05/13 23:29:11 augustss Exp $ */
/* $NetBSD: usbhid.h,v 1.4 1999/04/22 01:57:01 augustss Exp $ */
/* $FreeBSD$ */
/*