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