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