1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 
  27 /*
  28  * USB keyboard input streams module - processes USB keypacket
  29  * received from HID driver below to either ASCII or event
  30  * format for windowing system.
  31  */
  32 #include <sys/usb/usba/usbai_version.h>
  33 
  34 #define KEYMAP_SIZE_VARIABLE
  35 #include <sys/usb/usba.h>
  36 #include <sys/usb/clients/hid/hid.h>
  37 #include <sys/usb/clients/hid/hid_polled.h>
  38 #include <sys/usb/clients/hidparser/hidparser.h>
  39 #include <sys/stropts.h>
  40 #include <sys/stream.h>
  41 #include <sys/strsun.h>
  42 #include <sys/kbio.h>
  43 #include <sys/vuid_event.h>
  44 #include <sys/kbd.h>
  45 #include <sys/consdev.h>
  46 #include <sys/kbtrans.h>
  47 #include <sys/usb/clients/usbkbm/usbkbm.h>
  48 #include <sys/beep.h>
  49 #include <sys/inttypes.h>
  50 
  51 /* debugging information */
  52 uint_t  usbkbm_errmask = (uint_t)PRINT_MASK_ALL;
  53 uint_t  usbkbm_errlevel = USB_LOG_L2;
  54 static usb_log_handle_t usbkbm_log_handle;
  55 
  56 typedef void (*process_key_callback_t)(usbkbm_state_t *, int, enum keystate);
  57 
  58 /*
  59  * Internal Function Prototypes
  60  */
  61 static void usbkbm_streams_setled(struct kbtrans_hardware *, int);
  62 static void usbkbm_polled_setled(struct kbtrans_hardware *, int);
  63 static boolean_t usbkbm_polled_keycheck(struct kbtrans_hardware *,
  64                         int *, enum keystate *);
  65 static void usbkbm_poll_callback(usbkbm_state_t *, int, enum keystate);
  66 static void usbkbm_streams_callback(usbkbm_state_t *, int, enum keystate);
  67 static void usbkbm_unpack_usb_packet(usbkbm_state_t *, process_key_callback_t,
  68                         uchar_t *);
  69 static boolean_t usbkbm_is_modkey(uchar_t);
  70 static void usbkbm_reioctl(void *);
  71 static int usbkbm_polled_getchar(cons_polledio_arg_t);
  72 static boolean_t usbkbm_polled_ischar(cons_polledio_arg_t);
  73 static void usbkbm_polled_enter(cons_polledio_arg_t);
  74 static void usbkbm_polled_exit(cons_polledio_arg_t);
  75 static void usbkbm_mctl_receive(queue_t *, mblk_t *);
  76 static enum kbtrans_message_response usbkbm_ioctl(queue_t *, mblk_t *);
  77 static int usbkbm_kioccmd(usbkbm_state_t *, mblk_t *, char, size_t *);
  78 static void     usbkbm_usb2pc_xlate(usbkbm_state_t *, int, enum keystate);
  79 static void     usbkbm_wrap_kbtrans(usbkbm_state_t *, int, enum keystate);
  80 static int      usbkbm_get_input_format(usbkbm_state_t *);
  81 static int      usbkbm_get_vid_pid(usbkbm_state_t *);
  82 
  83 /* stream qinit functions defined here */
  84 static int      usbkbm_open(queue_t *, dev_t *, int, int, cred_t *);
  85 static int      usbkbm_close(queue_t *, int, cred_t *);
  86 static void     usbkbm_wput(queue_t *, mblk_t *);
  87 static void     usbkbm_rput(queue_t *, mblk_t *);
  88 static ushort_t usbkbm_get_state(usbkbm_state_t *);
  89 static void     usbkbm_get_scancode(usbkbm_state_t *, int *, enum keystate *);
  90 
  91 static struct keyboard *usbkbm_keyindex;
  92 
  93 /* External Functions */
  94 extern void space_free(char *);
  95 extern uintptr_t space_fetch(char *);
  96 extern int space_store(char *, uintptr_t);
  97 extern struct keyboard *kbtrans_usbkb_maptab_init(void);
  98 extern void kbtrans_usbkb_maptab_fini(struct keyboard **);
  99 extern keymap_entry_t kbtrans_keycode_usb2pc(int);
 100 
 101 /*
 102  * Structure to setup callbacks
 103  */
 104 struct kbtrans_callbacks kbd_usb_callbacks = {
 105         usbkbm_streams_setled,
 106         usbkbm_polled_setled,
 107         usbkbm_polled_keycheck,
 108 };
 109 
 110 /*
 111  * Global Variables
 112  */
 113 
 114 /* This variable saves the LED state across hotplugging. */
 115 static uchar_t  usbkbm_led_state = 0;
 116 
 117 /* This variable saves the layout state */
 118 static uint16_t usbkbm_layout = 0;
 119 
 120 /*
 121  * Function pointer array for mapping of scancodes.
 122  */
 123 void (*usbkbm_xlate[2])(usbkbm_state_t *, int, enum keystate) = {
 124         usbkbm_wrap_kbtrans,
 125         usbkbm_usb2pc_xlate
 126 };
 127 
 128 static struct streamtab usbkbm_info;
 129 static struct fmodsw fsw = {
 130         "usbkbm",
 131         &usbkbm_info,
 132         D_MP | D_MTPERMOD
 133 };
 134 
 135 
 136 /*
 137  * Module linkage information for the kernel.
 138  */
 139 static struct modlstrmod modlstrmod = {
 140         &mod_strmodops,
 141         "USB keyboard streams 1.44",
 142         &fsw
 143 };
 144 
 145 static struct modlinkage modlinkage = {
 146         MODREV_1,
 147         { (void *)&modlstrmod, NULL }
 148 };
 149 
 150 
 151 int
 152 _init(void)
 153 {
 154         int     rval = mod_install(&modlinkage);
 155         usbkbm_save_state_t *sp;
 156 
 157         if (rval != 0) {
 158 
 159                 return (rval);
 160         }
 161 
 162         usbkbm_keyindex = kbtrans_usbkb_maptab_init();
 163 
 164         usbkbm_log_handle = usb_alloc_log_hdl(NULL, "usbkbm",
 165             &usbkbm_errlevel, &usbkbm_errmask, NULL, 0);
 166 
 167         sp = (usbkbm_save_state_t *)space_fetch("SUNW,usbkbm_state");
 168 
 169         if (sp == NULL) {
 170 
 171                 return (0);
 172         }
 173 
 174         /* Restore LED information */
 175         usbkbm_led_state = sp->usbkbm_save_led;
 176 
 177         /* Restore the Layout */
 178         usbkbm_layout = sp->usbkbm_layout;
 179 
 180         /* Restore abort information */
 181         usbkbm_keyindex->k_abort1 =
 182             sp->usbkbm_save_keyindex.k_abort1;
 183 
 184         usbkbm_keyindex->k_abort2 =
 185             sp->usbkbm_save_keyindex.k_abort2;
 186 
 187         usbkbm_keyindex->k_newabort1 =
 188             sp->usbkbm_save_keyindex.k_newabort1;
 189 
 190         usbkbm_keyindex->k_newabort2 =
 191             sp->usbkbm_save_keyindex.k_newabort2;
 192 
 193         /* Restore keytables */
 194         bcopy(sp->usbkbm_save_keyindex.k_normal,
 195             usbkbm_keyindex->k_normal, USB_KEYTABLE_SIZE);
 196 
 197         bcopy(sp->usbkbm_save_keyindex.k_shifted,
 198             usbkbm_keyindex->k_shifted, USB_KEYTABLE_SIZE);
 199 
 200         bcopy(sp->usbkbm_save_keyindex.k_caps,
 201             usbkbm_keyindex->k_caps, USB_KEYTABLE_SIZE);
 202 
 203         bcopy(sp->usbkbm_save_keyindex.k_altgraph,
 204             usbkbm_keyindex->k_altgraph, USB_KEYTABLE_SIZE);
 205 
 206         bcopy(sp->usbkbm_save_keyindex.k_numlock,
 207             usbkbm_keyindex->k_numlock, USB_KEYTABLE_SIZE);
 208 
 209         bcopy(sp->usbkbm_save_keyindex.k_control,
 210             usbkbm_keyindex->k_control, USB_KEYTABLE_SIZE);
 211 
 212         bcopy(sp->usbkbm_save_keyindex.k_up,
 213             usbkbm_keyindex->k_up, USB_KEYTABLE_SIZE);
 214 
 215         kmem_free(sp->usbkbm_save_keyindex.k_normal,
 216             USB_KEYTABLE_SIZE);
 217         kmem_free(sp->usbkbm_save_keyindex.k_shifted,
 218             USB_KEYTABLE_SIZE);
 219         kmem_free(sp->usbkbm_save_keyindex.k_caps,
 220             USB_KEYTABLE_SIZE);
 221         kmem_free(sp->usbkbm_save_keyindex.k_altgraph,
 222             USB_KEYTABLE_SIZE);
 223         kmem_free(sp->usbkbm_save_keyindex.k_numlock,
 224             USB_KEYTABLE_SIZE);
 225         kmem_free(sp->usbkbm_save_keyindex.k_control,
 226             USB_KEYTABLE_SIZE);
 227         kmem_free(sp->usbkbm_save_keyindex.k_up,
 228             USB_KEYTABLE_SIZE);
 229 
 230         kmem_free(sp, sizeof (usbkbm_save_state_t));
 231         space_free("SUNW,usbkbm_state");
 232 
 233         return (0);
 234 }
 235 
 236 int
 237 _fini(void)
 238 {
 239         usbkbm_save_state_t *sp;
 240         int sval;
 241         int rval;
 242 
 243         sp = kmem_alloc(sizeof (usbkbm_save_state_t), KM_SLEEP);
 244         sval = space_store("SUNW,usbkbm_state", (uintptr_t)sp);
 245 
 246         /*
 247          * If it's not possible to store the state, return
 248          * EBUSY.
 249          */
 250         if (sval != 0) {
 251                 kmem_free(sp, sizeof (usbkbm_save_state_t));
 252 
 253                 return (EBUSY);
 254         }
 255 
 256         rval = mod_remove(&modlinkage);
 257 
 258         if (rval != 0) {
 259                 kmem_free(sp, sizeof (usbkbm_save_state_t));
 260                 space_free("SUNW,usbkbm_state");
 261 
 262                 return (rval);
 263         }
 264 
 265         usb_free_log_hdl(usbkbm_log_handle);
 266 
 267         /* Save the LED state */
 268         sp->usbkbm_save_led = usbkbm_led_state;
 269 
 270         /* Save the layout */
 271         sp->usbkbm_layout = (uchar_t)usbkbm_layout;
 272 
 273         /*
 274          * Save entries of the keyboard structure that
 275          * have changed.
 276          */
 277         sp->usbkbm_save_keyindex.k_abort1 = usbkbm_keyindex->k_abort1;
 278         sp->usbkbm_save_keyindex.k_abort2 = usbkbm_keyindex->k_abort2;
 279 
 280         sp->usbkbm_save_keyindex.k_newabort1 = usbkbm_keyindex->k_newabort1;
 281         sp->usbkbm_save_keyindex.k_newabort2 = usbkbm_keyindex->k_newabort2;
 282 
 283         /* Allocate space for keytables to be stored */
 284         sp->usbkbm_save_keyindex.k_normal =
 285             kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
 286         sp->usbkbm_save_keyindex.k_shifted =
 287             kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
 288         sp->usbkbm_save_keyindex.k_caps =
 289             kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
 290         sp->usbkbm_save_keyindex.k_altgraph =
 291             kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
 292         sp->usbkbm_save_keyindex.k_numlock =
 293             kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
 294         sp->usbkbm_save_keyindex.k_control =
 295             kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
 296         sp->usbkbm_save_keyindex.k_up =
 297             kmem_alloc(USB_KEYTABLE_SIZE, KM_SLEEP);
 298 
 299         /* Copy over the keytables */
 300         bcopy(usbkbm_keyindex->k_normal,
 301             sp->usbkbm_save_keyindex.k_normal, USB_KEYTABLE_SIZE);
 302 
 303         bcopy(usbkbm_keyindex->k_shifted,
 304             sp->usbkbm_save_keyindex.k_shifted, USB_KEYTABLE_SIZE);
 305 
 306         bcopy(usbkbm_keyindex->k_caps,
 307             sp->usbkbm_save_keyindex.k_caps, USB_KEYTABLE_SIZE);
 308 
 309         bcopy(usbkbm_keyindex->k_altgraph,
 310             sp->usbkbm_save_keyindex.k_altgraph, USB_KEYTABLE_SIZE);
 311 
 312         bcopy(usbkbm_keyindex->k_numlock,
 313             sp->usbkbm_save_keyindex.k_numlock, USB_KEYTABLE_SIZE);
 314 
 315         bcopy(usbkbm_keyindex->k_control,
 316             sp->usbkbm_save_keyindex.k_control, USB_KEYTABLE_SIZE);
 317 
 318         bcopy(usbkbm_keyindex->k_up,
 319             sp->usbkbm_save_keyindex.k_up, USB_KEYTABLE_SIZE);
 320 
 321         kbtrans_usbkb_maptab_fini(&usbkbm_keyindex);
 322 
 323         return (0);
 324 }
 325 
 326 int
 327 _info(struct modinfo *modinfop)
 328 {
 329         return (mod_info(&modlinkage, modinfop));
 330 }
 331 
 332 /*
 333  * Module qinit functions
 334  */
 335 
 336 static struct module_info usbkbm_minfo = {
 337         0,              /* module id number */
 338         "usbkbm",       /* module name */
 339         0,              /* min packet size accepted */
 340         INFPSZ,         /* max packet size accepted */
 341         2048,           /* hi-water mark */
 342         128             /* lo-water mark */
 343         };
 344 
 345 /* read side for key data and ioctl replies */
 346 static struct qinit usbkbm_rinit = {
 347         (int (*)())usbkbm_rput,
 348         (int (*)())NULL,                /* service not used */
 349         usbkbm_open,
 350         usbkbm_close,
 351         (int (*)())NULL,
 352         &usbkbm_minfo
 353         };
 354 
 355 /* write side for ioctls */
 356 static struct qinit usbkbm_winit = {
 357         (int (*)())usbkbm_wput,
 358         (int (*)())NULL,
 359         usbkbm_open,
 360         usbkbm_close,
 361         (int (*)())NULL,
 362         &usbkbm_minfo
 363         };
 364 
 365 static struct streamtab usbkbm_info = {
 366         &usbkbm_rinit,
 367         &usbkbm_winit,
 368         NULL,           /* for muxes */
 369         NULL,           /* for muxes */
 370 };
 371 
 372 /*
 373  * usbkbm_open :
 374  *      Open a keyboard
 375  */
 376 /* ARGSUSED */
 377 static int
 378 usbkbm_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp)
 379 {
 380         usbkbm_state_t  *usbkbmd;
 381         struct iocblk   mctlmsg;
 382         mblk_t          *mctl_ptr;
 383         uintptr_t       abortable = (uintptr_t)B_TRUE;
 384         int             error, ret;
 385 
 386         if (q->q_ptr) {
 387                 USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
 388                     "usbkbm_open already opened");
 389 
 390                 return (0); /* already opened */
 391         }
 392 
 393         switch (sflag) {
 394 
 395         case MODOPEN:
 396                 break;
 397 
 398         case CLONEOPEN:
 399                 USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
 400                     "usbkbm_open: Clone open not supported");
 401 
 402                 /* FALLTHRU */
 403         default:
 404 
 405                 return (EINVAL);
 406         }
 407 
 408         /* allocate usb keyboard state structure */
 409 
 410         usbkbmd = kmem_zalloc(sizeof (usbkbm_state_t), KM_SLEEP);
 411 
 412         USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
 413             "usbkbm_state= %p", (void *)usbkbmd);
 414 
 415         /*
 416          * Set up private data.
 417          */
 418         usbkbmd->usbkbm_readq = q;
 419         usbkbmd->usbkbm_writeq = WR(q);
 420 
 421         usbkbmd->usbkbm_vkbd_type = KB_USB;
 422         /*
 423          * Set up queue pointers, so that the "put" procedure will accept
 424          * the reply to the "ioctl" message we send down.
 425          */
 426         q->q_ptr = (caddr_t)usbkbmd;
 427         WR(q)->q_ptr = (caddr_t)usbkbmd;
 428 
 429         error = kbtrans_streams_init(q, sflag,
 430             (struct kbtrans_hardware *)usbkbmd, &kbd_usb_callbacks,
 431             &usbkbmd->usbkbm_kbtrans, usbkbm_led_state, 0);
 432 
 433         if (error != 0) {
 434                 USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
 435                     "kbdopen:  kbtrans_streams_init failed\n");
 436                 kmem_free(usbkbmd, sizeof (*usbkbmd));
 437 
 438                 return (error);
 439         }
 440 
 441         /*
 442          * Set the polled information in the state structure.
 443          * This information is set once, and doesn't change
 444          */
 445         usbkbmd->usbkbm_polled_info.cons_polledio_version =
 446             CONSPOLLEDIO_V1;
 447 
 448         usbkbmd->usbkbm_polled_info.cons_polledio_argument =
 449             (cons_polledio_arg_t)usbkbmd;
 450 
 451         usbkbmd->usbkbm_polled_info.cons_polledio_putchar = NULL;
 452 
 453         usbkbmd->usbkbm_polled_info.cons_polledio_getchar =
 454             usbkbm_polled_getchar;
 455 
 456         usbkbmd->usbkbm_polled_info.cons_polledio_ischar =
 457             usbkbm_polled_ischar;
 458 
 459         usbkbmd->usbkbm_polled_info.cons_polledio_enter =
 460             usbkbm_polled_enter;
 461 
 462         usbkbmd->usbkbm_polled_info.cons_polledio_exit =
 463             usbkbm_polled_exit;
 464 
 465         usbkbmd->usbkbm_polled_info.cons_polledio_setled =
 466             (void (*)(cons_polledio_arg_t, int))usbkbm_polled_setled;
 467 
 468         usbkbmd->usbkbm_polled_info.cons_polledio_keycheck =
 469             (boolean_t (*)(cons_polledio_arg_t, int *,
 470             enum keystate *))usbkbm_polled_keycheck;
 471         /*
 472          * The head and the tail pointing at the same byte means empty or
 473          * full. usbkbm_polled_buffer_num_characters is used to
 474          * tell the difference.
 475          */
 476         usbkbmd->usbkbm_polled_buffer_head =
 477             usbkbmd->usbkbm_polled_scancode_buffer;
 478         usbkbmd->usbkbm_polled_buffer_tail =
 479             usbkbmd->usbkbm_polled_scancode_buffer;
 480         usbkbmd->usbkbm_polled_buffer_num_characters = 0;
 481 
 482         qprocson(q);
 483 
 484         /* request hid report descriptor from HID */
 485         mctlmsg.ioc_cmd = HID_GET_PARSER_HANDLE;
 486         mctlmsg.ioc_count = 0;
 487         mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
 488         if (mctl_ptr == NULL) {
 489                 /* failure to allocate M_CTL message */
 490                 (void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
 491                 qprocsoff(q);
 492                 kmem_free(usbkbmd, sizeof (*usbkbmd));
 493 
 494                 return (ENOMEM);
 495         }
 496 
 497         /* send message to hid */
 498         putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
 499 
 500         /*
 501          * Now that M_CTL has been sent, wait for report descriptor.  Cleanup
 502          * if user signals in the mean time (as when this gets opened in an
 503          * inappropriate context and the user types a ^C).
 504          */
 505         usbkbmd->usbkbm_flags |= USBKBM_QWAIT;
 506         while (usbkbmd->usbkbm_flags & USBKBM_QWAIT) {
 507 
 508                 if (qwait_sig(q) == 0) {
 509                         usbkbmd->usbkbm_flags = 0;
 510                         (void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
 511                         qprocsoff(q);
 512                         kmem_free(usbkbmd, sizeof (*usbkbmd));
 513 
 514                         return (EINTR);
 515                 }
 516         }
 517 
 518 
 519         /* get the input format from the hid descriptor */
 520         if (usbkbm_get_input_format(usbkbmd) != USB_SUCCESS) {
 521 
 522                 USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
 523                     "usbkbm: Invalid HID Descriptor Tree."
 524                     "setting default report format");
 525         }
 526 
 527         /*
 528          * Although Sun Japanese type6 and type7 keyboards have the same
 529          * layout number(15), they should be recognized for loading the
 530          * different keytables on upper apps (e.g. X). The new layout
 531          * number (271) is defined for the Sun Japanese type6 keyboards.
 532          * The layout number (15) specified in HID spec is used for other
 533          * Japanese keyboards. It is a workaround for the old Sun Japanese
 534          * type6 keyboards defect.
 535          */
 536         if (usbkbmd->usbkbm_layout == SUN_JAPANESE_TYPE7) {
 537 
 538                 if ((ret = usbkbm_get_vid_pid(usbkbmd)) != 0) {
 539 
 540                         return (ret);
 541                 }
 542 
 543                 if ((usbkbmd->usbkbm_vid_pid.VendorId ==
 544                     HID_SUN_JAPANESE_TYPE6_KBD_VID) &&
 545                     (usbkbmd->usbkbm_vid_pid.ProductId ==
 546                     HID_SUN_JAPANESE_TYPE6_KBD_PID)) {
 547                         usbkbmd->usbkbm_layout = SUN_JAPANESE_TYPE6;
 548                 }
 549         }
 550 
 551         kbtrans_streams_set_keyboard(usbkbmd->usbkbm_kbtrans, KB_USB,
 552             usbkbm_keyindex);
 553 
 554         usbkbmd->usbkbm_flags = USBKBM_OPEN;
 555 
 556         kbtrans_streams_enable(usbkbmd->usbkbm_kbtrans);
 557 
 558         /*
 559          * Enable abort sequence on inital. For an internal open, conskbd
 560          * will disable driver abort handling (later through M_IOCTL) and
 561          * handle it by itself.
 562          * For an external (aka. physical) open, this is necessary since
 563          * no STREAMS module linked on top of usbkbm handles abort sequence.
 564          */
 565         mctlmsg.ioc_cmd = CONSSETABORTENABLE;
 566         mctlmsg.ioc_count = TRANSPARENT;
 567         mctl_ptr = usba_mk_mctl(mctlmsg, &abortable, sizeof (abortable));
 568         if (mctl_ptr != NULL) {
 569                 DB_TYPE(mctl_ptr) = M_IOCTL;
 570                 if (kbtrans_streams_message(usbkbmd->usbkbm_kbtrans, mctl_ptr)
 571                     != KBTRANS_MESSAGE_HANDLED) {
 572                         freemsg(mctl_ptr);
 573                 }
 574         } else {
 575                 USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
 576                     "usbkbm: enable abort sequence failed");
 577         }
 578 
 579         USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
 580             "usbkbm_open exiting");
 581         return (0);
 582 }
 583 
 584 
 585 /*
 586  * usbkbm_close :
 587  *      Close a keyboard.
 588  */
 589 /* ARGSUSED1 */
 590 static int
 591 usbkbm_close(register queue_t *q, int flag, cred_t *crp)
 592 {
 593         usbkbm_state_t *usbkbmd = (usbkbm_state_t *)q->q_ptr;
 594 
 595         /* If a beep is in progress, stop that */
 596         (void) beeper_off();
 597 
 598         (void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
 599 
 600         qprocsoff(q);
 601         /*
 602          * Since we're about to destroy our private data, turn off
 603          * our open flag first, so we don't accept any more input
 604          * and try to use that data.
 605          */
 606         usbkbmd->usbkbm_flags = 0;
 607 
 608         kmem_free(usbkbmd, sizeof (usbkbm_state_t));
 609 
 610         USB_DPRINTF_L3(PRINT_MASK_CLOSE, usbkbm_log_handle,
 611             "usbkbm_close exiting");
 612 
 613         return (0);
 614 }
 615 
 616 
 617 /*
 618  * usbkbm_wput :
 619  *      usb keyboard module output queue put procedure: handles M_IOCTL
 620  *      messages.
 621  */
 622 static void
 623 usbkbm_wput(register queue_t *q, register mblk_t *mp)
 624 {
 625         usbkbm_state_t                  *usbkbmd;
 626         enum kbtrans_message_response   ret;
 627 
 628         USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
 629             "usbkbm_wput entering");
 630 
 631         usbkbmd = (usbkbm_state_t *)q->q_ptr;
 632 
 633         /* First, see if kbtrans will handle the message */
 634         ret = kbtrans_streams_message(usbkbmd->usbkbm_kbtrans, mp);
 635 
 636         if (ret == KBTRANS_MESSAGE_HANDLED) {
 637 
 638                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
 639                     "usbkbm_wput exiting:2");
 640 
 641                 return;
 642         }
 643 
 644         /* kbtrans didn't handle the message.  Try to handle it here */
 645 
 646         switch (mp->b_datap->db_type) {
 647 
 648         case M_FLUSH:
 649                 if (*mp->b_rptr & FLUSHW) {
 650                         flushq(q, FLUSHDATA);
 651                 }
 652 
 653                 if (*mp->b_rptr & FLUSHR) {
 654                         flushq(RD(q), FLUSHDATA);
 655                 }
 656 
 657                 break;
 658 
 659         case M_IOCTL:
 660                 ret = usbkbm_ioctl(q, mp);
 661 
 662                 if (ret == KBTRANS_MESSAGE_HANDLED) {
 663 
 664                         USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
 665                             "usbkbm_wput exiting:1");
 666 
 667                         return;
 668                 }
 669         default:
 670                 break;
 671         }
 672 
 673         /*
 674          * The message has not been handled
 675          * by kbtrans or this module.  Pass it down the stream
 676          */
 677         putnext(q, mp);
 678 
 679         USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
 680             "usbkbm_wput exiting:3");
 681 }
 682 
 683 /*
 684  * usbkbm_ioctl :
 685  *      Handles the ioctls sent from upper module. Returns
 686  *      ACK/NACK back.
 687  */
 688 static enum kbtrans_message_response
 689 usbkbm_ioctl(register queue_t *q, register mblk_t *mp)
 690 {
 691         usbkbm_state_t          *usbkbmd;
 692         struct iocblk           mctlmsg;
 693         struct iocblk           *iocp;
 694         mblk_t                  *datap, *mctl_ptr;
 695         size_t                  ioctlrespsize;
 696         int                     err;
 697         int                     tmp;
 698         int                     cycles;
 699         int                     frequency;
 700         int                     msecs;
 701         char                    command;
 702 
 703         err = 0;
 704 
 705         usbkbmd = (usbkbm_state_t *)q->q_ptr;
 706         iocp = (struct iocblk *)mp->b_rptr;
 707 
 708         switch (iocp->ioc_cmd) {
 709         case CONSSETKBDTYPE:
 710                 err = miocpullup(mp, sizeof (int));
 711                 if (err != 0) {
 712                         break;
 713                 }
 714                 tmp = *(int *)mp->b_cont->b_rptr;
 715                 if (tmp != KB_PC && tmp != KB_USB) {
 716                         err = EINVAL;
 717                         break;
 718                 }
 719                 usbkbmd->usbkbm_vkbd_type = tmp;
 720                 break;
 721         case KIOCLAYOUT:
 722 
 723                 datap = allocb(sizeof (int), BPRI_HI);
 724                 if (datap == NULL) {
 725                         ioctlrespsize = sizeof (int);
 726 
 727                         goto allocfailure;
 728                 }
 729 
 730                 *(int *)datap->b_wptr = usbkbmd->usbkbm_layout;
 731                 datap->b_wptr += sizeof (int);
 732 
 733                 freemsg(mp->b_cont);
 734 
 735                 mp->b_cont = datap;
 736                 iocp->ioc_count = sizeof (int);
 737                 break;
 738 
 739         case KIOCSLAYOUT:
 740                 /*
 741                  * Supply a layout if not specified by the hardware, or
 742                  * override any that was specified.
 743                  */
 744                 if (iocp->ioc_count != TRANSPARENT) {
 745                         err = EINVAL;
 746                         break;
 747                 }
 748 
 749                 usbkbmd->usbkbm_layout = *(intptr_t *)mp->b_cont->b_rptr;
 750 
 751                 /*
 752                  * Save the layout in usbkbm_layout so as to handle the
 753                  * the case when the user has re-plugged in the non-self
 754                  * identifying non US keyboard. In this the layout is saved
 755                  * in global variable, so the user does not have to run
 756                  * kdmconfig again after the X server reset
 757                  */
 758 
 759                 usbkbm_layout = usbkbmd->usbkbm_layout;
 760                 break;
 761 
 762         case KIOCCMD:
 763                 /*
 764                  * Check if we have at least the subcommand field; any
 765                  * other argument validation has to occur inside
 766                  * usbkbm_kioccmd().
 767                  */
 768                 err = miocpullup(mp, sizeof (int));
 769                 if (err != 0)
 770                         break;
 771 
 772                 /* Subcommand */
 773                 command = (char)(*(int *)mp->b_cont->b_rptr);
 774 
 775                 /*
 776                  * Check if this ioctl is followed by a previous
 777                  * KBD_CMD_SETLED command, in which case we take
 778                  * the command byte as the data for setting the LED
 779                  */
 780                 if (usbkbmd->usbkbm_setled_second_byte) {
 781                         usbkbm_streams_setled((struct kbtrans_hardware *)
 782                             usbkbmd, command);
 783                         usbkbmd->usbkbm_setled_second_byte = 0;
 784                         break;
 785                 }
 786 
 787                 /*
 788                  * In  case of allocb failure, this will
 789                  * return the size of the allocation which
 790                  * failed so that it can be allocated later
 791                  * through bufcall.
 792                  */
 793                 ioctlrespsize = 0;
 794 
 795                 err = usbkbm_kioccmd(usbkbmd, mp, command, &ioctlrespsize);
 796 
 797                 if (ioctlrespsize != 0) {
 798 
 799                         goto allocfailure;
 800                 }
 801 
 802                 break;
 803 
 804         case CONSOPENPOLLEDIO:
 805                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
 806                     "usbkbm_ioctl CONSOPENPOLLEDIO");
 807 
 808                 err = miocpullup(mp, sizeof (struct cons_polledio *));
 809                 if (err != 0) {
 810                         USB_DPRINTF_L2(PRINT_MASK_ALL, usbkbm_log_handle,
 811                             "usbkbm_ioctl: malformed request");
 812                         break;
 813                 }
 814 
 815                 usbkbmd->usbkbm_pending_link = mp;
 816 
 817                 /*
 818                  * Get the polled input structure from hid
 819                  */
 820                 mctlmsg.ioc_cmd = HID_OPEN_POLLED_INPUT;
 821                 mctlmsg.ioc_count = 0;
 822                 mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
 823                 if (mctl_ptr == NULL) {
 824                         ioctlrespsize = sizeof (mctlmsg);
 825 
 826                         goto allocfailure;
 827                 }
 828 
 829                 putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
 830 
 831                 /*
 832                  * Do not ack or nack the message, we will wait for the
 833                  * result of HID_OPEN_POLLED_INPUT
 834                  */
 835 
 836                 return (KBTRANS_MESSAGE_HANDLED);
 837 
 838         case CONSCLOSEPOLLEDIO:
 839                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
 840                     "usbkbm_ioctl CONSCLOSEPOLLEDIO mp = 0x%p", (void *)mp);
 841 
 842                 usbkbmd->usbkbm_pending_link = mp;
 843 
 844                 /*
 845                  * Get the polled input structure from hid
 846                  */
 847                 mctlmsg.ioc_cmd = HID_CLOSE_POLLED_INPUT;
 848                 mctlmsg.ioc_count = 0;
 849                 mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
 850                 if (mctl_ptr == NULL) {
 851                         ioctlrespsize = sizeof (mctlmsg);
 852 
 853                         goto allocfailure;
 854                 }
 855 
 856                 putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
 857 
 858                 /*
 859                  * Do not ack or nack the message, we will wait for the
 860                  * result of HID_CLOSE_POLLED_INPUT
 861                  */
 862 
 863                 return (KBTRANS_MESSAGE_HANDLED);
 864 
 865         case CONSSETABORTENABLE:
 866                 /*
 867                  * Nothing special to do for USB.
 868                  */
 869                 break;
 870 
 871 
 872         case KIOCMKTONE:
 873                 if (iocp->ioc_count != TRANSPARENT) {
 874                         err = EINVAL;
 875                         break;
 876                 }
 877 
 878                 tmp = (int)(*(intptr_t *)mp->b_cont->b_rptr);
 879                 cycles = tmp & 0xffff;
 880                 msecs = (tmp >> 16) & 0xffff;
 881 
 882                 if (cycles == 0)
 883                         frequency = UINT16_MAX;
 884                 else if (cycles == UINT16_MAX)
 885                         frequency = 0;
 886                 else {
 887                         frequency = (PIT_HZ + cycles / 2) / cycles;
 888                         if (frequency > UINT16_MAX)
 889                                 frequency = UINT16_MAX;
 890                 }
 891 
 892                 err = beep_mktone(frequency, msecs);
 893                 break;
 894 
 895         default:
 896 
 897                 return (KBTRANS_MESSAGE_NOT_HANDLED);
 898         }
 899 
 900         /*
 901          * Send ACK/NACK to upper module for
 902          * the messages that have been handled.
 903          */
 904         if (err != 0) {
 905                 iocp->ioc_rval = 0;
 906                 iocp->ioc_error = err;
 907                 mp->b_datap->db_type = M_IOCNAK;
 908         } else {
 909                 iocp->ioc_rval = 0;
 910                 iocp->ioc_error = 0; /* brain rot */
 911                 mp->b_datap->db_type = M_IOCACK;
 912         }
 913 
 914         /* Send the response back up the stream */
 915         putnext(usbkbmd->usbkbm_readq, mp);
 916 
 917         return (KBTRANS_MESSAGE_HANDLED);
 918 
 919 allocfailure:
 920         /*
 921          * We needed to allocate something to handle this "ioctl", but
 922          * couldn't; save this "ioctl" and arrange to get called back when
 923          * it's more likely that we can get what we need.
 924          * If there's already one being saved, throw it out, since it
 925          * must have timed out.
 926          */
 927         freemsg(usbkbmd->usbkbm_streams_iocpending);
 928         usbkbmd->usbkbm_streams_iocpending = mp;
 929 
 930         if (usbkbmd->usbkbm_streams_bufcallid) {
 931 
 932                 qunbufcall(usbkbmd->usbkbm_readq,
 933                     usbkbmd->usbkbm_streams_bufcallid);
 934         }
 935         usbkbmd->usbkbm_streams_bufcallid =
 936             qbufcall(usbkbmd->usbkbm_readq, ioctlrespsize, BPRI_HI,
 937             usbkbm_reioctl, usbkbmd);
 938 
 939         return (KBTRANS_MESSAGE_HANDLED);
 940 }
 941 
 942 /*
 943  * usbkbm_kioccmd :
 944  *      Handles KIOCCMD ioctl.
 945  */
 946 static int
 947 usbkbm_kioccmd(usbkbm_state_t *usbkbmd, register mblk_t *mp,
 948                 char command, size_t *ioctlrepsize)
 949 {
 950         register mblk_t                 *datap;
 951         register struct iocblk          *iocp;
 952         int                             err = 0;
 953 
 954         iocp = (struct iocblk *)mp->b_rptr;
 955 
 956         switch (command) {
 957 
 958                 /* Keyboard layout command */
 959                 case KBD_CMD_GETLAYOUT:
 960                         /* layout learned at attached time. */
 961                         datap = allocb(sizeof (int), BPRI_HI);
 962 
 963                         /* Return error  on allocation failure */
 964                         if (datap == NULL) {
 965                                 *ioctlrepsize = sizeof (int);
 966 
 967                                 return (EIO);
 968                         }
 969 
 970                         *(int *)datap->b_wptr = usbkbmd->usbkbm_layout;
 971                         datap->b_wptr += sizeof (int);
 972                         freemsg(mp->b_cont);
 973                         mp->b_cont = datap;
 974                         iocp->ioc_count = sizeof (int);
 975                         break;
 976 
 977                 case KBD_CMD_SETLED:
 978                         /*
 979                          * Emulate type 4 keyboard :
 980                          * Ignore this ioctl; the following
 981                          * ioctl will specify the data byte for
 982                          * setting the LEDs; setting usbkbm_setled_second_byte
 983                          * will help recognizing that ioctl
 984                          */
 985                         usbkbmd->usbkbm_setled_second_byte = 1;
 986                         break;
 987 
 988                 case KBD_CMD_RESET:
 989                         break;
 990 
 991                 case KBD_CMD_BELL:
 992                         /*
 993                          * USB keyboards do not have a beeper
 994                          * in it, the generic beeper interface
 995                          * is used. Turn the beeper on.
 996                          */
 997                         (void) beeper_on(BEEP_TYPE4);
 998                         break;
 999 
1000                 case KBD_CMD_NOBELL:
1001                         /*
1002                          * USB keyboards do not have a beeper
1003                          * in it, the generic beeper interface
1004                          * is used. Turn the beeper off.
1005                          */
1006                         (void) beeper_off();
1007                         break;
1008 
1009                 case KBD_CMD_CLICK:
1010                         /* FALLTHRU */
1011                 case KBD_CMD_NOCLICK:
1012                         break;
1013 
1014                 default:
1015                         err = EIO;
1016                         break;
1017 
1018         }
1019 
1020         return (err);
1021 }
1022 
1023 
1024 /*
1025  * usbkbm_rput :
1026  *      Put procedure for input from driver end of stream (read queue).
1027  */
1028 static void
1029 usbkbm_rput(register queue_t *q, register mblk_t *mp)
1030 {
1031         usbkbm_state_t          *usbkbmd;
1032 
1033         usbkbmd = (usbkbm_state_t *)q->q_ptr;
1034 
1035         USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1036             "usbkbm_rput");
1037 
1038         if (usbkbmd == 0) {
1039                 freemsg(mp);    /* nobody's listening */
1040 
1041                 return;
1042         }
1043 
1044         switch (mp->b_datap->db_type) {
1045 
1046         case M_FLUSH:
1047                 if (*mp->b_rptr & FLUSHW)
1048                         flushq(WR(q), FLUSHDATA);
1049                 if (*mp->b_rptr & FLUSHR)
1050                         flushq(q, FLUSHDATA);
1051 
1052                 freemsg(mp);
1053 
1054                 return;
1055         case M_BREAK:
1056                 /*
1057                  * Will get M_BREAK only if this is not the system
1058                  * keyboard, otherwise serial port will eat break
1059                  * and call kmdb/OBP, without passing anything up.
1060                  */
1061                 freemsg(mp);
1062 
1063                 return;
1064         case M_DATA:
1065                 if (!(usbkbmd->usbkbm_flags & USBKBM_OPEN)) {
1066                         freemsg(mp);    /* not ready to listen */
1067 
1068                         return;
1069                 }
1070 
1071                 break;
1072         case M_CTL:
1073                 usbkbm_mctl_receive(q, mp);
1074 
1075                 return;
1076         case M_ERROR:
1077                 usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
1078                 if (*mp->b_rptr == ENODEV) {
1079                         putnext(q, mp);
1080                 } else {
1081                         freemsg(mp);
1082                 }
1083 
1084                 return;
1085         case M_IOCACK:
1086         case M_IOCNAK:
1087                 putnext(q, mp);
1088 
1089                 return;
1090         default:
1091                 putnext(q, mp);
1092 
1093                 return;
1094         }
1095 
1096         /*
1097          * A data message, consisting of bytes from the keyboard.
1098          * Ram them through the translator, only if there are
1099          * correct no. of bytes.
1100          */
1101         if (MBLKL(mp) == usbkbmd->usbkbm_report_format.tlen) {
1102                 if (usbkbmd->usbkbm_report_format.keyid !=
1103                     HID_REPORT_ID_UNDEFINED) {
1104                         if (*(mp->b_rptr) !=
1105                             usbkbmd->usbkbm_report_format.keyid) {
1106                                 freemsg(mp);
1107 
1108                                 return;
1109                         } else {
1110                                 /* We skip the report id prefix */
1111                                 mp->b_rptr++;
1112                         }
1113                 }
1114                 usbkbm_unpack_usb_packet(usbkbmd, usbkbm_streams_callback,
1115                     mp->b_rptr);
1116         }
1117 
1118         freemsg(mp);
1119 }
1120 
1121 /*
1122  * usbkbm_mctl_receive :
1123  *      Handle M_CTL messages from hid. If we don't understand
1124  *      the command, send it up.
1125  */
1126 static void
1127 usbkbm_mctl_receive(register queue_t *q, register mblk_t *mp)
1128 {
1129         register usbkbm_state_t *usbkbmd = (usbkbm_state_t *)q->q_ptr;
1130         register struct iocblk *iocp;
1131         caddr_t  data = NULL;
1132         mblk_t  *reply_mp;
1133         uchar_t new_buffer[USBKBM_MAXPKTSIZE];
1134         size_t   size;
1135 
1136         iocp = (struct iocblk *)mp->b_rptr;
1137         if (mp->b_cont != NULL)
1138                 data = (caddr_t)mp->b_cont->b_rptr;
1139 
1140         switch (iocp->ioc_cmd) {
1141 
1142         case HID_SET_REPORT:
1143                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1144                     "usbkbm_mctl_receive HID_SET mctl");
1145                 freemsg(mp);
1146                 /* Setting of the LED is not waiting for this message */
1147 
1148                 break;
1149         case HID_GET_PARSER_HANDLE:
1150                 if ((data != NULL) &&
1151                     (iocp->ioc_count == sizeof (hidparser_handle_t)) &&
1152                     (MBLKL(mp->b_cont) == iocp->ioc_count)) {
1153                         usbkbmd->usbkbm_report_descr =
1154                             *(hidparser_handle_t *)data;
1155                 } else {
1156                         usbkbmd->usbkbm_report_descr = NULL;
1157                 }
1158                 freemsg(mp);
1159                 usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
1160 
1161                 break;
1162         case HID_GET_VID_PID:
1163                 if ((data != NULL) &&
1164                     (iocp->ioc_count == sizeof (hid_vid_pid_t)) &&
1165                     (MBLKL(mp->b_cont) == iocp->ioc_count)) {
1166                         bcopy(data, &usbkbmd->usbkbm_vid_pid, iocp->ioc_count);
1167                 }
1168                 freemsg(mp);
1169                 usbkbmd->usbkbm_flags &= ~USBKBM_QWAIT;
1170 
1171                 break;
1172         case HID_OPEN_POLLED_INPUT:
1173                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1174                     "usbkbm_mctl_receive HID_OPEN_POLLED_INPUT");
1175 
1176                 size = sizeof (hid_polled_input_callback_t);
1177                 reply_mp = usbkbmd->usbkbm_pending_link;
1178                 if ((data != NULL) &&
1179                     (iocp->ioc_count == size) &&
1180                     (MBLKL(mp->b_cont) == size)) {
1181                         /*
1182                          *  Copy the information from hid into the
1183                          * state structure
1184                          */
1185                         bcopy(data, &usbkbmd->usbkbm_hid_callback, size);
1186                         reply_mp->b_datap->db_type = M_IOCACK;
1187 
1188                         /*
1189                          * We are given an appropriate-sized data block,
1190                          * and return a pointer to our structure in it.
1191                          * The structure is saved in the states structure
1192                          */
1193                         *(cons_polledio_t **)reply_mp->b_cont->b_rptr =
1194                             &usbkbmd->usbkbm_polled_info;
1195 
1196                 } else {
1197                         reply_mp->b_datap->db_type = M_IOCNAK;
1198                 }
1199                 freemsg(mp);
1200 
1201                 usbkbmd->usbkbm_pending_link = NULL;
1202 
1203                 putnext(q, reply_mp);
1204 
1205                 break;
1206         case HID_CLOSE_POLLED_INPUT:
1207                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1208                     "usbkbm_mctl_receive HID_CLOSE_POLLED_INPUT");
1209 
1210 
1211                 bzero(&usbkbmd->usbkbm_hid_callback,
1212                     sizeof (hid_polled_input_callback_t));
1213 
1214                 freemsg(mp);
1215 
1216                 reply_mp = usbkbmd->usbkbm_pending_link;
1217 
1218                 iocp = (struct iocblk *)reply_mp->b_rptr;
1219 
1220                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1221                     "usbkbm_mctl_receive reply reply_mp 0x%p cmd 0x%x",
1222                     (void *)reply_mp, iocp->ioc_cmd);
1223 
1224 
1225                 reply_mp->b_datap->db_type = M_IOCACK;
1226 
1227                 usbkbmd->usbkbm_pending_link = NULL;
1228 
1229                 putnext(q, reply_mp);
1230 
1231                 break;
1232         case HID_DISCONNECT_EVENT :
1233         case HID_POWER_OFF:
1234                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1235                     "usbkbm_mctl_receive HID_DISCONNECT_EVENT/HID_POWER_OFF");
1236 
1237                 /* Indicate all keys have been released */
1238                 bzero(new_buffer, USBKBM_MAXPKTSIZE);
1239                 usbkbm_unpack_usb_packet(usbkbmd, usbkbm_streams_callback,
1240                     new_buffer);
1241                 freemsg(mp);
1242 
1243                 break;
1244         case HID_CONNECT_EVENT:
1245         case HID_FULL_POWER :
1246                 USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1247                     "usbkbm_mctl_receive restore LEDs");
1248 
1249                 /* send setled command down to restore LED states */
1250                 usbkbm_streams_setled((struct kbtrans_hardware *)usbkbmd,
1251                     usbkbm_led_state);
1252 
1253                 freemsg(mp);
1254 
1255                 break;
1256         default:
1257                 putnext(q, mp);
1258 
1259                 break;
1260         }
1261 }
1262 
1263 
1264 /*
1265  * usbkbm_streams_setled :
1266  *      Update the keyboard LEDs to match the current keyboard state.
1267  *      Send LED state downstreams to hid driver.
1268  */
1269 static void
1270 usbkbm_streams_setled(struct kbtrans_hardware *kbtrans_hw, int state)
1271 {
1272         struct iocblk   mctlmsg;
1273         mblk_t          *mctl_ptr;
1274         hid_req_t       *LED_report;
1275         usbkbm_state_t  *usbkbmd;
1276         uchar_t         led_id, led_state;
1277 
1278         usbkbm_led_state = (uchar_t)state;
1279 
1280         usbkbmd = (usbkbm_state_t *)kbtrans_hw;
1281 
1282         LED_report = kmem_zalloc(sizeof (hid_req_t), KM_NOSLEEP);
1283         if (LED_report == NULL) {
1284 
1285                 return;
1286         }
1287 
1288         /*
1289          * Send the request to the hid driver to set LED.
1290          */
1291         led_id = usbkbmd->usbkbm_report_format.keyid;
1292         led_state = 0;
1293 
1294         /*
1295          * Set the led state based on the state that is passed in.
1296          */
1297         if (state & LED_NUM_LOCK) {
1298                 led_state |= USB_LED_NUM_LOCK;
1299         }
1300 
1301         if (state & LED_COMPOSE) {
1302                 led_state |= USB_LED_COMPOSE;
1303         }
1304 
1305         if (state & LED_SCROLL_LOCK) {
1306                 led_state |= USB_LED_SCROLL_LOCK;
1307         }
1308 
1309         if (state & LED_CAPS_LOCK) {
1310                 led_state |= USB_LED_CAPS_LOCK;
1311         }
1312 
1313         if (state & LED_KANA) {
1314                 led_state |= USB_LED_KANA;
1315         }
1316 
1317         LED_report->hid_req_version_no = HID_VERSION_V_0;
1318         LED_report->hid_req_wValue = REPORT_TYPE_OUTPUT | led_id;
1319         LED_report->hid_req_wLength = sizeof (uchar_t);
1320         LED_report->hid_req_data[0] = led_state;
1321 
1322         mctlmsg.ioc_cmd = HID_SET_REPORT;
1323         mctlmsg.ioc_count = sizeof (LED_report);
1324         mctl_ptr = usba_mk_mctl(mctlmsg, LED_report, sizeof (hid_req_t));
1325         if (mctl_ptr != NULL) {
1326                 putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
1327         }
1328 
1329         /*
1330          * We are not waiting for response of HID_SET_REPORT
1331          * mctl for setting the LED.
1332          */
1333         kmem_free(LED_report, sizeof (hid_req_t));
1334 }
1335 
1336 
1337 /*
1338  * usbkbm_polled_keycheck :
1339  *      This routine is called to determine if there is a scancode that
1340  *      is available for input.  This routine is called at poll time and
1341  *      returns a key/state pair to the caller.  If there are characters
1342  *      buffered up, the routine returns right away with the key/state pair.
1343  *      Otherwise, the routine calls down to check for characters and returns
1344  *      the first key/state pair if there are any characters pending.
1345  */
1346 static boolean_t
1347 usbkbm_polled_keycheck(struct kbtrans_hardware *hw,
1348         int *key, enum keystate *state)
1349 {
1350         usbkbm_state_t                  *usbkbmd;
1351         uchar_t                         *buffer;
1352         unsigned                        size;
1353         hid_polled_handle_t             hid_polled_handle;
1354 
1355         usbkbmd = (usbkbm_state_t *)hw;
1356 
1357         /*
1358          * If there are already characters buffered up, then we are done.
1359          */
1360         if (usbkbmd->usbkbm_polled_buffer_num_characters != 0) {
1361 
1362                 usbkbm_get_scancode(usbkbmd, key, state);
1363 
1364                 return (B_TRUE);
1365         }
1366 
1367         hid_polled_handle =
1368             usbkbmd->usbkbm_hid_callback.hid_polled_input_handle;
1369 
1370         size = (usbkbmd->usbkbm_hid_callback.hid_polled_read)
1371             (hid_polled_handle, &buffer);
1372 
1373         /*
1374          * If we don't get a valid input report then indicate that,
1375          * and we are done.
1376          */
1377         if (size != usbkbmd->usbkbm_report_format.tlen) {
1378                 return (B_FALSE);
1379         }
1380 
1381         /*
1382          * We have a usb packet, so pass this packet to
1383          * usbkbm_unpack_usb_packet so that it can be broken up into
1384          * individual key/state values.
1385          */
1386         if (usbkbmd->usbkbm_report_format.keyid != HID_REPORT_ID_UNDEFINED) {
1387                 if (*buffer != usbkbmd->usbkbm_report_format.keyid) {
1388                         return (B_FALSE);
1389                 } else {
1390                         /* We skip the report id prefix */
1391                         buffer++;
1392                 }
1393         }
1394         usbkbm_unpack_usb_packet(usbkbmd, usbkbm_poll_callback, buffer);
1395 
1396         /*
1397          * If a scancode was returned as a result of this packet,
1398          * then translate the scancode.
1399          */
1400         if (usbkbmd->usbkbm_polled_buffer_num_characters != 0) {
1401 
1402                 usbkbm_get_scancode(usbkbmd, key, state);
1403 
1404                 return (B_TRUE);
1405         }
1406 
1407         return (B_FALSE);
1408 }
1409 
1410 static ushort_t usbkbm_get_state(usbkbm_state_t *usbkbmd)
1411 {
1412         ushort_t        ret;
1413 
1414         ASSERT(usbkbmd->usbkbm_vkbd_type == KB_PC ||
1415             usbkbmd->usbkbm_vkbd_type == KB_USB);
1416 
1417         if (usbkbmd->usbkbm_vkbd_type == KB_PC)
1418                 ret = INDEXTO_PC;
1419         else
1420                 ret = INDEXTO_USB;
1421 
1422         return (ret);
1423 }
1424 /*
1425  * usbkbm_streams_callback :
1426  *      This is the routine that is going to be called when unpacking
1427  *      usb packets for normal streams-based input.  We pass a pointer
1428  *      to this routine to usbkbm_unpack_usb_packet.  This routine will
1429  *      get called with an unpacked key (scancode) and state (press/release).
1430  *      We pass it to the generic keyboard module.
1431  *
1432  *      'index' and the function pointers:
1433  *      Map USB scancodes to PC scancodes by lookup table.
1434  *      This fix is mainly meant for x86 platforms. For SPARC systems
1435  *      this fix doesn't change the way in which the scancodes are processed.
1436  */
1437 static void
1438 usbkbm_streams_callback(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1439 {
1440         ushort_t index = usbkbm_get_state(usbkbmd);
1441         (*usbkbm_xlate[index])(usbkbmd, key, state);
1442 }
1443 
1444 /*
1445  * Don't do any translations. Send to 'kbtrans' for processing.
1446  */
1447 static void
1448 usbkbm_wrap_kbtrans(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1449 {
1450         kbtrans_streams_key(usbkbmd->usbkbm_kbtrans, key, state);
1451 }
1452 
1453 /*
1454  * Translate USB scancodes to PC scancodes before sending it to 'kbtrans'
1455  */
1456 void
1457 usbkbm_usb2pc_xlate(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1458 {
1459         key = kbtrans_keycode_usb2pc(key);
1460         kbtrans_streams_key(usbkbmd->usbkbm_kbtrans, key, state);
1461 }
1462 
1463 /*
1464  * usbkbm_poll_callback :
1465  *      This is the routine that is going to be called when unpacking
1466  *      usb packets for polled input.  We pass a pointer to this routine
1467  *      to usbkbm_unpack_usb_packet.  This routine will get called with
1468  *      an unpacked key (scancode) and state (press/release).  We will
1469  *      store the key/state pair into a circular buffer so that it can
1470  *      be translated into an ascii key later.
1471  */
1472 static void
1473 usbkbm_poll_callback(usbkbm_state_t *usbkbmd, int key, enum keystate state)
1474 {
1475         /*
1476          * Check to make sure that the buffer isn't already full
1477          */
1478         if (usbkbmd->usbkbm_polled_buffer_num_characters ==
1479             USB_POLLED_BUFFER_SIZE) {
1480 
1481                 /*
1482                  * The buffer is full, we will drop this character.
1483                  */
1484                 return;
1485         }
1486 
1487         /*
1488          * Save the scancode in the buffer
1489          */
1490         usbkbmd->usbkbm_polled_buffer_head->poll_key = key;
1491         usbkbmd->usbkbm_polled_buffer_head->poll_state = state;
1492 
1493         /*
1494          * We have one more character in the buffer
1495          */
1496         usbkbmd->usbkbm_polled_buffer_num_characters++;
1497 
1498         /*
1499          * Increment to the next available slot.
1500          */
1501         usbkbmd->usbkbm_polled_buffer_head++;
1502 
1503         /*
1504          * Check to see if the tail has wrapped.
1505          */
1506         if (usbkbmd->usbkbm_polled_buffer_head -
1507             usbkbmd->usbkbm_polled_scancode_buffer ==
1508             USB_POLLED_BUFFER_SIZE) {
1509 
1510                 usbkbmd->usbkbm_polled_buffer_head =
1511                     usbkbmd->usbkbm_polled_scancode_buffer;
1512         }
1513 }
1514 
1515 /*
1516  * usbkbm_get_scancode :
1517  *      This routine retreives a key/state pair from the circular buffer.
1518  *      The pair was put in the buffer by usbkbm_poll_callback when a
1519  *      USB packet was translated into a key/state by usbkbm_unpack_usb_packet.
1520  */
1521 static void
1522 usbkbm_get_scancode(usbkbm_state_t *usbkbmd, int *key, enum keystate *state)
1523 {
1524         /*
1525          * Copy the character.
1526          */
1527         *key = usbkbmd->usbkbm_polled_buffer_tail->poll_key;
1528         *state = usbkbmd->usbkbm_polled_buffer_tail->poll_state;
1529 
1530         /*
1531          * Increment to the next character to be copied from
1532          * and to.
1533          */
1534         usbkbmd->usbkbm_polled_buffer_tail++;
1535 
1536         /*
1537          * Check to see if the tail has wrapped.
1538          */
1539         if (usbkbmd->usbkbm_polled_buffer_tail -
1540             usbkbmd->usbkbm_polled_scancode_buffer ==
1541             USB_POLLED_BUFFER_SIZE) {
1542 
1543                 usbkbmd->usbkbm_polled_buffer_tail =
1544                     usbkbmd->usbkbm_polled_scancode_buffer;
1545         }
1546 
1547         /*
1548          * We have one less character in the buffer.
1549          */
1550         usbkbmd->usbkbm_polled_buffer_num_characters--;
1551 }
1552 
1553 /*
1554  * usbkbm_polled_setled :
1555  *      This routine is a place holder.  Someday, we may want to allow led
1556  *      state to be updated from within polled mode.
1557  */
1558 /* ARGSUSED */
1559 static void
1560 usbkbm_polled_setled(struct kbtrans_hardware *hw, int led_state)
1561 {
1562         /* nothing to do for now */
1563 }
1564 
1565 /*
1566  * This is a pass-thru routine to get a character at poll time.
1567  */
1568 static int
1569 usbkbm_polled_getchar(cons_polledio_arg_t arg)
1570 {
1571         usbkbm_state_t                  *usbkbmd;
1572 
1573         usbkbmd = (usbkbm_state_t *)arg;
1574 
1575         return (kbtrans_getchar(usbkbmd->usbkbm_kbtrans));
1576 }
1577 
1578 /*
1579  * This is a pass-thru routine to test if character is available for reading
1580  * at poll time.
1581  */
1582 static boolean_t
1583 usbkbm_polled_ischar(cons_polledio_arg_t arg)
1584 {
1585         usbkbm_state_t                  *usbkbmd;
1586 
1587         usbkbmd = (usbkbm_state_t *)arg;
1588 
1589         return (kbtrans_ischar(usbkbmd->usbkbm_kbtrans));
1590 }
1591 
1592 /*
1593  * usbkbm_polled_input_enter :
1594  *      This is a pass-thru initialization routine for the lower layer drivers.
1595  *      This routine is called at poll time to set the state for polled input.
1596  */
1597 static void
1598 usbkbm_polled_enter(cons_polledio_arg_t arg)
1599 {
1600         usbkbm_state_t          *usbkbmd = (usbkbm_state_t *)arg;
1601         hid_polled_handle_t     hid_polled_handle;
1602         int                     kbstart, kbend, uindex;
1603 
1604         kbstart = usbkbmd->usbkbm_report_format.kpos;
1605         kbend = kbstart + usbkbmd->usbkbm_report_format.klen;
1606 
1607         /*
1608          * Before switching to POLLED mode, copy the contents of
1609          * usbkbm_pendingusbpacket to usbkbm_lastusbpacket since
1610          * usbkbm_pendingusbpacket field has currently processed
1611          * key events of the current OS mode usb keyboard packet.
1612          */
1613         for (uindex = kbstart + 2; uindex < kbend; uindex++) {
1614                 usbkbmd->usbkbm_lastusbpacket[uindex] =
1615                     usbkbmd->usbkbm_pendingusbpacket[uindex];
1616 
1617                 usbkbmd->usbkbm_pendingusbpacket[uindex] = 0;
1618         }
1619 
1620         hid_polled_handle =
1621             usbkbmd->usbkbm_hid_callback.hid_polled_input_handle;
1622 
1623         (void) (usbkbmd->usbkbm_hid_callback.hid_polled_input_enter)
1624             (hid_polled_handle);
1625 }
1626 
1627 /*
1628  * usbkbm_polled_input_exit :
1629  *      This is a pass-thru restoration routine for the lower layer drivers.
1630  *      This routine is called at poll time to reset the state back to streams
1631  *      input.
1632  */
1633 static void
1634 usbkbm_polled_exit(cons_polledio_arg_t arg)
1635 {
1636         usbkbm_state_t          *usbkbmd = (usbkbm_state_t *)arg;
1637         hid_polled_handle_t     hid_polled_handle;
1638         int                     kbstart, kbend, uindex;
1639 
1640         kbstart = usbkbmd->usbkbm_report_format.kpos;
1641         kbend = kbstart + usbkbmd->usbkbm_report_format.klen;
1642 
1643         /*
1644          * Before returning to OS mode, copy the contents of
1645          * usbkbm_lastusbpacket to usbkbm_pendingusbpacket since
1646          * usbkbm_lastusbpacket field has processed key events
1647          * of the last POLLED mode usb keyboard packet.
1648          */
1649         for (uindex = kbstart + 2; uindex < kbend; uindex ++) {
1650                 usbkbmd->usbkbm_pendingusbpacket[uindex] =
1651                     usbkbmd->usbkbm_lastusbpacket[uindex];
1652 
1653                 usbkbmd->usbkbm_lastusbpacket[uindex] = 0;
1654         }
1655 
1656         hid_polled_handle =
1657             usbkbmd->usbkbm_hid_callback.hid_polled_input_handle;
1658 
1659         (void) (usbkbmd->usbkbm_hid_callback.hid_polled_input_exit)
1660             (hid_polled_handle);
1661 }
1662 
1663 /*
1664  * usbkbm_unpack_usb_packet :
1665  *      USB key packets contain 8 bytes while in boot-protocol mode.
1666  *      The first byte contains bit packed modifier key information.
1667  *      Second byte is reserved. The last 6 bytes contain bytes of
1668  *      currently pressed keys. If a key was not recorded on the
1669  *      previous packet, but present in the current packet, then set
1670  *      state to KEY_PRESSED. If a key was recorded in the previous packet,
1671  *      but not present in the current packet, then state to KEY_RELEASED
1672  *      Follow a similar algorithm for bit packed modifier keys.
1673  */
1674 static void
1675 usbkbm_unpack_usb_packet(usbkbm_state_t *usbkbmd, process_key_callback_t func,
1676         uchar_t *usbpacket)
1677 {
1678         uchar_t         mkb;
1679         uchar_t         lastmkb;
1680         uchar_t         *lastusbpacket = usbkbmd->usbkbm_lastusbpacket;
1681         int             packet_size, kbstart, kbend;
1682         int             uindex, lindex, rollover;
1683 
1684         packet_size = usbkbmd->usbkbm_report_format.tlen;
1685         kbstart = usbkbmd->usbkbm_report_format.kpos;
1686         kbend = kbstart + usbkbmd->usbkbm_report_format.klen;
1687         mkb = usbpacket[kbstart];
1688         lastmkb = lastusbpacket[kbstart];
1689 
1690         for (uindex = 0; uindex < packet_size; uindex++) {
1691 
1692                 USB_DPRINTF_L3(PRINT_MASK_PACKET, usbkbm_log_handle,
1693                     " %x ", usbpacket[uindex]);
1694         }
1695 
1696         USB_DPRINTF_L3(PRINT_MASK_PACKET, usbkbm_log_handle,
1697             " is the usbkeypacket");
1698 
1699         /* check to see if modifier keys are different */
1700         if (mkb != lastmkb) {
1701 
1702                 if ((mkb & USB_LSHIFTBIT) != (lastmkb & USB_LSHIFTBIT)) {
1703                         (*func)(usbkbmd, USB_LSHIFTKEY, (mkb&USB_LSHIFTBIT) ?
1704                             KEY_PRESSED : KEY_RELEASED);
1705                         USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1706                             "unpack: sending USB_LSHIFTKEY");
1707                 }
1708 
1709                 if ((mkb & USB_LCTLBIT) != (lastmkb & USB_LCTLBIT)) {
1710                         (*func)(usbkbmd, USB_LCTLCKEY, mkb&USB_LCTLBIT ?
1711                             KEY_PRESSED : KEY_RELEASED);
1712                 }
1713 
1714                 if ((mkb & USB_LALTBIT) != (lastmkb & USB_LALTBIT)) {
1715                         (*func)(usbkbmd, USB_LALTKEY, mkb&USB_LALTBIT ?
1716                             KEY_PRESSED : KEY_RELEASED);
1717                 }
1718 
1719                 if ((mkb & USB_LMETABIT) != (lastmkb & USB_LMETABIT)) {
1720                         (*func)(usbkbmd, USB_LMETAKEY, mkb&USB_LMETABIT ?
1721                             KEY_PRESSED : KEY_RELEASED);
1722                 }
1723 
1724                 if ((mkb & USB_RMETABIT) != (lastmkb & USB_RMETABIT)) {
1725                         (*func)(usbkbmd, USB_RMETAKEY, mkb&USB_RMETABIT ?
1726                             KEY_PRESSED : KEY_RELEASED);
1727                 }
1728 
1729                 if ((mkb & USB_RALTBIT) != (lastmkb & USB_RALTBIT)) {
1730                         (*func)(usbkbmd, USB_RALTKEY, mkb&USB_RALTBIT ?
1731                             KEY_PRESSED : KEY_RELEASED);
1732                 }
1733 
1734                 if ((mkb & USB_RCTLBIT) != (lastmkb & USB_RCTLBIT)) {
1735                         (*func)(usbkbmd, USB_RCTLCKEY, mkb&USB_RCTLBIT ?
1736                             KEY_PRESSED : KEY_RELEASED);
1737                 }
1738 
1739                 if ((mkb & USB_RSHIFTBIT) != (lastmkb & USB_RSHIFTBIT)) {
1740                         (*func)(usbkbmd, USB_RSHIFTKEY, mkb&USB_RSHIFTBIT ?
1741                             KEY_PRESSED : KEY_RELEASED);
1742                         USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1743                             "unpack: sending USB_RSHIFTKEY");
1744                 }
1745         }
1746 
1747         /* save modifier bits */
1748         lastusbpacket[kbstart] = usbpacket[kbstart];
1749 
1750         /* Check Keyboard rollover error. */
1751         if (usbpacket[kbstart + 2] == USB_ERRORROLLOVER) {
1752                 rollover = 1;
1753                 for (uindex = kbstart + 3; uindex < kbend;
1754                     uindex++) {
1755                         if (usbpacket[uindex] != USB_ERRORROLLOVER) {
1756                                 rollover = 0;
1757                                 break;
1758                         }
1759                 }
1760                 if (rollover) {
1761                         USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
1762                             "unpack: errorrollover");
1763                         return;
1764                 }
1765         }
1766 
1767         /* check for released keys */
1768         for (lindex = kbstart + 2; lindex < kbend; lindex++) {
1769                 int released = 1;
1770 
1771                 if (lastusbpacket[lindex] == 0) {
1772                         continue;
1773                 }
1774                 for (uindex = kbstart + 2; uindex < kbend; uindex++)
1775                         if (usbpacket[uindex] == lastusbpacket[lindex]) {
1776                                 released = 0;
1777                                 break;
1778                         }
1779                 if (released) {
1780                         (*func)(usbkbmd, lastusbpacket[lindex], KEY_RELEASED);
1781                 }
1782         }
1783 
1784         /* check for new presses */
1785         for (uindex = kbstart + 2; uindex < kbend; uindex++) {
1786                 int newkey = 1;
1787 
1788                 usbkbmd->usbkbm_pendingusbpacket[uindex] = usbpacket[uindex];
1789 
1790                 if (usbpacket[uindex] == 0) {
1791                         continue;
1792                 }
1793 
1794                 for (lindex = kbstart + 2; lindex < kbend; lindex++) {
1795                         if (usbpacket[uindex] == lastusbpacket[lindex]) {
1796                                 newkey = 0;
1797                                 break;
1798                         }
1799                 }
1800 
1801                 if (newkey) {
1802                         /*
1803                          * Modifier keys can be present as part of both the
1804                          * first byte and as separate key bytes. In the sec-
1805                          * ond case ignore it.
1806                          */
1807 
1808                         if (!usbkbm_is_modkey(usbpacket[uindex])) {
1809                                 (*func)(usbkbmd, usbpacket[uindex],
1810                                     KEY_PRESSED);
1811                         } else {
1812                                 usbkbmd->usbkbm_pendingusbpacket[uindex] = 0;
1813 
1814                                 continue;
1815                         }
1816                 }
1817         }
1818 
1819         /*
1820          * Copy the processed key events of the current usb keyboard
1821          * packet, which is saved in the usbkbm_pendingusbpacket field
1822          * to the usbkbm_lastusbpacket field.
1823          */
1824         for (uindex = kbstart + 2; uindex < kbend; uindex++) {
1825                 lastusbpacket[uindex] =
1826                     usbkbmd->usbkbm_pendingusbpacket[uindex];
1827                 usbkbmd->usbkbm_pendingusbpacket[uindex] = 0;
1828         }
1829 }
1830 
1831 static boolean_t
1832 usbkbm_is_modkey(uchar_t key)
1833 {
1834 
1835         switch (key) {
1836 
1837         case USB_LSHIFTKEY:
1838         case USB_LCTLCKEY:
1839         case USB_LALTKEY:
1840         case USB_LMETAKEY:
1841         case USB_RCTLCKEY:
1842         case USB_RSHIFTKEY:
1843         case USB_RMETAKEY:
1844         case USB_RALTKEY:
1845 
1846                 return (B_TRUE);
1847 
1848         default:
1849 
1850                 break;
1851         }
1852 
1853         return (B_FALSE);
1854 }
1855 
1856 /*
1857  * usbkbm_reioctl :
1858  *      This function is set up as call-back function should an ioctl fail.
1859  *      It retries the ioctl
1860  */
1861 static void
1862 usbkbm_reioctl(void     *arg)
1863 {
1864         usbkbm_state_t  *usbkbmd;
1865         mblk_t *mp;
1866 
1867         usbkbmd = (usbkbm_state_t *)arg;
1868 
1869         usbkbmd->usbkbm_streams_bufcallid = 0;
1870 
1871         if ((mp = usbkbmd->usbkbm_streams_iocpending) != NULL) {
1872 
1873                 /* not pending any more */
1874                 usbkbmd->usbkbm_streams_iocpending = NULL;
1875 
1876                 (void) usbkbm_ioctl(usbkbmd->usbkbm_writeq, mp);
1877         }
1878 }
1879 
1880 /*
1881  * usbkbm_get_vid_pid
1882  *      Issue a M_CTL to hid to get the device info
1883  */
1884 static int
1885 usbkbm_get_vid_pid(usbkbm_state_t *usbkbmd)
1886 {
1887         struct iocblk mctlmsg;
1888         mblk_t *mctl_ptr;
1889         queue_t *q = usbkbmd->usbkbm_readq;
1890 
1891         mctlmsg.ioc_cmd = HID_GET_VID_PID;
1892         mctlmsg.ioc_count = 0;
1893 
1894         mctl_ptr = usba_mk_mctl(mctlmsg, NULL, 0);
1895         if (mctl_ptr == NULL) {
1896                 (void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
1897                 qprocsoff(q);
1898                 kmem_free(usbkbmd, sizeof (usbkbm_state_t));
1899 
1900                 return (ENOMEM);
1901         }
1902 
1903         putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
1904         usbkbmd->usbkbm_flags |= USBKBM_QWAIT;
1905         while (usbkbmd->usbkbm_flags & USBKBM_QWAIT) {
1906                 if (qwait_sig(q) == 0) {
1907                         usbkbmd->usbkbm_flags = 0;
1908                         (void) kbtrans_streams_fini(usbkbmd->usbkbm_kbtrans);
1909                         qprocsoff(q);
1910                         kmem_free(usbkbmd, sizeof (usbkbm_state_t));
1911 
1912                         return (EINTR);
1913                 }
1914         }
1915 
1916         return (0);
1917 }
1918 
1919 /*
1920  * usbkbm_get_input_format() :
1921  *     Get the input report format of keyboard
1922  */
1923 static int
1924 usbkbm_get_input_format(usbkbm_state_t *usbkbmd)
1925 {
1926 
1927         hidparser_rpt_t *kb_rpt;
1928         uint_t i, kbd_page = 0, kpos = 0, klen = 0, limit = 0;
1929         uint32_t rptcnt, rptsz;
1930         usbkbm_report_format_t *kbd_fmt = &usbkbmd->usbkbm_report_format;
1931         int rptid, rval;
1932 
1933         /* Setup default input report format */
1934         kbd_fmt->keyid = HID_REPORT_ID_UNDEFINED;
1935         kbd_fmt->tlen = USB_KBD_BOOT_PROTOCOL_PACKET_SIZE;
1936         kbd_fmt->klen = kbd_fmt->tlen;
1937         kbd_fmt->kpos = 0;
1938 
1939         if (usbkbmd->usbkbm_report_descr == NULL) {
1940                 return (USB_FAILURE);
1941         }
1942 
1943         /* Get keyboard layout */
1944         if (hidparser_get_country_code(usbkbmd->usbkbm_report_descr,
1945             (uint16_t *)&usbkbmd->usbkbm_layout) == HIDPARSER_FAILURE) {
1946 
1947                 USB_DPRINTF_L3(PRINT_MASK_OPEN,
1948                     usbkbm_log_handle, "get_country_code failed"
1949                     "setting default layout(0)");
1950 
1951                 usbkbmd->usbkbm_layout = usbkbm_layout;
1952         }
1953 
1954         /* Get the id of the report which contains keyboard data */
1955         if (hidparser_get_usage_attribute(
1956             usbkbmd->usbkbm_report_descr,
1957             0, /* Doesn't matter */
1958             HIDPARSER_ITEM_INPUT,
1959             HID_KEYBOARD_KEYPAD_KEYS,
1960             0,
1961             HIDPARSER_ITEM_REPORT_ID,
1962             &rptid) == HIDPARSER_NOT_FOUND) {
1963 
1964                 return (USB_SUCCESS);
1965         }
1966 
1967         /* Allocate hidparser report structure */
1968         kb_rpt = kmem_zalloc(sizeof (hidparser_rpt_t), KM_SLEEP);
1969 
1970         /*
1971          * Check what is the total length of the keyboard packet
1972          * and get the usages and their lengths in order
1973          */
1974         rval = hidparser_get_usage_list_in_order(
1975             usbkbmd->usbkbm_report_descr,
1976             rptid,
1977             HIDPARSER_ITEM_INPUT,
1978             kb_rpt);
1979         if (rval != HIDPARSER_SUCCESS) {
1980 
1981                 USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
1982                     "get_usage_list_in_order failed");
1983                 kmem_free(kb_rpt, sizeof (hidparser_rpt_t));
1984                 return (USB_FAILURE);
1985         }
1986 
1987         for (i = 0; i < kb_rpt->no_of_usages; i++) {
1988                 rptcnt = kb_rpt->usage_descr[i].rptcnt;
1989                 rptsz = kb_rpt->usage_descr[i].rptsz;
1990 
1991                 switch (kb_rpt->usage_descr[i].usage_page) {
1992                 case HID_KEYBOARD_KEYPAD_KEYS:
1993                         if (!kbd_page) {
1994                                 kpos = limit;
1995                                 kbd_page = 1;
1996                         }
1997                         klen += rptcnt * rptsz;
1998                         /*FALLTHRU*/
1999                 default:
2000                         limit += rptcnt * rptsz;
2001                         break;
2002                 }
2003         }
2004 
2005         kmem_free(kb_rpt, sizeof (hidparser_rpt_t));
2006 
2007         /* Invalid input report format */
2008         if (!kbd_page || limit > USBKBM_MAXPKTSIZE * 8 ||
2009             kpos + klen > limit || (kpos % 8 != 0)) {
2010 
2011                 USB_DPRINTF_L3(PRINT_MASK_OPEN, usbkbm_log_handle,
2012                     "Invalid input report format: kbd_page (%d), limit (%d), "
2013                     "kpos (%d), klen (%d)", kbd_page, limit, kpos, klen);
2014                 return (USB_FAILURE);
2015         }
2016 
2017         /* Set report format */
2018         kbd_fmt->keyid = (uint8_t)rptid;
2019         kbd_fmt->tlen = limit / 8 + 1;
2020         kbd_fmt->klen = klen / 8;
2021         kbd_fmt->kpos = kpos / 8;
2022 
2023         return (USB_SUCCESS);
2024 }