1 /* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This software was developed by the Computer Systems Engineering group 6 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7 * contributed to Berkeley. 8 * 9 * All advertising materials mentioning features or use of this software 10 * must display the following acknowledgement: 11 * This product includes software developed by the University of 12 * California, Lawrence Berkeley Laboratory. 13 * 14 * %sccs.include.redist.c% 15 * 16 * @(#)kbd.c 8.2 (Berkeley) 10/30/93 17 * 18 * from: $Header: kbd.c,v 1.18 93/10/31 05:44:01 torek Exp $ (LBL) 19 */ 20 21 /* 22 * Keyboard driver (/dev/kbd -- note that we do not have minor numbers 23 * [yet?]). Translates incoming bytes to ASCII or to `firm_events' and 24 * passes them up to the appropriate reader. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/conf.h> 29 #include <sys/device.h> 30 #include <sys/ioctl.h> 31 #include <sys/kernel.h> 32 #include <sys/proc.h> 33 #include <sys/syslog.h> 34 #include <sys/systm.h> 35 #include <sys/tty.h> 36 37 #include <machine/autoconf.h> 38 39 #include <sparc/dev/vuid_event.h> 40 #include <sparc/dev/event_var.h> 41 #include <sparc/dev/kbd.h> 42 #include <sparc/dev/kbio.h> 43 44 /* 45 * Sun keyboard definitions (from Sprite). 46 * These apply to type 2, 3 and 4 keyboards. 47 */ 48 #define KEY_CODE(c) ((c) & KBD_KEYMASK) /* keyboard code index */ 49 #define KEY_UP(c) ((c) & KBD_UP) /* true => key went up */ 50 51 /* 52 * Each KEY_CODE(x) can be translated via the tables below. 53 * The result is either a valid ASCII value in [0..0x7f] or is one 54 * of the following `magic' values saying something interesting 55 * happened. If LSHIFT or RSHIFT has changed state the next 56 * lookup should come from the appropriate table; if ALLUP is 57 * sent all keys (including both shifts and the control key) are 58 * now up, and the next byte is the keyboard ID code. 59 * 60 * These tables ignore all function keys (on the theory that if you 61 * want these keys, you should use a window system). Note that 62 * `caps lock' is just mapped as `ignore' (so there!). (Only the 63 * type 3 and 4 keyboards have a caps lock key anyway.) 64 */ 65 #define KEY_MAGIC 0x80 /* flag => magic value */ 66 #define KEY_IGNORE 0x80 67 #define KEY_L1 KEY_IGNORE 68 #define KEY_CAPSLOCK KEY_IGNORE 69 #define KEY_LSHIFT 0x81 70 #define KEY_RSHIFT 0x82 71 #define KEY_CONTROL 0x83 72 #define KEY_ALLUP 0x84 /* all keys are now up; also reset */ 73 74 /* 75 * Decode tables for type 2, 3, and 4 keyboards 76 * (stolen from Sprite; see also kbd.h). 77 */ 78 static const u_char kbd_unshifted[] = { 79 /* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE, 80 /* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 81 /* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 82 /* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 83 /* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 84 /* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 85 /* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 86 /* 28 */ KEY_IGNORE, '\033', '1', '2', 87 /* 32 */ '3', '4', '5', '6', 88 /* 36 */ '7', '8', '9', '0', 89 /* 40 */ '-', '=', '`', '\b', 90 /* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 91 /* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 92 /* 52 */ KEY_IGNORE, '\t', 'q', 'w', 93 /* 56 */ 'e', 'r', 't', 'y', 94 /* 60 */ 'u', 'i', 'o', 'p', 95 /* 64 */ '[', ']', '\177', KEY_IGNORE, 96 /* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 97 /* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 98 /* 76 */ KEY_CONTROL, 'a', 's', 'd', 99 /* 80 */ 'f', 'g', 'h', 'j', 100 /* 84 */ 'k', 'l', ';', '\'', 101 /* 88 */ '\\', '\r', KEY_IGNORE, KEY_IGNORE, 102 /* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 103 /* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT, 104 /* 100 */ 'z', 'x', 'c', 'v', 105 /* 104 */ 'b', 'n', 'm', ',', 106 /* 108 */ '.', '/', KEY_RSHIFT, '\n', 107 /* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 108 /* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK, 109 /* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE, 110 /* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP, 111 }; 112 113 static const u_char kbd_shifted[] = { 114 /* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE, 115 /* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 116 /* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 117 /* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 118 /* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 119 /* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 120 /* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 121 /* 28 */ KEY_IGNORE, '\033', '!', '@', 122 /* 32 */ '#', '$', '%', '^', 123 /* 36 */ '&', '*', '(', ')', 124 /* 40 */ '_', '+', '~', '\b', 125 /* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 126 /* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 127 /* 52 */ KEY_IGNORE, '\t', 'Q', 'W', 128 /* 56 */ 'E', 'R', 'T', 'Y', 129 /* 60 */ 'U', 'I', 'O', 'P', 130 /* 64 */ '{', '}', '\177', KEY_IGNORE, 131 /* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 132 /* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 133 /* 76 */ KEY_CONTROL, 'A', 'S', 'D', 134 /* 80 */ 'F', 'G', 'H', 'J', 135 /* 84 */ 'K', 'L', ':', '"', 136 /* 88 */ '|', '\r', KEY_IGNORE, KEY_IGNORE, 137 /* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 138 /* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT, 139 /* 100 */ 'Z', 'X', 'C', 'V', 140 /* 104 */ 'B', 'N', 'M', '<', 141 /* 108 */ '>', '?', KEY_RSHIFT, '\n', 142 /* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 143 /* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK, 144 /* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE, 145 /* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP, 146 }; 147 148 /* 149 * We need to remember the state of the keyboard's shift and control 150 * keys, and we need a per-type translation table. 151 */ 152 struct kbd_state { 153 const u_char *kbd_unshifted; /* unshifted keys */ 154 const u_char *kbd_shifted; /* shifted keys */ 155 const u_char *kbd_cur; /* current keys (either of the preceding) */ 156 union { 157 char c[2]; /* left and right shift keys */ 158 short s; /* true => either shift key */ 159 } kbd_shift; 160 #define kbd_lshift kbd_shift.c[0] 161 #define kbd_rshift kbd_shift.c[1] 162 #define kbd_anyshift kbd_shift.s 163 char kbd_control; /* true => ctrl down */ 164 char kbd_click; /* true => keyclick enabled */ 165 char kbd_takeid; /* take next byte as ID */ 166 u_char kbd_id; /* a place to store the ID */ 167 }; 168 169 /* 170 * Keyboard driver state. The ascii and kbd links go up and down and 171 * we just sit in the middle doing translation. Note that it is possible 172 * to get just one of the two links, in which case /dev/kbd is unavailable. 173 * The downlink supplies us with `internal' open and close routines which 174 * will enable dataflow across the downlink. We promise to call open when 175 * we are willing to take keystrokes, and to call close when we are not. 176 * If /dev/kbd is not the console tty input source, we do this whenever 177 * /dev/kbd is in use; otherwise we just leave it open forever. 178 */ 179 struct kbd_softc { 180 struct tty *k_cons; /* uplink for ASCII data to console */ 181 struct tty *k_kbd; /* downlink for output to keyboard */ 182 void (*k_open) __P((struct tty *)); /* enable dataflow */ 183 void (*k_close) __P((struct tty *)); /* disable dataflow */ 184 int k_evmode; /* set if we should produce events */ 185 struct kbd_state k_state; /* ASCII decode state */ 186 struct evvar k_events; /* event queue state */ 187 } kbd_softc; 188 189 /* Prototypes */ 190 void kbd_ascii(struct tty *); 191 void kbd_serial(struct tty *, void (*)(), void (*)()); 192 static void kbd_getid(void *); 193 void kbd_reset(struct kbd_state *); 194 static int kbd_translate(int, struct kbd_state *); 195 void kbd_rint(int); 196 int kbdopen(dev_t, int, int, struct proc *); 197 int kbdclose(dev_t, int, int, struct proc *); 198 int kbdread(dev_t, struct uio *, int); 199 int kbdwrite(dev_t, struct uio *, int); 200 int kbdioctl(dev_t, int, caddr_t, int, struct proc *); 201 int kbdselect(dev_t, int, struct proc *); 202 int kbd_docmd(int, int); 203 204 /* 205 * Attach the console keyboard ASCII (up-link) interface. 206 * This happens before kbd_serial. 207 */ 208 void 209 kbd_ascii(struct tty *tp) 210 { 211 212 kbd_softc.k_cons = tp; 213 } 214 215 /* 216 * Attach the console keyboard serial (down-link) interface. 217 * We pick up the initial keyboard click state here as well. 218 */ 219 void 220 kbd_serial(struct tty *tp, void (*iopen)(), void (*iclose)()) 221 { 222 register struct kbd_softc *k; 223 register char *cp; 224 225 k = &kbd_softc; 226 k->k_kbd = tp; 227 k->k_open = iopen; 228 k->k_close = iclose; 229 230 cp = getpropstring(optionsnode, "keyboard-click?"); 231 if (cp && strcmp(cp, "true") == 0) 232 k->k_state.kbd_click = 1; 233 } 234 235 /* 236 * Called from main() during pseudo-device setup. If this keyboard is 237 * the console, this is our chance to open the underlying serial port and 238 * send a RESET, so that we can find out what kind of keyboard it is. 239 */ 240 void 241 kbdattach(int nkbd) 242 { 243 register struct kbd_softc *k; 244 register struct tty *tp; 245 246 if (kbd_softc.k_cons != NULL) { 247 k = &kbd_softc; 248 tp = k->k_kbd; 249 (*k->k_open)(tp); /* never to be closed */ 250 if (ttyoutput(KBD_CMD_RESET, tp) >= 0) 251 panic("kbdattach"); 252 (*tp->t_oproc)(tp); /* get it going */ 253 } 254 } 255 256 void 257 kbd_reset(register struct kbd_state *ks) 258 { 259 /* 260 * On first identification, wake up anyone waiting for type 261 * and set up the table pointers. 262 */ 263 if (ks->kbd_unshifted == NULL) { 264 wakeup((caddr_t)ks); 265 ks->kbd_unshifted = kbd_unshifted; 266 ks->kbd_shifted = kbd_shifted; 267 ks->kbd_cur = ks->kbd_unshifted; 268 } 269 270 /* Restore keyclick, if necessary */ 271 switch (ks->kbd_id) { 272 273 case KB_SUN2: 274 /* Type 2 keyboards don't support keyclick */ 275 break; 276 277 case KB_SUN3: 278 /* Type 3 keyboards come up with keyclick on */ 279 if (!ks->kbd_click) 280 (void) kbd_docmd(KBD_CMD_NOCLICK, 0); 281 break; 282 283 case KB_SUN4: 284 /* Type 4 keyboards come up with keyclick off */ 285 if (ks->kbd_click) 286 (void) kbd_docmd(KBD_CMD_CLICK, 0); 287 break; 288 } 289 } 290 291 /* 292 * Turn keyboard up/down codes into ASCII. 293 */ 294 static int 295 kbd_translate(register int c, register struct kbd_state *ks) 296 { 297 register int down; 298 299 if (ks->kbd_cur == NULL) { 300 /* 301 * Do not know how to translate yet. 302 * We will find out when a RESET comes along. 303 */ 304 return (-1); 305 } 306 down = !KEY_UP(c); 307 c = ks->kbd_cur[KEY_CODE(c)]; 308 if (c & KEY_MAGIC) { 309 switch (c) { 310 311 case KEY_LSHIFT: 312 ks->kbd_lshift = down; 313 break; 314 315 case KEY_RSHIFT: 316 ks->kbd_rshift = down; 317 break; 318 319 case KEY_ALLUP: 320 ks->kbd_anyshift = 0; 321 ks->kbd_control = 0; 322 break; 323 324 case KEY_CONTROL: 325 ks->kbd_control = down; 326 /* FALLTHROUGH */ 327 328 case KEY_IGNORE: 329 return (-1); 330 331 default: 332 panic("kbd_translate"); 333 } 334 if (ks->kbd_anyshift) 335 ks->kbd_cur = ks->kbd_shifted; 336 else 337 ks->kbd_cur = ks->kbd_unshifted; 338 return (-1); 339 } 340 if (!down) 341 return (-1); 342 if (ks->kbd_control) { 343 /* control space and unshifted control atsign return null */ 344 if (c == ' ' || c == '2') 345 return (0); 346 /* unshifted control hat */ 347 if (c == '6') 348 return ('^' & 0x1f); 349 /* standard controls */ 350 if (c >= '@' && c < 0x7f) 351 return (c & 0x1f); 352 } 353 return (c); 354 } 355 356 void 357 kbd_rint(register int c) 358 { 359 register struct kbd_softc *k = &kbd_softc; 360 register struct firm_event *fe; 361 register int put; 362 363 /* 364 * Reset keyboard after serial port overrun, so we can resynch. 365 * The printf below should be shortened and/or replaced with a 366 * call to log() after this is tested (and how will we test it?!). 367 */ 368 if (c & (TTY_FE|TTY_PE)) { 369 printf("keyboard input parity or framing error (0x%x)\n", c); 370 (void) ttyoutput(KBD_CMD_RESET, k->k_kbd); 371 (*k->k_kbd->t_oproc)(k->k_kbd); 372 return; 373 } 374 375 /* Read the keyboard id if we read a KBD_RESET last time */ 376 if (k->k_state.kbd_takeid) { 377 k->k_state.kbd_takeid = 0; 378 k->k_state.kbd_id = c; 379 kbd_reset(&k->k_state); 380 return; 381 } 382 383 /* If we have been reset, setup to grab the keyboard id next time */ 384 if (c == KBD_RESET) { 385 k->k_state.kbd_takeid = 1; 386 return; 387 } 388 389 /* 390 * If /dev/kbd is not connected in event mode, but we are sending 391 * data to /dev/console, translate and send upstream. Note that 392 * we will get this while opening /dev/kbd if it is not already 393 * open and we do not know its type. 394 */ 395 if (!k->k_evmode) { 396 c = kbd_translate(c, &k->k_state); 397 if (c >= 0 && k->k_cons != NULL) 398 ttyinput(c, k->k_cons); 399 return; 400 } 401 402 /* 403 * IDLEs confuse the MIT X11R4 server badly, so we must drop them. 404 * This is bad as it means the server will not automatically resync 405 * on all-up IDLEs, but I did not drop them before, and the server 406 * goes crazy when it comes time to blank the screen.... 407 */ 408 if (c == KBD_IDLE) 409 return; 410 411 /* 412 * Keyboard is generating events. Turn this keystroke into an 413 * event and put it in the queue. If the queue is full, the 414 * keystroke is lost (sorry!). 415 */ 416 put = k->k_events.ev_put; 417 fe = &k->k_events.ev_q[put]; 418 put = (put + 1) % EV_QSIZE; 419 if (put == k->k_events.ev_get) { 420 log(LOG_WARNING, "keyboard event queue overflow\n"); /* ??? */ 421 return; 422 } 423 fe->id = KEY_CODE(c); 424 fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN; 425 fe->time = time; 426 k->k_events.ev_put = put; 427 EV_WAKEUP(&k->k_events); 428 } 429 430 int 431 kbdopen(dev_t dev, int flags, int mode, struct proc *p) 432 { 433 int s, error; 434 435 if (kbd_softc.k_events.ev_io) 436 return (EBUSY); 437 kbd_softc.k_events.ev_io = p; 438 /* 439 * If no console keyboard, tell the device to open up, maybe for 440 * the first time. Then make sure we know what kind of keyboard 441 * it is. 442 */ 443 if (kbd_softc.k_cons == NULL) 444 (*kbd_softc.k_open)(kbd_softc.k_kbd); 445 error = 0; 446 s = spltty(); 447 if (kbd_softc.k_state.kbd_cur == NULL) { 448 (void) ttyoutput(KBD_CMD_RESET, kbd_softc.k_kbd); 449 error = tsleep((caddr_t)&kbd_softc.k_state, PZERO | PCATCH, 450 devopn, hz); 451 if (error == EWOULDBLOCK) /* no response */ 452 error = ENXIO; 453 } 454 splx(s); 455 if (error) { 456 kbd_softc.k_events.ev_io = NULL; 457 return (error); 458 } 459 ev_init(&kbd_softc.k_events); 460 return (0); 461 } 462 463 int 464 kbdclose(dev_t dev, int flags, int mode, struct proc *p) 465 { 466 467 /* 468 * Turn off event mode, dump the queue, and close the keyboard 469 * unless it is supplying console input. 470 */ 471 kbd_softc.k_evmode = 0; 472 ev_fini(&kbd_softc.k_events); 473 if (kbd_softc.k_cons == NULL) 474 (*kbd_softc.k_close)(kbd_softc.k_kbd); 475 kbd_softc.k_events.ev_io = NULL; 476 return (0); 477 } 478 479 int 480 kbdread(dev_t dev, struct uio *uio, int flags) 481 { 482 483 return (ev_read(&kbd_softc.k_events, uio, flags)); 484 } 485 486 /* this routine should not exist, but is convenient to write here for now */ 487 int 488 kbdwrite(dev_t dev, struct uio *uio, int flags) 489 { 490 491 return (EOPNOTSUPP); 492 } 493 494 int 495 kbdioctl(dev_t dev, int cmd, register caddr_t data, int flag, struct proc *p) 496 { 497 register struct kbd_softc *k = &kbd_softc; 498 499 switch (cmd) { 500 501 case KIOCTRANS: 502 if (*(int *)data == TR_UNTRANS_EVENT) 503 return (0); 504 break; 505 506 case KIOCGTRANS: 507 /* 508 * Get translation mode 509 */ 510 *(int *)data = TR_UNTRANS_EVENT; 511 return (0); 512 513 case KIOCGETKEY: 514 if (((struct kiockey *)data)->kio_station == 118) { 515 /* 516 * This is X11 asking if a type 3 keyboard is 517 * really a type 3 keyboard. Say yes. 518 */ 519 ((struct kiockey *)data)->kio_entry = HOLE; 520 return (0); 521 } 522 break; 523 524 case KIOCCMD: 525 /* 526 * ``unimplemented commands are ignored'' (blech) 527 * so cannot check return value from kbd_docmd 528 */ 529 #ifdef notyet 530 while (kbd_docmd(*(int *)data, 1) == ENOSPC) /*ERESTART?*/ 531 (void) sleep((caddr_t)&lbolt, TTOPRI); 532 #else 533 (void) kbd_docmd(*(int *)data, 1); 534 #endif 535 return (0); 536 537 case KIOCTYPE: 538 *(int *)data = k->k_state.kbd_id; 539 return (0); 540 541 case KIOCSDIRECT: 542 k->k_evmode = *(int *)data; 543 return (0); 544 545 case FIONBIO: /* we will remove this someday (soon???) */ 546 return (0); 547 548 case FIOASYNC: 549 k->k_events.ev_async = *(int *)data != 0; 550 return (0); 551 552 case TIOCSPGRP: 553 if (*(int *)data != k->k_events.ev_io->p_pgid) 554 return (EPERM); 555 return (0); 556 557 default: 558 return (ENOTTY); 559 } 560 561 /* 562 * We identified the ioctl, but we do not handle it. 563 */ 564 return (EOPNOTSUPP); /* misuse, but what the heck */ 565 } 566 567 int 568 kbdselect(dev_t dev, int rw, struct proc *p) 569 { 570 571 return (ev_select(&kbd_softc.k_events, rw, p)); 572 } 573 574 /* 575 * Execute a keyboard command; return 0 on success. 576 * If `isuser', force a small delay before output if output queue 577 * is flooding. (The keyboard runs at 1200 baud, or 120 cps.) 578 */ 579 int 580 kbd_docmd(int cmd, int isuser) 581 { 582 register struct tty *tp = kbd_softc.k_kbd; 583 register struct kbd_softc *k = &kbd_softc; 584 int s; 585 586 if (tp == NULL) 587 return (ENXIO); /* ??? */ 588 switch (cmd) { 589 590 case KBD_CMD_BELL: 591 case KBD_CMD_NOBELL: 592 /* Supported by type 2, 3, and 4 keyboards */ 593 break; 594 595 case KBD_CMD_CLICK: 596 /* Unsupported by type 2 keyboards */ 597 if (k->k_state.kbd_id != KB_SUN2) { 598 k->k_state.kbd_click = 1; 599 break; 600 } 601 return (EINVAL); 602 603 case KBD_CMD_NOCLICK: 604 /* Unsupported by type 2 keyboards */ 605 if (k->k_state.kbd_id != KB_SUN2) { 606 k->k_state.kbd_click = 0; 607 break; 608 } 609 return (EINVAL); 610 611 default: 612 return (EINVAL); /* ENOTTY? EOPNOTSUPP? */ 613 } 614 615 if (isuser) { 616 s = spltty(); 617 if (tp->t_outq.c_cc > 120) 618 (void) tsleep((caddr_t)&lbolt, TTIPRI, 619 ttyout, 0); 620 splx(s); 621 } 622 if (ttyoutput(cmd, tp) >= 0) 623 return (ENOSPC); /* ERESTART? */ 624 (*tp->t_oproc)(tp); 625 return (0); 626 } 627