Mon Mar 28 12:44:28 2022 UTC ()
uhidev(9): Omit needless sc_dying.


(riastradh)
diff -r1.90 -r1.91 src/sys/dev/usb/uhidev.c

cvs diff -r1.90 -r1.91 src/sys/dev/usb/uhidev.c (expand / switch to unified diff)

--- src/sys/dev/usb/uhidev.c 2022/03/28 12:44:17 1.90
+++ src/sys/dev/usb/uhidev.c 2022/03/28 12:44:28 1.91
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uhidev.c,v 1.90 2022/03/28 12:44:17 riastradh Exp $ */ 1/* $NetBSD: uhidev.c,v 1.91 2022/03/28 12:44:28 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au). 9 * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au).
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf 34 * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.90 2022/03/28 12:44:17 riastradh Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.91 2022/03/28 12:44:28 riastradh Exp $");
39 39
40#ifdef _KERNEL_OPT 40#ifdef _KERNEL_OPT
41#include "opt_usb.h" 41#include "opt_usb.h"
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/types.h> 45#include <sys/types.h>
46 46
47#include <sys/atomic.h> 47#include <sys/atomic.h>
48#include <sys/conf.h> 48#include <sys/conf.h>
49#include <sys/device.h> 49#include <sys/device.h>
50#include <sys/ioctl.h> 50#include <sys/ioctl.h>
51#include <sys/kernel.h> 51#include <sys/kernel.h>
@@ -100,27 +100,26 @@ struct uhidev_softc { @@ -100,27 +100,26 @@ struct uhidev_softc {
100#define UHIDEV_OPEN 0x01 /* device is open */ 100#define UHIDEV_OPEN 0x01 /* device is open */
101#define UHIDEV_STOPPED 0x02 /* xfers are stopped */ 101#define UHIDEV_STOPPED 0x02 /* xfers are stopped */
102 } *sc_subdevs; 102 } *sc_subdevs;
103 103
104 kmutex_t sc_lock; 104 kmutex_t sc_lock;
105 kcondvar_t sc_cv; 105 kcondvar_t sc_cv;
106 106
107 /* Read/written under sc_lock. */ 107 /* Read/written under sc_lock. */
108 struct lwp *sc_writelock; 108 struct lwp *sc_writelock;
109 struct lwp *sc_configlock; 109 struct lwp *sc_configlock;
110 int sc_refcnt; 110 int sc_refcnt;
111 int sc_writereportid; 111 int sc_writereportid;
112 int sc_stopreportid; 112 int sc_stopreportid;
113 u_char sc_dying; 
114 113
115 /* 114 /*
116 * - Read under sc_lock, provided sc_refcnt > 0. 115 * - Read under sc_lock, provided sc_refcnt > 0.
117 * - Written under sc_configlock only when transitioning to and 116 * - Written under sc_configlock only when transitioning to and
118 * from sc_refcnt = 0. 117 * from sc_refcnt = 0.
119 */ 118 */
120 u_char *sc_ibuf; 119 u_char *sc_ibuf;
121 struct usbd_pipe *sc_ipipe; /* input interrupt pipe */ 120 struct usbd_pipe *sc_ipipe; /* input interrupt pipe */
122 struct usbd_pipe *sc_opipe; /* output interrupt pipe */ 121 struct usbd_pipe *sc_opipe; /* output interrupt pipe */
123 struct usbd_xfer *sc_oxfer; /* write request */ 122 struct usbd_xfer *sc_oxfer; /* write request */
124 usbd_callback sc_writecallback; /* async write request callback */ 123 usbd_callback sc_writecallback; /* async write request callback */
125 void *sc_writecookie; 124 void *sc_writecookie;
126 125
@@ -136,30 +135,29 @@ int uhidevdebug = 0; @@ -136,30 +135,29 @@ int uhidevdebug = 0;
136#define DPRINTF(x) 135#define DPRINTF(x)
137#define DPRINTFN(n,x) 136#define DPRINTFN(n,x)
138#endif 137#endif
139 138
140static void uhidev_intr(struct usbd_xfer *, void *, usbd_status); 139static void uhidev_intr(struct usbd_xfer *, void *, usbd_status);
141 140
142static int uhidev_maxrepid(void *, int); 141static int uhidev_maxrepid(void *, int);
143static int uhidevprint(void *, const char *); 142static int uhidevprint(void *, const char *);
144 143
145static int uhidev_match(device_t, cfdata_t, void *); 144static int uhidev_match(device_t, cfdata_t, void *);
146static void uhidev_attach(device_t, device_t, void *); 145static void uhidev_attach(device_t, device_t, void *);
147static void uhidev_childdet(device_t, device_t); 146static void uhidev_childdet(device_t, device_t);
148static int uhidev_detach(device_t, int); 147static int uhidev_detach(device_t, int);
149static int uhidev_activate(device_t, enum devact); 
150 148
151CFATTACH_DECL2_NEW(uhidev, sizeof(struct uhidev_softc), uhidev_match, 149CFATTACH_DECL2_NEW(uhidev, sizeof(struct uhidev_softc), uhidev_match,
152 uhidev_attach, uhidev_detach, uhidev_activate, NULL, uhidev_childdet); 150 uhidev_attach, uhidev_detach, NULL, NULL, uhidev_childdet);
153 151
154static int 152static int
155uhidev_match(device_t parent, cfdata_t match, void *aux) 153uhidev_match(device_t parent, cfdata_t match, void *aux)
156{ 154{
157 struct usbif_attach_arg *uiaa = aux; 155 struct usbif_attach_arg *uiaa = aux;
158 156
159 /* Game controllers in "XInput" mode */ 157 /* Game controllers in "XInput" mode */
160 if (USBIF_IS_XINPUT(uiaa)) 158 if (USBIF_IS_XINPUT(uiaa))
161 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; 159 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
162 /* Xbox One controllers */ 160 /* Xbox One controllers */
163 if (USBIF_IS_X1INPUT(uiaa) && uiaa->uiaa_ifaceno == 0) 161 if (USBIF_IS_X1INPUT(uiaa) && uiaa->uiaa_ifaceno == 0)
164 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; 162 return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO;
165 163
@@ -193,27 +191,26 @@ uhidev_attach(device_t parent, device_t  @@ -193,27 +191,26 @@ uhidev_attach(device_t parent, device_t
193 sc->sc_udev = uiaa->uiaa_device; 191 sc->sc_udev = uiaa->uiaa_device;
194 sc->sc_iface = iface; 192 sc->sc_iface = iface;
195 193
196 aprint_naive("\n"); 194 aprint_naive("\n");
197 aprint_normal("\n"); 195 aprint_normal("\n");
198 196
199 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 197 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
200 cv_init(&sc->sc_cv, "uhidev"); 198 cv_init(&sc->sc_cv, "uhidev");
201 sc->sc_writelock = NULL; 199 sc->sc_writelock = NULL;
202 sc->sc_configlock = NULL; 200 sc->sc_configlock = NULL;
203 sc->sc_refcnt = 0; 201 sc->sc_refcnt = 0;
204 sc->sc_writereportid = -1; 202 sc->sc_writereportid = -1;
205 sc->sc_stopreportid = -1; 203 sc->sc_stopreportid = -1;
206 sc->sc_dying = false; 
207 204
208 id = usbd_get_interface_descriptor(iface); 205 id = usbd_get_interface_descriptor(iface);
209 206
210 devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); 207 devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0);
211 aprint_normal_dev(self, "%s, iclass %d/%d\n", 208 aprint_normal_dev(self, "%s, iclass %d/%d\n",
212 devinfop, id->bInterfaceClass, id->bInterfaceSubClass); 209 devinfop, id->bInterfaceClass, id->bInterfaceSubClass);
213 usbd_devinfo_free(devinfop); 210 usbd_devinfo_free(devinfop);
214 211
215 if (!pmf_device_register(self, NULL, NULL)) 212 if (!pmf_device_register(self, NULL, NULL))
216 aprint_error_dev(self, "couldn't establish power handler\n"); 213 aprint_error_dev(self, "couldn't establish power handler\n");
217 214
218 if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) { 215 if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) {
219 if (uiaa->uiaa_product == USB_PRODUCT_WACOM_XD0912U) { 216 if (uiaa->uiaa_product == USB_PRODUCT_WACOM_XD0912U) {
@@ -234,27 +231,26 @@ uhidev_attach(device_t parent, device_t  @@ -234,27 +231,26 @@ uhidev_attach(device_t parent, device_t
234 */ 231 */
235 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_NO_SET_PROTO) == 0 && 232 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_NO_SET_PROTO) == 0 &&
236 id->bInterfaceSubClass == UISUBCLASS_BOOT) 233 id->bInterfaceSubClass == UISUBCLASS_BOOT)
237 (void)usbd_set_protocol(iface, 1); 234 (void)usbd_set_protocol(iface, 1);
238#endif 235#endif
239 236
240 maxinpktsize = 0; 237 maxinpktsize = 0;
241 sc->sc_iep_addr = sc->sc_oep_addr = -1; 238 sc->sc_iep_addr = sc->sc_oep_addr = -1;
242 for (i = 0; i < id->bNumEndpoints; i++) { 239 for (i = 0; i < id->bNumEndpoints; i++) {
243 ed = usbd_interface2endpoint_descriptor(iface, i); 240 ed = usbd_interface2endpoint_descriptor(iface, i);
244 if (ed == NULL) { 241 if (ed == NULL) {
245 aprint_error_dev(self, 242 aprint_error_dev(self,
246 "could not read endpoint descriptor\n"); 243 "could not read endpoint descriptor\n");
247 sc->sc_dying = 1; 
248 return; 244 return;
249 } 245 }
250 246
251 DPRINTFN(10,("uhidev_attach: bLength=%d bDescriptorType=%d " 247 DPRINTFN(10,("uhidev_attach: bLength=%d bDescriptorType=%d "
252 "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d" 248 "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
253 " bInterval=%d\n", 249 " bInterval=%d\n",
254 ed->bLength, ed->bDescriptorType, 250 ed->bLength, ed->bDescriptorType,
255 ed->bEndpointAddress & UE_ADDR, 251 ed->bEndpointAddress & UE_ADDR,
256 UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out", 252 UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
257 ed->bmAttributes & UE_XFERTYPE, 253 ed->bmAttributes & UE_XFERTYPE,
258 UGETW(ed->wMaxPacketSize), ed->bInterval)); 254 UGETW(ed->wMaxPacketSize), ed->bInterval));
259 255
260 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 256 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
@@ -265,27 +261,26 @@ uhidev_attach(device_t parent, device_t  @@ -265,27 +261,26 @@ uhidev_attach(device_t parent, device_t
265 (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) { 261 (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
266 sc->sc_oep_addr = ed->bEndpointAddress; 262 sc->sc_oep_addr = ed->bEndpointAddress;
267 } else { 263 } else {
268 aprint_verbose_dev(self, "endpoint %d: ignored\n", i); 264 aprint_verbose_dev(self, "endpoint %d: ignored\n", i);
269 } 265 }
270 } 266 }
271 267
272 /* 268 /*
273 * Check that we found an input interrupt endpoint. The output interrupt 269 * Check that we found an input interrupt endpoint. The output interrupt
274 * endpoint is optional 270 * endpoint is optional
275 */ 271 */
276 if (sc->sc_iep_addr == -1) { 272 if (sc->sc_iep_addr == -1) {
277 aprint_error_dev(self, "no input interrupt endpoint\n"); 273 aprint_error_dev(self, "no input interrupt endpoint\n");
278 sc->sc_dying = 1; 
279 return; 274 return;
280 } 275 }
281 276
282 /* XXX need to extend this */ 277 /* XXX need to extend this */
283 descptr = NULL; 278 descptr = NULL;
284 if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) { 279 if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) {
285 static uByte reportbuf[3]; 280 static uByte reportbuf[3];
286 281
287 /* The report descriptor for the Wacom Graphire is broken. */ 282 /* The report descriptor for the Wacom Graphire is broken. */
288 switch (uiaa->uiaa_product) { 283 switch (uiaa->uiaa_product) {
289 case USB_PRODUCT_WACOM_GRAPHIRE3_4X5: 284 case USB_PRODUCT_WACOM_GRAPHIRE3_4X5:
290 case USB_PRODUCT_WACOM_GRAPHIRE3_6X8: 285 case USB_PRODUCT_WACOM_GRAPHIRE3_6X8:
291 case USB_PRODUCT_WACOM_GRAPHIRE4_4X5: /* The 6x8 too? */ 286 case USB_PRODUCT_WACOM_GRAPHIRE4_4X5: /* The 6x8 too? */
@@ -326,27 +321,26 @@ uhidev_attach(device_t parent, device_t  @@ -326,27 +321,26 @@ uhidev_attach(device_t parent, device_t
326 descptr = uhid_x1input_report_descr; 321 descptr = uhid_x1input_report_descr;
327 } 322 }
328 323
329 if (descptr) { 324 if (descptr) {
330 desc = kmem_alloc(size, KM_SLEEP); 325 desc = kmem_alloc(size, KM_SLEEP);
331 err = USBD_NORMAL_COMPLETION; 326 err = USBD_NORMAL_COMPLETION;
332 memcpy(desc, descptr, size); 327 memcpy(desc, descptr, size);
333 } else { 328 } else {
334 desc = NULL; 329 desc = NULL;
335 err = usbd_read_report_desc(uiaa->uiaa_iface, &desc, &size); 330 err = usbd_read_report_desc(uiaa->uiaa_iface, &desc, &size);
336 } 331 }
337 if (err) { 332 if (err) {
338 aprint_error_dev(self, "no report descriptor\n"); 333 aprint_error_dev(self, "no report descriptor\n");
339 sc->sc_dying = 1; 
340 return; 334 return;
341 } 335 }
342 336
343 if (uiaa->uiaa_vendor == USB_VENDOR_HOSIDEN && 337 if (uiaa->uiaa_vendor == USB_VENDOR_HOSIDEN &&
344 uiaa->uiaa_product == USB_PRODUCT_HOSIDEN_PPP) { 338 uiaa->uiaa_product == USB_PRODUCT_HOSIDEN_PPP) {
345 static uByte reportbuf[] = { 1 }; 339 static uByte reportbuf[] = { 1 };
346 /* 340 /*
347 * This device was sold by Konami with its ParaParaParadise 341 * This device was sold by Konami with its ParaParaParadise
348 * game for PlayStation2. It needs to be "turned on" 342 * game for PlayStation2. It needs to be "turned on"
349 * before it will send any reports. 343 * before it will send any reports.
350 */ 344 */
351 345
352 usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 0, 346 usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 0,
@@ -469,40 +463,26 @@ uhidev_maxrepid(void *buf, int len) @@ -469,40 +463,26 @@ uhidev_maxrepid(void *buf, int len)
469 463
470static int 464static int
471uhidevprint(void *aux, const char *pnp) 465uhidevprint(void *aux, const char *pnp)
472{ 466{
473 struct uhidev_attach_arg *uha = aux; 467 struct uhidev_attach_arg *uha = aux;
474 468
475 if (pnp) 469 if (pnp)
476 aprint_normal("uhid at %s", pnp); 470 aprint_normal("uhid at %s", pnp);
477 if (uha->reportid != 0) 471 if (uha->reportid != 0)
478 aprint_normal(" reportid %d", uha->reportid); 472 aprint_normal(" reportid %d", uha->reportid);
479 return UNCONF; 473 return UNCONF;
480} 474}
481 475
482static int 
483uhidev_activate(device_t self, enum devact act) 
484{ 
485 struct uhidev_softc *sc = device_private(self); 
486 
487 switch (act) { 
488 case DVACT_DEACTIVATE: 
489 sc->sc_dying = 1; 
490 return 0; 
491 default: 
492 return EOPNOTSUPP; 
493 } 
494} 
495 
496static void 476static void
497uhidev_childdet(device_t self, device_t child) 477uhidev_childdet(device_t self, device_t child)
498{ 478{
499 int i; 479 int i;
500 struct uhidev_softc *sc = device_private(self); 480 struct uhidev_softc *sc = device_private(self);
501 481
502 for (i = 0; i < sc->sc_nrepid; i++) { 482 for (i = 0; i < sc->sc_nrepid; i++) {
503 if (sc->sc_subdevs[i].sc_dev == child) 483 if (sc->sc_subdevs[i].sc_dev == child)
504 break; 484 break;
505 } 485 }
506 KASSERT(i < sc->sc_nrepid); 486 KASSERT(i < sc->sc_nrepid);
507 sc->sc_subdevs[i].sc_dev = NULL; 487 sc->sc_subdevs[i].sc_dev = NULL;
508 /* 488 /*
@@ -513,46 +493,37 @@ uhidev_childdet(device_t self, device_t  @@ -513,46 +493,37 @@ uhidev_childdet(device_t self, device_t
513 * rescan method, but if there were, it could.) 493 * rescan method, but if there were, it could.)
514 */ 494 */
515 rnd_detach_source(&sc->sc_subdevs[i].sc_rndsource); 495 rnd_detach_source(&sc->sc_subdevs[i].sc_rndsource);
516} 496}
517 497
518static int 498static int
519uhidev_detach(device_t self, int flags) 499uhidev_detach(device_t self, int flags)
520{ 500{
521 struct uhidev_softc *sc = device_private(self); 501 struct uhidev_softc *sc = device_private(self);
522 int rv; 502 int rv;
523 503
524 DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags)); 504 DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags));
525 505
526 /* Notify that we are going away. */ 
527 mutex_enter(&sc->sc_lock); 
528 sc->sc_dying = 1; 
529 cv_broadcast(&sc->sc_cv); 
530 mutex_exit(&sc->sc_lock); 
531 
532 /* 506 /*
533 * Try to detach all our children. If anything fails, bail. 507 * Try to detach all our children. If anything fails, bail.
534 * Failure can happen if this is from drvctl -d; of course, if 508 * Failure can happen if this is from drvctl -d; of course, if
535 * this is a USB device being yanked, flags will have 509 * this is a USB device being yanked, flags will have
536 * DETACH_FORCE and the children will not have the option of 510 * DETACH_FORCE and the children will not have the option of
537 * refusing detachment. 511 * refusing detachment. If they do detach, the pipes can no
 512 * longer be in use.
538 */ 513 */
539 rv = config_detach_children(self, flags); 514 rv = config_detach_children(self, flags);
540 if (rv) { 515 if (rv)
541 mutex_enter(&sc->sc_lock); 
542 sc->sc_dying = 0; 
543 mutex_exit(&sc->sc_lock); 
544 return rv; 516 return rv;
545 } 
546 517
547 KASSERTMSG(sc->sc_refcnt == 0, 518 KASSERTMSG(sc->sc_refcnt == 0,
548 "%s: %d refs remain", device_xname(sc->sc_dev), sc->sc_refcnt); 519 "%s: %d refs remain", device_xname(sc->sc_dev), sc->sc_refcnt);
549 KASSERT(sc->sc_opipe == NULL); 520 KASSERT(sc->sc_opipe == NULL);
550 KASSERT(sc->sc_ipipe == NULL); 521 KASSERT(sc->sc_ipipe == NULL);
551 KASSERT(sc->sc_ibuf == NULL); 522 KASSERT(sc->sc_ibuf == NULL);
552 523
553 if (sc->sc_repdesc != NULL) { 524 if (sc->sc_repdesc != NULL) {
554 kmem_free(sc->sc_repdesc, sc->sc_repdesc_size); 525 kmem_free(sc->sc_repdesc, sc->sc_repdesc_size);
555 sc->sc_repdesc = NULL; 526 sc->sc_repdesc = NULL;
556 } 527 }
557 if (sc->sc_subdevs != NULL) { 528 if (sc->sc_subdevs != NULL) {
558 int nrepid = sc->sc_nrepid; 529 int nrepid = sc->sc_nrepid;
@@ -640,28 +611,26 @@ uhidev_get_report_desc(struct uhidev *sc @@ -640,28 +611,26 @@ uhidev_get_report_desc(struct uhidev *sc
640 611
641 *desc = sc->sc_repdesc; 612 *desc = sc->sc_repdesc;
642 *size = sc->sc_repdesc_size; 613 *size = sc->sc_repdesc_size;
643} 614}
644 615
645static int 616static int
646uhidev_config_enter(struct uhidev_softc *sc) 617uhidev_config_enter(struct uhidev_softc *sc)
647{ 618{
648 int error; 619 int error;
649 620
650 KASSERT(mutex_owned(&sc->sc_lock)); 621 KASSERT(mutex_owned(&sc->sc_lock));
651 622
652 for (;;) { 623 for (;;) {
653 if (sc->sc_dying) 
654 return ENXIO; 
655 if (sc->sc_configlock == NULL) 624 if (sc->sc_configlock == NULL)
656 break; 625 break;
657 error = cv_wait_sig(&sc->sc_cv, &sc->sc_lock); 626 error = cv_wait_sig(&sc->sc_cv, &sc->sc_lock);
658 if (error) 627 if (error)
659 return error; 628 return error;
660 } 629 }
661 630
662 sc->sc_configlock = curlwp; 631 sc->sc_configlock = curlwp;
663 return 0; 632 return 0;
664} 633}
665 634
666static void 635static void
667uhidev_config_enter_nointr(struct uhidev_softc *sc) 636uhidev_config_enter_nointr(struct uhidev_softc *sc)
@@ -690,30 +659,26 @@ uhidev_config_exit(struct uhidev_softc * @@ -690,30 +659,26 @@ uhidev_config_exit(struct uhidev_softc *
690 * uhidev_open_pipes(sc) 659 * uhidev_open_pipes(sc)
691 * 660 *
692 * Ensure the pipes of the softc are open. Caller must hold 661 * Ensure the pipes of the softc are open. Caller must hold
693 * sc_lock, which may be released and reacquired. 662 * sc_lock, which may be released and reacquired.
694 */ 663 */
695static int 664static int
696uhidev_open_pipes(struct uhidev_softc *sc) 665uhidev_open_pipes(struct uhidev_softc *sc)
697{ 666{
698 usbd_status err; 667 usbd_status err;
699 int error; 668 int error;
700 669
701 KASSERT(mutex_owned(&sc->sc_lock)); 670 KASSERT(mutex_owned(&sc->sc_lock));
702 671
703 /* If the device is dying, refuse. */ 
704 if (sc->sc_dying) 
705 return ENXIO; 
706 
707 /* 672 /*
708 * If the pipes are already open, just increment the reference 673 * If the pipes are already open, just increment the reference
709 * count, or fail if it would overflow. 674 * count, or fail if it would overflow.
710 */ 675 */
711 if (sc->sc_refcnt) { 676 if (sc->sc_refcnt) {
712 if (sc->sc_refcnt == INT_MAX) 677 if (sc->sc_refcnt == INT_MAX)
713 return EBUSY; 678 return EBUSY;
714 sc->sc_refcnt++; 679 sc->sc_refcnt++;
715 return 0; 680 return 0;
716 } 681 }
717 682
718 /* 683 /*
719 * If there's no input data to prepare, don't bother with the 684 * If there's no input data to prepare, don't bother with the
@@ -1112,30 +1077,26 @@ usbd_status @@ -1112,30 +1077,26 @@ usbd_status
1112uhidev_write(struct uhidev *scd, void *data, int len) 1077uhidev_write(struct uhidev *scd, void *data, int len)
1113{ 1078{
1114 struct uhidev_softc *sc = scd->sc_parent; 1079 struct uhidev_softc *sc = scd->sc_parent;
1115 usbd_status err; 1080 usbd_status err;
1116 1081
1117 DPRINTF(("uhidev_write: data=%p, len=%d\n", data, len)); 1082 DPRINTF(("uhidev_write: data=%p, len=%d\n", data, len));
1118 1083
1119 if (sc->sc_opipe == NULL) 1084 if (sc->sc_opipe == NULL)
1120 return USBD_INVAL; 1085 return USBD_INVAL;
1121 1086
1122 mutex_enter(&sc->sc_lock); 1087 mutex_enter(&sc->sc_lock);
1123 KASSERT(sc->sc_refcnt); 1088 KASSERT(sc->sc_refcnt);
1124 for (;;) { 1089 for (;;) {
1125 if (sc->sc_dying) { 
1126 err = USBD_IOERROR; 
1127 goto out; 
1128 } 
1129 if (scd->sc_state & UHIDEV_STOPPED) { 1090 if (scd->sc_state & UHIDEV_STOPPED) {
1130 err = USBD_CANCELLED; 1091 err = USBD_CANCELLED;
1131 goto out; 1092 goto out;
1132 } 1093 }
1133 if (sc->sc_writelock == NULL && sc->sc_stopreportid == -1) 1094 if (sc->sc_writelock == NULL && sc->sc_stopreportid == -1)
1134 break; 1095 break;
1135 if (cv_wait_sig(&sc->sc_cv, &sc->sc_lock)) { 1096 if (cv_wait_sig(&sc->sc_cv, &sc->sc_lock)) {
1136 err = USBD_INTERRUPTED; 1097 err = USBD_INTERRUPTED;
1137 goto out; 1098 goto out;
1138 } 1099 }
1139 } 1100 }
1140 sc->sc_writelock = curlwp; 1101 sc->sc_writelock = curlwp;
1141 sc->sc_writereportid = scd->sc_report_id; 1102 sc->sc_writereportid = scd->sc_report_id;
@@ -1200,30 +1161,26 @@ usbd_status @@ -1200,30 +1161,26 @@ usbd_status
1200uhidev_write_async(struct uhidev *scd, void *data, int len, int flags, 1161uhidev_write_async(struct uhidev *scd, void *data, int len, int flags,
1201 int timo, usbd_callback writecallback, void *writecookie) 1162 int timo, usbd_callback writecallback, void *writecookie)
1202{ 1163{
1203 struct uhidev_softc *sc = scd->sc_parent; 1164 struct uhidev_softc *sc = scd->sc_parent;
1204 usbd_status err; 1165 usbd_status err;
1205 1166
1206 DPRINTF(("%s: data=%p, len=%d\n", __func__, data, len)); 1167 DPRINTF(("%s: data=%p, len=%d\n", __func__, data, len));
1207 1168
1208 if (sc->sc_opipe == NULL) 1169 if (sc->sc_opipe == NULL)
1209 return USBD_INVAL; 1170 return USBD_INVAL;
1210 1171
1211 mutex_enter(&sc->sc_lock); 1172 mutex_enter(&sc->sc_lock);
1212 KASSERT(sc->sc_refcnt); 1173 KASSERT(sc->sc_refcnt);
1213 if (sc->sc_dying) { 
1214 err = USBD_IOERROR; 
1215 goto out; 
1216 } 
1217 if (scd->sc_state & UHIDEV_STOPPED) { 1174 if (scd->sc_state & UHIDEV_STOPPED) {
1218 err = USBD_CANCELLED; 1175 err = USBD_CANCELLED;
1219 goto out; 1176 goto out;
1220 } 1177 }
1221 if (sc->sc_writelock != NULL || sc->sc_stopreportid != -1) { 1178 if (sc->sc_writelock != NULL || sc->sc_stopreportid != -1) {
1222 err = USBD_IN_USE; 1179 err = USBD_IN_USE;
1223 goto out; 1180 goto out;
1224 } 1181 }
1225 sc->sc_writelock = (void *)1; /* XXX no lwp to attribute async xfer */ 1182 sc->sc_writelock = (void *)1; /* XXX no lwp to attribute async xfer */
1226 sc->sc_writereportid = scd->sc_report_id; 1183 sc->sc_writereportid = scd->sc_report_id;
1227 sc->sc_writecallback = writecallback; 1184 sc->sc_writecallback = writecallback;
1228 sc->sc_writecookie = writecookie; 1185 sc->sc_writecookie = writecookie;
1229 usbd_setup_xfer(sc->sc_oxfer, sc, data, len, flags, timo, 1186 usbd_setup_xfer(sc->sc_oxfer, sc, data, len, flags, timo,