1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate /* 31*0Sstevel@tonic-gate * VUIDMICE module: put mouse events into vuid format 32*0Sstevel@tonic-gate */ 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate #include <sys/param.h> 35*0Sstevel@tonic-gate #include <sys/stream.h> 36*0Sstevel@tonic-gate #include <sys/stropts.h> 37*0Sstevel@tonic-gate #include <sys/strsun.h> 38*0Sstevel@tonic-gate #include <sys/errno.h> 39*0Sstevel@tonic-gate #include <sys/debug.h> 40*0Sstevel@tonic-gate #include <sys/cmn_err.h> 41*0Sstevel@tonic-gate #include <sys/sad.h> 42*0Sstevel@tonic-gate #include <sys/vuid_event.h> 43*0Sstevel@tonic-gate #include <sys/vuidmice.h> 44*0Sstevel@tonic-gate #include <sys/vuid_wheel.h> 45*0Sstevel@tonic-gate #include <sys/msio.h> 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate #include <sys/conf.h> 48*0Sstevel@tonic-gate #include <sys/modctl.h> 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate #include <sys/kmem.h> 51*0Sstevel@tonic-gate #include <sys/ddi.h> 52*0Sstevel@tonic-gate #include <sys/sunddi.h> 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate static int vuidmice_open(queue_t *const, const dev_t *const, 55*0Sstevel@tonic-gate const int, const int, const cred_t *const); 56*0Sstevel@tonic-gate static int vuidmice_close(queue_t *const, const int, const cred_t *const); 57*0Sstevel@tonic-gate static int vuidmice_rput(queue_t *const, mblk_t *); 58*0Sstevel@tonic-gate static int vuidmice_rsrv(queue_t *const); 59*0Sstevel@tonic-gate static int vuidmice_wput(queue_t *const, mblk_t *); 60*0Sstevel@tonic-gate static void vuidmice_miocdata(queue_t *const, mblk_t *); 61*0Sstevel@tonic-gate static int vuidmice_handle_wheel_resolution_ioctl(queue_t *const, 62*0Sstevel@tonic-gate mblk_t *, int); 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate static int vuidmice_service_wheel_info(mblk_t *); 65*0Sstevel@tonic-gate static int vuidmice_service_wheel_state(queue_t *, mblk_t *, uint_t); 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate void VUID_QUEUE(queue_t *const, mblk_t *); 68*0Sstevel@tonic-gate int VUID_OPEN(queue_t *const); 69*0Sstevel@tonic-gate void VUID_CLOSE(queue_t *const); 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate static kmutex_t vuidmice_lock; 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate static struct module_info vuidmice_iinfo = { 74*0Sstevel@tonic-gate 0, 75*0Sstevel@tonic-gate VUID_NAME, 76*0Sstevel@tonic-gate 0, 77*0Sstevel@tonic-gate INFPSZ, 78*0Sstevel@tonic-gate 1000, 79*0Sstevel@tonic-gate 100 80*0Sstevel@tonic-gate }; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate static struct qinit vuidmice_rinit = { 83*0Sstevel@tonic-gate vuidmice_rput, 84*0Sstevel@tonic-gate vuidmice_rsrv, 85*0Sstevel@tonic-gate vuidmice_open, 86*0Sstevel@tonic-gate vuidmice_close, 87*0Sstevel@tonic-gate NULL, 88*0Sstevel@tonic-gate &vuidmice_iinfo, 89*0Sstevel@tonic-gate NULL 90*0Sstevel@tonic-gate }; 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate static struct module_info vuidmice_oinfo = { 93*0Sstevel@tonic-gate 0, 94*0Sstevel@tonic-gate VUID_NAME, 95*0Sstevel@tonic-gate 0, 96*0Sstevel@tonic-gate INFPSZ, 97*0Sstevel@tonic-gate 1000, 98*0Sstevel@tonic-gate 100 99*0Sstevel@tonic-gate }; 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate static struct qinit vuidmice_winit = { 102*0Sstevel@tonic-gate vuidmice_wput, 103*0Sstevel@tonic-gate NULL, 104*0Sstevel@tonic-gate NULL, 105*0Sstevel@tonic-gate NULL, 106*0Sstevel@tonic-gate NULL, 107*0Sstevel@tonic-gate &vuidmice_oinfo, 108*0Sstevel@tonic-gate NULL 109*0Sstevel@tonic-gate }; 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate struct streamtab vuidmice_info = { 112*0Sstevel@tonic-gate &vuidmice_rinit, 113*0Sstevel@tonic-gate &vuidmice_winit, 114*0Sstevel@tonic-gate NULL, 115*0Sstevel@tonic-gate NULL 116*0Sstevel@tonic-gate }; 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate /* 119*0Sstevel@tonic-gate * This is the loadable module wrapper. 120*0Sstevel@tonic-gate */ 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate /* 123*0Sstevel@tonic-gate * D_MTQPAIR effectively makes the module single threaded. 124*0Sstevel@tonic-gate * There can be only one thread active in the module at any time. 125*0Sstevel@tonic-gate * It may be a read or write thread. 126*0Sstevel@tonic-gate */ 127*0Sstevel@tonic-gate #define VUIDMICE_CONF_FLAG (D_MP | D_MTQPAIR) 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate static struct fmodsw fsw = { 130*0Sstevel@tonic-gate VUID_NAME, 131*0Sstevel@tonic-gate &vuidmice_info, 132*0Sstevel@tonic-gate VUIDMICE_CONF_FLAG 133*0Sstevel@tonic-gate }; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate static struct modlstrmod modlstrmod = { 136*0Sstevel@tonic-gate &mod_strmodops, 137*0Sstevel@tonic-gate "mouse events to vuid events", 138*0Sstevel@tonic-gate &fsw 139*0Sstevel@tonic-gate }; 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate /* 142*0Sstevel@tonic-gate * Module linkage information for the kernel. 143*0Sstevel@tonic-gate */ 144*0Sstevel@tonic-gate static struct modlinkage modlinkage = { 145*0Sstevel@tonic-gate MODREV_1, 146*0Sstevel@tonic-gate &modlstrmod, 147*0Sstevel@tonic-gate NULL 148*0Sstevel@tonic-gate }; 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate static int module_open = 0; /* allow only one open of this module */ 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate int 153*0Sstevel@tonic-gate _init(void) 154*0Sstevel@tonic-gate { 155*0Sstevel@tonic-gate register int rc; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate mutex_init(&vuidmice_lock, NULL, MUTEX_DEFAULT, NULL); 158*0Sstevel@tonic-gate if ((rc = mod_install(&modlinkage)) != 0) { 159*0Sstevel@tonic-gate mutex_destroy(&vuidmice_lock); 160*0Sstevel@tonic-gate } 161*0Sstevel@tonic-gate return (rc); 162*0Sstevel@tonic-gate } 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate int 165*0Sstevel@tonic-gate _fini(void) 166*0Sstevel@tonic-gate { 167*0Sstevel@tonic-gate register int rc; 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate if ((rc = mod_remove(&modlinkage)) == 0) 170*0Sstevel@tonic-gate mutex_destroy(&vuidmice_lock); 171*0Sstevel@tonic-gate return (rc); 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate int 175*0Sstevel@tonic-gate _info(struct modinfo *modinfop) 176*0Sstevel@tonic-gate { 177*0Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate /* ARGSUSED1 */ 182*0Sstevel@tonic-gate static int 183*0Sstevel@tonic-gate vuidmice_open(queue_t *const qp, const dev_t *const devp, 184*0Sstevel@tonic-gate const int oflag, const int sflag, const cred_t *const crp) 185*0Sstevel@tonic-gate { 186*0Sstevel@tonic-gate mutex_enter(&vuidmice_lock); 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate /* Allow only 1 open of this module */ 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate if (module_open) { 191*0Sstevel@tonic-gate mutex_exit(&vuidmice_lock); 192*0Sstevel@tonic-gate return (EBUSY); 193*0Sstevel@tonic-gate } 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate module_open++; 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate /* 198*0Sstevel@tonic-gate * If q_ptr already set, we've allocated a struct already 199*0Sstevel@tonic-gate */ 200*0Sstevel@tonic-gate if (qp->q_ptr != NULL) { 201*0Sstevel@tonic-gate module_open--; 202*0Sstevel@tonic-gate mutex_exit(&vuidmice_lock); 203*0Sstevel@tonic-gate return (0); /* not failure -- just simultaneous open */ 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate /* 207*0Sstevel@tonic-gate * Both the read and write queues share the same state structures. 208*0Sstevel@tonic-gate */ 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate qp->q_ptr = kmem_zalloc(sizeof (struct MouseStateInfo), KM_SLEEP); 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate WR(qp)->q_ptr = qp->q_ptr; 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate /* initialize state */ 215*0Sstevel@tonic-gate STATEP->format = VUID_NATIVE; 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gate mutex_exit(&vuidmice_lock); 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate qprocson(qp); 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate #ifdef VUID_OPEN 222*0Sstevel@tonic-gate if (VUID_OPEN(qp) != 0) { 223*0Sstevel@tonic-gate qprocsoff(qp); 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate mutex_enter(&vuidmice_lock); 226*0Sstevel@tonic-gate module_open--; 227*0Sstevel@tonic-gate kmem_free(qp->q_ptr, sizeof (struct MouseStateInfo)); 228*0Sstevel@tonic-gate qp->q_ptr = NULL; 229*0Sstevel@tonic-gate mutex_exit(&vuidmice_lock); 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate return (ENXIO); 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate #endif 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate return (0); 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate /* ARGSUSED1 */ 239*0Sstevel@tonic-gate static int 240*0Sstevel@tonic-gate vuidmice_close(queue_t *const qp, const int flag, const cred_t *const crp) 241*0Sstevel@tonic-gate { 242*0Sstevel@tonic-gate ASSERT(qp != NULL); 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate qprocsoff(qp); 245*0Sstevel@tonic-gate flushq(qp, FLUSHALL); 246*0Sstevel@tonic-gate flushq(OTHERQ(qp), FLUSHALL); 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate mutex_enter(&vuidmice_lock); 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate #ifdef VUID_CLOSE 251*0Sstevel@tonic-gate VUID_CLOSE(qp); 252*0Sstevel@tonic-gate #endif 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate module_open--; 255*0Sstevel@tonic-gate kmem_free(qp->q_ptr, sizeof (struct MouseStateInfo)); 256*0Sstevel@tonic-gate qp->q_ptr = NULL; /* Dump the associated state structure */ 257*0Sstevel@tonic-gate mutex_exit(&vuidmice_lock); 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate return (0); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate /* 263*0Sstevel@tonic-gate * Put procedure for input from driver end of stream (read queue). 264*0Sstevel@tonic-gate */ 265*0Sstevel@tonic-gate static int 266*0Sstevel@tonic-gate vuidmice_rput(queue_t *const qp, mblk_t *mp) 267*0Sstevel@tonic-gate { 268*0Sstevel@tonic-gate ASSERT(qp != NULL); 269*0Sstevel@tonic-gate ASSERT(mp != NULL); 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate /* 272*0Sstevel@tonic-gate * Handle all the related high priority messages here, hence 273*0Sstevel@tonic-gate * should spend the least amount of time here. 274*0Sstevel@tonic-gate */ 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate if (DB_TYPE(mp) == M_DATA) { 277*0Sstevel@tonic-gate if ((int)STATEP->format == VUID_FIRM_EVENT) 278*0Sstevel@tonic-gate return (putq(qp, mp)); /* queue message & return */ 279*0Sstevel@tonic-gate } else if (DB_TYPE(mp) == M_FLUSH) { 280*0Sstevel@tonic-gate if (*mp->b_rptr & FLUSHR) 281*0Sstevel@tonic-gate flushq(qp, FLUSHALL); 282*0Sstevel@tonic-gate } 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate putnext(qp, mp); /* pass it on */ 285*0Sstevel@tonic-gate return (0); 286*0Sstevel@tonic-gate } 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate static int 289*0Sstevel@tonic-gate vuidmice_rsrv(queue_t *const qp) 290*0Sstevel@tonic-gate { 291*0Sstevel@tonic-gate register mblk_t *mp; 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gate ASSERT(qp != NULL); 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate while ((mp = getq(qp)) != NULL) { 296*0Sstevel@tonic-gate ASSERT(DB_TYPE(mp) == M_DATA); 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate if (!canputnext(qp)) 299*0Sstevel@tonic-gate return (putbq(qp, mp)); /* read side is blocked */ 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate switch (DB_TYPE(mp)) { 302*0Sstevel@tonic-gate case M_DATA: { 303*0Sstevel@tonic-gate if ((int)STATEP->format == VUID_FIRM_EVENT) 304*0Sstevel@tonic-gate (void) VUID_QUEUE(qp, mp); 305*0Sstevel@tonic-gate else 306*0Sstevel@tonic-gate (void) putnext(qp, mp); 307*0Sstevel@tonic-gate break; 308*0Sstevel@tonic-gate } 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate default: 311*0Sstevel@tonic-gate cmn_err(CE_WARN, 312*0Sstevel@tonic-gate "vuidmice_rsrv: bad message type (0x%x)\n", 313*0Sstevel@tonic-gate DB_TYPE(mp)); 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate (void) putnext(qp, mp); 316*0Sstevel@tonic-gate break; 317*0Sstevel@tonic-gate } 318*0Sstevel@tonic-gate } 319*0Sstevel@tonic-gate return (0); 320*0Sstevel@tonic-gate } 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate /* 323*0Sstevel@tonic-gate * Put procedure for write from user end of stream (write queue). 324*0Sstevel@tonic-gate */ 325*0Sstevel@tonic-gate static int 326*0Sstevel@tonic-gate vuidmice_wput(queue_t *const qp, mblk_t *mp) 327*0Sstevel@tonic-gate { 328*0Sstevel@tonic-gate int error = 0; 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate ASSERT(qp != NULL); 331*0Sstevel@tonic-gate ASSERT(mp != NULL); 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate /* 334*0Sstevel@tonic-gate * Handle all the related high priority messages here, hence 335*0Sstevel@tonic-gate * should spend the least amount of time here. 336*0Sstevel@tonic-gate */ 337*0Sstevel@tonic-gate switch (DB_TYPE(mp)) { /* handle hi pri messages here */ 338*0Sstevel@tonic-gate case M_FLUSH: 339*0Sstevel@tonic-gate if (*mp->b_rptr & FLUSHW) 340*0Sstevel@tonic-gate flushq(qp, FLUSHALL); 341*0Sstevel@tonic-gate putnext(qp, mp); /* pass it on */ 342*0Sstevel@tonic-gate return (0); 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate case M_IOCTL: { 345*0Sstevel@tonic-gate struct iocblk *iocbp = (struct iocblk *)mp->b_rptr; 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate switch (iocbp->ioc_cmd) { 348*0Sstevel@tonic-gate case VUIDSFORMAT: 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate /* 351*0Sstevel@tonic-gate * VUIDSFORMAT is known to the stream head and thus 352*0Sstevel@tonic-gate * is guaranteed to be an I_STR ioctl. 353*0Sstevel@tonic-gate */ 354*0Sstevel@tonic-gate if (iocbp->ioc_count == TRANSPARENT) { 355*0Sstevel@tonic-gate miocnak(qp, mp, 0, EINVAL); 356*0Sstevel@tonic-gate return (0); 357*0Sstevel@tonic-gate } else { 358*0Sstevel@tonic-gate int format_type; 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate error = miocpullup(mp, sizeof (int)); 361*0Sstevel@tonic-gate if (error != 0) { 362*0Sstevel@tonic-gate miocnak(qp, mp, 0, error); 363*0Sstevel@tonic-gate return (0); 364*0Sstevel@tonic-gate } 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate format_type = *(int *)mp->b_cont->b_rptr; 367*0Sstevel@tonic-gate STATEP->format = (uchar_t)format_type; 368*0Sstevel@tonic-gate iocbp->ioc_rval = 0; 369*0Sstevel@tonic-gate iocbp->ioc_count = 0; 370*0Sstevel@tonic-gate iocbp->ioc_error = 0; 371*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCACK; 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gate /* return buffer to pool ASAP */ 375*0Sstevel@tonic-gate if (mp->b_cont) { 376*0Sstevel@tonic-gate freemsg(mp->b_cont); 377*0Sstevel@tonic-gate mp->b_cont = NULL; 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate qreply(qp, mp); 381*0Sstevel@tonic-gate return (0); 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate case VUIDGFORMAT: 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate /* return buffer to pool ASAP */ 386*0Sstevel@tonic-gate if (mp->b_cont) { 387*0Sstevel@tonic-gate freemsg(mp->b_cont); /* over written below */ 388*0Sstevel@tonic-gate mp->b_cont = NULL; 389*0Sstevel@tonic-gate } 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate /* 392*0Sstevel@tonic-gate * VUIDGFORMAT is known to the stream head and thus 393*0Sstevel@tonic-gate * is guaranteed to be an I_STR ioctl. 394*0Sstevel@tonic-gate */ 395*0Sstevel@tonic-gate if (iocbp->ioc_count == TRANSPARENT) { 396*0Sstevel@tonic-gate miocnak(qp, mp, 0, EINVAL); 397*0Sstevel@tonic-gate return (0); 398*0Sstevel@tonic-gate } 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate mp->b_cont = allocb(sizeof (int), BPRI_MED); 401*0Sstevel@tonic-gate if (mp->b_cont == NULL) { 402*0Sstevel@tonic-gate miocnak(qp, mp, 0, EAGAIN); 403*0Sstevel@tonic-gate return (0); 404*0Sstevel@tonic-gate } 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate *(int *)mp->b_cont->b_rptr = (int)STATEP->format; 407*0Sstevel@tonic-gate mp->b_cont->b_wptr += sizeof (int); 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate iocbp->ioc_count = sizeof (int); 410*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCACK; 411*0Sstevel@tonic-gate qreply(qp, mp); 412*0Sstevel@tonic-gate return (0); 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate case VUID_NATIVE: 415*0Sstevel@tonic-gate case VUIDSADDR: 416*0Sstevel@tonic-gate case VUIDGADDR: 417*0Sstevel@tonic-gate miocnak(qp, mp, 0, ENOTTY); 418*0Sstevel@tonic-gate return (0); 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate case MSIOBUTTONS: 421*0Sstevel@tonic-gate /* return buffer to pool ASAP */ 422*0Sstevel@tonic-gate if (mp->b_cont) { 423*0Sstevel@tonic-gate freemsg(mp->b_cont); /* over written below */ 424*0Sstevel@tonic-gate mp->b_cont = NULL; 425*0Sstevel@tonic-gate } 426*0Sstevel@tonic-gate 427*0Sstevel@tonic-gate /* 428*0Sstevel@tonic-gate * MSIOBUTTONS is known to streamio.c and this 429*0Sstevel@tonic-gate * is assume to be non-I_STR & non-TRANSPARENT ioctl 430*0Sstevel@tonic-gate */ 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate if (iocbp->ioc_count == TRANSPARENT) { 433*0Sstevel@tonic-gate miocnak(qp, mp, 0, EINVAL); 434*0Sstevel@tonic-gate return (0); 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate 437*0Sstevel@tonic-gate if (STATEP->nbuttons == 0) { 438*0Sstevel@tonic-gate miocnak(qp, mp, 0, EINVAL); 439*0Sstevel@tonic-gate return (0); 440*0Sstevel@tonic-gate } 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate mp->b_cont = allocb(sizeof (int), BPRI_MED); 443*0Sstevel@tonic-gate if (mp->b_cont == NULL) { 444*0Sstevel@tonic-gate miocnak(qp, mp, 0, EAGAIN); 445*0Sstevel@tonic-gate return (0); 446*0Sstevel@tonic-gate } 447*0Sstevel@tonic-gate 448*0Sstevel@tonic-gate *(int *)mp->b_cont->b_rptr = (int)STATEP->nbuttons; 449*0Sstevel@tonic-gate mp->b_cont->b_wptr += sizeof (int); 450*0Sstevel@tonic-gate 451*0Sstevel@tonic-gate iocbp->ioc_count = sizeof (int); 452*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCACK; 453*0Sstevel@tonic-gate qreply(qp, mp); 454*0Sstevel@tonic-gate return (0); 455*0Sstevel@tonic-gate 456*0Sstevel@tonic-gate /* 457*0Sstevel@tonic-gate * New IOCTL support. Since it's explicitly mentioned 458*0Sstevel@tonic-gate * that you can't add more ioctls to stream head's 459*0Sstevel@tonic-gate * hard coded list, we have to do the transparent 460*0Sstevel@tonic-gate * ioctl processing which is not very exciting. 461*0Sstevel@tonic-gate */ 462*0Sstevel@tonic-gate case VUIDGWHEELCOUNT: 463*0Sstevel@tonic-gate case VUIDGWHEELINFO: 464*0Sstevel@tonic-gate case VUIDGWHEELSTATE: 465*0Sstevel@tonic-gate case VUIDSWHEELSTATE: 466*0Sstevel@tonic-gate case MSIOSRESOLUTION: 467*0Sstevel@tonic-gate error = vuidmice_handle_wheel_resolution_ioctl(qp, 468*0Sstevel@tonic-gate mp, iocbp->ioc_cmd); 469*0Sstevel@tonic-gate if (!error) { 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate return (0); 472*0Sstevel@tonic-gate } else { 473*0Sstevel@tonic-gate miocnak(qp, mp, 0, error); 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate return (0); 476*0Sstevel@tonic-gate } 477*0Sstevel@tonic-gate default: 478*0Sstevel@tonic-gate putnext(qp, mp); /* nothing to process here */ 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate return (0); 481*0Sstevel@tonic-gate } 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate } /* End of case M_IOCTL */ 484*0Sstevel@tonic-gate 485*0Sstevel@tonic-gate case M_IOCDATA: 486*0Sstevel@tonic-gate vuidmice_miocdata(qp, mp); 487*0Sstevel@tonic-gate 488*0Sstevel@tonic-gate return (0); 489*0Sstevel@tonic-gate default: 490*0Sstevel@tonic-gate putnext(qp, mp); /* pass it on */ 491*0Sstevel@tonic-gate return (0); 492*0Sstevel@tonic-gate } 493*0Sstevel@tonic-gate /*NOTREACHED*/ 494*0Sstevel@tonic-gate } 495*0Sstevel@tonic-gate 496*0Sstevel@tonic-gate void 497*0Sstevel@tonic-gate VUID_PUTNEXT(queue_t *const qp, uchar_t event_id, uchar_t event_pair_type, 498*0Sstevel@tonic-gate uchar_t event_pair, int event_value) 499*0Sstevel@tonic-gate { 500*0Sstevel@tonic-gate int strikes = 1; 501*0Sstevel@tonic-gate mblk_t *bp; 502*0Sstevel@tonic-gate Firm_event *fep; 503*0Sstevel@tonic-gate 504*0Sstevel@tonic-gate /* 505*0Sstevel@tonic-gate * Give this event 3 chances to allocate blocks, 506*0Sstevel@tonic-gate * otherwise discard this mouse event. 3 Strikes and you're out. 507*0Sstevel@tonic-gate */ 508*0Sstevel@tonic-gate while ((bp = allocb((int)sizeof (Firm_event), BPRI_HI)) == NULL) { 509*0Sstevel@tonic-gate if (++strikes > 3) 510*0Sstevel@tonic-gate return; 511*0Sstevel@tonic-gate drv_usecwait(10); 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate 514*0Sstevel@tonic-gate fep = (Firm_event *)bp->b_wptr; 515*0Sstevel@tonic-gate fep->id = vuid_id_addr(VKEY_FIRST) | vuid_id_offset(event_id); 516*0Sstevel@tonic-gate 517*0Sstevel@tonic-gate fep->pair_type = event_pair_type; 518*0Sstevel@tonic-gate fep->pair = event_pair; 519*0Sstevel@tonic-gate fep->value = event_value; 520*0Sstevel@tonic-gate uniqtime32(&fep->time); 521*0Sstevel@tonic-gate bp->b_wptr += sizeof (Firm_event); 522*0Sstevel@tonic-gate 523*0Sstevel@tonic-gate if (canput(qp->q_next)) 524*0Sstevel@tonic-gate putnext(qp, bp); 525*0Sstevel@tonic-gate else 526*0Sstevel@tonic-gate (void) putbq(qp, bp); /* read side is blocked */ 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate 529*0Sstevel@tonic-gate 530*0Sstevel@tonic-gate /* 531*0Sstevel@tonic-gate * vuidmice_miocdata 532*0Sstevel@tonic-gate * M_IOCDATA processing for IOCTL's: VUIDGWHEELCOUNT, VUIDGWHEELINFO, 533*0Sstevel@tonic-gate * VUIDGWHEELSTATE, VUIDSWHEELSTATE & MSIOSRESOLUTION. 534*0Sstevel@tonic-gate */ 535*0Sstevel@tonic-gate static void 536*0Sstevel@tonic-gate vuidmice_miocdata(queue_t *qp, mblk_t *mp) 537*0Sstevel@tonic-gate { 538*0Sstevel@tonic-gate struct copyresp *copyresp; 539*0Sstevel@tonic-gate struct copyreq *copyreq; 540*0Sstevel@tonic-gate struct iocblk *iocbp; 541*0Sstevel@tonic-gate mblk_t *ioctmp; 542*0Sstevel@tonic-gate mblk_t *datap; 543*0Sstevel@tonic-gate Mouse_iocstate_t *Mouseioc; 544*0Sstevel@tonic-gate int err = 0; 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gate 547*0Sstevel@tonic-gate copyresp = (struct copyresp *)mp->b_rptr; 548*0Sstevel@tonic-gate copyreq = (struct copyreq *)mp->b_rptr; 549*0Sstevel@tonic-gate iocbp = (struct iocblk *)mp->b_rptr; 550*0Sstevel@tonic-gate 551*0Sstevel@tonic-gate if (copyresp->cp_rval) { 552*0Sstevel@tonic-gate err = EAGAIN; 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gate goto err; 555*0Sstevel@tonic-gate } 556*0Sstevel@tonic-gate switch (copyresp->cp_cmd) { 557*0Sstevel@tonic-gate case VUIDGWHEELCOUNT: 558*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCACK; 559*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr + sizeof (struct iocblk); 560*0Sstevel@tonic-gate iocbp->ioc_error = 0; 561*0Sstevel@tonic-gate iocbp->ioc_count = 0; 562*0Sstevel@tonic-gate iocbp->ioc_rval = 0; 563*0Sstevel@tonic-gate if (mp->b_cont != NULL) { 564*0Sstevel@tonic-gate freemsg(mp->b_cont); 565*0Sstevel@tonic-gate mp->b_cont = NULL; 566*0Sstevel@tonic-gate } 567*0Sstevel@tonic-gate 568*0Sstevel@tonic-gate break; 569*0Sstevel@tonic-gate case VUIDGWHEELINFO: 570*0Sstevel@tonic-gate case VUIDGWHEELSTATE: 571*0Sstevel@tonic-gate ioctmp = (mblk_t *)copyresp->cp_private; 572*0Sstevel@tonic-gate Mouseioc = (Mouse_iocstate_t *)ioctmp->b_rptr; 573*0Sstevel@tonic-gate if (Mouseioc->ioc_state == GETSTRUCT) { 574*0Sstevel@tonic-gate if (mp->b_cont == NULL) { 575*0Sstevel@tonic-gate err = EINVAL; 576*0Sstevel@tonic-gate 577*0Sstevel@tonic-gate break; 578*0Sstevel@tonic-gate } 579*0Sstevel@tonic-gate datap = mp->b_cont; 580*0Sstevel@tonic-gate if (copyresp->cp_cmd == VUIDGWHEELSTATE) { 581*0Sstevel@tonic-gate err = vuidmice_service_wheel_state(qp, datap, 582*0Sstevel@tonic-gate VUIDGWHEELSTATE); 583*0Sstevel@tonic-gate } else { 584*0Sstevel@tonic-gate err = vuidmice_service_wheel_info(datap); 585*0Sstevel@tonic-gate } 586*0Sstevel@tonic-gate if (err) { 587*0Sstevel@tonic-gate break; 588*0Sstevel@tonic-gate } 589*0Sstevel@tonic-gate 590*0Sstevel@tonic-gate if (copyresp->cp_cmd == VUIDGWHEELSTATE) { 591*0Sstevel@tonic-gate copyreq->cq_size = sizeof (wheel_state); 592*0Sstevel@tonic-gate } else { 593*0Sstevel@tonic-gate copyreq->cq_size = sizeof (wheel_info); 594*0Sstevel@tonic-gate copyreq->cq_flag = 0; 595*0Sstevel@tonic-gate } 596*0Sstevel@tonic-gate 597*0Sstevel@tonic-gate copyreq->cq_private = ioctmp; 598*0Sstevel@tonic-gate copyreq->cq_addr = Mouseioc->u_addr; 599*0Sstevel@tonic-gate Mouseioc->ioc_state = GETRESULT; 600*0Sstevel@tonic-gate mp->b_datap->db_type = M_COPYOUT; 601*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr + sizeof (struct copyreq); 602*0Sstevel@tonic-gate } else if (Mouseioc->ioc_state == GETRESULT) { 603*0Sstevel@tonic-gate freemsg(ioctmp); 604*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCACK; 605*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr + sizeof (struct iocblk); 606*0Sstevel@tonic-gate iocbp->ioc_error = 0; 607*0Sstevel@tonic-gate iocbp->ioc_count = 0; 608*0Sstevel@tonic-gate iocbp->ioc_rval = 0; 609*0Sstevel@tonic-gate if (mp->b_cont != NULL) { 610*0Sstevel@tonic-gate freemsg(mp->b_cont); 611*0Sstevel@tonic-gate mp->b_cont = NULL; 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate } 614*0Sstevel@tonic-gate 615*0Sstevel@tonic-gate break; 616*0Sstevel@tonic-gate case VUIDSWHEELSTATE: 617*0Sstevel@tonic-gate case MSIOSRESOLUTION: 618*0Sstevel@tonic-gate ioctmp = (mblk_t *)copyresp->cp_private; 619*0Sstevel@tonic-gate Mouseioc = (Mouse_iocstate_t *)ioctmp->b_rptr; 620*0Sstevel@tonic-gate if (mp->b_cont == NULL) { 621*0Sstevel@tonic-gate err = EINVAL; 622*0Sstevel@tonic-gate 623*0Sstevel@tonic-gate break; 624*0Sstevel@tonic-gate } 625*0Sstevel@tonic-gate datap = mp->b_cont; 626*0Sstevel@tonic-gate 627*0Sstevel@tonic-gate if (copyresp->cp_cmd == VUIDSWHEELSTATE) { 628*0Sstevel@tonic-gate err = vuidmice_service_wheel_state(qp, 629*0Sstevel@tonic-gate datap, VUIDSWHEELSTATE); 630*0Sstevel@tonic-gate } 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate if (err) { 633*0Sstevel@tonic-gate break; 634*0Sstevel@tonic-gate } 635*0Sstevel@tonic-gate 636*0Sstevel@tonic-gate if (mp->b_cont) { 637*0Sstevel@tonic-gate freemsg(mp->b_cont); 638*0Sstevel@tonic-gate mp->b_cont = (mblk_t *)NULL; 639*0Sstevel@tonic-gate } 640*0Sstevel@tonic-gate freemsg(ioctmp); 641*0Sstevel@tonic-gate iocbp->ioc_count = 0; 642*0Sstevel@tonic-gate iocbp->ioc_error = 0; 643*0Sstevel@tonic-gate iocbp->ioc_rval = 0; 644*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCACK; 645*0Sstevel@tonic-gate 646*0Sstevel@tonic-gate break; 647*0Sstevel@tonic-gate default: 648*0Sstevel@tonic-gate err = EINVAL; 649*0Sstevel@tonic-gate 650*0Sstevel@tonic-gate break; 651*0Sstevel@tonic-gate } 652*0Sstevel@tonic-gate 653*0Sstevel@tonic-gate err: 654*0Sstevel@tonic-gate if (err) { 655*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCNAK; 656*0Sstevel@tonic-gate if (mp->b_cont) { 657*0Sstevel@tonic-gate freemsg(mp->b_cont); 658*0Sstevel@tonic-gate mp->b_cont = (mblk_t *)NULL; 659*0Sstevel@tonic-gate } 660*0Sstevel@tonic-gate if (copyresp->cp_private) { 661*0Sstevel@tonic-gate freemsg((mblk_t *)copyresp->cp_private); 662*0Sstevel@tonic-gate copyresp->cp_private = (mblk_t *)NULL; 663*0Sstevel@tonic-gate } 664*0Sstevel@tonic-gate iocbp->ioc_count = 0; 665*0Sstevel@tonic-gate iocbp->ioc_error = err; 666*0Sstevel@tonic-gate } 667*0Sstevel@tonic-gate qreply(qp, mp); 668*0Sstevel@tonic-gate } 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate /* 672*0Sstevel@tonic-gate * vuidmice_handle_wheel_resolution_ioctl 673*0Sstevel@tonic-gate * Handle wheel mouse and MSIOSRESOLUTION ioctls. 674*0Sstevel@tonic-gate * 675*0Sstevel@tonic-gate * Here we also support non-transparent way of these ioctls 676*0Sstevel@tonic-gate * just like usb mouse driver does, so the consms module is 677*0Sstevel@tonic-gate * very simple to deal with these ioctls. 678*0Sstevel@tonic-gate */ 679*0Sstevel@tonic-gate static int 680*0Sstevel@tonic-gate vuidmice_handle_wheel_resolution_ioctl(queue_t *qp, mblk_t *mp, int cmd) 681*0Sstevel@tonic-gate { 682*0Sstevel@tonic-gate int err = 0; 683*0Sstevel@tonic-gate Mouse_iocstate_t *Mouseioc; 684*0Sstevel@tonic-gate struct copyreq *copyreq; 685*0Sstevel@tonic-gate mblk_t *ioctmp; 686*0Sstevel@tonic-gate mblk_t *datap; 687*0Sstevel@tonic-gate 688*0Sstevel@tonic-gate struct iocblk *iocbp = (struct iocblk *)mp->b_rptr; 689*0Sstevel@tonic-gate 690*0Sstevel@tonic-gate if (iocbp->ioc_count == TRANSPARENT) { 691*0Sstevel@tonic-gate copyreq = (struct copyreq *)mp->b_rptr; 692*0Sstevel@tonic-gate if (mp->b_cont == NULL) { 693*0Sstevel@tonic-gate err = EINVAL; 694*0Sstevel@tonic-gate 695*0Sstevel@tonic-gate return (err); 696*0Sstevel@tonic-gate } 697*0Sstevel@tonic-gate copyreq->cq_addr = 698*0Sstevel@tonic-gate (caddr_t)*((caddr_t *)mp->b_cont->b_rptr); 699*0Sstevel@tonic-gate switch (cmd) { 700*0Sstevel@tonic-gate case VUIDGWHEELCOUNT: 701*0Sstevel@tonic-gate copyreq->cq_size = sizeof (int); 702*0Sstevel@tonic-gate mp->b_datap->db_type = M_COPYOUT; 703*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr 704*0Sstevel@tonic-gate + sizeof (struct copyreq); 705*0Sstevel@tonic-gate freemsg(mp->b_cont); 706*0Sstevel@tonic-gate datap = allocb(sizeof (int), BPRI_HI); 707*0Sstevel@tonic-gate *((int *)datap->b_wptr) = 708*0Sstevel@tonic-gate STATEP->vuid_mouse_mode; 709*0Sstevel@tonic-gate datap->b_wptr += sizeof (int); 710*0Sstevel@tonic-gate mp->b_cont = datap; 711*0Sstevel@tonic-gate qreply(qp, mp); 712*0Sstevel@tonic-gate 713*0Sstevel@tonic-gate return (err); 714*0Sstevel@tonic-gate case VUIDGWHEELINFO: 715*0Sstevel@tonic-gate copyreq->cq_size = sizeof (wheel_info); 716*0Sstevel@tonic-gate break; 717*0Sstevel@tonic-gate 718*0Sstevel@tonic-gate case VUIDSWHEELSTATE: 719*0Sstevel@tonic-gate case VUIDGWHEELSTATE: 720*0Sstevel@tonic-gate copyreq->cq_size = sizeof (wheel_state); 721*0Sstevel@tonic-gate break; 722*0Sstevel@tonic-gate 723*0Sstevel@tonic-gate case MSIOSRESOLUTION: 724*0Sstevel@tonic-gate copyreq->cq_size = sizeof (Ms_screen_resolution); 725*0Sstevel@tonic-gate break; 726*0Sstevel@tonic-gate } 727*0Sstevel@tonic-gate 728*0Sstevel@tonic-gate if ((ioctmp = (mblk_t *)allocb(sizeof (Mouse_iocstate_t), 729*0Sstevel@tonic-gate BPRI_MED)) == NULL) { 730*0Sstevel@tonic-gate err = EAGAIN; 731*0Sstevel@tonic-gate 732*0Sstevel@tonic-gate return (err); 733*0Sstevel@tonic-gate } 734*0Sstevel@tonic-gate copyreq->cq_private = ioctmp; 735*0Sstevel@tonic-gate Mouseioc = (Mouse_iocstate_t *)ioctmp->b_rptr; 736*0Sstevel@tonic-gate Mouseioc->ioc_state = GETSTRUCT; 737*0Sstevel@tonic-gate Mouseioc->u_addr = copyreq->cq_addr; 738*0Sstevel@tonic-gate ioctmp->b_wptr = ioctmp->b_rptr + sizeof (Mouse_iocstate_t); 739*0Sstevel@tonic-gate copyreq->cq_flag = 0; 740*0Sstevel@tonic-gate mp->b_datap->db_type = M_COPYIN; 741*0Sstevel@tonic-gate freemsg(mp->b_cont); 742*0Sstevel@tonic-gate mp->b_cont = (mblk_t *)NULL; 743*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr + sizeof (struct copyreq); 744*0Sstevel@tonic-gate qreply(qp, mp); 745*0Sstevel@tonic-gate 746*0Sstevel@tonic-gate return (err); 747*0Sstevel@tonic-gate } else { 748*0Sstevel@tonic-gate switch (cmd) { 749*0Sstevel@tonic-gate case VUIDGWHEELCOUNT: 750*0Sstevel@tonic-gate if (mp->b_cont) { 751*0Sstevel@tonic-gate freemsg(mp->b_cont); 752*0Sstevel@tonic-gate mp->b_cont = NULL; 753*0Sstevel@tonic-gate } 754*0Sstevel@tonic-gate datap = allocb(sizeof (int), BPRI_HI); 755*0Sstevel@tonic-gate *((int *)datap->b_wptr) = 756*0Sstevel@tonic-gate STATEP->vuid_mouse_mode; 757*0Sstevel@tonic-gate datap->b_wptr += sizeof (int); 758*0Sstevel@tonic-gate mp->b_cont = datap; 759*0Sstevel@tonic-gate break; 760*0Sstevel@tonic-gate 761*0Sstevel@tonic-gate case VUIDGWHEELINFO: 762*0Sstevel@tonic-gate if (mp->b_cont == NULL || 763*0Sstevel@tonic-gate iocbp->ioc_count != sizeof (wheel_info)) { 764*0Sstevel@tonic-gate err = EINVAL; 765*0Sstevel@tonic-gate break; 766*0Sstevel@tonic-gate } 767*0Sstevel@tonic-gate datap = mp->b_cont; 768*0Sstevel@tonic-gate err = vuidmice_service_wheel_info(datap); 769*0Sstevel@tonic-gate break; 770*0Sstevel@tonic-gate 771*0Sstevel@tonic-gate case VUIDSWHEELSTATE: 772*0Sstevel@tonic-gate case VUIDGWHEELSTATE: 773*0Sstevel@tonic-gate if (mp->b_cont == NULL || 774*0Sstevel@tonic-gate iocbp->ioc_count != sizeof (wheel_state)) { 775*0Sstevel@tonic-gate err = EINVAL; 776*0Sstevel@tonic-gate break; 777*0Sstevel@tonic-gate } 778*0Sstevel@tonic-gate datap = mp->b_cont; 779*0Sstevel@tonic-gate err = vuidmice_service_wheel_state(qp, datap, cmd); 780*0Sstevel@tonic-gate break; 781*0Sstevel@tonic-gate 782*0Sstevel@tonic-gate case MSIOSRESOLUTION: 783*0Sstevel@tonic-gate /* 784*0Sstevel@tonic-gate * Now we just make Xserver and 785*0Sstevel@tonic-gate * the virtual mouse happy. Of course, 786*0Sstevel@tonic-gate * the screen resolution value may 787*0Sstevel@tonic-gate * be used later for absolute PS/2 mouse. 788*0Sstevel@tonic-gate */ 789*0Sstevel@tonic-gate err = 0; 790*0Sstevel@tonic-gate break; 791*0Sstevel@tonic-gate } 792*0Sstevel@tonic-gate 793*0Sstevel@tonic-gate if (!err) { 794*0Sstevel@tonic-gate mp->b_datap->db_type = M_IOCACK; 795*0Sstevel@tonic-gate iocbp->ioc_rval = 0; 796*0Sstevel@tonic-gate iocbp->ioc_error = 0; 797*0Sstevel@tonic-gate qreply(qp, mp); 798*0Sstevel@tonic-gate } 799*0Sstevel@tonic-gate 800*0Sstevel@tonic-gate return (err); 801*0Sstevel@tonic-gate } 802*0Sstevel@tonic-gate } 803*0Sstevel@tonic-gate 804*0Sstevel@tonic-gate static int 805*0Sstevel@tonic-gate vuidmice_service_wheel_info(register mblk_t *datap) 806*0Sstevel@tonic-gate { 807*0Sstevel@tonic-gate wheel_info *wi; 808*0Sstevel@tonic-gate int err = 0; 809*0Sstevel@tonic-gate 810*0Sstevel@tonic-gate wi = (wheel_info *)datap->b_rptr; 811*0Sstevel@tonic-gate if (wi->vers != VUID_WHEEL_INFO_VERS) { 812*0Sstevel@tonic-gate err = EINVAL; 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate return (err); 815*0Sstevel@tonic-gate } 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate if (wi->id > (VUIDMICE_NUM_WHEELS - 1)) { 818*0Sstevel@tonic-gate err = EINVAL; 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate return (err); 821*0Sstevel@tonic-gate } 822*0Sstevel@tonic-gate wi->format = (wi->id == 823*0Sstevel@tonic-gate VUIDMICE_VERTICAL_WHEEL_ID) ? 824*0Sstevel@tonic-gate VUID_WHEEL_FORMAT_VERTICAL : 825*0Sstevel@tonic-gate VUID_WHEEL_FORMAT_HORIZONTAL; 826*0Sstevel@tonic-gate 827*0Sstevel@tonic-gate return (err); 828*0Sstevel@tonic-gate } 829*0Sstevel@tonic-gate 830*0Sstevel@tonic-gate 831*0Sstevel@tonic-gate static int 832*0Sstevel@tonic-gate vuidmice_service_wheel_state(register queue_t *qp, 833*0Sstevel@tonic-gate register mblk_t *datap, 834*0Sstevel@tonic-gate register uint_t cmd) 835*0Sstevel@tonic-gate { 836*0Sstevel@tonic-gate wheel_state *ws; 837*0Sstevel@tonic-gate uint_t err = 0; 838*0Sstevel@tonic-gate 839*0Sstevel@tonic-gate ws = (wheel_state *)datap->b_rptr; 840*0Sstevel@tonic-gate if (ws->vers != VUID_WHEEL_STATE_VERS) { 841*0Sstevel@tonic-gate err = EINVAL; 842*0Sstevel@tonic-gate 843*0Sstevel@tonic-gate return (err); 844*0Sstevel@tonic-gate } 845*0Sstevel@tonic-gate 846*0Sstevel@tonic-gate if (ws->id > (VUIDMICE_NUM_WHEELS - 1)) { 847*0Sstevel@tonic-gate err = EINVAL; 848*0Sstevel@tonic-gate 849*0Sstevel@tonic-gate return (err); 850*0Sstevel@tonic-gate } 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gate switch (cmd) { 853*0Sstevel@tonic-gate case VUIDGWHEELSTATE: 854*0Sstevel@tonic-gate ws->stateflags = 855*0Sstevel@tonic-gate (STATEP->wheel_state_bf >> ws->id) & 1; 856*0Sstevel@tonic-gate 857*0Sstevel@tonic-gate break; 858*0Sstevel@tonic-gate case VUIDSWHEELSTATE: 859*0Sstevel@tonic-gate STATEP->wheel_state_bf = (ws->stateflags << ws->id) | 860*0Sstevel@tonic-gate (STATEP->wheel_state_bf & ~(1 << ws->id)); 861*0Sstevel@tonic-gate 862*0Sstevel@tonic-gate break; 863*0Sstevel@tonic-gate default: 864*0Sstevel@tonic-gate err = EINVAL; 865*0Sstevel@tonic-gate 866*0Sstevel@tonic-gate return (err); 867*0Sstevel@tonic-gate } 868*0Sstevel@tonic-gate 869*0Sstevel@tonic-gate return (err); 870*0Sstevel@tonic-gate } 871