10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57425SGongtian.Zhao@Sun.COM * Common Development and Distribution License (the "License").
67425SGongtian.Zhao@Sun.COM * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate *
21*8688SRaymond.Chen@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
220Sstevel@tonic-gate * Use is subject to license terms.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * UGEN: USB Generic Driver
280Sstevel@tonic-gate *
290Sstevel@tonic-gate * The "Universal Generic Driver" (UGEN) for USB devices provides interfaces
300Sstevel@tonic-gate * to talk to USB devices. This is very useful for Point of Sale sale
310Sstevel@tonic-gate * devices and other simple devices like USB scanner, USB palm pilot.
320Sstevel@tonic-gate * The UGEN provides a system call interface to USB devices enabling
330Sstevel@tonic-gate * a USB device vendor to write an application for his
340Sstevel@tonic-gate * device instead of writing a driver. This facilitates the vendor to write
350Sstevel@tonic-gate * device management s/w quickly in userland.
360Sstevel@tonic-gate *
370Sstevel@tonic-gate * UGEN supports read/write/poll entry points. An application can be written
380Sstevel@tonic-gate * using read/write/aioread/aiowrite/poll system calls to communicate
390Sstevel@tonic-gate * with the device.
400Sstevel@tonic-gate */
410Sstevel@tonic-gate #include <sys/usb/usba/usbai_version.h>
420Sstevel@tonic-gate #include <sys/usb/usba.h>
430Sstevel@tonic-gate #include <sys/usb/usba/usba_ugen.h>
440Sstevel@tonic-gate #include <sys/usb/clients/ugen/ugend.h>
450Sstevel@tonic-gate
460Sstevel@tonic-gate /* Global variables */
470Sstevel@tonic-gate static void *ugen_skel_statep;
480Sstevel@tonic-gate
490Sstevel@tonic-gate /* Prototypes declarations for the entry points */
500Sstevel@tonic-gate static int ugen_skel_getinfo(dev_info_t *, ddi_info_cmd_t,
510Sstevel@tonic-gate void *, void **);
520Sstevel@tonic-gate static int ugen_skel_open(dev_t *, int, int, cred_t *);
530Sstevel@tonic-gate static int ugen_skel_close(dev_t, int, int, cred_t *);
540Sstevel@tonic-gate static int ugen_skel_attach(dev_info_t *, ddi_attach_cmd_t);
550Sstevel@tonic-gate static int ugen_skel_detach(dev_info_t *, ddi_detach_cmd_t);
560Sstevel@tonic-gate static int ugen_skel_power(dev_info_t *, int, int);
570Sstevel@tonic-gate static int ugen_skel_read(dev_t, struct uio *, cred_t *);
580Sstevel@tonic-gate static int ugen_skel_write(dev_t, struct uio *, cred_t *);
590Sstevel@tonic-gate static int ugen_skel_poll(dev_t, short, int, short *,
600Sstevel@tonic-gate struct pollhead **);
610Sstevel@tonic-gate
620Sstevel@tonic-gate static int ugen_skel_disconnect_ev_cb(dev_info_t *);
630Sstevel@tonic-gate static int ugen_skel_reconnect_ev_cb(dev_info_t *);
640Sstevel@tonic-gate
650Sstevel@tonic-gate /* event support */
660Sstevel@tonic-gate static usb_event_t ugen_skel_events = {
670Sstevel@tonic-gate ugen_skel_disconnect_ev_cb,
680Sstevel@tonic-gate ugen_skel_reconnect_ev_cb,
690Sstevel@tonic-gate NULL, NULL
700Sstevel@tonic-gate };
710Sstevel@tonic-gate
720Sstevel@tonic-gate /* Driver cb_ops structure */
730Sstevel@tonic-gate static struct cb_ops ugen_skel_cb_ops = {
740Sstevel@tonic-gate ugen_skel_open, /* open */
750Sstevel@tonic-gate ugen_skel_close, /* close */
760Sstevel@tonic-gate nodev, /* strategy */
770Sstevel@tonic-gate nodev, /* print */
780Sstevel@tonic-gate nodev, /* dump */
790Sstevel@tonic-gate ugen_skel_read, /* read */
800Sstevel@tonic-gate ugen_skel_write, /* write */
810Sstevel@tonic-gate nodev, /* ioctl */
820Sstevel@tonic-gate nodev, /* devmap */
830Sstevel@tonic-gate nodev, /* mmap */
840Sstevel@tonic-gate nodev, /* segmap */
850Sstevel@tonic-gate ugen_skel_poll, /* poll */
860Sstevel@tonic-gate ddi_prop_op, /* cb_prop_op */
870Sstevel@tonic-gate 0, /* streamtab */
880Sstevel@tonic-gate D_MP, /* Driver compatibility flag */
890Sstevel@tonic-gate CB_REV, /* revision */
900Sstevel@tonic-gate nodev, /* aread */
910Sstevel@tonic-gate nodev /* awrite */
920Sstevel@tonic-gate };
930Sstevel@tonic-gate
940Sstevel@tonic-gate /*
950Sstevel@tonic-gate * Modloading support
960Sstevel@tonic-gate * driver dev_ops structure
970Sstevel@tonic-gate */
980Sstevel@tonic-gate static struct dev_ops ugen_skel_ops = {
990Sstevel@tonic-gate DEVO_REV, /* devo_rev, */
1000Sstevel@tonic-gate 0, /* refct */
1010Sstevel@tonic-gate ugen_skel_getinfo, /* info */
1020Sstevel@tonic-gate nulldev, /* indetify */
1030Sstevel@tonic-gate nulldev, /* probe */
1040Sstevel@tonic-gate ugen_skel_attach, /* attach */
1050Sstevel@tonic-gate ugen_skel_detach, /* detach */
1060Sstevel@tonic-gate nodev, /* reset */
1070Sstevel@tonic-gate &ugen_skel_cb_ops, /* driver operations */
1080Sstevel@tonic-gate NULL, /* bus operations */
1097656SSherry.Moore@Sun.COM ugen_skel_power, /* power */
110*8688SRaymond.Chen@Sun.COM ddi_quiesce_not_needed, /* devo_quiesce */
1110Sstevel@tonic-gate };
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate static struct modldrv modldrv = {
1140Sstevel@tonic-gate &mod_driverops, /* Module type */
1157425SGongtian.Zhao@Sun.COM "USB Generic driver", /* Name of the module. */
1160Sstevel@tonic-gate &ugen_skel_ops, /* driver ops */
1170Sstevel@tonic-gate };
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate static struct modlinkage modlinkage = {
1200Sstevel@tonic-gate MODREV_1,
1210Sstevel@tonic-gate (void *)&modldrv,
1220Sstevel@tonic-gate NULL
1230Sstevel@tonic-gate };
1240Sstevel@tonic-gate
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate int
_init()1270Sstevel@tonic-gate _init()
1280Sstevel@tonic-gate {
1290Sstevel@tonic-gate int rval;
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate if ((rval = ddi_soft_state_init(&ugen_skel_statep,
1327425SGongtian.Zhao@Sun.COM sizeof (ugen_skel_state_t), UGEN_INSTANCES)) != 0) {
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate return (rval);
1350Sstevel@tonic-gate }
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate if ((rval = mod_install(&modlinkage)) != 0) {
1380Sstevel@tonic-gate ddi_soft_state_fini(&ugen_skel_statep);
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate return (rval);
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate return (rval);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate int
_fini()1480Sstevel@tonic-gate _fini()
1490Sstevel@tonic-gate {
1500Sstevel@tonic-gate int rval;
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate if ((rval = mod_remove(&modlinkage)) != 0) {
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate return (rval);
1550Sstevel@tonic-gate }
1560Sstevel@tonic-gate ddi_soft_state_fini(&ugen_skel_statep);
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate return (rval);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate int
_info(struct modinfo * modinfop)1630Sstevel@tonic-gate _info(struct modinfo *modinfop)
1640Sstevel@tonic-gate {
1650Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop));
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate /*ARGSUSED*/
1700Sstevel@tonic-gate static int
ugen_skel_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)1710Sstevel@tonic-gate ugen_skel_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
1720Sstevel@tonic-gate void **result)
1730Sstevel@tonic-gate {
1740Sstevel@tonic-gate int rval = DDI_FAILURE;
1750Sstevel@tonic-gate int instance =
1767425SGongtian.Zhao@Sun.COM UGEN_MINOR_TO_INSTANCE(getminor((dev_t)arg));
1770Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp;
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate switch (infocmd) {
1800Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO:
1810Sstevel@tonic-gate ugen_skelp = ddi_get_soft_state(ugen_skel_statep, instance);
1820Sstevel@tonic-gate if (ugen_skelp != NULL) {
1830Sstevel@tonic-gate *result = ugen_skelp->ugen_skel_dip;
1840Sstevel@tonic-gate if (*result != NULL) {
1850Sstevel@tonic-gate rval = DDI_SUCCESS;
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate } else {
1880Sstevel@tonic-gate *result = NULL;
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate break;
1920Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE:
1930Sstevel@tonic-gate *result = (void *)(uintptr_t)instance;
1940Sstevel@tonic-gate rval = DDI_SUCCESS;
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate break;
1970Sstevel@tonic-gate default:
1980Sstevel@tonic-gate
1990Sstevel@tonic-gate break;
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate return (rval);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate /*
2070Sstevel@tonic-gate * ugen_skel_attach()
2080Sstevel@tonic-gate */
2090Sstevel@tonic-gate static int
ugen_skel_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)2100Sstevel@tonic-gate ugen_skel_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2110Sstevel@tonic-gate {
2120Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp;
2130Sstevel@tonic-gate int instance; /* Driver instance number */
2140Sstevel@tonic-gate int rval;
2150Sstevel@tonic-gate usb_ugen_info_t usb_ugen_info;
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate /* Get instance number */
2180Sstevel@tonic-gate instance = ddi_get_instance(dip);
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate switch (cmd) {
2210Sstevel@tonic-gate case DDI_ATTACH:
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate break;
2240Sstevel@tonic-gate case DDI_RESUME:
2250Sstevel@tonic-gate ugen_skelp = ddi_get_soft_state(ugen_skel_statep, instance);
2260Sstevel@tonic-gate if (ugen_skelp == NULL) {
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate return (DDI_FAILURE);
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate rval = usb_ugen_attach(ugen_skelp->ugen_skel_hdl, cmd);
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE);
2340Sstevel@tonic-gate default:
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate return (DDI_FAILURE);
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate
2390Sstevel@tonic-gate if (ddi_soft_state_zalloc(ugen_skel_statep, instance) ==
2400Sstevel@tonic-gate DDI_SUCCESS) {
2410Sstevel@tonic-gate ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
2427425SGongtian.Zhao@Sun.COM instance);
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate if (ugen_skelp == NULL) {
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate return (DDI_FAILURE);
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate if ((rval = usb_client_attach(dip, USBDRV_VERSION, 0)) !=
2500Sstevel@tonic-gate USB_SUCCESS) {
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate goto fail;
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate ugen_skelp->ugen_skel_dip = dip;
2560Sstevel@tonic-gate ugen_skelp->ugen_skel_instance = instance;
2570Sstevel@tonic-gate
2580Sstevel@tonic-gate /* get a ugen handle */
2590Sstevel@tonic-gate bzero(&usb_ugen_info, sizeof (usb_ugen_info));
2600Sstevel@tonic-gate usb_ugen_info.usb_ugen_flags =
2617425SGongtian.Zhao@Sun.COM USB_UGEN_ENABLE_PM | USB_UGEN_REMOVE_CHILDREN;
2620Sstevel@tonic-gate usb_ugen_info.usb_ugen_minor_node_ugen_bits_mask =
2637425SGongtian.Zhao@Sun.COM (dev_t)UGEN_MINOR_UGEN_BITS_MASK;
2640Sstevel@tonic-gate usb_ugen_info.usb_ugen_minor_node_instance_mask =
2657425SGongtian.Zhao@Sun.COM (dev_t)~UGEN_MINOR_UGEN_BITS_MASK;
2660Sstevel@tonic-gate ugen_skelp->ugen_skel_hdl = usb_ugen_get_hdl(dip,
2677425SGongtian.Zhao@Sun.COM &usb_ugen_info);
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate if (usb_ugen_attach(ugen_skelp->ugen_skel_hdl, cmd) != USB_SUCCESS) {
2700Sstevel@tonic-gate
2717425SGongtian.Zhao@Sun.COM goto fail;
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate /* register for hotplug events */
2750Sstevel@tonic-gate if (usb_register_event_cbs(dip, &ugen_skel_events, 0) != USB_SUCCESS) {
2760Sstevel@tonic-gate
2777425SGongtian.Zhao@Sun.COM goto fail;
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate ddi_report_dev(dip);
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate return (DDI_SUCCESS);
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate fail:
2850Sstevel@tonic-gate if (ugen_skelp) {
2860Sstevel@tonic-gate usb_unregister_event_cbs(dip, &ugen_skel_events);
2870Sstevel@tonic-gate usb_ugen_release_hdl(ugen_skelp->
2887425SGongtian.Zhao@Sun.COM ugen_skel_hdl);
2890Sstevel@tonic-gate ddi_soft_state_free(ugen_skel_statep,
2907425SGongtian.Zhao@Sun.COM ugen_skelp->ugen_skel_instance);
2910Sstevel@tonic-gate usb_client_detach(dip, NULL);
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate return (DDI_FAILURE);
2950Sstevel@tonic-gate }
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate
2980Sstevel@tonic-gate /*
2990Sstevel@tonic-gate * ugen_skel_detach()
3000Sstevel@tonic-gate */
3010Sstevel@tonic-gate static int
ugen_skel_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)3020Sstevel@tonic-gate ugen_skel_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
3030Sstevel@tonic-gate {
3040Sstevel@tonic-gate int rval = USB_FAILURE;
3050Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
3067425SGongtian.Zhao@Sun.COM ddi_get_instance(dip));
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate if (ugen_skelp) {
3090Sstevel@tonic-gate switch (cmd) {
3100Sstevel@tonic-gate case DDI_DETACH:
3110Sstevel@tonic-gate rval = usb_ugen_detach(ugen_skelp->ugen_skel_hdl, cmd);
3120Sstevel@tonic-gate if (rval == USB_SUCCESS) {
3130Sstevel@tonic-gate usb_unregister_event_cbs(dip,
3147425SGongtian.Zhao@Sun.COM &ugen_skel_events);
3150Sstevel@tonic-gate usb_ugen_release_hdl(ugen_skelp->
3167425SGongtian.Zhao@Sun.COM ugen_skel_hdl);
3170Sstevel@tonic-gate ddi_soft_state_free(ugen_skel_statep,
3180Sstevel@tonic-gate ugen_skelp->ugen_skel_instance);
3190Sstevel@tonic-gate usb_client_detach(dip, NULL);
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate
3220Sstevel@tonic-gate break;
3230Sstevel@tonic-gate case DDI_SUSPEND:
3240Sstevel@tonic-gate rval = usb_ugen_detach(ugen_skelp->ugen_skel_hdl, cmd);
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate break;
3270Sstevel@tonic-gate default:
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate break;
3300Sstevel@tonic-gate }
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE);
3340Sstevel@tonic-gate }
3350Sstevel@tonic-gate
3360Sstevel@tonic-gate
3370Sstevel@tonic-gate /*
3380Sstevel@tonic-gate * ugen_skel_disconnect_ev_cb:
3390Sstevel@tonic-gate */
3400Sstevel@tonic-gate static int
ugen_skel_disconnect_ev_cb(dev_info_t * dip)3410Sstevel@tonic-gate ugen_skel_disconnect_ev_cb(dev_info_t *dip)
3420Sstevel@tonic-gate {
3430Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
3447425SGongtian.Zhao@Sun.COM ddi_get_instance(dip));
3450Sstevel@tonic-gate
3460Sstevel@tonic-gate return (usb_ugen_disconnect_ev_cb(ugen_skelp->ugen_skel_hdl));
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate /*
3510Sstevel@tonic-gate * ugen_skel_reconnect_ev_cb:
3520Sstevel@tonic-gate */
3530Sstevel@tonic-gate static int
ugen_skel_reconnect_ev_cb(dev_info_t * dip)3540Sstevel@tonic-gate ugen_skel_reconnect_ev_cb(dev_info_t *dip)
3550Sstevel@tonic-gate {
3560Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
3577425SGongtian.Zhao@Sun.COM ddi_get_instance(dip));
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate return (usb_ugen_reconnect_ev_cb(ugen_skelp->ugen_skel_hdl));
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate /*
3640Sstevel@tonic-gate * ugen_skel_open:
3650Sstevel@tonic-gate */
3660Sstevel@tonic-gate static int
ugen_skel_open(dev_t * devp,int flag,int sflag,cred_t * cr)3670Sstevel@tonic-gate ugen_skel_open(dev_t *devp, int flag, int sflag, cred_t *cr)
3680Sstevel@tonic-gate {
3690Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp;
3700Sstevel@tonic-gate
3710Sstevel@tonic-gate if ((ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
3720Sstevel@tonic-gate UGEN_MINOR_TO_INSTANCE(getminor(*devp)))) == NULL) {
3730Sstevel@tonic-gate /* deferred detach */
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate return (ENXIO);
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate return (usb_ugen_open(ugen_skelp->ugen_skel_hdl, devp, flag,
3797425SGongtian.Zhao@Sun.COM sflag, cr));
3800Sstevel@tonic-gate }
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate
3830Sstevel@tonic-gate /*
3840Sstevel@tonic-gate * ugen_skel_close()
3850Sstevel@tonic-gate */
3860Sstevel@tonic-gate static int
ugen_skel_close(dev_t dev,int flag,int otype,cred_t * cr)3870Sstevel@tonic-gate ugen_skel_close(dev_t dev, int flag, int otype, cred_t *cr)
3880Sstevel@tonic-gate {
3890Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
3907425SGongtian.Zhao@Sun.COM UGEN_MINOR_TO_INSTANCE(getminor(dev)));
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate return (usb_ugen_close(ugen_skelp->ugen_skel_hdl, dev, flag,
3937425SGongtian.Zhao@Sun.COM otype, cr));
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate /*
3980Sstevel@tonic-gate * ugen_skel_read/write()
3990Sstevel@tonic-gate */
4000Sstevel@tonic-gate static int
ugen_skel_read(dev_t dev,struct uio * uiop,cred_t * credp)4010Sstevel@tonic-gate ugen_skel_read(dev_t dev, struct uio *uiop, cred_t *credp)
4020Sstevel@tonic-gate {
4030Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
4047425SGongtian.Zhao@Sun.COM UGEN_MINOR_TO_INSTANCE(getminor(dev)));
4050Sstevel@tonic-gate if (ugen_skelp == NULL) {
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate return (ENXIO);
4080Sstevel@tonic-gate }
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate return (usb_ugen_read(ugen_skelp->ugen_skel_hdl, dev,
4117425SGongtian.Zhao@Sun.COM uiop, credp));
4120Sstevel@tonic-gate }
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate
4150Sstevel@tonic-gate static int
ugen_skel_write(dev_t dev,struct uio * uiop,cred_t * credp)4160Sstevel@tonic-gate ugen_skel_write(dev_t dev, struct uio *uiop, cred_t *credp)
4170Sstevel@tonic-gate {
4180Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
4197425SGongtian.Zhao@Sun.COM UGEN_MINOR_TO_INSTANCE(getminor(dev)));
4200Sstevel@tonic-gate if (ugen_skelp == NULL) {
4210Sstevel@tonic-gate
4220Sstevel@tonic-gate return (ENXIO);
4230Sstevel@tonic-gate }
4240Sstevel@tonic-gate return (usb_ugen_write(ugen_skelp->ugen_skel_hdl,
4257425SGongtian.Zhao@Sun.COM dev, uiop, credp));
4260Sstevel@tonic-gate }
4270Sstevel@tonic-gate
4280Sstevel@tonic-gate
4290Sstevel@tonic-gate /*
4300Sstevel@tonic-gate * ugen_skel_poll
4310Sstevel@tonic-gate */
4320Sstevel@tonic-gate static int
ugen_skel_poll(dev_t dev,short events,int anyyet,short * reventsp,struct pollhead ** phpp)4330Sstevel@tonic-gate ugen_skel_poll(dev_t dev, short events,
4340Sstevel@tonic-gate int anyyet, short *reventsp, struct pollhead **phpp)
4350Sstevel@tonic-gate {
4360Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
4377425SGongtian.Zhao@Sun.COM UGEN_MINOR_TO_INSTANCE(getminor(dev)));
4380Sstevel@tonic-gate if (ugen_skelp == NULL) {
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate return (ENXIO);
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate return (usb_ugen_poll(ugen_skelp->ugen_skel_hdl, dev, events,
4447425SGongtian.Zhao@Sun.COM anyyet, reventsp, phpp));
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate
4480Sstevel@tonic-gate /*
4490Sstevel@tonic-gate * ugen_skel_power:
4500Sstevel@tonic-gate * PM entry point
4510Sstevel@tonic-gate */
4520Sstevel@tonic-gate static int
ugen_skel_power(dev_info_t * dip,int comp,int level)4530Sstevel@tonic-gate ugen_skel_power(dev_info_t *dip, int comp, int level)
4540Sstevel@tonic-gate {
4550Sstevel@tonic-gate int rval;
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate ugen_skel_state_t *ugen_skelp = ddi_get_soft_state(ugen_skel_statep,
4587425SGongtian.Zhao@Sun.COM ddi_get_instance(dip));
4590Sstevel@tonic-gate if (ugen_skelp == NULL) {
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate return (DDI_FAILURE);
4620Sstevel@tonic-gate }
4630Sstevel@tonic-gate rval = usb_ugen_power(ugen_skelp->ugen_skel_hdl, comp, level);
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate return (rval == USB_SUCCESS ? DDI_SUCCESS : DDI_FAILURE);
4660Sstevel@tonic-gate }
467