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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SYS_USB_USBSER_KEYSPAN_VAR_H
28 #define	_SYS_USB_USBSER_KEYSPAN_VAR_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*
33  * keyspan implementation definitions
34  */
35 
36 #include <sys/types.h>
37 #include <sys/dditypes.h>
38 #include <sys/note.h>
39 
40 #include <sys/usb/clients/usbser/usbser_dsdi.h>
41 
42 #include <sys/usb/clients/usbser/usbser_keyspan/usa90msg.h>
43 #include <sys/usb/clients/usbser/usbser_keyspan/usa49msg.h>
44 
45 #ifdef	__cplusplus
46 extern "C" {
47 #endif
48 
49 /* product id */
50 #define	KEYSPAN_USA19HS_PID		0x121
51 #define	KEYSPAN_USA49WLC_PID		0x12a
52 
53 #define	KEYSPAN_MAX_PORT_NUM		4
54 
55 /*
56  * forward typedefs needed to resolve recursive header dependencies
57  */
58 typedef struct keyspan_pre_state keyspan_pre_state_t;
59 typedef struct keyspan_state keyspan_state_t;
60 typedef struct keyspan_port keyspan_port_t;
61 
62 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_pipe.h>
63 
64 /*
65  * temporary soft state for pre_attach
66  */
67 struct keyspan_pre_state {
68 	dev_info_t		*kb_dip;	/* device info */
69 	int			kb_instance;	/* instance */
70 	usb_client_dev_data_t	*kb_dev_data;	/* registration data */
71 	usb_log_handle_t	kb_lh;		/* USBA log handle */
72 	keyspan_pipe_t		kb_def_pipe;	/* default pipe */
73 };
74 
75 /* Firmware structure */
76 typedef struct usbser_keyspan_fw_record {
77 	uint16_t address;
78 	uint8_t data_len;
79 	uint8_t data[64];
80 } usbser_keyspan_fw_record_t;
81 
82 #define	ezusb_hex_record usbser_keyspan_fw_record
83 
84 /*
85  * PM support
86  */
87 typedef struct keyspan_power {
88 	uint8_t		pm_wakeup_enabled;	/* remote wakeup enabled */
89 	uint8_t		pm_pwr_states;	/* bit mask of power states */
90 	boolean_t	pm_raise_power;	/* driver is about to raise power */
91 	uint8_t		pm_cur_power;	/* current power level */
92 	uint_t		pm_busy_cnt;	/* number of set_busy requests */
93 } keyspan_pm_t;
94 
95 /*
96  * device specific info structure
97  */
98 typedef struct keyspan_dev_spec {
99 
100 	uint16_t	id_product;	/* product ID value */
101 	uint8_t		port_cnt;	/* How many ports on the device */
102 	uint8_t	ctrl_ep_addr;	/* Endpoint used to control the device */
103 	uint8_t	stat_ep_addr;	/* Endpoint used to get device status */
104 	uint8_t	dataout_ep_addr[4];	/* Endpoint used to send data */
105 
106 	/* Endpoint used to get data from device */
107 	uint8_t	datain_ep_addr[4];
108 } keyspan_dev_spec_t;
109 
110 /*
111  * To support different keyspan adapters, use union type
112  * for different cmd msg format.
113  */
114 typedef union keyspan_port_ctrl_msg {
115 	keyspan_usa19hs_port_ctrl_msg_t	usa19hs;
116 	keyspan_usa49_port_ctrl_msg_t usa49;
117 } keyspan_port_ctrl_msg_t;
118 
119 /*
120  * To support different keyspan adapters, use union type
121  * for different status msg format.
122  */
123 typedef union keyspan_port_status_msg {
124 	keyspan_usa19hs_port_status_msg_t	usa19hs;
125 	keyspan_usa49_port_status_msg_t usa49;
126 } keyspan_port_status_msg_t;
127 
128 /*
129  * per device state structure
130  */
131 struct keyspan_state {
132 	kmutex_t		ks_mutex;	/* structure lock */
133 	dev_info_t		*ks_dip;	/* device info */
134 	keyspan_port_t		*ks_ports;	/* per port structs */
135 	keyspan_dev_spec_t	ks_dev_spec;	/* device specific info */
136 
137 	/*
138 	 * we use semaphore to serialize pipe open/close by different ports.
139 	 * mutex could be used too, but it causes trouble when warlocking
140 	 * with USBA: some functions inside usb_pipe_close() wait on cv
141 	 *
142 	 * since semaphore is only used for serialization during
143 	 * open/close and suspend/resume, there is no deadlock hazard
144 	 */
145 	ksema_t			ks_pipes_sema;
146 
147 	/*
148 	 * USBA related
149 	 */
150 	usb_client_dev_data_t	*ks_dev_data;	/* registration data */
151 	usb_event_t		*ks_usb_events;	/* usb events */
152 
153 	keyspan_pipe_t		ks_def_pipe;	/* default pipe */
154 
155 	/* bulk in pipe for getting device status */
156 	keyspan_pipe_t		ks_statin_pipe;
157 
158 	/* bulk out pipe for sending control cmd to device */
159 	keyspan_pipe_t		ks_ctrlout_pipe;
160 
161 	usb_log_handle_t	ks_lh;		/* USBA log handle */
162 	int			ks_dev_state;	/* USB device state */
163 	keyspan_pm_t		*ks_pm;		/* PM support */
164 
165 };
166 
167 _NOTE(MUTEX_PROTECTS_DATA(keyspan_state::ks_mutex, keyspan_state))
168 _NOTE(DATA_READABLE_WITHOUT_LOCK(keyspan_state::{
169 	ks_dip
170 	ks_dev_data
171 	ks_usb_events
172 	ks_dev_spec
173 	ks_ports
174 	ks_def_pipe
175 	ks_ctrlout_pipe.pipe_handle
176 	ks_statin_pipe.pipe_handle
177 	ks_lh
178 	ks_pm
179 }))
180 
181 /*
182  * per port structure
183  */
184 struct keyspan_port {
185 	kmutex_t	kp_mutex;	/* structure lock */
186 	keyspan_state_t	*kp_ksp;	/* back pointer to the state */
187 	char		kp_lh_name[16];	/* log handle name */
188 	usb_log_handle_t kp_lh;		/* log handle */
189 	uint_t		kp_port_num;	/* port number */
190 	int		kp_state;	/* port state */
191 	int		kp_flags;	/* port flags */
192 	ds_cb_t		kp_cb;		/* DSD callbacks */
193 	kcondvar_t	kp_tx_cv;	/* cv to wait for tx completion */
194 	/*
195 	 * data receipt and transmit
196 	 */
197 	mblk_t		*kp_rx_mp;	/* received data */
198 	mblk_t		*kp_tx_mp;	/* data to transmit */
199 	boolean_t	kp_no_more_reads; /* disable reads */
200 
201 	/* The control cmd sent to the port */
202 	keyspan_port_ctrl_msg_t	kp_ctrl_msg;
203 
204 	/* status msg of the port */
205 	keyspan_port_status_msg_t	kp_status_msg;
206 
207 	uint_t kp_baud;	/* the current baud speed code */
208 	uint8_t	kp_lcr;	/* the current lcr value */
209 	/*
210 	 * the current port status, including: rts, dtr,
211 	 * break, loopback, enable.
212 	 */
213 	uint8_t	kp_status_flag;
214 
215 	keyspan_pipe_t		kp_datain_pipe;	/* bulk in data pipe */
216 	keyspan_pipe_t		kp_dataout_pipe; /* bulk out data pipe */
217 
218 	uint_t		kp_read_len;	/* max length of bulkin request */
219 	uint_t		kp_write_len;	/* max length of bulkout request */
220 };
221 
222 _NOTE(MUTEX_PROTECTS_DATA(keyspan_port::kp_mutex, keyspan_port))
223 _NOTE(DATA_READABLE_WITHOUT_LOCK(keyspan_port::{
224 	kp_ksp
225 	kp_lh
226 	kp_port_num
227 	kp_read_len
228 	kp_write_len
229 	kp_cb
230 	kp_datain_pipe.pipe_handle
231 	kp_datain_pipe.pipe_ep_descr
232 }))
233 
234 /* lock relationships */
235 _NOTE(LOCK_ORDER(keyspan_state::ks_mutex keyspan_port::kp_mutex))
236 _NOTE(LOCK_ORDER(keyspan_port::kp_mutex keyspan_pipe::pipe_mutex))
237 
238 /* port status flags */
239 enum {
240 	KEYSPAN_PORT_ENABLE = 0x0001,		/* port is enabled */
241 	KEYSPAN_PORT_RTS = 0x0002,		/* port's rts is set */
242 	KEYSPAN_PORT_DTR = 0x0004,		/* port's dtr is set */
243 	KEYSPAN_PORT_TXBREAK = 0x0008,		/* port is in TX break mod */
244 	KEYSPAN_PORT_LOOPBACK = 0x0010,		/* port is in loopback mod */
245 
246 	/* the ctrl cmd sent to this port is responded */
247 	KEYSPAN_PORT_CTRLRESP = 0x0020,
248 	KEYSPAN_PORT_RXBREAK = 0x0040		/* port is in RX break mod */
249 };
250 
251 /* port state */
252 enum {
253 	KEYSPAN_PORT_NOT_INIT = 0,	/* port is not initialized */
254 	KEYSPAN_PORT_CLOSED,		/* port is closed */
255 	KEYSPAN_PORT_OPENING,		/* port is being opened */
256 	KEYSPAN_PORT_OPEN		/* port is open */
257 };
258 
259 /* port flags */
260 enum {
261 	KEYSPAN_PORT_TX_STOPPED	= 0x0001	/* transmit not allowed */
262 };
263 
264 /* various tunables */
265 enum {
266 	KEYSPAN_BULK_TIMEOUT		= 3,	/* transfer timeout */
267 	KEYSPAN_BULKIN_MAX_LEN		= 64,	/* bulk in max length */
268 	KEYSPAN_BULKOUT_MAX_LEN		= 64,	/* bulk out max length */
269 	KEYSPAN_STATIN_MAX_LEN		= 16	/* status in max length */
270 };
271 
272 /* This flag indicates if the firmware already downloaded to the device */
273 #define	KEYSPAN_FW_FLAG 0x8000
274 
275 /* Vendor specific ctrl req, used to set/download bytes in the device memory */
276 #define	KEYSPAN_REQ_SET 0xa0
277 
278 /*
279  * debug printing masks
280  */
281 #define	DPRINT_ATTACH		0x00000001
282 #define	DPRINT_OPEN		0x00000002
283 #define	DPRINT_CLOSE		0x00000004
284 #define	DPRINT_DEF_PIPE		0x00000010
285 #define	DPRINT_IN_PIPE		0x00000020
286 #define	DPRINT_OUT_PIPE		0x00000040
287 #define	DPRINT_INTR_PIPE	0x00000080
288 #define	DPRINT_PIPE_RESET	0x00000100
289 #define	DPRINT_IN_DATA		0x00000200
290 #define	DPRINT_OUT_DATA		0x00000400
291 #define	DPRINT_CTLOP		0x00000800
292 #define	DPRINT_HOTPLUG		0x00001000
293 #define	DPRINT_PM		0x00002000
294 #define	DPRINT_MASK_ALL		0xFFFFFFFF
295 
296 /*
297  * misc macros
298  */
299 #define	NELEM(a)	(sizeof (a) / sizeof (*(a)))
300 
301 /* common DSD functions */
302 int	keyspan_tx_copy_data(keyspan_port_t *, mblk_t *, int);
303 void	keyspan_tx_start(keyspan_port_t *, int *);
304 void	keyspan_put_tail(mblk_t **, mblk_t *);
305 void	keyspan_put_head(mblk_t **, mblk_t *, keyspan_port_t *);
306 
307 void	keyspan_bulkin_cb(usb_pipe_handle_t, usb_bulk_req_t *);
308 void	keyspan_bulkout_cb(usb_pipe_handle_t, usb_bulk_req_t *);
309 
310 int	keyspan_restore_device(keyspan_state_t *);
311 int	keyspan_send_cmd(keyspan_port_t *);
312 
313 int	keyspan_dev_is_online(keyspan_state_t *);
314 
315 
316 #ifdef	__cplusplus
317 }
318 #endif
319 
320 #endif	/* _SYS_USB_USBSER_KEYSPAN_VAR_H */
321