1*de81e71eSTim Marsland /*
2*de81e71eSTim Marsland  * CDDL HEADER START
3*de81e71eSTim Marsland  *
4*de81e71eSTim Marsland  * The contents of this file are subject to the terms of the
5*de81e71eSTim Marsland  * Common Development and Distribution License (the "License").
6*de81e71eSTim Marsland  * You may not use this file except in compliance with the License.
7*de81e71eSTim Marsland  *
8*de81e71eSTim Marsland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*de81e71eSTim Marsland  * or http://www.opensolaris.org/os/licensing.
10*de81e71eSTim Marsland  * See the License for the specific language governing permissions
11*de81e71eSTim Marsland  * and limitations under the License.
12*de81e71eSTim Marsland  *
13*de81e71eSTim Marsland  * When distributing Covered Code, include this CDDL HEADER in each
14*de81e71eSTim Marsland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*de81e71eSTim Marsland  * If applicable, add the following below this CDDL HEADER, with the
16*de81e71eSTim Marsland  * fields enclosed by brackets "[]" replaced with your own identifying
17*de81e71eSTim Marsland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*de81e71eSTim Marsland  *
19*de81e71eSTim Marsland  * CDDL HEADER END
20*de81e71eSTim Marsland  */
21*de81e71eSTim Marsland 
22*de81e71eSTim Marsland /*
23*de81e71eSTim Marsland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*de81e71eSTim Marsland  * Use is subject to license terms.
25*de81e71eSTim Marsland  */
26*de81e71eSTim Marsland 
27*de81e71eSTim Marsland /*
28*de81e71eSTim Marsland  * This driver supports FTDI FT232R USB-to-serial adapters. It is a
29*de81e71eSTim Marsland  * device-specific driver (DSD) working with the USB generic serial
30*de81e71eSTim Marsland  * driver (GSD) usbser.
31*de81e71eSTim Marsland  *
32*de81e71eSTim Marsland  * It implements the USB-to-serial device-specific driver interface (DSDI)
33*de81e71eSTim Marsland  * which is exported by GSD. The DSDI is defined by ds_ops_t structure.
34*de81e71eSTim Marsland  *
35*de81e71eSTim Marsland  * Also may work with the older FTDI 8U232AM devices.
36*de81e71eSTim Marsland  */
37*de81e71eSTim Marsland 
38*de81e71eSTim Marsland #include <sys/types.h>
39*de81e71eSTim Marsland #include <sys/param.h>
40*de81e71eSTim Marsland #include <sys/stream.h>
41*de81e71eSTim Marsland #include <sys/conf.h>
42*de81e71eSTim Marsland #include <sys/ddi.h>
43*de81e71eSTim Marsland #include <sys/sunddi.h>
44*de81e71eSTim Marsland 
45*de81e71eSTim Marsland #include <sys/usb/clients/usbser/usbser.h>
46*de81e71eSTim Marsland #include <sys/usb/clients/usbser/usbftdi/uftdi_var.h>
47*de81e71eSTim Marsland 
48*de81e71eSTim Marsland static void *usbser_uftdi_statep;	/* soft state handle for usbser */
49*de81e71eSTim Marsland 
50*de81e71eSTim Marsland extern ds_ops_t uftdi_ds_ops;	/* DSD operations */
51*de81e71eSTim Marsland 
52*de81e71eSTim Marsland static int
usbser_uftdi_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)53*de81e71eSTim Marsland usbser_uftdi_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
54*de81e71eSTim Marsland     void **result)
55*de81e71eSTim Marsland {
56*de81e71eSTim Marsland 	return (usbser_getinfo(dip, infocmd, arg, result, usbser_uftdi_statep));
57*de81e71eSTim Marsland }
58*de81e71eSTim Marsland 
59*de81e71eSTim Marsland 
60*de81e71eSTim Marsland static int
usbser_uftdi_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)61*de81e71eSTim Marsland usbser_uftdi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
62*de81e71eSTim Marsland {
63*de81e71eSTim Marsland 	return (usbser_attach(dip, cmd, usbser_uftdi_statep, &uftdi_ds_ops));
64*de81e71eSTim Marsland }
65*de81e71eSTim Marsland 
66*de81e71eSTim Marsland 
67*de81e71eSTim Marsland static int
usbser_uftdi_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)68*de81e71eSTim Marsland usbser_uftdi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
69*de81e71eSTim Marsland {
70*de81e71eSTim Marsland 	return (usbser_detach(dip, cmd, usbser_uftdi_statep));
71*de81e71eSTim Marsland }
72*de81e71eSTim Marsland 
73*de81e71eSTim Marsland 
74*de81e71eSTim Marsland static int
usbser_uftdi_open(queue_t * rq,dev_t * dev,int flag,int sflag,cred_t * cr)75*de81e71eSTim Marsland usbser_uftdi_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
76*de81e71eSTim Marsland {
77*de81e71eSTim Marsland 	return (usbser_open(rq, dev, flag, sflag, cr, usbser_uftdi_statep));
78*de81e71eSTim Marsland }
79*de81e71eSTim Marsland 
80*de81e71eSTim Marsland /*
81*de81e71eSTim Marsland  * Several linked data structures to tie it together ..
82*de81e71eSTim Marsland  */
83*de81e71eSTim Marsland struct module_info uftdi_modinfo = {
84*de81e71eSTim Marsland 	0,			/* module id */
85*de81e71eSTim Marsland 	"uftdi",		/* module name */
86*de81e71eSTim Marsland 	USBSER_MIN_PKTSZ,	/* min pkt size */
87*de81e71eSTim Marsland 	USBSER_MAX_PKTSZ,	/* max pkt size */
88*de81e71eSTim Marsland 	USBSER_HIWAT,		/* hi watermark */
89*de81e71eSTim Marsland 	USBSER_LOWAT		/* low watermark */
90*de81e71eSTim Marsland };
91*de81e71eSTim Marsland 
92*de81e71eSTim Marsland static struct qinit uftdi_rinit = {
93*de81e71eSTim Marsland 	putq,
94*de81e71eSTim Marsland 	usbser_rsrv,
95*de81e71eSTim Marsland 	usbser_uftdi_open,
96*de81e71eSTim Marsland 	usbser_close,
97*de81e71eSTim Marsland 	NULL,
98*de81e71eSTim Marsland 	&uftdi_modinfo,
99*de81e71eSTim Marsland };
100*de81e71eSTim Marsland 
101*de81e71eSTim Marsland static struct qinit uftdi_winit = {
102*de81e71eSTim Marsland 	usbser_wput,
103*de81e71eSTim Marsland 	usbser_wsrv,
104*de81e71eSTim Marsland 	NULL,
105*de81e71eSTim Marsland 	NULL,
106*de81e71eSTim Marsland 	NULL,
107*de81e71eSTim Marsland 	&uftdi_modinfo,
108*de81e71eSTim Marsland };
109*de81e71eSTim Marsland 
110*de81e71eSTim Marsland static struct streamtab uftdi_str_info = {
111*de81e71eSTim Marsland 	&uftdi_rinit,
112*de81e71eSTim Marsland 	&uftdi_winit,
113*de81e71eSTim Marsland };
114*de81e71eSTim Marsland 
115*de81e71eSTim Marsland static struct cb_ops uftdi_cb_ops = {
116*de81e71eSTim Marsland 	nodev,			/* cb_open */
117*de81e71eSTim Marsland 	nodev,			/* cb_close */
118*de81e71eSTim Marsland 	nodev,			/* cb_strategy */
119*de81e71eSTim Marsland 	nodev,			/* cb_print */
120*de81e71eSTim Marsland 	nodev,			/* cb_dump */
121*de81e71eSTim Marsland 	nodev,			/* cb_read */
122*de81e71eSTim Marsland 	nodev,			/* cb_write */
123*de81e71eSTim Marsland 	nodev,			/* cb_ioctl */
124*de81e71eSTim Marsland 	nodev,			/* cb_devmap */
125*de81e71eSTim Marsland 	nodev,			/* cb_mmap */
126*de81e71eSTim Marsland 	nodev,			/* cb_segmap */
127*de81e71eSTim Marsland 	nochpoll,		/* cb_chpoll */
128*de81e71eSTim Marsland 	ddi_prop_op,		/* cb_prop_op */
129*de81e71eSTim Marsland 	&uftdi_str_info,	/* cb_stream */
130*de81e71eSTim Marsland 	(int)(D_64BIT | D_NEW | D_MP | D_HOTPLUG)	/* cb_flag */
131*de81e71eSTim Marsland };
132*de81e71eSTim Marsland 
133*de81e71eSTim Marsland static struct dev_ops uftdi_ops = {
134*de81e71eSTim Marsland 	DEVO_REV,		/* devo_rev */
135*de81e71eSTim Marsland 	0,			/* devo_refcnt */
136*de81e71eSTim Marsland 	usbser_uftdi_getinfo,
137*de81e71eSTim Marsland 	nulldev,		/* devo_identify */
138*de81e71eSTim Marsland 	nulldev,		/* devo_probe */
139*de81e71eSTim Marsland 	usbser_uftdi_attach,
140*de81e71eSTim Marsland 	usbser_uftdi_detach,
141*de81e71eSTim Marsland 	nodev,			/* devo_reset */
142*de81e71eSTim Marsland 	&uftdi_cb_ops,
143*de81e71eSTim Marsland 	(struct bus_ops *)NULL,	/* devo_bus_ops */
144*de81e71eSTim Marsland 	usbser_power,		/* devo_power */
145*de81e71eSTim Marsland 	ddi_quiesce_not_needed
146*de81e71eSTim Marsland };
147*de81e71eSTim Marsland 
148*de81e71eSTim Marsland static struct modldrv modldrv = {
149*de81e71eSTim Marsland 	&mod_driverops,
150*de81e71eSTim Marsland 	"FTDI FT232R USB UART driver",
151*de81e71eSTim Marsland 	&uftdi_ops,
152*de81e71eSTim Marsland };
153*de81e71eSTim Marsland 
154*de81e71eSTim Marsland static struct modlinkage modlinkage = {
155*de81e71eSTim Marsland 	MODREV_1,
156*de81e71eSTim Marsland 	&modldrv
157*de81e71eSTim Marsland };
158*de81e71eSTim Marsland 
159*de81e71eSTim Marsland int
_init(void)160*de81e71eSTim Marsland _init(void)
161*de81e71eSTim Marsland {
162*de81e71eSTim Marsland 	int error;
163*de81e71eSTim Marsland 
164*de81e71eSTim Marsland 	if ((error = mod_install(&modlinkage)) != 0)
165*de81e71eSTim Marsland 		return (error);
166*de81e71eSTim Marsland 	if ((error = ddi_soft_state_init(&usbser_uftdi_statep,
167*de81e71eSTim Marsland 	    usbser_soft_state_size(), 1)) != 0)
168*de81e71eSTim Marsland 		(void) mod_remove(&modlinkage);
169*de81e71eSTim Marsland 	return (error);
170*de81e71eSTim Marsland }
171*de81e71eSTim Marsland 
172*de81e71eSTim Marsland 
173*de81e71eSTim Marsland int
_fini(void)174*de81e71eSTim Marsland _fini(void)
175*de81e71eSTim Marsland {
176*de81e71eSTim Marsland 	int error;
177*de81e71eSTim Marsland 
178*de81e71eSTim Marsland 	if ((error = mod_remove(&modlinkage)) == 0)
179*de81e71eSTim Marsland 		ddi_soft_state_fini(&usbser_uftdi_statep);
180*de81e71eSTim Marsland 	return (error);
181*de81e71eSTim Marsland }
182*de81e71eSTim Marsland 
183*de81e71eSTim Marsland 
184*de81e71eSTim Marsland int
_info(struct modinfo * modinfop)185*de81e71eSTim Marsland _info(struct modinfo *modinfop)
186*de81e71eSTim Marsland {
187*de81e71eSTim Marsland 	return (mod_info(&modlinkage, modinfop));
188*de81e71eSTim Marsland }
189