jcs's openbsd hax
openbsd
at jcs 134 lines 3.7 kB view raw
1/* $OpenBSD: ucrcom.c,v 1.3 2024/05/23 03:21:09 jsg Exp $ */ 2 3/* 4 * Copyright (c) 2019 Mark Kettenis <kettenis@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/param.h> 20#include <sys/systm.h> 21#include <sys/tty.h> 22#include <sys/device.h> 23 24#include <dev/usb/usb.h> 25#include <dev/usb/usbdi.h> 26#include <dev/usb/usbdevs.h> 27 28#include <dev/usb/ucomvar.h> 29 30#define UCRCOMBUFSZ 64 31 32struct ucrcom_softc { 33 struct device sc_dev; 34 struct device *sc_subdev; 35}; 36 37const struct ucom_methods ucrcom_methods = { NULL }; 38 39int ucrcom_match(struct device *, void *, void *); 40void ucrcom_attach(struct device *, struct device *, void *); 41int ucrcom_detach(struct device *, int); 42 43struct cfdriver ucrcom_cd = { 44 NULL, "ucrcom", DV_DULL 45}; 46 47const struct cfattach ucrcom_ca = { 48 sizeof(struct ucrcom_softc), ucrcom_match, ucrcom_attach, ucrcom_detach 49}; 50 51int 52ucrcom_match(struct device *parent, void *match, void *aux) 53{ 54 struct usb_attach_arg *uaa = aux; 55 usb_interface_descriptor_t *id; 56 usb_device_descriptor_t *dd; 57 58 if (uaa->iface == NULL) 59 return UMATCH_NONE; 60 61 id = usbd_get_interface_descriptor(uaa->iface); 62 dd = usbd_get_device_descriptor(uaa->device); 63 if (id == NULL || dd == NULL) 64 return UMATCH_NONE; 65 66 if (UGETW(dd->idVendor) == USB_VENDOR_GOOGLE && 67 id->bInterfaceClass == UICLASS_VENDOR && 68 id->bInterfaceSubClass == 0x50 && 69 id->bInterfaceProtocol == 1) 70 return UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO; 71 72 return UMATCH_NONE; 73} 74 75void 76ucrcom_attach(struct device *parent, struct device *self, void *aux) 77{ 78 struct ucrcom_softc *sc = (struct ucrcom_softc *)self; 79 struct usb_attach_arg *uaa = aux; 80 struct ucom_attach_args uca; 81 usb_interface_descriptor_t *id; 82 usb_endpoint_descriptor_t *ed; 83 int i; 84 85 id = usbd_get_interface_descriptor(uaa->iface); 86 87 memset(&uca, 0, sizeof(uca)); 88 uca.bulkin = uca.bulkout = -1; 89 for (i = 0; i < id->bNumEndpoints; i++) { 90 ed = usbd_interface2endpoint_descriptor(uaa->iface, i); 91 if (ed == NULL) { 92 printf("%s: no endpoint descriptor for %d\n", 93 sc->sc_dev.dv_xname, i); 94 usbd_deactivate(uaa->device); 95 return; 96 } 97 98 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 99 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) 100 uca.bulkin = ed->bEndpointAddress; 101 else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 102 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) 103 uca.bulkout = ed->bEndpointAddress; 104 } 105 106 if (uca.bulkin == -1 || uca.bulkout == -1) { 107 printf("%s: missing endpoint\n", sc->sc_dev.dv_xname); 108 usbd_deactivate(uaa->device); 109 return; 110 } 111 112 uca.ibufsize = UCRCOMBUFSZ; 113 uca.ibufsizepad = UCRCOMBUFSZ; 114 uca.obufsize = UCRCOMBUFSZ; 115 uca.opkthdrlen = 0; 116 uca.device = uaa->device; 117 uca.iface = uaa->iface; 118 uca.methods = &ucrcom_methods; 119 uca.arg = sc; 120 121 sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch); 122} 123 124int 125ucrcom_detach(struct device *self, int flags) 126{ 127 struct ucrcom_softc *sc = (struct ucrcom_softc *)self; 128 int rv = 0; 129 130 if (sc->sc_subdev != NULL) 131 rv = config_detach(sc->sc_subdev, flags); 132 133 return rv; 134}