Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/usb/usb_hub.c
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/condvar.h> | #include <sys/condvar.h> | ||||
#include <sys/sbuf.h> | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/unistd.h> | #include <sys/unistd.h> | ||||
#include <sys/callout.h> | #include <sys/callout.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <dev/usb/usb.h> | #include <dev/usb/usb.h> | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
#define UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB) | #define UHUB_IS_SUPER_SPEED(sc) (UHUB_PROTO(sc) == UDPROTO_SSHUB) | ||||
/* prototypes for type checking: */ | /* prototypes for type checking: */ | ||||
static device_suspend_t uhub_suspend; | static device_suspend_t uhub_suspend; | ||||
static device_resume_t uhub_resume; | static device_resume_t uhub_resume; | ||||
static bus_driver_added_t uhub_driver_added; | static bus_driver_added_t uhub_driver_added; | ||||
static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string; | static bus_child_pnpinfo_t uhub_child_pnpinfo; | ||||
static usb_callback_t uhub_intr_callback; | static usb_callback_t uhub_intr_callback; | ||||
#if USB_HAVE_TT_SUPPORT | #if USB_HAVE_TT_SUPPORT | ||||
static usb_callback_t uhub_reset_tt_callback; | static usb_callback_t uhub_reset_tt_callback; | ||||
#endif | #endif | ||||
static void usb_dev_resume_peer(struct usb_device *udev); | static void usb_dev_resume_peer(struct usb_device *udev); | ||||
static void usb_dev_suspend_peer(struct usb_device *udev); | static void usb_dev_suspend_peer(struct usb_device *udev); | ||||
Show All 32 Lines | |||||
static device_method_t uhub_methods[] = { | static device_method_t uhub_methods[] = { | ||||
DEVMETHOD(device_probe, uhub_probe), | DEVMETHOD(device_probe, uhub_probe), | ||||
DEVMETHOD(device_attach, uhub_attach), | DEVMETHOD(device_attach, uhub_attach), | ||||
DEVMETHOD(device_detach, uhub_detach), | DEVMETHOD(device_detach, uhub_detach), | ||||
DEVMETHOD(device_suspend, uhub_suspend), | DEVMETHOD(device_suspend, uhub_suspend), | ||||
DEVMETHOD(device_resume, uhub_resume), | DEVMETHOD(device_resume, uhub_resume), | ||||
DEVMETHOD(bus_child_location_str, uhub_child_location_string), | DEVMETHOD(bus_child_location, uhub_child_location), | ||||
DEVMETHOD(bus_child_pnpinfo_str, uhub_child_pnpinfo_string), | DEVMETHOD(bus_child_pnpinfo, uhub_child_pnpinfo), | ||||
DEVMETHOD(bus_driver_added, uhub_driver_added), | DEVMETHOD(bus_driver_added, uhub_driver_added), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
driver_t uhub_driver = { | driver_t uhub_driver = { | ||||
.name = "uhub", | .name = "uhub", | ||||
.methods = uhub_methods, | .methods = uhub_methods, | ||||
.size = sizeof(struct uhub_softc) | .size = sizeof(struct uhub_softc) | ||||
▲ Show 20 Lines • Show All 1,454 Lines • ▼ Show 20 Lines | for (x = 0; x != nports; x++) { | ||||
} | } | ||||
} | } | ||||
res->iface_index = 0; | res->iface_index = 0; | ||||
res->udev = NULL; | res->udev = NULL; | ||||
res->portno = 0; | res->portno = 0; | ||||
} | } | ||||
int | int | ||||
uhub_child_location_string(device_t parent, device_t child, | uhub_child_location(device_t parent, device_t child, struct sbuf *sb) | ||||
char *buf, size_t buflen) | |||||
{ | { | ||||
struct uhub_softc *sc; | struct uhub_softc *sc; | ||||
struct usb_hub *hub; | struct usb_hub *hub; | ||||
struct hub_result res; | struct hub_result res; | ||||
if (!device_is_attached(parent)) { | if (!device_is_attached(parent)) | ||||
if (buflen) | |||||
buf[0] = 0; | |||||
return (0); | return (0); | ||||
} | |||||
sc = device_get_softc(parent); | sc = device_get_softc(parent); | ||||
hub = sc->sc_udev->hub; | hub = sc->sc_udev->hub; | ||||
mtx_lock(&Giant); | mtx_lock(&Giant); | ||||
uhub_find_iface_index(hub, child, &res); | uhub_find_iface_index(hub, child, &res); | ||||
if (!res.udev) { | if (!res.udev) { | ||||
DPRINTF("device not on hub\n"); | DPRINTF("device not on hub\n"); | ||||
if (buflen) { | |||||
buf[0] = '\0'; | |||||
} | |||||
goto done; | goto done; | ||||
} | } | ||||
snprintf(buf, buflen, "bus=%u hubaddr=%u port=%u devaddr=%u" | sbuf_printf(sb, "bus=%u hubaddr=%u port=%u devaddr=%u" | ||||
" interface=%u" | " interface=%u" | ||||
#if USB_HAVE_UGEN | #if USB_HAVE_UGEN | ||||
" ugen=%s" | " ugen=%s" | ||||
#endif | #endif | ||||
, device_get_unit(res.udev->bus->bdev) | , device_get_unit(res.udev->bus->bdev) | ||||
, (res.udev->parent_hub != NULL) ? | , (res.udev->parent_hub != NULL) ? | ||||
res.udev->parent_hub->device_index : 0 | res.udev->parent_hub->device_index : 0 | ||||
, res.portno, res.udev->device_index, res.iface_index | , res.portno, res.udev->device_index, res.iface_index | ||||
#if USB_HAVE_UGEN | #if USB_HAVE_UGEN | ||||
, res.udev->ugen_name | , res.udev->ugen_name | ||||
#endif | #endif | ||||
); | ); | ||||
done: | done: | ||||
mtx_unlock(&Giant); | mtx_unlock(&Giant); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
uhub_child_pnpinfo_string(device_t parent, device_t child, | uhub_child_pnpinfo(device_t parent, device_t child, struct sbuf*sb) | ||||
char *buf, size_t buflen) | |||||
{ | { | ||||
struct uhub_softc *sc; | struct uhub_softc *sc; | ||||
struct usb_hub *hub; | struct usb_hub *hub; | ||||
struct usb_interface *iface; | struct usb_interface *iface; | ||||
struct hub_result res; | struct hub_result res; | ||||
uint8_t do_unlock; | uint8_t do_unlock; | ||||
if (!device_is_attached(parent)) { | if (!device_is_attached(parent)) | ||||
if (buflen) | |||||
buf[0] = 0; | |||||
return (0); | return (0); | ||||
} | |||||
sc = device_get_softc(parent); | sc = device_get_softc(parent); | ||||
hub = sc->sc_udev->hub; | hub = sc->sc_udev->hub; | ||||
mtx_lock(&Giant); | mtx_lock(&Giant); | ||||
uhub_find_iface_index(hub, child, &res); | uhub_find_iface_index(hub, child, &res); | ||||
if (!res.udev) { | if (!res.udev) { | ||||
DPRINTF("device not on hub\n"); | DPRINTF("device not on hub\n"); | ||||
if (buflen) { | |||||
buf[0] = '\0'; | |||||
} | |||||
goto done; | goto done; | ||||
} | } | ||||
iface = usbd_get_iface(res.udev, res.iface_index); | iface = usbd_get_iface(res.udev, res.iface_index); | ||||
if (iface && iface->idesc) { | if (iface && iface->idesc) { | ||||
/* Make sure device information is not changed during the print. */ | /* Make sure device information is not changed during the print. */ | ||||
do_unlock = usbd_ctrl_lock(res.udev); | do_unlock = usbd_ctrl_lock(res.udev); | ||||
snprintf(buf, buflen, "vendor=0x%04x product=0x%04x " | sbuf_printf(sb, "vendor=0x%04x product=0x%04x " | ||||
"devclass=0x%02x devsubclass=0x%02x " | "devclass=0x%02x devsubclass=0x%02x " | ||||
"devproto=0x%02x " | "devproto=0x%02x " | ||||
"sernum=\"%s\" " | "sernum=\"%s\" " | ||||
"release=0x%04x " | "release=0x%04x " | ||||
"mode=%s " | "mode=%s " | ||||
"intclass=0x%02x intsubclass=0x%02x " | "intclass=0x%02x intsubclass=0x%02x " | ||||
"intprotocol=0x%02x" "%s%s", | "intprotocol=0x%02x" "%s%s", | ||||
UGETW(res.udev->ddesc.idVendor), | UGETW(res.udev->ddesc.idVendor), | ||||
UGETW(res.udev->ddesc.idProduct), | UGETW(res.udev->ddesc.idProduct), | ||||
res.udev->ddesc.bDeviceClass, | res.udev->ddesc.bDeviceClass, | ||||
res.udev->ddesc.bDeviceSubClass, | res.udev->ddesc.bDeviceSubClass, | ||||
res.udev->ddesc.bDeviceProtocol, | res.udev->ddesc.bDeviceProtocol, | ||||
usb_get_serial(res.udev), | usb_get_serial(res.udev), | ||||
UGETW(res.udev->ddesc.bcdDevice), | UGETW(res.udev->ddesc.bcdDevice), | ||||
(res.udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device", | (res.udev->flags.usb_mode == USB_MODE_HOST) ? "host" : "device", | ||||
iface->idesc->bInterfaceClass, | iface->idesc->bInterfaceClass, | ||||
iface->idesc->bInterfaceSubClass, | iface->idesc->bInterfaceSubClass, | ||||
iface->idesc->bInterfaceProtocol, | iface->idesc->bInterfaceProtocol, | ||||
iface->pnpinfo ? " " : "", | iface->pnpinfo ? " " : "", | ||||
iface->pnpinfo ? iface->pnpinfo : ""); | iface->pnpinfo ? iface->pnpinfo : ""); | ||||
if (do_unlock) | if (do_unlock) | ||||
usbd_ctrl_unlock(res.udev); | usbd_ctrl_unlock(res.udev); | ||||
} else { | |||||
if (buflen) { | |||||
buf[0] = '\0'; | |||||
} | |||||
goto done; | |||||
} | } | ||||
done: | done: | ||||
mtx_unlock(&Giant); | mtx_unlock(&Giant); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 1,219 Lines • Show Last 20 Lines |