1 1.178 skrll /* $NetBSD: ugen.c,v 1.178 2025/04/26 07:08:48 skrll Exp $ */ 2 1.1 augustss 3 1.1 augustss /* 4 1.71 mycroft * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. 5 1.1 augustss * All rights reserved. 6 1.1 augustss * 7 1.1 augustss * This code is derived from software contributed to The NetBSD Foundation 8 1.38 augustss * by Lennart Augustsson (lennart (at) augustsson.net) at 9 1.1 augustss * Carlstedt Research & Technology. 10 1.1 augustss * 11 1.84 gdt * Copyright (c) 2006 BBN Technologies Corp. All rights reserved. 12 1.84 gdt * Effort sponsored in part by the Defense Advanced Research Projects 13 1.84 gdt * Agency (DARPA) and the Department of the Interior National Business 14 1.84 gdt * Center under agreement number NBCHC050166. 15 1.84 gdt * 16 1.1 augustss * Redistribution and use in source and binary forms, with or without 17 1.1 augustss * modification, are permitted provided that the following conditions 18 1.1 augustss * are met: 19 1.1 augustss * 1. Redistributions of source code must retain the above copyright 20 1.1 augustss * notice, this list of conditions and the following disclaimer. 21 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright 22 1.1 augustss * notice, this list of conditions and the following disclaimer in the 23 1.1 augustss * documentation and/or other materials provided with the distribution. 24 1.1 augustss * 25 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 1.1 augustss * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 1.1 augustss * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 1.1 augustss * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 1.1 augustss * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 1.1 augustss * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 1.1 augustss * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 1.1 augustss * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 1.1 augustss * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 1.1 augustss * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 1.1 augustss * POSSIBILITY OF SUCH DAMAGE. 36 1.1 augustss */ 37 1.1 augustss 38 1.50 lukem 39 1.50 lukem #include <sys/cdefs.h> 40 1.178 skrll __KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.178 2025/04/26 07:08:48 skrll Exp $"); 41 1.84 gdt 42 1.122 christos #ifdef _KERNEL_OPT 43 1.89 pavel #include "opt_compat_netbsd.h" 44 1.126 gson #include "opt_usb.h" 45 1.122 christos #endif 46 1.1 augustss 47 1.1 augustss #include <sys/param.h> 48 1.1 augustss #include <sys/systm.h> 49 1.1 augustss #include <sys/kernel.h> 50 1.133 skrll #include <sys/kmem.h> 51 1.1 augustss #include <sys/device.h> 52 1.1 augustss #include <sys/ioctl.h> 53 1.12 augustss #include <sys/conf.h> 54 1.1 augustss #include <sys/tty.h> 55 1.1 augustss #include <sys/file.h> 56 1.1 augustss #include <sys/select.h> 57 1.1 augustss #include <sys/proc.h> 58 1.1 augustss #include <sys/vnode.h> 59 1.1 augustss #include <sys/poll.h> 60 1.142 pgoyette #include <sys/compat_stub.h> 61 1.155 riastrad #include <sys/module.h> 62 1.155 riastrad #include <sys/rbtree.h> 63 1.1 augustss 64 1.1 augustss #include <dev/usb/usb.h> 65 1.1 augustss #include <dev/usb/usbdi.h> 66 1.1 augustss #include <dev/usb/usbdi_util.h> 67 1.169 mrg #include <dev/usb/usbhist.h> 68 1.1 augustss 69 1.146 mrg #include "ioconf.h" 70 1.146 mrg 71 1.169 mrg #ifdef USB_DEBUG 72 1.169 mrg #ifndef UGEN_DEBUG 73 1.169 mrg #define ugendebug 0 74 1.169 mrg #else 75 1.172 mrg 76 1.172 mrg #ifndef UGEN_DEBUG_DEFAULT 77 1.172 mrg #define UGEN_DEBUG_DEFAULT 0 78 1.172 mrg #endif 79 1.172 mrg 80 1.172 mrg int ugendebug = UGEN_DEBUG_DEFAULT; 81 1.169 mrg 82 1.169 mrg SYSCTL_SETUP(sysctl_hw_ugen_setup, "sysctl hw.ugen setup") 83 1.169 mrg { 84 1.169 mrg int err; 85 1.169 mrg const struct sysctlnode *rnode; 86 1.169 mrg const struct sysctlnode *cnode; 87 1.169 mrg 88 1.169 mrg err = sysctl_createv(clog, 0, NULL, &rnode, 89 1.169 mrg CTLFLAG_PERMANENT, CTLTYPE_NODE, "ugen", 90 1.169 mrg SYSCTL_DESCR("ugen global controls"), 91 1.169 mrg NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 92 1.169 mrg 93 1.169 mrg if (err) 94 1.169 mrg goto fail; 95 1.169 mrg 96 1.169 mrg /* control debugging printfs */ 97 1.169 mrg err = sysctl_createv(clog, 0, &rnode, &cnode, 98 1.169 mrg CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 99 1.169 mrg "debug", SYSCTL_DESCR("Enable debugging output"), 100 1.169 mrg NULL, 0, &ugendebug, sizeof(ugendebug), CTL_CREATE, CTL_EOL); 101 1.169 mrg if (err) 102 1.169 mrg goto fail; 103 1.169 mrg 104 1.169 mrg return; 105 1.169 mrg fail: 106 1.169 mrg aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 107 1.169 mrg } 108 1.169 mrg 109 1.169 mrg #endif /* UGEN_DEBUG */ 110 1.169 mrg #endif /* USB_DEBUG */ 111 1.169 mrg 112 1.169 mrg #define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(ugendebug,1,FMT,A,B,C,D) 113 1.169 mrg #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(ugendebug,N,FMT,A,B,C,D) 114 1.169 mrg #define UGENHIST_FUNC() USBHIST_FUNC() 115 1.169 mrg #define UGENHIST_CALLED(name) USBHIST_CALLED(ugendebug) 116 1.172 mrg #define UGENHIST_CALLARGS(FMT,A,B,C,D) \ 117 1.172 mrg USBHIST_CALLARGS(ugendebug,FMT,A,B,C,D) 118 1.172 mrg #define UGENHIST_CALLARGSN(N,FMT,A,B,C,D) \ 119 1.172 mrg USBHIST_CALLARGSN(ugendebug,N,FMT,A,B,C,D) 120 1.1 augustss 121 1.41 augustss #define UGEN_CHUNK 128 /* chunk size for read */ 122 1.41 augustss #define UGEN_IBSIZE 1020 /* buffer size */ 123 1.41 augustss #define UGEN_BBSIZE 1024 124 1.41 augustss 125 1.110 jakllsch #define UGEN_NISOREQS 4 /* number of outstanding xfer requests */ 126 1.110 jakllsch #define UGEN_NISORFRMS 8 /* number of transactions per req */ 127 1.110 jakllsch #define UGEN_NISOFRAMES (UGEN_NISORFRMS * UGEN_NISOREQS) 128 1.41 augustss 129 1.84 gdt #define UGEN_BULK_RA_WB_BUFSIZE 16384 /* default buffer size */ 130 1.84 gdt #define UGEN_BULK_RA_WB_BUFMAX (1 << 20) /* maximum allowed buffer */ 131 1.84 gdt 132 1.125 matt struct isoreq { 133 1.125 matt struct ugen_endpoint *sce; 134 1.133 skrll struct usbd_xfer *xfer; 135 1.125 matt void *dmabuf; 136 1.133 skrll uint16_t sizes[UGEN_NISORFRMS]; 137 1.125 matt }; 138 1.125 matt 139 1.1 augustss struct ugen_endpoint { 140 1.1 augustss struct ugen_softc *sc; 141 1.1 augustss usb_endpoint_descriptor_t *edesc; 142 1.133 skrll struct usbd_interface *iface; 143 1.1 augustss int state; 144 1.8 augustss #define UGEN_SHORT_OK 0x04 /* short xfers are OK */ 145 1.84 gdt #define UGEN_BULK_RA 0x08 /* in bulk read-ahead mode */ 146 1.84 gdt #define UGEN_BULK_WB 0x10 /* in bulk write-behind mode */ 147 1.84 gdt #define UGEN_RA_WB_STOP 0x20 /* RA/WB xfer is stopped (buffer full/empty) */ 148 1.133 skrll struct usbd_pipe *pipeh; 149 1.1 augustss struct clist q; 150 1.41 augustss u_char *ibuf; /* start of buffer (circular for isoc) */ 151 1.41 augustss u_char *fill; /* location for input (isoc) */ 152 1.41 augustss u_char *limit; /* end of circular buffer (isoc) */ 153 1.41 augustss u_char *cur; /* current read location (isoc) */ 154 1.133 skrll uint32_t timeout; 155 1.133 skrll uint32_t ra_wb_bufsize; /* requested size for RA/WB buffer */ 156 1.133 skrll uint32_t ra_wb_reqsize; /* requested xfer length for RA/WB */ 157 1.133 skrll uint32_t ra_wb_used; /* how much is in buffer */ 158 1.133 skrll uint32_t ra_wb_xferlen; /* current xfer length for RA/WB */ 159 1.133 skrll struct usbd_xfer *ra_wb_xfer; 160 1.125 matt struct isoreq isoreqs[UGEN_NISOREQS]; 161 1.121 riastrad /* Keep these last; we don't overwrite them in ugen_set_config() */ 162 1.121 riastrad #define UGEN_ENDPOINT_NONZERO_CRUFT offsetof(struct ugen_endpoint, rsel) 163 1.121 riastrad struct selinfo rsel; 164 1.121 riastrad kcondvar_t cv; 165 1.1 augustss }; 166 1.1 augustss 167 1.1 augustss struct ugen_softc { 168 1.111 dyoung device_t sc_dev; /* base device */ 169 1.133 skrll struct usbd_device *sc_udev; 170 1.155 riastrad struct rb_node sc_node; 171 1.155 riastrad unsigned sc_unit; 172 1.1 augustss 173 1.120 mrg kmutex_t sc_lock; 174 1.120 mrg kcondvar_t sc_detach_cv; 175 1.120 mrg 176 1.13 augustss char sc_is_open[USB_MAX_ENDPOINTS]; 177 1.1 augustss struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2]; 178 1.21 augustss #define OUT 0 179 1.21 augustss #define IN 1 180 1.1 augustss 181 1.12 augustss int sc_refcnt; 182 1.83 christos char sc_buffer[UGEN_BBSIZE]; 183 1.12 augustss u_char sc_dying; 184 1.157 riastrad u_char sc_attached; 185 1.1 augustss }; 186 1.1 augustss 187 1.155 riastrad static struct { 188 1.155 riastrad kmutex_t lock; 189 1.155 riastrad rb_tree_t tree; 190 1.155 riastrad } ugenif __cacheline_aligned; 191 1.155 riastrad 192 1.155 riastrad static int 193 1.155 riastrad compare_ugen(void *cookie, const void *vsca, const void *vscb) 194 1.155 riastrad { 195 1.155 riastrad const struct ugen_softc *sca = vsca; 196 1.155 riastrad const struct ugen_softc *scb = vscb; 197 1.155 riastrad 198 1.155 riastrad if (sca->sc_unit < scb->sc_unit) 199 1.155 riastrad return -1; 200 1.155 riastrad if (sca->sc_unit > scb->sc_unit) 201 1.155 riastrad return +1; 202 1.155 riastrad return 0; 203 1.155 riastrad } 204 1.155 riastrad 205 1.155 riastrad static int 206 1.155 riastrad compare_ugen_key(void *cookie, const void *vsc, const void *vk) 207 1.155 riastrad { 208 1.155 riastrad const struct ugen_softc *sc = vsc; 209 1.155 riastrad const unsigned *k = vk; 210 1.155 riastrad 211 1.155 riastrad if (sc->sc_unit < *k) 212 1.155 riastrad return -1; 213 1.155 riastrad if (sc->sc_unit > *k) 214 1.155 riastrad return +1; 215 1.155 riastrad return 0; 216 1.155 riastrad } 217 1.155 riastrad 218 1.155 riastrad static const rb_tree_ops_t ugenif_tree_ops = { 219 1.155 riastrad .rbto_compare_nodes = compare_ugen, 220 1.155 riastrad .rbto_compare_key = compare_ugen_key, 221 1.156 riastrad .rbto_node_offset = offsetof(struct ugen_softc, sc_node), 222 1.155 riastrad }; 223 1.155 riastrad 224 1.155 riastrad static void 225 1.155 riastrad ugenif_get_unit(struct ugen_softc *sc) 226 1.155 riastrad { 227 1.155 riastrad struct ugen_softc *sc0; 228 1.155 riastrad unsigned i; 229 1.155 riastrad 230 1.155 riastrad mutex_enter(&ugenif.lock); 231 1.155 riastrad for (i = 0, sc0 = RB_TREE_MIN(&ugenif.tree); 232 1.155 riastrad sc0 != NULL && i == sc0->sc_unit; 233 1.155 riastrad i++, sc0 = RB_TREE_NEXT(&ugenif.tree, sc0)) 234 1.155 riastrad KASSERT(i < UINT_MAX); 235 1.155 riastrad KASSERT(rb_tree_find_node(&ugenif.tree, &i) == NULL); 236 1.155 riastrad sc->sc_unit = i; 237 1.155 riastrad sc0 = rb_tree_insert_node(&ugenif.tree, sc); 238 1.155 riastrad KASSERT(sc0 == sc); 239 1.155 riastrad KASSERT(rb_tree_find_node(&ugenif.tree, &i) == sc); 240 1.155 riastrad mutex_exit(&ugenif.lock); 241 1.177 thorpej 242 1.177 thorpej prop_dictionary_set_uint(device_properties(sc->sc_dev), 243 1.177 thorpej "ugen-unit", sc->sc_unit); 244 1.155 riastrad } 245 1.155 riastrad 246 1.155 riastrad static void 247 1.155 riastrad ugenif_put_unit(struct ugen_softc *sc) 248 1.155 riastrad { 249 1.155 riastrad 250 1.177 thorpej prop_dictionary_remove(device_properties(sc->sc_dev), 251 1.177 thorpej "ugen-unit"); 252 1.177 thorpej 253 1.155 riastrad mutex_enter(&ugenif.lock); 254 1.155 riastrad KASSERT(rb_tree_find_node(&ugenif.tree, &sc->sc_unit) == sc); 255 1.155 riastrad rb_tree_remove_node(&ugenif.tree, sc); 256 1.155 riastrad sc->sc_unit = -1; 257 1.155 riastrad mutex_exit(&ugenif.lock); 258 1.155 riastrad } 259 1.155 riastrad 260 1.155 riastrad static struct ugen_softc * 261 1.155 riastrad ugenif_acquire(unsigned unit) 262 1.155 riastrad { 263 1.155 riastrad struct ugen_softc *sc; 264 1.155 riastrad 265 1.155 riastrad mutex_enter(&ugenif.lock); 266 1.155 riastrad sc = rb_tree_find_node(&ugenif.tree, &unit); 267 1.156 riastrad if (sc == NULL) 268 1.156 riastrad goto out; 269 1.156 riastrad mutex_enter(&sc->sc_lock); 270 1.156 riastrad if (sc->sc_dying) { 271 1.155 riastrad mutex_exit(&sc->sc_lock); 272 1.156 riastrad sc = NULL; 273 1.156 riastrad goto out; 274 1.155 riastrad } 275 1.156 riastrad KASSERT(sc->sc_refcnt < INT_MAX); 276 1.156 riastrad sc->sc_refcnt++; 277 1.156 riastrad mutex_exit(&sc->sc_lock); 278 1.156 riastrad out: mutex_exit(&ugenif.lock); 279 1.155 riastrad 280 1.155 riastrad return sc; 281 1.155 riastrad } 282 1.155 riastrad 283 1.155 riastrad static void 284 1.155 riastrad ugenif_release(struct ugen_softc *sc) 285 1.155 riastrad { 286 1.155 riastrad 287 1.155 riastrad mutex_enter(&sc->sc_lock); 288 1.155 riastrad if (--sc->sc_refcnt < 0) 289 1.155 riastrad cv_broadcast(&sc->sc_detach_cv); 290 1.155 riastrad mutex_exit(&sc->sc_lock); 291 1.155 riastrad } 292 1.155 riastrad 293 1.147 maxv static dev_type_open(ugenopen); 294 1.147 maxv static dev_type_close(ugenclose); 295 1.147 maxv static dev_type_read(ugenread); 296 1.147 maxv static dev_type_write(ugenwrite); 297 1.147 maxv static dev_type_ioctl(ugenioctl); 298 1.147 maxv static dev_type_poll(ugenpoll); 299 1.147 maxv static dev_type_kqfilter(ugenkqfilter); 300 1.60 gehenna 301 1.60 gehenna const struct cdevsw ugen_cdevsw = { 302 1.123 dholland .d_open = ugenopen, 303 1.123 dholland .d_close = ugenclose, 304 1.123 dholland .d_read = ugenread, 305 1.123 dholland .d_write = ugenwrite, 306 1.123 dholland .d_ioctl = ugenioctl, 307 1.123 dholland .d_stop = nostop, 308 1.123 dholland .d_tty = notty, 309 1.123 dholland .d_poll = ugenpoll, 310 1.123 dholland .d_mmap = nommap, 311 1.123 dholland .d_kqfilter = ugenkqfilter, 312 1.124 dholland .d_discard = nodiscard, 313 1.123 dholland .d_flag = D_OTHER, 314 1.60 gehenna }; 315 1.14 augustss 316 1.133 skrll Static void ugenintr(struct usbd_xfer *, void *, 317 1.133 skrll usbd_status); 318 1.133 skrll Static void ugen_isoc_rintr(struct usbd_xfer *, void *, 319 1.133 skrll usbd_status); 320 1.133 skrll Static void ugen_bulkra_intr(struct usbd_xfer *, void *, 321 1.133 skrll usbd_status); 322 1.133 skrll Static void ugen_bulkwb_intr(struct usbd_xfer *, void *, 323 1.133 skrll usbd_status); 324 1.40 augustss Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int); 325 1.40 augustss Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int); 326 1.55 augustss Static int ugen_do_ioctl(struct ugen_softc *, int, u_long, 327 1.92 christos void *, int, struct lwp *); 328 1.138 ws Static int ugen_set_config(struct ugen_softc *, int, int); 329 1.133 skrll Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *, 330 1.133 skrll int, int *); 331 1.40 augustss Static usbd_status ugen_set_interface(struct ugen_softc *, int, int); 332 1.133 skrll Static int ugen_get_alt_index(struct ugen_softc *, int); 333 1.131 skrll Static void ugen_clear_endpoints(struct ugen_softc *); 334 1.1 augustss 335 1.12 augustss #define UGENUNIT(n) ((minor(n) >> 4) & 0xf) 336 1.12 augustss #define UGENENDPOINT(n) (minor(n) & 0xf) 337 1.12 augustss #define UGENDEV(u, e) (makedev(0, ((u) << 4) | (e))) 338 1.1 augustss 339 1.147 maxv static int ugenif_match(device_t, cfdata_t, void *); 340 1.147 maxv static void ugenif_attach(device_t, device_t, void *); 341 1.147 maxv static int ugen_match(device_t, cfdata_t, void *); 342 1.147 maxv static void ugen_attach(device_t, device_t, void *); 343 1.147 maxv static int ugen_detach(device_t, int); 344 1.147 maxv static int ugen_activate(device_t, enum devact); 345 1.146 mrg 346 1.138 ws CFATTACH_DECL_NEW(ugen, sizeof(struct ugen_softc), ugen_match, 347 1.138 ws ugen_attach, ugen_detach, ugen_activate); 348 1.138 ws CFATTACH_DECL_NEW(ugenif, sizeof(struct ugen_softc), ugenif_match, 349 1.138 ws ugenif_attach, ugen_detach, ugen_activate); 350 1.1 augustss 351 1.105 pooka /* toggle to control attach priority. -1 means "let autoconf decide" */ 352 1.105 pooka int ugen_override = -1; 353 1.105 pooka 354 1.147 maxv static int 355 1.111 dyoung ugen_match(device_t parent, cfdata_t match, void *aux) 356 1.1 augustss { 357 1.111 dyoung struct usb_attach_arg *uaa = aux; 358 1.105 pooka int override; 359 1.105 pooka 360 1.105 pooka if (ugen_override != -1) 361 1.105 pooka override = ugen_override; 362 1.105 pooka else 363 1.105 pooka override = match->cf_flags & 1; 364 1.1 augustss 365 1.105 pooka if (override) 366 1.133 skrll return UMATCH_HIGHEST; 367 1.133 skrll else if (uaa->uaa_usegeneric) 368 1.133 skrll return UMATCH_GENERIC; 369 1.1 augustss else 370 1.133 skrll return UMATCH_NONE; 371 1.1 augustss } 372 1.1 augustss 373 1.147 maxv static int 374 1.138 ws ugenif_match(device_t parent, cfdata_t match, void *aux) 375 1.138 ws { 376 1.176 thorpej /* 377 1.176 thorpej * Like ugen(4), ugenif(4) also has an override flag. It has the 378 1.176 thorpej * opposite effect, however, causing us to match with GENERIC 379 1.176 thorpej * priority rather than HIGHEST. 380 1.176 thorpej */ 381 1.176 thorpej return (match->cf_flags & 1) ? UMATCH_GENERIC : UMATCH_HIGHEST; 382 1.138 ws } 383 1.138 ws 384 1.147 maxv static void 385 1.111 dyoung ugen_attach(device_t parent, device_t self, void *aux) 386 1.1 augustss { 387 1.138 ws struct usb_attach_arg *uaa = aux; 388 1.138 ws struct usbif_attach_arg uiaa; 389 1.138 ws 390 1.151 skrll memset(&uiaa, 0, sizeof(uiaa)); 391 1.138 ws uiaa.uiaa_port = uaa->uaa_port; 392 1.138 ws uiaa.uiaa_vendor = uaa->uaa_vendor; 393 1.138 ws uiaa.uiaa_product = uaa->uaa_product; 394 1.138 ws uiaa.uiaa_release = uaa->uaa_release; 395 1.138 ws uiaa.uiaa_device = uaa->uaa_device; 396 1.138 ws uiaa.uiaa_configno = -1; 397 1.138 ws uiaa.uiaa_ifaceno = -1; 398 1.138 ws 399 1.138 ws ugenif_attach(parent, self, &uiaa); 400 1.138 ws } 401 1.138 ws 402 1.147 maxv static void 403 1.138 ws ugenif_attach(device_t parent, device_t self, void *aux) 404 1.138 ws { 405 1.111 dyoung struct ugen_softc *sc = device_private(self); 406 1.138 ws struct usbif_attach_arg *uiaa = aux; 407 1.133 skrll struct usbd_device *udev; 408 1.72 augustss char *devinfop; 409 1.28 augustss usbd_status err; 410 1.97 rmind int i, dir, conf; 411 1.59 augustss 412 1.103 plunky aprint_naive("\n"); 413 1.103 plunky aprint_normal("\n"); 414 1.103 plunky 415 1.133 skrll mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 416 1.120 mrg cv_init(&sc->sc_detach_cv, "ugendet"); 417 1.120 mrg 418 1.138 ws devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); 419 1.99 cube aprint_normal_dev(self, "%s\n", devinfop); 420 1.72 augustss usbd_devinfo_free(devinfop); 421 1.1 augustss 422 1.99 cube sc->sc_dev = self; 423 1.138 ws sc->sc_udev = udev = uiaa->uiaa_device; 424 1.31 augustss 425 1.121 riastrad for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 426 1.121 riastrad for (dir = OUT; dir <= IN; dir++) { 427 1.121 riastrad struct ugen_endpoint *sce; 428 1.121 riastrad 429 1.121 riastrad sce = &sc->sc_endpoints[i][dir]; 430 1.121 riastrad selinit(&sce->rsel); 431 1.121 riastrad cv_init(&sce->cv, "ugensce"); 432 1.121 riastrad } 433 1.121 riastrad } 434 1.121 riastrad 435 1.157 riastrad if (!pmf_device_register(self, NULL, NULL)) 436 1.157 riastrad aprint_error_dev(self, "couldn't establish power handler\n"); 437 1.157 riastrad 438 1.138 ws if (uiaa->uiaa_ifaceno < 0) { 439 1.138 ws /* 440 1.138 ws * If we attach the whole device, 441 1.138 ws * set configuration index 0, the default one. 442 1.138 ws */ 443 1.138 ws err = usbd_set_config_index(udev, 0, 0); 444 1.138 ws if (err) { 445 1.138 ws aprint_error_dev(self, 446 1.138 ws "setting configuration index 0 failed\n"); 447 1.138 ws return; 448 1.138 ws } 449 1.31 augustss } 450 1.138 ws 451 1.138 ws /* Get current configuration */ 452 1.31 augustss conf = usbd_get_config_descriptor(udev)->bConfigurationValue; 453 1.31 augustss 454 1.31 augustss /* Set up all the local state for this configuration. */ 455 1.138 ws err = ugen_set_config(sc, conf, uiaa->uiaa_ifaceno < 0); 456 1.28 augustss if (err) { 457 1.99 cube aprint_error_dev(self, "setting configuration %d failed\n", 458 1.99 cube conf); 459 1.111 dyoung return; 460 1.1 augustss } 461 1.30 augustss 462 1.155 riastrad ugenif_get_unit(sc); 463 1.134 msaitoh usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 464 1.157 riastrad sc->sc_attached = 1; 465 1.1 augustss } 466 1.1 augustss 467 1.130 skrll Static void 468 1.130 skrll ugen_clear_endpoints(struct ugen_softc *sc) 469 1.130 skrll { 470 1.130 skrll 471 1.130 skrll /* Clear out the old info, but leave the selinfo and cv initialised. */ 472 1.130 skrll for (int i = 0; i < USB_MAX_ENDPOINTS; i++) { 473 1.130 skrll for (int dir = OUT; dir <= IN; dir++) { 474 1.130 skrll struct ugen_endpoint *sce = &sc->sc_endpoints[i][dir]; 475 1.130 skrll memset(sce, 0, UGEN_ENDPOINT_NONZERO_CRUFT); 476 1.130 skrll } 477 1.130 skrll } 478 1.130 skrll } 479 1.130 skrll 480 1.37 augustss Static int 481 1.138 ws ugen_set_config(struct ugen_softc *sc, int configno, int chkopen) 482 1.1 augustss { 483 1.133 skrll struct usbd_device *dev = sc->sc_udev; 484 1.102 drochner usb_config_descriptor_t *cdesc; 485 1.133 skrll struct usbd_interface *iface; 486 1.1 augustss usb_endpoint_descriptor_t *ed; 487 1.1 augustss struct ugen_endpoint *sce; 488 1.133 skrll uint8_t niface, nendpt; 489 1.1 augustss int ifaceno, endptno, endpt; 490 1.28 augustss usbd_status err; 491 1.130 skrll int dir; 492 1.1 augustss 493 1.172 mrg UGENHIST_FUNC(); 494 1.172 mrg UGENHIST_CALLARGSN(1, "ugen%jd: to configno %jd, sc=%jx", 495 1.172 mrg device_unit(sc->sc_dev), configno, (uintptr_t)sc, 0); 496 1.53 augustss 497 1.159 riastrad KASSERT(KERNEL_LOCKED_P()); /* sc_is_open */ 498 1.159 riastrad 499 1.138 ws if (chkopen) { 500 1.138 ws /* 501 1.138 ws * We start at 1, not 0, because we don't care whether the 502 1.138 ws * control endpoint is open or not. It is always present. 503 1.138 ws */ 504 1.138 ws for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) 505 1.138 ws if (sc->sc_is_open[endptno]) { 506 1.138 ws DPRINTFN(1, 507 1.178 skrll "ugen%jd - endpoint %jd is open", 508 1.170 skrll device_unit(sc->sc_dev), endptno, 0, 0); 509 1.138 ws return USBD_IN_USE; 510 1.138 ws } 511 1.161 riastrad 512 1.161 riastrad /* Prevent opening while we're setting the config. */ 513 1.161 riastrad for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) { 514 1.161 riastrad KASSERT(!sc->sc_is_open[endptno]); 515 1.161 riastrad sc->sc_is_open[endptno] = 1; 516 1.161 riastrad } 517 1.138 ws } 518 1.53 augustss 519 1.31 augustss /* Avoid setting the current value. */ 520 1.102 drochner cdesc = usbd_get_config_descriptor(dev); 521 1.102 drochner if (!cdesc || cdesc->bConfigurationValue != configno) { 522 1.43 augustss err = usbd_set_config_no(dev, configno, 1); 523 1.28 augustss if (err) 524 1.161 riastrad goto out; 525 1.7 augustss } 526 1.1 augustss 527 1.138 ws ugen_clear_endpoints(sc); 528 1.138 ws 529 1.28 augustss err = usbd_interface_count(dev, &niface); 530 1.28 augustss if (err) 531 1.161 riastrad goto out; 532 1.120 mrg 533 1.1 augustss for (ifaceno = 0; ifaceno < niface; ifaceno++) { 534 1.169 mrg DPRINTFN(1, "ifaceno %jd", ifaceno, 0, 0, 0); 535 1.28 augustss err = usbd_device2interface_handle(dev, ifaceno, &iface); 536 1.28 augustss if (err) 537 1.161 riastrad goto out; 538 1.28 augustss err = usbd_endpoint_count(iface, &nendpt); 539 1.28 augustss if (err) 540 1.161 riastrad goto out; 541 1.1 augustss for (endptno = 0; endptno < nendpt; endptno++) { 542 1.174 simonb ed = usbd_interface2endpoint_descriptor(iface, endptno); 543 1.82 christos KASSERT(ed != NULL); 544 1.1 augustss endpt = ed->bEndpointAddress; 545 1.21 augustss dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 546 1.21 augustss sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 547 1.169 mrg DPRINTFN(1, "endptno %jd, endpt=0x%02jx (%jd,%jd)", 548 1.169 mrg endptno, endpt, UE_GET_ADDR(endpt), 549 1.169 mrg UE_GET_DIR(endpt)); 550 1.1 augustss sce->sc = sc; 551 1.1 augustss sce->edesc = ed; 552 1.1 augustss sce->iface = iface; 553 1.1 augustss } 554 1.1 augustss } 555 1.161 riastrad err = USBD_NORMAL_COMPLETION; 556 1.161 riastrad 557 1.161 riastrad out: if (chkopen) { 558 1.161 riastrad /* 559 1.161 riastrad * Allow open again now that we're done trying to set 560 1.161 riastrad * the config. 561 1.161 riastrad */ 562 1.161 riastrad for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) { 563 1.161 riastrad KASSERT(sc->sc_is_open[endptno]); 564 1.161 riastrad sc->sc_is_open[endptno] = 0; 565 1.161 riastrad } 566 1.161 riastrad } 567 1.161 riastrad return err; 568 1.1 augustss } 569 1.1 augustss 570 1.147 maxv static int 571 1.88 christos ugenopen(dev_t dev, int flag, int mode, struct lwp *l) 572 1.1 augustss { 573 1.24 augustss struct ugen_softc *sc; 574 1.1 augustss int unit = UGENUNIT(dev); 575 1.1 augustss int endpt = UGENENDPOINT(dev); 576 1.1 augustss usb_endpoint_descriptor_t *edesc; 577 1.1 augustss struct ugen_endpoint *sce; 578 1.1 augustss int dir, isize; 579 1.28 augustss usbd_status err; 580 1.133 skrll struct usbd_xfer *xfer; 581 1.41 augustss int i, j; 582 1.155 riastrad int error; 583 1.171 riastrad int opened = 0; 584 1.1 augustss 585 1.172 mrg UGENHIST_FUNC(); 586 1.172 mrg UGENHIST_CALLARGS("flag=%jd, mode=%jd, unit=%jd endpt=%jd", 587 1.172 mrg flag, mode, unit, endpt); 588 1.169 mrg 589 1.159 riastrad KASSERT(KERNEL_LOCKED_P()); /* sc_is_open */ 590 1.159 riastrad 591 1.155 riastrad if ((sc = ugenif_acquire(unit)) == NULL) 592 1.111 dyoung return ENXIO; 593 1.30 augustss 594 1.73 augustss /* The control endpoint allows multiple opens. */ 595 1.1 augustss if (endpt == USB_CONTROL_ENDPOINT) { 596 1.160 riastrad opened = sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; 597 1.155 riastrad error = 0; 598 1.155 riastrad goto out; 599 1.13 augustss } 600 1.35 augustss 601 1.155 riastrad if (sc->sc_is_open[endpt]) { 602 1.155 riastrad error = EBUSY; 603 1.155 riastrad goto out; 604 1.155 riastrad } 605 1.160 riastrad opened = sc->sc_is_open[endpt] = 1; 606 1.73 augustss 607 1.13 augustss /* Make sure there are pipes for all directions. */ 608 1.13 augustss for (dir = OUT; dir <= IN; dir++) { 609 1.13 augustss if (flag & (dir == OUT ? FWRITE : FREAD)) { 610 1.13 augustss sce = &sc->sc_endpoints[endpt][dir]; 611 1.155 riastrad if (sce->edesc == NULL) { 612 1.155 riastrad error = ENXIO; 613 1.155 riastrad goto out; 614 1.155 riastrad } 615 1.1 augustss } 616 1.13 augustss } 617 1.13 augustss 618 1.13 augustss /* Actually open the pipes. */ 619 1.13 augustss /* XXX Should back out properly if it fails. */ 620 1.13 augustss for (dir = OUT; dir <= IN; dir++) { 621 1.13 augustss if (!(flag & (dir == OUT ? FWRITE : FREAD))) 622 1.13 augustss continue; 623 1.1 augustss sce = &sc->sc_endpoints[endpt][dir]; 624 1.13 augustss sce->state = 0; 625 1.17 augustss sce->timeout = USBD_NO_TIMEOUT; 626 1.178 skrll DPRINTFN(5, "sc=%jx, endpt=%jd, dir=%jd, sce=%#jx", 627 1.170 skrll (uintptr_t)sc, endpt, dir, (uintptr_t)sce); 628 1.1 augustss edesc = sce->edesc; 629 1.1 augustss switch (edesc->bmAttributes & UE_XFERTYPE) { 630 1.1 augustss case UE_INTERRUPT: 631 1.69 augustss if (dir == OUT) { 632 1.69 augustss err = usbd_open_pipe(sce->iface, 633 1.69 augustss edesc->bEndpointAddress, 0, &sce->pipeh); 634 1.155 riastrad if (err) { 635 1.155 riastrad error = EIO; 636 1.155 riastrad goto out; 637 1.155 riastrad } 638 1.69 augustss break; 639 1.69 augustss } 640 1.1 augustss isize = UGETW(edesc->wMaxPacketSize); 641 1.155 riastrad if (isize == 0) { /* shouldn't happen */ 642 1.155 riastrad error = EINVAL; 643 1.155 riastrad goto out; 644 1.155 riastrad } 645 1.133 skrll sce->ibuf = kmem_alloc(isize, KM_SLEEP); 646 1.178 skrll DPRINTFN(5, "intr endpt=%jd, isize=%jd", 647 1.169 mrg endpt, isize, 0, 0); 648 1.121 riastrad if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) { 649 1.133 skrll kmem_free(sce->ibuf, isize); 650 1.121 riastrad sce->ibuf = NULL; 651 1.155 riastrad error = ENOMEM; 652 1.155 riastrad goto out; 653 1.121 riastrad } 654 1.55 augustss err = usbd_open_pipe_intr(sce->iface, 655 1.55 augustss edesc->bEndpointAddress, 656 1.55 augustss USBD_SHORT_XFER_OK, &sce->pipeh, sce, 657 1.55 augustss sce->ibuf, isize, ugenintr, 658 1.32 augustss USBD_DEFAULT_INTERVAL); 659 1.28 augustss if (err) { 660 1.121 riastrad clfree(&sce->q); 661 1.133 skrll kmem_free(sce->ibuf, isize); 662 1.121 riastrad sce->ibuf = NULL; 663 1.155 riastrad error = EIO; 664 1.155 riastrad goto out; 665 1.1 augustss } 666 1.169 mrg DPRINTFN(5, "interrupt open done", 0, 0, 0, 0); 667 1.1 augustss break; 668 1.1 augustss case UE_BULK: 669 1.55 augustss err = usbd_open_pipe(sce->iface, 670 1.28 augustss edesc->bEndpointAddress, 0, &sce->pipeh); 671 1.155 riastrad if (err) { 672 1.155 riastrad error = EIO; 673 1.155 riastrad goto out; 674 1.155 riastrad } 675 1.84 gdt sce->ra_wb_bufsize = UGEN_BULK_RA_WB_BUFSIZE; 676 1.121 riastrad /* 677 1.84 gdt * Use request size for non-RA/WB transfers 678 1.84 gdt * as the default. 679 1.84 gdt */ 680 1.84 gdt sce->ra_wb_reqsize = UGEN_BBSIZE; 681 1.1 augustss break; 682 1.41 augustss case UE_ISOCHRONOUS: 683 1.155 riastrad if (dir == OUT) { 684 1.155 riastrad error = EINVAL; 685 1.155 riastrad goto out; 686 1.155 riastrad } 687 1.41 augustss isize = UGETW(edesc->wMaxPacketSize); 688 1.156 riastrad if (isize == 0) { /* shouldn't happen */ 689 1.156 riastrad error = EINVAL; 690 1.156 riastrad goto out; 691 1.156 riastrad } 692 1.133 skrll sce->ibuf = kmem_alloc(isize * UGEN_NISOFRAMES, 693 1.133 skrll KM_SLEEP); 694 1.41 augustss sce->cur = sce->fill = sce->ibuf; 695 1.41 augustss sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES; 696 1.178 skrll DPRINTFN(5, "isoc endpt=%jd, isize=%jd", 697 1.169 mrg endpt, isize, 0, 0); 698 1.41 augustss err = usbd_open_pipe(sce->iface, 699 1.41 augustss edesc->bEndpointAddress, 0, &sce->pipeh); 700 1.41 augustss if (err) { 701 1.133 skrll kmem_free(sce->ibuf, isize * UGEN_NISOFRAMES); 702 1.121 riastrad sce->ibuf = NULL; 703 1.155 riastrad error = EIO; 704 1.155 riastrad goto out; 705 1.41 augustss } 706 1.132 skrll for (i = 0; i < UGEN_NISOREQS; ++i) { 707 1.41 augustss sce->isoreqs[i].sce = sce; 708 1.133 skrll err = usbd_create_xfer(sce->pipeh, 709 1.133 skrll isize * UGEN_NISORFRMS, 0, UGEN_NISORFRMS, 710 1.133 skrll &xfer); 711 1.133 skrll if (err) 712 1.41 augustss goto bad; 713 1.41 augustss sce->isoreqs[i].xfer = xfer; 714 1.133 skrll sce->isoreqs[i].dmabuf = usbd_get_buffer(xfer); 715 1.132 skrll for (j = 0; j < UGEN_NISORFRMS; ++j) 716 1.41 augustss sce->isoreqs[i].sizes[j] = isize; 717 1.133 skrll usbd_setup_isoc_xfer(xfer, &sce->isoreqs[i], 718 1.133 skrll sce->isoreqs[i].sizes, UGEN_NISORFRMS, 0, 719 1.133 skrll ugen_isoc_rintr); 720 1.41 augustss (void)usbd_transfer(xfer); 721 1.41 augustss } 722 1.169 mrg DPRINTFN(5, "isoc open done", 0, 0, 0, 0); 723 1.41 augustss break; 724 1.41 augustss bad: 725 1.167 riastrad while (--i >= 0) { /* implicit buffer free */ 726 1.133 skrll usbd_destroy_xfer(sce->isoreqs[i].xfer); 727 1.167 riastrad sce->isoreqs[i].xfer = NULL; 728 1.167 riastrad } 729 1.121 riastrad usbd_close_pipe(sce->pipeh); 730 1.121 riastrad sce->pipeh = NULL; 731 1.133 skrll kmem_free(sce->ibuf, isize * UGEN_NISOFRAMES); 732 1.121 riastrad sce->ibuf = NULL; 733 1.155 riastrad error = ENOMEM; 734 1.155 riastrad goto out; 735 1.1 augustss case UE_CONTROL: 736 1.57 augustss sce->timeout = USBD_DEFAULT_TIMEOUT; 737 1.155 riastrad error = EINVAL; 738 1.155 riastrad goto out; 739 1.1 augustss } 740 1.1 augustss } 741 1.155 riastrad error = 0; 742 1.160 riastrad out: if (error && opened) 743 1.160 riastrad sc->sc_is_open[endpt] = 0; 744 1.160 riastrad ugenif_release(sc); 745 1.155 riastrad return error; 746 1.1 augustss } 747 1.1 augustss 748 1.163 riastrad static void 749 1.163 riastrad ugen_do_close(struct ugen_softc *sc, int flag, int endpt) 750 1.1 augustss { 751 1.1 augustss struct ugen_endpoint *sce; 752 1.1 augustss int dir; 753 1.41 augustss int i; 754 1.1 augustss 755 1.172 mrg UGENHIST_FUNC(); 756 1.172 mrg UGENHIST_CALLARGS("flag=%jd endpt=%jd", flag, endpt, 0, 0); 757 1.169 mrg 758 1.159 riastrad KASSERT(KERNEL_LOCKED_P()); /* sc_is_open */ 759 1.159 riastrad 760 1.167 riastrad if (!sc->sc_is_open[endpt]) 761 1.167 riastrad goto out; 762 1.1 augustss 763 1.1 augustss if (endpt == USB_CONTROL_ENDPOINT) { 764 1.169 mrg DPRINTFN(5, "close control", 0, 0, 0, 0); 765 1.155 riastrad goto out; 766 1.1 augustss } 767 1.9 augustss 768 1.9 augustss for (dir = OUT; dir <= IN; dir++) { 769 1.13 augustss if (!(flag & (dir == OUT ? FWRITE : FREAD))) 770 1.13 augustss continue; 771 1.13 augustss sce = &sc->sc_endpoints[endpt][dir]; 772 1.129 skrll if (sce->pipeh == NULL) 773 1.13 augustss continue; 774 1.169 mrg DPRINTFN(5, "endpt=%jd dir=%jd sce=%jx", 775 1.170 skrll endpt, dir, (uintptr_t)sce, 0); 776 1.59 augustss 777 1.13 augustss usbd_abort_pipe(sce->pipeh); 778 1.133 skrll 779 1.133 skrll int isize = UGETW(sce->edesc->wMaxPacketSize); 780 1.133 skrll int msize = 0; 781 1.41 augustss 782 1.56 augustss switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 783 1.56 augustss case UE_INTERRUPT: 784 1.56 augustss ndflush(&sce->q, sce->q.c_cc); 785 1.56 augustss clfree(&sce->q); 786 1.133 skrll msize = isize; 787 1.56 augustss break; 788 1.56 augustss case UE_ISOCHRONOUS: 789 1.167 riastrad for (i = 0; i < UGEN_NISOREQS; ++i) { 790 1.133 skrll usbd_destroy_xfer(sce->isoreqs[i].xfer); 791 1.167 riastrad sce->isoreqs[i].xfer = NULL; 792 1.167 riastrad } 793 1.133 skrll msize = isize * UGEN_NISOFRAMES; 794 1.84 gdt break; 795 1.84 gdt case UE_BULK: 796 1.133 skrll if (sce->state & (UGEN_BULK_RA | UGEN_BULK_WB)) { 797 1.133 skrll usbd_destroy_xfer(sce->ra_wb_xfer); 798 1.167 riastrad sce->ra_wb_xfer = NULL; 799 1.133 skrll msize = sce->ra_wb_bufsize; 800 1.133 skrll } 801 1.84 gdt break; 802 1.56 augustss default: 803 1.56 augustss break; 804 1.41 augustss } 805 1.133 skrll usbd_close_pipe(sce->pipeh); 806 1.133 skrll sce->pipeh = NULL; 807 1.28 augustss if (sce->ibuf != NULL) { 808 1.133 skrll kmem_free(sce->ibuf, msize); 809 1.30 augustss sce->ibuf = NULL; 810 1.9 augustss } 811 1.1 augustss } 812 1.1 augustss 813 1.163 riastrad out: sc->sc_is_open[endpt] = 0; 814 1.167 riastrad for (dir = OUT; dir <= IN; dir++) { 815 1.167 riastrad sce = &sc->sc_endpoints[endpt][dir]; 816 1.167 riastrad KASSERT(sce->pipeh == NULL); 817 1.167 riastrad KASSERT(sce->ibuf == NULL); 818 1.167 riastrad KASSERT(sce->ra_wb_xfer == NULL); 819 1.167 riastrad for (i = 0; i < UGEN_NISOREQS; i++) 820 1.167 riastrad KASSERT(sce->isoreqs[i].xfer == NULL); 821 1.167 riastrad } 822 1.163 riastrad } 823 1.163 riastrad 824 1.163 riastrad static int 825 1.163 riastrad ugenclose(dev_t dev, int flag, int mode, struct lwp *l) 826 1.163 riastrad { 827 1.163 riastrad int endpt = UGENENDPOINT(dev); 828 1.163 riastrad struct ugen_softc *sc; 829 1.163 riastrad 830 1.172 mrg UGENHIST_FUNC(); 831 1.172 mrg UGENHIST_CALLARGS("flag=%jd, mode=%jd, unit=%jd, endpt=%jd", 832 1.172 mrg flag, mode, UGENUNIT(dev), endpt); 833 1.163 riastrad 834 1.163 riastrad KASSERT(KERNEL_LOCKED_P()); /* ugen_do_close */ 835 1.163 riastrad 836 1.163 riastrad if ((sc = ugenif_acquire(UGENUNIT(dev))) == NULL) 837 1.163 riastrad return ENXIO; 838 1.163 riastrad 839 1.163 riastrad KASSERT(sc->sc_is_open[endpt]); 840 1.163 riastrad ugen_do_close(sc, flag, endpt); 841 1.163 riastrad KASSERT(!sc->sc_is_open[endpt]); 842 1.163 riastrad 843 1.163 riastrad ugenif_release(sc); 844 1.163 riastrad 845 1.163 riastrad return 0; 846 1.1 augustss } 847 1.1 augustss 848 1.37 augustss Static int 849 1.40 augustss ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) 850 1.1 augustss { 851 1.1 augustss struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; 852 1.133 skrll uint32_t n, tn; 853 1.133 skrll struct usbd_xfer *xfer; 854 1.28 augustss usbd_status err; 855 1.1 augustss int error = 0; 856 1.1 augustss 857 1.172 mrg UGENHIST_FUNC(); 858 1.172 mrg UGENHIST_CALLARGS("ugen%d: %jd", device_unit(sc->sc_dev), endpt, 0, 0); 859 1.26 augustss 860 1.26 augustss if (endpt == USB_CONTROL_ENDPOINT) 861 1.133 skrll return ENODEV; 862 1.26 augustss 863 1.154 riastrad KASSERT(sce->edesc); 864 1.154 riastrad KASSERT(sce->pipeh); 865 1.1 augustss 866 1.1 augustss switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 867 1.1 augustss case UE_INTERRUPT: 868 1.47 wiz /* Block until activity occurred. */ 869 1.120 mrg mutex_enter(&sc->sc_lock); 870 1.1 augustss while (sce->q.c_cc == 0) { 871 1.1 augustss if (flag & IO_NDELAY) { 872 1.120 mrg mutex_exit(&sc->sc_lock); 873 1.133 skrll return EWOULDBLOCK; 874 1.1 augustss } 875 1.170 skrll DPRINTFN(5, "sleep on %jx", (uintptr_t)sce, 0, 0, 0); 876 1.120 mrg /* "ugenri" */ 877 1.120 mrg error = cv_timedwait_sig(&sce->cv, &sc->sc_lock, 878 1.120 mrg mstohz(sce->timeout)); 879 1.169 mrg DPRINTFN(5, "woke, error=%jd", 880 1.169 mrg error, 0, 0, 0); 881 1.12 augustss if (sc->sc_dying) 882 1.12 augustss error = EIO; 883 1.152 riastrad if (error) 884 1.12 augustss break; 885 1.1 augustss } 886 1.120 mrg mutex_exit(&sc->sc_lock); 887 1.1 augustss 888 1.1 augustss /* Transfer as many chunks as possible. */ 889 1.12 augustss while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) { 890 1.140 riastrad n = uimin(sce->q.c_cc, uio->uio_resid); 891 1.83 christos if (n > sizeof(sc->sc_buffer)) 892 1.83 christos n = sizeof(sc->sc_buffer); 893 1.1 augustss 894 1.1 augustss /* Remove a small chunk from the input queue. */ 895 1.83 christos q_to_b(&sce->q, sc->sc_buffer, n); 896 1.169 mrg DPRINTFN(5, "got %jd chars", n, 0, 0, 0); 897 1.1 augustss 898 1.1 augustss /* Copy the data to the user process. */ 899 1.83 christos error = uiomove(sc->sc_buffer, n, uio); 900 1.1 augustss if (error) 901 1.1 augustss break; 902 1.1 augustss } 903 1.1 augustss break; 904 1.1 augustss case UE_BULK: 905 1.84 gdt if (sce->state & UGEN_BULK_RA) { 906 1.178 skrll DPRINTFN(5, "BULK_RA req: %jd used: %jd", 907 1.169 mrg uio->uio_resid, sce->ra_wb_used, 0, 0); 908 1.84 gdt xfer = sce->ra_wb_xfer; 909 1.84 gdt 910 1.120 mrg mutex_enter(&sc->sc_lock); 911 1.84 gdt if (sce->ra_wb_used == 0 && flag & IO_NDELAY) { 912 1.120 mrg mutex_exit(&sc->sc_lock); 913 1.133 skrll return EWOULDBLOCK; 914 1.84 gdt } 915 1.84 gdt while (uio->uio_resid > 0 && !error) { 916 1.84 gdt while (sce->ra_wb_used == 0) { 917 1.169 mrg DPRINTFN(5, "sleep on %jx", 918 1.170 skrll (uintptr_t)sce, 0, 0, 0); 919 1.120 mrg /* "ugenrb" */ 920 1.120 mrg error = cv_timedwait_sig(&sce->cv, 921 1.120 mrg &sc->sc_lock, mstohz(sce->timeout)); 922 1.169 mrg DPRINTFN(5, "woke, error=%jd", 923 1.169 mrg error, 0, 0, 0); 924 1.84 gdt if (sc->sc_dying) 925 1.84 gdt error = EIO; 926 1.152 riastrad if (error) 927 1.84 gdt break; 928 1.84 gdt } 929 1.84 gdt 930 1.84 gdt /* Copy data to the process. */ 931 1.84 gdt while (uio->uio_resid > 0 932 1.84 gdt && sce->ra_wb_used > 0) { 933 1.140 riastrad n = uimin(uio->uio_resid, 934 1.84 gdt sce->ra_wb_used); 935 1.140 riastrad n = uimin(n, sce->limit - sce->cur); 936 1.84 gdt error = uiomove(sce->cur, n, uio); 937 1.84 gdt if (error) 938 1.84 gdt break; 939 1.84 gdt sce->cur += n; 940 1.84 gdt sce->ra_wb_used -= n; 941 1.84 gdt if (sce->cur == sce->limit) 942 1.84 gdt sce->cur = sce->ibuf; 943 1.84 gdt } 944 1.84 gdt 945 1.122 christos /* 946 1.84 gdt * If the transfers stopped because the 947 1.84 gdt * buffer was full, restart them. 948 1.84 gdt */ 949 1.84 gdt if (sce->state & UGEN_RA_WB_STOP && 950 1.84 gdt sce->ra_wb_used < sce->limit - sce->ibuf) { 951 1.84 gdt n = (sce->limit - sce->ibuf) 952 1.84 gdt - sce->ra_wb_used; 953 1.133 skrll usbd_setup_xfer(xfer, sce, NULL, 954 1.140 riastrad uimin(n, sce->ra_wb_xferlen), 955 1.133 skrll 0, USBD_NO_TIMEOUT, 956 1.84 gdt ugen_bulkra_intr); 957 1.84 gdt sce->state &= ~UGEN_RA_WB_STOP; 958 1.84 gdt err = usbd_transfer(xfer); 959 1.84 gdt if (err != USBD_IN_PROGRESS) 960 1.84 gdt /* 961 1.84 gdt * The transfer has not been 962 1.84 gdt * queued. Setting STOP 963 1.84 gdt * will make us try 964 1.84 gdt * again at the next read. 965 1.84 gdt */ 966 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 967 1.84 gdt } 968 1.84 gdt } 969 1.120 mrg mutex_exit(&sc->sc_lock); 970 1.84 gdt break; 971 1.84 gdt } 972 1.133 skrll error = usbd_create_xfer(sce->pipeh, UGEN_BBSIZE, 973 1.137 skrll 0, 0, &xfer); 974 1.133 skrll if (error) 975 1.133 skrll return error; 976 1.140 riastrad while ((n = uimin(UGEN_BBSIZE, uio->uio_resid)) != 0) { 977 1.169 mrg DPRINTFN(1, "start transfer %jd bytes", n, 0, 0, 0); 978 1.10 augustss tn = n; 979 1.133 skrll err = usbd_bulk_transfer(xfer, sce->pipeh, 980 1.133 skrll sce->state & UGEN_SHORT_OK ? USBD_SHORT_XFER_OK : 0, 981 1.133 skrll sce->timeout, sc->sc_buffer, &tn); 982 1.30 augustss if (err) { 983 1.28 augustss if (err == USBD_INTERRUPTED) 984 1.8 augustss error = EINTR; 985 1.28 augustss else if (err == USBD_TIMEOUT) 986 1.17 augustss error = ETIMEDOUT; 987 1.8 augustss else 988 1.8 augustss error = EIO; 989 1.1 augustss break; 990 1.1 augustss } 991 1.169 mrg DPRINTFN(1, "got %jd bytes", tn, 0, 0, 0); 992 1.83 christos error = uiomove(sc->sc_buffer, tn, uio); 993 1.9 augustss if (error || tn < n) 994 1.1 augustss break; 995 1.1 augustss } 996 1.133 skrll usbd_destroy_xfer(xfer); 997 1.1 augustss break; 998 1.41 augustss case UE_ISOCHRONOUS: 999 1.120 mrg mutex_enter(&sc->sc_lock); 1000 1.41 augustss while (sce->cur == sce->fill) { 1001 1.41 augustss if (flag & IO_NDELAY) { 1002 1.120 mrg mutex_exit(&sc->sc_lock); 1003 1.133 skrll return EWOULDBLOCK; 1004 1.41 augustss } 1005 1.120 mrg /* "ugenri" */ 1006 1.170 skrll DPRINTFN(5, "sleep on %jx", (uintptr_t)sce, 0, 0, 0); 1007 1.120 mrg error = cv_timedwait_sig(&sce->cv, &sc->sc_lock, 1008 1.120 mrg mstohz(sce->timeout)); 1009 1.169 mrg DPRINTFN(5, "woke, error=%jd", error, 0, 0, 0); 1010 1.41 augustss if (sc->sc_dying) 1011 1.41 augustss error = EIO; 1012 1.152 riastrad if (error) 1013 1.41 augustss break; 1014 1.41 augustss } 1015 1.41 augustss 1016 1.41 augustss while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) { 1017 1.41 augustss if(sce->fill > sce->cur) 1018 1.140 riastrad n = uimin(sce->fill - sce->cur, uio->uio_resid); 1019 1.41 augustss else 1020 1.140 riastrad n = uimin(sce->limit - sce->cur, uio->uio_resid); 1021 1.41 augustss 1022 1.169 mrg DPRINTFN(5, "isoc got %jd chars", n, 0, 0, 0); 1023 1.41 augustss 1024 1.41 augustss /* Copy the data to the user process. */ 1025 1.41 augustss error = uiomove(sce->cur, n, uio); 1026 1.41 augustss if (error) 1027 1.41 augustss break; 1028 1.41 augustss sce->cur += n; 1029 1.120 mrg if (sce->cur >= sce->limit) 1030 1.41 augustss sce->cur = sce->ibuf; 1031 1.41 augustss } 1032 1.120 mrg mutex_exit(&sc->sc_lock); 1033 1.41 augustss break; 1034 1.41 augustss 1035 1.59 augustss 1036 1.1 augustss default: 1037 1.133 skrll return ENXIO; 1038 1.1 augustss } 1039 1.133 skrll return error; 1040 1.1 augustss } 1041 1.1 augustss 1042 1.147 maxv static int 1043 1.40 augustss ugenread(dev_t dev, struct uio *uio, int flag) 1044 1.1 augustss { 1045 1.1 augustss int endpt = UGENENDPOINT(dev); 1046 1.24 augustss struct ugen_softc *sc; 1047 1.12 augustss int error; 1048 1.12 augustss 1049 1.155 riastrad if ((sc = ugenif_acquire(UGENUNIT(dev))) == NULL) 1050 1.111 dyoung return ENXIO; 1051 1.12 augustss error = ugen_do_read(sc, endpt, uio, flag); 1052 1.155 riastrad ugenif_release(sc); 1053 1.120 mrg 1054 1.133 skrll return error; 1055 1.12 augustss } 1056 1.12 augustss 1057 1.37 augustss Static int 1058 1.87 xtraeme ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, 1059 1.88 christos int flag) 1060 1.12 augustss { 1061 1.10 augustss struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; 1062 1.133 skrll uint32_t n; 1063 1.1 augustss int error = 0; 1064 1.133 skrll uint32_t tn; 1065 1.84 gdt char *dbuf; 1066 1.133 skrll struct usbd_xfer *xfer; 1067 1.28 augustss usbd_status err; 1068 1.1 augustss 1069 1.172 mrg UGENHIST_FUNC(); 1070 1.172 mrg UGENHIST_CALLARGSN(5, "ugen%jd: %jd", 1071 1.172 mrg device_unit(sc->sc_dev), endpt, 0, 0); 1072 1.26 augustss 1073 1.26 augustss if (endpt == USB_CONTROL_ENDPOINT) 1074 1.133 skrll return ENODEV; 1075 1.26 augustss 1076 1.154 riastrad KASSERT(sce->edesc); 1077 1.154 riastrad KASSERT(sce->pipeh); 1078 1.1 augustss 1079 1.1 augustss switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 1080 1.1 augustss case UE_BULK: 1081 1.84 gdt if (sce->state & UGEN_BULK_WB) { 1082 1.169 mrg DPRINTFN(5, "BULK_WB req: %jd used: %jd", 1083 1.169 mrg uio->uio_resid, sce->ra_wb_used, 0, 0); 1084 1.84 gdt xfer = sce->ra_wb_xfer; 1085 1.84 gdt 1086 1.120 mrg mutex_enter(&sc->sc_lock); 1087 1.84 gdt if (sce->ra_wb_used == sce->limit - sce->ibuf && 1088 1.84 gdt flag & IO_NDELAY) { 1089 1.120 mrg mutex_exit(&sc->sc_lock); 1090 1.133 skrll return EWOULDBLOCK; 1091 1.84 gdt } 1092 1.84 gdt while (uio->uio_resid > 0 && !error) { 1093 1.122 christos while (sce->ra_wb_used == 1094 1.84 gdt sce->limit - sce->ibuf) { 1095 1.170 skrll DPRINTFN(5, "sleep on %#jx", 1096 1.170 skrll (uintptr_t)sce, 0, 0, 0); 1097 1.120 mrg /* "ugenwb" */ 1098 1.120 mrg error = cv_timedwait_sig(&sce->cv, 1099 1.120 mrg &sc->sc_lock, mstohz(sce->timeout)); 1100 1.178 skrll DPRINTFN(5, "woke, error=%jd", 1101 1.169 mrg error, 0, 0, 0); 1102 1.84 gdt if (sc->sc_dying) 1103 1.84 gdt error = EIO; 1104 1.152 riastrad if (error) 1105 1.84 gdt break; 1106 1.84 gdt } 1107 1.84 gdt 1108 1.84 gdt /* Copy data from the process. */ 1109 1.84 gdt while (uio->uio_resid > 0 && 1110 1.84 gdt sce->ra_wb_used < sce->limit - sce->ibuf) { 1111 1.140 riastrad n = uimin(uio->uio_resid, 1112 1.84 gdt (sce->limit - sce->ibuf) 1113 1.84 gdt - sce->ra_wb_used); 1114 1.140 riastrad n = uimin(n, sce->limit - sce->fill); 1115 1.84 gdt error = uiomove(sce->fill, n, uio); 1116 1.84 gdt if (error) 1117 1.84 gdt break; 1118 1.84 gdt sce->fill += n; 1119 1.84 gdt sce->ra_wb_used += n; 1120 1.84 gdt if (sce->fill == sce->limit) 1121 1.84 gdt sce->fill = sce->ibuf; 1122 1.84 gdt } 1123 1.84 gdt 1124 1.84 gdt /* 1125 1.84 gdt * If the transfers stopped because the 1126 1.84 gdt * buffer was empty, restart them. 1127 1.84 gdt */ 1128 1.84 gdt if (sce->state & UGEN_RA_WB_STOP && 1129 1.84 gdt sce->ra_wb_used > 0) { 1130 1.84 gdt dbuf = (char *)usbd_get_buffer(xfer); 1131 1.140 riastrad n = uimin(sce->ra_wb_used, 1132 1.84 gdt sce->ra_wb_xferlen); 1133 1.140 riastrad tn = uimin(n, sce->limit - sce->cur); 1134 1.84 gdt memcpy(dbuf, sce->cur, tn); 1135 1.84 gdt dbuf += tn; 1136 1.84 gdt if (n - tn > 0) 1137 1.84 gdt memcpy(dbuf, sce->ibuf, 1138 1.84 gdt n - tn); 1139 1.133 skrll usbd_setup_xfer(xfer, sce, NULL, n, 1140 1.133 skrll 0, USBD_NO_TIMEOUT, 1141 1.84 gdt ugen_bulkwb_intr); 1142 1.84 gdt sce->state &= ~UGEN_RA_WB_STOP; 1143 1.84 gdt err = usbd_transfer(xfer); 1144 1.84 gdt if (err != USBD_IN_PROGRESS) 1145 1.84 gdt /* 1146 1.84 gdt * The transfer has not been 1147 1.84 gdt * queued. Setting STOP 1148 1.84 gdt * will make us try again 1149 1.84 gdt * at the next read. 1150 1.84 gdt */ 1151 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 1152 1.84 gdt } 1153 1.84 gdt } 1154 1.120 mrg mutex_exit(&sc->sc_lock); 1155 1.84 gdt break; 1156 1.84 gdt } 1157 1.133 skrll error = usbd_create_xfer(sce->pipeh, UGEN_BBSIZE, 1158 1.137 skrll 0, 0, &xfer); 1159 1.133 skrll if (error) 1160 1.133 skrll return error; 1161 1.140 riastrad while ((n = uimin(UGEN_BBSIZE, uio->uio_resid)) != 0) { 1162 1.83 christos error = uiomove(sc->sc_buffer, n, uio); 1163 1.1 augustss if (error) 1164 1.1 augustss break; 1165 1.169 mrg DPRINTFN(1, "transfer %jd bytes", n, 0, 0, 0); 1166 1.133 skrll err = usbd_bulk_transfer(xfer, sce->pipeh, 0, sce->timeout, 1167 1.133 skrll sc->sc_buffer, &n); 1168 1.28 augustss if (err) { 1169 1.28 augustss if (err == USBD_INTERRUPTED) 1170 1.8 augustss error = EINTR; 1171 1.36 augustss else if (err == USBD_TIMEOUT) 1172 1.36 augustss error = ETIMEDOUT; 1173 1.8 augustss else 1174 1.8 augustss error = EIO; 1175 1.1 augustss break; 1176 1.1 augustss } 1177 1.1 augustss } 1178 1.133 skrll usbd_destroy_xfer(xfer); 1179 1.1 augustss break; 1180 1.69 augustss case UE_INTERRUPT: 1181 1.133 skrll error = usbd_create_xfer(sce->pipeh, 1182 1.133 skrll UGETW(sce->edesc->wMaxPacketSize), 0, 0, &xfer); 1183 1.133 skrll if (error) 1184 1.133 skrll return error; 1185 1.140 riastrad while ((n = uimin(UGETW(sce->edesc->wMaxPacketSize), 1186 1.69 augustss uio->uio_resid)) != 0) { 1187 1.83 christos error = uiomove(sc->sc_buffer, n, uio); 1188 1.69 augustss if (error) 1189 1.69 augustss break; 1190 1.169 mrg DPRINTFN(1, "transfer %jd bytes", n, 0, 0, 0); 1191 1.69 augustss err = usbd_intr_transfer(xfer, sce->pipeh, 0, 1192 1.133 skrll sce->timeout, sc->sc_buffer, &n); 1193 1.69 augustss if (err) { 1194 1.69 augustss if (err == USBD_INTERRUPTED) 1195 1.69 augustss error = EINTR; 1196 1.69 augustss else if (err == USBD_TIMEOUT) 1197 1.69 augustss error = ETIMEDOUT; 1198 1.69 augustss else 1199 1.69 augustss error = EIO; 1200 1.69 augustss break; 1201 1.69 augustss } 1202 1.69 augustss } 1203 1.133 skrll usbd_destroy_xfer(xfer); 1204 1.69 augustss break; 1205 1.1 augustss default: 1206 1.133 skrll return ENXIO; 1207 1.1 augustss } 1208 1.133 skrll return error; 1209 1.1 augustss } 1210 1.1 augustss 1211 1.147 maxv static int 1212 1.40 augustss ugenwrite(dev_t dev, struct uio *uio, int flag) 1213 1.12 augustss { 1214 1.12 augustss int endpt = UGENENDPOINT(dev); 1215 1.24 augustss struct ugen_softc *sc; 1216 1.12 augustss int error; 1217 1.12 augustss 1218 1.155 riastrad if ((sc = ugenif_acquire(UGENUNIT(dev))) == NULL) 1219 1.111 dyoung return ENXIO; 1220 1.12 augustss error = ugen_do_write(sc, endpt, uio, flag); 1221 1.155 riastrad ugenif_release(sc); 1222 1.120 mrg 1223 1.133 skrll return error; 1224 1.12 augustss } 1225 1.12 augustss 1226 1.147 maxv static int 1227 1.111 dyoung ugen_activate(device_t self, enum devact act) 1228 1.12 augustss { 1229 1.99 cube struct ugen_softc *sc = device_private(self); 1230 1.18 augustss 1231 1.18 augustss switch (act) { 1232 1.18 augustss case DVACT_DEACTIVATE: 1233 1.18 augustss sc->sc_dying = 1; 1234 1.106 dyoung return 0; 1235 1.106 dyoung default: 1236 1.106 dyoung return EOPNOTSUPP; 1237 1.18 augustss } 1238 1.12 augustss } 1239 1.12 augustss 1240 1.147 maxv static int 1241 1.111 dyoung ugen_detach(device_t self, int flags) 1242 1.12 augustss { 1243 1.111 dyoung struct ugen_softc *sc = device_private(self); 1244 1.12 augustss struct ugen_endpoint *sce; 1245 1.12 augustss int i, dir; 1246 1.25 augustss int maj, mn; 1247 1.12 augustss 1248 1.172 mrg UGENHIST_FUNC(); 1249 1.172 mrg UGENHIST_CALLARGS("sc=%ju flags=%ju", (uintptr_t)sc, flags, 0, 0); 1250 1.12 augustss 1251 1.162 riastrad KASSERT(KERNEL_LOCKED_P()); /* sc_is_open */ 1252 1.162 riastrad 1253 1.162 riastrad /* 1254 1.162 riastrad * Fail if we're not forced to detach and userland has any 1255 1.162 riastrad * endpoints open. 1256 1.162 riastrad */ 1257 1.162 riastrad if ((flags & DETACH_FORCE) == 0) { 1258 1.162 riastrad for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 1259 1.162 riastrad if (sc->sc_is_open[i]) 1260 1.162 riastrad return EBUSY; 1261 1.162 riastrad } 1262 1.162 riastrad } 1263 1.162 riastrad 1264 1.162 riastrad /* Prevent new users. Prevent suspend/resume. */ 1265 1.12 augustss sc->sc_dying = 1; 1266 1.96 smb pmf_device_deregister(self); 1267 1.157 riastrad 1268 1.162 riastrad /* 1269 1.162 riastrad * If we never finished attaching, skip nixing endpoints and 1270 1.162 riastrad * users because there aren't any. 1271 1.162 riastrad */ 1272 1.157 riastrad if (!sc->sc_attached) 1273 1.157 riastrad goto out; 1274 1.157 riastrad 1275 1.164 riastrad /* Abort all pipes. */ 1276 1.12 augustss for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 1277 1.12 augustss for (dir = OUT; dir <= IN; dir++) { 1278 1.12 augustss sce = &sc->sc_endpoints[i][dir]; 1279 1.129 skrll if (sce->pipeh) 1280 1.12 augustss usbd_abort_pipe(sce->pipeh); 1281 1.12 augustss } 1282 1.12 augustss } 1283 1.12 augustss 1284 1.166 riastrad /* 1285 1.166 riastrad * Wait for users to drain. Before this point there can be no 1286 1.166 riastrad * more I/O operations started because we set sc_dying; after 1287 1.166 riastrad * this, there can be no more I/O operations in progress, so it 1288 1.166 riastrad * will be safe to free things. 1289 1.166 riastrad */ 1290 1.120 mrg mutex_enter(&sc->sc_lock); 1291 1.12 augustss if (--sc->sc_refcnt >= 0) { 1292 1.12 augustss /* Wake everyone */ 1293 1.164 riastrad for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 1294 1.164 riastrad for (dir = OUT; dir <= IN; dir++) 1295 1.165 riastrad cv_broadcast(&sc->sc_endpoints[i][dir].cv); 1296 1.164 riastrad } 1297 1.12 augustss /* Wait for processes to go away. */ 1298 1.166 riastrad do { 1299 1.166 riastrad cv_wait(&sc->sc_detach_cv, &sc->sc_lock); 1300 1.166 riastrad } while (sc->sc_refcnt >= 0); 1301 1.12 augustss } 1302 1.120 mrg mutex_exit(&sc->sc_lock); 1303 1.12 augustss 1304 1.12 augustss /* locate the major number */ 1305 1.60 gehenna maj = cdevsw_lookup_major(&ugen_cdevsw); 1306 1.12 augustss 1307 1.163 riastrad /* 1308 1.163 riastrad * Nuke the vnodes for any open instances (calls ugenclose, but 1309 1.163 riastrad * with no effect because we already set sc_dying). 1310 1.163 riastrad */ 1311 1.155 riastrad mn = sc->sc_unit * USB_MAX_ENDPOINTS; 1312 1.12 augustss vdevgone(maj, mn, mn + USB_MAX_ENDPOINTS - 1, VCHR); 1313 1.33 augustss 1314 1.163 riastrad /* Actually close any lingering pipes. */ 1315 1.163 riastrad for (i = 0; i < USB_MAX_ENDPOINTS; i++) 1316 1.163 riastrad ugen_do_close(sc, FREAD|FWRITE, i); 1317 1.163 riastrad 1318 1.134 msaitoh usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 1319 1.155 riastrad ugenif_put_unit(sc); 1320 1.12 augustss 1321 1.157 riastrad out: for (i = 0; i < USB_MAX_ENDPOINTS; i++) { 1322 1.97 rmind for (dir = OUT; dir <= IN; dir++) { 1323 1.97 rmind sce = &sc->sc_endpoints[i][dir]; 1324 1.97 rmind seldestroy(&sce->rsel); 1325 1.120 mrg cv_destroy(&sce->cv); 1326 1.97 rmind } 1327 1.97 rmind } 1328 1.97 rmind 1329 1.120 mrg cv_destroy(&sc->sc_detach_cv); 1330 1.120 mrg mutex_destroy(&sc->sc_lock); 1331 1.120 mrg 1332 1.133 skrll return 0; 1333 1.12 augustss } 1334 1.1 augustss 1335 1.37 augustss Static void 1336 1.133 skrll ugenintr(struct usbd_xfer *xfer, void *addr, usbd_status status) 1337 1.1 augustss { 1338 1.1 augustss struct ugen_endpoint *sce = addr; 1339 1.120 mrg struct ugen_softc *sc = sce->sc; 1340 1.133 skrll uint32_t count; 1341 1.1 augustss u_char *ibuf; 1342 1.1 augustss 1343 1.172 mrg UGENHIST_FUNC(); 1344 1.172 mrg UGENHIST_CALLARGS("xfer %jx status %d", (uintptr_t)xfer, status, 0, 0); 1345 1.169 mrg 1346 1.1 augustss if (status == USBD_CANCELLED) 1347 1.1 augustss return; 1348 1.1 augustss 1349 1.1 augustss if (status != USBD_NORMAL_COMPLETION) { 1350 1.169 mrg DPRINTF("status=%jd", status, 0, 0, 0); 1351 1.52 augustss if (status == USBD_STALLED) 1352 1.52 augustss usbd_clear_endpoint_stall_async(sce->pipeh); 1353 1.1 augustss return; 1354 1.1 augustss } 1355 1.1 augustss 1356 1.34 augustss usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1357 1.1 augustss ibuf = sce->ibuf; 1358 1.1 augustss 1359 1.178 skrll DPRINTFN(5, "xfer=%#jx status=%jd count=%jd", 1360 1.175 hannken (uintptr_t)xfer, status, count, 0); 1361 1.178 skrll DPRINTFN(5, " data = %02jx %02jx %02jx", 1362 1.169 mrg ibuf[0], ibuf[1], ibuf[2], 0); 1363 1.1 augustss 1364 1.152 riastrad mutex_enter(&sc->sc_lock); 1365 1.8 augustss (void)b_to_q(ibuf, count, &sce->q); 1366 1.152 riastrad cv_signal(&sce->cv); 1367 1.120 mrg mutex_exit(&sc->sc_lock); 1368 1.97 rmind selnotify(&sce->rsel, 0, 0); 1369 1.1 augustss } 1370 1.1 augustss 1371 1.41 augustss Static void 1372 1.133 skrll ugen_isoc_rintr(struct usbd_xfer *xfer, void *addr, 1373 1.42 augustss usbd_status status) 1374 1.41 augustss { 1375 1.41 augustss struct isoreq *req = addr; 1376 1.41 augustss struct ugen_endpoint *sce = req->sce; 1377 1.120 mrg struct ugen_softc *sc = sce->sc; 1378 1.133 skrll uint32_t count, n; 1379 1.48 yamt int i, isize; 1380 1.41 augustss 1381 1.172 mrg UGENHIST_FUNC(); 1382 1.172 mrg UGENHIST_CALLARGS("xfer=%jx status=%jd", (uintptr_t)xfer, status, 0, 0); 1383 1.169 mrg 1384 1.41 augustss /* Return if we are aborting. */ 1385 1.41 augustss if (status == USBD_CANCELLED) 1386 1.41 augustss return; 1387 1.41 augustss 1388 1.41 augustss usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1389 1.178 skrll DPRINTFN(5, "xfer %jd, count=%jd", 1390 1.178 skrll (intmax_t)(req - sce->isoreqs), count, 0, 0); 1391 1.41 augustss 1392 1.152 riastrad mutex_enter(&sc->sc_lock); 1393 1.152 riastrad 1394 1.41 augustss /* throw away oldest input if the buffer is full */ 1395 1.152 riastrad if (sce->fill < sce->cur && sce->cur <= sce->fill + count) { 1396 1.41 augustss sce->cur += count; 1397 1.152 riastrad if (sce->cur >= sce->limit) 1398 1.41 augustss sce->cur = sce->ibuf + (sce->limit - sce->cur); 1399 1.169 mrg DPRINTFN(5, "throwing away %jd bytes", 1400 1.169 mrg count, 0, 0, 0); 1401 1.41 augustss } 1402 1.41 augustss 1403 1.48 yamt isize = UGETW(sce->edesc->wMaxPacketSize); 1404 1.48 yamt for (i = 0; i < UGEN_NISORFRMS; i++) { 1405 1.133 skrll uint32_t actlen = req->sizes[i]; 1406 1.74 christos char const *tbuf = (char const *)req->dmabuf + isize * i; 1407 1.48 yamt 1408 1.48 yamt /* copy data to buffer */ 1409 1.48 yamt while (actlen > 0) { 1410 1.140 riastrad n = uimin(actlen, sce->limit - sce->fill); 1411 1.74 christos memcpy(sce->fill, tbuf, n); 1412 1.48 yamt 1413 1.74 christos tbuf += n; 1414 1.48 yamt actlen -= n; 1415 1.48 yamt sce->fill += n; 1416 1.152 riastrad if (sce->fill == sce->limit) 1417 1.48 yamt sce->fill = sce->ibuf; 1418 1.48 yamt } 1419 1.48 yamt 1420 1.48 yamt /* setup size for next transfer */ 1421 1.48 yamt req->sizes[i] = isize; 1422 1.41 augustss } 1423 1.41 augustss 1424 1.133 skrll usbd_setup_isoc_xfer(xfer, req, req->sizes, UGEN_NISORFRMS, 0, 1425 1.133 skrll ugen_isoc_rintr); 1426 1.41 augustss (void)usbd_transfer(xfer); 1427 1.41 augustss 1428 1.152 riastrad cv_signal(&sce->cv); 1429 1.120 mrg mutex_exit(&sc->sc_lock); 1430 1.97 rmind selnotify(&sce->rsel, 0, 0); 1431 1.41 augustss } 1432 1.41 augustss 1433 1.84 gdt Static void 1434 1.133 skrll ugen_bulkra_intr(struct usbd_xfer *xfer, void *addr, 1435 1.84 gdt usbd_status status) 1436 1.84 gdt { 1437 1.84 gdt struct ugen_endpoint *sce = addr; 1438 1.120 mrg struct ugen_softc *sc = sce->sc; 1439 1.133 skrll uint32_t count, n; 1440 1.84 gdt char const *tbuf; 1441 1.84 gdt usbd_status err; 1442 1.84 gdt 1443 1.172 mrg UGENHIST_FUNC(); 1444 1.172 mrg UGENHIST_CALLARGS("xfer=%jx status=%jd", (uintptr_t)xfer, status, 0, 0); 1445 1.169 mrg 1446 1.84 gdt /* Return if we are aborting. */ 1447 1.84 gdt if (status == USBD_CANCELLED) 1448 1.84 gdt return; 1449 1.84 gdt 1450 1.84 gdt if (status != USBD_NORMAL_COMPLETION) { 1451 1.169 mrg DPRINTF("status=%jd", status, 0, 0, 0); 1452 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 1453 1.84 gdt if (status == USBD_STALLED) 1454 1.84 gdt usbd_clear_endpoint_stall_async(sce->pipeh); 1455 1.84 gdt return; 1456 1.84 gdt } 1457 1.84 gdt 1458 1.84 gdt usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1459 1.84 gdt 1460 1.152 riastrad mutex_enter(&sc->sc_lock); 1461 1.152 riastrad 1462 1.84 gdt /* Keep track of how much is in the buffer. */ 1463 1.84 gdt sce->ra_wb_used += count; 1464 1.84 gdt 1465 1.84 gdt /* Copy data to buffer. */ 1466 1.84 gdt tbuf = (char const *)usbd_get_buffer(sce->ra_wb_xfer); 1467 1.140 riastrad n = uimin(count, sce->limit - sce->fill); 1468 1.84 gdt memcpy(sce->fill, tbuf, n); 1469 1.84 gdt tbuf += n; 1470 1.84 gdt count -= n; 1471 1.84 gdt sce->fill += n; 1472 1.84 gdt if (sce->fill == sce->limit) 1473 1.84 gdt sce->fill = sce->ibuf; 1474 1.84 gdt if (count > 0) { 1475 1.84 gdt memcpy(sce->fill, tbuf, count); 1476 1.84 gdt sce->fill += count; 1477 1.84 gdt } 1478 1.84 gdt 1479 1.84 gdt /* Set up the next request if necessary. */ 1480 1.84 gdt n = (sce->limit - sce->ibuf) - sce->ra_wb_used; 1481 1.84 gdt if (n > 0) { 1482 1.140 riastrad usbd_setup_xfer(xfer, sce, NULL, uimin(n, sce->ra_wb_xferlen), 0, 1483 1.84 gdt USBD_NO_TIMEOUT, ugen_bulkra_intr); 1484 1.84 gdt err = usbd_transfer(xfer); 1485 1.84 gdt if (err != USBD_IN_PROGRESS) { 1486 1.169 mrg printf("error=%d", err); 1487 1.84 gdt /* 1488 1.84 gdt * The transfer has not been queued. Setting STOP 1489 1.84 gdt * will make us try again at the next read. 1490 1.84 gdt */ 1491 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 1492 1.84 gdt } 1493 1.84 gdt } 1494 1.84 gdt else 1495 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 1496 1.84 gdt 1497 1.152 riastrad cv_signal(&sce->cv); 1498 1.120 mrg mutex_exit(&sc->sc_lock); 1499 1.97 rmind selnotify(&sce->rsel, 0, 0); 1500 1.84 gdt } 1501 1.84 gdt 1502 1.84 gdt Static void 1503 1.133 skrll ugen_bulkwb_intr(struct usbd_xfer *xfer, void *addr, 1504 1.84 gdt usbd_status status) 1505 1.84 gdt { 1506 1.84 gdt struct ugen_endpoint *sce = addr; 1507 1.120 mrg struct ugen_softc *sc = sce->sc; 1508 1.133 skrll uint32_t count, n; 1509 1.84 gdt char *tbuf; 1510 1.84 gdt usbd_status err; 1511 1.84 gdt 1512 1.172 mrg UGENHIST_FUNC(); 1513 1.172 mrg UGENHIST_CALLARGS("xfer=%jx status=%jd", (uintptr_t)xfer, status, 0, 0); 1514 1.169 mrg 1515 1.84 gdt /* Return if we are aborting. */ 1516 1.84 gdt if (status == USBD_CANCELLED) 1517 1.84 gdt return; 1518 1.84 gdt 1519 1.84 gdt if (status != USBD_NORMAL_COMPLETION) { 1520 1.169 mrg DPRINTF("status=%jd", status, 0, 0, 0); 1521 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 1522 1.84 gdt if (status == USBD_STALLED) 1523 1.84 gdt usbd_clear_endpoint_stall_async(sce->pipeh); 1524 1.84 gdt return; 1525 1.84 gdt } 1526 1.84 gdt 1527 1.84 gdt usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1528 1.84 gdt 1529 1.152 riastrad mutex_enter(&sc->sc_lock); 1530 1.152 riastrad 1531 1.84 gdt /* Keep track of how much is in the buffer. */ 1532 1.84 gdt sce->ra_wb_used -= count; 1533 1.84 gdt 1534 1.84 gdt /* Update buffer pointers. */ 1535 1.84 gdt sce->cur += count; 1536 1.84 gdt if (sce->cur >= sce->limit) 1537 1.122 christos sce->cur = sce->ibuf + (sce->cur - sce->limit); 1538 1.84 gdt 1539 1.84 gdt /* Set up next request if necessary. */ 1540 1.84 gdt if (sce->ra_wb_used > 0) { 1541 1.84 gdt /* copy data from buffer */ 1542 1.84 gdt tbuf = (char *)usbd_get_buffer(sce->ra_wb_xfer); 1543 1.140 riastrad count = uimin(sce->ra_wb_used, sce->ra_wb_xferlen); 1544 1.140 riastrad n = uimin(count, sce->limit - sce->cur); 1545 1.84 gdt memcpy(tbuf, sce->cur, n); 1546 1.84 gdt tbuf += n; 1547 1.84 gdt if (count - n > 0) 1548 1.84 gdt memcpy(tbuf, sce->ibuf, count - n); 1549 1.84 gdt 1550 1.133 skrll usbd_setup_xfer(xfer, sce, NULL, count, 0, USBD_NO_TIMEOUT, 1551 1.133 skrll ugen_bulkwb_intr); 1552 1.84 gdt err = usbd_transfer(xfer); 1553 1.84 gdt if (err != USBD_IN_PROGRESS) { 1554 1.169 mrg printf("error=%d", err); 1555 1.84 gdt /* 1556 1.84 gdt * The transfer has not been queued. Setting STOP 1557 1.84 gdt * will make us try again at the next write. 1558 1.84 gdt */ 1559 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 1560 1.84 gdt } 1561 1.84 gdt } 1562 1.84 gdt else 1563 1.84 gdt sce->state |= UGEN_RA_WB_STOP; 1564 1.84 gdt 1565 1.152 riastrad cv_signal(&sce->cv); 1566 1.120 mrg mutex_exit(&sc->sc_lock); 1567 1.97 rmind selnotify(&sce->rsel, 0, 0); 1568 1.84 gdt } 1569 1.84 gdt 1570 1.37 augustss Static usbd_status 1571 1.40 augustss ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) 1572 1.1 augustss { 1573 1.133 skrll struct usbd_interface *iface; 1574 1.1 augustss usb_endpoint_descriptor_t *ed; 1575 1.28 augustss usbd_status err; 1576 1.1 augustss struct ugen_endpoint *sce; 1577 1.133 skrll uint8_t niface, nendpt, endptno, endpt; 1578 1.21 augustss int dir; 1579 1.1 augustss 1580 1.172 mrg UGENHIST_FUNC(); 1581 1.172 mrg UGENHIST_CALLARGSN(15, "ifaceidx=%jd altno=%jd", ifaceidx, altno, 0, 0); 1582 1.1 augustss 1583 1.28 augustss err = usbd_interface_count(sc->sc_udev, &niface); 1584 1.28 augustss if (err) 1585 1.133 skrll return err; 1586 1.1 augustss if (ifaceidx < 0 || ifaceidx >= niface) 1587 1.133 skrll return USBD_INVAL; 1588 1.59 augustss 1589 1.28 augustss err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 1590 1.28 augustss if (err) 1591 1.133 skrll return err; 1592 1.28 augustss err = usbd_endpoint_count(iface, &nendpt); 1593 1.28 augustss if (err) 1594 1.133 skrll return err; 1595 1.1 augustss 1596 1.1 augustss /* change setting */ 1597 1.28 augustss err = usbd_set_interface(iface, altno); 1598 1.28 augustss if (err) 1599 1.133 skrll return err; 1600 1.28 augustss 1601 1.28 augustss err = usbd_endpoint_count(iface, &nendpt); 1602 1.28 augustss if (err) 1603 1.133 skrll return err; 1604 1.130 skrll 1605 1.130 skrll ugen_clear_endpoints(sc); 1606 1.130 skrll 1607 1.1 augustss for (endptno = 0; endptno < nendpt; endptno++) { 1608 1.174 simonb ed = usbd_interface2endpoint_descriptor(iface, endptno); 1609 1.81 christos KASSERT(ed != NULL); 1610 1.1 augustss endpt = ed->bEndpointAddress; 1611 1.21 augustss dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; 1612 1.21 augustss sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; 1613 1.1 augustss sce->sc = sc; 1614 1.1 augustss sce->edesc = ed; 1615 1.1 augustss sce->iface = iface; 1616 1.1 augustss } 1617 1.133 skrll return 0; 1618 1.1 augustss } 1619 1.1 augustss 1620 1.1 augustss /* Retrieve a complete descriptor for a certain device and index. */ 1621 1.37 augustss Static usb_config_descriptor_t * 1622 1.40 augustss ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp) 1623 1.1 augustss { 1624 1.172 mrg usb_config_descriptor_t *cdesc = NULL, *tdesc, cdescr; 1625 1.172 mrg int len = 0; 1626 1.28 augustss usbd_status err; 1627 1.1 augustss 1628 1.172 mrg UGENHIST_FUNC(); UGENHIST_CALLARGS("index=%jd", index, 0, 0, 0); 1629 1.169 mrg 1630 1.172 mrg switch (index) { 1631 1.172 mrg case USB_CURRENT_CONFIG_INDEX: 1632 1.1 augustss tdesc = usbd_get_config_descriptor(sc->sc_udev); 1633 1.148 bouyer if (tdesc == NULL) 1634 1.172 mrg break; 1635 1.1 augustss len = UGETW(tdesc->wTotalLength); 1636 1.133 skrll cdesc = kmem_alloc(len, KM_SLEEP); 1637 1.1 augustss memcpy(cdesc, tdesc, len); 1638 1.172 mrg break; 1639 1.172 mrg default: 1640 1.28 augustss err = usbd_get_config_desc(sc->sc_udev, index, &cdescr); 1641 1.28 augustss if (err) 1642 1.172 mrg break; 1643 1.1 augustss len = UGETW(cdescr.wTotalLength); 1644 1.133 skrll cdesc = kmem_alloc(len, KM_SLEEP); 1645 1.56 augustss err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len); 1646 1.28 augustss if (err) { 1647 1.133 skrll kmem_free(cdesc, len); 1648 1.172 mrg cdesc = NULL; 1649 1.1 augustss } 1650 1.172 mrg break; 1651 1.1 augustss } 1652 1.172 mrg DPRINTFN(5, "req len=%jd cdesc=%jx", len, (uintptr_t)cdesc, 0, 0); 1653 1.172 mrg if (cdesc && lenp) 1654 1.172 mrg *lenp = len; 1655 1.133 skrll return cdesc; 1656 1.1 augustss } 1657 1.1 augustss 1658 1.37 augustss Static int 1659 1.40 augustss ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx) 1660 1.1 augustss { 1661 1.133 skrll struct usbd_interface *iface; 1662 1.28 augustss usbd_status err; 1663 1.1 augustss 1664 1.28 augustss err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); 1665 1.28 augustss if (err) 1666 1.133 skrll return -1; 1667 1.133 skrll return usbd_get_interface_altindex(iface); 1668 1.1 augustss } 1669 1.1 augustss 1670 1.37 augustss Static int 1671 1.40 augustss ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, 1672 1.92 christos void *addr, int flag, struct lwp *l) 1673 1.1 augustss { 1674 1.8 augustss struct ugen_endpoint *sce; 1675 1.28 augustss usbd_status err; 1676 1.133 skrll struct usbd_interface *iface; 1677 1.1 augustss struct usb_config_desc *cd; 1678 1.1 augustss usb_config_descriptor_t *cdesc; 1679 1.1 augustss struct usb_interface_desc *id; 1680 1.1 augustss usb_interface_descriptor_t *idesc; 1681 1.1 augustss struct usb_endpoint_desc *ed; 1682 1.1 augustss usb_endpoint_descriptor_t *edesc; 1683 1.1 augustss struct usb_alt_interface *ai; 1684 1.2 augustss struct usb_string_desc *si; 1685 1.133 skrll uint8_t conf, alt; 1686 1.133 skrll int cdesclen; 1687 1.133 skrll int error; 1688 1.141 manu int dir; 1689 1.1 augustss 1690 1.172 mrg UGENHIST_FUNC(); 1691 1.172 mrg UGENHIST_CALLARGS("ugen%d: endpt=%ju cmd=%08jx flag=%jx", 1692 1.172 mrg device_unit(sc->sc_dev), endpt, cmd, flag); 1693 1.169 mrg 1694 1.159 riastrad KASSERT(KERNEL_LOCKED_P()); /* ugen_set_config */ 1695 1.159 riastrad 1696 1.2 augustss switch (cmd) { 1697 1.2 augustss case FIONBIO: 1698 1.2 augustss /* All handled in the upper FS layer. */ 1699 1.133 skrll return 0; 1700 1.8 augustss case USB_SET_SHORT_XFER: 1701 1.13 augustss if (endpt == USB_CONTROL_ENDPOINT) 1702 1.133 skrll return EINVAL; 1703 1.51 augustss /* This flag only affects read */ 1704 1.8 augustss sce = &sc->sc_endpoints[endpt][IN]; 1705 1.51 augustss if (sce == NULL || sce->pipeh == NULL) 1706 1.133 skrll return EINVAL; 1707 1.8 augustss if (*(int *)addr) 1708 1.8 augustss sce->state |= UGEN_SHORT_OK; 1709 1.8 augustss else 1710 1.8 augustss sce->state &= ~UGEN_SHORT_OK; 1711 1.172 mrg DPRINTFN(5, "pipe=%jx short xfer=%ju", 1712 1.172 mrg (uintptr_t)sce->pipeh, sce->state & UGEN_SHORT_OK, 0, 0); 1713 1.133 skrll return 0; 1714 1.17 augustss case USB_SET_TIMEOUT: 1715 1.141 manu for (dir = OUT; dir <= IN; dir++) { 1716 1.141 manu sce = &sc->sc_endpoints[endpt][dir]; 1717 1.141 manu if (sce == NULL) 1718 1.141 manu return EINVAL; 1719 1.141 manu 1720 1.141 manu sce->timeout = *(int *)addr; 1721 1.172 mrg DPRINTFN(5, "pipe=%jx timeout[dir=%ju] timeout=%ju", 1722 1.172 mrg (uintptr_t)sce->pipeh, dir, sce->timeout, 0); 1723 1.141 manu } 1724 1.133 skrll return 0; 1725 1.84 gdt case USB_SET_BULK_RA: 1726 1.84 gdt if (endpt == USB_CONTROL_ENDPOINT) 1727 1.133 skrll return EINVAL; 1728 1.84 gdt sce = &sc->sc_endpoints[endpt][IN]; 1729 1.84 gdt if (sce == NULL || sce->pipeh == NULL) 1730 1.133 skrll return EINVAL; 1731 1.84 gdt edesc = sce->edesc; 1732 1.84 gdt if ((edesc->bmAttributes & UE_XFERTYPE) != UE_BULK) 1733 1.133 skrll return EINVAL; 1734 1.84 gdt 1735 1.84 gdt if (*(int *)addr) { 1736 1.84 gdt /* Only turn RA on if it's currently off. */ 1737 1.84 gdt if (sce->state & UGEN_BULK_RA) 1738 1.133 skrll return 0; 1739 1.167 riastrad KASSERT(sce->ra_wb_xfer == NULL); 1740 1.167 riastrad KASSERT(sce->ibuf == NULL); 1741 1.84 gdt 1742 1.84 gdt if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0) 1743 1.84 gdt /* shouldn't happen */ 1744 1.133 skrll return EINVAL; 1745 1.133 skrll error = usbd_create_xfer(sce->pipeh, 1746 1.133 skrll sce->ra_wb_reqsize, 0, 0, &sce->ra_wb_xfer); 1747 1.133 skrll if (error) 1748 1.133 skrll return error; 1749 1.84 gdt sce->ra_wb_xferlen = sce->ra_wb_reqsize; 1750 1.133 skrll sce->ibuf = kmem_alloc(sce->ra_wb_bufsize, KM_SLEEP); 1751 1.84 gdt sce->fill = sce->cur = sce->ibuf; 1752 1.84 gdt sce->limit = sce->ibuf + sce->ra_wb_bufsize; 1753 1.84 gdt sce->ra_wb_used = 0; 1754 1.84 gdt sce->state |= UGEN_BULK_RA; 1755 1.84 gdt sce->state &= ~UGEN_RA_WB_STOP; 1756 1.84 gdt /* Now start reading. */ 1757 1.133 skrll usbd_setup_xfer(sce->ra_wb_xfer, sce, NULL, 1758 1.140 riastrad uimin(sce->ra_wb_xferlen, sce->ra_wb_bufsize), 1759 1.133 skrll 0, USBD_NO_TIMEOUT, ugen_bulkra_intr); 1760 1.84 gdt err = usbd_transfer(sce->ra_wb_xfer); 1761 1.84 gdt if (err != USBD_IN_PROGRESS) { 1762 1.84 gdt sce->state &= ~UGEN_BULK_RA; 1763 1.133 skrll kmem_free(sce->ibuf, sce->ra_wb_bufsize); 1764 1.84 gdt sce->ibuf = NULL; 1765 1.133 skrll usbd_destroy_xfer(sce->ra_wb_xfer); 1766 1.167 riastrad sce->ra_wb_xfer = NULL; 1767 1.133 skrll return EIO; 1768 1.84 gdt } 1769 1.84 gdt } else { 1770 1.84 gdt /* Only turn RA off if it's currently on. */ 1771 1.84 gdt if (!(sce->state & UGEN_BULK_RA)) 1772 1.133 skrll return 0; 1773 1.84 gdt 1774 1.84 gdt sce->state &= ~UGEN_BULK_RA; 1775 1.84 gdt usbd_abort_pipe(sce->pipeh); 1776 1.133 skrll usbd_destroy_xfer(sce->ra_wb_xfer); 1777 1.167 riastrad sce->ra_wb_xfer = NULL; 1778 1.84 gdt /* 1779 1.84 gdt * XXX Discard whatever's in the buffer, but we 1780 1.84 gdt * should keep it around and drain the buffer 1781 1.84 gdt * instead. 1782 1.84 gdt */ 1783 1.133 skrll kmem_free(sce->ibuf, sce->ra_wb_bufsize); 1784 1.84 gdt sce->ibuf = NULL; 1785 1.84 gdt } 1786 1.133 skrll return 0; 1787 1.84 gdt case USB_SET_BULK_WB: 1788 1.84 gdt if (endpt == USB_CONTROL_ENDPOINT) 1789 1.133 skrll return EINVAL; 1790 1.84 gdt sce = &sc->sc_endpoints[endpt][OUT]; 1791 1.84 gdt if (sce == NULL || sce->pipeh == NULL) 1792 1.133 skrll return EINVAL; 1793 1.84 gdt edesc = sce->edesc; 1794 1.84 gdt if ((edesc->bmAttributes & UE_XFERTYPE) != UE_BULK) 1795 1.133 skrll return EINVAL; 1796 1.84 gdt 1797 1.84 gdt if (*(int *)addr) { 1798 1.84 gdt /* Only turn WB on if it's currently off. */ 1799 1.84 gdt if (sce->state & UGEN_BULK_WB) 1800 1.133 skrll return 0; 1801 1.167 riastrad KASSERT(sce->ra_wb_xfer == NULL); 1802 1.167 riastrad KASSERT(sce->ibuf == NULL); 1803 1.84 gdt 1804 1.84 gdt if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0) 1805 1.84 gdt /* shouldn't happen */ 1806 1.133 skrll return EINVAL; 1807 1.133 skrll error = usbd_create_xfer(sce->pipeh, sce->ra_wb_reqsize, 1808 1.133 skrll 0, 0, &sce->ra_wb_xfer); 1809 1.167 riastrad /* XXX check error??? */ 1810 1.84 gdt sce->ra_wb_xferlen = sce->ra_wb_reqsize; 1811 1.133 skrll sce->ibuf = kmem_alloc(sce->ra_wb_bufsize, KM_SLEEP); 1812 1.84 gdt sce->fill = sce->cur = sce->ibuf; 1813 1.84 gdt sce->limit = sce->ibuf + sce->ra_wb_bufsize; 1814 1.84 gdt sce->ra_wb_used = 0; 1815 1.84 gdt sce->state |= UGEN_BULK_WB | UGEN_RA_WB_STOP; 1816 1.84 gdt } else { 1817 1.84 gdt /* Only turn WB off if it's currently on. */ 1818 1.84 gdt if (!(sce->state & UGEN_BULK_WB)) 1819 1.133 skrll return 0; 1820 1.84 gdt 1821 1.84 gdt sce->state &= ~UGEN_BULK_WB; 1822 1.84 gdt /* 1823 1.84 gdt * XXX Discard whatever's in the buffer, but we 1824 1.122 christos * should keep it around and keep writing to 1825 1.84 gdt * drain the buffer instead. 1826 1.84 gdt */ 1827 1.84 gdt usbd_abort_pipe(sce->pipeh); 1828 1.133 skrll usbd_destroy_xfer(sce->ra_wb_xfer); 1829 1.167 riastrad sce->ra_wb_xfer = NULL; 1830 1.133 skrll kmem_free(sce->ibuf, sce->ra_wb_bufsize); 1831 1.84 gdt sce->ibuf = NULL; 1832 1.84 gdt } 1833 1.133 skrll return 0; 1834 1.84 gdt case USB_SET_BULK_RA_OPT: 1835 1.84 gdt case USB_SET_BULK_WB_OPT: 1836 1.84 gdt { 1837 1.84 gdt struct usb_bulk_ra_wb_opt *opt; 1838 1.84 gdt 1839 1.84 gdt if (endpt == USB_CONTROL_ENDPOINT) 1840 1.133 skrll return EINVAL; 1841 1.84 gdt opt = (struct usb_bulk_ra_wb_opt *)addr; 1842 1.84 gdt if (cmd == USB_SET_BULK_RA_OPT) 1843 1.84 gdt sce = &sc->sc_endpoints[endpt][IN]; 1844 1.84 gdt else 1845 1.84 gdt sce = &sc->sc_endpoints[endpt][OUT]; 1846 1.84 gdt if (sce == NULL || sce->pipeh == NULL) 1847 1.133 skrll return EINVAL; 1848 1.84 gdt if (opt->ra_wb_buffer_size < 1 || 1849 1.84 gdt opt->ra_wb_buffer_size > UGEN_BULK_RA_WB_BUFMAX || 1850 1.84 gdt opt->ra_wb_request_size < 1 || 1851 1.84 gdt opt->ra_wb_request_size > opt->ra_wb_buffer_size) 1852 1.133 skrll return EINVAL; 1853 1.122 christos /* 1854 1.84 gdt * XXX These changes do not take effect until the 1855 1.84 gdt * next time RA/WB mode is enabled but they ought to 1856 1.84 gdt * take effect immediately. 1857 1.84 gdt */ 1858 1.84 gdt sce->ra_wb_bufsize = opt->ra_wb_buffer_size; 1859 1.84 gdt sce->ra_wb_reqsize = opt->ra_wb_request_size; 1860 1.133 skrll return 0; 1861 1.84 gdt } 1862 1.2 augustss default: 1863 1.2 augustss break; 1864 1.2 augustss } 1865 1.2 augustss 1866 1.1 augustss if (endpt != USB_CONTROL_ENDPOINT) 1867 1.133 skrll return EINVAL; 1868 1.1 augustss 1869 1.1 augustss switch (cmd) { 1870 1.30 augustss #ifdef UGEN_DEBUG 1871 1.8 augustss case USB_SETDEBUG: 1872 1.8 augustss ugendebug = *(int *)addr; 1873 1.8 augustss break; 1874 1.8 augustss #endif 1875 1.1 augustss case USB_GET_CONFIG: 1876 1.28 augustss err = usbd_get_config(sc->sc_udev, &conf); 1877 1.28 augustss if (err) 1878 1.133 skrll return EIO; 1879 1.1 augustss *(int *)addr = conf; 1880 1.1 augustss break; 1881 1.1 augustss case USB_SET_CONFIG: 1882 1.2 augustss if (!(flag & FWRITE)) 1883 1.133 skrll return EPERM; 1884 1.138 ws err = ugen_set_config(sc, *(int *)addr, 1); 1885 1.53 augustss switch (err) { 1886 1.53 augustss case USBD_NORMAL_COMPLETION: 1887 1.53 augustss break; 1888 1.53 augustss case USBD_IN_USE: 1889 1.133 skrll return EBUSY; 1890 1.53 augustss default: 1891 1.133 skrll return EIO; 1892 1.53 augustss } 1893 1.1 augustss break; 1894 1.1 augustss case USB_GET_ALTINTERFACE: 1895 1.1 augustss ai = (struct usb_alt_interface *)addr; 1896 1.55 augustss err = usbd_device2interface_handle(sc->sc_udev, 1897 1.58 christos ai->uai_interface_index, &iface); 1898 1.28 augustss if (err) 1899 1.133 skrll return EINVAL; 1900 1.1 augustss idesc = usbd_get_interface_descriptor(iface); 1901 1.28 augustss if (idesc == NULL) 1902 1.133 skrll return EIO; 1903 1.58 christos ai->uai_alt_no = idesc->bAlternateSetting; 1904 1.1 augustss break; 1905 1.1 augustss case USB_SET_ALTINTERFACE: 1906 1.2 augustss if (!(flag & FWRITE)) 1907 1.133 skrll return EPERM; 1908 1.1 augustss ai = (struct usb_alt_interface *)addr; 1909 1.55 augustss err = usbd_device2interface_handle(sc->sc_udev, 1910 1.58 christos ai->uai_interface_index, &iface); 1911 1.28 augustss if (err) 1912 1.133 skrll return EINVAL; 1913 1.58 christos err = ugen_set_interface(sc, ai->uai_interface_index, 1914 1.58 christos ai->uai_alt_no); 1915 1.28 augustss if (err) 1916 1.133 skrll return EINVAL; 1917 1.1 augustss break; 1918 1.1 augustss case USB_GET_NO_ALT: 1919 1.1 augustss ai = (struct usb_alt_interface *)addr; 1920 1.133 skrll cdesc = ugen_get_cdesc(sc, ai->uai_config_index, &cdesclen); 1921 1.28 augustss if (cdesc == NULL) 1922 1.133 skrll return EINVAL; 1923 1.58 christos idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0); 1924 1.28 augustss if (idesc == NULL) { 1925 1.133 skrll kmem_free(cdesc, cdesclen); 1926 1.133 skrll return EINVAL; 1927 1.12 augustss } 1928 1.58 christos ai->uai_alt_no = usbd_get_no_alts(cdesc, 1929 1.58 christos idesc->bInterfaceNumber); 1930 1.133 skrll kmem_free(cdesc, cdesclen); 1931 1.1 augustss break; 1932 1.1 augustss case USB_GET_DEVICE_DESC: 1933 1.1 augustss *(usb_device_descriptor_t *)addr = 1934 1.1 augustss *usbd_get_device_descriptor(sc->sc_udev); 1935 1.1 augustss break; 1936 1.1 augustss case USB_GET_CONFIG_DESC: 1937 1.1 augustss cd = (struct usb_config_desc *)addr; 1938 1.133 skrll cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, &cdesclen); 1939 1.28 augustss if (cdesc == NULL) 1940 1.133 skrll return EINVAL; 1941 1.58 christos cd->ucd_desc = *cdesc; 1942 1.133 skrll kmem_free(cdesc, cdesclen); 1943 1.1 augustss break; 1944 1.1 augustss case USB_GET_INTERFACE_DESC: 1945 1.1 augustss id = (struct usb_interface_desc *)addr; 1946 1.133 skrll cdesc = ugen_get_cdesc(sc, id->uid_config_index, &cdesclen); 1947 1.28 augustss if (cdesc == NULL) 1948 1.133 skrll return EINVAL; 1949 1.58 christos if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX && 1950 1.58 christos id->uid_alt_index == USB_CURRENT_ALT_INDEX) 1951 1.58 christos alt = ugen_get_alt_index(sc, id->uid_interface_index); 1952 1.1 augustss else 1953 1.58 christos alt = id->uid_alt_index; 1954 1.58 christos idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt); 1955 1.28 augustss if (idesc == NULL) { 1956 1.133 skrll kmem_free(cdesc, cdesclen); 1957 1.133 skrll return EINVAL; 1958 1.1 augustss } 1959 1.58 christos id->uid_desc = *idesc; 1960 1.133 skrll kmem_free(cdesc, cdesclen); 1961 1.1 augustss break; 1962 1.1 augustss case USB_GET_ENDPOINT_DESC: 1963 1.1 augustss ed = (struct usb_endpoint_desc *)addr; 1964 1.133 skrll cdesc = ugen_get_cdesc(sc, ed->ued_config_index, &cdesclen); 1965 1.28 augustss if (cdesc == NULL) 1966 1.133 skrll return EINVAL; 1967 1.58 christos if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX && 1968 1.58 christos ed->ued_alt_index == USB_CURRENT_ALT_INDEX) 1969 1.58 christos alt = ugen_get_alt_index(sc, ed->ued_interface_index); 1970 1.1 augustss else 1971 1.58 christos alt = ed->ued_alt_index; 1972 1.58 christos edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, 1973 1.58 christos alt, ed->ued_endpoint_index); 1974 1.28 augustss if (edesc == NULL) { 1975 1.133 skrll kmem_free(cdesc, cdesclen); 1976 1.133 skrll return EINVAL; 1977 1.1 augustss } 1978 1.58 christos ed->ued_desc = *edesc; 1979 1.133 skrll kmem_free(cdesc, cdesclen); 1980 1.1 augustss break; 1981 1.1 augustss case USB_GET_FULL_DESC: 1982 1.1 augustss { 1983 1.1 augustss int len; 1984 1.1 augustss struct iovec iov; 1985 1.1 augustss struct uio uio; 1986 1.1 augustss struct usb_full_desc *fd = (struct usb_full_desc *)addr; 1987 1.1 augustss 1988 1.133 skrll cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &cdesclen); 1989 1.104 pooka if (cdesc == NULL) 1990 1.133 skrll return EINVAL; 1991 1.133 skrll len = cdesclen; 1992 1.58 christos if (len > fd->ufd_size) 1993 1.58 christos len = fd->ufd_size; 1994 1.92 christos iov.iov_base = (void *)fd->ufd_data; 1995 1.1 augustss iov.iov_len = len; 1996 1.1 augustss uio.uio_iov = &iov; 1997 1.1 augustss uio.uio_iovcnt = 1; 1998 1.1 augustss uio.uio_resid = len; 1999 1.1 augustss uio.uio_offset = 0; 2000 1.1 augustss uio.uio_rw = UIO_READ; 2001 1.79 yamt uio.uio_vmspace = l->l_proc->p_vmspace; 2002 1.30 augustss error = uiomove((void *)cdesc, len, &uio); 2003 1.133 skrll kmem_free(cdesc, cdesclen); 2004 1.133 skrll return error; 2005 1.1 augustss } 2006 1.68 mycroft case USB_GET_STRING_DESC: { 2007 1.68 mycroft int len; 2008 1.2 augustss si = (struct usb_string_desc *)addr; 2009 1.58 christos err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, 2010 1.68 mycroft si->usd_language_id, &si->usd_desc, &len); 2011 1.28 augustss if (err) 2012 1.133 skrll return EINVAL; 2013 1.2 augustss break; 2014 1.68 mycroft } 2015 1.1 augustss case USB_DO_REQUEST: 2016 1.1 augustss { 2017 1.1 augustss struct usb_ctl_request *ur = (void *)addr; 2018 1.58 christos int len = UGETW(ur->ucr_request.wLength); 2019 1.1 augustss struct iovec iov; 2020 1.1 augustss struct uio uio; 2021 1.1 augustss void *ptr = 0; 2022 1.74 christos usbd_status xerr; 2023 1.133 skrll 2024 1.133 skrll error = 0; 2025 1.1 augustss 2026 1.2 augustss if (!(flag & FWRITE)) 2027 1.133 skrll return EPERM; 2028 1.1 augustss /* Avoid requests that would damage the bus integrity. */ 2029 1.58 christos if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 2030 1.58 christos ur->ucr_request.bRequest == UR_SET_ADDRESS) || 2031 1.58 christos (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && 2032 1.58 christos ur->ucr_request.bRequest == UR_SET_CONFIG) || 2033 1.58 christos (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && 2034 1.58 christos ur->ucr_request.bRequest == UR_SET_INTERFACE)) 2035 1.133 skrll return EINVAL; 2036 1.1 augustss 2037 1.1 augustss if (len < 0 || len > 32767) 2038 1.133 skrll return EINVAL; 2039 1.1 augustss if (len != 0) { 2040 1.92 christos iov.iov_base = (void *)ur->ucr_data; 2041 1.1 augustss iov.iov_len = len; 2042 1.1 augustss uio.uio_iov = &iov; 2043 1.1 augustss uio.uio_iovcnt = 1; 2044 1.1 augustss uio.uio_resid = len; 2045 1.1 augustss uio.uio_offset = 0; 2046 1.1 augustss uio.uio_rw = 2047 1.58 christos ur->ucr_request.bmRequestType & UT_READ ? 2048 1.1 augustss UIO_READ : UIO_WRITE; 2049 1.79 yamt uio.uio_vmspace = l->l_proc->p_vmspace; 2050 1.133 skrll ptr = kmem_alloc(len, KM_SLEEP); 2051 1.1 augustss if (uio.uio_rw == UIO_WRITE) { 2052 1.1 augustss error = uiomove(ptr, len, &uio); 2053 1.1 augustss if (error) 2054 1.1 augustss goto ret; 2055 1.1 augustss } 2056 1.1 augustss } 2057 1.57 augustss sce = &sc->sc_endpoints[endpt][IN]; 2058 1.74 christos xerr = usbd_do_request_flags(sc->sc_udev, &ur->ucr_request, 2059 1.58 christos ptr, ur->ucr_flags, &ur->ucr_actlen, sce->timeout); 2060 1.74 christos if (xerr) { 2061 1.1 augustss error = EIO; 2062 1.1 augustss goto ret; 2063 1.1 augustss } 2064 1.1 augustss if (len != 0) { 2065 1.1 augustss if (uio.uio_rw == UIO_READ) { 2066 1.140 riastrad size_t alen = uimin(len, ur->ucr_actlen); 2067 1.133 skrll error = uiomove(ptr, alen, &uio); 2068 1.1 augustss if (error) 2069 1.1 augustss goto ret; 2070 1.1 augustss } 2071 1.1 augustss } 2072 1.1 augustss ret: 2073 1.1 augustss if (ptr) 2074 1.133 skrll kmem_free(ptr, len); 2075 1.133 skrll return error; 2076 1.1 augustss } 2077 1.2 augustss case USB_GET_DEVICEINFO: 2078 1.2 augustss usbd_fill_deviceinfo(sc->sc_udev, 2079 1.91 drochner (struct usb_device_info *)addr, 0); 2080 1.2 augustss break; 2081 1.173 christos case USB_GET_DEVICEINFO_30: 2082 1.142 pgoyette { 2083 1.142 pgoyette int ret; 2084 1.145 pgoyette MODULE_HOOK_CALL(usb_subr_fill_30_hook, 2085 1.173 christos (sc->sc_udev, (struct usb_device_info30 *)addr, 0, 2086 1.142 pgoyette usbd_devinfo_vp, usbd_printBCD), 2087 1.142 pgoyette enosys(), ret); 2088 1.142 pgoyette if (ret == 0) 2089 1.142 pgoyette return 0; 2090 1.142 pgoyette return EINVAL; 2091 1.142 pgoyette } 2092 1.1 augustss default: 2093 1.133 skrll return EINVAL; 2094 1.1 augustss } 2095 1.133 skrll return 0; 2096 1.1 augustss } 2097 1.1 augustss 2098 1.147 maxv static int 2099 1.92 christos ugenioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 2100 1.12 augustss { 2101 1.12 augustss int endpt = UGENENDPOINT(dev); 2102 1.24 augustss struct ugen_softc *sc; 2103 1.12 augustss int error; 2104 1.12 augustss 2105 1.155 riastrad if ((sc = ugenif_acquire(UGENUNIT(dev))) == 0) 2106 1.111 dyoung return ENXIO; 2107 1.155 riastrad error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, l); 2108 1.155 riastrad ugenif_release(sc); 2109 1.30 augustss 2110 1.133 skrll return error; 2111 1.12 augustss } 2112 1.12 augustss 2113 1.147 maxv static int 2114 1.78 christos ugenpoll(dev_t dev, int events, struct lwp *l) 2115 1.1 augustss { 2116 1.24 augustss struct ugen_softc *sc; 2117 1.84 gdt struct ugen_endpoint *sce_in, *sce_out; 2118 1.1 augustss int revents = 0; 2119 1.1 augustss 2120 1.155 riastrad if ((sc = ugenif_acquire(UGENUNIT(dev))) == NULL) 2121 1.133 skrll return POLLHUP; 2122 1.1 augustss 2123 1.155 riastrad if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT) { 2124 1.155 riastrad revents |= POLLERR; 2125 1.155 riastrad goto out; 2126 1.155 riastrad } 2127 1.113 jakllsch 2128 1.84 gdt sce_in = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 2129 1.84 gdt sce_out = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT]; 2130 1.154 riastrad KASSERT(sce_in->edesc || sce_out->edesc); 2131 1.154 riastrad KASSERT(sce_in->pipeh || sce_out->pipeh); 2132 1.120 mrg 2133 1.120 mrg mutex_enter(&sc->sc_lock); 2134 1.84 gdt if (sce_in && sce_in->pipeh && (events & (POLLIN | POLLRDNORM))) 2135 1.84 gdt switch (sce_in->edesc->bmAttributes & UE_XFERTYPE) { 2136 1.84 gdt case UE_INTERRUPT: 2137 1.84 gdt if (sce_in->q.c_cc > 0) 2138 1.41 augustss revents |= events & (POLLIN | POLLRDNORM); 2139 1.41 augustss else 2140 1.84 gdt selrecord(l, &sce_in->rsel); 2141 1.84 gdt break; 2142 1.84 gdt case UE_ISOCHRONOUS: 2143 1.84 gdt if (sce_in->cur != sce_in->fill) 2144 1.1 augustss revents |= events & (POLLIN | POLLRDNORM); 2145 1.1 augustss else 2146 1.84 gdt selrecord(l, &sce_in->rsel); 2147 1.84 gdt break; 2148 1.84 gdt case UE_BULK: 2149 1.84 gdt if (sce_in->state & UGEN_BULK_RA) { 2150 1.84 gdt if (sce_in->ra_wb_used > 0) 2151 1.84 gdt revents |= events & 2152 1.84 gdt (POLLIN | POLLRDNORM); 2153 1.84 gdt else 2154 1.84 gdt selrecord(l, &sce_in->rsel); 2155 1.84 gdt break; 2156 1.84 gdt } 2157 1.84 gdt /* 2158 1.84 gdt * We have no easy way of determining if a read will 2159 1.84 gdt * yield any data or a write will happen. 2160 1.84 gdt * Pretend they will. 2161 1.84 gdt */ 2162 1.155 riastrad revents |= events & (POLLIN | POLLRDNORM); 2163 1.155 riastrad break; 2164 1.84 gdt default: 2165 1.84 gdt break; 2166 1.1 augustss } 2167 1.84 gdt if (sce_out && sce_out->pipeh && (events & (POLLOUT | POLLWRNORM))) 2168 1.84 gdt switch (sce_out->edesc->bmAttributes & UE_XFERTYPE) { 2169 1.84 gdt case UE_INTERRUPT: 2170 1.84 gdt case UE_ISOCHRONOUS: 2171 1.84 gdt /* XXX unimplemented */ 2172 1.84 gdt break; 2173 1.84 gdt case UE_BULK: 2174 1.84 gdt if (sce_out->state & UGEN_BULK_WB) { 2175 1.84 gdt if (sce_out->ra_wb_used < 2176 1.84 gdt sce_out->limit - sce_out->ibuf) 2177 1.84 gdt revents |= events & 2178 1.84 gdt (POLLOUT | POLLWRNORM); 2179 1.84 gdt else 2180 1.84 gdt selrecord(l, &sce_out->rsel); 2181 1.84 gdt break; 2182 1.84 gdt } 2183 1.84 gdt /* 2184 1.84 gdt * We have no easy way of determining if a read will 2185 1.84 gdt * yield any data or a write will happen. 2186 1.84 gdt * Pretend they will. 2187 1.84 gdt */ 2188 1.84 gdt revents |= events & (POLLOUT | POLLWRNORM); 2189 1.84 gdt break; 2190 1.84 gdt default: 2191 1.84 gdt break; 2192 1.84 gdt } 2193 1.84 gdt 2194 1.120 mrg mutex_exit(&sc->sc_lock); 2195 1.84 gdt 2196 1.155 riastrad out: ugenif_release(sc); 2197 1.133 skrll return revents; 2198 1.62 jdolecek } 2199 1.62 jdolecek 2200 1.62 jdolecek static void 2201 1.62 jdolecek filt_ugenrdetach(struct knote *kn) 2202 1.62 jdolecek { 2203 1.62 jdolecek struct ugen_endpoint *sce = kn->kn_hook; 2204 1.120 mrg struct ugen_softc *sc = sce->sc; 2205 1.62 jdolecek 2206 1.120 mrg mutex_enter(&sc->sc_lock); 2207 1.158 thorpej selremove_knote(&sce->rsel, kn); 2208 1.120 mrg mutex_exit(&sc->sc_lock); 2209 1.62 jdolecek } 2210 1.62 jdolecek 2211 1.62 jdolecek static int 2212 1.88 christos filt_ugenread_intr(struct knote *kn, long hint) 2213 1.62 jdolecek { 2214 1.62 jdolecek struct ugen_endpoint *sce = kn->kn_hook; 2215 1.135 mrg struct ugen_softc *sc = sce->sc; 2216 1.153 riastrad int ret; 2217 1.135 mrg 2218 1.153 riastrad mutex_enter(&sc->sc_lock); 2219 1.153 riastrad if (sc->sc_dying) { 2220 1.153 riastrad ret = 0; 2221 1.153 riastrad } else { 2222 1.153 riastrad kn->kn_data = sce->q.c_cc; 2223 1.153 riastrad ret = kn->kn_data > 0; 2224 1.153 riastrad } 2225 1.153 riastrad mutex_exit(&sc->sc_lock); 2226 1.62 jdolecek 2227 1.153 riastrad return ret; 2228 1.62 jdolecek } 2229 1.62 jdolecek 2230 1.62 jdolecek static int 2231 1.88 christos filt_ugenread_isoc(struct knote *kn, long hint) 2232 1.62 jdolecek { 2233 1.62 jdolecek struct ugen_endpoint *sce = kn->kn_hook; 2234 1.135 mrg struct ugen_softc *sc = sce->sc; 2235 1.153 riastrad int ret; 2236 1.135 mrg 2237 1.153 riastrad mutex_enter(&sc->sc_lock); 2238 1.153 riastrad if (sc->sc_dying) { 2239 1.153 riastrad ret = 0; 2240 1.153 riastrad } else if (sce->cur == sce->fill) { 2241 1.153 riastrad ret = 0; 2242 1.153 riastrad } else if (sce->cur < sce->fill) { 2243 1.62 jdolecek kn->kn_data = sce->fill - sce->cur; 2244 1.153 riastrad ret = 1; 2245 1.153 riastrad } else { 2246 1.62 jdolecek kn->kn_data = (sce->limit - sce->cur) + 2247 1.62 jdolecek (sce->fill - sce->ibuf); 2248 1.153 riastrad ret = 1; 2249 1.153 riastrad } 2250 1.153 riastrad mutex_exit(&sc->sc_lock); 2251 1.62 jdolecek 2252 1.153 riastrad return ret; 2253 1.62 jdolecek } 2254 1.62 jdolecek 2255 1.84 gdt static int 2256 1.84 gdt filt_ugenread_bulk(struct knote *kn, long hint) 2257 1.84 gdt { 2258 1.84 gdt struct ugen_endpoint *sce = kn->kn_hook; 2259 1.135 mrg struct ugen_softc *sc = sce->sc; 2260 1.153 riastrad int ret; 2261 1.135 mrg 2262 1.153 riastrad mutex_enter(&sc->sc_lock); 2263 1.153 riastrad if (sc->sc_dying) { 2264 1.153 riastrad ret = 0; 2265 1.153 riastrad } else if (!(sce->state & UGEN_BULK_RA)) { 2266 1.84 gdt /* 2267 1.84 gdt * We have no easy way of determining if a read will 2268 1.84 gdt * yield any data or a write will happen. 2269 1.84 gdt * So, emulate "seltrue". 2270 1.84 gdt */ 2271 1.153 riastrad ret = filt_seltrue(kn, hint); 2272 1.153 riastrad } else if (sce->ra_wb_used == 0) { 2273 1.153 riastrad ret = 0; 2274 1.153 riastrad } else { 2275 1.153 riastrad kn->kn_data = sce->ra_wb_used; 2276 1.153 riastrad ret = 1; 2277 1.153 riastrad } 2278 1.153 riastrad mutex_exit(&sc->sc_lock); 2279 1.84 gdt 2280 1.153 riastrad return ret; 2281 1.84 gdt } 2282 1.84 gdt 2283 1.84 gdt static int 2284 1.84 gdt filt_ugenwrite_bulk(struct knote *kn, long hint) 2285 1.84 gdt { 2286 1.84 gdt struct ugen_endpoint *sce = kn->kn_hook; 2287 1.135 mrg struct ugen_softc *sc = sce->sc; 2288 1.153 riastrad int ret; 2289 1.135 mrg 2290 1.153 riastrad mutex_enter(&sc->sc_lock); 2291 1.153 riastrad if (sc->sc_dying) { 2292 1.153 riastrad ret = 0; 2293 1.153 riastrad } else if (!(sce->state & UGEN_BULK_WB)) { 2294 1.84 gdt /* 2295 1.84 gdt * We have no easy way of determining if a read will 2296 1.84 gdt * yield any data or a write will happen. 2297 1.84 gdt * So, emulate "seltrue". 2298 1.84 gdt */ 2299 1.153 riastrad ret = filt_seltrue(kn, hint); 2300 1.153 riastrad } else if (sce->ra_wb_used == sce->limit - sce->ibuf) { 2301 1.153 riastrad ret = 0; 2302 1.153 riastrad } else { 2303 1.153 riastrad kn->kn_data = (sce->limit - sce->ibuf) - sce->ra_wb_used; 2304 1.153 riastrad ret = 1; 2305 1.153 riastrad } 2306 1.153 riastrad mutex_exit(&sc->sc_lock); 2307 1.84 gdt 2308 1.153 riastrad return ret; 2309 1.84 gdt } 2310 1.84 gdt 2311 1.136 maya static const struct filterops ugenread_intr_filtops = { 2312 1.168 thorpej .f_flags = FILTEROP_ISFD, 2313 1.136 maya .f_attach = NULL, 2314 1.136 maya .f_detach = filt_ugenrdetach, 2315 1.136 maya .f_event = filt_ugenread_intr, 2316 1.136 maya }; 2317 1.62 jdolecek 2318 1.136 maya static const struct filterops ugenread_isoc_filtops = { 2319 1.168 thorpej .f_flags = FILTEROP_ISFD, 2320 1.136 maya .f_attach = NULL, 2321 1.136 maya .f_detach = filt_ugenrdetach, 2322 1.136 maya .f_event = filt_ugenread_isoc, 2323 1.136 maya }; 2324 1.62 jdolecek 2325 1.136 maya static const struct filterops ugenread_bulk_filtops = { 2326 1.168 thorpej .f_flags = FILTEROP_ISFD, 2327 1.136 maya .f_attach = NULL, 2328 1.136 maya .f_detach = filt_ugenrdetach, 2329 1.136 maya .f_event = filt_ugenread_bulk, 2330 1.136 maya }; 2331 1.84 gdt 2332 1.136 maya static const struct filterops ugenwrite_bulk_filtops = { 2333 1.168 thorpej .f_flags = FILTEROP_ISFD, 2334 1.136 maya .f_attach = NULL, 2335 1.136 maya .f_detach = filt_ugenrdetach, 2336 1.136 maya .f_event = filt_ugenwrite_bulk, 2337 1.136 maya }; 2338 1.62 jdolecek 2339 1.147 maxv static int 2340 1.62 jdolecek ugenkqfilter(dev_t dev, struct knote *kn) 2341 1.62 jdolecek { 2342 1.62 jdolecek struct ugen_softc *sc; 2343 1.62 jdolecek struct ugen_endpoint *sce; 2344 1.158 thorpej struct selinfo *sip; 2345 1.155 riastrad int error; 2346 1.62 jdolecek 2347 1.155 riastrad if ((sc = ugenif_acquire(UGENUNIT(dev))) == NULL) 2348 1.133 skrll return ENXIO; 2349 1.62 jdolecek 2350 1.155 riastrad if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT) { 2351 1.155 riastrad error = ENODEV; 2352 1.155 riastrad goto out; 2353 1.155 riastrad } 2354 1.113 jakllsch 2355 1.62 jdolecek switch (kn->kn_filter) { 2356 1.62 jdolecek case EVFILT_READ: 2357 1.84 gdt sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; 2358 1.155 riastrad if (sce == NULL) { 2359 1.155 riastrad error = EINVAL; 2360 1.155 riastrad goto out; 2361 1.155 riastrad } 2362 1.84 gdt 2363 1.158 thorpej sip = &sce->rsel; 2364 1.62 jdolecek switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 2365 1.62 jdolecek case UE_INTERRUPT: 2366 1.62 jdolecek kn->kn_fop = &ugenread_intr_filtops; 2367 1.62 jdolecek break; 2368 1.62 jdolecek case UE_ISOCHRONOUS: 2369 1.62 jdolecek kn->kn_fop = &ugenread_isoc_filtops; 2370 1.62 jdolecek break; 2371 1.62 jdolecek case UE_BULK: 2372 1.84 gdt kn->kn_fop = &ugenread_bulk_filtops; 2373 1.84 gdt break; 2374 1.62 jdolecek default: 2375 1.155 riastrad error = EINVAL; 2376 1.155 riastrad goto out; 2377 1.62 jdolecek } 2378 1.62 jdolecek break; 2379 1.62 jdolecek 2380 1.62 jdolecek case EVFILT_WRITE: 2381 1.84 gdt sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT]; 2382 1.155 riastrad if (sce == NULL) { 2383 1.155 riastrad error = EINVAL; 2384 1.155 riastrad goto out; 2385 1.155 riastrad } 2386 1.84 gdt 2387 1.158 thorpej sip = &sce->rsel; 2388 1.62 jdolecek switch (sce->edesc->bmAttributes & UE_XFERTYPE) { 2389 1.62 jdolecek case UE_INTERRUPT: 2390 1.62 jdolecek case UE_ISOCHRONOUS: 2391 1.62 jdolecek /* XXX poll doesn't support this */ 2392 1.155 riastrad error = EINVAL; 2393 1.155 riastrad goto out; 2394 1.62 jdolecek 2395 1.62 jdolecek case UE_BULK: 2396 1.84 gdt kn->kn_fop = &ugenwrite_bulk_filtops; 2397 1.62 jdolecek break; 2398 1.62 jdolecek default: 2399 1.155 riastrad error = EINVAL; 2400 1.155 riastrad goto out; 2401 1.62 jdolecek } 2402 1.62 jdolecek break; 2403 1.62 jdolecek 2404 1.62 jdolecek default: 2405 1.155 riastrad error = EINVAL; 2406 1.155 riastrad goto out; 2407 1.62 jdolecek } 2408 1.62 jdolecek 2409 1.62 jdolecek kn->kn_hook = sce; 2410 1.62 jdolecek 2411 1.120 mrg mutex_enter(&sc->sc_lock); 2412 1.158 thorpej selrecord_knote(sip, kn); 2413 1.120 mrg mutex_exit(&sc->sc_lock); 2414 1.62 jdolecek 2415 1.155 riastrad error = 0; 2416 1.155 riastrad 2417 1.155 riastrad out: ugenif_release(sc); 2418 1.155 riastrad return error; 2419 1.155 riastrad } 2420 1.155 riastrad 2421 1.155 riastrad MODULE(MODULE_CLASS_DRIVER, ugen, NULL); 2422 1.155 riastrad 2423 1.155 riastrad static int 2424 1.155 riastrad ugen_modcmd(modcmd_t cmd, void *aux) 2425 1.155 riastrad { 2426 1.155 riastrad 2427 1.155 riastrad switch (cmd) { 2428 1.155 riastrad case MODULE_CMD_INIT: 2429 1.155 riastrad mutex_init(&ugenif.lock, MUTEX_DEFAULT, IPL_NONE); 2430 1.155 riastrad rb_tree_init(&ugenif.tree, &ugenif_tree_ops); 2431 1.155 riastrad return 0; 2432 1.155 riastrad default: 2433 1.155 riastrad return ENOTTY; 2434 1.155 riastrad } 2435 1.1 augustss } 2436