diff options
Diffstat (limited to 'sys/dev/usb')
33 files changed, 0 insertions, 16181 deletions
diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c deleted file mode 100644 index ea04a05b67e56..0000000000000 --- a/sys/dev/usb/hid.c +++ /dev/null @@ -1,471 +0,0 @@ -/* $NetBSD: hid.c,v 1.7 1999/01/08 11:58:25 augustss Exp $ */ -/* FreeBSD $Id: hid.c,v 1.5 1999/01/07 23:31:29 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__FreeBSD__) -#include <sys/bus.h> -#endif - -#include <dev/usb/usb.h> -#include <dev/usb/usbhid.h> - -#include <dev/usb/hid.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -extern int usbdebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -static void hid_clear_local __P((struct hid_item *)); - -#define MAXUSAGE 100 -struct hid_data { - u_char *start; - u_char *end; - u_char *p; - struct hid_item cur; - int32_t usages[MAXUSAGE]; - int nu; - int minset; - int multi; - int multimax; - int kindset; -}; - -static void -hid_clear_local(c) - struct hid_item *c; -{ - c->usage = 0; - c->usage_minimum = 0; - c->usage_maximum = 0; - c->designator_index = 0; - c->designator_minimum = 0; - c->designator_maximum = 0; - c->string_index = 0; - c->string_minimum = 0; - c->string_maximum = 0; - c->set_delimiter = 0; -} - -struct hid_data * -hid_start_parse(d, len, kindset) - void *d; - int len; - int kindset; -{ - struct hid_data *s; - - s = malloc(sizeof *s, M_TEMP, M_WAITOK); - memset(s, 0, sizeof *s); - s->start = s->p = d; - s->end = (char *)d + len; - s->kindset = kindset; - return (s); -} - -void -hid_end_parse(s) - struct hid_data *s; -{ - while (s->cur.next) { - struct hid_item *hi = s->cur.next->next; - free(s->cur.next, M_TEMP); - s->cur.next = hi; - } - free(s, M_TEMP); -} - -int -hid_get_item(s, h) - struct hid_data *s; - struct hid_item *h; -{ - struct hid_item *c = &s->cur; - int bTag, bType, bSize; - u_char *data; - int32_t dval; - u_char *p; - struct hid_item *hi; - int i; - - top: - if (s->multimax) { - if (s->multi < s->multimax) { - c->usage = s->usages[min(s->multi, s->nu-1)]; - s->multi++; - *h = *c; - c->loc.pos += c->loc.size; - h->next = 0; - return (1); - } else { - c->loc.count = s->multimax; - s->multimax = 0; - s->nu = 0; - hid_clear_local(c); - } - } - for (;;) { - p = s->p; - if (p >= s->end) - return (0); - - bSize = *p++; - if (bSize == 0xfe) { - /* long item */ - bSize = *p++; - bSize |= *p++ << 8; - bTag = *p++; - data = p; - p += bSize; - bType = 0xff; /* XXX what should it be */ - } else { - /* short item */ - bTag = bSize >> 4; - bType = (bSize >> 2) & 3; - bSize &= 3; - if (bSize == 3) bSize = 4; - data = p; - p += bSize; - } - s->p = p; - switch(bSize) { - case 0: - dval = 0; - break; - case 1: - dval = (int8_t)*data++; - break; - case 2: - dval = *data++; - dval |= *data++ << 8; - dval = (int16_t)dval; - break; - case 4: - dval = *data++; - dval |= *data++ << 8; - dval |= *data++ << 16; - dval |= *data++ << 24; - break; - default: - printf("BAD LENGTH %d\n", bSize); - continue; - } - - switch (bType) { - case 0: /* Main */ - switch (bTag) { - case 8: /* Input */ - if (!(s->kindset & (1 << hid_input))) - continue; - c->kind = hid_input; - c->flags = dval; - ret: - if (c->flags & HIO_VARIABLE) { - s->multimax = c->loc.count; - s->multi = 0; - c->loc.count = 1; - if (s->minset) { - for (i = c->usage_minimum; - i <= c->usage_maximum; - i++) { - s->usages[s->nu] = i; - if (s->nu < MAXUSAGE-1) - s->nu++; - } - s->minset = 0; - } - goto top; - } else { - *h = *c; - h->next = 0; - c->loc.pos += - c->loc.size * c->loc.count; - hid_clear_local(c); - s->minset = 0; - return (1); - } - case 9: /* Output */ - if (!(s->kindset & (1 << hid_output))) - continue; - c->kind = hid_output; - c->flags = dval; - goto ret; - case 10: /* Collection */ - c->kind = hid_collection; - c->collection = dval; - c->collevel++; - *h = *c; - hid_clear_local(c); - s->nu = 0; - return (1); - case 11: /* Feature */ - if (!(s->kindset & (1 << hid_feature))) - continue; - c->kind = hid_feature; - c->flags = dval; - goto ret; - case 12: /* End collection */ - c->kind = hid_endcollection; - c->collevel--; - *h = *c; - hid_clear_local(c); - s->nu = 0; - return (1); - default: - printf("Main bTag=%d\n", bTag); - break; - } - break; - case 1: /* Global */ - switch (bTag) { - case 0: - c->_usage_page = dval << 16; - break; - case 1: - c->logical_minimum = dval; - break; - case 2: - c->logical_maximum = dval; - break; - case 3: - c->physical_maximum = dval; - break; - case 4: - c->physical_maximum = dval; - break; - case 5: - c->unit_exponent = dval; - break; - case 6: - c->unit = dval; - break; - case 7: - c->loc.size = dval; - break; - case 8: - c->report_ID = dval; - break; - case 9: - c->loc.count = dval; - break; - case 10: /* Push */ - hi = malloc(sizeof *hi, M_TEMP, M_WAITOK); - *hi = s->cur; - c->next = hi; - break; - case 11: /* Pop */ - hi = c->next; - s->cur = *hi; - free(hi, M_TEMP); - break; - default: - printf("Global bTag=%d\n", bTag); - break; - } - break; - case 2: /* Local */ - switch (bTag) { - case 0: - if (bSize == 1) - dval = c->_usage_page | (dval&0xff); - else if (bSize == 2) - dval = c->_usage_page | (dval&0xffff); - c->usage = dval; - if (s->nu < MAXUSAGE) - s->usages[s->nu++] = dval; - /* else XXX */ - break; - case 1: - s->minset = 1; - if (bSize == 1) - dval = c->_usage_page | (dval&0xff); - else if (bSize == 2) - dval = c->_usage_page | (dval&0xffff); - c->usage_minimum = dval; - break; - case 2: - if (bSize == 1) - dval = c->_usage_page | (dval&0xff); - else if (bSize == 2) - dval = c->_usage_page | (dval&0xffff); - c->usage_maximum = dval; - break; - case 3: - c->designator_index = dval; - break; - case 4: - c->designator_minimum = dval; - break; - case 5: - c->designator_maximum = dval; - break; - case 7: - c->string_index = dval; - break; - case 8: - c->string_minimum = dval; - break; - case 9: - c->string_maximum = dval; - break; - case 10: - c->set_delimiter = dval; - break; - default: - printf("Local bTag=%d\n", bTag); - break; - } - break; - default: - printf("default bType=%d\n", bType); - break; - } - } -} - -int -hid_report_size(buf, len, k, idp) - void *buf; - int len; - enum hid_kind k; - u_int8_t *idp; -{ - struct hid_data *d; - struct hid_item h; - int size, id; - - id = 0; - for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); ) - if (h.report_ID) - id = h.report_ID; - hid_end_parse(d); - size = h.loc.pos; - if (id) { - size += 8; - *idp = id; /* XXX wrong */ - } else - *idp = 0; - return ((size + 7) / 8); -} - -int -hid_locate(desc, size, u, k, loc, flags) - void *desc; - int size; - u_int32_t u; - enum hid_kind k; - struct hid_location *loc; - u_int32_t *flags; -{ - struct hid_data *d; - struct hid_item h; - - for (d = hid_start_parse(desc, size, 1<<k); hid_get_item(d, &h); ) { - if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) { - if (loc) - *loc = h.loc; - if (flags) - *flags = h.flags; - hid_end_parse(d); - return (1); - } - } - hid_end_parse(d); - loc->size = 0; - return (0); -} - -u_long -hid_get_data(buf, loc) - u_char *buf; - struct hid_location *loc; -{ - u_int hpos = loc->pos; - u_int hsize = loc->size; - u_int32_t data; - int i, s; - - DPRINTFN(10, ("hid_get_data: loc %d/%d\n", hpos, hsize)); - - if (hsize == 0) - return (0); - - data = 0; - s = hpos / 8; - for (i = hpos; i < hpos+hsize; i += 8) - data |= buf[i / 8] << ((i / 8 - s) * 8); - data >>= hpos % 8; - data &= (1 << hsize) - 1; - hsize = 32 - hsize; - /* Sign extend */ - data = ((int32_t)data << hsize) >> hsize; - DPRINTFN(10,("hid_get_data: loc %d/%d = %lu\n", - loc->pos, loc->size, (long)data)); - return (data); -} - -int -hid_is_collection(desc, size, usage) - void *desc; - int size; - u_int32_t usage; -{ - struct hid_data *hd; - struct hid_item hi; - int r; - - hd = hid_start_parse(desc, size, hid_input); - if (!hd) - return (0); - - r = hid_get_item(hd, &hi) && - hi.kind == hid_collection && - hi.usage == usage; - hid_end_parse(hd); - return (r); -} diff --git a/sys/dev/usb/hid.h b/sys/dev/usb/hid.h deleted file mode 100644 index 0529701d72a2e..0000000000000 --- a/sys/dev/usb/hid.h +++ /dev/null @@ -1,91 +0,0 @@ -/* $NetBSD: hid.h,v 1.3 1998/11/25 22:32:04 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -enum hid_kind { - hid_input, hid_output, hid_feature, hid_collection, hid_endcollection -}; - -struct hid_location { - u_int32_t size; - u_int32_t count; - u_int32_t pos; -}; - -struct hid_item { - /* Global */ - int32_t _usage_page; - int32_t logical_minimum; - int32_t logical_maximum; - int32_t physical_minimum; - int32_t physical_maximum; - int32_t unit_exponent; - int32_t unit; - int32_t report_ID; - /* Local */ - int32_t usage; - int32_t usage_minimum; - int32_t usage_maximum; - int32_t designator_index; - int32_t designator_minimum; - int32_t designator_maximum; - int32_t string_index; - int32_t string_minimum; - int32_t string_maximum; - int32_t set_delimiter; - /* Misc */ - int32_t collection; - int collevel; - enum hid_kind kind; - u_int32_t flags; - /* Location */ - struct hid_location loc; - /* */ - struct hid_item *next; -}; - -struct hid_data *hid_start_parse __P((void *d, int len, int kindset)); -void hid_end_parse __P((struct hid_data *s)); -int hid_get_item __P((struct hid_data *s, struct hid_item *h)); -int hid_report_size __P((void *buf, int len, enum hid_kind k, u_int8_t *id)); -int hid_locate __P((void *desc, int size, u_int32_t usage, - enum hid_kind kind, struct hid_location *loc, - u_int32_t *flags)); -u_long hid_get_data __P((u_char *buf, struct hid_location *loc)); -int hid_is_collection __P((void *desc, int size, u_int32_t usage)); diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c deleted file mode 100644 index 1cb64b33769ad..0000000000000 --- a/sys/dev/usb/ohci.c +++ /dev/null @@ -1,2228 +0,0 @@ -/* $NetBSD: ohci.c,v 1.23 1999/01/07 02:06:05 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * USB Open Host Controller driver. - * - * OHCI spec: http://www.intel.com/design/usb/ohci11d.pdf - * USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#endif -#include <sys/proc.h> -#include <sys/queue.h> -#include <sys/select.h> - -#include <machine/bus.h> -#include <machine/endian.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usb_quirks.h> -#include <dev/usb/usb_mem.h> - -#include <dev/usb/ohcireg.h> -#include <dev/usb/ohcivar.h> - -#if defined(__FreeBSD__) -#include <machine/clock.h> - -#define delay(d) DELAY(d) - -#endif - -/* - * The OHCI controller is little endian, so on big endian machines - * the data strored in memory needs to be swapped. - */ -#if BYTE_ORDER == BIG_ENDIAN -#define LE(x) (bswap32(x)) -#else -#define LE(x) (x) -#endif - -struct ohci_pipe; - -ohci_soft_ed_t *ohci_alloc_sed __P((ohci_softc_t *)); -void ohci_free_sed __P((ohci_softc_t *, ohci_soft_ed_t *)); - -ohci_soft_td_t *ohci_alloc_std __P((ohci_softc_t *)); -void ohci_free_std __P((ohci_softc_t *, ohci_soft_td_t *)); - -usbd_status ohci_open __P((usbd_pipe_handle)); -void ohci_poll __P((struct usbd_bus *)); -void ohci_waitintr __P((ohci_softc_t *, usbd_request_handle)); -void ohci_rhsc __P((ohci_softc_t *, usbd_request_handle)); -void ohci_process_done __P((ohci_softc_t *, ohci_physaddr_t)); -void ohci_ii_done __P((ohci_softc_t *, usbd_request_handle)); -void ohci_ctrl_done __P((ohci_softc_t *, usbd_request_handle)); -void ohci_intr_done __P((ohci_softc_t *, usbd_request_handle)); -void ohci_bulk_done __P((ohci_softc_t *, usbd_request_handle)); - -usbd_status ohci_device_request __P((usbd_request_handle reqh)); -void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *)); -void ohci_rem_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *)); -void ohci_hash_add_td __P((ohci_softc_t *, ohci_soft_td_t *)); -void ohci_hash_rem_td __P((ohci_softc_t *, ohci_soft_td_t *)); -ohci_soft_td_t *ohci_hash_find_td __P((ohci_softc_t *, ohci_physaddr_t)); - -usbd_status ohci_root_ctrl_transfer __P((usbd_request_handle)); -usbd_status ohci_root_ctrl_start __P((usbd_request_handle)); -void ohci_root_ctrl_abort __P((usbd_request_handle)); -void ohci_root_ctrl_close __P((usbd_pipe_handle)); - -usbd_status ohci_root_intr_transfer __P((usbd_request_handle)); -usbd_status ohci_root_intr_start __P((usbd_request_handle)); -void ohci_root_intr_abort __P((usbd_request_handle)); -void ohci_root_intr_close __P((usbd_pipe_handle)); - -usbd_status ohci_device_ctrl_transfer __P((usbd_request_handle)); -usbd_status ohci_device_ctrl_start __P((usbd_request_handle)); -void ohci_device_ctrl_abort __P((usbd_request_handle)); -void ohci_device_ctrl_close __P((usbd_pipe_handle)); - -usbd_status ohci_device_bulk_transfer __P((usbd_request_handle)); -usbd_status ohci_device_bulk_start __P((usbd_request_handle)); -void ohci_device_bulk_abort __P((usbd_request_handle)); -void ohci_device_bulk_close __P((usbd_pipe_handle)); - -usbd_status ohci_device_intr_transfer __P((usbd_request_handle)); -usbd_status ohci_device_intr_start __P((usbd_request_handle)); -void ohci_device_intr_abort __P((usbd_request_handle)); -void ohci_device_intr_close __P((usbd_pipe_handle)); -usbd_status ohci_device_setintr __P((ohci_softc_t *sc, - struct ohci_pipe *pipe, int ival)); - -int ohci_str __P((usb_string_descriptor_t *, int, char *)); - -void ohci_timeout __P((void *)); -void ohci_rhsc_able __P((ohci_softc_t *, int)); - -#ifdef USB_DEBUG -ohci_softc_t *thesc; -void ohci_dumpregs __P((ohci_softc_t *)); -void ohci_dump_tds __P((ohci_soft_td_t *)); -void ohci_dump_td __P((ohci_soft_td_t *)); -void ohci_dump_ed __P((ohci_soft_ed_t *)); -#endif - -#if defined(__NetBSD__) -#define OWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)) -#define OREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r)) -#define OREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r)) -#elif defined(__FreeBSD__) -#define OWRITE4(sc, r, x) *(u_int32_t *) ((sc)->sc_iobase + (r)) = x -#define OREAD4(sc, r) (*(u_int32_t *) ((sc)->sc_iobase + (r))) -#define OREAD2(sc, r) (*(u_int16_t *) ((sc)->sc_iobase + (r))) -#endif - -/* Reverse the bits in a value 0 .. 31 */ -static u_int8_t revbits[OHCI_NO_INTRS] = - { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c, - 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e, - 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, - 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f }; - -struct ohci_pipe { - struct usbd_pipe pipe; - ohci_soft_ed_t *sed; - ohci_soft_td_t *tail; - /* Info needed for different pipe kinds. */ - union { - /* Control pipe */ - struct { - usb_dma_t datadma; - usb_dma_t reqdma; - u_int length; - ohci_soft_td_t *setup, *xfer, *stat; - } ctl; - /* Interrupt pipe */ - struct { - usb_dma_t datadma; - int nslots; - int pos; - } intr; - /* Bulk pipe */ - struct { - usb_dma_t datadma; - u_int length; - } bulk; - } u; -}; - -#define OHCI_INTR_ENDPT 1 - -struct usbd_methods ohci_root_ctrl_methods = { - ohci_root_ctrl_transfer, - ohci_root_ctrl_start, - ohci_root_ctrl_abort, - ohci_root_ctrl_close, - 0, -}; - -struct usbd_methods ohci_root_intr_methods = { - ohci_root_intr_transfer, - ohci_root_intr_start, - ohci_root_intr_abort, - ohci_root_intr_close, - 0, -}; - -struct usbd_methods ohci_device_ctrl_methods = { - ohci_device_ctrl_transfer, - ohci_device_ctrl_start, - ohci_device_ctrl_abort, - ohci_device_ctrl_close, - 0, -}; - -struct usbd_methods ohci_device_intr_methods = { - ohci_device_intr_transfer, - ohci_device_intr_start, - ohci_device_intr_abort, - ohci_device_intr_close, -}; - -struct usbd_methods ohci_device_bulk_methods = { - ohci_device_bulk_transfer, - ohci_device_bulk_start, - ohci_device_bulk_abort, - ohci_device_bulk_close, - 0, -}; - -ohci_soft_ed_t * -ohci_alloc_sed(sc) - ohci_softc_t *sc; -{ - ohci_soft_ed_t *sed; - usbd_status r; - int i, offs; - usb_dma_t dma; - - if (!sc->sc_freeeds) { - DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n")); - sed = malloc(sizeof(ohci_soft_ed_t) * OHCI_ED_CHUNK, - M_USBDEV, M_NOWAIT); - if (!sed) - return 0; - r = usb_allocmem(sc->sc_dmatag, OHCI_ED_SIZE * OHCI_ED_CHUNK, - OHCI_ED_ALIGN, &dma); - if (r != USBD_NORMAL_COMPLETION) { - free(sed, M_USBDEV); - return 0; - } - for(i = 0; i < OHCI_ED_CHUNK; i++, sed++) { - offs = i * OHCI_ED_SIZE; - sed->physaddr = DMAADDR(&dma) + offs; - sed->ed = (ohci_ed_t *) - ((char *)KERNADDR(&dma) + offs); - sed->next = sc->sc_freeeds; - sc->sc_freeeds = sed; - } - } - sed = sc->sc_freeeds; - sc->sc_freeeds = sed->next; - memset(sed->ed, 0, OHCI_ED_SIZE); - sed->next = 0; - return sed; -} - -void -ohci_free_sed(sc, sed) - ohci_softc_t *sc; - ohci_soft_ed_t *sed; -{ - sed->next = sc->sc_freeeds; - sc->sc_freeeds = sed; -} - -ohci_soft_td_t * -ohci_alloc_std(sc) - ohci_softc_t *sc; -{ - ohci_soft_td_t *std; - usbd_status r; - int i, offs; - usb_dma_t dma; - - if (!sc->sc_freetds) { - DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n")); - std = malloc(sizeof(ohci_soft_td_t) * OHCI_TD_CHUNK, - M_USBDEV, M_NOWAIT); - if (!std) - return 0; - r = usb_allocmem(sc->sc_dmatag, OHCI_TD_SIZE * OHCI_TD_CHUNK, - OHCI_TD_ALIGN, &dma); - if (r != USBD_NORMAL_COMPLETION) { - free(std, M_USBDEV); - return 0; - } - for(i = 0; i < OHCI_TD_CHUNK; i++, std++) { - offs = i * OHCI_TD_SIZE; - std->physaddr = DMAADDR(&dma) + offs; - std->td = (ohci_td_t *) - ((char *)KERNADDR(&dma) + offs); - std->nexttd = sc->sc_freetds; - sc->sc_freetds = std; - } - } - std = sc->sc_freetds; - sc->sc_freetds = std->nexttd; - memset(std->td, 0, OHCI_TD_SIZE); - std->nexttd = 0; - return (std); -} - -void -ohci_free_std(sc, std) - ohci_softc_t *sc; - ohci_soft_td_t *std; -{ - std->nexttd = sc->sc_freetds; - sc->sc_freetds = std; -} - -usbd_status -ohci_init(sc) - ohci_softc_t *sc; -{ - ohci_soft_ed_t *sed, *psed; - usbd_status r; - int rev; - int i; - u_int32_t s, ctl, ival, hcr, fm, per; - - DPRINTF(("ohci_init: start\n")); - rev = OREAD4(sc, OHCI_REVISION); - printf("%s: OHCI version %d.%d%s\n", USBDEVNAME(sc->sc_bus.bdev), - OHCI_REV_HI(rev), OHCI_REV_LO(rev), - OHCI_REV_LEGACY(rev) ? ", legacy support" : ""); - if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) { - printf("%s: unsupported OHCI revision\n", - USBDEVNAME(sc->sc_bus.bdev)); - return (USBD_INVAL); - } - - for (i = 0; i < OHCI_HASH_SIZE; i++) - LIST_INIT(&sc->sc_hash_tds[i]); - - /* Allocate the HCCA area. */ - r = usb_allocmem(sc->sc_dmatag, OHCI_HCCA_SIZE, - OHCI_HCCA_ALIGN, &sc->sc_hccadma); - if (r != USBD_NORMAL_COMPLETION) - return (r); - sc->sc_hcca = (struct ohci_hcca *)KERNADDR(&sc->sc_hccadma); - memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE); - - sc->sc_eintrs = OHCI_NORMAL_INTRS; - - sc->sc_ctrl_head = ohci_alloc_sed(sc); - if (!sc->sc_ctrl_head) { - r = USBD_NOMEM; - goto bad1; - } - sc->sc_ctrl_head->ed->ed_flags |= LE(OHCI_ED_SKIP); - sc->sc_bulk_head = ohci_alloc_sed(sc); - if (!sc->sc_bulk_head) { - r = USBD_NOMEM; - goto bad2; - } - sc->sc_bulk_head->ed->ed_flags |= LE(OHCI_ED_SKIP); - - /* Allocate all the dummy EDs that make up the interrupt tree. */ - for (i = 0; i < OHCI_NO_EDS; i++) { - sed = ohci_alloc_sed(sc); - if (!sed) { - while (--i >= 0) - ohci_free_sed(sc, sc->sc_eds[i]); - r = USBD_NOMEM; - goto bad3; - } - /* All ED fields are set to 0. */ - sc->sc_eds[i] = sed; - sed->ed->ed_flags |= LE(OHCI_ED_SKIP); - if (i != 0) { - psed = sc->sc_eds[(i-1) / 2]; - sed->next = psed; - sed->ed->ed_nexted = LE(psed->physaddr); - } - } - /* - * Fill HCCA interrupt table. The bit reversal is to get - * the tree set up properly to spread the interrupts. - */ - for (i = 0; i < OHCI_NO_INTRS; i++) - sc->sc_hcca->hcca_interrupt_table[revbits[i]] = - LE(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]->physaddr); - - /* Determine in what context we are running. */ - ctl = OREAD4(sc, OHCI_CONTROL); - if (ctl & OHCI_IR) { - /* SMM active, request change */ - DPRINTF(("ohci_init: SMM active, request owner change\n")); - s = OREAD4(sc, OHCI_COMMAND_STATUS); - OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR); - for (i = 0; i < 100 && (ctl & OHCI_IR); i++) { - delay(1000); - ctl = OREAD4(sc, OHCI_CONTROL); - } - if ((ctl & OHCI_IR) == 0) { - printf("%s: SMM does not respond, resetting\n", - USBDEVNAME(sc->sc_bus.bdev)); - OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); - goto reset; - } - } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) { - /* BIOS started controller. */ - DPRINTF(("ohci_init: BIOS active\n")); - if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) { - OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL); - delay(USB_RESUME_DELAY * 1000); - } - } else { - DPRINTF(("ohci_init: cold started\n")); - reset: - /* Controller was cold started. */ - delay(USB_BUS_RESET_DELAY * 1000); - } - - /* - * This reset should not be necessary according to the OHCI spec, but - * without it some controllers do not start. - */ - DPRINTF(("%s: resetting\n", USBDEVNAME(sc->sc_bus.bdev))); - OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); - delay(USB_BUS_RESET_DELAY * 1000); - - /* We now own the host controller and the bus has been reset. */ - ival = OHCI_GET_IVAL(OREAD4(sc, OHCI_FM_INTERVAL)); - - OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */ - /* Nominal time for a reset is 10 us. */ - for (i = 0; i < 10; i++) { - delay(10); - hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR; - if (!hcr) - break; - } - if (hcr) { - printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev)); - r = USBD_IOERROR; - goto bad3; - } -#ifdef USB_DEBUG - thesc = sc; - if (ohcidebug > 15) - ohci_dumpregs(sc); -#endif - - /* The controller is now in suspend state, we have 2ms to finish. */ - - /* Set up HC registers. */ - OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma)); - OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr); - OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr); - OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS); - OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE); - ctl = OREAD4(sc, OHCI_CONTROL); - ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR); - ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE | - OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL; - /* And finally start it! */ - OWRITE4(sc, OHCI_CONTROL, ctl); - - /* - * The controller is now OPERATIONAL. Set a some final - * registers that should be set earlier, but that the - * controller ignores when in the SUSPEND state. - */ - fm = (OREAD4(sc, OHCI_FM_INTERVAL) & OHCI_FIT) ^ OHCI_FIT; - fm |= OHCI_FSMPS(ival) | ival; - OWRITE4(sc, OHCI_FM_INTERVAL, fm); - per = OHCI_PERIODIC(ival); /* 90% periodic */ - OWRITE4(sc, OHCI_PERIODIC_START, per); - - OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */ - - sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A)); - -#ifdef USB_DEBUG - if (ohcidebug > 5) - ohci_dumpregs(sc); -#endif - - /* Set up the bus struct. */ - sc->sc_bus.open_pipe = ohci_open; - sc->sc_bus.pipe_size = sizeof(struct ohci_pipe); - sc->sc_bus.do_poll = ohci_poll; - - return (USBD_NORMAL_COMPLETION); - - bad3: - ohci_free_sed(sc, sc->sc_ctrl_head); - bad2: - ohci_free_sed(sc, sc->sc_bulk_head); - bad1: - usb_freemem(sc->sc_dmatag, &sc->sc_hccadma); - return (r); -} - -#ifdef USB_DEBUG -void ohcidump(void); -void ohcidump(void) { ohci_dumpregs(thesc); } - -void -ohci_dumpregs(sc) - ohci_softc_t *sc; -{ - printf("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n", - OREAD4(sc, OHCI_REVISION), - OREAD4(sc, OHCI_CONTROL), - OREAD4(sc, OHCI_COMMAND_STATUS)); - printf(" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n", - OREAD4(sc, OHCI_INTERRUPT_STATUS), - OREAD4(sc, OHCI_INTERRUPT_ENABLE), - OREAD4(sc, OHCI_INTERRUPT_DISABLE)); - printf(" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n", - OREAD4(sc, OHCI_HCCA), - OREAD4(sc, OHCI_PERIOD_CURRENT_ED), - OREAD4(sc, OHCI_CONTROL_HEAD_ED)); - printf(" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n", - OREAD4(sc, OHCI_CONTROL_CURRENT_ED), - OREAD4(sc, OHCI_BULK_HEAD_ED), - OREAD4(sc, OHCI_BULK_CURRENT_ED)); - printf(" done=0x%08x fmival=0x%08x fmrem=0x%08x\n", - OREAD4(sc, OHCI_DONE_HEAD), - OREAD4(sc, OHCI_FM_INTERVAL), - OREAD4(sc, OHCI_FM_REMAINING)); - printf(" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n", - OREAD4(sc, OHCI_FM_NUMBER), - OREAD4(sc, OHCI_PERIODIC_START), - OREAD4(sc, OHCI_LS_THRESHOLD)); - printf(" desca=0x%08x descb=0x%08x stat=0x%08x\n", - OREAD4(sc, OHCI_RH_DESCRIPTOR_A), - OREAD4(sc, OHCI_RH_DESCRIPTOR_B), - OREAD4(sc, OHCI_RH_STATUS)); - printf(" port1=0x%08x port2=0x%08x\n", - OREAD4(sc, OHCI_RH_PORT_STATUS(1)), - OREAD4(sc, OHCI_RH_PORT_STATUS(2))); - printf(" HCCA: frame_number=0x%04x done_head=0x%08x\n", - LE(sc->sc_hcca->hcca_frame_number), - LE(sc->sc_hcca->hcca_done_head)); -} -#endif - -int -ohci_intr(p) - void *p; -{ - ohci_softc_t *sc = p; - u_int32_t intrs = 0, eintrs; - ohci_physaddr_t done; - - /* In case the interrupt occurs before initialization has completed. */ - if (sc == NULL || sc->sc_hcca == NULL) { /* NWH added sc==0 */ -#ifdef DIAGNOSTIC - printf("ohci_intr: sc->sc_hcca == NULL\n"); -#endif - return (0); - } - - done = LE(sc->sc_hcca->hcca_done_head); - if (done != 0) { - sc->sc_hcca->hcca_done_head = 0; - if (done & ~OHCI_DONE_INTRS) - intrs = OHCI_WDH; - if (done & OHCI_DONE_INTRS) - intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS); - } else - intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS); - if (!intrs) - return (0); - intrs &= ~OHCI_MIE; - OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */ - eintrs = intrs & sc->sc_eintrs; - if (!eintrs) - return (0); - - sc->sc_intrs++; - DPRINTFN(7, ("ohci_intr: sc=%p intrs=%x(%x) eintr=%x\n", - sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), - (u_int)eintrs)); - - if (eintrs & OHCI_SO) { - printf("%s: scheduling overrun\n",USBDEVNAME(sc->sc_bus.bdev)); - /* XXX do what */ - intrs &= ~OHCI_SO; - } - if (eintrs & OHCI_WDH) { - ohci_process_done(sc, done &~ OHCI_DONE_INTRS); - intrs &= ~OHCI_WDH; - } - if (eintrs & OHCI_RD) { - /* XXX process resume detect */ - } - if (eintrs & OHCI_UE) { - printf("%s: unrecoverable error, controller halted\n", - USBDEVNAME(sc->sc_bus.bdev)); - OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); - /* XXX what else */ - } - if (eintrs & OHCI_RHSC) { - ohci_rhsc(sc, sc->sc_intrreqh); - intrs &= ~OHCI_RHSC; - - /* - * Disable RHSC interrupt for now, because it will be - * on until the port has been reset. - */ - ohci_rhsc_able(sc, 0); - } - - /* Block unprocessed interrupts. XXX */ - OWRITE4(sc, OHCI_INTERRUPT_DISABLE, intrs); - sc->sc_eintrs &= ~intrs; - - return (1); -} - -void -ohci_rhsc_able(sc, on) - ohci_softc_t *sc; - int on; -{ - DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on)); - if (on) { - sc->sc_eintrs |= OHCI_RHSC; - OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC); - } else { - sc->sc_eintrs &= ~OHCI_RHSC; - OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC); - } -} - -#ifdef USB_DEBUG -char *ohci_cc_strs[] = { - "NO_ERROR", - "CRC", - "BIT_STUFFING", - "DATA_TOGGLE_MISMATCH", - "STALL", - "DEVICE_NOT_RESPONDING", - "PID_CHECK_FAILURE", - "UNEXPECTED_PID", - "DATA_OVERRUN", - "DATA_UNDERRUN", - "BUFFER_OVERRUN", - "BUFFER_UNDERRUN", - "NOT_ACCESSED", -}; -#endif - -void -ohci_process_done(sc, done) - ohci_softc_t *sc; - ohci_physaddr_t done; -{ - ohci_soft_td_t *std = NULL, *sdone; - usbd_request_handle reqh; - int len, cc; - - DPRINTFN(10,("ohci_process_done: done=0x%08lx\n", (u_long)done)); - - /* Reverse the done list. */ - for (sdone = 0; done; done = LE(std->td->td_nexttd)) { - std = ohci_hash_find_td(sc, done); - std->dnext = sdone; - sdone = std; - } - -#ifdef USB_DEBUG - if (ohcidebug > 10) { - printf("ohci_process_done: TD done:\n"); - ohci_dump_tds(sdone); - } -#endif - - for (std = sdone; std; std = std->dnext) { - reqh = std->reqh; - DPRINTFN(10, ("ohci_process_done: std=%p reqh=%p hcpriv=%p\n", - std, reqh, reqh->hcpriv)); - cc = OHCI_TD_GET_CC(LE(std->td->td_flags)); - if (cc == OHCI_CC_NO_ERROR) { - if (std->td->td_cbp == 0) - len = std->len; - else - len = LE(std->td->td_be) - - LE(std->td->td_cbp) + 1; - /* - * Only do a callback on the last stage of a transfer. - * Others have hcpriv = 0. - */ - if ((reqh->pipe->endpoint->edesc->bmAttributes & - UE_XFERTYPE) == UE_CONTROL) { - /* For a control transfer the length is in - * the xfer stage */ - if (reqh->hcpriv == std) { - reqh->status = USBD_NORMAL_COMPLETION; - ohci_ii_done(sc, reqh); - } else - reqh->actlen = len; - } else { - if (reqh->hcpriv == std) { - reqh->actlen = len; - reqh->status = USBD_NORMAL_COMPLETION; - ohci_ii_done(sc, reqh); - } - } - } else { - ohci_soft_td_t *p, *n; - struct ohci_pipe *opipe = - (struct ohci_pipe *)reqh->pipe; - DPRINTFN(-1,("ohci_process_done: error cc=%d (%s)\n", - OHCI_TD_GET_CC(LE(std->td->td_flags)), - ohci_cc_strs[OHCI_TD_GET_CC(LE(std->td->td_flags))])); - /* - * Endpoint is halted. First unlink all the TDs - * belonging to the failed transfer, and then restart - * the endpoint. - */ - for (p = std->nexttd; p->reqh == reqh; p = n) { - n = p->nexttd; - ohci_hash_rem_td(sc, p); - ohci_free_std(sc, p); - } - /* clear halt */ - opipe->sed->ed->ed_headp = LE(p->physaddr); - OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); - - if (cc == OHCI_CC_STALL) - reqh->status = USBD_STALLED; - else - reqh->status = USBD_IOERROR; - ohci_ii_done(sc, reqh); - } - ohci_hash_rem_td(sc, std); - ohci_free_std(sc, std); - } -} - -void -ohci_ii_done(sc, reqh) - ohci_softc_t *sc; - usbd_request_handle reqh; -{ - switch (reqh->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) { - case UE_CONTROL: - ohci_ctrl_done(sc, reqh); - usb_start_next(reqh->pipe); - break; - case UE_INTERRUPT: - ohci_intr_done(sc, reqh); - break; - case UE_BULK: - ohci_bulk_done(sc, reqh); - usb_start_next(reqh->pipe); - break; - case UE_ISOCHRONOUS: - printf("ohci_process_done: ISO done?\n"); - usb_start_next(reqh->pipe); - break; - } - - /* And finally execute callback. */ - reqh->xfercb(reqh); -} - -void -ohci_ctrl_done(sc, reqh) - ohci_softc_t *sc; - usbd_request_handle reqh; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe; - u_int len = opipe->u.ctl.length; - usb_dma_t *dma; - - DPRINTFN(10,("ohci_ctrl_done: reqh=%p\n", reqh)); - - if (!reqh->isreq) { - panic("ohci_ctrl_done: not a request\n"); - return; - } - - if (len != 0) { - dma = &opipe->u.ctl.datadma; - if (reqh->request.bmRequestType & UT_READ) - memcpy(reqh->buffer, KERNADDR(dma), len); - usb_freemem(sc->sc_dmatag, dma); - } - usb_untimeout(ohci_timeout, reqh, reqh->timo_handle); -} - -void -ohci_intr_done(sc, reqh) - ohci_softc_t *sc; - usbd_request_handle reqh; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe; - usb_dma_t *dma; - ohci_soft_ed_t *sed = opipe->sed; - ohci_soft_td_t *xfer, *tail; - - - DPRINTFN(10,("ohci_intr_done: reqh=%p, actlen=%d\n", - reqh, reqh->actlen)); - - dma = &opipe->u.intr.datadma; - memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen); - - if (reqh->pipe->intrreqh == reqh) { - xfer = opipe->tail; - tail = ohci_alloc_std(sc); /* XXX should reuse TD */ - if (!tail) { - reqh->status = USBD_NOMEM; - return; - } - tail->reqh = 0; - - xfer->td->td_flags = LE( - OHCI_TD_IN | OHCI_TD_NOCC | - OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); - if (reqh->flags & USBD_SHORT_XFER_OK) - xfer->td->td_flags |= LE(OHCI_TD_R); - xfer->td->td_cbp = LE(DMAADDR(dma)); - xfer->nexttd = tail; - xfer->td->td_nexttd = LE(tail->physaddr); - xfer->td->td_be = LE(LE(xfer->td->td_cbp) + reqh->length - 1); - xfer->len = reqh->length; - xfer->reqh = reqh; - - reqh->hcpriv = xfer; - - ohci_hash_add_td(sc, xfer); - sed->ed->ed_tailp = LE(tail->physaddr); - opipe->tail = tail; - } else { - usb_freemem(sc->sc_dmatag, dma); - usb_start_next(reqh->pipe); - } -} - -void -ohci_bulk_done(sc, reqh) - ohci_softc_t *sc; - usbd_request_handle reqh; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe; - usb_dma_t *dma; - - - DPRINTFN(10,("ohci_bulk_done: reqh=%p, actlen=%d\n", - reqh, reqh->actlen)); - - dma = &opipe->u.bulk.datadma; - if (reqh->request.bmRequestType & UT_READ) - memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen); - usb_freemem(sc->sc_dmatag, dma); - usb_untimeout(ohci_timeout, reqh, reqh->timo_handle); -} - -void -ohci_rhsc(sc, reqh) - ohci_softc_t *sc; - usbd_request_handle reqh; -{ - usbd_pipe_handle pipe; - struct ohci_pipe *opipe; - u_char *p; - int i, m; - int hstatus; - - hstatus = OREAD4(sc, OHCI_RH_STATUS); - DPRINTF(("ohci_rhsc: sc=%p reqh=%p hstatus=0x%08x\n", - sc, reqh, hstatus)); - - if (reqh == 0) { - /* Just ignore the change. */ - return; - } - - pipe = reqh->pipe; - opipe = (struct ohci_pipe *)pipe; - - p = KERNADDR(&opipe->u.intr.datadma); - m = min(sc->sc_noport, reqh->length * 8 - 1); - memset(p, 0, reqh->length); - for (i = 1; i <= m; i++) { - if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16) - p[i/8] |= 1 << (i%8); - } - DPRINTF(("ohci_rhsc: change=0x%02x\n", *p)); - reqh->actlen = reqh->length; - reqh->status = USBD_NORMAL_COMPLETION; - reqh->xfercb(reqh); - - if (reqh->pipe->intrreqh != reqh) { - sc->sc_intrreqh = 0; - usb_freemem(sc->sc_dmatag, &opipe->u.intr.datadma); - usb_start_next(reqh->pipe); - } -} - -/* - * Wait here until controller claims to have an interrupt. - * Then call ohci_intr and return. Use timeout to avoid waiting - * too long. - */ -void -ohci_waitintr(sc, reqh) - ohci_softc_t *sc; - usbd_request_handle reqh; -{ - int timo = reqh->timeout; - int usecs; - u_int32_t intrs; - - reqh->status = USBD_IN_PROGRESS; - for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) { - usb_delay_ms(&sc->sc_bus, 1); - intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs; - DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs)); -#ifdef USB_DEBUG - if (ohcidebug > 15) - ohci_dumpregs(sc); -#endif - if (intrs) { - ohci_intr(sc); - if (reqh->status != USBD_IN_PROGRESS) - return; - } - } - - /* Timeout */ - DPRINTF(("ohci_waitintr: timeout\n")); - reqh->status = USBD_TIMEOUT; - ohci_ii_done(sc, reqh); - /* XXX should free TD */ -} - -void -ohci_poll(bus) - struct usbd_bus *bus; -{ - ohci_softc_t *sc = (ohci_softc_t *)bus; - - if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs) - ohci_intr(sc); -} - -usbd_status -ohci_device_request(reqh) - usbd_request_handle reqh; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe; - usb_device_request_t *req = &reqh->request; - usbd_device_handle dev = opipe->pipe.device; - ohci_softc_t *sc = (ohci_softc_t *)dev->bus; - int addr = dev->address; - ohci_soft_td_t *setup, *xfer = 0, *stat, *next, *tail; - ohci_soft_ed_t *sed; - usb_dma_t *dmap; - int isread; - int len; - usbd_status r; - int s; - - isread = req->bmRequestType & UT_READ; - len = UGETW(req->wLength); - - DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, " - "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n", - req->bmRequestType, req->bRequest, UGETW(req->wValue), - UGETW(req->wIndex), len, addr, - opipe->pipe.endpoint->edesc->bEndpointAddress)); - - setup = opipe->tail; - stat = ohci_alloc_std(sc); - if (!stat) { - r = USBD_NOMEM; - goto bad1; - } - tail = ohci_alloc_std(sc); - if (!tail) { - r = USBD_NOMEM; - goto bad2; - } - tail->reqh = 0; - - sed = opipe->sed; - dmap = &opipe->u.ctl.datadma; - opipe->u.ctl.length = len; - - /* Update device address and length since they may have changed. */ - /* XXX This only needs to be done once, but it's too early in open. */ - sed->ed->ed_flags = LE( - (LE(sed->ed->ed_flags) & ~(OHCI_ED_ADDRMASK | OHCI_ED_MAXPMASK)) | - OHCI_ED_SET_FA(addr) | - OHCI_ED_SET_MAXP(UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize))); - - /* Set up data transaction */ - if (len != 0) { - xfer = ohci_alloc_std(sc); - if (!xfer) { - r = USBD_NOMEM; - goto bad3; - } - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - goto bad4; - xfer->td->td_flags = LE( - (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC | - OHCI_TD_TOGGLE_1 | OHCI_TD_NOINTR | - (reqh->flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0)); - xfer->td->td_cbp = LE(DMAADDR(dmap)); - xfer->nexttd = stat; - xfer->td->td_nexttd = LE(stat->physaddr); - xfer->td->td_be = LE(LE(xfer->td->td_cbp) + len - 1); - xfer->len = len; - xfer->reqh = reqh; - - next = xfer; - } else - next = stat; - - memcpy(KERNADDR(&opipe->u.ctl.reqdma), req, sizeof *req); - if (!isread && len != 0) - memcpy(KERNADDR(dmap), reqh->buffer, len); - - setup->td->td_flags = LE(OHCI_TD_SETUP | OHCI_TD_NOCC | - OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR); - setup->td->td_cbp = LE(DMAADDR(&opipe->u.ctl.reqdma)); - setup->nexttd = next; - setup->td->td_nexttd = LE(next->physaddr); - setup->td->td_be = LE(LE(setup->td->td_cbp) + sizeof *req - 1); - setup->len = 0; /* XXX The number of byte we count */ - setup->reqh = reqh; - - stat->td->td_flags = LE( - (isread ? OHCI_TD_OUT : OHCI_TD_IN) | OHCI_TD_NOCC | - OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1)); - stat->td->td_cbp = 0; - stat->nexttd = tail; - stat->td->td_nexttd = LE(tail->physaddr); - stat->td->td_be = 0; - stat->len = 0; - stat->reqh = reqh; - - reqh->hcpriv = stat; - -#if USB_DEBUG - if (ohcidebug > 5) { - printf("ohci_device_request:\n"); - ohci_dump_ed(sed); - ohci_dump_tds(setup); - } -#endif - - /* Insert ED in schedule */ - s = splusb(); - ohci_hash_add_td(sc, setup); - if (len != 0) - ohci_hash_add_td(sc, xfer); - ohci_hash_add_td(sc, stat); - sed->ed->ed_tailp = LE(tail->physaddr); - opipe->tail = tail; - OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); - if (reqh->timeout && !sc->sc_bus.use_polling) { - usb_timeout(ohci_timeout, reqh, - MS_TO_TICKS(reqh->timeout), reqh->timo_handle); - } - splx(s); - -#if USB_DEBUG - if (ohcidebug > 5) { - delay(5000); - printf("ohci_device_request: status=%x\n", - OREAD4(sc, OHCI_COMMAND_STATUS)); - ohci_dump_ed(sed); - ohci_dump_tds(setup); - } -#endif - - return (USBD_NORMAL_COMPLETION); - - bad4: - ohci_free_std(sc, xfer); - bad3: - ohci_free_std(sc, tail); - bad2: - ohci_free_std(sc, stat); - bad1: - return (r); -} - -/* - * Add an ED to the schedule. Called at splusb(). - */ -void -ohci_add_ed(sed, head) - ohci_soft_ed_t *sed; - ohci_soft_ed_t *head; -{ - sed->next = head->next; - sed->ed->ed_nexted = head->ed->ed_nexted; - head->next = sed; - head->ed->ed_nexted = LE(sed->physaddr); -} - -/* - * Remove an ED from the schedule. Called at splusb(). - */ -void -ohci_rem_ed(sed, head) - ohci_soft_ed_t *sed; - ohci_soft_ed_t *head; -{ - ohci_soft_ed_t *p; - - /* XXX */ - for (p = head; p && p->next != sed; p = p->next) - ; - if (!p) - panic("ohci_rem_ed: ED not found\n"); - p->next = sed->next; - p->ed->ed_nexted = sed->ed->ed_nexted; -} - -/* - * When a transfer is completed the TD is added to the done queue by - * the host controller. This queue is the processed by software. - * Unfortunately the queue contains the physical address of the TD - * and we have no simple way to translate this back to a kernel address. - * To make the translation possible (and fast) we use a hash table of - * TDs currently in the schedule. The physical address is used as the - * hash value. - */ - -#define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE) -/* Called at splusb() */ -void -ohci_hash_add_td(sc, std) - ohci_softc_t *sc; - ohci_soft_td_t *std; -{ - int h = HASH(std->physaddr); - - LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext); -} - -/* Called at splusb() */ -void -ohci_hash_rem_td(sc, std) - ohci_softc_t *sc; - ohci_soft_td_t *std; -{ - LIST_REMOVE(std, hnext); -} - -ohci_soft_td_t * -ohci_hash_find_td(sc, a) - ohci_softc_t *sc; - ohci_physaddr_t a; -{ - int h = HASH(a); - ohci_soft_td_t *std; - - for (std = LIST_FIRST(&sc->sc_hash_tds[h]); - std != 0; - std = LIST_NEXT(std, hnext)) - if (std->physaddr == a) - return (std); - panic("ohci_hash_find_td: addr 0x%08lx not found\n", (u_long)a); -} - -void -ohci_timeout(addr) - void *addr; -{ -#if 0 - usbd_request_handle *reqh = addr; - int s; - - DPRINTF(("ohci_timeout: reqh=%p\n", reqh)); - s = splusb(); - /* XXX need to inactivate TD before calling interrupt routine */ - ohci_XXX_done(reqh); - splx(s); -#endif -} - -#ifdef USB_DEBUG -void -ohci_dump_tds(std) - ohci_soft_td_t *std; -{ - for (; std; std = std->nexttd) - ohci_dump_td(std); -} - -void -ohci_dump_td(std) - ohci_soft_td_t *std; -{ - printf("TD(%p) at %08lx: %b delay=%d ec=%d cc=%d\ncbp=0x%08lx " - "nexttd=0x%08lx be=0x%08lx\n", - std, (u_long)std->physaddr, - (int)LE(std->td->td_flags), - "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE", - OHCI_TD_GET_DI(LE(std->td->td_flags)), - OHCI_TD_GET_EC(LE(std->td->td_flags)), - OHCI_TD_GET_CC(LE(std->td->td_flags)), - (u_long)LE(std->td->td_cbp), - (u_long)LE(std->td->td_nexttd), (u_long)LE(std->td->td_be)); -} - -void -ohci_dump_ed(sed) - ohci_soft_ed_t *sed; -{ - printf("ED(%p) at %08lx: addr=%d endpt=%d maxp=%d %b\ntailp=0x%08lx " - "headp=%b nexted=0x%08lx\n", - sed, (u_long)sed->physaddr, - OHCI_ED_GET_FA(LE(sed->ed->ed_flags)), - OHCI_ED_GET_EN(LE(sed->ed->ed_flags)), - OHCI_ED_GET_MAXP(LE(sed->ed->ed_flags)), - (int)LE(sed->ed->ed_flags), - "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO", - (u_long)LE(sed->ed->ed_tailp), - (int)LE(sed->ed->ed_headp), "\20\1HALT\2CARRY", - (u_long)LE(sed->ed->ed_nexted)); -} -#endif - -usbd_status -ohci_open(pipe) - usbd_pipe_handle pipe; -{ - usbd_device_handle dev = pipe->device; - ohci_softc_t *sc = (ohci_softc_t *)dev->bus; - usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - u_int8_t addr = dev->address; - ohci_soft_ed_t *sed; - ohci_soft_td_t *std; - usbd_status r; - int s; - - DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", - pipe, addr, ed->bEndpointAddress, sc->sc_addr)); - if (addr == sc->sc_addr) { - switch (ed->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &ohci_root_ctrl_methods; - break; - case UE_IN | OHCI_INTR_ENDPT: - pipe->methods = &ohci_root_intr_methods; - break; - default: - return (USBD_INVAL); - } - } else { - sed = ohci_alloc_sed(sc); - if (sed == 0) - goto bad0; - std = ohci_alloc_std(sc); - if (std == 0) - goto bad1; - opipe->sed = sed; - opipe->tail = std; - sed->ed->ed_flags = LE( - OHCI_ED_SET_FA(addr) | - OHCI_ED_SET_EN(ed->bEndpointAddress) | - OHCI_ED_DIR_TD | - (dev->lowspeed ? OHCI_ED_SPEED : 0) | - ((ed->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS ? - OHCI_ED_FORMAT_ISO : OHCI_ED_FORMAT_GEN) | - OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize))); - sed->ed->ed_headp = sed->ed->ed_tailp = LE(std->physaddr); - - switch (ed->bmAttributes & UE_XFERTYPE) { - case UE_CONTROL: - pipe->methods = &ohci_device_ctrl_methods; - r = usb_allocmem(sc->sc_dmatag, - sizeof(usb_device_request_t), - 0, &opipe->u.ctl.reqdma); - if (r != USBD_NORMAL_COMPLETION) - goto bad; - s = splusb(); - ohci_add_ed(sed, sc->sc_ctrl_head); - splx(s); - break; - case UE_INTERRUPT: - pipe->methods = &ohci_device_intr_methods; - return (ohci_device_setintr(sc, opipe, ed->bInterval)); - case UE_ISOCHRONOUS: - printf("ohci_open: open iso unimplemented\n"); - return (USBD_XXX); - case UE_BULK: - pipe->methods = &ohci_device_bulk_methods; - s = splusb(); - ohci_add_ed(sed, sc->sc_bulk_head); - splx(s); - break; - } - } - return (USBD_NORMAL_COMPLETION); - - bad: - ohci_free_std(sc, std); - bad1: - ohci_free_sed(sc, sed); - bad0: - return (USBD_NOMEM); - -} - -/* - * Data structures and routines to emulate the root hub. - */ -usb_device_descriptor_t ohci_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x00, 0x01}, /* USB version */ - UCLASS_HUB, /* class */ - USUBCLASS_HUB, /* subclass */ - 0, /* protocol */ - 64, /* max packet */ - {0},{0},{0x00,0x01}, /* device id */ - 1,2,0, /* string indicies */ - 1 /* # of configurations */ -}; - -usb_config_descriptor_t ohci_confd = { - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, - 1, - 0, - UC_SELF_POWERED, - 0 /* max power */ -}; - -usb_interface_descriptor_t ohci_ifcd = { - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, - 0, - 1, - UCLASS_HUB, - USUBCLASS_HUB, - 0, - 0 -}; - -usb_endpoint_descriptor_t ohci_endpd = { - USB_ENDPOINT_DESCRIPTOR_SIZE, - UDESC_ENDPOINT, - UE_IN | OHCI_INTR_ENDPT, - UE_INTERRUPT, - {8, 0}, /* max packet */ - 255 -}; - -usb_hub_descriptor_t ohci_hubd = { - USB_HUB_DESCRIPTOR_SIZE, - UDESC_HUB, - 0, - {0,0}, - 0, - 0, - {0}, -}; - -int -ohci_str(p, l, s) - usb_string_descriptor_t *p; - int l; - char *s; -{ - int i; - - if (l == 0) - return (0); - p->bLength = 2 * strlen(s) + 2; - if (l == 1) - return (1); - p->bDescriptorType = UDESC_STRING; - l -= 2; - for (i = 0; s[i] && l > 1; i++, l -= 2) - USETW2(p->bString[i], 0, s[i]); - return (2*i+2); -} - -/* - * Simulate a hardware hub by handling all the necessary requests. - */ -usbd_status -ohci_root_ctrl_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (ohci_root_ctrl_start(reqh)); -} - -usbd_status -ohci_root_ctrl_start(reqh) - usbd_request_handle reqh; -{ - ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus; - usb_device_request_t *req; - void *buf; - int port, i; - int len, value, index, l, totlen = 0; - usb_port_status_t ps; - usb_hub_descriptor_t hubd; - usbd_status r; - u_int32_t v; - - if (!reqh->isreq) - /* XXX panic */ - return (USBD_INVAL); - req = &reqh->request; - buf = reqh->buffer; - - DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n", - req->bmRequestType, req->bRequest)); - - len = UGETW(req->wLength); - value = UGETW(req->wValue); - index = UGETW(req->wIndex); -#define C(x,y) ((x) | ((y) << 8)) - switch(C(req->bRequest, req->bmRequestType)) { - case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): - case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): - case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* - * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops - * for the integrated root hub. - */ - break; - case C(UR_GET_CONFIG, UT_READ_DEVICE): - if (len > 0) { - *(u_int8_t *)buf = sc->sc_conf; - totlen = 1; - } - break; - case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): - DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value)); - switch(value >> 8) { - case UDESC_DEVICE: - if ((value & 0xff) != 0) { - r = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - memcpy(buf, &ohci_devd, l); - break; - case UDESC_CONFIG: - if ((value & 0xff) != 0) { - r = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); - memcpy(buf, &ohci_confd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &ohci_ifcd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &ohci_endpd, l); - break; - case UDESC_STRING: - if (len == 0) - break; - *(u_int8_t *)buf = 0; - totlen = 1; - switch (value & 0xff) { - case 1: /* Vendor */ - totlen = ohci_str(buf, len, sc->sc_vendor); - break; - case 2: /* Product */ - totlen = ohci_str(buf, len, "OHCI root hub"); - break; - } - break; - default: - r = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_INTERFACE, UT_READ_INTERFACE): - if (len > 0) { - *(u_int8_t *)buf = 0; - totlen = 1; - } - break; - case C(UR_GET_STATUS, UT_READ_DEVICE): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); - totlen = 2; - } - break; - case C(UR_GET_STATUS, UT_READ_INTERFACE): - case C(UR_GET_STATUS, UT_READ_ENDPOINT): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus, 0); - totlen = 2; - } - break; - case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): - if (value >= USB_MAX_DEVICES) { - r = USBD_IOERROR; - goto ret; - } - sc->sc_addr = value; - break; - case C(UR_SET_CONFIG, UT_WRITE_DEVICE): - if (value != 0 && value != 1) { - r = USBD_IOERROR; - goto ret; - } - sc->sc_conf = value; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_DEVICE): - case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): - case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): - r = USBD_IOERROR; - goto ret; - case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): - break; - case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): - break; - /* Hub requests */ - case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): - break; - case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): - DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE " - "port=%d feature=%d\n", - index, value)); - if (index < 1 || index > sc->sc_noport) { - r = USBD_IOERROR; - goto ret; - } - port = OHCI_RH_PORT_STATUS(index); - switch(value) { - case UHF_PORT_ENABLE: - OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS); - break; - case UHF_PORT_SUSPEND: - OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR); - break; - case UHF_PORT_POWER: - OWRITE4(sc, port, UPS_LOW_SPEED); - break; - case UHF_C_PORT_CONNECTION: - OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16); - break; - case UHF_C_PORT_ENABLE: - OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16); - break; - case UHF_C_PORT_SUSPEND: - OWRITE4(sc, port, UPS_C_SUSPEND << 16); - break; - case UHF_C_PORT_OVER_CURRENT: - OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16); - break; - case UHF_C_PORT_RESET: - OWRITE4(sc, port, UPS_C_PORT_RESET << 16); - break; - default: - r = USBD_IOERROR; - goto ret; - } - switch(value) { - case UHF_C_PORT_CONNECTION: - case UHF_C_PORT_ENABLE: - case UHF_C_PORT_SUSPEND: - case UHF_C_PORT_OVER_CURRENT: - case UHF_C_PORT_RESET: - /* Enable RHSC interrupt if condition is cleared. */ - if ((OREAD4(sc, port) >> 16) == 0) - ohci_rhsc_able(sc, 1); - break; - default: - break; - } - break; - case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): - if (value != 0) { - r = USBD_IOERROR; - goto ret; - } - v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A); - hubd = ohci_hubd; - hubd.bNbrPorts = sc->sc_noport; - USETW(hubd.wHubCharacteristics, - (v & OHCI_NPS ? UHD_PWR_NO_SWITCH : - v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL) - /* XXX overcurrent */ - ); - hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v); - v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B); - for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8) - hubd.DeviceRemovable[i++] = (u_int8_t)v; - hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i; - l = min(len, hubd.bDescLength); - totlen = l; - memcpy(buf, &hubd, l); - break; - case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): - if (len != 4) { - r = USBD_IOERROR; - goto ret; - } - memset(buf, 0, len); /* ? XXX */ - totlen = len; - break; - case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): - DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n", - index)); - if (index < 1 || index > sc->sc_noport) { - r = USBD_IOERROR; - goto ret; - } - if (len != 4) { - r = USBD_IOERROR; - goto ret; - } - v = OREAD4(sc, OHCI_RH_PORT_STATUS(index)); - DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n", - v)); - USETW(ps.wPortStatus, v); - USETW(ps.wPortChange, v >> 16); - l = min(len, sizeof ps); - memcpy(buf, &ps, l); - totlen = l; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): - r = USBD_IOERROR; - goto ret; - case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): - if (index < 1 || index > sc->sc_noport) { - r = USBD_IOERROR; - goto ret; - } - port = OHCI_RH_PORT_STATUS(index); - switch(value) { - case UHF_PORT_ENABLE: - OWRITE4(sc, port, UPS_PORT_ENABLED); - break; - case UHF_PORT_SUSPEND: - OWRITE4(sc, port, UPS_SUSPEND); - break; - case UHF_PORT_RESET: - DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n", - index)); - OWRITE4(sc, port, UPS_RESET); - for (i = 0; i < 10; i++) { - usb_delay_ms(&sc->sc_bus, 10); - if ((OREAD4(sc, port) & UPS_RESET) == 0) - break; - } - DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n", - index, OREAD4(sc, port))); - break; - case UHF_PORT_POWER: - DPRINTFN(2,("ohci_root_ctrl_transfer: set port power " - "%d\n", index)); - OWRITE4(sc, port, UPS_PORT_POWER); - break; - default: - r = USBD_IOERROR; - goto ret; - } - break; - default: - r = USBD_IOERROR; - goto ret; - } - reqh->actlen = totlen; - r = USBD_NORMAL_COMPLETION; - ret: - reqh->status = r; - reqh->xfercb(reqh); - usb_start_next(reqh->pipe); - return (USBD_IN_PROGRESS); -} - -/* Abort a root control request. */ -void -ohci_root_ctrl_abort(reqh) - usbd_request_handle reqh; -{ - /* Nothing to do, all transfers are synchronous. */ -} - -/* Close the root pipe. */ -void -ohci_root_ctrl_close(pipe) - usbd_pipe_handle pipe; -{ - DPRINTF(("ohci_root_ctrl_close\n")); -} - -usbd_status -ohci_root_intr_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (ohci_root_intr_start(reqh)); -} - -usbd_status -ohci_root_intr_start(reqh) - usbd_request_handle reqh; -{ - usbd_pipe_handle pipe = reqh->pipe; - ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus; - struct ohci_pipe *upipe = (struct ohci_pipe *)pipe; - usb_dma_t *dmap; - usbd_status r; - int len; - - len = reqh->length; - dmap = &upipe->u.intr.datadma; - if (len == 0) - return (USBD_INVAL); /* XXX should it be? */ - - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - return (r); - sc->sc_intrreqh = reqh; - - return (USBD_IN_PROGRESS); -} - -/* Abort a root interrupt request. */ -void -ohci_root_intr_abort(reqh) - usbd_request_handle reqh; -{ - /* No need to abort. */ -} - -/* Close the root pipe. */ -void -ohci_root_intr_close(pipe) - usbd_pipe_handle pipe; -{ - ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus; - sc->sc_intrreqh = 0; - - DPRINTF(("ohci_root_intr_close\n")); -} - -/************************/ - -usbd_status -ohci_device_ctrl_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (ohci_device_ctrl_start(reqh)); -} - -usbd_status -ohci_device_ctrl_start(reqh) - usbd_request_handle reqh; -{ - ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus; - usbd_status r; - - if (!reqh->isreq) { - /* XXX panic */ - printf("ohci_device_ctrl_transfer: not a request\n"); - return (USBD_INVAL); - } - - r = ohci_device_request(reqh); - if (r != USBD_NORMAL_COMPLETION) - return (r); - - if (sc->sc_bus.use_polling) - ohci_waitintr(sc, reqh); - return (USBD_IN_PROGRESS); -} - -/* Abort a device control request. */ -void -ohci_device_ctrl_abort(reqh) - usbd_request_handle reqh; -{ - /* XXX inactivate */ - usb_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is donw */ - /* XXX call done */ -} - -/* Close a device control pipe. */ -void -ohci_device_ctrl_close(pipe) - usbd_pipe_handle pipe; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus; - ohci_soft_ed_t *sed = opipe->sed; - int s; - - s = splusb(); - sed->ed->ed_flags |= LE(OHCI_ED_SKIP); - if ((LE(sed->ed->ed_tailp) & OHCI_TAILMASK) != LE(sed->ed->ed_headp)) - usb_delay_ms(&sc->sc_bus, 2); - ohci_rem_ed(sed, sc->sc_ctrl_head); - splx(s); - ohci_free_std(sc, opipe->tail); - ohci_free_sed(sc, opipe->sed); - /* XXX free other resources */ -} - -/************************/ - -usbd_status -ohci_device_bulk_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (ohci_device_bulk_start(reqh)); -} - -usbd_status -ohci_device_bulk_start(reqh) - usbd_request_handle reqh; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe; - usbd_device_handle dev = opipe->pipe.device; - ohci_softc_t *sc = (ohci_softc_t *)dev->bus; - int addr = dev->address; - ohci_soft_td_t *xfer, *tail; - ohci_soft_ed_t *sed; - usb_dma_t *dmap; - usbd_status r; - int s, len, isread; - - if (reqh->isreq) { - /* XXX panic */ - printf("ohci_device_bulk_transfer: a request\n"); - return (USBD_INVAL); - } - - len = reqh->length; - dmap = &opipe->u.bulk.datadma; - isread = reqh->pipe->endpoint->edesc->bEndpointAddress & UE_IN; - sed = opipe->sed; - - opipe->u.bulk.length = len; - - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - goto ret1; - - tail = ohci_alloc_std(sc); - if (!tail) { - r = USBD_NOMEM; - goto ret2; - } - tail->reqh = 0; - - /* Update device address */ - sed->ed->ed_flags = LE( - (LE(sed->ed->ed_flags) & ~OHCI_ED_ADDRMASK) | - OHCI_ED_SET_FA(addr)); - - /* Set up data transaction */ - xfer = opipe->tail; - xfer->td->td_flags = LE( - (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC | - OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY | - (reqh->flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0)); - xfer->td->td_cbp = LE(DMAADDR(dmap)); - xfer->nexttd = tail; - xfer->td->td_nexttd = LE(tail->physaddr); - xfer->td->td_be = LE(LE(xfer->td->td_cbp) + len - 1); - xfer->len = len; - xfer->reqh = reqh; - - reqh->hcpriv = xfer; - - if (!isread) - memcpy(KERNADDR(dmap), reqh->buffer, len); - - /* Insert ED in schedule */ - s = splusb(); - ohci_hash_add_td(sc, xfer); - sed->ed->ed_tailp = LE(tail->physaddr); - opipe->tail = tail; - OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); - if (reqh->timeout && !sc->sc_bus.use_polling) { - usb_timeout(ohci_timeout, reqh, - MS_TO_TICKS(reqh->timeout), reqh->timo_handle); - } - splx(s); - - return (USBD_IN_PROGRESS); - - ret2: - usb_freemem(sc->sc_dmatag, dmap); - ret1: - return (r); -} - -/* Abort a device bulk request. */ -void -ohci_device_bulk_abort(reqh) - usbd_request_handle reqh; -{ -#if 0 - sed->ed->ed_flags |= LE(OHCI_ED_SKIP); - if ((LE(sed->ed->ed_tailp) & OHCI_TAILMASK) != LE(sed->ed->ed_headp)) - usb_delay_ms(reqh->pipe->device->bus, 2); -#endif - /* XXX inactivate */ - usb_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is done */ - /* XXX call done */ -} - -/* Close a device bulk pipe. */ -void -ohci_device_bulk_close(pipe) - usbd_pipe_handle pipe; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - usbd_device_handle dev = opipe->pipe.device; - ohci_softc_t *sc = (ohci_softc_t *)dev->bus; - int s; - - s = splusb(); - ohci_rem_ed(opipe->sed, sc->sc_bulk_head); - splx(s); - ohci_free_std(sc, opipe->tail); - ohci_free_sed(sc, opipe->sed); - /* XXX free other resources */ -} - -/************************/ - -usbd_status -ohci_device_intr_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (ohci_device_intr_start(reqh)); -} - -usbd_status -ohci_device_intr_start(reqh) - usbd_request_handle reqh; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe; - usbd_device_handle dev = opipe->pipe.device; - ohci_softc_t *sc = (ohci_softc_t *)dev->bus; - ohci_soft_ed_t *sed = opipe->sed; - ohci_soft_td_t *xfer, *tail; - usb_dma_t *dmap; - usbd_status r; - int len; - int s; - - DPRINTFN(3, ("ohci_device_intr_transfer: reqh=%p buf=%p len=%d " - "flags=%d priv=%p\n", - reqh, reqh->buffer, reqh->length, reqh->flags, reqh->priv)); - - if (reqh->isreq) - panic("ohci_device_intr_transfer: a request\n"); - - len = reqh->length; - dmap = &opipe->u.intr.datadma; - if (len == 0) - return (USBD_INVAL); /* XXX should it be? */ - - xfer = opipe->tail; - tail = ohci_alloc_std(sc); - if (!tail) { - r = USBD_NOMEM; - goto ret1; - } - tail->reqh = 0; - - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - goto ret2; - - xfer->td->td_flags = LE( - OHCI_TD_IN | OHCI_TD_NOCC | - OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); - if (reqh->flags & USBD_SHORT_XFER_OK) - xfer->td->td_flags |= LE(OHCI_TD_R); - xfer->td->td_cbp = LE(DMAADDR(dmap)); - xfer->nexttd = tail; - xfer->td->td_nexttd = LE(tail->physaddr); - xfer->td->td_be = LE(LE(xfer->td->td_cbp) + len - 1); - xfer->len = len; - xfer->reqh = reqh; - - reqh->hcpriv = xfer; - -#if USB_DEBUG - if (ohcidebug > 5) { - printf("ohci_device_intr_transfer:\n"); - ohci_dump_ed(sed); - ohci_dump_tds(xfer); - } -#endif - - /* Insert ED in schedule */ - s = splusb(); - ohci_hash_add_td(sc, xfer); - sed->ed->ed_tailp = LE(tail->physaddr); - opipe->tail = tail; -#if 0 - if (reqh->timeout && !sc->sc_bus.use_polling) { - usb_timeout(ohci_timeout, reqh, - MS_TO_TICKS(reqh->timeout), reqh->timo_handle); - } -#endif - sed->ed->ed_flags &= LE(~OHCI_ED_SKIP); - -#ifdef USB_DEBUG - if (ohcidebug > 5) { - delay(5000); - printf("ohci_device_intr_transfer: status=%x\n", - OREAD4(sc, OHCI_COMMAND_STATUS)); - ohci_dump_ed(sed); - ohci_dump_tds(xfer); - } -#endif - /* moved splx(s) because of indefinite printing of TD's */ - splx(s); - - return (USBD_IN_PROGRESS); - - ret2: - ohci_free_std(sc, xfer); - ret1: - return (r); -} - -/* Abort a device control request. */ -void -ohci_device_intr_abort(reqh) - usbd_request_handle reqh; -{ - /* XXX inactivate */ - usb_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is done */ - if (reqh->pipe->intrreqh == reqh) { - DPRINTF(("ohci_device_intr_abort: remove\n")); - reqh->pipe->intrreqh = 0; - ohci_intr_done((ohci_softc_t *)reqh->pipe->device->bus, reqh); - } -} - -/* Close a device interrupt pipe. */ -void -ohci_device_intr_close(pipe) - usbd_pipe_handle pipe; -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus; - int nslots = opipe->u.intr.nslots; - int pos = opipe->u.intr.pos; - int j; - ohci_soft_ed_t *p, *sed = opipe->sed; - int s; - - DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n", - pipe, nslots, pos)); - s = splusb(); - sed->ed->ed_flags |= LE(OHCI_ED_SKIP); - if ((sed->ed->ed_tailp & LE(OHCI_TAILMASK)) != sed->ed->ed_headp) - usb_delay_ms(&sc->sc_bus, 2); - - for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next) - ; - if (!p) - panic("ohci_device_intr_close: ED not found\n"); - p->next = sed->next; - p->ed->ed_nexted = sed->ed->ed_nexted; - splx(s); - - for (j = 0; j < nslots; j++) - --sc->sc_bws[pos * nslots + j]; - - ohci_free_std(sc, opipe->tail); - ohci_free_sed(sc, opipe->sed); - /* XXX free other resources */ -} - -usbd_status -ohci_device_setintr(sc, opipe, ival) - ohci_softc_t *sc; - struct ohci_pipe *opipe; - int ival; -{ - int i, j, s, best; - u_int npoll, slow, shigh, nslots; - u_int bestbw, bw; - ohci_soft_ed_t *hsed, *sed = opipe->sed; - - DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe)); - if (ival == 0) { - printf("ohci_setintr: 0 interval\n"); - return (USBD_INVAL); - } - - npoll = OHCI_NO_INTRS; - while (npoll > ival) - npoll /= 2; - DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll)); - - /* - * We now know which level in the tree the ED must go into. - * Figure out which slot has most bandwidth left over. - * Slots to examine: - * npoll - * 1 0 - * 2 1 2 - * 4 3 4 5 6 - * 8 7 8 9 10 11 12 13 14 - * N (N-1) .. (N-1+N-1) - */ - slow = npoll-1; - shigh = slow + npoll; - nslots = OHCI_NO_INTRS / npoll; - for (best = i = slow, bestbw = ~0; i < shigh; i++) { - bw = 0; - for (j = 0; j < nslots; j++) - bw += sc->sc_bws[i * nslots + j]; - if (bw < bestbw) { - best = i; - bestbw = bw; - } - } - DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n", - best, slow, shigh, bestbw)); - - s = splusb(); - hsed = sc->sc_eds[best]; - sed->next = hsed->next; - sed->ed->ed_nexted = hsed->ed->ed_nexted; - hsed->next = sed; - hsed->ed->ed_nexted = LE(sed->physaddr); - splx(s); - - for (j = 0; j < nslots; j++) - ++sc->sc_bws[best * nslots + j]; - opipe->u.intr.nslots = nslots; - opipe->u.intr.pos = best; - - DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe)); - return (USBD_NORMAL_COMPLETION); -} - diff --git a/sys/dev/usb/ohcireg.h b/sys/dev/usb/ohcireg.h deleted file mode 100644 index bd44e8be40711..0000000000000 --- a/sys/dev/usb/ohcireg.h +++ /dev/null @@ -1,208 +0,0 @@ -/* $NetBSD: ohcireg.h,v 1.7 1998/12/10 23:16:47 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_PCI_OHCIREG_H_ -#define _DEV_PCI_OHCIREG_H_ - -/*** PCI config registers ***/ - -#define PCI_CBMEM 0x10 /* configuration base memory */ - -#define PCI_INTERFACE_OHCI 0x10 - -/*** OHCI registers */ - -#define OHCI_REVISION 0x00 /* OHCI revision # */ -#define OHCI_REV_LO(rev) ((rev)&0xf) -#define OHCI_REV_HI(rev) (((rev)>>4)&0xf) -#define OHCI_REV_LEGACY(rev) ((rev) & 0x100) - -#define OHCI_CONTROL 0x04 -#define OHCI_CBSR_MASK 0x00000003 /* Control/Bulk Service Ratio */ -#define OHCI_RATIO_1_1 0x00000000 -#define OHCI_RATIO_1_2 0x00000001 -#define OHCI_RATIO_1_3 0x00000002 -#define OHCI_RATIO_1_4 0x00000003 -#define OHCI_PLE 0x00000004 /* Periodic List Enable */ -#define OHCI_IE 0x00000008 /* Isochronous Enable */ -#define OHCI_CLE 0x00000010 /* Control List Enable */ -#define OHCI_BLE 0x00000020 /* Bulk List Enable */ -#define OHCI_HCFS_MASK 0x000000c0 /* HostControllerFunctionalState */ -#define OHCI_HCFS_RESET 0x00000000 -#define OHCI_HCFS_RESUME 0x00000040 -#define OHCI_HCFS_OPERATIONAL 0x00000080 -#define OHCI_HCFS_SUSPEND 0x000000c0 -#define OHCI_IR 0x00000100 /* Interrupt Routing */ -#define OHCI_RWC 0x00000200 /* Remote Wakeup Connected */ -#define OHCI_RWE 0x00000400 /* Remote Wakeup Enabled */ -#define OHCI_COMMAND_STATUS 0x08 -#define OHCI_HCR 0x00000001 /* Host Controller Reset */ -#define OHCI_CLF 0x00000002 /* Control List Filled */ -#define OHCI_BLF 0x00000004 /* Bulk List Filled */ -#define OHCI_OCR 0x00000008 /* Ownership Change Request */ -#define OHCI_SOC_MASK 0x00030000 /* Scheduling Overrun Count */ -#define OHCI_INTERRUPT_STATUS 0x0c -#define OHCI_SO 0x00000001 /* Scheduling Overrun */ -#define OHCI_WDH 0x00000002 /* Writeback Done Head */ -#define OHCI_SF 0x00000004 /* Start of Frame */ -#define OHCI_RD 0x00000008 /* Resume Detected */ -#define OHCI_UE 0x00000010 /* Unrecoverable Error */ -#define OHCI_FNO 0x00000020 /* Frame Number Overflow */ -#define OHCI_RHSC 0x00000040 /* Root Hub Status Change */ -#define OHCI_OC 0x40000000 /* Ownership Change */ -#define OHCI_MIE 0x80000000 /* Master Interrupt Enable */ -#define OHCI_INTERRUPT_ENABLE 0x10 -#define OHCI_INTERRUPT_DISABLE 0x14 -#define OHCI_HCCA 0x18 -#define OHCI_PERIOD_CURRENT_ED 0x1c -#define OHCI_CONTROL_HEAD_ED 0x20 -#define OHCI_CONTROL_CURRENT_ED 0x24 -#define OHCI_BULK_HEAD_ED 0x28 -#define OHCI_BULK_CURRENT_ED 0x2c -#define OHCI_DONE_HEAD 0x30 -#define OHCI_FM_INTERVAL 0x34 -#define OHCI_GET_IVAL(s) ((s) & 0x3fff) -#define OHCI_GET_FSMPS(s) (((s) >> 16) & 0x7fff) -#define OHCI_FIT 0x80000000 -#define OHCI_FM_REMAINING 0x38 -#define OHCI_FM_NUMBER 0x3c -#define OHCI_PERIODIC_START 0x40 -#define OHCI_LS_THRESHOLD 0x44 -#define OHCI_RH_DESCRIPTOR_A 0x48 -#define OHCI_GET_NDP(s) ((s) & 0xff) -#define OHCI_PSM 0x0100 /* Power Switching Mode */ -#define OHCI_NPS 0x0200 /* No Power Switching */ -#define OHCI_GET_POTPGT(s) ((s) >> 24) -#define OHCI_RH_DESCRIPTOR_B 0x4c -#define OHCI_RH_STATUS 0x50 -#define OHCI_LPS 0x00000001 /* Local Power Status */ -#define OHCI_OCI 0x00000002 /* OverCurrent Indicator */ -#define OHCI_DRWE 0x00008000 /* Device Remote Wakeup Enable */ -#define OHCI_LPSC 0x00010000 /* Local Power Status Change */ -#define OHCI_CCIC 0x00020000 /* OverCurrent Indicator Change */ -#define OHCI_CRWE 0x80000000 /* Clear Remote Wakeup Enable */ -#define OHCI_RH_PORT_STATUS(n) (0x50 + (n)*4) /* 1 based indexing */ - -#define OHCI_LES (OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE) -#define OHCI_ALL_INTRS (OHCI_SO | OHCI_WDH | OHCI_SF | OHCI_RD | OHCI_UE | \ - OHCI_FNO | OHCI_RHSC | OHCI_OC) -#define OHCI_NORMAL_INTRS (OHCI_SO | OHCI_WDH | OHCI_RD | OHCI_UE | OHCI_RHSC) - -#define OHCI_FSMPS(i) (((i-210)*6/7) << 16) -#define OHCI_PERIODIC(i) ((i)*9/10) - -typedef u_int32_t ohci_physaddr_t; - -#define OHCI_NO_INTRS 32 -struct ohci_hcca { - ohci_physaddr_t hcca_interrupt_table[OHCI_NO_INTRS]; - u_int32_t hcca_frame_number; - ohci_physaddr_t hcca_done_head; -#define OHCI_DONE_INTRS 1 -}; -#define OHCI_HCCA_SIZE 256 -#define OHCI_HCCA_ALIGN 256 - -typedef struct { - u_int32_t ed_flags; -#define OHCI_ED_GET_FA(s) ((s) & 0x7f) -#define OHCI_ED_ADDRMASK 0x0000007f -#define OHCI_ED_SET_FA(s) (s) -#define OHCI_ED_GET_EN(s) (((s) >> 7) & 0xf) -#define OHCI_ED_SET_EN(s) ((s) << 7) -#define OHCI_ED_DIR_MASK 0x00001800 -#define OHCI_ED_DIR_TD 0x00000000 -#define OHCI_ED_DIR_OUT 0x00000800 -#define OHCI_ED_DIR_IN 0x00001000 -#define OHCI_ED_SPEED 0x00002000 -#define OHCI_ED_SKIP 0x00004000 -#define OHCI_ED_FORMAT_GEN 0x00000000 -#define OHCI_ED_FORMAT_ISO 0x00008000 -#define OHCI_ED_GET_MAXP(s) (((s) >> 16) & 0x07ff) -#define OHCI_ED_SET_MAXP(s) ((s) << 16) -#define OHCI_ED_MAXPMASK (0x7ff << 16) - ohci_physaddr_t ed_tailp; -#define OHCI_HALTED 0x00000002 -#define OHCI_TOGGLECARRY 0x00000001 -#define OHCI_TAILMASK 0xfffffffc - ohci_physaddr_t ed_headp; - ohci_physaddr_t ed_nexted; -} ohci_ed_t; -#define OHCI_ED_SIZE 16 -#define OHCI_ED_ALIGN 16 - -typedef struct { - u_int32_t td_flags; -#define OHCI_TD_R 0x00040000 /* Buffer Rounding */ -#define OHCI_TD_DP_MASK 0x00180000 /* Direction / PID */ -#define OHCI_TD_SETUP 0x00000000 -#define OHCI_TD_OUT 0x00080000 -#define OHCI_TD_IN 0x00100000 -#define OHCI_TD_GET_DI(x) (((x) >> 21) & 7) /* Delay Interrupt */ -#define OHCI_TD_SET_DI(x) ((x) << 21) -#define OHCI_TD_NOINTR 0x00e00000 -#define OHCI_TD_TOGGLE_CARRY 0x00000000 -#define OHCI_TD_TOGGLE_0 0x02000000 -#define OHCI_TD_TOGGLE_1 0x03000000 -#define OHCI_TD_GET_EC(x) (((x) >> 26) & 3) /* Error Count */ -#define OHCI_TD_GET_CC(x) ((x) >> 28) /* Condition Code */ -#define OHCI_TD_NOCC 0xf0000000 - ohci_physaddr_t td_cbp; /* Current Buffer Pointer */ - 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_ALIGN 16 - -#define OHCI_CC_NO_ERROR 0 -#define OHCI_CC_CRC 1 -#define OHCI_CC_BIT_STUFFING 2 -#define OHCI_CC_DATA_TOGGLE_MISMATCH 3 -#define OHCI_CC_STALL 4 -#define OHCI_CC_DEVICE_NOT_RESPONDING 5 -#define OHCI_CC_PID_CHECK_FAILURE 6 -#define OHCI_CC_UNEXPECTED_PID 7 -#define OHCI_CC_DATA_OVERRUN 8 -#define OHCI_CC_DATA_UNDERRUN 9 -#define OHCI_CC_BUFFER_OVERRUN 12 -#define OHCI_CC_BUFFER_UNDERRUN 13 -#define OHCI_CC_NOT_ACCESSED 15 - -#endif /* _DEV_PCI_OHCIREG_H_ */ diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h deleted file mode 100644 index db8631f7976e1..0000000000000 --- a/sys/dev/usb/ohcivar.h +++ /dev/null @@ -1,115 +0,0 @@ -/* $NetBSD: ohcivar.h,v 1.4 1998/12/26 12:53:01 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -typedef struct ohci_soft_ed { - ohci_ed_t *ed; - struct ohci_soft_ed *next; - ohci_physaddr_t physaddr; -} ohci_soft_ed_t; -#define OHCI_ED_CHUNK 256 - -typedef struct ohci_soft_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; -} ohci_soft_td_t; -#define OHCI_TD_CHUNK 256 - -#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1) - -#define OHCI_HASH_SIZE 128 - -typedef struct ohci_softc { - struct usbd_bus sc_bus; /* base device */ -#if defined(__NetBSD__) - void *sc_ih; /* interrupt vectoring */ - bus_space_tag_t iot; - bus_space_handle_t ioh; - - bus_dma_tag_t sc_dmatag; /* DMA tag */ - /* XXX should keep track of all DMA memory */ - -#elif defined(__FreeBSD__) - int sc_iobase; - int unit; -#endif /* __FreeBSD__ */ - - usb_dma_t sc_hccadma; - struct ohci_hcca *sc_hcca; - ohci_soft_ed_t *sc_eds[OHCI_NO_EDS]; - u_int sc_bws[OHCI_NO_INTRS]; - - u_int32_t sc_eintrs; - ohci_soft_ed_t *sc_ctrl_head; - ohci_soft_ed_t *sc_bulk_head; - - LIST_HEAD(, ohci_soft_td) sc_hash_tds[OHCI_HASH_SIZE]; - - int sc_noport; - u_int8_t sc_addr; /* device address */ - u_int8_t sc_conf; /* device configuration */ - - ohci_soft_ed_t *sc_freeeds; - ohci_soft_td_t *sc_freetds; - - usbd_request_handle sc_intrreqh; - - int sc_intrs; - char sc_vendor[16]; -} ohci_softc_t; - -usbd_status ohci_init __P((ohci_softc_t *)); -int ohci_intr __P((void *)); - -#define MS_TO_TICKS(ms) ((ms) * hz / 1000) - -#ifdef USB_DEBUG -#define DPRINTF(x) if (ohcidebug) printf x -#define DPRINTFN(n,x) if (ohcidebug>(n)) printf x -extern int ohcidebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c deleted file mode 100644 index 749cad455f3f3..0000000000000 --- a/sys/dev/usb/ucom.c +++ /dev/null @@ -1,139 +0,0 @@ -/* $NetBSD: ucom.c,v 1.6 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <dev/usb/usb_port.h> - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#include <sys/ioctl.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/ioccom.h> -#include <sys/conf.h> -#endif -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/select.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/poll.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbhid.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdevs.h> -#include <dev/usb/usb_quirks.h> -#include <dev/usb/hid.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) if (ucomdebug) printf x -#define DPRINTFN(n,x) if (ucomdebug>(n)) printf x -int ucomdebug = 1; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -struct ucom_softc { - bdevice sc_dev; /* base device */ - usbd_interface_handle sc_iface; /* interface */ -}; - -void ucom_intr __P((usbd_request_handle, usbd_private_handle, usbd_status)); -void ucom_disco __P((void *)); - -USB_DECLARE_DRIVER(ucom); - -USB_MATCH(ucom) -{ - USB_MATCH_START(ucom, uaa); - usb_interface_descriptor_t *id; - - if (!uaa->iface) - return (UMATCH_NONE); - id = usbd_get_interface_descriptor(uaa->iface); - if (id && - id->bInterfaceClass != UCLASS_CDC || - id->bInterfaceSubClass != USUBCLASS_ABSTRACT_CONTROL_MODEL) - return (UMATCH_NONE); - return (UMATCH_IFACECLASS_IFACESUBCLASS); -} - -USB_ATTACH(ucom) -{ - USB_ATTACH_START(ucom, sc, uaa); - usbd_interface_handle iface = uaa->iface; - usb_interface_descriptor_t *id; - char devinfo[1024]; - - sc->sc_iface = iface; - id = usbd_get_interface_descriptor(iface); - usbd_devinfo(uaa->device, 0, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev), - devinfo, id->bInterfaceClass, id->bInterfaceSubClass); - - USB_ATTACH_SUCCESS_RETURN; -} - -#if defined(__FreeBSD__) -static int -ucom_detach(device_t self) -{ - char *devinfo = (char *) device_get_desc(self); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - return 0; -} -#endif - -#if defined(__FreeBSD__) -DRIVER_MODULE(ucom, uhub, ucom_driver, ucom_devclass, usbd_driver_load, 0); -#endif diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c deleted file mode 100644 index f739b4b642c95..0000000000000 --- a/sys/dev/usb/ugen.c +++ /dev/null @@ -1,985 +0,0 @@ -/* $NetBSD: ugen.c,v 1.11 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#include <sys/ioctl.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/ioccom.h> -#include <sys/conf.h> -#include <sys/fcntl.h> -#include <sys/filio.h> -#endif -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/select.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/poll.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) if (ugendebug) printf x -#define DPRINTFN(n,x) if (ugendebug>(n)) printf x -int ugendebug = 1; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -struct ugen_endpoint { - struct ugen_softc *sc; - 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; -}; - -#define UGEN_CHUNK 128 /* chunk size for read */ -#define UGEN_IBSIZE 1020 /* buffer size */ -#define UGEN_BBSIZE 1024 - -struct ugen_softc { - bdevice sc_dev; /* base device */ - struct usbd_device *sc_udev; - - 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 */ - - int sc_disconnected; /* device is gone */ -}; - -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 *)); -void ugenintr __P((usbd_request_handle reqh, usbd_private_handle addr, - usbd_status status)); -void ugen_disco __P((void *)); - -#define UGEN_CDEV_MAJOR 114 - -int ugen_set_config __P((struct ugen_softc *sc, int configno)); -usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, int index, - int *lenp)); -usbd_status ugen_set_interface __P((struct ugen_softc *, int, int)); -int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx)); - -#define UGENUNIT(n) (((n) >> 4) & 0xf) -#define UGENENDPOINT(n) ((n) & 0xf) - -USB_DECLARE_DRIVER(ugen); - -USB_MATCH(ugen) -{ - USB_MATCH_START(ugen, uaa); - - if (uaa->usegeneric) - return (UMATCH_GENERIC); - else - return (UMATCH_NONE); -} - -USB_ATTACH(ugen) -{ - USB_ATTACH_START(ugen, sc, uaa); - char devinfo[1024]; - usbd_status r; - int conf; - - usbd_devinfo(uaa->device, 0, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); - - sc->sc_udev = uaa->device; - conf = 1; /* XXX should not hard code 1 */ - r = ugen_set_config(sc, conf); - if (r != USBD_NORMAL_COMPLETION) { - printf("%s: setting configuration %d failed\n", - USBDEVNAME(sc->sc_dev), conf); - sc->sc_disconnected = 1; - USB_ATTACH_ERROR_RETURN; - } - USB_ATTACH_SUCCESS_RETURN; -} - -int -ugen_set_config(sc, configno) - struct ugen_softc *sc; - int configno; -{ - usbd_device_handle dev = sc->sc_udev; - usbd_interface_handle iface; - usb_endpoint_descriptor_t *ed; - struct ugen_endpoint *sce; - u_int8_t niface, nendpt; - int ifaceno, endptno, endpt; - usbd_status r; - - DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n", - USBDEVNAME(sc->sc_dev), configno, sc)); - if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) { - /* Avoid setting the current value. */ - r = usbd_set_config_no(dev, configno, 0); - if (r != USBD_NORMAL_COMPLETION) - return (r); - } - - r = usbd_interface_count(dev, &niface); - if (r != USBD_NORMAL_COMPLETION) - return (r); - memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); - for (ifaceno = 0; ifaceno < niface; ifaceno++) { - DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); - r = usbd_device2interface_handle(dev, ifaceno, &iface); - if (r != USBD_NORMAL_COMPLETION) - return (r); - r = usbd_endpoint_count(iface, &nendpt); - if (r != USBD_NORMAL_COMPLETION) - return (r); - 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)]; - 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)); - sce->sc = sc; - sce->edesc = ed; - sce->iface = iface; - } - } - 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; - int flag; - int mode; - struct proc *p; -{ - int unit = UGENUNIT(dev); - int endpt = UGENENDPOINT(dev); - usb_endpoint_descriptor_t *edesc; - struct ugen_endpoint *sce; - int dir, isize; - usbd_status r; - - USB_GET_SC_OPEN(ugen, unit, sc); - DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n", - flag, mode, unit, endpt)); - - if (sc->sc_disconnected) - return (EIO); - - 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) - return (EBUSY); - } else { - switch (flag & (FWRITE|FREAD)) { - case FWRITE: - dir = OUT; - break; - case FREAD: - dir = IN; - break; - default: - return (EACCES); - } - sce = &sc->sc_endpoints[endpt][dir]; - 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); - switch (edesc->bmAttributes & UE_XFERTYPE) { - case UE_INTERRUPT: - isize = UGETW(edesc->wMaxPacketSize); - if (isize == 0) /* shouldn't happen */ - return (EINVAL); - sce->ibuf = malloc(isize, M_USB, 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); -#elif defined(__FreeBSD__) - clist_alloc_cblocks(&sce->q, UGEN_IBSIZE, 0); -#endif - r = usbd_open_pipe_intr(sce->iface, - edesc->bEndpointAddress, - USBD_SHORT_XFER_OK, &sce->pipeh, sce, - sce->ibuf, isize, ugenintr); - if (r != USBD_NORMAL_COMPLETION) { - free(sce->ibuf, M_USB); -#if defined(__NetBSD__) - 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: - r = usbd_open_pipe(sce->iface, - edesc->bEndpointAddress, 0, - &sce->pipeh); - if (r != USBD_NORMAL_COMPLETION) - return (EIO); - break; - case UE_CONTROL: - case UE_ISOCHRONOUS: - return (EINVAL); - } - } - sce->state |= UGEN_OPEN; - return (0); -} - -int -ugenclose(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - USB_GET_SC(ugen, UGENUNIT(dev), sc); - int endpt = UGENENDPOINT(dev); - struct ugen_endpoint *sce; - int dir; - - DPRINTFN(5, ("ugenclose: flag=%d, mode=%d\n", flag, mode)); - if (sc->sc_disconnected) - return (EIO); - - if (endpt == USB_CONTROL_ENDPOINT) { - DPRINTFN(5, ("ugenclose: close control\n")); - sc->sc_endpoints[endpt][OUT].state = 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; - } - } - } - - return (0); -} - -int -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 = &sc->sc_endpoints[endpt][IN]; - u_int32_t n, tn; - char buf[UGEN_BBSIZE]; - usbd_request_handle reqh; - usbd_status r; - int s; - int error = 0; - u_char buffer[UGEN_CHUNK]; - - DPRINTFN(5, ("ugenread: %d:%d\n", UGENUNIT(dev), UGENENDPOINT(dev))); - if (sc->sc_disconnected) - return (EIO); - -#ifdef DIAGNOSTIC - if (!sce->edesc) { - printf("ugenread: no edesc\n"); - return (EIO); - } - if (!sce->pipeh) { - printf("ugenread: no pipe\n"); - return (EIO); - } -#endif - - switch (sce->edesc->bmAttributes & UE_XFERTYPE) { - case UE_INTERRUPT: - /* Block until activity occured. */ - s = splusb(); - while (sce->q.c_cc == 0) { - if (flag & IO_NDELAY) { - splx(s); - return (EWOULDBLOCK); - } - sce->state |= UGEN_ASLP; - DPRINTFN(5, ("ugenread: sleep on %p\n", sc)); - error = tsleep((caddr_t)sce, PZERO | PCATCH, - "ugenri", 0); - DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); - if (error) { - sce->state &= ~UGEN_ASLP; - splx(s); - return (error); - } - } - splx(s); - - /* Transfer as many chunks as possible. */ - while (sce->q.c_cc > 0 && uio->uio_resid > 0) { - n = min(sce->q.c_cc, uio->uio_resid); - if (n > sizeof(buffer)) - n = sizeof(buffer); - - /* Remove a small chunk from the input queue. */ - q_to_b(&sce->q, buffer, n); - DPRINTFN(5, ("ugenread: got %d chars\n", n)); - - /* Copy the data to the user process. */ - error = uiomove(buffer, n, uio); - if (error) - break; - } - break; - case UE_BULK: - reqh = usbd_alloc_request(); - if (reqh == 0) - return (ENOMEM); - while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { - DPRINTFN(1, ("ugenread: start transfer %d bytes\n", n)); - tn = n; - r = usbd_bulk_transfer(reqh, sce->pipeh, 0, buf, - &tn, "ugenrb"); - if (r != USBD_NORMAL_COMPLETION) { - if (r == USBD_INTERRUPTED) - error = EINTR; - else - error = EIO; - break; - } - DPRINTFN(1, ("ugenread: got %d bytes\n", tn)); - error = uiomove(buf, tn, uio); - if (error || tn < n) - break; - } - usbd_free_request(reqh); - break; - default: - return (ENXIO); - } - - 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); - struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; - size_t n; - int error = 0; - char buf[UGEN_BBSIZE]; - usbd_request_handle reqh; - usbd_status r; - - if (sc->sc_disconnected) - return (EIO); - -#ifdef DIAGNOSTIC - if (!sce->edesc) { - printf("ugenwrite: no edesc\n"); - return (EIO); - } - if (!sce->pipeh) { - printf("ugenwrite: no pipe\n"); - return (EIO); - } -#endif - - DPRINTF(("ugenwrite\n")); - switch (sce->edesc->bmAttributes & UE_XFERTYPE) { - case UE_BULK: - reqh = usbd_alloc_request(); - if (reqh == 0) - return (EIO); - while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { - error = uiomove(buf, n, uio); - if (error) - break; - DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); - r = usbd_bulk_transfer(reqh, sce->pipeh, 0, buf, - &n, "ugenwb"); - if (r != USBD_NORMAL_COMPLETION) { - if (r == USBD_INTERRUPTED) - error = EINTR; - else - error = EIO; - break; - } - } - usbd_free_request(reqh); - break; - default: - return (ENXIO); - } - return (error); -} - - -void -ugenintr(reqh, addr, status) - usbd_request_handle reqh; - usbd_private_handle addr; - usbd_status 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) - return; - - if (status != USBD_NORMAL_COMPLETION) { - DPRINTF(("ugenintr: status=%d\n", status)); - usbd_clear_endpoint_stall_async(sce->pipeh); - return; - } - - (void)usbd_get_request_status(reqh, &priv, &buffer, &count, &xstatus); - ibuf = sce->ibuf; - - DPRINTFN(5, ("ugenintr: reqh=%p status=%d count=%d\n", - reqh, xstatus, count)); - DPRINTFN(5, (" data = %02x %02x %02x\n", - ibuf[0], ibuf[1], ibuf[2])); - - (void)b_to_q(ibuf, count, &sce->q); - - if (sce->state & UGEN_ASLP) { - sce->state &= ~UGEN_ASLP; - DPRINTFN(5, ("ugen_intr: waking %p\n", sce)); - wakeup((caddr_t)sce); - } - selwakeup(&sce->rsel); -} - -usbd_status -ugen_set_interface(sc, ifaceidx, altno) - struct ugen_softc *sc; - int ifaceidx, altno; -{ - usbd_interface_handle iface; - usb_endpoint_descriptor_t *ed; - usbd_status r; - struct ugen_endpoint *sce; - u_int8_t niface, nendpt, endptno, endpt; - - DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); - - r = usbd_interface_count(sc->sc_udev, &niface); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (ifaceidx < 0 || ifaceidx >= niface) - return (USBD_INVAL); - - r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); - if (r != USBD_NORMAL_COMPLETION) - return (r); - r = usbd_endpoint_count(iface, &nendpt); - if (r != USBD_NORMAL_COMPLETION) - return (r); - 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)]; - sce->sc = 0; - sce->edesc = 0; - sce->iface = 0; - } - - /* change setting */ - r = usbd_set_interface(iface, altno); - if (r != USBD_NORMAL_COMPLETION) - return (r); - - r = usbd_endpoint_count(iface, &nendpt); - if (r != USBD_NORMAL_COMPLETION) - return (r); - 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)]; - sce->sc = sc; - sce->edesc = ed; - sce->iface = iface; - } - return (0); -} - -/* Retrieve a complete descriptor for a certain device and index. */ -usb_config_descriptor_t * -ugen_get_cdesc(sc, index, lenp) - struct ugen_softc *sc; - int index; - int *lenp; -{ - usb_config_descriptor_t *cdesc, *tdesc, cdescr; - int len; - usbd_status r; - - if (index == USB_CURRENT_CONFIG_INDEX) { - tdesc = usbd_get_config_descriptor(sc->sc_udev); - len = UGETW(tdesc->wTotalLength); - if (lenp) - *lenp = len; - cdesc = malloc(len, M_TEMP, M_WAITOK); - memcpy(cdesc, tdesc, len); - DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len)); - } else { - r = usbd_get_config_desc(sc->sc_udev, index, &cdescr); - if (r != USBD_NORMAL_COMPLETION) - return (0); - len = UGETW(cdescr.wTotalLength); - DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len)); - if (lenp) - *lenp = len; - cdesc = malloc(len, M_TEMP, M_WAITOK); - r = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len); - if (r != USBD_NORMAL_COMPLETION) { - free(cdesc, M_TEMP); - return (0); - } - } - return (cdesc); -} - -int -ugen_get_alt_index(sc, ifaceidx) - struct ugen_softc *sc; - int ifaceidx; -{ - usbd_interface_handle iface; - usbd_status r; - - r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); - if (r != USBD_NORMAL_COMPLETION) - return (-1); - return (usbd_get_interface_altindex(iface)); -} - -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); - struct ugen_endpoint *sce; - usbd_status r; - usbd_interface_handle iface; - struct usb_config_desc *cd; - usb_config_descriptor_t *cdesc; - struct usb_interface_desc *id; - usb_interface_descriptor_t *idesc; - struct usb_endpoint_desc *ed; - usb_endpoint_descriptor_t *edesc; - struct usb_alt_interface *ai; - struct usb_string_desc *si; - u_int8_t conf, alt; - - DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd)); - if (sc->sc_disconnected) - return (EIO); - - switch (cmd) { - case FIONBIO: - /* All handled in the upper FS layer. */ - return (0); - case USB_SET_SHORT_XFER: - /* This flag only affects read */ - sce = &sc->sc_endpoints[endpt][IN]; -#ifdef DIAGNOSTIC - if (!sce->pipeh) { - printf("ugenioctl: no pipe\n"); - return (EIO); - } -#endif - if (*(int *)addr) - sce->state |= UGEN_SHORT_OK; - else - sce->state &= ~UGEN_SHORT_OK; - return (0); - default: - break; - } - - if (endpt != USB_CONTROL_ENDPOINT) - return (EINVAL); - - switch (cmd) { -#ifdef USB_DEBUG - case USB_SETDEBUG: - ugendebug = *(int *)addr; - break; -#endif - case USB_GET_CONFIG: - r = usbd_get_config(sc->sc_udev, &conf); - if (r != USBD_NORMAL_COMPLETION) - return (EIO); - *(int *)addr = conf; - break; - case USB_SET_CONFIG: - if (!(flag & FWRITE)) - return (EPERM); - r = ugen_set_config(sc, *(int *)addr); - if (r != USBD_NORMAL_COMPLETION) - return (EIO); - break; - case USB_GET_ALTINTERFACE: - ai = (struct usb_alt_interface *)addr; - r = usbd_device2interface_handle(sc->sc_udev, - ai->interface_index, &iface); - if (r != USBD_NORMAL_COMPLETION) - return (EINVAL); - idesc = usbd_get_interface_descriptor(iface); - if (!idesc) - return (EIO); - ai->alt_no = idesc->bAlternateSetting; - break; - case USB_SET_ALTINTERFACE: - if (!(flag & FWRITE)) - return (EPERM); - ai = (struct usb_alt_interface *)addr; - r = usbd_device2interface_handle(sc->sc_udev, - ai->interface_index, &iface); - if (r != USBD_NORMAL_COMPLETION) - return (EINVAL); - r = ugen_set_interface(sc, ai->interface_index, ai->alt_no); - if (r != USBD_NORMAL_COMPLETION) - return (EINVAL); - break; - case USB_GET_NO_ALT: - ai = (struct usb_alt_interface *)addr; - cdesc = ugen_get_cdesc(sc, ai->config_index, 0); - if (!cdesc) - return (EINVAL); - idesc = usbd_find_idesc(cdesc, ai->interface_index, 0); - if (!idesc) - return (EINVAL); - ai->alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber); - break; - case USB_GET_DEVICE_DESC: - *(usb_device_descriptor_t *)addr = - *usbd_get_device_descriptor(sc->sc_udev); - break; - case USB_GET_CONFIG_DESC: - cd = (struct usb_config_desc *)addr; - cdesc = ugen_get_cdesc(sc, cd->config_index, 0); - if (!cdesc) - return (EINVAL); - cd->desc = *cdesc; - free(cdesc, M_TEMP); - break; - case USB_GET_INTERFACE_DESC: - id = (struct usb_interface_desc *)addr; - cdesc = ugen_get_cdesc(sc, id->config_index, 0); - if (!cdesc) - return (EINVAL); - if (id->config_index == USB_CURRENT_CONFIG_INDEX && - id->alt_index == USB_CURRENT_ALT_INDEX) - alt = ugen_get_alt_index(sc, id->interface_index); - else - alt = id->alt_index; - idesc = usbd_find_idesc(cdesc, id->interface_index, alt); - if (!idesc) { - free(cdesc, M_TEMP); - return (EINVAL); - } - id->desc = *idesc; - free(cdesc, M_TEMP); - break; - case USB_GET_ENDPOINT_DESC: - ed = (struct usb_endpoint_desc *)addr; - cdesc = ugen_get_cdesc(sc, ed->config_index, 0); - if (!cdesc) - return (EINVAL); - if (ed->config_index == USB_CURRENT_CONFIG_INDEX && - ed->alt_index == USB_CURRENT_ALT_INDEX) - alt = ugen_get_alt_index(sc, ed->interface_index); - else - alt = ed->alt_index; - edesc = usbd_find_edesc(cdesc, ed->interface_index, - alt, ed->endpoint_index); - if (!edesc) { - free(cdesc, M_TEMP); - return (EINVAL); - } - ed->desc = *edesc; - free(cdesc, M_TEMP); - break; - case USB_GET_FULL_DESC: - { - int len; - struct iovec iov; - struct uio uio; - struct usb_full_desc *fd = (struct usb_full_desc *)addr; - int error; - - cdesc = ugen_get_cdesc(sc, fd->config_index, &len); - if (len > fd->size) - len = fd->size; - iov.iov_base = (caddr_t)fd->data; - iov.iov_len = len; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_resid = len; - uio.uio_offset = 0; - uio.uio_segflg = UIO_USERSPACE; - uio.uio_rw = UIO_READ; - uio.uio_procp = p; - error = uiomove((caddr_t)cdesc, len, &uio); - free(cdesc, M_TEMP); - return (error); - } - case USB_GET_STRING_DESC: - si = (struct usb_string_desc *)addr; - r = usbd_get_string_desc(sc->sc_udev, si->string_index, - si->language_id, &si->desc); - if (r != USBD_NORMAL_COMPLETION) - return (EINVAL); - break; - case USB_DO_REQUEST: - { - struct usb_ctl_request *ur = (void *)addr; - int len = UGETW(ur->request.wLength); - struct iovec iov; - struct uio uio; - void *ptr = 0; - usbd_status r; - int error = 0; - - if (!(flag & FWRITE)) - return (EPERM); - /* Avoid requests that would damage the bus integrity. */ - if ((ur->request.bmRequestType == UT_WRITE_DEVICE && - ur->request.bRequest == UR_SET_ADDRESS) || - (ur->request.bmRequestType == UT_WRITE_DEVICE && - ur->request.bRequest == UR_SET_CONFIG) || - (ur->request.bmRequestType == UT_WRITE_INTERFACE && - ur->request.bRequest == UR_SET_INTERFACE)) - return (EINVAL); - - if (len < 0 || len > 32767) - return (EINVAL); - if (len != 0) { - iov.iov_base = (caddr_t)ur->data; - iov.iov_len = len; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_resid = len; - uio.uio_offset = 0; - uio.uio_segflg = UIO_USERSPACE; - uio.uio_rw = - ur->request.bmRequestType & UT_READ ? - UIO_READ : UIO_WRITE; - uio.uio_procp = p; - ptr = malloc(len, M_TEMP, M_WAITOK); - if (uio.uio_rw == UIO_WRITE) { - error = uiomove(ptr, len, &uio); - if (error) - goto ret; - } - } - r = usbd_do_request_flags(sc->sc_udev, &ur->request, - ptr, ur->flags, &ur->actlen); - if (r) { - error = EIO; - goto ret; - } - if (len != 0) { - if (uio.uio_rw == UIO_READ) { - error = uiomove(ptr, len, &uio); - if (error) - goto ret; - } - } - ret: - if (ptr) - free(ptr, M_TEMP); - return (error); - } - case USB_GET_DEVICEINFO: - usbd_fill_deviceinfo(sc->sc_udev, - (struct usb_device_info *)addr); - break; - default: - return (EINVAL); - } - return (0); -} - -int -ugenpoll(dev, events, p) - dev_t dev; - int events; - struct proc *p; -{ - USB_GET_SC(ugen, UGENUNIT(dev), sc); - /* XXX */ - struct ugen_endpoint *sce; - int revents = 0; - int s; - - if (sc->sc_disconnected) - return (EIO); - - sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; -#ifdef DIAGNOSTIC - if (!sce->edesc) { - printf("ugenwrite: no edesc\n"); - return (EIO); - } - if (!sce->pipeh) { - printf("ugenpoll: no pipe\n"); - return (EIO); - } -#endif - s = splusb(); - switch (sce->edesc->bmAttributes & UE_XFERTYPE) { - case UE_INTERRUPT: - if (events & (POLLIN | POLLRDNORM)) { - if (sce->q.c_cc > 0) - revents |= events & (POLLIN | POLLRDNORM); - else - selrecord(p, &sce->rsel); - } - break; - case UE_BULK: - /* - * We have no easy way of determining if a read will - * yield any data or a write will happen. - * Pretend they will. - */ - revents |= events & - (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); - break; - default: - break; - } - splx(s); - return (revents); -} - -#if defined(__FreeBSD__) -static int -ugen_detach(device_t self) -{ - char *devinfo = (char *) device_get_desc(self); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - return 0; -} - -DRIVER_MODULE(ugen, uhub, ugen_driver, ugen_devclass, usbd_driver_load, 0); -#endif diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c deleted file mode 100644 index 707bfe3795ba8..0000000000000 --- a/sys/dev/usb/uhci.c +++ /dev/null @@ -1,2620 +0,0 @@ -/* $NetBSD: uhci.c,v 1.22 1999/01/08 11:58:25 augustss Exp $ */ -/* FreeBSD $Id: uhci.c,v 1.6 1999/01/07 23:31:33 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * USB Universal Host Controller driver. - * Handles PIIX3 and PIIX4. - * - * Data sheets: ftp://download.intel.com/design/intarch/datashts/29055002.pdf - * ftp://download.intel.com/design/intarch/datashts/29056201.pdf - * UHCI spec: http://www.intel.com/design/usb/uhci11d.pdf - * USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#endif -#include <sys/proc.h> -#include <sys/queue.h> -#include <sys/select.h> - -#include <machine/bus.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usb_mem.h> -#include <dev/usb/usb_quirks.h> - -#include <dev/usb/uhcireg.h> -#include <dev/usb/uhcivar.h> - -#if defined(__FreeBSD__) -#include <machine/clock.h> - -#define delay(d) DELAY(d) -#endif - -#define MS_TO_TICKS(ms) ((ms) * hz / 1000) - -struct uhci_pipe { - struct usbd_pipe pipe; - uhci_intr_info_t *iinfo; - int newtoggle; - /* Info needed for different pipe kinds. */ - union { - /* Control pipe */ - struct { - uhci_soft_qh_t *sqh; - usb_dma_t reqdma; - usb_dma_t datadma; - uhci_soft_td_t *setup, *stat; - u_int length; - } ctl; - /* Interrupt pipe */ - struct { - usb_dma_t datadma; - int npoll; - uhci_soft_qh_t **qhs; - } intr; - /* Bulk pipe */ - struct { - uhci_soft_qh_t *sqh; - usb_dma_t datadma; - u_int length; - int isread; - } bulk; - /* Iso pipe */ - struct iso { - u_int bufsize; - u_int nbuf; - usb_dma_t *bufs; - uhci_soft_td_t **stds; - } iso; - } u; -}; - -/* - * The uhci_intr_info free list can be global since they contain - * no dma specific data. The other free lists do. - */ -LIST_HEAD(, uhci_intr_info) uhci_ii_free; - -void uhci_busreset __P((uhci_softc_t *)); -usbd_status uhci_run __P((uhci_softc_t *, int run)); -uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *)); -void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *)); -uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *)); -void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *)); -uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *)); -void uhci_free_intr_info __P((uhci_intr_info_t *ii)); -#if 0 -void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *, - uhci_intr_info_t *)); -void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *)); -#endif - -void uhci_free_std_chain __P((uhci_softc_t *, - uhci_soft_td_t *, uhci_soft_td_t *)); -usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *, uhci_softc_t *, - int, int, int, usb_dma_t *, - uhci_soft_td_t **, - uhci_soft_td_t **)); -void uhci_timo __P((void *)); -void uhci_waitintr __P((uhci_softc_t *, usbd_request_handle)); -void uhci_check_intr __P((uhci_softc_t *, uhci_intr_info_t *)); -void uhci_ii_done __P((uhci_intr_info_t *, int)); -void uhci_timeout __P((void *)); -void uhci_wakeup_ctrl __P((void *, int, int, void *, int)); -void uhci_lock_frames __P((uhci_softc_t *)); -void uhci_unlock_frames __P((uhci_softc_t *)); -void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *)); -void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *)); -void uhci_remove_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *)); -void uhci_remove_bulk __P((uhci_softc_t *, uhci_soft_qh_t *)); -int uhci_str __P((usb_string_descriptor_t *, int, char *)); - -void uhci_wakeup_cb __P((usbd_request_handle reqh)); - -usbd_status uhci_device_ctrl_transfer __P((usbd_request_handle)); -usbd_status uhci_device_ctrl_start __P((usbd_request_handle)); -void uhci_device_ctrl_abort __P((usbd_request_handle)); -void uhci_device_ctrl_close __P((usbd_pipe_handle)); -usbd_status uhci_device_intr_transfer __P((usbd_request_handle)); -usbd_status uhci_device_intr_start __P((usbd_request_handle)); -void uhci_device_intr_abort __P((usbd_request_handle)); -void uhci_device_intr_close __P((usbd_pipe_handle)); -usbd_status uhci_device_bulk_transfer __P((usbd_request_handle)); -usbd_status uhci_device_bulk_start __P((usbd_request_handle)); -void uhci_device_bulk_abort __P((usbd_request_handle)); -void uhci_device_bulk_close __P((usbd_pipe_handle)); -usbd_status uhci_device_isoc_transfer __P((usbd_request_handle)); -usbd_status uhci_device_isoc_start __P((usbd_request_handle)); -void uhci_device_isoc_abort __P((usbd_request_handle)); -void uhci_device_isoc_close __P((usbd_pipe_handle)); -usbd_status uhci_device_isoc_setbuf __P((usbd_pipe_handle, u_int, u_int)); - -usbd_status uhci_root_ctrl_transfer __P((usbd_request_handle)); -usbd_status uhci_root_ctrl_start __P((usbd_request_handle)); -void uhci_root_ctrl_abort __P((usbd_request_handle)); -void uhci_root_ctrl_close __P((usbd_pipe_handle)); -usbd_status uhci_root_intr_transfer __P((usbd_request_handle)); -usbd_status uhci_root_intr_start __P((usbd_request_handle)); -void uhci_root_intr_abort __P((usbd_request_handle)); -void uhci_root_intr_close __P((usbd_pipe_handle)); - -usbd_status uhci_open __P((usbd_pipe_handle)); -void uhci_poll __P((struct usbd_bus *)); - -usbd_status uhci_device_request __P((usbd_request_handle reqh)); -void uhci_ctrl_done __P((uhci_intr_info_t *ii)); -void uhci_bulk_done __P((uhci_intr_info_t *ii)); - -void uhci_add_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *)); -void uhci_remove_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *)); -usbd_status uhci_device_setintr __P((uhci_softc_t *sc, - struct uhci_pipe *pipe, int ival)); -void uhci_intr_done __P((uhci_intr_info_t *ii)); -void uhci_isoc_done __P((uhci_intr_info_t *ii)); - -#ifdef USB_DEBUG -static void uhci_dumpregs __P((uhci_softc_t *)); -void uhci_dump_tds __P((uhci_soft_td_t *)); -void uhci_dump_qh __P((uhci_soft_qh_t *)); -void uhci_dump __P((void)); -void uhci_dump_td __P((uhci_soft_td_t *)); -#endif - -#if defined(__NetBSD__) -#define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)) -#define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)) -#define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r)) -#define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r)) -#elif defined(__FreeBSD__) -#define UWRITE2(sc,r,x) outw((sc)->sc_iobase + (r), (x)) -#define UWRITE4(sc,r,x) outl((sc)->sc_iobase + (r), (x)) -#define UREAD2(sc,r) inw((sc)->sc_iobase + (r)) -#define UREAD4(sc,r) inl((sc)->sc_iobase + (r)) -#endif - -#define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd) -#define UHCISTS(sc) UREAD2(sc, UHCI_STS) - -#define UHCI_RESET_TIMEOUT 100 /* reset timeout */ - -#define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK) - -#define UHCI_INTR_ENDPT 1 - -struct usbd_methods uhci_root_ctrl_methods = { - uhci_root_ctrl_transfer, - uhci_root_ctrl_start, - uhci_root_ctrl_abort, - uhci_root_ctrl_close, - 0, -}; - -struct usbd_methods uhci_root_intr_methods = { - uhci_root_intr_transfer, - uhci_root_intr_start, - uhci_root_intr_abort, - uhci_root_intr_close, - 0, -}; - -struct usbd_methods uhci_device_ctrl_methods = { - uhci_device_ctrl_transfer, - uhci_device_ctrl_start, - uhci_device_ctrl_abort, - uhci_device_ctrl_close, - 0, -}; - -struct usbd_methods uhci_device_intr_methods = { - uhci_device_intr_transfer, - uhci_device_intr_start, - uhci_device_intr_abort, - uhci_device_intr_close, - 0, -}; - -struct usbd_methods uhci_device_bulk_methods = { - uhci_device_bulk_transfer, - uhci_device_bulk_start, - uhci_device_bulk_abort, - uhci_device_bulk_close, - 0, -}; - -struct usbd_methods uhci_device_isoc_methods = { - uhci_device_isoc_transfer, - uhci_device_isoc_start, - uhci_device_isoc_abort, - uhci_device_isoc_close, - uhci_device_isoc_setbuf, -}; - -void -uhci_busreset(sc) - uhci_softc_t *sc; -{ - UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */ - usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */ - UHCICMD(sc, 0); /* do nothing */ -} - -usbd_status -uhci_init(sc) - uhci_softc_t *sc; -{ - usbd_status r; - int i, j; - uhci_soft_qh_t *csqh, *bsqh, *sqh; - uhci_soft_td_t *std; - usb_dma_t dma; - static int uhci_global_init_done = 0; - - DPRINTFN(1,("uhci_init: start\n")); - - if (!uhci_global_init_done) { - uhci_global_init_done = 1; - LIST_INIT(&uhci_ii_free); - } - -#if defined(USB_DEBUG) - if (uhcidebug > 2) - uhci_dumpregs(sc); -#endif - - uhci_run(sc, 0); /* stop the controller */ - UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */ - - /* Allocate and initialize real frame array. */ - r = usb_allocmem(sc->sc_dmatag, - UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), - UHCI_FRAMELIST_ALIGN, &dma); - if (r != USBD_NORMAL_COMPLETION) - return (r); - sc->sc_pframes = KERNADDR(&dma); - UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */ - UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&dma)); /* set frame list */ - - uhci_busreset(sc); - - /* Allocate the dummy QH where bulk traffic will be queued. */ - bsqh = uhci_alloc_sqh(sc); - if (!bsqh) - return (USBD_NOMEM); - bsqh->qh->qh_hlink = UHCI_PTR_T; /* end of QH chain */ - bsqh->qh->qh_elink = UHCI_PTR_T; - sc->sc_bulk_start = sc->sc_bulk_end = bsqh; - - /* Allocate the dummy QH where control traffic will be queued. */ - csqh = uhci_alloc_sqh(sc); - if (!csqh) - return (USBD_NOMEM); - csqh->qh->hlink = bsqh; - csqh->qh->qh_hlink = bsqh->physaddr | UHCI_PTR_Q; - csqh->qh->qh_elink = UHCI_PTR_T; - sc->sc_ctl_start = sc->sc_ctl_end = csqh; - - /* - * Make all (virtual) frame list pointers point to the interrupt - * queue heads and the interrupt queue heads at the control - * queue head and point the physical frame list to the virtual. - */ - for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { - std = uhci_alloc_std(sc); - sqh = uhci_alloc_sqh(sc); - if (!std || !sqh) - return (USBD_NOMEM); - std->td->link.sqh = sqh; - std->td->td_link = sqh->physaddr | UHCI_PTR_Q; - std->td->td_status = UHCI_TD_IOS; /* iso, inactive */ - std->td->td_token = 0; - std->td->td_buffer = 0; - sqh->qh->hlink = csqh; - sqh->qh->qh_hlink = csqh->physaddr | UHCI_PTR_Q; - sqh->qh->elink = 0; - sqh->qh->qh_elink = UHCI_PTR_T; - sc->sc_vframes[i].htd = std; - sc->sc_vframes[i].etd = std; - sc->sc_vframes[i].hqh = sqh; - sc->sc_vframes[i].eqh = sqh; - for (j = i; - j < UHCI_FRAMELIST_COUNT; - j += UHCI_VFRAMELIST_COUNT) - sc->sc_pframes[j] = std->physaddr; - } - - LIST_INIT(&sc->sc_intrhead); - - /* Set up the bus struct. */ - sc->sc_bus.open_pipe = uhci_open; - sc->sc_bus.pipe_size = sizeof(struct uhci_pipe); - sc->sc_bus.do_poll = uhci_poll; - - DPRINTFN(1,("uhci_init: enabling\n")); - UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | - UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ - - return (uhci_run(sc, 1)); /* and here we go... */ -} - -#ifdef USB_DEBUG -static void -uhci_dumpregs(sc) - uhci_softc_t *sc; -{ - printf("%s; regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, " - "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n", - USBDEVNAME(sc->sc_bus.bdev), - UREAD2(sc, UHCI_CMD), - UREAD2(sc, UHCI_STS), - UREAD2(sc, UHCI_INTR), - UREAD2(sc, UHCI_FRNUM), - UREAD2(sc, UHCI_FLBASEADDR), - UREAD2(sc, UHCI_SOF), - UREAD2(sc, UHCI_PORTSC1), - UREAD2(sc, UHCI_PORTSC2)); -} - -int uhci_longtd = 1; - -void -uhci_dump_td(p) - uhci_soft_td_t *p; -{ - printf("TD(%p) at %08lx = 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n", - p, (long)p->physaddr, - (long)p->td->td_link, - (long)p->td->td_status, - (long)p->td->td_token, - (long)p->td->td_buffer); - if (uhci_longtd) - printf(" %b %b,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d," - "D=%d,maxlen=%d\n", - (int)p->td->td_link, - "\20\1T\2Q\3VF", - (int)p->td->td_status, - "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27" - "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD", - UHCI_TD_GET_ERRCNT(p->td->td_status), - UHCI_TD_GET_ACTLEN(p->td->td_status), - UHCI_TD_GET_PID(p->td->td_token), - UHCI_TD_GET_DEVADDR(p->td->td_token), - UHCI_TD_GET_ENDPT(p->td->td_token), - UHCI_TD_GET_DT(p->td->td_token), - UHCI_TD_GET_MAXLEN(p->td->td_token)); -} - -void -uhci_dump_qh(p) - uhci_soft_qh_t *p; -{ - printf("QH(%p) at %08x: hlink=%08x elink=%08x\n", p, (int)p->physaddr, - p->qh->qh_hlink, p->qh->qh_elink); -} - - -#if 0 -void -uhci_dump() -{ - uhci_softc_t *sc = uhci; - - uhci_dumpregs(sc); - printf("intrs=%d\n", sc->sc_intrs); - printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link); - uhci_dump_qh(sc->sc_ctl_start->qh->hlink); -} -#endif - -void -uhci_dump_tds(std) - uhci_soft_td_t *std; -{ - uhci_soft_td_t *p; - - for(p = std; p; p = p->td->link.std) - uhci_dump_td(p); -} -#endif - -/* - * This routine is executed periodically and simulates interrupts - * from the root controller interrupt pipe for port status change. - */ -void -uhci_timo(addr) - void *addr; -{ - usbd_request_handle reqh = addr; - usbd_pipe_handle pipe = reqh->pipe; - uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - int s; - u_char *p; - - DPRINTFN(15, ("uhci_timo\n")); - - p = KERNADDR(&upipe->u.intr.datadma); - p[0] = 0; - if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) - p[0] |= 1<<1; - if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) - p[0] |= 1<<2; - s = splusb(); - if (p[0] != 0) { - reqh->actlen = 1; - reqh->status = USBD_NORMAL_COMPLETION; - reqh->xfercb(reqh); - } - if (reqh->pipe->intrreqh == reqh) { - usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle); - } else { - usb_freemem(sc->sc_dmatag, &upipe->u.intr.datadma); - usb_start_next(reqh->pipe); - } - splx(s); -} - - -void -uhci_lock_frames(sc) - uhci_softc_t *sc; -{ - int s = splusb(); - while (sc->sc_vflock) { - sc->sc_vflock |= UHCI_WANT_LOCK; - tsleep(&sc->sc_vflock, PRIBIO, "uhcqhl", 0); - } - sc->sc_vflock = UHCI_HAS_LOCK; - splx(s); -} - -void -uhci_unlock_frames(sc) - uhci_softc_t *sc; -{ - int s = splusb(); - sc->sc_vflock &= ~UHCI_HAS_LOCK; - if (sc->sc_vflock & UHCI_WANT_LOCK) - wakeup(&sc->sc_vflock); - splx(s); -} - -/* - * Allocate an interrupt information struct. A free list is kept - * for fast allocation. - */ -uhci_intr_info_t * -uhci_alloc_intr_info(sc) - uhci_softc_t *sc; -{ - uhci_intr_info_t *ii; - - ii = LIST_FIRST(&uhci_ii_free); - if (ii) - LIST_REMOVE(ii, list); - else { - ii = malloc(sizeof(uhci_intr_info_t), M_USBDEV, M_NOWAIT); - } - ii->sc = sc; - return ii; -} - -void -uhci_free_intr_info(ii) - uhci_intr_info_t *ii; -{ - LIST_INSERT_HEAD(&uhci_ii_free, ii, list); /* and put on free list */ -} - -/* Add control QH, called at splusb(). */ -void -uhci_add_ctrl(sc, sqh) - uhci_softc_t *sc; - uhci_soft_qh_t *sqh; -{ - uhci_qh_t *eqh; - - DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh)); - eqh = sc->sc_ctl_end->qh; - sqh->qh->hlink = eqh->hlink; - sqh->qh->qh_hlink = eqh->qh_hlink; - eqh->hlink = sqh; - eqh->qh_hlink = sqh->physaddr | UHCI_PTR_Q; - sc->sc_ctl_end = sqh; -} - -/* Remove control QH, called at splusb(). */ -void -uhci_remove_ctrl(sc, sqh) - uhci_softc_t *sc; - uhci_soft_qh_t *sqh; -{ - uhci_soft_qh_t *pqh; - - DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh)); - for (pqh = sc->sc_ctl_start; pqh->qh->hlink != sqh; pqh=pqh->qh->hlink) -#if defined(DIAGNOSTIC) || defined(USB_DEBUG) - if (pqh->qh->qh_hlink & UHCI_PTR_T) { - printf("uhci_remove_ctrl: QH not found\n"); - return; - } -#else - ; -#endif - pqh->qh->hlink = sqh->qh->hlink; - pqh->qh->qh_hlink = sqh->qh->qh_hlink; - if (sc->sc_ctl_end == sqh) - sc->sc_ctl_end = pqh; -} - -/* Add bulk QH, called at splusb(). */ -void -uhci_add_bulk(sc, sqh) - uhci_softc_t *sc; - uhci_soft_qh_t *sqh; -{ - uhci_qh_t *eqh; - - DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh)); - eqh = sc->sc_bulk_end->qh; - sqh->qh->hlink = eqh->hlink; - sqh->qh->qh_hlink = eqh->qh_hlink; - eqh->hlink = sqh; - eqh->qh_hlink = sqh->physaddr | UHCI_PTR_Q; - sc->sc_bulk_end = sqh; -} - -/* Remove bulk QH, called at splusb(). */ -void -uhci_remove_bulk(sc, sqh) - uhci_softc_t *sc; - uhci_soft_qh_t *sqh; -{ - uhci_soft_qh_t *pqh; - - DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh)); - for (pqh = sc->sc_bulk_start; - pqh->qh->hlink != sqh; - pqh = pqh->qh->hlink) -#if defined(DIAGNOSTIC) || defined(USB_DEBUG) - if (pqh->qh->qh_hlink & UHCI_PTR_T) { - printf("uhci_remove_bulk: QH not found\n"); - return; - } -#else - ; -#endif - pqh->qh->hlink = sqh->qh->hlink; - pqh->qh->qh_hlink = sqh->qh->qh_hlink; - if (sc->sc_bulk_end == sqh) - sc->sc_bulk_end = pqh; -} - -int -uhci_intr(p) - void *p; -{ - uhci_softc_t *sc = p; - int status, ret; - uhci_intr_info_t *ii; - - sc->sc_intrs++; -#if defined(USB_DEBUG) - if (uhcidebug > 9) { - printf("uhci_intr %p\n", sc); - uhci_dumpregs(sc); - } -#endif - status = UREAD2(sc, UHCI_STS); - ret = 0; - if (status & UHCI_STS_USBINT) { - UWRITE2(sc, UHCI_STS, UHCI_STS_USBINT); /* acknowledge */ - ret = 1; - } - if (status & UHCI_STS_USBEI) { - UWRITE2(sc, UHCI_STS, UHCI_STS_USBEI); /* acknowledge */ - ret = 1; - } - if (status & UHCI_STS_RD) { - UWRITE2(sc, UHCI_STS, UHCI_STS_RD); /* acknowledge */ - printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev)); - ret = 1; - } - if (status & UHCI_STS_HSE) { - UWRITE2(sc, UHCI_STS, UHCI_STS_HSE); /* acknowledge */ - printf("%s: Host System Error\n", USBDEVNAME(sc->sc_bus.bdev)); - ret = 1; - } - if (status & UHCI_STS_HCPE) { - UWRITE2(sc, UHCI_STS, UHCI_STS_HCPE); /* acknowledge */ - printf("%s: Host System Error\n", USBDEVNAME(sc->sc_bus.bdev)); - ret = 1; - } - if (status & UHCI_STS_HCH) - printf("%s: controller halted\n", USBDEVNAME(sc->sc_bus.bdev)); - if (!ret) - return 0; - - /* - * Interrupts on UHCI really suck. When the host controller - * interrupts because a transfer is completed there is no - * way of knowing which transfer it was. You can scan down - * the TDs and QHs of the previous frame to limit the search, - * but that assumes that the interrupt was not delayed by more - * than 1 ms, which may not always be true (e.g. after debug - * output on a slow console). - * We scan all interrupt descriptors to see if any have - * completed. - */ - for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list)) - uhci_check_intr(sc, ii); - - DPRINTFN(10, ("uhci_intr: exit\n")); - return 1; -} - -/* Check for an interrupt. */ -void -uhci_check_intr(sc, ii) - uhci_softc_t *sc; - uhci_intr_info_t *ii; -{ - struct uhci_pipe *upipe; - uhci_soft_td_t *std, *lstd; - u_int32_t status; - - DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii)); -#ifdef DIAGNOSTIC - if (!ii) { - printf("uhci_check_intr: no ii? %p\n", ii); - return; - } -#endif - if (!ii->stdstart) - return; - lstd = ii->stdend; -#ifdef DIAGNOSTIC - if (!lstd) { - printf("uhci_check_intr: std==0\n"); - return; - } -#endif - /* If the last TD is still active the whole transfer probably is. */ - if (lstd->td->td_status & UHCI_TD_ACTIVE) { - DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii)); - for (std = ii->stdstart; std != lstd; std = std->td->link.std){ - status = std->td->td_status; - if ((status & UHCI_TD_STALLED) || - (status & (UHCI_TD_SPD | UHCI_TD_ACTIVE)) == - UHCI_TD_SPD) - goto done; - } - DPRINTFN(15, ("uhci_check_intr: ii=%p std=%p still active\n", - ii, ii->stdstart)); - return; - } - done: - upipe = (struct uhci_pipe *)ii->reqh->pipe; - upipe->pipe.endpoint->toggle = upipe->newtoggle; - uhci_ii_done(ii, 0); - usb_untimeout(uhci_timeout, ii, ii->timeout_handle); -} - -void -uhci_ii_done(ii, timo) - uhci_intr_info_t *ii; - int timo; -{ - usbd_request_handle reqh = ii->reqh; - uhci_soft_td_t *std; - u_int32_t tst; - int len, status, attr; - - DPRINTFN(10, ("uhci_ii_done: ii=%p ready %d\n", ii, timo)); - -#ifdef DIAGNOSTIC - { - int s = splhigh(); - if (ii->isdone) { - printf("uhci_ii_done: is done!\n"); - splx(s); - return; - } - ii->isdone = 1; - splx(s); - } -#endif - - /* The transfer is done, compute length and status. */ - /* XXX Should stop at first inactive to get toggle right. */ - /* XXX Is this correct for control xfers? */ - for (len = status = 0, std = ii->stdstart; - std != 0; - std = std->td->link.std) { - tst = std->td->td_status; - status |= tst; -#ifdef USB_DEBUG - if ((tst & UHCI_TD_ERROR) && uhcidebug) { - printf("uhci_ii_done: intr error TD:\n"); - uhci_dump_td(std); - } -#endif - if (UHCI_TD_GET_PID(std->td->td_token) != UHCI_TD_PID_SETUP) - len += UHCI_TD_GET_ACTLEN(tst); - } - status &= UHCI_TD_ERROR; - DPRINTFN(10, ("uhci_check_intr: len=%d, status=0x%x\n", len, status)); - if (status != 0) { - DPRINTFN(-1+(status==UHCI_TD_STALLED), - ("uhci_ii_done: error, addr=%d, endpt=0x%02x, " - "status 0x%b\n", - reqh->pipe->device->address, - reqh->pipe->endpoint->edesc->bEndpointAddress, - (int)status, - "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27" - "STALLED\30ACTIVE")); - if (status == UHCI_TD_STALLED) - reqh->status = USBD_STALLED; - else - reqh->status = USBD_IOERROR; /* more info XXX */ - reqh->actlen = 0; - } else { - reqh->status = USBD_NORMAL_COMPLETION; - reqh->actlen = len; - } - if (timo) { - /* We got a timeout. Make sure transaction is not active. */ - reqh->status = USBD_TIMEOUT; - for (std = ii->stdstart; std != 0; std = std->td->link.std) - std->td->td_status &= ~UHCI_TD_ACTIVE; - /* XXX should we wait 1 ms */ - } - DPRINTFN(5, ("uhci_ii_done: calling handler ii=%p\n", ii)); - - attr = reqh->pipe->endpoint->edesc->bmAttributes; - switch (attr & UE_XFERTYPE) { - case UE_CONTROL: - uhci_ctrl_done(ii); - usb_start_next(reqh->pipe); - break; - case UE_ISOCHRONOUS: - uhci_isoc_done(ii); - usb_start_next(reqh->pipe); - break; - case UE_BULK: - uhci_bulk_done(ii); - usb_start_next(reqh->pipe); - break; - case UE_INTERRUPT: - uhci_intr_done(ii); - break; - } - - /* And finally execute callback. */ - reqh->xfercb(reqh); -} - -/* - * Called when a request does not complete. - */ -void -uhci_timeout(addr) - void *addr; -{ - uhci_intr_info_t *ii = addr; - int s; - - DPRINTF(("uhci_timeout: ii=%p\n", ii)); - s = splusb(); - uhci_ii_done(ii, 1); - splx(s); -} - -/* - * Wait here until controller claims to have an interrupt. - * Then call uhci_intr and return. Use timeout to avoid waiting - * too long. - * Only used during boot when interrupts are not enabled yet. - */ -void -uhci_waitintr(sc, reqh) - uhci_softc_t *sc; - usbd_request_handle reqh; -{ - int timo = reqh->timeout; - int usecs; - uhci_intr_info_t *ii; - - DPRINTFN(10,("uhci_waitintr: timeout = %ds\n", timo)); - - reqh->status = USBD_IN_PROGRESS; - for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) { - usb_delay_ms(&sc->sc_bus, 1); - DPRINTFN(10,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS))); - if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) { - uhci_intr(sc); - if (reqh->status != USBD_IN_PROGRESS) - return; - } - } - - /* Timeout */ - DPRINTF(("uhci_waitintr: timeout\n")); - for (ii = LIST_FIRST(&sc->sc_intrhead); - ii && ii->reqh != reqh; - ii = LIST_NEXT(ii, list)) - ; - if (ii) - uhci_ii_done(ii, 1); - else - panic("uhci_waitintr: lost intr_info\n"); -} - -void -uhci_poll(bus) - struct usbd_bus *bus; -{ - uhci_softc_t *sc = (uhci_softc_t *)bus; - - if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) - uhci_intr(sc); -} - -#if 0 -void -uhci_reset(p) - void *p; -{ - uhci_softc_t *sc = p; - int n; - - UHCICMD(sc, UHCI_CMD_HCRESET); - /* The reset bit goes low when the controller is done. */ - for (n = 0; n < UHCI_RESET_TIMEOUT && - (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++) - delay(100); - if (n >= UHCI_RESET_TIMEOUT) - printf("%s: controller did not reset\n", - USBDEVNAME(sc->sc_bus.bdev)); -} -#endif - -usbd_status -uhci_run(sc, run) - uhci_softc_t *sc; - int run; -{ - int s, n, running; - - run = run != 0; - s = splusb(); - running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH); - if (run == running) { - splx(s); - return (USBD_NORMAL_COMPLETION); - } - UWRITE2(sc, UHCI_CMD, run ? UHCI_CMD_RS : 0); - for(n = 0; n < 10; n++) { - running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH); - /* return when we've entered the state we want */ - if (run == running) { - splx(s); - return (USBD_NORMAL_COMPLETION); - } - usb_delay_ms(&sc->sc_bus, 1); - } - splx(s); - printf("%s: cannot %s\n", USBDEVNAME(sc->sc_bus.bdev), - run ? "start" : "stop"); - return (USBD_IOERROR); -} - -/* - * Memory management routines. - * uhci_alloc_std allocates TDs - * uhci_alloc_sqh allocates QHs - * These two routines do their own free list management, - * partly for speed, partly because allocating DMAable memory - * has page size granularaity so much memory would be wasted if - * only one TD/QH (32 bytes) was placed in each allocated chunk. - */ - -uhci_soft_td_t * -uhci_alloc_std(sc) - uhci_softc_t *sc; -{ - uhci_soft_td_t *std; - usbd_status r; - int i; - usb_dma_t dma; - - if (!sc->sc_freetds) { - DPRINTFN(2,("uhci_alloc_std: allocating chunk\n")); - std = malloc(sizeof(uhci_soft_td_t) * UHCI_TD_CHUNK, - M_USBDEV, M_NOWAIT); - if (!std) - return (0); - r = usb_allocmem(sc->sc_dmatag, UHCI_TD_SIZE * UHCI_TD_CHUNK, - UHCI_TD_ALIGN, &dma); - if (r != USBD_NORMAL_COMPLETION) { - free(std, M_USBDEV); - return (0); - } - for(i = 0; i < UHCI_TD_CHUNK; i++, std++) { - std->physaddr = DMAADDR(&dma) + i * UHCI_TD_SIZE; - std->td = (uhci_td_t *) - ((char *)KERNADDR(&dma) + i * UHCI_TD_SIZE); - std->td->link.std = sc->sc_freetds; - sc->sc_freetds = std; - } - } - std = sc->sc_freetds; - sc->sc_freetds = std->td->link.std; - memset(std->td, 0, UHCI_TD_SIZE); - return std; -} - -void -uhci_free_std(sc, std) - uhci_softc_t *sc; - uhci_soft_td_t *std; -{ -#ifdef DIAGNOSTIC -#define TD_IS_FREE 0x12345678 - if (std->td->td_token == TD_IS_FREE) { - printf("uhci_free_std: freeing free TD %p\n", std); - return; - } - std->td->td_token = TD_IS_FREE; -#endif - std->td->link.std = sc->sc_freetds; - sc->sc_freetds = std; -} - -uhci_soft_qh_t * -uhci_alloc_sqh(sc) - uhci_softc_t *sc; -{ - uhci_soft_qh_t *sqh; - usbd_status r; - int i, offs; - usb_dma_t dma; - - if (!sc->sc_freeqhs) { - DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n")); - sqh = malloc(sizeof(uhci_soft_qh_t) * UHCI_QH_CHUNK, - M_USBDEV, M_NOWAIT); - if (!sqh) - return 0; - r = usb_allocmem(sc->sc_dmatag, UHCI_QH_SIZE * UHCI_QH_CHUNK, - UHCI_QH_ALIGN, &dma); - if (r != USBD_NORMAL_COMPLETION) { - free(sqh, M_USBDEV); - return 0; - } - for(i = 0; i < UHCI_QH_CHUNK; i++, sqh++) { - offs = i * UHCI_QH_SIZE; - sqh->physaddr = DMAADDR(&dma) + offs; - sqh->qh = (uhci_qh_t *) - ((char *)KERNADDR(&dma) + offs); - sqh->qh->hlink = sc->sc_freeqhs; - sc->sc_freeqhs = sqh; - } - } - sqh = sc->sc_freeqhs; - sc->sc_freeqhs = sqh->qh->hlink; - memset(sqh->qh, 0, UHCI_QH_SIZE); - return (sqh); -} - -void -uhci_free_sqh(sc, sqh) - uhci_softc_t *sc; - uhci_soft_qh_t *sqh; -{ - sqh->qh->hlink = sc->sc_freeqhs; - sc->sc_freeqhs = sqh; -} - -#if 0 -/* - * Enter a list of transfers onto a control queue. - * Called at splusb() - */ -void -uhci_enter_ctl_q(sc, sqh, ii) - uhci_softc_t *sc; - uhci_soft_qh_t *sqh; - uhci_intr_info_t *ii; -{ - DPRINTFN(5, ("uhci_enter_ctl_q: sqh=%p\n", sqh)); - -} -#endif - -void -uhci_free_std_chain(sc, std, stdend) - uhci_softc_t *sc; - uhci_soft_td_t *std; - uhci_soft_td_t *stdend; -{ - uhci_soft_td_t *p; - - for (; std != stdend; std = p) { - p = std->td->link.std; - uhci_free_std(sc, std); - } -} - -usbd_status -uhci_alloc_std_chain(upipe, sc, len, rd, spd, dma, sp, ep) - struct uhci_pipe *upipe; - uhci_softc_t *sc; - int len, rd, spd; - usb_dma_t *dma; - uhci_soft_td_t **sp, **ep; -{ - uhci_soft_td_t *p, *lastp; - uhci_physaddr_t lastlink; - int i, ntd, l, tog, maxp; - u_int32_t status; - int addr = upipe->pipe.device->address; - int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; - - DPRINTFN(15, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d " - "spd=%d\n", addr, endpt, len, - upipe->pipe.device->lowspeed, spd)); - if (len == 0) { - *sp = *ep = 0; - DPRINTFN(-1,("uhci_alloc_std_chain: len=0\n")); - return (USBD_NORMAL_COMPLETION); - } - maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize); - if (maxp == 0) { - printf("uhci_alloc_std_chain: maxp=0\n"); - return (USBD_INVAL); - } - ntd = (len + maxp - 1) / maxp; - tog = upipe->pipe.endpoint->toggle; - if (ntd % 2 == 0) - tog ^= 1; - upipe->newtoggle = tog ^ 1; - lastp = 0; - lastlink = UHCI_PTR_T; - ntd--; - status = UHCI_TD_SET_ERRCNT(2) | UHCI_TD_ACTIVE; - if (upipe->pipe.device->lowspeed) - status |= UHCI_TD_LS; - if (spd) - status |= UHCI_TD_SPD; - for (i = ntd; i >= 0; i--) { - p = uhci_alloc_std(sc); - if (!p) { - uhci_free_std_chain(sc, lastp, 0); - return (USBD_NOMEM); - } - p->td->link.std = lastp; - p->td->td_link = lastlink; - lastp = p; - lastlink = p->physaddr; - p->td->td_status = status; - if (i == ntd) { - /* last TD */ - l = len % maxp; - if (l == 0) l = maxp; - *ep = p; - } else - l = maxp; - p->td->td_token = - rd ? UHCI_TD_IN (l, endpt, addr, tog) : - UHCI_TD_OUT(l, endpt, addr, tog); - p->td->td_buffer = DMAADDR(dma) + i * maxp; - tog ^= 1; - } - *sp = lastp; - /*upipe->pipe.endpoint->toggle = tog;*/ - DPRINTFN(10, ("uhci_alloc_std_chain: oldtog=%d newtog=%d\n", - upipe->pipe.endpoint->toggle, upipe->newtoggle)); - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -uhci_device_bulk_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (uhci_device_bulk_start(reqh)); -} - -usbd_status -uhci_device_bulk_start(reqh) - usbd_request_handle reqh; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - uhci_intr_info_t *ii = upipe->iinfo; - uhci_soft_td_t *xfer, *xferend; - uhci_soft_qh_t *sqh; - usb_dma_t *dmap; - usbd_status r; - int len, isread; - int s; - - DPRINTFN(3, ("uhci_device_bulk_transfer: reqh=%p buf=%p len=%d " - "flags=%d\n", - reqh, reqh->buffer, reqh->length, reqh->flags)); - - if (reqh->isreq) - panic("uhci_device_bulk_transfer: a request\n"); - - len = reqh->length; - dmap = &upipe->u.bulk.datadma; - isread = reqh->pipe->endpoint->edesc->bEndpointAddress & UE_IN; - sqh = upipe->u.bulk.sqh; - - upipe->u.bulk.isread = isread; - upipe->u.bulk.length = len; - - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - goto ret1; - r = uhci_alloc_std_chain(upipe, sc, len, isread, - reqh->flags & USBD_SHORT_XFER_OK, - dmap, &xfer, &xferend); - if (r != USBD_NORMAL_COMPLETION) - goto ret2; - xferend->td->td_status |= UHCI_TD_IOC; - - if (!isread && len != 0) - memcpy(KERNADDR(dmap), reqh->buffer, len); - -#ifdef USB_DEBUG - if (uhcidebug > 10) { - printf("uhci_device_bulk_transfer: xfer(1)\n"); - uhci_dump_tds(xfer); - } -#endif - - /* Set up interrupt info. */ - ii->reqh = reqh; - ii->stdstart = xfer; - ii->stdend = xferend; -#ifdef DIAGNOSTIC - ii->isdone = 0; -#endif - - sqh->qh->elink = xfer; - sqh->qh->qh_elink = xfer->physaddr; - sqh->intr_info = ii; - - s = splusb(); - uhci_add_bulk(sc, sqh); - LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); - - if (reqh->timeout && !sc->sc_bus.use_polling) { - usb_timeout(uhci_timeout, ii, - MS_TO_TICKS(reqh->timeout), ii->timeout_handle); - } - splx(s); - -#ifdef USB_DEBUG - if (uhcidebug > 10) { - printf("uhci_device_bulk_transfer: xfer(2)\n"); - uhci_dump_tds(xfer); - } -#endif - - return (USBD_IN_PROGRESS); - - ret2: - if (len != 0) - usb_freemem(sc->sc_dmatag, dmap); - ret1: - return (r); -} - -/* Abort a device bulk request. */ -void -uhci_device_bulk_abort(reqh) - usbd_request_handle reqh; -{ - /* XXX inactivate */ - usb_delay_ms(reqh->pipe->device->bus, 1);/* make sure it is done */ - /* XXX call done */ -} - -/* Close a device bulk pipe. */ -void -uhci_device_bulk_close(pipe) - usbd_pipe_handle pipe; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - - uhci_free_sqh(sc, upipe->u.bulk.sqh); - uhci_free_intr_info(upipe->iinfo); - /* XXX free other resources */ -} - -usbd_status -uhci_device_ctrl_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (uhci_device_ctrl_start(reqh)); -} - -usbd_status -uhci_device_ctrl_start(reqh) - usbd_request_handle reqh; -{ - uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus; - usbd_status r; - - if (!reqh->isreq) - panic("uhci_device_ctrl_transfer: not a request\n"); - - r = uhci_device_request(reqh); - if (r != USBD_NORMAL_COMPLETION) - return (r); - - if (sc->sc_bus.use_polling) - uhci_waitintr(sc, reqh); - return (USBD_IN_PROGRESS); -} - -usbd_status -uhci_device_intr_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (uhci_device_intr_start(reqh)); -} - -usbd_status -uhci_device_intr_start(reqh) - usbd_request_handle reqh; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - uhci_intr_info_t *ii = upipe->iinfo; - uhci_soft_td_t *xfer, *xferend; - uhci_soft_qh_t *sqh; - usb_dma_t *dmap; - usbd_status r; - int len, i; - int s; - - DPRINTFN(3, ("uhci_device_intr_transfer: reqh=%p buf=%p len=%d " - "flags=%d\n", - reqh, reqh->buffer, reqh->length, reqh->flags)); - - if (reqh->isreq) - panic("uhci_device_intr_transfer: a request\n"); - - len = reqh->length; - dmap = &upipe->u.intr.datadma; - if (len == 0) - return (USBD_INVAL); /* XXX should it be? */ - - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - goto ret1; - r = uhci_alloc_std_chain(upipe, sc, len, 1, - reqh->flags & USBD_SHORT_XFER_OK, - dmap, &xfer, &xferend); - if (r != USBD_NORMAL_COMPLETION) - goto ret2; - xferend->td->td_status |= UHCI_TD_IOC; - -#ifdef USB_DEBUG - if (uhcidebug > 10) { - printf("uhci_device_intr_transfer: xfer(1)\n"); - uhci_dump_tds(xfer); - uhci_dump_qh(upipe->u.intr.qhs[0]); - } -#endif - - s = splusb(); - /* Set up interrupt info. */ - ii->reqh = reqh; - ii->stdstart = xfer; - ii->stdend = xferend; -#ifdef DIAGNOSTIC - ii->isdone = 0; -#endif - - DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n", - upipe->u.intr.qhs[0])); - for (i = 0; i < upipe->u.intr.npoll; i++) { - sqh = upipe->u.intr.qhs[i]; - sqh->qh->elink = xfer; - sqh->qh->qh_elink = xfer->physaddr; - } - splx(s); - -#ifdef USB_DEBUG - if (uhcidebug > 10) { - printf("uhci_device_intr_transfer: xfer(2)\n"); - uhci_dump_tds(xfer); - uhci_dump_qh(upipe->u.intr.qhs[0]); - } -#endif - - return (USBD_IN_PROGRESS); - - ret2: - if (len != 0) - usb_freemem(sc->sc_dmatag, dmap); - ret1: - return (r); -} - -/* Abort a device control request. */ -void -uhci_device_ctrl_abort(reqh) - usbd_request_handle reqh; -{ - /* XXX inactivate */ - usb_delay_ms(reqh->pipe->device->bus, 1); /* make sure it is done */ - /* XXX call done */ -} - -/* Close a device control pipe. */ -void -uhci_device_ctrl_close(pipe) - usbd_pipe_handle pipe; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - - uhci_free_intr_info(upipe->iinfo); - /* XXX free other resources */ -} - -/* Abort a device interrupt request. */ -void -uhci_device_intr_abort(reqh) - usbd_request_handle reqh; -{ - struct uhci_pipe *upipe; - - DPRINTFN(1, ("uhci_device_intr_abort: reqh=%p\n", reqh)); - /* XXX inactivate */ - usb_delay_ms(reqh->pipe->device->bus, 2); /* make sure it is done */ - if (reqh->pipe->intrreqh == reqh) { - DPRINTF(("uhci_device_intr_abort: remove\n")); - reqh->pipe->intrreqh = 0; - upipe = (struct uhci_pipe *)reqh->pipe; - uhci_intr_done(upipe->u.intr.qhs[0]->intr_info); - } -} - -/* Close a device interrupt pipe. */ -void -uhci_device_intr_close(pipe) - usbd_pipe_handle pipe; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; - int i, s, npoll; - - upipe->iinfo->stdstart = 0; /* inactive */ - - /* Unlink descriptors from controller data structures. */ - npoll = upipe->u.intr.npoll; - uhci_lock_frames(sc); - for (i = 0; i < npoll; i++) - uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos, - upipe->u.intr.qhs[i]); - uhci_unlock_frames(sc); - - /* - * We now have to wait for any activity on the physical - * descriptors to stop. - */ - usb_delay_ms(&sc->sc_bus, 2); - - for(i = 0; i < npoll; i++) - uhci_free_sqh(sc, upipe->u.intr.qhs[i]); - free(upipe->u.intr.qhs, M_USB); - - s = splusb(); - LIST_REMOVE(upipe->iinfo, list); /* remove from active list */ - splx(s); - uhci_free_intr_info(upipe->iinfo); - - /* XXX free other resources */ -} - -usbd_status -uhci_device_request(reqh) - usbd_request_handle reqh; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; - usb_device_request_t *req = &reqh->request; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - int addr = dev->address; - int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; - uhci_intr_info_t *ii = upipe->iinfo; - uhci_soft_td_t *setup, *xfer, *stat, *next, *xferend; - uhci_soft_qh_t *sqh; - usb_dma_t *dmap; - int len; - u_int32_t ls; - usbd_status r; - int isread; - int s; - - DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, " - "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n", - req->bmRequestType, req->bRequest, UGETW(req->wValue), - UGETW(req->wIndex), UGETW(req->wLength), - addr, endpt)); - - ls = dev->lowspeed ? UHCI_TD_LS : 0; - isread = req->bmRequestType & UT_READ; - len = UGETW(req->wLength); - - setup = upipe->u.ctl.setup; - stat = upipe->u.ctl.stat; - sqh = upipe->u.ctl.sqh; - dmap = &upipe->u.ctl.datadma; - - /* Set up data transaction */ - if (len != 0) { - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - goto ret1; - upipe->pipe.endpoint->toggle = 1; - r = uhci_alloc_std_chain(upipe, sc, len, isread, - reqh->flags & USBD_SHORT_XFER_OK, - dmap, &xfer, &xferend); - if (r != USBD_NORMAL_COMPLETION) - goto ret2; - next = xfer; - xferend->td->link.std = stat; - xferend->td->td_link = stat->physaddr; - } else { - next = stat; - } - upipe->u.ctl.length = len; - - memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req); - if (!isread && len != 0) - memcpy(KERNADDR(dmap), reqh->buffer, len); - - setup->td->link.std = next; - setup->td->td_link = next->physaddr; - setup->td->td_status = UHCI_TD_SET_ERRCNT(2) | ls | UHCI_TD_ACTIVE; - setup->td->td_token = UHCI_TD_SETUP(sizeof *req, endpt, addr); - setup->td->td_buffer = DMAADDR(&upipe->u.ctl.reqdma); - - stat->td->link.std = 0; - stat->td->td_link = UHCI_PTR_T; - stat->td->td_status = UHCI_TD_SET_ERRCNT(2) | ls | - UHCI_TD_ACTIVE | UHCI_TD_IOC; - stat->td->td_token = - isread ? UHCI_TD_OUT(0, endpt, addr, 1) : - UHCI_TD_IN (0, endpt, addr, 1); - stat->td->td_buffer = 0; - -#ifdef USB_DEBUG - if (uhcidebug > 20) { - printf("uhci_device_request: setup\n"); - uhci_dump_td(setup); - printf("uhci_device_request: stat\n"); - uhci_dump_td(stat); - } -#endif - - /* Set up interrupt info. */ - ii->reqh = reqh; - ii->stdstart = setup; - ii->stdend = stat; -#ifdef DIAGNOSTIC - ii->isdone = 0; -#endif - - sqh->qh->elink = setup; - sqh->qh->qh_elink = setup->physaddr; - sqh->intr_info = ii; - - s = splusb(); - uhci_add_ctrl(sc, sqh); - LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list); -#ifdef USB_DEBUG - if (uhcidebug > 12) { - uhci_soft_td_t *std; - uhci_soft_qh_t *xqh; - uhci_soft_qh_t *sxqh; - int maxqh = 0; - uhci_physaddr_t link; - printf("uhci_enter_ctl_q: follow from [0]\n"); - for (std = sc->sc_vframes[0].htd, link = 0; - (link & UHCI_PTR_Q) == 0; - std = std->td->link.std) { - link = std->td->td_link; - uhci_dump_td(std); - } - for (sxqh = xqh = (uhci_soft_qh_t *)std; - xqh; - xqh = (maxqh++ == 5 || xqh->qh->hlink==sxqh || - xqh->qh->hlink==xqh ? NULL : xqh->qh->hlink)) { - uhci_dump_qh(xqh); - uhci_dump_qh(sxqh); - } - printf("Enqueued QH:\n"); - uhci_dump_qh(sqh); - uhci_dump_tds(sqh->qh->elink); - } -#endif - if (reqh->timeout && !sc->sc_bus.use_polling) { - usb_timeout(uhci_timeout, ii, - MS_TO_TICKS(reqh->timeout), ii->timeout_handle); - } - splx(s); - - return (USBD_NORMAL_COMPLETION); - - ret2: - if (len != 0) - usb_freemem(sc->sc_dmatag, dmap); - ret1: - return (r); -} - -usbd_status -uhci_device_isoc_transfer(reqh) - usbd_request_handle reqh; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; -#ifdef USB_DEBUG - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = (uhci_softc_t *)dev->bus; -#endif - - DPRINTFN(1,("uhci_device_isoc_transfer: sc=%p\n", sc)); - if (upipe->u.iso.bufsize == 0) - return (USBD_INVAL); - - /* XXX copy data */ - return (USBD_XXX); -} - -usbd_status -uhci_device_isoc_start(reqh) - usbd_request_handle reqh; -{ - return (USBD_XXX); -} - -void -uhci_device_isoc_abort(reqh) - usbd_request_handle reqh; -{ - /* XXX Can't abort a single request. */ -} - -void -uhci_device_isoc_close(pipe) - usbd_pipe_handle pipe; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - struct iso *iso; - int i; - - /* - * Make sure all TDs are marked as inactive. - * Wait for completion. - * Unschedule. - * Deallocate. - */ - iso = &upipe->u.iso; - - for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) - iso->stds[i]->td->td_status &= ~UHCI_TD_ACTIVE; - usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */ - - uhci_lock_frames(sc); - for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { - uhci_soft_td_t *std, *vstd; - - std = iso->stds[i]; - for (vstd = sc->sc_vframes[i % UHCI_VFRAMELIST_COUNT].htd; - vstd && vstd->td->link.std != std; - vstd = vstd->td->link.std) - ; - if (!vstd) { - /*panic*/ - printf("uhci_device_isoc_close: %p not found\n", std); - uhci_unlock_frames(sc); - return; - } - vstd->td->link = std->td->link; - vstd->td->td_link = std->td->td_link; - uhci_free_std(sc, std); - } - uhci_unlock_frames(sc); - - for (i = 0; i < iso->nbuf; i++) - usb_freemem(sc->sc_dmatag, &iso->bufs[i]); - free(iso->stds, M_USB); - free(iso->bufs, M_USB); - - /* XXX what else? */ -} - -usbd_status -uhci_device_isoc_setbuf(pipe, bufsize, nbuf) - usbd_pipe_handle pipe; - u_int bufsize; - u_int nbuf; -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = (uhci_softc_t *)dev->bus; - int addr = upipe->pipe.device->address; - int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; - int rd = upipe->pipe.endpoint->edesc->bEndpointAddress & UE_IN; - struct iso *iso; - int i; - usbd_status r; - - /* - * For simplicity the number of buffers must fit nicely in the frame - * list. - */ - if (UHCI_VFRAMELIST_COUNT % nbuf != 0) - return (USBD_INVAL); - - iso = &upipe->u.iso; - iso->bufsize = bufsize; - iso->nbuf = nbuf; - - /* Allocate memory for buffers. */ - iso->bufs = malloc(nbuf * sizeof(usb_dma_t), M_USB, M_WAITOK); - iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *), - M_USB, M_WAITOK); - - for (i = 0; i < nbuf; i++) { - r = usb_allocmem(sc->sc_dmatag, bufsize, 0, &iso->bufs[i]); - if (r != USBD_NORMAL_COMPLETION) { - nbuf = i; - goto bad1; - } - } - - /* Allocate the TDs. */ - for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { - iso->stds[i] = uhci_alloc_std(sc); - if (iso->stds[i] == 0) - goto bad2; - } - - /* XXX check schedule */ - - /* XXX interrupts */ - - /* Insert TDs into schedule, all marked inactive. */ - uhci_lock_frames(sc); - for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { - uhci_soft_td_t *std, *vstd; - - std = iso->stds[i]; - std->td->td_status = UHCI_TD_IOS; /* iso, inactive */ - std->td->td_token = - rd ? UHCI_TD_IN (0, endpt, addr, 0) : - UHCI_TD_OUT(0, endpt, addr, 0); - std->td->td_buffer = DMAADDR(&iso->bufs[i % nbuf]); - - vstd = sc->sc_vframes[i % UHCI_VFRAMELIST_COUNT].htd; - std->td->link = vstd->td->link; - std->td->td_link = vstd->td->td_link; - vstd->td->link.std = std; - vstd->td->td_link = std->physaddr; - } - uhci_unlock_frames(sc); - - return (USBD_NORMAL_COMPLETION); - - bad2: - while (--i >= 0) - uhci_free_std(sc, iso->stds[i]); - bad1: - for (i = 0; i < nbuf; i++) - usb_freemem(sc->sc_dmatag, &iso->bufs[i]); - free(iso->stds, M_USB); - free(iso->bufs, M_USB); - return (USBD_NOMEM); -} - -void -uhci_isoc_done(ii) - uhci_intr_info_t *ii; -{ -} - -void -uhci_intr_done(ii) - uhci_intr_info_t *ii; -{ - uhci_softc_t *sc = ii->sc; - usbd_request_handle reqh = ii->reqh; - struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; - usb_dma_t *dma; - uhci_soft_qh_t *sqh; - int i, npoll; - - DPRINTFN(5, ("uhci_intr_done: length=%d\n", reqh->actlen)); - - dma = &upipe->u.intr.datadma; - memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen); - npoll = upipe->u.intr.npoll; - for(i = 0; i < npoll; i++) { - sqh = upipe->u.intr.qhs[i]; - sqh->qh->elink = 0; - sqh->qh->qh_elink = UHCI_PTR_T; - } - uhci_free_std_chain(sc, ii->stdstart, 0); - - /* XXX Wasteful. */ - if (reqh->pipe->intrreqh == reqh) { - uhci_soft_td_t *xfer, *xferend; - - /* This alloc cannot fail since we freed the chain above. */ - uhci_alloc_std_chain(upipe, sc, reqh->length, 1, - reqh->flags & USBD_SHORT_XFER_OK, - dma, &xfer, &xferend); - xferend->td->td_status |= UHCI_TD_IOC; - -#ifdef USB_DEBUG - if (uhcidebug > 10) { - printf("uhci_device_intr_done: xfer(1)\n"); - uhci_dump_tds(xfer); - uhci_dump_qh(upipe->u.intr.qhs[0]); - } -#endif - - ii->stdstart = xfer; - ii->stdend = xferend; -#ifdef DIAGNOSTIC - ii->isdone = 0; -#endif - for (i = 0; i < npoll; i++) { - sqh = upipe->u.intr.qhs[i]; - sqh->qh->elink = xfer; - sqh->qh->qh_elink = xfer->physaddr; - } - } else { - usb_freemem(sc->sc_dmatag, dma); - ii->stdstart = 0; /* mark as inactive */ - usb_start_next(reqh->pipe); - } -} - -/* Deallocate request data structures */ -void -uhci_ctrl_done(ii) - uhci_intr_info_t *ii; -{ - uhci_softc_t *sc = ii->sc; - usbd_request_handle reqh = ii->reqh; - struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; - u_int len = upipe->u.ctl.length; - usb_dma_t *dma; - uhci_td_t *htd = ii->stdstart->td; - -#ifdef DIAGNOSTIC - if (!reqh->isreq) - panic("uhci_ctrl_done: not a request\n"); -#endif - - LIST_REMOVE(ii, list); /* remove from active list */ - - uhci_remove_ctrl(sc, upipe->u.ctl.sqh); - - if (len != 0) { - dma = &upipe->u.ctl.datadma; - if (reqh->request.bmRequestType & UT_READ) - memcpy(reqh->buffer, KERNADDR(dma), len); - uhci_free_std_chain(sc, htd->link.std, ii->stdend); - usb_freemem(sc->sc_dmatag, dma); - } - DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", reqh->actlen)); -} - -/* Deallocate request data structures */ -void -uhci_bulk_done(ii) - uhci_intr_info_t *ii; -{ - uhci_softc_t *sc = ii->sc; - usbd_request_handle reqh = ii->reqh; - struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe; - u_int len = upipe->u.bulk.length; - usb_dma_t *dma; - uhci_td_t *htd = ii->stdstart->td; - - LIST_REMOVE(ii, list); /* remove from active list */ - - uhci_remove_bulk(sc, upipe->u.bulk.sqh); - - if (len != 0) { - dma = &upipe->u.bulk.datadma; - if (upipe->u.bulk.isread && len != 0) - memcpy(reqh->buffer, KERNADDR(dma), len); - uhci_free_std_chain(sc, htd->link.std, 0); - usb_freemem(sc->sc_dmatag, dma); - } - DPRINTFN(4, ("uhci_bulk_done: length=%d\n", reqh->actlen)); - /* XXX compute new toggle */ -} - -/* Add interrupt QH, called with vflock. */ -void -uhci_add_intr(sc, n, sqh) - uhci_softc_t *sc; - int n; - uhci_soft_qh_t *sqh; -{ - struct uhci_vframe *vf = &sc->sc_vframes[n]; - uhci_qh_t *eqh; - - DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh)); - eqh = vf->eqh->qh; - sqh->qh->hlink = eqh->hlink; - sqh->qh->qh_hlink = eqh->qh_hlink; - eqh->hlink = sqh; - eqh->qh_hlink = sqh->physaddr | UHCI_PTR_Q; - vf->eqh = sqh; - vf->bandwidth++; -} - -/* Remove interrupt QH, called with vflock. */ -void -uhci_remove_intr(sc, n, sqh) - uhci_softc_t *sc; - int n; - uhci_soft_qh_t *sqh; -{ - struct uhci_vframe *vf = &sc->sc_vframes[n]; - uhci_soft_qh_t *pqh; - - DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh)); - - for (pqh = vf->hqh; pqh->qh->hlink != sqh; pqh = pqh->qh->hlink) -#if defined(DIAGNOSTIC) || defined(USB_DEBUG) - if (pqh->qh->qh_hlink & UHCI_PTR_T) { - printf("uhci_remove_intr: QH not found\n"); - return; - } -#else - ; -#endif - pqh->qh->hlink = sqh->qh->hlink; - pqh->qh->qh_hlink = sqh->qh->qh_hlink; - if (vf->eqh == sqh) - vf->eqh = pqh; - vf->bandwidth--; -} - -usbd_status -uhci_device_setintr(sc, upipe, ival) - uhci_softc_t *sc; - struct uhci_pipe *upipe; - int ival; -{ - uhci_soft_qh_t *sqh; - int i, npoll, s; - u_int bestbw, bw, bestoffs, offs; - - DPRINTFN(2, ("uhci_setintr: pipe=%p\n", upipe)); - if (ival == 0) { - printf("uhci_setintr: 0 interval\n"); - return (USBD_INVAL); - } - - if (ival > UHCI_VFRAMELIST_COUNT) - ival = UHCI_VFRAMELIST_COUNT; - npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival; - DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll)); - - upipe->u.intr.npoll = npoll; - upipe->u.intr.qhs = - malloc(npoll * sizeof(uhci_soft_qh_t *), M_USB, M_WAITOK); - - /* - * Figure out which offset in the schedule that has most - * bandwidth left over. - */ -#define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1)) - for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) { - for (bw = i = 0; i < npoll; i++) - bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth; - if (bw < bestbw) { - bestbw = bw; - bestoffs = offs; - } - } - DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs)); - - upipe->iinfo->stdstart = 0; - for(i = 0; i < npoll; i++) { - upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc); - sqh->qh->elink = 0; - sqh->qh->qh_elink = UHCI_PTR_T; - sqh->pos = MOD(i * ival + bestoffs); - sqh->intr_info = upipe->iinfo; - } -#undef MOD - - s = splusb(); - LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list); - splx(s); - - uhci_lock_frames(sc); - /* Enter QHs into the controller data structures. */ - for(i = 0; i < npoll; i++) - uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos, - upipe->u.intr.qhs[i]); - uhci_unlock_frames(sc); - - DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe)); - return (USBD_NORMAL_COMPLETION); -} - -/* Open a new pipe. */ -usbd_status -uhci_open(pipe) - usbd_pipe_handle pipe; -{ - uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; - usbd_status r; - - DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", - pipe, pipe->device->address, - ed->bEndpointAddress, sc->sc_addr)); - if (pipe->device->address == sc->sc_addr) { - switch (ed->bEndpointAddress) { - case USB_CONTROL_ENDPOINT: - pipe->methods = &uhci_root_ctrl_methods; - break; - case UE_IN | UHCI_INTR_ENDPT: - pipe->methods = &uhci_root_intr_methods; - break; - default: - return (USBD_INVAL); - } - } else { - upipe->iinfo = uhci_alloc_intr_info(sc); - if (upipe->iinfo == 0) - return (USBD_NOMEM); - switch (ed->bmAttributes & UE_XFERTYPE) { - case UE_CONTROL: - pipe->methods = &uhci_device_ctrl_methods; - upipe->u.ctl.sqh = uhci_alloc_sqh(sc); - if (upipe->u.ctl.sqh == 0) - goto bad; - upipe->u.ctl.setup = uhci_alloc_std(sc); - if (upipe->u.ctl.setup == 0) { - uhci_free_sqh(sc, upipe->u.ctl.sqh); - goto bad; - } - upipe->u.ctl.stat = uhci_alloc_std(sc); - if (upipe->u.ctl.stat == 0) { - uhci_free_sqh(sc, upipe->u.ctl.sqh); - uhci_free_std(sc, upipe->u.ctl.setup); - goto bad; - } - r = usb_allocmem(sc->sc_dmatag, - sizeof(usb_device_request_t), - 0, &upipe->u.ctl.reqdma); - if (r != USBD_NORMAL_COMPLETION) { - uhci_free_sqh(sc, upipe->u.ctl.sqh); - uhci_free_std(sc, upipe->u.ctl.setup); - uhci_free_std(sc, upipe->u.ctl.stat); - goto bad; - } - break; - case UE_INTERRUPT: - pipe->methods = &uhci_device_intr_methods; - return (uhci_device_setintr(sc, upipe, ed->bInterval)); - case UE_ISOCHRONOUS: - pipe->methods = &uhci_device_isoc_methods; - upipe->u.iso.nbuf = 0; - return (USBD_NORMAL_COMPLETION); - case UE_BULK: - pipe->methods = &uhci_device_bulk_methods; - upipe->u.bulk.sqh = uhci_alloc_sqh(sc); - if (upipe->u.bulk.sqh == 0) - goto bad; - break; - } - } - return (USBD_NORMAL_COMPLETION); - - bad: - uhci_free_intr_info(upipe->iinfo); - return (USBD_NOMEM); -} - -/* - * Data structures and routines to emulate the root hub. - */ -usb_device_descriptor_t uhci_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x00, 0x01}, /* USB version */ - UCLASS_HUB, /* class */ - USUBCLASS_HUB, /* subclass */ - 0, /* protocol */ - 64, /* max packet */ - {0},{0},{0x00,0x01}, /* device id */ - 1,2,0, /* string indicies */ - 1 /* # of configurations */ -}; - -usb_config_descriptor_t uhci_confd = { - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, - 1, - 0, - UC_SELF_POWERED, - 0 /* max power */ -}; - -usb_interface_descriptor_t uhci_ifcd = { - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, - 0, - 1, - UCLASS_HUB, - USUBCLASS_HUB, - 0, - 0 -}; - -usb_endpoint_descriptor_t uhci_endpd = { - USB_ENDPOINT_DESCRIPTOR_SIZE, - UDESC_ENDPOINT, - UE_IN | UHCI_INTR_ENDPT, - UE_INTERRUPT, - {8}, - 255 -}; - -usb_hub_descriptor_t uhci_hubd_piix = { - USB_HUB_DESCRIPTOR_SIZE, - UDESC_HUB, - 2, - { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 }, - 50, /* power on to power good */ - 0, - { 0x00 }, /* both ports are removable */ -}; - -int -uhci_str(p, l, s) - usb_string_descriptor_t *p; - int l; - char *s; -{ - int i; - - if (l == 0) - return (0); - p->bLength = 2 * strlen(s) + 2; - if (l == 1) - return (1); - p->bDescriptorType = UDESC_STRING; - l -= 2; - for (i = 0; s[i] && l > 1; i++, l -= 2) - USETW2(p->bString[i], 0, s[i]); - return (2*i+2); -} - -/* - * Simulate a hardware hub by handling all the necessary requests. - */ -usbd_status -uhci_root_ctrl_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (uhci_root_ctrl_start(reqh)); -} - -usbd_status -uhci_root_ctrl_start(reqh) - usbd_request_handle reqh; -{ - uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus; - usb_device_request_t *req; - void *buf; - int port, x; - int len, value, index, status, change, l, totlen = 0; - usb_port_status_t ps; - usbd_status r; - - if (!reqh->isreq) - panic("uhci_root_ctrl_transfer: not a request\n"); - req = &reqh->request; - buf = reqh->buffer; - - DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n", - req->bmRequestType, req->bRequest)); - - len = UGETW(req->wLength); - value = UGETW(req->wValue); - index = UGETW(req->wIndex); -#define C(x,y) ((x) | ((y) << 8)) - switch(C(req->bRequest, req->bmRequestType)) { - case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): - case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): - case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* - * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops - * for the integrated root hub. - */ - break; - case C(UR_GET_CONFIG, UT_READ_DEVICE): - if (len > 0) { - *(u_int8_t *)buf = sc->sc_conf; - totlen = 1; - } - break; - case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): - DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value)); - switch(value >> 8) { - case UDESC_DEVICE: - if ((value & 0xff) != 0) { - r = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - memcpy(buf, &uhci_devd, l); - break; - case UDESC_CONFIG: - if ((value & 0xff) != 0) { - r = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); - memcpy(buf, &uhci_confd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &uhci_ifcd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &uhci_endpd, l); - break; - case UDESC_STRING: - if (len == 0) - break; - *(u_int8_t *)buf = 0; - totlen = 1; - switch (value & 0xff) { - case 1: /* Vendor */ - totlen = uhci_str(buf, len, sc->sc_vendor); - break; - case 2: /* Product */ - totlen = uhci_str(buf, len, "UHCI root hub"); - break; - } - break; - default: - r = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_INTERFACE, UT_READ_INTERFACE): - if (len > 0) { - *(u_int8_t *)buf = 0; - totlen = 1; - } - break; - case C(UR_GET_STATUS, UT_READ_DEVICE): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); - totlen = 2; - } - break; - case C(UR_GET_STATUS, UT_READ_INTERFACE): - case C(UR_GET_STATUS, UT_READ_ENDPOINT): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus, 0); - totlen = 2; - } - break; - case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): - if (value >= USB_MAX_DEVICES) { - r = USBD_IOERROR; - goto ret; - } - sc->sc_addr = value; - break; - case C(UR_SET_CONFIG, UT_WRITE_DEVICE): - if (value != 0 && value != 1) { - r = USBD_IOERROR; - goto ret; - } - sc->sc_conf = value; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_DEVICE): - case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): - case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): - r = USBD_IOERROR; - goto ret; - case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): - break; - case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): - break; - /* Hub requests */ - case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): - break; - case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): - DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE " - "port=%d feature=%d\n", - index, value)); - if (index == 1) - port = UHCI_PORTSC1; - else if (index == 2) - port = UHCI_PORTSC2; - else { - r = USBD_IOERROR; - goto ret; - } - switch(value) { - case UHF_PORT_ENABLE: - x = UREAD2(sc, port); - UWRITE2(sc, port, x & ~UHCI_PORTSC_PE); - break; - case UHF_PORT_SUSPEND: - x = UREAD2(sc, port); - UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP); - break; - case UHF_PORT_RESET: - x = UREAD2(sc, port); - UWRITE2(sc, port, x & ~UHCI_PORTSC_PR); - break; - case UHF_C_PORT_CONNECTION: - x = UREAD2(sc, port); - UWRITE2(sc, port, x | UHCI_PORTSC_CSC); - break; - case UHF_C_PORT_ENABLE: - x = UREAD2(sc, port); - UWRITE2(sc, port, x | UHCI_PORTSC_POEDC); - break; - case UHF_C_PORT_OVER_CURRENT: - x = UREAD2(sc, port); - UWRITE2(sc, port, x | UHCI_PORTSC_OCIC); - break; - case UHF_C_PORT_RESET: - sc->sc_isreset = 0; - r = USBD_NORMAL_COMPLETION; - goto ret; - case UHF_PORT_CONNECTION: - case UHF_PORT_OVER_CURRENT: - case UHF_PORT_POWER: - case UHF_PORT_LOW_SPEED: - case UHF_C_PORT_SUSPEND: - default: - r = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): - if (index == 1) - port = UHCI_PORTSC1; - else if (index == 2) - port = UHCI_PORTSC2; - else { - r = USBD_IOERROR; - goto ret; - } - if (len > 0) { - *(u_int8_t *)buf = - (UREAD2(sc, port) & UHCI_PORTSC_LS) >> - UHCI_PORTSC_LS_SHIFT; - totlen = 1; - } - break; - case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): - if (value != 0) { - r = USBD_IOERROR; - goto ret; - } - l = min(len, USB_HUB_DESCRIPTOR_SIZE); - totlen = l; - memcpy(buf, &uhci_hubd_piix, l); - break; - case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): - if (len != 4) { - r = USBD_IOERROR; - goto ret; - } - memset(buf, 0, len); - totlen = len; - break; - case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): - if (index == 1) - port = UHCI_PORTSC1; - else if (index == 2) - port = UHCI_PORTSC2; - else { - r = USBD_IOERROR; - goto ret; - } - if (len != 4) { - r = USBD_IOERROR; - goto ret; - } - x = UREAD2(sc, port); - status = change = 0; - if (x & UHCI_PORTSC_CCS ) - status |= UPS_CURRENT_CONNECT_STATUS; - if (x & UHCI_PORTSC_CSC ) - change |= UPS_C_CONNECT_STATUS; - if (x & UHCI_PORTSC_PE ) - status |= UPS_PORT_ENABLED; - if (x & UHCI_PORTSC_POEDC) - change |= UPS_C_PORT_ENABLED; - if (x & UHCI_PORTSC_OCI ) - status |= UPS_OVERCURRENT_INDICATOR; - if (x & UHCI_PORTSC_OCIC ) - change |= UPS_C_OVERCURRENT_INDICATOR; - if (x & UHCI_PORTSC_SUSP ) - status |= UPS_SUSPEND; - if (x & UHCI_PORTSC_LSDA ) - status |= UPS_LOW_SPEED; - status |= UPS_PORT_POWER; - if (sc->sc_isreset) - change |= UPS_C_PORT_RESET; - USETW(ps.wPortStatus, status); - USETW(ps.wPortChange, change); - l = min(len, sizeof ps); - memcpy(buf, &ps, l); - totlen = l; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): - r = USBD_IOERROR; - goto ret; - case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): - if (index == 1) - port = UHCI_PORTSC1; - else if (index == 2) - port = UHCI_PORTSC2; - else { - r = USBD_IOERROR; - goto ret; - } - switch(value) { - case UHF_PORT_ENABLE: - x = UREAD2(sc, port); - UWRITE2(sc, port, x | UHCI_PORTSC_PE); - break; - case UHF_PORT_SUSPEND: - x = UREAD2(sc, port); - UWRITE2(sc, port, x | UHCI_PORTSC_SUSP); - break; - case UHF_PORT_RESET: - x = UREAD2(sc, port); - UWRITE2(sc, port, x | UHCI_PORTSC_PR); - usb_delay_ms(&sc->sc_bus, 10); - UWRITE2(sc, port, x & ~UHCI_PORTSC_PR); - delay(100); - x = UREAD2(sc, port); - UWRITE2(sc, port, x | UHCI_PORTSC_PE); - delay(100); - DPRINTFN(3,("uhci port %d reset, status = 0x%04x\n", - index, UREAD2(sc, port))); - sc->sc_isreset = 1; - break; - case UHF_C_PORT_CONNECTION: - case UHF_C_PORT_ENABLE: - case UHF_C_PORT_OVER_CURRENT: - case UHF_PORT_CONNECTION: - case UHF_PORT_OVER_CURRENT: - case UHF_PORT_POWER: - case UHF_PORT_LOW_SPEED: - case UHF_C_PORT_SUSPEND: - case UHF_C_PORT_RESET: - default: - r = USBD_IOERROR; - goto ret; - } - break; - default: - r = USBD_IOERROR; - goto ret; - } - reqh->actlen = totlen; - r = USBD_NORMAL_COMPLETION; - ret: - reqh->status = r; - reqh->xfercb(reqh); - usb_start_next(reqh->pipe); - return (USBD_IN_PROGRESS); -} - -/* Abort a root control request. */ -void -uhci_root_ctrl_abort(reqh) - usbd_request_handle reqh; -{ - /* Nothing to do, all transfers are syncronous. */ -} - -/* Close the root pipe. */ -void -uhci_root_ctrl_close(pipe) - usbd_pipe_handle pipe; -{ - usb_untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->timo_handle); - DPRINTF(("uhci_root_ctrl_close\n")); -} - -/* Abort a root interrupt request. */ -void -uhci_root_intr_abort(reqh) - usbd_request_handle reqh; -{ - usb_untimeout(uhci_timo, reqh, reqh->timo_handle); -} - -usbd_status -uhci_root_intr_transfer(reqh) - usbd_request_handle reqh; -{ - int s; - usbd_status r; - - s = splusb(); - r = usb_insert_transfer(reqh); - splx(s); - if (r != USBD_NORMAL_COMPLETION) - return (r); - else - return (uhci_root_intr_start(reqh)); -} - -/* Start a transfer on the root interrupt pipe */ -usbd_status -uhci_root_intr_start(reqh) - usbd_request_handle reqh; -{ - usbd_pipe_handle pipe = reqh->pipe; - uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus; - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usb_dma_t *dmap; - usbd_status r; - int len; - - DPRINTFN(3, ("uhci_root_intr_transfer: reqh=%p buf=%p len=%d " - "flags=%d\n", - reqh, reqh->buffer, reqh->length, reqh->flags)); - - len = reqh->length; - dmap = &upipe->u.intr.datadma; - if (len == 0) - return (USBD_INVAL); /* XXX should it be? */ - - r = usb_allocmem(sc->sc_dmatag, len, 0, dmap); - if (r != USBD_NORMAL_COMPLETION) - return (r); - - sc->sc_ival = MS_TO_TICKS(reqh->pipe->endpoint->edesc->bInterval); - usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle); - return (USBD_IN_PROGRESS); -} - -/* Close the root interrupt pipe. */ -void -uhci_root_intr_close(pipe) - usbd_pipe_handle pipe; -{ - usb_untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->timo_handle); - DPRINTF(("uhci_root_intr_close\n")); -} diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h deleted file mode 100644 index 9c8ef008b2b70..0000000000000 --- a/sys/dev/usb/uhcireg.h +++ /dev/null @@ -1,191 +0,0 @@ -/* $NetBSD: uhcireg.h,v 1.5 1998/12/27 23:40:52 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _DEV_PCI_UHCIREG_H_ -#define _DEV_PCI_UHCIREG_H_ - -/*** PCI config registers ***/ - -#define PCI_USBREV 0x60 /* USB protocol revision */ -#define PCI_USBREV_MASK 0xff -#define PCI_USBREV_PRE_1_0 0x00 -#define PCI_USBREV_1_0 0x10 - -#define PCI_CBIO 0x20 /* configuration base IO */ - -#define PCI_INTERFACE_UHCI 0x00 - -/*** UHCI registers ***/ - -#define UHCI_CMD 0x00 -#define UHCI_CMD_RS 0x0001 -#define UHCI_CMD_HCRESET 0x0002 -#define UHCI_CMD_GRESET 0x0004 -#define UHCI_CMD_EGSM 0x0008 -#define UHCI_CMD_FGR 0x0010 -#define UHCI_CMD_SWDBG 0x0020 -#define UHCI_CMD_CF 0x0040 -#define UHCI_CMD_MAXP 0x0080 - -#define UHCI_STS 0x02 -#define UHCI_STS_USBINT 0x0001 -#define UHCI_STS_USBEI 0x0002 -#define UHCI_STS_RD 0x0004 -#define UHCI_STS_HSE 0x0008 -#define UHCI_STS_HCPE 0x0010 -#define UHCI_STS_HCH 0x0020 - -#define UHCI_INTR 0x04 -#define UHCI_INTR_TOCRCIE 0x0001 -#define UHCI_INTR_RIE 0x0002 -#define UHCI_INTR_IOCE 0x0004 -#define UHCI_INTR_SPIE 0x0008 - -#define UHCI_FRNUM 0x06 -#define UHCI_FRNUM_MASK 0x03ff - - -#define UHCI_FLBASEADDR 0x08 - -#define UHCI_SOF 0x0c -#define UHCI_SOF_MASK 0x7f - -#define UHCI_PORTSC1 0x010 -#define UHCI_PORTSC2 0x012 -#define UHCI_PORTSC_CCS 0x0001 -#define UHCI_PORTSC_CSC 0x0002 -#define UHCI_PORTSC_PE 0x0004 -#define UHCI_PORTSC_POEDC 0x0008 -#define UHCI_PORTSC_LS 0x0030 -#define UHCI_PORTSC_LS_SHIFT 4 -#define UHCI_PORTSC_RD 0x0040 -#define UHCI_PORTSC_LSDA 0x0100 -#define UHCI_PORTSC_PR 0x0200 -#define UHCI_PORTSC_OCI 0x0400 -#define UHCI_PORTSC_OCIC 0x0800 -#define UHCI_PORTSC_SUSP 0x1000 - -#define UHCI_FRAMELIST_COUNT 1024 -#define UHCI_FRAMELIST_ALIGN 4096 - -#define UHCI_TD_ALIGN 16 -#define UHCI_QH_ALIGN 16 - -typedef u_int32_t uhci_physaddr_t; -#define UHCI_PTR_T 0x00000001 -#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 - * concurrently. This means that they have to be accessed - * with great care. As long as the data structures are - * not linked into the controller's frame list they cannot - * be accessed by it and anything goes. As soon as a - * TD is accessible by the controller it "owns" the td_status - * field; it will not be written by the CPU. Similarly - * the controller "owns" the qh_elink field. - */ - -typedef struct { - uhci_physaddr_t td_link; - u_int32_t td_status; -#define UHCI_TD_GET_ACTLEN(s) (((s) + 1) & 0x3ff) -#define UHCI_TD_ZERO_ACTLEN(t) ((t) | 0x3ff) -#define UHCI_TD_BITSTUFF 0x00020000 -#define UHCI_TD_CRCTO 0x00040000 -#define UHCI_TD_NAK 0x00080000 -#define UHCI_TD_BABBLE 0x00100000 -#define UHCI_TD_DBUFFER 0x00200000 -#define UHCI_TD_STALLED 0x00400000 -#define UHCI_TD_ACTIVE 0x00800000 -#define UHCI_TD_IOC 0x01000000 -#define UHCI_TD_IOS 0x02000000 -#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 - u_int32_t td_token; -#define UHCI_TD_PID_IN 0x00000069 -#define UHCI_TD_PID_OUT 0x000000e1 -#define UHCI_TD_PID_SETUP 0x0000002d -#define UHCI_TD_GET_PID(s) ((s) & 0xff) -#define UHCI_TD_SET_DEVADDR(a) ((a) << 8) -#define UHCI_TD_GET_DEVADDR(s) (((s) >> 8) & 0x7f) -#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(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; /* soft version of the td_link field */ - /* 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) - -#define UHCI_TD_SETUP(len, endp, dev) (UHCI_TD_SET_MAXLEN(len) | \ - UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_SETUP) -#define UHCI_TD_OUT(len, endp, dev, dt) (UHCI_TD_SET_MAXLEN(len) | \ - UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | \ - UHCI_TD_PID_OUT | UHCI_TD_SET_DT(dt)) -#define UHCI_TD_IN(len, endp, dev, dt) (UHCI_TD_SET_MAXLEN(len) | \ - UHCI_TD_SET_ENDPT(endp) | UHCI_TD_SET_DEVADDR(dev) | UHCI_TD_PID_IN | \ - UHCI_TD_SET_DT(dt)) - -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_ */ diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h deleted file mode 100644 index 7143c42fbf0d1..0000000000000 --- a/sys/dev/usb/uhcivar.h +++ /dev/null @@ -1,180 +0,0 @@ -/* $NetBSD: uhcivar.h,v 1.5 1998/12/26 12:53:02 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * To avoid having 1024 TDs for each isochronous transfer we introduce - * 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. - * - * 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; - -/* - * An interrupt info struct contains the information needed to - * execute a requested routine when the controller generates an - * interrupt. Since we cannot know which transfer generated - * the interrupt all structs are linked together so they can be - * searched at interrupt time. - */ -typedef struct uhci_intr_info { - struct uhci_softc *sc; - usbd_request_handle reqh; - uhci_soft_td_t *stdstart; - uhci_soft_td_t *stdend; - LIST_ENTRY(uhci_intr_info) list; -#if defined(__FreeBSD__) - struct callout_handle timeout_handle; -#endif /* defined(__FreeBSD__) */ -#ifdef DIAGNOSTIC - int isdone; -#endif -} uhci_intr_info_t; - -/* - * 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. */ -}; -#define UHCI_TD_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. */ - int pos; /* Timeslot position */ - uhci_intr_info_t *intr_info; /* Who to call on completion. */ -}; -#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)*/ - -/* - * Information about an entry in the virtial frame list. - */ -struct uhci_vframe { - uhci_soft_td_t *htd; /* pointer to dummy TD */ - uhci_soft_td_t *etd; /* pointer to last TD */ - uhci_soft_qh_t *hqh; /* pointer to dummy QH */ - uhci_soft_qh_t *eqh; /* pointer to last QH */ - u_int bandwidth; /* max bandwidth used by this frame */ -}; - -typedef struct uhci_softc { - struct usbd_bus sc_bus; /* base device */ -#if defined(__NetBSD__) - void *sc_ih; /* interrupt vectoring */ - bus_space_tag_t iot; - bus_space_handle_t ioh; - - bus_dma_tag_t sc_dmatag; /* DMA tag */ - /* XXX should keep track of all DMA memory */ -#elif defined(__FreeBSD__) - int sc_iobase; - int unit; -#endif /* defined(__FreeBSD__) */ - - uhci_physaddr_t *sc_pframes; - struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT]; - - uhci_soft_qh_t *sc_ctl_start; /* dummy QH for control */ - uhci_soft_qh_t *sc_ctl_end; /* last control QH */ - uhci_soft_qh_t *sc_bulk_start; /* dummy QH for bulk */ - uhci_soft_qh_t *sc_bulk_end; /* last bulk transfer */ - - 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; - - int sc_intrs; - LIST_HEAD(, uhci_intr_info) sc_intrhead; - - /* Info for the root hub interrupt channel. */ - int sc_ival; - - char sc_vflock; -#define UHCI_HAS_LOCK 1 -#define UHCI_WANT_LOCK 2 - -#if defined(__NetBSD__) - usb_dma_t *sc_mallocs; -#endif - - char sc_vendor[16]; -} uhci_softc_t; - -usbd_status uhci_init __P((uhci_softc_t *)); -int uhci_intr __P((void *)); -#if 0 -void uhci_reset __P((void *)); -#endif - -#ifdef USB_DEBUG -#define DPRINTF(x) if (uhcidebug) printf x -#define DPRINTFN(n,x) if (uhcidebug>(n)) printf x -extern int uhcidebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c deleted file mode 100644 index 26c0e5b5b20f6..0000000000000 --- a/sys/dev/usb/uhid.c +++ /dev/null @@ -1,546 +0,0 @@ -/* $NetBSD: uhid.c,v 1.14 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#include <sys/ioctl.h> -#elif defined(__FreeBSD__) -#include <sys/ioccom.h> -#include <sys/filio.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/ioccom.h> -#endif -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/select.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/poll.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbhid.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/hid.h> -#include <dev/usb/usb_quirks.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) if (uhiddebug) printf x -#define DPRINTFN(n,x) if (uhiddebug>(n)) printf x -int uhiddebug = 1; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -struct uhid_softc { - bdevice sc_dev; /* base device */ - usbd_interface_handle sc_iface; /* interface */ - usbd_pipe_handle sc_intrpipe; /* interrupt pipe */ - int sc_ep_addr; - - int sc_isize; - int sc_osize; - int sc_fsize; - u_int8_t sc_iid; - u_int8_t sc_oid; - u_int8_t sc_fid; - - char *sc_ibuf; - char *sc_obuf; - - void *sc_repdesc; - int sc_repdesc_size; - - struct clist sc_q; - struct selinfo sc_rsel; - u_char sc_state; /* driver state */ -#define UHID_OPEN 0x01 /* device is open */ -#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 */ -}; - -#define UHIDUNIT(dev) (minor(dev)) -#define UHID_CHUNK 128 /* chunk size for read */ -#define UHID_BSIZE 1020 /* buffer size */ - -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 *)); -void uhid_intr __P((usbd_request_handle, usbd_private_handle, usbd_status)); -void uhid_disco __P((void *)); - -USB_DECLARE_DRIVER(uhid); - -USB_MATCH(uhid) -{ - USB_MATCH_START(uhid, uaa); - usb_interface_descriptor_t *id; - - if (!uaa->iface) - return (UMATCH_NONE); - id = usbd_get_interface_descriptor(uaa->iface); - if (!id || id->bInterfaceClass != UCLASS_HID) - return (UMATCH_NONE); - return (UMATCH_IFACECLASS_GENERIC); -} - -USB_ATTACH(uhid) -{ - USB_ATTACH_START(uhid, sc, uaa); - usbd_interface_handle iface = uaa->iface; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - int size; - void *desc; - 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); - USB_ATTACH_SETUP; - printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev), - devinfo, id->bInterfaceClass, id->bInterfaceSubClass); - - ed = usbd_interface2endpoint_descriptor(iface, 0); - if (!ed) { - printf("%s: could not read endpoint descriptor\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - DPRINTFN(10,("uhid_attach: bLength=%d bDescriptorType=%d " - "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d" - " bInterval=%d\n", - ed->bLength, ed->bDescriptorType, - ed->bEndpointAddress & UE_ADDR, - ed->bEndpointAddress & UE_IN ? "in" : "out", - ed->bmAttributes & UE_XFERTYPE, - UGETW(ed->wMaxPacketSize), ed->bInterval)); - - if ((ed->bEndpointAddress & UE_IN) != UE_IN || - (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) { - printf("%s: unexpected endpoint\n", USBDEVNAME(sc->sc_dev)); - 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); - if (r != USBD_NORMAL_COMPLETION) { - printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - (void)usbd_set_idle(iface, 0, 0); - - sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid); - sc->sc_osize = hid_report_size(desc, size, hid_output, &sc->sc_oid); - sc->sc_fsize = hid_report_size(desc, size, hid_feature, &sc->sc_fid); - - sc->sc_repdesc = desc; - sc->sc_repdesc_size = size; - - USB_ATTACH_SUCCESS_RETURN; -} - -#if defined(__FreeBSD__) -static int -uhid_detach(device_t self) -{ - char *devinfo = (char *) device_get_desc(self); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - return 0; -} -#endif - -void -uhid_disco(p) - void *p; -{ - struct uhid_softc *sc = p; - - DPRINTF(("ums_hid: sc=%p\n", sc)); - usbd_abort_pipe(sc->sc_intrpipe); - sc->sc_disconnected = 1; -} - -void -uhid_intr(reqh, addr, status) - usbd_request_handle reqh; - usbd_private_handle addr; - usbd_status status; -{ - struct uhid_softc *sc = addr; - - DPRINTFN(5, ("uhid_intr: status=%d\n", status)); - DPRINTFN(5, ("uhid_intr: data = %02x %02x %02x\n", - sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2])); - - if (status == USBD_CANCELLED) - return; - - if (status != USBD_NORMAL_COMPLETION) { - DPRINTF(("uhid_intr: status=%d\n", status)); - sc->sc_state |= UHID_NEEDCLEAR; - return; - } - - (void) b_to_q(sc->sc_ibuf, sc->sc_isize, &sc->sc_q); - - if (sc->sc_state & UHID_ASLP) { - sc->sc_state &= ~UHID_ASLP; - DPRINTFN(5, ("uhid_intr: waking %p\n", sc)); - wakeup((caddr_t)sc); - } - selwakeup(&sc->sc_rsel); -} - -int -uhidopen(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - usbd_status r; - USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc); - - if (!sc) - 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); - -#if defined(__NetBSD__) - if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) - 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); - - /* Set up interrupt pipe. */ - r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, - USBD_SHORT_XFER_OK, - &sc->sc_intrpipe, sc, sc->sc_ibuf, - sc->sc_isize, uhid_intr); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("uhidopen: usbd_open_pipe_intr failed, " - "error=%d\n",r)); - sc->sc_state &= ~UHID_OPEN; - return (EIO); - } - usbd_set_disco(sc->sc_intrpipe, uhid_disco, sc); - - return (0); -} - -int -uhidclose(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *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_state &= ~UHID_OPEN; - -#if defined(__NetBSD__) - 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); - - return (0); -} - -int -uhidread(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - int s; - int error = 0; - 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); - if (r != USBD_NORMAL_COMPLETION) - return (EIO); - return (uiomove(buffer, sc->sc_isize, uio)); - } - - s = splusb(); - while (sc->sc_q.c_cc == 0) { - if (flag & IO_NDELAY) { - splx(s); - return EWOULDBLOCK; - } - sc->sc_state |= UHID_ASLP; - DPRINTFN(5, ("uhidread: sleep on %p\n", sc)); - error = tsleep((caddr_t)sc, PZERO | PCATCH, "uhidrea", 0); - DPRINTFN(5, ("uhidread: woke, error=%d\n", error)); - if (error) { - sc->sc_state &= ~UHID_ASLP; - splx(s); - return (error); - } - if (sc->sc_state & UHID_NEEDCLEAR) { - DPRINTFN(-1,("uhidread: clearing stall\n")); - sc->sc_state &= ~UHID_NEEDCLEAR; - usbd_clear_endpoint_stall(sc->sc_intrpipe); - } - } - splx(s); - - /* Transfer as many chunks as possible. */ - while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) { - length = min(sc->sc_q.c_cc, uio->uio_resid); - if (length > sizeof(buffer)) - length = sizeof(buffer); - - /* Remove a small chunk from the input queue. */ - (void) q_to_b(&sc->sc_q, buffer, length); - DPRINTFN(5, ("uhidread: got %d chars\n", length)); - - /* Copy the data to the user process. */ - if ((error = uiomove(buffer, length, uio)) != 0) - break; - } - - return (error); -} - -int -uhidwrite(dev, uio, flag) - dev_t dev; - 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")); - - 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 (sc->sc_oid) - r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT, - sc->sc_obuf[0], - sc->sc_obuf+1, size-1); - else - r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT, - 0, sc->sc_obuf, size); - if (r != USBD_NORMAL_COMPLETION) { - error = EIO; - break; - } - } - return (error); -} - -int -uhidioctl(dev, cmd, addr, flag, p) - dev_t dev; - u_long cmd; - caddr_t addr; - int flag; - struct proc *p; -{ - struct usb_ctl_report_desc *rd; - 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)); - switch (cmd) { - case FIONBIO: - /* All handled in the upper FS layer. */ - break; - - case USB_GET_REPORT_DESC: - rd = (struct usb_ctl_report_desc *)addr; - size = min(sc->sc_repdesc_size, sizeof rd->data); - rd->size = size; - memcpy(rd->data, sc->sc_repdesc, size); - break; - - case USB_SET_IMMED: - if (*(int *)addr) { - /* XXX should read into ibuf, but does it matter */ - r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT, - sc->sc_iid, sc->sc_ibuf, - sc->sc_isize); - if (r != USBD_NORMAL_COMPLETION) - return (EOPNOTSUPP); - - sc->sc_state |= UHID_IMMED; - } else - sc->sc_state &= ~UHID_IMMED; - break; - - case USB_GET_REPORT: - re = (struct usb_ctl_report *)addr; - switch (re->report) { - case UHID_INPUT_REPORT: - size = sc->sc_isize; - id = sc->sc_iid; - break; - case UHID_OUTPUT_REPORT: - size = sc->sc_osize; - id = sc->sc_oid; - break; - case UHID_FEATURE_REPORT: - size = sc->sc_fsize; - id = sc->sc_fid; - break; - default: - return (EINVAL); - } - r = usbd_get_report(sc->sc_iface, re->report, id, - re->data, size); - if (r != USBD_NORMAL_COMPLETION) - return (EIO); - break; - - default: - return (EINVAL); - } - return (0); -} - -int -uhidpoll(dev, events, p) - dev_t dev; - int events; - struct proc *p; -{ - int revents = 0; - int s; - USB_GET_SC(uhid, UHIDUNIT(dev), sc); - - if (sc->sc_disconnected) - return (EIO); - - s = splusb(); - if (events & (POLLOUT | POLLWRNORM)) - revents |= events & (POLLOUT | POLLWRNORM); - if (events & (POLLIN | POLLRDNORM)) { - if (sc->sc_q.c_cc > 0) - revents |= events & (POLLIN | POLLRDNORM); - else - selrecord(p, &sc->sc_rsel); - } - - splx(s); - return (revents); -} - -#if defined(__FreeBSD__) -DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, usbd_driver_load, 0); -#endif diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c deleted file mode 100644 index 40ff36317addc..0000000000000 --- a/sys/dev/usb/uhub.c +++ /dev/null @@ -1,521 +0,0 @@ -/* $NetBSD: uhub.c,v 1.14 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#endif -#include <sys/proc.h> - -#include <dev/usb/usb.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -extern int usbdebug; -extern char *usbd_error_strs[]; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -struct uhub_softc { - bdevice 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 */ - u_char sc_running; -}; - -usbd_status uhub_init_port __P((struct usbd_port *)); -void uhub_disconnect __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__) -devclass_t uhubroot_devclass; - -static device_method_t uhubroot_methods[] = { - DEVMETHOD(device_probe, uhub_match), - DEVMETHOD(device_attach, uhub_attach), - /* detach is not allowed for a root hub */ - {0,0} -}; - -static driver_t uhubroot_driver = { - "uhub", - uhubroot_methods, - DRIVER_TYPE_MISC, - 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) -{ - USB_MATCH_START(uhub, uaa); - usb_device_descriptor_t *dd = usbd_get_device_descriptor(uaa->device); - - DPRINTFN(5,("uhub_match, dd=%p\n", dd)); - /* - * The subclass for hubs seems to be 0 for some and 1 for others, - * so we just ignore the subclass. - */ - if (uaa->iface == 0 && dd->bDeviceClass == UCLASS_HUB) - return (UMATCH_DEVCLASS_DEVSUBCLASS); - return (UMATCH_NONE); -} - -USB_ATTACH(uhub) -{ - USB_ATTACH_START(uhub, sc, uaa); - usbd_device_handle dev = uaa->device; - char devinfo[1024]; - usbd_status r; - struct usbd_hub *hub; - usb_device_request_t req; - usb_hub_descriptor_t hubdesc; - int p, port, nports, nremov; - usbd_interface_handle iface; - usb_endpoint_descriptor_t *ed; - - DPRINTFN(1,("uhub_attach\n")); - sc->sc_hub = dev; - usbd_devinfo(dev, 1, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo); - - r = usbd_set_config_index(dev, 0, 1); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("%s: configuration failed, error=%d(%s)\n", - USBDEVNAME(sc->sc_dev), r, usbd_error_strs[r])); - USB_ATTACH_ERROR_RETURN; - } - - if (dev->depth > USB_HUB_MAX_DEPTH) { - printf("%s: hub depth (%d) exceeded, hub ignored\n", - USBDEVNAME(sc->sc_dev), USB_HUB_MAX_DEPTH); - USB_ATTACH_ERROR_RETURN; - } - - /* Get hub descriptor. */ - req.bmRequestType = UT_READ_CLASS_DEVICE; - req.bRequest = UR_GET_DESCRIPTOR; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE); - DPRINTFN(1,("usb_init_hub: getting hub descriptor\n")); - r = usbd_do_request(dev, &req, &hubdesc); - nports = hubdesc.bNbrPorts; - if (r == USBD_NORMAL_COMPLETION && nports > 7) { - USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8); - r = usbd_do_request(dev, &req, &hubdesc); - } - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("%s: getting hub descriptor failed, error=%d(%s)\n", - USBDEVNAME(sc->sc_dev), r, usbd_error_strs[r])); - USB_ATTACH_ERROR_RETURN; - } - - for (nremov = 0, port = 1; port <= nports; port++) - if (!UHD_NOT_REMOV(&hubdesc, port)) - nremov++; - printf("%s: %d port%s with %d removable, %s powered\n", - USBDEVNAME(sc->sc_dev), nports, nports != 1 ? "s" : "", - nremov, dev->self_powered ? "self" : "bus"); - - - hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port), - M_USB, M_NOWAIT); - if (hub == 0) - USB_ATTACH_ERROR_RETURN; - dev->hub = hub; - dev->hub->hubsoftc = sc; - hub->explore = uhub_explore; - hub->hubdesc = hubdesc; - - DPRINTFN(1,("usbhub_init_hub: selfpowered=%d, parent=%p, " - "parent->selfpowered=%d\n", - 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; - } - - /* 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; - } - ed = usbd_interface2endpoint_descriptor(iface, 0); - if (ed == 0) { - printf("%s: no endpoint descriptor\n", USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - if ((ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) { - printf("%s: bad interrupt endpoint\n", USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - r = usbd_open_pipe_intr(iface, ed->bEndpointAddress,USBD_SHORT_XFER_OK, - &sc->sc_ipipe, sc, sc->sc_status, - sizeof(sc->sc_status), - uhub_intr); - if (r != USBD_NORMAL_COMPLETION) { - printf("%s: cannot open interrupt pipe\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - /* Wait with power off for a while. */ - usbd_delay_ms(dev, USB_POWER_DOWN_TIME); - - for (p = 0; p < nports; p++) { - struct usbd_port *up = &hub->ports[p]; - up->device = 0; - up->parent = dev; - up->portno = p+1; - r = uhub_init_port(up); - if (r != USBD_NORMAL_COMPLETION) - printf("%s: init of port %d failed\n", - USBDEVNAME(sc->sc_dev), up->portno); - } - 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); - int nports = sc->sc_hub->hub->hubdesc.bNbrPorts; - int p; - - for (p = 0; p < nports; p++) { - struct usbd_port *up = &sc->sc_hub->hub->ports[p]; - if (up->device) - uhub_disconnect(up); - } - - free(sc->sc_hub->hub, M_USB); - - return 0; -} -#endif - -usbd_status -uhub_init_port(up) - struct usbd_port *up; -{ - int port = up->portno; - usbd_device_handle dev = up->parent; - usbd_status r; - u_int16_t pstatus; - - r = usbd_get_port_status(dev, port, &up->status); - if (r != USBD_NORMAL_COMPLETION) - return (r); - pstatus = UGETW(up->status.wPortStatus); - DPRINTF(("usbd_init_port: adding hub port=%d status=0x%04x " - "change=0x%04x\n", - port, pstatus, UGETW(up->status.wPortChange))); - if ((pstatus & UPS_PORT_POWER) == 0) { - /* Port lacks power, turn it on */ - - /* First let the device go through a good power cycle, */ - usbd_delay_ms(dev, USB_PORT_POWER_DOWN_TIME); - - /* 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 " - "change=0x%04x\n", - port, UGETW(up->status.wPortStatus), - UGETW(up->status.wPortChange))); - /* Wait for stable power. */ - usbd_delay_ms(dev, dev->hub->hubdesc.bPwrOn2PwrGood * - UHD_PWRON_FACTOR); - } - if (dev->self_powered) - /* Self powered hub, give ports maximum current. */ - up->power = USB_MAX_POWER; - else - up->power = USB_MIN_POWER; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -uhub_explore(dev) - usbd_device_handle dev; -{ - usb_hub_descriptor_t *hd = &dev->hub->hubdesc; - struct uhub_softc *sc = dev->hub->hubsoftc; - struct usbd_port *up; - usbd_status r; - int port; - int change, status; - - DPRINTFN(10, ("uhub_explore dev=%p addr=%d\n", dev, dev->address)); - - if (!sc->sc_running) - return (USBD_NOT_STARTED); - - /* Ignore hubs that are too deep. */ - if (dev->depth > USB_HUB_MAX_DEPTH) - return (USBD_TOO_DEEP); - - for(port = 1; port <= hd->bNbrPorts; port++) { - up = &dev->hub->ports[port-1]; - r = usbd_get_port_status(dev, port, &up->status); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("uhub_explore: get port status failed, " - "error=%d(%s)\n", - r, usbd_error_strs[r])); - continue; - } - status = UGETW(up->status.wPortStatus); - change = UGETW(up->status.wPortChange); - DPRINTFN(5, ("uhub_explore: port %d status 0x%04x 0x%04x\n", - port, status, change)); - if (change & UPS_C_PORT_ENABLED) { - usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE); - if (status & UPS_PORT_ENABLED) { - 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 error, restarting " - "port %d\n", - USBDEVNAME(sc->sc_dev), port); - goto disco; - } else { - printf("%s: port error, giving up " - "port %d\n", - USBDEVNAME(sc->sc_dev), port); - } - } - } - if (!(change & UPS_C_CONNECT_STATUS)) { - /* No status change, just do recursive explore. */ - if (up->device && up->device->hub) - up->device->hub->explore(up->device); - continue; - } - DPRINTF(("uhub_explore: status change hub=%d port=%d\n", - dev->address, port)); - usbd_clear_port_feature(dev, port, UHF_C_PORT_CONNECTION); - usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE); - /* - * If there is already a device on the port the change status - * must mean that is has disconnected. Looking at the - * current connect status is not enough to figure this out - * since a new unit may have been connected before we handle - * the disconnect. - */ - disco: - if (up->device) { - /* Disconnected */ - DPRINTF(("uhub_explore: device %d disappeared " - "on port %d\n", - up->device->address, port)); - uhub_disconnect(up); - usbd_clear_port_feature(dev, port, - UHF_C_PORT_CONNECTION); - } - if (!(status & UPS_CURRENT_CONNECT_STATUS)) - continue; - - /* Connected */ - up->restartcnt = 0; - - /* Wait for maximum device power up time. */ - usbd_delay_ms(dev, USB_PORT_POWERUP_DELAY); - - /* Reset port, which implies enabling it. */ - if (usbd_reset_port(dev, port, &up->status) != - USBD_NORMAL_COMPLETION) - continue; - - /* Get device info and set its address. */ - r = usbd_new_device(&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, " - "error=%d(%s)\n", r, usbd_error_strs[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 - * at 0 we have to disable the port - * instead. */ - printf("%s: device problem, disabling " - "port %d\n", - USBDEVNAME(sc->sc_dev), port); - usbd_clear_port_feature(dev, port, - UHF_PORT_ENABLE); - /* Make sure we don't try to restart it. */ - up->restartcnt = USBD_RESTART_MAX; - } - } else { - if (up->device->hub) - up->device->hub->explore(up->device); - } - } - return (USBD_NORMAL_COMPLETION); -} - -void -uhub_disconnect(up) - struct usbd_port *up; -{ - usbd_device_handle dev = up->device; - usbd_pipe_handle p, n; - int i; - struct softc { bdevice sc_dev; }; /* all softc begin like this */ - - 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(((struct softc *)dev->softc)->sc_dev), - USBDEVNAME(((struct uhub_softc *)up->parent->softc)->sc_dev), - up->portno, dev->address); - - if (!dev->cdesc) { - /* Partially attached device, just drop it. */ - dev->bus->devices[dev->address] = 0; - up->device = 0; - return; - } - - 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); - usbd_abort_pipe(p); - usbd_close_pipe(p); - } - } - - /* 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(rup); - } - } - - dev->bus->devices[dev->address] = 0; - up->device = 0; - /* XXX free */ -#if defined(__FreeBSD__) - device_delete_child( - device_get_parent(((struct softc *)dev->softc)->sc_dev), - ((struct softc *)dev->softc)->sc_dev); -#endif -} - -void -uhub_intr(reqh, addr, status) - usbd_request_handle reqh; - usbd_private_handle addr; - usbd_status status; -{ - struct uhub_softc *sc = addr; - - 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); -} - -#if defined(__FreeBSD__) -DRIVER_MODULE(uhub, usb, uhubroot_driver, uhubroot_devclass, 0, 0); -DRIVER_MODULE(uhub, uhub, uhub_driver, uhub_devclass, usbd_driver_load, 0); -#endif diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c deleted file mode 100644 index 0d54e01f3ac1f..0000000000000 --- a/sys/dev/usb/ukbd.c +++ /dev/null @@ -1,680 +0,0 @@ -/* $NetBSD: ukbd.c,v 1.22 1999/01/09 12:10:36 drochner Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Information about USB keyboard can be found in the USB HID spec. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#include <sys/ioctl.h> -#elif defined(__FreeBSD__) -#include <sys/ioccom.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <machine/clock.h> -#endif -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/select.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/poll.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbhid.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdevs.h> -#include <dev/usb/usb_quirks.h> -#include <dev/usb/hid.h> - -#if defined(__NetBSD__) -#include <dev/wscons/wsconsio.h> -#include <dev/wscons/wskbdvar.h> -#include <dev/wscons/wsksymdef.h> -#include <dev/wscons/wsksymvar.h> -#include <dev/wscons/wskbdmap_mfii.h> - -#include "opt_pckbd_layout.h" -#include "opt_wsdisplay_compat.h" - -#elif defined(__FreeBSD__) -#include <machine/clock.h> -#define delay(d) DELAY(d) -#endif - -#ifdef USB_DEBUG -#define DPRINTF(x) if (ukbddebug) printf x -#define DPRINTFN(n,x) if (ukbddebug>(n)) printf x -int ukbddebug = 1; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -#define UPROTO_BOOT_KEYBOARD 1 - -#define NKEYCODE 6 - -#define NUM_LOCK 0x01 -#define CAPS_LOCK 0x02 -#define SCROLL_LOCK 0x04 - -struct ukbd_data { - u_int8_t modifiers; -#define MOD_CONTROL_L 0x01 -#define MOD_CONTROL_R 0x10 -#define MOD_SHIFT_L 0x02 -#define MOD_SHIFT_R 0x20 -#define MOD_ALT_L 0x04 -#define MOD_ALT_R 0x40 -#define MOD_WIN_L 0x08 -#define MOD_WIN_R 0x80 - u_int8_t reserved; - u_int8_t keycode[NKEYCODE]; -}; - -#define PRESS 0 -#define RELEASE 0x100 - -#define NMOD 6 -static struct { - int mask, key; -} ukbd_mods[NMOD] = { - { MOD_CONTROL_L, 29 }, - { MOD_CONTROL_R, 58 }, - { MOD_SHIFT_L, 42 }, - { MOD_SHIFT_R, 54 }, - { MOD_ALT_L, 56 }, - { MOD_ALT_R, 184 }, -}; - -#define NN 0 /* no translation */ -/* - * Translate USB keycodes to US keyboard AT scancodes. - * Scancodes >= 128 represent EXTENDED keycodes. - */ -static u_int8_t ukbd_trtab[256] = { - 0, 0, 0, 0, 30, 48, 46, 32, /* 00 - 07 */ - 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */ - 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */ - 22, 47, 17, 45, 21, 44, 2, 3, /* 18 - 1F */ - 4, 5, 6, 7, 8, 9, 10, 11, /* 20 - 27 */ - 28, 1, 14, 15, 57, 12, 13, 26, /* 28 - 2F */ - 27, 43, NN, 39, 40, 41, 51, 52, /* 30 - 37 */ - 53, 58, 59, 60, 61, 62, 63, 64, /* 38 - 3F */ - 65, 66, 67, 68, 87, 88, 170, 70, /* 40 - 47 */ - 127, 210, 199, 201, 211, 207, 209, 205, /* 48 - 4F */ - 203, 208, 200, 69, 181, 55, 74, 78, /* 50 - 57 */ - 156, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */ - 72, 73, 82, 83, NN, NN, NN, NN, /* 60 - 67 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */ - NN, NN, NN, NN, NN, NN, 221, NN, /* 70 - 77 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 78 - 7F */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 80 - 87 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 88 - 8F */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */ - NN, NN, NN, NN, NN, NN, NN, NN, /* A0 - A7 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* A8 - AF */ - NN, NN, NN, NN, NN, NN, NN, NN, /* B0 - B7 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* B8 - BF */ - NN, NN, NN, NN, NN, NN, NN, NN, /* C0 - C7 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* C8 - CF */ - NN, NN, NN, NN, NN, NN, NN, NN, /* D0 - D7 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* D8 - DF */ - NN, NN, NN, NN, NN, NN, NN, NN, /* E0 - E7 */ - NN, NN, NN, 219, NN, NN, NN, 220, /* E8 - EF */ - NN, NN, NN, NN, NN, NN, NN, NN, /* F0 - F7 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* F8 - FF */ -}; - -#define KEY_ERROR 0x01 - -#define MAXKEYS (NMOD+2*NKEYCODE) - -struct ukbd_softc { - bdevice sc_dev; /* base device */ - usbd_interface_handle sc_iface; /* interface */ - usbd_pipe_handle sc_intrpipe; /* interrupt pipe */ - int sc_ep_addr; - - struct ukbd_data sc_ndata; - struct ukbd_data sc_odata; - - char sc_enabled; - char sc_disconnected; /* device is gone */ - - int sc_leds; -#if defined(__NetBSD__) - struct device *sc_wskbddev; -#ifdef WSDISPLAY_COMPAT_RAWKBD -#define REP_DELAY1 400 -#define REP_DELAYN 100 - int sc_rawkbd; - int sc_nrep; - char sc_rep[MAXKEYS]; -#endif - - int sc_polling; - int sc_pollchar; -#endif -}; - -#define UKBDUNIT(dev) (minor(dev)) -#define UKBD_CHUNK 128 /* chunk size for read */ -#define UKBD_BSIZE 1020 /* buffer size */ - -void ukbd_cngetc __P((void *, u_int *, int *)); -void ukbd_cnpollc __P((void *, int)); - -#if defined(__NetBSD__) -const struct wskbd_consops ukbd_consops = { - ukbd_cngetc, - ukbd_cnpollc, -}; -#endif - -void ukbd_intr __P((usbd_request_handle, usbd_private_handle, usbd_status)); -void ukbd_disco __P((void *)); - -int ukbd_enable __P((void *, int)); -void ukbd_set_leds __P((void *, int)); -#if defined(__NetBSD__) -int ukbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); -int ukbd_cnattach __P((void *v)); -void ukbd_rawrepeat __P((void *v)); - -const struct wskbd_accessops ukbd_accessops = { - ukbd_enable, - ukbd_set_leds, - ukbd_ioctl, -#if 0 - ukbd_cnattach, -#endif -}; - -const struct wskbd_mapdata ukbd_keymapdata = { - pckbd_keydesctab, -#ifdef PCKBD_LAYOUT - PCKBD_LAYOUT, -#else - KB_US, -#endif -}; -#endif - -USB_DECLARE_DRIVER(ukbd); - -USB_MATCH(ukbd) -{ - USB_MATCH_START(ukbd, uaa); - usb_interface_descriptor_t *id; - - /* Check that this is a keyboard that speaks the boot protocol. */ - if (!uaa->iface) - return (UMATCH_NONE); - id = usbd_get_interface_descriptor(uaa->iface); - if (!id || - id->bInterfaceClass != UCLASS_HID || - id->bInterfaceSubClass != USUBCLASS_BOOT || - id->bInterfaceProtocol != UPROTO_BOOT_KEYBOARD) - return (UMATCH_NONE); - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); -} - -USB_ATTACH(ukbd) -{ - USB_ATTACH_START(ukbd, sc, uaa); - usbd_interface_handle iface = uaa->iface; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; - usbd_status r; - char devinfo[1024]; -#if defined(__NetBSD__) - struct wskbddev_attach_args a; -#endif - - sc->sc_disconnected = 1; - sc->sc_iface = iface; - id = usbd_get_interface_descriptor(iface); - usbd_devinfo(uaa->device, 0, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev), - devinfo, id->bInterfaceClass, id->bInterfaceSubClass); - - ed = usbd_interface2endpoint_descriptor(iface, 0); - if (!ed) { - printf("%s: could not read endpoint descriptor\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - DPRINTFN(10,("ukbd_attach: bLength=%d bDescriptorType=%d " - "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d" - " bInterval=%d\n", - ed->bLength, ed->bDescriptorType, - ed->bEndpointAddress & UE_ADDR, - ed->bEndpointAddress & UE_IN ? "in" : "out", - ed->bmAttributes & UE_XFERTYPE, - UGETW(ed->wMaxPacketSize), ed->bInterval)); - - if ((ed->bEndpointAddress & UE_IN) != UE_IN || - (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) { - printf("%s: unexpected endpoint\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - if ((usbd_get_quirks(uaa->device)->uq_flags & UQ_NO_SET_PROTO) == 0) { - r = usbd_set_protocol(iface, 0); - DPRINTFN(5, ("ukbd_attach: protocol set\n")); - if (r != USBD_NORMAL_COMPLETION) { - printf("%s: set protocol failed\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - } - - /* Ignore if SETIDLE fails since it is not crucial. */ - usbd_set_idle(iface, 0, 0); - - sc->sc_ep_addr = ed->bEndpointAddress; - sc->sc_disconnected = 0; - -#if defined(__NetBSD__) - a.console = 0; - - a.keymap = &ukbd_keymapdata; - - a.accessops = &ukbd_accessops; - a.accesscookie = sc; - - /* Flash the leds; no real purpose, just shows we're alive. */ - ukbd_set_leds(sc, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS); - usbd_delay_ms(uaa->device, 300); - ukbd_set_leds(sc, 0); - - sc->sc_wskbddev = config_found(self, &a, wskbddevprint); - -#elif defined(__FreeBSD__) - /* XXX why waste CPU in delay() ? */ - /* It's alive! IT'S ALIVE! Do a little song and dance. */ - ukbd_set_leds(sc, NUM_LOCK); - delay(15000); - ukbd_set_leds(sc, CAPS_LOCK); - delay(20000); - ukbd_set_leds(sc, SCROLL_LOCK); - delay(30000); - ukbd_set_leds(sc, CAPS_LOCK); - delay(50000); - ukbd_set_leds(sc, NUM_LOCK); - - ukbd_enable(sc, 1); -#endif - - USB_ATTACH_SUCCESS_RETURN; -} - -#if defined(__FreeBSD__) -int -ukbd_detach(device_t self) -{ - struct ukbd_softc *sc = device_get_softc(self); - char *devinfo = (char *) device_get_desc(self); - - if (sc->sc_enabled) - return (ENXIO); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - - return (0); -} -#endif - -void -ukbd_disco(p) - void *p; -{ - struct ukbd_softc *sc = p; - - DPRINTF(("ukbd_disco: sc=%p\n", sc)); - usbd_abort_pipe(sc->sc_intrpipe); - sc->sc_disconnected = 1; -} - -int -ukbd_enable(v, on) - void *v; - int on; -{ - struct ukbd_softc *sc = v; - usbd_status r; - - if (on) { - /* Set up interrupt pipe. */ - if (sc->sc_enabled) - return (EBUSY); - - sc->sc_enabled = 1; - r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, - USBD_SHORT_XFER_OK, - &sc->sc_intrpipe, sc, &sc->sc_ndata, - sizeof(sc->sc_ndata), ukbd_intr); - if (r != USBD_NORMAL_COMPLETION) - return (EIO); - usbd_set_disco(sc->sc_intrpipe, ukbd_disco, sc); - } else { - /* Disable interrupts. */ - usbd_abort_pipe(sc->sc_intrpipe); - usbd_close_pipe(sc->sc_intrpipe); - - sc->sc_enabled = 0; - } - - return (0); -} - -void -ukbd_intr(reqh, addr, status) - usbd_request_handle reqh; - usbd_private_handle addr; - usbd_status status; -{ - struct ukbd_softc *sc = addr; - struct ukbd_data *ud = &sc->sc_ndata; - int mod, omod; - int ibuf[MAXKEYS]; /* chars events */ - int nkeys, i, j; - int key, c; -#define ADDKEY(c) ibuf[nkeys++] = (c) - - DPRINTFN(5, ("ukbd_intr: status=%d\n", status)); - if (status == USBD_CANCELLED) - return; - - if (status != USBD_NORMAL_COMPLETION) { - DPRINTF(("ukbd_intr: status=%d\n", status)); - usbd_clear_endpoint_stall_async(sc->sc_intrpipe); - return; - } - - DPRINTFN(5, (" mod=0x%02x key0=0x%02x key1=0x%02x\n", - ud->modifiers, ud->keycode[0], ud->keycode[1])); - - if (ud->keycode[0] == KEY_ERROR) - return; /* ignore */ - nkeys = 0; - mod = ud->modifiers; - omod = sc->sc_odata.modifiers; - if (mod != omod) - for (i = 0; i < NMOD; i++) - if (( mod & ukbd_mods[i].mask) != - (omod & ukbd_mods[i].mask)) - ADDKEY(ukbd_mods[i].key | - (mod & ukbd_mods[i].mask - ? PRESS : RELEASE)); - if (memcmp(ud->keycode, sc->sc_odata.keycode, NKEYCODE) != 0) { - /* Check for released keys. */ - for (i = 0; i < NKEYCODE; i++) { - key = sc->sc_odata.keycode[i]; - if (key == 0) - continue; - for (j = 0; j < NKEYCODE; j++) - if (key == ud->keycode[j]) - goto rfound; - c = ukbd_trtab[key]; - if (c) - ADDKEY(c | RELEASE); - rfound: - ; - } - - /* Check for pressed keys. */ - for (i = 0; i < NKEYCODE; i++) { - key = ud->keycode[i]; - if (key == 0) - continue; - for (j = 0; j < NKEYCODE; j++) - if (key == sc->sc_odata.keycode[j]) - goto pfound; - c = ukbd_trtab[key]; - DPRINTFN(2,("ukbd_intr: press key=0x%02x -> 0x%02x\n", - key, c)); - if (c) - ADDKEY(c | PRESS); - pfound: - ; - } - } - sc->sc_odata = *ud; - - if (nkeys == 0) - return; - -#if defined(__NetBSD__) - if (sc->sc_polling) { - DPRINTFN(1,("ukbd_intr: pollchar = 0x%02x\n", ibuf[0])); - if (nkeys > 0) - sc->sc_pollchar = ibuf[0]; /* XXX lost keys? */ - return; - } -#ifdef WSDISPLAY_COMPAT_RAWKBD - if (sc->sc_rawkbd) { - char cbuf[MAXKEYS * 2]; - int npress; - - for (npress = i = j = 0; i < nkeys; i++, j++) { - c = ibuf[i]; - if (c & 0x80) - cbuf[j++] = 0xe0; - cbuf[j] = c & 0x7f; - if (c & RELEASE) - cbuf[j] |= 0x80; - else { - /* remember keys for autorepeat */ - if (c & 0x80) - sc->sc_rep[npress++] = 0xe0; - sc->sc_rep[npress++] = c & 0x7f; - } - } - wskbd_rawinput(sc->sc_wskbddev, cbuf, j); - untimeout(ukbd_rawrepeat, sc); - if (npress != 0) { - sc->sc_nrep = npress; - timeout(ukbd_rawrepeat, sc, hz * REP_DELAY1 / 1000); - } - return; - } -#endif - - for (i = 0; i < nkeys; i++) { - c = ibuf[i]; - wskbd_input(sc->sc_wskbddev, - c & RELEASE ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN, - c & 0xff); - } -#elif defined(__FreeBSD__) - /* XXX shouldn't the keys be used? */ - for (i = 0; i < nkeys; i++) { - c = ibuf[i]; - printf("%c (%d) %s ", - ((c&0xff) < 32 || (c&0xff) > 126? '.':(c&0xff)), c, - (c&RELEASE? "released":"pressed")); - if (ud->modifiers) - printf("mod = 0x%04x ", ud->modifiers); - for (i = 0; i < NKEYCODE; i++) - if (ud->keycode[i]) - printf("%d ", ud->keycode[i]); - printf("\n"); - } -#endif -} - -void -ukbd_set_leds(v, leds) - void *v; - int leds; -{ - struct ukbd_softc *sc = v; - u_int8_t res; - - DPRINTF(("ukbd_set_leds: sc=%p leds=%d\n", sc, leds)); - - sc->sc_leds = leds; -#if defined(__NetBSD__) - res = 0; - if (leds & WSKBD_LED_SCROLL) - res |= SCROLL_LOCK; - if (leds & WSKBD_LED_NUM) - res |= NUM_LOCK; - if (leds & WSKBD_LED_CAPS) - res |= CAPS_LOCK; -#elif defined(__FreeBSD__) - res = leds; -#endif - usbd_set_report_async(sc->sc_iface, UHID_OUTPUT_REPORT, 0, &res, 1); -} - -#if defined(__NetBSD__) - -#ifdef WSDISPLAY_COMPAT_RAWKBD -void -ukbd_rawrepeat(v) - void *v; -{ - struct ukbd_softc *sc = v; - - wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep); - timeout(ukbd_rawrepeat, sc, hz * REP_DELAYN / 1000); -} -#endif - -int -ukbd_ioctl(v, cmd, data, flag, p) - void *v; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - struct ukbd_softc *sc = v; - - switch (cmd) { - case WSKBDIO_GTYPE: - *(int *)data = WSKBD_TYPE_USB; - return (0); - case WSKBDIO_SETLEDS: - ukbd_set_leds(v, *(int *)data); - return (0); - case WSKBDIO_GETLEDS: - *(int *)data = sc->sc_leds; - return (0); -#ifdef WSDISPLAY_COMPAT_RAWKBD - case WSKBDIO_SETMODE: - DPRINTF(("ukbd_ioctl: set raw = %d\n", *(int *)data)); - sc->sc_rawkbd = *(int *)data == WSKBD_RAW; - untimeout(ukbd_rawrepeat, sc); - return (0); -#endif - } - return (-1); -} - -/* Console interface. */ -void -ukbd_cngetc(v, type, data) - void *v; - u_int *type; - int *data; -{ - struct ukbd_softc *sc = v; - usbd_lock_token s; - int c; - - DPRINTFN(1,("ukbd_cngetc: enter\n")); - s = usbd_lock(); - sc->sc_polling = 1; - sc->sc_pollchar = -1; - while(sc->sc_pollchar == -1) - usbd_dopoll(sc->sc_iface); - sc->sc_polling = 0; - c = sc->sc_pollchar; - *type = c & RELEASE ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; - *data = c & 0xff; - usbd_unlock(s); - DPRINTFN(1,("ukbd_cngetc: return 0x%02x\n", c)); -} - -void -ukbd_cnpollc(v, on) - void *v; - int on; -{ - struct ukbd_softc *sc = v; - - DPRINTFN(2,("ukbd_cnpollc: sc=%p on=%d\n", v, on)); - - usbd_set_polling(sc->sc_iface, on); -} - -int -ukbd_cnattach(v) - void *v; -{ - struct ukbd_softc *sc = v; - - DPRINTF(("ukbd_cnattach: sc=%p\n", sc)); - wskbd_cnattach(&ukbd_consops, sc, &ukbd_keymapdata); - return (0); -} - -#endif /* NetBSD */ - -#if defined(__FreeBSD__) -DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, usbd_driver_load, 0); -#endif diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c deleted file mode 100644 index 074fe04893335..0000000000000 --- a/sys/dev/usb/ulpt.c +++ /dev/null @@ -1,451 +0,0 @@ -/* $NetBSD: ulpt.c,v 1.10 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#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> -#include <sys/ioctl.h> -#elif defined(__FreeBSD__) -#include <sys/ioccom.h> -#include <sys/module.h> -#include <sys/bus.h> -#endif -#include <sys/uio.h> -#include <sys/conf.h> -#include <sys/syslog.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdevs.h> -#include <dev/usb/usb_quirks.h> - -#define TIMEOUT hz*16 /* wait up to 16 seconds for a ready */ -#define STEP hz/4 - -#define LPTPRI (PZERO+8) -#define ULPT_BSIZE 1024 - -#ifdef USB_DEBUG -#define DPRINTF(x) if (ulptdebug) printf x -#define DPRINTFN(n,x) if (ulptdebug>(n)) printf x -int ulptdebug = 1; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -#define UR_GET_DEVICE_ID 0 -#define UR_GET_PORT_STATUS 1 -#define UR_SOFT_RESET 2 - -#define LPS_NERR 0x08 /* printer no error */ -#define LPS_SELECT 0x10 /* printer selected */ -#define LPS_NOPAPER 0x20 /* printer out of paper */ -#define LPS_INVERT (LPS_SELECT|LPS_NERR) -#define LPS_MASK (LPS_SELECT|LPS_NERR|LPS_NOPAPER) - -struct ulpt_softc { - bdevice sc_dev; - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ - int sc_ifaceno; - usbd_pipe_handle sc_bulkpipe; /* bulk pipe */ - int sc_bulk; - - u_char sc_state; -#define ULPT_OPEN 0x01 /* device is open */ -#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; -}; - -#if defined(__NetBSD__) -int ulptopen __P((dev_t, int, int, struct proc *)); -int ulptclose __P((dev_t, int, int, struct proc *p)); -int ulptwrite __P((dev_t, struct uio *uio, int)); -int ulptioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); -#elif defined(__FreeBSD__) -static d_open_t ulptopen; -static d_close_t ulptclose; -static d_write_t ulptwrite; -static d_ioctl_t ulptioctl; - -#define ULPT_CDEV_MAJOR 113 - -static struct cdevsw ulpt_cdevsw = { - ulptopen, ulptclose, noread, ulptwrite, - ulptioctl, nostop, nullreset, nodevtotty, - seltrue, nommap, nostrat, - "ulpt", NULL, -1 -}; -#endif - -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__) -#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); - -USB_MATCH(ulpt) -{ - USB_MATCH_START(ulpt, uaa); - usb_interface_descriptor_t *id; - - DPRINTFN(10,("ulpt_match\n")); - if (!uaa->iface) - return (UMATCH_NONE); - id = usbd_get_interface_descriptor(uaa->iface); - if (id && - id->bInterfaceClass == UCLASS_PRINTER && - id->bInterfaceSubClass == USUBCLASS_PRINTER && - (id->bInterfaceProtocol == UPROTO_PRINTER_UNI || - id->bInterfaceProtocol == UPROTO_PRINTER_BI)) - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); - return (UMATCH_NONE); -} - -USB_ATTACH(ulpt) -{ - USB_ATTACH_START(ulpt, sc, uaa); - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface = uaa->iface; - usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface); -#if 0 - usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); - usb_device_request_t req; -#endif - char devinfo[1024]; - usb_endpoint_descriptor_t *ed; - usbd_status r; - - DPRINTFN(10,("ulpt_attach: sc=%p\n", sc)); - usbd_devinfo(dev, 0, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev), - devinfo, id->bInterfaceClass, id->bInterfaceSubClass); - - /* Figure out which endpoint is the bulk out endpoint. */ - ed = usbd_interface2endpoint_descriptor(iface, 0); - if (!ed) - goto nobulk; - if ((ed->bEndpointAddress & UE_IN) != UE_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 || - (ed->bmAttributes & UE_XFERTYPE) != UE_BULK) - goto nobulk; - } - sc->sc_bulk = ed->bEndpointAddress; - DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_bulk)); - - sc->sc_iface = iface; - r = usbd_interface2device_handle(iface, &sc->sc_udev); - if (r != USBD_NORMAL_COMPLETION) - USB_ATTACH_ERROR_RETURN; - sc->sc_ifaceno = id->bInterfaceNumber; - -#if 0 -XXX needs a different way to read the id string since the length -is unknown. usbd_do_request() returns error on a short transfer. - 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(dev, &req, devinfo); - 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 { - printf("%s: cannot get device id\n", USBDEVNAME(sc->sc_dev)); - } -#endif - - USB_ATTACH_SUCCESS_RETURN; - - nobulk: - printf("%s: could not find bulk endpoint\n", USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; -} - -int -ulpt_status(sc) - struct ulpt_softc *sc; -{ - usb_device_request_t req; - usbd_status r; - u_char status; - - req.bmRequestType = UT_READ_CLASS_INTERFACE; - req.bRequest = UR_GET_PORT_STATUS; - USETW(req.wValue, 0); - USETW(req.wIndex, sc->sc_ifaceno); - USETW(req.wLength, 1); - r = usbd_do_request(sc->sc_udev, &req, &status); - DPRINTFN(1, ("ulpt_status: status=0x%02x r=%d\n", status, r)); - if (r == USBD_NORMAL_COMPLETION) - return (status); - else - return (0); -} - -void -ulpt_reset(sc) - struct ulpt_softc *sc; -{ - usb_device_request_t req; - - DPRINTFN(1, ("ulpt_reset\n")); - req.bmRequestType = UT_WRITE_CLASS_OTHER; - req.bRequest = UR_SOFT_RESET; - USETW(req.wValue, 0); - USETW(req.wIndex, sc->sc_ifaceno); - USETW(req.wLength, 0); - (void)usbd_do_request(sc->sc_udev, &req, 0); -} - -/* - * Reset the printer, then wait until it's selected and not busy. - */ -int -ulptopen(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - u_char flags = ULPTFLAGS(dev); - usbd_status r; - int spin, error; - USB_GET_SC_OPEN(ulpt, ULPTUNIT(dev), sc); - - if (!sc || !sc->sc_iface) - return ENXIO; - - if (sc->sc_state) - return EBUSY; - - sc->sc_state = ULPT_INIT; - sc->sc_flags = flags; - DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags)); - -#if USB_DEBUG && defined(__FreeBSD__) - /* Ignoring these flags might not be a good idea */ - if ((flags ^ ULPT_NOPRIME) != 0) - DPRINTF(("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; - } - - /* 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; - } - } - - r = usbd_open_pipe(sc->sc_iface, sc->sc_bulk, 0, &sc->sc_bulkpipe); - if (r != USBD_NORMAL_COMPLETION) { - sc->sc_state = 0; - return (EIO); - } - - sc->sc_state = ULPT_OPEN; - - DPRINTF(("ulptopen: done\n")); - return (0); -} - -int -ulpt_statusmsg(status, sc) - u_char status; - struct ulpt_softc *sc; -{ - u_char new; - - status = (status ^ LPS_INVERT) & LPS_MASK; - new = status & ~sc->sc_laststatus; - sc->sc_laststatus = status; - - if (new & LPS_SELECT) - log(LOG_NOTICE, "%s: offline\n", USBDEVNAME(sc->sc_dev)); - else if (new & LPS_NOPAPER) - log(LOG_NOTICE, "%s: out of paper\n", USBDEVNAME(sc->sc_dev)); - else if (new & LPS_NERR) - log(LOG_NOTICE, "%s: output error\n", USBDEVNAME(sc->sc_dev)); - - return status; -} - -int -ulptclose(dev, flag, mode, p) - dev_t dev; - int flag; - int mode; - struct proc *p; -{ - USB_GET_SC(ulpt, ULPTUNIT(dev), sc); - - usbd_close_pipe(sc->sc_bulkpipe); - - sc->sc_state = 0; - - DPRINTF(("ulptclose: closed\n")); - return (0); -} - -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); - - DPRINTF(("ulptwrite\n")); - 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) { - DPRINTF(("ulptwrite: error=%d\n", r)); - usbd_clear_endpoint_stall(sc->sc_bulkpipe); - error = EIO; - break; - } - } - usbd_free_request(reqh); - return (error); -} - -int -ulptioctl(dev, cmd, data, flag, p) - dev_t dev; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - int error = 0; - - switch (cmd) { - default: - error = ENODEV; - } - - return error; -} - -#if defined(__FreeBSD__) -static int -ulpt_detach(device_t self) -{ - char *devinfo = (char *) device_get_desc(self); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - return 0; -} - -CDEV_DRIVER_MODULE(ulpt, uhub, ulpt_driver, ulpt_devclass, - ULPT_CDEV_MAJOR, ulpt_cdevsw, usbd_driver_load, 0); -#endif diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c deleted file mode 100644 index 16bfae25ae168..0000000000000 --- a/sys/dev/usb/umodem.c +++ /dev/null @@ -1,142 +0,0 @@ -/* $NetBSD: umodem.c,v 1.5 1999/01/08 11:58:25 augustss Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/ioctl.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/ioccom.h> -#include <sys/conf.h> -#endif -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/select.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/device.h> -#include <sys/poll.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbcdc.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdevs.h> -#include <dev/usb/usb_quirks.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) if (umodemdebug) printf x -#define DPRINTFN(n,x) if (umodemdebug>(n)) printf x -int umodemdebug = 1; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -struct umodem_softc { - bdevice sc_dev; /* base device */ - usbd_interface_handle sc_ctl; /* control interface */ - usbd_interface_handle sc_data; /* data interface */ - uByte cmCaps; - uByte acmCaps; -}; - -void umodem_intr __P((usbd_request_handle, usbd_private_handle, usbd_status)); -void umodem_disco __P((void *)); - -USB_DECLARE_DRIVER(umodem); - -USB_MATCH(umodem) -{ - USB_MATCH_START(umodem, uaa); - - usb_interface_descriptor_t *id; - - if (!uaa->iface) - return (UMATCH_NONE); - id = usbd_get_interface_descriptor(uaa->iface); - if (!id || - id->bInterfaceClass != UCLASS_CDC || - id->bInterfaceSubClass != USUBCLASS_ABSTRACT_CONTROL_MODEL || - id->bInterfaceProtocol != UPROTO_CDC_AT) - return (UMATCH_NONE); - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); -} - -USB_ATTACH(umodem) -{ - USB_ATTACH_START(umodem, sc, uaa); - usbd_interface_handle iface = uaa->iface; - usb_interface_descriptor_t *id; - char devinfo[1024]; - - sc->sc_ctl = iface; - id = usbd_get_interface_descriptor(iface); - usbd_devinfo(uaa->device, 0, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev), - devinfo, id->bInterfaceClass, id->bInterfaceSubClass); - - USB_ATTACH_SUCCESS_RETURN; -} - -#if defined(__FreeBSD__) -static int -umodem_detach(device_t self) -{ - char *devinfo = (char *) device_get_desc(self); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - - return 0; -} -#endif - -#if defined(__FreeBSD__) -DRIVER_MODULE(umodem, uhub, umodem_driver, umodem_devclass, usbd_driver_load,0); -#endif - diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c deleted file mode 100644 index e92d027ec0db3..0000000000000 --- a/sys/dev/usb/ums.c +++ /dev/null @@ -1,720 +0,0 @@ -/* $NetBSD: ums.c,v 1.19 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#include <sys/ioctl.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/ioccom.h> -#include <sys/conf.h> -#endif -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/select.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/poll.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbhid.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdevs.h> -#include <dev/usb/usb_quirks.h> -#include <dev/usb/hid.h> - -#if defined(__NetBSD__) -#include <dev/wscons/wsconsio.h> -#include <dev/wscons/wsmousevar.h> -#elif defined(__FreeBSD__) -#include <machine/mouse.h> -#endif - -#ifdef USB_DEBUG -#define DPRINTF(x) if (umsdebug) printf x -#define DPRINTFN(n,x) if (umsdebug>(n)) printf x -int umsdebug = 6; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -#define UMSUNIT(s) (minor(s)&0x1f) - -#define PS2LBUTMASK x01 -#define PS2RBUTMASK x02 -#define PS2MBUTMASK x04 -#define PS2BUTMASK 0x0f - -#define QUEUE_BUFSIZE 240 /* MUST be divisible by 3 _and_ 4 */ - -struct ums_softc { - bdevice sc_dev; /* base device */ - usbd_interface_handle sc_iface; /* interface */ - usbd_pipe_handle sc_intrpipe; /* interrupt pipe */ - int sc_ep_addr; - - u_char *sc_ibuf; - u_int8_t sc_iid; - int sc_isize; - struct hid_location sc_loc_x, sc_loc_y, sc_loc_z; - struct hid_location *sc_loc_btn; - - int sc_enabled; - int sc_disconnected; /* device is gone */ - - int flags; /* device configuration */ -#define UMS_Z 0x01 /* z direction available */ - int nbuttons; -#define MAX_BUTTONS 7 /* chosen because sc_buttons is u_char */ - -#if defined(__NetBSD__) - u_char sc_buttons; /* mouse button status */ - struct device *sc_wsmousedev; -#elif defined(__FreeBSD__) - u_char qbuf[QUEUE_BUFSIZE]; /* must be divisable by 3&4 */ - u_char dummy[100]; /* XXX just for safety and for now */ - int qcount, qhead, qtail; - mousehw_t hw; - mousemode_t mode; - mousestatus_t status; - - int state; -# define UMS_ASLEEP 0x01 /* readFromDevice is waiting */ -# define UMS_SELECT 0x02 /* select is waiting */ - struct selinfo rsel; /* process waiting in select */ -#endif -}; - -#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE) -#define MOUSE_FLAGS (HIO_RELATIVE) - -void ums_intr __P((usbd_request_handle, usbd_private_handle, usbd_status)); -void ums_disco __P((void *)); - -static int ums_enable __P((void *)); -static void ums_disable __P((void *)); - -#if defined(__NetBSD__) -static int ums_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); - -const struct wsmouse_accessops ums_accessops = { - ums_enable, - ums_ioctl, - ums_disable, -}; - -#elif defined(__FreeBSD__) -static d_open_t ums_open; -static d_close_t ums_close; -static d_read_t ums_read; -static d_ioctl_t ums_ioctl; -static d_poll_t ums_poll; - -#define UMS_CDEV_MAJOR 111 - -static struct cdevsw ums_cdevsw = { - ums_open, ums_close, ums_read, nowrite, - ums_ioctl, nostop, nullreset, nodevtotty, - ums_poll, nommap, nostrat, - "ums", NULL, -1 -}; -#endif - -USB_DECLARE_DRIVER(ums); - -USB_MATCH(ums) -{ - USB_MATCH_START(ums, uaa); - usb_interface_descriptor_t *id; - int size, ret; - void *desc; - usbd_status r; - - if (!uaa->iface) - return (UMATCH_NONE); - id = usbd_get_interface_descriptor(uaa->iface); - if (!id || id->bInterfaceClass != UCLASS_HID) - return (UMATCH_NONE); - - r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP); - if (r != USBD_NORMAL_COMPLETION) - return (UMATCH_NONE); - - if (hid_is_collection(desc, size, - HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE))) - ret = UMATCH_IFACECLASS; - else - ret = UMATCH_NONE; - - free(desc, M_TEMP); - return (ret); -} - -USB_ATTACH(ums) -{ - USB_ATTACH_START(ums, sc, uaa); - usbd_interface_handle iface = uaa->iface; - usb_interface_descriptor_t *id; - usb_endpoint_descriptor_t *ed; -#if defined(__NetBSD__) - struct wsmousedev_attach_args a; -#endif - int size; - void *desc; - usbd_status r; - char devinfo[1024]; - u_int32_t flags; - int i; - struct hid_location loc_btn; - - sc->sc_disconnected = 1; - sc->sc_iface = iface; - id = usbd_get_interface_descriptor(iface); - usbd_devinfo(uaa->device, 0, devinfo); - USB_ATTACH_SETUP; - printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev), - devinfo, id->bInterfaceClass, id->bInterfaceSubClass); - ed = usbd_interface2endpoint_descriptor(iface, 0); - if (!ed) { - printf("%s: could not read endpoint descriptor\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - DPRINTFN(10,("ums_attach: bLength=%d bDescriptorType=%d " - "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d" - " bInterval=%d\n", - ed->bLength, ed->bDescriptorType, - ed->bEndpointAddress & UE_ADDR, - ed->bEndpointAddress & UE_IN ? "in" : "out", - ed->bmAttributes & UE_XFERTYPE, - UGETW(ed->wMaxPacketSize), ed->bInterval)); - - if ((ed->bEndpointAddress & UE_IN) != UE_IN || - (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) { - printf("%s: unexpected endpoint\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - - r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP); - if (r != USBD_NORMAL_COMPLETION) - USB_ATTACH_ERROR_RETURN; - - if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), - hid_input, &sc->sc_loc_x, &flags)) { - printf("%s: mouse has no X report\n", USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) { - printf("%s: X report 0x%04x not supported\n", - USBDEVNAME(sc->sc_dev), flags); - USB_ATTACH_ERROR_RETURN; - } - - if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), - hid_input, &sc->sc_loc_y, &flags)) { - printf("%s: mouse has no Y report\n", USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) { - printf("%s: Y report 0x%04x not supported\n", - USBDEVNAME(sc->sc_dev), flags); - USB_ATTACH_ERROR_RETURN; - } - - /* try to guess the Z activator: first check Z, then WHEEL */ - if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z), - hid_input, &sc->sc_loc_z, &flags) || - hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), - hid_input, &sc->sc_loc_z, &flags)) { - if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) { - sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */ - } else { -#if defined(__FreeBSD__) -#ifdef USBVERBOSE - printf("%s: Z dir. ignored due to bugs in ums.c\n", - USBDEVNAME(sc->sc_dev)); -#endif -#else - sc->flags |= UMS_Z; -#endif - } - } - - /* figure out the number of buttons */ - for (i = 1; i <= MAX_BUTTONS; i++) - if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i), - hid_input, &loc_btn, 0)) - break; - sc->nbuttons = i - 1; - sc->sc_loc_btn = malloc(sizeof(struct hid_location)*sc->nbuttons, - M_USBDEV, M_NOWAIT); - if (!sc->sc_loc_btn) - USB_ATTACH_ERROR_RETURN; - - printf("%s: %d buttons%s\n", USBDEVNAME(sc->sc_dev), - sc->nbuttons, (sc->flags & UMS_Z? " and Z dir." : "")); - - for (i = 1; i <= sc->nbuttons; i++) - hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i), - hid_input, &sc->sc_loc_btn[i-1], 0); - - sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid); - sc->sc_ibuf = malloc(sc->sc_isize, M_USB, M_NOWAIT); - if (!sc->sc_ibuf) { - free(sc->sc_loc_btn, M_USB); - USB_ATTACH_ERROR_RETURN; - } - - sc->sc_ep_addr = ed->bEndpointAddress; - sc->sc_disconnected = 0; - free(desc, M_TEMP); - -#ifdef USB_DEBUG - DPRINTF(("ums_attach: sc=%p\n", sc)); - DPRINTF(("ums_attach: X\t%d/%d\n", - sc->sc_loc_x.pos, sc->sc_loc_x.size)); - DPRINTF(("ums_attach: Y\t%d/%d\n", - sc->sc_loc_x.pos, sc->sc_loc_x.size)); - if (sc->flags & UMS_Z) - DPRINTF(("ums_attach: Z\t%d/%d\n", - sc->sc_loc_z.pos, sc->sc_loc_z.size)); - for (i = 1; i <= sc->nbuttons; i++) { - DPRINTF(("ums_attach: B%d\t%d/%d\n", - i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size)); - } - DPRINTF(("ums_attach: size=%d, id=%d\n", sc->sc_isize, sc->sc_iid)); -#endif - -#if defined(__NetBSD__) - a.accessops = &ums_accessops; - a.accesscookie = sc; - - sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint); -#elif defined(__FreeBSD__) - sc->hw.buttons = 2; /* XXX hw&mode values are bogus */ - sc->hw.iftype = MOUSE_IF_PS2; - sc->hw.type = MOUSE_MOUSE; - if (sc->flags & UMS_Z) - sc->hw.model = MOUSE_MODEL_INTELLI; - else - sc->hw.model = MOUSE_MODEL_GENERIC; - sc->hw.hwid = 0; - sc->mode.protocol = MOUSE_PROTO_PS2; - sc->mode.rate = -1; - sc->mode.resolution = MOUSE_RES_DEFAULT; - sc->mode.accelfactor = 1; - sc->mode.level = 0; - if (sc->flags & UMS_Z) { - sc->mode.packetsize = MOUSE_INTELLI_PACKETSIZE; - sc->mode.syncmask[0] = 0xc8; - } else { - sc->mode.packetsize = MOUSE_PS2_PACKETSIZE; - sc->mode.syncmask[0] = 0xc0; - } - sc->mode.syncmask[1] = 0; - - sc->status.flags = 0; - sc->status.button = sc->status.obutton = 0; - sc->status.dx = sc->status.dy = sc->status.dz = 0; - - sc->rsel.si_flags = 0; - sc->rsel.si_pid = 0; -#endif - - USB_ATTACH_SUCCESS_RETURN; -} - - -#if defined(__FreeBSD__) -static int -ums_detach(device_t self) -{ - struct ums_softc *sc = device_get_softc(self); - char *devinfo = (char *) device_get_desc(self); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - free(sc->sc_loc_btn, M_USB); - free(sc->sc_ibuf, M_USB); - - return 0; -} -#endif - -void -ums_disco(p) - void *p; -{ - struct ums_softc *sc = p; - - DPRINTF(("ums_disco: sc=%p\n", sc)); - usbd_abort_pipe(sc->sc_intrpipe); - sc->sc_disconnected = 1; -} - -void -ums_intr(reqh, addr, status) - usbd_request_handle reqh; - usbd_private_handle addr; - usbd_status status; -{ - struct ums_softc *sc = addr; - u_char *ibuf; - int dx, dy, dz; - u_char buttons = 0; - int i; - -#if defined(__NetBSD__) -#define UMS_BUT(i) ((i) == 1 || (i) == 2 ? 3 - (i) : i) -#elif defined(__FreeBSD__) -#define UMS_BUT(i) (i) -#endif - - DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status)); - DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n", - sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2])); - - if (status == USBD_CANCELLED) - return; - - if (status != USBD_NORMAL_COMPLETION) { - DPRINTF(("ums_intr: status=%d\n", status)); - usbd_clear_endpoint_stall_async(sc->sc_intrpipe); - return; - } - - ibuf = sc->sc_ibuf; - if (sc->sc_iid) { - if (*ibuf++ != sc->sc_iid) - return; - } - - dx = hid_get_data(ibuf, &sc->sc_loc_x); - dy = -hid_get_data(ibuf, &sc->sc_loc_y); - dz = hid_get_data(ibuf, &sc->sc_loc_z); - for (i = 0; i < sc->nbuttons; i++) - if (hid_get_data(ibuf, &sc->sc_loc_btn[i])) - buttons |= (1 << UMS_BUT(i)); - -#if defined(__NetBSD__) - if (dx || dy || buttons != sc->sc_buttons) { - DPRINTFN(10, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n", - dx, dy, dz, buttons)); - sc->sc_buttons = buttons; - if (sc->sc_wsmousedev) - wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, dz); -#elif defined(__FreeBSD__) - if (dx || dy || (sc->flags & UMS_Z && dz) - || buttons != sc->status.button) { - DPRINTFN(5, ("ums_intr: x:%d y:%d z:%d buttons:0x%x\n", - dx, dy, dz, buttons)); - - sc->status.button = buttons; - sc->status.dx += dx; - sc->status.dy += dy; - sc->status.dz += dz; - - /* Discard data in case of full buffer */ - if (sc->qcount == sizeof(sc->qbuf)) { - DPRINTF(("Buffer full, discarded packet")); - return; - } - - sc->qbuf[sc->qhead] = MOUSE_PS2_SYNC; - if (dx < 0) - sc->qbuf[sc->qhead] |= MOUSE_PS2_XNEG; - if (dx > 255 || dx < -255) - sc->qbuf[sc->qhead] |= MOUSE_PS2_XOVERFLOW; - if (dy < 0) - sc->qbuf[sc->qhead] |= MOUSE_PS2_YNEG; - if (dy > 255 || dy < -255) - sc->qbuf[sc->qhead] |= MOUSE_PS2_YOVERFLOW; - sc->qbuf[sc->qhead++] |= buttons; - sc->qbuf[sc->qhead++] = dx; - sc->qbuf[sc->qhead++] = dy; - sc->qcount += 3; - if (sc->flags & UMS_Z) { - sc->qbuf[sc->qhead++] = dz; - sc->qcount++; - } -#ifdef USB_DEBUG - if (sc->qhead > sizeof(sc->qbuf)) - DPRINTF(("Buffer overrun! %d %d\n", - sc->qhead, sizeof(sc->qbuf))); -#endif - /* wrap round at end of buffer */ - if (sc->qhead >= sizeof(sc->qbuf)) - sc->qhead = 0; - - /* someone waiting for data */ - if (sc->state & UMS_ASLEEP) { - DPRINTF(("Waking up %p\n", sc)); - wakeup(sc); - } - if (sc->state & UMS_SELECT) { - DPRINTF(("Waking up select %p\n", &sc->rsel)); - selwakeup(&sc->rsel); - } -#endif - } -} - - -static int -ums_enable(v) - void *v; -{ - struct ums_softc *sc = v; - - usbd_status r; - - if (sc->sc_enabled) - return EBUSY; - - sc->sc_enabled = 1; -#if defined(__NetBSD__) - sc->sc_buttons = 0; -#elif defined(__FreeBSD__) - sc->qcount = 0; - sc->qhead = sc->qtail = 0; - sc->status.flags = 0; - sc->status.button = sc->status.obutton = 0; - sc->status.dx = sc->status.dy = sc->status.dz = 0; -#endif - - /* Set up interrupt pipe. */ - r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr, - USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, - sc->sc_ibuf, sc->sc_isize, ums_intr); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n", - r)); - sc->sc_enabled = 0; - return (EIO); - } - usbd_set_disco(sc->sc_intrpipe, ums_disco, sc); - return (0); -} - -static void -ums_disable(v) - void *v; -{ - struct ums_softc *sc = v; - - /* Disable interrupts. */ - usbd_abort_pipe(sc->sc_intrpipe); - usbd_close_pipe(sc->sc_intrpipe); - - sc->sc_enabled = 0; - -#if defined(USBVERBOSE) && defined(__FreeBSD__) - if (sc->qcount != 0) - DPRINTF(("Discarded %d bytes in queue\n", sc->qcount)); -#endif -} - -#if defined(__NetBSD__) -static int -ums_ioctl(v, cmd, data, flag, p) - void *v; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; - -{ - switch (cmd) { - case WSMOUSEIO_GTYPE: - *(u_int *)data = WSMOUSE_TYPE_USB; - return (0); - } - - return (-1); -} - -#elif defined(__FreeBSD__) -static int -ums_open(dev_t dev, int flag, int fmt, struct proc *p) -{ - USB_GET_SC_OPEN(ums, UMSUNIT(dev), sc); - - return ums_enable(sc); -} - -static int -ums_close(dev_t dev, int flag, int fmt, struct proc *p) -{ - USB_GET_SC(ums, UMSUNIT(dev), sc); - - if (sc->sc_enabled) - ums_disable(sc); - - return 0; -} - -static int -ums_read(dev_t dev, struct uio *uio, int flag) -{ - USB_GET_SC(ums, UMSUNIT(dev), sc); - int s; - char buf[sizeof(sc->qbuf)]; - int l = 0; - int error; - - s = splusb(); - while (sc->qcount == 0 ) { - /* NWH XXX non blocking I/O ?? - if (non blocking I/O ) { - splx(s); - return EWOULDBLOCK; - } else { - */ - sc->state |= UMS_ASLEEP; - error = tsleep(sc, PZERO | PCATCH, "umsrea", 0); - sc->state &= ~UMS_ASLEEP; - if (error) { - splx(s); - return error; - } - } - - while ((sc->qcount > 0) && (uio->uio_resid > 0)) { - l = (sc->qcount < uio->uio_resid? sc->qcount:uio->uio_resid); - if (l > sizeof(buf)) - l = sizeof(buf); - if (l > sizeof(sc->qbuf) - sc->qtail) /* transfer till end of buf */ - l = sizeof(sc->qbuf) - sc->qtail; - - splx(s); - uiomove(&sc->qbuf[sc->qtail], l, uio); - s = splusb(); - - if ( sc->qcount - l < 0 ) { - DPRINTF(("qcount below 0, count=%d l=%d\n", sc->qcount, l)); - sc->qcount = l; - } - sc->qcount -= l; /* remove the bytes from the buffer */ - sc->qtail = (sc->qtail + l) % sizeof(sc->qbuf); - } - splx(s); - - return 0; -} - -static int -ums_poll(dev_t dev, int events, struct proc *p) -{ - USB_GET_SC(ums, UMSUNIT(dev), sc); - int revents = 0; - int s; - - s = splusb(); - if (events & (POLLIN | POLLRDNORM)) { - if (sc->qcount) { - revents = events & (POLLIN | POLLRDNORM); - } else { - sc->state |= UMS_SELECT; - selrecord(p, &sc->rsel); - sc->state &= ~UMS_SELECT; - } - } - splx(s); - - return revents; -} - -int -ums_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) -{ - USB_GET_SC(ums, UMSUNIT(dev), sc); - int error = 0; - int s; - - switch(cmd) { - case MOUSE_GETHWINFO: - *(mousehw_t *)addr = sc->hw; - break; - case MOUSE_GETMODE: - *(mousemode_t *)addr = sc->mode; - break; - case MOUSE_GETLEVEL: - *(int *)addr = sc->mode.level; - break; - case MOUSE_GETSTATUS: { - mousestatus_t *status = (mousestatus_t *) addr; - - s = splusb(); - *status = sc->status; - sc->status.obutton = sc->status.button; - sc->status.button = 0; - sc->status.dx = sc->status.dy = sc->status.dz = 0; - splx(s); - - if (status->dx || status->dy || status->dz) - status->flags |= MOUSE_POSCHANGED; - if (status->button != status->obutton) - status->flags |= MOUSE_BUTTONSCHANGED; - break; - } - default: - error = ENOTTY; - } - - return error; -} -#endif - -#if defined(__FreeBSD__) -CDEV_DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass, - UMS_CDEV_MAJOR, ums_cdevsw, usbd_driver_load, 0); -#endif diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c deleted file mode 100644 index 70c75166b2662..0000000000000 --- a/sys/dev/usb/usb.c +++ /dev/null @@ -1,418 +0,0 @@ -/* $NetBSD: usb.c,v 1.11 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * USB specifications and other documentation can be found at - * http://www.usb.org/developers/data/ and - * http://www.usb.org/developers/index.html . - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/ioccom.h> -#include <sys/uio.h> -#include <sys/conf.h> -#endif -#include <sys/poll.h> -#include <sys/proc.h> -#include <sys/select.h> - -#include <dev/usb/usb.h> - -#if defined(__FreeBSD__) -MALLOC_DEFINE(M_USB, "USB", "USB"); -MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device"); - -#include "usb_if.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) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -int usbdebug = 1; -int uhcidebug = 1; -int ohcidebug = 1; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -#define USBUNIT(dev) (minor(dev)) - -struct usb_softc { - bdevice 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 */ -}; - -#if defined(__NetBSD__) -int usbopen __P((dev_t, int, int, struct proc *)); -int usbclose __P((dev_t, int, int, struct proc *)); -int usbioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); -int usbpoll __P((dev_t, int, struct proc *)); - -#elif defined(__FreeBSD__) -d_open_t usbopen; -d_close_t usbclose; -d_ioctl_t usbioctl; -int usbpoll __P((dev_t, int, struct proc *)); - -struct cdevsw usb_cdevsw = { - usbopen, usbclose, noread, nowrite, - usbioctl, nullstop, nullreset, nodevtotty, - usbpoll, nommap, nostrat, - "usb", NULL, -1 -}; -#endif - -usbd_status usb_discover __P((struct usb_softc *)); - -USB_DECLARE_DRIVER_INIT(usb, DEVMETHOD(bus_print_child, usbd_print_child)); - -USB_MATCH(usb) -{ - DPRINTF(("usbd_match\n")); - return (UMATCH_GENERIC); -} - -USB_ATTACH(usb) -{ -#if defined(__NetBSD__) - struct usb_softc *sc = (struct usb_softc *)self; -#elif defined(__FreeBSD__) - struct usb_softc *sc = device_get_softc(self); - void *aux = device_get_ivars(self); -#endif - usbd_device_handle dev; - usbd_status r; - -#if defined(__NetBSD__) - 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); - - if (r == USBD_NORMAL_COMPLETION) { - dev = sc->sc_port.device; - if (!dev->hub) { - sc->sc_running = 0; - printf("%s: root device is not a hub\n", - USBDEVNAME(sc->sc_dev)); - USB_ATTACH_ERROR_RETURN; - } - sc->sc_bus->root_hub = dev; - dev->hub->explore(sc->sc_bus->root_hub); - } else { - printf("%s: root hub problem, error=%d\n", - USBDEVNAME(sc->sc_dev), r); - sc->sc_running = 0; - } - sc->sc_bus->use_polling = 0; - - USB_ATTACH_SUCCESS_RETURN; -} - -#if defined(__NetBSD__) -int -usbctlprint(aux, pnp) - void *aux; - const char *pnp; -{ - /* only "usb"es can attach to host controllers */ - if (pnp) - printf("usb at %s", pnp); - - return (UNCONF); -} -#endif - -int -usbopen(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -{ - USB_GET_SC_OPEN(usb, USBUNIT(dev), sc); - - if (sc == 0 || !sc->sc_running) - return (ENXIO); - - return (0); -} - -int -usbclose(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -{ - return (0); -} - -int -usbioctl(dev, cmd, data, flag, p) - dev_t dev; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - USB_GET_SC(usb, USBUNIT(dev), sc); - - if (sc == 0 || !sc->sc_running) - return (ENXIO); - switch (cmd) { -#ifdef USB_DEBUG - case USB_SETDEBUG: - usbdebug = uhcidebug = ohcidebug = *(int *)data; - break; -#endif - case USB_DISCOVER: - usb_discover(sc); - break; - case USB_REQUEST: - { - struct usb_ctl_request *ur = (void *)data; - int len = UGETW(ur->request.wLength); - struct iovec iov; - struct uio uio; - void *ptr = 0; - int addr = ur->addr; - usbd_status r; - int error = 0; - - DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len)); - if (len < 0 || len > 32768) - return (EINVAL); - if (addr < 0 || addr >= USB_MAX_DEVICES || - sc->sc_bus->devices[addr] == 0) - return (EINVAL); - if (len != 0) { - iov.iov_base = (caddr_t)ur->data; - iov.iov_len = len; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_resid = len; - uio.uio_offset = 0; - uio.uio_segflg = UIO_USERSPACE; - uio.uio_rw = - ur->request.bmRequestType & UT_READ ? - UIO_READ : UIO_WRITE; - uio.uio_procp = p; - ptr = malloc(len, M_TEMP, M_WAITOK); - if (uio.uio_rw == UIO_WRITE) { - error = uiomove(ptr, len, &uio); - if (error) - goto ret; - } - } - r = usbd_do_request_flags(sc->sc_bus->devices[addr], - &ur->request, ptr, - ur->flags, &ur->actlen); - if (r) { - error = EIO; - goto ret; - } - if (len != 0) { - if (uio.uio_rw == UIO_READ) { - error = uiomove(ptr, len, &uio); - if (error) - goto ret; - } - } - ret: - if (ptr) - free(ptr, M_TEMP); - return (error); - } - - case USB_DEVICEINFO: - { - struct usb_device_info *di = (void *)data; - int addr = di->addr; - usbd_device_handle dev; - - if (addr < 1 || addr >= USB_MAX_DEVICES) - return (EINVAL); - dev = sc->sc_bus->devices[addr]; - if (dev == 0) - return (ENXIO); - usbd_fill_deviceinfo(dev, di); - break; - } - - case USB_DEVICESTATS: - *(struct usb_device_stats *)data = sc->sc_bus->stats; - break; - - default: - return (ENXIO); - } - return (0); -} - -int -usbpoll(dev, events, p) - dev_t dev; - int events; - struct proc *p; -{ - int revents, s; - USB_GET_SC(usb, USBUNIT(dev), sc); - - DPRINTFN(2, ("usbpoll: sc=%p events=0x%x\n", sc, events)); - s = splusb(); - revents = 0; - if (events & (POLLOUT | POLLWRNORM)) - if (sc->sc_bus->needs_explore) - revents |= events & (POLLOUT | POLLWRNORM); - DPRINTFN(2, ("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); -} - -#if 0 -int -usb_bus_count() -{ - int i, n; - - for (i = n = 0; i < usb_cd.cd_ndevs; i++) - if (usb_cd.cd_devs[i]) - n++; - return (n); -} -#endif - -#if defined(__NetBSD__) -usbd_status -usb_get_bus_handle(n, h) - int n; - usbd_bus_handle *h; -{ - int i; - - for (i = 0; i < usb_cd.cd_ndevs; i++) - if (usb_cd.cd_devs[i] && n-- == 0) { - *h = usb_cd.cd_devs[i]; - return (USBD_NORMAL_COMPLETION); - } - return (USBD_INVAL); -} -#endif - -usbd_status -usb_discover(sc) - struct usb_softc *sc; -{ - int s; - - /* 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); -} - -void -usb_needs_explore(bus) - usbd_bus_handle bus; -{ - bus->needs_explore = 1; - selwakeup(&bus->usbctl->sc_consel); -} - -#if defined(__FreeBSD__) -int -usb_detach(device_t self) -{ - char *devinfo = (char *) device_get_desc(self); - - if (devinfo) { - device_set_desc(self, NULL); - free(devinfo, M_USB); - } - - return (0); -} - -DRIVER_MODULE(usb, root, usb_driver, usb_devclass, 0, 0); -#endif diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h deleted file mode 100644 index 17f0f0eeed715..0000000000000 --- a/sys/dev/usb/usb.h +++ /dev/null @@ -1,493 +0,0 @@ -/* $NetBSD: usb.h,v 1.17 1999/01/03 01:09:18 augustss Exp $ */ -/* FreeBSD $Id: usb.h,v 1.6 1999/01/07 23:31:37 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef _USB_H_ -#define _USB_H_ - -#include <sys/types.h> -#if defined(__NetBSD__) -#include <sys/ioctl.h> -#endif - -#if defined(__NetBSD__) -#if defined(_KERNEL) -#include <dev/usb/usb_port.h> -#endif /* _KERNEL */ - -#elif defined(__FreeBSD__) -#include <sys/malloc.h> - -#if defined(KERNEL) -MALLOC_DECLARE(M_USB); -MALLOC_DECLARE(M_USBDEV); - -#include <dev/usb/usb_port.h> -#endif /* KERNEL */ -#endif /* __FreeBSD__ */ - - -#define USB_MAX_DEVICES 128 -#define USB_START_ADDR 0 - -#define USB_CONTROL_ENDPOINT 0 -#define USB_MAX_ENDPOINTS 16 - -#define USB_FRAMES_PER_SECOND 1000 - -/* - * The USB records contain some unaligned little-endian word - * components. The U[SG]ETW macros take care of both the alignment - * and endian problem and should always be used to access 16 bit - * values. - */ -typedef u_int8_t uByte; -typedef u_int8_t uWord[2]; -#define UGETW(w) ((w)[0] | ((w)[1] << 8)) -#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8)) -#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h)) -typedef u_int8_t uDWord[4]; -#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) -#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \ - (w)[1] = (u_int8_t)((v) >> 8), \ - (w)[2] = (u_int8_t)((v) >> 16), \ - (w)[3] = (u_int8_t)((v) >> 24)) -/* - * On little-endian machines that can handle unanliged accesses - * (e.g. i386) these macros can be replaced by the following. - */ -#if 0 -#define UGETW(w) (*(u_int16_t *)(w)) -#define USETW(w,v) (*(u_int16_t *)(w) = (v)) -#endif - -typedef struct { - uByte bmRequestType; - uByte bRequest; - uWord wValue; - uWord wIndex; - uWord wLength; -} usb_device_request_t; - -#define UT_WRITE 0x00 -#define UT_READ 0x80 -#define UT_STANDARD 0x00 -#define UT_CLASS 0x20 -#define UT_VENDOR 0x40 -#define UT_DEVICE 0x00 -#define UT_INTERFACE 0x01 -#define UT_ENDPOINT 0x02 -#define UT_OTHER 0x03 - -#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE) -#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE) -#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT) -#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE) -#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE) -#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT) -#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_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_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_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) - -/* Requests */ -#define UR_GET_STATUS 0x00 -#define UR_CLEAR_FEATURE 0x01 -#define UR_SET_FEATURE 0x03 -#define UR_SET_ADDRESS 0x05 -#define UR_GET_DESCRIPTOR 0x06 -#define UDESC_DEVICE 1 -#define UDESC_CONFIG 2 -#define UDESC_STRING 3 -#define UDESC_INTERFACE 4 -#define UDESC_ENDPOINT 5 -#define UR_SET_DESCRIPTOR 0x07 -#define UR_GET_CONFIG 0x08 -#define UR_SET_CONFIG 0x09 -#define UR_GET_INTERFACE 0x0a -#define UR_SET_INTERFACE 0x0b -#define UR_SYNCH_FRAME 0x0c - -/* Feature numbers */ -#define UF_ENDPOINT_HALT 0 -#define UF_DEVICE_REMOTE_WAKEUP 1 - -#define USB_MAX_IPACKET 8 /* maximum size of the initial packet */ - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; -} usb_descriptor_t; - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uWord bcdUSB; - uByte bDeviceClass; - uByte bDeviceSubClass; - uByte bDeviceProtocol; - uByte bMaxPacketSize; - /* The fields below are not part of the initial descriptor. */ - uWord idVendor; - uWord idProduct; - uWord bcdDevice; - uByte iManufacturer; - uByte iProduct; - uByte iSerialNumber; - uByte bNumConfigurations; -} usb_device_descriptor_t; -#define USB_DEVICE_DESCRIPTOR_SIZE 18 - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uWord wTotalLength; - uByte bNumInterface; - uByte bConfigurationValue; - uByte iConfiguration; - uByte bmAttributes; -#define UC_BUS_POWERED 0x80 -#define UC_SELF_POWERED 0x40 -#define UC_REMOTE_WAKEUP 0x20 - uByte bMaxPower; /* max current in 2 mA units */ -#define UC_POWER_FACTOR 2 -} usb_config_descriptor_t; -#define USB_CONFIG_DESCRIPTOR_SIZE 9 - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bInterfaceNumber; - uByte bAlternateSetting; - uByte bNumEndpoints; - uByte bInterfaceClass; - uByte bInterfaceSubClass; - uByte bInterfaceProtocol; - uByte iInterface; -} usb_interface_descriptor_t; -#define USB_INTERFACE_DESCRIPTOR_SIZE 9 - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bEndpointAddress; -#define UE_IN 0x80 -#define UE_OUT 0x00 -#define UE_ADDR 0x0f -#define UE_GET_ADDR(a) ((a) & UE_ADDR) -#define UE_GET_IN(a) (((a) >> 7) & 1) - uByte bmAttributes; -#define UE_XFERTYPE 0x03 -#define UE_CONTROL 0x00 -#define UE_ISOCHRONOUS 0x01 -#define UE_BULK 0x02 -#define UE_INTERRUPT 0x03 -#define UE_ISO_TYPE 0x0c -#define UE_ISO_ASYNC 0x04 -#define UE_ISO_ADAPT 0x08 -#define UE_ISO_SYNC 0x0c - uWord wMaxPacketSize; - uByte bInterval; -} usb_endpoint_descriptor_t; -#define USB_ENDPOINT_DESCRIPTOR_SIZE 7 - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uWord bString[127]; -} usb_string_descriptor_t; -#define USB_MAX_STRING_LEN 128 -#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */ - -/* Hub specific request */ -#define UR_GET_BUS_STATE 0x02 - -/* Hub features */ -#define UHF_C_HUB_LOCAL_POWER 0 -#define UHF_C_HUB_OVER_CURRENT 1 -#define UHF_PORT_CONNECTION 0 -#define UHF_PORT_ENABLE 1 -#define UHF_PORT_SUSPEND 2 -#define UHF_PORT_OVER_CURRENT 3 -#define UHF_PORT_RESET 4 -#define UHF_PORT_POWER 8 -#define UHF_PORT_LOW_SPEED 9 -#define UHF_C_PORT_CONNECTION 16 -#define UHF_C_PORT_ENABLE 17 -#define UHF_C_PORT_SUSPEND 18 -#define UHF_C_PORT_OVER_CURRENT 19 -#define UHF_C_PORT_RESET 20 - -typedef struct { - uByte bDescLength; - uByte bDescriptorType; - uByte bNbrPorts; - uWord wHubCharacteristics; -#define UHD_PWR 0x03 -#define UHD_PWR_GANGED 0x00 -#define UHD_PWR_INDIVIDUAL 0x01 -#define UHD_PWR_NO_SWITCH 0x02 -#define UHD_COMPOUND 0x04 -#define UHD_OC 0x18 -#define UHD_OC_GLOBAL 0x00 -#define UHD_OC_INDIVIDUAL 0x08 -#define UHD_OC_NONE 0x10 - uByte bPwrOn2PwrGood; /* delay in 2 ms units */ -#define UHD_PWRON_FACTOR 2 - uByte bHubContrCurrent; - uByte DeviceRemovable[32]; /* max 255 ports */ -#define UHD_NOT_REMOV(desc, i) \ - (((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1) - /* deprecated uByte PortPowerCtrlMask[]; */ -} usb_hub_descriptor_t; -#define USB_HUB_DESCRIPTOR_SIZE 8 - -typedef struct { - uWord wStatus; -/* Device status flags */ -#define UDS_SELF_POWERED 0x0001 -#define UDS_REMOTE_WAKEUP 0x0002 -/* Endpoint status flags */ -#define UES_HALT 0x0001 -} usb_status_t; - -typedef struct { - uWord wHubStatus; -#define UHS_LOCAL_POWER 0x0001 -#define UHS_OVER_CURRENT 0x0002 - uWord wHubChange; -} usb_hub_status_t; - -typedef struct { - uWord wPortStatus; -#define UPS_CURRENT_CONNECT_STATUS 0x0001 -#define UPS_PORT_ENABLED 0x0002 -#define UPS_SUSPEND 0x0004 -#define UPS_OVERCURRENT_INDICATOR 0x0008 -#define UPS_RESET 0x0010 -#define UPS_PORT_POWER 0x0100 -#define UPS_LOW_SPEED 0x0200 - uWord wPortChange; -#define UPS_C_CONNECT_STATUS 0x0001 -#define UPS_C_PORT_ENABLED 0x0002 -#define UPS_C_SUSPEND 0x0004 -#define UPS_C_OVERCURRENT_INDICATOR 0x0008 -#define UPS_C_PORT_RESET 0x0010 -} usb_port_status_t; - -#define UDESC_CS_DEVICE 0x21 -#define UDESC_CS_CONFIG 0x22 -#define UDESC_CS_STRING 0x23 -#define UDESC_CS_INTERFACE 0x24 -#define UDESC_CS_ENDPOINT 0x25 - -#define UDESC_HUB 0x29 - -#define UCLASS_UNSPEC 0 -#define UCLASS_AUDIO 1 -#define USUBCLASS_AUDIOCONTROL 1 -#define USUBCLASS_AUDIOSTREAM 2 -#define UCLASS_CDC 2 /* communication */ -#define USUBCLASS_ABSTRACT_CONTROL_MODEL 2 -#define UPROTO_CDC_AT 1 -#define UCLASS_HID 3 -#define USUBCLASS_BOOT 1 -#define UCLASS_PRINTER 7 -#define USUBCLASS_PRINTER 1 -#define UPROTO_PRINTER_UNI 1 -#define UPROTO_PRINTER_BI 2 -#define UCLASS_HUB 9 -#define USUBCLASS_HUB 0 -#define UCLASS_DATA 10 - -#define USB_HUB_MAX_DEPTH 5 - -/* - * Minimum time a device needs to be powered down to go through - * a power cycle. XXX Are these time in the spec? - */ -#define USB_POWER_DOWN_TIME 200 /* ms */ -#define USB_PORT_POWER_DOWN_TIME 100 /* ms */ - -#if 0 -/* These are the values from the spec. */ -#define USB_PORT_RESET_DELAY 10 /* ms */ -#define USB_PORT_RESET_SETTLE 10 /* ms */ -#define USB_PORT_POWERUP_DELAY 100 /* ms */ -#define USB_SET_ADDRESS_SETTLE 2 /* ms */ -#else -/* Allow for marginal (i.e. non-conforming) devices. */ -#define USB_PORT_RESET_DELAY 20 /* ms */ -#define USB_PORT_RESET_RECOVERY 50 /* ms */ -#define USB_PORT_POWERUP_DELAY 200 /* ms */ -#define USB_SET_ADDRESS_SETTLE 10 /* 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 ***/ - -struct usb_ctl_request { - int addr; - usb_device_request_t request; - void *data; - int flags; -/* XXX must match flags in usbdi.h */ -#define USBD_SHORT_XFER_OK 0x04 - int actlen; /* actual length transferred */ -}; - -struct usb_alt_interface { - int config_index; - int interface_index; - int alt_no; -}; - -#define USB_CURRENT_CONFIG_INDEX (-1) -#define USB_CURRENT_ALT_INDEX (-1) - -struct usb_config_desc { - int config_index; - usb_config_descriptor_t desc; -}; - -struct usb_interface_desc { - int config_index; - int interface_index; - int alt_index; - usb_interface_descriptor_t desc; -}; - -struct usb_endpoint_desc { - int config_index; - int interface_index; - int alt_index; - int endpoint_index; - usb_endpoint_descriptor_t desc; -}; - -struct usb_full_desc { - int config_index; - u_int size; - u_char *data; -}; - -struct usb_string_desc { - int string_index; - int language_id; - usb_string_descriptor_t desc; -}; - -struct usb_ctl_report_desc { - int size; - u_char data[1024]; /* filled data size will vary */ -}; - -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]; - u_int16_t productNo; - u_int16_t vendorNo; - u_int8_t class; - u_int8_t config; - u_int8_t lowspeed; - int power; /* power consumption in mA, 0 if selfpowered */ - int nports; - u_int8_t ports[16];/* hub only: addresses of devices on ports */ -#define USB_PORT_ENABLED 0xff -#define USB_PORT_SUSPENDED 0xfe -#define USB_PORT_POWERED 0xfd -#define USB_PORT_DISABLED 0xfc -}; - -struct usb_ctl_report { - int report; - u_char data[1024]; /* filled data size will vary */ -}; - -struct usb_device_stats { - u_long requests[4]; /* indexed by transfer type UE_* */ -}; - -/* USB controller */ -#define USB_REQUEST _IOWR('U', 1, struct usb_ctl_request) -#define USB_SETDEBUG _IOW ('U', 2, int) -#define USB_DISCOVER _IO ('U', 3) -#define USB_DEVICEINFO _IOWR('U', 4, struct usb_device_info) -#define USB_DEVICESTATS _IOR ('U', 5, struct usb_device_stats) - -/* Generic HID device */ -#define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb_ctl_report_desc) -#define USB_SET_IMMED _IOW ('U', 22, int) -#define USB_GET_REPORT _IOWR('U', 23, struct usb_ctl_report) - -/* Generic USB device */ -#define USB_GET_CONFIG _IOR ('U', 100, int) -#define USB_SET_CONFIG _IOW ('U', 101, int) -#define USB_GET_ALTINTERFACE _IOWR('U', 102, struct usb_alt_interface) -#define USB_SET_ALTINTERFACE _IOWR('U', 103, struct usb_alt_interface) -#define USB_GET_NO_ALT _IOWR('U', 104, struct usb_alt_interface) -#define USB_GET_DEVICE_DESC _IOR ('U', 105, usb_device_descriptor_t) -#define USB_GET_CONFIG_DESC _IOWR('U', 106, struct usb_config_desc) -#define USB_GET_INTERFACE_DESC _IOWR('U', 107, struct usb_interface_desc) -#define USB_GET_ENDPOINT_DESC _IOWR('U', 108, struct usb_endpoint_desc) -#define USB_GET_FULL_DESC _IOWR('U', 109, struct usb_full_desc) -#define USB_GET_STRING_DESC _IOWR('U', 110, struct usb_string_desc) -#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) - -#endif /* _USB_H_ */ diff --git a/sys/dev/usb/usb_if.m b/sys/dev/usb/usb_if.m deleted file mode 100644 index fa5649c555dad..0000000000000 --- a/sys/dev/usb/usb_if.m +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (c) 1992-1998 Nick Hibma <hibma@skylink.it> -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer, -# without modification, immediately at the beginning of the file. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# $Id$ -# - -# USB interface description -# - -INTERFACE usb; - -# The device should start probing for new children again -# -METHOD int reconfigure { - device_t dev; -}; - diff --git a/sys/dev/usb/usb_mem.h b/sys/dev/usb/usb_mem.h deleted file mode 100644 index f6ffb96879457..0000000000000 --- a/sys/dev/usb/usb_mem.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD: usb_mem.h,v 1.4 1999/01/09 12:16:54 augustss Exp $ */ -/* FreeBSD $Id: usb_mem.h,v 1.4 1999/01/07 23:31:38 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#if defined(__NetBSD__) -typedef struct usb_block_dma { - bus_dma_tag_t tag; - bus_dmamap_t map; - caddr_t kaddr; - bus_dma_segment_t segs[1]; - int nsegs; - size_t size; - size_t align; - int fullblock; - LIST_ENTRY(usb_block_dma) 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)) - -usbd_status usb_allocmem __P((bus_dma_tag_t, size_t, size_t, usb_dma_t *)); -void usb_freemem __P((bus_dma_tag_t, usb_dma_t *)); - -#elif defined(__FreeBSD__) - -/* - * FreeBSD does not have special functions for dma memory, so let's keep it - * simple for now. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/proc.h> -#include <sys/buf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <vm/vm.h> -#include <vm/pmap.h> - -#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)) - -#define DMAADDR(dma) (vtophys(*(dma))) -#define KERNADDR(dma) ((void *) *(dma)) -#endif - diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h deleted file mode 100644 index d7bd4f0040ddf..0000000000000 --- a/sys/dev/usb/usb_port.h +++ /dev/null @@ -1,217 +0,0 @@ -/* $NetBSD: usb_port.h,v 1.5 1999/01/08 11:58:25 augustss Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -/* - * Macro's to cope with the differences between operating systems. - */ - -/* - * NetBSD - */ - -#if defined(__NetBSD__) -#include "opt_usbverbose.h" - -#define USBDEVNAME(bdev) ((bdev).dv_xname) - -typedef struct device bdevice; /* base device */ - -#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) \ -int __CONCAT(dname,_match) __P((struct device *, struct cfdata *, void *)); \ -void __CONCAT(dname,_attach) __P((struct device *, struct device *, void *)); \ -\ -extern struct cfdriver __CONCAT(dname,_cd); \ -\ -struct cfattach __CONCAT(dname,_ca) = { \ - sizeof(struct __CONCAT(dname,_softc)), \ - __CONCAT(dname,_match), \ - __CONCAT(dname,_attach) \ -} - -#define USB_MATCH(dname) \ -int \ -__CONCAT(dname,_match)(parent, match, aux) \ - struct device *parent; \ - struct cfdata *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_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) \ - ((dev)->softc = config_found_sm(parent, args, print, sub)) - - - - -#elif defined(__FreeBSD__) -/* - * FreeBSD - */ - -#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) usbd_devname(&bdev) - -/* 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 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...) \ -static device_probe_t __CONCAT(dname,_match); \ -static device_attach_t __CONCAT(dname,_attach); \ -static device_detach_t __CONCAT(dname,_detach); \ -\ -static devclass_t __CONCAT(dname,_devclass); \ -\ -static device_method_t __CONCAT(dname,_methods)[] = { \ - DEVMETHOD(device_probe, __CONCAT(dname,_match)), \ - DEVMETHOD(device_attach, __CONCAT(dname,_attach)), \ - DEVMETHOD(device_detach, __CONCAT(dname,_detach)), \ - init, \ - {0,0} \ -}; \ -\ -static driver_t __CONCAT(dname,_driver) = { \ - #dname, \ - __CONCAT(dname,_methods), \ - DRIVER_TYPE_MISC, \ - sizeof(struct __CONCAT(dname,_softc)) \ -} - -#define USB_MATCH(dname) \ -static int \ -__CONCAT(dname,_match)(device_t device) - -#define USB_MATCH_START(dname, uaa) \ - struct usb_attach_arg *uaa = device_get_ivars(device) - -#define USB_ATTACH(dname) \ -static int \ -__CONCAT(dname,_attach)(device_t self) - -#define USB_ATTACH_START(dname, sc, uaa) \ - struct __CONCAT(dname,_softc) *sc = device_get_softc(self); \ - struct usb_attach_arg *uaa = device_get_ivars(self) - -/* Returns from attach */ -#define USB_ATTACH_ERROR_RETURN return ENXIO -#define USB_ATTACH_SUCCESS_RETURN return 0 - -#define USB_ATTACH_SETUP \ - usbd_device_set_desc(self, devinfo); \ - sc->sc_dev = self - -#define USB_GET_SC_OPEN(dname, unit, sc) \ - struct __CONCAT(dname,_softc) *sc = \ - devclass_get_softc(__CONCAT(dname,_devclass), unit); \ - if (!sc) \ - return (ENXIO) - -#define USB_GET_SC(dname, unit, sc) \ - struct __CONCAT(dname,_softc) *sc = \ - devclass_get_softc(__CONCAT(dname,_devclass), unit) - -#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \ - (device_probe_and_attach((bdev)) == 0 ? ((dev)->softc = (bdev)) : 0) - -/* conversion from one type of queue to the other */ -#define SIMPLEQ_REMOVE_HEAD STAILQ_REMOVE_HEAD_UNTIL -#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_ENTRY STAILQ_ENTRY - -#endif /* __FreeBSD__ */ - - - -#define USB_DECLARE_DRIVER(dname) \ - USB_DECLARE_DRIVER_INIT(dname, {0,0} ) diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c deleted file mode 100644 index e7c8208abce19..0000000000000 --- a/sys/dev/usb/usb_quirks.c +++ /dev/null @@ -1,94 +0,0 @@ -/* $NetBSD: usb_quirks.c,v 1.8 1999/01/08 11:58:25 augustss Exp $ */ -/* FreeBSD $Id: usb_quirks.c,v 1.5 1999/01/07 23:31:39 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#if defined(__FreeBSD__) -#include <sys/bus.h> -#endif - -#include <dev/usb/usb.h> - -#include <dev/usb/usbdevs.h> -#include <dev/usb/usb_quirks.h> - -#ifdef USB_DEBUG -extern int usbdebug; -#endif - -struct usbd_quirk_entry { - u_int16_t idVendor; - u_int16_t idProduct; - u_int16_t bcdDevice; - struct usbd_quirks quirks; -} quirks[] = { - { 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_UNIXTAR, USB_PRODUCT_UNIXTAR_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 }}, - { 0, 0, 0, { 0 } } -}; - -struct usbd_quirks usbd_no_quirk = { 0 }; - -struct usbd_quirks * -usbd_find_quirk(d) - usb_device_descriptor_t *d; -{ - struct usbd_quirk_entry *t; - - for (t = quirks; t->idVendor != 0; t++) { - if (t->idVendor == UGETW(d->idVendor) && - t->idProduct == UGETW(d->idProduct) && - t->bcdDevice == UGETW(d->bcdDevice)) - break; - } -#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); -#endif - return (&t->quirks); -} diff --git a/sys/dev/usb/usb_quirks.h b/sys/dev/usb/usb_quirks.h deleted file mode 100644 index 07935d58143f6..0000000000000 --- a/sys/dev/usb/usb_quirks.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: usb_quirks.h,v 1.5 1998/12/29 15:23:59 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -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_NO_STRINGS 0x08 /* string descriptors are broken. */ -#define UQ_BAD_ADC 0x10 /* bad audio spec version number. */ -}; - -extern struct usbd_quirks usbd_no_quirk; - -struct usbd_quirks *usbd_find_quirk __P((usb_device_descriptor_t *)); diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c deleted file mode 100644 index d903c07951642..0000000000000 --- a/sys/dev/usb/usb_subr.c +++ /dev/null @@ -1,1127 +0,0 @@ -/* $NetBSD: usb_subr.c,v 1.27 1999/01/08 11:58:25 augustss Exp $ */ -/* FreeBSD $Id: usb_subr.c,v 1.6 1999/01/07 23:31:40 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#elif defined(__FreeBSD__) -#include <sys/module.h> -#include <sys/bus.h> -#endif -#include <sys/proc.h> -#include <sys/select.h> - -#include <dev/usb/usb.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usbdevs.h> -#include <dev/usb/usb_quirks.h> - -#if defined(__FreeBSD__) -#include <machine/clock.h> -#define delay(d) DELAY(d) -#endif - -#ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -extern int usbdebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -static usbd_status usbd_set_config __P((usbd_device_handle, int)); -char *usbd_get_string __P((usbd_device_handle, int, char *)); -int usbd_getnewaddr __P((usbd_bus_handle bus)); -#if defined(__NetBSD__) -int usbd_print __P((void *aux, const char *pnp)); -int usbd_submatch __P((bdevice *, struct cfdata *cf, void *)); -#endif -void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno)); -void usbd_kill_pipe __P((usbd_pipe_handle)); -usbd_status usbd_probe_and_attach - __P((bdevice *parent, usbd_device_handle dev, int port, int addr)); - - -#ifdef USBVERBOSE -typedef u_int16_t usb_vendor_id_t; -typedef u_int16_t usb_product_id_t; - -/* - * Descriptions of of known vendors and devices ("products"). - */ -struct usb_knowndev { - usb_vendor_id_t vendor; - usb_product_id_t product; - int flags; - char *vendorname, *productname; -}; -#define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */ - -#include <dev/usb/usbdevs_data.h> -#endif /* USBVERBOSE */ - -#ifdef USB_DEBUG -char *usbd_error_strs[] = { - "NORMAL_COMPLETION", - "IN_PROGRESS", - "PENDING_REQUESTS", - "NOT_STARTED", - "INVAL", - "IS_IDLE", - "NOMEM", - "CANCELLED", - "BAD_ADDRESS", - "IN_USE", - "INTERFACE_NOT_ACTIVE", - "NO_ADDR", - "SET_ADDR_FAILED", - "NO_POWER", - "TOO_DEEP", - "IOERROR", - "NOT_CONFIGURED", - "TIMEOUT", - "SHORT_XFER", - "STALLED", - "XXX", -}; -#endif - -usbd_status -usbd_get_string_desc(dev, sindex, langid, sdesc) - usbd_device_handle dev; - int sindex; - int langid; - usb_string_descriptor_t *sdesc; -{ - usb_device_request_t req; - usbd_status r; - - req.bmRequestType = UT_READ_DEVICE; - req.bRequest = UR_GET_DESCRIPTOR; - USETW2(req.wValue, UDESC_STRING, sindex); - USETW(req.wIndex, langid); - USETW(req.wLength, 1); /* only size byte first */ - r = usbd_do_request(dev, &req, sdesc); - if (r != USBD_NORMAL_COMPLETION) - return (r); - USETW(req.wLength, sdesc->bLength); /* the whole string */ - return (usbd_do_request(dev, &req, sdesc)); -} - -char * -usbd_get_string(dev, si, buf) - usbd_device_handle dev; - int si; - char *buf; -{ - int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; - usb_string_descriptor_t us; - char *s; - int i, n; - u_int16_t c; - usbd_status r; - - if (si == 0) - return (0); - if (dev->quirks->uq_flags & UQ_NO_STRINGS) - return (0); - if (dev->langid == USBD_NOLANG) { - /* Set up default language */ - r = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us); - if (r != USBD_NORMAL_COMPLETION || us.bLength < 4) { - dev->langid = 0; /* Well, just pick English then */ - } else { - /* Pick the first language as the default. */ - dev->langid = UGETW(us.bString[0]); - } - } - r = usbd_get_string_desc(dev, si, dev->langid, &us); - if (r != USBD_NORMAL_COMPLETION) - return (0); - s = buf; - n = us.bLength / 2 - 1; - for (i = 0; i < n; i++) { - c = UGETW(us.bString[i]); - /* Convert from Unicode, handle buggy strings. */ - if ((c & 0xff00) == 0) - *s++ = c; - else if ((c & 0x00ff) == 0 && swap) - *s++ = c >> 8; - else - *s++ = '?'; - } - *s++ = 0; - return buf; -} - -void -usbd_devinfo_vp(dev, v, p) - usbd_device_handle dev; - char *v, *p; -{ - usb_device_descriptor_t *udd = &dev->ddesc; - char *vendor = 0, *product = 0; -#ifdef USBVERBOSE - struct usb_knowndev *kdp; -#endif - - vendor = usbd_get_string(dev, udd->iManufacturer, v); - product = usbd_get_string(dev, udd->iProduct, p); -#ifdef USBVERBOSE - if (!vendor) { - for(kdp = usb_knowndevs; - kdp->vendorname != NULL; - kdp++) { - if (kdp->vendor == UGETW(udd->idVendor) && - (kdp->product == UGETW(udd->idProduct) || - (kdp->flags & USB_KNOWNDEV_NOPROD) != 0)) - break; - } - if (kdp->vendorname == NULL) - vendor = product = NULL; - else { - vendor = kdp->vendorname; - product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ? - kdp->productname : NULL; - } - } -#endif - if (vendor) - strcpy(v, vendor); - else - sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor)); - if (product) - strcpy(p, product); - else - sprintf(p, "product 0x%04x", UGETW(udd->idProduct)); -} - -int -usbd_printBCD(cp, bcd) - char *cp; - int bcd; -{ - return (sprintf(cp, "%x.%02x", bcd >> 8, bcd & 0xff)); -} - -void -usbd_devinfo(dev, showclass, cp) - usbd_device_handle dev; - int showclass; - char *cp; -{ - usb_device_descriptor_t *udd = &dev->ddesc; - char vendor[USB_MAX_STRING_LEN]; - char product[USB_MAX_STRING_LEN]; - int bcdDevice, bcdUSB; - - usbd_devinfo_vp(dev, vendor, product); - cp += sprintf(cp, "%s %s", vendor, product); - if (showclass) - cp += sprintf(cp, ", class %d/%d", - udd->bDeviceClass, udd->bDeviceSubClass); - bcdUSB = UGETW(udd->bcdUSB); - bcdDevice = UGETW(udd->bcdDevice); - cp += sprintf(cp, ", rev "); - cp += usbd_printBCD(cp, bcdUSB); - *cp++ = '/'; - cp += usbd_printBCD(cp, bcdDevice); - cp += sprintf(cp, ", addr %d", dev->address); - *cp = 0; -} - -/* Delay for a certain number of ms */ -void -usb_delay_ms(bus, ms) - usbd_bus_handle bus; - u_int ms; -{ - /* Wait at least two clock ticks so we know the time has passed. */ - if (bus->use_polling) - delay((ms+1) * 1000); - else - tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1); -} - -/* Delay given a device handle. */ -void -usbd_delay_ms(dev, ms) - usbd_device_handle dev; - u_int ms; -{ - usb_delay_ms(dev->bus, ms); -} - -usbd_status -usbd_reset_port(dev, port, ps) - usbd_device_handle dev; - int port; - usb_port_status_t *ps; -{ - usb_device_request_t req; - usbd_status r; - int n; - - req.bmRequestType = UT_WRITE_CLASS_OTHER; - req.bRequest = UR_SET_FEATURE; - USETW(req.wValue, UHF_PORT_RESET); - USETW(req.wIndex, port); - USETW(req.wLength, 0); - r = usbd_do_request(dev, &req, 0); - DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%d(%s)\n", - port, r, usbd_error_strs[r])); - if (r != USBD_NORMAL_COMPLETION) - return (r); - n = 10; - do { - /* Wait for device to recover from reset. */ - usbd_delay_ms(dev, USB_PORT_RESET_DELAY); - r = usbd_get_port_status(dev, port, ps); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("usbd_reset_port: get status failed %d\n",r)); - return (r); - } - } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0); - if (n == 0) { - printf("usbd_reset_port: timeout\n"); - return (USBD_IOERROR); - } - r = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET); -#ifdef USB_DEBUG - if (r != USBD_NORMAL_COMPLETION) - DPRINTF(("usbd_reset_port: clear port feature failed %d\n",r)); -#endif - - /* Wait for the device to recover from reset. */ - usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY); - return (r); -} - -usb_interface_descriptor_t * -usbd_find_idesc(cd, ifaceidx, altidx) - usb_config_descriptor_t *cd; - int ifaceidx; - int altidx; -{ - char *p = (char *)cd; - char *end = p + UGETW(cd->wTotalLength); - usb_interface_descriptor_t *d; - int curidx, lastidx, curaidx = 0; - - for (curidx = lastidx = -1; p < end; ) { - d = (usb_interface_descriptor_t *)p; - DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d " - "type=%d\n", - ifaceidx, curidx, altidx, curaidx, - d->bLength, d->bDescriptorType)); - if (d->bLength == 0) /* bad descriptor */ - break; - p += d->bLength; - if (p <= end && d->bDescriptorType == UDESC_INTERFACE) { - if (d->bInterfaceNumber != lastidx) { - lastidx = d->bInterfaceNumber; - curidx++; - curaidx = 0; - } else - curaidx++; - if (ifaceidx == curidx && altidx == curaidx) - return (d); - } - } - return (0); -} - -usb_endpoint_descriptor_t * -usbd_find_edesc(cd, ifaceidx, altidx, endptidx) - usb_config_descriptor_t *cd; - int ifaceidx; - int altidx; - int endptidx; -{ - char *p = (char *)cd; - char *end = p + UGETW(cd->wTotalLength); - usb_interface_descriptor_t *d; - usb_endpoint_descriptor_t *e; - int curidx; - - d = usbd_find_idesc(cd, ifaceidx, altidx); - if (!d) - return (0); - if (endptidx >= d->bNumEndpoints) /* quick exit */ - return (0); - - curidx = -1; - for (p = (char *)d + d->bLength; p < end; ) { - e = (usb_endpoint_descriptor_t *)p; - if (e->bLength == 0) /* bad descriptor */ - break; - p += e->bLength; - if (p <= end && e->bDescriptorType == UDESC_INTERFACE) - return (0); - if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) { - curidx++; - if (curidx == endptidx) - return (e); - } - } - return (0); -} - -usbd_status -usbd_fill_iface_data(dev, ifaceidx, altidx) - usbd_device_handle dev; - int ifaceidx; - int altidx; -{ - usbd_interface_handle ifc = &dev->ifaces[ifaceidx]; - char *p, *end; - int endpt, nendpt; - - DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n", - ifaceidx, altidx)); - ifc->device = dev; - ifc->idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx); - if (ifc->idesc == 0) - return (USBD_INVAL); - ifc->index = ifaceidx; - ifc->altindex = altidx; - nendpt = ifc->idesc->bNumEndpoints; - DPRINTFN(10,("usbd_fill_iface_data: found idesc n=%d\n", nendpt)); - if (nendpt != 0) { - ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint), - M_USB, M_NOWAIT); - if (ifc->endpoints == 0) - return (USBD_NOMEM); - } else - ifc->endpoints = 0; - ifc->priv = 0; - p = (char *)ifc->idesc + ifc->idesc->bLength; - end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength); -#define ed ((usb_endpoint_descriptor_t *)p) - for (endpt = 0; endpt < nendpt; endpt++) { - DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt)); - for (; p < end; p += ed->bLength) { - ed = (usb_endpoint_descriptor_t *)p; - DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p " - "len=%d type=%d\n", - p, end, ed->bLength, ed->bDescriptorType)); - if (p + ed->bLength <= end && ed->bLength != 0 && - ed->bDescriptorType == UDESC_ENDPOINT) - goto found; - if (ed->bDescriptorType == UDESC_INTERFACE || - ed->bLength == 0) - break; - } - /* passed end, or bad desc */ - goto bad; - found: - ifc->endpoints[endpt].edesc = ed; - ifc->endpoints[endpt].state = USBD_ENDPOINT_ACTIVE; - ifc->endpoints[endpt].refcnt = 0; - ifc->endpoints[endpt].toggle = 0; - p += ed->bLength; - } -#undef ed - LIST_INIT(&ifc->pipes); - ifc->state = USBD_INTERFACE_ACTIVE; - return (USBD_NORMAL_COMPLETION); - - bad: - free(ifc->endpoints, M_USB); - return (USBD_INVAL); -} - -void -usbd_free_iface_data(dev, ifcno) - usbd_device_handle dev; - int ifcno; -{ - usbd_interface_handle ifc = &dev->ifaces[ifcno]; - if (ifc->endpoints) - free(ifc->endpoints, M_USB); -} - -static usbd_status -usbd_set_config(dev, conf) - usbd_device_handle dev; - int conf; -{ - usb_device_request_t req; - - req.bmRequestType = UT_WRITE_DEVICE; - req.bRequest = UR_SET_CONFIG; - USETW(req.wValue, conf); - USETW(req.wIndex, 0); - USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); -} - -usbd_status -usbd_set_config_no(dev, no, msg) - usbd_device_handle dev; - int no; - int msg; -{ - int index; - usb_config_descriptor_t cd; - usbd_status r; - - DPRINTFN(5,("usbd_set_config_no: %d\n", no)); - /* Figure out what config index to use. */ - for (index = 0; index < dev->ddesc.bNumConfigurations; index++) { - r = usbd_get_config_desc(dev, index, &cd); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (cd.bConfigurationValue == no) - return (usbd_set_config_index(dev, index, msg)); - } - return (USBD_INVAL); -} - -usbd_status -usbd_set_config_index(dev, index, msg) - usbd_device_handle dev; - int index; - int msg; -{ - usb_status_t ds; - usb_hub_status_t hs; - usb_config_descriptor_t cd, *cdp; - usbd_status r; - int ifcidx, nifc, len, selfpowered, power; - - DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index)); - - /* XXX check that all interfaces are idle */ - if (dev->config != 0) { - DPRINTF(("usbd_set_config_index: free old config\n")); - /* Free all configuration data structures. */ - nifc = dev->cdesc->bNumInterface; - for (ifcidx = 0; ifcidx < nifc; ifcidx++) - usbd_free_iface_data(dev, ifcidx); - free(dev->ifaces, M_USB); - free(dev->cdesc, M_USB); - dev->ifaces = 0; - dev->cdesc = 0; - dev->config = 0; - dev->state = USBD_DEVICE_ADDRESSED; - } - - /* Figure out what config number to use. */ - r = usbd_get_config_desc(dev, index, &cd); - if (r != USBD_NORMAL_COMPLETION) - return (r); - len = UGETW(cd.wTotalLength); - cdp = malloc(len, M_USB, M_NOWAIT); - if (cdp == 0) - return (USBD_NOMEM); - r = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp); - if (r != USBD_NORMAL_COMPLETION) - goto bad; - if (cdp->bDescriptorType != UDESC_CONFIG) { - DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n", - cdp->bDescriptorType)); - r = USBD_INVAL; - goto bad; - } - selfpowered = 0; - if (cdp->bmAttributes & UC_SELF_POWERED) { - /* May be self powered. */ - if (cdp->bmAttributes & UC_BUS_POWERED) { - /* Must ask device. */ - if (dev->quirks->uq_flags & UQ_HUB_POWER) { - /* Buggy hub, use hub descriptor. */ - r = usbd_get_hub_status(dev, &hs); - if (r == USBD_NORMAL_COMPLETION && - !(UGETW(hs.wHubStatus) & UHS_LOCAL_POWER)) - selfpowered = 1; - } else { - r = usbd_get_device_status(dev, &ds); - if (r == USBD_NORMAL_COMPLETION && - (UGETW(ds.wStatus) & UDS_SELF_POWERED)) - selfpowered = 1; - } - DPRINTF(("usbd_set_config_index: status=0x%04x, " - "error=%d(%s)\n", - UGETW(ds.wStatus), r, usbd_error_strs[r])); - } else - selfpowered = 1; - } - DPRINTF(("usbd_set_config_index: (addr %d) attr=0x%02x, " - "selfpowered=%d, power=%d, powerquirk=%x\n", - dev->address, cdp->bmAttributes, - selfpowered, cdp->bMaxPower * 2, - dev->quirks->uq_flags & UQ_HUB_POWER)); -#ifdef USB_DEBUG - if (!dev->powersrc) { - printf("usbd_set_config_index: No power source?\n"); - return (USBD_IOERROR); - } -#endif - power = cdp->bMaxPower * 2; - if (power > dev->powersrc->power) { - /* XXX print nicer message. */ - if (msg) - printf("%s: device addr %d (config %d) exceeds power " - "budget, %d mA > %d mA\n", - USBDEVNAME(dev->bus->bdev), dev->address, - cdp->bConfigurationValue, - power, dev->powersrc->power); - r = USBD_NO_POWER; - goto bad; - } - dev->power = power; - dev->self_powered = selfpowered; - - DPRINTF(("usbd_set_config_index: set config %d\n", - cdp->bConfigurationValue)); - r = usbd_set_config(dev, cdp->bConfigurationValue); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("usbd_set_config_index: setting config=%d failed, " - "error=%d(%s)\n", - cdp->bConfigurationValue, r, usbd_error_strs[r])); - goto bad; - } - DPRINTF(("usbd_set_config_index: setting new config %d\n", - cdp->bConfigurationValue)); - nifc = cdp->bNumInterface; - dev->ifaces = malloc(nifc * sizeof(struct usbd_interface), - M_USB, M_NOWAIT); - if (dev->ifaces == 0) { - r = USBD_NOMEM; - goto bad; - } - DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp)); - dev->cdesc = cdp; - dev->config = cdp->bConfigurationValue; - dev->state = USBD_DEVICE_CONFIGURED; - for (ifcidx = 0; ifcidx < nifc; ifcidx++) { - r = usbd_fill_iface_data(dev, ifcidx, 0); - if (r != USBD_NORMAL_COMPLETION) { - while (--ifcidx >= 0) - usbd_free_iface_data(dev, ifcidx); - goto bad; - } - } - - return (USBD_NORMAL_COMPLETION); - - bad: - free(cdp, M_USB); - return (r); -} - -/* XXX add function for alternate settings */ - -usbd_status -usbd_setup_pipe(dev, iface, ep, pipe) - usbd_device_handle dev; - usbd_interface_handle iface; - struct usbd_endpoint *ep; - usbd_pipe_handle *pipe; -{ - usbd_pipe_handle p; - usbd_status r; - - DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n", - dev, iface, ep, pipe)); - p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT); - if (p == 0) - return (USBD_NOMEM); - p->device = dev; - p->iface = iface; - p->state = USBD_PIPE_ACTIVE; - p->endpoint = ep; - ep->refcnt++; - p->refcnt = 1; - p->intrreqh = 0; - p->running = 0; - SIMPLEQ_INIT(&p->queue); - r = dev->bus->open_pipe(p); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error=%d" - "(%s)\n", - ep->edesc->bEndpointAddress, r, usbd_error_strs[r])); - free(p, M_USB); - return (r); - } - *pipe = p; - return (USBD_NORMAL_COMPLETION); -} - -/* Abort the device control pipe. */ -void -usbd_kill_pipe(pipe) - usbd_pipe_handle pipe; -{ - pipe->methods->close(pipe); - pipe->endpoint->refcnt--; - free(pipe, M_USB); -} - -int -usbd_getnewaddr(bus) - usbd_bus_handle bus; -{ - int addr; - - for (addr = 1; addr < USB_MAX_DEVICES; addr++) - if (bus->devices[addr] == 0) - return (addr); - return (-1); -} - - -usbd_status -usbd_probe_and_attach(parent, dev, port, addr) - bdevice *parent; - usbd_device_handle dev; - int port; - int addr; -{ - struct usb_attach_arg uaa; - usb_device_descriptor_t *dd = &dev->ddesc; - int r, found, i, confi, nifaces; - usbd_interface_handle ifaces[256]; /* 256 is the absolute max */ - -#if defined(__FreeBSD__) -/* XXX uaa is a static var. Not a problem as it _should_ be used only - * during probe and attach. Should be changed however - */ - bdevice bdev; - bdev = device_add_child(*parent, NULL, -1, &uaa); - if (!bdev) { - printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev)); - return (USBD_INVAL); - } -#endif - - uaa.device = dev; - uaa.iface = 0; - uaa.ifaces = 0; - uaa.nifaces = 0; - uaa.usegeneric = 0; - uaa.port = port; - uaa.configno = UHUB_UNK_CONFIGURATION; - uaa.ifaceno = UHUB_UNK_INTERFACE; - - /* First try with device specific drivers. */ - if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch)) - return (USBD_NORMAL_COMPLETION); - - DPRINTF(("usbd_probe_and_attach: no device specific driver found\n")); - - /* Next try with interface drivers. */ - for (confi = 0; confi < dd->bNumConfigurations; confi++) { - DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n", - confi)); - r = usbd_set_config_index(dev, confi, 1); - if (r != USBD_NORMAL_COMPLETION) { -#ifdef USB_DEBUG - DPRINTF(("%s: port %d, set config at addr %d failed, " - "error=%d(%s)\n", USBDEVNAME(*parent), port, - addr, r, usbd_error_strs[r])); -#else - printf("%s: port %d, set config at addr %d failed\n", - USBDEVNAME(*parent), port, addr); -#endif -#if defined(__FreeBSD__) - device_delete_child(*parent, bdev); -#endif - return (r); - } - nifaces = dev->cdesc->bNumInterface; - uaa.configno = dev->cdesc->bConfigurationValue; - for (i = 0; i < nifaces; i++) - ifaces[i] = &dev->ifaces[i]; - uaa.ifaces = ifaces; - uaa.nifaces = nifaces; - for (found = i = 0; i < nifaces; i++) { - if (!ifaces[i]) - continue; /* interface already claimed */ - uaa.iface = ifaces[i]; - uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; - if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, - usbd_submatch)) { - found++; - ifaces[i] = 0; /* consumed */ - } - } - if (found != 0) - return (USBD_NORMAL_COMPLETION); - } - /* No interfaces were attached in any of the configurations. */ - if (dd->bNumConfigurations > 1)/* don't change if only 1 config */ - usbd_set_config_index(dev, 0, 0); - - DPRINTF(("usbd_probe_and_attach: no interface drivers found\n")); - - /* Finally try the generic driver. */ - uaa.iface = 0; - uaa.usegeneric = 1; - uaa.configno = UHUB_UNK_CONFIGURATION; - uaa.ifaceno = UHUB_UNK_INTERFACE; - if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch)) - return (USBD_NORMAL_COMPLETION); - - /* - * The generic attach failed, but leave the device as it is. - * We just did not find any drivers, that's all. The device is - * fully operational and not harming anyone. - */ - DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); -#if defined(__FreeBSD__) -/* - * XXX should we delete the child again? Left for now to avoid dangling - * references. - device_delete_child(*parent, bdev); -*/ -#endif - return (USBD_NORMAL_COMPLETION); -} - - - -/* - * Called when a new device has been put in the powered state, - * but not yet in the addressed state. - * Get initial descriptor, set the address, get full descriptor, - * and attach a driver. - */ -usbd_status -usbd_new_device(parent, bus, depth, lowspeed, port, up) - bdevice *parent; - usbd_bus_handle bus; - int depth; - int lowspeed; - int port; - struct usbd_port *up; -{ - usbd_device_handle dev; - usb_device_descriptor_t *dd; - usbd_status r; - int addr; - int i; - - DPRINTF(("usbd_new_device bus=%p depth=%d lowspeed=%d\n", - bus, depth, lowspeed)); - addr = usbd_getnewaddr(bus); - if (addr < 0) { - printf("%s: No free USB addresses, new device ignored.\n", - USBDEVNAME(bus->bdev)); - return (USBD_NO_ADDR); - } - - dev = malloc(sizeof *dev, M_USB, M_NOWAIT); - if (dev == 0) - return (USBD_NOMEM); - memset(dev, 0, sizeof(*dev)); - - dev->bus = bus; - - /* Set up default endpoint handle. */ - dev->def_ep.edesc = &dev->def_ep_desc; - dev->def_ep.state = USBD_ENDPOINT_ACTIVE; - - /* Set up default endpoint descriptor. */ - dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; - dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT; - dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; - dev->def_ep_desc.bmAttributes = UE_CONTROL; - USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET); - dev->def_ep_desc.bInterval = 0; - - dev->state = USBD_DEVICE_DEFAULT; - dev->quirks = &usbd_no_quirk; - dev->address = USB_START_ADDR; - dev->ddesc.bMaxPacketSize = 0; - dev->lowspeed = lowspeed != 0; - dev->depth = depth; - dev->powersrc = up; - dev->langid = USBD_NOLANG; - - /* Establish the the default pipe. */ - r = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe); - if (r != USBD_NORMAL_COMPLETION) { - usbd_remove_device(dev, up); - return (r); - } - - up->device = dev; - dd = &dev->ddesc; - /* Try a few times in case the device is slow (i.e. outside specs.) */ - for (i = 0; i < 5; i++) { - /* Get the first 8 bytes of the device descriptor. */ - r = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd); - if (r == USBD_NORMAL_COMPLETION) - break; - usbd_delay_ms(dev, 200); - } - if (r != USBD_NORMAL_COMPLETION) { - DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc " - "failed\n", - addr)); - usbd_remove_device(dev, up); - return (r); - } - - if (dd->bDescriptorType != UDESC_DEVICE) { - /* Illegal device descriptor */ - DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n", - dd->bDescriptorType)); - usbd_remove_device(dev, up); - return (USBD_INVAL); - } - - DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, " - "subclass=%d, protocol=%d, maxpacket=%d, ls=%d\n", - addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass, - dd->bDeviceProtocol, dd->bMaxPacketSize, dev->lowspeed)); - - USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); - - /* Get the full device descriptor. */ - r = usbd_get_device_desc(dev, dd); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc " - "failed\n", addr)); - usbd_remove_device(dev, up); - return (r); - } - - /* Figure out what's wrong with this device. */ - dev->quirks = usbd_find_quirk(dd); - - /* Set the address */ - r = usbd_set_address(dev, addr); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr)); - r = USBD_SET_ADDR_FAILED; - usbd_remove_device(dev, up); - return (r); - } - /* Allow device time to set new address */ - usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); - - dev->address = addr; /* New device address now */ - dev->state = USBD_DEVICE_ADDRESSED; - bus->devices[addr] = dev; - - /* Assume 100mA bus powered for now. Changed when configured. */ - dev->power = USB_MIN_POWER; - dev->self_powered = 0; - - DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n", - addr, dev, parent)); - - r = usbd_probe_and_attach(parent, dev, port, addr); - if (r != USBD_NORMAL_COMPLETION) { - usbd_remove_device(dev, up); - return (r); - } - - return (USBD_NORMAL_COMPLETION); -} - -void -usbd_remove_device(dev, up) - usbd_device_handle dev; - struct usbd_port *up; -{ - DPRINTF(("usbd_remove_device: %p\n", dev)); - - if (dev->default_pipe) - usbd_kill_pipe(dev->default_pipe); - up->device = 0; - dev->bus->devices[dev->address] = 0; - - free(dev, M_USB); -} - -#if defined(__NetBSD__) -int -usbd_print(aux, pnp) - void *aux; - const char *pnp; -{ - struct usb_attach_arg *uaa = aux; - char devinfo[1024]; - - DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device)); - if (pnp) { - if (!uaa->usegeneric) - return (QUIET); - usbd_devinfo(uaa->device, 1, devinfo); - printf("%s, %s", devinfo, pnp); - } - if (uaa->port != 0) - printf(" port %d", uaa->port); - if (uaa->configno != UHUB_UNK_CONFIGURATION) - printf(" configuration %d", uaa->configno); - if (uaa->ifaceno != UHUB_UNK_INTERFACE) - printf(" interface %d", uaa->ifaceno); - return (UNCONF); -} - -int -usbd_submatch(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct usb_attach_arg *uaa = aux; - - if ((uaa->port != 0 && - cf->uhubcf_port != UHUB_UNK_PORT && - cf->uhubcf_port != uaa->port) || - (uaa->configno != UHUB_UNK_CONFIGURATION && - cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION && - cf->uhubcf_configuration != uaa->configno) || - (uaa->ifaceno != UHUB_UNK_INTERFACE && - cf->uhubcf_interface != UHUB_UNK_INTERFACE && - cf->uhubcf_interface != uaa->ifaceno)) - return 0; - return ((*cf->cf_attach->ca_match)(parent, cf, aux)); -} -#endif - -usbd_status -usb_insert_transfer(reqh) - usbd_request_handle reqh; -{ - usbd_pipe_handle pipe = reqh->pipe; - usbd_interface_handle iface = pipe->iface; - - if (pipe->state == USBD_PIPE_IDLE || - (iface && iface->state == USBD_INTERFACE_IDLE)) - return (USBD_IS_IDLE); - SIMPLEQ_INSERT_TAIL(&pipe->queue, reqh, next); - if (pipe->state != USBD_PIPE_ACTIVE || - (iface && iface->state != USBD_INTERFACE_ACTIVE)) - return (USBD_NOT_STARTED); - if (pipe->running) - return (USBD_IN_PROGRESS); - pipe->running = 1; - return (USBD_NORMAL_COMPLETION); -} - -void -usb_start_next(pipe) - usbd_pipe_handle pipe; -{ - usbd_request_handle reqh; - usbd_status r; - -#ifdef DIAGNOSTIC - if (SIMPLEQ_FIRST(&pipe->queue) == 0) { - printf("usb_start_next: empty\n"); - return; - } -#endif - - /* First remove remove old */ - SIMPLEQ_REMOVE_HEAD(&pipe->queue, SIMPLEQ_FIRST(&pipe->queue), next); - if (pipe->state != USBD_PIPE_ACTIVE) { - pipe->running = 0; - return; - } - reqh = SIMPLEQ_FIRST(&pipe->queue); - DPRINTFN(5, ("usb_start_next: start reqh=%p\n", reqh)); - if (!reqh) - pipe->running = 0; - else { - r = pipe->methods->start(reqh); - if (r != USBD_IN_PROGRESS) { - printf("usb_start_next: error=%d\n", r); - pipe->running = 0; - /* XXX do what? */ - } - } -} - -void -usbd_fill_deviceinfo(dev, di) - usbd_device_handle dev; - struct usb_device_info *di; -{ - struct usbd_port *p; - int i, r, s; - - di->config = dev->config; - usbd_devinfo_vp(dev, di->vendor, di->product); - usbd_printBCD(di->revision, UGETW(dev->ddesc.bcdDevice)); - di->vendorNo = UGETW(dev->ddesc.idVendor); - di->productNo = UGETW(dev->ddesc.idProduct); - di->class = dev->ddesc.bDeviceClass; - di->power = dev->self_powered ? 0 : dev->power; - di->lowspeed = dev->lowspeed; - di->addr = dev->address; - if (dev->hub) { - for (i = 0; - i < sizeof(di->ports) / sizeof(di->ports[0]) && - i < dev->hub->hubdesc.bNbrPorts; - i++) { - p = &dev->hub->ports[i]; - if (p->device) - r = p->device->address; - else { - s = UGETW(p->status.wPortStatus); - if (s & UPS_PORT_ENABLED) - r = USB_PORT_ENABLED; - else if (s & UPS_SUSPEND) - r = USB_PORT_SUSPENDED; - else if (s & UPS_PORT_POWER) - r = USB_PORT_POWERED; - else - r = USB_PORT_DISABLED; - } - di->ports[i] = r; - } - di->nports = dev->hub->hubdesc.bNbrPorts; - } else - di->nports = 0; -} diff --git a/sys/dev/usb/usbcdc.h b/sys/dev/usb/usbcdc.h deleted file mode 100644 index 3d3eb818f1b2e..0000000000000 --- a/sys/dev/usb/usbcdc.h +++ /dev/null @@ -1,141 +0,0 @@ -/* $NetBSD: usbcdc.h,v 1.3 1999/01/03 01:09:18 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _USBCDC_H_ -#define _USBCDC_H_ - -#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; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uWord bcdCDC; -} usb_cdc_header_descriptor_t; - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bmCapabilities; -#define USB_CDC_CM_DOES_CM 0x01 -#define USB_CDC_CM_CM_OVER_DATA 0x02 - uByte bDataInterface; -} usb_cdc_cm_descriptor_t; - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bmCapabilities; -#define USB_CDC_ACM_HAS_FEATURE 0x01 -#define USB_CDC_ACM_HAS_LINE 0x02 -#define USB_CDC_ACM_HAS_BREAK 0x04 -#define USB_CDC_ACM_HAS_NETWORK_CONN 0x08 -} usb_cdc_acm_descriptor_t; - -typedef struct { - uByte bLength; - uByte bDescriptorType; - uByte bDescriptorSubtype; - uByte bMasterInterface; - uByte bSlaveInterface[1]; -} usb_cdc_union_descriptor_t; - -#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 -#define UCDC_GET_ENCAPSULATED_RESPONSE 0x01 -#define UCDC_SET_COMM_FEATURE 0x02 -#define UCDC_GET_COMM_FEATURE 0x03 -#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 - -typedef struct { - uWord wState; -#define UCDC_IDLE_SETTING 0x0001 -#define UCDC_DATA_MULTIPLEXED 0x0002 -} usb_cdc_abstract_state_t; - -typedef struct { - uDWord dwDTERate; - uByte bCharFormat; -#define UCDC_STOP_BIT_1 0 -#define UCDC_STOP_BIT_1_5 1 -#define UCDC_STOP_BIT_2 2 - uByte bParityType; -#define UCDC_PARITY_NONE 0 -#define UCDC_PARITY_ODD 1 -#define UCDC_PARITY_EVEN 2 -#define UCDC_PARITY_MARK 3 -#define UCDC_PARITY_SPACE 4 - uByte bDataBits; -} usb_cdc_line_state_t; - -typedef struct { - uByte bmRequestType; -#define UCDC_NOTIFICATION 0xa1 - uByte bNotification; -#define UCDC_N_NETWORK_CONNECTION 0x00 -#define UCDC_N_RESPONSE_AVAILABLE 0x01 -#define UCDC_N_AUX_JACK_HOOK_STATE 0x08 -#define UCDC_N_RING_DETECT 0x09 -#define UCDC_N_SERIAL_STATE 0x20 -#define UCDC_N_CALL_STATE_CHANGED 0x28 -#define UCDC_N_LINE_STATE_CHANGED 0x29 -#define UCDC_N_CONNECTION_SPEED_CHANGE 0x2a - uWord wValue; - uWord wIndex; - uWord wLength; - uByte data[16]; -} usb_cdc_notification_t; -#define UCDC_NOTIFICATION_LENGTH 8 - -#endif /* _USBCDC_H_ */ diff --git a/sys/dev/usb/usbdevs.h b/sys/dev/usb/usbdevs.h deleted file mode 100644 index 24398066a8c92..0000000000000 --- a/sys/dev/usb/usbdevs.h +++ /dev/null @@ -1,176 +0,0 @@ -/* $FreeBSD$ */ - -/* - * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. - * - * generated from: - * NetBSD: usbdevs,v 1.19 1999/01/08 11:18:38 augustss Exp - */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * List of known USB vendors - */ - -#define USB_VENDOR_NEC 0x0409 /* NEC */ -#define USB_VENDOR_KODAK 0x040a /* Eastman Kodak */ -/* Computer Access Technology Corporation */ -#define USB_VENDOR_CATC 0x0423 /* CATC */ -#define USB_VENDOR_NANAO 0x0440 /* Nanao */ -#define USB_VENDOR_UNIXTAR 0x0451 /* Unixtar */ -#define USB_VENDOR_GENIUS 0x0458 /* Genius */ -#define USB_VENDOR_MICROSOFT 0x045e /* Microsoft */ -#define USB_VENDOR_KENSINGTON 0x0461 /* Kensington */ -#define USB_VENDOR_CHERRY 0x046a /* Cherry */ -/* Behavior Technology Corporation */ -#define USB_VENDOR_BTC 0x046e /* BTC */ -#define USB_VENDOR_PHILIPS 0x0471 /* Philips */ -#define USB_VENDOR_CONNECTIX 0x0478 /* Connectix */ -#define USB_VENDOR_ACER 0x04a5 /* Acer Peripherals */ -#define USB_VENDOR_CYPRESS 0x04b4 /* Cypress Semiconductor */ -#define USB_VENDOR_3COM 0x04c1 /* 3Com */ -#define USB_VENDOR_SHUTTLE 0x04e6 /* Shuttle Technology */ -#define USB_VENDOR_JAZZ 0x04fa /* Jazz */ -#define USB_VENDOR_ATEN 0x0557 /* ATen */ -#define USB_VENDOR_PERACOM 0x0565 /* Peracom */ -#define USB_VENDOR_EIZO 0x056d /* EIZO */ -#define USB_VENDOR_AGILER 0x056e /* Agiler */ -#define USB_VENDOR_BELKIN 0x05ab /* Belkin */ -#define USB_VENDOR_LOGITECH 0x05ac /* Logitech */ -#define USB_VENDOR_EIZONANAO 0x05e7 /* EIZO Nanao */ -#define USB_VENDOR_CHIC 0x05fe /* Chic Technology */ -#define USB_VENDOR_ADS 0x06e1 /* ADS Technologies */ -#define USB_VENDOR_PLX 0x10b5 /* PLX */ -#define USB_VENDOR_ENTREGA 0x1645 /* Entrega */ -#define USB_VENDOR_INSIDEOUT 0x1608 /* Inside Out Networks */ -#define USB_VENDOR_INTEL 0x8086 /* Intel */ - -/* - * List of known products. Grouped by vendor. - */ - -/* NEC products */ -#define USB_PRODUCT_NEC_HUB 0x55aa /* hub */ -#define USB_PRODUCT_NEC_HUB_B 0x55ab /* hub */ - -/* Kodak products */ -#define USB_PRODUCT_KODAK_DC260 0x0110 /* Digital Science DC260 */ - -/* CATC products */ -#define USB_PRODUCT_CATC_ANDROMEDA 0x1237 /* Andromeda hub */ - -/* Unixtar products */ -#define USB_PRODUCT_UNIXTAR_UTUSB41 0x1446 /* UT-USB41 hub */ - -/* Genius products */ -#define USB_PRODUCT_GENIUS_NICHE 0x0001 /* Niche mouse */ -#define USB_PRODUCT_GENIUS_FLIGHT2000 0x1004 /* Flight 2000 joystick */ - -/* Microsoft products */ -#define USB_PRODUCT_MICROSOFT_INTELLIMOUSE 0x0009 /* IntelliMouse */ - -/* Kensington products */ -#define USB_PRODUCT_KENSINGTON_MOUSEINABOX 0x4d02 /* Mouse-in-a-Box */ - -/* Cherry products */ -#define USB_PRODUCT_CHERRY_MY3000KBD 0x0001 /* My3000 keyboard */ -#define USB_PRODUCT_CHERRY_MY3000HUB 0x0003 /* My3000 hub */ - -/* Behavior Technology Corporation products */ -#define USB_PRODUCT_BTC_BTC7932 0x6782 /* Keyboard with mouse port */ - -/* Philips products */ -#define USB_PRODUCT_PHILIPS_DSS 0x0101 /* DSS 350 Digital Speaker System */ -#define USB_PRODUCT_PHILIPS_HUB 0x0201 /* hub */ - -/* Connectix products */ -#define USB_PRODUCT_CONNECTIX_QUICKCAM 0x0001 /* QuickCam */ - -/* Acer products */ -#define USB_PRODUCT_ACER_ACERSCAN_C310U 0x12a6 /* Acerscan C310U */ - -/* Cypress Semiconduuctor products */ -#define USB_PRODUCT_CYPRESS_MOUSE 0x0001 /* mouse */ - -/* 3Com products */ -#define USB_PRODUCT_3COM_USR56K 0x3021 /* U.S.Robotics 56000 Voice USB Modem */ - -/* Shuttle Technology products */ -#define USB_PRODUCT_SHUTTLE_EUSB 0x0001 /* E-USB Bridge */ - -/* Jazz products */ -#define USB_PRODUCT_JAZZ_J6502 0x4201 /* J-6502 speakers */ - -/* ATen products */ -#define USB_PRODUCT_ATEN_UC1284 0x2001 /* Parallel printer adapter */ - -/* Peracom products */ -#define USB_PRODUCT_PERACOM_SERIAL1 0x0001 /* Serial Converter */ - -/* EIZO products */ -#define USB_PRODUCT_EIZO_HUB 0x0000 /* hub */ -#define USB_PRODUCT_EIZO_MONITOR 0x0001 /* monitor */ - -/* Agiler products */ -#define USB_PRODUCT_AGILER_MOUSE29UO 0x0002 /* mouse 29UO */ - -/* Belkin products */ -#define USB_PRODUCT_BELKIN_F5U002 0x0002 /* Parallel printer adapter */ - -/* Logitech products */ -#define USB_PRODUCT_LOGITECH_M2452 0x0203 /* M2452 keyboard */ -#define USB_PRODUCT_LOGITECH_M4848 0x0301 /* M4848 mouse */ - -/* Chic Technology products */ -#define USB_PRODUCT_CHIC_MOUSE1 0x0001 /* mouse */ - -/* ADS products */ -#define USB_PRODUCT_ADS_ENET 0x0008 /* Ethernet adapter */ - -/* PLX products */ -#define USB_PRODUCT_PLX_TESTBOARD 0x9060 /* test board */ - -#define USB_PRODUCT_ENTREGA_CENTRONICS 0x0006 /* Centronics connector */ -#define USB_PRODUCT_ENTREGA_SERIAL 0x8001 /* DB25 Serial connector */ - -/* Inside Out Networks products */ -#define USB_PRODUCT_INSIDEOUT_EDGEPORT4 0x0001 /* EdgePort/4 serial ports */ - -/* Intel products */ -#define USB_PRODUCT_INTEL_TESTBOARD 0x9890 /* 82930 test board */ diff --git a/sys/dev/usb/usbdevs_data.h b/sys/dev/usb/usbdevs_data.h deleted file mode 100644 index a6815eb6c9da6..0000000000000 --- a/sys/dev/usb/usbdevs_data.h +++ /dev/null @@ -1,439 +0,0 @@ -/* $FreeBSD$ */ - -/* - * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. - * - * generated from: - * NetBSD: usbdevs,v 1.19 1999/01/08 11:18:38 augustss Exp - */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -struct usb_knowndev usb_knowndevs[] = { - { - USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB, - 0, - "NEC", - "hub", - }, - { - USB_VENDOR_NEC, USB_PRODUCT_NEC_HUB_B, - 0, - "NEC", - "hub", - }, - { - USB_VENDOR_KODAK, USB_PRODUCT_KODAK_DC260, - 0, - "Eastman Kodak", - "Digital Science DC260", - }, - { - USB_VENDOR_CATC, USB_PRODUCT_CATC_ANDROMEDA, - 0, - "CATC", - "Andromeda hub", - }, - { - USB_VENDOR_UNIXTAR, USB_PRODUCT_UNIXTAR_UTUSB41, - 0, - "Unixtar", - "UT-USB41 hub", - }, - { - USB_VENDOR_GENIUS, USB_PRODUCT_GENIUS_NICHE, - 0, - "Genius", - "Niche mouse", - }, - { - USB_VENDOR_GENIUS, USB_PRODUCT_GENIUS_FLIGHT2000, - 0, - "Genius", - "Flight 2000 joystick", - }, - { - USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_INTELLIMOUSE, - 0, - "Microsoft", - "IntelliMouse", - }, - { - USB_VENDOR_KENSINGTON, USB_PRODUCT_KENSINGTON_MOUSEINABOX, - 0, - "Kensington", - "Mouse-in-a-Box", - }, - { - USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000KBD, - 0, - "Cherry", - "My3000 keyboard", - }, - { - USB_VENDOR_CHERRY, USB_PRODUCT_CHERRY_MY3000HUB, - 0, - "Cherry", - "My3000 hub", - }, - { - USB_VENDOR_BTC, USB_PRODUCT_BTC_BTC7932, - 0, - "BTC", - "Keyboard with mouse port", - }, - { - USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_DSS, - 0, - "Philips", - "DSS 350 Digital Speaker System", - }, - { - USB_VENDOR_PHILIPS, USB_PRODUCT_PHILIPS_HUB, - 0, - "Philips", - "hub", - }, - { - USB_VENDOR_CONNECTIX, USB_PRODUCT_CONNECTIX_QUICKCAM, - 0, - "Connectix", - "QuickCam", - }, - { - USB_VENDOR_ACER, USB_PRODUCT_ACER_ACERSCAN_C310U, - 0, - "Acer Peripherals", - "Acerscan C310U", - }, - { - USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_MOUSE, - 0, - "Cypress Semiconductor", - "mouse", - }, - { - USB_VENDOR_3COM, USB_PRODUCT_3COM_USR56K, - 0, - "3Com", - "U.S.Robotics 56000 Voice USB Modem", - }, - { - USB_VENDOR_SHUTTLE, USB_PRODUCT_SHUTTLE_EUSB, - 0, - "Shuttle Technology", - "E-USB Bridge", - }, - { - USB_VENDOR_JAZZ, USB_PRODUCT_JAZZ_J6502, - 0, - "Jazz", - "J-6502 speakers", - }, - { - USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC1284, - 0, - "ATen", - "Parallel printer adapter", - }, - { - USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_SERIAL1, - 0, - "Peracom", - "Serial Converter", - }, - { - USB_VENDOR_EIZO, USB_PRODUCT_EIZO_HUB, - 0, - "EIZO", - "hub", - }, - { - USB_VENDOR_EIZO, USB_PRODUCT_EIZO_MONITOR, - 0, - "EIZO", - "monitor", - }, - { - USB_VENDOR_AGILER, USB_PRODUCT_AGILER_MOUSE29UO, - 0, - "Agiler", - "mouse 29UO", - }, - { - USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U002, - 0, - "Belkin", - "Parallel printer adapter", - }, - { - USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M2452, - 0, - "Logitech", - "M2452 keyboard", - }, - { - USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M4848, - 0, - "Logitech", - "M4848 mouse", - }, - { - USB_VENDOR_CHIC, USB_PRODUCT_CHIC_MOUSE1, - 0, - "Chic Technology", - "mouse", - }, - { - USB_VENDOR_ADS, USB_PRODUCT_ADS_ENET, - 0, - "ADS Technologies", - "Ethernet adapter", - }, - { - USB_VENDOR_PLX, USB_PRODUCT_PLX_TESTBOARD, - 0, - "PLX", - "test board", - }, - { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_CENTRONICS, - 0, - "Entrega", - "Centronics connector", - }, - { - USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_SERIAL, - 0, - "Entrega", - "DB25 Serial connector", - }, - { - USB_VENDOR_INSIDEOUT, USB_PRODUCT_INSIDEOUT_EDGEPORT4, - 0, - "Inside Out Networks", - "EdgePort/4 serial ports", - }, - { - USB_VENDOR_INTEL, USB_PRODUCT_INTEL_TESTBOARD, - 0, - "Intel", - "82930 test board", - }, - { - USB_VENDOR_NEC, 0, - USB_KNOWNDEV_NOPROD, - "NEC", - NULL, - }, - { - USB_VENDOR_KODAK, 0, - USB_KNOWNDEV_NOPROD, - "Eastman Kodak", - NULL, - }, - { - USB_VENDOR_CATC, 0, - USB_KNOWNDEV_NOPROD, - "CATC", - NULL, - }, - { - USB_VENDOR_NANAO, 0, - USB_KNOWNDEV_NOPROD, - "Nanao", - NULL, - }, - { - USB_VENDOR_UNIXTAR, 0, - USB_KNOWNDEV_NOPROD, - "Unixtar", - NULL, - }, - { - USB_VENDOR_GENIUS, 0, - USB_KNOWNDEV_NOPROD, - "Genius", - NULL, - }, - { - USB_VENDOR_MICROSOFT, 0, - USB_KNOWNDEV_NOPROD, - "Microsoft", - NULL, - }, - { - USB_VENDOR_KENSINGTON, 0, - USB_KNOWNDEV_NOPROD, - "Kensington", - NULL, - }, - { - USB_VENDOR_CHERRY, 0, - USB_KNOWNDEV_NOPROD, - "Cherry", - NULL, - }, - { - USB_VENDOR_BTC, 0, - USB_KNOWNDEV_NOPROD, - "BTC", - NULL, - }, - { - USB_VENDOR_PHILIPS, 0, - USB_KNOWNDEV_NOPROD, - "Philips", - NULL, - }, - { - USB_VENDOR_CONNECTIX, 0, - USB_KNOWNDEV_NOPROD, - "Connectix", - NULL, - }, - { - USB_VENDOR_ACER, 0, - USB_KNOWNDEV_NOPROD, - "Acer Peripherals", - NULL, - }, - { - USB_VENDOR_CYPRESS, 0, - USB_KNOWNDEV_NOPROD, - "Cypress Semiconductor", - NULL, - }, - { - USB_VENDOR_3COM, 0, - USB_KNOWNDEV_NOPROD, - "3Com", - NULL, - }, - { - USB_VENDOR_SHUTTLE, 0, - USB_KNOWNDEV_NOPROD, - "Shuttle Technology", - NULL, - }, - { - USB_VENDOR_JAZZ, 0, - USB_KNOWNDEV_NOPROD, - "Jazz", - NULL, - }, - { - USB_VENDOR_ATEN, 0, - USB_KNOWNDEV_NOPROD, - "ATen", - NULL, - }, - { - USB_VENDOR_PERACOM, 0, - USB_KNOWNDEV_NOPROD, - "Peracom", - NULL, - }, - { - USB_VENDOR_EIZO, 0, - USB_KNOWNDEV_NOPROD, - "EIZO", - NULL, - }, - { - USB_VENDOR_AGILER, 0, - USB_KNOWNDEV_NOPROD, - "Agiler", - NULL, - }, - { - USB_VENDOR_BELKIN, 0, - USB_KNOWNDEV_NOPROD, - "Belkin", - NULL, - }, - { - USB_VENDOR_LOGITECH, 0, - USB_KNOWNDEV_NOPROD, - "Logitech", - NULL, - }, - { - USB_VENDOR_EIZONANAO, 0, - USB_KNOWNDEV_NOPROD, - "EIZO Nanao", - NULL, - }, - { - USB_VENDOR_CHIC, 0, - USB_KNOWNDEV_NOPROD, - "Chic Technology", - NULL, - }, - { - USB_VENDOR_ADS, 0, - USB_KNOWNDEV_NOPROD, - "ADS Technologies", - NULL, - }, - { - USB_VENDOR_PLX, 0, - USB_KNOWNDEV_NOPROD, - "PLX", - NULL, - }, - { - USB_VENDOR_ENTREGA, 0, - USB_KNOWNDEV_NOPROD, - "Entrega", - NULL, - }, - { - USB_VENDOR_INSIDEOUT, 0, - USB_KNOWNDEV_NOPROD, - "Inside Out Networks", - NULL, - }, - { - USB_VENDOR_INTEL, 0, - USB_KNOWNDEV_NOPROD, - "Intel", - NULL, - }, - { 0, 0, 0, NULL, NULL, } -}; diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c deleted file mode 100644 index e1ed20a0f8a72..0000000000000 --- a/sys/dev/usb/usbdi.c +++ /dev/null @@ -1,1294 +0,0 @@ -/* $NetBSD: usbdi.c,v 1.20 1999/01/08 11:58:26 augustss Exp $ */ -/* FreeBSD $Id: usbdi.c,v 1.7 1999/01/07 23:31:42 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#if defined(__NetBSD__) -#include <sys/device.h> -#else -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/conf.h> -#endif -#include <sys/malloc.h> -#include <sys/proc.h> - -#include <dev/usb/usb.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> - -#if defined(__FreeBSD__) -#include "usb_if.h" -#endif - -#ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -extern int usbdebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -static usbd_status usbd_ar_pipe __P((usbd_pipe_handle pipe)); -static usbd_status usbd_ar_iface __P((usbd_interface_handle iface)); -static void usbd_transfer_cb __P((usbd_request_handle reqh)); -static void usbd_sync_transfer_cb __P((usbd_request_handle reqh)); -static usbd_status usbd_do_transfer __P((usbd_request_handle reqh)); -void usbd_do_request_async_cb - __P((usbd_request_handle, usbd_private_handle, usbd_status)); - -static SIMPLEQ_HEAD(, usbd_request) usbd_free_requests; - -#if defined(__FreeBSD__) -#define USB_CDEV_MAJOR 108 - -extern struct cdevsw usb_cdevsw; -#endif - -usbd_status -usbd_open_pipe(iface, address, flags, pipe) - usbd_interface_handle iface; - u_int8_t address; - u_int8_t flags; - usbd_pipe_handle *pipe; -{ - usbd_pipe_handle p; - struct usbd_endpoint *ep; - usbd_status r; - int i; - - if (iface->state != USBD_INTERFACE_ACTIVE) - return (USBD_INTERFACE_NOT_ACTIVE); - for (i = 0; i < iface->idesc->bNumEndpoints; i++) { - ep = &iface->endpoints[i]; - if (ep->edesc->bEndpointAddress == address) - goto found; - } - return (USBD_BAD_ADDRESS); - found: - if ((flags & USBD_EXCLUSIVE_USE) && - ep->refcnt != 0) - return (USBD_IN_USE); - r = usbd_setup_pipe(iface->device, iface, ep, &p); - if (r != USBD_NORMAL_COMPLETION) - return (r); - LIST_INSERT_HEAD(&iface->pipes, p, next); - *pipe = p; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, length, cb) - 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 cb; -{ - usbd_status r; - usbd_request_handle reqh; - usbd_pipe_handle ipipe; - - reqh = usbd_alloc_request(); - if (reqh == 0) - return (USBD_NOMEM); - r = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &ipipe); - if (r != USBD_NORMAL_COMPLETION) - goto bad1; - r = usbd_setup_request(reqh, ipipe, priv, buffer, length, - USBD_XFER_IN | flags, USBD_NO_TIMEOUT, cb); - if (r != USBD_NORMAL_COMPLETION) - goto bad2; - ipipe->intrreqh = reqh; - r = usbd_transfer(reqh); - *pipe = ipipe; - if (r != USBD_IN_PROGRESS) - goto bad3; - return (USBD_NORMAL_COMPLETION); - - bad3: - ipipe->intrreqh = 0; - bad2: - usbd_close_pipe(ipipe); - bad1: - usbd_free_request(reqh); - return r; -} - -usbd_status -usbd_open_pipe_iso(iface, address, flags, pipe, priv, bufsize, nbuf, cb) - 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 cb; -{ - usbd_status r; - usbd_pipe_handle p; - - r = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &p); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (!p->methods->isobuf) { - usbd_close_pipe(p); - return (USBD_INVAL); - } - r = p->methods->isobuf(p, bufsize, nbuf); - if (r != USBD_NORMAL_COMPLETION) { - usbd_close_pipe(p); - return (r); - } - *pipe = p; - return r; -} - -usbd_status -usbd_close_pipe(pipe) - usbd_pipe_handle pipe; -{ - if (pipe->iface->state != USBD_INTERFACE_ACTIVE) - return (USBD_INTERFACE_NOT_ACTIVE); - if (--pipe->refcnt != 0) - return (USBD_NORMAL_COMPLETION); - if (SIMPLEQ_FIRST(&pipe->queue) != 0) - return (USBD_PENDING_REQUESTS); - LIST_REMOVE(pipe, next); - pipe->endpoint->refcnt--; - pipe->methods->close(pipe); - if (pipe->intrreqh) - usbd_free_request(pipe->intrreqh); - free(pipe, M_USB); - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_transfer(reqh) - usbd_request_handle reqh; -{ - reqh->xfercb = usbd_transfer_cb; - return (usbd_do_transfer(reqh)); -} - -static usbd_status -usbd_do_transfer(reqh) - usbd_request_handle reqh; -{ - usbd_pipe_handle pipe = reqh->pipe; - - DPRINTFN(10,("usbd_do_transfer: reqh=%p\n", reqh)); - reqh->done = 0; - return (pipe->methods->transfer(reqh)); -} - -usbd_request_handle -usbd_alloc_request() -{ - usbd_request_handle reqh; - - reqh = SIMPLEQ_FIRST(&usbd_free_requests); - if (reqh) - SIMPLEQ_REMOVE_HEAD(&usbd_free_requests, reqh, next); - else - reqh = malloc(sizeof(*reqh), M_USB, M_NOWAIT); - if (!reqh) - return (0); - memset(reqh, 0, sizeof *reqh); - return (reqh); -} - -usbd_status -usbd_free_request(reqh) - usbd_request_handle reqh; -{ - SIMPLEQ_INSERT_HEAD(&usbd_free_requests, reqh, next); - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_setup_request(reqh, pipe, priv, buffer, length, flags, timeout, callback) - 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; - void (*callback) __P((usbd_request_handle, - usbd_private_handle, - usbd_status)); -{ - reqh->pipe = pipe; - reqh->isreq = 0; - reqh->priv = priv; - reqh->buffer = buffer; - reqh->length = length; - reqh->actlen = 0; - reqh->flags = flags; - reqh->callback = callback; - reqh->status = USBD_NOT_STARTED; - reqh->retries = 1; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_setup_device_request(reqh, req) - usbd_request_handle reqh; - usb_device_request_t *req; -{ - reqh->isreq = 1; - reqh->request = *req; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_setup_default_request(reqh, dev, priv, timeout, req, buffer, - length, flags, callback) - 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; - void (*callback) __P((usbd_request_handle, - usbd_private_handle, - usbd_status)); -{ - reqh->pipe = dev->default_pipe; - reqh->priv = priv; - reqh->buffer = buffer; - reqh->length = length; - reqh->actlen = 0; - reqh->flags = flags; - reqh->timeout = timeout; - reqh->status = USBD_NOT_STARTED; - reqh->callback = callback; - reqh->request = *req; - reqh->isreq = 1; - reqh->retries = 1; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_set_request_timeout(reqh, timeout) - usbd_request_handle reqh; - u_int32_t timeout; -{ - reqh->timeout = timeout; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_get_request_status(reqh, priv, buffer, count, status) - usbd_request_handle reqh; - usbd_private_handle *priv; - void **buffer; - u_int32_t *count; - usbd_status *status; -{ - *priv = reqh->priv; - *buffer = reqh->buffer; - *count = reqh->actlen; - *status = reqh->status; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_request_device_data(reqh, req) - usbd_request_handle reqh; - usb_device_request_t *req; -{ - if (!reqh->isreq) - return (USBD_INVAL); - *req = reqh->request; - return (USBD_NORMAL_COMPLETION); -} - -#if 0 -usb_descriptor_t * -usbd_get_descriptor(iface, desc_type) - usbd_interface_handle *iface; - u_int8_t desc_type; -XX -#endif - -usb_config_descriptor_t * -usbd_get_config_descriptor(dev) - usbd_device_handle dev; -{ - return (dev->cdesc); -} - -usb_interface_descriptor_t * -usbd_get_interface_descriptor(iface) - usbd_interface_handle iface; -{ - return (iface->idesc); -} - -usb_device_descriptor_t * -usbd_get_device_descriptor(dev) - usbd_device_handle dev; -{ - return (&dev->ddesc); -} - -usb_endpoint_descriptor_t * -usbd_interface2endpoint_descriptor(iface, index) - usbd_interface_handle iface; - u_int8_t index; -{ - if (index >= iface->idesc->bNumEndpoints) - return (0); - return (iface->endpoints[index].edesc); -} - -usbd_status -usbd_set_configuration(dev, conf) - usbd_device_handle dev; - u_int8_t conf; -{ - return usbd_set_config_no(dev, conf, 0); -} - -usbd_status -usbd_retry_request(reqh, retry_count) - usbd_request_handle reqh; - u_int32_t retry_count; -{ - usbd_status r; - - r = usbd_set_pipe_state(reqh->pipe, USBD_PIPE_ACTIVE); - if (r != USBD_NORMAL_COMPLETION) - return (r); - reqh->retries = retry_count; - return (usbd_transfer(reqh)); -} - -usbd_status -usbd_abort_pipe(pipe) - usbd_pipe_handle pipe; -{ - usbd_status r; - int s, st; - - if (pipe->iface->state != USBD_INTERFACE_ACTIVE) - return (USBD_INTERFACE_NOT_ACTIVE); - s = splusb(); - st = pipe->state; - r = usbd_ar_pipe(pipe); - pipe->state = st; - splx(s); - return (r); -} - -usbd_status -usbd_abort_interface(iface) - usbd_interface_handle iface; -{ - usbd_status r; - int s, st; - - s = splusb(); - st = iface->state; - r = usbd_ar_iface(iface); - iface->state = st; - splx(s); - return (r); -} - -usbd_status -usbd_reset_pipe(pipe) - usbd_pipe_handle pipe; -{ - usbd_status r; - int s; - - if (pipe->iface->state != USBD_INTERFACE_ACTIVE) - return (USBD_INTERFACE_NOT_ACTIVE); - s = splusb(); - r = usbd_ar_pipe(pipe); - /* XXX anything else */ - pipe->state = USBD_PIPE_ACTIVE; - splx(s); - return (r); -} - -usbd_status -usbd_reset_interface(iface) - usbd_interface_handle iface; -{ - usbd_status r; - int s; - - s = splusb(); - r = usbd_ar_iface(iface); - /* XXX anything else */ - iface->state = USBD_INTERFACE_ACTIVE; - splx(s); - return (r); -} - -usbd_status -usbd_clear_endpoint_stall(pipe) - usbd_pipe_handle pipe; -{ - usbd_device_handle dev = pipe->device; - usb_device_request_t req; - usbd_status r; - - req.bmRequestType = UT_WRITE_ENDPOINT; - req.bRequest = UR_CLEAR_FEATURE; - USETW(req.wValue, UF_ENDPOINT_HALT); - USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); - USETW(req.wLength, 0); - r = usbd_do_request(dev, &req, 0); -#if 0 -XXX should we do this? - if (r == USBD_NORMAL_COMPLETION) { - pipe->state = USBD_PIPE_ACTIVE; - /* XXX activate pipe */ - } -#endif - return (r); -} - -usbd_status -usbd_clear_endpoint_stall_async(pipe) - usbd_pipe_handle pipe; -{ - usbd_device_handle dev = pipe->device; - usb_device_request_t req; - usbd_status r; - - req.bmRequestType = UT_WRITE_ENDPOINT; - req.bRequest = UR_CLEAR_FEATURE; - USETW(req.wValue, UF_ENDPOINT_HALT); - USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); - USETW(req.wLength, 0); - r = usbd_do_request_async(dev, &req, 0); - return (r); -} - -usbd_status -usbd_set_pipe_state(pipe, state) - usbd_pipe_handle pipe; - usbd_pipe_state state; -{ - int s; - usbd_status r; - usbd_request_handle reqh; - - if (pipe->iface->state != USBD_INTERFACE_ACTIVE) - return (USBD_INTERFACE_NOT_ACTIVE); - if (state != USBD_PIPE_ACTIVE && - state != USBD_PIPE_STALLED && - state != USBD_PIPE_IDLE) - return (USBD_INVAL); - pipe->state = state; - r = USBD_NORMAL_COMPLETION; - if (state == USBD_PIPE_ACTIVE) { - s = splusb(); - if (!pipe->running) { - reqh = SIMPLEQ_FIRST(&pipe->queue); - if (reqh != 0) { - pipe->running = 1; - splx(s); - r = pipe->methods->start(reqh); - } else - splx(s); - } else - splx(s); - } - return (r); -} - -usbd_status -usbd_get_pipe_state(pipe, state, endpoint_state, request_count) - usbd_pipe_handle pipe; - usbd_pipe_state *state; - u_int32_t *endpoint_state; - u_int32_t *request_count; -{ - int n; - usbd_request_handle r; - - *state = pipe->state; - *endpoint_state = pipe->endpoint->state; - for (r = SIMPLEQ_FIRST(&pipe->queue), n = 0; - r != 0; - r = SIMPLEQ_NEXT(r, next), n++) - ; - *request_count = n; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_set_interface_state(iface, state) - usbd_interface_handle iface; - usbd_interface_state state; -{ - int ps; - usbd_pipe_handle p; - - if (state == USBD_INTERFACE_ACTIVE) - ps = USBD_PIPE_ACTIVE; - else if (state == USBD_INTERFACE_STALLED) - ps = USBD_PIPE_STALLED; - else if (state == USBD_INTERFACE_IDLE) - ps = USBD_PIPE_IDLE; - else - return (USBD_INVAL); - iface->state = USBD_INTERFACE_ACTIVE; /* to allow setting the pipe */ - for (p = LIST_FIRST(&iface->pipes); p != 0; p = LIST_NEXT(p, next)) - usbd_set_pipe_state(p, ps); - iface->state = state; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_get_interface_state(iface, state) - usbd_interface_handle iface; - usbd_interface_state *state; -{ - *state = iface->state; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_get_device_state(dev, state) - usbd_device_handle dev; - usbd_device_state *state; -{ - *state = dev->state; - return (USBD_NORMAL_COMPLETION); -} - -#if 0 -usbd_status -usbd_set_device_state(dev, state) - usbd_device_handle dev; - usbd_device_state state; -X -#endif - -usbd_status -usbd_device_address(dev, address) - usbd_device_handle dev; - u_int8_t *address; -{ - *address = dev->address; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_endpoint_address(pipe, address) - usbd_pipe_handle pipe; - u_int8_t *address; -{ - *address = pipe->endpoint->edesc->bEndpointAddress; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_endpoint_count(iface, count) - usbd_interface_handle iface; - u_int8_t *count; -{ - *count = iface->idesc->bNumEndpoints; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_interface_count(dev, count) - usbd_device_handle dev; - u_int8_t *count; -{ - if (!dev->cdesc) - return (USBD_NOT_CONFIGURED); - *count = dev->cdesc->bNumInterface; - return (USBD_NORMAL_COMPLETION); -} - -#if 0 -u_int8_t -usbd_bus_count() -{ - return (usb_bus_count()); -} -#endif - -#if defined(__NetBSD__) -usbd_status -usbd_get_bus_handle(index, bus) - u_int8_t index; - usbd_bus_handle *bus; -{ - return (usb_get_bus_handle(index, bus)); -} -#endif - -usbd_status -usbd_get_root_hub(bus, dev) - usbd_bus_handle bus; - usbd_device_handle *dev; -{ - *dev = bus->root_hub; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_port_count(dev, nports) - usbd_device_handle dev; - u_int8_t *nports; -{ - if (dev->hub == 0) - return (USBD_INVAL); - *nports = dev->hub->hubdesc.bNbrPorts; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_hub2device_handle(dev, port, devp) - usbd_device_handle dev; - u_int8_t port; - usbd_device_handle *devp; -{ - if (dev->hub == 0 || port >= dev->hub->hubdesc.bNbrPorts || - dev->hub->ports[port].device == 0) - return (USBD_INVAL); - *devp = dev->hub->ports[port].device; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_request2pipe_handle(reqh, pipe) - usbd_request_handle reqh; - usbd_pipe_handle *pipe; -{ - *pipe = reqh->pipe; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_pipe2interface_handle(pipe, iface) - usbd_pipe_handle pipe; - usbd_interface_handle *iface; -{ - *iface = pipe->iface; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_interface2device_handle(iface, dev) - usbd_interface_handle iface; - usbd_device_handle *dev; -{ - *dev = iface->device; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_device2bus_handle(dev, bus) - usbd_device_handle dev; - usbd_bus_handle *bus; -{ - *bus = dev->bus; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_device2interface_handle(dev, ifaceno, iface) - usbd_device_handle dev; - u_int8_t ifaceno; - usbd_interface_handle *iface; -{ - if (!dev->cdesc) - return (USBD_NOT_CONFIGURED); - if (ifaceno >= dev->cdesc->bNumInterface) - return (USBD_INVAL); - *iface = &dev->ifaces[ifaceno]; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_set_interface_private_handle(iface, priv) - usbd_interface_handle iface; - usbd_private_handle priv; -{ - iface->priv = priv; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_get_interface_private_handle(iface, priv) - usbd_interface_handle iface; - usbd_private_handle *priv; -{ - *priv = iface->priv; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_reference_pipe(pipe) - usbd_pipe_handle pipe; -{ - pipe->refcnt++; - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_dereference_pipe(pipe) - usbd_pipe_handle pipe; -{ - pipe->refcnt--; - return (USBD_NORMAL_COMPLETION); -} - -usbd_lock_token -usbd_lock() -{ - return (splusb()); -} - -void -usbd_unlock(tok) - usbd_lock_token tok; -{ - splx(tok); -} - -/* XXXX use altno */ -usbd_status -usbd_set_interface(iface, altidx) - usbd_interface_handle iface; - int altidx; -{ - usb_device_request_t req; - usbd_status r; - - if (LIST_FIRST(&iface->pipes) != 0) - return (USBD_IN_USE); - - if (iface->endpoints) - free(iface->endpoints, M_USB); - iface->endpoints = 0; - iface->idesc = 0; - iface->state = USBD_INTERFACE_IDLE; - - r = usbd_fill_iface_data(iface->device, iface->index, altidx); - if (r != USBD_NORMAL_COMPLETION) - return (r); - - req.bmRequestType = UT_WRITE_INTERFACE; - req.bRequest = UR_SET_INTERFACE; - USETW(req.wValue, iface->idesc->bAlternateSetting); - USETW(req.wIndex, iface->idesc->bInterfaceNumber); - USETW(req.wLength, 0); - return usbd_do_request(iface->device, &req, 0); -} - -int -usbd_get_no_alts(cdesc, ifaceno) - usb_config_descriptor_t *cdesc; - int ifaceno; -{ - char *p = (char *)cdesc; - char *end = p + UGETW(cdesc->wTotalLength); - usb_interface_descriptor_t *d; - int n; - - for (n = 0; p < end; p += d->bLength) { - d = (usb_interface_descriptor_t *)p; - if (p + d->bLength <= end && - d->bDescriptorType == UDESC_INTERFACE && - d->bInterfaceNumber == ifaceno) - n++; - } - return (n); -} - -int -usbd_get_interface_altindex(iface) - usbd_interface_handle iface; -{ - return (iface->altindex); -} - -usbd_status -usbd_get_interface(iface, aiface) - usbd_interface_handle iface; - u_int8_t *aiface; -{ - usb_device_request_t req; - - req.bmRequestType = UT_READ_INTERFACE; - req.bRequest = UR_GET_INTERFACE; - USETW(req.wValue, 0); - USETW(req.wIndex, iface->idesc->bInterfaceNumber); - USETW(req.wLength, 1); - return usbd_do_request(iface->device, &req, aiface); -} - -/*** Internal routines ***/ - -/* Dequeue all pipe operations, called at splusb(). */ -static usbd_status -usbd_ar_pipe(pipe) - usbd_pipe_handle pipe; -{ - usbd_request_handle reqh; - -#if 0 - for (;;) { - reqh = SIMPLEQ_FIRST(&pipe->queue); - if (reqh == 0) - break; - SIMPLEQ_REMOVE_HEAD(&pipe->queue, reqh, next); - reqh->status = USBD_CANCELLED; - if (reqh->callback) - reqh->callback(reqh, reqh->priv, reqh->status); - } -#else - while ((reqh = SIMPLEQ_FIRST(&pipe->queue))) { - pipe->methods->abort(reqh); - SIMPLEQ_REMOVE_HEAD(&pipe->queue, reqh, next); - } -#endif - return (USBD_NORMAL_COMPLETION); -} - -/* Dequeue all interface operations, called at splusb(). */ -static usbd_status -usbd_ar_iface(iface) - usbd_interface_handle iface; -{ - usbd_pipe_handle p; - usbd_status r, ret = USBD_NORMAL_COMPLETION; - - for (p = LIST_FIRST(&iface->pipes); p != 0; p = LIST_NEXT(p, next)) { - r = usbd_ar_pipe(p); - if (r != USBD_NORMAL_COMPLETION) - ret = r; - } - return (ret); -} - -static int usbd_global_init_done = 0; - -void -usbd_init() -{ -#if defined(__FreeBSD__) - dev_t dev; -#endif - - if (!usbd_global_init_done) { - usbd_global_init_done = 1; - SIMPLEQ_INIT(&usbd_free_requests); - -#if defined(__FreeBSD__) - dev = makedev(USB_CDEV_MAJOR, 0); - cdevsw_add(&dev, &usb_cdevsw, NULL); -#endif - } -} - -static void -usbd_transfer_cb(reqh) - usbd_request_handle reqh; -{ - usbd_pipe_handle pipe = reqh->pipe; - - /* Count completed transfers. */ - ++pipe->device->bus->stats.requests - [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE]; - - /* XXX check retry count */ - reqh->done = 1; - if (reqh->status == USBD_NORMAL_COMPLETION && - reqh->actlen < reqh->length && - !(reqh->flags & USBD_SHORT_XFER_OK)) { - DPRINTFN(-1, ("usbd_transfer_cb: short xfer %d<%d (bytes)\n", - reqh->actlen, reqh->length)); - reqh->status = USBD_SHORT_XFER; - } - if (reqh->callback) - reqh->callback(reqh, reqh->priv, reqh->status); -} - -static void -usbd_sync_transfer_cb(reqh) - usbd_request_handle reqh; -{ - usbd_transfer_cb(reqh); - if (!reqh->pipe->device->bus->use_polling) - wakeup(reqh); -} - -/* Like usbd_transfer(), but waits for completion. */ -usbd_status -usbd_sync_transfer(reqh) - usbd_request_handle reqh; -{ - usbd_status r; - int s; - - reqh->xfercb = usbd_sync_transfer_cb; - r = usbd_do_transfer(reqh); - if (r != USBD_IN_PROGRESS) - return (r); - s = splusb(); - if (!reqh->done) { - if (reqh->pipe->device->bus->use_polling) - panic("usbd_sync_transfer: not done\n"); - tsleep(reqh, PRIBIO, "usbsyn", 0); - } - splx(s); - return (reqh->status); -} - -usbd_status -usbd_do_request(dev, req, data) - usbd_device_handle dev; - usb_device_request_t *req; - void *data; -{ - return (usbd_do_request_flags(dev, req, data, 0, 0)); -} - -usbd_status -usbd_do_request_flags(dev, req, data, flags, actlen) - usbd_device_handle dev; - usb_device_request_t *req; - void *data; - u_int16_t flags; - int *actlen; -{ - usbd_request_handle reqh; - usbd_status r; - -#ifdef DIAGNOSTIC - if (!curproc) { - printf("usbd_do_request: not in process context\n"); - return (USBD_XXX); - } -#endif - - reqh = usbd_alloc_request(); - if (reqh == 0) - return (USBD_NOMEM); - r = usbd_setup_default_request( - reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data, - UGETW(req->wLength), flags, 0); - if (r != USBD_NORMAL_COMPLETION) - goto bad; - r = usbd_sync_transfer(reqh); -#if defined(USB_DEBUG) || defined(DIAGNOSTIC) - if (reqh->actlen > reqh->length) - printf("usbd_do_request: overrun addr=%d type=0x%02x req=0x" - "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n", - dev->address, reqh->request.bmRequestType, - reqh->request.bRequest, UGETW(reqh->request.wValue), - UGETW(reqh->request.wIndex), - UGETW(reqh->request.wLength), - reqh->length, reqh->actlen); -#endif - if (actlen) - *actlen = reqh->actlen; - if (r == USBD_STALLED) { - /* - * The control endpoint has stalled. Control endpoints - * should not halt, but some may do so anyway so clear - * any halt condition. - */ - usb_device_request_t treq; - usb_status_t status; - u_int16_t s; - usbd_status nr; - - treq.bmRequestType = UT_READ_ENDPOINT; - treq.bRequest = UR_GET_STATUS; - USETW(treq.wValue, 0); - USETW(treq.wIndex, 0); - USETW(treq.wLength, sizeof(usb_status_t)); - nr = usbd_setup_default_request( - reqh, dev, 0, USBD_DEFAULT_TIMEOUT, &treq, &status, - sizeof(usb_status_t), 0, 0); - if (nr != USBD_NORMAL_COMPLETION) - goto bad; - nr = usbd_sync_transfer(reqh); - if (nr != USBD_NORMAL_COMPLETION) - goto bad; - s = UGETW(status.wStatus); - DPRINTF(("usbd_do_request: status = 0x%04x\n", s)); - if (!(s & UES_HALT)) - goto bad; - treq.bmRequestType = UT_WRITE_ENDPOINT; - treq.bRequest = UR_CLEAR_FEATURE; - USETW(treq.wValue, UF_ENDPOINT_HALT); - USETW(treq.wIndex, 0); - USETW(treq.wLength, 0); - nr = usbd_setup_default_request( - reqh, dev, 0, USBD_DEFAULT_TIMEOUT, &treq, &status, - 0, 0, 0); - if (nr != USBD_NORMAL_COMPLETION) - goto bad; - nr = usbd_sync_transfer(reqh); - if (nr != USBD_NORMAL_COMPLETION) - goto bad; - } - - bad: - usbd_free_request(reqh); - return (r); -} - -void -usbd_do_request_async_cb(reqh, priv, status) - usbd_request_handle reqh; - usbd_private_handle priv; - usbd_status status; -{ -#if defined(USB_DEBUG) || defined(DIAGNOSTIC) - if (reqh->actlen > reqh->length) - printf("usbd_do_request: overrun addr=%d type=0x%02x req=0x" - "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n", - reqh->pipe->device->address, - reqh->request.bmRequestType, - reqh->request.bRequest, UGETW(reqh->request.wValue), - UGETW(reqh->request.wIndex), - UGETW(reqh->request.wLength), - reqh->length, reqh->actlen); -#endif - usbd_free_request(reqh); -} - -/* - * Execute a request without waiting for completion. - * Can be used from interrupt context. - */ -usbd_status -usbd_do_request_async(dev, req, data) - usbd_device_handle dev; - usb_device_request_t *req; - void *data; -{ - usbd_request_handle reqh; - usbd_status r; - - reqh = usbd_alloc_request(); - if (reqh == 0) - return (USBD_NOMEM); - r = usbd_setup_default_request( - reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data, - UGETW(req->wLength), 0, usbd_do_request_async_cb); - if (r != USBD_NORMAL_COMPLETION) { - usbd_free_request(reqh); - return (r); - } - r = usbd_transfer(reqh); - if (r != USBD_IN_PROGRESS) - return (r); - return (USBD_NORMAL_COMPLETION); -} - -struct usbd_quirks * -usbd_get_quirks(dev) - usbd_device_handle dev; -{ - return (dev->quirks); -} - -void -usbd_set_disco(p, hdl, data) - usbd_pipe_handle p; - void (*hdl) __P((void *)); - void *data; -{ - p->disco = hdl; - p->discoarg = data; -} - -/* XXX do periodic free() of free list */ - -/* - * Called from keyboard driver when in polling mode. - */ -void -usbd_dopoll(iface) - usbd_interface_handle iface; -{ - iface->device->bus->do_poll(iface->device->bus); -} - -void -usbd_set_polling(iface, on) - usbd_interface_handle iface; - int on; -{ - iface->device->bus->use_polling = on; -} - - -usb_endpoint_descriptor_t * -usbd_get_endpoint_descriptor(iface, address) - usbd_interface_handle iface; - u_int8_t address; -{ - struct usbd_endpoint *ep; - int i; - - for (i = 0; i < iface->idesc->bNumEndpoints; i++) { - ep = &iface->endpoints[i]; - if (ep->edesc->bEndpointAddress == address) - return (iface->endpoints[i].edesc); - } - return (0); -} - -#if defined(__FreeBSD__) -void -usbd_print_child(device_t parent, device_t child) -{ - /* - struct usb_softc *sc = device_get_softc(child); - */ - - printf(" at %s%d", device_get_name(parent), device_get_unit(parent)); - - /* XXX How do we get to the usbd_device_handle??? - usbd_device_handle dev = invalidadosch; - - printf(" addr %d", dev->addr); - - if (bootverbose) { - if (dev->lowspeed) - printf(", lowspeed"); - if (dev->self_powered) - printf(", self powered"); - else - printf(", %dmA", dev->power); - printf(", config %d", dev->config); - } - */ -} - -/* Reconfigure all the USB busses in the system. */ -int -usbd_driver_load(module_t mod, int what, void *arg) -{ - devclass_t usb_devclass = devclass_find("usb"); - devclass_t ugen_devclass = devclass_find("ugen"); - device_t *devlist; - int devcount; - int error; - - switch (what) { - case MOD_LOAD: - case MOD_UNLOAD: - if (!usb_devclass) - return 0; /* just ignore call */ - - if (ugen_devclass) { - /* detach devices from generic driver if possible */ - error = devclass_get_devices(ugen_devclass, &devlist, - &devcount); - if (!error) - for (devcount--; devcount >= 0; devcount--) - (void)DEVICE_DETACH(devlist[devcount]); - } - - error = devclass_get_devices(usb_devclass, &devlist, &devcount); - if (error) - return 0; /* XXX maybe transient, or error? */ - - for (devcount--; devcount >= 0; devcount--) - USB_RECONFIGURE(devlist[devcount]); - - free(devlist, M_TEMP); - return 0; - } - - return 0; /* nothing to do by us */ -} - -/* Set the description of the device including a malloc and copy. */ -void -usbd_device_set_desc(device_t device, char *devinfo) -{ - size_t l; - char *desc; - - if ( devinfo ) { - l = strlen(devinfo); - desc = malloc(l+1, M_USB, M_NOWAIT); - if (desc) - memcpy(desc, devinfo, l+1); - } else - desc = NULL; - - device_set_desc(device, desc); -} - -char * -usbd_devname(bdevice *bdev) -{ - static char buf[20]; - /* XXX a static buffer is not exactly a good idea, but the only - * thing that goes wrong is the string that is being printed - */ - - sprintf(buf, "%s%d", device_get_name(*bdev), device_get_unit(*bdev)); - return (buf); -} - -#endif diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h deleted file mode 100644 index 88db91f8cb006..0000000000000 --- a/sys/dev/usb/usbdi.h +++ /dev/null @@ -1,343 +0,0 @@ -/* $NetBSD: usbdi.h,v 1.16 1999/01/08 11:58:26 augustss Exp $ */ -/* FreeBSD $Id: usbdi.h,v 1.4 1999/01/07 23:31:43 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -typedef struct usbd_bus *usbd_bus_handle; -typedef struct usbd_device *usbd_device_handle; -typedef struct usbd_interface *usbd_interface_handle; -typedef struct usbd_pipe *usbd_pipe_handle; -typedef struct usbd_request *usbd_request_handle; -typedef 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, - 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, - USBD_TOO_DEEP, - USBD_IOERROR, - USBD_NOT_CONFIGURED, - USBD_TIMEOUT, - USBD_SHORT_XFER, - USBD_STALLED, - USBD_INTERRUPTED, - - USBD_XXX, -} usbd_status; - -typedef int usbd_lock_token; - -typedef void (*usbd_callback) __P((usbd_request_handle, usbd_private_handle, - usbd_status)); - -/* Open flags */ -#define USBD_EXCLUSIVE_USE 0x01 - -/* Request flags */ -#define USBD_XFER_OUT 0x01 -#define USBD_XFER_IN 0x02 -#define USBD_SHORT_XFER_OK 0x04 - -#define USBD_NO_TIMEOUT 0 -#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */ - -usbd_status usbd_open_pipe - __P((usbd_interface_handle iface, u_int8_t address, - u_int8_t flags, usbd_pipe_handle *pipe)); -usbd_status usbd_close_pipe __P((usbd_pipe_handle pipe)); -usbd_status usbd_transfer __P((usbd_request_handle req)); -usbd_request_handle usbd_alloc_request __P((void)); -usbd_status usbd_free_request __P((usbd_request_handle reqh)); -usbd_status 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 - __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 - __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)); -#endif -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)); -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)); - -/* Non-standard */ -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 pipe, usb_device_request_t *req, void *data)); -usbd_status usbd_do_request_async - __P((usbd_device_handle pipe, usb_device_request_t *req, void *data)); -usbd_status usbd_do_request_flags - __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)); -usb_config_descriptor_t *usbd_get_config_descriptor - __P((usbd_device_handle dev)); -usb_device_descriptor_t *usbd_get_device_descriptor - __P((usbd_device_handle dev)); -usbd_status usbd_set_interface __P((usbd_interface_handle, int)); -int usbd_get_no_alts __P((usb_config_descriptor_t *, int)); -usbd_status usbd_get_interface - __P((usbd_interface_handle iface, u_int8_t *aiface)); -void usbd_fill_deviceinfo - __P((usbd_device_handle dev, struct usb_device_info *di)); -int usbd_get_interface_altindex __P((usbd_interface_handle iface)); - -usb_interface_descriptor_t *usbd_find_idesc - __P((usb_config_descriptor_t *cd, int iindex, int ano)); -usb_endpoint_descriptor_t *usbd_find_edesc - __P((usb_config_descriptor_t *cd, int ifaceidx, int altidx, - int endptidx)); - -void usbd_dopoll __P((usbd_interface_handle)); -void usbd_set_polling __P((usbd_interface_handle iface, int on)); - -/* NetBSD attachment information */ - -/* Attach data */ -struct usb_attach_arg { - int port; - int configno; - int ifaceno; - usbd_device_handle device; /* current device */ - usbd_interface_handle iface; /* current interface */ - int usegeneric; - usbd_interface_handle *ifaces; /* all interfaces */ - int nifaces; /* number of interfaces */ -}; - -#if defined(__NetBSD__) -/* Match codes. */ -/* First five codes is for a whole device. */ -#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 -/* Next six codes are for interfaces. */ -#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 -/* Generic driver */ -#define UMATCH_GENERIC 1 -/* No match */ -#define UMATCH_NONE 0 - -#elif defined(__FreeBSD__) -/* FreeBSD needs values less than zero */ -/* 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)); - -#if defined(__FreeBSD__) -int usbd_driver_load __P((module_t mod, int what, void *arg)); -void usbd_device_set_desc __P((device_t device, char *devinfo)); -char *usbd_devname(bdevice *bdev); -bus_print_child_t usbd_print_child; -#endif - -/* XXX */ -#define splusb splbio -#define IPL_USB IPL_BIO -/* XXX */ - diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c deleted file mode 100644 index fbb7a809ef40f..0000000000000 --- a/sys/dev/usb/usbdi_util.c +++ /dev/null @@ -1,511 +0,0 @@ -/* $NetBSD: usbdi_util.c,v 1.13 1999/01/08 11:58:26 augustss Exp $ */ -/* FreeBSD $Id: usbdi_util.c,v 1.5 1999/01/07 23:31:43 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/proc.h> -#if defined(__FreeBSD__) -#include <sys/bus.h> -#endif - -#include <dev/usb/usb.h> -#include <dev/usb/usbhid.h> - -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> - -#ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -extern int usbdebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif - -usbd_status -usbd_get_desc(dev, type, index, len, desc) - usbd_device_handle dev; - int type, index; - int len; - void *desc; -{ - usb_device_request_t req; - - req.bmRequestType = UT_READ_DEVICE; - req.bRequest = UR_GET_DESCRIPTOR; - USETW2(req.wValue, type, index); - USETW(req.wIndex, 0); - USETW(req.wLength, len); - return (usbd_do_request(dev, &req, desc)); -} - -usbd_status -usbd_get_config_desc(dev, conf, d) - usbd_device_handle dev; - int conf; - usb_config_descriptor_t *d; -{ - usbd_status r; - - DPRINTFN(3,("usbd_get_config_desc: conf=%d\n", conf)); - r = usbd_get_desc(dev, UDESC_CONFIG, conf, - USB_CONFIG_DESCRIPTOR_SIZE, d); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (d->bDescriptorType != UDESC_CONFIG) { - DPRINTFN(-1,("usbd_get_config_desc: conf %d, bad desc %d\n", - conf, d->bDescriptorType)); - return (USBD_INVAL); - } - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_get_config_desc_full(dev, conf, d, size) - usbd_device_handle dev; - int conf; - void *d; - int size; -{ - DPRINTFN(3,("usbd_get_config_desc_full: conf=%d\n", conf)); - return (usbd_get_desc(dev, UDESC_CONFIG, conf, size, d)); -} - -usbd_status -usbd_get_device_desc(dev, d) - usbd_device_handle dev; - usb_device_descriptor_t *d; -{ - DPRINTFN(3,("usbd_get_device_desc:\n")); - return (usbd_get_desc(dev, UDESC_DEVICE, - 0, USB_DEVICE_DESCRIPTOR_SIZE, d)); -} - -usbd_status -usbd_get_device_status(dev, st) - usbd_device_handle dev; - usb_status_t *st; -{ - usb_device_request_t req; - - req.bmRequestType = UT_READ_DEVICE; - req.bRequest = UR_GET_STATUS; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, sizeof(usb_status_t)); - return (usbd_do_request(dev, &req, st)); -} - -usbd_status -usbd_get_hub_status(dev, st) - usbd_device_handle dev; - usb_hub_status_t *st; -{ - usb_device_request_t req; - - req.bmRequestType = UT_READ_CLASS_DEVICE; - req.bRequest = UR_GET_STATUS; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, sizeof(usb_hub_status_t)); - return (usbd_do_request(dev, &req, st)); -} - -usbd_status -usbd_set_address(dev, addr) - usbd_device_handle dev; - int addr; -{ - usb_device_request_t req; - - req.bmRequestType = UT_WRITE_DEVICE; - req.bRequest = UR_SET_ADDRESS; - USETW(req.wValue, addr); - USETW(req.wIndex, 0); - USETW(req.wLength, 0); - return usbd_do_request(dev, &req, 0); -} - -usbd_status -usbd_get_port_status(dev, port, ps) - usbd_device_handle dev; - int port; - usb_port_status_t *ps; -{ - usb_device_request_t req; - - req.bmRequestType = UT_READ_CLASS_OTHER; - req.bRequest = UR_GET_STATUS; - USETW(req.wValue, 0); - USETW(req.wIndex, port); - USETW(req.wLength, sizeof *ps); - return (usbd_do_request(dev, &req, ps)); -} - -usbd_status -usbd_clear_port_feature(dev, port, sel) - usbd_device_handle dev; - int port, sel; -{ - usb_device_request_t req; - - req.bmRequestType = UT_WRITE_CLASS_OTHER; - req.bRequest = UR_CLEAR_FEATURE; - USETW(req.wValue, sel); - USETW(req.wIndex, port); - USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); -} - -usbd_status -usbd_set_port_feature(dev, port, sel) - usbd_device_handle dev; - int port, sel; -{ - usb_device_request_t req; - - req.bmRequestType = UT_WRITE_CLASS_OTHER; - req.bRequest = UR_SET_FEATURE; - USETW(req.wValue, sel); - USETW(req.wIndex, port); - USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); -} - - -usbd_status -usbd_set_protocol(iface, report) - usbd_interface_handle iface; - int report; -{ - usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; - usb_device_request_t req; - usbd_status r; - - DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n", - iface, report, id->bInterfaceNumber)); - if (!id) - return (USBD_IOERROR); - r = usbd_interface2device_handle(iface, &dev); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (!id) - return (USBD_INVAL); - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = UR_SET_PROTOCOL; - USETW(req.wValue, report); - USETW(req.wIndex, id->bInterfaceNumber); - USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); -} - -usbd_status -usbd_set_report(iface, type, id, data, len) - usbd_interface_handle iface; - int type; - int id; - void *data; - int len; -{ - usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; - usb_device_request_t req; - usbd_status r; - - DPRINTFN(4, ("usbd_set_report: len=%d\n", len)); - if (!ifd) - return (USBD_IOERROR); - r = usbd_interface2device_handle(iface, &dev); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (!ifd) - return (USBD_INVAL); - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = UR_SET_REPORT; - USETW2(req.wValue, type, id); - USETW(req.wIndex, ifd->bInterfaceNumber); - USETW(req.wLength, len); - return (usbd_do_request(dev, &req, data)); -} - -usbd_status -usbd_set_report_async(iface, type, id, data, len) - usbd_interface_handle iface; - int type; - int id; - void *data; - int len; -{ - usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; - usb_device_request_t req; - usbd_status r; - - DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len)); - if (!ifd) - return (USBD_IOERROR); - r = usbd_interface2device_handle(iface, &dev); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (!ifd) - return (USBD_INVAL); - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = UR_SET_REPORT; - USETW2(req.wValue, type, id); - USETW(req.wIndex, ifd->bInterfaceNumber); - USETW(req.wLength, len); - return (usbd_do_request_async(dev, &req, data)); -} - -usbd_status -usbd_get_report(iface, type, id, data, len) - usbd_interface_handle iface; - int type; - int id; - void *data; - int len; -{ - usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; - usb_device_request_t req; - usbd_status r; - - DPRINTFN(4, ("usbd_set_report: len=%d\n", len)); - if (!id) - return (USBD_IOERROR); - r = usbd_interface2device_handle(iface, &dev); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (!ifd) - return (USBD_INVAL); - req.bmRequestType = UT_READ_CLASS_INTERFACE; - req.bRequest = UR_GET_REPORT; - USETW2(req.wValue, type, id); - USETW(req.wIndex, ifd->bInterfaceNumber); - USETW(req.wLength, len); - return (usbd_do_request(dev, &req, data)); -} - -usbd_status -usbd_set_idle(iface, duration, id) - usbd_interface_handle iface; - int duration; - int id; -{ - usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; - usb_device_request_t req; - usbd_status r; - - DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id)); - if (!ifd) - return (USBD_IOERROR); - r = usbd_interface2device_handle(iface, &dev); - if (r != USBD_NORMAL_COMPLETION) - return (r); - if (!ifd) - return (USBD_INVAL); - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - req.bRequest = UR_SET_IDLE; - USETW2(req.wValue, duration, id); - USETW(req.wIndex, ifd->bInterfaceNumber); - USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); -} - -usbd_status -usbd_get_report_descriptor(dev, ifcno, repid, size, d) - usbd_device_handle dev; - int ifcno; - int repid; - int size; - void *d; -{ - usb_device_request_t req; - - req.bmRequestType = UT_READ_INTERFACE; - req.bRequest = UR_GET_DESCRIPTOR; - USETW2(req.wValue, UDESC_REPORT, repid); - USETW(req.wIndex, ifcno); - USETW(req.wLength, size); - return (usbd_do_request(dev, &req, d)); -} - -usb_hid_descriptor_t * -usbd_get_hid_descriptor(ifc) - usbd_interface_handle ifc; -{ - usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc); - usbd_device_handle dev; - usb_config_descriptor_t *cdesc; - usb_hid_descriptor_t *hd; - char *p, *end; - usbd_status r; - - if (!idesc) - return (0); - r = usbd_interface2device_handle(ifc, &dev); - if (r != USBD_NORMAL_COMPLETION) - return (0); - cdesc = usbd_get_config_descriptor(dev); - - p = (char *)idesc + idesc->bLength; - end = (char *)cdesc + UGETW(cdesc->wTotalLength); - - for (; p < end; p += hd->bLength) { - hd = (usb_hid_descriptor_t *)p; - if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID) - return (hd); - if (hd->bDescriptorType == UDESC_INTERFACE) - break; - } - return (0); -} - -usbd_status -usbd_alloc_report_desc(ifc, descp, sizep, mem) - usbd_interface_handle ifc; - void **descp; - int *sizep; -#if defined(__NetBSD__) - int mem; -#elif defined(__FreeBSD__) - struct malloc_type *mem; -#endif - -{ - usb_interface_descriptor_t *id; - usb_hid_descriptor_t *hid; - usbd_device_handle dev; - usbd_status r; - - r = usbd_interface2device_handle(ifc, &dev); - if (r != USBD_NORMAL_COMPLETION) - return (r); - id = usbd_get_interface_descriptor(ifc); - if (!id) - return (USBD_INVAL); - hid = usbd_get_hid_descriptor(ifc); - if (!hid) - return (USBD_IOERROR); - *sizep = UGETW(hid->descrs[0].wDescriptorLength); - *descp = malloc(*sizep, mem, M_NOWAIT); - if (!*descp) - return (USBD_NOMEM); - /* XXX should not use 0 Report ID */ - r = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0, - *sizep, *descp); - if (r != USBD_NORMAL_COMPLETION) { - free(*descp, mem); - return (r); - } - return (USBD_NORMAL_COMPLETION); -} - -usbd_status -usbd_get_config(dev, conf) - usbd_device_handle dev; - u_int8_t *conf; -{ - usb_device_request_t req; - - req.bmRequestType = UT_READ_DEVICE; - req.bRequest = UR_GET_CONFIG; - USETW(req.wValue, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, 1); - return (usbd_do_request(dev, &req, conf)); -} - -static void usbd_bulk_transfer_cb __P((usbd_request_handle reqh, - usbd_private_handle priv, usbd_status status)); -static void -usbd_bulk_transfer_cb(reqh, priv, status) - usbd_request_handle reqh; - usbd_private_handle priv; - usbd_status status; -{ - wakeup(reqh); -} - -usbd_status -usbd_bulk_transfer(reqh, pipe, flags, buf, size, lbl) - usbd_request_handle reqh; - usbd_pipe_handle pipe; - u_int16_t flags; - void *buf; - u_int32_t *size; - char *lbl; -{ - usbd_private_handle priv; - void *buffer; - usbd_status r; - int s, error; - - r = usbd_setup_request(reqh, pipe, 0, buf, *size, - flags, USBD_NO_TIMEOUT, usbd_bulk_transfer_cb); - if (r != USBD_NORMAL_COMPLETION) - return (r); - DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size)); - s = splusb(); /* don't want callback until tsleep() */ - r = usbd_transfer(reqh); - if (r != USBD_IN_PROGRESS) { - splx(s); - return (r); - } - error = tsleep((caddr_t)reqh, PZERO | PCATCH, lbl, 0); - splx(s); - if (error) { - usbd_abort_pipe(pipe); - return (USBD_INTERRUPTED); - } - usbd_get_request_status(reqh, &priv, &buffer, size, &r); - DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size)); - if (r != USBD_NORMAL_COMPLETION) { - DPRINTF(("usbd_bulk_transfer: error=%d\n", r)); - usbd_clear_endpoint_stall(pipe); - } - return (r); -} - diff --git a/sys/dev/usb/usbdi_util.h b/sys/dev/usb/usbdi_util.h deleted file mode 100644 index f5d700d1d91ce..0000000000000 --- a/sys/dev/usb/usbdi_util.h +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD: usbdi_util.h,v 1.12 1999/01/01 15:25:57 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -usbd_status usbd_get_desc __P((usbd_device_handle dev, int type, - int index, int len, void *desc)); -usbd_status usbd_get_config_desc __P((usbd_device_handle, int, - usb_config_descriptor_t *)); -usbd_status usbd_get_config_desc_full __P((usbd_device_handle, int, - void *, int)); -usbd_status usbd_get_device_desc __P((usbd_device_handle dev, - usb_device_descriptor_t *d)); -usbd_status usbd_set_address __P((usbd_device_handle dev, int addr)); -usbd_status usbd_get_port_status __P((usbd_device_handle, - int, usb_port_status_t *)); -usbd_status usbd_set_port_feature __P((usbd_device_handle dev, int, int)); -usbd_status usbd_clear_port_feature __P((usbd_device_handle, int, int)); -usbd_status usbd_get_device_status __P((usbd_device_handle,usb_status_t*)); -usbd_status usbd_get_hub_status __P((usbd_device_handle dev, - usb_hub_status_t *st)); -usbd_status usbd_set_protocol __P((usbd_interface_handle dev, int report)); -usbd_status usbd_get_report_descriptor - __P((usbd_device_handle dev, int ifcno, int repid, int size, void *d)); -struct usb_hid_descriptor *usbd_get_hid_descriptor - __P((usbd_interface_handle ifc)); -usbd_status usbd_set_report - __P((usbd_interface_handle iface,int type,int id,void *data,int len)); -usbd_status usbd_set_report_async - __P((usbd_interface_handle iface,int type,int id,void *data,int len)); -usbd_status usbd_get_report - __P((usbd_interface_handle iface,int type,int id,void *data,int len)); -usbd_status usbd_set_idle - __P((usbd_interface_handle iface, int duration, int id)); -#if defined(__NetBSD__) -usbd_status usbd_alloc_report_desc - __P((usbd_interface_handle ifc, void **descp, int *sizep, int mem)); -#elif defined(__FreeBSD__) -usbd_status usbd_alloc_report_desc - __P((usbd_interface_handle ifc, void **descp, int *sizep, struct malloc_type * mem)); -#endif -usbd_status usbd_get_config - __P((usbd_device_handle dev, u_int8_t *conf)); -usbd_status usbd_get_string_desc - __P((usbd_device_handle dev, int sindex, int langid, - usb_string_descriptor_t *sdesc)); -void usbd_delay_ms __P((usbd_device_handle, u_int)); - - -usbd_status usbd_set_config_no - __P((usbd_device_handle dev, int no, int msg)); -usbd_status usbd_set_config_index - __P((usbd_device_handle dev, int index, int msg)); - -usbd_status usbd_bulk_transfer - __P((usbd_request_handle reqh, usbd_pipe_handle pipe, u_int16_t flags, - void *buf, u_int32_t *size, char *lbl)); diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h deleted file mode 100644 index 7c89b777e3d03..0000000000000 --- a/sys/dev/usb/usbdivar.h +++ /dev/null @@ -1,227 +0,0 @@ -/* $NetBSD: usbdivar.h,v 1.16 1999/01/08 11:58:26 augustss Exp $ */ -/* FreeBSD $Id: usbdivar.h,v 1.6 1999/01/07 23:31:45 n_hibma Exp $ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -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_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)); -}; - -struct usbd_port { - usb_port_status_t status; - u_int16_t power; /* mA of current on port */ - u_int8_t portno; - u_int8_t restartcnt; -#define USBD_RESTART_MAX 5 - struct usbd_device *device; - struct usbd_device *parent; /* The ports hub */ -}; - -struct usbd_hub { - usbd_status (*explore)__P((usbd_device_handle hub)); - void *hubsoftc; - usb_hub_descriptor_t hubdesc; - struct usbd_port ports[1]; -}; - -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)); - 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]; - char needs_explore;/* a hub a signalled a change */ - char use_polling; - struct usb_softc *usbctl; - struct usb_device_stats stats; -}; - -struct usbd_device { - struct usbd_bus *bus; - usbd_device_state state; - struct usbd_pipe *default_pipe; - u_int8_t address; - u_int8_t depth; - u_int8_t lowspeed; - u_int16_t power; - u_int8_t self_powered; - int config; - int langid; /* language to use for strings */ -#define USBD_NOLANG (-1) - struct usbd_port *powersrc; - struct usbd_endpoint def_ep; /* for pipe 0 */ - usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */ - struct usbd_interface *ifaces; - usb_device_descriptor_t ddesc; - 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 */ -}; - -struct usbd_interface { - struct usbd_device *device; - usbd_interface_state state; - usb_interface_descriptor_t *idesc; - int index; - int altindex; - struct usbd_endpoint *endpoints; - void *priv; - LIST_HEAD(, usbd_pipe) pipes; -}; - -struct usbd_pipe { - struct usbd_interface *iface; - struct usbd_device *device; - struct usbd_endpoint *endpoint; - usbd_pipe_state state; - int32_t 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 */ - - /* Filled by HC driver. */ - struct usbd_methods *methods; -}; - -struct usbd_request { - struct usbd_pipe *pipe; - void *priv; - void *buffer; - u_int32_t length; - u_int32_t actlen; - u_int16_t flags; - u_int32_t timeout; - usbd_status status; - usbd_callback callback; - usbd_xfercb xfercb; - u_int32_t retries; - char done; - - usb_device_request_t request; - u_int8_t isreq; - - SIMPLEQ_ENTRY(usbd_request) next; - - void *hcpriv; /* XXX private use by the HC driver */ - -#if defined(__FreeBSD__) - 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)); -void usbd_devinfo_vp __P((usbd_device_handle, char *, char *)); -usbd_status usbd_reset_port __P((usbd_device_handle dev, - int port, usb_port_status_t *ps)); -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_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)); - -/* Routines from usb.c */ -int usb_bus_count __P((void)); -usbd_status usb_get_bus_handle __P((int, usbd_bus_handle *)); -void usb_needs_explore __P((usbd_bus_handle)); - -/* Locator stuff. */ - -#if defined(__NetBSD__) -#include "locators.h" -#elif defined(__FreeBSD__) -/* 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. - * The values are copied from the files.usb file in the NetBSD sources. - */ -#define UHUBCF_PORT_DEFAULT -1 -#define UHUBCF_CONFIGURATION_DEFAULT -1 -#define UHUBCF_INTERFACE_DEFAULT -1 -#endif - -#define uhubcf_port cf_loc[UHUBCF_PORT] -#define uhubcf_configuration cf_loc[UHUBCF_CONFIGURATION] -#define uhubcf_interface cf_loc[UHUBCF_INTERFACE] -#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' */ - diff --git a/sys/dev/usb/usbhid.h b/sys/dev/usb/usbhid.h deleted file mode 100644 index edec4130e1473..0000000000000 --- a/sys/dev/usb/usbhid.h +++ /dev/null @@ -1,135 +0,0 @@ -/* $NetBSD: usbhid.h,v 1.3 1998/12/26 12:53:04 augustss Exp $ */ -/* FreeBSD $Id$ */ - -/* - * Copyright (c) 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Lennart Augustsson (augustss@carlstedt.se) at - * Carlstedt Research & Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef _USBHID_H_ -#define _USBHID_H_ - -#define UR_GET_HID_DESCRIPTOR 0x06 -#define UDESC_HID 0x21 -#define UDESC_REPORT 0x22 -#define UDESC_PHYSICAL 0x23 -#define UR_SET_HID_DESCRIPTOR 0x07 -#define UR_GET_REPORT 0x01 -#define UR_SET_REPORT 0x09 -#define UR_GET_IDLE 0x02 -#define UR_SET_IDLE 0x0a -#define UR_GET_PROTOCOL 0x03 -#define UR_SET_PROTOCOL 0x0b - -typedef struct usb_hid_descriptor { - uByte bLength; - uByte bDescriptorType; - uWord bcdHID; - uByte bCountryCode; - uByte bNumDescriptors; - struct { - uByte bDescriptorType; - uWord wDescriptorLength; - } descrs[1]; -} usb_hid_descriptor_t; -#define USB_HID_DESCRIPTOR_SIZE(n) (9+(n)*3) - -/* Usage pages */ -#define HUP_GENERIC_DESKTOP 0x0001 -#define HUP_SIMULATION 0x0002 -#define HUP_LEDS 0x0008 -#define HUP_BUTTON 0x0009 - -/* Usages, generic desktop */ -#define HUG_POINTER 0x0001 -#define HUG_MOUSE 0x0002 -#define HUG_JOYSTICK 0x0004 -#define HUG_GAME_PAD 0x0005 -#define HUG_KEYBOARD 0x0006 -#define HUG_KEYPAD 0x0007 -#define HUG_X 0x0030 -#define HUG_Y 0x0031 -#define HUG_Z 0x0032 -#define HUG_RX 0x0033 -#define HUG_RY 0x0034 -#define HUG_RZ 0x0035 -#define HUG_SLIDER 0x0036 -#define HUG_DIAL 0x0037 -#define HUG_WHEEL 0x0038 -#define HUG_HAT_SWITCH 0x0039 -#define HUG_COUNTED_BUFFER 0x003a -#define HUG_BYTE_COUNT 0x003b -#define HUG_MOTION_WAKEUP 0x003c -#define HUG_VX 0x0040 -#define HUG_VY 0x0041 -#define HUG_VZ 0x0042 -#define HUG_VBRX 0x0043 -#define HUG_VBRY 0x0044 -#define HUG_VBRZ 0x0045 -#define HUG_VNO 0x0046 -#define HUG_SYSTEM_CONTROL 0x0080 -#define HUG_SYSTEM_POWER_DOWN 0x0081 -#define HUG_SYSTEM_SLEEP 0x0082 -#define HUG_SYSTEM_WAKEUP 0x0083 -#define HUG_SYSTEM_CONTEXT_MENU 0x0084 -#define HUG_SYSTEM_MAIN_MENU 0x0085 -#define HUG_SYSTEM_APP_MENU 0x0086 -#define HUG_SYSTEM_MENU_HELP 0x0087 -#define HUG_SYSTEM_MENU_EXIT 0x0088 -#define HUG_SYSTEM_MENU_SELECT 0x0089 -#define HUG_SYSTEM_MENU_RIGHT 0x008a -#define HUG_SYSTEM_MENU_LEFT 0x008b -#define HUG_SYSTEM_MENU_UP 0x008c -#define HUG_SYSTEM_MENU_DOWN 0x008d - -#define HID_USAGE2(p,u) (((p) << 16) | u) - -#define UHID_INPUT_REPORT 0x01 -#define UHID_OUTPUT_REPORT 0x02 -#define UHID_FEATURE_REPORT 0x03 - -/* Bits in the input/output/feature items */ -#define HIO_CONST 0x001 -#define HIO_VARIABLE 0x002 -#define HIO_RELATIVE 0x004 -#define HIO_WRAP 0x008 -#define HIO_NONLINEAR 0x010 -#define HIO_NOPREF 0x020 -#define HIO_NULLSTATE 0x040 -#define HIO_VOLATILE 0x080 -#define HIO_BUFBYTES 0x100 - -#endif /* _USBHID_H_ */ |
