xref: /illumos-gate/usr/src/uts/common/io/usb/clients/usbser/usbser_keyspan/keyspan_pipe.c (revision cb6207858a9fcc2feaee22e626912fba281ac969)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  *
30  * keyspanport pipe routines (mostly device-neutral)
31  *
32  */
33 #include <sys/types.h>
34 #include <sys/param.h>
35 #include <sys/conf.h>
36 #include <sys/stream.h>
37 #include <sys/strsun.h>
38 #include <sys/termio.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 
42 #include <sys/usb/usba.h>
43 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_var.h>
44 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_pipe.h>
45 
46 /*
47  * initialize pipe structure with the given parameters
48  */
49 static void
50 keyspan_init_one_pipe(keyspan_state_t *ksp, keyspan_port_t *kp,
51     keyspan_pipe_t *pipe)
52 {
53 	usb_pipe_policy_t	*policy;
54 
55 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_init_one_pipe: "
56 	    "pipe = %p, pipe_stat %x", (void *)pipe, pipe->pipe_state);
57 
58 	/* init sync primitives */
59 	mutex_init(&pipe->pipe_mutex, NULL, MUTEX_DRIVER, (void *)NULL);
60 
61 	/* init pipe policy */
62 	policy = &pipe->pipe_policy;
63 	policy->pp_max_async_reqs = 2;
64 
65 	pipe->pipe_ksp = ksp;
66 	if (kp == NULL) {
67 		/* globle pipes should have device log handle */
68 		pipe->pipe_lh = ksp->ks_lh;
69 	} else {
70 		/* port pipes should have port log handle */
71 		pipe->pipe_lh = kp->kp_lh;
72 	}
73 
74 	pipe->pipe_state = KEYSPAN_PIPE_CLOSED;
75 }
76 
77 
78 static void
79 keyspan_fini_one_pipe(keyspan_pipe_t *pipe)
80 {
81 	USB_DPRINTF_L4(DPRINT_OPEN, pipe->pipe_ksp->ks_lh,
82 	    "keyspan_fini_one_pipe: pipe_stat %x", pipe->pipe_state);
83 
84 	if (pipe->pipe_state != KEYSPAN_PIPE_NOT_INIT) {
85 		mutex_destroy(&pipe->pipe_mutex);
86 		pipe->pipe_state = KEYSPAN_PIPE_NOT_INIT;
87 	}
88 }
89 
90 /*
91  * Lookup the endpoints defined in the spec;
92  * Allocate resources, initialize pipe structures.
93  * All are bulk pipes, including data in/out, cmd/status pipes.
94  */
95 int
96 keyspan_init_pipes(keyspan_state_t *ksp)
97 {
98 	usb_client_dev_data_t *dev_data = ksp->ks_dev_data;
99 	int		ifc, alt, i, j, k = 0;
100 	uint8_t		port_cnt = ksp->ks_dev_spec.port_cnt;
101 	uint8_t		ep_addr, ep_cnt;
102 	usb_ep_data_t	*dataout[KEYSPAN_MAX_PORT_NUM],
103 			*datain[KEYSPAN_MAX_PORT_NUM],
104 			*status = NULL, *ctrl = NULL, *tmp_ep;
105 	usb_alt_if_data_t *alt_data;
106 	usb_if_data_t *if_data;
107 
108 
109 	ifc = dev_data->dev_curr_if;
110 	alt = 0;
111 	if_data = &dev_data->dev_curr_cfg->cfg_if[ifc];
112 	alt_data = &if_data->if_alt[alt];
113 
114 	/*
115 	 * The actual EP number (indicated by bNumEndpoints) is more than
116 	 * those defined in spec. We have to match those we need according
117 	 * to EP addresses. And we'll lookup In EPs and Out EPs separately.
118 	 */
119 	ep_cnt = (alt_data->altif_descr.bNumEndpoints + 1) / 2;
120 
121 	/*
122 	 * get DIR_IN EP descriptors, and then match with EP addresses.
123 	 * Different keyspan devices may has different EP addresses.
124 	 */
125 	for (i = 0; i < ep_cnt; i++) {
126 		tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, i,
127 			    USB_EP_ATTR_BULK, USB_EP_DIR_IN);
128 		if (tmp_ep == NULL) {
129 			USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
130 			    "keyspan_init_pipes: can't find bulk in ep, i=%d,"
131 			    "ep_cnt=%d", i, ep_cnt);
132 
133 			continue;
134 		}
135 		ep_addr = tmp_ep->ep_descr.bEndpointAddress;
136 
137 		USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh, "keyspan_init_pipes: "
138 		    "ep_addr =%x, stat_ep_addr=%x, i=%d", ep_addr,
139 		    ksp->ks_dev_spec.stat_ep_addr, i);
140 
141 		/* match the status EP */
142 		if (ep_addr == ksp->ks_dev_spec.stat_ep_addr) {
143 			status = tmp_ep;
144 
145 			continue;
146 		}
147 
148 		/* match the EPs of the ports */
149 		for (j = 0; j < port_cnt; j++) {
150 			USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
151 			    "keyspan_init_pipes: try to match bulk in data ep,"
152 			    " j=%d", j);
153 			if (ep_addr == ksp->ks_dev_spec.datain_ep_addr[j]) {
154 				datain[j] = tmp_ep;
155 				k++;
156 				USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
157 				    "keyspan_init_pipes: matched a bulk in"
158 				    " data ep");
159 
160 				break;
161 			}
162 		}
163 
164 		/* if have matched all the necessary endpoints, break out */
165 		if (k >= port_cnt && status != NULL) {
166 
167 			break;
168 		}
169 
170 		USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh, "keyspan_init_pipes: "
171 		    "try to match bulk in data ep, j=%d", j);
172 
173 		if (j == port_cnt) {
174 			/* this ep can't be matched by any addr */
175 			USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh,
176 			    "keyspan_init_pipes: can't match bulk in ep,"
177 			    " addr =%x,", ep_addr);
178 		}
179 	}
180 
181 	if (k != port_cnt || status == NULL) {
182 
183 		/* Some of the necessary IN endpoints are not matched */
184 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
185 		    "keyspan_init_pipes: matched %d data in endpoints,"
186 		    " not enough", k);
187 
188 		return (USB_FAILURE);
189 	}
190 
191 	k = 0;
192 
193 	/*
194 	 * get DIR_OUT EP descriptors, and then match with ep addrs.
195 	 * different keyspan devices may has different ep addresses.
196 	 */
197 	for (i = 0; i < ep_cnt; i++) {
198 		tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, i,
199 			    USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
200 		if (tmp_ep == NULL) {
201 			USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
202 			    "keyspan_init_pipes: can't find bulk out ep, i=%d,"
203 			    "ep_cnt=%d", i, ep_cnt);
204 
205 			continue;
206 		}
207 		ep_addr = tmp_ep->ep_descr.bEndpointAddress;
208 
209 		/* match the status ep */
210 		if (ep_addr == ksp->ks_dev_spec.ctrl_ep_addr) {
211 			ctrl = tmp_ep;
212 
213 			continue;
214 		}
215 
216 		/* match the ep of the ports */
217 		for (j = 0; j < port_cnt; j++) {
218 			if (ep_addr == ksp->ks_dev_spec.dataout_ep_addr[j]) {
219 				dataout[j] = tmp_ep;
220 				k++;
221 
222 				break;
223 			}
224 		}
225 		/* if have matched all the necessary endpoints, break out */
226 		if (k >= port_cnt && ctrl != NULL) {
227 
228 			break;
229 		}
230 
231 		if (j == port_cnt) {
232 
233 			/* this ep can't be matched by any addr */
234 			USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh,
235 			    "keyspan_init_pipes: can't match bulk out ep,"
236 			    " ep_addr =%x", ep_addr);
237 
238 		}
239 	}
240 
241 	if (k != port_cnt || ctrl == NULL) {
242 		/* Not all the necessary OUT endpoints are matched */
243 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
244 		    "keyspan_init_pipes: matched %d data in endpoints,"
245 		    " not enough", k);
246 
247 		return (USB_FAILURE);
248 	}
249 
250 	mutex_enter(&ksp->ks_mutex);
251 
252 	/*
253 	 * Device globle pipes: a bulk in pipe for status and a bulk out
254 	 * pipe for controle cmd.
255 	 */
256 	ksp->ks_statin_pipe.pipe_ep_descr = status->ep_descr;
257 	keyspan_init_one_pipe(ksp, NULL, &ksp->ks_statin_pipe);
258 
259 	ksp->ks_ctrlout_pipe.pipe_ep_descr = ctrl->ep_descr;
260 	keyspan_init_one_pipe(ksp, NULL, &ksp->ks_ctrlout_pipe);
261 
262 	/* for data in/out pipes of each port */
263 	for (i = 0; i < port_cnt; i++) {
264 
265 		ksp->ks_ports[i].kp_datain_pipe.pipe_ep_descr =
266 		    datain[i]->ep_descr;
267 		keyspan_init_one_pipe(ksp, &ksp->ks_ports[i],
268 		    &ksp->ks_ports[i].kp_datain_pipe);
269 
270 		ksp->ks_ports[i].kp_dataout_pipe.pipe_ep_descr =
271 		    dataout[i]->ep_descr;
272 		keyspan_init_one_pipe(ksp, &ksp->ks_ports[i],
273 		    &ksp->ks_ports[i].kp_dataout_pipe);
274 	}
275 
276 	mutex_exit(&ksp->ks_mutex);
277 
278 	return (USB_SUCCESS);
279 }
280 /*
281  * For USA_49WG only.
282  * Lookup the endpoints defined in the spec.
283  * Allocate resources, initialize pipe structures.
284  * There are 6 EPs, 3 bulk out Eps, 1 bulk in EP, 1 intr in EP, 1 intr out EP
285  */
286 int
287 keyspan_init_pipes_usa49wg(keyspan_state_t *ksp)
288 {
289 	usb_client_dev_data_t *dev_data = ksp->ks_dev_data;
290 	int		ifc, alt, i, j = 0;
291 	uint8_t		port_cnt = ksp->ks_dev_spec.port_cnt;
292 	uint8_t		ep_addr;
293 	usb_ep_data_t	*dataout[KEYSPAN_MAX_PORT_NUM],
294 			*datain[KEYSPAN_MAX_PORT_NUM],
295 			*status = NULL, *tmp_ep;
296 
297 	ifc = dev_data->dev_curr_if;
298 	alt = 0;
299 
300 	/*
301 	 * get intr out EP descriptor as port0 data out EP, and then
302 	 * match with EP address.
303 	 * Different keyspan devices may has different EP addresses.
304 	 */
305 	tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, 0,
306 		    USB_EP_ATTR_INTR, USB_EP_DIR_OUT);
307 	if (tmp_ep == NULL) {
308 		USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
309 		"keyspan_init_pipes: can't find port1 data out ep");
310 
311 		return (USB_FAILURE);
312 		}
313 	ep_addr = tmp_ep->ep_descr.bEndpointAddress;
314 
315 	/* match the port0 data out EP */
316 	if (ep_addr == ksp->ks_dev_spec.dataout_ep_addr[0]) {
317 		dataout[0] = tmp_ep;
318 	}
319 
320 	/*
321 	 * get bulk out EP descriptors as other port data out EPs, and then
322 	 * match with EP addresses.
323 	 */
324 	for (j = 1; j < port_cnt; j++) {
325 		tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt,
326 				j-1, USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
327 		if (tmp_ep == NULL) {
328 			USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
329 			"keyspan_init_pipes: can't find port[%d] data out ep",
330 			j);
331 			return (USB_FAILURE);
332 		}
333 
334 		ep_addr = tmp_ep->ep_descr.bEndpointAddress;
335 
336 		/* match other port data out EPs */
337 		if (ep_addr == ksp->ks_dev_spec.dataout_ep_addr[j]) {
338 			dataout[j] = tmp_ep;
339 		}
340 	}
341 
342 	/*
343 	 * get intr in EP descriptor as status EP, and then match with EP addrs
344 	 */
345 	tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, 0,
346 		    USB_EP_ATTR_INTR, USB_EP_DIR_IN);
347 	if (tmp_ep == NULL) {
348 		USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
349 		    "keyspan_init_pipes: can't find status in ep");
350 
351 		return (USB_FAILURE);
352 	}
353 	ep_addr = tmp_ep->ep_descr.bEndpointAddress;
354 
355 	/* match the status ep */
356 	if (ep_addr == ksp->ks_dev_spec.stat_ep_addr) {
357 		status = tmp_ep;
358 	}
359 
360 	/*
361 	 * get bulk in EP descriptors as data in EP, All the ports share one
362 	 * data in EP.
363 	 */
364 	tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, 0,
365 		    USB_EP_ATTR_BULK, USB_EP_DIR_IN);
366 	if (tmp_ep == NULL) {
367 		USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
368 		    "keyspan_init_pipes: can't find bulk in ep");
369 
370 		return (USB_FAILURE);
371 	}
372 	ep_addr = tmp_ep->ep_descr.bEndpointAddress;
373 
374 	/* match data in EPs */
375 	if (ep_addr == ksp->ks_dev_spec.datain_ep_addr[0]) {
376 		datain[0] = tmp_ep;
377 	}
378 
379 	mutex_enter(&ksp->ks_mutex);
380 
381 	/* intr in pipe for status */
382 	ksp->ks_statin_pipe.pipe_ep_descr = status->ep_descr;
383 	keyspan_init_one_pipe(ksp, NULL, &ksp->ks_statin_pipe);
384 
385 	/* for data in/out pipes of each port */
386 	for (i = 0; i < port_cnt; i++) {
387 		ksp->ks_ports[i].kp_datain_pipe.pipe_ep_descr =
388 			datain[0]->ep_descr;
389 		keyspan_init_one_pipe(ksp, &ksp->ks_ports[i],
390 				&ksp->ks_ports[i].kp_datain_pipe);
391 
392 		ksp->ks_ports[i].kp_dataout_pipe.pipe_ep_descr =
393 		    dataout[i]->ep_descr;
394 		keyspan_init_one_pipe(ksp, &ksp->ks_ports[i],
395 				&ksp->ks_ports[i].kp_dataout_pipe);
396 	}
397 
398 	mutex_exit(&ksp->ks_mutex);
399 
400 	return (USB_SUCCESS);
401 }
402 
403 void
404 keyspan_fini_pipes(keyspan_state_t *ksp)
405 {
406 	keyspan_port_t	*kp;
407 	int		i;
408 
409 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
410 		kp = &ksp->ks_ports[i];
411 		keyspan_fini_one_pipe(&kp->kp_datain_pipe);
412 		keyspan_fini_one_pipe(&kp->kp_dataout_pipe);
413 	}
414 
415 	/* fini status pipe */
416 	keyspan_fini_one_pipe(&ksp->ks_statin_pipe);
417 	/*
418 	 * fini control pipe
419 	 * If USA_49WG, don't need fini control pipe
420 	 */
421 	switch (ksp->ks_dev_spec.id_product) {
422 		case KEYSPAN_USA19HS_PID:
423 		case KEYSPAN_USA49WLC_PID:
424 			keyspan_fini_one_pipe(&ksp->ks_ctrlout_pipe);
425 
426 			break;
427 		case KEYSPAN_USA49WG_PID:
428 
429 			break;
430 		default:
431 			USB_DPRINTF_L2(DPRINT_CTLOP, ksp->ks_lh,
432 				"keyspan_fini_pipes: the device's product id"
433 				"can't be recognized");
434 	}
435 }
436 
437 static int
438 keyspan_open_one_pipe(keyspan_state_t *ksp, keyspan_pipe_t *pipe)
439 {
440 	int	rval;
441 
442 	/* don't open for the second time */
443 	mutex_enter(&pipe->pipe_mutex);
444 	ASSERT(pipe->pipe_state != KEYSPAN_PIPE_NOT_INIT);
445 	if (pipe->pipe_state != KEYSPAN_PIPE_CLOSED) {
446 		mutex_exit(&pipe->pipe_mutex);
447 
448 		return (USB_SUCCESS);
449 	}
450 	mutex_exit(&pipe->pipe_mutex);
451 
452 	rval = usb_pipe_open(ksp->ks_dip, &pipe->pipe_ep_descr,
453 	    &pipe->pipe_policy, USB_FLAGS_SLEEP, &pipe->pipe_handle);
454 
455 	if (rval == USB_SUCCESS) {
456 		mutex_enter(&pipe->pipe_mutex);
457 		pipe->pipe_state = KEYSPAN_PIPE_OPEN;
458 		mutex_exit(&pipe->pipe_mutex);
459 	}
460 
461 	return (rval);
462 }
463 
464 /*
465  * Open shared datain pipe for USA_49WG
466  */
467 static int
468 keyspan_open_pipe_datain_usa49wg(keyspan_state_t *ksp, keyspan_pipe_t *pipe)
469 {
470 	int	rval = USB_SUCCESS;
471 
472 	/* don't open for the second time */
473 	mutex_enter(&pipe->pipe_mutex);
474 	ASSERT(pipe->pipe_state != KEYSPAN_PIPE_NOT_INIT);
475 	if (pipe->pipe_state != KEYSPAN_PIPE_CLOSED) {
476 		mutex_exit(&pipe->pipe_mutex);
477 
478 		return (USB_SUCCESS);
479 	}
480 	mutex_exit(&pipe->pipe_mutex);
481 
482 	mutex_enter(&ksp->ks_mutex);
483 	ksp->ks_datain_open_cnt++;
484 	if (ksp->ks_datain_open_cnt == 1) {
485 		mutex_exit(&ksp->ks_mutex);
486 
487 		if ((rval = (usb_pipe_open(ksp->ks_dip, &pipe->pipe_ep_descr,
488 			&pipe->pipe_policy, USB_FLAGS_SLEEP,
489 			&pipe->pipe_handle))) == USB_SUCCESS) {
490 				mutex_enter(&pipe->pipe_mutex);
491 				pipe->pipe_state = KEYSPAN_PIPE_OPEN;
492 				mutex_exit(&pipe->pipe_mutex);
493 
494 				mutex_enter(&ksp->ks_mutex);
495 				ksp->ks_datain_pipe_handle = pipe->pipe_handle;
496 				mutex_exit(&ksp->ks_mutex);
497 		} else {
498 				mutex_enter(&ksp->ks_mutex);
499 				ksp->ks_datain_open_cnt--;
500 				mutex_exit(&ksp->ks_mutex);
501 		}
502 
503 		return (rval);
504 	} else {
505 		/* data in pipe has been opened by other port */
506 		ASSERT(ksp->ks_datain_pipe_handle != NULL);
507 
508 		mutex_enter(&pipe->pipe_mutex);
509 		pipe->pipe_handle = ksp->ks_datain_pipe_handle;
510 		/* Set datain pipe state */
511 		pipe->pipe_state = KEYSPAN_PIPE_OPEN;
512 		mutex_exit(&pipe->pipe_mutex);
513 		mutex_exit(&ksp->ks_mutex);
514 
515 		return (USB_SUCCESS);
516 	}
517 }
518 
519 /*
520  * close one pipe if open
521  */
522 static void
523 keyspan_close_one_pipe(keyspan_pipe_t *pipe)
524 {
525 	/*
526 	 * pipe may already be closed, e.g. if device has been physically
527 	 * disconnected and the driver immediately detached
528 	 */
529 	if (pipe->pipe_handle != NULL) {
530 		usb_pipe_close(pipe->pipe_ksp->ks_dip, pipe->pipe_handle,
531 				USB_FLAGS_SLEEP, NULL, NULL);
532 		mutex_enter(&pipe->pipe_mutex);
533 		pipe->pipe_handle = NULL;
534 		pipe->pipe_state = KEYSPAN_PIPE_CLOSED;
535 		mutex_exit(&pipe->pipe_mutex);
536 	}
537 }
538 
539 /*
540  * close shared datain pipe if open for USA_49WG
541  */
542 static void
543 keyspan_close_pipe_datain_usa49wg(keyspan_pipe_t *pipe)
544 {
545 	keyspan_state_t *ksp = pipe->pipe_ksp;
546 	/*
547 	 * pipe may already be closed, e.g. if device has been physically
548 	 * disconnected and the driver immediately detached
549 	 */
550 	if (pipe->pipe_handle != NULL) {
551 		mutex_enter(&ksp->ks_mutex);
552 		ksp->ks_datain_open_cnt--;
553 		if (!ksp->ks_datain_open_cnt) {
554 			mutex_exit(&ksp->ks_mutex);
555 			usb_pipe_close(pipe->pipe_ksp->ks_dip,
556 				pipe->pipe_handle, USB_FLAGS_SLEEP,
557 				NULL, NULL);
558 		} else {
559 			mutex_exit(&ksp->ks_mutex);
560 		}
561 
562 		mutex_enter(&pipe->pipe_mutex);
563 		pipe->pipe_handle = NULL;
564 		pipe->pipe_state = KEYSPAN_PIPE_CLOSED;
565 		mutex_exit(&pipe->pipe_mutex);
566 	}
567 }
568 
569 /*
570  * For USA19HS and USA49WLC:
571  * Open global pipes, a status pipe and a control pipe
572  */
573 int
574 keyspan_open_dev_pipes_usa49(keyspan_state_t *ksp)
575 {
576 	int		rval;
577 
578 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh,
579 			"keyspan_open_dev_pipes_usa49");
580 
581 	rval = keyspan_open_one_pipe(ksp, &ksp->ks_ctrlout_pipe);
582 	if (rval != USB_SUCCESS) {
583 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
584 		"keyspan_open_dev_pipes_usa49: open ctrl pipe failed %d", rval);
585 
586 		return (rval);
587 	}
588 
589 	rval = keyspan_open_one_pipe(ksp, &ksp->ks_statin_pipe);
590 	if (rval != USB_SUCCESS) {
591 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
592 		"keyspan_open_dev_pipes_usa49: open status pipe failed %d",
593 			rval);
594 
595 		/* close the first opened pipe here */
596 		keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe);
597 
598 		return (rval);
599 	}
600 
601 	/* start receive device status */
602 	rval = keyspan_receive_status(ksp);
603 	if (rval != USB_SUCCESS) {
604 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
605 		"keyspan_open_dev_pipes_usa49: receive device status"
606 		    " failed %d", rval);
607 
608 		/* close opened pipes here */
609 		keyspan_close_one_pipe(&ksp->ks_statin_pipe);
610 		keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe);
611 
612 		return (rval);
613 	}
614 
615 	return (rval);
616 }
617 
618 /*
619  * For keyspan USA_49WG:
620  * Open global pipes, a status pipe
621  * Use default control pipe, don't need to open it.
622  */
623 int
624 keyspan_open_dev_pipes_usa49wg(keyspan_state_t *ksp)
625 {
626 	int		rval;
627 
628 	/* Open status pipe */
629 	rval = keyspan_open_one_pipe(ksp, &ksp->ks_statin_pipe);
630 	if (rval != USB_SUCCESS) {
631 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
632 		"keyspan_open_dev_pipes_usa49wg: open status pipe failed %d",
633 			rval);
634 
635 		return (rval);
636 	}
637 	/* start device polling */
638 	keyspan_pipe_start_polling(&ksp->ks_statin_pipe);
639 
640 	return (rval);
641 }
642 
643 /*
644  * Open global pipes, status pipe and control pipe,
645  */
646 int
647 keyspan_open_dev_pipes(keyspan_state_t *ksp)
648 {
649 	int		rval = USB_SUCCESS;
650 
651 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_open_dev_pipes");
652 
653 	switch (ksp->ks_dev_spec.id_product) {
654 	case KEYSPAN_USA19HS_PID:
655 	case KEYSPAN_USA49WLC_PID:
656 		rval = keyspan_open_dev_pipes_usa49(ksp);
657 
658 		break;
659 	case KEYSPAN_USA49WG_PID:
660 		rval = keyspan_open_dev_pipes_usa49wg(ksp);
661 
662 		break;
663 	default:
664 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
665 			"keyspan_open_dev_pipes: the device's product id can't"
666 			"be recognized");
667 
668 		return (USB_FAILURE);
669 	}
670 	return (rval);
671 }
672 
673 /*
674  * Reopen all pipes if the port had them open
675  */
676 int
677 keyspan_reopen_pipes(keyspan_state_t *ksp)
678 {
679 	keyspan_port_t	*kp;
680 	int		i;
681 
682 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_reopen_pipes");
683 
684 	if (keyspan_open_dev_pipes(ksp) != USB_SUCCESS) {
685 
686 		return (USB_FAILURE);
687 	}
688 
689 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
690 		kp = &ksp->ks_ports[i];
691 		mutex_enter(&kp->kp_mutex);
692 		if (kp->kp_state == KEYSPAN_PORT_OPEN) {
693 			USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh,
694 			    "keyspan_reopen_pipes() reopen pipe #%d", i);
695 			mutex_exit(&kp->kp_mutex);
696 			if (keyspan_open_port_pipes(kp) != USB_SUCCESS) {
697 
698 				return (USB_FAILURE);
699 			}
700 			mutex_enter(&kp->kp_mutex);
701 			kp->kp_no_more_reads = B_FALSE;
702 		}
703 		mutex_exit(&kp->kp_mutex);
704 	}
705 
706 	return (USB_SUCCESS);
707 }
708 
709 void
710 keyspan_close_port_pipes(keyspan_port_t *kp)
711 {
712 	keyspan_state_t *ksp =	kp->kp_ksp;
713 
714 	USB_DPRINTF_L4(DPRINT_CLOSE, kp->kp_lh, "keyspan_close_port_pipes");
715 
716 	switch (ksp->ks_dev_spec.id_product) {
717 	case KEYSPAN_USA19HS_PID:
718 	case KEYSPAN_USA49WLC_PID:
719 		keyspan_close_one_pipe(&kp->kp_datain_pipe);
720 
721 		break;
722 	case KEYSPAN_USA49WG_PID:
723 		keyspan_close_pipe_datain_usa49wg(&kp->kp_datain_pipe);
724 
725 		break;
726 	default:
727 		USB_DPRINTF_L2(DPRINT_CLOSE, kp->kp_lh,
728 			"keyspan_close_port_pipes:"
729 			"the device's product id can't be recognized");
730 	}
731 	keyspan_close_one_pipe(&kp->kp_dataout_pipe);
732 }
733 
734 /*
735  * Close IN and OUT bulk pipes of all ports
736  */
737 void
738 keyspan_close_open_pipes(keyspan_state_t *ksp)
739 {
740 	keyspan_port_t	*kp;
741 	int		i;
742 	int		port_num = -1;
743 
744 	USB_DPRINTF_L4(DPRINT_CLOSE, ksp->ks_lh, "keyspan_close_open_pipes");
745 
746 	switch (ksp->ks_dev_spec.id_product) {
747 	case KEYSPAN_USA19HS_PID:
748 	case KEYSPAN_USA49WLC_PID:
749 		for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
750 			kp = &ksp->ks_ports[i];
751 			mutex_enter(&kp->kp_mutex);
752 			if (kp->kp_state == KEYSPAN_PORT_OPEN) {
753 				kp->kp_no_more_reads = B_TRUE;
754 				mutex_exit(&kp->kp_mutex);
755 				usb_pipe_reset(ksp->ks_dip,
756 					kp->kp_datain_pipe.pipe_handle,
757 					USB_FLAGS_SLEEP, NULL, NULL);
758 				keyspan_close_port_pipes(kp);
759 			} else {
760 				mutex_exit(&kp->kp_mutex);
761 			}
762 		}
763 
764 		break;
765 
766 	case KEYSPAN_USA49WG_PID:
767 		for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
768 			kp = &ksp->ks_ports[i];
769 			mutex_enter(&kp->kp_mutex);
770 			if (kp->kp_state == KEYSPAN_PORT_OPEN) {
771 				kp->kp_no_more_reads = B_TRUE;
772 				port_num = i;
773 			}
774 			mutex_exit(&kp->kp_mutex);
775 		}
776 		if (port_num >= 0) {
777 			kp = &ksp->ks_ports[port_num];
778 			usb_pipe_reset(ksp->ks_dip,
779 				kp->kp_datain_pipe.pipe_handle,
780 				USB_FLAGS_SLEEP, NULL, NULL);
781 		}
782 
783 		for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
784 			kp = &ksp->ks_ports[i];
785 			mutex_enter(&kp->kp_mutex);
786 			if (kp->kp_state == KEYSPAN_PORT_OPEN) {
787 				mutex_exit(&kp->kp_mutex);
788 				keyspan_close_port_pipes(kp);
789 			} else {
790 				mutex_exit(&kp->kp_mutex);
791 			}
792 		}
793 
794 		break;
795 	default:
796 		USB_DPRINTF_L2(DPRINT_CLOSE, ksp->ks_lh,
797 			"keyspan_close_open_pipes:"
798 			"the device's product id can't be recognized");
799 
800 	}
801 }
802 
803 /*
804  * Close global pipes
805  */
806 void
807 keyspan_close_dev_pipes(keyspan_state_t *ksp)
808 {
809 	USB_DPRINTF_L4(DPRINT_CLOSE, ksp->ks_lh, "keyspan_close_dev_pipes");
810 
811 	switch (ksp->ks_dev_spec.id_product) {
812 	case KEYSPAN_USA19HS_PID:
813 	case KEYSPAN_USA49WLC_PID:
814 		keyspan_close_one_pipe(&ksp->ks_statin_pipe);
815 		keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe);
816 
817 		break;
818 
819 	case KEYSPAN_USA49WG_PID:
820 		/*
821 		 * USA_49WG use default control pipe, don't need close it
822 		 * Stop polling before close status in pipe
823 		 */
824 		usb_pipe_stop_intr_polling(ksp->ks_statin_pipe.pipe_handle,
825 				USB_FLAGS_SLEEP);
826 		keyspan_close_one_pipe(&ksp->ks_statin_pipe);
827 
828 		break;
829 	default:
830 		USB_DPRINTF_L2(DPRINT_CLOSE, ksp->ks_lh,
831 			"keyspan_close_dev_pipes:"
832 			"the device's product id can't be recognized");
833 	}
834 
835 }
836 
837 /*
838  * Open bulk data IN and data OUT pipes for one port.
839  * The status and control pipes are opened in attach because they are global.
840  */
841 int
842 keyspan_open_port_pipes(keyspan_port_t *kp)
843 {
844 	keyspan_state_t	*ksp = kp->kp_ksp;
845 	int		rval;
846 
847 	USB_DPRINTF_L4(DPRINT_OPEN, kp->kp_lh, "keyspan_open_port_pipes");
848 
849 	switch (ksp->ks_dev_spec.id_product) {
850 	case KEYSPAN_USA19HS_PID:
851 	case KEYSPAN_USA49WLC_PID:
852 		rval = keyspan_open_one_pipe(ksp, &kp->kp_datain_pipe);
853 
854 		break;
855 	case KEYSPAN_USA49WG_PID:
856 		rval = keyspan_open_pipe_datain_usa49wg(ksp,
857 				&kp->kp_datain_pipe);
858 
859 		break;
860 	default:
861 		USB_DPRINTF_L2(DPRINT_OPEN, kp->kp_lh,
862 			"keyspan_open_port_pipes:"
863 			"the device's product id can't be recognized");
864 	}
865 
866 	if (rval != USB_SUCCESS) {
867 
868 		goto fail;
869 	}
870 
871 	rval = keyspan_open_one_pipe(ksp, &kp->kp_dataout_pipe);
872 	if (rval != USB_SUCCESS) {
873 
874 		goto fail;
875 	}
876 
877 	return (rval);
878 
879 fail:
880 	USB_DPRINTF_L2(DPRINT_OPEN, kp->kp_lh,
881 	    "keyspan_open_port_pipes: failed %d", rval);
882 	keyspan_close_port_pipes(kp);
883 
884 	return (rval);
885 }
886 
887 void
888 keyspan_close_pipes(keyspan_state_t *ksp)
889 {
890 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_close_pipes");
891 
892 	/* close all ports' pipes first, and then device ctrl/status pipes. */
893 	keyspan_close_open_pipes(ksp);
894 	keyspan_close_dev_pipes(ksp);
895 }
896 /*
897  * bulk out common callback
898  */
899 /*ARGSUSED*/
900 void
901 keyspan_bulkout_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
902 {
903 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private;
904 	keyspan_pipe_t	*bulkout = &kp->kp_dataout_pipe;
905 	mblk_t		*data = req->bulk_data;
906 	int		data_len;
907 
908 	data_len = (data) ? MBLKL(data) : 0;
909 
910 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh,
911 	    "keyspan_bulkout_cb: len=%d cr=%d cb_flags=%x",
912 	    data_len, req->bulk_completion_reason, req->bulk_cb_flags);
913 
914 	if (req->bulk_completion_reason && data) {
915 
916 		/*
917 		 * Data wasn't transfered successfully.
918 		 * Put data back on the queue.
919 		 */
920 		keyspan_put_head(&kp->kp_tx_mp, data, kp);
921 
922 		/* don't release mem in usb_free_bulk_req */
923 		req->bulk_data = NULL;
924 	}
925 
926 	usb_free_bulk_req(req);
927 
928 	/* if more data available, kick off another transmit */
929 	mutex_enter(&kp->kp_mutex);
930 	if (kp->kp_tx_mp == NULL) {
931 		/*
932 		 * Attach a zero packet if data length is muliple of 64,
933 		 * due to the specification of keyspan_usa19hs.
934 		 */
935 		if ((kp->kp_ksp->ks_dev_spec.id_product ==
936 			KEYSPAN_USA19HS_PID) && (data_len == 64)) {
937 			kp->kp_tx_mp = allocb(0, BPRI_LO);
938 			if (kp->kp_tx_mp) {
939 				keyspan_tx_start(kp, NULL);
940 				mutex_exit(&kp->kp_mutex);
941 
942 				return;
943 			}
944 		}
945 		/* no more data, notify waiters */
946 		cv_broadcast(&kp->kp_tx_cv);
947 		mutex_exit(&kp->kp_mutex);
948 
949 		/* tx callback for this port */
950 		kp->kp_cb.cb_tx(kp->kp_cb.cb_arg);
951 	} else {
952 		keyspan_tx_start(kp, NULL);
953 		mutex_exit(&kp->kp_mutex);
954 	}
955 }
956 
957 /*
958  * intr out common callback for USA_49WG port0 only
959  */
960 /*ARGSUSED*/
961 void
962 keyspan_introut_cb_usa49wg(usb_pipe_handle_t pipe, usb_intr_req_t *req)
963 {
964 	keyspan_port_t	*kp = (keyspan_port_t *)req->intr_client_private;
965 	keyspan_pipe_t	*introut = &kp->kp_dataout_pipe;
966 	mblk_t		*data = req->intr_data;
967 	int		data_len;
968 
969 	data_len = (data) ? MBLKL(data) : 0;
970 
971 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, introut->pipe_lh,
972 	    "keyspan_introut_cb_usa49wg: len=%d cr=%d cb_flags=%x",
973 	    data_len, req->intr_completion_reason, req->intr_cb_flags);
974 
975 	if (req->intr_completion_reason && (data_len > 0)) {
976 
977 		/*
978 		 * Data wasn't transfered successfully.
979 		 * Put data back on the queue.
980 		 */
981 		keyspan_put_head(&kp->kp_tx_mp, data, kp);
982 
983 		/* don't release mem in usb_free_bulk_req */
984 		req->intr_data = NULL;
985 	}
986 
987 	usb_free_intr_req(req);
988 
989 	/* if more data available, kick off another transmit */
990 	mutex_enter(&kp->kp_mutex);
991 	if (kp->kp_tx_mp == NULL) {
992 
993 		/* no more data, notify waiters */
994 		cv_broadcast(&kp->kp_tx_cv);
995 		mutex_exit(&kp->kp_mutex);
996 
997 		/* tx callback for this port */
998 		kp->kp_cb.cb_tx(kp->kp_cb.cb_arg);
999 	} else {
1000 		keyspan_tx_start(kp, NULL);
1001 		mutex_exit(&kp->kp_mutex);
1002 	}
1003 }
1004 
1005 
1006 /* For incoming data only. Parse a status byte and return the err code */
1007 void
1008 keyspan_parse_status(uchar_t *status, uchar_t *err)
1009 {
1010 	if (*status & RXERROR_BREAK) {
1011 		/*
1012 		 * Parity and Framing errors only count if they
1013 		 * occur exclusive of a break being received.
1014 		 */
1015 		*status &= (uint8_t)(RXERROR_OVERRUN | RXERROR_BREAK);
1016 	}
1017 	*err |= (*status & RXERROR_OVERRUN) ? DS_OVERRUN_ERR : 0;
1018 	*err |= (*status & RXERROR_PARITY) ? DS_PARITY_ERR : 0;
1019 	*err |= (*status & RXERROR_FRAMING) ? DS_FRAMING_ERR : 0;
1020 	*err |= (*status & RXERROR_BREAK) ? DS_BREAK_ERR : 0;
1021 }
1022 
1023 /* Bulk in data process function, used by all models */
1024 int
1025 keyspan_bulkin_cb_process(keyspan_port_t *kp,
1026 		uint8_t data_len, uchar_t status, mblk_t *data)
1027 {
1028 	uchar_t	err = 0;
1029 	mblk_t	*mp;
1030 	/*
1031 	 * According to Keyspan spec, if 0x80 bit is clear, there is
1032 	 * only one status byte at the head of the data buf; if 0x80 bit
1033 	 * set, then data buf contains alternate status and data bytes;
1034 	 * In the first case, only OVERRUN err can exist; In the second
1035 	 * case, there are four kinds of err bits may appear in status.
1036 	 */
1037 
1038 	/* if 0x80 bit AND overrun bit are clear, just send up data */
1039 	if (!(status & 0x80) && !(status & RXERROR_OVERRUN)) {
1040 
1041 		/* Get rid of the first status byte */
1042 		data->b_rptr++;
1043 		data_len--;
1044 
1045 	} else if (!(status & 0x80)) {
1046 		/* If 0x80 bit is clear and overrun bit is set */
1047 
1048 		keyspan_parse_status(&status, &err);
1049 		mutex_exit(&kp->kp_mutex);
1050 		if ((mp = allocb(2, BPRI_HI)) == NULL) {
1051 			USB_DPRINTF_L2(DPRINT_IN_PIPE, kp->kp_lh,
1052 			"keyspan_bulkin_cb_process: allocb failed");
1053 			mutex_enter(&kp->kp_mutex);
1054 
1055 			return (0);
1056 		}
1057 		DB_TYPE(mp) = M_BREAK;
1058 		*mp->b_wptr++ = err;
1059 		*mp->b_wptr++ = status;
1060 		mutex_enter(&kp->kp_mutex);
1061 
1062 		/* Add to the received list; Send up the err code. */
1063 		keyspan_put_tail(&kp->kp_rx_mp, mp);
1064 
1065 		/*
1066 		 * Don't send up the first byte because
1067 		 * it is a status byte.
1068 		 */
1069 		data->b_rptr++;
1070 		data_len--;
1071 
1072 	} else { /* 0x80 bit set, there are some errs in the data */
1073 		/*
1074 		 * Usually, there are at least two bytes,
1075 		 * one status and one data.
1076 		 */
1077 		if (data_len > 1) {
1078 			int i = 0;
1079 			int j = 1;
1080 			/*
1081 			 * In this case, there might be multi status
1082 			 * bytes. Parse each status byte and move the
1083 			 * data bytes together.
1084 			 */
1085 			for (j = 1; j < data_len; j += 2) {
1086 				status = data->b_rptr[j-1];
1087 				keyspan_parse_status(&status, &err);
1088 
1089 				/* move the data togeter */
1090 				data->b_rptr[i] = data->b_rptr[j];
1091 				i++;
1092 			}
1093 			data->b_wptr = data->b_rptr + i;
1094 		} else { /* There are only one byte in incoming buf */
1095 			keyspan_parse_status(&status, &err);
1096 		}
1097 		mutex_exit(&kp->kp_mutex);
1098 		if ((mp = allocb(2, BPRI_HI)) == NULL) {
1099 			USB_DPRINTF_L2(DPRINT_IN_PIPE, kp->kp_lh,
1100 			"keyspan_bulkin_cb_process: allocb failed");
1101 			mutex_enter(&kp->kp_mutex);
1102 
1103 			return (0);
1104 		}
1105 		DB_TYPE(mp) = M_BREAK;
1106 		*mp->b_wptr++ = err;
1107 		if (data_len > 2) {
1108 			/*
1109 			 * There are multiple status bytes in this case.
1110 			 * Use err as status character since err is got
1111 			 * by or in all status bytes.
1112 			 */
1113 			*mp->b_wptr++ = err;
1114 		} else {
1115 			*mp->b_wptr++ = status;
1116 		}
1117 		mutex_enter(&kp->kp_mutex);
1118 
1119 		/* Add to the received list; Send up the err code. */
1120 		keyspan_put_tail(&kp->kp_rx_mp, mp);
1121 
1122 		if (data_len > 1) {
1123 			data_len = data->b_wptr - data->b_rptr;
1124 		}
1125 	}
1126 	return (data_len);
1127 }
1128 
1129 /*
1130  * pipe callbacks
1131  * --------------
1132  *
1133  * bulk in common callback for USA19HS and USA49WLC model
1134  */
1135 /*ARGSUSED*/
1136 int
1137 keyspan_bulkin_cb_usa49(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
1138 {
1139 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private;
1140 	keyspan_pipe_t	*bulkin = &kp->kp_datain_pipe;
1141 	mblk_t		*data = req->bulk_data;
1142 	uint_t		cr = req->bulk_completion_reason;
1143 	int		data_len;
1144 
1145 	ASSERT(mutex_owned(&kp->kp_mutex));
1146 
1147 	data_len = (data) ? MBLKL(data) : 0;
1148 
1149 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1150 	    "keyspan_bulkin_cb_usa49: len=%d"
1151 	    " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags);
1152 
1153 	/* put data on the read queue */
1154 	if ((data_len > 0) && (kp->kp_state != KEYSPAN_PORT_CLOSED) &&
1155 	    (cr == USB_CR_OK)) {
1156 		uchar_t	status = data->b_rptr[0];
1157 
1158 		if ((data_len = keyspan_bulkin_cb_process(kp, data_len,
1159 				status, data)) > 0) {
1160 			keyspan_put_tail(&kp->kp_rx_mp, data);
1161 			/*
1162 			 * the data will not be freed and
1163 			 * will be sent up later.
1164 			 */
1165 			req->bulk_data = NULL;
1166 		}
1167 	} else {
1168 		/* usb error happened, so don't send up data */
1169 		data_len = 0;
1170 		USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh,
1171 		    "keyspan_bulkin_cb_usa49: port_state=%d"
1172 		    " b_rptr[0]=%c", kp->kp_state, data->b_rptr[0]);
1173 	}
1174 	if (kp->kp_state != KEYSPAN_PORT_OPEN) {
1175 		kp->kp_no_more_reads = B_TRUE;
1176 	}
1177 
1178 	return (data_len);
1179 }
1180 
1181 /*
1182  * pipe callbacks
1183  * --------------
1184  *
1185  * bulk in common callback for USA_49WG model
1186  */
1187 /*ARGSUSED*/
1188 void
1189 keyspan_bulkin_cb_usa49wg(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
1190 {
1191 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private,
1192 			*kp_true;
1193 	keyspan_state_t *ksp = (keyspan_state_t *)kp->kp_ksp;
1194 	mblk_t		*data = req->bulk_data,
1195 			*mp_data;
1196 	uint_t		cr = req->bulk_completion_reason,
1197 			port_data_len;
1198 	int		data_len, copy_len;
1199 	uint8_t		port_num,
1200 			port_cnt = 0,
1201 			port[4],
1202 			receive_flag = 1;
1203 	uint16_t	status;
1204 	unsigned char	*old_rptr;
1205 
1206 	data_len = (data) ? MBLKL(data) : 0;
1207 
1208 	USB_DPRINTF_L2(DPRINT_IN_PIPE, ksp->ks_lh,
1209 	    "keyspan_bulkin_cb_usa49wg: len=%d"
1210 	    " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags);
1211 
1212 	/* put data on the read queue */
1213 	if ((data_len > 0) && (cr == USB_CR_OK)) {
1214 		old_rptr = data->b_rptr;
1215 		while (data->b_rptr < data->b_wptr) {
1216 			port_num = data->b_rptr[0];
1217 			port_data_len = data->b_rptr[1];
1218 			status = data->b_rptr[2];
1219 			data->b_rptr += 2;
1220 
1221 			if (port_num > 3) {
1222 				USB_DPRINTF_L2(DPRINT_IN_PIPE, ksp->ks_lh,
1223 				"keyspan_bulkin_cb_usa49wg,port num is not"
1224 				" correct: port=%d, len=%d, status=%x",
1225 				port_num, port_data_len, status);
1226 
1227 				break;
1228 			}
1229 
1230 			kp_true = &ksp->ks_ports[port_num];
1231 			port[++port_cnt] = port_num;
1232 			mutex_enter(&kp_true->kp_mutex);
1233 
1234 			if (kp_true->kp_state != KEYSPAN_PORT_OPEN) {
1235 				mutex_exit(&kp_true->kp_mutex);
1236 
1237 				USB_DPRINTF_L2(DPRINT_IN_PIPE, kp_true->kp_lh,
1238 				"keyspan_bulkin_cb_usa49wg,port isn't opened");
1239 				data->b_rptr += port_data_len;
1240 				port_cnt--;
1241 
1242 				continue;
1243 			}
1244 
1245 			USB_DPRINTF_L2(DPRINT_IN_PIPE, kp_true->kp_lh,
1246 			    "keyspan_bulkin_cb_usa49wg: status=0x%x, len=%d",
1247 			    status, port_data_len);
1248 
1249 			if ((copy_len = keyspan_bulkin_cb_process(kp_true,
1250 					port_data_len, status, data)) > 0) {
1251 
1252 				mutex_exit(&kp_true->kp_mutex);
1253 				if ((mp_data = allocb(copy_len, BPRI_HI))
1254 					== NULL) {
1255 					USB_DPRINTF_L2(DPRINT_IN_PIPE,
1256 					kp_true->kp_lh, "keyspan_bulkin_cb_"
1257 					"usa49wg: allocb failed");
1258 
1259 					return;
1260 				}
1261 				mutex_enter(&kp_true->kp_mutex);
1262 				DB_TYPE(mp_data) = M_DATA;
1263 				bcopy(data->b_rptr, mp_data->b_wptr, copy_len);
1264 				mp_data->b_wptr += copy_len;
1265 				if (copy_len < port_data_len -1) {
1266 					/*
1267 					 * data has multi status bytes, b_wptr
1268 					 * has changed by
1269 					 * keyspan_bulkin_process(), need to
1270 					 * be recovered to old one
1271 					 */
1272 					data->b_rptr += port_data_len;
1273 					data->b_wptr = old_rptr + data_len;
1274 				} else {
1275 					data->b_rptr += copy_len;
1276 				}
1277 
1278 				keyspan_put_tail(&kp_true->kp_rx_mp, mp_data);
1279 				mutex_exit(&kp_true->kp_mutex);
1280 			} else {
1281 				mutex_exit(&kp_true->kp_mutex);
1282 
1283 				break;
1284 			}
1285 		} /* End of while loop */
1286 
1287 		while (port_cnt) {
1288 			port_num = port[port_cnt--];
1289 			kp_true = &ksp->ks_ports[port_num];
1290 			mutex_enter(&kp_true->kp_mutex);
1291 
1292 			if (kp_true->kp_state != KEYSPAN_PORT_OPEN) {
1293 				kp_true->kp_no_more_reads = B_TRUE;
1294 			}
1295 			if (receive_flag && (!kp_true->kp_no_more_reads)) {
1296 				mutex_exit(&kp_true->kp_mutex);
1297 				/* kick off another read */
1298 				(void) keyspan_receive_data(
1299 						&kp_true->kp_datain_pipe,
1300 						kp_true->kp_read_len, kp_true);
1301 
1302 				receive_flag = 0;
1303 			} else {
1304 				mutex_exit(&kp_true->kp_mutex);
1305 			}
1306 			/* setup rx callback for this port */
1307 			kp_true->kp_cb.cb_rx(kp_true->kp_cb.cb_arg);
1308 		}
1309 	} else {
1310 		/* cr != USB_CR_OK, usb error happened */
1311 		USB_DPRINTF_L2(DPRINT_IN_PIPE, ksp->ks_lh,
1312 			"keyspan_bulkin_cb_usa49wg: port=%d, len=%d, status=%x",
1313 			data->b_rptr[0], data->b_rptr[1], data->b_rptr[2]);
1314 
1315 		mutex_enter(&kp->kp_mutex);
1316 		if (kp->kp_state != KEYSPAN_PORT_OPEN) {
1317 			kp->kp_no_more_reads = B_TRUE;
1318 		}
1319 		if (!kp->kp_no_more_reads) {
1320 			mutex_exit(&kp->kp_mutex);
1321 			/* kick off another read */
1322 			(void) keyspan_receive_data(&kp->kp_datain_pipe,
1323 					kp->kp_read_len, kp);
1324 		} else {
1325 			mutex_exit(&kp->kp_mutex);
1326 		}
1327 	}
1328 
1329 	freemsg(data);
1330 	req->bulk_data = NULL;
1331 	usb_free_bulk_req(req);
1332 
1333 }
1334 
1335 /*
1336  * pipe callbacks
1337  * --------------
1338  *
1339  * bulk in common callback for USA19HS and USA49WLC
1340  */
1341 /*ARGSUSED*/
1342 void
1343 keyspan_bulkin_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
1344 {
1345 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private;
1346 	int		data_len;
1347 	boolean_t	no_more_reads = B_FALSE;
1348 
1349 	USB_DPRINTF_L4(DPRINT_IN_PIPE, (&kp->kp_datain_pipe)->pipe_lh,
1350 	    "keyspan_bulkin_cb");
1351 
1352 	mutex_enter(&kp->kp_mutex);
1353 
1354 	/* put data on the read queue */
1355 	data_len = keyspan_bulkin_cb_usa49(pipe, req);
1356 	no_more_reads = kp->kp_no_more_reads;
1357 
1358 	mutex_exit(&kp->kp_mutex);
1359 
1360 	usb_free_bulk_req(req);
1361 
1362 	/* kick off another read unless indicated otherwise */
1363 	if (!no_more_reads) {
1364 		(void) keyspan_receive_data(&kp->kp_datain_pipe,
1365 		    kp->kp_read_len, kp);
1366 	}
1367 
1368 	/* setup rx callback for this port */
1369 	if (data_len > 0)  {
1370 		kp->kp_cb.cb_rx(kp->kp_cb.cb_arg);
1371 	}
1372 }
1373 
1374 /*
1375  * pipe callbacks
1376  * --------------
1377  *
1378  * bulk in status callback for usa19hs model
1379  */
1380 /*ARGSUSED*/
1381 void
1382 keyspan_status_cb_usa19hs(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
1383 {
1384 	keyspan_state_t	*ksp = (keyspan_state_t *)req->bulk_client_private;
1385 	keyspan_pipe_t	*bulkin = &ksp->ks_statin_pipe;
1386 	mblk_t		*data = req->bulk_data;
1387 	usb_cr_t	cr = req->bulk_completion_reason;
1388 	int		data_len;
1389 
1390 	data_len = (data) ? MBLKL(data) : 0;
1391 
1392 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1393 	    "keyspan_status_cb_usa19hs: len=%d"
1394 	    " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags);
1395 
1396 	/* put data on the read queue */
1397 	if ((data_len == 14) && (cr == USB_CR_OK)) {
1398 		keyspan_port_t	*kp = &ksp->ks_ports[0];
1399 		keyspan_usa19hs_port_status_msg_t *status_msg =
1400 		    &(kp->kp_status_msg.usa19hs);
1401 
1402 		mutex_enter(&kp->kp_mutex);
1403 		bcopy(data->b_rptr, status_msg, data_len);
1404 
1405 		if (status_msg->controlResponse) {
1406 			kp->kp_status_flag |= KEYSPAN_PORT_CTRLRESP;
1407 		} else {
1408 			kp->kp_status_flag &= ~KEYSPAN_PORT_CTRLRESP;
1409 		}
1410 
1411 		if (status_msg->portState & PORTSTATE_ENABLED) {
1412 			kp->kp_status_flag |= KEYSPAN_PORT_ENABLE;
1413 		} else {
1414 			kp->kp_status_flag &= ~KEYSPAN_PORT_ENABLE;
1415 		}
1416 
1417 		if (status_msg->portState & PORTSTATE_TXBREAK) {
1418 			kp->kp_status_flag |= KEYSPAN_PORT_TXBREAK;
1419 		} else {
1420 			kp->kp_status_flag &= ~KEYSPAN_PORT_TXBREAK;
1421 		}
1422 
1423 		if (status_msg->rxBreak) {
1424 			kp->kp_status_flag |= KEYSPAN_PORT_RXBREAK;
1425 		} else {
1426 			kp->kp_status_flag &= ~KEYSPAN_PORT_RXBREAK;
1427 		}
1428 
1429 		if (status_msg->portState & PORTSTATE_LOOPBACK) {
1430 			kp->kp_status_flag |= KEYSPAN_PORT_LOOPBACK;
1431 		} else {
1432 			kp->kp_status_flag &= ~KEYSPAN_PORT_LOOPBACK;
1433 		}
1434 
1435 		/* if msr status changed, then invoke status callback */
1436 		if (status_msg->msr & USA_MSR_dCTS ||
1437 		    status_msg->msr & USA_MSR_dDSR ||
1438 		    status_msg->msr & USA_MSR_dRI ||
1439 		    status_msg->msr & USA_MSR_dDCD) {
1440 
1441 			mutex_exit(&kp->kp_mutex);
1442 			kp->kp_cb.cb_status(kp->kp_cb.cb_arg);
1443 		} else {
1444 			mutex_exit(&kp->kp_mutex);
1445 		}
1446 	} else {
1447 
1448 		USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh,
1449 		    "keyspan_status_cb_usa19hs: get status failed, cr=%d"
1450 		    " data_len=%d", cr, data_len);
1451 	}
1452 }
1453 
1454 
1455 /*
1456  * pipe callbacks
1457  * --------------
1458  *
1459  * bulk in status callback for usa49 model
1460  */
1461 /*ARGSUSED*/
1462 void
1463 keyspan_status_cb_usa49(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
1464 {
1465 	keyspan_state_t	*ksp = (keyspan_state_t *)req->bulk_client_private;
1466 	keyspan_pipe_t	*bulkin = &ksp->ks_statin_pipe;
1467 	mblk_t		*data = req->bulk_data;
1468 	uint_t		cr = req->bulk_completion_reason;
1469 	int		data_len;
1470 
1471 	data_len = (data) ? MBLKL(data) : 0;
1472 
1473 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1474 	    "keyspan_status_cb_usa49: len=%d"
1475 	    " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags);
1476 
1477 	/* put data on the read queue */
1478 	if ((data_len == 11) && (cr == USB_CR_OK)) {
1479 		keyspan_usa49_port_status_msg_t status_msg;
1480 		keyspan_port_t *cur_kp;
1481 		keyspan_usa49_port_status_msg_t *kp_status_msg;
1482 		boolean_t need_cb = B_FALSE;
1483 
1484 		bcopy(data->b_rptr, &status_msg, data_len);
1485 		if (status_msg.portNumber >= ksp->ks_dev_spec.port_cnt) {
1486 
1487 			return;
1488 		}
1489 		cur_kp = &ksp->ks_ports[status_msg.portNumber];
1490 		kp_status_msg = &(cur_kp->kp_status_msg.usa49);
1491 
1492 		mutex_enter(&cur_kp->kp_mutex);
1493 
1494 		/* if msr status changed, then need invoke status callback */
1495 		if (status_msg.cts !=  kp_status_msg->cts ||
1496 		    status_msg.dsr != kp_status_msg->dsr ||
1497 		    status_msg.ri != kp_status_msg->ri ||
1498 		    status_msg.dcd != kp_status_msg->dcd) {
1499 
1500 			need_cb = B_TRUE;
1501 		}
1502 
1503 		bcopy(&status_msg, kp_status_msg, data_len);
1504 
1505 		if (kp_status_msg->controlResponse) {
1506 			cur_kp->kp_status_flag |= KEYSPAN_PORT_CTRLRESP;
1507 		} else {
1508 			cur_kp->kp_status_flag &= ~KEYSPAN_PORT_CTRLRESP;
1509 		}
1510 
1511 		if (!kp_status_msg->rxEnabled) {
1512 			cur_kp->kp_status_flag |= KEYSPAN_PORT_RXBREAK;
1513 		} else {
1514 			cur_kp->kp_status_flag &= ~KEYSPAN_PORT_RXBREAK;
1515 		}
1516 
1517 		mutex_exit(&cur_kp->kp_mutex);
1518 
1519 		if (need_cb) {
1520 
1521 			cur_kp->kp_cb.cb_status(cur_kp->kp_cb.cb_arg);
1522 		}
1523 	} else {
1524 
1525 		USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh,
1526 		    "keyspan_status_cb_usa49: get status failed, cr=%d"
1527 		    " data_len=%d", cr, data_len);
1528 	}
1529 }
1530 
1531 
1532 /*
1533  * pipe callbacks
1534  * --------------
1535  *
1536  * bulk in callback for status receiving
1537  */
1538 /*ARGSUSED*/
1539 void
1540 keyspan_status_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
1541 {
1542 	keyspan_state_t	*ksp = (keyspan_state_t *)req->bulk_client_private;
1543 	usb_cr_t	cr = req->bulk_completion_reason;
1544 
1545 	USB_DPRINTF_L4(DPRINT_IN_PIPE, (&ksp->ks_statin_pipe)->pipe_lh,
1546 	    "keyspan_status_cb");
1547 
1548 	/* put data on the read queue */
1549 	switch (ksp->ks_dev_spec.id_product) {
1550 	case KEYSPAN_USA19HS_PID:
1551 		keyspan_status_cb_usa19hs(pipe, req);
1552 
1553 		break;
1554 
1555 
1556 	case KEYSPAN_USA49WLC_PID:
1557 		keyspan_status_cb_usa49(pipe, req);
1558 
1559 		break;
1560 
1561 	default:
1562 		USB_DPRINTF_L2(DPRINT_IN_PIPE,
1563 		    (&ksp->ks_statin_pipe)->pipe_lh, "keyspan_status_cb:"
1564 		    "the device's product id can't be recognized");
1565 
1566 		return;
1567 	}
1568 
1569 	usb_free_bulk_req(req);
1570 
1571 	/* kick off another read to receive status */
1572 	if ((cr != USB_CR_FLUSHED) && (cr != USB_CR_DEV_NOT_RESP) &&
1573 	    keyspan_dev_is_online(ksp)) {
1574 		if (keyspan_receive_status(ksp) != USB_SUCCESS) {
1575 			USB_DPRINTF_L2(DPRINT_IN_PIPE,
1576 			    (&ksp->ks_statin_pipe)->pipe_lh,
1577 			    "keyspan_status_cb:"
1578 			    "receive status can't be restarted.");
1579 		}
1580 	} else {
1581 		USB_DPRINTF_L2(DPRINT_IN_PIPE,
1582 		    (&ksp->ks_statin_pipe)->pipe_lh, "keyspan_status_cb:"
1583 		    "get status failed: cr=%d", cr);
1584 	}
1585 }
1586 
1587 /*
1588  * Submit data read request (asynchronous). If this function returns
1589  * USB_SUCCESS, pipe is acquired and request is sent, otherwise req is free.
1590  */
1591 int
1592 keyspan_receive_data(keyspan_pipe_t *bulkin, int len, void *cb_arg)
1593 {
1594 	keyspan_state_t	*ksp = bulkin->pipe_ksp;
1595 	usb_bulk_req_t	*br;
1596 	int		rval = USB_SUCCESS;
1597 
1598 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, "keyspan_receive_data:"
1599 	    "len=%d", len);
1600 
1601 	ASSERT(!mutex_owned(&bulkin->pipe_mutex));
1602 
1603 	br = usb_alloc_bulk_req(ksp->ks_dip, len, USB_FLAGS_SLEEP);
1604 	br->bulk_len = len;
1605 
1606 	/* No timeout, just wait for data */
1607 	br->bulk_timeout = 0;
1608 	br->bulk_client_private = cb_arg;
1609 	br->bulk_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING;
1610 
1611 	switch (ksp->ks_dev_spec.id_product) {
1612 	case KEYSPAN_USA19HS_PID:
1613 	case KEYSPAN_USA49WLC_PID:
1614 		br->bulk_cb = keyspan_bulkin_cb;
1615 		br->bulk_exc_cb = keyspan_bulkin_cb;
1616 
1617 		break;
1618 
1619 	case KEYSPAN_USA49WG_PID:
1620 		br->bulk_cb = keyspan_bulkin_cb_usa49wg;
1621 		br->bulk_exc_cb = keyspan_bulkin_cb_usa49wg;
1622 
1623 		break;
1624 
1625 	default:
1626 		usb_free_bulk_req(br);
1627 
1628 		USB_DPRINTF_L2(DPRINT_IN_PIPE,
1629 		    (&ksp->ks_statin_pipe)->pipe_lh, "keyspan_receive_data:"
1630 		    "the device's product id can't be recognized");
1631 
1632 		return (USB_FAILURE);
1633 	}
1634 
1635 
1636 	rval = usb_pipe_bulk_xfer(bulkin->pipe_handle, br, 0);
1637 	if (rval != USB_SUCCESS) {
1638 		usb_free_bulk_req(br);
1639 	}
1640 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1641 	    "keyspan_receive_data: rval = %d", rval);
1642 	return (rval);
1643 }
1644 
1645 /*
1646  * submit device status read request (asynchronous).
1647  */
1648 int
1649 keyspan_receive_status(keyspan_state_t	*ksp)
1650 {
1651 	keyspan_pipe_t *bulkin = &ksp->ks_statin_pipe;
1652 	usb_bulk_req_t	*br;
1653 	int		rval;
1654 
1655 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1656 	    "keyspan_receive_status");
1657 
1658 	ASSERT(!mutex_owned(&bulkin->pipe_mutex));
1659 
1660 	br = usb_alloc_bulk_req(ksp->ks_dip, 32, USB_FLAGS_SLEEP);
1661 	br->bulk_len = KEYSPAN_STATIN_MAX_LEN;
1662 
1663 	/* No timeout, just wait for data */
1664 	br->bulk_timeout = 0;
1665 	br->bulk_client_private = (void *)ksp;
1666 	br->bulk_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING;
1667 	br->bulk_cb = keyspan_status_cb;
1668 	br->bulk_exc_cb = keyspan_status_cb;
1669 
1670 	rval = usb_pipe_bulk_xfer(bulkin->pipe_handle, br, 0);
1671 	if (rval != USB_SUCCESS) {
1672 		usb_free_bulk_req(br);
1673 	}
1674 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1675 	    "keyspan_receive_status: rval = %d", rval);
1676 	return (rval);
1677 }
1678 
1679 /*
1680  * submit data for transfer (asynchronous)
1681  *
1682  * if data was sent successfully, 'mpp' will be nulled to indicate
1683  * that mblk is consumed by USBA and no longer belongs to the caller.
1684  *
1685  * if this function returns USB_SUCCESS, pipe is acquired and request
1686  * is sent, otherwise pipe is free.
1687  */
1688 int
1689 keyspan_send_data(keyspan_pipe_t *bulkout, mblk_t **mpp, void *cb_arg)
1690 {
1691 	keyspan_state_t	*ksp = bulkout->pipe_ksp;
1692 	usb_bulk_req_t	*br;
1693 	int		rval;
1694 
1695 	ASSERT(!mutex_owned(&bulkout->pipe_mutex));
1696 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh,
1697 	    "keyspan_send_data");
1698 
1699 	br = usb_alloc_bulk_req(ksp->ks_dip, 0, USB_FLAGS_SLEEP);
1700 	br->bulk_len = MBLKL(*mpp);
1701 	br->bulk_data = *mpp;
1702 	br->bulk_timeout = KEYSPAN_BULK_TIMEOUT;
1703 	br->bulk_client_private = cb_arg;
1704 	br->bulk_attributes = USB_ATTRS_AUTOCLEARING;
1705 	br->bulk_cb = keyspan_bulkout_cb;
1706 	br->bulk_exc_cb = keyspan_bulkout_cb;
1707 
1708 	USB_DPRINTF_L3(DPRINT_OUT_PIPE, bulkout->pipe_lh, "keyspan_send_data:"
1709 	    "bulk_len = %d", br->bulk_len);
1710 
1711 	rval = usb_pipe_bulk_xfer(bulkout->pipe_handle, br, 0);
1712 	if (rval == USB_SUCCESS) {
1713 
1714 		/* data consumed. The mem will be released in bulkout_cb */
1715 		*mpp = NULL;
1716 	} else {
1717 
1718 		/*
1719 		 * Don't free it in usb_free_bulk_req because it will
1720 		 * be linked in keyspan_put_head
1721 		 */
1722 		br->bulk_data = NULL;
1723 
1724 		usb_free_bulk_req(br);
1725 	}
1726 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh,
1727 	    "keyspan_send_data: rval = %d", rval);
1728 
1729 	return (rval);
1730 }
1731 
1732 /*
1733  * submit data for transfer (asynchronous) for USA_49WG Port0 only
1734  *
1735  * if data was sent successfully, 'mpp' will be nulled to indicate
1736  * that mblk is consumed by USBA and no longer belongs to the caller.
1737  *
1738  * if this function returns USB_SUCCESS, pipe is acquired and request
1739  * is sent, otherwise pipe is free.
1740  */
1741 int
1742 keyspan_send_data_port0(keyspan_pipe_t *introut, mblk_t **mpp, void *cb_arg)
1743 {
1744 	keyspan_state_t	*ksp = introut->pipe_ksp;
1745 	usb_intr_req_t	*br;
1746 	int		rval;
1747 
1748 	ASSERT(!mutex_owned(&introut->pipe_mutex));
1749 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, introut->pipe_lh,
1750 	    "keyspan_send_data_port0");
1751 
1752 	br = usb_alloc_intr_req(ksp->ks_dip, 0, USB_FLAGS_SLEEP);
1753 	br->intr_len = MBLKL(*mpp);
1754 	br->intr_data = *mpp;
1755 	br->intr_timeout = KEYSPAN_BULK_TIMEOUT;
1756 	br->intr_client_private = cb_arg;
1757 	br->intr_cb = keyspan_introut_cb_usa49wg;
1758 	br->intr_exc_cb = keyspan_introut_cb_usa49wg;
1759 
1760 	USB_DPRINTF_L3(DPRINT_OUT_PIPE, introut->pipe_lh,
1761 			"keyspan_send_data_port0: intr_len = %d",
1762 			br->intr_len);
1763 
1764 	rval = usb_pipe_intr_xfer(introut->pipe_handle, br, 0);
1765 	if (rval == USB_SUCCESS) {
1766 
1767 		/*
1768 		 * data consumed. The mem will be released in
1769 		 * introut_cb_usa49wg
1770 		 */
1771 		*mpp = NULL;
1772 	} else {
1773 		br->intr_data = NULL;
1774 
1775 		usb_free_intr_req(br);
1776 	}
1777 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, introut->pipe_lh,
1778 	    "keyspan_send_data_port0: rval = %d", rval);
1779 
1780 	return (rval);
1781 }
1782 
1783 /*
1784  * pipe callbacks
1785  * --------------
1786  *
1787  * bulk in status callback for USA_49WG model
1788  */
1789 /*ARGSUSED*/
1790 void
1791 keyspan_status_cb_usa49wg(usb_pipe_handle_t pipe, usb_intr_req_t *req)
1792 {
1793 	keyspan_state_t	*ksp = (keyspan_state_t *)req->intr_client_private;
1794 	keyspan_pipe_t	*intr = &ksp->ks_statin_pipe;
1795 	mblk_t		*data = req->intr_data;
1796 	uint_t		cr = req->intr_completion_reason;
1797 	int		data_len;
1798 
1799 	data_len = (data) ? MBLKL(data) : 0;
1800 
1801 	USB_DPRINTF_L4(DPRINT_IN_PIPE, intr->pipe_lh,
1802 	    "keyspan_status_cb_usa49wg: len=%d"
1803 	    " cr=%d flags=%x", data_len, cr, req->intr_cb_flags);
1804 
1805 	/* put data on the read queue */
1806 	if ((data_len == 11) && (cr == USB_CR_OK)) {
1807 		keyspan_usa49_port_status_msg_t status_msg;
1808 		keyspan_port_t *cur_kp;
1809 		keyspan_usa49_port_status_msg_t *kp_status_msg;
1810 		boolean_t need_cb = B_FALSE;
1811 
1812 		bcopy(data->b_rptr, &status_msg, data_len);
1813 		if (status_msg.portNumber >= ksp->ks_dev_spec.port_cnt) {
1814 
1815 			return;
1816 		}
1817 		cur_kp = &ksp->ks_ports[status_msg.portNumber];
1818 		kp_status_msg = &(cur_kp->kp_status_msg.usa49);
1819 
1820 		mutex_enter(&cur_kp->kp_mutex);
1821 
1822 		/* if msr status changed, then need invoke status callback */
1823 		if (status_msg.cts !=  kp_status_msg->cts ||
1824 		    status_msg.dsr != kp_status_msg->dsr ||
1825 		    status_msg.ri != kp_status_msg->ri ||
1826 		    status_msg.dcd != kp_status_msg->dcd) {
1827 
1828 			need_cb = B_TRUE;
1829 		}
1830 
1831 		bcopy(&status_msg, kp_status_msg, data_len);
1832 
1833 		if (kp_status_msg->controlResponse) {
1834 			cur_kp->kp_status_flag |= KEYSPAN_PORT_CTRLRESP;
1835 		} else {
1836 			cur_kp->kp_status_flag &= ~KEYSPAN_PORT_CTRLRESP;
1837 		}
1838 
1839 		if (!kp_status_msg->rxEnabled) {
1840 			cur_kp->kp_status_flag |= KEYSPAN_PORT_RXBREAK;
1841 		} else {
1842 			cur_kp->kp_status_flag &= ~KEYSPAN_PORT_RXBREAK;
1843 		}
1844 
1845 		mutex_exit(&cur_kp->kp_mutex);
1846 
1847 		if (need_cb) {
1848 
1849 			cur_kp->kp_cb.cb_status(cur_kp->kp_cb.cb_arg);
1850 		}
1851 	} else {
1852 
1853 		USB_DPRINTF_L2(DPRINT_IN_PIPE, intr->pipe_lh,
1854 		    "keyspan_status_cb_usa49wg: get status failed, cr=%d"
1855 		    " data_len=%d", cr, data_len);
1856 	}
1857 }
1858 
1859 /*
1860  * pipe callbacks
1861  * --------------
1862  *
1863  * intr in callback for status receiving for USA_49WG model only
1864  */
1865 /*ARGSUSED*/
1866 void
1867 keyspan_intr_cb_usa49wg(usb_pipe_handle_t pipe, usb_intr_req_t *req)
1868 {
1869 	keyspan_state_t	*ksp = (keyspan_state_t *)req->intr_client_private;
1870 	usb_cr_t	cr = req->intr_completion_reason;
1871 
1872 	USB_DPRINTF_L4(DPRINT_IN_PIPE, (&ksp->ks_statin_pipe)->pipe_lh,
1873 	    "keyspan_intr_cb_usa49wg: cr=%d", cr);
1874 
1875 	/* put data on the read queue */
1876 	(void) keyspan_status_cb_usa49wg(pipe, req);
1877 
1878 	usb_free_intr_req(req);
1879 }
1880 
1881 /*
1882  * pipe callbacks
1883  * --------------
1884  *
1885  * intr in exception callback for status receiving for USA_49WG model only
1886  */
1887 /*ARGSUSED*/
1888 void
1889 keyspan_intr_ex_cb_usa49wg(usb_pipe_handle_t pipe, usb_intr_req_t *req)
1890 {
1891 	keyspan_state_t	*ksp = (keyspan_state_t *)req->intr_client_private;
1892 	usb_cr_t	cr = req->intr_completion_reason;
1893 
1894 	USB_DPRINTF_L4(DPRINT_IN_PIPE, (&ksp->ks_statin_pipe)->pipe_lh,
1895 	    "keyspan_intr_ex_cb_usa49wg: cr=%d", cr);
1896 
1897 	usb_free_intr_req(req);
1898 
1899 	if ((cr != USB_CR_PIPE_CLOSING) && (cr != USB_CR_STOPPED_POLLING) &&
1900 		(cr != USB_CR_FLUSHED) && (cr != USB_CR_DEV_NOT_RESP) &&
1901 		(cr != USB_CR_PIPE_RESET) && keyspan_dev_is_online(ksp)) {
1902 		keyspan_pipe_start_polling(&ksp->ks_statin_pipe);
1903 	} else {
1904 		USB_DPRINTF_L2(DPRINT_IN_PIPE,
1905 		(&ksp->ks_statin_pipe)->pipe_lh, "keyspan_intr_ex_cb_usa49wg:"
1906 		"get status failed: cr=%d", cr);
1907 	}
1908 }
1909 
1910 /*
1911  * start polling on the interrupt pipe for USA_49WG model only
1912  */
1913 void
1914 keyspan_pipe_start_polling(keyspan_pipe_t *intr)
1915 {
1916 	usb_intr_req_t	*br;
1917 	keyspan_state_t	*ksp = intr->pipe_ksp;
1918 	int		rval;
1919 
1920 	USB_DPRINTF_L4(DPRINT_IN_PIPE, ksp->ks_lh,
1921 			"keyspan_pipe_start_polling");
1922 
1923 	br = usb_alloc_intr_req(ksp->ks_dip, 0, USB_FLAGS_SLEEP);
1924 
1925 	/*
1926 	 * If it is in interrupt context, usb_alloc_intr_req will return NULL if
1927 	 * called with SLEEP flag.
1928 	 */
1929 	if (!br) {
1930 		USB_DPRINTF_L2(DPRINT_IN_PIPE, ksp->ks_lh,
1931 		    "keyspan_pipe_start_polling: alloc req failed.");
1932 
1933 		return;
1934 	}
1935 	br->intr_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING;
1936 	br->intr_len = intr->pipe_ep_descr.wMaxPacketSize;
1937 	br->intr_client_private = (void *)ksp;
1938 
1939 	br->intr_cb = keyspan_intr_cb_usa49wg;
1940 	br->intr_exc_cb = keyspan_intr_ex_cb_usa49wg;
1941 
1942 
1943 	rval = usb_pipe_intr_xfer(intr->pipe_handle, br, USB_FLAGS_SLEEP);
1944 
1945 	mutex_enter(&intr->pipe_mutex);
1946 	if (rval != USB_SUCCESS) {
1947 		usb_free_intr_req(br);
1948 		intr->pipe_state = KEYSPAN_PIPE_CLOSED;
1949 
1950 		USB_DPRINTF_L3(DPRINT_IN_PIPE, ksp->ks_lh,
1951 		    "keyspan_pipe_start_polling: failed (%d)", rval);
1952 	} else {
1953 		intr->pipe_state = KEYSPAN_PIPE_OPEN;
1954 	}
1955 
1956 	mutex_exit(&intr->pipe_mutex);
1957 }
1958