Major synchronisation with the NetBSD USB stack:

- Some cleanup and improvements in the uhci and ohci drivers
- Support for plugging and unplugging devices improved
- Now available is bulk transport over OHCI controllers
- Resume and suspend have been temporarily been disabled again.  Proper
  support for it is available in the uhci.c and ohci.c files but I have
  not yet spent the brain cycles to use it.
- OpenBSD now uses the USB stack as well
- Add FreeBSD tags
This commit is contained in:
Nick Hibma 1999-10-07 19:26:38 +00:00
parent eaaceb5416
commit 8c895d718b
31 changed files with 4894 additions and 4178 deletions

47
sys/dev/usb/FILES Normal file
View File

@ -0,0 +1,47 @@
$FreeBSD$
A small roadmap of the USB files:
FILES this file
Makefile to install .h files
Makefile.usbdevs to run devlist2h.awk
TODO just a list of things to do
devlist2h.awk script to generate usbdevs*.h
files.usb config inclued file
hid.c subroutines to parse and access HID data
hid.h API for hid.c
ohci.c Host controller driver for OHCI
ohcireg.h Hardware definitions for OHCI
ohcivar.h API for ohci.c
uaudio.c USB audio class driver
uaudioreg.h and definitions for it
ugen.c generic driver that can handle access to any USB device
uhci.c Host controller driver for UHCI
uhcireg.h Hardware definitions for UHCI
uhcivar.h API for uhci.c
uhid.c USB HID class driver
uhub.c USB hub driver
ukbd.c USB keyboard driver
ukbdmap.c wscons key mapping for ukbd
ukbdvar.h API for ukbd.c
ulpt.c USB printer class driver
umodem.c USB modem (CDC ACM) driver
ums.c USB mouse driver
usb.c usb (bus) device driver
usb.h general USB defines
usb_mem.c memory allocation for DMAable memory
usb_mem.h API for usb_mem.c
usb_port.h compatibility defines for different OSs
usb_quirks.c table of non-conforming USB devices and their problems
usb_quirks.h API for usb_quirks.c
usb_subr.c various subroutines used by USB code
usbcdc.h USB CDC class definitions
usbdevs data base of known device
usbdevs.h generated from usbdevs
usbdevs_data.h generated from usbdevs
usbdi.c implementation of the USBDI API, which all drivers use
usbdi.h API for usbdi.c
usbdi_util.c utilities built on top of usbdi.h
usbdi_util.h API for usbdi_util.c
usbdivar.h internal defines and structures for usbdi.c
usbhid.h USB HID class definitions

View File

@ -1,5 +1,5 @@
/* $NetBSD: hid.c,v 1.7 1999/01/08 11:58:25 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: hid.c,v 1.8 1999/08/14 14:49:31 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -45,7 +45,7 @@
#if defined(__FreeBSD__)
#include <sys/bus.h>
#endif
#include <dev/usb/usb.h>
#include <dev/usb/usbhid.h>

View File

@ -1,5 +1,5 @@
/* $NetBSD: hid.h,v 1.3 1998/11/25 22:32:04 augustss Exp $ */
/* $FreeBSD$ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* $NetBSD: ohcireg.h,v 1.7 1998/12/10 23:16:47 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: ohcireg.h,v 1.8 1999/08/22 23:41:00 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -165,7 +165,7 @@ typedef struct {
ohci_physaddr_t ed_headp;
ohci_physaddr_t ed_nexted;
} ohci_ed_t;
#define OHCI_ED_SIZE 16
/* #define OHCI_ED_SIZE 16 */
#define OHCI_ED_ALIGN 16
typedef struct {
@ -188,7 +188,7 @@ typedef struct {
ohci_physaddr_t td_nexttd; /* Next TD */
ohci_physaddr_t td_be; /* Buffer End */
} ohci_td_t;
#define OHCI_TD_SIZE 16
/* #define OHCI_TD_SIZE 16 */
#define OHCI_TD_ALIGN 16
#define OHCI_CC_NO_ERROR 0

View File

@ -1,5 +1,5 @@
/* $NetBSD: ohcivar.h,v 1.4 1998/12/26 12:53:01 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: ohcivar.h,v 1.8 1999/08/22 23:41:00 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -39,23 +39,27 @@
*/
typedef struct ohci_soft_ed {
ohci_ed_t *ed;
ohci_ed_t ed;
struct ohci_soft_ed *next;
ohci_physaddr_t physaddr;
} ohci_soft_ed_t;
#define OHCI_ED_CHUNK 256
#define OHCI_SED_SIZE ((sizeof (struct ohci_soft_ed) + OHCI_ED_ALIGN - 1) / OHCI_ED_ALIGN * OHCI_ED_ALIGN)
#define OHCI_SED_CHUNK 128
typedef struct ohci_soft_td {
ohci_td_t *td;
ohci_td_t td;
struct ohci_soft_td *nexttd; /* mirrors nexttd in TD */
struct ohci_soft_td *dnext; /* next in done list */
ohci_physaddr_t physaddr;
LIST_ENTRY(ohci_soft_td) hnext;
/*ohci_soft_ed_t *sed;*/
usbd_request_handle reqh;
u_int16_t len;
u_int16_t flags;
#define OHCI_CALL_DONE 0x0001
#define OHCI_SET_LEN 0x0002
} ohci_soft_td_t;
#define OHCI_TD_CHUNK 256
#define OHCI_STD_SIZE ((sizeof (struct ohci_soft_td) + OHCI_TD_ALIGN - 1) / OHCI_TD_ALIGN * OHCI_TD_ALIGN)
#define OHCI_STD_CHUNK 128
#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1)
@ -65,12 +69,12 @@ typedef struct ohci_softc {
struct usbd_bus sc_bus; /* base device */
bus_space_tag_t iot;
bus_space_handle_t ioh;
#if defined(__NetBSD__)
#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 /* __FreeBSD__ */
#endif /* __NetBSD__ || defined(__OpenBSD__) */
usb_dma_t sc_hccadma;
struct ohci_hcca *sc_hcca;
@ -93,11 +97,12 @@ typedef struct ohci_softc {
usbd_request_handle sc_intrreqh;
int sc_intrs;
char sc_vendor[16];
int sc_id_vendor;
} ohci_softc_t;
usbd_status ohci_init __P((ohci_softc_t *));
int ohci_intr __P((void *));
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ugen.c,v 1.11 1999/01/08 11:58:25 augustss Exp $ */
/* $NetBSD: ugen.c,v 1.23 1999/09/09 12:26:44 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -43,7 +43,7 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#include <sys/ioctl.h>
#elif defined(__FreeBSD__)
@ -54,6 +54,7 @@
#include <sys/fcntl.h>
#include <sys/filio.h>
#endif
#include <sys/conf.h>
#include <sys/tty.h>
#include <sys/file.h>
#include <sys/select.h>
@ -68,7 +69,7 @@
#ifdef UGEN_DEBUG
#define DPRINTF(x) if (ugendebug) logprintf x
#define DPRINTFN(n,x) if (ugendebug>(n)) logprintf x
int ugendebug = 1;
int ugendebug = 0;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@ -79,13 +80,13 @@ struct ugen_endpoint {
usb_endpoint_descriptor_t *edesc;
usbd_interface_handle iface;
int state;
#define UGEN_OPEN 0x01 /* device is open */
#define UGEN_ASLP 0x02 /* waiting for data */
#define UGEN_SHORT_OK 0x04 /* short xfers are OK */
usbd_pipe_handle pipeh;
struct clist q;
struct selinfo rsel;
void *ibuf;
u_int32_t timeout;
};
#define UGEN_CHUNK 128 /* chunk size for read */
@ -93,23 +94,20 @@ struct ugen_endpoint {
#define UGEN_BBSIZE 1024
struct ugen_softc {
bdevice sc_dev; /* base device */
struct usbd_device *sc_udev;
USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_udev;
char sc_is_open[USB_MAX_ENDPOINTS][2];
struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
#define OUT 0 /* index order is important, from UE_OUT */
#define IN 1 /* from UE_IN */
#define OUT 0
#define IN 1
int sc_disconnected; /* device is gone */
int sc_refcnt;
u_char sc_dying;
};
#if defined(__NetBSD__)
int ugenopen __P((dev_t, int, int, struct proc *));
int ugenclose __P((dev_t, int, int, struct proc *p));
int ugenread __P((dev_t, struct uio *uio, int));
int ugenwrite __P((dev_t, struct uio *uio, int));
int ugenioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
int ugenpoll __P((dev_t, int, struct proc *));
#if defined(__NetBSD__) || defined(__OpenBSD__)
cdev_decl(ugen);
#elif defined(__FreeBSD__)
d_open_t ugenopen;
d_close_t ugenclose;
@ -140,11 +138,11 @@ static struct cdevsw ugen_cdevsw = {
void ugenintr __P((usbd_request_handle reqh, usbd_private_handle addr,
usbd_status status));
void ugen_disco __P((void *));
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));
@ -153,6 +151,7 @@ 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)
#define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e)))
USB_DECLARE_DRIVER(ugen);
@ -183,9 +182,10 @@ USB_ATTACH(ugen)
if (r != USBD_NORMAL_COMPLETION) {
printf("%s: setting configuration %d failed\n",
USBDEVNAME(sc->sc_dev), conf);
sc->sc_disconnected = 1;
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
USB_ATTACH_SUCCESS_RETURN;
}
@ -201,6 +201,7 @@ ugen_set_config(sc, configno)
u_int8_t niface, nendpt;
int ifaceno, endptno, endpt;
usbd_status r;
int dir;
DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
USBDEVNAME(sc->sc_dev), configno, sc));
@ -226,12 +227,12 @@ ugen_set_config(sc, configno)
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)]
[UE_GET_IN(endpt)];
dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
DPRINTFN(1,("ugen_set_config: endptno %d, endpt=0x%02x"
"(%d,%d), sce=%p\n",
endptno, endpt, UE_GET_ADDR(endpt),
UE_GET_IN(endpt), sce));
UE_GET_DIR(endpt), sce));
sce->sc = sc;
sce->edesc = ed;
sce->iface = iface;
@ -240,14 +241,6 @@ ugen_set_config(sc, configno)
return (USBD_NORMAL_COMPLETION);
}
void
ugen_disco(p)
void *p;
{
struct ugen_softc *sc = p;
sc->sc_disconnected = 1;
}
int
ugenopen(dev, flag, mode, p)
dev_t dev;
@ -263,34 +256,38 @@ ugenopen(dev, flag, mode, p)
usbd_status r;
USB_GET_SC_OPEN(ugen, unit, sc);
DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
flag, mode, unit, endpt));
if (sc->sc_disconnected)
return (EIO);
if (!sc || sc->sc_dying)
return (ENXIO);
if (endpt == USB_CONTROL_ENDPOINT) {
/*if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD))
return (EACCES);*/
sce = &sc->sc_endpoints[USB_CONTROL_ENDPOINT][OUT];
if (sce->state & UGEN_OPEN)
sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 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);
} else {
switch (flag & (FWRITE|FREAD)) {
case FWRITE:
dir = OUT;
break;
case FREAD:
dir = IN;
break;
default:
return (EACCES);
if (flag & (dir == OUT ? FWRITE : FREAD)) {
sce = &sc->sc_endpoints[endpt][dir];
if (sce == 0 || sce->edesc == 0)
return (ENXIO);
}
}
/* Actually open the pipes. */
/* XXX Should back out properly if it fails. */
for (dir = OUT; dir <= IN; dir++) {
if (!(flag & (dir == OUT ? FWRITE : FREAD)))
continue;
sce = &sc->sc_endpoints[endpt][dir];
sce->state = 0;
sce->timeout = USBD_NO_TIMEOUT;
DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
sc, endpt, dir, sce));
if (sce->state & UGEN_OPEN)
return (EBUSY);
edesc = sce->edesc;
if (!edesc)
return (ENXIO);
@ -299,12 +296,12 @@ ugenopen(dev, flag, mode, p)
isize = UGETW(edesc->wMaxPacketSize);
if (isize == 0) /* shouldn't happen */
return (EINVAL);
sce->ibuf = malloc(isize, M_USB, M_WAITOK);
sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
endpt, isize));
#if defined(__NetBSD__)
if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
return (ENOMEM);
#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
@ -313,15 +310,14 @@ ugenopen(dev, flag, mode, p)
USBD_SHORT_XFER_OK, &sce->pipeh, sce,
sce->ibuf, isize, ugenintr);
if (r != USBD_NORMAL_COMPLETION) {
free(sce->ibuf, M_USB);
#if defined(__NetBSD__)
free(sce->ibuf, M_USBDEV);
#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sce->q);
#elif defined(__FreeBSD__)
clist_free_cblocks(&sce->q);
#endif
return (EIO);
}
usbd_set_disco(sce->pipeh, ugen_disco, sc);
DPRINTFN(5, ("ugenopen: interrupt open done\n"));
break;
case UE_BULK:
@ -335,8 +331,8 @@ ugenopen(dev, flag, mode, p)
case UE_ISOCHRONOUS:
return (EINVAL);
}
sc->sc_is_open[endpt][dir] = 1;
}
sce->state |= UGEN_OPEN;
return (0);
}
@ -352,52 +348,58 @@ ugenclose(dev, flag, mode, p)
struct ugen_endpoint *sce;
int dir;
DPRINTFN(5, ("ugenclose: flag=%d, mode=%d\n", flag, mode));
DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
flag, mode, UGENUNIT(dev), endpt));
if (!sc || sc->sc_disconnected)
return (EIO);
#ifdef DIAGNOSTIC
if (!sc->sc_is_open[endpt][IN] || !sc->sc_is_open[endpt][OUT] ) {
printf("ugenclose: not open\n");
return (EINVAL);
}
#endif
if (endpt == USB_CONTROL_ENDPOINT) {
DPRINTFN(5, ("ugenclose: close control\n"));
sc->sc_endpoints[endpt][OUT].state = 0;
sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 0;
return (0);
}
flag = FWRITE | FREAD; /* XXX bug if generic open/close */
/* The open modes have been joined, so check for both modes. */
for (dir = OUT; dir <= IN; dir++) {
if (flag & (dir == OUT ? FWRITE : FREAD)) {
sce = &sc->sc_endpoints[endpt][dir];
if (!sce || !sce->pipeh) /* XXX */
continue; /* XXX */
DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
endpt, dir, sce));
sce->state = 0;
usbd_abort_pipe(sce->pipeh);
usbd_close_pipe(sce->pipeh);
sce->pipeh = 0;
if (sce->ibuf) {
free(sce->ibuf, M_USB);
sce->ibuf = 0;
}
if (!(flag & (dir == OUT ? FWRITE : FREAD)))
continue;
sce = &sc->sc_endpoints[endpt][dir];
if (!sce || !sce->pipeh)
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;
if (sce->ibuf) {
free(sce->ibuf, M_USBDEV);
sce->ibuf = 0;
#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sce->q);
#elif defined(__FreeBSD__)
clist_free_cblocks(&sce->q);
#endif
}
sc->sc_is_open[endpt][dir] = 0;
}
return (0);
}
int
ugenread(dev, uio, flag)
dev_t dev;
ugen_do_read(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
struct uio *uio;
int flag;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
struct ugen_endpoint *sce;
struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
u_int32_t n, tn;
char buf[UGEN_BBSIZE];
usbd_request_handle reqh;
@ -406,12 +408,12 @@ ugenread(dev, uio, flag)
int error = 0;
u_char buffer[UGEN_CHUNK];
DPRINTFN(5, ("ugenread: %d:%d\n", UGENUNIT(dev), UGENENDPOINT(dev)));
if (!sc || sc->sc_disconnected)
#ifdef __NetBSD__
DPRINTFN(5, ("ugenread: %d:%d\n", sc->sc_dev.dv_unit, endpt));
#endif
if (sc->sc_dying)
return (EIO);
sce = &sc->sc_endpoints[endpt][IN];
#ifdef DIAGNOSTIC
if (!sce->edesc) {
printf("ugenread: no edesc\n");
@ -434,19 +436,19 @@ ugenread(dev, uio, flag)
}
sce->state |= UGEN_ASLP;
DPRINTFN(5, ("ugenread: sleep on %p\n", sc));
error = tsleep((caddr_t)sce, PZERO | PCATCH,
"ugenri", 0);
error = tsleep(sce, PZERO | PCATCH, "ugenri", 0);
DPRINTFN(5, ("ugenread: woke, error=%d\n", error));
if (sc->sc_dying)
error = EIO;
if (error) {
sce->state &= ~UGEN_ASLP;
splx(s);
return (error);
break;
}
}
splx(s);
/* Transfer as many chunks as possible. */
while (sce->q.c_cc > 0 && uio->uio_resid > 0) {
while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
n = min(sce->q.c_cc, uio->uio_resid);
if (n > sizeof(buffer))
n = sizeof(buffer);
@ -462,18 +464,22 @@ ugenread(dev, uio, flag)
}
break;
case UE_BULK:
reqh = usbd_alloc_request();
reqh = usbd_alloc_request(sc->sc_udev);
if (reqh == 0)
return (ENOMEM);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
DPRINTFN(1, ("ugenread: start transfer %d bytes\n", n));
DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
tn = n;
r = usbd_bulk_transfer(reqh, sce->pipeh, 0,
USBD_NO_TIMEOUT, buf,
&tn, "ugenrb");
r = usbd_bulk_transfer(
reqh, 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)
error = EINTR;
else if (r == USBD_TIMEOUT)
error = ETIMEDOUT;
else
error = EIO;
break;
@ -488,30 +494,43 @@ ugenread(dev, uio, flag)
default:
return (ENXIO);
}
return (error);
}
int
ugenwrite(dev, uio, flag)
ugenread(dev, uio, flag)
dev_t dev;
struct uio *uio;
int flag;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
struct ugen_endpoint *sce;
size_t n;
int error;
sc->sc_refcnt++;
error = ugen_do_read(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
int
ugen_do_write(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
struct uio *uio;
int flag;
{
struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
u_int32_t n;
int error = 0;
char buf[UGEN_BBSIZE];
usbd_request_handle reqh;
usbd_status r;
if (!sc || sc->sc_disconnected)
if (sc->sc_dying)
return (EIO);
sce = &sc->sc_endpoints[endpt][OUT];
#ifdef DIAGNOSTIC
if (!sce->edesc) {
printf("ugenwrite: no edesc\n");
@ -526,7 +545,7 @@ ugenwrite(dev, uio, flag)
DPRINTF(("ugenwrite\n"));
switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
case UE_BULK:
reqh = usbd_alloc_request();
reqh = usbd_alloc_request(sc->sc_udev);
if (reqh == 0)
return (EIO);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
@ -534,9 +553,8 @@ ugenwrite(dev, uio, flag)
if (error)
break;
DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
r = usbd_bulk_transfer(reqh, sce->pipeh, 0,
USBD_NO_TIMEOUT, buf,
&n, "ugenwb");
r = usbd_bulk_transfer(reqh, sce->pipeh, 0,
sce->timeout, buf, &n,"ugenwb");
if (r != USBD_NORMAL_COMPLETION) {
if (r == USBD_INTERRUPTED)
error = EINTR;
@ -553,6 +571,94 @@ ugenwrite(dev, uio, flag)
return (error);
}
int
ugenwrite(dev, uio, flag)
dev_t dev;
struct uio *uio;
int flag;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
int error;
sc->sc_refcnt++;
error = ugen_do_write(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
ugen_activate(self, act)
device_ptr_t self;
enum devact act;
{
struct ugen_softc *sc = (struct ugen_softc *)self;
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
break;
}
return (0);
}
#endif
USB_DETACH(ugen)
{
USB_DETACH_START(ugen, sc);
struct ugen_endpoint *sce;
int i, dir;
int s;
#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
DPRINTF(("ugen_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("ugen_detach: sc=%p\n", sc));
#endif
sc->sc_dying = 1;
/* Abort all pipes. Causes processes waiting for transfer to wake. */
for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
for (dir = OUT; dir <= IN; dir++) {
sce = &sc->sc_endpoints[i][dir];
if (sce && sce->pipeh)
usbd_abort_pipe(sce->pipeh);
}
}
s = splusb();
if (--sc->sc_refcnt >= 0) {
/* Wake everyone */
for (i = 0; i < USB_MAX_ENDPOINTS; i++)
wakeup(&sc->sc_endpoints[i][IN]);
/* Wait for processes to go away. */
usb_detach_wait(USBDEV(sc->sc_dev));
}
splx(s);
#if defined(__NetBSD__) || defined(__OpenBSD__)
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == ugenopen)
break;
/* Nuke the vnodes for any open instances (calls close). */
mn = self->dv_unit * USB_MAX_ENDPOINTS;
vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR);
#elif defined(__FreeBSD__)
/* XXX not implemented yet */
#endif
return (0);
}
void
ugenintr(reqh, addr, status)
@ -562,10 +668,7 @@ ugenintr(reqh, addr, status)
{
struct ugen_endpoint *sce = addr;
/*struct ugen_softc *sc = sce->sc;*/
usbd_private_handle priv;
void *buffer;
u_int32_t count;
usbd_status xstatus;
u_char *ibuf;
if (status == USBD_CANCELLED)
@ -577,11 +680,11 @@ ugenintr(reqh, addr, status)
return;
}
(void)usbd_get_request_status(reqh, &priv, &buffer, &count, &xstatus);
usbd_get_request_status(reqh, 0, 0, &count, 0);
ibuf = sce->ibuf;
DPRINTFN(5, ("ugenintr: reqh=%p status=%d count=%d\n",
reqh, xstatus, count));
reqh, status, count));
DPRINTFN(5, (" data = %02x %02x %02x\n",
ibuf[0], ibuf[1], ibuf[2]));
@ -590,7 +693,7 @@ ugenintr(reqh, addr, status)
if (sce->state & UGEN_ASLP) {
sce->state &= ~UGEN_ASLP;
DPRINTFN(5, ("ugen_intr: waking %p\n", sce));
wakeup((caddr_t)sce);
wakeup(sce);
}
selwakeup(&sce->rsel);
}
@ -605,6 +708,7 @@ ugen_set_interface(sc, ifaceidx, altno)
usbd_status r;
struct ugen_endpoint *sce;
u_int8_t niface, nendpt, endptno, endpt;
int dir;
DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
@ -623,7 +727,8 @@ ugen_set_interface(sc, ifaceidx, altno)
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][UE_GET_IN(endpt)];
dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
sce->sc = 0;
sce->edesc = 0;
sce->iface = 0;
@ -640,7 +745,8 @@ ugen_set_interface(sc, ifaceidx, altno)
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][UE_GET_IN(endpt)];
dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT;
sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir];
sce->sc = sc;
sce->edesc = ed;
sce->iface = iface;
@ -700,15 +806,14 @@ ugen_get_alt_index(sc, ifaceidx)
}
int
ugenioctl(dev, cmd, addr, flag, p)
dev_t dev;
ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct ugen_softc *sc;
int endpt;
u_long cmd;
caddr_t addr;
int flag;
struct proc *p;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
struct ugen_endpoint *sce;
usbd_status r;
usbd_interface_handle iface;
@ -723,7 +828,7 @@ ugenioctl(dev, cmd, addr, flag, p)
u_int8_t conf, alt;
DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd));
if (!sc || sc->sc_disconnected)
if (sc->sc_dying)
return (EIO);
switch (cmd) {
@ -732,10 +837,12 @@ ugenioctl(dev, cmd, addr, flag, p)
return (0);
case USB_SET_SHORT_XFER:
/* This flag only affects read */
if (endpt == USB_CONTROL_ENDPOINT)
return (EINVAL);
sce = &sc->sc_endpoints[endpt][IN];
#ifdef DIAGNOSTIC
if (!sce->pipeh) {
printf("ugenioctl: no pipe\n");
printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
return (EIO);
}
#endif
@ -744,6 +851,16 @@ ugenioctl(dev, cmd, addr, flag, p)
else
sce->state &= ~UGEN_SHORT_OK;
return (0);
case USB_SET_TIMEOUT:
sce = &sc->sc_endpoints[endpt][IN];
#ifdef DIAGNOSTIC
if (!sce->pipeh) {
printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n");
return (EIO);
}
#endif
sce->timeout = *(int *)addr;
return (0);
default:
break;
}
@ -799,9 +916,12 @@ ugenioctl(dev, cmd, addr, flag, p)
if (!cdesc)
return (EINVAL);
idesc = usbd_find_idesc(cdesc, ai->interface_index, 0);
if (!idesc)
if (!idesc) {
free(cdesc, M_TEMP);
return (EINVAL);
}
ai->alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber);
free(cdesc, M_TEMP);
break;
case USB_GET_DEVICE_DESC:
*(usb_device_descriptor_t *)addr =
@ -872,7 +992,11 @@ ugenioctl(dev, cmd, addr, flag, p)
uio.uio_segflg = UIO_USERSPACE;
uio.uio_rw = UIO_READ;
uio.uio_procp = p;
#if defined(__NetBSD__) || defined(__OpenBSD__)
error = uiomove((caddr_t)cdesc, len, &uio);
#elif defined(__FreeBSD__)
error = uiomove((void *)cdesc, len, &uio);
#endif
free(cdesc, M_TEMP);
return (error);
}
@ -927,7 +1051,7 @@ ugenioctl(dev, cmd, addr, flag, p)
}
r = usbd_do_request_flags(sc->sc_udev, &ur->request,
ptr, ur->flags, &ur->actlen);
if (r) {
if (r != USBD_NORMAL_COMPLETION) {
error = EIO;
goto ret;
}
@ -953,6 +1077,25 @@ ugenioctl(dev, cmd, addr, flag, p)
return (0);
}
int
ugenioctl(dev, cmd, addr, flag, p)
dev_t dev;
u_long cmd;
caddr_t addr;
int flag;
struct proc *p;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
int error;
sc->sc_refcnt++;
error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
int
ugenpoll(dev, events, p)
dev_t dev;
@ -960,14 +1103,14 @@ ugenpoll(dev, events, p)
struct proc *p;
{
USB_GET_SC(ugen, UGENUNIT(dev), sc);
/* XXX */
struct ugen_endpoint *sce;
int revents = 0;
int s;
if (!sc || sc->sc_disconnected)
if (sc->sc_dying)
return (EIO);
/* XXX always IN */
sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
#ifdef DIAGNOSTIC
if (!sce->edesc) {
@ -1006,13 +1149,5 @@ ugenpoll(dev, events, p)
}
#if defined(__FreeBSD__)
static int
ugen_detach(device_t self)
{
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
return 0;
}
DEV_DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, ugen_cdevsw, usbd_driver_load, 0);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* $NetBSD: uhcireg.h,v 1.5 1998/12/27 23:40:52 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: uhcireg.h,v 1.7 1999/08/22 23:19:57 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -116,11 +116,6 @@ typedef u_int32_t uhci_physaddr_t;
#define UHCI_PTR_Q 0x00000002
#define UHCI_PTR_VF 0x00000004
typedef union {
struct uhci_soft_qh *sqh;
struct uhci_soft_td *std;
} uhci_soft_td_qh_t;
/*
* The Queue Heads and Transfer Descriptors and accessed
* by both the CPU and the USB controller which runs
@ -147,7 +142,7 @@ typedef struct {
#define UHCI_TD_ACTIVE 0x00800000
#define UHCI_TD_IOC 0x01000000
#define UHCI_TD_IOS 0x02000000
#define UHCI_TD_LOWSPEED 0x04000000
#define UHCI_TD_LS 0x04000000
#define UHCI_TD_GET_ERRCNT(s) (((s) >> 27) & 3)
#define UHCI_TD_SET_ERRCNT(n) ((n) << 27)
#define UHCI_TD_SPD 0x20000000
@ -161,15 +156,12 @@ typedef struct {
#define UHCI_TD_SET_ENDPT(e) (((e)&0xf) << 15)
#define UHCI_TD_GET_ENDPT(s) (((s) >> 15) & 0xf)
#define UHCI_TD_SET_DT(t) ((t) << 19)
#define UHCI_TD_GET_DT(t) (((t) >> 19) & 1)
#define UHCI_TD_GET_DT(s) (((s) >> 19) & 1)
#define UHCI_TD_SET_MAXLEN(l) (((l)-1) << 21)
#define UHCI_TD_GET_MAXLEN(s) ((((s) >> 21) + 1) & 0x7ff)
#define UHCI_TD_MAXLEN_MASK 0xffe00000
u_int32_t td_buffer;
uhci_soft_td_qh_t link; /* link to next TD (points to soft version of TD */
/* padding to 32 bytes */
} uhci_td_t;
#define UHCI_TD_SIZE 32
#define UHCI_TD_ERROR (UHCI_TD_BITSTUFF|UHCI_TD_CRCTO|UHCI_TD_BABBLE|UHCI_TD_DBUFFER|UHCI_TD_STALLED)
@ -185,10 +177,6 @@ typedef struct {
typedef struct {
uhci_physaddr_t qh_hlink;
uhci_physaddr_t qh_elink;
struct uhci_soft_qh *hlink; /* soft version of qh_hlink */
struct uhci_soft_td *elink; /* soft version of qh_elink */
/* padding to 32 bytes */
} uhci_qh_t;
#define UHCI_QH_SIZE 32
#endif /* _DEV_PCI_UHCIREG_H_ */

View File

@ -1,5 +1,5 @@
/* $NetBSD: uhcivar.h,v 1.5 1998/12/26 12:53:02 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: uhcivar.h,v 1.12 1999/08/22 23:41:00 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -39,27 +39,28 @@
*/
/*
* The framelist:
*
* To avoid having 1024 TDs for each isochronous transfer we introduce
* a virtual frame list. Every UHCI_VFRAMELIST_COUNT'th entry in the real
* frame list points to a non-active TD. This TD is
* UHCI_FRAMELIST_COUNT/UHCI_VFRAMELIST_COUNT times the start of the
* virtual frame list for a queue of isochroneous transfers.
* a virtual frame list. Every UHCI_VFRAMELIST_COUNT entries in the real
* frame list points to a non-active TD. These, in turn, which form the
* starts of the virtual frame list. This also has the advantage that it
* simplifies linking in/out TD/QH in the schedule.
* Furthermore, initially each of the inactive TDs point to an inactive
* QH that forms the start of the interrupt traffic for that slot.
* Each of these QHs point to the same QH that is the start of control
* traffic.
*
* The last isochroneous transfer in the list points to a QH for the
* interrupt transfer in that timeslot. The QHs for interrupt transfers
* all point to the single QH for control transfers, which in turn
* points at the QH for control transfers.
*
* UHCI_VFRAMELIST_COUNT should be a power of 2 and UHCI_FRAMELIST_COUNT
* should be a multiple of UHCI_VFRAMELIST_COUNT.
* UHCI_VFRAMELIST_COUNT should be a power of 2 and <= UHCI_FRAMELIST_COUNT.
*/
#define UHCI_VFRAMELIST_COUNT 128
typedef struct uhci_soft_qh uhci_soft_qh_t;
typedef struct uhci_soft_td uhci_soft_td_t;
typedef union {
struct uhci_soft_qh *sqh;
struct uhci_soft_td *std;
} uhci_soft_td_qh_t;
/*
* An interrupt info struct contains the information needed to
* execute a requested routine when the controller generates an
@ -85,28 +86,34 @@ typedef struct uhci_intr_info {
* Extra information that we need for a TD.
*/
struct uhci_soft_td {
uhci_td_t *td; /* The real TD */
uhci_physaddr_t physaddr; /* and its physical address. */
uhci_td_t td; /* The real TD, must be first */
uhci_soft_td_qh_t link; /* soft version of the td_link field */
uhci_physaddr_t physaddr; /* TD's physical address. */
};
#define UHCI_TD_CHUNK 128 /*(PAGE_SIZE / UHCI_TD_SIZE)*/
/*
* Make the size such that it is a multiple of UHCI_TD_ALIGN. This way
* we can pack a number of soft TD together and have the real TS well
* aligned.
* NOTE: Minimum size is 32 bytes.
*/
#define UHCI_STD_SIZE ((sizeof (struct uhci_soft_td) + UHCI_TD_ALIGN - 1) / UHCI_TD_ALIGN * UHCI_TD_ALIGN)
#define UHCI_STD_CHUNK 128 /*(PAGE_SIZE / UHCI_TD_SIZE)*/
/*
* Extra information that we need for a QH.
*/
struct uhci_soft_qh {
uhci_qh_t *qh; /* The real QH */
uhci_physaddr_t physaddr; /* and its physical address. */
uhci_qh_t qh; /* The real QH, must be first */
uhci_soft_qh_t *hlink; /* soft version of qh_hlink */
uhci_soft_td_t *elink; /* soft version of qh_elink */
uhci_physaddr_t physaddr; /* QH's physical address. */
int pos; /* Timeslot position */
uhci_intr_info_t *intr_info; /* Who to call on completion. */
/* XXX should try to shrink with 4 bytes to fit into 32 bytes */
};
#define UHCI_QH_CHUNK 128 /*(PAGE_SIZE / UHCI_QH_SIZE)*/
/* Only used for buffer free list. */
struct uhci_buffer {
struct uhci_buffer *next;
};
#define UHCI_BUFFER_SIZE 64
#define UHCI_BUFFER_CHUNK 64 /*(PAGE_SIZE / UHCI_BUFFER_SIZE)*/
/* See comment about UHCI_STD_SIZE. */
#define UHCI_SQH_SIZE ((sizeof (struct uhci_soft_qh) + UHCI_QH_ALIGN - 1) / UHCI_QH_ALIGN * UHCI_QH_ALIGN)
#define UHCI_SQH_CHUNK 128 /*(PAGE_SIZE / UHCI_QH_SIZE)*/
/*
* Information about an entry in the virtial frame list.
@ -121,19 +128,17 @@ struct uhci_vframe {
typedef struct uhci_softc {
struct usbd_bus sc_bus; /* base device */
#if defined(__NetBSD__)
void *sc_ih; /* interrupt vectoring */
#endif
bus_space_tag_t iot;
bus_space_handle_t ioh;
#if defined(__NetBSD__) || defined(__OpenBSD__)
void *sc_ih; /* interrupt vectoring */
#if defined(__NetBSD__)
bus_dma_tag_t sc_dmatag; /* DMA tag */
/* XXX should keep track of all DMA memory */
#endif
#endif /* defined(__FreeBSD__) */
uhci_physaddr_t *sc_pframes;
vm_offset_t sc_flbase;
usb_dma_t sc_dma;
struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT];
uhci_soft_qh_t *sc_ctl_start; /* dummy QH for control */
@ -143,13 +148,17 @@ typedef struct uhci_softc {
uhci_soft_td_t *sc_freetds;
uhci_soft_qh_t *sc_freeqhs;
struct uhci_buffer *sc_freebuffers;
u_int8_t sc_addr; /* device address */
u_int8_t sc_conf; /* device configuration */
char sc_isreset;
#if defined(__NetBSD__)
char sc_suspend;
#endif
usbd_request_handle sc_has_timo;
int sc_intrs;
LIST_HEAD(, uhci_intr_info) sc_intrhead;
@ -160,13 +169,13 @@ typedef struct uhci_softc {
#define UHCI_HAS_LOCK 1
#define UHCI_WANT_LOCK 2
#if defined(__NetBSD__)
usb_dma_t *sc_mallocs;
#endif
char sc_vendor[16];
int sc_id_vendor;
} uhci_softc_t;
usbd_status uhci_init __P((uhci_softc_t *));
int uhci_intr __P((void *));
usbd_status uhci_reset __P((uhci_softc_t *));
#if 0
void uhci_reset __P((void *));
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhid.c,v 1.15 1999/01/10 11:13:36 augustss Exp $ */
/* $NetBSD: uhid.c,v 1.24 1999/09/05 19:32:18 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -42,22 +42,21 @@
* HID spec: http://www.usb.org/developers/data/usbhid10.pdf
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#include <sys/ioctl.h>
#elif defined(__FreeBSD__)
#include <sys/ioccom.h>
#include <sys/conf.h>
#include <sys/filio.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/ioccom.h>
#endif
#include <sys/conf.h>
#include <sys/tty.h>
#include <sys/file.h>
#include <sys/select.h>
@ -76,14 +75,14 @@
#ifdef UHID_DEBUG
#define DPRINTF(x) if (uhiddebug) logprintf x
#define DPRINTFN(n,x) if (uhiddebug>(n)) logprintf x
int uhiddebug = 1;
int uhiddebug = 0;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
#endif
struct uhid_softc {
bdevice sc_dev; /* base device */
USBBASEDEVICE sc_dev; /* base device */
usbd_interface_handle sc_iface; /* interface */
usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
int sc_ep_addr;
@ -108,20 +107,17 @@ struct uhid_softc {
#define UHID_ASLP 0x02 /* waiting for device data */
#define UHID_NEEDCLEAR 0x04 /* needs clearing endpoint stall */
#define UHID_IMMED 0x08 /* return read data immediately */
int sc_disconnected; /* device is gone */
int sc_refcnt;
u_char sc_dying;
};
#define UHIDUNIT(dev) (minor(dev))
#define UHID_CHUNK 128 /* chunk size for read */
#define UHID_BSIZE 1020 /* buffer size */
#if defined(__NetBSD__)
int uhidopen __P((dev_t, int, int, struct proc *));
int uhidclose __P((dev_t, int, int, struct proc *p));
int uhidread __P((dev_t, struct uio *uio, int));
int uhidwrite __P((dev_t, struct uio *uio, int));
int uhidioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
int uhidpoll __P((dev_t, int, struct proc *));
#if defined(__NetBSD__) || defined(__OpenBSD__)
cdev_decl(uhid);
#elif defined(__FreeBSD__)
d_open_t uhidopen;
d_close_t uhidclose;
@ -151,7 +147,10 @@ static struct cdevsw uhid_cdevsw = {
#endif
void uhid_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
void uhid_disco __P((void *));
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 *));
USB_DECLARE_DRIVER(uhid);
@ -179,7 +178,6 @@ USB_ATTACH(uhid)
usbd_status r;
char devinfo[1024];
sc->sc_disconnected = 1;
sc->sc_iface = iface;
id = usbd_get_interface_descriptor(iface);
usbd_devinfo(uaa->device, 0, devinfo);
@ -191,6 +189,7 @@ USB_ATTACH(uhid)
if (!ed) {
printf("%s: could not read endpoint descriptor\n",
USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
@ -199,22 +198,26 @@ USB_ATTACH(uhid)
" bInterval=%d\n",
ed->bLength, ed->bDescriptorType,
ed->bEndpointAddress & UE_ADDR,
ed->bEndpointAddress & UE_IN ? "in" : "out",
UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
ed->bmAttributes & UE_XFERTYPE,
UGETW(ed->wMaxPacketSize), ed->bInterval));
if ((ed->bEndpointAddress & UE_IN) != UE_IN ||
if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
(ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
printf("%s: unexpected endpoint\n", USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
sc->sc_ep_addr = ed->bEndpointAddress;
sc->sc_disconnected = 0;
r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USB);
desc = 0;
r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USBDEV);
if (r != USBD_NORMAL_COMPLETION) {
printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
if (desc)
free(desc, M_USBDEV);
USB_ATTACH_ERROR_RETURN;
}
@ -230,25 +233,70 @@ USB_ATTACH(uhid)
USB_ATTACH_SUCCESS_RETURN;
}
#if defined(__FreeBSD__)
static int
uhid_detach(device_t self)
{
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
uhid_activate(self, act)
device_ptr_t self;
enum devact act;
{
struct uhid_softc *sc = (struct uhid_softc *)self;
return 0;
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
break;
}
return (0);
}
#endif
void
uhid_disco(p)
void *p;
USB_DETACH(uhid)
{
struct uhid_softc *sc = p;
USB_DETACH_START(uhid, sc);
int s;
#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
DPRINTF(("ums_hid: sc=%p\n", sc));
usbd_abort_pipe(sc->sc_intrpipe);
sc->sc_disconnected = 1;
DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("uhid_detach: sc=%p\n", sc));
#endif
sc->sc_dying = 1;
if (sc->sc_intrpipe)
usbd_abort_pipe(sc->sc_intrpipe);
if (sc->sc_state & UHID_OPEN) {
s = splusb();
if (--sc->sc_refcnt >= 0) {
/* Wake everyone */
wakeup(&sc->sc_q);
/* Wait for processes to go away. */
usb_detach_wait(USBDEV(sc->sc_dev));
}
splx(s);
}
#if defined(__NetBSD__) || defined(__OpenBSD__)
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == uhidopen)
break;
/* Nuke the vnodes for any open instances (calls close). */
mn = self->dv_unit;
vdevgone(maj, mn, mn, VCHR);
#elif defined(__FreeBSD__)
/* XXX not implemented yet */
#endif
free(sc->sc_repdesc, M_USBDEV);
return (0);
}
void
@ -277,7 +325,7 @@ uhid_intr(reqh, addr, status)
if (sc->sc_state & UHID_ASLP) {
sc->sc_state &= ~UHID_ASLP;
DPRINTFN(5, ("uhid_intr: waking %p\n", sc));
wakeup((caddr_t)sc);
wakeup(&sc->sc_q);
}
selwakeup(&sc->sc_rsel);
}
@ -292,29 +340,26 @@ uhidopen(dev, flag, mode, p)
usbd_status r;
USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);
if (!sc)
DPRINTF(("uhidopen: sc=%p\n", sc));
if (sc->sc_dying)
return (ENXIO);
DPRINTF(("uhidopen: sc=%p, disco=%d\n", sc, sc->sc_disconnected));
if (sc->sc_disconnected)
return (EIO);
if (sc->sc_state & UHID_OPEN)
return (EBUSY);
sc->sc_state |= UHID_OPEN;
#if defined(__NetBSD__)
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1)
#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_state |= UHID_OPEN;
sc->sc_state &= ~UHID_IMMED;
sc->sc_ibuf = malloc(sc->sc_isize, M_USB, M_WAITOK);
sc->sc_obuf = malloc(sc->sc_osize, M_USB, M_WAITOK);
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,
@ -324,10 +369,13 @@ uhidopen(dev, flag, mode, p)
if (r != USBD_NORMAL_COMPLETION) {
DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
"error=%d\n",r));
free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
sc->sc_state &= ~UHID_OPEN;
return (EIO);
}
usbd_set_disco(sc->sc_intrpipe, uhid_disco, sc);
sc->sc_state &= ~UHID_IMMED;
return (0);
}
@ -341,32 +389,30 @@ uhidclose(dev, flag, mode, p)
{
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
DPRINTF(("uhidclose: sc=%p\n", sc));
/* Disable interrupts. */
usbd_abort_pipe(sc->sc_intrpipe);
usbd_close_pipe(sc->sc_intrpipe);
sc->sc_intrpipe = 0;
sc->sc_state &= ~UHID_OPEN;
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sc->sc_q);
#elif defined(__FreeBSD__)
clist_free_cblocks(&sc->sc_q);
#endif
free(sc->sc_ibuf, M_USB);
free(sc->sc_obuf, M_USB);
free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
sc->sc_state &= ~UHID_OPEN;
return (0);
}
int
uhidread(dev, uio, flag)
dev_t dev;
uhid_do_read(sc, uio, flag)
struct uhid_softc *sc;
struct uio *uio;
int flag;
{
@ -375,17 +421,13 @@ uhidread(dev, uio, flag)
size_t length;
u_char buffer[UHID_CHUNK];
usbd_status r;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
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, sc->sc_ibuf, sc->sc_isize);
sc->sc_iid, buffer, sc->sc_isize);
if (r != USBD_NORMAL_COMPLETION)
return (EIO);
return (uiomove(buffer, sc->sc_isize, uio));
@ -395,16 +437,17 @@ uhidread(dev, uio, flag)
while (sc->sc_q.c_cc == 0) {
if (flag & IO_NDELAY) {
splx(s);
return EWOULDBLOCK;
return (EWOULDBLOCK);
}
sc->sc_state |= UHID_ASLP;
DPRINTFN(5, ("uhidread: sleep on %p\n", sc));
error = tsleep((caddr_t)sc, PZERO | PCATCH, "uhidrea", 0);
error = tsleep(&sc->sc_q, PZERO | PCATCH, "uhidrea", 0);
DPRINTFN(5, ("uhidread: woke, error=%d\n", error));
if (sc->sc_dying)
error = EIO;
if (error) {
sc->sc_state &= ~UHID_ASLP;
splx(s);
return (error);
break;
}
if (sc->sc_state & UHID_NEEDCLEAR) {
DPRINTFN(-1,("uhidread: clearing stall\n"));
@ -415,7 +458,7 @@ uhidread(dev, uio, flag)
splx(s);
/* Transfer as many chunks as possible. */
while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) {
length = min(sc->sc_q.c_cc, uio->uio_resid);
if (length > sizeof(buffer))
length = sizeof(buffer);
@ -433,28 +476,42 @@ uhidread(dev, uio, flag)
}
int
uhidwrite(dev, uio, flag)
uhidread(dev, uio, flag)
dev_t dev;
struct uio *uio;
int flag;
{
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
int error;
sc->sc_refcnt++;
error = uhid_do_read(sc, uio, flag);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
int
uhid_do_write(sc, uio, flag)
struct uhid_softc *sc;
struct uio *uio;
int flag;
{
int error;
int size;
usbd_status r;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
DPRINTFN(1, ("uhidwrite\n"));
if (sc->sc_dying)
return (EIO);
size = sc->sc_osize;
error = 0;
while (uio->uio_resid > 0) {
if (uio->uio_resid != size)
return (0);
if ((error = uiomove(sc->sc_obuf, size, uio)) != 0)
break;
if (uio->uio_resid != size)
return (EINVAL);
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],
@ -464,15 +521,31 @@ uhidwrite(dev, uio, flag)
0, sc->sc_obuf, size);
if (r != USBD_NORMAL_COMPLETION) {
error = EIO;
break;
}
}
return (error);
}
int
uhidioctl(dev, cmd, addr, flag, p)
uhidwrite(dev, uio, flag)
dev_t dev;
struct uio *uio;
int flag;
{
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
int error;
sc->sc_refcnt++;
error = uhid_do_write(sc, uio, flag);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
int
uhid_do_ioctl(sc, cmd, addr, flag, p)
struct uhid_softc *sc;
u_long cmd;
caddr_t addr;
int flag;
@ -482,12 +555,12 @@ uhidioctl(dev, cmd, addr, flag, p)
struct usb_ctl_report *re;
int size, id;
usbd_status r;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
if (sc->sc_dying)
return (EIO);
switch (cmd) {
case FIONBIO:
/* All handled in the upper FS layer. */
@ -544,6 +617,24 @@ uhidioctl(dev, cmd, addr, flag, p)
return (0);
}
int
uhidioctl(dev, cmd, addr, flag, p)
dev_t dev;
u_long cmd;
caddr_t addr;
int flag;
struct proc *p;
{
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
int error;
sc->sc_refcnt++;
error = uhid_do_ioctl(sc, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
int
uhidpoll(dev, events, p)
dev_t dev;
@ -554,7 +645,7 @@ uhidpoll(dev, events, p)
int s;
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
if (sc->sc_dying)
return (EIO);
s = splusb();
@ -573,5 +664,5 @@ uhidpoll(dev, events, p)
#if defined(__FreeBSD__)
DEV_DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass,
uhid_cdevsw, usbd_driver_load, 0);
uhid_cdevsw, usbd_driver_load, 0);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhub.c,v 1.16 1999/01/10 19:13:15 augustss Exp $ */
/* $NetBSD: uhub.c,v 1.26 1999/09/05 19:32:18 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -46,7 +46,7 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#elif defined(__FreeBSD__)
#include <sys/module.h>
@ -54,8 +54,9 @@
#endif
#include <sys/proc.h>
#include <dev/usb/usb.h>
#include "bus_if.h"
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdivar.h>
@ -70,7 +71,7 @@ extern int usbdebug;
#endif
struct uhub_softc {
bdevice sc_dev; /* base device */
USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_hub; /* USB device */
usbd_pipe_handle sc_ipipe; /* interrupt pipe */
u_int8_t sc_status[1]; /* XXX more ports */
@ -82,32 +83,42 @@ 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));
/* void uhub_disco __P((void *)); */
USB_DECLARE_DRIVER(uhub);
#if defined(__FreeBSD__)
static bus_child_detached_t uhub_child_detached;
#endif
USB_DECLARE_DRIVER_INIT(uhub, DEVMETHOD(bus_child_detached, uhub_child_detached));
/* We need two attachment points:
* hub to usb and hub to hub
* Every other driver only connects to hubs
*/
#if defined(__NetBSD__) || defined(__OpenBSD__)
/* Create the driver instance for the hub connected to hub case */
struct cfattach uhub_uhub_ca = {
sizeof(struct uhub_softc), uhub_match, uhub_attach,
uhub_detach, uhub_activate
};
#elif defined(__FreeBSD__)
/* Create the driver instance for the hub connected to usb case. */
devclass_t uhubroot_devclass;
static device_method_t uhubroot_methods[] = {
DEVMETHOD(device_probe, uhub_match),
DEVMETHOD(device_attach, uhub_attach),
DEVMETHOD(device_probe, uhub_match),
DEVMETHOD(device_attach, uhub_attach),
/* detach is not allowed for a root hub */
{0,0}
{0,0}
};
static driver_t uhubroot_driver = {
"uhub",
uhubroot_methods,
sizeof(struct uhub_softc)
static driver_t uhubroot_driver = {
"uhub",
uhubroot_methods,
sizeof(struct uhub_softc)
};
#endif
#if defined(__NetBSD__)
struct cfattach uhub_uhub_ca = {
sizeof(struct uhub_softc), uhub_match, uhub_attach
};
#endif
USB_MATCH(uhub)
{
@ -145,7 +156,7 @@ USB_ATTACH(uhub)
r = usbd_set_config_index(dev, 0, 1);
if (r != USBD_NORMAL_COMPLETION) {
DPRINTF(("%s: configuration failed, %s\n",
DPRINTF(("%s: configuration failed, error=%s\n",
USBDEVNAME(sc->sc_dev), usbd_errstr(r)));
USB_ATTACH_ERROR_RETURN;
}
@ -170,7 +181,7 @@ USB_ATTACH(uhub)
r = usbd_do_request(dev, &req, &hubdesc);
}
if (r != USBD_NORMAL_COMPLETION) {
DPRINTF(("%s: getting hub descriptor failed, %s\n",
DPRINTF(("%s: getting hub descriptor failed, error=%s\n",
USBDEVNAME(sc->sc_dev), usbd_errstr(r)));
USB_ATTACH_ERROR_RETURN;
}
@ -184,7 +195,7 @@ USB_ATTACH(uhub)
hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port),
M_USB, M_NOWAIT);
M_USBDEV, M_NOWAIT);
if (hub == 0)
USB_ATTACH_ERROR_RETURN;
dev->hub = hub;
@ -197,28 +208,28 @@ USB_ATTACH(uhub)
dev->self_powered, dev->powersrc->parent,
dev->powersrc->parent ?
dev->powersrc->parent->self_powered : 0));
if (!dev->self_powered && dev->powersrc->parent &&
!dev->powersrc->parent->self_powered) {
printf("%s: bus powered hub connected to bus powered hub, "
"ignored\n",
USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
"ignored\n", USBDEVNAME(sc->sc_dev));
goto bad;
}
/* Set up interrupt pipe. */
r = usbd_device2interface_handle(dev, 0, &iface);
if (r != USBD_NORMAL_COMPLETION) {
printf("%s: no interface handle\n", USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
goto bad;
}
ed = usbd_interface2endpoint_descriptor(iface, 0);
if (ed == 0) {
printf("%s: no endpoint descriptor\n", USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
goto bad;
}
if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
printf("%s: bad interrupt endpoint\n", USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
goto bad;
}
r = usbd_open_pipe_intr(iface, ed->bEndpointAddress,USBD_SHORT_XFER_OK,
@ -228,7 +239,7 @@ USB_ATTACH(uhub)
if (r != USBD_NORMAL_COMPLETION) {
printf("%s: cannot open interrupt pipe\n",
USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
goto bad;
}
/* Wait with power off for a while. */
@ -247,18 +258,12 @@ USB_ATTACH(uhub)
sc->sc_running = 1;
USB_ATTACH_SUCCESS_RETURN;
}
#if defined(__FreeBSD__)
static int
uhub_detach(device_t self)
{
struct uhub_softc *sc = device_get_softc(self);
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
free(sc->sc_hub->hub, M_USB);
return 0;
bad:
free(hub, M_USBDEV);
dev->hub = 0;
USB_ATTACH_ERROR_RETURN;
}
#endif
usbd_status
uhub_init_port(up)
@ -282,11 +287,13 @@ uhub_init_port(up)
/* First let the device go through a good power cycle, */
usbd_delay_ms(dev, USB_PORT_POWER_DOWN_TIME);
#if 0
usbd_clear_hub_feature(dev, UHF_C_HUB_OVER_CURRENT);
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);
r = usbd_get_port_status(dev, port, &up->status);
if (r != USBD_NORMAL_COMPLETION)
return (r);
DPRINTF(("usb_init_port: turn on port %d power status=0x%04x "
@ -296,6 +303,26 @@ uhub_init_port(up)
/* Wait for stable power. */
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);
DPRINTF(("usb_init_port: after power on status=0x%04x "
"change=0x%04x\n",
UGETW(up->status.wPortStatus),
UGETW(up->status.wPortChange)));
#if 0
usbd_clear_hub_feature(dev, UHF_C_HUB_OVER_CURRENT);
usbd_clear_port_feature(dev, port, UHF_C_PORT_OVER_CURRENT);
usbd_get_port_status(dev, port, &up->status);
#endif
pstatus = UGETW(up->status.wPortStatus);
if ((pstatus & UPS_PORT_POWER) == 0)
printf("%s: port %d did not power up\n",
USBDEVNAME(((struct uhub_softc *)dev->hub->hubsoftc)->sc_dev), port);
}
if (dev->self_powered)
/* Self powered hub, give ports maximum current. */
@ -329,8 +356,9 @@ uhub_explore(dev)
up = &dev->hub->ports[port-1];
r = usbd_get_port_status(dev, port, &up->status);
if (r != USBD_NORMAL_COMPLETION) {
DPRINTF(("uhub_explore: get port %d status failed, %s\n",
port, usbd_errstr(r)));
DPRINTF(("uhub_explore: get port status failed, "
"error=%s\n",
usbd_errstr(r)));
continue;
}
status = UGETW(up->status.wPortStatus);
@ -340,16 +368,18 @@ uhub_explore(dev)
if (change & UPS_C_PORT_ENABLED) {
usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE);
if (status & UPS_PORT_ENABLED) {
printf("%s: port %d illegal enable change\n",
printf("%s: illegal enable change, port %d\n",
USBDEVNAME(sc->sc_dev), port);
} else {
/* Port error condition. */
if (up->restartcnt++ < USBD_RESTART_MAX) {
printf("%s: port %d error, restarting\n",
printf("%s: port error, restarting "
"port %d\n",
USBDEVNAME(sc->sc_dev), port);
goto disco;
} else {
printf("%s: port %d error, giving up\n",
printf("%s: port error, giving up "
"port %d\n",
USBDEVNAME(sc->sc_dev), port);
}
}
@ -378,6 +408,7 @@ uhub_explore(dev)
"on port %d\n",
up->device->address, port));
uhub_disconnect_port(up);
usbd_clear_port_feature(dev, port,
UHF_C_PORT_CONNECTION);
}
@ -396,25 +427,23 @@ uhub_explore(dev)
continue;
/* Get device info and set its address. */
r = usbd_new_device(&sc->sc_dev, dev->bus,
r = 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) {
DPRINTFN(-1,("uhub_explore: usb_new_device failed, %s\n",
usbd_errstr(r)));
DPRINTFN(-1,("uhub_explore: usb_new_device failed, "
"error=%s\n", usbd_errstr(r)));
/* 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.
* Maybe the port should be disabled until the device is
* disconnected.
*/
if (r == USBD_SET_ADDR_FAILED || 1) {/* XXX */
/* The unit refused to accept a new
* address, and since we cannot leave
* it at 0 we have to disable the port
* at 0 we have to disable the port
* instead. */
printf("%s: device problem, disabling "
"port %d\n",
@ -432,31 +461,35 @@ 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;
usbd_pipe_handle p, n;
int i;
struct softc { /* all softc begin like this */
bdevice sc_dev;
};
struct softc *sc;
struct softc *scp;
if (!dev) /* no device driver attached at port */
return;
sc = (struct softc *)dev->softc;
scp = (struct softc *)up->parent->softc;
DPRINTFN(3,("uhub_disconnect_port: up=%p dev=%p port=%d\n",
DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
up, dev, up->portno));
printf("%s: at %s port %d (addr %d) disconnected\n",
USBDEVNAME(sc->sc_dev), USBDEVNAME(scp->sc_dev),
up->portno, dev->address);
if (!dev) /* not even generic device was attached */
return;
if (!dev->cdesc) {
/* Partially attached device, just drop it. */
@ -465,46 +498,126 @@ uhub_disconnect_port(up)
return;
}
/* Remove the device */
for (i = 0; i < dev->cdesc->bNumInterface; i++) {
for (p = LIST_FIRST(&dev->ifaces[i].pipes); p; p = n) {
n = LIST_NEXT(p, next);
if (p->disco)
p->disco(p->discoarg);
}
}
if (dev->subdevs) {
for (i = 0; dev->subdevs[i]; i++) {
if (!dev->subdevs[i]) /* skip empty elements */
continue;
/* XXX Free all data structures and disable further I/O. */
if (dev->hub) {
struct usbd_port *rup;
int p, nports;
DPRINTFN(3,("usb_disconnect: hub, recursing\n"));
nports = dev->hub->hubdesc.bNbrPorts;
for(p = 0; p < nports; p++) {
rup = &dev->hub->ports[p];
if (rup->device)
uhub_disconnect_port(rup);
}
}
#if defined(__FreeBSD__)
device_delete_child(scp->sc_dev, sc->sc_dev);
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
/* clean up the kitchen */
for (i = 0; i < dev->cdesc->bNumInterface; i++) {
for (p = LIST_FIRST(&dev->ifaces[i].pipes); p; p = n) {
n = LIST_NEXT(p, next);
usbd_abort_pipe(p);
usbd_close_pipe(p);
}
}
dev->bus->devices[dev->address] = 0;
up->device = 0;
/* XXX free */
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?");
for (port = 0; port < dev->hub->hubdesc.bNbrPorts; 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;
{
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
break;
}
return (0);
}
#endif
/*
* Called from process context when the hub is gone.
* Detach all devices on active ports.
*/
USB_DETACH(uhub)
{
USB_DETACH_START(uhub, sc);
usbd_device_handle dev = sc->sc_hub;
struct usbd_port *up;
int port, nports;
#if defined(__NetBSD__) || defined(__OpenBSD__)
DPRINTF(("uhub_detach: sc=%port flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("uhub_detach: sc=%port\n", sc));
#endif
if (!dev->hub) /* Must be partially working */
return (0);
usbd_abort_pipe(sc->sc_ipipe);
usbd_close_pipe(sc->sc_ipipe);
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);
}
}
free(dev->hub, M_USBDEV);
dev->hub = 0;
return (0);
}
/*
* Hub interrupt.
* This an indication that some port has changed status.
* Notify the bus event handler thread that we need
* to be explored again.
*/
void
uhub_intr(reqh, addr, status)
usbd_request_handle reqh;
@ -516,8 +629,8 @@ uhub_intr(reqh, addr, status)
DPRINTFN(5,("uhub_intr: sc=%p\n", sc));
if (status != USBD_NORMAL_COMPLETION)
usbd_clear_endpoint_stall_async(sc->sc_ipipe);
else
usb_needs_explore(sc->sc_hub->bus);
usb_needs_explore(sc->sc_hub->bus);
}
#if defined(__FreeBSD__)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulpt.c,v 1.11 1999/01/10 11:13:36 augustss Exp $ */
/* $NetBSD: ulpt.c,v 1.23 1999/09/11 10:40:07 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -42,10 +42,11 @@
* Printer Class spec: http://www.usb.org/developers/data/usbprn10.pdf
*/
/* XXX Note in the manpage the ULPT_NOPRIME version of the printer */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#if defined(__NetBSD__)
#include <sys/device.h>
@ -57,6 +58,7 @@
#endif
#include <sys/uio.h>
#include <sys/conf.h>
#include <sys/vnode.h>
#include <sys/syslog.h>
#include <dev/usb/usb.h>
@ -74,7 +76,7 @@
#ifdef ULPT_DEBUG
#define DPRINTF(x) if (ulptdebug) logprintf x
#define DPRINTFN(n,x) if (ulptdebug>(n)) logprintf x
int ulptdebug = 1;
int ulptdebug = 0;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@ -91,7 +93,7 @@ int ulptdebug = 1;
#define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER)
struct ulpt_softc {
bdevice sc_dev;
USBBASEDEVICE sc_dev;
usbd_device_handle sc_udev; /* device */
usbd_interface_handle sc_iface; /* interface */
int sc_ifaceno;
@ -103,21 +105,19 @@ struct ulpt_softc {
#define ULPT_OBUSY 0x02 /* printer is busy doing output */
#define ULPT_INIT 0x04 /* waiting to initialize for open */
u_char sc_flags;
#if defined(__NetBSD__)
#define ULPT_NOPRIME 0x40 /* don't prime on open */
#elif defined(__FreeBSD__)
/* values taken from i386/isa/lpt.c */
#define ULPT_POS_INIT 0x04 /* if we are a postive init signal */
#define ULPT_POS_ACK 0x08 /* if we are a positive going ack */
#define ULPT_NOPRIME 0x10 /* don't prime the printer at all */
#define ULPT_PRIMEOPEN 0x20 /* prime on every open */
#define ULPT_AUTOLF 0x40 /* tell printer to do an automatic lf */
#define ULPT_BYPASS 0x80 /* bypass printer ready checks */
#endif
u_char sc_laststatus;
int sc_refcnt;
u_char sc_dying;
#if defined(__FreeBSD__)
dev_t dev;
dev_t dev_noprime;
#endif
};
#if defined(__NetBSD__)
#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));
@ -148,18 +148,18 @@ static struct cdevsw ulpt_cdevsw = {
};
#endif
void ulpt_disco __P((void *));
int ulpt_do_write __P((struct ulpt_softc *, struct uio *uio, int));
int ulpt_status __P((struct ulpt_softc *));
void ulpt_reset __P((struct ulpt_softc *));
int ulpt_statusmsg __P((u_char, struct ulpt_softc *));
#if defined(__NetBSD__)
void ieee1284_print_id __P((char *));
#define ULPTUNIT(s) (minor(s) & 0x1f)
#define ULPTFLAGS(s) (minor(s) & 0xe0)
#elif defined(__FreeBSD__)
/* defines taken from i386/isa/lpt.c */
#define ULPTUNIT(s) (minor(s) & 0x03)
#define ULPTFLAGS(s) (minor(s) & 0xfc)
#endif
USB_DECLARE_DRIVER(ulpt);
@ -187,8 +187,6 @@ USB_ATTACH(ulpt)
usbd_device_handle dev = uaa->device;
usbd_interface_handle iface = uaa->iface;
usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
usb_device_request_t req;
char devinfo[1024];
usb_endpoint_descriptor_t *ed;
usbd_status r;
@ -203,13 +201,13 @@ USB_ATTACH(ulpt)
ed = usbd_interface2endpoint_descriptor(iface, 0);
if (!ed)
goto nobulk;
if ((ed->bEndpointAddress & UE_DIR) != UE_OUT ||
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)
goto nobulk;
if ((ed->bEndpointAddress & UE_IN) != UE_OUT ||
if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT ||
(ed->bmAttributes & UE_XFERTYPE) != UE_BULK)
goto nobulk;
}
@ -218,35 +216,127 @@ USB_ATTACH(ulpt)
sc->sc_iface = iface;
r = usbd_interface2device_handle(iface, &sc->sc_udev);
if (r != USBD_NORMAL_COMPLETION)
if (r != USBD_NORMAL_COMPLETION) {
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
sc->sc_ifaceno = id->bInterfaceNumber;
#if 0
/*
* This code is disabled because for some mysterious it causes
* printing not to work. But only sometimes, and mostly with
* UHCI and less often with OHCI. *sigh*
*/
{
usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
usb_device_request_t req;
int len, alen;
req.bmRequestType = UT_READ_CLASS_INTERFACE;
req.bRequest = UR_GET_DEVICE_ID;
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, NULL);
if (r == USBD_NORMAL_COMPLETION) {
int len;
char *idstr;
len = (devinfo[0] << 8) | (devinfo[1] & 0xff);
/* devinfo now contains an IEEE-1284 device ID */
idstr = devinfo+2;
idstr[len] = 0;
printf("%s: device id <%s>\n", USBDEVNAME(sc->sc_dev), idstr);
} else {
r = usbd_do_request_flags(dev, &req, devinfo,USBD_SHORT_XFER_OK,&alen);
if (r != USBD_NORMAL_COMPLETION) {
printf("%s: cannot get device id\n", USBDEVNAME(sc->sc_dev));
} else if (alen <= 2) {
printf("%s: empty device id, no printer connected?\n",
USBDEVNAME(sc->sc_dev));
} else {
/* devinfo now contains an IEEE-1284 device ID */
len = ((devinfo[0] & 0xff) << 8) | (devinfo[1] & 0xff);
if (len > sizeof devinfo - 3)
len = sizeof devinfo - 3;
devinfo[len] = 0;
printf("%s: device id <", USBDEVNAME(sc->sc_dev));
ieee1284_print_id(devinfo+2);
printf(">\n");
}
}
#endif
#if defined(__FreeBSD__)
sc->dev = make_dev(&ulpt_cdevsw, device_get_unit(self),
UID_ROOT, GID_OPERATOR, 0644, "ulpt%d", device_get_unit(self));
sc->dev_noprime = make_dev(&ulpt_cdevsw,
device_get_unit(self)|ULPT_NOPRIME,
UID_ROOT, GID_OPERATOR, 0644, "unlpt%d", device_get_unit(self));
#endif
USB_ATTACH_SUCCESS_RETURN;
nobulk:
printf("%s: could not find bulk endpoint\n", USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
ulpt_activate(self, act)
device_ptr_t self;
enum devact act;
{
struct ulpt_softc *sc = (struct ulpt_softc *)self;
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
sc->sc_dying = 1;
break;
}
return (0);
}
#endif
USB_DETACH(ulpt)
{
USB_DETACH_START(ulpt, sc);
int s;
#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
DPRINTF(("ulpt_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("ulpt_detach: sc=%p\n", sc));
#endif
sc->sc_dying = 1;
if (sc->sc_bulkpipe)
usbd_abort_pipe(sc->sc_bulkpipe);
s = splusb();
if (--sc->sc_refcnt >= 0) {
/* There is noone to wake, aborting the pipe is enough */
/* Wait for processes to go away. */
usb_detach_wait(USBDEV(sc->sc_dev));
}
splx(s);
#if defined(__NetBSD__) || defined(__OpenBSD__)
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == ulptopen)
break;
/* Nuke the vnodes for any open instances (calls close). */
mn = self->dv_unit;
vdevgone(maj, mn, mn, VCHR);
#elif defined(__FreeBSD__)
/* XXX not implemented yet */
remove_dev(sc->dev);
remove_dev(sc->dev_noprime);
#endif
return (0);
}
int
ulpt_status(sc)
struct ulpt_softc *sc;
@ -298,11 +388,11 @@ ulptopen(dev, flag, mode, p)
int spin, error;
USB_GET_SC_OPEN(ulpt, ULPTUNIT(dev), sc);
if (!sc || !sc->sc_iface)
return ENXIO;
if (!sc || !sc->sc_iface || sc->sc_dying)
return (ENXIO);
if (sc->sc_state)
return EBUSY;
return (EBUSY);
sc->sc_state = ULPT_INIT;
sc->sc_flags = flags;
@ -314,20 +404,22 @@ ulptopen(dev, flag, mode, p)
printf("ulptopen: flags ignored: %b\n", flags,
"\20\3POS_INIT\4POS_ACK\6PRIME_OPEN\7AUTOLF\10BYPASS");
#endif
if ((flags & ULPT_NOPRIME) == 0)
ulpt_reset(sc);
for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) {
if (spin >= TIMEOUT) {
sc->sc_state = 0;
return EBUSY;
return (EBUSY);
}
/* wait 1/4 second, give up if we get a signal */
error = tsleep((caddr_t)sc, LPTPRI | PCATCH, "ulptop", STEP);
if (error != EWOULDBLOCK) {
sc->sc_state = 0;
return error;
return (error);
}
}
@ -361,7 +453,7 @@ ulpt_statusmsg(status, sc)
else if (new & LPS_NERR)
log(LOG_NOTICE, "%s: output error\n", USBDEVNAME(sc->sc_dev));
return status;
return (status);
}
int
@ -373,51 +465,75 @@ ulptclose(dev, flag, mode, p)
{
USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
if (sc->sc_state != ULPT_OPEN)
/* We are being forced to close before the open completed. */
return (0);
usbd_close_pipe(sc->sc_bulkpipe);
sc->sc_bulkpipe = 0;
sc->sc_state = 0;
DPRINTF(("ulptclose: closed\n"));
return (0);
}
int
ulpt_do_write(sc, uio, flags)
struct ulpt_softc *sc;
struct uio *uio;
int flags;
{
u_int32_t n;
int error = 0;
void *bufp;
usbd_request_handle reqh;
usbd_status r;
DPRINTF(("ulptwrite\n"));
reqh = usbd_alloc_request(sc->sc_udev);
if (reqh == 0)
return (ENOMEM);
bufp = usbd_alloc_buffer(reqh, ULPT_BSIZE);
if (bufp == 0) {
usbd_free_request(reqh);
return (ENOMEM);
}
while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
ulpt_statusmsg(ulpt_status(sc), sc);
error = uiomove(bufp, n, uio);
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));
error = EIO;
break;
}
}
usbd_free_request(reqh);
return (error);
}
int
ulptwrite(dev, uio, flags)
dev_t dev;
struct uio *uio;
int flags;
{
size_t n;
int error = 0;
char buf[ULPT_BSIZE];
usbd_request_handle reqh;
usbd_status r;
USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
int error;
reqh = usbd_alloc_request();
if (reqh == 0)
return (ENOMEM);
while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
ulpt_statusmsg(ulpt_status(sc), sc);
error = uiomove(buf, n, uio);
if (error)
break;
/* XXX use callback to enable interrupt? */
r = usbd_setup_request(reqh, sc->sc_bulkpipe, 0, buf, n,
0, USBD_NO_TIMEOUT, 0);
if (r != USBD_NORMAL_COMPLETION) {
error = EIO;
break;
}
DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n));
r = usbd_sync_transfer(reqh);
if (r != USBD_NORMAL_COMPLETION) {
DPRINTFN(1, ("ulptwrite: error=%d\n", r));
usbd_clear_endpoint_stall(sc->sc_bulkpipe);
error = EIO;
break;
}
}
usbd_free_request(reqh);
if (sc->sc_dying)
return (EIO);
sc->sc_refcnt++;
error = ulpt_do_write(sc, uio, flags);
if (--sc->sc_refcnt < 0)
usb_detach_wakeup(USBDEV(sc->sc_dev));
return (error);
}
@ -436,17 +552,35 @@ ulptioctl(dev, cmd, data, flag, p)
error = ENODEV;
}
return error;
return (error);
}
#if 0
/* XXX This does not belong here. */
/*
* Print select parts of a IEEE 1284 device ID.
*/
void
ieee1284_print_id(str)
char *str;
{
char *p, *q;
for (p = str-1; p; p = strchr(p, ';')) {
p++; /* skip ';' */
if (strncmp(p, "MFG:", 4) == 0 ||
strncmp(p, "MANUFACTURER:", 14) == 0 ||
strncmp(p, "MDL:", 4) == 0 ||
strncmp(p, "MODEL:", 6) == 0) {
q = strchr(p, ';');
if (q)
printf("%.*s", (int)(q - p + 1), p);
}
}
}
#endif
#if defined(__FreeBSD__)
static int
ulpt_detach(device_t self)
{
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
return 0;
}
DEV_DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass, ulpt_cdevsw, usbd_driver_load, 0);
DEV_DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass,
ulpt_cdevsw, usbd_driver_load, 0);
#endif

View File

@ -76,7 +76,7 @@ int umassdebug = UDMASS_CAM|UDMASS_BULK|UDMASS_USB;
#endif
typedef struct umass_softc {
bdevice sc_dev; /* base device */
USBBASEDEVICE sc_dev; /* base device */
usbd_interface_handle sc_iface; /* the interface we use */
u_int8_t sc_bulkout; /* bulk-out Endpoint Address */
@ -213,10 +213,10 @@ USB_ATTACH(umass)
USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
if (UE_GET_DIR(ed->bEndpointAddress) == UE_IN
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN
&& (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
sc->sc_bulkin = ed->bEndpointAddress;
} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_OUT
} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT
&& (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
sc->sc_bulkout = ed->bEndpointAddress;
}
@ -287,6 +287,7 @@ usbd_status
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_private_handle priv;
void *buffer;
@ -297,7 +298,9 @@ umass_usb_transfer(usbd_interface_handle iface, usbd_pipe_handle pipe,
* transfer and then wait for it to complete
*/
reqh = usbd_alloc_request();
usbd_interface2device_handle(iface, &dev);
reqh = usbd_alloc_request(dev);
if (!reqh) {
DPRINTF(UDMASS_USB, ("Not enough memory\n"));
return USBD_NOMEM;

View File

@ -1,4 +1,5 @@
/* $NetBSD: umodem.c,v 1.5 1999/01/08 11:58:25 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb.c,v 1.12 1999/01/10 19:13:16 augustss Exp $ */
/* $NetBSD: usb.c,v 1.19 1999/09/05 19:32:19 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -48,8 +48,9 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#include <sys/kthread.h>
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
@ -62,31 +63,26 @@
#include <sys/select.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#if defined(__FreeBSD__)
MALLOC_DEFINE(M_USB, "USB", "USB");
MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
#include "usb_if.h"
#include "uhci.h"
#include "ohci.h"
#endif /* defined(__FreeBSD__) */
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_quirks.h>
#ifdef USB_DEBUG
#define DPRINTF(x) if (usbdebug) logprintf x
#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
int usbdebug = 1;
#if NUHCI > 0
extern int uhcidebug;
#endif
#if NOHCI > 0
extern int ohcidebug;
#endif
int usbdebug = 0;
extern int uhcidebug;
extern int ohcidebug;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@ -95,15 +91,17 @@ extern int ohcidebug;
#define USBUNIT(dev) (minor(dev))
struct usb_softc {
bdevice 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(__NetBSD__)
#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 *));
@ -116,26 +114,28 @@ d_ioctl_t usbioctl;
int usbpoll __P((dev_t, int, struct proc *));
struct cdevsw usb_cdevsw = {
/* open */ usbopen,
/* close */ usbclose,
/* read */ noread,
/* write */ nowrite,
/* ioctl */ usbioctl,
/* poll */ usbpoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
/* name */ "usb",
/* maj */ USB_CDEV_MAJOR,
/* dump */ nodump,
/* psize */ nopsize,
/* flags */ 0,
/* bmaj */ -1
/* open */ usbopen,
/* close */ usbclose,
/* read */ noread,
/* write */ nowrite,
/* ioctl */ usbioctl,
/* poll */ usbpoll,
/* mmap */ nommap,
/* strategy */ nostrategy,
/* name */ "usb",
/* maj */ USB_CDEV_MAJOR,
/* dump */ nodump,
/* psize */ nopsize,
/* flags */ 0,
/* bmaj */ -1
};
#endif
usbd_status usb_discover __P((struct usb_softc *));
void usb_create_event_thread __P((void *));
void usb_event_thread __P((void *));
USB_DECLARE_DRIVER_INIT(usb, DEVMETHOD(bus_print_child, usbd_print_child));
USB_DECLARE_DRIVER(usb);
USB_MATCH(usb)
{
@ -145,7 +145,7 @@ USB_MATCH(usb)
USB_ATTACH(usb)
{
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
struct usb_softc *sc = (struct usb_softc *)self;
#elif defined(__FreeBSD__)
struct usb_softc *sc = device_get_softc(self);
@ -154,20 +154,20 @@ USB_ATTACH(usb)
usbd_device_handle dev;
usbd_status r;
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
printf("\n");
#elif defined(__FreeBSD__)
sc->sc_dev = self;
#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(&sc->sc_dev, sc->sc_bus, 0, 0, 0, &sc->sc_port);
r = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0,0,0, &sc->sc_port);
if (r == USBD_NORMAL_COMPLETION) {
dev = sc->sc_port.device;
@ -186,10 +186,55 @@ USB_ATTACH(usb)
}
sc->sc_bus->use_polling = 0;
#if defined(__NetBSD__) || defined(__OpenBSD__)
kthread_create(usb_create_event_thread, sc);
#endif
#if defined(__FreeBSD__)
device_printf(self, "make_dev(usb_cdevsw, %d,_,_,_,'usb%%d',_)\n",
device_get_unit(self));
make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR,
0644, "usb%d", device_get_unit(self));
#endif
USB_ATTACH_SUCCESS_RETURN;
}
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
void
usb_create_event_thread(arg)
void *arg;
{
struct usb_softc *sc = arg;
if (kthread_create1(usb_event_thread, sc, &sc->event_thread,
"%s", sc->sc_dev.dv_xname)) {
printf("%s: unable to create event thread for\n",
sc->sc_dev.dv_xname);
panic("usb_create_event_thread");
}
}
void
usb_event_thread(arg)
void *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"));
usb_discover(sc);
}
sc->event_thread = 0;
/* In case parent is waiting for us to exit. */
wakeup(sc);
kthread_exit(0);
}
int
usbctlprint(aux, pnp)
void *aux;
@ -201,7 +246,7 @@ usbctlprint(aux, pnp)
return (UNCONF);
}
#endif
#endif /* NetBSD && OpenBSD */
int
usbopen(dev, flag, mode, p)
@ -227,33 +272,28 @@ usbclose(dev, flag, mode, p)
}
int
usbioctl(dev, cmd, data, flag, p)
dev_t dev;
usbioctl(devt, cmd, data, flag, p)
dev_t devt;
u_long cmd;
caddr_t data;
int flag;
struct proc *p;
{
USB_GET_SC(usb, USBUNIT(dev), sc);
USB_GET_SC(usb, USBUNIT(devt), sc);
if (sc == 0 || !sc->sc_running)
return (ENXIO);
switch (cmd) {
#ifdef USB_DEBUG
case USB_SETDEBUG:
usbdebug = *(int *)data;
#if NUHCI > 0
uhcidebug = *(int *)data;
#endif
#if NOHCI > 0
ohcidebug = *(int *)data;
#endif
usbdebug = uhcidebug = ohcidebug = *(int *)data;
break;
#endif
#if defined(__FreeBSD__)
case USB_DISCOVER:
usb_discover(sc);
break;
#endif
case USB_REQUEST:
{
struct usb_ctl_request *ur = (void *)data;
@ -291,9 +331,9 @@ usbioctl(dev, cmd, data, flag, p)
}
}
r = usbd_do_request_flags(sc->sc_bus->devices[addr],
&ur->request, ptr,
&ur->request, ptr,
ur->flags, &ur->actlen);
if (r) {
if (r != USBD_NORMAL_COMPLETION) {
error = EIO;
goto ret;
}
@ -341,23 +381,23 @@ usbpoll(dev, events, p)
int events;
struct proc *p;
{
int revents = 0;
int s;
int revents, s;
USB_GET_SC(usb, USBUNIT(dev), sc);
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);
if (revents == 0)
if (events & (POLLOUT | POLLWRNORM))
DPRINTFN(15, ("usbpoll: revents=0x%x\n", revents));
if (revents == 0) {
if (events & (POLLOUT | POLLWRNORM)) {
DPRINTFN(2, ("usbpoll: selrecord\n"));
selrecord(p, &sc->sc_consel);
}
}
splx(s);
return (revents);
}
@ -399,21 +439,22 @@ usb_discover(sc)
/* Explore device tree from the root */
/* We need mutual exclusion while traversing the device tree. */
s = splusb();
while (sc->sc_exploring)
tsleep(&sc->sc_exploring, PRIBIO, "usbdis", 0);
sc->sc_exploring = 1;
sc->sc_bus->needs_explore = 0;
splx(s);
sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
s = splusb();
sc->sc_exploring = 0;
wakeup(&sc->sc_exploring);
splx(s);
/* XXX should we start over if sc_needsexplore is set again? */
return (0);
do {
s = splusb();
while (sc->sc_exploring)
tsleep(&sc->sc_exploring, PRIBIO, "usbdis", 0);
sc->sc_exploring = 1;
sc->sc_bus->needs_explore = 0;
splx(s);
sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
s = splusb();
sc->sc_exploring = 0;
wakeup(&sc->sc_exploring);
splx(s);
} while (sc->sc_bus->needs_explore);
return (USBD_NORMAL_COMPLETION);
}
void
@ -422,9 +463,28 @@ usb_needs_explore(bus)
{
bus->needs_explore = 1;
selwakeup(&bus->usbctl->sc_consel);
wakeup(&bus->needs_explore);
}
#if defined(__FreeBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
usb_activate(self, act)
device_ptr_t self;
enum devact act;
{
panic("usb_activate\n");
return (0);
}
int
usb_detach(self, flags)
device_ptr_t self;
int flags;
{
panic("usb_detach\n");
return (0);
}
#elif defined(__FreeBSD__)
int
usb_detach(device_t self)
{
@ -432,7 +492,10 @@ usb_detach(device_t self)
return (EINVAL);
}
DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
#endif
#if defined(__FreeBSD__)
DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb.h,v 1.17 1999/01/03 01:09:18 augustss Exp $ */
/* $NetBSD: usb.h,v 1.33 1999/09/11 08:19:27 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -43,21 +43,21 @@
#define _USB_H_
#include <sys/types.h>
#if defined(__NetBSD__)
#include <sys/ioctl.h>
#endif
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/ioctl.h>
#if defined(_KERNEL)
#include <dev/usb/usb_port.h>
#endif /* _KERNEL */
#elif defined(__FreeBSD__)
#if defined(KERNEL)
#include <sys/malloc.h>
#if defined(KERNEL)
MALLOC_DECLARE(M_USB);
MALLOC_DECLARE(M_USBDEV);
MALLOC_DECLARE(M_USBHC);
#include <dev/usb/usb_port.h>
#endif /* KERNEL */
@ -125,15 +125,19 @@ typedef struct {
#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE)
#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE)
#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER)
#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT)
#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE)
#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE)
#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER)
#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT)
#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE)
#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE)
#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER)
#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT)
#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE)
#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE)
#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER)
#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT)
/* Requests */
#define UR_GET_STATUS 0x00
@ -141,12 +145,12 @@ typedef struct {
#define UR_SET_FEATURE 0x03
#define UR_SET_ADDRESS 0x05
#define UR_GET_DESCRIPTOR 0x06
#define UDESC_DEVICE 0x01 /* descriptor types */
#define UDESC_DEVICE 0x01
#define UDESC_CONFIG 0x02
#define UDESC_STRING 0x03
#define UDESC_INTERFACE 0x04
#define UDESC_ENDPOINT 0x05
#define UDESC_CS_DEVICE 0x21 /* class specific */
#define UDESC_CS_DEVICE 0x21 /* class specific */
#define UDESC_CS_CONFIG 0x22
#define UDESC_CS_STRING 0x23
#define UDESC_CS_INTERFACE 0x24
@ -223,19 +227,19 @@ typedef struct {
uByte bLength;
uByte bDescriptorType;
uByte bEndpointAddress;
#define UE_DIR 0x80 /* mask */
#define UE_IN 0x80
#define UE_OUT 0x00
#define UE_GET_DIR(a) ((a) & 0x80)
#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7))
#define UE_DIR_IN 0x80
#define UE_DIR_OUT 0x00
#define UE_ADDR 0x0f
#define UE_GET_ADDR(a) ((a) & UE_ADDR)
#define UE_GET_IN(a) (((a) >> 7) & 1) /* XXX should be removed */
#define UE_GET_DIR(a) ((a) & UE_DIR)
uByte bmAttributes;
#define UE_XFERTYPE 0x03
#define UE_CONTROL 0x00
#define UE_ISOCHRONOUS 0x01
#define UE_BULK 0x02
#define UE_INTERRUPT 0x03
#define UE_GET_XFERTYPE(a) ((a) & UE_XFERTYPE)
#define UE_ISO_TYPE 0x0c
#define UE_ISO_ASYNC 0x04
#define UE_ISO_ADAPT 0x08
@ -329,59 +333,55 @@ typedef struct {
#define UPS_C_PORT_RESET 0x0010
} usb_port_status_t;
#define UCLASS_UNSPEC 0 /* Unspecified */
#define UCLASS_AUDIO 1 /* Audio */
#define UCLASS_UNSPEC 0
#define UCLASS_AUDIO 1
#define USUBCLASS_AUDIOCONTROL 1
#define USUBCLASS_AUDIOSTREAM 2
#define UCLASS_CDC 2 /* Communication */
#define USUBCLASS_MIDISTREAM 3
#define UCLASS_CDC 2 /* communication */
#define USUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
#define USUBCLASS_ABSTRACT_CONTROL_MODEL 2
#define USUBCLASS_TELEPHONE_CONTROL_MODEL 3
#define USUBCLASS_MULTICHANNEL_CONTROL_MODEL /*TBD*/
#define USUBCLASS_CAPI_CONTROL_MODEL /*TBD*/
#define USUBCLASS_ETHERNET_CONTROL_MODEL /*TBD*/
#define USUBCLASS_ATM_CONTROL_MODEL /*TBD*/
#define UPROTO_CDC_NONE 0 /* No class spec. protocol required */
#define UPROTO_CDC_AT 1 /* V25.ter (AT commands) */
#define UCLASS_HID 3 /* Human Interface Device */
#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
#define UCLASS_PRINTER 7 /* Printer/Parallel Port */
#define UCLASS_PRINTER 7
#define USUBCLASS_PRINTER 1
#define UPROTO_PRINTER_UNI 1 /* Unidirectional */
#define UPROTO_PRINTER_BI 2 /* Bidirectional */
#define UCLASS_MASS 8 /* Mass Storage */
#define USUBCLASS_RBC 1 /* Reduced Block comm. (e.g. Flash ) */
#define USUBCLASS_SFF8020I 2 /* (e.g. CD ROM) */
#define USUBCLASS_QIC157 3 /* (e.g. tape drives) */
#define USUBCLASS_UFI 4 /* (e.g. floppy drives) */
#define USUBCLASS_SFF8070I 5 /* (e.g. floppy drives) */
#define USUBCLASS_SCSI 6 /* SCSI transparent comman set */
#define UPROTO_MASS_CBI_I 0 /* CBI protocol with comm. compl. int */
#define UPROTO_MASS_CBI 1 /* CBI protocol */
/*
* XXX Pat LaVarre (Iomega): there are Bulk-Only devices using 0x02,
* but recent versions of the Mass Storage spec. require it to be 0x50.
*/
#define UPROTO_MASS_BULK 80 /* 'P' for prototype, used by ZIP 100 */
#define UPROTO_MASS_BULK2 2 /* Bulk only transport */
#define UCLASS_HUB 9 /* Hub */
#define UPROTO_PRINTER_UNI 1
#define UPROTO_PRINTER_BI 2
#define UCLASS_MASS 8
#define USUBCLASS_RBC 1
#define USUBCLASS_SFF8020I 2
#define USUBCLASS_QIC157 3
#define USUBCLASS_UFI 4
#define USUBCLASS_SFF8070I 5
#define USUBCLASS_SCSI 6
#define UPROTO_MASS_CBI_I 0
#define UPROTO_MASS_CBI 1
#define UPROTO_MASS_BULK 2
#define UPROTO_MASS_BULK_P 80 /* 'P' for the Iomega Zip drive */
#define UCLASS_HUB 9
#define USUBCLASS_HUB 0
#define UCLASS_DATA 10 /* Data pipe for CDC */
#define UCLASS_DATA 10
#define USUBCLASS_DATA 0
#define UPROTO_DATA_NONE 0
#define UPROTO_DATA_ISDNBRI 0x30 /* Physical iface ISDN BRI */
#define UPROTO_DATA_HDLC 0x31 /* HDLC */
#define UPROTO_DATA_TRANSPARENT 0x32 /* Transparent */
#define UPROTO_DATA_Q921M 0x50 /* Management for Q921 */
#define UPROTO_DATA_Q921 0x51 /* Data for Q921 */
#define UPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */
#define UPROTO_DATA_V42BIS 0x90 /* Data compression */
#define UPROTO_DATA_Q931 0x91 /* Euro-ISDN */
#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_VENDOR 0xff /* Vendor specific */
#define UPROTO_DATA_ISDNBRI 0x30 /* Physical iface */
#define UPROTO_DATA_HDLC 0x31 /* HDLC */
#define UPROTO_DATA_TRANSPARENT 0x32 /* Transparent */
#define UPROTO_DATA_Q921M 0x50 /* Management for Q921 */
#define UPROTO_DATA_Q921 0x51 /* Data for Q921 */
#define UPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */
#define UPROTO_DATA_V42BIS 0x90 /* Data compression */
#define UPROTO_DATA_Q931 0x91 /* Euro-ISDN */
#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_VENDOR 0xff /* Vendor specific */
#define USB_HUB_MAX_DEPTH 5
@ -398,20 +398,24 @@ typedef struct {
#define USB_PORT_RESET_SETTLE 10 /* ms */
#define USB_PORT_POWERUP_DELAY 100 /* ms */
#define USB_SET_ADDRESS_SETTLE 2 /* ms */
#define USB_RESUME_TIME (20*5) /* ms */
#define USB_RESUME_WAIT 10 /* ms */
#define USB_RESUME_RECOVERY 10 /* ms */
#else
/* Allow for marginal (i.e. non-conforming) devices. */
#define USB_PORT_RESET_DELAY 50 /* ms */
#define USB_PORT_RESET_RECOVERY 50 /* ms */
#define USB_PORT_POWERUP_DELAY 200 /* ms */
#define USB_SET_ADDRESS_SETTLE 10 /* ms */
#define USB_RESUME_DELAY (50*5) /* ms */
#define USB_RESUME_WAIT 50 /* ms */
#define USB_RESUME_RECOVERY 50 /* ms */
#endif
#define USB_MIN_POWER 100 /* mA */
#define USB_MAX_POWER 500 /* mA */
#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/
#define USB_RESUME_DELAY 10 /* ms XXX?*/
/*** ioctl() related stuff ***/
@ -420,8 +424,7 @@ struct usb_ctl_request {
usb_device_request_t request;
void *data;
int flags;
/* XXX must match flags in usbdi.h */
#define USBD_SHORT_XFER_OK 0x04
#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */
int actlen; /* actual length transferred */
};
@ -475,7 +478,7 @@ struct usb_device_info {
u_int8_t addr; /* device address */
char product[USB_MAX_STRING_LEN];
char vendor[USB_MAX_STRING_LEN];
char revision[8];
char release[8];
u_int16_t productNo;
u_int16_t vendorNo;
u_int8_t class;
@ -526,5 +529,10 @@ struct usb_device_stats {
#define USB_DO_REQUEST _IOWR('U', 111, struct usb_ctl_request)
#define USB_GET_DEVICEINFO _IOR ('U', 112, struct usb_device_info)
#define USB_SET_SHORT_XFER _IOW ('U', 113, int)
#define USB_SET_TIMEOUT _IOW ('U', 114, int)
/* Modem device */
#define USB_GET_CM_OVER_DATA _IOR ('U', 130, int)
#define USB_SET_CM_OVER_DATA _IOW ('U', 131, int)
#endif /* _USB_H_ */

View File

@ -1,5 +1,5 @@
/* $NetBSD: usb_mem.h,v 1.4 1999/01/09 12:16:54 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: usb_mem.h,v 1.7 1999/09/09 12:26:47 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -38,8 +38,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(__NetBSD__)
typedef struct usb_block_dma {
#if defined(__NetBSD__) || defined(__OpenBSD__)
typedef struct usb_dma_block {
bus_dma_tag_t tag;
bus_dmamap_t map;
caddr_t kaddr;
@ -48,14 +48,9 @@ typedef struct usb_block_dma {
size_t size;
size_t align;
int fullblock;
LIST_ENTRY(usb_block_dma) next;
LIST_ENTRY(usb_dma_block) next;
} usb_dma_block_t;
typedef struct {
usb_dma_block_t *block;
u_int offs;
} usb_dma_t;
#define DMAADDR(dma) ((dma)->block->segs[0].ds_addr + (dma)->offs)
#define KERNADDR(dma) ((void *)((dma)->block->kaddr + (dma)->offs))
@ -81,8 +76,6 @@ void usb_freemem __P((bus_dma_tag_t, usb_dma_t *));
#include <machine/pmap.h> /* for vtophys */
typedef void * usb_dma_t;
#define usb_allocmem(t,s,a,p) (*(p) = malloc(s, M_USB, M_NOWAIT), (*(p) == NULL? USBD_NOMEM: USBD_NORMAL_COMPLETION))
#define usb_freemem(t,p) (free(*(p), M_USB))

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_port.h,v 1.5 1999/01/08 11:58:25 augustss Exp $ */
/* $NetBSD: usb_port.h,v 1.11 1999/09/11 08:19:27 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -39,34 +39,49 @@
*/
/*
/*
* Macro's to cope with the differences between operating systems.
*/
#if defined(__NetBSD__)
/*
* NetBSD
*/
#if defined(__NetBSD__)
#include "opt_usbverbose.h"
typedef struct device *device_ptr_t;
#define USBBASEDEVICE struct device
#define USBDEV(bdev) (&(bdev))
#define USBDEVNAME(bdev) ((bdev).dv_xname)
#define USBDEVPTRNAME(bdevptr) ((bdevptr)->dv_xname)
typedef struct device bdevice; /* base device */
#define DECLARE_USB_DMA_T \
struct usb_dma_block; \
typedef struct { \
struct usb_dma_block *block; \
u_int offs; \
} usb_dma_t
#define usb_timeout(f, d, t, h) timeout((f), (d), (t))
#define usb_untimeout(f, d, h) untimeout((f), (d))
#define USB_DECLARE_DRIVER_INIT(dname, _2) \
#define logprintf printf
#define USB_DECLARE_DRIVER_NAME_INIT(_1, dname, _2) \
int __CONCAT(dname,_match) __P((struct device *, struct cfdata *, void *)); \
void __CONCAT(dname,_attach) __P((struct device *, struct device *, void *)); \
int __CONCAT(dname,_detach) __P((struct device *, int)); \
int __CONCAT(dname,_activate) __P((struct device *, enum devact)); \
\
extern struct cfdriver __CONCAT(dname,_cd); \
\
struct cfattach __CONCAT(dname,_ca) = { \
sizeof(struct __CONCAT(dname,_softc)), \
__CONCAT(dname,_match), \
__CONCAT(dname,_attach) \
__CONCAT(dname,_attach), \
__CONCAT(dname,_detach), \
__CONCAT(dname,_activate), \
}
#define USB_MATCH(dname) \
@ -97,6 +112,16 @@ __CONCAT(dname,_attach)(parent, self, aux) \
#define USB_ATTACH_SETUP printf("\n")
#define USB_DETACH(dname) \
int \
__CONCAT(dname,_detach)(self, flags) \
struct device *self; \
int flags;
#define USB_DETACH_START(dname, sc) \
struct __CONCAT(dname,_softc) *sc = \
(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) \
@ -109,11 +134,107 @@ __CONCAT(dname,_attach)(parent, self, aux) \
struct __CONCAT(dname,_softc) *sc = __CONCAT(dname,_cd).cd_devs[unit]
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
((dev)->softc = config_found_sm(parent, args, print, sub))
(config_found_sm(parent, args, print, sub))
#define logprintf printf
#elif defined(__OpenBSD__)
/*
* OpenBSD
*/
#define memcpy(d, s, l) bcopy((s),(d),(l))
#define memset(d, v, l) bzero((d),(l))
#define bswap32(x) swap32(x)
#define kthread_create1 kthread_create
#define kthread_create kthread_create_deferred
#define usbpoll usbselect
#define uhidpoll uhidselect
#define ugenpoll ugenselect
typedef struct device device_ptr_t;
#define USBBASEDEVICE struct device
#define USBDEV(bdev) (&(bdev))
#define USBDEVNAME(bdev) ((bdev).dv_xname)
#define USBDEVPTRNAME(bdevptr) ((bdevptr)->dv_xname)
#define DECLARE_USB_DMA_T \
struct usb_dma_block; \
typedef struct { \
struct usb_dma_block *block; \
u_int offs; \
} usb_dma_t
#define usb_timeout(f, d, t, h) timeout((f), (d), (t))
#define usb_untimeout(f, d, h) untimeout((f), (d))
#define USB_DECLARE_DRIVER_NAME_INIT(_1, dname, _2) \
int __CONCAT(dname,_match) __P((struct device *, void *, void *)); \
void __CONCAT(dname,_attach) __P((struct device *, struct device *, void *)); \
int __CONCAT(dname,_detach) __P((struct device *, int)); \
int __CONCAT(dname,_activate) __P((struct device *, enum devact)); \
\
struct cfdriver __CONCAT(dname,_cd) = { \
NULL, #dname, DV_DULL \
}; \
\
struct cfattach __CONCAT(dname,_ca) = { \
sizeof(struct __CONCAT(dname,_softc)), \
__CONCAT(dname,_match), \
__CONCAT(dname,_attach), \
__CONCAT(dname,_detach), \
__CONCAT(dname,_activate), \
}
#define USB_MATCH(dname) \
int \
__CONCAT(dname,_match)(parent, match, aux) \
struct device *parent; \
void *match; \
void *aux;
#define USB_MATCH_START(dname, uaa) \
struct usb_attach_arg *uaa = aux
#define USB_ATTACH(dname) \
void \
__CONCAT(dname,_attach)(parent, self, aux) \
struct device *parent; \
struct device *self; \
void *aux;
#define USB_ATTACH_START(dname, sc, uaa) \
struct __CONCAT(dname,_softc) *sc = \
(struct __CONCAT(dname,_softc) *)self; \
struct usb_attach_arg *uaa = aux
/* Returns from attach */
#define USB_ATTACH_ERROR_RETURN return
#define USB_ATTACH_SUCCESS_RETURN return
#define USB_ATTACH_SETUP printf("\n")
#define USB_DETACH(dname) \
int \
__CONCAT(dname,_detach)(self, flags) \
struct device *self; \
int flags;
#define USB_DETACH_START(dname, sc) \
struct __CONCAT(dname,_softc) *sc = \
(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]; \
if (!sc) \
return (ENXIO)
#define USB_GET_SC(dname, unit, sc) \
struct __CONCAT(dname,_softc) *sc = __CONCAT(dname,_cd).cd_devs[unit]
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(config_found_sm(parent, args, print, sub))
#elif defined(__FreeBSD__)
/*
@ -121,28 +242,30 @@ __CONCAT(dname,_attach)(parent, self, aux) \
*/
#include "opt_usb.h"
/*
* The following is not a type def to avoid error messages
* because of includes in the wrong order.
*/
#define bdevice device_t
#define USBDEVNAME(bdev) (bdev? device_get_nameunit(bdev):"-")
#define USBVERBOSE
#define device_ptr_t device_t
#define USBBASEDEVICE device_t
#define USBDEV(bdev) (bdev)
#define USBDEVNAME(bdev) device_get_nameunit(bdev)
#define USBDEVPTRNAME(bdev) device_get_nameunit(bdev)
#define DECLARE_USB_DMA_T typedef void * usb_dma_t
/* XXX Change this when FreeBSD has memset
*/
#define memset(d, v, s) \
do{ \
if ((v) == 0) \
bzero((d), (s));\
else \
panic("Non zero filler for memset, cannot handle!"); \
} while (0)
#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 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 USB_DECLARE_DRIVER_NAME_INIT(name, dname, init...) \
static device_probe_t __CONCAT(dname,_match); \
static device_attach_t __CONCAT(dname,_attach); \
static device_detach_t __CONCAT(dname,_detach); \
@ -158,7 +281,7 @@ static device_method_t __CONCAT(dname,_methods)[] = { \
}; \
\
static driver_t __CONCAT(dname,_driver) = { \
#dname, \
name, \
__CONCAT(dname,_methods), \
sizeof(struct __CONCAT(dname,_softc)) \
}
@ -186,6 +309,13 @@ __CONCAT(dname,_attach)(device_t self)
sc->sc_dev = self; \
device_set_desc_copy(self, devinfo)
#define USB_DETACH(dname) \
static int \
__CONCAT(dname,_detach)(device_t self)
#define USB_DETACH_START(dname, sc) \
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); \
@ -196,26 +326,43 @@ __CONCAT(dname,_attach)(device_t self)
struct __CONCAT(dname,_softc) *sc = \
devclass_get_softc(__CONCAT(dname,_devclass), unit)
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(device_probe_and_attach((bdev)) == 0 ? \
((dev)->softc = device_get_softc(bdev)) : 0)
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(device_probe_and_attach((bdev)) == 0 ? (bdev) : 0)
/* conversion from one type of queue to the other */
#define SIMPLEQ_REMOVE_HEAD STAILQ_REMOVE_HEAD
/* XXX In FreeBSD SIMPLEQ_REMOVE_HEAD only removes the head element.
*/
#define SIMPLEQ_REMOVE_HEAD(h, e, f) do { \
if ( (e) != SIMPLEQ_FIRST((h)) ) \
panic("Removing other than first element"); \
STAILQ_REMOVE_HEAD(h, f); \
} while (0)
#define SIMPLEQ_INSERT_HEAD STAILQ_INSERT_HEAD
#define SIMPLEQ_INSERT_TAIL STAILQ_INSERT_TAIL
#define SIMPLEQ_NEXT STAILQ_NEXT
#define SIMPLEQ_FIRST STAILQ_FIRST
#define SIMPLEQ_HEAD STAILQ_HEAD
#define SIMPLEQ_INIT STAILQ_INIT
#define SIMPLEQ_HEAD_INITIALIZER STAILQ_HEAD_INITIALIZER
#define SIMPLEQ_ENTRY STAILQ_ENTRY
#include <sys/syslog.h>
#define logprintf(args...) log(LOG_DEBUG, args);
/*
#define logprintf(args...) log(LOG_DEBUG, args)
*/
#define logprintf printf
#endif /* __FreeBSD__ */
#define NONE {0,0}
#define USB_DECLARE_DRIVER_NAME(name, dname) \
USB_DECLARE_DRIVER_NAME_INIT(#name, dname, NONE )
#define USB_DECLARE_DRIVER_INIT(dname, init...) \
USB_DECLARE_DRIVER_NAME_INIT(#dname, dname, init)
#define USB_DECLARE_DRIVER(dname) \
USB_DECLARE_DRIVER_INIT(dname, {0,0} )
USB_DECLARE_DRIVER_NAME_INIT(#dname, dname, NONE )
#if defined(__NetBSD__) || defined(__OpenBSD__)
#elif defined(__FreeBSD__)
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb_quirks.c,v 1.8 1999/01/08 11:58:25 augustss Exp $ */
/* $NetBSD: usb_quirks.c,v 1.12 1999/09/05 21:22:39 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -43,7 +43,7 @@
#if defined(__FreeBSD__)
#include <sys/bus.h>
#endif
#include <dev/usb/usb.h>
#include <dev/usb/usbdevs.h>
@ -62,11 +62,11 @@ struct usbd_quirk_entry {
{ USB_VENDOR_GENIUS, USB_PRODUCT_GENIUS_NICHE, 0x100, { UQ_NO_SET_PROTO}},
{ USB_VENDOR_INSIDEOUT,USB_PRODUCT_INSIDEOUT_EDGEPORT4,
0x094, { UQ_SWAP_UNICODE}},
{ USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41, 0x100, { UQ_HUB_POWER }},
{ USB_VENDOR_BTC, USB_PRODUCT_BTC_BTC7932, 0x100, { UQ_NO_STRINGS }},
{ USB_VENDOR_ADS, USB_PRODUCT_ADS_ENET, 0x002, { UQ_NO_STRINGS }},
{ USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, 0x101, { UQ_NO_STRINGS }},
{ USB_VENDOR_JAZZ, USB_PRODUCT_JAZZ_J6502, 0x0a2, { UQ_BAD_ADC }},
{ USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_USBPS2,0x110, { UQ_MS_REVZ }},
{ 0, 0, 0, { 0 } }
};
@ -86,9 +86,9 @@ usbd_find_quirk(d)
}
#ifdef USB_DEBUG
if (usbdebug && t->quirks.uq_flags)
printf("usbd_find_quirk 0x%04x/0x%04x/%x: %d\n",
UGETW(d->idVendor), UGETW(d->idProduct),
UGETW(d->bcdDevice), t->quirks.uq_flags);
logprintf("usbd_find_quirk 0x%04x/0x%04x/%x: %d\n",
UGETW(d->idVendor), UGETW(d->idProduct),
UGETW(d->bcdDevice), t->quirks.uq_flags);
#endif
return (&t->quirks);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: usb_quirks.h,v 1.5 1998/12/29 15:23:59 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: usb_quirks.h,v 1.7 1999/06/26 00:09:15 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -42,8 +42,7 @@ struct usbd_quirks {
u_int32_t uq_flags; /* Device problems: */
#define UQ_NO_SET_PROTO 0x01 /* cannot handle SET PROTOCOL. */
#define UQ_SWAP_UNICODE 0x02 /* has some Unicode strings swapped. */
#define UQ_HUB_POWER 0x04 /* does not respond correctly to get
device status; use get hub status. */
#define UQ_MS_REVZ 0x04 /* mouse has Z-axis reversed */
#define UQ_NO_STRINGS 0x08 /* string descriptors are broken. */
#define UQ_BAD_ADC 0x10 /* bad audio spec version number. */
};

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbcdc.h,v 1.3 1999/01/03 01:09:18 augustss Exp $ */
/* $NetBSD: usbcdc.h,v 1.4 1999/08/16 20:20:19 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -41,24 +41,16 @@
#ifndef _USBCDC_H_
#define _USBCDC_H_
#define UDESCSUB_CDC_HEADER 0x00 /* Header */
#define UDESCSUB_CDC_CM 0x01 /* Call Management */
#define UDESCSUB_CDC_ACM 0x02 /* Abstract Control Model */
#define UDESCSUB_CDC_DLM 0x03 /* Direct Line Management */
#define UDESCSUB_CDC_TRF 0x04 /* Telephone Ringer */
#define UDESCSUB_CDC_TCLSR 0x05 /* Tel. Call and Line State Rep. Cap. */
#define UDESCSUB_CDC_UNION 0x06 /* Union */
#define UDESCSUB_CDC_CS 0x07 /* Country Selection */
#define UDESCSUB_CDC_TOM 0x08 /* Telephone Operational Modes */
#define UDESCSUB_CDC_USBT 0x09 /* USB Terminal */
#define UDESCSUB_CDC_NCT 0x0a /* Network Channel Terminal */
#define UDESCSUB_CDC_PU 0x0b /* Protocol Unit */
#define UDESCSUB_CDC_EU 0x0c /* Extention Unit */
#define UDESCSUB_CDC_MCM 0x0d /* Multi-Channel Management */
#define UDESCSUB_CDC_CCM 0x0e /* CAPI Control Management */
#define UDESCSUB_CDC_EN 0x0f /* Ethernet Networking */
#define UDESCSUB_CDC_AN 0x10 /* ATM Networking */
#define UDESCSUB_CDC_HEADER 0
#define UDESCSUB_CDC_CM 1 /* Call Management */
#define UDESCSUB_CDC_ACM 2 /* Abstract Control Model */
#define UDESCSUB_CDC_DLM 3 /* Direct Line Management */
#define UDESCSUB_CDC_TRF 4 /* Telephone Ringer */
#define UDESCSUB_CDC_TCLSR 5 /* Telephone Call ... */
#define UDESCSUB_CDC_UNION 6
#define UDESCSUB_CDC_CS 7 /* Country Selection */
#define UDESCSUB_CDC_TOM 8 /* Telephone Operational Modes */
#define UDESCSUB_CDC_USBT 9 /* USB Terminal */
typedef struct {
uByte bLength;
@ -100,17 +92,24 @@ typedef struct {
#define UCDC_GET_ENCAPSULATED_RESPONSE 0x01
#define UCDC_SET_COMM_FEATURE 0x02
#define UCDC_GET_COMM_FEATURE 0x03
#define UCDC_CLEAR_COMM_FEATURE 0x04
#define UCDC_ABSTRACT_STATE 0x01
#define UCDC_COUNTRY_SETTING 0x02
#define UCDC_CLEAR_COMM_FEATURE 0x04
#define UCDC_SET_LINE_CODING 0x20
#define UCDC_GET_LINE_CODING 0x21
#define UCDC_SET_CONTROL_LINE_STATE 0x22
#define UCDC_LINE_DTR 0x0001
#define UCDC_LINE_RTS 0x0002
#define UCDC_SEND_BREAK 0x23
#define UCDC_BREAK_ON 0xffff
#define UCDC_BREAK_OFF 0x0000
typedef struct {
uWord wState;
#define UCDC_IDLE_SETTING 0x0001
#define UCDC_DATA_MULTIPLEXED 0x0002
} usb_cdc_abstract_state_t;
#define UCDC_ABSTRACT_STATE_LENGTH 2
typedef struct {
uDWord dwDTERate;
@ -126,6 +125,7 @@ typedef struct {
#define UCDC_PARITY_SPACE 4
uByte bDataBits;
} usb_cdc_line_state_t;
#define UCDC_LINE_STATE_LENGTH 7
typedef struct {
uByte bmRequestType;

View File

@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
* NetBSD: usbdevs,v 1.19 1999/01/08 11:18:38 augustss Exp
* NetBSD: usbdevs,v 1.35 1999/06/28 04:09:53 augustss Exp
*/
/*
@ -73,6 +73,7 @@
#define USB_VENDOR_SHUTTLE 0x04e6 /* Shuttle Technology */
#define USB_VENDOR_BROTHER 0x04f9 /* Brother Industries Corp. */
#define USB_VENDOR_JAZZ 0x04fa /* Dallas Semiconductor */
#define USB_VENDOR_KAWATSU 0x050f /* Kawatsu Semiconductor, Inc. */
#define USB_VENDOR_AKS 0x0529 /* Fast Security AG */
#define USB_VENDOR_VISION 0x0533 /* Alcatel Mobile Phones */
#define USB_VENDOR_ATEN 0x0557 /* ATEN International Corp. Ltd. */
@ -86,10 +87,13 @@
#define USB_VENDOR_BELKIN 0x05ab /* In-System Design */
#define USB_VENDOR_APPLE 0x05ac /* Apple Computer */
#define USB_VENDOR_EIZONANAO 0x05e7 /* EIZO Nanao */
#define USB_VENDOR_PIENGINEERING 0x05f3 /* P.I. Engineering */
#define USB_VENDOR_CHIC 0x05fe /* Chic Technology */
#define USB_VENDOR_MACALLY 0x0618 /* Macally */
#define USB_VENDOR_MULTITECH 0x06e0 /* MultiTech */
#define USB_VENDOR_ADS 0x06e1 /* ADS Technologies */
#define USB_VENDOR_SIIG 0x07cc /* SIIG */
#define USB_VENDOR_ACTIVEWIRE 0x0854 /* ActiveWire Inc. */
#define USB_VENDOR_PLX 0x10b5 /* PLX */
#define USB_VENDOR_INSIDEOUT 0x1608 /* Inside Out Networks */
#define USB_VENDOR_ENTREGA 0x1645 /* Entrega */
@ -99,9 +103,6 @@
* List of known products. Grouped by vendor.
*/
/* Thrustmaster products */
#define USB_PRODUCT_THRUST_FUSION_PAD 0xa0a3 /* Fusion Digital Gamepad */
/* NEC products */
#define USB_PRODUCT_NEC_HUB 0x55aa /* hub */
#define USB_PRODUCT_NEC_HUB_B 0x55ab /* hub */
@ -115,7 +116,10 @@
/* Gravis products */
#define USB_PRODUCT_GRAVIS_GAMEPADPRO 0x4001 /* GamePad Pro */
/* Unixtar/Texas Instruments products */
/* Thrustmaster products */
#define USB_PRODUCT_THRUST_FUSION_PAD 0xa0a3 /* Fusion Digital Gamepad */
/* Texas Intel products */
#define USB_PRODUCT_TI_UTUSB41 0x1446 /* UT-USB41 hub */
/* Genius products */
@ -145,16 +149,16 @@
/* Connectix products */
#define USB_PRODUCT_CONNECTIX_QUICKCAM 0x0001 /* QuickCam */
/* STMicroelectronics products */
#define USB_PRODUCT_STMICRO_COMMUNICATOR 0x7554 /* USB Communicator */
/* Lucent products */
#define USB_PRODUCT_LUCENT_EVALKIT 0x1001 /* USS-720 evaluation kit */
/* STMicroelectronics products */
#define USB_PRODUCT_STMICRO_COMMUNICATOR 0x7554 /* USB Communicator */
/* Acer products */
#define USB_PRODUCT_ACER_ACERSCAN_C310U 0x12a6 /* Acerscan C310U */
/* Cypress Semiconduuctor products */
/* Cypress Semiconductor products */
#define USB_PRODUCT_CYPRESS_MOUSE 0x0001 /* mouse */
/* Epson products */
@ -175,6 +179,9 @@
/* Jazz products */
#define USB_PRODUCT_JAZZ_J6502 0x4201 /* J-6502 speakers */
/* Kawatsu products */
#define USB_PRODUCT_KAWATSU_MH4000P 0x0003 /* MiniHub 4000P */
/* AKS products */
#define USB_PRODUCT_AKS_USBHASP 0x0001 /* USB-HASP 0.06 */
@ -208,25 +215,43 @@
/* Belkin products */
#define USB_PRODUCT_BELKIN_F5U002 0x0002 /* Parallel printer adapter */
#define USB_PRODUCT_BELKIN_1COM 0x8007 /* Serial port */
/* Logitech products */
#define USB_PRODUCT_LOGITECH_M2452 0x0203 /* M2452 keyboard */
#define USB_PRODUCT_LOGITECH_M4848 0x0301 /* M4848 mouse */
#define USB_PRODUCT_LOGITECH_QUICKCAM 0x0801 /* QuickCam */
#define USB_PRODUCT_LOGITECH_USBPS2 0xc001 /* USB-PS/2 mouse */
/* P.I. Engineering products */
#define USB_PRODUCT_PIENGINEERING_PS2USB 0x020b /* PS2 to Mac USB Adapter */
/* Chic Technology products */
#define USB_PRODUCT_CHIC_MOUSE1 0x0001 /* mouse */
/* Macally products */
#define USB_PRODUCT_MACALLY_MOUSE1 0x0101 /* mouse */
/* MultiTech Products */
/* MultiTech products */
#define USB_PRODUCT_MULTITECH_ATLAS 0xf101 /* MT5634ZBA-USB modem */
/* ADS products */
#define USB_PRODUCT_ADS_ENET 0x0008 /* Ethernet adapter */
/* SIIG products */
#define USB_PRODUCT_SIIG_DIGIFILMREADER 0x0004 /* DigiFilm-Combo Reader */
/* ActiveWire Inc. products */
#define USB_PRODUCT_ACTIVEWIRE_IOBOARD 0x0100 /* I/O Board */
#define USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW 0x0101 /* I/O Board, rev. 1 firmware */
/* Entrega products */
#define USB_PRODUCT_ENTREGA_1S 0x0001 /* 1S serial connector */
#define USB_PRODUCT_ENTREGA_2S 0x0002 /* 2S serial connector */
#define USB_PRODUCT_ENTREGA_1S25 0x0003 /* 1S25 serial connector */
#define USB_PRODUCT_ENTREGA_4S 0x0004 /* 4S serial connector */
#define USB_PRODUCT_ENTREGA_CENTRONICS 0x0006 /* Centronics connector */
#define USB_PRODUCT_ENTREGA_1S9 0x0093 /* 1S9 serial connector */
#define USB_PRODUCT_ENTREGA_SERIAL 0x8001 /* DB25 Serial connector */
/* PLX products */

View File

@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
* NetBSD: usbdevs,v 1.19 1999/01/08 11:18:38 augustss Exp
* NetBSD: usbdevs,v 1.35 1999/06/28 04:09:53 augustss Exp
*/
/*
@ -45,12 +45,6 @@
*/
struct usb_knowndev usb_knowndevs[] = {
{
USB_VENDOR_THRUST, USB_PRODUCT_THRUST_FUSION_PAD,
0,
"Thrustmaster",
"Fusion Digital Gamepad",
},
{
USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB,
0,
@ -81,6 +75,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Advanced Gravis Computer Tech. Ltd.",
"GamePad Pro",
},
{
USB_VENDOR_THRUST, USB_PRODUCT_THRUST_FUSION_PAD,
0,
"Thrustmaster",
"Fusion Digital Gamepad",
},
{
USB_VENDOR_TI, USB_PRODUCT_TI_UTUSB41,
0,
@ -165,18 +165,18 @@ struct usb_knowndev usb_knowndevs[] = {
"Connectix Corp.",
"QuickCam",
},
{
USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_COMMUNICATOR,
0,
"STMicroelectronics",
"USB Communicator",
},
{
USB_VENDOR_LUCENT, USB_PRODUCT_LUCENT_EVALKIT,
0,
"Lucent",
"USS-720 evaluation kit",
},
{
USB_VENDOR_STMICRO, USB_PRODUCT_STMICRO_COMMUNICATOR,
0,
"STMicroelectronics",
"USB Communicator",
},
{
USB_VENDOR_ACER, USB_PRODUCT_ACER_ACERSCAN_C310U,
0,
@ -225,6 +225,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Dallas Semiconductor",
"J-6502 speakers",
},
{
USB_VENDOR_KAWATSU, USB_PRODUCT_KAWATSU_MH4000P,
0,
"Kawatsu Semiconductor, Inc.",
"MiniHub 4000P",
},
{
USB_VENDOR_AKS, USB_PRODUCT_AKS_USBHASP,
0,
@ -297,6 +303,12 @@ struct usb_knowndev usb_knowndevs[] = {
"In-System Design",
"Parallel printer adapter",
},
{
USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_1COM,
0,
"In-System Design",
"Serial port",
},
{
USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M2452,
0,
@ -309,12 +321,24 @@ struct usb_knowndev usb_knowndevs[] = {
"Logitech Inc.",
"M4848 mouse",
},
{
USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAM,
0,
"Logitech Inc.",
"QuickCam",
},
{
USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_USBPS2,
0,
"Logitech Inc.",
"USB-PS/2 mouse",
},
{
USB_VENDOR_PIENGINEERING, USB_PRODUCT_PIENGINEERING_PS2USB,
0,
"P.I. Engineering",
"PS2 to Mac USB Adapter",
},
{
USB_VENDOR_CHIC, USB_PRODUCT_CHIC_MOUSE1,
0,
@ -339,12 +363,60 @@ struct usb_knowndev usb_knowndevs[] = {
"ADS Technologies",
"Ethernet adapter",
},
{
USB_VENDOR_SIIG, USB_PRODUCT_SIIG_DIGIFILMREADER,
0,
"SIIG",
"DigiFilm-Combo Reader",
},
{
USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD,
0,
"ActiveWire Inc.",
"I/O Board",
},
{
USB_VENDOR_ACTIVEWIRE, USB_PRODUCT_ACTIVEWIRE_IOBOARD_FW,
0,
"ActiveWire Inc.",
"I/O Board, rev. 1 firmware",
},
{
USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S,
0,
"Entrega",
"1S serial connector",
},
{
USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_2S,
0,
"Entrega",
"2S serial connector",
},
{
USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S25,
0,
"Entrega",
"1S25 serial connector",
},
{
USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_4S,
0,
"Entrega",
"4S serial connector",
},
{
USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_CENTRONICS,
0,
"Entrega",
"Centronics connector",
},
{
USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_1S9,
0,
"Entrega",
"1S9 serial connector",
},
{
USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_SERIAL,
0,
@ -519,6 +591,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Dallas Semiconductor",
NULL,
},
{
USB_VENDOR_KAWATSU, 0,
USB_KNOWNDEV_NOPROD,
"Kawatsu Semiconductor, Inc.",
NULL,
},
{
USB_VENDOR_AKS, 0,
USB_KNOWNDEV_NOPROD,
@ -597,6 +675,12 @@ struct usb_knowndev usb_knowndevs[] = {
"EIZO Nanao",
NULL,
},
{
USB_VENDOR_PIENGINEERING, 0,
USB_KNOWNDEV_NOPROD,
"P.I. Engineering",
NULL,
},
{
USB_VENDOR_CHIC, 0,
USB_KNOWNDEV_NOPROD,
@ -621,6 +705,18 @@ struct usb_knowndev usb_knowndevs[] = {
"ADS Technologies",
NULL,
},
{
USB_VENDOR_SIIG, 0,
USB_KNOWNDEV_NOPROD,
"SIIG",
NULL,
},
{
USB_VENDOR_ACTIVEWIRE, 0,
USB_KNOWNDEV_NOPROD,
"ActiveWire Inc.",
NULL,
},
{
USB_VENDOR_PLX, 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.16 1999/01/08 11:58:26 augustss Exp $ */
/* $NetBSD: usbdi.h,v 1.28 1999/09/11 08:19:27 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -45,45 +45,17 @@ typedef struct usbd_pipe *usbd_pipe_handle;
typedef struct usbd_request *usbd_request_handle;
typedef void *usbd_private_handle;
typedef enum {
USBD_ENDPOINT_ACTIVE,
USBD_ENDPOINT_STALLED,
} usbd_endpoint_state;
typedef enum {
USBD_PIPE_ACTIVE,
USBD_PIPE_STALLED,
USBD_PIPE_IDLE,
} usbd_pipe_state;
typedef enum {
USBD_INTERFACE_ACTIVE,
USBD_INTERFACE_STALLED,
USBD_INTERFACE_IDLE,
} usbd_interface_state;
typedef enum {
USBD_DEVICE_ATTACHED,
USBD_DEVICE_POWERED,
USBD_DEVICE_DEFAULT,
USBD_DEVICE_ADDRESSED,
USBD_DEVICE_CONFIGURED,
USBD_DEVICE_SUSPENDED,
} usbd_device_state;
typedef enum {
USBD_NORMAL_COMPLETION = 0,
typedef enum { /* keep in sync with usbd_status_msgs */
USBD_NORMAL_COMPLETION = 0, /* must be 0 */
USBD_IN_PROGRESS,
/* errors */
USBD_PENDING_REQUESTS,
USBD_NOT_STARTED,
USBD_INVAL,
USBD_IS_IDLE,
USBD_NOMEM,
USBD_CANCELLED,
USBD_BAD_ADDRESS,
USBD_IN_USE,
USBD_INTERFACE_NOT_ACTIVE,
USBD_NO_ADDR,
USBD_SET_ADDR_FAILED,
USBD_NO_POWER,
@ -95,8 +67,7 @@ typedef enum {
USBD_STALLED,
USBD_INTERRUPTED,
USBD_XXX,
#define USBD_ERROR_MAX 21 /* used for usbd_error_strs */
USBD_ERROR_MAX, /* must be last */
} usbd_status;
typedef int usbd_lock_token;
@ -107,19 +78,15 @@ typedef void (*usbd_callback) __P((usbd_request_handle, usbd_private_handle,
/* Open flags */
#define USBD_EXCLUSIVE_USE 0x01
/* XXX broken, should not use the same value */
/* Request flags */
#define USBD_XFER_OUT 0x01
#define USBD_XFER_IN 0x02
#define USBD_SHORT_XFER_OK 0x04
/* 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 */
#if defined(__FreeBSD__)
#define USB_CDEV_MAJOR 108
extern struct cdevsw usb_cdevsw;
#endif
usbd_status usbd_open_pipe
@ -127,109 +94,54 @@ usbd_status usbd_open_pipe
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((void));
usbd_request_handle usbd_alloc_request __P((usbd_device_handle));
usbd_status usbd_free_request __P((usbd_request_handle reqh));
usbd_status usbd_setup_request
void usbd_setup_request
__P((usbd_request_handle reqh, usbd_pipe_handle pipe,
usbd_private_handle priv, void *buffer,
u_int32_t length, u_int16_t flags, u_int32_t timeout,
usbd_callback));
usbd_status usbd_setup_device_request
__P((usbd_request_handle reqh, usb_device_request_t *req));
usbd_status usbd_setup_default_request
void usbd_setup_default_request
__P((usbd_request_handle reqh, 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));
usbd_status usbd_set_request_timeout
__P((usbd_request_handle reqh, u_int32_t timeout));
usbd_status usbd_get_request_status
void usbd_setup_isoc_request
__P((usbd_request_handle reqh, usbd_pipe_handle pipe,
usbd_private_handle priv, u_int16_t *frlengths,
u_int32_t nframes, usbd_callback));
void usbd_get_request_status
__P((usbd_request_handle reqh, usbd_private_handle *priv,
void **buffer, u_int32_t *count, usbd_status *status));
usbd_status usbd_request_device_data
__P((usbd_request_handle reqh, usb_device_request_t *req));
usb_descriptor_t *usbd_get_descriptor
__P((usbd_interface_handle *iface, u_int8_t desc_type));
usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
__P((usbd_interface_handle iface, u_int8_t address));
usbd_status usbd_set_configuration
__P((usbd_device_handle dev, u_int8_t conf));
usbd_status usbd_retry_request
__P((usbd_request_handle reqh, u_int32_t retry_count));
usbd_status usbd_abort_pipe __P((usbd_pipe_handle pipe));
usbd_status usbd_abort_interface __P((usbd_interface_handle iface));
usbd_status usbd_reset_pipe __P((usbd_pipe_handle pipe));
usbd_status usbd_reset_interface __P((usbd_interface_handle iface));
usbd_status usbd_clear_endpoint_stall __P((usbd_pipe_handle pipe));
usbd_status usbd_clear_endpoint_stall_async __P((usbd_pipe_handle pipe));
usbd_status usbd_set_pipe_state
__P((usbd_pipe_handle pipe, usbd_pipe_state state));
usbd_status usbd_get_pipe_state
__P((usbd_pipe_handle pipe, usbd_pipe_state *state,
u_int32_t *endpoint_state, u_int32_t *request_count));
usbd_status usbd_set_interface_state
__P((usbd_interface_handle iface, usbd_interface_state state));
usbd_status usbd_get_interface_state
__P((usbd_interface_handle iface, usbd_interface_state *state));
usbd_status usbd_get_device_state
__P((usbd_device_handle dev, usbd_device_state *state));
usbd_status usbd_set_device_state
__P((usbd_device_handle dev, usbd_device_state state));
usbd_status usbd_device_address
__P((usbd_device_handle dev, u_int8_t *address));
usbd_status usbd_endpoint_address
__P((usbd_pipe_handle dev, u_int8_t *address));
usbd_status usbd_endpoint_count
__P((usbd_interface_handle dev, u_int8_t *count));
usbd_status usbd_interface_count
__P((usbd_device_handle dev, u_int8_t *count));
#if 0
u_int8_t usbd_bus_count __P((void));
usbd_status usbd_get_bus_handle __P((u_int8_t index, usbd_bus_handle *bus));
usbd_status usbd_get_root_hub
__P((usbd_bus_handle bus, usbd_device_handle *dev));
usbd_status usbd_port_count __P((usbd_device_handle hub, u_int8_t *nports));
usbd_status usbd_hub2device_handle
__P((usbd_device_handle hub, u_int8_t port, usbd_device_handle *dev));
#endif
usbd_status usbd_request2pipe_handle
__P((usbd_request_handle reqh, usbd_pipe_handle *pipe));
usbd_status usbd_pipe2interface_handle
__P((usbd_pipe_handle pipe, usbd_interface_handle *iface));
usbd_status usbd_interface2device_handle
__P((usbd_interface_handle iface, usbd_device_handle *dev));
usbd_status usbd_device2bus_handle
__P((usbd_device_handle dev, usbd_bus_handle *bus));
usbd_status usbd_device2interface_handle
__P((usbd_device_handle dev, u_int8_t ifaceno,
usbd_interface_handle *iface));
usbd_status usbd_set_interface_private_handle
__P((usbd_interface_handle iface, usbd_private_handle priv));
usbd_status usbd_get_interface_private_handle
__P((usbd_interface_handle iface, usbd_private_handle *priv));
usbd_status usbd_reference_pipe __P((usbd_pipe_handle pipe));
usbd_status usbd_dereference_pipe __P((usbd_pipe_handle pipe));
usbd_lock_token usbd_lock __P((void));
void usbd_unlock __P((usbd_lock_token tok));
__P((usbd_device_handle dev, u_int8_t ifaceno, usbd_interface_handle *iface));
/* Non-standard */
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));
usbd_status usbd_open_pipe_intr
__P((usbd_interface_handle iface, u_int8_t address,
u_int8_t flags, usbd_pipe_handle *pipe,
usbd_private_handle priv, void *buffer,
u_int32_t length, usbd_callback));
usbd_status usbd_open_pipe_iso
__P((usbd_interface_handle iface, u_int8_t address,
u_int8_t flags, usbd_pipe_handle *pipe,
usbd_private_handle priv, u_int32_t bufsize, u_int32_t nbuf,
usbd_callback));
usbd_status usbd_do_request
__P((usbd_device_handle dev, usb_device_request_t *req, void *data));
__P((usbd_device_handle pipe, usb_device_request_t *req, void *data));
usbd_status usbd_do_request_async
__P((usbd_device_handle dev, usb_device_request_t *req, void *data));
__P((usbd_device_handle pipe, usb_device_request_t *req, void *data));
usbd_status usbd_do_request_flags
__P((usbd_device_handle dev, usb_device_request_t *req,
__P((usbd_device_handle pipe, usb_device_request_t *req,
void *data, u_int16_t flags, int *));
usb_interface_descriptor_t *usbd_get_interface_descriptor
__P((usbd_interface_handle iface));
@ -251,9 +163,6 @@ usb_endpoint_descriptor_t *usbd_find_edesc
__P((usb_config_descriptor_t *cd, int ifaceidx, int altidx,
int endptidx));
char * usbd_errstr(usbd_status err);
void usbd_dopoll __P((usbd_interface_handle));
void usbd_set_polling __P((usbd_interface_handle iface, int on));
@ -264,6 +173,9 @@ struct usb_attach_arg {
int port;
int configno;
int ifaceno;
int vendor;
int product;
int release;
usbd_device_handle device; /* current device */
usbd_interface_handle iface; /* current interface */
int usegeneric;
@ -271,7 +183,7 @@ struct usb_attach_arg {
int nifaces; /* number of interfaces */
};
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
/* Match codes. */
/* First five codes is for a whole device. */
#define UMATCH_VENDOR_PRODUCT_REV 14
@ -295,33 +207,54 @@ struct usb_attach_arg {
#elif defined(__FreeBSD__)
/* FreeBSD needs values less than zero */
#define UMATCH_VENDOR_PRODUCT_REV (-10)
#define UMATCH_VENDOR_PRODUCT (-20)
#define UMATCH_VENDOR_DEVCLASS_DEVPROTO (-30)
#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO (-40)
#define UMATCH_DEVCLASS_DEVSUBCLASS (-50)
#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE (-60)
#define UMATCH_VENDOR_PRODUCT_CONF_IFACE (-70)
#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO (-80)
#define UMATCH_VENDOR_IFACESUBCLASS (-90)
#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO (-100)
#define UMATCH_IFACECLASS_IFACESUBCLASS (-110)
#define UMATCH_IFACECLASS (-120)
#define UMATCH_IFACECLASS_GENERIC (-130)
#define UMATCH_GENERIC (-140)
#define UMATCH_NONE (ENXIO)
#endif
/* for the moment disabled
#define UMATCH_VENDOR_PRODUCT_REV -14
#define UMATCH_VENDOR_PRODUCT -13
#define UMATCH_VENDOR_DEVCLASS_DEVPROTO -12
#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO -11
#define UMATCH_DEVCLASS_DEVSUBCLASS -10
#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE -9
#define UMATCH_VENDOR_PRODUCT_CONF_IFACE -8
#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO -7
#define UMATCH_VENDOR_IFACESUBCLASS -6
#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO -5
#define UMATCH_IFACECLASS_IFACESUBCLASS -4
#define UMATCH_IFACECLASS -3
#define UMATCH_IFACECLASS_GENERIC -2
#define UMATCH_GENERIC -1
#define UMATCH_NONE ENXIO
* For the moment we use Yes/No answers with appropriate
* sorting in the config file
*/
#define UMATCH_VENDOR_PRODUCT_REV 0
#define UMATCH_VENDOR_PRODUCT 0
#define UMATCH_VENDOR_DEVCLASS_DEVPROTO 0
#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO 0
#define UMATCH_DEVCLASS_DEVSUBCLASS 0
#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE 0
#define UMATCH_VENDOR_PRODUCT_CONF_IFACE 0
#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO 0
#define UMATCH_VENDOR_IFACESUBCLASS 0
#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO 0
#define UMATCH_IFACECLASS_IFACESUBCLASS 0
#define UMATCH_IFACECLASS 0
#define UMATCH_IFACECLASS_GENERIC 0
#define UMATCH_GENERIC 0
#define UMATCH_NONE ENXIO
#endif
void usbd_devinfo __P((usbd_device_handle, int, char *));
struct usbd_quirks *usbd_get_quirks __P((usbd_device_handle));
void usbd_set_disco __P((usbd_pipe_handle, void (*)(void *), void *));
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));
bus_print_child_t usbd_print_child;
#endif
/* XXX */

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi_util.c,v 1.19 1999/08/22 20:12:40 augustss Exp $ */
/* $NetBSD: usbdi_util.c,v 1.21 1999/09/09 12:26:48 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -43,7 +43,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#if defined(__NetBSD__)
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#elif defined(__FreeBSD__)
#include <sys/bus.h>
@ -514,10 +514,8 @@ usbd_bulk_transfer(reqh, pipe, flags, timeout, buf, size, lbl)
usbd_status r;
int s, error;
r = usbd_setup_request(reqh, pipe, 0, buf, *size,
flags, timeout, usbd_bulk_transfer_cb);
if (r != USBD_NORMAL_COMPLETION)
return (r);
usbd_setup_request(reqh, 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);
@ -543,19 +541,19 @@ usbd_bulk_transfer(reqh, pipe, flags, timeout, buf, size, lbl)
void
usb_detach_wait(dv)
bdevice *dv;
device_ptr_t dv;
{
DPRINTF(("usb_detach_wait: waiting for %s\n", USBDEVNAME(*dv)));
DPRINTF(("usb_detach_wait: waiting for %s\n", USBDEVPTRNAME(dv)));
if (tsleep(dv, PZERO, "usbdet", hz * 60))
printf("usb_detach_wait: %s didn't detach\n",
USBDEVNAME(*dv));
DPRINTF(("usb_detach_wait: %s done\n", USBDEVNAME(*dv)));
USBDEVPTRNAME(dv));
DPRINTF(("usb_detach_wait: %s done\n", USBDEVPTRNAME(dv)));
}
void
usb_detach_wakeup(dv)
bdevice *dv;
device_ptr_t dv;
{
DPRINTF(("usb_detach_wakeup: for %s\n", USBDEVNAME(*dv)));
DPRINTF(("usb_detach_wakeup: for %s\n", USBDEVPTRNAME(dv)));
wakeup(dv);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi_util.h,v 1.16 1999/08/22 20:12:40 augustss Exp $ */
/* $NetBSD: usbdi_util.h,v 1.17 1999/09/05 19:32:19 augustss Exp $ */
/* $FreeBSD$ */
/*
@ -93,6 +93,6 @@ usbd_status usbd_bulk_transfer
__P((usbd_request_handle reqh, 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((bdevice *));
void usb_detach_wakeup __P((bdevice *));
void usb_detach_wait __P((device_ptr_t));
void usb_detach_wakeup __P((device_ptr_t));

View File

@ -1,5 +1,5 @@
/* $NetBSD: usbdivar.h,v 1.16 1999/01/08 11:58:26 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: usbdivar.h,v 1.30 1999/09/11 08:19:27 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -38,25 +38,32 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/* From usb_mem.h */
DECLARE_USB_DMA_T;
struct usbd_request;
struct usbd_pipe;
struct usbd_endpoint {
usb_endpoint_descriptor_t *edesc;
usbd_endpoint_state state;
int refcnt;
int toggle; /* XXX */
};
typedef void (*usbd_xfercb)__P((usbd_request_handle req));
struct usbd_bus_methods {
usbd_status (*open_pipe)__P((struct usbd_pipe *pipe));
void (*do_poll)__P((struct usbd_bus *));
usbd_status (*allocm)__P((struct usbd_bus *, usb_dma_t *,
u_int32_t bufsize));
void (*freem)__P((struct usbd_bus *, usb_dma_t *));
};
struct usbd_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));
void (*close)__P((usbd_pipe_handle pipe));
usbd_status (*isobuf)__P((usbd_pipe_handle pipe,
u_int32_t bufsize,u_int32_t nbuf));
void (*close)__P((usbd_pipe_handle pipe));
void (*cleartoggle)__P((usbd_pipe_handle pipe));
void (*done)__P((usbd_request_handle reqh));
};
struct usbd_port {
@ -82,10 +89,9 @@ struct usb_softc;
struct usbd_bus {
/* Filled by HC driver */
bdevice bdev; /* base device, host adapter */
usbd_status (*open_pipe)__P((struct usbd_pipe *pipe));
USBBASEDEVICE bdev; /* base device, host adapter */
struct usbd_bus_methods *methods;
u_int32_t pipe_size; /* size of a pipe struct */
void (*do_poll)__P((struct usbd_bus *));
/* Filled by usb driver */
struct usbd_device *root_hub;
usbd_device_handle devices[USB_MAX_DEVICES];
@ -97,7 +103,6 @@ struct usbd_bus {
struct usbd_device {
struct usbd_bus *bus;
usbd_device_state state;
struct usbd_pipe *default_pipe;
u_int8_t address;
u_int8_t depth;
@ -115,12 +120,11 @@ struct usbd_device {
usb_config_descriptor_t *cdesc; /* full config descr */
struct usbd_quirks *quirks;
struct usbd_hub *hub; /* only if this is a hub */
void *softc; /* device softc if attached */
device_ptr_t *subdevs; /* sub-devices, 0 terminated */
};
struct usbd_interface {
struct usbd_device *device;
usbd_interface_state state;
usb_interface_descriptor_t *idesc;
int index;
int altindex;
@ -133,19 +137,16 @@ struct usbd_pipe {
struct usbd_interface *iface;
struct usbd_device *device;
struct usbd_endpoint *endpoint;
usbd_pipe_state state;
int32_t refcnt;
int refcnt;
char running;
SIMPLEQ_HEAD(, usbd_request) queue;
LIST_ENTRY(usbd_pipe) next;
void (*disco) __P((void *));
void *discoarg;
usbd_request_handle intrreqh; /* used for repeating requests */
char repeat;
/* Filled by HC driver. */
struct usbd_methods *methods;
struct usbd_pipe_methods *methods;
};
struct usbd_request {
@ -158,24 +159,34 @@ struct usbd_request {
u_int32_t timeout;
usbd_status status;
usbd_callback callback;
usbd_xfercb xfercb;
u_int32_t retries;
char done;
__volatile char done;
/* For control pipe */
usb_device_request_t request;
u_int8_t isreq;
/* For isoc */
u_int16_t *frlengths;
int nframes;
/* For memory allocation */
struct usbd_device *device;
usb_dma_t dmabuf;
int rqflags;
#define URQ_REQUEST 0x01
#define URQ_AUTO_DMABUF 0x10
#define URQ_DEV_DMABUF 0x20
SIMPLEQ_ENTRY(usbd_request) next;
void *hcpriv; /* XXX private use by the HC driver */
void *hcpriv; /* private use by the HC driver */
int hcprivint; /* ditto */
#if defined(__FreeBSD__)
struct callout_handle timeout_handle;
struct callout_handle timo_handle;
#endif
};
void usbd_init __P((void));
/* Routines from usb_subr.c */
int usbctlprint __P((void *, const char *));
void usb_delay_ms __P((usbd_bus_handle, u_int));
@ -186,30 +197,29 @@ usbd_status usbd_setup_pipe __P((usbd_device_handle dev,
usbd_interface_handle iface,
struct usbd_endpoint *,
usbd_pipe_handle *pipe));
usbd_status usbd_new_device __P((bdevice *parent,
usbd_status usbd_new_device __P((device_ptr_t parent,
usbd_bus_handle bus, int depth,
int lowspeed, int port,
struct usbd_port *));
void usbd_remove_device __P((usbd_device_handle,
struct usbd_port *));
int usbd_printBCD __P((char *cp, int bcd));
usbd_status usb_insert_transfer __P((usbd_request_handle reqh));
void usb_start_next __P((usbd_pipe_handle pipe));
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));
/* Routines from usb.c */
int usb_bus_count __P((void));
void usb_needs_explore __P((usbd_bus_handle));
#if 0
usbd_status usb_get_bus_handle __P((int, usbd_bus_handle *));
#endif
/* Locator stuff. */
#if defined(__NetBSD__)
#include "locators.h"
#elif defined(__FreeBSD__)
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
/* XXX these values are used to statically bind some elements in the USB tree
* to specific driver instances. This should be somehow emulated in FreeBSD
* but can be done later on.
@ -218,12 +228,30 @@ usbd_status usb_get_bus_handle __P((int, usbd_bus_handle *));
#define UHUBCF_PORT_DEFAULT -1
#define UHUBCF_CONFIGURATION_DEFAULT -1
#define UHUBCF_INTERFACE_DEFAULT -1
#define UHUBCF_VENDOR_DEFAULT -1
#define UHUBCF_PRODUCT_DEFAULT -1
#define UHUBCF_RELEASE_DEFAULT -1
#endif
#if defined (__OpenBSD__)
#define UHUBCF_PORT 0
#define UHUBCF_CONFIGURATION 1
#define UHUBCF_INTERFACE 2
#define UHUBCF_VENDOR 3
#define UHUBCF_PRODUCT 4
#define UHUBCF_RELEASE 5
#endif
#define uhubcf_port cf_loc[UHUBCF_PORT]
#define uhubcf_configuration cf_loc[UHUBCF_CONFIGURATION]
#define uhubcf_interface cf_loc[UHUBCF_INTERFACE]
#define uhubcf_vendor cf_loc[UHUBCF_VENDOR]
#define uhubcf_product cf_loc[UHUBCF_PRODUCT]
#define uhubcf_release cf_loc[UHUBCF_RELEASE]
#define UHUB_UNK_PORT UHUBCF_PORT_DEFAULT /* wildcarded 'port' */
#define UHUB_UNK_CONFIGURATION UHUBCF_CONFIGURATION_DEFAULT /* wildcarded 'configuration' */
#define UHUB_UNK_INTERFACE UHUBCF_INTERFACE_DEFAULT /* wildcarded 'interface' */
#define UHUB_UNK_VENDOR UHUBCF_VENDOR_DEFAULT /* wildcarded 'vendor' */
#define UHUB_UNK_PRODUCT UHUBCF_PRODUCT_DEFAULT /* wildcarded 'product' */
#define UHUB_UNK_RELEASE UHUBCF_RELEASE_DEFAULT /* wildcarded 'release' */

View File

@ -1,5 +1,5 @@
/* $NetBSD: usbhid.h,v 1.3 1998/12/26 12:53:04 augustss Exp $ */
/* $FreeBSD$ */
/* $NetBSD: usbhid.h,v 1.5 1999/05/13 23:29:11 augustss Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -72,6 +72,7 @@ typedef struct usb_hid_descriptor {
#define HUP_SIMULATION 0x0002
#define HUP_LEDS 0x0008
#define HUP_BUTTON 0x0009
#define HUP_DIGITIZERS 0x000d
/* Usages, generic desktop */
#define HUG_POINTER 0x0001
@ -115,6 +116,26 @@ typedef struct usb_hid_descriptor {
#define HUG_SYSTEM_MENU_UP 0x008c
#define HUG_SYSTEM_MENU_DOWN 0x008d
/* Usages Digitizers */
#define HUD_TIP_PRESSURE 0x0030
#define HUD_BARREL_PRESSURE 0x0031
#define HUD_IN_RANGE 0x0032
#define HUD_TOUCH 0x0033
#define HUD_UNTOUCH 0x0034
#define HUD_TAP 0x0035
#define HUD_QUALITY 0x0036
#define HUD_INVERT 0x003c
#define HUD_X_TILT 0x003d
#define HUD_Y_TILT 0x003e
#define HUD_AZIMUTH 0x003f
#define HUD_ALTITUDE 0x0040
#define HUD_TWIST 0x0041
#define HUD_TIP_SWITCH 0x0042
#define HUD_SEC_TIP_SWITCH 0x0043
#define HUD_BARREL_SWITCH 0x0044
#define HUD_ERASER 0x0045
#define HUD_TABLET_PICK 0x0046
#define HID_USAGE2(p,u) (((p) << 16) | u)
#define UHID_INPUT_REPORT 0x01