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