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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  *
31  * keyspanport pipe routines (mostly device-neutral)
32  *
33  */
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/conf.h>
37 #include <sys/stream.h>
38 #include <sys/strsun.h>
39 #include <sys/termio.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
42 
43 #include <sys/usb/usba.h>
44 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_var.h>
45 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_pipe.h>
46 
47 /*
48  * initialize pipe structure with the given parameters
49  */
50 static void
51 keyspan_init_one_pipe(keyspan_state_t *ksp, keyspan_port_t *kp,
52     keyspan_pipe_t *pipe)
53 {
54 	usb_pipe_policy_t	*policy;
55 
56 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_init_one_pipe: "
57 	    "pipe = %p, pipe_stat %x", (void *)pipe, pipe->pipe_state);
58 
59 	/* init sync primitives */
60 	mutex_init(&pipe->pipe_mutex, NULL, MUTEX_DRIVER, (void *)NULL);
61 
62 	/* init pipe policy */
63 	policy = &pipe->pipe_policy;
64 	policy->pp_max_async_reqs = 2;
65 
66 	pipe->pipe_ksp = ksp;
67 	if (kp == NULL) {
68 		/* globle pipes should have device log handle */
69 		pipe->pipe_lh = ksp->ks_lh;
70 	} else {
71 		/* port pipes should have port log handle */
72 		pipe->pipe_lh = kp->kp_lh;
73 	}
74 
75 	pipe->pipe_state = KEYSPAN_PIPE_CLOSED;
76 }
77 
78 
79 static void
80 keyspan_fini_one_pipe(keyspan_pipe_t *pipe)
81 {
82 	USB_DPRINTF_L4(DPRINT_OPEN, pipe->pipe_ksp->ks_lh,
83 	    "keyspan_fini_one_pipe: pipe_stat %x", pipe->pipe_state);
84 
85 	if (pipe->pipe_state != KEYSPAN_PIPE_NOT_INIT) {
86 		mutex_destroy(&pipe->pipe_mutex);
87 		pipe->pipe_state = KEYSPAN_PIPE_NOT_INIT;
88 	}
89 }
90 
91 /*
92  * Lookup the endpoints defined in the spec;
93  * Allocate resources, initialize pipe structures.
94  * All are bulk pipes, including data in/out, cmd/status pipes.
95  */
96 int
97 keyspan_init_pipes(keyspan_state_t *ksp)
98 {
99 	usb_client_dev_data_t *dev_data = ksp->ks_dev_data;
100 	int		ifc, alt, i, j, k = 0;
101 	uint8_t		port_cnt = ksp->ks_dev_spec.port_cnt;
102 	uint8_t		ep_addr, ep_cnt;
103 	usb_ep_data_t	*dataout[KEYSPAN_MAX_PORT_NUM],
104 			*datain[KEYSPAN_MAX_PORT_NUM],
105 			*status = NULL, *ctrl = NULL, *tmp_ep;
106 	usb_alt_if_data_t *alt_data;
107 	usb_if_data_t *if_data;
108 
109 
110 	ifc = dev_data->dev_curr_if;
111 	alt = 0;
112 	if_data = &dev_data->dev_curr_cfg->cfg_if[ifc];
113 	alt_data = &if_data->if_alt[alt];
114 
115 	/*
116 	 * The actual EP number (indicated by bNumEndpoints) is more than
117 	 * those defined in spec. We have to match those we need according
118 	 * to EP addresses. And we'll lookup In EPs and Out EPs separately.
119 	 */
120 	ep_cnt = (alt_data->altif_descr.bNumEndpoints + 1) / 2;
121 
122 	/*
123 	 * get DIR_IN EP descriptors, and then match with EP addresses.
124 	 * Different keyspan devices may has different EP addresses.
125 	 */
126 	for (i = 0; i < ep_cnt; i++) {
127 		tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, i,
128 			    USB_EP_ATTR_BULK, USB_EP_DIR_IN);
129 		if (tmp_ep == NULL) {
130 			USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
131 			    "keyspan_init_pipes: can't find bulk in ep, i=%d,"
132 			    "ep_cnt=%d", i, ep_cnt);
133 
134 			continue;
135 		}
136 		ep_addr = tmp_ep->ep_descr.bEndpointAddress;
137 
138 		USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh, "keyspan_init_pipes: "
139 		    "ep_addr =%x, stat_ep_addr=%x, i=%d", ep_addr,
140 		    ksp->ks_dev_spec.stat_ep_addr, i);
141 
142 		/* match the status EP */
143 		if (ep_addr == ksp->ks_dev_spec.stat_ep_addr) {
144 			status = tmp_ep;
145 
146 			continue;
147 		}
148 
149 		/* match the EPs of the ports */
150 		for (j = 0; j < port_cnt; j++) {
151 			USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
152 			    "keyspan_init_pipes: try to match bulk in data ep,"
153 			    " j=%d", j);
154 			if (ep_addr == ksp->ks_dev_spec.datain_ep_addr[j]) {
155 				datain[j] = tmp_ep;
156 				k++;
157 				USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
158 				    "keyspan_init_pipes: matched a bulk in"
159 				    " data ep");
160 
161 				break;
162 			}
163 		}
164 
165 		/* if have matched all the necessary endpoints, break out */
166 		if (k >= port_cnt && status != NULL) {
167 
168 			break;
169 		}
170 
171 		USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh, "keyspan_init_pipes: "
172 		    "try to match bulk in data ep, j=%d", j);
173 
174 		if (j == port_cnt) {
175 			/* this ep can't be matched by any addr */
176 			USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh,
177 			    "keyspan_init_pipes: can't match bulk in ep,"
178 			    " addr =%x,", ep_addr);
179 		}
180 	}
181 
182 	if (k != port_cnt || status == NULL) {
183 
184 		/* Some of the necessary IN endpoints are not matched */
185 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
186 		    "keyspan_init_pipes: matched %d data in endpoints,"
187 		    " not enough", k);
188 
189 		return (USB_FAILURE);
190 	}
191 
192 	k = 0;
193 
194 	/*
195 	 * get DIR_OUT EP descriptors, and then match with ep addrs.
196 	 * different keyspan devices may has different ep addresses.
197 	 */
198 	for (i = 0; i < ep_cnt; i++) {
199 		tmp_ep = usb_lookup_ep_data(ksp->ks_dip, dev_data, ifc, alt, i,
200 			    USB_EP_ATTR_BULK, USB_EP_DIR_OUT);
201 		if (tmp_ep == NULL) {
202 			USB_DPRINTF_L3(DPRINT_ATTACH, ksp->ks_lh,
203 			    "keyspan_init_pipes: can't find bulk out ep, i=%d,"
204 			    "ep_cnt=%d", i, ep_cnt);
205 
206 			continue;
207 		}
208 		ep_addr = tmp_ep->ep_descr.bEndpointAddress;
209 
210 		/* match the status ep */
211 		if (ep_addr == ksp->ks_dev_spec.ctrl_ep_addr) {
212 			ctrl = tmp_ep;
213 
214 			continue;
215 		}
216 
217 		/* match the ep of the ports */
218 		for (j = 0; j < port_cnt; j++) {
219 			if (ep_addr == ksp->ks_dev_spec.dataout_ep_addr[j]) {
220 				dataout[j] = tmp_ep;
221 				k++;
222 
223 				break;
224 			}
225 		}
226 		/* if have matched all the necessary endpoints, break out */
227 		if (k >= port_cnt && ctrl != NULL) {
228 
229 			break;
230 		}
231 
232 		if (j == port_cnt) {
233 
234 			/* this ep can't be matched by any addr */
235 			USB_DPRINTF_L4(DPRINT_ATTACH, ksp->ks_lh,
236 			    "keyspan_init_pipes: can't match bulk out ep,"
237 			    " ep_addr =%x", ep_addr);
238 
239 		}
240 	}
241 
242 	if (k != port_cnt || ctrl == NULL) {
243 		/* Not all the necessary OUT endpoints are matched */
244 		USB_DPRINTF_L2(DPRINT_ATTACH, ksp->ks_lh,
245 		    "keyspan_init_pipes: matched %d data in endpoints,"
246 		    " not enough", k);
247 
248 		return (USB_FAILURE);
249 	}
250 
251 	mutex_enter(&ksp->ks_mutex);
252 
253 	/*
254 	 * Device globle pipes: a bulk in pipe for status and a bulk out
255 	 * pipe for controle cmd.
256 	 */
257 	ksp->ks_statin_pipe.pipe_ep_descr = status->ep_descr;
258 	keyspan_init_one_pipe(ksp, NULL, &ksp->ks_statin_pipe);
259 
260 	ksp->ks_ctrlout_pipe.pipe_ep_descr = ctrl->ep_descr;
261 	keyspan_init_one_pipe(ksp, NULL, &ksp->ks_ctrlout_pipe);
262 
263 	/* for data in/out pipes of each port */
264 	for (i = 0; i < port_cnt; i++) {
265 
266 		ksp->ks_ports[i].kp_datain_pipe.pipe_ep_descr =
267 		    datain[i]->ep_descr;
268 		keyspan_init_one_pipe(ksp, &ksp->ks_ports[i],
269 		    &ksp->ks_ports[i].kp_datain_pipe);
270 
271 		ksp->ks_ports[i].kp_dataout_pipe.pipe_ep_descr =
272 		    dataout[i]->ep_descr;
273 		keyspan_init_one_pipe(ksp, &ksp->ks_ports[i],
274 		    &ksp->ks_ports[i].kp_dataout_pipe);
275 	}
276 
277 	mutex_exit(&ksp->ks_mutex);
278 
279 	return (USB_SUCCESS);
280 }
281 
282 void
283 keyspan_fini_pipes(keyspan_state_t *ksp)
284 {
285 	keyspan_port_t	*kp;
286 	int		i;
287 
288 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
289 		kp = &ksp->ks_ports[i];
290 		keyspan_fini_one_pipe(&kp->kp_datain_pipe);
291 		keyspan_fini_one_pipe(&kp->kp_dataout_pipe);
292 	}
293 
294 	/* fini global pipes */
295 	keyspan_fini_one_pipe(&ksp->ks_statin_pipe);
296 	keyspan_fini_one_pipe(&ksp->ks_ctrlout_pipe);
297 }
298 
299 
300 static int
301 keyspan_open_one_pipe(keyspan_state_t *ksp, keyspan_pipe_t *pipe)
302 {
303 	int	rval;
304 
305 	/* don't open for the second time */
306 	mutex_enter(&pipe->pipe_mutex);
307 	ASSERT(pipe->pipe_state != KEYSPAN_PIPE_NOT_INIT);
308 	if (pipe->pipe_state != KEYSPAN_PIPE_CLOSED) {
309 		mutex_exit(&pipe->pipe_mutex);
310 
311 		return (USB_SUCCESS);
312 	}
313 	mutex_exit(&pipe->pipe_mutex);
314 
315 	rval = usb_pipe_open(ksp->ks_dip, &pipe->pipe_ep_descr,
316 	    &pipe->pipe_policy, USB_FLAGS_SLEEP, &pipe->pipe_handle);
317 
318 	if (rval == USB_SUCCESS) {
319 		mutex_enter(&pipe->pipe_mutex);
320 		pipe->pipe_state = KEYSPAN_PIPE_OPEN;
321 		mutex_exit(&pipe->pipe_mutex);
322 	}
323 
324 	return (rval);
325 }
326 
327 
328 /*
329  * close one pipe if open
330  */
331 static void
332 keyspan_close_one_pipe(keyspan_pipe_t *pipe)
333 {
334 	/*
335 	 * pipe may already be closed, e.g. if device has been physically
336 	 * disconnected and the driver immediately detached
337 	 */
338 	if (pipe->pipe_handle != NULL) {
339 		usb_pipe_close(pipe->pipe_ksp->ks_dip, pipe->pipe_handle,
340 				USB_FLAGS_SLEEP, NULL, NULL);
341 		mutex_enter(&pipe->pipe_mutex);
342 		pipe->pipe_handle = NULL;
343 		pipe->pipe_state = KEYSPAN_PIPE_CLOSED;
344 		mutex_exit(&pipe->pipe_mutex);
345 	}
346 }
347 
348 /*
349  * Open global pipes, a status pipe and a control pipe
350  */
351 int
352 keyspan_open_dev_pipes(keyspan_state_t *ksp)
353 {
354 	int		rval;
355 
356 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_open_dev_pipes");
357 
358 	rval = keyspan_open_one_pipe(ksp, &ksp->ks_ctrlout_pipe);
359 	if (rval != USB_SUCCESS) {
360 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
361 		    "keyspan_open_dev_pipes: open ctrl pipe failed %d", rval);
362 
363 		return (rval);
364 	}
365 
366 	rval = keyspan_open_one_pipe(ksp, &ksp->ks_statin_pipe);
367 	if (rval != USB_SUCCESS) {
368 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
369 		    "keyspan_open_dev_pipes: open status pipe failed %d", rval);
370 
371 		/* close the first opened pipe here */
372 		keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe);
373 
374 		return (rval);
375 	}
376 
377 	/* start receive device status */
378 	rval = keyspan_receive_status(ksp);
379 	if (rval != USB_SUCCESS) {
380 		USB_DPRINTF_L2(DPRINT_OPEN, ksp->ks_lh,
381 		    "keyspan_open_dev_pipes: receive device status failed %d",
382 		    rval);
383 
384 		/* close opened pipes here */
385 		keyspan_close_one_pipe(&ksp->ks_statin_pipe);
386 		keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe);
387 
388 		return (rval);
389 	}
390 
391 	return (rval);
392 }
393 
394 
395 /*
396  * Reopen all pipes if the port had them open
397  */
398 int
399 keyspan_reopen_pipes(keyspan_state_t *ksp)
400 {
401 	keyspan_port_t	*kp;
402 	int		i;
403 
404 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_reopen_pipes");
405 
406 	if (keyspan_open_dev_pipes(ksp) != USB_SUCCESS) {
407 
408 		return (USB_FAILURE);
409 	}
410 
411 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
412 		kp = &ksp->ks_ports[i];
413 		mutex_enter(&kp->kp_mutex);
414 		if (kp->kp_state == KEYSPAN_PORT_OPEN) {
415 			USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh,
416 			    "keyspan_reopen_pipes() reopen pipe #%d", i);
417 			mutex_exit(&kp->kp_mutex);
418 			if (keyspan_open_port_pipes(kp) != USB_SUCCESS) {
419 
420 				return (USB_FAILURE);
421 			}
422 			mutex_enter(&kp->kp_mutex);
423 			kp->kp_no_more_reads = B_FALSE;
424 		}
425 		mutex_exit(&kp->kp_mutex);
426 	}
427 
428 	return (USB_SUCCESS);
429 }
430 
431 void
432 keyspan_close_port_pipes(keyspan_port_t *kp)
433 {
434 	USB_DPRINTF_L4(DPRINT_CLOSE, kp->kp_lh, "keyspan_close_port_pipes");
435 
436 	keyspan_close_one_pipe(&kp->kp_dataout_pipe);
437 	keyspan_close_one_pipe(&kp->kp_datain_pipe);
438 }
439 
440 /*
441  * Close IN and OUT bulk pipes of all ports
442  */
443 void
444 keyspan_close_open_pipes(keyspan_state_t *ksp)
445 {
446 	keyspan_port_t	*kp;
447 	int		i;
448 
449 	USB_DPRINTF_L4(DPRINT_CLOSE, ksp->ks_lh, "keyspan_close_open_pipes");
450 
451 	for (i = 0; i < ksp->ks_dev_spec.port_cnt; i++) {
452 		kp = &ksp->ks_ports[i];
453 		mutex_enter(&kp->kp_mutex);
454 		if (kp->kp_state == KEYSPAN_PORT_OPEN) {
455 			kp->kp_no_more_reads = B_TRUE;
456 			mutex_exit(&kp->kp_mutex);
457 			usb_pipe_reset(ksp->ks_dip,
458 			    kp->kp_datain_pipe.pipe_handle, USB_FLAGS_SLEEP,
459 			    NULL, NULL);
460 			keyspan_close_port_pipes(kp);
461 		} else {
462 			mutex_exit(&kp->kp_mutex);
463 		}
464 	}
465 }
466 
467 
468 /*
469  * Close global pipes
470  */
471 void
472 keyspan_close_dev_pipes(keyspan_state_t *ksp)
473 {
474 	USB_DPRINTF_L4(DPRINT_CLOSE, ksp->ks_lh, "keyspan_close_dev_pipes");
475 
476 	keyspan_close_one_pipe(&ksp->ks_statin_pipe);
477 	keyspan_close_one_pipe(&ksp->ks_ctrlout_pipe);
478 }
479 
480 
481 /*
482  * Open bulk data IN and data OUT pipes for one port.
483  * The status and control pipes are opened in attach because they are global.
484  */
485 int
486 keyspan_open_port_pipes(keyspan_port_t *kp)
487 {
488 	keyspan_state_t	*ksp = kp->kp_ksp;
489 	int		rval;
490 
491 	USB_DPRINTF_L4(DPRINT_OPEN, kp->kp_lh, "keyspan_open_port_pipes");
492 
493 	rval = keyspan_open_one_pipe(ksp, &kp->kp_datain_pipe);
494 	if (rval != USB_SUCCESS) {
495 
496 		goto fail;
497 	}
498 
499 	rval = keyspan_open_one_pipe(ksp, &kp->kp_dataout_pipe);
500 	if (rval != USB_SUCCESS) {
501 
502 		goto fail;
503 	}
504 
505 	return (rval);
506 
507 fail:
508 	USB_DPRINTF_L2(DPRINT_OPEN, kp->kp_lh,
509 	    "keyspan_open_port_pipes: failed %d", rval);
510 	keyspan_close_port_pipes(kp);
511 
512 	return (rval);
513 }
514 
515 void
516 keyspan_close_pipes(keyspan_state_t *ksp)
517 {
518 	USB_DPRINTF_L4(DPRINT_OPEN, ksp->ks_lh, "keyspan_close_pipes");
519 
520 	/* close all ports' pipes first, and then device ctrl/status pipes. */
521 	keyspan_close_open_pipes(ksp);
522 	keyspan_close_dev_pipes(ksp);
523 
524 }
525 
526 
527 /*
528  * bulk out common callback
529  */
530 /*ARGSUSED*/
531 void
532 keyspan_bulkout_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
533 {
534 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private;
535 	keyspan_pipe_t	*bulkout = &kp->kp_dataout_pipe;
536 	mblk_t		*data = req->bulk_data;
537 	int		data_len;
538 
539 	data_len = (data) ? MBLKL(data) : 0;
540 
541 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh,
542 	    "keyspan_bulkout_cb: len=%d cr=%d cb_flags=%x",
543 	    data_len, req->bulk_completion_reason, req->bulk_cb_flags);
544 
545 	if (req->bulk_completion_reason && (data_len > 0)) {
546 
547 		/*
548 		 * Data wasn't transfered successfully.
549 		 * Put data back on the queue.
550 		 */
551 		keyspan_put_head(&kp->kp_tx_mp, data, kp);
552 
553 		/* don't release mem in usb_free_bulk_req */
554 		req->bulk_data = NULL;
555 	}
556 
557 	usb_free_bulk_req(req);
558 
559 	/* if more data available, kick off another transmit */
560 	mutex_enter(&kp->kp_mutex);
561 	if (kp->kp_tx_mp == NULL) {
562 
563 			/* no more data, notify waiters */
564 			cv_broadcast(&kp->kp_tx_cv);
565 			mutex_exit(&kp->kp_mutex);
566 
567 			/* tx callback for this port */
568 			kp->kp_cb.cb_tx(kp->kp_cb.cb_arg);
569 	} else {
570 		keyspan_tx_start(kp, NULL);
571 		mutex_exit(&kp->kp_mutex);
572 	}
573 }
574 
575 /*
576  * pipe callbacks
577  * --------------
578  *
579  * bulk in common callback for usa19hs model
580  */
581 /*ARGSUSED*/
582 int
583 keyspan_bulkin_cb_usa19hs(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
584 {
585 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private;
586 	keyspan_pipe_t	*bulkin = &kp->kp_datain_pipe;
587 	mblk_t		*data = req->bulk_data;
588 	uint_t		cr = req->bulk_completion_reason;
589 	int		data_len;
590 
591 	ASSERT(mutex_owned(&kp->kp_mutex));
592 
593 	data_len = (data) ? MBLKL(data) : 0;
594 
595 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
596 	    "keyspan_bulkin_cb_usa19hs: len=%d"
597 	    " cr=%d flags=%x baud=%x",
598 	    data_len, cr, req->bulk_cb_flags, kp->kp_baud);
599 
600 	/* put data on the read queue */
601 	if ((data_len > 0) && (kp->kp_state != KEYSPAN_PORT_CLOSED) &&
602 	    (cr == USB_CR_OK)) {
603 
604 		/*
605 		 * According to Keyspan spec, if 0x80 bit set, the data
606 		 * buf contains alternate status and data bytes;
607 		 * if 0x80 bit is clear, then there are no status bytes,
608 		 * so we put tail to send up data.
609 		 */
610 		if ((data->b_rptr[0] & 0x80) == 0) {
611 			USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
612 			    "keyspan_bulkin_cb_usa19hs: len=%d",
613 			    data_len);
614 
615 			data->b_rptr++;
616 			data_len--;
617 			if (data_len > 0) {
618 				keyspan_put_tail(&kp->kp_rx_mp, data);
619 
620 				/*
621 				 * the data will not be freed and
622 				 * will be sent up later.
623 				 */
624 				req->bulk_data = NULL;
625 			}
626 		} else {  /* there might be some errs in the data */
627 
628 			USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
629 			    "keyspan_bulkin_cb_usa19hs:"
630 			    " err in the data, len=%d",
631 			    data_len);
632 
633 			if (data_len > 1) {
634 				int i = 0;
635 				int j = 1;
636 
637 				/* get rid of status bytes. */
638 				for (j = 1; j < data_len; j += 2) {
639 					data->b_rptr[i] = data->b_rptr[j];
640 					i++;
641 				}
642 				data->b_wptr = data->b_rptr + i;
643 				keyspan_put_tail(&kp->kp_rx_mp, data);
644 
645 				/*
646 				 * The data will not be freed and
647 				 * will be sent up later.
648 				 */
649 				req->bulk_data = NULL;
650 			} else {
651 				/*
652 				 * When zero len returned, no data will
653 				 * be sent up and the data buf will be
654 				 * just freed.
655 				 */
656 				data_len = 0;
657 			}
658 		}
659 
660 	} else {
661 
662 		/* usb error happened, so don't send up data */
663 		USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
664 		    "keyspan_bulkin_cb_usa19hs: error happened, len=%d, "
665 		    "cr=0x%x, cb_flags=0x%x", data_len, cr, req->bulk_cb_flags);
666 
667 		data_len = 0;
668 		if (kp->kp_state != KEYSPAN_PORT_OPEN) {
669 			kp->kp_no_more_reads = B_TRUE;
670 		}
671 	}
672 
673 	return (data_len);
674 }
675 
676 #ifdef	KEYSPAN_USA49WLC
677 /*
678  * pipe callbacks
679  * --------------
680  *
681  * bulk in common callback for usa49 model
682  */
683 /*ARGSUSED*/
684 int
685 keyspan_bulkin_cb_usa49(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
686 {
687 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private;
688 	keyspan_pipe_t	*bulkin = &kp->kp_datain_pipe;
689 	mblk_t		*data = req->bulk_data;
690 	uint_t		cr = req->bulk_completion_reason;
691 	int		data_len;
692 
693 	ASSERT(mutex_owned(&kp->kp_mutex));
694 
695 	data_len = (data) ? MBLKL(data) : 0;
696 
697 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
698 	    "keyspan_bulkin_cb_usa49: len=%d"
699 	    " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags);
700 
701 	/* put data on the read queue */
702 	if ((data_len > 0) && (kp->kp_state != KEYSPAN_PORT_CLOSED) &&
703 	    (cr == USB_CR_OK)) {
704 
705 		/*
706 		 * According to Keyspan spec, if 0x80 bit set, the data
707 		 * buf contains alternate status and data bytes;
708 		 * if 0x80 bit is clear, then there are no status bytes,
709 		 * so we put tail to send up data.
710 		 */
711 		if ((data->b_rptr[0] & 0x80) == 0) {
712 			USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
713 			    "keyspan_bulkin_cb_usa49: len=%d"
714 			    "cr=%d", data_len, cr);
715 
716 			data->b_rptr++;
717 			data_len--;
718 			if (data_len > 0) {
719 				keyspan_put_tail(&kp->kp_rx_mp, data);
720 
721 				/*
722 				 * The data will not be freed and
723 				 * will be sent up later.
724 				 */
725 				req->bulk_data = NULL;
726 			}
727 		} else {
728 			if (data_len > 1) {
729 				int i = 0;
730 				int j = 1;
731 
732 				/* get rid of the status bytes in the data. */
733 				for (j = 1; j < data_len; j += 2) {
734 					data->b_rptr[i] = data->b_rptr[j];
735 					i++;
736 				}
737 				data->b_wptr = data->b_rptr + i;
738 				keyspan_put_tail(&kp->kp_rx_mp, data);
739 
740 				/*
741 				 * The data will not be freed and
742 				 * will be sent up later.
743 				 */
744 				req->bulk_data = NULL;
745 			} else {
746 				/*
747 				 * When zero len returned, no data will be sent
748 				 * up and the data buf will be just freed.
749 				 */
750 				data_len = 0;
751 			}
752 		}
753 	} else {
754 
755 		/* usb error happened, so don't send up data */
756 		data_len = 0;
757 		USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh,
758 		    "keyspan_bulkin_cb_usa49: port_state=%d"
759 		    " b_rptr[0]=%c", kp->kp_state, data->b_rptr[0]);
760 
761 		if (kp->kp_state != KEYSPAN_PORT_OPEN) {
762 			kp->kp_no_more_reads = B_TRUE;
763 		}
764 	}
765 
766 	return (data_len);
767 }
768 #endif	/* If KEYSPAN_USA49WLC defined */
769 
770 /*
771  * pipe callbacks
772  * --------------
773  *
774  * bulk in common callback
775  */
776 /*ARGSUSED*/
777 void
778 keyspan_bulkin_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
779 {
780 	keyspan_port_t	*kp = (keyspan_port_t *)req->bulk_client_private;
781 	keyspan_state_t	*ksp = kp->kp_ksp;
782 	int		data_len;
783 	boolean_t	no_more_reads = B_FALSE;
784 
785 	USB_DPRINTF_L4(DPRINT_IN_PIPE, (&kp->kp_datain_pipe)->pipe_lh,
786 	    "keyspan_bulkin_cb");
787 
788 	mutex_enter(&kp->kp_mutex);
789 
790 	/* put data on the read queue */
791 	switch (ksp->ks_dev_spec.id_product) {
792 	case KEYSPAN_USA19HS_PID:
793 		data_len = keyspan_bulkin_cb_usa19hs(pipe, req);
794 
795 		break;
796 
797 #ifdef	KEYSPAN_USA49WLC
798 	case KEYSPAN_USA49WLC_PID:
799 		data_len = keyspan_bulkin_cb_usa49(pipe, req);
800 
801 		break;
802 #endif	/* If KEYSPAN_USA49WLC defined */
803 	default:
804 		USB_DPRINTF_L2(DPRINT_IN_PIPE, (&kp->kp_datain_pipe)->pipe_lh,
805 		    "keyspan_bulkin_cb:"
806 		    "the device's product id can't be recognized");
807 		mutex_exit(&kp->kp_mutex);
808 
809 		return;
810 	}
811 
812 	no_more_reads = kp->kp_no_more_reads;
813 
814 	mutex_exit(&kp->kp_mutex);
815 
816 	usb_free_bulk_req(req);
817 
818 	/* kick off another read unless indicated otherwise */
819 	if (!no_more_reads) {
820 		(void) keyspan_receive_data(&kp->kp_datain_pipe,
821 		    kp->kp_read_len, kp);
822 	}
823 
824 	/* setup rx callback for this port */
825 	if (data_len > 0)  {
826 		kp->kp_cb.cb_rx(kp->kp_cb.cb_arg);
827 	}
828 }
829 
830 /*
831  * pipe callbacks
832  * --------------
833  *
834  * bulk in status callback for usa19hs model
835  */
836 /*ARGSUSED*/
837 void
838 keyspan_status_cb_usa19hs(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
839 {
840 	keyspan_state_t	*ksp = (keyspan_state_t *)req->bulk_client_private;
841 	keyspan_pipe_t	*bulkin = &ksp->ks_statin_pipe;
842 	mblk_t		*data = req->bulk_data;
843 	usb_cr_t	cr = req->bulk_completion_reason;
844 	int		data_len;
845 
846 	data_len = (data) ? MBLKL(data) : 0;
847 
848 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
849 	    "keyspan_status_cb_usa19hs: len=%d"
850 	    " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags);
851 
852 	/* put data on the read queue */
853 	if ((data_len == 14) && (cr == USB_CR_OK)) {
854 		keyspan_port_t	*kp = &ksp->ks_ports[0];
855 		keyspan_usa19hs_port_status_msg_t *status_msg =
856 		    &(kp->kp_status_msg.usa19hs);
857 
858 		mutex_enter(&kp->kp_mutex);
859 		bcopy(data->b_rptr, status_msg, data_len);
860 
861 		if (status_msg->controlResponse) {
862 			kp->kp_status_flag |= KEYSPAN_PORT_CTRLRESP;
863 		} else {
864 			kp->kp_status_flag &= ~KEYSPAN_PORT_CTRLRESP;
865 		}
866 
867 		if (status_msg->portState & PORTSTATE_ENABLED) {
868 			kp->kp_status_flag |= KEYSPAN_PORT_ENABLE;
869 		} else {
870 			kp->kp_status_flag &= ~KEYSPAN_PORT_ENABLE;
871 		}
872 
873 		if (status_msg->portState & PORTSTATE_TXBREAK) {
874 			kp->kp_status_flag |= KEYSPAN_PORT_TXBREAK;
875 		} else {
876 			kp->kp_status_flag &= ~KEYSPAN_PORT_TXBREAK;
877 		}
878 
879 		if (status_msg->rxBreak) {
880 			kp->kp_status_flag |= KEYSPAN_PORT_RXBREAK;
881 		} else {
882 			kp->kp_status_flag &= ~KEYSPAN_PORT_RXBREAK;
883 		}
884 
885 		if (status_msg->portState & PORTSTATE_LOOPBACK) {
886 			kp->kp_status_flag |= KEYSPAN_PORT_LOOPBACK;
887 		} else {
888 			kp->kp_status_flag &= ~KEYSPAN_PORT_LOOPBACK;
889 		}
890 
891 		/* if msr status changed, then invoke status callback */
892 		if (status_msg->msr & USA_MSR_dCTS ||
893 		    status_msg->msr & USA_MSR_dDSR ||
894 		    status_msg->msr & USA_MSR_dRI ||
895 		    status_msg->msr & USA_MSR_dDCD) {
896 
897 			mutex_exit(&kp->kp_mutex);
898 			kp->kp_cb.cb_status(kp->kp_cb.cb_arg);
899 		} else {
900 			mutex_exit(&kp->kp_mutex);
901 		}
902 	} else {
903 
904 		USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh,
905 		    "keyspan_status_cb_usa19hs: get status failed, cr=%d"
906 		    " data_len=%d", cr, data_len);
907 	}
908 }
909 
910 #ifdef	KEYSPAN_USA49WLC
911 /*
912  * pipe callbacks
913  * --------------
914  *
915  * bulk in status callback for usa49 model
916  */
917 /*ARGSUSED*/
918 void
919 keyspan_status_cb_usa49(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
920 {
921 	keyspan_state_t	*ksp = (keyspan_state_t *)req->bulk_client_private;
922 	keyspan_pipe_t	*bulkin = &ksp->ks_statin_pipe;
923 	mblk_t		*data = req->bulk_data;
924 	uint_t		cr = req->bulk_completion_reason;
925 	int		data_len;
926 
927 	data_len = (data) ? MBLKL(data) : 0;
928 
929 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
930 	    "keyspan_status_cb_usa49: len=%d"
931 	    " cr=%d flags=%x", data_len, cr, req->bulk_cb_flags);
932 
933 	/* put data on the read queue */
934 	if ((data_len == 11) && (cr == USB_CR_OK)) {
935 		keyspan_usa49_port_status_msg_t status_msg;
936 		keyspan_port_t *cur_kp;
937 		keyspan_usa49_port_status_msg_t *kp_status_msg;
938 		boolean_t need_cb = B_FALSE;
939 
940 		bcopy(data->b_rptr, &status_msg, data_len);
941 		if (status_msg.portNumber >= ksp->ks_dev_spec.port_cnt) {
942 
943 			return;
944 		}
945 		cur_kp = &ksp->ks_ports[status_msg.portNumber];
946 		kp_status_msg = &(cur_kp->kp_status_msg.usa49);
947 
948 		mutex_enter(&cur_kp->kp_mutex);
949 
950 		/* if msr status changed, then need invoke status callback */
951 		if (status_msg.cts !=  kp_status_msg->cts ||
952 		    status_msg.dsr != kp_status_msg->dsr ||
953 		    status_msg.ri != kp_status_msg->ri ||
954 		    status_msg.dcd != kp_status_msg->dcd) {
955 
956 			need_cb = B_TRUE;
957 		}
958 
959 		bcopy(&status_msg, kp_status_msg, data_len);
960 
961 		if (kp_status_msg->controlResponse) {
962 			cur_kp->kp_status_flag |= KEYSPAN_PORT_CTRLRESP;
963 		} else {
964 			cur_kp->kp_status_flag &= ~KEYSPAN_PORT_CTRLRESP;
965 		}
966 
967 		if (!kp_status_msg->rxEnabled) {
968 			cur_kp->kp_status_flag |= KEYSPAN_PORT_RXBREAK;
969 		} else {
970 			cur_kp->kp_status_flag &= ~KEYSPAN_PORT_RXBREAK;
971 		}
972 
973 		mutex_exit(&cur_kp->kp_mutex);
974 
975 		if (need_cb) {
976 
977 			cur_kp->kp_cb.cb_status(cur_kp->kp_cb.cb_arg);
978 		}
979 	} else {
980 
981 		USB_DPRINTF_L2(DPRINT_IN_PIPE, bulkin->pipe_lh,
982 		    "keyspan_status_cb_usa49: get status failed, cr=%d"
983 		    " data_len=%d", cr, data_len);
984 	}
985 }
986 #endif	/* If KEYSPAN_USA49WLC defined */
987 
988 /*
989  * pipe callbacks
990  * --------------
991  *
992  * bulk in callback for status receiving
993  */
994 /*ARGSUSED*/
995 void
996 keyspan_status_cb(usb_pipe_handle_t pipe, usb_bulk_req_t *req)
997 {
998 	keyspan_state_t	*ksp = (keyspan_state_t *)req->bulk_client_private;
999 	usb_cr_t	cr = req->bulk_completion_reason;
1000 
1001 	USB_DPRINTF_L4(DPRINT_IN_PIPE, (&ksp->ks_statin_pipe)->pipe_lh,
1002 	    "keyspan_status_cb");
1003 
1004 	/* put data on the read queue */
1005 	switch (ksp->ks_dev_spec.id_product) {
1006 	case KEYSPAN_USA19HS_PID:
1007 		keyspan_status_cb_usa19hs(pipe, req);
1008 
1009 		break;
1010 
1011 #ifdef	KEYSPAN_USA49WLC
1012 	case KEYSPAN_USA49WLC_PID:
1013 		keyspan_status_cb_usa49(pipe, req);
1014 
1015 		break;
1016 #endif	/* If KEYSPAN_USA49WLC defined */
1017 	default:
1018 		USB_DPRINTF_L2(DPRINT_IN_PIPE,
1019 		    (&ksp->ks_statin_pipe)->pipe_lh, "keyspan_status_cb:"
1020 		    "the device's product id can't be recognized");
1021 
1022 		return;
1023 	}
1024 
1025 	usb_free_bulk_req(req);
1026 
1027 	/* kick off another read to receive status */
1028 	if ((cr != USB_CR_FLUSHED) && (cr != USB_CR_DEV_NOT_RESP) &&
1029 	    keyspan_dev_is_online(ksp)) {
1030 		if (keyspan_receive_status(ksp) != USB_SUCCESS) {
1031 			USB_DPRINTF_L2(DPRINT_IN_PIPE,
1032 			    (&ksp->ks_statin_pipe)->pipe_lh,
1033 			    "keyspan_status_cb:"
1034 			    "receive status can't be restarted.");
1035 		}
1036 	} else {
1037 		USB_DPRINTF_L2(DPRINT_IN_PIPE,
1038 		    (&ksp->ks_statin_pipe)->pipe_lh, "keyspan_status_cb:"
1039 		    "get status failed: cr=%d", cr);
1040 	}
1041 }
1042 
1043 /*
1044  * Submit data read request (asynchronous). If this function returns
1045  * USB_SUCCESS, pipe is acquired and request is sent, otherwise req is free.
1046  */
1047 int
1048 keyspan_receive_data(keyspan_pipe_t *bulkin, int len, void *cb_arg)
1049 {
1050 	keyspan_state_t	*ksp = bulkin->pipe_ksp;
1051 	usb_bulk_req_t	*br;
1052 	int		rval;
1053 
1054 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh, "keyspan_receive_data:"
1055 	    "len=%d", len);
1056 
1057 	ASSERT(!mutex_owned(&bulkin->pipe_mutex));
1058 
1059 	br = usb_alloc_bulk_req(ksp->ks_dip, len, USB_FLAGS_SLEEP);
1060 	br->bulk_len = len;
1061 
1062 	/* No timeout, just wait for data */
1063 	br->bulk_timeout = 0;
1064 	br->bulk_client_private = cb_arg;
1065 	br->bulk_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING;
1066 	br->bulk_cb = keyspan_bulkin_cb;
1067 	br->bulk_exc_cb = keyspan_bulkin_cb;
1068 
1069 	rval = usb_pipe_bulk_xfer(bulkin->pipe_handle, br, 0);
1070 	if (rval != USB_SUCCESS) {
1071 		usb_free_bulk_req(br);
1072 	}
1073 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1074 	    "keyspan_receive_data: rval = %d", rval);
1075 	return (rval);
1076 }
1077 
1078 /*
1079  * submit device status read request (asynchronous).
1080  */
1081 int
1082 keyspan_receive_status(keyspan_state_t	*ksp)
1083 {
1084 	keyspan_pipe_t *bulkin = &ksp->ks_statin_pipe;
1085 	usb_bulk_req_t	*br;
1086 	int		rval;
1087 
1088 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1089 	    "keyspan_receive_status");
1090 
1091 	ASSERT(!mutex_owned(&bulkin->pipe_mutex));
1092 
1093 	br = usb_alloc_bulk_req(ksp->ks_dip, 32, USB_FLAGS_SLEEP);
1094 	br->bulk_len = KEYSPAN_STATIN_MAX_LEN;
1095 
1096 	/* No timeout, just wait for data */
1097 	br->bulk_timeout = 0;
1098 	br->bulk_client_private = (void *)ksp;
1099 	br->bulk_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING;
1100 	br->bulk_cb = keyspan_status_cb;
1101 	br->bulk_exc_cb = keyspan_status_cb;
1102 
1103 	rval = usb_pipe_bulk_xfer(bulkin->pipe_handle, br, 0);
1104 	if (rval != USB_SUCCESS) {
1105 		usb_free_bulk_req(br);
1106 	}
1107 	USB_DPRINTF_L4(DPRINT_IN_PIPE, bulkin->pipe_lh,
1108 	    "keyspan_receive_status: rval = %d", rval);
1109 	return (rval);
1110 }
1111 
1112 /*
1113  * submit data for transfer (asynchronous)
1114  *
1115  * if data was sent successfully, 'mpp' will be nulled to indicate
1116  * that mblk is consumed by USBA and no longer belongs to the caller.
1117  *
1118  * if this function returns USB_SUCCESS, pipe is acquired and request
1119  * is sent, otherwise pipe is free.
1120  */
1121 int
1122 keyspan_send_data(keyspan_pipe_t *bulkout, mblk_t **mpp, void *cb_arg)
1123 {
1124 	keyspan_state_t	*ksp = bulkout->pipe_ksp;
1125 	usb_bulk_req_t	*br;
1126 	int		rval;
1127 
1128 	ASSERT(!mutex_owned(&bulkout->pipe_mutex));
1129 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh,
1130 	    "keyspan_send_data");
1131 
1132 	br = usb_alloc_bulk_req(ksp->ks_dip, 0, USB_FLAGS_SLEEP);
1133 	br->bulk_len = MBLKL(*mpp);
1134 	br->bulk_data = *mpp;
1135 	br->bulk_timeout = KEYSPAN_BULK_TIMEOUT;
1136 	br->bulk_client_private = cb_arg;
1137 	br->bulk_attributes = USB_ATTRS_AUTOCLEARING;
1138 	br->bulk_cb = keyspan_bulkout_cb;
1139 	br->bulk_exc_cb = keyspan_bulkout_cb;
1140 
1141 	USB_DPRINTF_L3(DPRINT_OUT_PIPE, bulkout->pipe_lh, "keyspan_send_data:"
1142 	    "bulk_len = %d", br->bulk_len);
1143 
1144 	rval = usb_pipe_bulk_xfer(bulkout->pipe_handle, br, 0);
1145 	if (rval == USB_SUCCESS) {
1146 
1147 		/* data consumed. The mem will be released in bulkout_cb */
1148 		*mpp = NULL;
1149 	} else {
1150 
1151 		/*
1152 		 * Don't free it in usb_free_bulk_req because it will
1153 		 * be linked in keyspan_put_head
1154 		 */
1155 		br->bulk_data = NULL;
1156 
1157 		usb_free_bulk_req(br);
1158 	}
1159 	USB_DPRINTF_L4(DPRINT_OUT_PIPE, bulkout->pipe_lh,
1160 	    "keyspan_send_data: rval = %d", rval);
1161 
1162 	return (rval);
1163 }
1164