17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*77e51571Sgongtian zhao - Sun Microsystems - Beijing China * Common Development and Distribution License (the "License"). 6*77e51571Sgongtian zhao - Sun Microsystems - Beijing China * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate * 21*77e51571Sgongtian zhao - Sun Microsystems - Beijing China * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 227c478bd9Sstevel@tonic-gate * Use is subject to license terms. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * UGEN: USB Generic Driver 287c478bd9Sstevel@tonic-gate * 297c478bd9Sstevel@tonic-gate * The "Universal Generic Driver" (UGEN) for USB devices provides interfaces 307c478bd9Sstevel@tonic-gate * to talk to USB devices. This is very useful for Point of Sale sale 317c478bd9Sstevel@tonic-gate * devices and other simple devices like USB scanner, USB palm pilot. 327c478bd9Sstevel@tonic-gate * The UGEN provides a system call interface to USB devices enabling 337c478bd9Sstevel@tonic-gate * a USB device vendor to write an application for his 347c478bd9Sstevel@tonic-gate * device instead of writing a driver. This facilitates the vendor to write 357c478bd9Sstevel@tonic-gate * device management s/w quickly in userland. 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * UGEN supports read/write/poll entry points. An application can be written 387c478bd9Sstevel@tonic-gate * using read/write/aioread/aiowrite/poll system calls to communicate 397c478bd9Sstevel@tonic-gate * with the device. 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate #include <sys/usb/usba/usbai_version.h> 427c478bd9Sstevel@tonic-gate #include <sys/usb/usba.h> 437c478bd9Sstevel@tonic-gate #include <sys/usb/usba/usba_ugen.h> 447c478bd9Sstevel@tonic-gate #include <sys/usb/clients/ugen/ugend.h> 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* Global variables */ 477c478bd9Sstevel@tonic-gate static void *ugen_skel_statep; 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* Prototypes declarations for the entry points */ 507c478bd9Sstevel@tonic-gate static int ugen_skel_getinfo(dev_info_t *, ddi_info_cmd_t, 517c478bd9Sstevel@tonic-gate void *, void **); 527c478bd9Sstevel@tonic-gate static int ugen_skel_open(dev_t *, int, int, cred_t *); 537c478bd9Sstevel@tonic-gate static int ugen_skel_close(dev_t, int, int, cred_t *); 547c478bd9Sstevel@tonic-gate static int ugen_skel_attach(dev_info_t *, ddi_attach_cmd_t); 557c478bd9Sstevel@tonic-gate static int ugen_skel_detach(dev_info_t *, ddi_detach_cmd_t); 567c478bd9Sstevel@tonic-gate static int ugen_skel_power(dev_info_t *, int, int); 577c478bd9Sstevel@tonic-gate static int ugen_skel_strategy(struct buf *); 587c478bd9Sstevel@tonic-gate static int ugen_skel_read(dev_t, struct uio *, cred_t *); 597c478bd9Sstevel@tonic-gate static int ugen_skel_write(dev_t, struct uio *, cred_t *); 607c478bd9Sstevel@tonic-gate static int ugen_skel_poll(dev_t, short, int, short *, 617c478bd9Sstevel@tonic-gate struct pollhead **); 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate static int ugen_skel_disconnect_ev_cb(dev_info_t *); 647c478bd9Sstevel@tonic-gate static int ugen_skel_reconnect_ev_cb(dev_info_t *); 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* event support */ 677c478bd9Sstevel@tonic-gate static usb_event_t ugen_skel_events = { 687c478bd9Sstevel@tonic-gate ugen_skel_disconnect_ev_cb, 697c478bd9Sstevel@tonic-gate ugen_skel_reconnect_ev_cb, 707c478bd9Sstevel@tonic-gate NULL, NULL 717c478bd9Sstevel@tonic-gate }; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* Driver cb_ops structure */ 747c478bd9Sstevel@tonic-gate static struct cb_ops ugen_skel_cb_ops = { 757c478bd9Sstevel@tonic-gate ugen_skel_open, /* open */ 767c478bd9Sstevel@tonic-gate ugen_skel_close, /* close */ 777c478bd9Sstevel@tonic-gate nodev, /* strategy */ 787c478bd9Sstevel@tonic-gate nodev, /* print */ 797c478bd9Sstevel@tonic-gate nodev, /* dump */ 807c478bd9Sstevel@tonic-gate ugen_skel_read, /* read */ 817c478bd9Sstevel@tonic-gate ugen_skel_write, /* write */ 827c478bd9Sstevel@tonic-gate nodev, /* ioctl */ 837c478bd9Sstevel@tonic-gate nodev, /* devmap */ 847c478bd9Sstevel@tonic-gate nodev, /* mmap */ 857c478bd9Sstevel@tonic-gate nodev, /* segmap */ 867c478bd9Sstevel@tonic-gate ugen_skel_poll, /* poll */ 877c478bd9Sstevel@tonic-gate ddi_prop_op, /* cb_prop_op */ 887c478bd9Sstevel@tonic-gate 0, /* streamtab */ 897c478bd9Sstevel@tonic-gate D_MP, /* Driver compatibility flag */ 907c478bd9Sstevel@tonic-gate CB_REV, /* revision */ 917c478bd9Sstevel@tonic-gate nodev, /* aread */ 927c478bd9Sstevel@tonic-gate nodev /* awrite */ 937c478bd9Sstevel@tonic-gate }; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * Modloading support 977c478bd9Sstevel@tonic-gate * driver dev_ops structure 987c478bd9Sstevel@tonic-gate */ 997c478bd9Sstevel@tonic-gate static struct dev_ops ugen_skel_ops = { 1007c478bd9Sstevel@tonic-gate DEVO_REV, /* devo_rev, */ 1017c478bd9Sstevel@tonic-gate 0, /* refct */ 1027c478bd9Sstevel@tonic-gate ugen_skel_getinfo, /* info */ 1037c478bd9Sstevel@tonic-gate nulldev, /* indetify */ 1047c478bd9Sstevel@tonic-gate nulldev, /* probe */ 1057c478bd9Sstevel@tonic-gate ugen_skel_attach, /* attach */ 1067c478bd9Sstevel@tonic-gate ugen_skel_detach, /* detach */ 1077c478bd9Sstevel@tonic-gate nodev, /* reset */ 1087c478bd9Sstevel@tonic-gate &ugen_skel_cb_ops, /* driver operations */ 1097c478bd9Sstevel@tonic-gate NULL, /* bus operations */ 1107c478bd9Sstevel@tonic-gate ugen_skel_power /* power */ 1117c478bd9Sstevel@tonic-gate }; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate static struct modldrv modldrv = { 1147c478bd9Sstevel@tonic-gate &mod_driverops, /* Module type */ 115*77e51571Sgongtian zhao - Sun Microsystems - Beijing China "USB Generic driver", /* Name of the module. */ 1167c478bd9Sstevel@tonic-gate &ugen_skel_ops, /* driver ops */ 1177c478bd9Sstevel@tonic-gate }; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = { 1207c478bd9Sstevel@tonic-gate MODREV_1, 1217c478bd9Sstevel@tonic-gate (void *)&modldrv, 1227c478bd9Sstevel@tonic-gate NULL 1237c478bd9Sstevel@tonic-gate }; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate int 1277c478bd9Sstevel@tonic-gate _init() 1287c478bd9Sstevel@tonic-gate { 1297c478bd9Sstevel@tonic-gate int rval; 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate if ((rval = ddi_soft_state_init(&ugen_skel_statep, 132*77e51571Sgongtian zhao - Sun Microsystems - Beijing China sizeof (ugen_skel_state_t), UGEN_INSTANCES)) != 0) { 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate return (rval); 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate if ((rval = mod_install(&modlinkage)) != 0) { 1387c478bd9Sstevel@tonic-gate ddi_soft_state_fini(&ugen_skel_statep); 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate return (rval); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate return (rval); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate int 1487c478bd9Sstevel@tonic-gate _fini() 1497c478bd9Sstevel@tonic-gate { 1507c478bd9Sstevel@tonic-gate int rval; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate if ((rval = mod_remove(&modlinkage)) != 0) { 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate return (rval); 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate ddi_soft_state_fini(&ugen_skel_statep); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate return (rval); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate int 1637c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop) 1647c478bd9Sstevel@tonic-gate { 1657c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1707c478bd9Sstevel@tonic-gate static int 1717c478bd9Sstevel@tonic-gate ugen_skel_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 1727c478bd9Sstevel@tonic-gate void **result) 1737c478bd9Sstevel@tonic-gate { 1747c478bd9Sstevel@tonic-gate int rval = DDI_FAILURE; 1757c478bd9Sstevel@tonic-gate int instance = 176*77e51571Sgongtian zhao - Sun Microsystems - Beijing China UGEN_MINOR_TO_INSTANCE(getminor((dev_t)arg)); 1777c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate switch (infocmd) { 1807c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO: 1817c478bd9Sstevel@tonic-gate ugen_skelp = ddi_get_soft_state(ugen_skel_statep, instance); 1827c478bd9Sstevel@tonic-gate if (ugen_skelp != NULL) { 1837c478bd9Sstevel@tonic-gate *result = ugen_skelp->ugen_skel_dip; 1847c478bd9Sstevel@tonic-gate if (*result != NULL) { 1857c478bd9Sstevel@tonic-gate rval = DDI_SUCCESS; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate } else { 1887c478bd9Sstevel@tonic-gate *result = NULL; 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate break; 1927c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE: 1937c478bd9Sstevel@tonic-gate *result = (void *)(uintptr_t)instance; 1947c478bd9Sstevel@tonic-gate rval = DDI_SUCCESS; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate break; 1977c478bd9Sstevel@tonic-gate default: 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate break; 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate return (rval); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* 2077c478bd9Sstevel@tonic-gate * ugen_skel_attach() 2087c478bd9Sstevel@tonic-gate */ 2097c478bd9Sstevel@tonic-gate static int 2107c478bd9Sstevel@tonic-gate ugen_skel_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 2117c478bd9Sstevel@tonic-gate { 2127c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp; 2137c478bd9Sstevel@tonic-gate int instance; /* Driver instance number */ 2147c478bd9Sstevel@tonic-gate int rval; 2157c478bd9Sstevel@tonic-gate usb_ugen_info_t usb_ugen_info; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate /* Get instance number */ 2187c478bd9Sstevel@tonic-gate instance = ddi_get_instance(dip); 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate switch (cmd) { 2217c478bd9Sstevel@tonic-gate case DDI_ATTACH: 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate break; 2247c478bd9Sstevel@tonic-gate case DDI_RESUME: 2257c478bd9Sstevel@tonic-gate ugen_skelp = ddi_get_soft_state(ugen_skel_statep, instance); 2267c478bd9Sstevel@tonic-gate if (ugen_skelp == NULL) { 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate rval = usb_ugen_attach(ugen_skelp->ugen_skel_hdl, cmd); 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE); 2347c478bd9Sstevel@tonic-gate default: 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate if (ddi_soft_state_zalloc(ugen_skel_statep, instance) == 2407c478bd9Sstevel@tonic-gate DDI_SUCCESS) { 2417c478bd9Sstevel@tonic-gate ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 242*77e51571Sgongtian zhao - Sun Microsystems - Beijing China instance); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate if (ugen_skelp == NULL) { 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate if ((rval = usb_client_attach(dip, USBDRV_VERSION, 0)) != 2507c478bd9Sstevel@tonic-gate USB_SUCCESS) { 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate goto fail; 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate ugen_skelp->ugen_skel_dip = dip; 2567c478bd9Sstevel@tonic-gate ugen_skelp->ugen_skel_instance = instance; 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate /* get a ugen handle */ 2597c478bd9Sstevel@tonic-gate bzero(&usb_ugen_info, sizeof (usb_ugen_info)); 2607c478bd9Sstevel@tonic-gate usb_ugen_info.usb_ugen_flags = 261*77e51571Sgongtian zhao - Sun Microsystems - Beijing China USB_UGEN_ENABLE_PM | USB_UGEN_REMOVE_CHILDREN; 2627c478bd9Sstevel@tonic-gate usb_ugen_info.usb_ugen_minor_node_ugen_bits_mask = 263*77e51571Sgongtian zhao - Sun Microsystems - Beijing China (dev_t)UGEN_MINOR_UGEN_BITS_MASK; 2647c478bd9Sstevel@tonic-gate usb_ugen_info.usb_ugen_minor_node_instance_mask = 265*77e51571Sgongtian zhao - Sun Microsystems - Beijing China (dev_t)~UGEN_MINOR_UGEN_BITS_MASK; 2667c478bd9Sstevel@tonic-gate ugen_skelp->ugen_skel_hdl = usb_ugen_get_hdl(dip, 267*77e51571Sgongtian zhao - Sun Microsystems - Beijing China &usb_ugen_info); 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate if (usb_ugen_attach(ugen_skelp->ugen_skel_hdl, cmd) != USB_SUCCESS) { 2707c478bd9Sstevel@tonic-gate 271*77e51571Sgongtian zhao - Sun Microsystems - Beijing China goto fail; 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate /* register for hotplug events */ 2757c478bd9Sstevel@tonic-gate if (usb_register_event_cbs(dip, &ugen_skel_events, 0) != USB_SUCCESS) { 2767c478bd9Sstevel@tonic-gate 277*77e51571Sgongtian zhao - Sun Microsystems - Beijing China goto fail; 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate ddi_report_dev(dip); 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate return (DDI_SUCCESS); 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate fail: 2857c478bd9Sstevel@tonic-gate if (ugen_skelp) { 2867c478bd9Sstevel@tonic-gate usb_unregister_event_cbs(dip, &ugen_skel_events); 2877c478bd9Sstevel@tonic-gate usb_ugen_release_hdl(ugen_skelp-> 288*77e51571Sgongtian zhao - Sun Microsystems - Beijing China ugen_skel_hdl); 2897c478bd9Sstevel@tonic-gate ddi_soft_state_free(ugen_skel_statep, 290*77e51571Sgongtian zhao - Sun Microsystems - Beijing China ugen_skelp->ugen_skel_instance); 2917c478bd9Sstevel@tonic-gate usb_client_detach(dip, NULL); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /* 2997c478bd9Sstevel@tonic-gate * ugen_skel_detach() 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate static int 3027c478bd9Sstevel@tonic-gate ugen_skel_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 3037c478bd9Sstevel@tonic-gate { 3047c478bd9Sstevel@tonic-gate int rval = USB_FAILURE; 3057c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 306*77e51571Sgongtian zhao - Sun Microsystems - Beijing China ddi_get_instance(dip)); 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate if (ugen_skelp) { 3097c478bd9Sstevel@tonic-gate switch (cmd) { 3107c478bd9Sstevel@tonic-gate case DDI_DETACH: 3117c478bd9Sstevel@tonic-gate rval = usb_ugen_detach(ugen_skelp->ugen_skel_hdl, cmd); 3127c478bd9Sstevel@tonic-gate if (rval == USB_SUCCESS) { 3137c478bd9Sstevel@tonic-gate usb_unregister_event_cbs(dip, 314*77e51571Sgongtian zhao - Sun Microsystems - Beijing China &ugen_skel_events); 3157c478bd9Sstevel@tonic-gate usb_ugen_release_hdl(ugen_skelp-> 316*77e51571Sgongtian zhao - Sun Microsystems - Beijing China ugen_skel_hdl); 3177c478bd9Sstevel@tonic-gate ddi_soft_state_free(ugen_skel_statep, 3187c478bd9Sstevel@tonic-gate ugen_skelp->ugen_skel_instance); 3197c478bd9Sstevel@tonic-gate usb_client_detach(dip, NULL); 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate break; 3237c478bd9Sstevel@tonic-gate case DDI_SUSPEND: 3247c478bd9Sstevel@tonic-gate rval = usb_ugen_detach(ugen_skelp->ugen_skel_hdl, cmd); 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate break; 3277c478bd9Sstevel@tonic-gate default: 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate break; 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate /* 3387c478bd9Sstevel@tonic-gate * ugen_skel_disconnect_ev_cb: 3397c478bd9Sstevel@tonic-gate */ 3407c478bd9Sstevel@tonic-gate static int 3417c478bd9Sstevel@tonic-gate ugen_skel_disconnect_ev_cb(dev_info_t *dip) 3427c478bd9Sstevel@tonic-gate { 3437c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 344*77e51571Sgongtian zhao - Sun Microsystems - Beijing China ddi_get_instance(dip)); 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate return (usb_ugen_disconnect_ev_cb(ugen_skelp->ugen_skel_hdl)); 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* 3517c478bd9Sstevel@tonic-gate * ugen_skel_reconnect_ev_cb: 3527c478bd9Sstevel@tonic-gate */ 3537c478bd9Sstevel@tonic-gate static int 3547c478bd9Sstevel@tonic-gate ugen_skel_reconnect_ev_cb(dev_info_t *dip) 3557c478bd9Sstevel@tonic-gate { 3567c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 357*77e51571Sgongtian zhao - Sun Microsystems - Beijing China ddi_get_instance(dip)); 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate return (usb_ugen_reconnect_ev_cb(ugen_skelp->ugen_skel_hdl)); 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate /* 3647c478bd9Sstevel@tonic-gate * ugen_skel_open: 3657c478bd9Sstevel@tonic-gate */ 3667c478bd9Sstevel@tonic-gate static int 3677c478bd9Sstevel@tonic-gate ugen_skel_open(dev_t *devp, int flag, int sflag, cred_t *cr) 3687c478bd9Sstevel@tonic-gate { 3697c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp; 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate if ((ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 3727c478bd9Sstevel@tonic-gate UGEN_MINOR_TO_INSTANCE(getminor(*devp)))) == NULL) { 3737c478bd9Sstevel@tonic-gate /* deferred detach */ 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate return (ENXIO); 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate return (usb_ugen_open(ugen_skelp->ugen_skel_hdl, devp, flag, 379*77e51571Sgongtian zhao - Sun Microsystems - Beijing China sflag, cr)); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate /* 3847c478bd9Sstevel@tonic-gate * ugen_skel_close() 3857c478bd9Sstevel@tonic-gate */ 3867c478bd9Sstevel@tonic-gate static int 3877c478bd9Sstevel@tonic-gate ugen_skel_close(dev_t dev, int flag, int otype, cred_t *cr) 3887c478bd9Sstevel@tonic-gate { 3897c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 390*77e51571Sgongtian zhao - Sun Microsystems - Beijing China UGEN_MINOR_TO_INSTANCE(getminor(dev))); 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate return (usb_ugen_close(ugen_skelp->ugen_skel_hdl, dev, flag, 393*77e51571Sgongtian zhao - Sun Microsystems - Beijing China otype, cr)); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * ugen_skel_read/write() 3997c478bd9Sstevel@tonic-gate */ 4007c478bd9Sstevel@tonic-gate static int 4017c478bd9Sstevel@tonic-gate ugen_skel_read(dev_t dev, struct uio *uiop, cred_t *credp) 4027c478bd9Sstevel@tonic-gate { 4037c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 404*77e51571Sgongtian zhao - Sun Microsystems - Beijing China UGEN_MINOR_TO_INSTANCE(getminor(dev))); 4057c478bd9Sstevel@tonic-gate if (ugen_skelp == NULL) { 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate return (ENXIO); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate return (usb_ugen_read(ugen_skelp->ugen_skel_hdl, dev, 411*77e51571Sgongtian zhao - Sun Microsystems - Beijing China uiop, credp)); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate static int 4167c478bd9Sstevel@tonic-gate ugen_skel_write(dev_t dev, struct uio *uiop, cred_t *credp) 4177c478bd9Sstevel@tonic-gate { 4187c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 419*77e51571Sgongtian zhao - Sun Microsystems - Beijing China UGEN_MINOR_TO_INSTANCE(getminor(dev))); 4207c478bd9Sstevel@tonic-gate if (ugen_skelp == NULL) { 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate return (ENXIO); 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate return (usb_ugen_write(ugen_skelp->ugen_skel_hdl, 425*77e51571Sgongtian zhao - Sun Microsystems - Beijing China dev, uiop, credp)); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * ugen_skel_poll 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate static int 4337c478bd9Sstevel@tonic-gate ugen_skel_poll(dev_t dev, short events, 4347c478bd9Sstevel@tonic-gate int anyyet, short *reventsp, struct pollhead **phpp) 4357c478bd9Sstevel@tonic-gate { 4367c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 437*77e51571Sgongtian zhao - Sun Microsystems - Beijing China UGEN_MINOR_TO_INSTANCE(getminor(dev))); 4387c478bd9Sstevel@tonic-gate if (ugen_skelp == NULL) { 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate return (ENXIO); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate return (usb_ugen_poll(ugen_skelp->ugen_skel_hdl, dev, events, 444*77e51571Sgongtian zhao - Sun Microsystems - Beijing China anyyet, reventsp, phpp)); 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate /* 4497c478bd9Sstevel@tonic-gate * ugen_skel_power: 4507c478bd9Sstevel@tonic-gate * PM entry point 4517c478bd9Sstevel@tonic-gate */ 4527c478bd9Sstevel@tonic-gate static int 4537c478bd9Sstevel@tonic-gate ugen_skel_power(dev_info_t *dip, int comp, int level) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate int rval; 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep, 458*77e51571Sgongtian zhao - Sun Microsystems - Beijing China ddi_get_instance(dip)); 4597c478bd9Sstevel@tonic-gate if (ugen_skelp == NULL) { 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate return (DDI_FAILURE); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate rval = usb_ugen_power(ugen_skelp->ugen_skel_hdl, comp, level); 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE); 4667c478bd9Sstevel@tonic-gate } 467