xref: /onnv-gate/usr/src/uts/common/io/usb/clients/usbser/usbsacm/usbsacm.c (revision 7425:e4dbffd35ebc)
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  * USB Serial CDC ACM driver
29  *
30  * 1. General Concepts
31  * -------------------
32  *
33  * 1.1 Overview
34  * ------------
35  * This driver supports devices that comply with the USB Communication
36  * Device Class Abstract Control Model (USB CDC ACM) specification,
37  * which is available at http://www.usb.org. Given the broad nature
38  * of communication equipment, this driver supports the following
39  * types of devices:
40  *	+ Telecommunications devices: analog modems, mobile phones;
41  *	+ Networking devices: cable modems;
42  * Except the above mentioned acm devices, this driver also supports
43  * some devices which provide modem-like function and have pairs of
44  * bulk in/out pipes.
45  *
46  * There are three classes that make up the definition for communication
47  * devices: the Communication Device Class, the Communication Interface
48  * Class and the Data Interface Class. The Communication Device Class
49  * is a device level definition and is used by the host to properly
50  * identify a communication device that may present several different
51  * types of interfaces. The Communication Interface Class defines a
52  * general-purpose mechanism that can be used to enable all types of
53  * communication services on the Universal Serial Bus (USB). The Data
54  * Interface Class defines a general-purpose mechanism to enable bulk
55  * transfer on the USB when the data does not meet the requirements
56  * for any other class.
57  *
58  * 1.2 Interface Definitions
59  * -------------------------
60  * Communication Class Interface is used for device management and,
61  * optionally, call management. Device management includes the requests
62  * that manage the operational state of a device, the device responses,
63  * and event notifications. In Abstract Control Model, the device can
64  * provide an internal implementation of call management over the Data
65  * Class interface or the Communication Class interface.
66  *
67  * The Data Class defines a data interface as an interface with a class
68  * type of Data Class. Data transmission on a communication device is
69  * not restricted to interfaces using the Data Class. Rather, a data
70  * interface is used to transmit and/or receive data that is not
71  * defined by any other class. The data could be:
72  *	+ Some form of raw data from a communication line.
73  *	+ Legacy modem data.
74  *	+ Data using a proprietary format.
75  *
76  * 1.3 Endpoint Requirements
77  * -------------------------
78  * The Communication Class interface requires one endpoint, the management
79  * element. Optionally, it can have an additional endpoint, the notification
80  * element. The management element uses the default endpoint for all
81  * standard and Communication Class-specific requests. The notification
82  * element normally uses an interrupt endpoint.
83  *
84  * The type of endpoints belonging to a Data Class interface are restricted
85  * to bulk, and are expected to exist in pairs of the same type (one In and
86  * one Out).
87  *
88  * 1.4 ACM Function Characteristics
89  * --------------------------------
90  * With Abstract Control Model, the USB device understands standard
91  * V.25ter (AT) commands. The device contains a Datapump and micro-
92  * controller that handles the AT commands and relay controls. The
93  * device uses both a Data Class interface and a Communication Class.
94  * interface.
95  *
96  * A Communication Class interface of type Abstract Control Model will
97  * consist of a minimum of two pipes; one is used to implement the
98  * management element and the other to implement a notification element.
99  * In addition, the device can use two pipes to implement channels over
100  * which to carry unspecified data, typically over a Data Class interface.
101  *
102  * 1.5 ACM Serial Emulation
103  * ------------------------
104  * The Abstract Control Model can bridge the gap between legacy modem
105  * devices and USB devices. To support certain types of legacy applications,
106  * two problems need to be addressed. The first is supporting specific
107  * legacy control signals and state variables which are addressed
108  * directly by the various carrier modulation standards. To support these
109  * requirement, additional requests and notifications have been created.
110  * Please refer to macro, beginning with USB_CDC_REQ_* and
111  * USB_CDC_NOTIFICATION_*.
112  *
113  * The second significant item which is needed to bridge the gap between
114  * legacy modem designs and the Abstract Control Model is a means to
115  * multiplex call control (AT commands) on the Data Class interface.
116  * Legacy modem designs are limited by only supporting one channel for
117  * both "AT" commands and the actual data. To allow this type of
118  * functionality, the device must have a means to specify this limitation
119  * to the host.
120  *
121  * When describing this type of device, the Communication Class interface
122  * would still specify a Abstract Control Model, but call control would
123  * actually occur over the Data Class interface. To describe this
124  * particular characteristic, the Call Management Functional Descriptor
125  * would have bit D1 of bmCapabilities set.
126  *
127  * 1.6 Other Bulk In/Out Devices
128  * -----------------------------
129  * Some devices don't conform to USB CDC specification, but they provide
130  * modem-like function and have pairs of bulk in/out pipes. This driver
131  * supports this kind of device and exports term nodes by their pipes.
132  *
133  * 2. Implementation
134  * -----------------
135  *
136  * 2.1 Overview
137  * ------------
138  * It is a device-specific driver (DSD) working with USB generic serial
139  * driver (GSD). It implements the USB-to-serial device-specific driver
140  * interface (DSDI) which is offered by GSD. The interface is defined
141  * by ds_ops_t structure.
142  *
143  * 2.2 Port States
144  * ---------------
145  * For USB CDC ACM devices, this driver is attached to its interface,
146  * and exports one port for each interface. For other modem-like devices,
147  * this driver can dynamically find the ports in the current device,
148  * and export one port for each pair bulk in/out pipes. Each port can
149  * be operated independently.
150  *
151  * port_state:
152  *
153  *		attach_ports
154  *		    |
155  *		    |
156  *		    |
157  *		    v
158  *	    USBSACM_PORT_CLOSED
159  *		|	    ^
160  *		|	    |
161  *		V	    |
162  *	   open_port	close_port
163  *		|	    ^
164  *		|	    |
165  *		V	    |
166  *	      USBSACM_PORT_OPEN
167  *
168  *
169  * 2.3 Pipe States
170  * ---------------
171  * Each port has its own bulk in/out pipes and some ports could also have
172  * its own interrupt pipes (traced by usbsacm_port structure), which are
173  * opened during attach. The pipe status is as following:
174  *
175  * pipe_state:
176  *
177  *		usbsacm_init_alloc_ports  usbsacm_free_ports
178  *				|		^
179  *				v		|
180  *		  |---->------ USBSACM_PORT_CLOSED ------>------+
181  *		  ^						|
182  *		  |				reconnect/resume/open_port
183  *		  |						|
184  *    disconnect/suspend/close_port				|
185  *		  |						v
186  *		  +------<------ USBSACM_PIPE_IDLE ------<------|
187  *				    |		|
188  *				    V		^
189  *				    |		|
190  *		  +-----------------+		+-----------+
191  *		  |					    |
192  *		  V					    ^
193  *		  |					    |
194  *	rx_start/tx_start----->------failed------->---------|
195  *		  |					    |
196  *		  |				bulkin_cb/bulkout_cb
197  *		  V					    |
198  *		  |					    ^
199  *		  |					    |
200  *		  +----->----- USBSACM_PIPE_BUSY ---->------+
201  *
202  *
203  * To get its status in a timely way, acm driver can get the status
204  * of the device by polling the interrupt pipe.
205  *
206  */
207 
208 #include <sys/types.h>
209 #include <sys/param.h>
210 #include <sys/conf.h>
211 #include <sys/stream.h>
212 #include <sys/strsun.h>
213 #include <sys/termio.h>
214 #include <sys/termiox.h>
215 #include <sys/ddi.h>
216 #include <sys/sunddi.h>
217 #include <sys/byteorder.h>
218 #define	USBDRV_MAJOR_VER	2
219 #define	USBDRV_MINOR_VER	0
220 #include <sys/usb/usba.h>
221 #include <sys/usb/usba/usba_types.h>
222 #include <sys/usb/clients/usbser/usbser.h>
223 #include <sys/usb/clients/usbser/usbser_dsdi.h>
224 #include <sys/usb/clients/usbcdc/usb_cdc.h>
225 #include <sys/usb/clients/usbser/usbsacm/usbsacm.h>
226 
227 /* devops entry points */
228 static int	usbsacm_attach(dev_info_t *, ddi_attach_cmd_t);
229 static int	usbsacm_detach(dev_info_t *, ddi_detach_cmd_t);
230 static int	usbsacm_getinfo(dev_info_t *, ddi_info_cmd_t, void *,
231 		void **);
232 static int	usbsacm_open(queue_t *, dev_t *, int, int, cred_t *);
233 
234 /* DSD operations */
235 static int	usbsacm_ds_attach(ds_attach_info_t *);
236 static void	usbsacm_ds_detach(ds_hdl_t);
237 static int	usbsacm_ds_register_cb(ds_hdl_t, uint_t, ds_cb_t *);
238 static void	usbsacm_ds_unregister_cb(ds_hdl_t, uint_t);
239 static int	usbsacm_ds_open_port(ds_hdl_t, uint_t);
240 static int	usbsacm_ds_close_port(ds_hdl_t, uint_t);
241 
242 /* standard UART operations */
243 static int	usbsacm_ds_set_port_params(ds_hdl_t, uint_t,
244 		ds_port_params_t *);
245 static int	usbsacm_ds_set_modem_ctl(ds_hdl_t, uint_t, int, int);
246 static int	usbsacm_ds_get_modem_ctl(ds_hdl_t, uint_t, int, int *);
247 static int	usbsacm_ds_break_ctl(ds_hdl_t, uint_t, int);
248 
249 /* data xfer */
250 static int	usbsacm_ds_tx(ds_hdl_t, uint_t, mblk_t *);
251 static mblk_t	*usbsacm_ds_rx(ds_hdl_t, uint_t);
252 static void	usbsacm_ds_stop(ds_hdl_t, uint_t, int);
253 static void	usbsacm_ds_start(ds_hdl_t, uint_t, int);
254 
255 /* fifo operations */
256 static int	usbsacm_ds_fifo_flush(ds_hdl_t, uint_t, int);
257 static int	usbsacm_ds_fifo_drain(ds_hdl_t, uint_t, int);
258 static int	usbsacm_wait_tx_drain(usbsacm_port_t *, int);
259 static int	usbsacm_fifo_flush_locked(usbsacm_state_t *, uint_t, int);
260 
261 /* power management and CPR */
262 static int	usbsacm_ds_suspend(ds_hdl_t);
263 static int	usbsacm_ds_resume(ds_hdl_t);
264 static int	usbsacm_ds_disconnect(ds_hdl_t);
265 static int	usbsacm_ds_reconnect(ds_hdl_t);
266 static int	usbsacm_ds_usb_power(ds_hdl_t, int, int, int *);
267 static int	usbsacm_create_pm_components(usbsacm_state_t *);
268 static void	usbsacm_destroy_pm_components(usbsacm_state_t *);
269 static void	usbsacm_pm_set_busy(usbsacm_state_t *);
270 static void	usbsacm_pm_set_idle(usbsacm_state_t *);
271 static int	usbsacm_pwrlvl0(usbsacm_state_t *);
272 static int	usbsacm_pwrlvl1(usbsacm_state_t *);
273 static int	usbsacm_pwrlvl2(usbsacm_state_t *);
274 static int	usbsacm_pwrlvl3(usbsacm_state_t *);
275 
276 /* event handling */
277 /* pipe callbacks */
278 static void	usbsacm_bulkin_cb(usb_pipe_handle_t, usb_bulk_req_t *);
279 static void	usbsacm_bulkout_cb(usb_pipe_handle_t, usb_bulk_req_t *);
280 
281 /* interrupt pipe */
282 static void	usbsacm_pipe_start_polling(usbsacm_port_t *acmp);
283 static void	usbsacm_intr_cb(usb_pipe_handle_t ph, usb_intr_req_t *req);
284 static void	usbsacm_intr_ex_cb(usb_pipe_handle_t ph, usb_intr_req_t *req);
285 static void	usbsacm_parse_intr_data(usbsacm_port_t *acmp, mblk_t *data);
286 
287 /* Utility functions */
288 /* data transfer routines */
289 static int	usbsacm_rx_start(usbsacm_port_t *);
290 static void	usbsacm_tx_start(usbsacm_port_t *);
291 static int	usbsacm_send_data(usbsacm_port_t *, mblk_t *);
292 
293 /* Initialize or release resources */
294 static int	usbsacm_init_alloc_ports(usbsacm_state_t *);
295 static void	usbsacm_free_ports(usbsacm_state_t *);
296 static void	usbsacm_cleanup(usbsacm_state_t *);
297 
298 /* analysis functional descriptors */
299 static int	usbsacm_get_descriptors(usbsacm_state_t *);
300 
301 /* hotplug */
302 static int	usbsacm_restore_device_state(usbsacm_state_t *);
303 static int	usbsacm_restore_port_state(usbsacm_state_t *);
304 
305 /* pipe operations */
306 static int	usbsacm_open_port_pipes(usbsacm_port_t *);
307 static void	usbsacm_close_port_pipes(usbsacm_port_t *);
308 static void	usbsacm_close_pipes(usbsacm_state_t *);
309 static void	usbsacm_disconnect_pipes(usbsacm_state_t *);
310 static int	usbsacm_reconnect_pipes(usbsacm_state_t *);
311 
312 /* vendor-specific commands */
313 static int	usbsacm_req_write(usbsacm_port_t *, uchar_t, uint16_t,
314 		mblk_t **);
315 static int	usbsacm_set_line_coding(usbsacm_port_t *,
316 		usb_cdc_line_coding_t *);
317 static void	usbsacm_mctl2reg(int mask, int val, uint8_t *);
318 static int	usbsacm_reg2mctl(uint8_t);
319 
320 /* misc */
321 static void	usbsacm_put_tail(mblk_t **, mblk_t *);
322 static void	usbsacm_put_head(mblk_t **, mblk_t *);
323 
324 
325 /*
326  * Standard STREAMS driver definitions
327  */
328 struct module_info usbsacm_modinfo = {
329 	0,			/* module id */
330 	"usbsacm",		/* module name */
331 	USBSER_MIN_PKTSZ,	/* min pkt size */
332 	USBSER_MAX_PKTSZ,	/* max pkt size */
333 	USBSER_HIWAT,		/* hi watermark */
334 	USBSER_LOWAT		/* low watermark */
335 };
336 
337 static struct qinit usbsacm_rinit = {
338 	NULL,
339 	usbser_rsrv,
340 	usbsacm_open,
341 	usbser_close,
342 	NULL,
343 	&usbsacm_modinfo,
344 	NULL
345 };
346 
347 static struct qinit usbsacm_winit = {
348 	usbser_wput,
349 	usbser_wsrv,
350 	NULL,
351 	NULL,
352 	NULL,
353 	&usbsacm_modinfo,
354 	NULL
355 };
356 
357 
358 struct streamtab usbsacm_str_info = {
359 	&usbsacm_rinit, &usbsacm_winit, NULL, NULL
360 };
361 
362 /* cb_ops structure */
363 static struct cb_ops usbsacm_cb_ops = {
364 	nodev,			/* cb_open */
365 	nodev,			/* cb_close */
366 	nodev,			/* cb_strategy */
367 	nodev,			/* cb_print */
368 	nodev,			/* cb_dump */
369 	nodev,			/* cb_read */
370 	nodev,			/* cb_write */
371 	nodev,			/* cb_ioctl */
372 	nodev,			/* cb_devmap */
373 	nodev,			/* cb_mmap */
374 	nodev,			/* cb_segmap */
375 	nochpoll,		/* cb_chpoll */
376 	ddi_prop_op,		/* cb_prop_op */
377 	&usbsacm_str_info,	/* cb_stream */
378 	(int)(D_64BIT | D_NEW | D_MP | D_HOTPLUG)	/* cb_flag */
379 };
380 
381 /* dev_ops structure */
382 struct dev_ops usbsacm_ops = {
383 	DEVO_REV,		/* devo_rev */
384 	0,			/* devo_refcnt */
385 	usbsacm_getinfo,	/* devo_getinfo */
386 	nulldev,		/* devo_identify */
387 	nulldev,		/* devo_probe */
388 	usbsacm_attach,		/* devo_attach */
389 	usbsacm_detach,		/* devo_detach */
390 	nodev,			/* devo_reset */
391 	&usbsacm_cb_ops,	/* devo_cb_ops */
392 	(struct bus_ops *)NULL,	/* devo_bus_ops */
393 	usbser_power		/* devo_power */
394 };
395 
396 extern struct mod_ops mod_driverops;
397 /* modldrv structure */
398 static struct modldrv modldrv = {
399 	&mod_driverops,		/* type of module - driver */
400 	"USB Serial CDC ACM driver",
401 	&usbsacm_ops,
402 };
403 
404 /* modlinkage structure */
405 static struct modlinkage modlinkage = {
406 	MODREV_1,
407 	&modldrv,
408 	NULL
409 };
410 
411 static void	*usbsacm_statep;	/* soft state */
412 
413 /*
414  * DSD definitions
415  */
416 ds_ops_t ds_ops = {
417 	DS_OPS_VERSION,
418 	usbsacm_ds_attach,
419 	usbsacm_ds_detach,
420 	usbsacm_ds_register_cb,
421 	usbsacm_ds_unregister_cb,
422 	usbsacm_ds_open_port,
423 	usbsacm_ds_close_port,
424 	usbsacm_ds_usb_power,
425 	usbsacm_ds_suspend,
426 	usbsacm_ds_resume,
427 	usbsacm_ds_disconnect,
428 	usbsacm_ds_reconnect,
429 	usbsacm_ds_set_port_params,
430 	usbsacm_ds_set_modem_ctl,
431 	usbsacm_ds_get_modem_ctl,
432 	usbsacm_ds_break_ctl,
433 	NULL,			/* NULL if h/w doesn't support loopback */
434 	usbsacm_ds_tx,
435 	usbsacm_ds_rx,
436 	usbsacm_ds_stop,
437 	usbsacm_ds_start,
438 	usbsacm_ds_fifo_flush,
439 	usbsacm_ds_fifo_drain
440 };
441 
442 /*
443  * baud code -> baud rate (0 means unsupported rate)
444  */
445 static int usbsacm_speedtab[] = {
446 	0,	/* B0 */
447 	50,	/* B50 */
448 	75,	/* B75 */
449 	110,	/* B110 */
450 	134,	/* B134 */
451 	150,	/* B150 */
452 	200,	/* B200 */
453 	300,	/* B300 */
454 	600,	/* B600 */
455 	1200,	/* B1200 */
456 	1800,	/* B1800 */
457 	2400,	/* B2400 */
458 	4800,	/* B4800 */
459 	9600,	/* B9600 */
460 	19200,	/* B19200 */
461 	38400,	/* B38400 */
462 	57600,	/* B57600 */
463 	76800,	/* B76800 */
464 	115200,	/* B115200 */
465 	153600,	/* B153600 */
466 	230400,	/* B230400 */
467 	307200,	/* B307200 */
468 	460800	/* B460800 */
469 };
470 
471 
472 static uint_t	usbsacm_errlevel = USB_LOG_L4;
473 static uint_t	usbsacm_errmask = 0xffffffff;
474 static uint_t	usbsacm_instance_debug = (uint_t)-1;
475 
476 
477 /*
478  * usbsacm driver's entry points
479  * -----------------------------
480  */
481 /*
482  * Module-wide initialization routine.
483  */
484 int
485 _init(void)
486 {
487 	int    error;
488 
489 	if ((error = mod_install(&modlinkage)) == 0) {
490 
491 		error = ddi_soft_state_init(&usbsacm_statep,
492 		    usbser_soft_state_size(), 1);
493 	}
494 
495 	return (error);
496 }
497 
498 
499 /*
500  * Module-wide tear-down routine.
501  */
502 int
503 _fini(void)
504 {
505 	int    error;
506 
507 	if ((error = mod_remove(&modlinkage)) == 0) {
508 		ddi_soft_state_fini(&usbsacm_statep);
509 	}
510 
511 	return (error);
512 }
513 
514 
515 int
516 _info(struct modinfo *modinfop)
517 {
518 	return (mod_info(&modlinkage, modinfop));
519 }
520 
521 
522 /*
523  * Device configuration entry points
524  */
525 static int
526 usbsacm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
527 {
528 	return (usbser_attach(dip, cmd, usbsacm_statep, &ds_ops));
529 }
530 
531 
532 static int
533 usbsacm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
534 {
535 	return (usbser_detach(dip, cmd, usbsacm_statep));
536 }
537 
538 
539 int
540 usbsacm_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
541 		void **result)
542 {
543 	return (usbser_getinfo(dip, infocmd, arg, result, usbsacm_statep));
544 }
545 
546 
547 static int
548 usbsacm_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
549 {
550 	return (usbser_open(rq, dev, flag, sflag, cr, usbsacm_statep));
551 }
552 
553 /*
554  * usbsacm_ds_detach:
555  *	attach device instance, called from GSD attach
556  *	initialize state and device, including:
557  *		state variables, locks, device node
558  *		device registration with system
559  *		power management
560  */
561 static int
562 usbsacm_ds_attach(ds_attach_info_t *aip)
563 {
564 	usbsacm_state_t	*acmp;
565 
566 	acmp = (usbsacm_state_t *)kmem_zalloc(sizeof (usbsacm_state_t),
567 	    KM_SLEEP);
568 	acmp->acm_dip = aip->ai_dip;
569 	acmp->acm_usb_events = aip->ai_usb_events;
570 	acmp->acm_ports = NULL;
571 	*aip->ai_hdl = (ds_hdl_t)acmp;
572 
573 	/* registers usbsacm with the USBA framework */
574 	if (usb_client_attach(acmp->acm_dip, USBDRV_VERSION,
575 	    0) != USB_SUCCESS) {
576 
577 		goto fail;
578 	}
579 
580 	/* Get the configuration information of device */
581 	if (usb_get_dev_data(acmp->acm_dip, &acmp->acm_dev_data,
582 	    USB_PARSE_LVL_CFG, 0) != USB_SUCCESS) {
583 
584 		goto fail;
585 	}
586 	acmp->acm_def_ph = acmp->acm_dev_data->dev_default_ph;
587 	acmp->acm_dev_state = USB_DEV_ONLINE;
588 	mutex_init(&acmp->acm_mutex, NULL, MUTEX_DRIVER,
589 	    acmp->acm_dev_data->dev_iblock_cookie);
590 
591 	acmp->acm_lh = usb_alloc_log_hdl(acmp->acm_dip, "usbsacm",
592 	    &usbsacm_errlevel, &usbsacm_errmask, &usbsacm_instance_debug, 0);
593 
594 	/* Create power management components */
595 	if (usbsacm_create_pm_components(acmp) != USB_SUCCESS) {
596 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
597 		    "usbsacm_ds_attach: create pm components failed.");
598 
599 		goto fail;
600 	}
601 
602 	/* Register to get callbacks for USB events */
603 	if (usb_register_event_cbs(acmp->acm_dip, acmp->acm_usb_events, 0)
604 	    != USB_SUCCESS) {
605 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
606 		    "usbsacm_ds_attach: register event callback failed.");
607 
608 		goto fail;
609 	}
610 
611 	/*
612 	 * If devices conform to acm spec, driver will attach using class id;
613 	 * if not, using device id.
614 	 */
615 	if ((strcmp(DEVI(acmp->acm_dip)->devi_binding_name,
616 	    "usbif,class2.2") == 0) ||
617 	    ((strcmp(DEVI(acmp->acm_dip)->devi_binding_name,
618 	    "usb,class2.2.0") == 0))) {
619 
620 		acmp->acm_compatibility = B_TRUE;
621 	} else {
622 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
623 		    "usbsacm_ds_attach: A nonstandard device is attaching to "
624 		    "usbsacm driver. This device doesn't conform to "
625 		    "usb cdc spec.");
626 
627 		acmp->acm_compatibility = B_FALSE;
628 	}
629 
630 	/* initialize state variables */
631 	if (usbsacm_init_alloc_ports(acmp) != USB_SUCCESS) {
632 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
633 		    "usbsacm_ds_attach: initialize port structure failed.");
634 
635 		goto fail;
636 	}
637 	*aip->ai_port_cnt = acmp->acm_port_cnt;
638 
639 	/* Get max data size of bulk transfer */
640 	if (usb_pipe_get_max_bulk_transfer_size(acmp->acm_dip,
641 	    &acmp->acm_xfer_sz) != USB_SUCCESS) {
642 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
643 		    "usbsacm_ds_attach: get max size of transfer failed.");
644 
645 		goto fail;
646 	}
647 
648 	return (USB_SUCCESS);
649 fail:
650 	usbsacm_cleanup(acmp);
651 
652 	return (USB_FAILURE);
653 }
654 
655 
656 /*
657  * usbsacm_ds_detach:
658  *	detach device instance, called from GSD detach
659  */
660 static void
661 usbsacm_ds_detach(ds_hdl_t hdl)
662 {
663 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
664 
665 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
666 	    "usbsacm_ds_detach:");
667 
668 	usbsacm_close_pipes(acmp);
669 	usbsacm_cleanup(acmp);
670 }
671 
672 
673 /*
674  * usbsacm_ds_register_cb:
675  *	GSD routine call ds_register_cb to register interrupt callbacks
676  *	for the given port
677  */
678 /*ARGSUSED*/
679 static int
680 usbsacm_ds_register_cb(ds_hdl_t hdl, uint_t port_num, ds_cb_t *cb)
681 {
682 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
683 	usbsacm_port_t	*acm_port;
684 
685 	USB_DPRINTF_L4(PRINT_MASK_OPEN, acmp->acm_lh,
686 	    "usbsacm_ds_register_cb: acmp = 0x%p port_num = %d",
687 	    (void *)acmp, port_num);
688 
689 	/* Check if port number is greater than actual port number. */
690 	if (port_num >= acmp->acm_port_cnt) {
691 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
692 		    "usbsacm_ds_register_cb: port number is wrong.");
693 
694 		return (USB_FAILURE);
695 	}
696 	acm_port = &acmp->acm_ports[port_num];
697 	acm_port->acm_cb = *cb;
698 
699 	return (USB_SUCCESS);
700 }
701 
702 
703 /*
704  * usbsacm_ds_unregister_cb:
705  *	GSD routine call ds_unregister_cb to unregister
706  *	interrupt callbacks for the given port
707  */
708 /*ARGSUSED*/
709 static void
710 usbsacm_ds_unregister_cb(ds_hdl_t hdl, uint_t port_num)
711 {
712 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
713 	usbsacm_port_t	*acm_port;
714 
715 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
716 	    "usbsacm_ds_unregister_cb: ");
717 
718 	if (port_num < acmp->acm_port_cnt) {
719 		/* Release callback function */
720 		acm_port = &acmp->acm_ports[port_num];
721 		bzero(&acm_port->acm_cb, sizeof (acm_port->acm_cb));
722 	}
723 }
724 
725 
726 /*
727  * usbsacm_ds_open_port:
728  *	GSD routine call ds_open_port
729  *	to open the given port
730  */
731 /*ARGSUSED*/
732 static int
733 usbsacm_ds_open_port(ds_hdl_t hdl, uint_t port_num)
734 {
735 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
736 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
737 
738 	USB_DPRINTF_L4(PRINT_MASK_OPEN, acmp->acm_lh,
739 	    "usbsacm_ds_open_port: port_num = %d", port_num);
740 
741 	mutex_enter(&acm_port->acm_port_mutex);
742 	/* Check the status of the given port and device */
743 	if ((acmp->acm_dev_state == USB_DEV_DISCONNECTED) ||
744 	    (acm_port->acm_port_state != USBSACM_PORT_CLOSED)) {
745 		mutex_exit(&acm_port->acm_port_mutex);
746 
747 		return (USB_FAILURE);
748 	}
749 	mutex_exit(&acm_port->acm_port_mutex);
750 
751 	usbsacm_pm_set_busy(acmp);
752 
753 	/* open pipes of port */
754 	if (usbsacm_open_port_pipes(acm_port) != USB_SUCCESS) {
755 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
756 		    "usbsacm_ds_open_port: open pipes failed.");
757 
758 		return (USB_FAILURE);
759 	}
760 
761 	mutex_enter(&acm_port->acm_port_mutex);
762 	/* data receipt */
763 	if (usbsacm_rx_start(acm_port) != USB_SUCCESS) {
764 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
765 		    "usbsacm_ds_open_port: start receive data failed.");
766 		mutex_exit(&acm_port->acm_port_mutex);
767 
768 		return (USB_FAILURE);
769 	}
770 	acm_port->acm_port_state = USBSACM_PORT_OPEN;
771 
772 	mutex_exit(&acm_port->acm_port_mutex);
773 
774 	return (USB_SUCCESS);
775 }
776 
777 
778 /*
779  * usbsacm_ds_close_port:
780  *	GSD routine call ds_close_port
781  *	to close the given port
782  */
783 /*ARGSUSED*/
784 static int
785 usbsacm_ds_close_port(ds_hdl_t hdl, uint_t port_num)
786 {
787 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
788 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
789 	int		rval = USB_SUCCESS;
790 
791 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
792 	    "usbsacm_ds_close_port: acmp = 0x%p", (void *)acmp);
793 
794 	mutex_enter(&acm_port->acm_port_mutex);
795 	acm_port->acm_port_state = USBSACM_PORT_CLOSED;
796 	mutex_exit(&acm_port->acm_port_mutex);
797 
798 	usbsacm_close_port_pipes(acm_port);
799 
800 	mutex_enter(&acm_port->acm_port_mutex);
801 	rval = usbsacm_fifo_flush_locked(acmp, port_num, DS_TX | DS_RX);
802 	mutex_exit(&acm_port->acm_port_mutex);
803 
804 	usbsacm_pm_set_idle(acmp);
805 
806 	return (rval);
807 }
808 
809 
810 /*
811  * usbsacm_ds_usb_power:
812  *	GSD routine call ds_usb_power
813  *	to set power level of the component
814  */
815 /*ARGSUSED*/
816 static int
817 usbsacm_ds_usb_power(ds_hdl_t hdl, int comp, int level, int *new_state)
818 {
819 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
820 	usbsacm_pm_t	*pm = acmp->acm_pm;
821 	int		rval = USB_SUCCESS;
822 
823 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
824 	    "usbsacm_ds_usb_power: ");
825 
826 	/* check if pm is NULL */
827 	if (pm == NULL) {
828 		USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
829 		    "usbsacm_ds_usb_power: pm is NULL.");
830 
831 		return (USB_FAILURE);
832 	}
833 
834 	mutex_enter(&acmp->acm_mutex);
835 	/*
836 	 * check if we are transitioning to a legal power level
837 	 */
838 	if (USB_DEV_PWRSTATE_OK(pm->pm_pwr_states, level)) {
839 		USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
840 		    "usbsacm_ds_usb_power: "
841 		    "illegal power level %d, pwr_states=%x",
842 		    level, pm->pm_pwr_states);
843 		mutex_exit(&acmp->acm_mutex);
844 
845 		return (USB_FAILURE);
846 	}
847 
848 	/*
849 	 * if we are about to raise power and asked to lower power, fail
850 	 */
851 	if (pm->pm_raise_power && (level < (int)pm->pm_cur_power)) {
852 		USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
853 		    "usbsacm_ds_usb_power: wrong condition.");
854 		mutex_exit(&acmp->acm_mutex);
855 
856 		return (USB_FAILURE);
857 	}
858 
859 	/*
860 	 * Set the power status of device by request level.
861 	 */
862 	switch (level) {
863 	case USB_DEV_OS_PWR_OFF:
864 		rval = usbsacm_pwrlvl0(acmp);
865 
866 		break;
867 	case USB_DEV_OS_PWR_1:
868 		rval = usbsacm_pwrlvl1(acmp);
869 
870 		break;
871 	case USB_DEV_OS_PWR_2:
872 		rval = usbsacm_pwrlvl2(acmp);
873 
874 		break;
875 	case USB_DEV_OS_FULL_PWR:
876 		rval = usbsacm_pwrlvl3(acmp);
877 		/*
878 		 * If usbser dev_state is DISCONNECTED or SUSPENDED, it shows
879 		 * that the usb serial device is disconnected/suspended while it
880 		 * is under power down state, now the device is powered up
881 		 * before it is reconnected/resumed. xxx_pwrlvl3() will set dev
882 		 * state to ONLINE, we need to set the dev state back to
883 		 * DISCONNECTED/SUSPENDED.
884 		 */
885 		if ((rval == USB_SUCCESS) &&
886 		    ((*new_state == USB_DEV_DISCONNECTED) ||
887 		    (*new_state == USB_DEV_SUSPENDED))) {
888 			acmp->acm_dev_state = *new_state;
889 		}
890 
891 		break;
892 	}
893 
894 	*new_state = acmp->acm_dev_state;
895 	mutex_exit(&acmp->acm_mutex);
896 
897 	return (rval);
898 }
899 
900 
901 /*
902  * usbsacm_ds_suspend:
903  *	GSD routine call ds_suspend
904  *	during CPR suspend
905  */
906 static int
907 usbsacm_ds_suspend(ds_hdl_t hdl)
908 {
909 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
910 	int		state = USB_DEV_SUSPENDED;
911 
912 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
913 	    "usbsacm_ds_suspend: ");
914 	/*
915 	 * If the device is suspended while it is under PWRED_DOWN state, we
916 	 * need to keep the PWRED_DOWN state so that it could be powered up
917 	 * later. In the mean while, usbser dev state will be changed to
918 	 * SUSPENDED state.
919 	 */
920 	mutex_enter(&acmp->acm_mutex);
921 	if (acmp->acm_dev_state != USB_DEV_PWRED_DOWN) {
922 		/* set device status to suspend */
923 		acmp->acm_dev_state = USB_DEV_SUSPENDED;
924 	}
925 	mutex_exit(&acmp->acm_mutex);
926 
927 	usbsacm_disconnect_pipes(acmp);
928 
929 	return (state);
930 }
931 
932 /*
933  * usbsacm_ds_resume:
934  *	GSD routine call ds_resume
935  *	during CPR resume
936  */
937 /*ARGSUSED*/
938 static int
939 usbsacm_ds_resume(ds_hdl_t hdl)
940 {
941 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
942 	int		current_state;
943 	int		ret;
944 
945 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
946 	    "usbsacm_ds_resume: ");
947 
948 	mutex_enter(&acmp->acm_mutex);
949 	current_state = acmp->acm_dev_state;
950 	mutex_exit(&acmp->acm_mutex);
951 
952 	/* restore the status of device */
953 	if (current_state != USB_DEV_ONLINE) {
954 		ret = usbsacm_restore_device_state(acmp);
955 	} else {
956 		ret = USB_DEV_ONLINE;
957 	}
958 
959 	return (ret);
960 }
961 
962 /*
963  * usbsacm_ds_disconnect:
964  *	GSD routine call ds_disconnect
965  *	to disconnect USB device
966  */
967 static int
968 usbsacm_ds_disconnect(ds_hdl_t hdl)
969 {
970 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
971 	int		state = USB_DEV_DISCONNECTED;
972 
973 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
974 	    "usbsacm_ds_disconnect: ");
975 
976 	/*
977 	 * If the device is disconnected while it is under PWRED_DOWN state, we
978 	 * need to keep the PWRED_DOWN state so that it could be powered up
979 	 * later. In the mean while, usbser dev state will be changed to
980 	 * DISCONNECTED state.
981 	 */
982 	mutex_enter(&acmp->acm_mutex);
983 	if (acmp->acm_dev_state != USB_DEV_PWRED_DOWN) {
984 		/* set device status to disconnected */
985 		acmp->acm_dev_state = USB_DEV_DISCONNECTED;
986 	}
987 	mutex_exit(&acmp->acm_mutex);
988 
989 	usbsacm_disconnect_pipes(acmp);
990 
991 	return (state);
992 }
993 
994 
995 /*
996  * usbsacm_ds_reconnect:
997  *	GSD routine call ds_reconnect
998  *	to reconnect USB device
999  */
1000 /*ARGSUSED*/
1001 static int
1002 usbsacm_ds_reconnect(ds_hdl_t hdl)
1003 {
1004 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1005 
1006 	USB_DPRINTF_L4(PRINT_MASK_OPEN, acmp->acm_lh,
1007 	    "usbsacm_ds_reconnect: ");
1008 
1009 	return (usbsacm_restore_device_state(acmp));
1010 }
1011 
1012 
1013 /*
1014  * usbsacm_ds_set_port_params:
1015  *	GSD routine call ds_set_port_params
1016  *	to set one or more port parameters
1017  */
1018 /*ARGSUSED*/
1019 static int
1020 usbsacm_ds_set_port_params(ds_hdl_t hdl, uint_t port_num, ds_port_params_t *tp)
1021 {
1022 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1023 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1024 	int		i;
1025 	uint_t		ui;
1026 	ds_port_param_entry_t *pe;
1027 	usb_cdc_line_coding_t lc;
1028 	int		ret;
1029 
1030 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1031 	    "usbsacm_ds_set_port_params: acmp = 0x%p", (void *)acmp);
1032 
1033 	mutex_enter(&acm_port->acm_port_mutex);
1034 	/*
1035 	 * If device conform to acm spec, check if it support to set port param.
1036 	 */
1037 	if ((acm_port->acm_cap & USB_CDC_ACM_CAP_SERIAL_LINE) == 0 &&
1038 	    acmp->acm_compatibility == B_TRUE) {
1039 
1040 		mutex_exit(&acm_port->acm_port_mutex);
1041 		USB_DPRINTF_L2(PRINT_MASK_ALL, acmp->acm_lh,
1042 		    "usbsacm_ds_set_port_params: "
1043 		    "don't support Set_Line_Coding.");
1044 
1045 		return (USB_FAILURE);
1046 	}
1047 
1048 	lc = acm_port->acm_line_coding;
1049 	mutex_exit(&acm_port->acm_port_mutex);
1050 	pe = tp->tp_entries;
1051 	/* Get parameter information from ds_port_params_t */
1052 	for (i = 0; i < tp->tp_cnt; i++, pe++) {
1053 		switch (pe->param) {
1054 		case DS_PARAM_BAUD:
1055 			/* Data terminal rate, in bits per second. */
1056 			ui = pe->val.ui;
1057 
1058 			/* if we don't support this speed, return USB_FAILURE */
1059 			if ((ui >= NELEM(usbsacm_speedtab)) ||
1060 			    ((ui > 0) && (usbsacm_speedtab[ui] == 0))) {
1061 				USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
1062 				    "usbsacm_ds_set_port_params: "
1063 				    " error baud rate");
1064 
1065 				return (USB_FAILURE);
1066 			}
1067 			lc.dwDTERate = LE_32(usbsacm_speedtab[ui]);
1068 
1069 			break;
1070 		case DS_PARAM_PARITY:
1071 			/* Parity Type */
1072 			if (pe->val.ui & PARENB) {
1073 				if (pe->val.ui & PARODD) {
1074 					lc.bParityType = USB_CDC_PARITY_ODD;
1075 				} else {
1076 					lc.bParityType = USB_CDC_PARITY_EVEN;
1077 				}
1078 			} else {
1079 				lc.bParityType = USB_CDC_PARITY_NO;
1080 			}
1081 
1082 			break;
1083 		case DS_PARAM_STOPB:
1084 			/* Stop bit */
1085 			if (pe->val.ui & CSTOPB) {
1086 				lc.bCharFormat = USB_CDC_STOP_BITS_2;
1087 			} else {
1088 				lc.bCharFormat = USB_CDC_STOP_BITS_1;
1089 			}
1090 
1091 			break;
1092 		case DS_PARAM_CHARSZ:
1093 			/* Data Bits */
1094 			switch (pe->val.ui) {
1095 			case CS5:
1096 				lc.bDataBits = 5;
1097 				break;
1098 			case CS6:
1099 				lc.bDataBits = 6;
1100 				break;
1101 			case CS7:
1102 				lc.bDataBits = 7;
1103 				break;
1104 			case CS8:
1105 			default:
1106 				lc.bDataBits = 8;
1107 				break;
1108 			}
1109 
1110 			break;
1111 		default:
1112 			USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
1113 			    "usbsacm_ds_set_port_params: "
1114 			    "parameter 0x%x isn't supported",
1115 			    pe->param);
1116 
1117 			break;
1118 		}
1119 	}
1120 
1121 	if ((ret = usbsacm_set_line_coding(acm_port, &lc)) == USB_SUCCESS) {
1122 		mutex_enter(&acm_port->acm_port_mutex);
1123 		acm_port->acm_line_coding = lc;
1124 		mutex_exit(&acm_port->acm_port_mutex);
1125 	}
1126 
1127 	/*
1128 	 * If device don't conform to acm spec, return success directly.
1129 	 */
1130 	if (acmp->acm_compatibility != B_TRUE) {
1131 		ret = USB_SUCCESS;
1132 	}
1133 
1134 	return (ret);
1135 }
1136 
1137 
1138 /*
1139  * usbsacm_ds_set_modem_ctl:
1140  *	GSD routine call ds_set_modem_ctl
1141  *	to set modem control of the given port
1142  */
1143 /*ARGSUSED*/
1144 static int
1145 usbsacm_ds_set_modem_ctl(ds_hdl_t hdl, uint_t port_num, int mask, int val)
1146 {
1147 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1148 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1149 	uint8_t		new_mctl;
1150 	int		ret;
1151 
1152 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1153 	    "usbsacm_ds_set_modem_ctl: mask = 0x%x val = 0x%x",
1154 	    mask, val);
1155 
1156 	mutex_enter(&acm_port->acm_port_mutex);
1157 	/*
1158 	 * If device conform to acm spec, check if it support to set modem
1159 	 * controls.
1160 	 */
1161 	if ((acm_port->acm_cap & USB_CDC_ACM_CAP_SERIAL_LINE) == 0 &&
1162 	    acmp->acm_compatibility == B_TRUE) {
1163 
1164 		mutex_exit(&acm_port->acm_port_mutex);
1165 		USB_DPRINTF_L2(PRINT_MASK_ALL, acmp->acm_lh,
1166 		    "usbsacm_ds_set_modem_ctl: "
1167 		    "don't support Set_Control_Line_State.");
1168 
1169 		return (USB_FAILURE);
1170 	}
1171 
1172 	new_mctl = acm_port->acm_mctlout;
1173 	mutex_exit(&acm_port->acm_port_mutex);
1174 
1175 	usbsacm_mctl2reg(mask, val, &new_mctl);
1176 
1177 	if ((acmp->acm_compatibility == B_FALSE) || ((ret =
1178 	    usbsacm_req_write(acm_port, USB_CDC_REQ_SET_CONTROL_LINE_STATE,
1179 	    new_mctl, NULL)) == USB_SUCCESS)) {
1180 		mutex_enter(&acm_port->acm_port_mutex);
1181 		acm_port->acm_mctlout = new_mctl;
1182 		mutex_exit(&acm_port->acm_port_mutex);
1183 	}
1184 
1185 	/*
1186 	 * If device don't conform to acm spec, return success directly.
1187 	 */
1188 	if (acmp->acm_compatibility != B_TRUE) {
1189 		ret = USB_SUCCESS;
1190 	}
1191 
1192 	return (ret);
1193 }
1194 
1195 
1196 /*
1197  * usbsacm_ds_get_modem_ctl:
1198  *	GSD routine call ds_get_modem_ctl
1199  *	to get modem control/status of the given port
1200  */
1201 /*ARGSUSED*/
1202 static int
1203 usbsacm_ds_get_modem_ctl(ds_hdl_t hdl, uint_t port_num, int mask, int *valp)
1204 {
1205 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1206 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1207 
1208 	mutex_enter(&acm_port->acm_port_mutex);
1209 	*valp = usbsacm_reg2mctl(acm_port->acm_mctlout) & mask;
1210 	/*
1211 	 * If device conform to acm spec, polling function can modify the value
1212 	 * of acm_mctlin; else set to default value.
1213 	 */
1214 	if (acmp->acm_compatibility) {
1215 		*valp |= usbsacm_reg2mctl(acm_port->acm_mctlin) & mask;
1216 		*valp |= (mask & (TIOCM_CD | TIOCM_CTS));
1217 	} else {
1218 		*valp |= (mask & (TIOCM_CD | TIOCM_CTS | TIOCM_DSR | TIOCM_RI));
1219 	}
1220 	mutex_exit(&acm_port->acm_port_mutex);
1221 
1222 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1223 	    "usbsacm_ds_get_modem_ctl: val = 0x%x", *valp);
1224 
1225 	return (USB_SUCCESS);
1226 }
1227 
1228 
1229 /*
1230  * usbsacm_ds_tx:
1231  *	GSD routine call ds_break_ctl
1232  *	to set/clear break
1233  */
1234 /*ARGSUSED*/
1235 static int
1236 usbsacm_ds_break_ctl(ds_hdl_t hdl, uint_t port_num, int ctl)
1237 {
1238 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1239 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1240 
1241 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1242 	    "usbsacm_ds_break_ctl: ");
1243 
1244 	mutex_enter(&acm_port->acm_port_mutex);
1245 	/*
1246 	 * If device conform to acm spec, check if it support to send break.
1247 	 */
1248 	if ((acm_port->acm_cap & USB_CDC_ACM_CAP_SEND_BREAK) == 0 &&
1249 	    acmp->acm_compatibility == B_TRUE) {
1250 
1251 		mutex_exit(&acm_port->acm_port_mutex);
1252 		USB_DPRINTF_L2(PRINT_MASK_ALL, acmp->acm_lh,
1253 		    "usbsacm_ds_break_ctl: don't support send break.");
1254 
1255 		return (USB_FAILURE);
1256 	}
1257 	mutex_exit(&acm_port->acm_port_mutex);
1258 
1259 	return (usbsacm_req_write(acm_port, USB_CDC_REQ_SEND_BREAK,
1260 	    ((ctl == DS_ON) ? 0xffff : 0), NULL));
1261 }
1262 
1263 
1264 /*
1265  * usbsacm_ds_tx:
1266  *	GSD routine call ds_tx
1267  *	to data transmit
1268  */
1269 /*ARGSUSED*/
1270 static int
1271 usbsacm_ds_tx(ds_hdl_t hdl, uint_t port_num, mblk_t *mp)
1272 {
1273 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1274 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1275 
1276 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1277 	    "usbsacm_ds_tx: mp = 0x%p acmp = 0x%p", (void *)mp, (void *)acmp);
1278 
1279 	/* sanity checks */
1280 	if (mp == NULL) {
1281 
1282 		return (USB_SUCCESS);
1283 	}
1284 	if (MBLKL(mp) < 1) {
1285 		freemsg(mp);
1286 
1287 		return (USB_SUCCESS);
1288 	}
1289 
1290 	mutex_enter(&acm_port->acm_port_mutex);
1291 	/* put mblk to tail of mblk chain */
1292 	usbsacm_put_tail(&acm_port->acm_tx_mp, mp);
1293 	usbsacm_tx_start(acm_port);
1294 	mutex_exit(&acm_port->acm_port_mutex);
1295 
1296 	return (USB_SUCCESS);
1297 }
1298 
1299 
1300 /*
1301  * usbsacm_ds_rx:
1302  *	GSD routine call ds_rx;
1303  *	to data receipt
1304  */
1305 /*ARGSUSED*/
1306 static mblk_t *
1307 usbsacm_ds_rx(ds_hdl_t hdl, uint_t port_num)
1308 {
1309 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1310 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1311 	mblk_t		*mp;
1312 
1313 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1314 	    "usbsacm_ds_rx: acmp = 0x%p", (void *)acmp);
1315 
1316 	mutex_enter(&acm_port->acm_port_mutex);
1317 
1318 	mp = acm_port->acm_rx_mp;
1319 	acm_port->acm_rx_mp = NULL;
1320 	mutex_exit(&acm_port->acm_port_mutex);
1321 
1322 	return (mp);
1323 }
1324 
1325 
1326 /*
1327  * usbsacm_ds_stop:
1328  *	GSD routine call ds_stop;
1329  *	but acm spec don't define this function
1330  */
1331 /*ARGSUSED*/
1332 static void
1333 usbsacm_ds_stop(ds_hdl_t hdl, uint_t port_num, int dir)
1334 {
1335 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1336 
1337 	USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
1338 	    "usbsacm_ds_stop: don't support!");
1339 }
1340 
1341 
1342 /*
1343  * usbsacm_ds_start:
1344  *	GSD routine call ds_start;
1345  *	but acm spec don't define this function
1346  */
1347 /*ARGSUSED*/
1348 static void
1349 usbsacm_ds_start(ds_hdl_t hdl, uint_t port_num, int dir)
1350 {
1351 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1352 
1353 	USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
1354 	    "usbsacm_ds_start: don't support!");
1355 }
1356 
1357 
1358 /*
1359  * usbsacm_ds_fifo_flush:
1360  *	GSD routine call ds_fifo_flush
1361  *	to flush FIFOs
1362  */
1363 /*ARGSUSED*/
1364 static int
1365 usbsacm_ds_fifo_flush(ds_hdl_t hdl, uint_t port_num, int dir)
1366 {
1367 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1368 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1369 	int		ret = USB_SUCCESS;
1370 
1371 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1372 	    "usbsacm_ds_fifo_flush: ");
1373 
1374 	mutex_enter(&acm_port->acm_port_mutex);
1375 	ret = usbsacm_fifo_flush_locked(acmp, port_num, dir);
1376 	mutex_exit(&acm_port->acm_port_mutex);
1377 
1378 	return (ret);
1379 }
1380 
1381 
1382 /*
1383  * usbsacm_ds_fifo_drain:
1384  *	GSD routine call ds_fifo_drain
1385  *	to wait until empty output FIFO
1386  */
1387 /*ARGSUSED*/
1388 static int
1389 usbsacm_ds_fifo_drain(ds_hdl_t hdl, uint_t port_num, int timeout)
1390 {
1391 	usbsacm_state_t	*acmp = (usbsacm_state_t *)hdl;
1392 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1393 	int		rval = USB_SUCCESS;
1394 
1395 	USB_DPRINTF_L4(PRINT_MASK_EVENTS, acmp->acm_lh,
1396 	    "usbsacm_ds_fifo_drain: ");
1397 
1398 	mutex_enter(&acm_port->acm_port_mutex);
1399 	ASSERT(acm_port->acm_port_state == USBSACM_PORT_OPEN);
1400 
1401 	if (usbsacm_wait_tx_drain(acm_port, timeout) != USB_SUCCESS) {
1402 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
1403 		    "usbsacm_ds_fifo_drain: fifo drain failed.");
1404 		mutex_exit(&acm_port->acm_port_mutex);
1405 
1406 		return (USB_FAILURE);
1407 	}
1408 
1409 	mutex_exit(&acm_port->acm_port_mutex);
1410 
1411 	return (rval);
1412 }
1413 
1414 
1415 /*
1416  * usbsacm_fifo_flush_locked:
1417  *	flush FIFOs of the given ports
1418  */
1419 /*ARGSUSED*/
1420 static int
1421 usbsacm_fifo_flush_locked(usbsacm_state_t *acmp, uint_t port_num, int dir)
1422 {
1423 	usbsacm_port_t	*acm_port = &acmp->acm_ports[port_num];
1424 
1425 	USB_DPRINTF_L4(PRINT_MASK_EVENTS, acmp->acm_lh,
1426 	    "usbsacm_fifo_flush_locked: ");
1427 
1428 	/* flush transmit FIFO if DS_TX is set */
1429 	if ((dir & DS_TX) && acm_port->acm_tx_mp) {
1430 		freemsg(acm_port->acm_tx_mp);
1431 		acm_port->acm_tx_mp = NULL;
1432 	}
1433 	/* flush received FIFO if DS_RX is set */
1434 	if ((dir & DS_RX) && acm_port->acm_rx_mp) {
1435 		freemsg(acm_port->acm_rx_mp);
1436 		acm_port->acm_rx_mp = NULL;
1437 	}
1438 
1439 	return (USB_SUCCESS);
1440 }
1441 
1442 
1443 /*
1444  * usbsacm_get_bulk_pipe_number:
1445  *	Calculate the number of bulk in or out pipes in current device.
1446  */
1447 static int
1448 usbsacm_get_bulk_pipe_number(usbsacm_state_t *acmp, uint_t dir)
1449 {
1450 	int		count = 0;
1451 	int		i, skip;
1452 	usb_if_data_t	*cur_if;
1453 	int		ep_num;
1454 	int		if_num;
1455 	int		if_no;
1456 
1457 	USB_DPRINTF_L4(PRINT_MASK_ATTA, acmp->acm_lh,
1458 	    "usbsacm_get_bulk_pipe_number: ");
1459 
1460 	cur_if = acmp->acm_dev_data->dev_curr_cfg->cfg_if;
1461 	if_num = acmp->acm_dev_data->dev_curr_cfg->cfg_n_if;
1462 	if_no = acmp->acm_dev_data->dev_curr_if;
1463 
1464 	/* search each interface which have bulk endpoint */
1465 	for (i = 0; i < if_num; i++) {
1466 		ep_num = cur_if->if_alt->altif_n_ep;
1467 
1468 		/*
1469 		 * search endpoints in current interface,
1470 		 * which type is input parameter 'dir'
1471 		 */
1472 		for (skip = 0; skip < ep_num; skip++) {
1473 			if (usb_lookup_ep_data(acmp->acm_dip,
1474 			    acmp->acm_dev_data, if_no + i, 0, skip,
1475 			    USB_EP_ATTR_BULK, dir) == NULL) {
1476 
1477 				/*
1478 				 * If not found, skip the internal loop
1479 				 * and search the next interface.
1480 				 */
1481 				break;
1482 			}
1483 			count++;
1484 		}
1485 
1486 		cur_if++;
1487 	}
1488 
1489 	return (count);
1490 }
1491 
1492 
1493 /*
1494  * port management
1495  * ---------------
1496  *	initialize, release port.
1497  *
1498  *
1499  * usbsacm_init_ports_status:
1500  *	Initialize the port status for the current device.
1501  */
1502 static int
1503 usbsacm_init_ports_status(usbsacm_state_t *acmp)
1504 {
1505 	usbsacm_port_t	*cur_port;
1506 	int		i, skip;
1507 	int		if_num;
1508 	int		intr_if_no = 0;
1509 	int		ep_num;
1510 	usb_if_data_t	*cur_if;
1511 
1512 	USB_DPRINTF_L4(PRINT_MASK_OPEN, acmp->acm_lh,
1513 	    "usbsacm_init_ports_status: acmp = 0x%p", (void *)acmp);
1514 
1515 	/* Initialize the port status to default value */
1516 	for (i = 0; i < acmp->acm_port_cnt; i++) {
1517 		cur_port = &acmp->acm_ports[i];
1518 
1519 		cv_init(&cur_port->acm_tx_cv, NULL, CV_DRIVER, NULL);
1520 
1521 		cur_port->acm_port_state = USBSACM_PORT_CLOSED;
1522 
1523 		cur_port->acm_line_coding.dwDTERate = LE_32((uint32_t)9600);
1524 		cur_port->acm_line_coding.bCharFormat = 0;
1525 		cur_port->acm_line_coding.bParityType = USB_CDC_PARITY_NO;
1526 		cur_port->acm_line_coding.bDataBits = 8;
1527 		cur_port->acm_device = acmp;
1528 		mutex_init(&cur_port->acm_port_mutex, NULL, MUTEX_DRIVER,
1529 		    acmp->acm_dev_data->dev_iblock_cookie);
1530 	}
1531 
1532 	/*
1533 	 * If device conform to cdc acm spec, parse function descriptors.
1534 	 */
1535 	if (acmp->acm_compatibility == B_TRUE) {
1536 
1537 		if (usbsacm_get_descriptors(acmp) != USB_SUCCESS) {
1538 
1539 			return (USB_FAILURE);
1540 		}
1541 
1542 		return (USB_SUCCESS);
1543 	}
1544 
1545 	/*
1546 	 * If device don't conform to spec, search pairs of bulk in/out
1547 	 * endpoints and fill port structure.
1548 	 */
1549 	cur_if = acmp->acm_dev_data->dev_curr_cfg->cfg_if;
1550 	if_num = acmp->acm_dev_data->dev_curr_cfg->cfg_n_if;
1551 	cur_port = acmp->acm_ports;
1552 
1553 	/* search each interface which have bulk in and out */
1554 	for (i = 0; i < if_num; i++) {
1555 		ep_num = cur_if->if_alt->altif_n_ep;
1556 
1557 		for (skip = 0; skip < ep_num; skip++) {
1558 
1559 		/* search interrupt pipe. */
1560 		if ((usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1561 		    i, 0, skip, USB_EP_ATTR_INTR, USB_EP_DIR_IN) != NULL)) {
1562 
1563 			intr_if_no = i;
1564 		}
1565 
1566 		/* search pair of bulk in/out endpoints. */
1567 		if ((usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1568 		    i, 0, skip, USB_EP_ATTR_BULK, USB_EP_DIR_IN) == NULL) ||
1569 		    (usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1570 		    i, 0, skip, USB_EP_ATTR_BULK, USB_EP_DIR_OUT) == NULL)) {
1571 
1572 			continue;
1573 		}
1574 
1575 		cur_port->acm_data_if_no = i;
1576 		cur_port->acm_ctrl_if_no = intr_if_no;
1577 		cur_port->acm_data_port_no = skip;
1578 		cur_port++;
1579 		intr_if_no = 0;
1580 		}
1581 
1582 		cur_if++;
1583 	}
1584 
1585 	return (USB_SUCCESS);
1586 }
1587 
1588 
1589 /*
1590  * usbsacm_init_alloc_ports:
1591  *	Allocate memory and initialize the port state for the current device.
1592  */
1593 static int
1594 usbsacm_init_alloc_ports(usbsacm_state_t *acmp)
1595 {
1596 	int		rval = USB_SUCCESS;
1597 	int		count_in = 0, count_out = 0;
1598 
1599 	if (acmp->acm_compatibility) {
1600 		acmp->acm_port_cnt = 1;
1601 	} else {
1602 		/* Calculate the number of the bulk in/out endpoints */
1603 		count_in = usbsacm_get_bulk_pipe_number(acmp, USB_EP_DIR_IN);
1604 		count_out = usbsacm_get_bulk_pipe_number(acmp, USB_EP_DIR_OUT);
1605 
1606 		USB_DPRINTF_L3(PRINT_MASK_OPEN, acmp->acm_lh,
1607 		    "usbsacm_init_alloc_ports: count_in = %d, count_out = %d",
1608 		    count_in, count_out);
1609 
1610 		acmp->acm_port_cnt = min(count_in, count_out);
1611 	}
1612 
1613 	/* return if not found any pair of bulk in/out endpoint. */
1614 	if (acmp->acm_port_cnt == 0) {
1615 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
1616 		    "usbsacm_init_alloc_ports: port count is zero.");
1617 
1618 		return (USB_FAILURE);
1619 	}
1620 
1621 	/* allocate memory for ports */
1622 	acmp->acm_ports = (usbsacm_port_t *)kmem_zalloc(acmp->acm_port_cnt *
1623 	    sizeof (usbsacm_port_t), KM_SLEEP);
1624 	if (acmp->acm_ports == NULL) {
1625 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
1626 		    "usbsacm_init_alloc_ports: allocate memory failed.");
1627 
1628 		return (USB_FAILURE);
1629 	}
1630 
1631 	/* fill the status of port structure. */
1632 	rval = usbsacm_init_ports_status(acmp);
1633 	if (rval != USB_SUCCESS) {
1634 		usbsacm_free_ports(acmp);
1635 	}
1636 
1637 	return (rval);
1638 }
1639 
1640 
1641 /*
1642  * usbsacm_free_ports:
1643  *	Release ports and deallocate memory.
1644  */
1645 static void
1646 usbsacm_free_ports(usbsacm_state_t *acmp)
1647 {
1648 	int		i;
1649 
1650 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
1651 	    "usbsacm_free_ports: ");
1652 
1653 	/* Release memory and data structure for each port */
1654 	for (i = 0; i < acmp->acm_port_cnt; i++) {
1655 		cv_destroy(&acmp->acm_ports[i].acm_tx_cv);
1656 		mutex_destroy(&acmp->acm_ports[i].acm_port_mutex);
1657 	}
1658 	kmem_free((caddr_t)acmp->acm_ports, sizeof (usbsacm_port_t) *
1659 	    acmp->acm_port_cnt);
1660 	acmp->acm_ports = NULL;
1661 }
1662 
1663 
1664 /*
1665  * usbsacm_get_descriptors:
1666  *	analysis functional descriptors of acm device
1667  */
1668 static int
1669 usbsacm_get_descriptors(usbsacm_state_t *acmp)
1670 {
1671 	int			i;
1672 	usb_cfg_data_t		*cfg;
1673 	usb_alt_if_data_t	*altif;
1674 	usb_cvs_data_t		*cvs;
1675 	int			mgmt_cap = 0;
1676 	int			master_if = -1, slave_if = -1;
1677 	usbsacm_port_t		*acm_port = acmp->acm_ports;
1678 
1679 	USB_DPRINTF_L4(PRINT_MASK_ATTA, acmp->acm_lh,
1680 	    "usbsacm_get_descriptors: ");
1681 
1682 	cfg = acmp->acm_dev_data->dev_curr_cfg;
1683 	/* set default control and data interface */
1684 	acm_port->acm_ctrl_if_no = acm_port->acm_data_if_no = 0;
1685 
1686 	/* get current interfaces */
1687 	acm_port->acm_ctrl_if_no = acmp->acm_dev_data->dev_curr_if;
1688 	if (cfg->cfg_if[acm_port->acm_ctrl_if_no].if_n_alt == 0) {
1689 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1690 		    "usbsacm_get_descriptors: elements in if_alt is %d",
1691 		    cfg->cfg_if[acm_port->acm_ctrl_if_no].if_n_alt);
1692 
1693 		return (USB_FAILURE);
1694 	}
1695 
1696 	altif = &cfg->cfg_if[acm_port->acm_ctrl_if_no].if_alt[0];
1697 
1698 	/*
1699 	 * Based on CDC specification, ACM devices usually include the
1700 	 * following function descriptors: Header, ACM, Union and Call
1701 	 * Management function descriptors. This loop search tree data
1702 	 * structure for each acm class descriptor.
1703 	 */
1704 	for (i = 0; i < altif->altif_n_cvs; i++) {
1705 
1706 		cvs = &altif->altif_cvs[i];
1707 
1708 		if ((cvs->cvs_buf == NULL) ||
1709 		    (cvs->cvs_buf[1] != USB_CDC_CS_INTERFACE)) {
1710 			continue;
1711 		}
1712 
1713 		switch (cvs->cvs_buf[2]) {
1714 		case USB_CDC_DESCR_TYPE_CALL_MANAGEMENT:
1715 			/* parse call management functional descriptor. */
1716 			if (cvs->cvs_buf_len >= 5) {
1717 				mgmt_cap = cvs->cvs_buf[3];
1718 				acm_port->acm_data_if_no = cvs->cvs_buf[4];
1719 			}
1720 			break;
1721 		case USB_CDC_DESCR_TYPE_ACM:
1722 			/* parse ACM functional descriptor. */
1723 			if (cvs->cvs_buf_len >= 4) {
1724 				acm_port->acm_cap = cvs->cvs_buf[3];
1725 			}
1726 			break;
1727 		case USB_CDC_DESCR_TYPE_UNION:
1728 			/* parse Union functional descriptor. */
1729 			if (cvs->cvs_buf_len >= 5) {
1730 				master_if = cvs->cvs_buf[3];
1731 				slave_if = cvs->cvs_buf[4];
1732 			}
1733 			break;
1734 		default:
1735 			break;
1736 		}
1737 	}
1738 
1739 	/* For usb acm devices, it must satisfy the following options. */
1740 	if (cfg->cfg_n_if < 2) {
1741 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1742 		    "usbsacm_get_descriptors: # of interfaces %d < 2",
1743 		    cfg->cfg_n_if);
1744 
1745 		return (USB_FAILURE);
1746 	}
1747 
1748 	if (acm_port->acm_data_if_no == 0 &&
1749 	    slave_if != acm_port->acm_data_if_no) {
1750 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1751 		    "usbsacm_get_descriptors: Device hasn't call management "
1752 		    "descriptor and use Union Descriptor.");
1753 
1754 		acm_port->acm_data_if_no = slave_if;
1755 	}
1756 
1757 	if ((master_if != acm_port->acm_ctrl_if_no) ||
1758 	    (slave_if != acm_port->acm_data_if_no)) {
1759 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1760 		    "usbsacm_get_descriptors: control interface or "
1761 		    "data interface don't match.");
1762 
1763 		return (USB_FAILURE);
1764 	}
1765 
1766 	/*
1767 	 * We usually need both call and data capabilities, but
1768 	 * some devices, such as Nokia mobile phones, don't provide
1769 	 * call management descriptor, so we just give a warning
1770 	 * message.
1771 	 */
1772 	if (((mgmt_cap & USB_CDC_CALL_MGMT_CAP_CALL_MGMT) == 0) ||
1773 	    ((mgmt_cap & USB_CDC_CALL_MGMT_CAP_DATA_INTERFACE) == 0)) {
1774 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1775 		    "usbsacm_get_descriptors: "
1776 		    "insufficient mgmt capabilities %x",
1777 		    mgmt_cap);
1778 	}
1779 
1780 	if ((acm_port->acm_ctrl_if_no >= cfg->cfg_n_if) ||
1781 	    (acm_port->acm_data_if_no >= cfg->cfg_n_if)) {
1782 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1783 		    "usbsacm_get_descriptors: control interface %d or "
1784 		    "data interface %d out of range.",
1785 		    acm_port->acm_ctrl_if_no, acm_port->acm_data_if_no);
1786 
1787 		return (USB_FAILURE);
1788 	}
1789 
1790 	/* control interface must have interrupt endpoint */
1791 	if (usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1792 	    acm_port->acm_ctrl_if_no, 0, 0, USB_EP_ATTR_INTR,
1793 	    USB_EP_DIR_IN) == NULL) {
1794 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1795 		    "usbsacm_get_descriptors: "
1796 		    "ctrl interface %d has no interrupt endpoint",
1797 		    acm_port->acm_data_if_no);
1798 
1799 		return (USB_FAILURE);
1800 	}
1801 
1802 	/* data interface must have bulk in and out */
1803 	if (usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1804 	    acm_port->acm_data_if_no, 0, 0, USB_EP_ATTR_BULK,
1805 	    USB_EP_DIR_IN) == NULL) {
1806 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1807 		    "usbsacm_get_descriptors: "
1808 		    "data interface %d has no bulk in endpoint",
1809 		    acm_port->acm_data_if_no);
1810 
1811 		return (USB_FAILURE);
1812 	}
1813 	if (usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1814 	    acm_port->acm_data_if_no, 0, 0, USB_EP_ATTR_BULK,
1815 	    USB_EP_DIR_OUT) == NULL) {
1816 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1817 		    "usbsacm_get_descriptors: "
1818 		    "data interface %d has no bulk out endpoint",
1819 		    acm_port->acm_data_if_no);
1820 
1821 		return (USB_FAILURE);
1822 	}
1823 
1824 	return (USB_SUCCESS);
1825 }
1826 
1827 
1828 /*
1829  * usbsacm_cleanup:
1830  *	Release resources of current device during detach.
1831  */
1832 static void
1833 usbsacm_cleanup(usbsacm_state_t *acmp)
1834 {
1835 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
1836 	    "usbsacm_cleanup: ");
1837 
1838 	if (acmp != NULL) {
1839 		/* free ports */
1840 		if (acmp->acm_ports != NULL) {
1841 			usbsacm_free_ports(acmp);
1842 		}
1843 
1844 		/* unregister callback function */
1845 		if (acmp->acm_usb_events != NULL) {
1846 			usb_unregister_event_cbs(acmp->acm_dip,
1847 			    acmp->acm_usb_events);
1848 		}
1849 
1850 		/* destroy power management components */
1851 		if (acmp->acm_pm != NULL) {
1852 			usbsacm_destroy_pm_components(acmp);
1853 		}
1854 
1855 		/* free description of device tree. */
1856 		if (acmp->acm_def_ph != NULL) {
1857 			mutex_destroy(&acmp->acm_mutex);
1858 
1859 			usb_free_descr_tree(acmp->acm_dip, acmp->acm_dev_data);
1860 			acmp->acm_def_ph = NULL;
1861 		}
1862 
1863 		if (acmp->acm_lh != NULL) {
1864 			usb_free_log_hdl(acmp->acm_lh);
1865 			acmp->acm_lh = NULL;
1866 		}
1867 
1868 		/* detach client device */
1869 		if (acmp->acm_dev_data != NULL) {
1870 			usb_client_detach(acmp->acm_dip, acmp->acm_dev_data);
1871 		}
1872 
1873 		kmem_free((caddr_t)acmp, sizeof (usbsacm_state_t));
1874 	}
1875 }
1876 
1877 
1878 /*
1879  * usbsacm_restore_device_state:
1880  *	restore device state after CPR resume or reconnect
1881  */
1882 static int
1883 usbsacm_restore_device_state(usbsacm_state_t *acmp)
1884 {
1885 	int	state;
1886 
1887 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1888 	    "usbsacm_restore_device_state: ");
1889 
1890 	mutex_enter(&acmp->acm_mutex);
1891 	state = acmp->acm_dev_state;
1892 	mutex_exit(&acmp->acm_mutex);
1893 
1894 	/* Check device status */
1895 	if ((state != USB_DEV_DISCONNECTED) && (state != USB_DEV_SUSPENDED)) {
1896 
1897 		return (state);
1898 	}
1899 
1900 	/* Check if we are talking to the same device */
1901 	if (usb_check_same_device(acmp->acm_dip, acmp->acm_lh, USB_LOG_L0,
1902 	    -1, USB_CHK_ALL, NULL) != USB_SUCCESS) {
1903 		mutex_enter(&acmp->acm_mutex);
1904 		state = acmp->acm_dev_state = USB_DEV_DISCONNECTED;
1905 		mutex_exit(&acmp->acm_mutex);
1906 
1907 		return (state);
1908 	}
1909 
1910 	if (state == USB_DEV_DISCONNECTED) {
1911 		USB_DPRINTF_L1(PRINT_MASK_ALL, acmp->acm_lh,
1912 		    "usbsacm_restore_device_state: Device has been reconnected "
1913 		    "but data may have been lost");
1914 	}
1915 
1916 	/* reconnect pipes */
1917 	if (usbsacm_reconnect_pipes(acmp) != USB_SUCCESS) {
1918 
1919 		return (state);
1920 	}
1921 
1922 	/*
1923 	 * init device state
1924 	 */
1925 	mutex_enter(&acmp->acm_mutex);
1926 	state = acmp->acm_dev_state = USB_DEV_ONLINE;
1927 	mutex_exit(&acmp->acm_mutex);
1928 
1929 	if ((usbsacm_restore_port_state(acmp) != USB_SUCCESS)) {
1930 		USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1931 		    "usbsacm_restore_device_state: failed");
1932 	}
1933 
1934 	return (state);
1935 }
1936 
1937 
1938 /*
1939  * usbsacm_restore_port_state:
1940  *	restore ports state after CPR resume or reconnect
1941  */
1942 static int
1943 usbsacm_restore_port_state(usbsacm_state_t *acmp)
1944 {
1945 	int		i, ret = USB_SUCCESS;
1946 	usbsacm_port_t	*cur_port;
1947 
1948 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
1949 	    "usbsacm_restore_port_state: ");
1950 
1951 	/* restore status of all ports */
1952 	for (i = 0; i < acmp->acm_port_cnt; i++) {
1953 		cur_port = &acmp->acm_ports[i];
1954 		mutex_enter(&cur_port->acm_port_mutex);
1955 		if (cur_port->acm_port_state != USBSACM_PORT_OPEN) {
1956 			mutex_exit(&cur_port->acm_port_mutex);
1957 
1958 			continue;
1959 		}
1960 		mutex_exit(&cur_port->acm_port_mutex);
1961 
1962 		if ((ret = usbsacm_set_line_coding(cur_port,
1963 		    &cur_port->acm_line_coding)) != USB_SUCCESS) {
1964 			USB_DPRINTF_L2(PRINT_MASK_ATTA, acmp->acm_lh,
1965 			    "usbsacm_restore_port_state: failed.");
1966 		}
1967 	}
1968 
1969 	return (ret);
1970 }
1971 
1972 
1973 /*
1974  * pipe management
1975  * ---------------
1976  *
1977  *
1978  * usbsacm_open_port_pipes:
1979  *	Open pipes of one port and set port structure;
1980  *	Each port includes three pipes: bulk in, bulk out and interrupt.
1981  */
1982 static int
1983 usbsacm_open_port_pipes(usbsacm_port_t *acm_port)
1984 {
1985 	int		rval = USB_SUCCESS;
1986 	usbsacm_state_t	*acmp = acm_port->acm_device;
1987 	usb_ep_data_t	*in_data, *out_data, *intr_pipe;
1988 	usb_pipe_policy_t policy;
1989 
1990 	USB_DPRINTF_L4(PRINT_MASK_OPEN, acmp->acm_lh,
1991 	    "usbsacm_open_port_pipes: acmp = 0x%p", (void *)acmp);
1992 
1993 	/* Get bulk and interrupt endpoint data */
1994 	intr_pipe = usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1995 	    acm_port->acm_ctrl_if_no, 0, 0,
1996 	    USB_EP_ATTR_INTR, USB_EP_DIR_IN);
1997 	in_data = usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
1998 	    acm_port->acm_data_if_no, 0, acm_port->acm_data_port_no,
1999 	    USB_EP_ATTR_BULK, USB_EP_DIR_IN);
2000 	out_data = usb_lookup_ep_data(acmp->acm_dip, acmp->acm_dev_data,
2001 	    acm_port->acm_data_if_no, 0, acm_port->acm_data_port_no,
2002 	    USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
2003 
2004 	/* Bulk in and out must exist meanwhile. */
2005 	if ((in_data == NULL) || (out_data == NULL)) {
2006 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
2007 		    "usbsacm_open_port_pipes: look up bulk pipe failed in "
2008 		    "interface %d port %d",
2009 		    acm_port->acm_data_if_no, acm_port->acm_data_port_no);
2010 
2011 		return (USB_FAILURE);
2012 	}
2013 
2014 	/*
2015 	 * If device conform to acm spec, it must have an interrupt pipe
2016 	 * for this port.
2017 	 */
2018 	if (acmp->acm_compatibility == B_TRUE && intr_pipe == NULL) {
2019 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
2020 		    "usbsacm_open_port_pipes: look up interrupt pipe failed in "
2021 		    "interface %d", acm_port->acm_ctrl_if_no);
2022 
2023 		return (USB_FAILURE);
2024 	}
2025 
2026 	policy.pp_max_async_reqs = 2;
2027 
2028 	/* Open bulk in endpoint */
2029 	if (usb_pipe_open(acmp->acm_dip, &in_data->ep_descr, &policy,
2030 	    USB_FLAGS_SLEEP, &acm_port->acm_bulkin_ph) != USB_SUCCESS) {
2031 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
2032 		    "usbsacm_open_port_pipes: open bulkin pipe failed!");
2033 
2034 		return (USB_FAILURE);
2035 	}
2036 
2037 	/* Open bulk out endpoint */
2038 	if (usb_pipe_open(acmp->acm_dip, &out_data->ep_descr, &policy,
2039 	    USB_FLAGS_SLEEP, &acm_port->acm_bulkout_ph) != USB_SUCCESS) {
2040 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
2041 		    "usbsacm_open_port_pipes: open bulkout pipe failed!");
2042 
2043 		usb_pipe_close(acmp->acm_dip, acm_port->acm_bulkin_ph,
2044 		    USB_FLAGS_SLEEP, NULL, NULL);
2045 
2046 		return (USB_FAILURE);
2047 	}
2048 
2049 	/* Open interrupt endpoint if found. */
2050 	if (intr_pipe != NULL) {
2051 
2052 		if (usb_pipe_open(acmp->acm_dip, &intr_pipe->ep_descr, &policy,
2053 		    USB_FLAGS_SLEEP, &acm_port->acm_intr_ph) != USB_SUCCESS) {
2054 			USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
2055 			    "usbsacm_open_port_pipes: "
2056 			    "open control pipe failed");
2057 
2058 			usb_pipe_close(acmp->acm_dip, acm_port->acm_bulkin_ph,
2059 			    USB_FLAGS_SLEEP, NULL, NULL);
2060 			usb_pipe_close(acmp->acm_dip, acm_port->acm_bulkout_ph,
2061 			    USB_FLAGS_SLEEP, NULL, NULL);
2062 
2063 			return (USB_FAILURE);
2064 		}
2065 	}
2066 
2067 	/* initialize the port structure. */
2068 	mutex_enter(&acm_port->acm_port_mutex);
2069 	acm_port->acm_bulkin_size = in_data->ep_descr.wMaxPacketSize;
2070 	acm_port->acm_bulkin_state = USBSACM_PIPE_IDLE;
2071 	acm_port->acm_bulkout_state = USBSACM_PIPE_IDLE;
2072 	if (acm_port->acm_intr_ph != NULL) {
2073 		acm_port->acm_intr_state = USBSACM_PIPE_IDLE;
2074 		acm_port->acm_intr_ep_descr = intr_pipe->ep_descr;
2075 	}
2076 	mutex_exit(&acm_port->acm_port_mutex);
2077 
2078 	if (acm_port->acm_intr_ph != NULL) {
2079 
2080 		usbsacm_pipe_start_polling(acm_port);
2081 	}
2082 
2083 	return (rval);
2084 }
2085 
2086 
2087 /*
2088  * usbsacm_close_port_pipes:
2089  *	Close pipes of one port and reset port structure to closed;
2090  *	Each port includes three pipes: bulk in, bulk out and interrupt.
2091  */
2092 static void
2093 usbsacm_close_port_pipes(usbsacm_port_t	*acm_port)
2094 {
2095 	usbsacm_state_t	*acmp = acm_port->acm_device;
2096 
2097 	mutex_enter(&acm_port->acm_port_mutex);
2098 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
2099 	    "usbsacm_close_port_pipes: acm_bulkin_state = %d",
2100 	    acm_port->acm_bulkin_state);
2101 
2102 	/*
2103 	 * Check the status of the given port. If port is closing or closed,
2104 	 * return directly.
2105 	 */
2106 	if ((acm_port->acm_bulkin_state == USBSACM_PIPE_CLOSED) ||
2107 	    (acm_port->acm_bulkin_state == USBSACM_PIPE_CLOSING)) {
2108 		USB_DPRINTF_L2(PRINT_MASK_CLOSE, acmp->acm_lh,
2109 		    "usbsacm_close_port_pipes: port is closing or has closed");
2110 		mutex_exit(&acm_port->acm_port_mutex);
2111 
2112 		return;
2113 	}
2114 
2115 	acm_port->acm_bulkin_state = USBSACM_PIPE_CLOSING;
2116 	mutex_exit(&acm_port->acm_port_mutex);
2117 
2118 	/* Close pipes */
2119 	usb_pipe_reset(acmp->acm_dip, acm_port->acm_bulkin_ph,
2120 	    USB_FLAGS_SLEEP, 0, 0);
2121 	usb_pipe_close(acmp->acm_dip, acm_port->acm_bulkin_ph,
2122 	    USB_FLAGS_SLEEP, 0, 0);
2123 	usb_pipe_close(acmp->acm_dip, acm_port->acm_bulkout_ph,
2124 	    USB_FLAGS_SLEEP, 0, 0);
2125 	if (acm_port->acm_intr_ph != NULL) {
2126 		usb_pipe_stop_intr_polling(acm_port->acm_intr_ph,
2127 		    USB_FLAGS_SLEEP);
2128 		usb_pipe_close(acmp->acm_dip, acm_port->acm_intr_ph,
2129 		    USB_FLAGS_SLEEP, 0, 0);
2130 	}
2131 
2132 	mutex_enter(&acm_port->acm_port_mutex);
2133 	/* Reset the status of pipes to closed */
2134 	acm_port->acm_bulkin_state = USBSACM_PIPE_CLOSED;
2135 	acm_port->acm_bulkin_ph = NULL;
2136 	acm_port->acm_bulkout_state = USBSACM_PIPE_CLOSED;
2137 	acm_port->acm_bulkout_ph = NULL;
2138 	if (acm_port->acm_intr_ph != NULL) {
2139 		acm_port->acm_intr_state = USBSACM_PIPE_CLOSED;
2140 		acm_port->acm_intr_ph = NULL;
2141 	}
2142 
2143 	mutex_exit(&acm_port->acm_port_mutex);
2144 
2145 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
2146 	    "usbsacm_close_port_pipes: port has been closed.");
2147 }
2148 
2149 
2150 /*
2151  * usbsacm_close_pipes:
2152  *	close all opened pipes of current devices.
2153  */
2154 static void
2155 usbsacm_close_pipes(usbsacm_state_t *acmp)
2156 {
2157 	int		i;
2158 
2159 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
2160 	    "usbsacm_close_pipes: ");
2161 
2162 	/* Close all ports */
2163 	for (i = 0; i < acmp->acm_port_cnt; i++) {
2164 		usbsacm_close_port_pipes(&acmp->acm_ports[i]);
2165 	}
2166 }
2167 
2168 
2169 /*
2170  * usbsacm_disconnect_pipes:
2171  *	this function just call usbsacm_close_pipes.
2172  */
2173 static void
2174 usbsacm_disconnect_pipes(usbsacm_state_t *acmp)
2175 {
2176 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
2177 	    "usbsacm_disconnect_pipes: ");
2178 
2179 	usbsacm_close_pipes(acmp);
2180 }
2181 
2182 
2183 /*
2184  * usbsacm_reconnect_pipes:
2185  *	reconnect pipes in CPR resume or reconnect
2186  */
2187 static int
2188 usbsacm_reconnect_pipes(usbsacm_state_t *acmp)
2189 {
2190 	usbsacm_port_t	*cur_port = acmp->acm_ports;
2191 	int		i;
2192 
2193 	USB_DPRINTF_L4(PRINT_MASK_OPEN, acmp->acm_lh,
2194 	    "usbsacm_reconnect_pipes: ");
2195 
2196 	/* reopen all ports of current device. */
2197 	for (i = 0; i < acmp->acm_port_cnt; i++) {
2198 		cur_port = &acmp->acm_ports[i];
2199 
2200 		mutex_enter(&cur_port->acm_port_mutex);
2201 		/*
2202 		 * If port status is open, reopen it;
2203 		 * else retain the current status.
2204 		 */
2205 		if (cur_port->acm_port_state == USBSACM_PORT_OPEN) {
2206 
2207 			mutex_exit(&cur_port->acm_port_mutex);
2208 			if (usbsacm_open_port_pipes(cur_port) != USB_SUCCESS) {
2209 				USB_DPRINTF_L4(PRINT_MASK_OPEN, acmp->acm_lh,
2210 				    "usbsacm_reconnect_pipes: "
2211 				    "open port %d failed.", i);
2212 
2213 				return (USB_FAILURE);
2214 			}
2215 			mutex_enter(&cur_port->acm_port_mutex);
2216 		}
2217 		mutex_exit(&cur_port->acm_port_mutex);
2218 	}
2219 
2220 	return (USB_SUCCESS);
2221 }
2222 
2223 /*
2224  * usbsacm_bulkin_cb:
2225  *	Bulk In regular and exeception callback;
2226  *	USBA framework will call this callback
2227  *	after deal with bulkin request.
2228  */
2229 /*ARGSUSED*/
2230 static void
2231 usbsacm_bulkin_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2232 {
2233 	usbsacm_port_t	*acm_port = (usbsacm_port_t *)req->bulk_client_private;
2234 	usbsacm_state_t	*acmp = acm_port->acm_device;
2235 	mblk_t		*data;
2236 	int		data_len;
2237 
2238 	data = req->bulk_data;
2239 	data_len = (data) ? MBLKL(data) : 0;
2240 
2241 	mutex_enter(&acm_port->acm_port_mutex);
2242 	USB_DPRINTF_L4(PRINT_MASK_EVENTS, acmp->acm_lh,
2243 	    "usbsacm_bulkin_cb: "
2244 	    "acm_bulkin_state = %d acm_port_state = %d data_len = %d",
2245 	    acm_port->acm_bulkin_state, acm_port->acm_port_state, data_len);
2246 
2247 	if ((acm_port->acm_port_state == USBSACM_PORT_OPEN) && (data_len) &&
2248 	    (req->bulk_completion_reason == USB_CR_OK)) {
2249 		mutex_exit(&acm_port->acm_port_mutex);
2250 		/* prevent USBA from freeing data along with the request */
2251 		req->bulk_data = NULL;
2252 
2253 		/* save data on the receive list */
2254 		usbsacm_put_tail(&acm_port->acm_rx_mp, data);
2255 
2256 		/* invoke GSD receive callback */
2257 		if (acm_port->acm_cb.cb_rx) {
2258 			acm_port->acm_cb.cb_rx(acm_port->acm_cb.cb_arg);
2259 		}
2260 		mutex_enter(&acm_port->acm_port_mutex);
2261 	}
2262 	mutex_exit(&acm_port->acm_port_mutex);
2263 
2264 	usb_free_bulk_req(req);
2265 
2266 	/* receive more */
2267 	mutex_enter(&acm_port->acm_port_mutex);
2268 	if (((acm_port->acm_bulkin_state == USBSACM_PIPE_BUSY) ||
2269 	    (acm_port->acm_bulkin_state == USBSACM_PIPE_IDLE)) &&
2270 	    (acm_port->acm_port_state == USBSACM_PORT_OPEN) &&
2271 	    (acmp->acm_dev_state == USB_DEV_ONLINE)) {
2272 		if (usbsacm_rx_start(acm_port) != USB_SUCCESS) {
2273 			USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2274 			    "usbsacm_bulkin_cb: restart rx fail "
2275 			    "acm_port_state = %d", acm_port->acm_port_state);
2276 		}
2277 	} else if (acm_port->acm_bulkin_state == USBSACM_PIPE_BUSY) {
2278 		acm_port->acm_bulkin_state = USBSACM_PIPE_IDLE;
2279 	}
2280 	mutex_exit(&acm_port->acm_port_mutex);
2281 }
2282 
2283 
2284 /*
2285  * usbsacm_bulkout_cb:
2286  *	Bulk Out regular and exeception callback;
2287  *	USBA framework will call this callback function
2288  *	after deal with bulkout request.
2289  */
2290 /*ARGSUSED*/
2291 static void
2292 usbsacm_bulkout_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
2293 {
2294 	usbsacm_port_t	*acm_port = (usbsacm_port_t *)req->bulk_client_private;
2295 	usbsacm_state_t	*acmp = acm_port->acm_device;
2296 	int		data_len;
2297 	mblk_t		*data = req->bulk_data;
2298 
2299 	USB_DPRINTF_L4(PRINT_MASK_EVENTS, acmp->acm_lh,
2300 	    "usbsacm_bulkout_cb: acmp = 0x%p", (void *)acmp);
2301 
2302 	data_len = (req->bulk_data) ? MBLKL(req->bulk_data) : 0;
2303 
2304 	/* put untransferred residue back on the transfer list */
2305 	if (req->bulk_completion_reason && (data_len > 0)) {
2306 		usbsacm_put_head(&acm_port->acm_tx_mp, data);
2307 		req->bulk_data = NULL;
2308 	}
2309 
2310 	usb_free_bulk_req(req);
2311 
2312 	/* invoke GSD transmit callback */
2313 	if (acm_port->acm_cb.cb_tx) {
2314 		acm_port->acm_cb.cb_tx(acm_port->acm_cb.cb_arg);
2315 	}
2316 
2317 	/* send more */
2318 	mutex_enter(&acm_port->acm_port_mutex);
2319 	acm_port->acm_bulkout_state = USBSACM_PIPE_IDLE;
2320 	if (acm_port->acm_tx_mp == NULL) {
2321 		cv_broadcast(&acm_port->acm_tx_cv);
2322 	} else {
2323 		usbsacm_tx_start(acm_port);
2324 	}
2325 	mutex_exit(&acm_port->acm_port_mutex);
2326 }
2327 
2328 
2329 /*
2330  * usbsacm_rx_start:
2331  *	start data receipt
2332  */
2333 static int
2334 usbsacm_rx_start(usbsacm_port_t *acm_port)
2335 {
2336 	usbsacm_state_t	*acmp = acm_port->acm_device;
2337 	usb_bulk_req_t	*br;
2338 	int		rval = USB_FAILURE;
2339 	int		data_len;
2340 
2341 	USB_DPRINTF_L4(PRINT_MASK_EVENTS, acmp->acm_lh,
2342 	    "usbsacm_rx_start: acm_xfer_sz = 0x%lx acm_bulkin_size = 0x%lx",
2343 	    acmp->acm_xfer_sz, acm_port->acm_bulkin_size);
2344 
2345 	acm_port->acm_bulkin_state = USBSACM_PIPE_BUSY;
2346 	/*
2347 	 * Qualcomm CDMA card won't response the first request,
2348 	 * if the following code don't multiply by 2.
2349 	 */
2350 	data_len = min(acmp->acm_xfer_sz, acm_port->acm_bulkin_size * 2);
2351 	mutex_exit(&acm_port->acm_port_mutex);
2352 
2353 	br = usb_alloc_bulk_req(acmp->acm_dip, data_len, USB_FLAGS_SLEEP);
2354 	if (br == NULL) {
2355 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2356 		    "usbsacm_rx_start: allocate bulk request failed");
2357 
2358 		mutex_enter(&acm_port->acm_port_mutex);
2359 
2360 		return (USB_FAILURE);
2361 	}
2362 	/* initialize bulk in request. */
2363 	br->bulk_len = data_len;
2364 	br->bulk_timeout = USBSACM_BULKIN_TIMEOUT;
2365 	br->bulk_cb = usbsacm_bulkin_cb;
2366 	br->bulk_exc_cb = usbsacm_bulkin_cb;
2367 	br->bulk_client_private = (usb_opaque_t)acm_port;
2368 	br->bulk_attributes = USB_ATTRS_AUTOCLEARING
2369 	    | USB_ATTRS_SHORT_XFER_OK;
2370 
2371 	rval = usb_pipe_bulk_xfer(acm_port->acm_bulkin_ph, br, 0);
2372 
2373 	mutex_enter(&acm_port->acm_port_mutex);
2374 	if (rval != USB_SUCCESS) {
2375 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2376 		    "usbsacm_rx_start: bulk transfer failed %d", rval);
2377 		usb_free_bulk_req(br);
2378 		acm_port->acm_bulkin_state = USBSACM_PIPE_IDLE;
2379 	}
2380 
2381 	return (rval);
2382 }
2383 
2384 
2385 /*
2386  * usbsacm_tx_start:
2387  *	start data transmit
2388  */
2389 static void
2390 usbsacm_tx_start(usbsacm_port_t *acm_port)
2391 {
2392 	int		len;		/* bytes we can transmit */
2393 	mblk_t		*data;		/* data to be transmitted */
2394 	int		data_len;	/* bytes in 'data' */
2395 	mblk_t		*mp;		/* current msgblk */
2396 	int		copylen;	/* bytes copy from 'mp' to 'data' */
2397 	int		rval;
2398 	usbsacm_state_t	*acmp = acm_port->acm_device;
2399 
2400 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
2401 	    "usbsacm_tx_start: ");
2402 
2403 	/* check the transmitted data. */
2404 	if (acm_port->acm_tx_mp == NULL) {
2405 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2406 		    "usbsacm_tx_start: acm_tx_mp is NULL");
2407 
2408 		return;
2409 	}
2410 
2411 	/* check pipe status */
2412 	if (acm_port->acm_bulkout_state != USBSACM_PIPE_IDLE) {
2413 
2414 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2415 		    "usbsacm_tx_start: error state in bulkout endpoint");
2416 
2417 		return;
2418 	}
2419 	ASSERT(MBLKL(acm_port->acm_tx_mp) > 0);
2420 
2421 	/* send as much data as port can receive */
2422 	len = min(msgdsize(acm_port->acm_tx_mp), acmp->acm_xfer_sz);
2423 
2424 	if (len == 0) {
2425 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2426 		    "usbsacm_tx_start: data len is 0");
2427 
2428 		return;
2429 	}
2430 
2431 	/* allocate memory for sending data. */
2432 	if ((data = allocb(len, BPRI_LO)) == NULL) {
2433 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2434 		    "usbsacm_tx_start: failure in allocate memory");
2435 
2436 		return;
2437 	}
2438 
2439 	/*
2440 	 * copy no more than 'len' bytes from mblk chain to transmit mblk 'data'
2441 	 */
2442 	data_len = 0;
2443 	while ((data_len < len) && acm_port->acm_tx_mp) {
2444 		/* Get the first mblk from chain. */
2445 		mp = acm_port->acm_tx_mp;
2446 		copylen = min(MBLKL(mp), len - data_len);
2447 		bcopy(mp->b_rptr, data->b_wptr, copylen);
2448 		mp->b_rptr += copylen;
2449 		data->b_wptr += copylen;
2450 		data_len += copylen;
2451 
2452 		if (MBLKL(mp) < 1) {
2453 			acm_port->acm_tx_mp = unlinkb(mp);
2454 			freeb(mp);
2455 		} else {
2456 			ASSERT(data_len == len);
2457 		}
2458 	}
2459 
2460 	if (data_len <= 0) {
2461 		freeb(data);
2462 
2463 		return;
2464 	}
2465 
2466 	acm_port->acm_bulkout_state = USBSACM_PIPE_BUSY;
2467 
2468 	mutex_exit(&acm_port->acm_port_mutex);
2469 	/* send request. */
2470 	rval = usbsacm_send_data(acm_port, data);
2471 	mutex_enter(&acm_port->acm_port_mutex);
2472 
2473 	/*
2474 	 * If send failed, retransmit data when acm_tx_mp is null.
2475 	 */
2476 	if (rval != USB_SUCCESS) {
2477 		acm_port->acm_bulkout_state = USBSACM_PIPE_IDLE;
2478 		if (acm_port->acm_tx_mp == NULL) {
2479 			usbsacm_put_head(&acm_port->acm_tx_mp, data);
2480 		}
2481 	}
2482 }
2483 
2484 
2485 /*
2486  * usbsacm_send_data:
2487  *	data transfer
2488  */
2489 static int
2490 usbsacm_send_data(usbsacm_port_t *acm_port, mblk_t *data)
2491 {
2492 	usbsacm_state_t	*acmp = acm_port->acm_device;
2493 	usb_bulk_req_t	*br;
2494 	int		rval;
2495 	int		data_len = MBLKL(data);
2496 
2497 	USB_DPRINTF_L4(PRINT_MASK_EVENTS, acmp->acm_lh,
2498 	    "usbsacm_send_data: data address is 0x%p, length = %d",
2499 	    (void *)data, data_len);
2500 
2501 	br = usb_alloc_bulk_req(acmp->acm_dip, 0, USB_FLAGS_SLEEP);
2502 	if (br == NULL) {
2503 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
2504 		    "usbsacm_send_data: alloc req failed.");
2505 
2506 		return (USB_FAILURE);
2507 	}
2508 
2509 	/* initialize the bulk out request */
2510 	br->bulk_data = data;
2511 	br->bulk_len = data_len;
2512 	br->bulk_timeout = USBSACM_BULKOUT_TIMEOUT;
2513 	br->bulk_cb = usbsacm_bulkout_cb;
2514 	br->bulk_exc_cb = usbsacm_bulkout_cb;
2515 	br->bulk_client_private = (usb_opaque_t)acm_port;
2516 	br->bulk_attributes = USB_ATTRS_AUTOCLEARING;
2517 
2518 	rval = usb_pipe_bulk_xfer(acm_port->acm_bulkout_ph, br, 0);
2519 
2520 	if (rval != USB_SUCCESS) {
2521 		USB_DPRINTF_L2(PRINT_MASK_EVENTS, acmp->acm_lh,
2522 		    "usbsacm_send_data: Send Data failed.");
2523 
2524 		/*
2525 		 * Don't free it in usb_free_bulk_req because it will
2526 		 * be linked in usbsacm_put_head
2527 		 */
2528 		br->bulk_data = NULL;
2529 
2530 		usb_free_bulk_req(br);
2531 	}
2532 
2533 	return (rval);
2534 }
2535 
2536 /*
2537  * usbsacm_wait_tx_drain:
2538  *	wait until local tx buffer drains.
2539  *	'timeout' is in seconds, zero means wait forever
2540  */
2541 static int
2542 usbsacm_wait_tx_drain(usbsacm_port_t *acm_port, int timeout)
2543 {
2544 	clock_t		until;
2545 	int		over = 0;
2546 
2547 	until = ddi_get_lbolt() + drv_usectohz(1000 * 1000 * timeout);
2548 
2549 	while (acm_port->acm_tx_mp && !over) {
2550 		if (timeout > 0) {
2551 			over = (cv_timedwait_sig(&acm_port->acm_tx_cv,
2552 			    &acm_port->acm_port_mutex, until) <= 0);
2553 		} else {
2554 			over = (cv_wait_sig(&acm_port->acm_tx_cv,
2555 			    &acm_port->acm_port_mutex) == 0);
2556 		}
2557 	}
2558 
2559 	return ((acm_port->acm_tx_mp == NULL) ? USB_SUCCESS : USB_FAILURE);
2560 }
2561 
2562 
2563 /*
2564  * usbsacm_req_write:
2565  *	send command over control pipe
2566  */
2567 static int
2568 usbsacm_req_write(usbsacm_port_t *acm_port, uchar_t request, uint16_t value,
2569     mblk_t **data)
2570 {
2571 	usbsacm_state_t	*acmp = acm_port->acm_device;
2572 	usb_ctrl_setup_t setup;
2573 	usb_cb_flags_t	cb_flags;
2574 	usb_cr_t	cr;
2575 
2576 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
2577 	    "usbsacm_req_write: ");
2578 
2579 	/* initialize the control request. */
2580 	setup.bmRequestType = USBSACM_REQ_WRITE_IF;
2581 	setup.bRequest = request;
2582 	setup.wValue = value;
2583 	setup.wIndex = acm_port->acm_ctrl_if_no;
2584 	setup.wLength = ((data != NULL) && (*data != NULL)) ? MBLKL(*data) : 0;
2585 	setup.attrs = 0;
2586 
2587 	return (usb_pipe_ctrl_xfer_wait(acmp->acm_def_ph, &setup, data,
2588 	    &cr, &cb_flags, 0));
2589 }
2590 
2591 
2592 /*
2593  * usbsacm_set_line_coding:
2594  *	Send USB_CDC_REQ_SET_LINE_CODING request
2595  */
2596 static int
2597 usbsacm_set_line_coding(usbsacm_port_t *acm_port, usb_cdc_line_coding_t *lc)
2598 {
2599 	mblk_t		*bp;
2600 	int		ret;
2601 
2602 	/* allocate mblk and copy supplied structure into it */
2603 	if ((bp = allocb(USB_CDC_LINE_CODING_LEN, BPRI_HI)) == NULL) {
2604 
2605 		return (USB_NO_RESOURCES);
2606 	}
2607 
2608 #ifndef __lock_lint /* warlock gets confused here */
2609 	*((usb_cdc_line_coding_t *)bp->b_wptr) = *lc;
2610 	bp->b_wptr += USB_CDC_LINE_CODING_LEN;
2611 #endif
2612 
2613 	ret = usbsacm_req_write(acm_port, USB_CDC_REQ_SET_LINE_CODING, 0, &bp);
2614 
2615 	if (bp != NULL) {
2616 		freeb(bp);
2617 	}
2618 
2619 	return (ret);
2620 }
2621 
2622 
2623 
2624 /*
2625  * usbsacm_mctl2reg:
2626  *	Set Modem control status
2627  */
2628 static void
2629 usbsacm_mctl2reg(int mask, int val, uint8_t *line_ctl)
2630 {
2631 	if (mask & TIOCM_RTS) {
2632 		if (val & TIOCM_RTS) {
2633 			*line_ctl |= USB_CDC_ACM_CONTROL_RTS;
2634 		} else {
2635 			*line_ctl &= ~USB_CDC_ACM_CONTROL_RTS;
2636 		}
2637 	}
2638 	if (mask & TIOCM_DTR) {
2639 		if (val & TIOCM_DTR) {
2640 			*line_ctl |= USB_CDC_ACM_CONTROL_DTR;
2641 		} else {
2642 			*line_ctl &= ~USB_CDC_ACM_CONTROL_DTR;
2643 		}
2644 	}
2645 }
2646 
2647 
2648 /*
2649  * usbsacm_reg2mctl:
2650  *	Get Modem control status
2651  */
2652 static int
2653 usbsacm_reg2mctl(uint8_t line_ctl)
2654 {
2655 	int	val = 0;
2656 
2657 	if (line_ctl & USB_CDC_ACM_CONTROL_RTS) {
2658 		val |= TIOCM_RTS;
2659 	}
2660 	if (line_ctl & USB_CDC_ACM_CONTROL_DTR) {
2661 		val |= TIOCM_DTR;
2662 	}
2663 	if (line_ctl & USB_CDC_ACM_CONTROL_DSR) {
2664 		val |= TIOCM_DSR;
2665 	}
2666 	if (line_ctl & USB_CDC_ACM_CONTROL_RNG) {
2667 		val |= TIOCM_RI;
2668 	}
2669 
2670 	return (val);
2671 }
2672 
2673 
2674 /*
2675  * misc routines
2676  * -------------
2677  *
2678  */
2679 
2680 /*
2681  * usbsacm_put_tail:
2682  *	link a message block to tail of message
2683  *	account for the case when message is null
2684  */
2685 static void
2686 usbsacm_put_tail(mblk_t **mpp, mblk_t *bp)
2687 {
2688 	if (*mpp) {
2689 		linkb(*mpp, bp);
2690 	} else {
2691 		*mpp = bp;
2692 	}
2693 }
2694 
2695 
2696 /*
2697  * usbsacm_put_head:
2698  *	put a message block at the head of the message
2699  *	account for the case when message is null
2700  */
2701 static void
2702 usbsacm_put_head(mblk_t **mpp, mblk_t *bp)
2703 {
2704 	if (*mpp) {
2705 		linkb(bp, *mpp);
2706 	}
2707 	*mpp = bp;
2708 }
2709 
2710 
2711 /*
2712  * power management
2713  * ----------------
2714  *
2715  * usbsacm_create_pm_components:
2716  *	create PM components
2717  */
2718 static int
2719 usbsacm_create_pm_components(usbsacm_state_t *acmp)
2720 {
2721 	dev_info_t	*dip = acmp->acm_dip;
2722 	usbsacm_pm_t	*pm;
2723 	uint_t		pwr_states;
2724 	usb_dev_descr_t *dev_descr;
2725 
2726 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
2727 	    "usbsacm_create_pm_components: ");
2728 
2729 	if (usb_create_pm_components(dip, &pwr_states) != USB_SUCCESS) {
2730 		USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
2731 		    "usbsacm_create_pm_components: failed");
2732 
2733 		return (USB_SUCCESS);
2734 	}
2735 
2736 	pm = acmp->acm_pm =
2737 	    (usbsacm_pm_t *)kmem_zalloc(sizeof (usbsacm_pm_t), KM_SLEEP);
2738 
2739 	pm->pm_pwr_states = (uint8_t)pwr_states;
2740 	pm->pm_cur_power = USB_DEV_OS_FULL_PWR;
2741 	/*
2742 	 * Qualcomm CDMA card won't response the following control commands
2743 	 * after receive USB_REMOTE_WAKEUP_ENABLE. So we just set
2744 	 * pm_wakeup_enable to 0 for this specific device.
2745 	 */
2746 	dev_descr = acmp->acm_dev_data->dev_descr;
2747 	if (dev_descr->idVendor == 0x5c6 && dev_descr->idProduct == 0x3100) {
2748 		pm->pm_wakeup_enabled = 0;
2749 	} else {
2750 		pm->pm_wakeup_enabled = (usb_handle_remote_wakeup(dip,
2751 		    USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS);
2752 	}
2753 
2754 	(void) pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
2755 
2756 	return (USB_SUCCESS);
2757 }
2758 
2759 
2760 /*
2761  * usbsacm_destroy_pm_components:
2762  *	destroy PM components
2763  */
2764 static void
2765 usbsacm_destroy_pm_components(usbsacm_state_t *acmp)
2766 {
2767 	usbsacm_pm_t	*pm = acmp->acm_pm;
2768 	dev_info_t	*dip = acmp->acm_dip;
2769 	int		rval;
2770 
2771 	USB_DPRINTF_L4(PRINT_MASK_CLOSE, acmp->acm_lh,
2772 	    "usbsacm_destroy_pm_components: ");
2773 
2774 	if (acmp->acm_dev_state != USB_DEV_DISCONNECTED) {
2775 		if (pm->pm_wakeup_enabled) {
2776 			rval = pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
2777 			if (rval != DDI_SUCCESS) {
2778 				USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
2779 				    "usbsacm_destroy_pm_components: "
2780 				    "raising power failed (%d)", rval);
2781 			}
2782 
2783 			rval = usb_handle_remote_wakeup(dip,
2784 			    USB_REMOTE_WAKEUP_DISABLE);
2785 			if (rval != USB_SUCCESS) {
2786 				USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
2787 				    "usbsacm_destroy_pm_components: "
2788 				    "disable remote wakeup failed (%d)", rval);
2789 			}
2790 		}
2791 
2792 		(void) pm_lower_power(dip, 0, USB_DEV_OS_PWR_OFF);
2793 	}
2794 	kmem_free((caddr_t)pm, sizeof (usbsacm_pm_t));
2795 	acmp->acm_pm = NULL;
2796 }
2797 
2798 
2799 /*
2800  * usbsacm_pm_set_busy:
2801  *	mark device busy and raise power
2802  */
2803 static void
2804 usbsacm_pm_set_busy(usbsacm_state_t *acmp)
2805 {
2806 	usbsacm_pm_t	*pm = acmp->acm_pm;
2807 	dev_info_t	*dip = acmp->acm_dip;
2808 	int		rval;
2809 
2810 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
2811 	    "usbsacm_pm_set_busy: pm = 0x%p", (void *)pm);
2812 
2813 	if (pm == NULL) {
2814 
2815 		return;
2816 	}
2817 
2818 	mutex_enter(&acmp->acm_mutex);
2819 	/* if already marked busy, just increment the counter */
2820 	if (pm->pm_busy_cnt++ > 0) {
2821 		mutex_exit(&acmp->acm_mutex);
2822 
2823 		return;
2824 	}
2825 
2826 	(void) pm_busy_component(dip, 0);
2827 
2828 	if (pm->pm_cur_power == USB_DEV_OS_FULL_PWR) {
2829 		mutex_exit(&acmp->acm_mutex);
2830 
2831 		return;
2832 	}
2833 
2834 	/* need to raise power	*/
2835 	pm->pm_raise_power = B_TRUE;
2836 	mutex_exit(&acmp->acm_mutex);
2837 
2838 	rval = pm_raise_power(dip, 0, USB_DEV_OS_FULL_PWR);
2839 	if (rval != DDI_SUCCESS) {
2840 		USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
2841 		    "usbsacm_pm_set_busy: raising power failed");
2842 	}
2843 
2844 	mutex_enter(&acmp->acm_mutex);
2845 	pm->pm_raise_power = B_FALSE;
2846 	mutex_exit(&acmp->acm_mutex);
2847 }
2848 
2849 
2850 /*
2851  * usbsacm_pm_set_idle:
2852  *	mark device idle
2853  */
2854 static void
2855 usbsacm_pm_set_idle(usbsacm_state_t *acmp)
2856 {
2857 	usbsacm_pm_t	*pm = acmp->acm_pm;
2858 	dev_info_t	*dip = acmp->acm_dip;
2859 
2860 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
2861 	    "usbsacm_pm_set_idle: ");
2862 
2863 	if (pm == NULL) {
2864 
2865 		return;
2866 	}
2867 
2868 	/*
2869 	 * if more ports use the device, do not mark as yet
2870 	 */
2871 	mutex_enter(&acmp->acm_mutex);
2872 	if (--pm->pm_busy_cnt > 0) {
2873 		mutex_exit(&acmp->acm_mutex);
2874 
2875 		return;
2876 	}
2877 
2878 	if (pm) {
2879 		(void) pm_idle_component(dip, 0);
2880 	}
2881 	mutex_exit(&acmp->acm_mutex);
2882 }
2883 
2884 
2885 /*
2886  * usbsacm_pwrlvl0:
2887  *	Functions to handle power transition for OS levels 0 -> 3
2888  *	The same level as OS state, different from USB state
2889  */
2890 static int
2891 usbsacm_pwrlvl0(usbsacm_state_t *acmp)
2892 {
2893 	int		rval;
2894 	int		i;
2895 	usbsacm_port_t	*cur_port = acmp->acm_ports;
2896 
2897 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
2898 	    "usbsacm_pwrlvl0: ");
2899 
2900 	switch (acmp->acm_dev_state) {
2901 	case USB_DEV_ONLINE:
2902 		/* issue USB D3 command to the device */
2903 		rval = usb_set_device_pwrlvl3(acmp->acm_dip);
2904 		ASSERT(rval == USB_SUCCESS);
2905 
2906 		if (cur_port != NULL) {
2907 			for (i = 0; i < acmp->acm_port_cnt; i++) {
2908 				cur_port = &acmp->acm_ports[i];
2909 				if (cur_port->acm_intr_ph != NULL &&
2910 				    cur_port->acm_port_state !=
2911 				    USBSACM_PORT_CLOSED) {
2912 
2913 					mutex_exit(&acmp->acm_mutex);
2914 					usb_pipe_stop_intr_polling(
2915 					    cur_port->acm_intr_ph,
2916 					    USB_FLAGS_SLEEP);
2917 					mutex_enter(&acmp->acm_mutex);
2918 
2919 					mutex_enter(&cur_port->acm_port_mutex);
2920 					cur_port->acm_intr_state =
2921 					    USBSACM_PIPE_IDLE;
2922 					mutex_exit(&cur_port->acm_port_mutex);
2923 				}
2924 			}
2925 		}
2926 
2927 		acmp->acm_dev_state = USB_DEV_PWRED_DOWN;
2928 		acmp->acm_pm->pm_cur_power = USB_DEV_OS_PWR_OFF;
2929 
2930 		/* FALLTHRU */
2931 	case USB_DEV_DISCONNECTED:
2932 	case USB_DEV_SUSPENDED:
2933 		/* allow a disconnect/cpr'ed device to go to lower power */
2934 
2935 		return (USB_SUCCESS);
2936 	case USB_DEV_PWRED_DOWN:
2937 	default:
2938 		USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
2939 		    "usbsacm_pwrlvl0: illegal device state");
2940 
2941 		return (USB_FAILURE);
2942 	}
2943 }
2944 
2945 
2946 /*
2947  * usbsacm_pwrlvl1:
2948  *	Functions to handle power transition for OS levels 1 -> 2
2949  */
2950 static int
2951 usbsacm_pwrlvl1(usbsacm_state_t *acmp)
2952 {
2953 	/* issue USB D2 command to the device */
2954 	(void) usb_set_device_pwrlvl2(acmp->acm_dip);
2955 
2956 	return (USB_FAILURE);
2957 }
2958 
2959 
2960 /*
2961  * usbsacm_pwrlvl2:
2962  *	Functions to handle power transition for OS levels 2 -> 1
2963  */
2964 static int
2965 usbsacm_pwrlvl2(usbsacm_state_t *acmp)
2966 {
2967 	/* issue USB D1 command to the device */
2968 	(void) usb_set_device_pwrlvl1(acmp->acm_dip);
2969 
2970 	return (USB_FAILURE);
2971 }
2972 
2973 
2974 /*
2975  * usbsacm_pwrlvl3:
2976  *	Functions to handle power transition for OS levels 3 -> 0
2977  *	The same level as OS state, different from USB state
2978  */
2979 static int
2980 usbsacm_pwrlvl3(usbsacm_state_t *acmp)
2981 {
2982 	int		rval;
2983 	int		i;
2984 	usbsacm_port_t	*cur_port = acmp->acm_ports;
2985 
2986 	USB_DPRINTF_L4(PRINT_MASK_PM, acmp->acm_lh,
2987 	    "usbsacm_pwrlvl3: ");
2988 
2989 	switch (acmp->acm_dev_state) {
2990 	case USB_DEV_PWRED_DOWN:
2991 		/* Issue USB D0 command to the device here */
2992 		rval = usb_set_device_pwrlvl0(acmp->acm_dip);
2993 		ASSERT(rval == USB_SUCCESS);
2994 
2995 		if (cur_port != NULL) {
2996 			for (i = 0; i < acmp->acm_port_cnt; i++) {
2997 				cur_port = &acmp->acm_ports[i];
2998 				if (cur_port->acm_intr_ph != NULL &&
2999 				    cur_port->acm_port_state !=
3000 				    USBSACM_PORT_CLOSED) {
3001 
3002 					mutex_exit(&acmp->acm_mutex);
3003 					usbsacm_pipe_start_polling(cur_port);
3004 					mutex_enter(&acmp->acm_mutex);
3005 				}
3006 			}
3007 		}
3008 
3009 		acmp->acm_dev_state = USB_DEV_ONLINE;
3010 		acmp->acm_pm->pm_cur_power = USB_DEV_OS_FULL_PWR;
3011 
3012 		/* FALLTHRU */
3013 	case USB_DEV_ONLINE:
3014 		/* we are already in full power */
3015 
3016 		/* FALLTHRU */
3017 	case USB_DEV_DISCONNECTED:
3018 	case USB_DEV_SUSPENDED:
3019 
3020 		return (USB_SUCCESS);
3021 	default:
3022 		USB_DPRINTF_L2(PRINT_MASK_PM, acmp->acm_lh,
3023 		    "usbsacm_pwrlvl3: illegal device state");
3024 
3025 		return (USB_FAILURE);
3026 	}
3027 }
3028 
3029 
3030 /*
3031  * usbsacm_pipe_start_polling:
3032  *	start polling on the interrupt pipe
3033  */
3034 static void
3035 usbsacm_pipe_start_polling(usbsacm_port_t *acm_port)
3036 {
3037 	usb_intr_req_t	*intr;
3038 	int		rval;
3039 	usbsacm_state_t	*acmp = acm_port->acm_device;
3040 
3041 	USB_DPRINTF_L4(PRINT_MASK_ATTA, acmp->acm_lh,
3042 	    "usbsacm_pipe_start_polling: ");
3043 
3044 	if (acm_port->acm_intr_ph == NULL) {
3045 
3046 		return;
3047 	}
3048 
3049 	intr = usb_alloc_intr_req(acmp->acm_dip, 0, USB_FLAGS_SLEEP);
3050 
3051 	/*
3052 	 * If it is in interrupt context, usb_alloc_intr_req will return NULL if
3053 	 * called with SLEEP flag.
3054 	 */
3055 	if (!intr) {
3056 		USB_DPRINTF_L2(PRINT_MASK_OPEN, acmp->acm_lh,
3057 		    "usbsacm_pipe_start_polling: alloc req failed.");
3058 
3059 		return;
3060 	}
3061 
3062 	/* initialize the interrupt request. */
3063 	intr->intr_attributes = USB_ATTRS_SHORT_XFER_OK |
3064 	    USB_ATTRS_AUTOCLEARING;
3065 	mutex_enter(&acm_port->acm_port_mutex);
3066 	intr->intr_len = acm_port->acm_intr_ep_descr.wMaxPacketSize;
3067 	mutex_exit(&acm_port->acm_port_mutex);
3068 	intr->intr_client_private = (usb_opaque_t)acm_port;
3069 	intr->intr_cb = usbsacm_intr_cb;
3070 	intr->intr_exc_cb = usbsacm_intr_ex_cb;
3071 
3072 	rval = usb_pipe_intr_xfer(acm_port->acm_intr_ph, intr, USB_FLAGS_SLEEP);
3073 
3074 	mutex_enter(&acm_port->acm_port_mutex);
3075 	if (rval == USB_SUCCESS) {
3076 		acm_port->acm_intr_state = USBSACM_PIPE_BUSY;
3077 	} else {
3078 		usb_free_intr_req(intr);
3079 		acm_port->acm_intr_state = USBSACM_PIPE_IDLE;
3080 		USB_DPRINTF_L3(PRINT_MASK_OPEN, acmp->acm_lh,
3081 		    "usbsacm_pipe_start_polling: failed (%d)", rval);
3082 	}
3083 	mutex_exit(&acm_port->acm_port_mutex);
3084 }
3085 
3086 
3087 /*
3088  * usbsacm_intr_cb:
3089  *	interrupt pipe normal callback
3090  */
3091 /*ARGSUSED*/
3092 static void
3093 usbsacm_intr_cb(usb_pipe_handle_t ph, usb_intr_req_t *req)
3094 {
3095 	usbsacm_port_t	*acm_port = (usbsacm_port_t *)req->intr_client_private;
3096 	usbsacm_state_t	*acmp = acm_port->acm_device;
3097 	mblk_t		*data = req->intr_data;
3098 	int		data_len;
3099 
3100 	USB_DPRINTF_L4(PRINT_MASK_CB, acmp->acm_lh,
3101 	    "usbsacm_intr_cb: ");
3102 
3103 	data_len = (data) ? MBLKL(data) : 0;
3104 
3105 	/* check data length */
3106 	if (data_len < 8) {
3107 		USB_DPRINTF_L2(PRINT_MASK_CB, acmp->acm_lh,
3108 		    "usbsacm_intr_cb: %d packet too short", data_len);
3109 		usb_free_intr_req(req);
3110 
3111 		return;
3112 	}
3113 	req->intr_data = NULL;
3114 	usb_free_intr_req(req);
3115 
3116 	mutex_enter(&acm_port->acm_port_mutex);
3117 	/* parse interrupt data. */
3118 	usbsacm_parse_intr_data(acm_port, data);
3119 	mutex_exit(&acm_port->acm_port_mutex);
3120 }
3121 
3122 
3123 /*
3124  * usbsacm_intr_ex_cb:
3125  *	interrupt pipe exception callback
3126  */
3127 /*ARGSUSED*/
3128 static void
3129 usbsacm_intr_ex_cb(usb_pipe_handle_t ph, usb_intr_req_t *req)
3130 {
3131 	usbsacm_port_t	*acm_port = (usbsacm_port_t *)req->intr_client_private;
3132 	usbsacm_state_t	*acmp = acm_port->acm_device;
3133 	usb_cr_t	cr = req->intr_completion_reason;
3134 
3135 	USB_DPRINTF_L4(PRINT_MASK_CB, acmp->acm_lh,
3136 	    "usbsacm_intr_ex_cb: ");
3137 
3138 	usb_free_intr_req(req);
3139 
3140 	/*
3141 	 * If completion reason isn't USB_CR_PIPE_CLOSING and
3142 	 * USB_CR_STOPPED_POLLING, restart polling.
3143 	 */
3144 	if ((cr != USB_CR_PIPE_CLOSING) && (cr != USB_CR_STOPPED_POLLING)) {
3145 		mutex_enter(&acmp->acm_mutex);
3146 
3147 		if (acmp->acm_dev_state != USB_DEV_ONLINE) {
3148 
3149 			USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3150 			    "usbsacm_intr_ex_cb: state = %d",
3151 			    acmp->acm_dev_state);
3152 
3153 			mutex_exit(&acmp->acm_mutex);
3154 
3155 			return;
3156 		}
3157 		mutex_exit(&acmp->acm_mutex);
3158 
3159 		usbsacm_pipe_start_polling(acm_port);
3160 	}
3161 }
3162 
3163 
3164 /*
3165  * usbsacm_parse_intr_data:
3166  *	Parse data received from interrupt callback
3167  */
3168 static void
3169 usbsacm_parse_intr_data(usbsacm_port_t *acm_port, mblk_t *data)
3170 {
3171 	usbsacm_state_t	*acmp = acm_port->acm_device;
3172 	uint8_t		bmRequestType;
3173 	uint8_t		bNotification;
3174 	uint16_t	wValue;
3175 	uint16_t	wLength;
3176 	uint16_t	wData;
3177 
3178 	USB_DPRINTF_L4(PRINT_MASK_ALL, acmp->acm_lh,
3179 	    "usbsacm_parse_intr_data: ");
3180 
3181 	bmRequestType = data->b_rptr[0];
3182 	bNotification = data->b_rptr[1];
3183 	/*
3184 	 * If Notification type is NETWORK_CONNECTION, wValue is 0 or 1,
3185 	 * mLength is 0. If Notification type is SERIAL_TYPE, mValue is 0,
3186 	 * mLength is 2. So we directly get the value from the byte.
3187 	 */
3188 	wValue = data->b_rptr[2];
3189 	wLength = data->b_rptr[6];
3190 
3191 	if (bmRequestType != USB_CDC_NOTIFICATION_REQUEST_TYPE) {
3192 		USB_DPRINTF_L2(PRINT_MASK_CB, acmp->acm_lh,
3193 		    "usbsacm_parse_intr_data: unknown request type - 0x%x",
3194 		    bmRequestType);
3195 
3196 		return;
3197 	}
3198 
3199 	/*
3200 	 * Check the return value of device
3201 	 */
3202 	switch (bNotification) {
3203 	case USB_CDC_NOTIFICATION_NETWORK_CONNECTION:
3204 		USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3205 		    "usbsacm_parse_intr_data: %s network!",
3206 		    wValue ? "connected to" :"disconnected from");
3207 
3208 		break;
3209 	case USB_CDC_NOTIFICATION_RESPONSE_AVAILABLE:
3210 		USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3211 		    "usbsacm_parse_intr_data: A response is a available.");
3212 
3213 		break;
3214 	case USB_CDC_NOTIFICATION_SERIAL_STATE:
3215 		/* check the parameter's length. */
3216 		if (wLength != 2) {
3217 
3218 			USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3219 			    "usbsacm_parse_intr_data: error data length.");
3220 		} else {
3221 			/*
3222 			 * The Data field is a bitmapped value that contains
3223 			 * the current state of carrier detect, transmission
3224 			 * carrier, break, ring signal and device overrun
3225 			 * error.
3226 			 */
3227 			wData = data->b_rptr[8];
3228 			/*
3229 			 * Check the serial state of the current port.
3230 			 */
3231 			if (wData & USB_CDC_ACM_CONTROL_DCD) {
3232 
3233 				USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3234 				    "usbsacm_parse_intr_data: "
3235 				    "receiver carrier is set.");
3236 			}
3237 			if (wData & USB_CDC_ACM_CONTROL_DSR) {
3238 
3239 				USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3240 				    "usbsacm_parse_intr_data: "
3241 				    "transmission carrier is set.");
3242 
3243 				acm_port->acm_mctlin |= USB_CDC_ACM_CONTROL_DSR;
3244 			}
3245 			if (wData & USB_CDC_ACM_CONTROL_BREAK) {
3246 
3247 				USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3248 				    "usbsacm_parse_intr_data: "
3249 				    "break detection mechanism is set.");
3250 			}
3251 			if (wData & USB_CDC_ACM_CONTROL_RNG) {
3252 
3253 				USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3254 				    "usbsacm_parse_intr_data: "
3255 				    "ring signal detection is set.");
3256 
3257 				acm_port->acm_mctlin |= USB_CDC_ACM_CONTROL_RNG;
3258 			}
3259 			if (wData & USB_CDC_ACM_CONTROL_FRAMING) {
3260 
3261 				USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3262 				    "usbsacm_parse_intr_data: "
3263 				    "A framing error has occurred.");
3264 			}
3265 			if (wData & USB_CDC_ACM_CONTROL_PARITY) {
3266 
3267 				USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3268 				    "usbsacm_parse_intr_data: "
3269 				    "A parity error has occurred.");
3270 			}
3271 			if (wData & USB_CDC_ACM_CONTROL_OVERRUN) {
3272 
3273 				USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3274 				    "usbsacm_parse_intr_data: "
3275 				    "Received data has been discarded "
3276 				    "due to overrun.");
3277 			}
3278 		}
3279 
3280 		break;
3281 	default:
3282 		USB_DPRINTF_L3(PRINT_MASK_CB, acmp->acm_lh,
3283 		    "usbsacm_parse_intr_data: unknown notification - 0x%x!",
3284 		    bNotification);
3285 
3286 		break;
3287 	}
3288 
3289 	freemsg(data);
3290 }
3291