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 #ifndef _SYS_USB_USBSER_DSDI_H
27 #define	_SYS_USB_USBSER_DSDI_H
28 
29 
30 /*
31  * USB-to-serial device-specific driver interface (DSDI)
32  */
33 
34 #include <sys/types.h>
35 #include <sys/dditypes.h>
36 #include <sys/usb/usba.h>
37 #include <sys/usb/usba/usbai_private.h>
38 
39 #ifdef	__cplusplus
40 extern "C" {
41 #endif
42 
43 typedef void	*ds_hdl_t;	/* DSD device handler */
44 
45 /*
46  * interrupt emulation callbacks
47  */
48 typedef struct ds_cb {
49 	void		(*cb_tx)(caddr_t);	/* transmit callback */
50 	void		(*cb_rx)(caddr_t);	/* receive callback */
51 	void		(*cb_status)(caddr_t);	/* status change callback */
52 	caddr_t		cb_arg;			/* callback argument */
53 } ds_cb_t;
54 
55 typedef struct ds_port_params ds_port_params_t;	/* see below */
56 
57 typedef struct ds_attach_info {
58 	/*
59 	 * passed to DSD:
60 	 */
61 	dev_info_t	*ai_dip;	/* devinfo */
62 	/*
63 	 * these event callbacks should be registered by DSD
64 	 * using usb_register_event_cbs()
65 	 */
66 	usb_event_t	*ai_usb_events;
67 	/*
68 	 * returned by DSD:
69 	 */
70 	ds_hdl_t	*ai_hdl; /* handle to be used by GSD in other calls */
71 	uint_t		*ai_port_cnt;	/* number of ports */
72 } ds_attach_info_t;
73 
74 /*
75  * device operations used by Generic Serial Driver (GSD)
76  *
77  * ops returning int should return USB_SUCCESS on successful completion
78  * or appropriate USB_* error code in case of failure
79  *
80  * ops can block unless otherwise indicated
81  */
82 typedef struct ds_ops {
83 	int	ds_version;	/* structure version */
84 
85 	/*
86 	 * configuration operations
87 	 * ------------------------
88 	 *
89 	 * attach/detach device instance, called from GSD attach(9E)/detach(9E)
90 	 */
91 	int	(*ds_attach)(ds_attach_info_t *aip);
92 	void	(*ds_detach)(ds_hdl_t);
93 
94 	/*
95 	 * register/unregister interrupt callbacks for the given port
96 	 */
97 	int	(*ds_register_cb)(ds_hdl_t, uint_t port_num, ds_cb_t *cb);
98 	void	(*ds_unregister_cb)(ds_hdl_t, uint_t port_num);
99 
100 	/*
101 	 * open/close port
102 	 */
103 	int	(*ds_open_port)(ds_hdl_t, uint_t port_num);
104 	int	(*ds_close_port)(ds_hdl_t, uint_t port_num);
105 
106 	/*
107 	 * power management
108 	 * ----------------
109 	 *
110 	 * set power level of the component;
111 	 * DSD should set new_state to the resulting USB device state
112 	 */
113 	int	(*ds_usb_power)(ds_hdl_t, int comp, int level, int *new_state);
114 
115 	/*
116 	 * CPR suspend/resume
117 	 */
118 	int	(*ds_suspend)(ds_hdl_t);
119 	int	(*ds_resume)(ds_hdl_t);
120 
121 	/*
122 	 * USB device disconnect/reconnect
123 	 */
124 	int	(*ds_disconnect)(ds_hdl_t);
125 	int	(*ds_reconnect)(ds_hdl_t);
126 
127 	/*
128 	 * standard UART operations
129 	 * ------------------------
130 	 *
131 	 * set one or more port parameters: baud rate, parity,
132 	 * stop bits, character size, xon/xoff char, flow control
133 	 */
134 	int	(*ds_set_port_params)(ds_hdl_t, uint_t port_num,
135 			ds_port_params_t *tp);
136 
137 	/*
138 	 * set modem controls: each bit set to 1 in 'mask' will be set to the
139 	 * value of corresponding bit in 'val'; other bits are not affected
140 	 */
141 	int	(*ds_set_modem_ctl)(ds_hdl_t, uint_t port_num,
142 			int mask, int val);
143 
144 	/*
145 	 * get modem control/status: values of bits that correspond
146 	 * to those set to 1 in 'mask' are returned in 'valp'
147 	 */
148 	int	(*ds_get_modem_ctl)(ds_hdl_t, uint_t port_num,
149 			int mask, int *valp);
150 
151 	/*
152 	 * set/clear break ('ctl' is DS_ON/DS_OFF)
153 	 */
154 	int	(*ds_break_ctl)(ds_hdl_t, uint_t port_num, int ctl);
155 
156 	/*
157 	 * set/clear internal loopback ('ctl' is DS_ON/DS_OFF)
158 	 */
159 	int	(*ds_loopback)(ds_hdl_t, uint_t port_num, int ctl);
160 
161 	/*
162 	 * data xfer
163 	 * ---------
164 	 *
165 	 * data transmit: DSD is *required* to accept mblk for transfer and
166 	 * return USB_SUCCESS; after which GSD no longer owns the mblk
167 	 */
168 	int	(*ds_tx)(ds_hdl_t, uint_t port_num, mblk_t *mp);
169 
170 	/*
171 	 * data receipt: DSD returns either received data mblk or NULL
172 	 * if no data available. this op must not block as it is intended
173 	 * to be called from is usually called GSD receive callback
174 	 */
175 	mblk_t	*(*ds_rx)(ds_hdl_t, uint_t port_num);
176 
177 	/*
178 	 * stop/start data transmit or/and receive:
179 	 * 'dir' can be an OR of DS_TX and DS_RX; must succeed.
180 	 */
181 	void	(*ds_stop)(ds_hdl_t, uint_t port_num, int dir);
182 	void	(*ds_start)(ds_hdl_t, uint_t port_num, int dir);
183 
184 	/*
185 	 * flush FIFOs: 'dir' can be an OR of DS_TX and DS_RX,
186 	 * affecting transmit and received FIFO respectively
187 	 */
188 	int	(*ds_fifo_flush)(ds_hdl_t, uint_t port_num, int dir);
189 
190 	/*
191 	 * drain (wait until empty) output FIFO
192 	 *
193 	 * return failure if the FIFO does not get empty after at least
194 	 * 'timeout' seconds (zero timeout means wait forever)
195 	 */
196 	int	(*ds_fifo_drain)(ds_hdl_t, uint_t port_num, int timeout);
197 
198 	/* V1 ops for polled I/O */
199 	usb_pipe_handle_t (*ds_out_pipe)(ds_hdl_t, uint_t port_num);
200 	usb_pipe_handle_t (*ds_in_pipe)(ds_hdl_t, uint_t port_num);
201 } ds_ops_t;
202 
203 /*
204  * ds_version
205  */
206 enum {
207 	DS_OPS_VERSION_V0	= 0,
208 	DS_OPS_VERSION_V1	= 1,
209 	DS_OPS_VERSION		= DS_OPS_VERSION_V1
210 };
211 
212 /*
213  * parameter type
214  */
215 typedef enum {
216 	DS_PARAM_BAUD,		/* baud rate */
217 	DS_PARAM_PARITY,	/* parity */
218 	DS_PARAM_STOPB,		/* stop bits */
219 	DS_PARAM_CHARSZ,	/* char size */
220 	DS_PARAM_XON_XOFF,	/* xon/xoff chars */
221 	DS_PARAM_FLOW_CTL	/* flow control */
222 } ds_port_param_type_t;
223 
224 /*
225  * a single param entry, union used to pass various data types
226  */
227 typedef struct ds_port_param_entry {
228 	ds_port_param_type_t	param;	 /* parameter */
229 	union {
230 		uint_t		ui;
231 		uchar_t		uc[4];
232 	} val;			/* parameter value(s) */
233 } ds_port_param_entry_t;
234 
235 /*
236  * port parameter array
237  */
238 struct ds_port_params {
239 	ds_port_param_entry_t	*tp_entries;	/* entry array */
240 	int			tp_cnt;		/* entry count */
241 };
242 
243 /*
244  * direction (ds_fifo_flush, ds_fifo_drain)
245  */
246 enum {
247 	DS_TX		= 0x01,	/* transmit direction */
248 	DS_RX		= 0x02	/* receive direction */
249 };
250 
251 /*
252  * on/off (ds_break_ctl, ds_loopback)
253  */
254 enum {
255 	DS_OFF,
256 	DS_ON
257 };
258 
259 /*
260  * input error codes, returned by DSD in an M_BREAK message
261  */
262 enum {
263 	DS_PARITY_ERR	= 0x01,	/* parity error */
264 	DS_FRAMING_ERR	= 0x02,	/* framing error */
265 	DS_OVERRUN_ERR	= 0x03,	/* data overrun */
266 	DS_BREAK_ERR	= 0x04	/* break detected */
267 };
268 
269 #ifdef	__cplusplus
270 }
271 #endif
272 
273 #endif	/* _SYS_USB_USBSER_DSDI_H */
274