usbser_pl2303.c revision 7656:2621e50fdf4a
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 2008 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 */
55static int	usbser_pl2303_attach(dev_info_t *, ddi_attach_cmd_t);
56static int	usbser_pl2303_detach(dev_info_t *, ddi_detach_cmd_t);
57static int 	usbser_pl2303_getinfo(dev_info_t *, ddi_info_cmd_t, void *,
58		void **);
59static int	usbser_pl2303_open(queue_t *, dev_t *, int, int, cred_t *);
60static void	*usbser_pl2303_statep;	/* soft state */
61
62extern		ds_ops_t ds_ops;	/* DSD operations */
63
64
65/*
66 * STREAMS structures
67 */
68struct 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
78static 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
89static 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
100struct streamtab usbser_pl2303_str_info = {
101	&usbser_pl2303_rinit, &usbser_pl2303_winit, NULL, NULL
102};
103
104
105static 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 */
127struct 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_supported,	/* devo_quiesce */
140};
141
142
143extern struct mod_ops mod_driverops;
144
145
146static struct modldrv modldrv = {
147	&mod_driverops,		/* type of module - driver */
148	"USB Prolific PL2303 driver",
149	&usbser_pl2303_ops,
150};
151
152
153static struct modlinkage modlinkage = {
154	MODREV_1, &modldrv, 0
155};
156
157
158/*
159 * entry points
160 * ------------
161 *
162 */
163int
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
177int
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
190int
191_info(struct modinfo *modinfop)
192{
193	return (mod_info(&modlinkage, modinfop));
194}
195
196
197int
198usbser_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
206static int
207usbser_pl2303_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
208{
209	return (usbser_attach(dip, cmd, usbser_pl2303_statep, &ds_ops));
210}
211
212
213static int
214usbser_pl2303_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
215{
216	return (usbser_detach(dip, cmd, usbser_pl2303_statep));
217}
218
219
220static int
221usbser_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