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_USBSACM_H
27 #define	_SYS_USB_USBSACM_H
28 
29 
30 #include <sys/types.h>
31 #include <sys/dditypes.h>
32 #include <sys/note.h>
33 
34 #include <sys/usb/clients/usbser/usbser_dsdi.h>
35 
36 #ifdef	__cplusplus
37 extern "C" {
38 #endif
39 
40 
41 typedef struct usbsacm_port usbsacm_port_t;
42 typedef struct usbsacm_state usbsacm_state_t;
43 
44 
45 /*
46  * PM support
47  */
48 typedef struct usbsacm_power {
49 	uint8_t		pm_wakeup_enabled;	/* remote wakeup enabled */
50 	uint8_t		pm_pwr_states;	/* bit mask of power states */
51 	boolean_t	pm_raise_power;	/* driver is about to raise power */
52 	uint8_t		pm_cur_power;	/* current power level */
53 	uint_t		pm_busy_cnt;	/* number of set_busy requests */
54 } usbsacm_pm_t;
55 
56 
57 /*
58  * per bulk in/out structure
59  */
60 struct usbsacm_port {
61 	kmutex_t		acm_port_mutex;		/* structure lock */
62 	usbsacm_state_t		*acm_device;		/* back pointer */
63 	usb_pipe_handle_t	acm_bulkin_ph;		/* in pipe hdl */
64 	int			acm_bulkin_state;	/* in pipe state */
65 	usb_pipe_handle_t	acm_bulkout_ph;		/* out pipe hdl */
66 	int			acm_bulkout_state;	/* out pipe state */
67 	usb_pipe_handle_t	acm_intr_ph;		/* intr pipe hdl */
68 	int			acm_intr_state;		/* intr pipe state */
69 	usb_ep_descr_t		acm_intr_ep_descr;	/* ep descriptor */
70 	int			acm_ctrl_if_no;		/* control interface */
71 	int			acm_data_if_no;		/* data interface */
72 	int			acm_data_port_no;	/* which data port */
73 	ds_cb_t			acm_cb;			/* DSD callbacks */
74 	mblk_t			*acm_rx_mp;		/* rx data */
75 	mblk_t			*acm_tx_mp;		/* tx data */
76 	kcondvar_t		acm_tx_cv;		/* tx completion */
77 	uint8_t			acm_mctlout;		/* controls out */
78 	uint8_t			acm_mctlin;		/* controls in */
79 	int			acm_cap;		/* port capabilities */
80 	usb_cdc_line_coding_t	acm_line_coding;	/* port line coding */
81 	int			acm_port_state;		/* port state */
82 	size_t			acm_bulkin_size;	/* bulkin xfer size */
83 };
84 
85 _NOTE(MUTEX_PROTECTS_DATA(usbsacm_port::acm_port_mutex, usbsacm_port))
86 _NOTE(DATA_READABLE_WITHOUT_LOCK(usbsacm_port::{
87 	acm_device
88 	acm_cb.cb_rx
89 	acm_cb.cb_tx
90 	acm_cb.cb_arg
91 	acm_bulkin_ph
92 	acm_bulkout_ph
93 	acm_intr_ph
94 	acm_ctrl_if_no
95 	acm_data_if_no
96 	acm_data_port_no
97 	acm_port_state
98 }))
99 
100 struct usbsacm_state {
101 	kmutex_t		acm_mutex;		/* structure lock */
102 	dev_info_t		*acm_dip;		/* device info */
103 	usb_client_dev_data_t	*acm_dev_data;		/* registration data */
104 	usb_event_t		*acm_usb_events;	/* usb events */
105 	usb_pipe_handle_t	acm_def_ph;		/* default pipe hdl */
106 	usb_log_handle_t	acm_lh;			/* USBA log handle */
107 	int			acm_dev_state;		/* USB device state */
108 	size_t			acm_xfer_sz;		/* bulk xfer size */
109 	boolean_t		acm_compatibility;	/* if conform to spec */
110 	usbsacm_port_t		*acm_ports;		/* per port structs */
111 	int			acm_port_cnt;		/* port number */
112 	usbsacm_pm_t		*acm_pm;		/* PM support */
113 };
114 
115 _NOTE(MUTEX_PROTECTS_DATA(usbsacm_state::acm_mutex, usbsacm_state))
116 _NOTE(DATA_READABLE_WITHOUT_LOCK(usbsacm_state::{
117 	acm_dip
118 	acm_dev_data
119 	acm_usb_events
120 	acm_def_ph
121 	acm_lh
122 	acm_dev_state
123 	acm_xfer_sz
124 	acm_compatibility
125 	acm_ports
126 	acm_port_cnt
127 	acm_pm
128 }))
129 
130 /* port state */
131 enum {
132 	USBSACM_PORT_CLOSED,			/* port is closed */
133 	USBSACM_PORT_OPEN,			/* port is open */
134 	USBSACM_PORT_CLOSING
135 };
136 
137 /* pipe state */
138 enum {
139 	USBSACM_PIPE_CLOSED,			/* pipe is closed */
140 	USBSACM_PIPE_IDLE,			/* open but no requests */
141 	USBSACM_PIPE_BUSY,			/* servicing request */
142 	USBSACM_PIPE_CLOSING			/* pipe is closing */
143 };
144 
145 /* various tunables */
146 enum {
147 	USBSACM_BULKOUT_TIMEOUT		= 15,	/* bulkout timeout */
148 	USBSACM_BULKIN_TIMEOUT		= 0	/* bulkin timeout */
149 };
150 
151 /* hardware definitions */
152 enum {
153 	USBSACM_REQ_OUT	= USB_DEV_REQ_TYPE_CLASS| USB_DEV_REQ_HOST_TO_DEV,
154 	USBSACM_REQ_IN	= USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_DEV_TO_HOST,
155 	USBSACM_REQ_WRITE_IF		= USBSACM_REQ_OUT | USB_DEV_REQ_RCPT_IF,
156 	USBSACM_REQ_READ_IF		= USBSACM_REQ_IN | USB_DEV_REQ_RCPT_IF
157 };
158 
159 #define	PRINT_MASK_ATTA		0x00000001
160 #define	PRINT_MASK_CLOSE	0x00000002
161 #define	PRINT_MASK_OPEN		0x00000004
162 #define	PRINT_MASK_EVENTS	0x00000008
163 #define	PRINT_MASK_PM		0x00000010
164 #define	PRINT_MASK_CB		0x00000020
165 #define	PRINT_MASK_ALL		0xFFFFFFFF
166 
167 
168 #define	NELEM(a)	(sizeof (a) / sizeof (*(a)))
169 
170 
171 #ifdef	__cplusplus
172 }
173 #endif
174 
175 #endif	/* _SYS_USB_USBSACM_H */
176