Home | History | Annotate | Download | only in usbsprl
      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  * This driver supports Prolific PL-2303H/HX/X USB-to-serial adapters. It is a
     29  * device-specific driver (DSD) working with USB generic serial driver (GSD). It
     30  * implements the USB-to-serial device-specific driver interface (DSDI) which is
     31  * offered by GSD. The interface is defined by ds_ops_t structure.
     32  *
     33  *
     34  * PL-2303HX and PL-2303X devices have different hardware, but from the
     35  * perspective of device driver, they have the same software interface.
     36  */
     37 
     38 /*
     39  *
     40  * USB Prolific PL2303 driver glue code
     41  *
     42  */
     43 #include <sys/types.h>
     44 #include <sys/param.h>
     45 #include <sys/stream.h>
     46 #include <sys/conf.h>
     47 #include <sys/ddi.h>
     48 #include <sys/sunddi.h>
     49 
     50 #include <sys/usb/clients/usbser/usbser.h>
     51 #include <sys/usb/clients/usbser/usbsprl/pl2303_var.h>
     52 
     53 
     54 /* configuration entry points */
     55 static int	usbser_pl2303_attach(dev_info_t *, ddi_attach_cmd_t);
     56 static int	usbser_pl2303_detach(dev_info_t *, ddi_detach_cmd_t);
     57 static int 	usbser_pl2303_getinfo(dev_info_t *, ddi_info_cmd_t, void *,
     58 		void **);
     59 static int	usbser_pl2303_open(queue_t *, dev_t *, int, int, cred_t *);
     60 static void	*usbser_pl2303_statep;	/* soft state */
     61 
     62 extern		ds_ops_t pl2303_ds_ops;	/* DSD operations */
     63 
     64 
     65 /*
     66  * STREAMS structures
     67  */
     68 struct module_info usbser_pl2303_modinfo = {
     69 	0,			/* module id */
     70 	"usbsprl",		/* module name */
     71 	USBSER_MIN_PKTSZ,	/* min pkt size */
     72 	USBSER_MAX_PKTSZ,	/* max pkt size */
     73 	USBSER_HIWAT,		/* hi watermark */
     74 	USBSER_LOWAT		/* low watermark */
     75 };
     76 
     77 
     78 static struct qinit usbser_pl2303_rinit = {
     79 	putq,
     80 	usbser_rsrv,
     81 	usbser_pl2303_open,
     82 	usbser_close,
     83 	NULL,
     84 	&usbser_pl2303_modinfo,
     85 	NULL
     86 };
     87 
     88 
     89 static struct qinit usbser_pl2303_winit = {
     90 	usbser_wput,
     91 	usbser_wsrv,
     92 	NULL,
     93 	NULL,
     94 	NULL,
     95 	&usbser_pl2303_modinfo,
     96 	NULL
     97 };
     98 
     99 
    100 struct streamtab usbser_pl2303_str_info = {
    101 	&usbser_pl2303_rinit, &usbser_pl2303_winit, NULL, NULL
    102 };
    103 
    104 
    105 static struct cb_ops usbser_pl2303_cb_ops = {
    106 	nodev,			/* cb_open */
    107 	nodev,			/* cb_close */
    108 	nodev,			/* cb_strategy */
    109 	nodev,			/* cb_print */
    110 	nodev,			/* cb_dump */
    111 	nodev,			/* cb_read */
    112 	nodev,			/* cb_write */
    113 	nodev,			/* cb_ioctl */
    114 	nodev,			/* cb_devmap */
    115 	nodev,			/* cb_mmap */
    116 	nodev,			/* cb_segmap */
    117 	nochpoll,		/* cb_chpoll */
    118 	ddi_prop_op,		/* cb_prop_op */
    119 	&usbser_pl2303_str_info,			/* cb_stream */
    120 	(int)(D_64BIT | D_NEW | D_MP | D_HOTPLUG)	/* cb_flag */
    121 };
    122 
    123 
    124 /*
    125  * auto configuration ops
    126  */
    127 struct dev_ops usbser_pl2303_ops = {
    128 	DEVO_REV,		/* devo_rev */
    129 	0,			/* devo_refcnt */
    130 	usbser_pl2303_getinfo,	/* devo_getinfo */
    131 	nulldev,		/* devo_identify */
    132 	nulldev,		/* devo_probe */
    133 	usbser_pl2303_attach,	/* devo_attach */
    134 	usbser_pl2303_detach,	/* devo_detach */
    135 	nodev,			/* devo_reset */
    136 	&usbser_pl2303_cb_ops,	/* devo_cb_ops */
    137 	(struct bus_ops *)NULL,	/* devo_bus_ops */
    138 	usbser_power,		/* devo_power */
    139 	ddi_quiesce_not_needed,	/* devo_quiesce */
    140 };
    141 
    142 
    143 extern struct mod_ops mod_driverops;
    144 
    145 
    146 static struct modldrv modldrv = {
    147 	&mod_driverops,		/* type of module - driver */
    148 	"USB Prolific PL2303 driver",
    149 	&usbser_pl2303_ops,
    150 };
    151 
    152 
    153 static struct modlinkage modlinkage = {
    154 	MODREV_1, &modldrv, 0
    155 };
    156 
    157 
    158 /*
    159  * entry points
    160  * ------------
    161  *
    162  */
    163 int
    164 _init(void)
    165 {
    166 	int    error;
    167 
    168 	if ((error = mod_install(&modlinkage)) == 0) {
    169 		error = ddi_soft_state_init(&usbser_pl2303_statep,
    170 		    usbser_soft_state_size(), 1);
    171 	}
    172 
    173 	return (error);
    174 }
    175 
    176 
    177 int
    178 _fini(void)
    179 {
    180 	int    error;
    181 
    182 	if ((error = mod_remove(&modlinkage)) == 0) {
    183 		ddi_soft_state_fini(&usbser_pl2303_statep);
    184 	}
    185 
    186 	return (error);
    187 }
    188 
    189 
    190 int
    191 _info(struct modinfo *modinfop)
    192 {
    193 	return (mod_info(&modlinkage, modinfop));
    194 }
    195 
    196 
    197 int
    198 usbser_pl2303_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
    199 		void **result)
    200 {
    201 	return (usbser_getinfo(dip, infocmd, arg, result,
    202 	    usbser_pl2303_statep));
    203 }
    204 
    205 
    206 static int
    207 usbser_pl2303_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
    208 {
    209 	return (usbser_attach(dip, cmd, usbser_pl2303_statep, &pl2303_ds_ops));
    210 }
    211 
    212 
    213 static int
    214 usbser_pl2303_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
    215 {
    216 	return (usbser_detach(dip, cmd, usbser_pl2303_statep));
    217 }
    218 
    219 
    220 static int
    221 usbser_pl2303_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
    222 {
    223 	return (usbser_open(rq, dev, flag, sflag, cr, usbser_pl2303_statep));
    224 }
    225