Bug Summary

File:dev/usb/uhid.c
Warning:line 332, column 2
Value stored to 'error' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name uhid.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/usb/uhid.c
1/* $OpenBSD: uhid.c,v 1.88 2021/11/15 15:36:24 anton Exp $ */
2/* $NetBSD: uhid.c,v 1.57 2003/03/11 16:44:00 augustss Exp $ */
3
4/*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * HID spec: https://www.usb.org/sites/default/files/hid1_11.pdf
36 */
37
38#include "fido.h"
39#include "ujoy.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/kernel.h>
44#include <sys/malloc.h>
45#include <sys/signalvar.h>
46#include <sys/device.h>
47#include <sys/ioctl.h>
48#include <sys/conf.h>
49#include <sys/tty.h>
50#include <sys/selinfo.h>
51#include <sys/proc.h>
52#include <sys/vnode.h>
53#include <sys/poll.h>
54
55#include <dev/usb/usb.h>
56#include <dev/usb/usbhid.h>
57
58#include <dev/usb/usbdevs.h>
59#include <dev/usb/usbdi.h>
60#include <dev/usb/usbdi_util.h>
61
62#include <dev/usb/uhidev.h>
63#include <dev/usb/uhid.h>
64
65#ifdef UHID_DEBUG
66#define DPRINTF(x) do { if (uhiddebug) printf x; } while (0)
67#define DPRINTFN(n,x) do { if (uhiddebug>(n)) printf x; } while (0)
68int uhiddebug = 0;
69#else
70#define DPRINTF(x)
71#define DPRINTFN(n,x)
72#endif
73
74int uhid_match(struct device *, void *, void *);
75
76struct cfdriver uhid_cd = {
77 NULL((void *)0), "uhid", DV_DULL
78};
79
80const struct cfattach uhid_ca = {
81 sizeof(struct uhid_softc),
82 uhid_match,
83 uhid_attach,
84 uhid_detach,
85};
86
87struct uhid_softc *
88uhid_lookup(dev_t dev)
89{
90 struct uhid_softc *sc = NULL((void *)0);
91 struct cdevsw *cdev;
92 struct cfdriver *cd;
93
94 cdev = &cdevsw[major(dev)(((unsigned)(dev) >> 8) & 0xff)];
95 if (cdev->d_open == uhidopen)
96 cd = &uhid_cd;
97#if NFIDO1 > 0
98 else if (cdev->d_open == fidoopen)
99 cd = &fido_cd;
100#endif
101#if NUJOY1 > 0
102 else if (cdev->d_open == ujoyopen)
103 cd = &ujoy_cd;
104#endif
105 else
106 return (NULL((void *)0));
107 if (UHIDUNIT(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)))
< cd->cd_ndevs)
108 sc = cd->cd_devs[UHIDUNIT(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)))
];
109
110 return (sc);
111}
112
113int
114uhid_match(struct device *parent, void *match, void *aux)
115{
116 struct uhidev_attach_arg *uha = aux;
117
118 if (UHIDEV_CLAIM_MULTIPLE_REPORTID(uha)((uha)->claimed != ((void *)0)))
119 return (UMATCH_NONE0);
120
121 return (UMATCH_IFACECLASS_GENERIC2);
122}
123
124void
125uhid_attach(struct device *parent, struct device *self, void *aux)
126{
127 struct uhid_softc *sc = (struct uhid_softc *)self;
128 struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
129 int size, repid;
130 void *desc;
131
132 sc->sc_hdev.sc_intr = uhid_intr;
133 sc->sc_hdev.sc_parent = uha->parent;
134 sc->sc_hdev.sc_udev = uha->uaa->device;
135 sc->sc_hdev.sc_report_id = uha->reportid;
136
137 uhidev_get_report_desc(uha->parent, &desc, &size);
138 repid = uha->reportid;
139 sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
140 sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
141 sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
142
143 printf(": input=%d, output=%d, feature=%d\n",
144 sc->sc_hdev.sc_isize, sc->sc_hdev.sc_osize, sc->sc_hdev.sc_fsize);
145}
146
147int
148uhid_detach(struct device *self, int flags)
149{
150 struct uhid_softc *sc = (struct uhid_softc *)self;
151 int s;
152 int maj, mn;
153
154 DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
155
156 if (sc->sc_hdev.sc_state & UHIDEV_OPEN0x01) {
157 s = splusb()splraise(0x5);
158 if (--sc->sc_refcnt >= 0) {
159 /* Wake everyone */
160 wakeup(&sc->sc_q);
161 /* Wait for processes to go away. */
162 usb_detach_wait(&sc->sc_hdev.sc_dev);
163 }
164 splx(s)spllower(s);
165 }
166
167 /* locate the major number */
168 for (maj = 0; maj < nchrdev; maj++)
169 if (cdevsw[maj].d_open == uhidopen)
170 break;
171
172 /* Nuke the vnodes for any open instances (calls close). */
173 mn = self->dv_unit;
174 vdevgone(maj, mn, mn, VCHR);
175
176 s = splusb()splraise(0x5);
177 klist_invalidate(&sc->sc_rsel.si_note);
178 splx(s)spllower(s);
179
180 return (0);
181}
182
183void
184uhid_intr(struct uhidev *addr, void *data, u_int len)
185{
186 struct uhid_softc *sc = (struct uhid_softc *)addr;
187
188#ifdef UHID_DEBUG
189 if (uhiddebug > 5) {
190 u_int32_t i;
191
192 DPRINTF(("uhid_intr: data ="));
193 for (i = 0; i < len; i++)
194 DPRINTF((" %02x", ((u_char *)data)[i]));
195 DPRINTF(("\n"));
196 }
197#endif
198
199 (void)b_to_q(data, len, &sc->sc_q);
200
201 if (sc->sc_state & UHID_ASLP0x01) {
202 sc->sc_state &= ~UHID_ASLP0x01;
203 DPRINTFN(5, ("uhid_intr: waking %p\n", &sc->sc_q));
204 wakeup(&sc->sc_q);
205 }
206 selwakeup(&sc->sc_rsel);
207}
208
209int
210uhidopen(dev_t dev, int flag, int mode, struct proc *p)
211{
212 return (uhid_do_open(dev, flag, mode, p));
213}
214
215int
216uhid_do_open(dev_t dev, int flag, int mode, struct proc *p)
217{
218 struct uhid_softc *sc;
219 int error;
220
221 if ((sc = uhid_lookup(dev)) == NULL((void *)0))
222 return (ENXIO6);
223
224 DPRINTF(("uhidopen: sc=%p\n", sc));
225
226 if (usbd_is_dying(sc->sc_hdev.sc_udev))
227 return (ENXIO6);
228
229 error = uhidev_open(&sc->sc_hdev);
230 if (error)
231 return (error);
232
233 clalloc(&sc->sc_q, UHID_BSIZE1020, 0);
234
235 sc->sc_obuf = malloc(sc->sc_hdev.sc_osize, M_USBDEV102, M_WAITOK0x0001);
236
237 return (0);
238}
239
240int
241uhidclose(dev_t dev, int flag, int mode, struct proc *p)
242{
243 struct uhid_softc *sc;
244
245 if ((sc = uhid_lookup(dev)) == NULL((void *)0))
246 return (ENXIO6);
247
248 DPRINTF(("uhidclose: sc=%p\n", sc));
249
250 clfree(&sc->sc_q);
251 free(sc->sc_obuf, M_USBDEV102, sc->sc_hdev.sc_osize);
252 uhidev_close(&sc->sc_hdev);
253
254 return (0);
255}
256
257int
258uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
259{
260 int s;
261 int error = 0;
262 size_t length;
263 u_char buffer[UHID_CHUNK128];
264
265 DPRINTFN(1, ("uhidread\n"));
266
267 s = splusb()splraise(0x5);
268 while (sc->sc_q.c_cc == 0) {
269 if (flag & IO_NDELAY0x10) {
270 splx(s)spllower(s);
271 return (EWOULDBLOCK35);
272 }
273 sc->sc_state |= UHID_ASLP0x01;
274 DPRINTFN(5, ("uhidread: sleep on %p\n", &sc->sc_q));
275 error = tsleep_nsec(&sc->sc_q, PZERO22|PCATCH0x100, "uhidrea", INFSLP0xffffffffffffffffULL);
276 DPRINTFN(5, ("uhidread: woke, error=%d\n", error));
277 if (usbd_is_dying(sc->sc_hdev.sc_udev))
278 error = EIO5;
279 if (error) {
280 sc->sc_state &= ~UHID_ASLP0x01;
281 break;
282 }
283 }
284 splx(s)spllower(s);
285
286 /* Transfer as many chunks as possible. */
287 while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0 && !error) {
288 length = ulmin(sc->sc_q.c_cc, uio->uio_resid);
289 if (length > sizeof(buffer))
290 length = sizeof(buffer);
291
292 /* Remove a small chunk from the input queue. */
293 (void) q_to_b(&sc->sc_q, buffer, length);
294 DPRINTFN(5, ("uhidread: got %zu chars\n", length));
295
296 /* Copy the data to the user process. */
297 if ((error = uiomove(buffer, length, uio)) != 0)
298 break;
299 }
300
301 return (error);
302}
303
304int
305uhidread(dev_t dev, struct uio *uio, int flag)
306{
307 struct uhid_softc *sc;
308 int error;
309
310 if ((sc = uhid_lookup(dev)) == NULL((void *)0))
311 return (ENXIO6);
312
313 sc->sc_refcnt++;
314 error = uhid_do_read(sc, uio, flag);
315 if (--sc->sc_refcnt < 0)
316 usb_detach_wakeup(&sc->sc_hdev.sc_dev);
317 return (error);
318}
319
320int
321uhid_do_write(struct uhid_softc *sc, struct uio *uio, int flag)
322{
323 int error;
324 int size;
325
326 DPRINTFN(1, ("uhidwrite\n"));
327
328 if (usbd_is_dying(sc->sc_hdev.sc_udev))
329 return (EIO5);
330
331 size = sc->sc_hdev.sc_osize;
332 error = 0;
Value stored to 'error' is never read
333 if (uio->uio_resid > size)
334 return (EMSGSIZE40);
335 else if (uio->uio_resid < size) {
336 /* don't leak kernel memory to the USB device */
337 memset(sc->sc_obuf + uio->uio_resid, 0, size - uio->uio_resid)__builtin_memset((sc->sc_obuf + uio->uio_resid), (0), (
size - uio->uio_resid))
;
338 }
339 error = uiomove(sc->sc_obuf, uio->uio_resid, uio);
340 if (!error) {
341 if (uhidev_set_report(sc->sc_hdev.sc_parent,
342 UHID_OUTPUT_REPORT0x02, sc->sc_hdev.sc_report_id, sc->sc_obuf,
343 size) != size)
344 error = EIO5;
345 }
346
347 return (error);
348}
349
350int
351uhidwrite(dev_t dev, struct uio *uio, int flag)
352{
353 struct uhid_softc *sc;
354 int error;
355
356 if ((sc = uhid_lookup(dev)) == NULL((void *)0))
357 return (ENXIO6);
358
359 sc->sc_refcnt++;
360 error = uhid_do_write(sc, uio, flag);
361 if (--sc->sc_refcnt < 0)
362 usb_detach_wakeup(&sc->sc_hdev.sc_dev);
363 return (error);
364}
365
366int
367uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
368 int flag, struct proc *p)
369{
370 int rc;
371
372 DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
373
374 if (usbd_is_dying(sc->sc_hdev.sc_udev))
375 return (EIO5);
376
377 switch (cmd) {
378 case FIONBIO((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('f')) << 8) | ((126)))
:
379 case FIOASYNC((unsigned long)0x80000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('f')) << 8) | ((125)))
:
380 /* All handled in the upper FS layer. */
381 break;
382
383 case USB_GET_DEVICEINFO((unsigned long)0x40000000 | ((sizeof(struct usb_device_info)
& 0x1fff) << 16) | ((('U')) << 8) | ((112)))
:
384 usbd_fill_deviceinfo(sc->sc_hdev.sc_udev,
385 (struct usb_device_info *)addr);
386 break;
387
388 case USB_GET_REPORT_DESC((unsigned long)0x40000000 | ((sizeof(struct usb_ctl_report_desc
) & 0x1fff) << 16) | ((('U')) << 8) | ((21)))
:
389 case USB_GET_REPORT(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct usb_ctl_report) & 0x1fff) << 16) | ((('U'))
<< 8) | ((23)))
:
390 case USB_SET_REPORT((unsigned long)0x80000000 | ((sizeof(struct usb_ctl_report) &
0x1fff) << 16) | ((('U')) << 8) | ((24)))
:
391 case USB_GET_REPORT_ID((unsigned long)0x40000000 | ((sizeof(int) & 0x1fff) <<
16) | ((('U')) << 8) | ((25)))
:
392 default:
393 rc = uhidev_ioctl(&sc->sc_hdev, cmd, addr, flag, p);
394 if (rc == -1)
395 rc = ENOTTY25;
396 return rc;
397 }
398 return (0);
399}
400
401int
402uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
403{
404 struct uhid_softc *sc;
405 int error;
406
407 if ((sc = uhid_lookup(dev)) == NULL((void *)0))
408 return (ENXIO6);
409
410 sc->sc_refcnt++;
411 error = uhid_do_ioctl(sc, cmd, addr, flag, p);
412 if (--sc->sc_refcnt < 0)
413 usb_detach_wakeup(&sc->sc_hdev.sc_dev);
414 return (error);
415}
416
417int
418uhidpoll(dev_t dev, int events, struct proc *p)
419{
420 struct uhid_softc *sc;
421 int revents = 0;
422 int s;
423
424 if ((sc = uhid_lookup(dev)) == NULL((void *)0))
425 return (POLLERR0x0008);
426
427 if (usbd_is_dying(sc->sc_hdev.sc_udev))
428 return (POLLHUP0x0010);
429
430 s = splusb()splraise(0x5);
431 if (events & (POLLOUT0x0004 | POLLWRNORM0x0004))
432 revents |= events & (POLLOUT0x0004 | POLLWRNORM0x0004);
433 if (events & (POLLIN0x0001 | POLLRDNORM0x0040)) {
434 if (sc->sc_q.c_cc > 0)
435 revents |= events & (POLLIN0x0001 | POLLRDNORM0x0040);
436 else
437 selrecord(p, &sc->sc_rsel);
438 }
439
440 splx(s)spllower(s);
441 return (revents);
442}
443
444void filt_uhidrdetach(struct knote *);
445int filt_uhidread(struct knote *, long);
446int uhidkqfilter(dev_t, struct knote *);
447
448void
449filt_uhidrdetach(struct knote *kn)
450{
451 struct uhid_softc *sc = (void *)kn->kn_hook;
452 int s;
453
454 s = splusb()splraise(0x5);
455 klist_remove_locked(&sc->sc_rsel.si_note, kn);
456 splx(s)spllower(s);
457}
458
459int
460filt_uhidread(struct knote *kn, long hint)
461{
462 struct uhid_softc *sc = (void *)kn->kn_hook;
463
464 kn->kn_datakn_kevent.data = sc->sc_q.c_cc;
465 return (kn->kn_datakn_kevent.data > 0);
466}
467
468const struct filterops uhidread_filtops = {
469 .f_flags = FILTEROP_ISFD0x00000001,
470 .f_attach = NULL((void *)0),
471 .f_detach = filt_uhidrdetach,
472 .f_event = filt_uhidread,
473};
474
475int
476uhidkqfilter(dev_t dev, struct knote *kn)
477{
478 struct uhid_softc *sc;
479 struct klist *klist;
480 int s;
481
482 if ((sc = uhid_lookup(dev)) == NULL((void *)0))
483 return (ENXIO6);
484
485 if (usbd_is_dying(sc->sc_hdev.sc_udev))
486 return (ENXIO6);
487
488 switch (kn->kn_filterkn_kevent.filter) {
489 case EVFILT_READ(-1):
490 klist = &sc->sc_rsel.si_note;
491 kn->kn_fop = &uhidread_filtops;
492 break;
493
494 case EVFILT_WRITE(-2):
495 return (seltrue_kqfilter(dev, kn));
496
497 default:
498 return (EINVAL22);
499 }
500
501 kn->kn_hook = (void *)sc;
502
503 s = splusb()splraise(0x5);
504 klist_insert_locked(klist, kn);
505 splx(s)spllower(s);
506
507 return (0);
508}