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