14de26129Sxs /*
24de26129Sxs  * CDDL HEADER START
34de26129Sxs  *
44de26129Sxs  * The contents of this file are subject to the terms of the
577e51571Sgongtian zhao - Sun Microsystems - Beijing China  * Common Development and Distribution License (the "License").
677e51571Sgongtian zhao - Sun Microsystems - Beijing China  * You may not use this file except in compliance with the License.
74de26129Sxs  *
84de26129Sxs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94de26129Sxs  * or http://www.opensolaris.org/os/licensing.
104de26129Sxs  * See the License for the specific language governing permissions
114de26129Sxs  * and limitations under the License.
124de26129Sxs  *
134de26129Sxs  * When distributing Covered Code, include this CDDL HEADER in each
144de26129Sxs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154de26129Sxs  * If applicable, add the following below this CDDL HEADER, with the
164de26129Sxs  * fields enclosed by brackets "[]" replaced with your own identifying
174de26129Sxs  * information: Portions Copyright [yyyy] [name of copyright owner]
184de26129Sxs  *
194de26129Sxs  * CDDL HEADER END
204de26129Sxs  */
214de26129Sxs /*
22*be529ebcSRaymond Chen  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
234de26129Sxs  * Use is subject to license terms.
244de26129Sxs  */
254de26129Sxs 
264de26129Sxs 
274de26129Sxs /*
284de26129Sxs  * This driver supports Prolific PL-2303H/HX/X USB-to-serial adapters. It is a
294de26129Sxs  * device-specific driver (DSD) working with USB generic serial driver (GSD). It
304de26129Sxs  * implements the USB-to-serial device-specific driver interface (DSDI) which is
314de26129Sxs  * offered by GSD. The interface is defined by ds_ops_t structure.
324de26129Sxs  *
334de26129Sxs  *
344de26129Sxs  * PL-2303HX and PL-2303X devices have different hardware, but from the
354de26129Sxs  * perspective of device driver, they have the same software interface.
364de26129Sxs  */
374de26129Sxs 
384de26129Sxs /*
394de26129Sxs  *
404de26129Sxs  * USB Prolific PL2303 driver glue code
414de26129Sxs  *
424de26129Sxs  */
434de26129Sxs #include <sys/types.h>
444de26129Sxs #include <sys/param.h>
454de26129Sxs #include <sys/stream.h>
464de26129Sxs #include <sys/conf.h>
474de26129Sxs #include <sys/ddi.h>
484de26129Sxs #include <sys/sunddi.h>
494de26129Sxs 
504de26129Sxs #include <sys/usb/clients/usbser/usbser.h>
514de26129Sxs #include <sys/usb/clients/usbser/usbsprl/pl2303_var.h>
524de26129Sxs 
534de26129Sxs 
544de26129Sxs /* configuration entry points */
554de26129Sxs static int	usbser_pl2303_attach(dev_info_t *, ddi_attach_cmd_t);
564de26129Sxs static int	usbser_pl2303_detach(dev_info_t *, ddi_detach_cmd_t);
574de26129Sxs static int 	usbser_pl2303_getinfo(dev_info_t *, ddi_info_cmd_t, void *,
584de26129Sxs 		void **);
594de26129Sxs static int	usbser_pl2303_open(queue_t *, dev_t *, int, int, cred_t *);
604de26129Sxs static void	*usbser_pl2303_statep;	/* soft state */
614de26129Sxs 
62e8ed0869SJohn Beck extern		ds_ops_t pl2303_ds_ops;	/* DSD operations */
634de26129Sxs 
644de26129Sxs 
654de26129Sxs /*
664de26129Sxs  * STREAMS structures
674de26129Sxs  */
684de26129Sxs struct module_info usbser_pl2303_modinfo = {
694de26129Sxs 	0,			/* module id */
704de26129Sxs 	"usbsprl",		/* module name */
714de26129Sxs 	USBSER_MIN_PKTSZ,	/* min pkt size */
724de26129Sxs 	USBSER_MAX_PKTSZ,	/* max pkt size */
734de26129Sxs 	USBSER_HIWAT,		/* hi watermark */
744de26129Sxs 	USBSER_LOWAT		/* low watermark */
754de26129Sxs };
764de26129Sxs 
774de26129Sxs 
784de26129Sxs static struct qinit usbser_pl2303_rinit = {
794de26129Sxs 	putq,
804de26129Sxs 	usbser_rsrv,
814de26129Sxs 	usbser_pl2303_open,
824de26129Sxs 	usbser_close,
834de26129Sxs 	NULL,
844de26129Sxs 	&usbser_pl2303_modinfo,
854de26129Sxs 	NULL
864de26129Sxs };
874de26129Sxs 
884de26129Sxs 
894de26129Sxs static struct qinit usbser_pl2303_winit = {
904de26129Sxs 	usbser_wput,
914de26129Sxs 	usbser_wsrv,
924de26129Sxs 	NULL,
934de26129Sxs 	NULL,
944de26129Sxs 	NULL,
954de26129Sxs 	&usbser_pl2303_modinfo,
964de26129Sxs 	NULL
974de26129Sxs };
984de26129Sxs 
994de26129Sxs 
1004de26129Sxs struct streamtab usbser_pl2303_str_info = {
1014de26129Sxs 	&usbser_pl2303_rinit, &usbser_pl2303_winit, NULL, NULL
1024de26129Sxs };
1034de26129Sxs 
1044de26129Sxs 
1054de26129Sxs static struct cb_ops usbser_pl2303_cb_ops = {
1064de26129Sxs 	nodev,			/* cb_open */
1074de26129Sxs 	nodev,			/* cb_close */
1084de26129Sxs 	nodev,			/* cb_strategy */
1094de26129Sxs 	nodev,			/* cb_print */
1104de26129Sxs 	nodev,			/* cb_dump */
1114de26129Sxs 	nodev,			/* cb_read */
1124de26129Sxs 	nodev,			/* cb_write */
1134de26129Sxs 	nodev,			/* cb_ioctl */
1144de26129Sxs 	nodev,			/* cb_devmap */
1154de26129Sxs 	nodev,			/* cb_mmap */
1164de26129Sxs 	nodev,			/* cb_segmap */
1174de26129Sxs 	nochpoll,		/* cb_chpoll */
1184de26129Sxs 	ddi_prop_op,		/* cb_prop_op */
1194de26129Sxs 	&usbser_pl2303_str_info,			/* cb_stream */
1204de26129Sxs 	(int)(D_64BIT | D_NEW | D_MP | D_HOTPLUG)	/* cb_flag */
1214de26129Sxs };
1224de26129Sxs 
1234de26129Sxs 
1244de26129Sxs /*
1254de26129Sxs  * auto configuration ops
1264de26129Sxs  */
1274de26129Sxs struct dev_ops usbser_pl2303_ops = {
1284de26129Sxs 	DEVO_REV,		/* devo_rev */
1294de26129Sxs 	0,			/* devo_refcnt */
1304de26129Sxs 	usbser_pl2303_getinfo,	/* devo_getinfo */
1314de26129Sxs 	nulldev,		/* devo_identify */
1324de26129Sxs 	nulldev,		/* devo_probe */
1334de26129Sxs 	usbser_pl2303_attach,	/* devo_attach */
1344de26129Sxs 	usbser_pl2303_detach,	/* devo_detach */
1354de26129Sxs 	nodev,			/* devo_reset */
1364de26129Sxs 	&usbser_pl2303_cb_ops,	/* devo_cb_ops */
1374de26129Sxs 	(struct bus_ops *)NULL,	/* devo_bus_ops */
13819397407SSherry Moore 	usbser_power,		/* devo_power */
139*be529ebcSRaymond Chen 	ddi_quiesce_not_needed,	/* devo_quiesce */
1404de26129Sxs };
1414de26129Sxs 
1424de26129Sxs 
1434de26129Sxs extern struct mod_ops mod_driverops;
1444de26129Sxs 
1454de26129Sxs 
1464de26129Sxs static struct modldrv modldrv = {
1474de26129Sxs 	&mod_driverops,		/* type of module - driver */
14819397407SSherry Moore 	"USB Prolific PL2303 driver",
1494de26129Sxs 	&usbser_pl2303_ops,
1504de26129Sxs };
1514de26129Sxs 
1524de26129Sxs 
1534de26129Sxs static struct modlinkage modlinkage = {
1544de26129Sxs 	MODREV_1, &modldrv, 0
1554de26129Sxs };
1564de26129Sxs 
1574de26129Sxs 
1584de26129Sxs /*
1594de26129Sxs  * entry points
1604de26129Sxs  * ------------
1614de26129Sxs  *
1624de26129Sxs  */
1634de26129Sxs int
_init(void)1644de26129Sxs _init(void)
1654de26129Sxs {
1664de26129Sxs 	int    error;
1674de26129Sxs 
1684de26129Sxs 	if ((error = mod_install(&modlinkage)) == 0) {
1694de26129Sxs 		error = ddi_soft_state_init(&usbser_pl2303_statep,
17077e51571Sgongtian zhao - Sun Microsystems - Beijing China 		    usbser_soft_state_size(), 1);
1714de26129Sxs 	}
1724de26129Sxs 
1734de26129Sxs 	return (error);
1744de26129Sxs }
1754de26129Sxs 
1764de26129Sxs 
1774de26129Sxs int
_fini(void)1784de26129Sxs _fini(void)
1794de26129Sxs {
1804de26129Sxs 	int    error;
1814de26129Sxs 
1824de26129Sxs 	if ((error = mod_remove(&modlinkage)) == 0) {
1834de26129Sxs 		ddi_soft_state_fini(&usbser_pl2303_statep);
1844de26129Sxs 	}
1854de26129Sxs 
1864de26129Sxs 	return (error);
1874de26129Sxs }
1884de26129Sxs 
1894de26129Sxs 
1904de26129Sxs int
_info(struct modinfo * modinfop)1914de26129Sxs _info(struct modinfo *modinfop)
1924de26129Sxs {
1934de26129Sxs 	return (mod_info(&modlinkage, modinfop));
1944de26129Sxs }
1954de26129Sxs 
1964de26129Sxs 
1974de26129Sxs int
usbser_pl2303_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)1984de26129Sxs usbser_pl2303_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
1994de26129Sxs 		void **result)
2004de26129Sxs {
2014de26129Sxs 	return (usbser_getinfo(dip, infocmd, arg, result,
2024de26129Sxs 	    usbser_pl2303_statep));
2034de26129Sxs }
2044de26129Sxs 
2054de26129Sxs 
2064de26129Sxs static int
usbser_pl2303_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)2074de26129Sxs usbser_pl2303_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2084de26129Sxs {
209e8ed0869SJohn Beck 	return (usbser_attach(dip, cmd, usbser_pl2303_statep, &pl2303_ds_ops));
2104de26129Sxs }
2114de26129Sxs 
2124de26129Sxs 
2134de26129Sxs static int
usbser_pl2303_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)2144de26129Sxs usbser_pl2303_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
2154de26129Sxs {
2164de26129Sxs 	return (usbser_detach(dip, cmd, usbser_pl2303_statep));
2174de26129Sxs }
2184de26129Sxs 
2194de26129Sxs 
2204de26129Sxs static int
usbser_pl2303_open(queue_t * rq,dev_t * dev,int flag,int sflag,cred_t * cr)2214de26129Sxs usbser_pl2303_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
2224de26129Sxs {
2234de26129Sxs 	return (usbser_open(rq, dev, flag, sflag, cr, usbser_pl2303_statep));
2244de26129Sxs }
225