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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * Open Host Controller Driver (OHCI)
29 *
30 * The USB Open Host Controller driver is a software driver which interfaces
31 * to the Universal Serial Bus layer (USBA) and the USB Open Host Controller.
32 * The interface to USB Open Host Controller is defined by the OpenHCI Host
33 * Controller Interface.
34 *
35 * NOTE:
36 *
37 * Currently OHCI driver does not support the following features
38 *
39 * - Handle request with multiple TDs under short xfer conditions except for
40 * bulk transfers.
41 */
42 #include <sys/usb/hcd/openhci/ohcid.h>
43
44 #include <sys/disp.h>
45 #include <sys/strsun.h>
46
47 /* Pointer to the state structure */
48 static void *ohci_statep;
49
50 int force_ohci_off = 1;
51
52 /* Number of instances */
53 #define OHCI_INSTS 1
54
55 /* Adjustable variables for the size of the pools */
56 int ohci_ed_pool_size = OHCI_ED_POOL_SIZE;
57 int ohci_td_pool_size = OHCI_TD_POOL_SIZE;
58
59 /*
60 * Initialize the values which are used for setting up head pointers for
61 * the 32ms scheduling lists which starts from the HCCA.
62 */
63 static uchar_t ohci_index[NUM_INTR_ED_LISTS / 2] = {0x0, 0x8, 0x4, 0xc,
64 0x2, 0xa, 0x6, 0xe,
65 0x1, 0x9, 0x5, 0xd,
66 0x3, 0xb, 0x7, 0xf};
67 /* Debugging information */
68 uint_t ohci_errmask = (uint_t)PRINT_MASK_ALL;
69 uint_t ohci_errlevel = USB_LOG_L2;
70 uint_t ohci_instance_debug = (uint_t)-1;
71
72 /*
73 * OHCI MSI tunable:
74 *
75 * By default MSI is enabled on all supported platforms.
76 */
77 boolean_t ohci_enable_msi = B_TRUE;
78
79 /*
80 * HCDI entry points
81 *
82 * The Host Controller Driver Interfaces (HCDI) are the software interfaces
83 * between the Universal Serial Bus Driver (USBA) and the Host Controller
84 * Driver (HCD). The HCDI interfaces or entry points are subject to change.
85 */
86 static int ohci_hcdi_pipe_open(
87 usba_pipe_handle_data_t *ph,
88 usb_flags_t usb_flags);
89 static int ohci_hcdi_pipe_close(
90 usba_pipe_handle_data_t *ph,
91 usb_flags_t usb_flags);
92 static int ohci_hcdi_pipe_reset(
93 usba_pipe_handle_data_t *ph,
94 usb_flags_t usb_flags);
95 static void ohci_hcdi_pipe_reset_data_toggle(
96 usba_pipe_handle_data_t *ph);
97 static int ohci_hcdi_pipe_ctrl_xfer(
98 usba_pipe_handle_data_t *ph,
99 usb_ctrl_req_t *ctrl_reqp,
100 usb_flags_t usb_flags);
101 static int ohci_hcdi_bulk_transfer_size(
102 usba_device_t *usba_device,
103 size_t *size);
104 static int ohci_hcdi_pipe_bulk_xfer(
105 usba_pipe_handle_data_t *ph,
106 usb_bulk_req_t *bulk_reqp,
107 usb_flags_t usb_flags);
108 static int ohci_hcdi_pipe_intr_xfer(
109 usba_pipe_handle_data_t *ph,
110 usb_intr_req_t *intr_req,
111 usb_flags_t usb_flags);
112 static int ohci_hcdi_pipe_stop_intr_polling(
113 usba_pipe_handle_data_t *ph,
114 usb_flags_t usb_flags);
115 static int ohci_hcdi_get_current_frame_number(
116 usba_device_t *usba_device,
117 usb_frame_number_t *frame_number);
118 static int ohci_hcdi_get_max_isoc_pkts(
119 usba_device_t *usba_device,
120 uint_t *max_isoc_pkts_per_request);
121 static int ohci_hcdi_pipe_isoc_xfer(
122 usba_pipe_handle_data_t *ph,
123 usb_isoc_req_t *isoc_reqp,
124 usb_flags_t usb_flags);
125 static int ohci_hcdi_pipe_stop_isoc_polling(
126 usba_pipe_handle_data_t *ph,
127 usb_flags_t usb_flags);
128
129 /*
130 * Internal Function Prototypes
131 */
132
133 /* Host Controller Driver (HCD) initialization functions */
134 static void ohci_set_dma_attributes(ohci_state_t *ohcip);
135 static int ohci_allocate_pools(ohci_state_t *ohcip);
136 static void ohci_decode_ddi_dma_addr_bind_handle_result(
137 ohci_state_t *ohcip,
138 int result);
139 static int ohci_map_regs(ohci_state_t *ohcip);
140 static int ohci_register_intrs_and_init_mutex(
141 ohci_state_t *ohcip);
142 static int ohci_add_intrs(ohci_state_t *ohcip,
143 int intr_type);
144 static int ohci_init_ctlr(ohci_state_t *ohcip);
145 static int ohci_init_hcca(ohci_state_t *ohcip);
146 static void ohci_build_interrupt_lattice(
147 ohci_state_t *ohcip);
148 static int ohci_take_control(ohci_state_t *ohcip);
149 static usba_hcdi_ops_t *ohci_alloc_hcdi_ops(
150 ohci_state_t *ohcip);
151
152 /* Host Controller Driver (HCD) deinitialization functions */
153 static int ohci_cleanup(ohci_state_t *ohcip);
154 static void ohci_rem_intrs(ohci_state_t *ohcip);
155 static int ohci_cpr_suspend(ohci_state_t *ohcip);
156 static int ohci_cpr_resume(ohci_state_t *ohcip);
157
158 /* Bandwidth Allocation functions */
159 static int ohci_allocate_bandwidth(ohci_state_t *ohcip,
160 usba_pipe_handle_data_t *ph,
161 uint_t *node);
162 static void ohci_deallocate_bandwidth(ohci_state_t *ohcip,
163 usba_pipe_handle_data_t *ph);
164 static int ohci_compute_total_bandwidth(
165 usb_ep_descr_t *endpoint,
166 usb_port_status_t port_status,
167 uint_t *bandwidth);
168 static int ohci_adjust_polling_interval(
169 ohci_state_t *ohcip,
170 usb_ep_descr_t *endpoint,
171 usb_port_status_t port_status);
172 static uint_t ohci_lattice_height(uint_t interval);
173 static uint_t ohci_lattice_parent(uint_t node);
174 static uint_t ohci_leftmost_leaf(uint_t node,
175 uint_t height);
176 static uint_t ohci_hcca_intr_index(
177 uint_t node);
178 static uint_t ohci_hcca_leaf_index(
179 uint_t leaf);
180 static uint_t ohci_pow_2(uint_t x);
181 static uint_t ohci_log_2(uint_t x);
182
183 /* Endpoint Descriptor (ED) related functions */
184 static uint_t ohci_unpack_endpoint(ohci_state_t *ohcip,
185 usba_pipe_handle_data_t *ph);
186 static void ohci_insert_ed(ohci_state_t *ohcip,
187 usba_pipe_handle_data_t *ph);
188 static void ohci_insert_ctrl_ed(
189 ohci_state_t *ohcip,
190 ohci_pipe_private_t *pp);
191 static void ohci_insert_bulk_ed(
192 ohci_state_t *ohcip,
193 ohci_pipe_private_t *pp);
194 static void ohci_insert_intr_ed(
195 ohci_state_t *ohcip,
196 ohci_pipe_private_t *pp);
197 static void ohci_insert_isoc_ed(
198 ohci_state_t *ohcip,
199 ohci_pipe_private_t *pp);
200 static void ohci_modify_sKip_bit(ohci_state_t *ohcip,
201 ohci_pipe_private_t *pp,
202 skip_bit_t action,
203 usb_flags_t flag);
204 static void ohci_remove_ed(ohci_state_t *ohcip,
205 ohci_pipe_private_t *pp);
206 static void ohci_remove_ctrl_ed(
207 ohci_state_t *ohcip,
208 ohci_pipe_private_t *pp);
209 static void ohci_remove_bulk_ed(
210 ohci_state_t *ohcip,
211 ohci_pipe_private_t *pp);
212 static void ohci_remove_periodic_ed(
213 ohci_state_t *ohcip,
214 ohci_pipe_private_t *pp);
215 static void ohci_insert_ed_on_reclaim_list(
216 ohci_state_t *ohcip,
217 ohci_pipe_private_t *pp);
218 static void ohci_detach_ed_from_list(
219 ohci_state_t *ohcip,
220 ohci_ed_t *ept,
221 uint_t ept_type);
222 static ohci_ed_t *ohci_ed_iommu_to_cpu(
223 ohci_state_t *ohcip,
224 uintptr_t addr);
225
226 /* Transfer Descriptor (TD) related functions */
227 static int ohci_initialize_dummy(ohci_state_t *ohcip,
228 ohci_ed_t *ept);
229 static ohci_trans_wrapper_t *ohci_allocate_ctrl_resources(
230 ohci_state_t *ohcip,
231 ohci_pipe_private_t *pp,
232 usb_ctrl_req_t *ctrl_reqp,
233 usb_flags_t usb_flags);
234 static void ohci_insert_ctrl_req(
235 ohci_state_t *ohcip,
236 usba_pipe_handle_data_t *ph,
237 usb_ctrl_req_t *ctrl_reqp,
238 ohci_trans_wrapper_t *tw,
239 usb_flags_t usb_flags);
240 static ohci_trans_wrapper_t *ohci_allocate_bulk_resources(
241 ohci_state_t *ohcip,
242 ohci_pipe_private_t *pp,
243 usb_bulk_req_t *bulk_reqp,
244 usb_flags_t usb_flags);
245 static void ohci_insert_bulk_req(ohci_state_t *ohcip,
246 usba_pipe_handle_data_t *ph,
247 usb_bulk_req_t *bulk_reqp,
248 ohci_trans_wrapper_t *tw,
249 usb_flags_t flags);
250 static int ohci_start_pipe_polling(ohci_state_t *ohcip,
251 usba_pipe_handle_data_t *ph,
252 usb_flags_t flags);
253 static void ohci_set_periodic_pipe_polling(
254 ohci_state_t *ohcip,
255 usba_pipe_handle_data_t *ph);
256 static ohci_trans_wrapper_t *ohci_allocate_intr_resources(
257 ohci_state_t *ohcip,
258 usba_pipe_handle_data_t *ph,
259 usb_intr_req_t *intr_reqp,
260 usb_flags_t usb_flags);
261 static void ohci_insert_intr_req(ohci_state_t *ohcip,
262 ohci_pipe_private_t *pp,
263 ohci_trans_wrapper_t *tw,
264 usb_flags_t flags);
265 static int ohci_stop_periodic_pipe_polling(
266 ohci_state_t *ohcip,
267 usba_pipe_handle_data_t *ph,
268 usb_flags_t flags);
269 static ohci_trans_wrapper_t *ohci_allocate_isoc_resources(
270 ohci_state_t *ohcip,
271 usba_pipe_handle_data_t *ph,
272 usb_isoc_req_t *isoc_reqp,
273 usb_flags_t usb_flags);
274 static int ohci_insert_isoc_req(ohci_state_t *ohcip,
275 ohci_pipe_private_t *pp,
276 ohci_trans_wrapper_t *tw,
277 uint_t flags);
278 static int ohci_insert_hc_td(ohci_state_t *ohcip,
279 uint_t hctd_ctrl,
280 uint32_t hctd_dma_offs,
281 size_t hctd_length,
282 uint32_t hctd_ctrl_phase,
283 ohci_pipe_private_t *pp,
284 ohci_trans_wrapper_t *tw);
285 static ohci_td_t *ohci_allocate_td_from_pool(
286 ohci_state_t *ohcip);
287 static void ohci_fill_in_td(ohci_state_t *ohcip,
288 ohci_td_t *td,
289 ohci_td_t *new_dummy,
290 uint_t hctd_ctrl,
291 uint32_t hctd_dma_offs,
292 size_t hctd_length,
293 uint32_t hctd_ctrl_phase,
294 ohci_pipe_private_t *pp,
295 ohci_trans_wrapper_t *tw);
296 static void ohci_init_itd(
297 ohci_state_t *ohcip,
298 ohci_trans_wrapper_t *tw,
299 uint_t hctd_ctrl,
300 uint32_t index,
301 ohci_td_t *td);
302 static int ohci_insert_td_with_frame_number(
303 ohci_state_t *ohcip,
304 ohci_pipe_private_t *pp,
305 ohci_trans_wrapper_t *tw,
306 ohci_td_t *current_td,
307 ohci_td_t *dummy_td);
308 static void ohci_insert_td_on_tw(ohci_state_t *ohcip,
309 ohci_trans_wrapper_t *tw,
310 ohci_td_t *td);
311 static void ohci_done_list_tds(ohci_state_t *ohcip,
312 usba_pipe_handle_data_t *ph);
313
314 /* Transfer Wrapper (TW) functions */
315 static ohci_trans_wrapper_t *ohci_create_transfer_wrapper(
316 ohci_state_t *ohcip,
317 ohci_pipe_private_t *pp,
318 size_t length,
319 uint_t usb_flags);
320 static ohci_trans_wrapper_t *ohci_create_isoc_transfer_wrapper(
321 ohci_state_t *ohcip,
322 ohci_pipe_private_t *pp,
323 size_t length,
324 usb_isoc_pkt_descr_t *descr,
325 ushort_t pkt_count,
326 size_t td_count,
327 uint_t usb_flags);
328 int ohci_allocate_tds_for_tw(
329 ohci_state_t *ohcip,
330 ohci_trans_wrapper_t *tw,
331 size_t td_count);
332 static ohci_trans_wrapper_t *ohci_allocate_tw_resources(
333 ohci_state_t *ohcip,
334 ohci_pipe_private_t *pp,
335 size_t length,
336 usb_flags_t usb_flags,
337 size_t td_count);
338 static void ohci_free_tw_tds_resources(
339 ohci_state_t *ohcip,
340 ohci_trans_wrapper_t *tw);
341 static void ohci_start_xfer_timer(
342 ohci_state_t *ohcip,
343 ohci_pipe_private_t *pp,
344 ohci_trans_wrapper_t *tw);
345 static void ohci_stop_xfer_timer(
346 ohci_state_t *ohcip,
347 ohci_trans_wrapper_t *tw,
348 uint_t flag);
349 static void ohci_xfer_timeout_handler(void *arg);
350 static void ohci_remove_tw_from_timeout_list(
351 ohci_state_t *ohcip,
352 ohci_trans_wrapper_t *tw);
353 static void ohci_start_timer(ohci_state_t *ohcip);
354 static void ohci_free_dma_resources(ohci_state_t *ohcip,
355 usba_pipe_handle_data_t *ph);
356 static void ohci_free_tw(ohci_state_t *ohcip,
357 ohci_trans_wrapper_t *tw);
358 static int ohci_tw_rebind_cookie(
359 ohci_state_t *ohcip,
360 ohci_pipe_private_t *pp,
361 ohci_trans_wrapper_t *tw);
362
363 /* Interrupt Handling functions */
364 static uint_t ohci_intr(caddr_t arg1,
365 caddr_t arg2);
366 static void ohci_handle_missed_intr(
367 ohci_state_t *ohcip);
368 static void ohci_handle_ue(ohci_state_t *ohcip);
369 static void ohci_handle_endpoint_reclaimation(
370 ohci_state_t *ohcip);
371 static void ohci_traverse_done_list(
372 ohci_state_t *ohcip,
373 ohci_td_t *head_done_list);
374 static ohci_td_t *ohci_reverse_done_list(
375 ohci_state_t *ohcip,
376 ohci_td_t *head_done_list);
377 static usb_cr_t ohci_parse_error(ohci_state_t *ohcip,
378 ohci_td_t *td);
379 static void ohci_parse_isoc_error(
380 ohci_state_t *ohcip,
381 ohci_pipe_private_t *pp,
382 ohci_trans_wrapper_t *tw,
383 ohci_td_t *td);
384 static usb_cr_t ohci_check_for_error(
385 ohci_state_t *ohcip,
386 ohci_pipe_private_t *pp,
387 ohci_trans_wrapper_t *tw,
388 ohci_td_t *td,
389 uint_t ctrl);
390 static void ohci_handle_error(
391 ohci_state_t *ohcip,
392 ohci_td_t *td,
393 usb_cr_t error);
394 static int ohci_cleanup_data_underrun(
395 ohci_state_t *ohcip,
396 ohci_pipe_private_t *pp,
397 ohci_trans_wrapper_t *tw,
398 ohci_td_t *td);
399 static void ohci_handle_normal_td(
400 ohci_state_t *ohcip,
401 ohci_td_t *td,
402 ohci_trans_wrapper_t *tw);
403 static void ohci_handle_ctrl_td(ohci_state_t *ohcip,
404 ohci_pipe_private_t *pp,
405 ohci_trans_wrapper_t *tw,
406 ohci_td_t *td,
407 void *);
408 static void ohci_handle_bulk_td(ohci_state_t *ohcip,
409 ohci_pipe_private_t *pp,
410 ohci_trans_wrapper_t *tw,
411 ohci_td_t *td,
412 void *);
413 static void ohci_handle_intr_td(ohci_state_t *ohcip,
414 ohci_pipe_private_t *pp,
415 ohci_trans_wrapper_t *tw,
416 ohci_td_t *td,
417 void *);
418 static void ohci_handle_one_xfer_completion(
419 ohci_state_t *ohcip,
420 ohci_trans_wrapper_t *tw);
421 static void ohci_handle_isoc_td(ohci_state_t *ohcip,
422 ohci_pipe_private_t *pp,
423 ohci_trans_wrapper_t *tw,
424 ohci_td_t *td,
425 void *);
426 static void ohci_sendup_td_message(
427 ohci_state_t *ohcip,
428 ohci_pipe_private_t *pp,
429 ohci_trans_wrapper_t *tw,
430 ohci_td_t *td,
431 usb_cr_t error);
432 static int ohci_check_done_head(
433 ohci_state_t *ohcip,
434 ohci_td_t *done_head);
435
436 /* Miscillaneous functions */
437 static void ohci_cpr_cleanup(
438 ohci_state_t *ohcip);
439 static usb_req_attrs_t ohci_get_xfer_attrs(ohci_state_t *ohcip,
440 ohci_pipe_private_t *pp,
441 ohci_trans_wrapper_t *tw);
442 static int ohci_allocate_periodic_in_resource(
443 ohci_state_t *ohcip,
444 ohci_pipe_private_t *pp,
445 ohci_trans_wrapper_t *tw,
446 usb_flags_t flags);
447 static int ohci_wait_for_sof(
448 ohci_state_t *ohcip);
449 static void ohci_pipe_cleanup(
450 ohci_state_t *ohcip,
451 usba_pipe_handle_data_t *ph);
452 static void ohci_wait_for_transfers_completion(
453 ohci_state_t *ohcip,
454 ohci_pipe_private_t *pp);
455 static void ohci_check_for_transfers_completion(
456 ohci_state_t *ohcip,
457 ohci_pipe_private_t *pp);
458 static void ohci_save_data_toggle(ohci_state_t *ohcip,
459 usba_pipe_handle_data_t *ph);
460 static void ohci_restore_data_toggle(ohci_state_t *ohcip,
461 usba_pipe_handle_data_t *ph);
462 static void ohci_deallocate_periodic_in_resource(
463 ohci_state_t *ohcip,
464 ohci_pipe_private_t *pp,
465 ohci_trans_wrapper_t *tw);
466 static void ohci_do_client_periodic_in_req_callback(
467 ohci_state_t *ohcip,
468 ohci_pipe_private_t *pp,
469 usb_cr_t completion_reason);
470 static void ohci_hcdi_callback(
471 usba_pipe_handle_data_t *ph,
472 ohci_trans_wrapper_t *tw,
473 usb_cr_t completion_reason);
474
475 /* Kstat Support */
476 static void ohci_create_stats(ohci_state_t *ohcip);
477 static void ohci_destroy_stats(ohci_state_t *ohcip);
478 static void ohci_do_byte_stats(
479 ohci_state_t *ohcip,
480 size_t len,
481 uint8_t attr,
482 uint8_t addr);
483 static void ohci_do_intrs_stats(
484 ohci_state_t *ohcip,
485 int val);
486 static void ohci_print_op_regs(ohci_state_t *ohcip);
487 static void ohci_print_ed(ohci_state_t *ohcip,
488 ohci_ed_t *ed);
489 static void ohci_print_td(ohci_state_t *ohcip,
490 ohci_td_t *td);
491
492 /* extern */
493 int usba_hubdi_root_hub_power(dev_info_t *dip, int comp, int level);
494
495 /*
496 * Device operations (dev_ops) entries function prototypes.
497 *
498 * We use the hub cbops since all nexus ioctl operations defined so far will
499 * be executed by the root hub. The following are the Host Controller Driver
500 * (HCD) entry points.
501 *
502 * the open/close/ioctl functions call the corresponding usba_hubdi_*
503 * calls after looking up the dip thru the dev_t.
504 */
505 static int ohci_open(dev_t *devp, int flags, int otyp, cred_t *credp);
506 static int ohci_close(dev_t dev, int flag, int otyp, cred_t *credp);
507 static int ohci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
508 cred_t *credp, int *rvalp);
509
510 static int ohci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
511 static int ohci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
512 static int ohci_quiesce(dev_info_t *dip);
513
514 static int ohci_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
515 void *arg, void **result);
516
517 static struct cb_ops ohci_cb_ops = {
518 ohci_open, /* Open */
519 ohci_close, /* Close */
520 nodev, /* Strategy */
521 nodev, /* Print */
522 nodev, /* Dump */
523 nodev, /* Read */
524 nodev, /* Write */
525 ohci_ioctl, /* Ioctl */
526 nodev, /* Devmap */
527 nodev, /* Mmap */
528 nodev, /* Segmap */
529 nochpoll, /* Poll */
530 ddi_prop_op, /* cb_prop_op */
531 NULL, /* Streamtab */
532 D_MP /* Driver compatibility flag */
533 };
534
535 static struct dev_ops ohci_ops = {
536 DEVO_REV, /* Devo_rev */
537 0, /* Refcnt */
538 ohci_info, /* Info */
539 nulldev, /* Identify */
540 nulldev, /* Probe */
541 ohci_attach, /* Attach */
542 ohci_detach, /* Detach */
543 nodev, /* Reset */
544 &ohci_cb_ops, /* Driver operations */
545 &usba_hubdi_busops, /* Bus operations */
546 usba_hubdi_root_hub_power, /* Power */
547 ohci_quiesce, /* Quiesce */
548 };
549
550 /*
551 * The USBA library must be loaded for this driver.
552 */
553 static struct modldrv modldrv = {
554 &mod_driverops, /* Type of module. This one is a driver */
555 "USB OpenHCI Driver", /* Name of the module. */
556 &ohci_ops, /* Driver ops */
557 };
558
559 static struct modlinkage modlinkage = {
560 MODREV_1, (void *)&modldrv, NULL
561 };
562
563
564 int
_init(void)565 _init(void)
566 {
567 int error;
568
569 /* Initialize the soft state structures */
570 if ((error = ddi_soft_state_init(&ohci_statep, sizeof (ohci_state_t),
571 OHCI_INSTS)) != 0) {
572 return (error);
573 }
574
575 /* Install the loadable module */
576 if ((error = mod_install(&modlinkage)) != 0) {
577 ddi_soft_state_fini(&ohci_statep);
578 }
579
580 return (error);
581 }
582
583
584 int
_info(struct modinfo * modinfop)585 _info(struct modinfo *modinfop)
586 {
587 return (mod_info(&modlinkage, modinfop));
588 }
589
590
591 int
_fini(void)592 _fini(void)
593 {
594 int error;
595
596 if ((error = mod_remove(&modlinkage)) == 0) {
597 /* Release per module resources */
598 ddi_soft_state_fini(&ohci_statep);
599 }
600
601 return (error);
602 }
603
604
605 /*
606 * Host Controller Driver (HCD) entry points
607 */
608
609 /*
610 * ohci_attach:
611 */
612 static int
ohci_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)613 ohci_attach(dev_info_t *dip,
614 ddi_attach_cmd_t cmd)
615 {
616 int instance;
617 ohci_state_t *ohcip = NULL;
618 usba_hcdi_register_args_t hcdi_args;
619
620 switch (cmd) {
621 case DDI_ATTACH:
622 break;
623 case DDI_RESUME:
624 ohcip = ohci_obtain_state(dip);
625
626 return (ohci_cpr_resume(ohcip));
627 default:
628 return (DDI_FAILURE);
629 }
630
631 /* Get the instance and create soft state */
632 instance = ddi_get_instance(dip);
633
634 if (ddi_soft_state_zalloc(ohci_statep, instance) != 0) {
635
636 return (DDI_FAILURE);
637 }
638
639 ohcip = ddi_get_soft_state(ohci_statep, instance);
640 if (ohcip == NULL) {
641
642 return (DDI_FAILURE);
643 }
644
645 ohcip->ohci_flags = OHCI_ATTACH;
646
647 ohcip->ohci_log_hdl = usb_alloc_log_hdl(dip, "ohci", &ohci_errlevel,
648 &ohci_errmask, &ohci_instance_debug, 0);
649
650 ohcip->ohci_flags |= OHCI_ZALLOC;
651
652 /* Set host controller soft state to initilization */
653 ohcip->ohci_hc_soft_state = OHCI_CTLR_INIT_STATE;
654
655 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
656 "ohcip = 0x%p", (void *)ohcip);
657
658 /* Initialize the DMA attributes */
659 ohci_set_dma_attributes(ohcip);
660
661 /* Save the dip and instance */
662 ohcip->ohci_dip = dip;
663 ohcip->ohci_instance = instance;
664
665 /* Initialize the kstat structures */
666 ohci_create_stats(ohcip);
667
668 /* Create the td and ed pools */
669 if (ohci_allocate_pools(ohcip) != DDI_SUCCESS) {
670 (void) ohci_cleanup(ohcip);
671
672 return (DDI_FAILURE);
673 }
674
675 /* Map the registers */
676 if (ohci_map_regs(ohcip) != DDI_SUCCESS) {
677 (void) ohci_cleanup(ohcip);
678
679 return (DDI_FAILURE);
680 }
681
682 /* Get the ohci chip vendor and device id */
683 ohcip->ohci_vendor_id = pci_config_get16(
684 ohcip->ohci_config_handle, PCI_CONF_VENID);
685 ohcip->ohci_device_id = pci_config_get16(
686 ohcip->ohci_config_handle, PCI_CONF_DEVID);
687 ohcip->ohci_rev_id = pci_config_get8(
688 ohcip->ohci_config_handle, PCI_CONF_REVID);
689
690 /* Register interrupts */
691 if (ohci_register_intrs_and_init_mutex(ohcip) != DDI_SUCCESS) {
692 (void) ohci_cleanup(ohcip);
693
694 return (DDI_FAILURE);
695 }
696
697 mutex_enter(&ohcip->ohci_int_mutex);
698
699 /* Initialize the controller */
700 if (ohci_init_ctlr(ohcip) != DDI_SUCCESS) {
701 mutex_exit(&ohcip->ohci_int_mutex);
702 (void) ohci_cleanup(ohcip);
703
704 return (DDI_FAILURE);
705 }
706
707 /*
708 * At this point, the hardware wiil be okay.
709 * Initialize the usba_hcdi structure
710 */
711 ohcip->ohci_hcdi_ops = ohci_alloc_hcdi_ops(ohcip);
712
713 mutex_exit(&ohcip->ohci_int_mutex);
714
715 /*
716 * Make this HCD instance known to USBA
717 * (dma_attr must be passed for USBA busctl's)
718 */
719 hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION;
720 hcdi_args.usba_hcdi_register_dip = dip;
721 hcdi_args.usba_hcdi_register_ops = ohcip->ohci_hcdi_ops;
722 hcdi_args.usba_hcdi_register_dma_attr = &ohcip->ohci_dma_attr;
723
724 /*
725 * Priority and iblock_cookie are one and the same
726 * (However, retaining hcdi_soft_iblock_cookie for now
727 * assigning it w/ priority. In future all iblock_cookie
728 * could just go)
729 */
730 hcdi_args.usba_hcdi_register_iblock_cookie =
731 (ddi_iblock_cookie_t)(uintptr_t)ohcip->ohci_intr_pri;
732
733 if (usba_hcdi_register(&hcdi_args, 0) != DDI_SUCCESS) {
734 (void) ohci_cleanup(ohcip);
735
736 return (DDI_FAILURE);
737 }
738 ohcip->ohci_flags |= OHCI_USBAREG;
739
740 mutex_enter(&ohcip->ohci_int_mutex);
741
742 if ((ohci_init_root_hub(ohcip)) != USB_SUCCESS) {
743 mutex_exit(&ohcip->ohci_int_mutex);
744 (void) ohci_cleanup(ohcip);
745
746 return (DDI_FAILURE);
747 }
748
749 mutex_exit(&ohcip->ohci_int_mutex);
750
751 /* Finally load the root hub driver */
752 if (ohci_load_root_hub_driver(ohcip) != USB_SUCCESS) {
753 (void) ohci_cleanup(ohcip);
754
755 return (DDI_FAILURE);
756 }
757 ohcip->ohci_flags |= OHCI_RHREG;
758
759 /* Display information in the banner */
760 ddi_report_dev(dip);
761
762 mutex_enter(&ohcip->ohci_int_mutex);
763
764 /* Reset the ohci initilization flag */
765 ohcip->ohci_flags &= ~OHCI_ATTACH;
766
767 /* Print the Host Control's Operational registers */
768 ohci_print_op_regs(ohcip);
769
770 /* For RIO we need to call pci_report_pmcap */
771 if (OHCI_IS_RIO(ohcip)) {
772
773 (void) pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000);
774 }
775
776 mutex_exit(&ohcip->ohci_int_mutex);
777
778 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
779 "ohci_attach: dip = 0x%p done", (void *)dip);
780
781 return (DDI_SUCCESS);
782 }
783
784
785 /*
786 * ohci_detach:
787 */
788 int
ohci_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)789 ohci_detach(dev_info_t *dip,
790 ddi_detach_cmd_t cmd)
791 {
792 ohci_state_t *ohcip = ohci_obtain_state(dip);
793
794 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_detach:");
795
796 switch (cmd) {
797 case DDI_DETACH:
798
799 return (ohci_cleanup(ohcip));
800
801 case DDI_SUSPEND:
802
803 return (ohci_cpr_suspend(ohcip));
804 default:
805
806 return (DDI_FAILURE);
807 }
808 }
809
810
811 /*
812 * ohci_info:
813 */
814 /* ARGSUSED */
815 static int
ohci_info(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)816 ohci_info(dev_info_t *dip,
817 ddi_info_cmd_t infocmd,
818 void *arg,
819 void **result)
820 {
821 dev_t dev;
822 ohci_state_t *ohcip;
823 int instance;
824 int error = DDI_FAILURE;
825
826 switch (infocmd) {
827 case DDI_INFO_DEVT2DEVINFO:
828 dev = (dev_t)arg;
829 instance = OHCI_UNIT(dev);
830 ohcip = ddi_get_soft_state(ohci_statep, instance);
831 if (ohcip != NULL) {
832 *result = (void *)ohcip->ohci_dip;
833 if (*result != NULL) {
834 error = DDI_SUCCESS;
835 }
836 } else {
837 *result = NULL;
838 }
839
840 break;
841 case DDI_INFO_DEVT2INSTANCE:
842 dev = (dev_t)arg;
843 instance = OHCI_UNIT(dev);
844 *result = (void *)(uintptr_t)instance;
845 error = DDI_SUCCESS;
846 break;
847 default:
848 break;
849 }
850
851 return (error);
852 }
853
854
855 /*
856 * cb_ops entry points
857 */
858 static dev_info_t *
ohci_get_dip(dev_t dev)859 ohci_get_dip(dev_t dev)
860 {
861 int instance = OHCI_UNIT(dev);
862 ohci_state_t *ohcip = ddi_get_soft_state(ohci_statep, instance);
863
864 if (ohcip) {
865
866 return (ohcip->ohci_dip);
867 } else {
868
869 return (NULL);
870 }
871 }
872
873
874 static int
ohci_open(dev_t * devp,int flags,int otyp,cred_t * credp)875 ohci_open(dev_t *devp,
876 int flags,
877 int otyp,
878 cred_t *credp)
879 {
880 dev_info_t *dip = ohci_get_dip(*devp);
881
882 return (usba_hubdi_open(dip, devp, flags, otyp, credp));
883 }
884
885
886 static int
ohci_close(dev_t dev,int flag,int otyp,cred_t * credp)887 ohci_close(dev_t dev,
888 int flag,
889 int otyp,
890 cred_t *credp)
891 {
892 dev_info_t *dip = ohci_get_dip(dev);
893
894 return (usba_hubdi_close(dip, dev, flag, otyp, credp));
895 }
896
897
898 static int
ohci_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)899 ohci_ioctl(dev_t dev,
900 int cmd,
901 intptr_t arg,
902 int mode,
903 cred_t *credp,
904 int *rvalp)
905 {
906 dev_info_t *dip = ohci_get_dip(dev);
907
908 return (usba_hubdi_ioctl(dip,
909 dev, cmd, arg, mode, credp, rvalp));
910 }
911
912
913 /*
914 * Host Controller Driver (HCD) initialization functions
915 */
916
917 /*
918 * ohci_set_dma_attributes:
919 *
920 * Set the limits in the DMA attributes structure. Most of the values used
921 * in the DMA limit structres are the default values as specified by the
922 * Writing PCI device drivers document.
923 */
924 static void
ohci_set_dma_attributes(ohci_state_t * ohcip)925 ohci_set_dma_attributes(ohci_state_t *ohcip)
926 {
927 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
928 "ohci_set_dma_attributes:");
929
930 /* Initialize the DMA attributes */
931 ohcip->ohci_dma_attr.dma_attr_version = DMA_ATTR_V0;
932 ohcip->ohci_dma_attr.dma_attr_addr_lo = 0x00000000ull;
933 ohcip->ohci_dma_attr.dma_attr_addr_hi = 0xfffffffeull;
934
935 /* 32 bit addressing */
936 ohcip->ohci_dma_attr.dma_attr_count_max = OHCI_DMA_ATTR_COUNT_MAX;
937
938 /* Byte alignment */
939 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT;
940
941 /*
942 * Since PCI specification is byte alignment, the
943 * burstsize field should be set to 1 for PCI devices.
944 */
945 ohcip->ohci_dma_attr.dma_attr_burstsizes = 0x1;
946
947 ohcip->ohci_dma_attr.dma_attr_minxfer = 0x1;
948 ohcip->ohci_dma_attr.dma_attr_maxxfer = OHCI_DMA_ATTR_MAX_XFER;
949 ohcip->ohci_dma_attr.dma_attr_seg = 0xffffffffull;
950 ohcip->ohci_dma_attr.dma_attr_sgllen = 1;
951 ohcip->ohci_dma_attr.dma_attr_granular = OHCI_DMA_ATTR_GRANULAR;
952 ohcip->ohci_dma_attr.dma_attr_flags = 0;
953 }
954
955
956 /*
957 * ohci_allocate_pools:
958 *
959 * Allocate the system memory for the Endpoint Descriptor (ED) and for the
960 * Transfer Descriptor (TD) pools. Both ED and TD structures must be aligned
961 * to a 16 byte boundary.
962 */
963 static int
ohci_allocate_pools(ohci_state_t * ohcip)964 ohci_allocate_pools(ohci_state_t *ohcip)
965 {
966 ddi_device_acc_attr_t dev_attr;
967 size_t real_length;
968 int result;
969 uint_t ccount;
970 int i;
971
972 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
973 "ohci_allocate_pools:");
974
975 /* The host controller will be little endian */
976 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
977 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
978 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
979
980 /* Byte alignment to TD alignment */
981 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_TD_ALIGNMENT;
982
983 /* Allocate the TD pool DMA handle */
984 if (ddi_dma_alloc_handle(ohcip->ohci_dip, &ohcip->ohci_dma_attr,
985 DDI_DMA_SLEEP, 0,
986 &ohcip->ohci_td_pool_dma_handle) != DDI_SUCCESS) {
987
988 return (DDI_FAILURE);
989 }
990
991 /* Allocate the memory for the TD pool */
992 if (ddi_dma_mem_alloc(ohcip->ohci_td_pool_dma_handle,
993 ohci_td_pool_size * sizeof (ohci_td_t),
994 &dev_attr,
995 DDI_DMA_CONSISTENT,
996 DDI_DMA_SLEEP,
997 0,
998 (caddr_t *)&ohcip->ohci_td_pool_addr,
999 &real_length,
1000 &ohcip->ohci_td_pool_mem_handle)) {
1001
1002 return (DDI_FAILURE);
1003 }
1004
1005 /* Map the TD pool into the I/O address space */
1006 result = ddi_dma_addr_bind_handle(
1007 ohcip->ohci_td_pool_dma_handle,
1008 NULL,
1009 (caddr_t)ohcip->ohci_td_pool_addr,
1010 real_length,
1011 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1012 DDI_DMA_SLEEP,
1013 NULL,
1014 &ohcip->ohci_td_pool_cookie,
1015 &ccount);
1016
1017 bzero((void *)ohcip->ohci_td_pool_addr,
1018 ohci_td_pool_size * sizeof (ohci_td_t));
1019
1020 /* Process the result */
1021 if (result == DDI_DMA_MAPPED) {
1022 /* The cookie count should be 1 */
1023 if (ccount != 1) {
1024 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1025 "ohci_allocate_pools: More than 1 cookie");
1026
1027 return (DDI_FAILURE);
1028 }
1029 } else {
1030 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1031 "ohci_allocate_pools: Result = %d", result);
1032
1033 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
1034
1035 return (DDI_FAILURE);
1036 }
1037
1038 /*
1039 * DMA addresses for TD pools are bound
1040 */
1041 ohcip->ohci_dma_addr_bind_flag |= OHCI_TD_POOL_BOUND;
1042
1043 /* Initialize the TD pool */
1044 for (i = 0; i < ohci_td_pool_size; i ++) {
1045 Set_TD(ohcip->ohci_td_pool_addr[i].hctd_state, HC_TD_FREE);
1046 }
1047
1048 /* Byte alignment to ED alignment */
1049 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_ED_ALIGNMENT;
1050
1051 /* Allocate the ED pool DMA handle */
1052 if (ddi_dma_alloc_handle(ohcip->ohci_dip,
1053 &ohcip->ohci_dma_attr,
1054 DDI_DMA_SLEEP,
1055 0,
1056 &ohcip->ohci_ed_pool_dma_handle) != DDI_SUCCESS) {
1057
1058 return (DDI_FAILURE);
1059 }
1060
1061 /* Allocate the memory for the ED pool */
1062 if (ddi_dma_mem_alloc(ohcip->ohci_ed_pool_dma_handle,
1063 ohci_ed_pool_size * sizeof (ohci_ed_t),
1064 &dev_attr,
1065 DDI_DMA_CONSISTENT,
1066 DDI_DMA_SLEEP,
1067 0,
1068 (caddr_t *)&ohcip->ohci_ed_pool_addr,
1069 &real_length,
1070 &ohcip->ohci_ed_pool_mem_handle) != DDI_SUCCESS) {
1071
1072 return (DDI_FAILURE);
1073 }
1074
1075 result = ddi_dma_addr_bind_handle(ohcip->ohci_ed_pool_dma_handle,
1076 NULL,
1077 (caddr_t)ohcip->ohci_ed_pool_addr,
1078 real_length,
1079 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1080 DDI_DMA_SLEEP,
1081 NULL,
1082 &ohcip->ohci_ed_pool_cookie,
1083 &ccount);
1084
1085 bzero((void *)ohcip->ohci_ed_pool_addr,
1086 ohci_ed_pool_size * sizeof (ohci_ed_t));
1087
1088 /* Process the result */
1089 if (result == DDI_DMA_MAPPED) {
1090 /* The cookie count should be 1 */
1091 if (ccount != 1) {
1092 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1093 "ohci_allocate_pools: More than 1 cookie");
1094
1095 return (DDI_FAILURE);
1096 }
1097 } else {
1098 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
1099
1100 return (DDI_FAILURE);
1101 }
1102
1103 /*
1104 * DMA addresses for ED pools are bound
1105 */
1106 ohcip->ohci_dma_addr_bind_flag |= OHCI_ED_POOL_BOUND;
1107
1108 /* Initialize the ED pool */
1109 for (i = 0; i < ohci_ed_pool_size; i ++) {
1110 Set_ED(ohcip->ohci_ed_pool_addr[i].hced_state, HC_EPT_FREE);
1111 }
1112
1113 return (DDI_SUCCESS);
1114 }
1115
1116
1117 /*
1118 * ohci_decode_ddi_dma_addr_bind_handle_result:
1119 *
1120 * Process the return values of ddi_dma_addr_bind_handle()
1121 */
1122 static void
ohci_decode_ddi_dma_addr_bind_handle_result(ohci_state_t * ohcip,int result)1123 ohci_decode_ddi_dma_addr_bind_handle_result(
1124 ohci_state_t *ohcip,
1125 int result)
1126 {
1127 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
1128 "ohci_decode_ddi_dma_addr_bind_handle_result:");
1129
1130 switch (result) {
1131 case DDI_DMA_PARTIAL_MAP:
1132 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl,
1133 "Partial transfers not allowed");
1134 break;
1135 case DDI_DMA_INUSE:
1136 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl,
1137 "Handle is in use");
1138 break;
1139 case DDI_DMA_NORESOURCES:
1140 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl,
1141 "No resources");
1142 break;
1143 case DDI_DMA_NOMAPPING:
1144 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl,
1145 "No mapping");
1146 break;
1147 case DDI_DMA_TOOBIG:
1148 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl,
1149 "Object is too big");
1150 break;
1151 default:
1152 USB_DPRINTF_L2(PRINT_MASK_ALL, ohcip->ohci_log_hdl,
1153 "Unknown dma error");
1154 }
1155 }
1156
1157
1158 /*
1159 * ohci_map_regs:
1160 *
1161 * The Host Controller (HC) contains a set of on-chip operational registers
1162 * and which should be mapped into a non-cacheable portion of the system
1163 * addressable space.
1164 */
1165 static int
ohci_map_regs(ohci_state_t * ohcip)1166 ohci_map_regs(ohci_state_t *ohcip)
1167 {
1168 ddi_device_acc_attr_t attr;
1169 uint16_t cmd_reg;
1170
1171 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_map_regs:");
1172
1173 /* The host controller will be little endian */
1174 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1175 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
1176 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1177
1178 /* Map in operational registers */
1179 if (ddi_regs_map_setup(ohcip->ohci_dip, 1,
1180 (caddr_t *)&ohcip->ohci_regsp, 0,
1181 sizeof (ohci_regs_t), &attr,
1182 &ohcip->ohci_regs_handle) != DDI_SUCCESS) {
1183
1184 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1185 "ohci_map_regs: Map setup error");
1186
1187 return (DDI_FAILURE);
1188 }
1189
1190 if (pci_config_setup(ohcip->ohci_dip,
1191 &ohcip->ohci_config_handle) != DDI_SUCCESS) {
1192
1193 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1194 "ohci_map_regs: Config error");
1195
1196 return (DDI_FAILURE);
1197 }
1198
1199 /* Make sure Memory Access Enable and Master Enable are set */
1200 cmd_reg = pci_config_get16(ohcip->ohci_config_handle, PCI_CONF_COMM);
1201
1202 if (!(cmd_reg & PCI_COMM_MAE)) {
1203
1204 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1205 "ohci_map_regs: Memory base address access disabled");
1206
1207 return (DDI_FAILURE);
1208 }
1209
1210 cmd_reg |= (PCI_COMM_MAE | PCI_COMM_ME);
1211
1212 pci_config_put16(ohcip->ohci_config_handle, PCI_CONF_COMM, cmd_reg);
1213
1214 return (DDI_SUCCESS);
1215 }
1216
1217 /*
1218 * The following simulated polling is for debugging purposes only.
1219 * It is activated on x86 by setting usb-polling=true in GRUB or ohci.conf.
1220 */
1221 static int
ohci_is_polled(dev_info_t * dip)1222 ohci_is_polled(dev_info_t *dip)
1223 {
1224 int ret;
1225 char *propval;
1226
1227 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
1228 "usb-polling", &propval) != DDI_SUCCESS)
1229
1230 return (0);
1231
1232 ret = (strcmp(propval, "true") == 0);
1233 ddi_prop_free(propval);
1234
1235 return (ret);
1236 }
1237
1238 static void
ohci_poll_intr(void * arg)1239 ohci_poll_intr(void *arg)
1240 {
1241 /* poll every millisecond */
1242 for (;;) {
1243 (void) ohci_intr(arg, NULL);
1244 delay(drv_usectohz(1000));
1245 }
1246 }
1247
1248 /*
1249 * ohci_register_intrs_and_init_mutex:
1250 *
1251 * Register interrupts and initialize each mutex and condition variables
1252 */
1253 static int
ohci_register_intrs_and_init_mutex(ohci_state_t * ohcip)1254 ohci_register_intrs_and_init_mutex(ohci_state_t *ohcip)
1255 {
1256 int intr_types;
1257
1258 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1259 "ohci_register_intrs_and_init_mutex:");
1260
1261 /*
1262 * Sometimes the OHCI controller of ULI1575 southbridge
1263 * could not receive SOF intrs when enable MSI. Hence
1264 * MSI is disabled for this chip.
1265 */
1266 if ((ohcip->ohci_vendor_id == PCI_ULI1575_VENID) &&
1267 (ohcip->ohci_device_id == PCI_ULI1575_DEVID)) {
1268 ohcip->ohci_msi_enabled = B_FALSE;
1269 } else {
1270 ohcip->ohci_msi_enabled = ohci_enable_msi;
1271 }
1272
1273 if (ohci_is_polled(ohcip->ohci_dip)) {
1274 extern pri_t maxclsyspri;
1275
1276 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1277 "ohci_register_intrs_and_init_mutex: "
1278 "running in simulated polled mode");
1279
1280 (void) thread_create(NULL, 0, ohci_poll_intr, ohcip, 0, &p0,
1281 TS_RUN, maxclsyspri);
1282
1283 goto skip_intr;
1284 }
1285
1286 /* Get supported interrupt types */
1287 if (ddi_intr_get_supported_types(ohcip->ohci_dip,
1288 &intr_types) != DDI_SUCCESS) {
1289 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1290 "ohci_register_intrs_and_init_mutex: "
1291 "ddi_intr_get_supported_types failed");
1292
1293 return (DDI_FAILURE);
1294 }
1295
1296 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1297 "ohci_register_intrs_and_init_mutex: "
1298 "supported interrupt types 0x%x", intr_types);
1299
1300 if ((intr_types & DDI_INTR_TYPE_MSI) && ohcip->ohci_msi_enabled) {
1301 if (ohci_add_intrs(ohcip, DDI_INTR_TYPE_MSI)
1302 != DDI_SUCCESS) {
1303 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1304 "ohci_register_intrs_and_init_mutex: MSI "
1305 "registration failed, trying FIXED interrupt \n");
1306 } else {
1307 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1308 "ohci_register_intrs_and_init_mutex: "
1309 "Using MSI interrupt type\n");
1310
1311 ohcip->ohci_intr_type = DDI_INTR_TYPE_MSI;
1312 ohcip->ohci_flags |= OHCI_INTR;
1313 }
1314 }
1315
1316 if ((!(ohcip->ohci_flags & OHCI_INTR)) &&
1317 (intr_types & DDI_INTR_TYPE_FIXED)) {
1318 if (ohci_add_intrs(ohcip, DDI_INTR_TYPE_FIXED)
1319 != DDI_SUCCESS) {
1320 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1321 "ohci_register_intrs_and_init_mutex: "
1322 "FIXED interrupt registration failed\n");
1323
1324 return (DDI_FAILURE);
1325 }
1326
1327 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1328 "ohci_register_intrs_and_init_mutex: "
1329 "Using FIXED interrupt type\n");
1330
1331 ohcip->ohci_intr_type = DDI_INTR_TYPE_FIXED;
1332 ohcip->ohci_flags |= OHCI_INTR;
1333 }
1334
1335 skip_intr:
1336 /* Create prototype for SOF condition variable */
1337 cv_init(&ohcip->ohci_SOF_cv, NULL, CV_DRIVER, NULL);
1338
1339 /* Semaphore to serialize opens and closes */
1340 sema_init(&ohcip->ohci_ocsem, 1, NULL, SEMA_DRIVER, NULL);
1341
1342 return (DDI_SUCCESS);
1343 }
1344
1345
1346 /*
1347 * ohci_add_intrs:
1348 *
1349 * Register FIXED or MSI interrupts.
1350 */
1351 static int
ohci_add_intrs(ohci_state_t * ohcip,int intr_type)1352 ohci_add_intrs(ohci_state_t *ohcip,
1353 int intr_type)
1354 {
1355 int actual, avail, intr_size, count = 0;
1356 int i, flag, ret;
1357
1358 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1359 "ohci_add_intrs: interrupt type 0x%x", intr_type);
1360
1361 /* Get number of interrupts */
1362 ret = ddi_intr_get_nintrs(ohcip->ohci_dip, intr_type, &count);
1363 if ((ret != DDI_SUCCESS) || (count == 0)) {
1364 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1365 "ohci_add_intrs: ddi_intr_get_nintrs() failure, "
1366 "ret: %d, count: %d", ret, count);
1367
1368 return (DDI_FAILURE);
1369 }
1370
1371 /* Get number of available interrupts */
1372 ret = ddi_intr_get_navail(ohcip->ohci_dip, intr_type, &avail);
1373 if ((ret != DDI_SUCCESS) || (avail == 0)) {
1374 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1375 "ohci_add_intrs: ddi_intr_get_navail() failure, "
1376 "ret: %d, count: %d", ret, count);
1377
1378 return (DDI_FAILURE);
1379 }
1380
1381 if (avail < count) {
1382 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1383 "ohci_add_intrs: ohci_add_intrs: nintrs () "
1384 "returned %d, navail returned %d\n", count, avail);
1385 }
1386
1387 /* Allocate an array of interrupt handles */
1388 intr_size = count * sizeof (ddi_intr_handle_t);
1389 ohcip->ohci_htable = kmem_zalloc(intr_size, KM_SLEEP);
1390
1391 flag = (intr_type == DDI_INTR_TYPE_MSI) ?
1392 DDI_INTR_ALLOC_STRICT:DDI_INTR_ALLOC_NORMAL;
1393
1394 /* call ddi_intr_alloc() */
1395 ret = ddi_intr_alloc(ohcip->ohci_dip, ohcip->ohci_htable,
1396 intr_type, 0, count, &actual, flag);
1397
1398 if ((ret != DDI_SUCCESS) || (actual == 0)) {
1399 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1400 "ohci_add_intrs: ddi_intr_alloc() failed %d", ret);
1401
1402 kmem_free(ohcip->ohci_htable, intr_size);
1403
1404 return (DDI_FAILURE);
1405 }
1406
1407 if (actual < count) {
1408 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1409 "ohci_add_intrs: Requested: %d, Received: %d\n",
1410 count, actual);
1411
1412 for (i = 0; i < actual; i++)
1413 (void) ddi_intr_free(ohcip->ohci_htable[i]);
1414
1415 kmem_free(ohcip->ohci_htable, intr_size);
1416
1417 return (DDI_FAILURE);
1418 }
1419
1420 ohcip->ohci_intr_cnt = actual;
1421
1422 if ((ret = ddi_intr_get_pri(ohcip->ohci_htable[0],
1423 &ohcip->ohci_intr_pri)) != DDI_SUCCESS) {
1424 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1425 "ohci_add_intrs: ddi_intr_get_pri() failed %d", ret);
1426
1427 for (i = 0; i < actual; i++)
1428 (void) ddi_intr_free(ohcip->ohci_htable[i]);
1429
1430 kmem_free(ohcip->ohci_htable, intr_size);
1431
1432 return (DDI_FAILURE);
1433 }
1434
1435 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1436 "ohci_add_intrs: Supported Interrupt priority 0x%x",
1437 ohcip->ohci_intr_pri);
1438
1439 /* Test for high level mutex */
1440 if (ohcip->ohci_intr_pri >= ddi_intr_get_hilevel_pri()) {
1441 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1442 "ohci_add_intrs: Hi level interrupt not supported");
1443
1444 for (i = 0; i < actual; i++)
1445 (void) ddi_intr_free(ohcip->ohci_htable[i]);
1446
1447 kmem_free(ohcip->ohci_htable, intr_size);
1448
1449 return (DDI_FAILURE);
1450 }
1451
1452 /* Initialize the mutex */
1453 mutex_init(&ohcip->ohci_int_mutex, NULL, MUTEX_DRIVER,
1454 DDI_INTR_PRI(ohcip->ohci_intr_pri));
1455
1456 /* Call ddi_intr_add_handler() */
1457 for (i = 0; i < actual; i++) {
1458 if ((ret = ddi_intr_add_handler(ohcip->ohci_htable[i],
1459 ohci_intr, (caddr_t)ohcip,
1460 (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
1461 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1462 "ohci_add_intrs: ddi_intr_add_handler() "
1463 "failed %d", ret);
1464
1465 for (i = 0; i < actual; i++)
1466 (void) ddi_intr_free(ohcip->ohci_htable[i]);
1467
1468 mutex_destroy(&ohcip->ohci_int_mutex);
1469 kmem_free(ohcip->ohci_htable, intr_size);
1470
1471 return (DDI_FAILURE);
1472 }
1473 }
1474
1475 if ((ret = ddi_intr_get_cap(ohcip->ohci_htable[0],
1476 &ohcip->ohci_intr_cap)) != DDI_SUCCESS) {
1477 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1478 "ohci_add_intrs: ddi_intr_get_cap() failed %d", ret);
1479
1480 for (i = 0; i < actual; i++) {
1481 (void) ddi_intr_remove_handler(ohcip->ohci_htable[i]);
1482 (void) ddi_intr_free(ohcip->ohci_htable[i]);
1483 }
1484
1485 mutex_destroy(&ohcip->ohci_int_mutex);
1486 kmem_free(ohcip->ohci_htable, intr_size);
1487
1488 return (DDI_FAILURE);
1489 }
1490
1491 /* Enable all interrupts */
1492 if (ohcip->ohci_intr_cap & DDI_INTR_FLAG_BLOCK) {
1493 /* Call ddi_intr_block_enable() for MSI interrupts */
1494 (void) ddi_intr_block_enable(ohcip->ohci_htable,
1495 ohcip->ohci_intr_cnt);
1496 } else {
1497 /* Call ddi_intr_enable for MSI or FIXED interrupts */
1498 for (i = 0; i < ohcip->ohci_intr_cnt; i++)
1499 (void) ddi_intr_enable(ohcip->ohci_htable[i]);
1500 }
1501
1502 return (DDI_SUCCESS);
1503 }
1504
1505
1506 /*
1507 * ohci_init_ctlr:
1508 *
1509 * Initialize the Host Controller (HC).
1510 */
1511 static int
ohci_init_ctlr(ohci_state_t * ohcip)1512 ohci_init_ctlr(ohci_state_t *ohcip)
1513 {
1514 int revision, curr_control, max_packet = 0;
1515 clock_t sof_time_wait;
1516 int retry = 0;
1517 int ohci_frame_interval;
1518
1519 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_init_ctlr:");
1520
1521 if (ohci_take_control(ohcip) != DDI_SUCCESS) {
1522 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1523 "ohci_init_ctlr: ohci_take_control failed\n");
1524
1525 return (DDI_FAILURE);
1526 }
1527
1528 /*
1529 * Soft reset the host controller.
1530 *
1531 * On soft reset, the ohci host controller moves to the
1532 * USB Suspend state in which most of the ohci operational
1533 * registers are reset except stated ones. The soft reset
1534 * doesn't cause a reset to the ohci root hub and even no
1535 * subsequent reset signaling should be asserterd to its
1536 * down stream.
1537 */
1538 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
1539
1540 mutex_exit(&ohcip->ohci_int_mutex);
1541 /* Wait 10ms for reset to complete */
1542 delay(drv_usectohz(OHCI_RESET_TIMEWAIT));
1543 mutex_enter(&ohcip->ohci_int_mutex);
1544
1545 /*
1546 * Do hard reset the host controller.
1547 *
1548 * Now perform USB reset in order to reset the ohci root
1549 * hub.
1550 */
1551 Set_OpReg(hcr_control, HCR_CONTROL_RESET);
1552
1553 /*
1554 * According to Section 5.1.2.3 of the specification, the
1555 * host controller will go into suspend state immediately
1556 * after the reset.
1557 */
1558
1559 /* Verify the version number */
1560 revision = Get_OpReg(hcr_revision);
1561
1562 if ((revision & HCR_REVISION_MASK) != HCR_REVISION_1_0) {
1563
1564 return (DDI_FAILURE);
1565 }
1566
1567 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1568 "ohci_init_ctlr: Revision verified");
1569
1570 /* hcca area need not be initialized on resume */
1571 if (ohcip->ohci_hc_soft_state == OHCI_CTLR_INIT_STATE) {
1572
1573 /* Initialize the hcca area */
1574 if (ohci_init_hcca(ohcip) != DDI_SUCCESS) {
1575
1576 return (DDI_FAILURE);
1577 }
1578 }
1579
1580 /*
1581 * Workaround for ULI1575 chipset. Following OHCI Operational Memory
1582 * Registers are not cleared to their default value on reset.
1583 * Explicitly set the registers to default value.
1584 */
1585 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
1586 ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
1587 Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
1588 Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
1589 Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
1590 Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
1591 Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
1592 Set_OpReg(hcr_frame_interval, HCR_FRAME_INTERVAL_DEFAULT);
1593 Set_OpReg(hcr_periodic_strt, HCR_PERIODIC_START_DEFAULT);
1594 }
1595
1596 /* Set the HcHCCA to the physical address of the HCCA block */
1597 Set_OpReg(hcr_HCCA, (uint_t)ohcip->ohci_hcca_cookie.dmac_address);
1598
1599 /*
1600 * Set HcInterruptEnable to enable all interrupts except Root
1601 * Hub Status change and SOF interrupts.
1602 */
1603 Set_OpReg(hcr_intr_enable, HCR_INTR_SO | HCR_INTR_WDH |
1604 HCR_INTR_RD | HCR_INTR_UE | HCR_INTR_FNO | HCR_INTR_MIE);
1605
1606 /*
1607 * For non-periodic transfers, reserve atleast for one low-speed
1608 * device transaction. According to USB Bandwidth Analysis white
1609 * paper and also as per OHCI Specification 1.0a, section 7.3.5,
1610 * page 123, one low-speed transaction takes 0x628h full speed
1611 * bits (197 bytes), which comes to around 13% of USB frame time.
1612 *
1613 * The periodic transfers will get around 87% of USB frame time.
1614 */
1615 Set_OpReg(hcr_periodic_strt,
1616 ((PERIODIC_XFER_STARTS * BITS_PER_BYTE) - 1));
1617
1618 /* Save the contents of the Frame Interval Registers */
1619 ohcip->ohci_frame_interval = Get_OpReg(hcr_frame_interval);
1620
1621 /*
1622 * Initialize the FSLargestDataPacket value in the frame interval
1623 * register. The controller compares the value of MaxPacketSize to
1624 * this value to see if the entire packet may be sent out before
1625 * the EOF.
1626 */
1627 max_packet = ((((ohcip->ohci_frame_interval -
1628 MAX_OVERHEAD) * 6) / 7) << HCR_FRME_FSMPS_SHFT);
1629
1630 Set_OpReg(hcr_frame_interval,
1631 (max_packet | ohcip->ohci_frame_interval));
1632
1633 /*
1634 * Sometimes the HcFmInterval register in OHCI controller does not
1635 * maintain its value after the first write. This problem is found
1636 * on ULI M1575 South Bridge. To workaround the hardware problem,
1637 * check the value after write and retry if the last write failed.
1638 */
1639 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
1640 ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
1641 ohci_frame_interval = Get_OpReg(hcr_frame_interval);
1642 while ((ohci_frame_interval != (max_packet |
1643 ohcip->ohci_frame_interval))) {
1644 if (retry >= 10) {
1645 USB_DPRINTF_L1(PRINT_MASK_ATTA,
1646 ohcip->ohci_log_hdl, "Failed to program"
1647 " Frame Interval Register.");
1648
1649 return (DDI_FAILURE);
1650 }
1651 retry++;
1652 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1653 "ohci_init_ctlr: Failed to program Frame"
1654 " Interval Register, retry=%d", retry);
1655 Set_OpReg(hcr_frame_interval,
1656 (max_packet | ohcip->ohci_frame_interval));
1657 ohci_frame_interval = Get_OpReg(hcr_frame_interval);
1658 }
1659 }
1660
1661 /* Begin sending SOFs */
1662 curr_control = Get_OpReg(hcr_control);
1663
1664 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1665 "ohci_init_ctlr: curr_control=0x%x", curr_control);
1666
1667 /* Set the state to operational */
1668 curr_control = (curr_control &
1669 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT;
1670
1671 Set_OpReg(hcr_control, curr_control);
1672
1673 ASSERT((Get_OpReg(hcr_control) &
1674 HCR_CONTROL_HCFS) == HCR_CONTROL_OPERAT);
1675
1676 /* Set host controller soft state to operational */
1677 ohcip->ohci_hc_soft_state = OHCI_CTLR_OPERATIONAL_STATE;
1678
1679 /* Get the number of clock ticks to wait */
1680 sof_time_wait = drv_usectohz(OHCI_MAX_SOF_TIMEWAIT * 1000000);
1681
1682 /* Clear ohci_sof_flag indicating waiting for SOF interrupt */
1683 ohcip->ohci_sof_flag = B_FALSE;
1684
1685 /* Enable the SOF interrupt */
1686 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
1687
1688 ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF);
1689
1690 (void) cv_reltimedwait(&ohcip->ohci_SOF_cv,
1691 &ohcip->ohci_int_mutex, sof_time_wait, TR_CLOCK_TICK);
1692
1693 /* Wait for the SOF or timeout event */
1694 if (ohcip->ohci_sof_flag == B_FALSE) {
1695
1696 /* Set host controller soft state to error */
1697 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE;
1698
1699 USB_DPRINTF_L0(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1700 "No SOF interrupts have been received, this USB OHCI host"
1701 "controller is unusable");
1702 return (DDI_FAILURE);
1703 }
1704
1705 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1706 "ohci_init_ctlr: SOF's have started");
1707
1708 return (DDI_SUCCESS);
1709 }
1710
1711
1712 /*
1713 * ohci_init_hcca:
1714 *
1715 * Allocate the system memory and initialize Host Controller Communication
1716 * Area (HCCA). The HCCA structure must be aligned to a 256-byte boundary.
1717 */
1718 static int
ohci_init_hcca(ohci_state_t * ohcip)1719 ohci_init_hcca(ohci_state_t *ohcip)
1720 {
1721 ddi_device_acc_attr_t dev_attr;
1722 size_t real_length;
1723 uint_t mask, ccount;
1724 int result;
1725 uintptr_t addr;
1726
1727 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
1728
1729 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_init_hcca:");
1730
1731 /* The host controller will be little endian */
1732 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1733 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
1734 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1735
1736 /* Byte alignment to HCCA alignment */
1737 ohcip->ohci_dma_attr.dma_attr_align = OHCI_DMA_ATTR_HCCA_ALIGNMENT;
1738
1739 /* Create space for the HCCA block */
1740 if (ddi_dma_alloc_handle(ohcip->ohci_dip, &ohcip->ohci_dma_attr,
1741 DDI_DMA_SLEEP,
1742 0,
1743 &ohcip->ohci_hcca_dma_handle)
1744 != DDI_SUCCESS) {
1745
1746 return (DDI_FAILURE);
1747 }
1748
1749 if (ddi_dma_mem_alloc(ohcip->ohci_hcca_dma_handle,
1750 2 * sizeof (ohci_hcca_t),
1751 &dev_attr,
1752 DDI_DMA_CONSISTENT,
1753 DDI_DMA_SLEEP,
1754 0,
1755 (caddr_t *)&ohcip->ohci_hccap,
1756 &real_length,
1757 &ohcip->ohci_hcca_mem_handle)) {
1758
1759 return (DDI_FAILURE);
1760 }
1761
1762 bzero((void *)ohcip->ohci_hccap, real_length);
1763
1764 /* Figure out the alignment requirements */
1765 Set_OpReg(hcr_HCCA, 0xFFFFFFFF);
1766
1767 /*
1768 * Read the hcr_HCCA register until
1769 * contenets are non-zero.
1770 */
1771 mask = Get_OpReg(hcr_HCCA);
1772
1773 mutex_exit(&ohcip->ohci_int_mutex);
1774 while (mask == 0) {
1775 delay(drv_usectohz(OHCI_TIMEWAIT));
1776 mask = Get_OpReg(hcr_HCCA);
1777 }
1778 mutex_enter(&ohcip->ohci_int_mutex);
1779
1780 ASSERT(mask != 0);
1781
1782 addr = (uintptr_t)ohcip->ohci_hccap;
1783
1784 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1785 "ohci_init_hcca: addr=0x%lx, mask=0x%x", addr, mask);
1786
1787 while (addr & (~mask)) {
1788 addr++;
1789 }
1790
1791 ohcip->ohci_hccap = (ohci_hcca_t *)addr;
1792
1793 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1794 "ohci_init_hcca: Real length %lu", real_length);
1795
1796 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1797 "ohci_init_hcca: virtual hcca 0x%p", (void *)ohcip->ohci_hccap);
1798
1799 /* Map the whole HCCA into the I/O address space */
1800 result = ddi_dma_addr_bind_handle(ohcip->ohci_hcca_dma_handle,
1801 NULL,
1802 (caddr_t)ohcip->ohci_hccap,
1803 real_length,
1804 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
1805 DDI_DMA_SLEEP, NULL,
1806 &ohcip->ohci_hcca_cookie,
1807 &ccount);
1808
1809 if (result == DDI_DMA_MAPPED) {
1810 /* The cookie count should be 1 */
1811 if (ccount != 1) {
1812 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1813 "ohci_init_hcca: More than 1 cookie");
1814
1815 return (DDI_FAILURE);
1816 }
1817 } else {
1818 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
1819
1820 return (DDI_FAILURE);
1821 }
1822
1823 /*
1824 * DMA addresses for HCCA are bound
1825 */
1826 ohcip->ohci_dma_addr_bind_flag |= OHCI_HCCA_DMA_BOUND;
1827
1828 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1829 "ohci_init_hcca: physical 0x%p",
1830 (void *)(uintptr_t)ohcip->ohci_hcca_cookie.dmac_address);
1831
1832 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1833 "ohci_init_hcca: size %lu", ohcip->ohci_hcca_cookie.dmac_size);
1834
1835 /* Initialize the interrupt lists */
1836 ohci_build_interrupt_lattice(ohcip);
1837
1838 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1839 "ohci_init_hcca: End");
1840
1841 return (DDI_SUCCESS);
1842 }
1843
1844
1845 /*
1846 * ohci_build_interrupt_lattice:
1847 *
1848 * Construct the interrupt lattice tree using static Endpoint Descriptors
1849 * (ED). This interrupt lattice tree will have total of 32 interrupt ED
1850 * lists and the Host Controller (HC) processes one interrupt ED list in
1851 * every frame. The lower five bits of the current frame number indexes
1852 * into an array of 32 interrupt Endpoint Descriptor lists found in the
1853 * HCCA.
1854 */
1855 static void
ohci_build_interrupt_lattice(ohci_state_t * ohcip)1856 ohci_build_interrupt_lattice(ohci_state_t *ohcip)
1857 {
1858 ohci_ed_t *list_array = ohcip->ohci_ed_pool_addr;
1859 int half_list = NUM_INTR_ED_LISTS / 2;
1860 ohci_hcca_t *hccap = ohcip->ohci_hccap;
1861 uintptr_t addr;
1862 int i;
1863
1864 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1865 "ohci_build_interrupt_lattice:");
1866
1867 /*
1868 * Reserve the first 31 Endpoint Descriptor (ED) structures
1869 * in the pool as static endpoints & these are required for
1870 * constructing interrupt lattice tree.
1871 */
1872 for (i = 0; i < NUM_STATIC_NODES; i++) {
1873 Set_ED(list_array[i].hced_ctrl, HC_EPT_sKip);
1874
1875 Set_ED(list_array[i].hced_state, HC_EPT_STATIC);
1876 }
1877
1878 /* Build the interrupt lattice tree */
1879 for (i = 0; i < half_list - 1; i++) {
1880
1881 /*
1882 * The next pointer in the host controller endpoint
1883 * descriptor must contain an iommu address. Calculate
1884 * the offset into the cpu address and add this to the
1885 * starting iommu address.
1886 */
1887 addr = ohci_ed_cpu_to_iommu(ohcip, (ohci_ed_t *)&list_array[i]);
1888
1889 Set_ED(list_array[2*i + 1].hced_next, addr);
1890 Set_ED(list_array[2*i + 2].hced_next, addr);
1891 }
1892
1893 /*
1894 * Initialize the interrupt list in the HCCA so that it points
1895 * to the bottom of the tree.
1896 */
1897 for (i = 0; i < half_list; i++) {
1898 addr = ohci_ed_cpu_to_iommu(ohcip,
1899 (ohci_ed_t *)&list_array[half_list - 1 + ohci_index[i]]);
1900
1901 ASSERT(Get_ED(list_array[half_list - 1 +
1902 ohci_index[i]].hced_ctrl));
1903
1904 ASSERT(addr != 0);
1905
1906 Set_HCCA(hccap->HccaIntTble[i], addr);
1907 Set_HCCA(hccap->HccaIntTble[i + half_list], addr);
1908 }
1909 }
1910
1911
1912 /*
1913 * ohci_take_control:
1914 *
1915 * Take control of the host controller. OpenHCI allows for optional support
1916 * of legacy devices through the use of System Management Mode software and
1917 * system Management interrupt hardware. See section 5.1.1.3 of the OpenHCI
1918 * spec for more details.
1919 */
1920 static int
ohci_take_control(ohci_state_t * ohcip)1921 ohci_take_control(ohci_state_t *ohcip)
1922 {
1923 #if defined(__x86)
1924 uint32_t hcr_control_val;
1925 uint32_t hcr_cmd_status_val;
1926 int wait;
1927 #endif /* __x86 */
1928
1929 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1930 "ohci_take_control:");
1931
1932 #if defined(__x86)
1933 /*
1934 * On x86, we must tell the BIOS we want the controller,
1935 * and wait for it to respond that we can have it.
1936 */
1937 hcr_control_val = Get_OpReg(hcr_control);
1938 if ((hcr_control_val & HCR_CONTROL_IR) == 0) {
1939 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1940 "ohci_take_control: InterruptRouting off\n");
1941
1942 return (DDI_SUCCESS);
1943 }
1944
1945 /* attempt the OwnershipChange request */
1946 hcr_cmd_status_val = Get_OpReg(hcr_cmd_status);
1947 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1948 "ohci_take_control: hcr_cmd_status: 0x%x\n",
1949 hcr_cmd_status_val);
1950 hcr_cmd_status_val |= HCR_STATUS_OCR;
1951
1952 Set_OpReg(hcr_cmd_status, hcr_cmd_status_val);
1953
1954
1955 mutex_exit(&ohcip->ohci_int_mutex);
1956 /* now wait for 5 seconds for InterruptRouting to go away */
1957 for (wait = 0; wait < 5000; wait++) {
1958 if ((Get_OpReg(hcr_control) & HCR_CONTROL_IR) == 0)
1959 break;
1960 delay(drv_usectohz(1000));
1961 }
1962 mutex_enter(&ohcip->ohci_int_mutex);
1963
1964 if (wait >= 5000) {
1965 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1966 "ohci_take_control: couldn't take control from BIOS\n");
1967
1968 return (DDI_FAILURE);
1969 }
1970 #else /* __x86 */
1971 /*
1972 * On Sparc, there won't be special System Management Mode
1973 * hardware for legacy devices, while the x86 platforms may
1974 * have to deal with this. This function may be platform
1975 * specific.
1976 *
1977 * The interrupt routing bit should not be set.
1978 */
1979 if (Get_OpReg(hcr_control) & HCR_CONTROL_IR) {
1980 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1981 "ohci_take_control: Routing bit set");
1982
1983 return (DDI_FAILURE);
1984 }
1985 #endif /* __x86 */
1986
1987 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
1988 "ohci_take_control: End");
1989
1990 return (DDI_SUCCESS);
1991 }
1992
1993 /*
1994 * ohci_pm_support:
1995 * always return success since PM has been quite reliable on ohci
1996 */
1997 /*ARGSUSED*/
1998 int
ohci_hcdi_pm_support(dev_info_t * dip)1999 ohci_hcdi_pm_support(dev_info_t *dip)
2000 {
2001 return (USB_SUCCESS);
2002 }
2003
2004 /*
2005 * ohci_alloc_hcdi_ops:
2006 *
2007 * The HCDI interfaces or entry points are the software interfaces used by
2008 * the Universal Serial Bus Driver (USBA) to access the services of the
2009 * Host Controller Driver (HCD). During HCD initialization, inform USBA
2010 * about all available HCDI interfaces or entry points.
2011 */
2012 static usba_hcdi_ops_t *
ohci_alloc_hcdi_ops(ohci_state_t * ohcip)2013 ohci_alloc_hcdi_ops(ohci_state_t *ohcip)
2014 {
2015 usba_hcdi_ops_t *usba_hcdi_ops;
2016
2017 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2018 "ohci_alloc_hcdi_ops:");
2019
2020 usba_hcdi_ops = usba_alloc_hcdi_ops();
2021
2022 usba_hcdi_ops->usba_hcdi_ops_version = HCDI_OPS_VERSION;
2023
2024 usba_hcdi_ops->usba_hcdi_pm_support = ohci_hcdi_pm_support;
2025 usba_hcdi_ops->usba_hcdi_pipe_open = ohci_hcdi_pipe_open;
2026 usba_hcdi_ops->usba_hcdi_pipe_close = ohci_hcdi_pipe_close;
2027
2028 usba_hcdi_ops->usba_hcdi_pipe_reset = ohci_hcdi_pipe_reset;
2029 usba_hcdi_ops->usba_hcdi_pipe_reset_data_toggle =
2030 ohci_hcdi_pipe_reset_data_toggle;
2031
2032 usba_hcdi_ops->usba_hcdi_pipe_ctrl_xfer = ohci_hcdi_pipe_ctrl_xfer;
2033 usba_hcdi_ops->usba_hcdi_pipe_bulk_xfer = ohci_hcdi_pipe_bulk_xfer;
2034 usba_hcdi_ops->usba_hcdi_pipe_intr_xfer = ohci_hcdi_pipe_intr_xfer;
2035 usba_hcdi_ops->usba_hcdi_pipe_isoc_xfer = ohci_hcdi_pipe_isoc_xfer;
2036
2037 usba_hcdi_ops->usba_hcdi_bulk_transfer_size =
2038 ohci_hcdi_bulk_transfer_size;
2039
2040 usba_hcdi_ops->usba_hcdi_pipe_stop_intr_polling =
2041 ohci_hcdi_pipe_stop_intr_polling;
2042 usba_hcdi_ops->usba_hcdi_pipe_stop_isoc_polling =
2043 ohci_hcdi_pipe_stop_isoc_polling;
2044
2045 usba_hcdi_ops->usba_hcdi_get_current_frame_number =
2046 ohci_hcdi_get_current_frame_number;
2047 usba_hcdi_ops->usba_hcdi_get_max_isoc_pkts =
2048 ohci_hcdi_get_max_isoc_pkts;
2049 usba_hcdi_ops->usba_hcdi_console_input_init =
2050 ohci_hcdi_polled_input_init;
2051 usba_hcdi_ops->usba_hcdi_console_input_enter =
2052 ohci_hcdi_polled_input_enter;
2053 usba_hcdi_ops->usba_hcdi_console_read = ohci_hcdi_polled_read;
2054 usba_hcdi_ops->usba_hcdi_console_input_exit =
2055 ohci_hcdi_polled_input_exit;
2056 usba_hcdi_ops->usba_hcdi_console_input_fini =
2057 ohci_hcdi_polled_input_fini;
2058
2059 usba_hcdi_ops->usba_hcdi_console_output_init =
2060 ohci_hcdi_polled_output_init;
2061 usba_hcdi_ops->usba_hcdi_console_output_enter =
2062 ohci_hcdi_polled_output_enter;
2063 usba_hcdi_ops->usba_hcdi_console_write = ohci_hcdi_polled_write;
2064 usba_hcdi_ops->usba_hcdi_console_output_exit =
2065 ohci_hcdi_polled_output_exit;
2066 usba_hcdi_ops->usba_hcdi_console_output_fini =
2067 ohci_hcdi_polled_output_fini;
2068
2069 return (usba_hcdi_ops);
2070 }
2071
2072
2073 /*
2074 * Host Controller Driver (HCD) deinitialization functions
2075 */
2076
2077 /*
2078 * ohci_cleanup:
2079 *
2080 * Cleanup on attach failure or detach
2081 */
2082 static int
ohci_cleanup(ohci_state_t * ohcip)2083 ohci_cleanup(ohci_state_t *ohcip)
2084 {
2085 ohci_trans_wrapper_t *tw;
2086 ohci_pipe_private_t *pp;
2087 ohci_td_t *td;
2088 int i, state, rval;
2089 int flags = ohcip->ohci_flags;
2090
2091 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl, "ohci_cleanup:");
2092
2093 if (flags & OHCI_RHREG) {
2094 /* Unload the root hub driver */
2095 if (ohci_unload_root_hub_driver(ohcip) != USB_SUCCESS) {
2096
2097 return (DDI_FAILURE);
2098 }
2099 }
2100
2101 if (flags & OHCI_USBAREG) {
2102 /* Unregister this HCD instance with USBA */
2103 usba_hcdi_unregister(ohcip->ohci_dip);
2104 }
2105
2106 if (flags & OHCI_INTR) {
2107
2108 mutex_enter(&ohcip->ohci_int_mutex);
2109
2110 /* Disable all HC ED list processing */
2111 Set_OpReg(hcr_control,
2112 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
2113 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
2114
2115 /* Disable all HC interrupts */
2116 Set_OpReg(hcr_intr_disable,
2117 (HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE));
2118
2119 /* Wait for the next SOF */
2120 (void) ohci_wait_for_sof(ohcip);
2121
2122 /* Disable Master and SOF interrupts */
2123 Set_OpReg(hcr_intr_disable, (HCR_INTR_MIE | HCR_INTR_SOF));
2124
2125 /* Set the Host Controller Functional State to Reset */
2126 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
2127 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESET));
2128
2129 mutex_exit(&ohcip->ohci_int_mutex);
2130 /* Wait for sometime */
2131 delay(drv_usectohz(OHCI_TIMEWAIT));
2132 mutex_enter(&ohcip->ohci_int_mutex);
2133
2134 /*
2135 * Workaround for ULI1575 chipset. Following OHCI Operational
2136 * Memory Registers are not cleared to their default value
2137 * on reset. Explicitly set the registers to default value.
2138 */
2139 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
2140 ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
2141 Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
2142 Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
2143 Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
2144 Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
2145 Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
2146 Set_OpReg(hcr_frame_interval,
2147 HCR_FRAME_INTERVAL_DEFAULT);
2148 Set_OpReg(hcr_periodic_strt,
2149 HCR_PERIODIC_START_DEFAULT);
2150 }
2151
2152 mutex_exit(&ohcip->ohci_int_mutex);
2153
2154 ohci_rem_intrs(ohcip);
2155 }
2156
2157 /* Unmap the OHCI registers */
2158 if (ohcip->ohci_regs_handle) {
2159 /* Reset the host controller */
2160 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
2161
2162 ddi_regs_map_free(&ohcip->ohci_regs_handle);
2163 }
2164
2165 if (ohcip->ohci_config_handle) {
2166 pci_config_teardown(&ohcip->ohci_config_handle);
2167 }
2168
2169 /* Free all the buffers */
2170 if (ohcip->ohci_td_pool_addr && ohcip->ohci_td_pool_mem_handle) {
2171 for (i = 0; i < ohci_td_pool_size; i ++) {
2172 td = &ohcip->ohci_td_pool_addr[i];
2173 state = Get_TD(ohcip->ohci_td_pool_addr[i].hctd_state);
2174
2175 if ((state != HC_TD_FREE) && (state != HC_TD_DUMMY) &&
2176 (td->hctd_trans_wrapper)) {
2177
2178 mutex_enter(&ohcip->ohci_int_mutex);
2179
2180 tw = (ohci_trans_wrapper_t *)
2181 OHCI_LOOKUP_ID((uint32_t)
2182 Get_TD(td->hctd_trans_wrapper));
2183
2184 /* Obtain the pipe private structure */
2185 pp = tw->tw_pipe_private;
2186
2187 /* Stop the the transfer timer */
2188 ohci_stop_xfer_timer(ohcip, tw,
2189 OHCI_REMOVE_XFER_ALWAYS);
2190
2191 ohci_deallocate_tw_resources(ohcip, pp, tw);
2192
2193 mutex_exit(&ohcip->ohci_int_mutex);
2194 }
2195 }
2196
2197 /*
2198 * If OHCI_TD_POOL_BOUND flag is set, then unbind
2199 * the handle for TD pools.
2200 */
2201 if ((ohcip->ohci_dma_addr_bind_flag &
2202 OHCI_TD_POOL_BOUND) == OHCI_TD_POOL_BOUND) {
2203
2204 rval = ddi_dma_unbind_handle(
2205 ohcip->ohci_td_pool_dma_handle);
2206
2207 ASSERT(rval == DDI_SUCCESS);
2208 }
2209 ddi_dma_mem_free(&ohcip->ohci_td_pool_mem_handle);
2210 }
2211
2212 /* Free the TD pool */
2213 if (ohcip->ohci_td_pool_dma_handle) {
2214 ddi_dma_free_handle(&ohcip->ohci_td_pool_dma_handle);
2215 }
2216
2217 if (ohcip->ohci_ed_pool_addr && ohcip->ohci_ed_pool_mem_handle) {
2218 /*
2219 * If OHCI_ED_POOL_BOUND flag is set, then unbind
2220 * the handle for ED pools.
2221 */
2222 if ((ohcip->ohci_dma_addr_bind_flag &
2223 OHCI_ED_POOL_BOUND) == OHCI_ED_POOL_BOUND) {
2224
2225 rval = ddi_dma_unbind_handle(
2226 ohcip->ohci_ed_pool_dma_handle);
2227
2228 ASSERT(rval == DDI_SUCCESS);
2229 }
2230
2231 ddi_dma_mem_free(&ohcip->ohci_ed_pool_mem_handle);
2232 }
2233
2234 /* Free the ED pool */
2235 if (ohcip->ohci_ed_pool_dma_handle) {
2236 ddi_dma_free_handle(&ohcip->ohci_ed_pool_dma_handle);
2237 }
2238
2239 /* Free the HCCA area */
2240 if (ohcip->ohci_hccap && ohcip->ohci_hcca_mem_handle) {
2241 /*
2242 * If OHCI_HCCA_DMA_BOUND flag is set, then unbind
2243 * the handle for HCCA.
2244 */
2245 if ((ohcip->ohci_dma_addr_bind_flag &
2246 OHCI_HCCA_DMA_BOUND) == OHCI_HCCA_DMA_BOUND) {
2247
2248 rval = ddi_dma_unbind_handle(
2249 ohcip->ohci_hcca_dma_handle);
2250
2251 ASSERT(rval == DDI_SUCCESS);
2252 }
2253
2254 ddi_dma_mem_free(&ohcip->ohci_hcca_mem_handle);
2255 }
2256
2257 if (ohcip->ohci_hcca_dma_handle) {
2258 ddi_dma_free_handle(&ohcip->ohci_hcca_dma_handle);
2259 }
2260
2261 if (flags & OHCI_INTR) {
2262
2263 /* Destroy the mutex */
2264 mutex_destroy(&ohcip->ohci_int_mutex);
2265
2266 /* Destroy the SOF condition varibale */
2267 cv_destroy(&ohcip->ohci_SOF_cv);
2268
2269 /* Destroy the serialize opens and closes semaphore */
2270 sema_destroy(&ohcip->ohci_ocsem);
2271 }
2272
2273 /* clean up kstat structs */
2274 ohci_destroy_stats(ohcip);
2275
2276 /* Free ohci hcdi ops */
2277 if (ohcip->ohci_hcdi_ops) {
2278 usba_free_hcdi_ops(ohcip->ohci_hcdi_ops);
2279 }
2280
2281 if (flags & OHCI_ZALLOC) {
2282
2283 usb_free_log_hdl(ohcip->ohci_log_hdl);
2284
2285 /* Remove all properties that might have been created */
2286 ddi_prop_remove_all(ohcip->ohci_dip);
2287
2288 /* Free the soft state */
2289 ddi_soft_state_free(ohci_statep,
2290 ddi_get_instance(ohcip->ohci_dip));
2291 }
2292
2293 return (DDI_SUCCESS);
2294 }
2295
2296
2297 /*
2298 * ohci_rem_intrs:
2299 *
2300 * Unregister FIXED or MSI interrupts
2301 */
2302 static void
ohci_rem_intrs(ohci_state_t * ohcip)2303 ohci_rem_intrs(ohci_state_t *ohcip)
2304 {
2305 int i;
2306
2307 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2308 "ohci_rem_intrs: interrupt type 0x%x", ohcip->ohci_intr_type);
2309
2310 /* Disable all interrupts */
2311 if (ohcip->ohci_intr_cap & DDI_INTR_FLAG_BLOCK) {
2312 (void) ddi_intr_block_disable(ohcip->ohci_htable,
2313 ohcip->ohci_intr_cnt);
2314 } else {
2315 for (i = 0; i < ohcip->ohci_intr_cnt; i++) {
2316 (void) ddi_intr_disable(ohcip->ohci_htable[i]);
2317 }
2318 }
2319
2320 /* Call ddi_intr_remove_handler() */
2321 for (i = 0; i < ohcip->ohci_intr_cnt; i++) {
2322 (void) ddi_intr_remove_handler(ohcip->ohci_htable[i]);
2323 (void) ddi_intr_free(ohcip->ohci_htable[i]);
2324 }
2325
2326 kmem_free(ohcip->ohci_htable,
2327 ohcip->ohci_intr_cnt * sizeof (ddi_intr_handle_t));
2328 }
2329
2330
2331 /*
2332 * ohci_cpr_suspend
2333 */
2334 static int
ohci_cpr_suspend(ohci_state_t * ohcip)2335 ohci_cpr_suspend(ohci_state_t *ohcip)
2336 {
2337 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2338 "ohci_cpr_suspend:");
2339
2340 /* Call into the root hub and suspend it */
2341 if (usba_hubdi_detach(ohcip->ohci_dip, DDI_SUSPEND) != DDI_SUCCESS) {
2342
2343 return (DDI_FAILURE);
2344 }
2345
2346 /* Only root hub's intr pipe should be open at this time */
2347 mutex_enter(&ohcip->ohci_int_mutex);
2348
2349 if (ohcip->ohci_open_pipe_count > 1) {
2350
2351 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2352 "ohci_cpr_suspend: fails as open pipe count = %d",
2353 ohcip->ohci_open_pipe_count);
2354
2355 mutex_exit(&ohcip->ohci_int_mutex);
2356
2357 return (DDI_FAILURE);
2358 }
2359
2360 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2361 "ohci_cpr_suspend: Disable HC ED list processing");
2362
2363 /* Disable all HC ED list processing */
2364 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
2365 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
2366
2367 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2368 "ohci_cpr_suspend: Disable HC interrupts");
2369
2370 /* Disable all HC interrupts */
2371 Set_OpReg(hcr_intr_disable, ~(HCR_INTR_MIE|HCR_INTR_SOF));
2372
2373 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2374 "ohci_cpr_suspend: Wait for the next SOF");
2375
2376 /* Wait for the next SOF */
2377 if (ohci_wait_for_sof(ohcip) != USB_SUCCESS) {
2378
2379 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2380 "ohci_cpr_suspend: ohci host controller suspend failed");
2381
2382 mutex_exit(&ohcip->ohci_int_mutex);
2383 return (DDI_FAILURE);
2384 }
2385
2386 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2387 "ohci_cpr_suspend: Disable Master interrupt");
2388
2389 /*
2390 * Disable Master interrupt so that ohci driver don't
2391 * get any ohci interrupts.
2392 */
2393 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE);
2394
2395 /*
2396 * Suspend the ohci host controller
2397 * if usb keyboard is not connected.
2398 */
2399 if (ohcip->ohci_polled_kbd_count == 0 || force_ohci_off != 0) {
2400 Set_OpReg(hcr_control, HCR_CONTROL_SUSPD);
2401 }
2402
2403 /* Set host controller soft state to suspend */
2404 ohcip->ohci_hc_soft_state = OHCI_CTLR_SUSPEND_STATE;
2405
2406 mutex_exit(&ohcip->ohci_int_mutex);
2407
2408 return (DDI_SUCCESS);
2409 }
2410
2411
2412 /*
2413 * ohci_cpr_resume
2414 */
2415 static int
ohci_cpr_resume(ohci_state_t * ohcip)2416 ohci_cpr_resume(ohci_state_t *ohcip)
2417 {
2418 mutex_enter(&ohcip->ohci_int_mutex);
2419
2420 USB_DPRINTF_L4(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2421 "ohci_cpr_resume: Restart the controller");
2422
2423 /* Cleanup ohci specific information across cpr */
2424 ohci_cpr_cleanup(ohcip);
2425
2426 /* Restart the controller */
2427 if (ohci_init_ctlr(ohcip) != DDI_SUCCESS) {
2428
2429 USB_DPRINTF_L2(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
2430 "ohci_cpr_resume: ohci host controller resume failed ");
2431
2432 mutex_exit(&ohcip->ohci_int_mutex);
2433
2434 return (DDI_FAILURE);
2435 }
2436
2437 mutex_exit(&ohcip->ohci_int_mutex);
2438
2439 /* Now resume the root hub */
2440 if (usba_hubdi_attach(ohcip->ohci_dip, DDI_RESUME) != DDI_SUCCESS) {
2441
2442 return (DDI_FAILURE);
2443 }
2444
2445 return (DDI_SUCCESS);
2446 }
2447
2448
2449 /*
2450 * HCDI entry points
2451 *
2452 * The Host Controller Driver Interfaces (HCDI) are the software interfaces
2453 * between the Universal Serial Bus Layer (USBA) and the Host Controller
2454 * Driver (HCD). The HCDI interfaces or entry points are subject to change.
2455 */
2456
2457 /*
2458 * ohci_hcdi_pipe_open:
2459 *
2460 * Member of HCD Ops structure and called during client specific pipe open
2461 * Add the pipe to the data structure representing the device and allocate
2462 * bandwidth for the pipe if it is a interrupt or isochronous endpoint.
2463 */
2464 static int
ohci_hcdi_pipe_open(usba_pipe_handle_data_t * ph,usb_flags_t flags)2465 ohci_hcdi_pipe_open(
2466 usba_pipe_handle_data_t *ph,
2467 usb_flags_t flags)
2468 {
2469 ohci_state_t *ohcip = ohci_obtain_state(
2470 ph->p_usba_device->usb_root_hub_dip);
2471 usb_ep_descr_t *epdt = &ph->p_ep;
2472 int rval, error = USB_SUCCESS;
2473 int kmflag = (flags & USB_FLAGS_SLEEP) ?
2474 KM_SLEEP : KM_NOSLEEP;
2475 uint_t node = 0;
2476 ohci_pipe_private_t *pp;
2477
2478 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2479 "ohci_hcdi_pipe_open: addr = 0x%x, ep%d",
2480 ph->p_usba_device->usb_addr,
2481 epdt->bEndpointAddress & USB_EP_NUM_MASK);
2482
2483 sema_p(&ohcip->ohci_ocsem);
2484
2485 mutex_enter(&ohcip->ohci_int_mutex);
2486 rval = ohci_state_is_operational(ohcip);
2487 mutex_exit(&ohcip->ohci_int_mutex);
2488
2489 if (rval != USB_SUCCESS) {
2490 sema_v(&ohcip->ohci_ocsem);
2491
2492 return (rval);
2493 }
2494
2495 /*
2496 * Check and handle root hub pipe open.
2497 */
2498 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2499
2500 mutex_enter(&ohcip->ohci_int_mutex);
2501 error = ohci_handle_root_hub_pipe_open(ph, flags);
2502 mutex_exit(&ohcip->ohci_int_mutex);
2503 sema_v(&ohcip->ohci_ocsem);
2504
2505 return (error);
2506 }
2507
2508 /*
2509 * Opening of other pipes excluding root hub pipe are
2510 * handled below. Check whether pipe is already opened.
2511 */
2512 if (ph->p_hcd_private) {
2513 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2514 "ohci_hcdi_pipe_open: Pipe is already opened");
2515
2516 sema_v(&ohcip->ohci_ocsem);
2517
2518 return (USB_FAILURE);
2519 }
2520
2521 /*
2522 * A portion of the bandwidth is reserved for the non-periodic
2523 * transfers, i.e control and bulk transfers in each of one
2524 * millisecond frame period & usually it will be 10% of frame
2525 * period. Hence there is no need to check for the available
2526 * bandwidth before adding the control or bulk endpoints.
2527 *
2528 * There is a need to check for the available bandwidth before
2529 * adding the periodic transfers, i.e interrupt & isochronous,
2530 * since all these periodic transfers are guaranteed transfers.
2531 * Usually 90% of the total frame time is reserved for periodic
2532 * transfers.
2533 */
2534 if (OHCI_PERIODIC_ENDPOINT(epdt)) {
2535
2536 mutex_enter(&ohcip->ohci_int_mutex);
2537 mutex_enter(&ph->p_mutex);
2538
2539 error = ohci_allocate_bandwidth(ohcip, ph, &node);
2540
2541 if (error != USB_SUCCESS) {
2542
2543 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2544 "ohci_hcdi_pipe_open: Bandwidth allocation failed");
2545
2546 mutex_exit(&ph->p_mutex);
2547 mutex_exit(&ohcip->ohci_int_mutex);
2548 sema_v(&ohcip->ohci_ocsem);
2549
2550 return (error);
2551 }
2552
2553 mutex_exit(&ph->p_mutex);
2554 mutex_exit(&ohcip->ohci_int_mutex);
2555 }
2556
2557 /* Create the HCD pipe private structure */
2558 pp = kmem_zalloc(sizeof (ohci_pipe_private_t), kmflag);
2559
2560 /*
2561 * Return failure if ohci pipe private
2562 * structure allocation fails.
2563 */
2564 if (pp == NULL) {
2565
2566 mutex_enter(&ohcip->ohci_int_mutex);
2567
2568 /* Deallocate bandwidth */
2569 if (OHCI_PERIODIC_ENDPOINT(epdt)) {
2570
2571 mutex_enter(&ph->p_mutex);
2572 ohci_deallocate_bandwidth(ohcip, ph);
2573 mutex_exit(&ph->p_mutex);
2574 }
2575
2576 mutex_exit(&ohcip->ohci_int_mutex);
2577 sema_v(&ohcip->ohci_ocsem);
2578
2579 return (USB_NO_RESOURCES);
2580 }
2581
2582 mutex_enter(&ohcip->ohci_int_mutex);
2583
2584 /* Store the node in the interrupt lattice */
2585 pp->pp_node = node;
2586
2587 /* Create prototype for xfer completion condition variable */
2588 cv_init(&pp->pp_xfer_cmpl_cv, NULL, CV_DRIVER, NULL);
2589
2590 /* Set the state of pipe as idle */
2591 pp->pp_state = OHCI_PIPE_STATE_IDLE;
2592
2593 /* Store a pointer to the pipe handle */
2594 pp->pp_pipe_handle = ph;
2595
2596 mutex_enter(&ph->p_mutex);
2597
2598 /* Store the pointer in the pipe handle */
2599 ph->p_hcd_private = (usb_opaque_t)pp;
2600
2601 /* Store a copy of the pipe policy */
2602 bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t));
2603
2604 mutex_exit(&ph->p_mutex);
2605
2606 /* Allocate the host controller endpoint descriptor */
2607 pp->pp_ept = ohci_alloc_hc_ed(ohcip, ph);
2608
2609 if (pp->pp_ept == NULL) {
2610 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2611 "ohci_hcdi_pipe_open: ED allocation failed");
2612
2613 mutex_enter(&ph->p_mutex);
2614
2615 /* Deallocate bandwidth */
2616 if (OHCI_PERIODIC_ENDPOINT(epdt)) {
2617
2618 ohci_deallocate_bandwidth(ohcip, ph);
2619 }
2620
2621 /* Destroy the xfer completion condition varibale */
2622 cv_destroy(&pp->pp_xfer_cmpl_cv);
2623
2624 /*
2625 * Deallocate the hcd private portion
2626 * of the pipe handle.
2627 */
2628 kmem_free(ph->p_hcd_private, sizeof (ohci_pipe_private_t));
2629
2630 /*
2631 * Set the private structure in the
2632 * pipe handle equal to NULL.
2633 */
2634 ph->p_hcd_private = NULL;
2635 mutex_exit(&ph->p_mutex);
2636
2637 mutex_exit(&ohcip->ohci_int_mutex);
2638 sema_v(&ohcip->ohci_ocsem);
2639
2640 return (USB_NO_RESOURCES);
2641 }
2642
2643 /* Restore the data toggle information */
2644 ohci_restore_data_toggle(ohcip, ph);
2645
2646 /*
2647 * Insert the endpoint onto the host controller's
2648 * appropriate endpoint list. The host controller
2649 * will not schedule this endpoint and will not have
2650 * any TD's to process.
2651 */
2652 ohci_insert_ed(ohcip, ph);
2653
2654 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2655 "ohci_hcdi_pipe_open: ph = 0x%p", (void *)ph);
2656
2657 ohcip->ohci_open_pipe_count++;
2658
2659 mutex_exit(&ohcip->ohci_int_mutex);
2660
2661 sema_v(&ohcip->ohci_ocsem);
2662
2663 return (USB_SUCCESS);
2664 }
2665
2666
2667 /*
2668 * ohci_hcdi_pipe_close:
2669 *
2670 * Member of HCD Ops structure and called during the client specific pipe
2671 * close. Remove the pipe and the data structure representing the device.
2672 * Deallocate bandwidth for the pipe if it is a interrupt or isochronous
2673 * endpoint.
2674 */
2675 /* ARGSUSED */
2676 static int
ohci_hcdi_pipe_close(usba_pipe_handle_data_t * ph,usb_flags_t flags)2677 ohci_hcdi_pipe_close(
2678 usba_pipe_handle_data_t *ph,
2679 usb_flags_t flags)
2680 {
2681 ohci_state_t *ohcip = ohci_obtain_state(
2682 ph->p_usba_device->usb_root_hub_dip);
2683 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2684 usb_ep_descr_t *eptd = &ph->p_ep;
2685 int error = USB_SUCCESS;
2686
2687 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2688 "ohci_hcdi_pipe_close: addr = 0x%x, ep%d",
2689 ph->p_usba_device->usb_addr,
2690 eptd->bEndpointAddress & USB_EP_NUM_MASK);
2691
2692 sema_p(&ohcip->ohci_ocsem);
2693
2694 /* Check and handle root hub pipe close */
2695 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2696
2697 mutex_enter(&ohcip->ohci_int_mutex);
2698 error = ohci_handle_root_hub_pipe_close(ph);
2699 mutex_exit(&ohcip->ohci_int_mutex);
2700 sema_v(&ohcip->ohci_ocsem);
2701
2702 return (error);
2703 }
2704
2705 ASSERT(ph->p_hcd_private != NULL);
2706
2707 mutex_enter(&ohcip->ohci_int_mutex);
2708
2709 /* Set pipe state to pipe close */
2710 pp->pp_state = OHCI_PIPE_STATE_CLOSE;
2711
2712 ohci_pipe_cleanup(ohcip, ph);
2713
2714 /*
2715 * Remove the endoint descriptor from Host
2716 * Controller's appropriate endpoint list.
2717 */
2718 ohci_remove_ed(ohcip, pp);
2719
2720 /* Deallocate bandwidth */
2721 if (OHCI_PERIODIC_ENDPOINT(eptd)) {
2722
2723 mutex_enter(&ph->p_mutex);
2724 ohci_deallocate_bandwidth(ohcip, ph);
2725 mutex_exit(&ph->p_mutex);
2726 }
2727
2728 mutex_enter(&ph->p_mutex);
2729
2730 /* Destroy the xfer completion condition varibale */
2731 cv_destroy(&pp->pp_xfer_cmpl_cv);
2732
2733 /*
2734 * Deallocate the hcd private portion
2735 * of the pipe handle.
2736 */
2737 kmem_free(ph->p_hcd_private, sizeof (ohci_pipe_private_t));
2738 ph->p_hcd_private = NULL;
2739
2740 mutex_exit(&ph->p_mutex);
2741
2742 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2743 "ohci_hcdi_pipe_close: ph = 0x%p", (void *)ph);
2744
2745 ohcip->ohci_open_pipe_count--;
2746
2747 mutex_exit(&ohcip->ohci_int_mutex);
2748 sema_v(&ohcip->ohci_ocsem);
2749
2750 return (error);
2751 }
2752
2753
2754 /*
2755 * ohci_hcdi_pipe_reset:
2756 */
2757 /* ARGSUSED */
2758 static int
ohci_hcdi_pipe_reset(usba_pipe_handle_data_t * ph,usb_flags_t usb_flags)2759 ohci_hcdi_pipe_reset(
2760 usba_pipe_handle_data_t *ph,
2761 usb_flags_t usb_flags)
2762 {
2763 ohci_state_t *ohcip = ohci_obtain_state(
2764 ph->p_usba_device->usb_root_hub_dip);
2765 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2766 int error = USB_SUCCESS;
2767
2768 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2769 "ohci_hcdi_pipe_reset: ph = 0x%p ", (void *)ph);
2770
2771 /*
2772 * Check and handle root hub pipe reset.
2773 */
2774 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2775
2776 error = ohci_handle_root_hub_pipe_reset(ph, usb_flags);
2777 return (error);
2778 }
2779
2780 mutex_enter(&ohcip->ohci_int_mutex);
2781
2782 /* Set pipe state to pipe reset */
2783 pp->pp_state = OHCI_PIPE_STATE_RESET;
2784
2785 ohci_pipe_cleanup(ohcip, ph);
2786
2787 mutex_exit(&ohcip->ohci_int_mutex);
2788
2789 return (error);
2790 }
2791
2792 /*
2793 * ohci_hcdi_pipe_reset_data_toggle:
2794 */
2795 void
ohci_hcdi_pipe_reset_data_toggle(usba_pipe_handle_data_t * ph)2796 ohci_hcdi_pipe_reset_data_toggle(
2797 usba_pipe_handle_data_t *ph)
2798 {
2799 ohci_state_t *ohcip = ohci_obtain_state(
2800 ph->p_usba_device->usb_root_hub_dip);
2801 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2802
2803 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2804 "ohci_hcdi_pipe_reset_data_toggle:");
2805
2806 mutex_enter(&ohcip->ohci_int_mutex);
2807
2808 mutex_enter(&ph->p_mutex);
2809 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress,
2810 DATA0);
2811 mutex_exit(&ph->p_mutex);
2812
2813 Set_ED(pp->pp_ept->hced_headp,
2814 Get_ED(pp->pp_ept->hced_headp) & (~HC_EPT_Carry));
2815 mutex_exit(&ohcip->ohci_int_mutex);
2816
2817 }
2818
2819 /*
2820 * ohci_hcdi_pipe_ctrl_xfer:
2821 */
2822 static int
ohci_hcdi_pipe_ctrl_xfer(usba_pipe_handle_data_t * ph,usb_ctrl_req_t * ctrl_reqp,usb_flags_t usb_flags)2823 ohci_hcdi_pipe_ctrl_xfer(
2824 usba_pipe_handle_data_t *ph,
2825 usb_ctrl_req_t *ctrl_reqp,
2826 usb_flags_t usb_flags)
2827 {
2828 ohci_state_t *ohcip = ohci_obtain_state(
2829 ph->p_usba_device->usb_root_hub_dip);
2830 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2831 int rval;
2832 int error = USB_SUCCESS;
2833 ohci_trans_wrapper_t *tw;
2834
2835 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2836 "ohci_hcdi_pipe_ctrl_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
2837 (void *)ph, (void *)ctrl_reqp, usb_flags);
2838
2839 mutex_enter(&ohcip->ohci_int_mutex);
2840 rval = ohci_state_is_operational(ohcip);
2841 mutex_exit(&ohcip->ohci_int_mutex);
2842
2843 if (rval != USB_SUCCESS) {
2844
2845 return (rval);
2846 }
2847
2848 /*
2849 * Check and handle root hub control request.
2850 */
2851 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
2852
2853 error = ohci_handle_root_hub_request(ohcip, ph, ctrl_reqp);
2854
2855 return (error);
2856 }
2857
2858 mutex_enter(&ohcip->ohci_int_mutex);
2859
2860 /*
2861 * Check whether pipe is in halted state.
2862 */
2863 if (pp->pp_state == OHCI_PIPE_STATE_ERROR) {
2864
2865 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2866 "ohci_hcdi_pipe_ctrl_xfer:"
2867 "Pipe is in error state, need pipe reset to continue");
2868
2869 mutex_exit(&ohcip->ohci_int_mutex);
2870
2871 return (USB_FAILURE);
2872 }
2873
2874 /* Allocate a transfer wrapper */
2875 if ((tw = ohci_allocate_ctrl_resources(ohcip, pp, ctrl_reqp,
2876 usb_flags)) == NULL) {
2877
2878 error = USB_NO_RESOURCES;
2879 } else {
2880 /* Insert the td's on the endpoint */
2881 ohci_insert_ctrl_req(ohcip, ph, ctrl_reqp, tw, usb_flags);
2882 }
2883
2884 mutex_exit(&ohcip->ohci_int_mutex);
2885
2886 return (error);
2887 }
2888
2889
2890 /*
2891 * ohci_hcdi_bulk_transfer_size:
2892 *
2893 * Return maximum bulk transfer size
2894 */
2895
2896 /* ARGSUSED */
2897 static int
ohci_hcdi_bulk_transfer_size(usba_device_t * usba_device,size_t * size)2898 ohci_hcdi_bulk_transfer_size(
2899 usba_device_t *usba_device,
2900 size_t *size)
2901 {
2902 ohci_state_t *ohcip = ohci_obtain_state(
2903 usba_device->usb_root_hub_dip);
2904 int rval;
2905
2906 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2907 "ohci_hcdi_bulk_transfer_size:");
2908
2909 mutex_enter(&ohcip->ohci_int_mutex);
2910 rval = ohci_state_is_operational(ohcip);
2911 mutex_exit(&ohcip->ohci_int_mutex);
2912
2913 if (rval != USB_SUCCESS) {
2914
2915 return (rval);
2916 }
2917
2918 *size = OHCI_MAX_BULK_XFER_SIZE;
2919
2920 return (USB_SUCCESS);
2921 }
2922
2923
2924 /*
2925 * ohci_hcdi_pipe_bulk_xfer:
2926 */
2927 static int
ohci_hcdi_pipe_bulk_xfer(usba_pipe_handle_data_t * ph,usb_bulk_req_t * bulk_reqp,usb_flags_t usb_flags)2928 ohci_hcdi_pipe_bulk_xfer(
2929 usba_pipe_handle_data_t *ph,
2930 usb_bulk_req_t *bulk_reqp,
2931 usb_flags_t usb_flags)
2932 {
2933 ohci_state_t *ohcip = ohci_obtain_state(
2934 ph->p_usba_device->usb_root_hub_dip);
2935 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
2936 int rval, error = USB_SUCCESS;
2937 ohci_trans_wrapper_t *tw;
2938
2939 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2940 "ohci_hcdi_pipe_bulk_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
2941 (void *)ph, (void *)bulk_reqp, usb_flags);
2942
2943 mutex_enter(&ohcip->ohci_int_mutex);
2944 rval = ohci_state_is_operational(ohcip);
2945
2946 if (rval != USB_SUCCESS) {
2947 mutex_exit(&ohcip->ohci_int_mutex);
2948
2949 return (rval);
2950 }
2951
2952 /*
2953 * Check whether pipe is in halted state.
2954 */
2955 if (pp->pp_state == OHCI_PIPE_STATE_ERROR) {
2956
2957 USB_DPRINTF_L2(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2958 "ohci_hcdi_pipe_bulk_xfer:"
2959 "Pipe is in error state, need pipe reset to continue");
2960
2961 mutex_exit(&ohcip->ohci_int_mutex);
2962
2963 return (USB_FAILURE);
2964 }
2965
2966 /* Allocate a transfer wrapper */
2967 if ((tw = ohci_allocate_bulk_resources(ohcip, pp, bulk_reqp,
2968 usb_flags)) == NULL) {
2969
2970 error = USB_NO_RESOURCES;
2971 } else {
2972 /* Add the TD into the Host Controller's bulk list */
2973 ohci_insert_bulk_req(ohcip, ph, bulk_reqp, tw, usb_flags);
2974 }
2975
2976 mutex_exit(&ohcip->ohci_int_mutex);
2977
2978 return (error);
2979 }
2980
2981
2982 /*
2983 * ohci_hcdi_pipe_intr_xfer:
2984 */
2985 static int
ohci_hcdi_pipe_intr_xfer(usba_pipe_handle_data_t * ph,usb_intr_req_t * intr_reqp,usb_flags_t usb_flags)2986 ohci_hcdi_pipe_intr_xfer(
2987 usba_pipe_handle_data_t *ph,
2988 usb_intr_req_t *intr_reqp,
2989 usb_flags_t usb_flags)
2990 {
2991 ohci_state_t *ohcip = ohci_obtain_state(
2992 ph->p_usba_device->usb_root_hub_dip);
2993 int pipe_dir, rval, error = USB_SUCCESS;
2994 ohci_trans_wrapper_t *tw;
2995
2996 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
2997 "ohci_hcdi_pipe_intr_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
2998 (void *)ph, (void *)intr_reqp, usb_flags);
2999
3000 mutex_enter(&ohcip->ohci_int_mutex);
3001 rval = ohci_state_is_operational(ohcip);
3002
3003 if (rval != USB_SUCCESS) {
3004 mutex_exit(&ohcip->ohci_int_mutex);
3005
3006 return (rval);
3007 }
3008
3009 /* Get the pipe direction */
3010 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
3011
3012 if (pipe_dir == USB_EP_DIR_IN) {
3013 error = ohci_start_periodic_pipe_polling(ohcip, ph,
3014 (usb_opaque_t)intr_reqp, usb_flags);
3015 } else {
3016 /* Allocate transaction resources */
3017 if ((tw = ohci_allocate_intr_resources(ohcip, ph,
3018 intr_reqp, usb_flags)) == NULL) {
3019 error = USB_NO_RESOURCES;
3020 } else {
3021 ohci_insert_intr_req(ohcip,
3022 (ohci_pipe_private_t *)ph->p_hcd_private,
3023 tw, usb_flags);
3024 }
3025 }
3026
3027 mutex_exit(&ohcip->ohci_int_mutex);
3028
3029 return (error);
3030 }
3031
3032
3033 /*
3034 * ohci_hcdi_pipe_stop_intr_polling()
3035 */
3036 static int
ohci_hcdi_pipe_stop_intr_polling(usba_pipe_handle_data_t * ph,usb_flags_t flags)3037 ohci_hcdi_pipe_stop_intr_polling(
3038 usba_pipe_handle_data_t *ph,
3039 usb_flags_t flags)
3040 {
3041 ohci_state_t *ohcip = ohci_obtain_state(
3042 ph->p_usba_device->usb_root_hub_dip);
3043 int error = USB_SUCCESS;
3044
3045 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3046 "ohci_hcdi_pipe_stop_intr_polling: ph = 0x%p fl = 0x%x",
3047 (void *)ph, flags);
3048
3049 mutex_enter(&ohcip->ohci_int_mutex);
3050
3051 error = ohci_stop_periodic_pipe_polling(ohcip, ph, flags);
3052
3053 mutex_exit(&ohcip->ohci_int_mutex);
3054
3055 return (error);
3056 }
3057
3058
3059 /*
3060 * ohci_hcdi_get_current_frame_number:
3061 *
3062 * Get the current usb frame number.
3063 * Return whether the request is handled successfully.
3064 */
3065 static int
ohci_hcdi_get_current_frame_number(usba_device_t * usba_device,usb_frame_number_t * frame_number)3066 ohci_hcdi_get_current_frame_number(
3067 usba_device_t *usba_device,
3068 usb_frame_number_t *frame_number)
3069 {
3070 ohci_state_t *ohcip = ohci_obtain_state(
3071 usba_device->usb_root_hub_dip);
3072 int rval;
3073
3074 ohcip = ohci_obtain_state(usba_device->usb_root_hub_dip);
3075
3076 mutex_enter(&ohcip->ohci_int_mutex);
3077 rval = ohci_state_is_operational(ohcip);
3078
3079 if (rval != USB_SUCCESS) {
3080 mutex_exit(&ohcip->ohci_int_mutex);
3081
3082 return (rval);
3083 }
3084
3085 *frame_number = ohci_get_current_frame_number(ohcip);
3086
3087 mutex_exit(&ohcip->ohci_int_mutex);
3088
3089 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3090 "ohci_hcdi_get_current_frame_number:"
3091 "Current frame number 0x%llx", (unsigned long long)(*frame_number));
3092
3093 return (rval);
3094 }
3095
3096
3097 /*
3098 * ohci_hcdi_get_max_isoc_pkts:
3099 *
3100 * Get maximum isochronous packets per usb isochronous request.
3101 * Return whether the request is handled successfully.
3102 */
3103 static int
ohci_hcdi_get_max_isoc_pkts(usba_device_t * usba_device,uint_t * max_isoc_pkts_per_request)3104 ohci_hcdi_get_max_isoc_pkts(
3105 usba_device_t *usba_device,
3106 uint_t *max_isoc_pkts_per_request)
3107 {
3108 ohci_state_t *ohcip = ohci_obtain_state(
3109 usba_device->usb_root_hub_dip);
3110 int rval;
3111
3112 mutex_enter(&ohcip->ohci_int_mutex);
3113 rval = ohci_state_is_operational(ohcip);
3114 mutex_exit(&ohcip->ohci_int_mutex);
3115
3116 if (rval != USB_SUCCESS) {
3117
3118 return (rval);
3119 }
3120
3121 *max_isoc_pkts_per_request = OHCI_MAX_ISOC_PKTS_PER_XFER;
3122
3123 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3124 "ohci_hcdi_get_max_isoc_pkts: maximum isochronous"
3125 "packets per usb isochronous request = 0x%x",
3126 *max_isoc_pkts_per_request);
3127
3128 return (rval);
3129 }
3130
3131
3132 /*
3133 * ohci_hcdi_pipe_isoc_xfer:
3134 */
3135 static int
ohci_hcdi_pipe_isoc_xfer(usba_pipe_handle_data_t * ph,usb_isoc_req_t * isoc_reqp,usb_flags_t usb_flags)3136 ohci_hcdi_pipe_isoc_xfer(
3137 usba_pipe_handle_data_t *ph,
3138 usb_isoc_req_t *isoc_reqp,
3139 usb_flags_t usb_flags)
3140 {
3141 ohci_state_t *ohcip = ohci_obtain_state(
3142 ph->p_usba_device->usb_root_hub_dip);
3143 int error = USB_SUCCESS;
3144 int pipe_dir, rval;
3145 ohci_trans_wrapper_t *tw;
3146
3147 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3148 "ohci_hcdi_pipe_isoc_xfer: ph = 0x%p reqp = 0x%p flags = 0x%x",
3149 (void *)ph, (void *)isoc_reqp, usb_flags);
3150
3151 mutex_enter(&ohcip->ohci_int_mutex);
3152 rval = ohci_state_is_operational(ohcip);
3153
3154 if (rval != USB_SUCCESS) {
3155 mutex_exit(&ohcip->ohci_int_mutex);
3156
3157 return (rval);
3158 }
3159
3160 /* Get the isochronous pipe direction */
3161 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
3162
3163 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3164 "ohci_hcdi_pipe_isoc_xfer: isoc_reqp = 0x%p, uf = 0x%x",
3165 (void *)isoc_reqp, usb_flags);
3166
3167 if (pipe_dir == USB_EP_DIR_IN) {
3168 error = ohci_start_periodic_pipe_polling(ohcip, ph,
3169 (usb_opaque_t)isoc_reqp, usb_flags);
3170 } else {
3171 /* Allocate transaction resources */
3172 if ((tw = ohci_allocate_isoc_resources(ohcip, ph,
3173 isoc_reqp, usb_flags)) == NULL) {
3174 error = USB_NO_RESOURCES;
3175 } else {
3176 error = ohci_insert_isoc_req(ohcip,
3177 (ohci_pipe_private_t *)ph->p_hcd_private,
3178 tw, usb_flags);
3179 }
3180 }
3181
3182 mutex_exit(&ohcip->ohci_int_mutex);
3183
3184 return (error);
3185 }
3186
3187
3188 /*
3189 * ohci_hcdi_pipe_stop_isoc_polling()
3190 */
3191 static int
ohci_hcdi_pipe_stop_isoc_polling(usba_pipe_handle_data_t * ph,usb_flags_t flags)3192 ohci_hcdi_pipe_stop_isoc_polling(
3193 usba_pipe_handle_data_t *ph,
3194 usb_flags_t flags)
3195 {
3196 ohci_state_t *ohcip = ohci_obtain_state(
3197 ph->p_usba_device->usb_root_hub_dip);
3198 int rval, error = USB_SUCCESS;
3199
3200 USB_DPRINTF_L4(PRINT_MASK_HCDI, ohcip->ohci_log_hdl,
3201 "ohci_hcdi_pipe_stop_isoc_polling: ph = 0x%p fl = 0x%x",
3202 (void *)ph, flags);
3203
3204 mutex_enter(&ohcip->ohci_int_mutex);
3205 rval = ohci_state_is_operational(ohcip);
3206
3207 if (rval != USB_SUCCESS) {
3208 mutex_exit(&ohcip->ohci_int_mutex);
3209 return (rval);
3210 }
3211
3212 error = ohci_stop_periodic_pipe_polling(ohcip, ph, flags);
3213
3214 mutex_exit(&ohcip->ohci_int_mutex);
3215 return (error);
3216 }
3217
3218
3219 /*
3220 * Bandwidth Allocation functions
3221 */
3222
3223 /*
3224 * ohci_allocate_bandwidth:
3225 *
3226 * Figure out whether or not this interval may be supported. Return the index
3227 * into the lattice if it can be supported. Return allocation failure if it
3228 * can not be supported.
3229 *
3230 * The lattice structure looks like this with the bottom leaf actually
3231 * being an array. There is a total of 63 nodes in this tree. The lattice tree
3232 * itself is 0 based, while the bottom leaf array is 0 based. The 0 bucket in
3233 * the bottom leaf array is used to store the smalled allocated bandwidth of all
3234 * the leaves.
3235 *
3236 * 0
3237 * 1 2
3238 * 3 4 5 6
3239 * ...
3240 * (32 33 ... 62 63) <-- last row does not exist in lattice, but an array
3241 * 0 1 2 3 ... 30 31
3242 *
3243 * We keep track of the bandwidth that each leaf uses. First we search for the
3244 * first leaf with the smallest used bandwidth. Based on that leaf we find the
3245 * parent node of that leaf based on the interval time.
3246 *
3247 * From the parent node, we find all the leafs of that subtree and update the
3248 * additional bandwidth needed. In order to balance the load the leaves are not
3249 * executed directly from left to right, but scattered. For a better picture
3250 * refer to Section 3.3.2 in the OpenHCI 1.0 spec, there should be a figure
3251 * showing the Interrupt ED Structure.
3252 */
3253 static int
ohci_allocate_bandwidth(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,uint_t * node)3254 ohci_allocate_bandwidth(
3255 ohci_state_t *ohcip,
3256 usba_pipe_handle_data_t *ph,
3257 uint_t *node)
3258 {
3259 int interval, error, i;
3260 uint_t min, min_index, height;
3261 uint_t leftmost, list, bandwidth;
3262 usb_ep_descr_t *endpoint = &ph->p_ep;
3263
3264 /* This routine is protected by the ohci_int_mutex */
3265 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3266
3267 /*
3268 * Calculate the length in bytes of a transaction on this
3269 * periodic endpoint.
3270 */
3271 mutex_enter(&ph->p_usba_device->usb_mutex);
3272 error = ohci_compute_total_bandwidth(
3273 endpoint, ph->p_usba_device->usb_port_status, &bandwidth);
3274 mutex_exit(&ph->p_usba_device->usb_mutex);
3275
3276 /*
3277 * If length is zero, then, it means endpoint maximum packet
3278 * supported is zero. In that case, return failure without
3279 * allocating any bandwidth.
3280 */
3281 if (error != USB_SUCCESS) {
3282 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3283 "ohci_allocate_bandwidth: Periodic endpoint with "
3284 "zero endpoint maximum packet size is not supported");
3285
3286 return (USB_NOT_SUPPORTED);
3287 }
3288
3289 /*
3290 * If the length in bytes plus the allocated bandwidth exceeds
3291 * the maximum, return bandwidth allocation failure.
3292 */
3293 if ((ohcip->ohci_periodic_minimum_bandwidth + bandwidth) >
3294 (MAX_PERIODIC_BANDWIDTH)) {
3295
3296 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3297 "ohci_allocate_bandwidth: Reached maximum "
3298 "bandwidth value and cannot allocate bandwidth "
3299 "for a given periodic endpoint");
3300
3301 return (USB_NO_BANDWIDTH);
3302 }
3303
3304 /* Adjust polling interval to be a power of 2 */
3305 mutex_enter(&ph->p_usba_device->usb_mutex);
3306 interval = ohci_adjust_polling_interval(ohcip,
3307 endpoint, ph->p_usba_device->usb_port_status);
3308 mutex_exit(&ph->p_usba_device->usb_mutex);
3309
3310 /*
3311 * If this interval can't be supported,
3312 * return allocation failure.
3313 */
3314 if (interval == USB_FAILURE) {
3315
3316 return (USB_FAILURE);
3317 }
3318
3319 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3320 "The new interval is %d", interval);
3321
3322 /* Find the leaf with the smallest allocated bandwidth */
3323 min_index = 0;
3324 min = ohcip->ohci_periodic_bandwidth[0];
3325
3326 for (i = 1; i < NUM_INTR_ED_LISTS; i++) {
3327 if (ohcip->ohci_periodic_bandwidth[i] < min) {
3328 min_index = i;
3329 min = ohcip->ohci_periodic_bandwidth[i];
3330 }
3331 }
3332
3333 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3334 "The leaf %d for minimal bandwidth %d", min_index, min);
3335
3336 /* Adjust min for the lattice */
3337 min_index = min_index + NUM_INTR_ED_LISTS - 1;
3338
3339 /*
3340 * Find the index into the lattice given the
3341 * leaf with the smallest allocated bandwidth.
3342 */
3343 height = ohci_lattice_height(interval);
3344
3345 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3346 "The height is %d", height);
3347
3348 *node = min_index;
3349
3350 for (i = 0; i < height; i++) {
3351 *node = ohci_lattice_parent(*node);
3352 }
3353
3354 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3355 "Real node is %d", *node);
3356
3357 /*
3358 * Find the leftmost leaf in the subtree
3359 * specified by the node.
3360 */
3361 leftmost = ohci_leftmost_leaf(*node, height);
3362
3363 USB_DPRINTF_L4(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3364 "Leftmost %d", leftmost);
3365
3366 for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) {
3367 list = ohci_hcca_leaf_index(leftmost + i);
3368 if ((ohcip->ohci_periodic_bandwidth[list] +
3369 bandwidth) > MAX_PERIODIC_BANDWIDTH) {
3370
3371 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3372 "ohci_allocate_bandwidth: Reached maximum "
3373 "bandwidth value and cannot allocate bandwidth "
3374 "for periodic endpoint");
3375
3376 return (USB_NO_BANDWIDTH);
3377 }
3378 }
3379
3380 /*
3381 * All the leaves for this node must be updated with the bandwidth.
3382 */
3383 for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) {
3384 list = ohci_hcca_leaf_index(leftmost + i);
3385 ohcip->ohci_periodic_bandwidth[list] += bandwidth;
3386 }
3387
3388 /* Find the leaf with the smallest allocated bandwidth */
3389 min_index = 0;
3390 min = ohcip->ohci_periodic_bandwidth[0];
3391
3392 for (i = 1; i < NUM_INTR_ED_LISTS; i++) {
3393 if (ohcip->ohci_periodic_bandwidth[i] < min) {
3394 min_index = i;
3395 min = ohcip->ohci_periodic_bandwidth[i];
3396 }
3397 }
3398
3399 /* Save the minimum for later use */
3400 ohcip->ohci_periodic_minimum_bandwidth = min;
3401
3402 return (USB_SUCCESS);
3403 }
3404
3405
3406 /*
3407 * ohci_deallocate_bandwidth:
3408 *
3409 * Deallocate bandwidth for the given node in the lattice and the length
3410 * of transfer.
3411 */
3412 static void
ohci_deallocate_bandwidth(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)3413 ohci_deallocate_bandwidth(
3414 ohci_state_t *ohcip,
3415 usba_pipe_handle_data_t *ph)
3416 {
3417 uint_t min, node, bandwidth;
3418 uint_t height, leftmost, list;
3419 int i, interval;
3420 usb_ep_descr_t *endpoint = &ph->p_ep;
3421 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
3422
3423 /* This routine is protected by the ohci_int_mutex */
3424 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3425
3426 /* Obtain the length */
3427 mutex_enter(&ph->p_usba_device->usb_mutex);
3428 (void) ohci_compute_total_bandwidth(
3429 endpoint, ph->p_usba_device->usb_port_status, &bandwidth);
3430 mutex_exit(&ph->p_usba_device->usb_mutex);
3431
3432 /* Obtain the node */
3433 node = pp->pp_node;
3434
3435 /* Adjust polling interval to be a power of 2 */
3436 mutex_enter(&ph->p_usba_device->usb_mutex);
3437 interval = ohci_adjust_polling_interval(ohcip,
3438 endpoint, ph->p_usba_device->usb_port_status);
3439 mutex_exit(&ph->p_usba_device->usb_mutex);
3440
3441 /* Find the height in the tree */
3442 height = ohci_lattice_height(interval);
3443
3444 /*
3445 * Find the leftmost leaf in the subtree specified by the node
3446 */
3447 leftmost = ohci_leftmost_leaf(node, height);
3448
3449 /* Delete the bandwith from the appropriate lists */
3450 for (i = 0; i < (NUM_INTR_ED_LISTS/interval); i++) {
3451 list = ohci_hcca_leaf_index(leftmost + i);
3452 ohcip->ohci_periodic_bandwidth[list] -= bandwidth;
3453 }
3454
3455 min = ohcip->ohci_periodic_bandwidth[0];
3456
3457 /* Recompute the minimum */
3458 for (i = 1; i < NUM_INTR_ED_LISTS; i++) {
3459 if (ohcip->ohci_periodic_bandwidth[i] < min) {
3460 min = ohcip->ohci_periodic_bandwidth[i];
3461 }
3462 }
3463
3464 /* Save the minimum for later use */
3465 ohcip->ohci_periodic_minimum_bandwidth = min;
3466 }
3467
3468
3469 /*
3470 * ohci_compute_total_bandwidth:
3471 *
3472 * Given a periodic endpoint (interrupt or isochronous) determine the total
3473 * bandwidth for one transaction. The OpenHCI host controller traverses the
3474 * endpoint descriptor lists on a first-come-first-serve basis. When the HC
3475 * services an endpoint, only a single transaction attempt is made. The HC
3476 * moves to the next Endpoint Descriptor after the first transaction attempt
3477 * rather than finishing the entire Transfer Descriptor. Therefore, when a
3478 * Transfer Descriptor is inserted into the lattice, we will only count the
3479 * number of bytes for one transaction.
3480 *
3481 * The following are the formulas used for calculating bandwidth in terms
3482 * bytes and it is for the single USB full speed and low speed transaction
3483 * respectively. The protocol overheads will be different for each of type
3484 * of USB transfer and all these formulas & protocol overheads are derived
3485 * from the 5.9.3 section of USB Specification & with the help of Bandwidth
3486 * Analysis white paper which is posted on the USB developer forum.
3487 *
3488 * Full-Speed:
3489 * Protocol overhead + ((MaxPacketSize * 7)/6 ) + Host_Delay
3490 *
3491 * Low-Speed:
3492 * Protocol overhead + Hub LS overhead +
3493 * (Low-Speed clock * ((MaxPacketSize * 7)/6 )) + Host_Delay
3494 */
3495 static int
ohci_compute_total_bandwidth(usb_ep_descr_t * endpoint,usb_port_status_t port_status,uint_t * bandwidth)3496 ohci_compute_total_bandwidth(
3497 usb_ep_descr_t *endpoint,
3498 usb_port_status_t port_status,
3499 uint_t *bandwidth)
3500 {
3501 ushort_t maxpacketsize = endpoint->wMaxPacketSize;
3502
3503 /*
3504 * If endpoint maximum packet is zero, then return immediately.
3505 */
3506 if (maxpacketsize == 0) {
3507
3508 return (USB_NOT_SUPPORTED);
3509 }
3510
3511 /* Add Host Controller specific delay to required bandwidth */
3512 *bandwidth = HOST_CONTROLLER_DELAY;
3513
3514 /* Add bit-stuffing overhead */
3515 maxpacketsize = (ushort_t)((maxpacketsize * 7) / 6);
3516
3517 /* Low Speed interrupt transaction */
3518 if (port_status == USBA_LOW_SPEED_DEV) {
3519 /* Low Speed interrupt transaction */
3520 *bandwidth += (LOW_SPEED_PROTO_OVERHEAD +
3521 HUB_LOW_SPEED_PROTO_OVERHEAD +
3522 (LOW_SPEED_CLOCK * maxpacketsize));
3523 } else {
3524 /* Full Speed transaction */
3525 *bandwidth += maxpacketsize;
3526
3527 if ((endpoint->bmAttributes &
3528 USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) {
3529 /* Full Speed interrupt transaction */
3530 *bandwidth += FS_NON_ISOC_PROTO_OVERHEAD;
3531 } else {
3532 /* Isochronous and input transaction */
3533 if ((endpoint->bEndpointAddress &
3534 USB_EP_DIR_MASK) == USB_EP_DIR_IN) {
3535 *bandwidth += FS_ISOC_INPUT_PROTO_OVERHEAD;
3536 } else {
3537 /* Isochronous and output transaction */
3538 *bandwidth += FS_ISOC_OUTPUT_PROTO_OVERHEAD;
3539 }
3540 }
3541 }
3542
3543 return (USB_SUCCESS);
3544 }
3545
3546
3547 /*
3548 * ohci_adjust_polling_interval:
3549 */
3550 static int
ohci_adjust_polling_interval(ohci_state_t * ohcip,usb_ep_descr_t * endpoint,usb_port_status_t port_status)3551 ohci_adjust_polling_interval(
3552 ohci_state_t *ohcip,
3553 usb_ep_descr_t *endpoint,
3554 usb_port_status_t port_status)
3555 {
3556 uint_t interval;
3557 int i = 0;
3558
3559 /*
3560 * Get the polling interval from the endpoint descriptor
3561 */
3562 interval = endpoint->bInterval;
3563
3564 /*
3565 * The bInterval value in the endpoint descriptor can range
3566 * from 1 to 255ms. The interrupt lattice has 32 leaf nodes,
3567 * and the host controller cycles through these nodes every
3568 * 32ms. The longest polling interval that the controller
3569 * supports is 32ms.
3570 */
3571
3572 /*
3573 * Return an error if the polling interval is less than 1ms
3574 * and greater than 255ms
3575 */
3576 if ((interval < MIN_POLL_INTERVAL) ||
3577 (interval > MAX_POLL_INTERVAL)) {
3578
3579 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3580 "ohci_adjust_polling_interval: "
3581 "Endpoint's poll interval must be between %d and %d ms",
3582 MIN_POLL_INTERVAL, MAX_POLL_INTERVAL);
3583
3584 return (USB_FAILURE);
3585 }
3586
3587 /*
3588 * According USB Specifications, a full-speed endpoint can
3589 * specify a desired polling interval 1ms to 255ms and a low
3590 * speed endpoints are limited to specifying only 10ms to
3591 * 255ms. But some old keyboards & mice uses polling interval
3592 * of 8ms. For compatibility purpose, we are using polling
3593 * interval between 8ms & 255ms for low speed endpoints. But
3594 * ohci driver will reject the any low speed endpoints which
3595 * request polling interval less than 8ms.
3596 */
3597 if ((port_status == USBA_LOW_SPEED_DEV) &&
3598 (interval < MIN_LOW_SPEED_POLL_INTERVAL)) {
3599
3600 USB_DPRINTF_L2(PRINT_MASK_BW, ohcip->ohci_log_hdl,
3601 "ohci_adjust_polling_interval: "
3602 "Low speed endpoint's poll interval of %d ms "
3603 "is below threshold. Rounding up to %d ms",
3604 interval, MIN_LOW_SPEED_POLL_INTERVAL);
3605
3606 interval = MIN_LOW_SPEED_POLL_INTERVAL;
3607 }
3608
3609 /*
3610 * If polling interval is greater than 32ms,
3611 * adjust polling interval equal to 32ms.
3612 */
3613 if (interval > NUM_INTR_ED_LISTS) {
3614 interval = NUM_INTR_ED_LISTS;
3615 }
3616
3617 /*
3618 * Find the nearest power of 2 that'sless
3619 * than interval.
3620 */
3621 while ((ohci_pow_2(i)) <= interval) {
3622 i++;
3623 }
3624
3625 return (ohci_pow_2((i - 1)));
3626 }
3627
3628
3629 /*
3630 * ohci_lattice_height:
3631 *
3632 * Given the requested bandwidth, find the height in the tree at which the
3633 * nodes for this bandwidth fall. The height is measured as the number of
3634 * nodes from the leaf to the level specified by bandwidth The root of the
3635 * tree is at height TREE_HEIGHT.
3636 */
3637 static uint_t
ohci_lattice_height(uint_t interval)3638 ohci_lattice_height(uint_t interval)
3639 {
3640 return (TREE_HEIGHT - (ohci_log_2(interval)));
3641 }
3642
3643
3644 /*
3645 * ohci_lattice_parent:
3646 */
3647 static uint_t
ohci_lattice_parent(uint_t node)3648 ohci_lattice_parent(uint_t node)
3649 {
3650 if ((node % 2) == 0) {
3651 return ((node/2) - 1);
3652 } else {
3653 return ((node + 1)/2 - 1);
3654 }
3655 }
3656
3657
3658 /*
3659 * ohci_leftmost_leaf:
3660 *
3661 * Find the leftmost leaf in the subtree specified by the node. Height refers
3662 * to number of nodes from the bottom of the tree to the node, including the
3663 * node.
3664 *
3665 * The formula for a zero based tree is:
3666 * 2^H * Node + 2^H - 1
3667 * The leaf of the tree is an array, convert the number for the array.
3668 * Subtract the size of nodes not in the array
3669 * 2^H * Node + 2^H - 1 - (NUM_INTR_ED_LIST - 1) =
3670 * 2^H * Node + 2^H - NUM_INTR_ED_LIST =
3671 * 2^H * (Node + 1) - NUM_INTR_ED_LIST
3672 * 0
3673 * 1 2
3674 * 0 1 2 3
3675 */
3676 static uint_t
ohci_leftmost_leaf(uint_t node,uint_t height)3677 ohci_leftmost_leaf(
3678 uint_t node,
3679 uint_t height)
3680 {
3681 return ((ohci_pow_2(height) * (node + 1)) - NUM_INTR_ED_LISTS);
3682 }
3683
3684 /*
3685 * ohci_hcca_intr_index:
3686 *
3687 * Given a node in the lattice, find the index for the hcca interrupt table
3688 */
3689 static uint_t
ohci_hcca_intr_index(uint_t node)3690 ohci_hcca_intr_index(uint_t node)
3691 {
3692 /*
3693 * Adjust the node to the array representing
3694 * the bottom of the tree.
3695 */
3696 node = node - NUM_STATIC_NODES;
3697
3698 if ((node % 2) == 0) {
3699 return (ohci_index[node / 2]);
3700 } else {
3701 return (ohci_index[node / 2] + (NUM_INTR_ED_LISTS / 2));
3702 }
3703 }
3704
3705 /*
3706 * ohci_hcca_leaf_index:
3707 *
3708 * Given a node in the bottom leaf array of the lattice, find the index
3709 * for the hcca interrupt table
3710 */
3711 static uint_t
ohci_hcca_leaf_index(uint_t leaf)3712 ohci_hcca_leaf_index(uint_t leaf)
3713 {
3714 if ((leaf % 2) == 0) {
3715 return (ohci_index[leaf / 2]);
3716 } else {
3717 return (ohci_index[leaf / 2] + (NUM_INTR_ED_LISTS / 2));
3718 }
3719 }
3720
3721 /*
3722 * ohci_pow_2:
3723 *
3724 * Compute 2 to the power
3725 */
3726 static uint_t
ohci_pow_2(uint_t x)3727 ohci_pow_2(uint_t x)
3728 {
3729 if (x == 0) {
3730 return (1);
3731 } else {
3732 return (2 << (x - 1));
3733 }
3734 }
3735
3736
3737 /*
3738 * ohci_log_2:
3739 *
3740 * Compute log base 2 of x
3741 */
3742 static uint_t
ohci_log_2(uint_t x)3743 ohci_log_2(uint_t x)
3744 {
3745 int i = 0;
3746
3747 while (x != 1) {
3748 x = x >> 1;
3749 i++;
3750 }
3751
3752 return (i);
3753 }
3754
3755
3756 /*
3757 * Endpoint Descriptor (ED) manipulations functions
3758 */
3759
3760 /*
3761 * ohci_alloc_hc_ed:
3762 * NOTE: This function is also called from POLLED MODE.
3763 *
3764 * Allocate an endpoint descriptor (ED)
3765 */
3766 ohci_ed_t *
ohci_alloc_hc_ed(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)3767 ohci_alloc_hc_ed(
3768 ohci_state_t *ohcip,
3769 usba_pipe_handle_data_t *ph)
3770 {
3771 int i, state;
3772 ohci_ed_t *hc_ed;
3773
3774 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3775 "ohci_alloc_hc_ed: ph = 0x%p", (void *)ph);
3776
3777 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3778
3779 /*
3780 * The first 31 endpoints in the Endpoint Descriptor (ED)
3781 * buffer pool are reserved for building interrupt lattice
3782 * tree. Search for a blank endpoint descriptor in the ED
3783 * buffer pool.
3784 */
3785 for (i = NUM_STATIC_NODES; i < ohci_ed_pool_size; i ++) {
3786 state = Get_ED(ohcip->ohci_ed_pool_addr[i].hced_state);
3787
3788 if (state == HC_EPT_FREE) {
3789 break;
3790 }
3791 }
3792
3793 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3794 "ohci_alloc_hc_ed: Allocated %d", i);
3795
3796 if (i == ohci_ed_pool_size) {
3797 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3798 "ohci_alloc_hc_ed: ED exhausted");
3799
3800 return (NULL);
3801 } else {
3802
3803 hc_ed = &ohcip->ohci_ed_pool_addr[i];
3804
3805 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
3806 "ohci_alloc_hc_ed: Allocated address 0x%p", (void *)hc_ed);
3807
3808 ohci_print_ed(ohcip, hc_ed);
3809
3810 /* Unpack the endpoint descriptor into a control field */
3811 if (ph) {
3812 if ((ohci_initialize_dummy(ohcip,
3813 hc_ed)) == USB_NO_RESOURCES) {
3814 bzero((void *)hc_ed, sizeof (ohci_ed_t));
3815 Set_ED(hc_ed->hced_state, HC_EPT_FREE);
3816 return (NULL);
3817 }
3818
3819 Set_ED(hc_ed->hced_prev, NULL);
3820 Set_ED(hc_ed->hced_next, NULL);
3821
3822 /* Change ED's state Active */
3823 Set_ED(hc_ed->hced_state, HC_EPT_ACTIVE);
3824
3825 Set_ED(hc_ed->hced_ctrl,
3826 ohci_unpack_endpoint(ohcip, ph));
3827 } else {
3828 Set_ED(hc_ed->hced_ctrl, HC_EPT_sKip);
3829
3830 /* Change ED's state Static */
3831 Set_ED(hc_ed->hced_state, HC_EPT_STATIC);
3832 }
3833
3834 return (hc_ed);
3835 }
3836 }
3837
3838
3839 /*
3840 * ohci_unpack_endpoint:
3841 *
3842 * Unpack the information in the pipe handle and create the first byte
3843 * of the Host Controller's (HC) Endpoint Descriptor (ED).
3844 */
3845 static uint_t
ohci_unpack_endpoint(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)3846 ohci_unpack_endpoint(
3847 ohci_state_t *ohcip,
3848 usba_pipe_handle_data_t *ph)
3849 {
3850 usb_ep_descr_t *endpoint = &ph->p_ep;
3851 uint_t maxpacketsize, addr, ctrl = 0;
3852
3853 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3854 "ohci_unpack_endpoint:");
3855
3856 ctrl = ph->p_usba_device->usb_addr;
3857
3858 addr = endpoint->bEndpointAddress;
3859
3860 /* Assign the endpoint's address */
3861 ctrl = ctrl | ((addr & USB_EP_NUM_MASK) << HC_EPT_EP_SHFT);
3862
3863 /*
3864 * Assign the direction. If the endpoint is a control endpoint,
3865 * the direction is assigned by the Transfer Descriptor (TD).
3866 */
3867 if ((endpoint->bmAttributes &
3868 USB_EP_ATTR_MASK) != USB_EP_ATTR_CONTROL) {
3869 if (addr & USB_EP_DIR_MASK) {
3870 /* The direction is IN */
3871 ctrl = ctrl | HC_EPT_DF_IN;
3872 } else {
3873 /* The direction is OUT */
3874 ctrl = ctrl | HC_EPT_DF_OUT;
3875 }
3876 }
3877
3878 /* Assign the speed */
3879 mutex_enter(&ph->p_usba_device->usb_mutex);
3880 if (ph->p_usba_device->usb_port_status == USBA_LOW_SPEED_DEV) {
3881 ctrl = ctrl | HC_EPT_Speed;
3882 }
3883 mutex_exit(&ph->p_usba_device->usb_mutex);
3884
3885 /* Assign the format */
3886 if ((endpoint->bmAttributes &
3887 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
3888 ctrl = ctrl | HC_EPT_Format;
3889 }
3890
3891 maxpacketsize = endpoint->wMaxPacketSize;
3892 maxpacketsize = maxpacketsize << HC_EPT_MAXPKTSZ;
3893 ctrl = ctrl | (maxpacketsize & HC_EPT_MPS);
3894
3895 return (ctrl);
3896 }
3897
3898
3899 /*
3900 * ohci_insert_ed:
3901 *
3902 * Add the Endpoint Descriptor (ED) into the Host Controller's
3903 * (HC) appropriate endpoint list.
3904 */
3905 static void
ohci_insert_ed(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)3906 ohci_insert_ed(
3907 ohci_state_t *ohcip,
3908 usba_pipe_handle_data_t *ph)
3909 {
3910 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
3911
3912 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3913 "ohci_insert_ed:");
3914
3915 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3916
3917 switch (ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) {
3918 case USB_EP_ATTR_CONTROL:
3919 ohci_insert_ctrl_ed(ohcip, pp);
3920 break;
3921 case USB_EP_ATTR_BULK:
3922 ohci_insert_bulk_ed(ohcip, pp);
3923 break;
3924 case USB_EP_ATTR_INTR:
3925 ohci_insert_intr_ed(ohcip, pp);
3926 break;
3927 case USB_EP_ATTR_ISOCH:
3928 ohci_insert_isoc_ed(ohcip, pp);
3929 break;
3930 }
3931 }
3932
3933
3934 /*
3935 * ohci_insert_ctrl_ed:
3936 *
3937 * Insert a control endpoint into the Host Controller's (HC)
3938 * control endpoint list.
3939 */
3940 static void
ohci_insert_ctrl_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)3941 ohci_insert_ctrl_ed(
3942 ohci_state_t *ohcip,
3943 ohci_pipe_private_t *pp)
3944 {
3945 ohci_ed_t *ept = pp->pp_ept;
3946 ohci_ed_t *prev_ept;
3947
3948 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3949 "ohci_insert_ctrl_ed:");
3950
3951 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3952
3953 /* Obtain a ptr to the head of the list */
3954 if (Get_OpReg(hcr_ctrl_head)) {
3955 prev_ept = ohci_ed_iommu_to_cpu(ohcip,
3956 Get_OpReg(hcr_ctrl_head));
3957
3958 /* Set up the backwards pointer */
3959 Set_ED(prev_ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, ept));
3960 }
3961
3962 /* The new endpoint points to the head of the list */
3963 Set_ED(ept->hced_next, Get_OpReg(hcr_ctrl_head));
3964
3965 /* Set the head ptr to the new endpoint */
3966 Set_OpReg(hcr_ctrl_head, ohci_ed_cpu_to_iommu(ohcip, ept));
3967
3968 /*
3969 * Enable Control list processing if control open
3970 * pipe count is zero.
3971 */
3972 if (!ohcip->ohci_open_ctrl_pipe_count) {
3973 /* Start Control list processing */
3974 Set_OpReg(hcr_control,
3975 (Get_OpReg(hcr_control) | HCR_CONTROL_CLE));
3976 }
3977
3978 ohcip->ohci_open_ctrl_pipe_count++;
3979 }
3980
3981
3982 /*
3983 * ohci_insert_bulk_ed:
3984 *
3985 * Insert a bulk endpoint into the Host Controller's (HC) bulk endpoint list.
3986 */
3987 static void
ohci_insert_bulk_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)3988 ohci_insert_bulk_ed(
3989 ohci_state_t *ohcip,
3990 ohci_pipe_private_t *pp)
3991 {
3992 ohci_ed_t *ept = pp->pp_ept;
3993 ohci_ed_t *prev_ept;
3994
3995 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
3996 "ohci_insert_bulk_ed:");
3997
3998 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
3999
4000 /* Obtain a ptr to the head of the Bulk list */
4001 if (Get_OpReg(hcr_bulk_head)) {
4002 prev_ept = ohci_ed_iommu_to_cpu(ohcip,
4003 Get_OpReg(hcr_bulk_head));
4004
4005 /* Set up the backwards pointer */
4006 Set_ED(prev_ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, ept));
4007 }
4008
4009 /* The new endpoint points to the head of the Bulk list */
4010 Set_ED(ept->hced_next, Get_OpReg(hcr_bulk_head));
4011
4012 /* Set the Bulk head ptr to the new endpoint */
4013 Set_OpReg(hcr_bulk_head, ohci_ed_cpu_to_iommu(ohcip, ept));
4014
4015 /*
4016 * Enable Bulk list processing if bulk open pipe
4017 * count is zero.
4018 */
4019 if (!ohcip->ohci_open_bulk_pipe_count) {
4020 /* Start Bulk list processing */
4021 Set_OpReg(hcr_control,
4022 (Get_OpReg(hcr_control) | HCR_CONTROL_BLE));
4023 }
4024
4025 ohcip->ohci_open_bulk_pipe_count++;
4026 }
4027
4028
4029 /*
4030 * ohci_insert_intr_ed:
4031 *
4032 * Insert a interrupt endpoint into the Host Controller's (HC) interrupt
4033 * lattice tree.
4034 */
4035 static void
ohci_insert_intr_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)4036 ohci_insert_intr_ed(
4037 ohci_state_t *ohcip,
4038 ohci_pipe_private_t *pp)
4039 {
4040 ohci_ed_t *ept = pp->pp_ept;
4041 ohci_ed_t *next_lattice_ept, *lattice_ept;
4042 uint_t node;
4043
4044 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4045
4046 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4047 "ohci_insert_intr_ed:");
4048
4049 /*
4050 * The appropriate node was found
4051 * during the opening of the pipe.
4052 */
4053 node = pp->pp_node;
4054
4055 if (node >= NUM_STATIC_NODES) {
4056 /* Get the hcca interrupt table index */
4057 node = ohci_hcca_intr_index(node);
4058
4059 /* Get the first endpoint on the list */
4060 next_lattice_ept = ohci_ed_iommu_to_cpu(ohcip,
4061 Get_HCCA(ohcip->ohci_hccap->HccaIntTble[node]));
4062
4063 /* Update this endpoint to point to it */
4064 Set_ED(ept->hced_next,
4065 ohci_ed_cpu_to_iommu(ohcip, next_lattice_ept));
4066
4067 /* Put this endpoint at the head of the list */
4068 Set_HCCA(ohcip->ohci_hccap->HccaIntTble[node],
4069 ohci_ed_cpu_to_iommu(ohcip, ept));
4070
4071 /* The previous pointer is NULL */
4072 Set_ED(ept->hced_prev, NULL);
4073
4074 /* Update the previous pointer of ept->hced_next */
4075 if (Get_ED(next_lattice_ept->hced_state) != HC_EPT_STATIC) {
4076 Set_ED(next_lattice_ept->hced_prev,
4077 ohci_ed_cpu_to_iommu(ohcip, ept));
4078 }
4079 } else {
4080 /* Find the lattice endpoint */
4081 lattice_ept = &ohcip->ohci_ed_pool_addr[node];
4082
4083 /* Find the next lattice endpoint */
4084 next_lattice_ept = ohci_ed_iommu_to_cpu(
4085 ohcip, Get_ED(lattice_ept->hced_next));
4086
4087 /*
4088 * Update this endpoint to point to the next one in the
4089 * lattice.
4090 */
4091 Set_ED(ept->hced_next, Get_ED(lattice_ept->hced_next));
4092
4093 /* Insert this endpoint into the lattice */
4094 Set_ED(lattice_ept->hced_next,
4095 ohci_ed_cpu_to_iommu(ohcip, ept));
4096
4097 /* Update the previous pointer */
4098 Set_ED(ept->hced_prev,
4099 ohci_ed_cpu_to_iommu(ohcip, lattice_ept));
4100
4101 /* Update the previous pointer of ept->hced_next */
4102 if ((next_lattice_ept) &&
4103 (Get_ED(next_lattice_ept->hced_state) != HC_EPT_STATIC)) {
4104
4105 Set_ED(next_lattice_ept->hced_prev,
4106 ohci_ed_cpu_to_iommu(ohcip, ept));
4107 }
4108 }
4109
4110 /*
4111 * Enable periodic list processing if periodic (interrupt
4112 * and isochronous) open pipe count is zero.
4113 */
4114 if (!ohcip->ohci_open_periodic_pipe_count) {
4115 ASSERT(!ohcip->ohci_open_isoch_pipe_count);
4116
4117 Set_OpReg(hcr_control,
4118 (Get_OpReg(hcr_control) | HCR_CONTROL_PLE));
4119 }
4120
4121 ohcip->ohci_open_periodic_pipe_count++;
4122 }
4123
4124
4125 /*
4126 * ohci_insert_isoc_ed:
4127 *
4128 * Insert a isochronous endpoint into the Host Controller's (HC) interrupt
4129 * lattice tree. A isochronous endpoint will be inserted at the end of the
4130 * 1ms interrupt endpoint list.
4131 */
4132 static void
ohci_insert_isoc_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)4133 ohci_insert_isoc_ed(
4134 ohci_state_t *ohcip,
4135 ohci_pipe_private_t *pp)
4136 {
4137 ohci_ed_t *next_lattice_ept, *lattice_ept;
4138 ohci_ed_t *ept = pp->pp_ept;
4139 uint_t node;
4140
4141 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4142
4143 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4144 "ohci_insert_isoc_ed:");
4145
4146 /*
4147 * The appropriate node was found during the opening of the pipe.
4148 * This node must be root of the interrupt lattice tree.
4149 */
4150 node = pp->pp_node;
4151
4152 ASSERT(node == 0);
4153
4154 /* Find the 1ms interrupt lattice endpoint */
4155 lattice_ept = &ohcip->ohci_ed_pool_addr[node];
4156
4157 /* Find the next lattice endpoint */
4158 next_lattice_ept = ohci_ed_iommu_to_cpu(
4159 ohcip, Get_ED(lattice_ept->hced_next));
4160
4161 while (next_lattice_ept) {
4162 lattice_ept = next_lattice_ept;
4163
4164 /* Find the next lattice endpoint */
4165 next_lattice_ept = ohci_ed_iommu_to_cpu(
4166 ohcip, Get_ED(lattice_ept->hced_next));
4167 }
4168
4169 /* The next pointer is NULL */
4170 Set_ED(ept->hced_next, NULL);
4171
4172 /* Update the previous pointer */
4173 Set_ED(ept->hced_prev, ohci_ed_cpu_to_iommu(ohcip, lattice_ept));
4174
4175 /* Insert this endpoint into the lattice */
4176 Set_ED(lattice_ept->hced_next, ohci_ed_cpu_to_iommu(ohcip, ept));
4177
4178 /*
4179 * Enable periodic and isoch lists processing if isoch
4180 * open pipe count is zero.
4181 */
4182 if (!ohcip->ohci_open_isoch_pipe_count) {
4183
4184 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) |
4185 HCR_CONTROL_PLE | HCR_CONTROL_IE));
4186 }
4187
4188 ohcip->ohci_open_periodic_pipe_count++;
4189 ohcip->ohci_open_isoch_pipe_count++;
4190 }
4191
4192
4193 /*
4194 * ohci_modify_sKip_bit:
4195 *
4196 * Modify the sKip bit on the Host Controller (HC) Endpoint Descriptor (ED).
4197 */
4198 static void
ohci_modify_sKip_bit(ohci_state_t * ohcip,ohci_pipe_private_t * pp,skip_bit_t action,usb_flags_t flag)4199 ohci_modify_sKip_bit(
4200 ohci_state_t *ohcip,
4201 ohci_pipe_private_t *pp,
4202 skip_bit_t action,
4203 usb_flags_t flag)
4204 {
4205 ohci_ed_t *ept = pp->pp_ept;
4206
4207 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4208 "ohci_modify_sKip_bit: action = 0x%x flag = 0x%x",
4209 action, flag);
4210
4211 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4212
4213 if (action == CLEAR_sKip) {
4214 /*
4215 * If the skip bit is to be cleared, just clear it.
4216 * there shouldn't be any race condition problems.
4217 * If the host controller reads the bit before the
4218 * driver has a chance to set the bit, the bit will
4219 * be reread on the next frame.
4220 */
4221 Set_ED(ept->hced_ctrl, (Get_ED(ept->hced_ctrl) & ~HC_EPT_sKip));
4222 } else {
4223 /* Sync ED and TD pool */
4224 if (flag & OHCI_FLAGS_DMA_SYNC) {
4225 Sync_ED_TD_Pool(ohcip);
4226 }
4227
4228 /* Check Halt or Skip bit is already set */
4229 if ((Get_ED(ept->hced_headp) & HC_EPT_Halt) ||
4230 (Get_ED(ept->hced_ctrl) & HC_EPT_sKip)) {
4231
4232 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4233 "ohci_modify_sKip_bit: "
4234 "Halt or Skip bit is already set");
4235 } else {
4236 /*
4237 * The action is to set the skip bit. In order to
4238 * be sure that the HCD has seen the sKip bit, wait
4239 * for the next start of frame.
4240 */
4241 Set_ED(ept->hced_ctrl,
4242 (Get_ED(ept->hced_ctrl) | HC_EPT_sKip));
4243
4244 if (flag & OHCI_FLAGS_SLEEP) {
4245 /* Wait for the next SOF */
4246 (void) ohci_wait_for_sof(ohcip);
4247
4248 /* Sync ED and TD pool */
4249 if (flag & OHCI_FLAGS_DMA_SYNC) {
4250 Sync_ED_TD_Pool(ohcip);
4251 }
4252 }
4253 }
4254 }
4255 }
4256
4257
4258 /*
4259 * ohci_remove_ed:
4260 *
4261 * Remove the Endpoint Descriptor (ED) from the Host Controller's appropriate
4262 * endpoint list.
4263 */
4264 static void
ohci_remove_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)4265 ohci_remove_ed(
4266 ohci_state_t *ohcip,
4267 ohci_pipe_private_t *pp)
4268 {
4269 uchar_t attributes;
4270
4271 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4272
4273 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4274 "ohci_remove_ed:");
4275
4276 attributes = pp->pp_pipe_handle->p_ep.bmAttributes & USB_EP_ATTR_MASK;
4277
4278 switch (attributes) {
4279 case USB_EP_ATTR_CONTROL:
4280 ohci_remove_ctrl_ed(ohcip, pp);
4281 break;
4282 case USB_EP_ATTR_BULK:
4283 ohci_remove_bulk_ed(ohcip, pp);
4284 break;
4285 case USB_EP_ATTR_INTR:
4286 case USB_EP_ATTR_ISOCH:
4287 ohci_remove_periodic_ed(ohcip, pp);
4288 break;
4289 }
4290 }
4291
4292
4293 /*
4294 * ohci_remove_ctrl_ed:
4295 *
4296 * Remove a control Endpoint Descriptor (ED) from the Host Controller's (HC)
4297 * control endpoint list.
4298 */
4299 static void
ohci_remove_ctrl_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)4300 ohci_remove_ctrl_ed(
4301 ohci_state_t *ohcip,
4302 ohci_pipe_private_t *pp)
4303 {
4304 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */
4305
4306 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4307 "ohci_remove_ctrl_ed:");
4308
4309 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4310
4311 /* The control list should already be stopped */
4312 ASSERT(!(Get_OpReg(hcr_control) & HCR_CONTROL_CLE));
4313
4314 ohcip->ohci_open_ctrl_pipe_count--;
4315
4316 /* Detach the endpoint from the list that it's on */
4317 ohci_detach_ed_from_list(ohcip, ept, USB_EP_ATTR_CONTROL);
4318
4319 /*
4320 * If next endpoint pointed by endpoint to be removed is not NULL
4321 * then set current control pointer to the next endpoint pointed by
4322 * endpoint to be removed. Otherwise set current control pointer to
4323 * the beginning of the control list.
4324 */
4325 if (Get_ED(ept->hced_next)) {
4326 Set_OpReg(hcr_ctrl_curr, Get_ED(ept->hced_next));
4327 } else {
4328 Set_OpReg(hcr_ctrl_curr, Get_OpReg(hcr_ctrl_head));
4329 }
4330
4331 if (ohcip->ohci_open_ctrl_pipe_count) {
4332 ASSERT(Get_OpReg(hcr_ctrl_head));
4333
4334 /* Reenable the control list */
4335 Set_OpReg(hcr_control,
4336 (Get_OpReg(hcr_control) | HCR_CONTROL_CLE));
4337 }
4338
4339 ohci_insert_ed_on_reclaim_list(ohcip, pp);
4340 }
4341
4342
4343 /*
4344 * ohci_remove_bulk_ed:
4345 *
4346 * Remove free the bulk Endpoint Descriptor (ED) from the Host Controller's
4347 * (HC) bulk endpoint list.
4348 */
4349 static void
ohci_remove_bulk_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)4350 ohci_remove_bulk_ed(
4351 ohci_state_t *ohcip,
4352 ohci_pipe_private_t *pp)
4353 {
4354 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */
4355
4356 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4357 "ohci_remove_bulk_ed:");
4358
4359 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4360
4361 /* The bulk list should already be stopped */
4362 ASSERT(!(Get_OpReg(hcr_control) & HCR_CONTROL_BLE));
4363
4364 ohcip->ohci_open_bulk_pipe_count--;
4365
4366 /* Detach the endpoint from the bulk list */
4367 ohci_detach_ed_from_list(ohcip, ept, USB_EP_ATTR_BULK);
4368
4369 /*
4370 * If next endpoint pointed by endpoint to be removed is not NULL
4371 * then set current bulk pointer to the next endpoint pointed by
4372 * endpoint to be removed. Otherwise set current bulk pointer to
4373 * the beginning of the bulk list.
4374 */
4375 if (Get_ED(ept->hced_next)) {
4376 Set_OpReg(hcr_bulk_curr, Get_ED(ept->hced_next));
4377 } else {
4378 Set_OpReg(hcr_bulk_curr, Get_OpReg(hcr_bulk_head));
4379 }
4380
4381 if (ohcip->ohci_open_bulk_pipe_count) {
4382 ASSERT(Get_OpReg(hcr_bulk_head));
4383
4384 /* Re-enable the bulk list */
4385 Set_OpReg(hcr_control,
4386 (Get_OpReg(hcr_control) | HCR_CONTROL_BLE));
4387 }
4388
4389 ohci_insert_ed_on_reclaim_list(ohcip, pp);
4390 }
4391
4392
4393 /*
4394 * ohci_remove_periodic_ed:
4395 *
4396 * Set up an periodic endpoint to be removed from the Host Controller's (HC)
4397 * interrupt lattice tree. The Endpoint Descriptor (ED) will be freed in the
4398 * interrupt handler.
4399 */
4400 static void
ohci_remove_periodic_ed(ohci_state_t * ohcip,ohci_pipe_private_t * pp)4401 ohci_remove_periodic_ed(
4402 ohci_state_t *ohcip,
4403 ohci_pipe_private_t *pp)
4404 {
4405 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */
4406 uint_t ept_type;
4407
4408 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4409 "ohci_remove_periodic_ed:");
4410
4411 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4412
4413 ASSERT((Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL) ==
4414 (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD));
4415
4416 ohcip->ohci_open_periodic_pipe_count--;
4417
4418 ept_type = pp->pp_pipe_handle->
4419 p_ep.bmAttributes & USB_EP_ATTR_MASK;
4420
4421 if (ept_type == USB_EP_ATTR_ISOCH) {
4422 ohcip->ohci_open_isoch_pipe_count--;
4423 }
4424
4425 /* Store the node number */
4426 Set_ED(ept->hced_node, pp->pp_node);
4427
4428 /* Remove the endpoint from interrupt lattice tree */
4429 ohci_detach_ed_from_list(ohcip, ept, ept_type);
4430
4431 /*
4432 * Disable isoch list processing if isoch open pipe count
4433 * is zero.
4434 */
4435 if (!ohcip->ohci_open_isoch_pipe_count) {
4436 Set_OpReg(hcr_control,
4437 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_IE)));
4438 }
4439
4440 /*
4441 * Disable periodic list processing if periodic (interrupt
4442 * and isochrous) open pipe count is zero.
4443 */
4444 if (!ohcip->ohci_open_periodic_pipe_count) {
4445 ASSERT(!ohcip->ohci_open_isoch_pipe_count);
4446
4447 Set_OpReg(hcr_control,
4448 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_PLE)));
4449 }
4450
4451 ohci_insert_ed_on_reclaim_list(ohcip, pp);
4452 }
4453
4454
4455 /*
4456 * ohci_detach_ed_from_list:
4457 *
4458 * Remove the Endpoint Descriptor (ED) from the appropriate Host Controller's
4459 * (HC) endpoint list.
4460 */
4461 static void
ohci_detach_ed_from_list(ohci_state_t * ohcip,ohci_ed_t * ept,uint_t ept_type)4462 ohci_detach_ed_from_list(
4463 ohci_state_t *ohcip,
4464 ohci_ed_t *ept,
4465 uint_t ept_type)
4466 {
4467 ohci_ed_t *prev_ept; /* Previous endpoint */
4468 ohci_ed_t *next_ept; /* Endpoint after one to be removed */
4469 uint_t node;
4470
4471 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4472 "ohci_detach_ed_from_list:");
4473
4474 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4475
4476 prev_ept = ohci_ed_iommu_to_cpu(ohcip, Get_ED(ept->hced_prev));
4477 next_ept = ohci_ed_iommu_to_cpu(ohcip, Get_ED(ept->hced_next));
4478
4479 /*
4480 * If there is no previous endpoint, then this
4481 * endpoint is at the head of the endpoint list.
4482 */
4483 if (prev_ept == NULL) {
4484 if (next_ept) {
4485 /*
4486 * If this endpoint is the first element of the
4487 * list and there is more than one endpoint on
4488 * the list then perform specific actions based
4489 * on the type of endpoint list.
4490 */
4491 switch (ept_type) {
4492 case USB_EP_ATTR_CONTROL:
4493 /* Set the head of list to next ept */
4494 Set_OpReg(hcr_ctrl_head,
4495 Get_ED(ept->hced_next));
4496
4497 /* Clear prev ptr of next endpoint */
4498 Set_ED(next_ept->hced_prev, NULL);
4499 break;
4500 case USB_EP_ATTR_BULK:
4501 /* Set the head of list to next ept */
4502 Set_OpReg(hcr_bulk_head,
4503 Get_ED(ept->hced_next));
4504
4505 /* Clear prev ptr of next endpoint */
4506 Set_ED(next_ept->hced_prev, NULL);
4507 break;
4508 case USB_EP_ATTR_INTR:
4509 /*
4510 * HCCA area should point
4511 * directly to this ept.
4512 */
4513 ASSERT(Get_ED(ept->hced_node) >=
4514 NUM_STATIC_NODES);
4515
4516 /* Get the hcca interrupt table index */
4517 node = ohci_hcca_intr_index(
4518 Get_ED(ept->hced_node));
4519
4520 /*
4521 * Delete the ept from the
4522 * bottom of the tree.
4523 */
4524 Set_HCCA(ohcip->ohci_hccap->
4525 HccaIntTble[node], Get_ED(ept->hced_next));
4526
4527 /*
4528 * Update the previous pointer
4529 * of ept->hced_next
4530 */
4531 if (Get_ED(next_ept->hced_state) !=
4532 HC_EPT_STATIC) {
4533
4534 Set_ED(next_ept->hced_prev, NULL);
4535 }
4536
4537 break;
4538 case USB_EP_ATTR_ISOCH:
4539 default:
4540 break;
4541 }
4542 } else {
4543 /*
4544 * If there was only one element on the list
4545 * perform specific actions based on the type
4546 * of the list.
4547 */
4548 switch (ept_type) {
4549 case USB_EP_ATTR_CONTROL:
4550 /* Set the head to NULL */
4551 Set_OpReg(hcr_ctrl_head, NULL);
4552 break;
4553 case USB_EP_ATTR_BULK:
4554 /* Set the head to NULL */
4555 Set_OpReg(hcr_bulk_head, NULL);
4556 break;
4557 case USB_EP_ATTR_INTR:
4558 case USB_EP_ATTR_ISOCH:
4559 default:
4560 break;
4561 }
4562 }
4563 } else {
4564 /* The previous ept points to the next one */
4565 Set_ED(prev_ept->hced_next, Get_ED(ept->hced_next));
4566
4567 /*
4568 * Set the previous ptr of the next_ept to prev_ept
4569 * if this isn't the last endpoint on the list
4570 */
4571 if ((next_ept) &&
4572 (Get_ED(next_ept->hced_state) != HC_EPT_STATIC)) {
4573
4574 /* Set the previous ptr of the next one */
4575 Set_ED(next_ept->hced_prev, Get_ED(ept->hced_prev));
4576 }
4577 }
4578 }
4579
4580
4581 /*
4582 * ohci_insert_ed_on_reclaim_list:
4583 *
4584 * Insert Endpoint onto the reclaim list
4585 */
4586 static void
ohci_insert_ed_on_reclaim_list(ohci_state_t * ohcip,ohci_pipe_private_t * pp)4587 ohci_insert_ed_on_reclaim_list(
4588 ohci_state_t *ohcip,
4589 ohci_pipe_private_t *pp)
4590 {
4591 ohci_ed_t *ept = pp->pp_ept; /* ept to be removed */
4592 ohci_ed_t *next_ept, *prev_ept;
4593 usb_frame_number_t frame_number;
4594
4595 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4596
4597 /*
4598 * Read current usb frame number and add appropriate number of
4599 * usb frames needs to wait before reclaiming current endpoint.
4600 */
4601 frame_number =
4602 ohci_get_current_frame_number(ohcip) + MAX_SOF_WAIT_COUNT;
4603
4604 /* Store 32bit ID */
4605 Set_ED(ept->hced_reclaim_frame,
4606 ((uint32_t)(OHCI_GET_ID((void *)(uintptr_t)frame_number))));
4607
4608 /* Insert the endpoint onto the reclaimation list */
4609 if (ohcip->ohci_reclaim_list) {
4610 next_ept = ohcip->ohci_reclaim_list;
4611
4612 while (next_ept) {
4613 prev_ept = next_ept;
4614 next_ept = ohci_ed_iommu_to_cpu(ohcip,
4615 Get_ED(next_ept->hced_reclaim_next));
4616 }
4617
4618 Set_ED(prev_ept->hced_reclaim_next,
4619 ohci_ed_cpu_to_iommu(ohcip, ept));
4620 } else {
4621 ohcip->ohci_reclaim_list = ept;
4622 }
4623
4624 ASSERT(Get_ED(ept->hced_reclaim_next) == NULL);
4625
4626 /* Enable the SOF interrupt */
4627 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
4628 }
4629
4630
4631 /*
4632 * ohci_deallocate_ed:
4633 * NOTE: This function is also called from POLLED MODE.
4634 *
4635 * Deallocate a Host Controller's (HC) Endpoint Descriptor (ED).
4636 */
4637 void
ohci_deallocate_ed(ohci_state_t * ohcip,ohci_ed_t * old_ed)4638 ohci_deallocate_ed(
4639 ohci_state_t *ohcip,
4640 ohci_ed_t *old_ed)
4641 {
4642 ohci_td_t *dummy_td;
4643
4644 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4645 "ohci_deallocate_ed:");
4646
4647 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4648
4649 dummy_td = ohci_td_iommu_to_cpu(ohcip, Get_ED(old_ed->hced_headp));
4650
4651 if (dummy_td) {
4652
4653 ASSERT(Get_TD(dummy_td->hctd_state) == HC_TD_DUMMY);
4654 ohci_deallocate_td(ohcip, dummy_td);
4655 }
4656
4657 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4658 "ohci_deallocate_ed: Deallocated 0x%p", (void *)old_ed);
4659
4660 bzero((void *)old_ed, sizeof (ohci_ed_t));
4661 Set_ED(old_ed->hced_state, HC_EPT_FREE);
4662 }
4663
4664
4665 /*
4666 * ohci_ed_cpu_to_iommu:
4667 * NOTE: This function is also called from POLLED MODE.
4668 *
4669 * This function converts for the given Endpoint Descriptor (ED) CPU address
4670 * to IO address.
4671 */
4672 uint32_t
ohci_ed_cpu_to_iommu(ohci_state_t * ohcip,ohci_ed_t * addr)4673 ohci_ed_cpu_to_iommu(
4674 ohci_state_t *ohcip,
4675 ohci_ed_t *addr)
4676 {
4677 uint32_t ed;
4678
4679 ed = (uint32_t)ohcip->ohci_ed_pool_cookie.dmac_address +
4680 (uint32_t)((uintptr_t)addr - (uintptr_t)(ohcip->ohci_ed_pool_addr));
4681
4682 ASSERT(ed >= ohcip->ohci_ed_pool_cookie.dmac_address);
4683 ASSERT(ed <= ohcip->ohci_ed_pool_cookie.dmac_address +
4684 sizeof (ohci_ed_t) * ohci_ed_pool_size);
4685
4686 return (ed);
4687 }
4688
4689
4690 /*
4691 * ohci_ed_iommu_to_cpu:
4692 *
4693 * This function converts for the given Endpoint Descriptor (ED) IO address
4694 * to CPU address.
4695 */
4696 static ohci_ed_t *
ohci_ed_iommu_to_cpu(ohci_state_t * ohcip,uintptr_t addr)4697 ohci_ed_iommu_to_cpu(
4698 ohci_state_t *ohcip,
4699 uintptr_t addr)
4700 {
4701 ohci_ed_t *ed;
4702
4703 if (addr == NULL) {
4704
4705 return (NULL);
4706 }
4707
4708 ed = (ohci_ed_t *)((uintptr_t)
4709 (addr - ohcip->ohci_ed_pool_cookie.dmac_address) +
4710 (uintptr_t)ohcip->ohci_ed_pool_addr);
4711
4712 ASSERT(ed >= ohcip->ohci_ed_pool_addr);
4713 ASSERT((uintptr_t)ed <= (uintptr_t)ohcip->ohci_ed_pool_addr +
4714 (uintptr_t)(sizeof (ohci_ed_t) * ohci_ed_pool_size));
4715
4716 return (ed);
4717 }
4718
4719
4720 /*
4721 * Transfer Descriptor manipulations functions
4722 */
4723
4724 /*
4725 * ohci_initialize_dummy:
4726 *
4727 * An Endpoint Descriptor (ED) has a dummy Transfer Descriptor (TD) on the
4728 * end of its TD list. Initially, both the head and tail pointers of the ED
4729 * point to the dummy TD.
4730 */
4731 static int
ohci_initialize_dummy(ohci_state_t * ohcip,ohci_ed_t * ept)4732 ohci_initialize_dummy(
4733 ohci_state_t *ohcip,
4734 ohci_ed_t *ept)
4735 {
4736 ohci_td_t *dummy;
4737
4738 /* Obtain a dummy TD */
4739 dummy = ohci_allocate_td_from_pool(ohcip);
4740
4741 if (dummy == NULL) {
4742 return (USB_NO_RESOURCES);
4743 }
4744
4745 /*
4746 * Both the head and tail pointers of an ED point
4747 * to this new dummy TD.
4748 */
4749 Set_ED(ept->hced_headp, (ohci_td_cpu_to_iommu(ohcip, dummy)));
4750 Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, dummy)));
4751
4752 return (USB_SUCCESS);
4753 }
4754
4755 /*
4756 * ohci_allocate_ctrl_resources:
4757 *
4758 * Calculates the number of tds necessary for a ctrl transfer, and allocates
4759 * all the resources necessary.
4760 *
4761 * Returns NULL if there is insufficient resources otherwise TW.
4762 */
4763 static ohci_trans_wrapper_t *
ohci_allocate_ctrl_resources(ohci_state_t * ohcip,ohci_pipe_private_t * pp,usb_ctrl_req_t * ctrl_reqp,usb_flags_t usb_flags)4764 ohci_allocate_ctrl_resources(
4765 ohci_state_t *ohcip,
4766 ohci_pipe_private_t *pp,
4767 usb_ctrl_req_t *ctrl_reqp,
4768 usb_flags_t usb_flags)
4769 {
4770 size_t td_count = 2;
4771 size_t ctrl_buf_size;
4772 ohci_trans_wrapper_t *tw;
4773
4774 /* Add one more td for data phase */
4775 if (ctrl_reqp->ctrl_wLength) {
4776 td_count++;
4777 }
4778
4779 /*
4780 * If we have a control data phase, the data buffer starts
4781 * on the next 4K page boundary. So the TW buffer is allocated
4782 * to be larger than required. The buffer in the range of
4783 * [SETUP_SIZE, OHCI_MAX_TD_BUF_SIZE) is just for padding
4784 * and not to be transferred.
4785 */
4786 if (ctrl_reqp->ctrl_wLength) {
4787 ctrl_buf_size = OHCI_MAX_TD_BUF_SIZE +
4788 ctrl_reqp->ctrl_wLength;
4789 } else {
4790 ctrl_buf_size = SETUP_SIZE;
4791 }
4792
4793 tw = ohci_allocate_tw_resources(ohcip, pp, ctrl_buf_size,
4794 usb_flags, td_count);
4795
4796 return (tw);
4797 }
4798
4799 /*
4800 * ohci_insert_ctrl_req:
4801 *
4802 * Create a Transfer Descriptor (TD) and a data buffer for a control endpoint.
4803 */
4804 /* ARGSUSED */
4805 static void
ohci_insert_ctrl_req(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_ctrl_req_t * ctrl_reqp,ohci_trans_wrapper_t * tw,usb_flags_t usb_flags)4806 ohci_insert_ctrl_req(
4807 ohci_state_t *ohcip,
4808 usba_pipe_handle_data_t *ph,
4809 usb_ctrl_req_t *ctrl_reqp,
4810 ohci_trans_wrapper_t *tw,
4811 usb_flags_t usb_flags)
4812 {
4813 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
4814 uchar_t bmRequestType = ctrl_reqp->ctrl_bmRequestType;
4815 uchar_t bRequest = ctrl_reqp->ctrl_bRequest;
4816 uint16_t wValue = ctrl_reqp->ctrl_wValue;
4817 uint16_t wIndex = ctrl_reqp->ctrl_wIndex;
4818 uint16_t wLength = ctrl_reqp->ctrl_wLength;
4819 mblk_t *data = ctrl_reqp->ctrl_data;
4820 uint32_t ctrl = 0;
4821 int sdata;
4822
4823 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4824 "ohci_insert_ctrl_req:");
4825
4826 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
4827
4828 /*
4829 * Save current control request pointer and timeout values
4830 * in transfer wrapper.
4831 */
4832 tw->tw_curr_xfer_reqp = (usb_opaque_t)ctrl_reqp;
4833 tw->tw_timeout = ctrl_reqp->ctrl_timeout ?
4834 ctrl_reqp->ctrl_timeout : OHCI_DEFAULT_XFER_TIMEOUT;
4835
4836 /*
4837 * Initialize the callback and any callback data for when
4838 * the td completes.
4839 */
4840 tw->tw_handle_td = ohci_handle_ctrl_td;
4841 tw->tw_handle_callback_value = NULL;
4842
4843 /* Create the first four bytes of the setup packet */
4844 sdata = (bmRequestType << 24) | (bRequest << 16) |
4845 (((wValue >> 8) | (wValue << 8)) & 0x0000FFFF);
4846
4847 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4848 "ohci_create_setup_pkt: sdata = 0x%x", sdata);
4849
4850 ddi_put32(tw->tw_accesshandle, (uint_t *)tw->tw_buf, sdata);
4851
4852 /* Create the second four bytes */
4853 sdata = (uint32_t)(((((wIndex >> 8) |
4854 (wIndex << 8)) << 16) & 0xFFFF0000) |
4855 (((wLength >> 8) | (wLength << 8)) & 0x0000FFFF));
4856
4857 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4858 "ohci_create_setup_pkt: sdata = 0x%x", sdata);
4859
4860 ddi_put32(tw->tw_accesshandle,
4861 (uint_t *)((uintptr_t)tw->tw_buf + sizeof (uint_t)), sdata);
4862
4863 ctrl = HC_TD_SETUP|HC_TD_MS_DT|HC_TD_DT_0|HC_TD_6I;
4864
4865 /*
4866 * The TD's are placed on the ED one at a time.
4867 * Once this TD is placed on the done list, the
4868 * data or status phase TD will be enqueued.
4869 */
4870 (void) ohci_insert_hc_td(ohcip, ctrl, 0, SETUP_SIZE,
4871 OHCI_CTRL_SETUP_PHASE, pp, tw);
4872
4873 USB_DPRINTF_L3(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
4874 "Create_setup: pp 0x%p", (void *)pp);
4875
4876 /*
4877 * If this control transfer has a data phase, record the
4878 * direction. If the data phase is an OUT transaction,
4879 * copy the data into the buffer of the transfer wrapper.
4880 */
4881 if (wLength != 0) {
4882 /* There is a data stage. Find the direction */
4883 if (bmRequestType & USB_DEV_REQ_DEV_TO_HOST) {
4884 tw->tw_direction = HC_TD_IN;
4885 } else {
4886 tw->tw_direction = HC_TD_OUT;
4887
4888 /* Copy the data into the message */
4889 ddi_rep_put8(tw->tw_accesshandle, data->b_rptr,
4890 (uint8_t *)(tw->tw_buf + OHCI_MAX_TD_BUF_SIZE),
4891 wLength, DDI_DEV_AUTOINCR);
4892
4893 }
4894
4895 ctrl = (ctrl_reqp->ctrl_attributes & USB_ATTRS_SHORT_XFER_OK) ?
4896 HC_TD_R : 0;
4897
4898 /*
4899 * There is a data stage.
4900 * Find the direction.
4901 */
4902 if (tw->tw_direction == HC_TD_IN) {
4903 ctrl = ctrl|HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_6I;
4904 } else {
4905 ctrl = ctrl|HC_TD_OUT|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_6I;
4906 }
4907
4908 /*
4909 * Create the TD. If this is an OUT transaction,
4910 * the data is already in the buffer of the TW.
4911 */
4912 (void) ohci_insert_hc_td(ohcip, ctrl, OHCI_MAX_TD_BUF_SIZE,
4913 wLength, OHCI_CTRL_DATA_PHASE, pp, tw);
4914
4915 /*
4916 * The direction of the STATUS TD depends on
4917 * the direction of the transfer.
4918 */
4919 if (tw->tw_direction == HC_TD_IN) {
4920 ctrl = HC_TD_OUT|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I;
4921 } else {
4922 ctrl = HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I;
4923 }
4924 } else {
4925 ctrl = HC_TD_IN|HC_TD_MS_DT|HC_TD_DT_1|HC_TD_1I;
4926 }
4927
4928 /* Status stage */
4929 (void) ohci_insert_hc_td(ohcip, ctrl, 0,
4930 0, OHCI_CTRL_STATUS_PHASE, pp, tw);
4931
4932 /* Indicate that the control list is filled */
4933 Set_OpReg(hcr_cmd_status, HCR_STATUS_CLF);
4934
4935 /* Start the timer for this control transfer */
4936 ohci_start_xfer_timer(ohcip, pp, tw);
4937 }
4938
4939 /*
4940 * ohci_allocate_bulk_resources:
4941 *
4942 * Calculates the number of tds necessary for a ctrl transfer, and allocates
4943 * all the resources necessary.
4944 *
4945 * Returns NULL if there is insufficient resources otherwise TW.
4946 */
4947 static ohci_trans_wrapper_t *
ohci_allocate_bulk_resources(ohci_state_t * ohcip,ohci_pipe_private_t * pp,usb_bulk_req_t * bulk_reqp,usb_flags_t usb_flags)4948 ohci_allocate_bulk_resources(
4949 ohci_state_t *ohcip,
4950 ohci_pipe_private_t *pp,
4951 usb_bulk_req_t *bulk_reqp,
4952 usb_flags_t usb_flags)
4953 {
4954 size_t td_count = 0;
4955 ohci_trans_wrapper_t *tw;
4956
4957 /* Check the size of bulk request */
4958 if (bulk_reqp->bulk_len > OHCI_MAX_BULK_XFER_SIZE) {
4959
4960 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
4961 "ohci_allocate_bulk_resources: Bulk request size 0x%x is "
4962 "more than 0x%x", bulk_reqp->bulk_len,
4963 OHCI_MAX_BULK_XFER_SIZE);
4964
4965 return (NULL);
4966 }
4967
4968 /* Get the required bulk packet size */
4969 td_count = bulk_reqp->bulk_len / OHCI_MAX_TD_XFER_SIZE;
4970 if (bulk_reqp->bulk_len % OHCI_MAX_TD_XFER_SIZE ||
4971 bulk_reqp->bulk_len == 0) {
4972 td_count++;
4973 }
4974
4975 tw = ohci_allocate_tw_resources(ohcip, pp, bulk_reqp->bulk_len,
4976 usb_flags, td_count);
4977
4978 return (tw);
4979 }
4980
4981 /*
4982 * ohci_insert_bulk_req:
4983 *
4984 * Create a Transfer Descriptor (TD) and a data buffer for a bulk
4985 * endpoint.
4986 */
4987 /* ARGSUSED */
4988 static void
ohci_insert_bulk_req(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_bulk_req_t * bulk_reqp,ohci_trans_wrapper_t * tw,usb_flags_t flags)4989 ohci_insert_bulk_req(
4990 ohci_state_t *ohcip,
4991 usba_pipe_handle_data_t *ph,
4992 usb_bulk_req_t *bulk_reqp,
4993 ohci_trans_wrapper_t *tw,
4994 usb_flags_t flags)
4995 {
4996 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
4997 uint_t bulk_pkt_size, count;
4998 size_t residue = 0, len = 0;
4999 uint32_t ctrl = 0;
5000 int pipe_dir;
5001
5002 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5003 "ohci_insert_bulk_req: bulk_reqp = 0x%p flags = 0x%x",
5004 (void *)bulk_reqp, flags);
5005
5006 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5007
5008 /* Get the bulk pipe direction */
5009 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
5010
5011 /* Get the required bulk packet size */
5012 bulk_pkt_size = min(bulk_reqp->bulk_len, OHCI_MAX_TD_XFER_SIZE);
5013
5014 if (bulk_pkt_size)
5015 residue = tw->tw_length % bulk_pkt_size;
5016
5017 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5018 "ohci_insert_bulk_req: bulk_pkt_size = %d", bulk_pkt_size);
5019
5020 /*
5021 * Save current bulk request pointer and timeout values
5022 * in transfer wrapper.
5023 */
5024 tw->tw_curr_xfer_reqp = (usb_opaque_t)bulk_reqp;
5025 tw->tw_timeout = bulk_reqp->bulk_timeout;
5026
5027 /*
5028 * Initialize the callback and any callback
5029 * data required when the td completes.
5030 */
5031 tw->tw_handle_td = ohci_handle_bulk_td;
5032 tw->tw_handle_callback_value = NULL;
5033
5034 tw->tw_direction =
5035 (pipe_dir == USB_EP_DIR_OUT) ? HC_TD_OUT : HC_TD_IN;
5036
5037 if (tw->tw_direction == HC_TD_OUT && bulk_reqp->bulk_len) {
5038
5039 ASSERT(bulk_reqp->bulk_data != NULL);
5040
5041 /* Copy the data into the message */
5042 ddi_rep_put8(tw->tw_accesshandle,
5043 bulk_reqp->bulk_data->b_rptr, (uint8_t *)tw->tw_buf,
5044 bulk_reqp->bulk_len, DDI_DEV_AUTOINCR);
5045 }
5046
5047 ctrl = tw->tw_direction|HC_TD_DT_0|HC_TD_6I;
5048
5049 /* Insert all the bulk TDs */
5050 for (count = 0; count < tw->tw_num_tds; count++) {
5051
5052 /* Check for last td */
5053 if (count == (tw->tw_num_tds - 1)) {
5054
5055 ctrl = ((ctrl & ~HC_TD_DI) | HC_TD_1I);
5056
5057 /* Check for inserting residue data */
5058 if (residue) {
5059 bulk_pkt_size = (uint_t)residue;
5060 }
5061
5062 /*
5063 * Only set the round bit on the last TD, to ensure
5064 * the controller will always HALT the ED in case of
5065 * a short transfer.
5066 */
5067 if (bulk_reqp->bulk_attributes &
5068 USB_ATTRS_SHORT_XFER_OK) {
5069 ctrl |= HC_TD_R;
5070 }
5071 }
5072
5073 /* Insert the TD onto the endpoint */
5074 (void) ohci_insert_hc_td(ohcip, ctrl, len,
5075 bulk_pkt_size, 0, pp, tw);
5076
5077 len = len + bulk_pkt_size;
5078 }
5079
5080 /* Indicate that the bulk list is filled */
5081 Set_OpReg(hcr_cmd_status, HCR_STATUS_BLF);
5082
5083 /* Start the timer for this bulk transfer */
5084 ohci_start_xfer_timer(ohcip, pp, tw);
5085 }
5086
5087
5088 /*
5089 * ohci_start_periodic_pipe_polling:
5090 * NOTE: This function is also called from POLLED MODE.
5091 */
5092 int
ohci_start_periodic_pipe_polling(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_opaque_t periodic_in_reqp,usb_flags_t flags)5093 ohci_start_periodic_pipe_polling(
5094 ohci_state_t *ohcip,
5095 usba_pipe_handle_data_t *ph,
5096 usb_opaque_t periodic_in_reqp,
5097 usb_flags_t flags)
5098 {
5099 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5100 usb_ep_descr_t *eptd = &ph->p_ep;
5101 int error = USB_SUCCESS;
5102
5103 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5104 "ohci_start_periodic_pipe_polling: ep%d",
5105 ph->p_ep.bEndpointAddress & USB_EP_NUM_MASK);
5106
5107 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5108
5109 /*
5110 * Check and handle start polling on root hub interrupt pipe.
5111 */
5112 if ((ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) &&
5113 ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
5114 USB_EP_ATTR_INTR)) {
5115
5116 error = ohci_handle_root_hub_pipe_start_intr_polling(ph,
5117 (usb_intr_req_t *)periodic_in_reqp, flags);
5118
5119 return (error);
5120 }
5121
5122 switch (pp->pp_state) {
5123 case OHCI_PIPE_STATE_IDLE:
5124 /* Save the Original client's Periodic IN request */
5125 pp->pp_client_periodic_in_reqp = periodic_in_reqp;
5126
5127 /*
5128 * This pipe is uninitialized or if a valid TD is
5129 * not found then insert a TD on the interrupt or
5130 * isochronous IN endpoint.
5131 */
5132 error = ohci_start_pipe_polling(ohcip, ph, flags);
5133
5134 if (error != USB_SUCCESS) {
5135 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5136 "ohci_start_periodic_pipe_polling: "
5137 "Start polling failed");
5138
5139 pp->pp_client_periodic_in_reqp = NULL;
5140
5141 return (error);
5142 }
5143
5144 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
5145 "ohci_start_periodic_pipe_polling: PP = 0x%p", (void *)pp);
5146
5147 ASSERT((pp->pp_tw_head != NULL) && (pp->pp_tw_tail != NULL));
5148
5149 break;
5150 case OHCI_PIPE_STATE_ACTIVE:
5151 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5152 "ohci_start_periodic_pipe_polling: "
5153 "Polling is already in progress");
5154
5155 error = USB_FAILURE;
5156 break;
5157 case OHCI_PIPE_STATE_ERROR:
5158 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5159 "ohci_start_periodic_pipe_polling: "
5160 "Pipe is halted and perform reset before restart polling");
5161
5162 error = USB_FAILURE;
5163 break;
5164 default:
5165 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5166 "ohci_start_periodic_pipe_polling: Undefined state");
5167
5168 error = USB_FAILURE;
5169 break;
5170 }
5171
5172 return (error);
5173 }
5174
5175
5176 /*
5177 * ohci_start_pipe_polling:
5178 *
5179 * Insert the number of periodic requests corresponding to polling
5180 * interval as calculated during pipe open.
5181 */
5182 static int
ohci_start_pipe_polling(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_flags_t flags)5183 ohci_start_pipe_polling(
5184 ohci_state_t *ohcip,
5185 usba_pipe_handle_data_t *ph,
5186 usb_flags_t flags)
5187 {
5188 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5189 usb_ep_descr_t *eptd = &ph->p_ep;
5190 ohci_trans_wrapper_t *tw_list, *tw;
5191 int i, total_tws;
5192 int error = USB_SUCCESS;
5193
5194 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5195 "ohci_start_pipe_polling:");
5196
5197 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5198
5199 /*
5200 * For the start polling, pp_max_periodic_req_cnt will be zero
5201 * and for the restart polling request, it will be non zero.
5202 *
5203 * In case of start polling request, find out number of requests
5204 * required for the Interrupt IN endpoints corresponding to the
5205 * endpoint polling interval. For Isochronous IN endpoints, it is
5206 * always fixed since its polling interval will be one ms.
5207 */
5208 if (pp->pp_max_periodic_req_cnt == 0) {
5209
5210 ohci_set_periodic_pipe_polling(ohcip, ph);
5211 }
5212
5213 ASSERT(pp->pp_max_periodic_req_cnt != 0);
5214
5215 /* Allocate all the necessary resources for the IN transfer */
5216 tw_list = NULL;
5217 total_tws = pp->pp_max_periodic_req_cnt - pp->pp_cur_periodic_req_cnt;
5218 for (i = 0; i < total_tws; i++) {
5219 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
5220 case USB_EP_ATTR_INTR:
5221 tw = ohci_allocate_intr_resources(
5222 ohcip, ph, NULL, flags);
5223 break;
5224 case USB_EP_ATTR_ISOCH:
5225 tw = ohci_allocate_isoc_resources(
5226 ohcip, ph, NULL, flags);
5227 break;
5228 }
5229 if (tw == NULL) {
5230 error = USB_NO_RESOURCES;
5231 /* There are not enough resources, deallocate the TWs */
5232 tw = tw_list;
5233 while (tw != NULL) {
5234 tw_list = tw->tw_next;
5235 ohci_deallocate_periodic_in_resource(
5236 ohcip, pp, tw);
5237 ohci_deallocate_tw_resources(ohcip, pp, tw);
5238 tw = tw_list;
5239 }
5240 return (error);
5241 } else {
5242 if (tw_list == NULL) {
5243 tw_list = tw;
5244 }
5245 }
5246 }
5247
5248 i = 0;
5249 while (pp->pp_cur_periodic_req_cnt < pp->pp_max_periodic_req_cnt) {
5250
5251 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5252 "ohci_start_pipe_polling: max = %d curr = %d tw = %p:",
5253 pp->pp_max_periodic_req_cnt, pp->pp_cur_periodic_req_cnt,
5254 (void *)tw_list);
5255
5256 tw = tw_list;
5257 tw_list = tw->tw_next;
5258
5259 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
5260 case USB_EP_ATTR_INTR:
5261 ohci_insert_intr_req(ohcip, pp, tw, flags);
5262 break;
5263 case USB_EP_ATTR_ISOCH:
5264 error = ohci_insert_isoc_req(ohcip, pp, tw, flags);
5265 break;
5266 }
5267 if (error == USB_SUCCESS) {
5268 pp->pp_cur_periodic_req_cnt++;
5269 } else {
5270 /*
5271 * Deallocate the remaining tw
5272 * The current tw should have already been deallocated
5273 */
5274 tw = tw_list;
5275 while (tw != NULL) {
5276 tw_list = tw->tw_next;
5277 ohci_deallocate_periodic_in_resource(
5278 ohcip, pp, tw);
5279 ohci_deallocate_tw_resources(ohcip, pp, tw);
5280 tw = tw_list;
5281 }
5282 /*
5283 * If this is the first req return an error.
5284 * Otherwise return success.
5285 */
5286 if (i != 0) {
5287 error = USB_SUCCESS;
5288 }
5289
5290 break;
5291 }
5292 i++;
5293 }
5294
5295 return (error);
5296 }
5297
5298
5299 /*
5300 * ohci_set_periodic_pipe_polling:
5301 *
5302 * Calculate the number of periodic requests needed corresponding to the
5303 * interrupt/isochronous IN endpoints polling interval. Table below gives
5304 * the number of periodic requests needed for the interrupt/isochronous
5305 * IN endpoints according to endpoint polling interval.
5306 *
5307 * Polling interval Number of periodic requests
5308 *
5309 * 1ms 4
5310 * 2ms 2
5311 * 4ms to 32ms 1
5312 */
5313 static void
ohci_set_periodic_pipe_polling(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)5314 ohci_set_periodic_pipe_polling(
5315 ohci_state_t *ohcip,
5316 usba_pipe_handle_data_t *ph)
5317 {
5318 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5319 usb_ep_descr_t *endpoint = &ph->p_ep;
5320 uchar_t ep_attr = endpoint->bmAttributes;
5321 uint_t interval;
5322
5323 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5324 "ohci_set_periodic_pipe_polling:");
5325
5326 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5327
5328 pp->pp_cur_periodic_req_cnt = 0;
5329
5330 /*
5331 * Check usb flag whether USB_FLAGS_ONE_TIME_POLL flag is
5332 * set and if so, set pp->pp_max_periodic_req_cnt to one.
5333 */
5334 if (((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) &&
5335 (pp->pp_client_periodic_in_reqp)) {
5336 usb_intr_req_t *intr_reqp =
5337 (usb_intr_req_t *)pp->pp_client_periodic_in_reqp;
5338
5339 if (intr_reqp->intr_attributes &
5340 USB_ATTRS_ONE_XFER) {
5341
5342 pp->pp_max_periodic_req_cnt = INTR_XMS_REQS;
5343
5344 return;
5345 }
5346 }
5347
5348 mutex_enter(&ph->p_usba_device->usb_mutex);
5349
5350 /*
5351 * The ohci_adjust_polling_interval function will not fail
5352 * at this instance since bandwidth allocation is already
5353 * done. Here we are getting only the periodic interval.
5354 */
5355 interval = ohci_adjust_polling_interval(ohcip, endpoint,
5356 ph->p_usba_device->usb_port_status);
5357
5358 mutex_exit(&ph->p_usba_device->usb_mutex);
5359
5360 switch (interval) {
5361 case INTR_1MS_POLL:
5362 pp->pp_max_periodic_req_cnt = INTR_1MS_REQS;
5363 break;
5364 case INTR_2MS_POLL:
5365 pp->pp_max_periodic_req_cnt = INTR_2MS_REQS;
5366 break;
5367 default:
5368 pp->pp_max_periodic_req_cnt = INTR_XMS_REQS;
5369 break;
5370 }
5371
5372 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5373 "ohci_set_periodic_pipe_polling: Max periodic requests = %d",
5374 pp->pp_max_periodic_req_cnt);
5375 }
5376
5377 /*
5378 * ohci_allocate_intr_resources:
5379 *
5380 * Calculates the number of tds necessary for a intr transfer, and allocates
5381 * all the necessary resources.
5382 *
5383 * Returns NULL if there is insufficient resources otherwise TW.
5384 */
5385 static ohci_trans_wrapper_t *
ohci_allocate_intr_resources(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_intr_req_t * intr_reqp,usb_flags_t flags)5386 ohci_allocate_intr_resources(
5387 ohci_state_t *ohcip,
5388 usba_pipe_handle_data_t *ph,
5389 usb_intr_req_t *intr_reqp,
5390 usb_flags_t flags)
5391 {
5392 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5393 int pipe_dir;
5394 size_t td_count = 1;
5395 size_t tw_length;
5396 ohci_trans_wrapper_t *tw;
5397
5398 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5399 "ohci_allocate_intr_resources:");
5400
5401 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5402
5403 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
5404
5405 /* Get the length of interrupt transfer & alloc data */
5406 if (intr_reqp) {
5407 tw_length = intr_reqp->intr_len;
5408 } else {
5409 ASSERT(pipe_dir == USB_EP_DIR_IN);
5410 tw_length = (pp->pp_client_periodic_in_reqp) ?
5411 (((usb_intr_req_t *)pp->
5412 pp_client_periodic_in_reqp)->intr_len) :
5413 ph->p_ep.wMaxPacketSize;
5414 }
5415
5416 /* Check the size of interrupt request */
5417 if (tw_length > OHCI_MAX_TD_XFER_SIZE) {
5418
5419 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5420 "ohci_allocate_intr_resources: Intr request size 0x%lx is "
5421 "more than 0x%x", tw_length, OHCI_MAX_TD_XFER_SIZE);
5422
5423 return (NULL);
5424 }
5425
5426 if ((tw = ohci_allocate_tw_resources(ohcip, pp, tw_length,
5427 flags, td_count)) == NULL) {
5428
5429 return (NULL);
5430 }
5431
5432 if (pipe_dir == USB_EP_DIR_IN) {
5433 if (ohci_allocate_periodic_in_resource(ohcip, pp, tw, flags) !=
5434 USB_SUCCESS) {
5435
5436 ohci_deallocate_tw_resources(ohcip, pp, tw);
5437 return (NULL);
5438 }
5439 tw->tw_direction = HC_TD_IN;
5440 } else {
5441 if (tw_length) {
5442 ASSERT(intr_reqp->intr_data != NULL);
5443
5444 /* Copy the data into the message */
5445 ddi_rep_put8(tw->tw_accesshandle,
5446 intr_reqp->intr_data->b_rptr, (uint8_t *)tw->tw_buf,
5447 intr_reqp->intr_len, DDI_DEV_AUTOINCR);
5448 }
5449
5450 tw->tw_curr_xfer_reqp = (usb_opaque_t)intr_reqp;
5451 tw->tw_direction = HC_TD_OUT;
5452 }
5453
5454 if (intr_reqp) {
5455 tw->tw_timeout = intr_reqp->intr_timeout;
5456 }
5457
5458 /*
5459 * Initialize the callback and any callback
5460 * data required when the td completes.
5461 */
5462 tw->tw_handle_td = ohci_handle_intr_td;
5463 tw->tw_handle_callback_value = NULL;
5464
5465 return (tw);
5466 }
5467
5468 /*
5469 * ohci_insert_intr_req:
5470 *
5471 * Insert an Interrupt request into the Host Controller's periodic list.
5472 */
5473 /* ARGSUSED */
5474 static void
ohci_insert_intr_req(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,usb_flags_t flags)5475 ohci_insert_intr_req(
5476 ohci_state_t *ohcip,
5477 ohci_pipe_private_t *pp,
5478 ohci_trans_wrapper_t *tw,
5479 usb_flags_t flags)
5480 {
5481 usb_intr_req_t *curr_intr_reqp = NULL;
5482 uint_t ctrl = 0;
5483
5484 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5485
5486 ASSERT(tw->tw_curr_xfer_reqp != NULL);
5487
5488 /* Get the current interrupt request pointer */
5489 curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
5490
5491 ctrl = tw->tw_direction | HC_TD_DT_0 | HC_TD_1I;
5492
5493 if (curr_intr_reqp->intr_attributes & USB_ATTRS_SHORT_XFER_OK) {
5494 ctrl |= HC_TD_R;
5495 }
5496
5497 /* Insert another interrupt TD */
5498 (void) ohci_insert_hc_td(ohcip, ctrl, 0, tw->tw_length, 0, pp, tw);
5499
5500 /* Start the timer for this Interrupt transfer */
5501 ohci_start_xfer_timer(ohcip, pp, tw);
5502 }
5503
5504
5505 /*
5506 * ohci_stop_periodic_pipe_polling:
5507 */
5508 /* ARGSUSED */
5509 static int
ohci_stop_periodic_pipe_polling(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_flags_t flags)5510 ohci_stop_periodic_pipe_polling(
5511 ohci_state_t *ohcip,
5512 usba_pipe_handle_data_t *ph,
5513 usb_flags_t flags)
5514 {
5515 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5516 usb_ep_descr_t *eptd = &ph->p_ep;
5517
5518 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5519 "ohci_stop_periodic_pipe_polling: Flags = 0x%x", flags);
5520
5521 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5522
5523 /*
5524 * Check and handle stop polling on root hub interrupt pipe.
5525 */
5526 if ((ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) &&
5527 ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
5528 USB_EP_ATTR_INTR)) {
5529
5530 ohci_handle_root_hub_pipe_stop_intr_polling(
5531 ph, flags);
5532 return (USB_SUCCESS);
5533 }
5534
5535 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) {
5536
5537 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5538 "ohci_stop_periodic_pipe_polling: Polling already stopped");
5539
5540 return (USB_SUCCESS);
5541 }
5542
5543 /* Set pipe state to pipe stop polling */
5544 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
5545
5546 ohci_pipe_cleanup(ohcip, ph);
5547
5548 return (USB_SUCCESS);
5549 }
5550
5551 /*
5552 * ohci_allocate_isoc_resources:
5553 *
5554 * Calculates the number of tds necessary for a intr transfer, and allocates
5555 * all the necessary resources.
5556 *
5557 * Returns NULL if there is insufficient resources otherwise TW.
5558 */
5559 static ohci_trans_wrapper_t *
ohci_allocate_isoc_resources(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph,usb_isoc_req_t * isoc_reqp,usb_flags_t flags)5560 ohci_allocate_isoc_resources(
5561 ohci_state_t *ohcip,
5562 usba_pipe_handle_data_t *ph,
5563 usb_isoc_req_t *isoc_reqp,
5564 usb_flags_t flags)
5565 {
5566 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
5567 int pipe_dir;
5568 uint_t max_pkt_size = ph->p_ep.wMaxPacketSize;
5569 uint_t max_isoc_xfer_size;
5570 usb_isoc_pkt_descr_t *isoc_pkt_descr, *start_isoc_pkt_descr;
5571 ushort_t isoc_pkt_count;
5572 size_t count, td_count;
5573 size_t tw_length;
5574 size_t isoc_pkts_length;
5575 ohci_trans_wrapper_t *tw;
5576
5577
5578 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5579 "ohci_allocate_isoc_resources: flags = ox%x", flags);
5580
5581 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5582
5583 /*
5584 * Check whether pipe is in halted state.
5585 */
5586 if (pp->pp_state == OHCI_PIPE_STATE_ERROR) {
5587 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5588 "ohci_allocate_isoc_resources:"
5589 "Pipe is in error state, need pipe reset to continue");
5590
5591 return (NULL);
5592 }
5593
5594 pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK;
5595
5596 /* Calculate the maximum isochronous transfer size */
5597 max_isoc_xfer_size = OHCI_MAX_ISOC_PKTS_PER_XFER * max_pkt_size;
5598
5599 if (isoc_reqp) {
5600 isoc_pkt_descr = isoc_reqp->isoc_pkt_descr;
5601 isoc_pkt_count = isoc_reqp->isoc_pkts_count;
5602 isoc_pkts_length = isoc_reqp->isoc_pkts_length;
5603 } else {
5604 isoc_pkt_descr = ((usb_isoc_req_t *)
5605 pp->pp_client_periodic_in_reqp)->isoc_pkt_descr;
5606
5607 isoc_pkt_count = ((usb_isoc_req_t *)
5608 pp->pp_client_periodic_in_reqp)->isoc_pkts_count;
5609
5610 isoc_pkts_length = ((usb_isoc_req_t *)
5611 pp->pp_client_periodic_in_reqp)->isoc_pkts_length;
5612 }
5613
5614 start_isoc_pkt_descr = isoc_pkt_descr;
5615
5616 /*
5617 * For isochronous IN pipe, get value of number of isochronous
5618 * packets per usb isochronous request
5619 */
5620 if (pipe_dir == USB_EP_DIR_IN) {
5621 for (count = 0, tw_length = 0;
5622 count < isoc_pkt_count; count++) {
5623 tw_length += isoc_pkt_descr->isoc_pkt_length;
5624 isoc_pkt_descr++;
5625 }
5626
5627 if ((isoc_pkts_length) && (isoc_pkts_length != tw_length)) {
5628
5629 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5630 "ohci_allocate_isoc_resources: "
5631 "isoc_pkts_length 0x%lx is not equal to the sum of "
5632 "all pkt lengths 0x%lx in an isoc request",
5633 isoc_pkts_length, tw_length);
5634
5635 return (NULL);
5636 }
5637
5638 } else {
5639 ASSERT(isoc_reqp != NULL);
5640 tw_length = MBLKL(isoc_reqp->isoc_data);
5641 }
5642
5643 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5644 "ohci_allocate_isoc_resources: length = 0x%lx", tw_length);
5645
5646 /* Check the size of isochronous request */
5647 if (tw_length > max_isoc_xfer_size) {
5648
5649 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5650 "ohci_allocate_isoc_resources: Maximum isoc request"
5651 "size 0x%x Given isoc request size 0x%lx",
5652 max_isoc_xfer_size, tw_length);
5653
5654 return (NULL);
5655 }
5656
5657 /*
5658 * Each isochronous TD can hold data upto eight isochronous
5659 * data packets. Calculate the number of isochronous TDs needs
5660 * to be insert to complete current isochronous request.
5661 */
5662 td_count = isoc_pkt_count / OHCI_ISOC_PKTS_PER_TD;
5663
5664 if (isoc_pkt_count % OHCI_ISOC_PKTS_PER_TD) {
5665 td_count++;
5666 }
5667
5668 tw = ohci_create_isoc_transfer_wrapper(ohcip, pp, tw_length,
5669 start_isoc_pkt_descr, isoc_pkt_count, td_count, flags);
5670
5671 if (tw == NULL) {
5672 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5673 "ohci_create_isoc_transfer_wrapper: "
5674 "Unable to allocate TW");
5675
5676 return (NULL);
5677 }
5678
5679 if (ohci_allocate_tds_for_tw(ohcip, tw, td_count) ==
5680 USB_SUCCESS) {
5681 tw->tw_num_tds = (uint_t)td_count;
5682 } else {
5683 ohci_deallocate_tw_resources(ohcip, pp, tw);
5684
5685 return (NULL);
5686 }
5687
5688 if (pipe_dir == USB_EP_DIR_IN) {
5689 if (ohci_allocate_periodic_in_resource(ohcip, pp, tw, flags) !=
5690 USB_SUCCESS) {
5691
5692 ohci_deallocate_tw_resources(ohcip, pp, tw);
5693 return (NULL);
5694 }
5695 tw->tw_direction = HC_TD_IN;
5696 } else {
5697 if (tw->tw_length) {
5698 uchar_t *p;
5699 int i;
5700
5701 ASSERT(isoc_reqp->isoc_data != NULL);
5702 p = isoc_reqp->isoc_data->b_rptr;
5703
5704 /* Copy the data into the message */
5705 for (i = 0; i < td_count; i++) {
5706 ddi_rep_put8(
5707 tw->tw_isoc_bufs[i].mem_handle, p,
5708 (uint8_t *)tw->tw_isoc_bufs[i].buf_addr,
5709 tw->tw_isoc_bufs[i].length,
5710 DDI_DEV_AUTOINCR);
5711 p += tw->tw_isoc_bufs[i].length;
5712 }
5713 }
5714 tw->tw_curr_xfer_reqp = (usb_opaque_t)isoc_reqp;
5715 tw->tw_direction = HC_TD_OUT;
5716 }
5717
5718 /*
5719 * Initialize the callback and any callback
5720 * data required when the td completes.
5721 */
5722 tw->tw_handle_td = ohci_handle_isoc_td;
5723 tw->tw_handle_callback_value = NULL;
5724
5725 return (tw);
5726 }
5727
5728 /*
5729 * ohci_insert_isoc_req:
5730 *
5731 * Insert an isochronous request into the Host Controller's
5732 * isochronous list. If there is an error is will appropriately
5733 * deallocate the unused resources.
5734 */
5735 static int
ohci_insert_isoc_req(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,uint_t flags)5736 ohci_insert_isoc_req(
5737 ohci_state_t *ohcip,
5738 ohci_pipe_private_t *pp,
5739 ohci_trans_wrapper_t *tw,
5740 uint_t flags)
5741 {
5742 size_t curr_isoc_xfer_offset, curr_isoc_xfer_len;
5743 uint_t isoc_pkts, residue, count;
5744 uint_t i, ctrl, frame_count;
5745 uint_t error = USB_SUCCESS;
5746 usb_isoc_req_t *curr_isoc_reqp;
5747 usb_isoc_pkt_descr_t *curr_isoc_pkt_descr;
5748
5749 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5750 "ohci_insert_isoc_req: flags = 0x%x", flags);
5751
5752 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5753
5754 /*
5755 * Get the current isochronous request and packet
5756 * descriptor pointers.
5757 */
5758 curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
5759 curr_isoc_pkt_descr = curr_isoc_reqp->isoc_pkt_descr;
5760
5761 ASSERT(curr_isoc_reqp != NULL);
5762 ASSERT(curr_isoc_reqp->isoc_pkt_descr != NULL);
5763
5764 /*
5765 * Save address of first usb isochronous packet descriptor.
5766 */
5767 tw->tw_curr_isoc_pktp = curr_isoc_reqp->isoc_pkt_descr;
5768
5769 /* Insert all the isochronous TDs */
5770 for (count = 0, curr_isoc_xfer_offset = 0,
5771 isoc_pkts = 0; count < tw->tw_num_tds; count++) {
5772
5773 residue = curr_isoc_reqp->isoc_pkts_count - isoc_pkts;
5774
5775 /* Check for inserting residue data */
5776 if ((count == (tw->tw_num_tds - 1)) &&
5777 (residue < OHCI_ISOC_PKTS_PER_TD)) {
5778 frame_count = residue;
5779 } else {
5780 frame_count = OHCI_ISOC_PKTS_PER_TD;
5781 }
5782
5783 curr_isoc_pkt_descr = tw->tw_curr_isoc_pktp;
5784
5785 /*
5786 * Calculate length of isochronous transfer
5787 * for the current TD.
5788 */
5789 for (i = 0, curr_isoc_xfer_len = 0;
5790 i < frame_count; i++, curr_isoc_pkt_descr++) {
5791 curr_isoc_xfer_len +=
5792 curr_isoc_pkt_descr->isoc_pkt_length;
5793 }
5794
5795 /*
5796 * Programm td control field by checking whether this
5797 * is last td.
5798 */
5799 if (count == (tw->tw_num_tds - 1)) {
5800 ctrl = ((((frame_count - 1) << HC_ITD_FC_SHIFT) &
5801 HC_ITD_FC) | HC_TD_DT_0 | HC_TD_0I);
5802 } else {
5803 ctrl = ((((frame_count - 1) << HC_ITD_FC_SHIFT) &
5804 HC_ITD_FC) | HC_TD_DT_0 | HC_TD_6I);
5805 }
5806
5807 /* Insert the TD into the endpoint */
5808 if ((error = ohci_insert_hc_td(ohcip, ctrl, count,
5809 curr_isoc_xfer_len, 0, pp, tw)) !=
5810 USB_SUCCESS) {
5811 tw->tw_num_tds = count;
5812 tw->tw_length = curr_isoc_xfer_offset;
5813 break;
5814 }
5815
5816 isoc_pkts += frame_count;
5817 tw->tw_curr_isoc_pktp += frame_count;
5818 curr_isoc_xfer_offset += curr_isoc_xfer_len;
5819 }
5820
5821 if (error != USB_SUCCESS) {
5822 /* Free periodic in resources */
5823 if (tw->tw_direction == USB_EP_DIR_IN) {
5824 ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
5825 }
5826
5827 /* Free all resources if IN or if count == 0(for both IN/OUT) */
5828 if (tw->tw_direction == USB_EP_DIR_IN || count == 0) {
5829
5830 ohci_deallocate_tw_resources(ohcip, pp, tw);
5831
5832 if (pp->pp_cur_periodic_req_cnt) {
5833 /*
5834 * Set pipe state to stop polling and
5835 * error to no resource. Don't insert
5836 * any more isochronous polling requests.
5837 */
5838 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
5839 pp->pp_error = error;
5840 } else {
5841 /* Set periodic in pipe state to idle */
5842 pp->pp_state = OHCI_PIPE_STATE_IDLE;
5843 }
5844 }
5845 } else {
5846
5847 /*
5848 * Reset back to the address of first usb isochronous
5849 * packet descriptor.
5850 */
5851 tw->tw_curr_isoc_pktp = curr_isoc_reqp->isoc_pkt_descr;
5852
5853 /* Reset the CONTINUE flag */
5854 pp->pp_flag &= ~OHCI_ISOC_XFER_CONTINUE;
5855 }
5856
5857 return (error);
5858 }
5859
5860
5861 /*
5862 * ohci_insert_hc_td:
5863 *
5864 * Insert a Transfer Descriptor (TD) on an Endpoint Descriptor (ED).
5865 * Always returns USB_SUCCESS, except for ISOCH.
5866 */
5867 static int
ohci_insert_hc_td(ohci_state_t * ohcip,uint_t hctd_ctrl,uint32_t hctd_dma_offs,size_t hctd_length,uint32_t hctd_ctrl_phase,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)5868 ohci_insert_hc_td(
5869 ohci_state_t *ohcip,
5870 uint_t hctd_ctrl,
5871 uint32_t hctd_dma_offs,
5872 size_t hctd_length,
5873 uint32_t hctd_ctrl_phase,
5874 ohci_pipe_private_t *pp,
5875 ohci_trans_wrapper_t *tw)
5876 {
5877 ohci_td_t *new_dummy;
5878 ohci_td_t *cpu_current_dummy;
5879 ohci_ed_t *ept = pp->pp_ept;
5880 int error;
5881
5882 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5883
5884 /* Retrieve preallocated td from the TW */
5885 new_dummy = tw->tw_hctd_free_list;
5886
5887 ASSERT(new_dummy != NULL);
5888
5889 tw->tw_hctd_free_list = ohci_td_iommu_to_cpu(ohcip,
5890 Get_TD(new_dummy->hctd_tw_next_td));
5891 Set_TD(new_dummy->hctd_tw_next_td, NULL);
5892
5893 /* Fill in the current dummy */
5894 cpu_current_dummy = (ohci_td_t *)
5895 (ohci_td_iommu_to_cpu(ohcip, Get_ED(ept->hced_tailp)));
5896
5897 /*
5898 * Fill in the current dummy td and
5899 * add the new dummy to the end.
5900 */
5901 ohci_fill_in_td(ohcip, cpu_current_dummy, new_dummy,
5902 hctd_ctrl, hctd_dma_offs, hctd_length, hctd_ctrl_phase, pp, tw);
5903
5904 /*
5905 * If this is an isochronous TD, first write proper
5906 * starting usb frame number in which this TD must
5907 * can be processed. After writing the frame number
5908 * insert this TD into the ED's list.
5909 */
5910 if ((pp->pp_pipe_handle->p_ep.bmAttributes &
5911 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
5912
5913 error = ohci_insert_td_with_frame_number(
5914 ohcip, pp, tw, cpu_current_dummy, new_dummy);
5915
5916 if (error != USB_SUCCESS) {
5917 /* Reset the current dummy back to a dummy */
5918 bzero((char *)cpu_current_dummy, sizeof (ohci_td_t));
5919 Set_TD(cpu_current_dummy->hctd_state, HC_TD_DUMMY);
5920
5921 /* return the new dummy back to the free list */
5922 bzero((char *)new_dummy, sizeof (ohci_td_t));
5923 Set_TD(new_dummy->hctd_state, HC_TD_DUMMY);
5924 if (tw->tw_hctd_free_list != NULL) {
5925 Set_TD(new_dummy->hctd_tw_next_td,
5926 ohci_td_cpu_to_iommu(ohcip,
5927 tw->tw_hctd_free_list));
5928 }
5929 tw->tw_hctd_free_list = new_dummy;
5930
5931 return (error);
5932 }
5933 } else {
5934 /*
5935 * For control, bulk and interrupt TD, just
5936 * add the new dummy to the ED's list. When
5937 * this occurs, the Host Controller ill see
5938 * the newly filled in dummy TD.
5939 */
5940 Set_ED(ept->hced_tailp,
5941 (ohci_td_cpu_to_iommu(ohcip, new_dummy)));
5942 }
5943
5944 /* Insert this td onto the tw */
5945 ohci_insert_td_on_tw(ohcip, tw, cpu_current_dummy);
5946
5947 return (USB_SUCCESS);
5948 }
5949
5950
5951 /*
5952 * ohci_allocate_td_from_pool:
5953 *
5954 * Allocate a Transfer Descriptor (TD) from the TD buffer pool.
5955 */
5956 static ohci_td_t *
ohci_allocate_td_from_pool(ohci_state_t * ohcip)5957 ohci_allocate_td_from_pool(ohci_state_t *ohcip)
5958 {
5959 int i, state;
5960 ohci_td_t *td;
5961
5962 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
5963
5964 /*
5965 * Search for a blank Transfer Descriptor (TD)
5966 * in the TD buffer pool.
5967 */
5968 for (i = 0; i < ohci_td_pool_size; i ++) {
5969 state = Get_TD(ohcip->ohci_td_pool_addr[i].hctd_state);
5970 if (state == HC_TD_FREE) {
5971 break;
5972 }
5973 }
5974
5975 if (i >= ohci_td_pool_size) {
5976 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
5977 "ohci_allocate_td_from_pool: TD exhausted");
5978
5979 return (NULL);
5980 }
5981
5982 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
5983 "ohci_allocate_td_from_pool: Allocated %d", i);
5984
5985 /* Create a new dummy for the end of the TD list */
5986 td = &ohcip->ohci_td_pool_addr[i];
5987
5988 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
5989 "ohci_allocate_td_from_pool: td 0x%p", (void *)td);
5990
5991 /* Mark the newly allocated TD as a dummy */
5992 Set_TD(td->hctd_state, HC_TD_DUMMY);
5993
5994 return (td);
5995 }
5996
5997 /*
5998 * ohci_fill_in_td:
5999 *
6000 * Fill in the fields of a Transfer Descriptor (TD).
6001 *
6002 * hctd_dma_offs - different meanings for non-isoc and isoc TDs:
6003 * starting offset into the TW buffer for a non-isoc TD
6004 * and the index into the isoc TD list for an isoc TD.
6005 * For non-isoc TDs, the starting offset should be 4k
6006 * aligned and the TDs in one transfer must be filled in
6007 * increasing order.
6008 */
6009 static void
ohci_fill_in_td(ohci_state_t * ohcip,ohci_td_t * td,ohci_td_t * new_dummy,uint_t hctd_ctrl,uint32_t hctd_dma_offs,size_t hctd_length,uint32_t hctd_ctrl_phase,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)6010 ohci_fill_in_td(
6011 ohci_state_t *ohcip,
6012 ohci_td_t *td,
6013 ohci_td_t *new_dummy,
6014 uint_t hctd_ctrl,
6015 uint32_t hctd_dma_offs,
6016 size_t hctd_length,
6017 uint32_t hctd_ctrl_phase,
6018 ohci_pipe_private_t *pp,
6019 ohci_trans_wrapper_t *tw)
6020 {
6021 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6022 "ohci_fill_in_td: td 0x%p bufoffs 0x%x len 0x%lx",
6023 (void *)td, hctd_dma_offs, hctd_length);
6024
6025 /* Assert that the td to be filled in is a dummy */
6026 ASSERT(Get_TD(td->hctd_state) == HC_TD_DUMMY);
6027
6028 /* Change TD's state Active */
6029 Set_TD(td->hctd_state, HC_TD_ACTIVE);
6030
6031 /* Update the TD special fields */
6032 if ((pp->pp_pipe_handle->p_ep.bmAttributes &
6033 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
6034 ohci_init_itd(ohcip, tw, hctd_ctrl, hctd_dma_offs, td);
6035 } else {
6036 /* Update the dummy with control information */
6037 Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA));
6038
6039 ohci_init_td(ohcip, tw, hctd_dma_offs, hctd_length, td);
6040 }
6041
6042 /* The current dummy now points to the new dummy */
6043 Set_TD(td->hctd_next_td, (ohci_td_cpu_to_iommu(ohcip, new_dummy)));
6044
6045 /*
6046 * For Control transfer, hctd_ctrl_phase is a valid field.
6047 */
6048 if (hctd_ctrl_phase) {
6049 Set_TD(td->hctd_ctrl_phase, hctd_ctrl_phase);
6050 }
6051
6052 /* Print the td */
6053 ohci_print_td(ohcip, td);
6054
6055 /* Fill in the wrapper portion of the TD */
6056
6057 /* Set the transfer wrapper */
6058 ASSERT(tw != NULL);
6059 ASSERT(tw->tw_id != NULL);
6060
6061 Set_TD(td->hctd_trans_wrapper, (uint32_t)tw->tw_id);
6062 Set_TD(td->hctd_tw_next_td, NULL);
6063 }
6064
6065
6066 /*
6067 * ohci_init_td:
6068 *
6069 * Initialize the buffer address portion of non-isoc Transfer
6070 * Descriptor (TD).
6071 */
6072 void
ohci_init_td(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw,uint32_t hctd_dma_offs,size_t hctd_length,ohci_td_t * td)6073 ohci_init_td(
6074 ohci_state_t *ohcip,
6075 ohci_trans_wrapper_t *tw,
6076 uint32_t hctd_dma_offs,
6077 size_t hctd_length,
6078 ohci_td_t *td)
6079 {
6080 uint32_t page_addr, start_addr = 0, end_addr = 0;
6081 size_t buf_len = hctd_length;
6082 int rem_len, i;
6083
6084 /*
6085 * TDs must be filled in increasing DMA offset order.
6086 * tw_dma_offs is initialized to be 0 at TW creation and
6087 * is only increased in this function.
6088 */
6089 ASSERT(buf_len == 0 || hctd_dma_offs >= tw->tw_dma_offs);
6090
6091 Set_TD(td->hctd_xfer_offs, hctd_dma_offs);
6092 Set_TD(td->hctd_xfer_len, buf_len);
6093
6094 /* Computing the starting buffer address and end buffer address */
6095 for (i = 0; (i < 2) && (buf_len > 0); i++) {
6096 /* Advance to the next DMA cookie if necessary */
6097 if ((tw->tw_dma_offs + tw->tw_cookie.dmac_size) <=
6098 hctd_dma_offs) {
6099 /*
6100 * tw_dma_offs always points to the starting offset
6101 * of a cookie
6102 */
6103 tw->tw_dma_offs += tw->tw_cookie.dmac_size;
6104 ddi_dma_nextcookie(tw->tw_dmahandle, &tw->tw_cookie);
6105 tw->tw_cookie_idx++;
6106 ASSERT(tw->tw_cookie_idx < tw->tw_ncookies);
6107 }
6108
6109 ASSERT((tw->tw_dma_offs + tw->tw_cookie.dmac_size) >
6110 hctd_dma_offs);
6111
6112 /*
6113 * Counting the remained buffer length to be filled in
6114 * the TD for current DMA cookie
6115 */
6116 rem_len = (tw->tw_dma_offs + tw->tw_cookie.dmac_size) -
6117 hctd_dma_offs;
6118
6119 /* Get the beginning address of the buffer */
6120 page_addr = (hctd_dma_offs - tw->tw_dma_offs) +
6121 tw->tw_cookie.dmac_address;
6122 ASSERT((page_addr % OHCI_4K_ALIGN) == 0);
6123
6124 if (i == 0) {
6125 start_addr = page_addr;
6126 }
6127
6128 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6129 "ohci_init_td: page_addr 0x%x dmac_size "
6130 "0x%lx idx %d", page_addr, tw->tw_cookie.dmac_size,
6131 tw->tw_cookie_idx);
6132
6133 if (buf_len <= OHCI_MAX_TD_BUF_SIZE) {
6134 ASSERT(buf_len <= rem_len);
6135 end_addr = page_addr + buf_len - 1;
6136 buf_len = 0;
6137 break;
6138 } else {
6139 ASSERT(rem_len >= OHCI_MAX_TD_BUF_SIZE);
6140 buf_len -= OHCI_MAX_TD_BUF_SIZE;
6141 hctd_dma_offs += OHCI_MAX_TD_BUF_SIZE;
6142 }
6143 }
6144
6145 ASSERT(buf_len == 0);
6146
6147 Set_TD(td->hctd_cbp, start_addr);
6148 Set_TD(td->hctd_buf_end, end_addr);
6149 }
6150
6151
6152 /*
6153 * ohci_init_itd:
6154 *
6155 * Initialize the buffer address portion of isoc Transfer Descriptor (TD).
6156 */
6157 static void
ohci_init_itd(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw,uint_t hctd_ctrl,uint32_t index,ohci_td_t * td)6158 ohci_init_itd(
6159 ohci_state_t *ohcip,
6160 ohci_trans_wrapper_t *tw,
6161 uint_t hctd_ctrl,
6162 uint32_t index,
6163 ohci_td_t *td)
6164 {
6165 uint32_t start_addr, end_addr, offset, offset_addr;
6166 ohci_isoc_buf_t *bufp;
6167 size_t buf_len;
6168 uint_t buf, fc, toggle, flag;
6169 usb_isoc_pkt_descr_t *temp_pkt_descr;
6170 int i;
6171
6172 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6173
6174 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6175 "ohci_init_itd: ctrl = 0x%x", hctd_ctrl);
6176
6177 /*
6178 * Write control information except starting
6179 * usb frame number.
6180 */
6181 Set_TD(td->hctd_ctrl, (hctd_ctrl | HC_TD_CC_NA));
6182
6183 bufp = &tw->tw_isoc_bufs[index];
6184 Set_TD(td->hctd_xfer_offs, index);
6185 Set_TD(td->hctd_xfer_len, bufp->length);
6186
6187 start_addr = bufp->cookie.dmac_address;
6188 ASSERT((start_addr % OHCI_4K_ALIGN) == 0);
6189
6190 buf_len = bufp->length;
6191 if (bufp->ncookies == OHCI_DMA_ATTR_TD_SGLLEN) {
6192 buf_len = bufp->length - bufp->cookie.dmac_size;
6193 ddi_dma_nextcookie(bufp->dma_handle, &bufp->cookie);
6194 }
6195 end_addr = bufp->cookie.dmac_address + buf_len - 1;
6196
6197 /*
6198 * For an isochronous transfer, the hctd_cbp contains,
6199 * the 4k page, and not the actual start of the buffer.
6200 */
6201 Set_TD(td->hctd_cbp, ((uint32_t)start_addr & HC_ITD_PAGE_MASK));
6202 Set_TD(td->hctd_buf_end, end_addr);
6203
6204 fc = (hctd_ctrl & HC_ITD_FC) >> HC_ITD_FC_SHIFT;
6205 toggle = 0;
6206 buf = start_addr;
6207
6208 /*
6209 * Get the address of first isochronous data packet
6210 * for the current isochronous TD.
6211 */
6212 temp_pkt_descr = tw->tw_curr_isoc_pktp;
6213
6214 /* The offsets are actually offsets into the page */
6215 for (i = 0; i <= fc; i++) {
6216 offset_addr = (uint32_t)((buf &
6217 HC_ITD_OFFSET_ADDR) | (HC_ITD_OFFSET_CC));
6218
6219 flag = ((start_addr &
6220 HC_ITD_PAGE_MASK) ^ (buf & HC_ITD_PAGE_MASK));
6221
6222 if (flag) {
6223 offset_addr |= HC_ITD_4KBOUNDARY_CROSS;
6224 }
6225
6226 if (toggle) {
6227 offset = (uint32_t)((offset_addr <<
6228 HC_ITD_OFFSET_SHIFT) & HC_ITD_ODD_OFFSET);
6229
6230 Set_TD(td->hctd_offsets[i / 2],
6231 Get_TD(td->hctd_offsets[i / 2]) | offset);
6232 toggle = 0;
6233 } else {
6234 offset = (uint32_t)(offset_addr & HC_ITD_EVEN_OFFSET);
6235
6236 Set_TD(td->hctd_offsets[i / 2],
6237 Get_TD(td->hctd_offsets[i / 2]) | offset);
6238 toggle = 1;
6239 }
6240
6241 buf = (uint32_t)(buf + temp_pkt_descr->isoc_pkt_length);
6242 temp_pkt_descr++;
6243 }
6244 }
6245
6246
6247 /*
6248 * ohci_insert_td_with_frame_number:
6249 *
6250 * Insert current isochronous TD into the ED's list. with proper
6251 * usb frame number in which this TD can be processed.
6252 */
6253 static int
ohci_insert_td_with_frame_number(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * current_td,ohci_td_t * dummy_td)6254 ohci_insert_td_with_frame_number(
6255 ohci_state_t *ohcip,
6256 ohci_pipe_private_t *pp,
6257 ohci_trans_wrapper_t *tw,
6258 ohci_td_t *current_td,
6259 ohci_td_t *dummy_td)
6260 {
6261 usb_isoc_req_t *isoc_reqp =
6262 (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
6263 usb_frame_number_t current_frame_number, start_frame_number;
6264 uint_t ddic, ctrl, isoc_pkts;
6265 ohci_ed_t *ept = pp->pp_ept;
6266
6267 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6268 "ohci_insert_td_with_frame_number:"
6269 "isoc flags 0x%x", isoc_reqp->isoc_attributes);
6270
6271 /* Get the TD ctrl information */
6272 isoc_pkts = ((Get_TD(current_td->hctd_ctrl) &
6273 HC_ITD_FC) >> HC_ITD_FC_SHIFT) + 1;
6274
6275 /*
6276 * Enter critical, while programming the usb frame number
6277 * and inserting current isochronous TD into the ED's list.
6278 */
6279 ddic = ddi_enter_critical();
6280
6281 /* Get the current frame number */
6282 current_frame_number = ohci_get_current_frame_number(ohcip);
6283
6284 /* Check the given isochronous flags */
6285 switch (isoc_reqp->isoc_attributes &
6286 (USB_ATTRS_ISOC_START_FRAME | USB_ATTRS_ISOC_XFER_ASAP)) {
6287 case USB_ATTRS_ISOC_START_FRAME:
6288 /* Starting frame number is specified */
6289 if (pp->pp_flag & OHCI_ISOC_XFER_CONTINUE) {
6290 /* Get the starting usb frame number */
6291 start_frame_number = pp->pp_next_frame_number;
6292 } else {
6293 /* Check for the Starting usb frame number */
6294 if ((isoc_reqp->isoc_frame_no == 0) ||
6295 ((isoc_reqp->isoc_frame_no +
6296 isoc_reqp->isoc_pkts_count) <
6297 current_frame_number)) {
6298
6299 /* Exit the critical */
6300 ddi_exit_critical(ddic);
6301
6302 USB_DPRINTF_L2(PRINT_MASK_LISTS,
6303 ohcip->ohci_log_hdl,
6304 "ohci_insert_td_with_frame_number:"
6305 "Invalid starting frame number");
6306
6307 return (USB_INVALID_START_FRAME);
6308 }
6309
6310 /* Get the starting usb frame number */
6311 start_frame_number = isoc_reqp->isoc_frame_no;
6312
6313 pp->pp_next_frame_number = 0;
6314 }
6315 break;
6316 case USB_ATTRS_ISOC_XFER_ASAP:
6317 /* ohci has to specify starting frame number */
6318 if ((pp->pp_next_frame_number) &&
6319 (pp->pp_next_frame_number > current_frame_number)) {
6320 /*
6321 * Get the next usb frame number.
6322 */
6323 start_frame_number = pp->pp_next_frame_number;
6324 } else {
6325 /*
6326 * Add appropriate offset to the current usb
6327 * frame number and use it as a starting frame
6328 * number.
6329 */
6330 start_frame_number =
6331 current_frame_number + OHCI_FRAME_OFFSET;
6332 }
6333
6334 if (!(pp->pp_flag & OHCI_ISOC_XFER_CONTINUE)) {
6335 isoc_reqp->isoc_frame_no = start_frame_number;
6336 }
6337 break;
6338 default:
6339 /* Exit the critical */
6340 ddi_exit_critical(ddic);
6341
6342 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6343 "ohci_insert_td_with_frame_number: Either starting "
6344 "frame number or ASAP flags are not set, attrs = 0x%x",
6345 isoc_reqp->isoc_attributes);
6346
6347 return (USB_NO_FRAME_NUMBER);
6348 }
6349
6350 /* Get the TD ctrl information */
6351 ctrl = Get_TD(current_td->hctd_ctrl) & (~(HC_ITD_SF));
6352
6353 /* Set the frame number field */
6354 Set_TD(current_td->hctd_ctrl, ctrl | (start_frame_number & HC_ITD_SF));
6355
6356 /*
6357 * Add the new dummy to the ED's list. When this occurs,
6358 * the Host Controller will see newly filled in dummy TD.
6359 */
6360 Set_ED(ept->hced_tailp, (ohci_td_cpu_to_iommu(ohcip, dummy_td)));
6361
6362 /* Exit the critical */
6363 ddi_exit_critical(ddic);
6364
6365 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6366 "ohci_insert_td_with_frame_number:"
6367 "current frame number 0x%llx start frame number 0x%llx",
6368 (unsigned long long)current_frame_number,
6369 (unsigned long long)start_frame_number);
6370
6371 /*
6372 * Increment this saved frame number by current number
6373 * of data packets needs to be transfer.
6374 */
6375 pp->pp_next_frame_number = start_frame_number + isoc_pkts;
6376
6377 /*
6378 * Set OHCI_ISOC_XFER_CONTINUE flag in order to send other
6379 * isochronous packets, part of the current isoch request
6380 * in the subsequent frames.
6381 */
6382 pp->pp_flag |= OHCI_ISOC_XFER_CONTINUE;
6383
6384 return (USB_SUCCESS);
6385 }
6386
6387
6388 /*
6389 * ohci_insert_td_on_tw:
6390 *
6391 * The transfer wrapper keeps a list of all Transfer Descriptors (TD) that
6392 * are allocated for this transfer. Insert a TD onto this list. The list
6393 * of TD's does not include the dummy TD that is at the end of the list of
6394 * TD's for the endpoint.
6395 */
6396 static void
ohci_insert_td_on_tw(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw,ohci_td_t * td)6397 ohci_insert_td_on_tw(
6398 ohci_state_t *ohcip,
6399 ohci_trans_wrapper_t *tw,
6400 ohci_td_t *td)
6401 {
6402 /*
6403 * Set the next pointer to NULL because
6404 * this is the last TD on list.
6405 */
6406 Set_TD(td->hctd_tw_next_td, NULL);
6407
6408 if (tw->tw_hctd_head == NULL) {
6409 ASSERT(tw->tw_hctd_tail == NULL);
6410 tw->tw_hctd_head = td;
6411 tw->tw_hctd_tail = td;
6412 } else {
6413 ohci_td_t *dummy = (ohci_td_t *)tw->tw_hctd_tail;
6414
6415 ASSERT(dummy != NULL);
6416 ASSERT(dummy != td);
6417 ASSERT(Get_TD(td->hctd_state) != HC_TD_DUMMY);
6418
6419 /* Add the td to the end of the list */
6420 Set_TD(dummy->hctd_tw_next_td,
6421 ohci_td_cpu_to_iommu(ohcip, td));
6422
6423 tw->tw_hctd_tail = td;
6424
6425 ASSERT(Get_TD(td->hctd_tw_next_td) == NULL);
6426 }
6427 }
6428
6429
6430 /*
6431 * ohci_traverse_tds:
6432 * NOTE: This function is also called from POLLED MODE.
6433 *
6434 * Traverse the list of TD's for an endpoint. Since the endpoint is marked
6435 * as sKipped, the Host Controller (HC) is no longer accessing these TD's.
6436 * Remove all the TD's that are attached to the endpoint.
6437 */
6438 void
ohci_traverse_tds(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)6439 ohci_traverse_tds(
6440 ohci_state_t *ohcip,
6441 usba_pipe_handle_data_t *ph)
6442 {
6443 ohci_trans_wrapper_t *tw;
6444 ohci_ed_t *ept;
6445 ohci_pipe_private_t *pp;
6446 uint32_t addr;
6447 ohci_td_t *tailp, *headp, *next;
6448
6449 pp = (ohci_pipe_private_t *)ph->p_hcd_private;
6450 ept = pp->pp_ept;
6451
6452 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6453 "ohci_traverse_tds: ph = 0x%p ept = 0x%p",
6454 (void *)ph, (void *)ept);
6455
6456 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6457
6458 addr = Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD;
6459
6460 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6461 "ohci_traverse_tds: addr (head) = 0x%x", addr);
6462
6463 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, addr));
6464
6465 addr = Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL;
6466
6467 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6468 "ohci_traverse_tds: addr (tail) = 0x%x", addr);
6469
6470 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip, addr));
6471
6472 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6473 "ohci_traverse_tds: cpu head = 0x%p cpu tail = 0x%p",
6474 (void *)headp, (void *)tailp);
6475
6476 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6477 "ohci_traverse_tds: iommu head = 0x%x iommu tail = 0x%x",
6478 ohci_td_cpu_to_iommu(ohcip, headp),
6479 ohci_td_cpu_to_iommu(ohcip, tailp));
6480
6481 /*
6482 * Traverse the list of TD's that are currently on the endpoint.
6483 * These TD's have not been processed and will not be processed
6484 * because the endpoint processing is stopped.
6485 */
6486 while (headp != tailp) {
6487 next = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
6488 (Get_TD(headp->hctd_next_td) & HC_EPT_TD_TAIL)));
6489
6490 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
6491 (uint32_t)Get_TD(headp->hctd_trans_wrapper));
6492
6493 /* Stop the the transfer timer */
6494 ohci_stop_xfer_timer(ohcip, tw, OHCI_REMOVE_XFER_ALWAYS);
6495
6496 ohci_deallocate_td(ohcip, headp);
6497 headp = next;
6498 }
6499
6500 /* Both head and tail pointers must be same */
6501 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6502 "ohci_traverse_tds: head = 0x%p tail = 0x%p",
6503 (void *)headp, (void *)tailp);
6504
6505 /* Update the pointer in the endpoint descriptor */
6506 Set_ED(ept->hced_headp, (ohci_td_cpu_to_iommu(ohcip, headp)));
6507
6508 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6509 "ohci_traverse_tds: new head = 0x%x",
6510 (ohci_td_cpu_to_iommu(ohcip, headp)));
6511
6512 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6513 "ohci_traverse_tds: tailp = 0x%x headp = 0x%x",
6514 (Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL),
6515 (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD));
6516
6517 ASSERT((Get_ED(ept->hced_tailp) & HC_EPT_TD_TAIL) ==
6518 (Get_ED(ept->hced_headp) & HC_EPT_TD_HEAD));
6519 }
6520
6521
6522 /*
6523 * ohci_done_list_tds:
6524 *
6525 * There may be TD's on the done list that have not been processed yet. Walk
6526 * through these TD's and mark them as RECLAIM. All the mappings for the TD
6527 * will be torn down, so the interrupt handle is alerted of this fact through
6528 * the RECLAIM flag.
6529 */
6530 static void
ohci_done_list_tds(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)6531 ohci_done_list_tds(
6532 ohci_state_t *ohcip,
6533 usba_pipe_handle_data_t *ph)
6534 {
6535 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
6536 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head;
6537 ohci_trans_wrapper_t *next_tw;
6538 ohci_td_t *head_td, *next_td;
6539
6540 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6541
6542 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6543 "ohci_done_list_tds:");
6544
6545 /* Process the transfer wrappers for this pipe */
6546 next_tw = head_tw;
6547 while (next_tw) {
6548 head_td = (ohci_td_t *)next_tw->tw_hctd_head;
6549 next_td = head_td;
6550
6551 if (head_td) {
6552 /*
6553 * Walk through each TD for this transfer
6554 * wrapper. If a TD still exists, then it
6555 * is currently on the done list.
6556 */
6557 while (next_td) {
6558
6559 /* To free TD, set TD state to RECLAIM */
6560 Set_TD(next_td->hctd_state, HC_TD_RECLAIM);
6561
6562 Set_TD(next_td->hctd_trans_wrapper, NULL);
6563
6564 next_td = ohci_td_iommu_to_cpu(ohcip,
6565 Get_TD(next_td->hctd_tw_next_td));
6566 }
6567 }
6568
6569 /* Stop the the transfer timer */
6570 ohci_stop_xfer_timer(ohcip, next_tw, OHCI_REMOVE_XFER_ALWAYS);
6571
6572 next_tw = next_tw->tw_next;
6573 }
6574 }
6575
6576
6577 /*
6578 * Remove old_td from tw and update the links.
6579 */
6580 void
ohci_unlink_td_from_tw(ohci_state_t * ohcip,ohci_td_t * old_td,ohci_trans_wrapper_t * tw)6581 ohci_unlink_td_from_tw(
6582 ohci_state_t *ohcip,
6583 ohci_td_t *old_td,
6584 ohci_trans_wrapper_t *tw)
6585 {
6586 ohci_td_t *next, *head, *tail;
6587
6588 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6589 "ohci_unlink_td_from_tw: ohcip = 0x%p, old_td = 0x%p, tw = 0x%p",
6590 (void *)ohcip, (void *)old_td, (void *)tw);
6591
6592 if (old_td == NULL || tw == NULL) {
6593
6594 return;
6595 }
6596
6597 head = tw->tw_hctd_head;
6598 tail = tw->tw_hctd_tail;
6599
6600 if (head == NULL) {
6601
6602 return;
6603 }
6604
6605 /* if this old_td is on head */
6606 if (old_td == head) {
6607 if (old_td == tail) {
6608 tw->tw_hctd_head = NULL;
6609 tw->tw_hctd_tail = NULL;
6610 } else {
6611 tw->tw_hctd_head = ohci_td_iommu_to_cpu(ohcip,
6612 Get_TD(head->hctd_tw_next_td));
6613 }
6614
6615 return;
6616 }
6617
6618 /* find this old_td's position in the tw */
6619 next = ohci_td_iommu_to_cpu(ohcip, Get_TD(head->hctd_tw_next_td));
6620 while (next && (old_td != next)) {
6621 head = next;
6622 next = ohci_td_iommu_to_cpu(ohcip,
6623 Get_TD(next->hctd_tw_next_td));
6624 }
6625
6626 /* unlink the found old_td from the tw */
6627 if (old_td == next) {
6628 Set_TD(head->hctd_tw_next_td, Get_TD(next->hctd_tw_next_td));
6629 if (old_td == tail) {
6630 tw->tw_hctd_tail = head;
6631 }
6632 }
6633 }
6634
6635
6636 /*
6637 * ohci_deallocate_td:
6638 * NOTE: This function is also called from POLLED MODE.
6639 *
6640 * Deallocate a Host Controller's (HC) Transfer Descriptor (TD).
6641 */
6642 void
ohci_deallocate_td(ohci_state_t * ohcip,ohci_td_t * old_td)6643 ohci_deallocate_td(
6644 ohci_state_t *ohcip,
6645 ohci_td_t *old_td)
6646 {
6647 ohci_trans_wrapper_t *tw;
6648
6649 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6650 "ohci_deallocate_td: old_td = 0x%p", (void *)old_td);
6651
6652 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6653
6654 /*
6655 * Obtain the transaction wrapper and tw will be
6656 * NULL for the dummy and for the reclaim TD's.
6657 */
6658 if ((Get_TD(old_td->hctd_state) == HC_TD_DUMMY) ||
6659 (Get_TD(old_td->hctd_state) == HC_TD_RECLAIM)) {
6660 tw = (ohci_trans_wrapper_t *)((uintptr_t)
6661 Get_TD(old_td->hctd_trans_wrapper));
6662 ASSERT(tw == NULL);
6663 } else {
6664 tw = (ohci_trans_wrapper_t *)
6665 OHCI_LOOKUP_ID((uint32_t)
6666 Get_TD(old_td->hctd_trans_wrapper));
6667 ASSERT(tw != NULL);
6668 }
6669
6670 /*
6671 * If this TD should be reclaimed, don't try to access its
6672 * transfer wrapper.
6673 */
6674 if ((Get_TD(old_td->hctd_state) != HC_TD_RECLAIM) && tw) {
6675
6676 ohci_unlink_td_from_tw(ohcip, old_td, tw);
6677 }
6678
6679 bzero((void *)old_td, sizeof (ohci_td_t));
6680 Set_TD(old_td->hctd_state, HC_TD_FREE);
6681
6682 USB_DPRINTF_L3(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6683 "ohci_deallocate_td: td 0x%p", (void *)old_td);
6684 }
6685
6686
6687 /*
6688 * ohci_td_cpu_to_iommu:
6689 * NOTE: This function is also called from POLLED MODE.
6690 *
6691 * This function converts for the given Transfer Descriptor (TD) CPU address
6692 * to IO address.
6693 */
6694 uint32_t
ohci_td_cpu_to_iommu(ohci_state_t * ohcip,ohci_td_t * addr)6695 ohci_td_cpu_to_iommu(
6696 ohci_state_t *ohcip,
6697 ohci_td_t *addr)
6698 {
6699 uint32_t td;
6700
6701 td = (uint32_t)ohcip->ohci_td_pool_cookie.dmac_address +
6702 (uint32_t)((uintptr_t)addr - (uintptr_t)(ohcip->ohci_td_pool_addr));
6703
6704 ASSERT((ohcip->ohci_td_pool_cookie.dmac_address +
6705 (uint32_t) (sizeof (ohci_td_t) *
6706 (addr - ohcip->ohci_td_pool_addr))) ==
6707 (ohcip->ohci_td_pool_cookie.dmac_address +
6708 (uint32_t)((uintptr_t)addr - (uintptr_t)
6709 (ohcip->ohci_td_pool_addr))));
6710
6711 ASSERT(td >= ohcip->ohci_td_pool_cookie.dmac_address);
6712 ASSERT(td <= ohcip->ohci_td_pool_cookie.dmac_address +
6713 sizeof (ohci_td_t) * ohci_td_pool_size);
6714
6715 return (td);
6716 }
6717
6718
6719 /*
6720 * ohci_td_iommu_to_cpu:
6721 * NOTE: This function is also called from POLLED MODE.
6722 *
6723 * This function converts for the given Transfer Descriptor (TD) IO address
6724 * to CPU address.
6725 */
6726 ohci_td_t *
ohci_td_iommu_to_cpu(ohci_state_t * ohcip,uintptr_t addr)6727 ohci_td_iommu_to_cpu(
6728 ohci_state_t *ohcip,
6729 uintptr_t addr)
6730 {
6731 ohci_td_t *td;
6732
6733 if (addr == NULL) {
6734
6735 return (NULL);
6736 }
6737
6738 td = (ohci_td_t *)((uintptr_t)
6739 (addr - ohcip->ohci_td_pool_cookie.dmac_address) +
6740 (uintptr_t)ohcip->ohci_td_pool_addr);
6741
6742 ASSERT(td >= ohcip->ohci_td_pool_addr);
6743 ASSERT((uintptr_t)td <= (uintptr_t)ohcip->ohci_td_pool_addr +
6744 (uintptr_t)(sizeof (ohci_td_t) * ohci_td_pool_size));
6745
6746 return (td);
6747 }
6748
6749 /*
6750 * ohci_allocate_tds_for_tw:
6751 *
6752 * Allocate n Transfer Descriptors (TD) from the TD buffer pool and places it
6753 * into the TW.
6754 *
6755 * Returns USB_NO_RESOURCES if it was not able to allocate all the requested TD
6756 * otherwise USB_SUCCESS.
6757 */
6758 int
ohci_allocate_tds_for_tw(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw,size_t td_count)6759 ohci_allocate_tds_for_tw(
6760 ohci_state_t *ohcip,
6761 ohci_trans_wrapper_t *tw,
6762 size_t td_count)
6763 {
6764 ohci_td_t *td;
6765 uint32_t td_addr;
6766 int i;
6767 int error = USB_SUCCESS;
6768
6769 for (i = 0; i < td_count; i++) {
6770 td = ohci_allocate_td_from_pool(ohcip);
6771 if (td == NULL) {
6772 error = USB_NO_RESOURCES;
6773 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6774 "ohci_allocate_tds_for_tw: "
6775 "Unable to allocate %lu TDs",
6776 td_count);
6777 break;
6778 }
6779 if (tw->tw_hctd_free_list != NULL) {
6780 td_addr = ohci_td_cpu_to_iommu(ohcip,
6781 tw->tw_hctd_free_list);
6782 Set_TD(td->hctd_tw_next_td, td_addr);
6783 }
6784 tw->tw_hctd_free_list = td;
6785 }
6786
6787 return (error);
6788 }
6789
6790 /*
6791 * ohci_allocate_tw_resources:
6792 *
6793 * Allocate a Transaction Wrapper (TW) and n Transfer Descriptors (TD)
6794 * from the TD buffer pool and places it into the TW. It does an all
6795 * or nothing transaction.
6796 *
6797 * Returns NULL if there is insufficient resources otherwise TW.
6798 */
6799 static ohci_trans_wrapper_t *
ohci_allocate_tw_resources(ohci_state_t * ohcip,ohci_pipe_private_t * pp,size_t tw_length,usb_flags_t usb_flags,size_t td_count)6800 ohci_allocate_tw_resources(
6801 ohci_state_t *ohcip,
6802 ohci_pipe_private_t *pp,
6803 size_t tw_length,
6804 usb_flags_t usb_flags,
6805 size_t td_count)
6806 {
6807 ohci_trans_wrapper_t *tw;
6808
6809 tw = ohci_create_transfer_wrapper(ohcip, pp, tw_length, usb_flags);
6810
6811 if (tw == NULL) {
6812 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
6813 "ohci_allocate_tw_resources: Unable to allocate TW");
6814 } else {
6815 if (ohci_allocate_tds_for_tw(ohcip, tw, td_count) ==
6816 USB_SUCCESS) {
6817 tw->tw_num_tds = (uint_t)td_count;
6818 } else {
6819 ohci_deallocate_tw_resources(ohcip, pp, tw);
6820 tw = NULL;
6821 }
6822 }
6823
6824 return (tw);
6825 }
6826
6827 /*
6828 * ohci_free_tw_tds_resources:
6829 *
6830 * Free all allocated resources for Transaction Wrapper (TW).
6831 * Does not free the TW itself.
6832 */
6833 static void
ohci_free_tw_tds_resources(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw)6834 ohci_free_tw_tds_resources(
6835 ohci_state_t *ohcip,
6836 ohci_trans_wrapper_t *tw)
6837 {
6838 ohci_td_t *td;
6839 ohci_td_t *temp_td;
6840
6841 td = tw->tw_hctd_free_list;
6842 while (td != NULL) {
6843 /* Save the pointer to the next td before destroying it */
6844 temp_td = ohci_td_iommu_to_cpu(ohcip,
6845 Get_TD(td->hctd_tw_next_td));
6846 ohci_deallocate_td(ohcip, td);
6847 td = temp_td;
6848 }
6849 tw->tw_hctd_free_list = NULL;
6850 }
6851
6852
6853 /*
6854 * Transfer Wrapper functions
6855 *
6856 * ohci_create_transfer_wrapper:
6857 *
6858 * Create a Transaction Wrapper (TW) for non-isoc transfer types
6859 * and this involves the allocating of DMA resources.
6860 */
6861 static ohci_trans_wrapper_t *
ohci_create_transfer_wrapper(ohci_state_t * ohcip,ohci_pipe_private_t * pp,size_t length,uint_t usb_flags)6862 ohci_create_transfer_wrapper(
6863 ohci_state_t *ohcip,
6864 ohci_pipe_private_t *pp,
6865 size_t length,
6866 uint_t usb_flags)
6867 {
6868 ddi_device_acc_attr_t dev_attr;
6869 int result;
6870 size_t real_length;
6871 ohci_trans_wrapper_t *tw;
6872 ddi_dma_attr_t dma_attr;
6873 int kmem_flag;
6874 int (*dmamem_wait)(caddr_t);
6875 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
6876
6877 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6878 "ohci_create_transfer_wrapper: length = 0x%lx flags = 0x%x",
6879 length, usb_flags);
6880
6881 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
6882
6883 /* isochronous pipe should not call into this function */
6884 if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) ==
6885 USB_EP_ATTR_ISOCH) {
6886
6887 return (NULL);
6888 }
6889
6890 /* SLEEP flag should not be used while holding mutex */
6891 kmem_flag = KM_NOSLEEP;
6892 dmamem_wait = DDI_DMA_DONTWAIT;
6893
6894 /* Allocate space for the transfer wrapper */
6895 tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag);
6896
6897 if (tw == NULL) {
6898 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6899 "ohci_create_transfer_wrapper: kmem_zalloc failed");
6900
6901 return (NULL);
6902 }
6903
6904 /* zero-length packet doesn't need to allocate dma memory */
6905 if (length == 0) {
6906
6907 goto dmadone;
6908 }
6909
6910 /* allow sg lists for transfer wrapper dma memory */
6911 bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t));
6912 dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TW_SGLLEN;
6913 dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT;
6914
6915 /* Allocate the DMA handle */
6916 result = ddi_dma_alloc_handle(ohcip->ohci_dip,
6917 &dma_attr, dmamem_wait, 0, &tw->tw_dmahandle);
6918
6919 if (result != DDI_SUCCESS) {
6920 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6921 "ohci_create_transfer_wrapper: Alloc handle failed");
6922
6923 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
6924
6925 return (NULL);
6926 }
6927
6928 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
6929
6930 /* The host controller will be little endian */
6931 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC;
6932 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
6933
6934 /* Allocate the memory */
6935 result = ddi_dma_mem_alloc(tw->tw_dmahandle, length,
6936 &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait, NULL,
6937 (caddr_t *)&tw->tw_buf, &real_length, &tw->tw_accesshandle);
6938
6939 if (result != DDI_SUCCESS) {
6940 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6941 "ohci_create_transfer_wrapper: dma_mem_alloc fail");
6942
6943 ddi_dma_free_handle(&tw->tw_dmahandle);
6944 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
6945
6946 return (NULL);
6947 }
6948
6949 ASSERT(real_length >= length);
6950
6951 /* Bind the handle */
6952 result = ddi_dma_addr_bind_handle(tw->tw_dmahandle, NULL,
6953 (caddr_t)tw->tw_buf, real_length, DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
6954 dmamem_wait, NULL, &tw->tw_cookie, &tw->tw_ncookies);
6955
6956 if (result != DDI_DMA_MAPPED) {
6957 ohci_decode_ddi_dma_addr_bind_handle_result(ohcip, result);
6958
6959 ddi_dma_mem_free(&tw->tw_accesshandle);
6960 ddi_dma_free_handle(&tw->tw_dmahandle);
6961 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
6962
6963 return (NULL);
6964 }
6965
6966 tw->tw_cookie_idx = 0;
6967 tw->tw_dma_offs = 0;
6968
6969 dmadone:
6970 /*
6971 * Only allow one wrapper to be added at a time. Insert the
6972 * new transaction wrapper into the list for this pipe.
6973 */
6974 if (pp->pp_tw_head == NULL) {
6975 pp->pp_tw_head = tw;
6976 pp->pp_tw_tail = tw;
6977 } else {
6978 pp->pp_tw_tail->tw_next = tw;
6979 pp->pp_tw_tail = tw;
6980 }
6981
6982 /* Store the transfer length */
6983 tw->tw_length = length;
6984
6985 /* Store a back pointer to the pipe private structure */
6986 tw->tw_pipe_private = pp;
6987
6988 /* Store the transfer type - synchronous or asynchronous */
6989 tw->tw_flags = usb_flags;
6990
6991 /* Get and Store 32bit ID */
6992 tw->tw_id = OHCI_GET_ID((void *)tw);
6993
6994 ASSERT(tw->tw_id != NULL);
6995
6996 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
6997 "ohci_create_transfer_wrapper: tw = 0x%p, ncookies = %u",
6998 (void *)tw, tw->tw_ncookies);
6999
7000 return (tw);
7001 }
7002
7003
7004 /*
7005 * Transfer Wrapper functions
7006 *
7007 * ohci_create_isoc_transfer_wrapper:
7008 *
7009 * Create a Transaction Wrapper (TW) for isoc transfer
7010 * and this involves the allocating of DMA resources.
7011 */
7012 static ohci_trans_wrapper_t *
ohci_create_isoc_transfer_wrapper(ohci_state_t * ohcip,ohci_pipe_private_t * pp,size_t length,usb_isoc_pkt_descr_t * descr,ushort_t pkt_count,size_t td_count,uint_t usb_flags)7013 ohci_create_isoc_transfer_wrapper(
7014 ohci_state_t *ohcip,
7015 ohci_pipe_private_t *pp,
7016 size_t length,
7017 usb_isoc_pkt_descr_t *descr,
7018 ushort_t pkt_count,
7019 size_t td_count,
7020 uint_t usb_flags)
7021 {
7022 ddi_device_acc_attr_t dev_attr;
7023 int result;
7024 size_t real_length, xfer_size;
7025 uint_t ccount;
7026 ohci_trans_wrapper_t *tw;
7027 ddi_dma_attr_t dma_attr;
7028 int kmem_flag;
7029 uint_t i, j, frame_count, residue;
7030 int (*dmamem_wait)(caddr_t);
7031 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
7032 usb_isoc_pkt_descr_t *isoc_pkt_descr = descr;
7033
7034 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7035 "ohci_create_isoc_transfer_wrapper: length = 0x%lx flags = 0x%x",
7036 length, usb_flags);
7037
7038 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7039
7040 /* non-isochronous pipe should not call into this function */
7041 if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) !=
7042 USB_EP_ATTR_ISOCH) {
7043
7044 return (NULL);
7045 }
7046
7047 /* SLEEP flag should not be used in interrupt context */
7048 if (servicing_interrupt()) {
7049 kmem_flag = KM_NOSLEEP;
7050 dmamem_wait = DDI_DMA_DONTWAIT;
7051 } else {
7052 kmem_flag = KM_SLEEP;
7053 dmamem_wait = DDI_DMA_SLEEP;
7054 }
7055
7056 /* Allocate space for the transfer wrapper */
7057 tw = kmem_zalloc(sizeof (ohci_trans_wrapper_t), kmem_flag);
7058
7059 if (tw == NULL) {
7060 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7061 "ohci_create_transfer_wrapper: kmem_zalloc failed");
7062
7063 return (NULL);
7064 }
7065
7066 /* Allocate space for the isoc buffer handles */
7067 tw->tw_isoc_strtlen = sizeof (ohci_isoc_buf_t) * td_count;
7068 if ((tw->tw_isoc_bufs = kmem_zalloc(tw->tw_isoc_strtlen,
7069 kmem_flag)) == NULL) {
7070 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
7071 "ohci_create_isoc_transfer_wrapper: kmem_alloc "
7072 "isoc buffer failed");
7073 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7074
7075 return (NULL);
7076 }
7077
7078 /* allow sg lists for transfer wrapper dma memory */
7079 bcopy(&ohcip->ohci_dma_attr, &dma_attr, sizeof (ddi_dma_attr_t));
7080 dma_attr.dma_attr_sgllen = OHCI_DMA_ATTR_TD_SGLLEN;
7081 dma_attr.dma_attr_align = OHCI_DMA_ATTR_ALIGNMENT;
7082
7083 dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
7084
7085 /* The host controller will be little endian */
7086 dev_attr.devacc_attr_endian_flags = DDI_STRUCTURE_BE_ACC;
7087 dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
7088
7089 residue = pkt_count % OHCI_ISOC_PKTS_PER_TD;
7090
7091 for (i = 0; i < td_count; i++) {
7092 tw->tw_isoc_bufs[i].index = i;
7093
7094 if ((i == (td_count - 1)) && (residue != 0)) {
7095 frame_count = residue;
7096 } else {
7097 frame_count = OHCI_ISOC_PKTS_PER_TD;
7098 }
7099
7100 /* Allocate the DMA handle */
7101 result = ddi_dma_alloc_handle(ohcip->ohci_dip, &dma_attr,
7102 dmamem_wait, 0, &tw->tw_isoc_bufs[i].dma_handle);
7103
7104 if (result != DDI_SUCCESS) {
7105 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7106 "ohci_create_isoc_transfer_wrapper: "
7107 "Alloc handle failed");
7108
7109 for (j = 0; j < i; j++) {
7110 result = ddi_dma_unbind_handle(
7111 tw->tw_isoc_bufs[j].dma_handle);
7112 ASSERT(result == USB_SUCCESS);
7113 ddi_dma_mem_free(&tw->tw_isoc_bufs[j].
7114 mem_handle);
7115 ddi_dma_free_handle(&tw->tw_isoc_bufs[j].
7116 dma_handle);
7117 }
7118 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7119 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7120
7121 return (NULL);
7122 }
7123
7124 /* Compute the memory length */
7125 for (xfer_size = 0, j = 0; j < frame_count; j++) {
7126 ASSERT(isoc_pkt_descr != NULL);
7127 xfer_size += isoc_pkt_descr->isoc_pkt_length;
7128 isoc_pkt_descr++;
7129 }
7130
7131 /* Allocate the memory */
7132 result = ddi_dma_mem_alloc(tw->tw_isoc_bufs[i].dma_handle,
7133 xfer_size, &dev_attr, DDI_DMA_CONSISTENT, dmamem_wait,
7134 NULL, (caddr_t *)&tw->tw_isoc_bufs[i].buf_addr,
7135 &real_length, &tw->tw_isoc_bufs[i].mem_handle);
7136
7137 if (result != DDI_SUCCESS) {
7138 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7139 "ohci_create_isoc_transfer_wrapper: "
7140 "dma_mem_alloc %d fail", i);
7141 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle);
7142
7143 for (j = 0; j < i; j++) {
7144 result = ddi_dma_unbind_handle(
7145 tw->tw_isoc_bufs[j].dma_handle);
7146 ASSERT(result == USB_SUCCESS);
7147 ddi_dma_mem_free(&tw->tw_isoc_bufs[j].
7148 mem_handle);
7149 ddi_dma_free_handle(&tw->tw_isoc_bufs[j].
7150 dma_handle);
7151 }
7152 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7153 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7154
7155 return (NULL);
7156 }
7157
7158 ASSERT(real_length >= xfer_size);
7159
7160 /* Bind the handle */
7161 result = ddi_dma_addr_bind_handle(
7162 tw->tw_isoc_bufs[i].dma_handle, NULL,
7163 (caddr_t)tw->tw_isoc_bufs[i].buf_addr, real_length,
7164 DDI_DMA_RDWR|DDI_DMA_CONSISTENT, dmamem_wait, NULL,
7165 &tw->tw_isoc_bufs[i].cookie, &ccount);
7166
7167 if ((result == DDI_DMA_MAPPED) &&
7168 (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) {
7169 tw->tw_isoc_bufs[i].length = xfer_size;
7170 tw->tw_isoc_bufs[i].ncookies = ccount;
7171
7172 continue;
7173 } else {
7174 USB_DPRINTF_L2(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7175 "ohci_create_isoc_transfer_wrapper: "
7176 "Bind handle %d failed", i);
7177 if (result == DDI_DMA_MAPPED) {
7178 result = ddi_dma_unbind_handle(
7179 tw->tw_isoc_bufs[i].dma_handle);
7180 ASSERT(result == USB_SUCCESS);
7181 }
7182 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle);
7183 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle);
7184
7185 for (j = 0; j < i; j++) {
7186 result = ddi_dma_unbind_handle(
7187 tw->tw_isoc_bufs[j].dma_handle);
7188 ASSERT(result == USB_SUCCESS);
7189 ddi_dma_mem_free(&tw->tw_isoc_bufs[j].
7190 mem_handle);
7191 ddi_dma_free_handle(&tw->tw_isoc_bufs[j].
7192 dma_handle);
7193 }
7194 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7195 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7196
7197 return (NULL);
7198 }
7199 }
7200
7201 /*
7202 * Only allow one wrapper to be added at a time. Insert the
7203 * new transaction wrapper into the list for this pipe.
7204 */
7205 if (pp->pp_tw_head == NULL) {
7206 pp->pp_tw_head = tw;
7207 pp->pp_tw_tail = tw;
7208 } else {
7209 pp->pp_tw_tail->tw_next = tw;
7210 pp->pp_tw_tail = tw;
7211 }
7212
7213 /* Store the transfer length */
7214 tw->tw_length = length;
7215
7216 /* Store the td numbers */
7217 tw->tw_ncookies = (uint_t)td_count;
7218
7219 /* Store a back pointer to the pipe private structure */
7220 tw->tw_pipe_private = pp;
7221
7222 /* Store the transfer type - synchronous or asynchronous */
7223 tw->tw_flags = usb_flags;
7224
7225 /* Get and Store 32bit ID */
7226 tw->tw_id = OHCI_GET_ID((void *)tw);
7227
7228 ASSERT(tw->tw_id != NULL);
7229
7230 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7231 "ohci_create_isoc_transfer_wrapper: tw = 0x%p", (void *)tw);
7232
7233 return (tw);
7234 }
7235
7236
7237 /*
7238 * ohci_start_xfer_timer:
7239 *
7240 * Start the timer for the control, bulk and for one time interrupt
7241 * transfers.
7242 */
7243 /* ARGSUSED */
7244 static void
ohci_start_xfer_timer(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)7245 ohci_start_xfer_timer(
7246 ohci_state_t *ohcip,
7247 ohci_pipe_private_t *pp,
7248 ohci_trans_wrapper_t *tw)
7249 {
7250 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
7251 "ohci_start_xfer_timer: tw = 0x%p", (void *)tw);
7252
7253 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7254
7255 /*
7256 * The timeout handling is done only for control, bulk and for
7257 * one time Interrupt transfers.
7258 *
7259 * NOTE: If timeout is zero; Assume infinite timeout and don't
7260 * insert this transfer on the timeout list.
7261 */
7262 if (tw->tw_timeout) {
7263 /*
7264 * Increase timeout value by one second and this extra one
7265 * second is used to halt the endpoint if given transfer
7266 * times out.
7267 */
7268 tw->tw_timeout++;
7269
7270 /*
7271 * Add this transfer wrapper into the transfer timeout list.
7272 */
7273 if (ohcip->ohci_timeout_list) {
7274 tw->tw_timeout_next = ohcip->ohci_timeout_list;
7275 }
7276
7277 ohcip->ohci_timeout_list = tw;
7278 ohci_start_timer(ohcip);
7279 }
7280 }
7281
7282
7283 /*
7284 * ohci_stop_xfer_timer:
7285 *
7286 * Start the timer for the control, bulk and for one time interrupt
7287 * transfers.
7288 */
7289 void
ohci_stop_xfer_timer(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw,uint_t flag)7290 ohci_stop_xfer_timer(
7291 ohci_state_t *ohcip,
7292 ohci_trans_wrapper_t *tw,
7293 uint_t flag)
7294 {
7295 timeout_id_t timer_id;
7296
7297 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
7298 "ohci_stop_xfer_timer: tw = 0x%p", (void *)tw);
7299
7300 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7301
7302 /*
7303 * The timeout handling is done only for control, bulk
7304 * and for one time Interrupt transfers.
7305 */
7306 if (ohcip->ohci_timeout_list == NULL) {
7307 return;
7308 }
7309
7310 switch (flag) {
7311 case OHCI_REMOVE_XFER_IFLAST:
7312 if (tw->tw_hctd_head != tw->tw_hctd_tail) {
7313 break;
7314 }
7315 /* FALLTHRU */
7316 case OHCI_REMOVE_XFER_ALWAYS:
7317 ohci_remove_tw_from_timeout_list(ohcip, tw);
7318
7319 if ((ohcip->ohci_timeout_list == NULL) &&
7320 (ohcip->ohci_timer_id)) {
7321
7322 timer_id = ohcip->ohci_timer_id;
7323
7324 /* Reset the timer id to zero */
7325 ohcip->ohci_timer_id = 0;
7326
7327 mutex_exit(&ohcip->ohci_int_mutex);
7328
7329 (void) untimeout(timer_id);
7330
7331 mutex_enter(&ohcip->ohci_int_mutex);
7332 }
7333 break;
7334 default:
7335 break;
7336 }
7337 }
7338
7339
7340 /*
7341 * ohci_xfer_timeout_handler:
7342 *
7343 * Control or bulk transfer timeout handler.
7344 */
7345 static void
ohci_xfer_timeout_handler(void * arg)7346 ohci_xfer_timeout_handler(void *arg)
7347 {
7348 ohci_state_t *ohcip = (ohci_state_t *)arg;
7349 ohci_trans_wrapper_t *exp_xfer_list_head = NULL;
7350 ohci_trans_wrapper_t *exp_xfer_list_tail = NULL;
7351 ohci_trans_wrapper_t *tw, *next;
7352 ohci_td_t *td;
7353 usb_flags_t flags;
7354
7355 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
7356 "ohci_xfer_timeout_handler: ohcip = 0x%p", (void *)ohcip);
7357
7358 mutex_enter(&ohcip->ohci_int_mutex);
7359
7360 /* Set the required flags */
7361 flags = OHCI_FLAGS_NOSLEEP | OHCI_FLAGS_DMA_SYNC;
7362
7363 /*
7364 * Check whether still timeout handler is valid.
7365 */
7366 if (ohcip->ohci_timer_id) {
7367
7368 /* Reset the timer id to zero */
7369 ohcip->ohci_timer_id = 0;
7370 } else {
7371 mutex_exit(&ohcip->ohci_int_mutex);
7372
7373 return;
7374 }
7375
7376 /* Get the transfer timeout list head */
7377 tw = ohcip->ohci_timeout_list;
7378
7379 /*
7380 * Process ohci timeout list and look whether the timer
7381 * has expired for any transfers. Create a temporary list
7382 * of expired transfers and process them later.
7383 */
7384 while (tw) {
7385 /* Get the transfer on the timeout list */
7386 next = tw->tw_timeout_next;
7387
7388 tw->tw_timeout--;
7389
7390 /*
7391 * Set the sKip bit to stop all transactions on
7392 * this pipe
7393 */
7394 if (tw->tw_timeout == 1) {
7395 ohci_modify_sKip_bit(ohcip,
7396 tw->tw_pipe_private, SET_sKip, flags);
7397
7398 /* Reset dma sync flag */
7399 flags &= ~OHCI_FLAGS_DMA_SYNC;
7400 }
7401
7402 /* Remove tw from the timeout list */
7403 if (tw->tw_timeout == 0) {
7404
7405 ohci_remove_tw_from_timeout_list(ohcip, tw);
7406
7407 /* Add tw to the end of expire list */
7408 if (exp_xfer_list_head) {
7409 exp_xfer_list_tail->tw_timeout_next = tw;
7410 } else {
7411 exp_xfer_list_head = tw;
7412 }
7413 exp_xfer_list_tail = tw;
7414 tw->tw_timeout_next = NULL;
7415 }
7416
7417 tw = next;
7418 }
7419
7420 /* Get the expired transfer timeout list head */
7421 tw = exp_xfer_list_head;
7422
7423 if (tw && (flags & OHCI_FLAGS_DMA_SYNC)) {
7424 /* Sync ED and TD pool */
7425 Sync_ED_TD_Pool(ohcip);
7426 }
7427
7428 /*
7429 * Process the expired transfers by notifing the corrsponding
7430 * client driver through the exception callback.
7431 */
7432 while (tw) {
7433 /* Get the transfer on the expired transfer timeout list */
7434 next = tw->tw_timeout_next;
7435
7436 td = tw->tw_hctd_head;
7437
7438 while (td) {
7439 /* Set TD state to TIMEOUT */
7440 Set_TD(td->hctd_state, HC_TD_TIMEOUT);
7441
7442 /* Get the next TD from the wrapper */
7443 td = ohci_td_iommu_to_cpu(ohcip,
7444 Get_TD(td->hctd_tw_next_td));
7445 }
7446
7447 ohci_handle_error(ohcip, tw->tw_hctd_head, USB_CR_TIMEOUT);
7448
7449 tw = next;
7450 }
7451
7452 ohci_start_timer(ohcip);
7453 mutex_exit(&ohcip->ohci_int_mutex);
7454 }
7455
7456
7457 /*
7458 * ohci_remove_tw_from_timeout_list:
7459 *
7460 * Remove Control or bulk transfer from the timeout list.
7461 */
7462 static void
ohci_remove_tw_from_timeout_list(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw)7463 ohci_remove_tw_from_timeout_list(
7464 ohci_state_t *ohcip,
7465 ohci_trans_wrapper_t *tw)
7466 {
7467 ohci_trans_wrapper_t *prev, *next;
7468
7469 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
7470 "ohci_remove_tw_from_timeout_list: tw = 0x%p", (void *)tw);
7471
7472 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7473
7474 if (ohcip->ohci_timeout_list == tw) {
7475 ohcip->ohci_timeout_list = tw->tw_timeout_next;
7476 } else {
7477 prev = ohcip->ohci_timeout_list;
7478 next = prev->tw_timeout_next;
7479
7480 while (next && (next != tw)) {
7481 prev = next;
7482 next = next->tw_timeout_next;
7483 }
7484
7485 if (next == tw) {
7486 prev->tw_timeout_next = next->tw_timeout_next;
7487 }
7488 }
7489
7490 /* Reset the xfer timeout */
7491 tw->tw_timeout_next = NULL;
7492 }
7493
7494
7495 /*
7496 * ohci_start_timer:
7497 *
7498 * Start the ohci timer
7499 */
7500 static void
ohci_start_timer(ohci_state_t * ohcip)7501 ohci_start_timer(ohci_state_t *ohcip)
7502 {
7503 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
7504 "ohci_start_timer: ohcip = 0x%p", (void *)ohcip);
7505
7506 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7507
7508 /*
7509 * Start the global timer only if currently timer is not
7510 * running and if there are any transfers on the timeout
7511 * list. This timer will be per USB Host Controller.
7512 */
7513 if ((!ohcip->ohci_timer_id) && (ohcip->ohci_timeout_list)) {
7514 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler,
7515 (void *)ohcip, drv_usectohz(1000000));
7516 }
7517 }
7518
7519
7520 /*
7521 * ohci_deallocate_tw_resources:
7522 * NOTE: This function is also called from POLLED MODE.
7523 *
7524 * Deallocate of a Transaction Wrapper (TW) and this involves the freeing of
7525 * of DMA resources.
7526 */
7527 void
ohci_deallocate_tw_resources(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)7528 ohci_deallocate_tw_resources(
7529 ohci_state_t *ohcip,
7530 ohci_pipe_private_t *pp,
7531 ohci_trans_wrapper_t *tw)
7532 {
7533 ohci_trans_wrapper_t *prev, *next;
7534
7535 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7536 "ohci_deallocate_tw_resources: tw = 0x%p", (void *)tw);
7537
7538 /*
7539 * If the transfer wrapper has no Host Controller (HC)
7540 * Transfer Descriptors (TD) associated with it, then
7541 * remove the transfer wrapper.
7542 */
7543 if (tw->tw_hctd_head) {
7544 ASSERT(tw->tw_hctd_tail != NULL);
7545
7546 return;
7547 }
7548
7549 ASSERT(tw->tw_hctd_tail == NULL);
7550
7551 /* Make sure we return all the unused td's to the pool as well */
7552 ohci_free_tw_tds_resources(ohcip, tw);
7553
7554 /*
7555 * If pp->pp_tw_head and pp->pp_tw_tail are pointing to
7556 * given TW then set the head and tail equal to NULL.
7557 * Otherwise search for this TW in the linked TW's list
7558 * and then remove this TW from the list.
7559 */
7560 if (pp->pp_tw_head == tw) {
7561 if (pp->pp_tw_tail == tw) {
7562 pp->pp_tw_head = NULL;
7563 pp->pp_tw_tail = NULL;
7564 } else {
7565 pp->pp_tw_head = tw->tw_next;
7566 }
7567 } else {
7568 prev = pp->pp_tw_head;
7569 next = prev->tw_next;
7570
7571 while (next && (next != tw)) {
7572 prev = next;
7573 next = next->tw_next;
7574 }
7575
7576 if (next == tw) {
7577 prev->tw_next = next->tw_next;
7578
7579 if (pp->pp_tw_tail == tw) {
7580 pp->pp_tw_tail = prev;
7581 }
7582 }
7583 }
7584
7585 ohci_free_tw(ohcip, tw);
7586 }
7587
7588
7589 /*
7590 * ohci_free_dma_resources:
7591 *
7592 * Free dma resources of a Transfer Wrapper (TW) and also free the TW.
7593 */
7594 static void
ohci_free_dma_resources(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)7595 ohci_free_dma_resources(
7596 ohci_state_t *ohcip,
7597 usba_pipe_handle_data_t *ph)
7598 {
7599 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
7600 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head;
7601 ohci_trans_wrapper_t *next_tw, *tw;
7602
7603 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7604 "ohci_free_dma_resources: ph = 0x%p", (void *)ph);
7605
7606 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7607
7608 /* Process the Transfer Wrappers */
7609 next_tw = head_tw;
7610 while (next_tw) {
7611 tw = next_tw;
7612 next_tw = tw->tw_next;
7613
7614 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7615 "ohci_free_dma_resources: Free TW = 0x%p", (void *)tw);
7616
7617 ohci_free_tw(ohcip, tw);
7618 }
7619
7620 /* Adjust the head and tail pointers */
7621 pp->pp_tw_head = NULL;
7622 pp->pp_tw_tail = NULL;
7623 }
7624
7625
7626 /*
7627 * ohci_free_tw:
7628 *
7629 * Free the Transfer Wrapper (TW).
7630 */
7631 static void
ohci_free_tw(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw)7632 ohci_free_tw(
7633 ohci_state_t *ohcip,
7634 ohci_trans_wrapper_t *tw)
7635 {
7636 int rval, i;
7637
7638 USB_DPRINTF_L4(PRINT_MASK_ALLOC, ohcip->ohci_log_hdl,
7639 "ohci_free_tw: tw = 0x%p", (void *)tw);
7640
7641 ASSERT(tw != NULL);
7642 ASSERT(tw->tw_id != NULL);
7643
7644 /* Free 32bit ID */
7645 OHCI_FREE_ID((uint32_t)tw->tw_id);
7646
7647 if (tw->tw_isoc_strtlen > 0) {
7648 ASSERT(tw->tw_isoc_bufs != NULL);
7649 for (i = 0; i < tw->tw_ncookies; i++) {
7650 if (tw->tw_isoc_bufs[i].ncookies > 0) {
7651 rval = ddi_dma_unbind_handle(
7652 tw->tw_isoc_bufs[i].dma_handle);
7653 ASSERT(rval == USB_SUCCESS);
7654 }
7655 ddi_dma_mem_free(&tw->tw_isoc_bufs[i].mem_handle);
7656 ddi_dma_free_handle(&tw->tw_isoc_bufs[i].dma_handle);
7657 }
7658 kmem_free(tw->tw_isoc_bufs, tw->tw_isoc_strtlen);
7659 } else if (tw->tw_dmahandle != NULL) {
7660 if (tw->tw_ncookies > 0) {
7661 rval = ddi_dma_unbind_handle(tw->tw_dmahandle);
7662 ASSERT(rval == DDI_SUCCESS);
7663 }
7664 ddi_dma_mem_free(&tw->tw_accesshandle);
7665 ddi_dma_free_handle(&tw->tw_dmahandle);
7666 }
7667
7668 /* Free transfer wrapper */
7669 kmem_free(tw, sizeof (ohci_trans_wrapper_t));
7670 }
7671
7672
7673 /*
7674 * Interrupt Handling functions
7675 */
7676
7677 /*
7678 * ohci_intr:
7679 *
7680 * OpenHCI (OHCI) interrupt handling routine.
7681 */
7682 static uint_t
ohci_intr(caddr_t arg1,caddr_t arg2)7683 ohci_intr(caddr_t arg1, caddr_t arg2)
7684 {
7685 ohci_state_t *ohcip = (ohci_state_t *)arg1;
7686 uint_t intr;
7687 ohci_td_t *done_head = NULL;
7688 ohci_save_intr_sts_t *ohci_intr_sts = &ohcip->ohci_save_intr_sts;
7689
7690 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7691 "ohci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p",
7692 (void *)arg1, (void *)arg2);
7693
7694 mutex_enter(&ohcip->ohci_int_mutex);
7695
7696 /* Any interrupt is not handled for the suspended device. */
7697 if (ohcip->ohci_hc_soft_state == OHCI_CTLR_SUSPEND_STATE) {
7698 mutex_exit(&ohcip->ohci_int_mutex);
7699
7700 return (DDI_INTR_UNCLAIMED);
7701 }
7702
7703 /*
7704 * Suppose if we switched to the polled mode from the normal
7705 * mode when interrupt handler is executing then we need to
7706 * save the interrupt status information in the polled mode
7707 * to avoid race conditions. The following flag will be set
7708 * and reset on entering & exiting of ohci interrupt handler
7709 * respectively. This flag will be used in the polled mode
7710 * to check whether the interrupt handler was running when we
7711 * switched to the polled mode from the normal mode.
7712 */
7713 ohci_intr_sts->ohci_intr_flag = OHCI_INTR_HANDLING;
7714
7715 /* Temporarily turn off interrupts */
7716 Set_OpReg(hcr_intr_disable, HCR_INTR_MIE);
7717
7718 /*
7719 * Handle any missed ohci interrupt especially WriteDoneHead
7720 * and SOF interrupts because of previous polled mode switch.
7721 */
7722 ohci_handle_missed_intr(ohcip);
7723
7724 /*
7725 * Now process the actual ohci interrupt events that caused
7726 * invocation of this ohci interrupt handler.
7727 */
7728
7729 /*
7730 * Updating the WriteDoneHead interrupt:
7731 *
7732 * (a) Host Controller
7733 *
7734 * - First Host controller (HC) checks whether WDH bit
7735 * in the interrupt status register is cleared.
7736 *
7737 * - If WDH bit is cleared then HC writes new done head
7738 * list information into the HCCA done head field.
7739 *
7740 * - Set WDH bit in the interrupt status register.
7741 *
7742 * (b) Host Controller Driver (HCD)
7743 *
7744 * - First read the interrupt status register. The HCCA
7745 * done head and WDH bit may be set or may not be set
7746 * while reading the interrupt status register.
7747 *
7748 * - Read the HCCA done head list. By this time may be
7749 * HC has updated HCCA done head and WDH bit in ohci
7750 * interrupt status register.
7751 *
7752 * - If done head is non-null and if WDH bit is not set
7753 * then Host Controller has updated HCCA done head &
7754 * WDH bit in the interrupt stats register in between
7755 * reading the interrupt status register & HCCA done
7756 * head. In that case, definitely WDH bit will be set
7757 * in the interrupt status register & driver can take
7758 * it for granted.
7759 *
7760 * Now read the Interrupt Status & Interrupt enable register
7761 * to determine the exact interrupt events.
7762 */
7763 intr = ohci_intr_sts->ohci_curr_intr_sts =
7764 (Get_OpReg(hcr_intr_status) & Get_OpReg(hcr_intr_enable));
7765
7766 if (ohcip->ohci_hccap) {
7767 /* Sync HCCA area */
7768 Sync_HCCA(ohcip);
7769
7770 /* Read and Save the HCCA DoneHead value */
7771 done_head = ohci_intr_sts->ohci_curr_done_lst =
7772 (ohci_td_t *)(uintptr_t)
7773 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) &
7774 HCCA_DONE_HEAD_MASK);
7775
7776 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7777 "ohci_intr: Done head! 0x%p", (void *)done_head);
7778 }
7779
7780 /* Update kstat values */
7781 ohci_do_intrs_stats(ohcip, intr);
7782
7783 /*
7784 * Look at the HccaDoneHead, if it is a non-zero valid address,
7785 * a done list update interrupt is indicated. Otherwise, this
7786 * intr bit is cleared.
7787 */
7788 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) {
7789
7790 /* Set the WriteDoneHead bit in the interrupt events */
7791 intr |= HCR_INTR_WDH;
7792 } else {
7793
7794 /* Clear the WriteDoneHead bit */
7795 intr &= ~HCR_INTR_WDH;
7796 }
7797
7798 /*
7799 * We could have gotten a spurious interrupts. If so, do not
7800 * claim it. This is quite possible on some architectures
7801 * where more than one PCI slots share the IRQs. If so, the
7802 * associated driver's interrupt routine may get called even
7803 * if the interrupt is not meant for them.
7804 *
7805 * By unclaiming the interrupt, the other driver gets chance
7806 * to service its interrupt.
7807 */
7808 if (!intr) {
7809
7810 /* Reset the interrupt handler flag */
7811 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING;
7812
7813 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE);
7814 mutex_exit(&ohcip->ohci_int_mutex);
7815 return (DDI_INTR_UNCLAIMED);
7816 }
7817
7818 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7819 "Interrupt status 0x%x", intr);
7820
7821 /*
7822 * Check for Frame Number Overflow.
7823 */
7824 if (intr & HCR_INTR_FNO) {
7825 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7826 "ohci_intr: Frame Number Overflow");
7827
7828 ohci_handle_frame_number_overflow(ohcip);
7829 }
7830
7831 if (intr & HCR_INTR_SOF) {
7832 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7833 "ohci_intr: Start of Frame");
7834
7835 /* Set ohci_sof_flag indicating SOF interrupt occurred */
7836 ohcip->ohci_sof_flag = B_TRUE;
7837
7838 /* Disabel SOF interrupt */
7839 Set_OpReg(hcr_intr_disable, HCR_INTR_SOF);
7840
7841 /*
7842 * Call cv_broadcast on every SOF interrupt to wakeup
7843 * all the threads that are waiting the SOF. Calling
7844 * cv_broadcast on every SOF has no effect even if no
7845 * threads are waiting for the SOF.
7846 */
7847 cv_broadcast(&ohcip->ohci_SOF_cv);
7848 }
7849
7850 if (intr & HCR_INTR_SO) {
7851 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7852 "ohci_intr: Schedule overrun");
7853
7854 ohcip->ohci_so_error++;
7855 }
7856
7857 if ((intr & HCR_INTR_WDH) && (done_head)) {
7858 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7859 "ohci_intr: Done Head");
7860
7861 /*
7862 * Currently if we are processing one WriteDoneHead
7863 * interrupt and also if we switched to the polled
7864 * mode at least once during this time, then there
7865 * may be chance that Host Controller generates one
7866 * more Write DoneHead or Start of Frame interrupts
7867 * for the normal since the polled code clears WDH &
7868 * SOF interrupt bits before returning to the normal
7869 * mode. Under this condition, we must not clear the
7870 * HCCA done head field & also we must not clear WDH
7871 * interrupt bit in the interrupt status register.
7872 */
7873 if (done_head == (ohci_td_t *)(uintptr_t)
7874 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) &
7875 HCCA_DONE_HEAD_MASK)) {
7876
7877 /* Reset the done head to NULL */
7878 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL);
7879 } else {
7880 intr &= ~HCR_INTR_WDH;
7881 }
7882
7883 /* Clear the current done head field */
7884 ohci_intr_sts->ohci_curr_done_lst = NULL;
7885
7886 ohci_traverse_done_list(ohcip, done_head);
7887 }
7888
7889 /* Process endpoint reclaimation list */
7890 if (ohcip->ohci_reclaim_list) {
7891 ohci_handle_endpoint_reclaimation(ohcip);
7892 }
7893
7894 if (intr & HCR_INTR_RD) {
7895 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7896 "ohci_intr: Resume Detected");
7897 }
7898
7899 if (intr & HCR_INTR_RHSC) {
7900 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7901 "ohci_intr: Root hub status change");
7902 }
7903
7904 if (intr & HCR_INTR_OC) {
7905 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7906 "ohci_intr: Change ownership");
7907
7908 }
7909
7910 if (intr & HCR_INTR_UE) {
7911 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7912 "ohci_intr: Unrecoverable error");
7913
7914 ohci_handle_ue(ohcip);
7915 }
7916
7917 /* Acknowledge the interrupt */
7918 Set_OpReg(hcr_intr_status, intr);
7919
7920 /* Clear the current interrupt event field */
7921 ohci_intr_sts->ohci_curr_intr_sts = 0;
7922
7923 /*
7924 * Reset the following flag indicating exiting the interrupt
7925 * handler and this flag will be used in the polled mode to
7926 * do some extra processing.
7927 */
7928 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_HANDLING;
7929
7930 Set_OpReg(hcr_intr_enable, HCR_INTR_MIE);
7931
7932 /*
7933 * Read interrupt status register to make sure that any PIO
7934 * store to clear the ISR has made it on the PCI bus before
7935 * returning from its interrupt handler.
7936 */
7937 (void) Get_OpReg(hcr_intr_status);
7938
7939 mutex_exit(&ohcip->ohci_int_mutex);
7940
7941 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7942 "Interrupt handling completed");
7943
7944 return (DDI_INTR_CLAIMED);
7945 }
7946
7947 /*
7948 * Check whether done_head is a valid td point address.
7949 * It should be non-zero, 16-byte aligned, and fall in ohci_td_pool.
7950 */
7951 static int
ohci_check_done_head(ohci_state_t * ohcip,ohci_td_t * done_head)7952 ohci_check_done_head(ohci_state_t *ohcip, ohci_td_t *done_head)
7953 {
7954 uintptr_t lower, upper, headp;
7955 lower = ohcip->ohci_td_pool_cookie.dmac_address;
7956 upper = lower + ohcip->ohci_td_pool_cookie.dmac_size;
7957 headp = (uintptr_t)done_head;
7958
7959 if (headp && !(headp & ~HCCA_DONE_HEAD_MASK) &&
7960 (headp >= lower) && (headp < upper)) {
7961
7962 return (USB_SUCCESS);
7963 } else {
7964
7965 return (USB_FAILURE);
7966 }
7967 }
7968
7969 /*
7970 * ohci_handle_missed_intr:
7971 *
7972 * Handle any ohci missed interrupts because of polled mode switch.
7973 */
7974 static void
ohci_handle_missed_intr(ohci_state_t * ohcip)7975 ohci_handle_missed_intr(ohci_state_t *ohcip)
7976 {
7977 ohci_save_intr_sts_t *ohci_intr_sts =
7978 &ohcip->ohci_save_intr_sts;
7979 ohci_td_t *done_head;
7980 uint_t intr;
7981
7982 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
7983
7984 /*
7985 * Check whether we have missed any ohci interrupts because
7986 * of the polled mode switch during previous ohci interrupt
7987 * handler execution. Only Write Done Head & SOF interrupts
7988 * saved in the polled mode. First process these interrupts
7989 * before processing actual interrupts that caused invocation
7990 * of ohci interrupt handler.
7991 */
7992 if (!ohci_intr_sts->ohci_missed_intr_sts) {
7993 /* No interrupts are missed, simply return */
7994
7995 return;
7996 }
7997
7998 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
7999 "ohci_handle_missed_intr: Handle ohci missed interrupts");
8000
8001 /*
8002 * The functionality and importance of critical code section
8003 * in the normal mode ohci interrupt handler & its usage in
8004 * the polled mode is explained below.
8005 *
8006 * (a) Normal mode:
8007 *
8008 * - Set the flag indicating that processing critical
8009 * code in ohci interrupt handler.
8010 *
8011 * - Process the missed ohci interrupts by copying the
8012 * miised interrupt events and done head list fields
8013 * information to the critical interrupt event & done
8014 * list fields.
8015 *
8016 * - Reset the missed ohci interrupt events & done head
8017 * list fields so that the new missed interrupt event
8018 * and done head list information can be saved.
8019 *
8020 * - All above steps will be executed with in critical
8021 * section of the interrupt handler.Then ohci missed
8022 * interrupt handler will be called to service missed
8023 * ohci interrupts.
8024 *
8025 * (b) Polled mode:
8026 *
8027 * - On entering the polled code,it checks for critical
8028 * section code execution within the normal mode ohci
8029 * interrupt handler.
8030 *
8031 * - If the critical section code is executing in normal
8032 * mode ohci interrupt handler and if copying of ohci
8033 * missed interrupt events & done head list fields to
8034 * the critical fields is finished then save the "any
8035 * missed interrupt events & done head list" because
8036 * of current polled mode switch into "critical missed
8037 * interrupt events & done list fields" instead actual
8038 * missed events and done list fields.
8039 *
8040 * - Otherwise save "any missed interrupt events & done
8041 * list" because of this current polled mode switch
8042 * in the actual missed interrupt events & done head
8043 * list fields.
8044 */
8045
8046 /*
8047 * Set flag indicating that interrupt handler is processing
8048 * critical interrupt code, so that polled mode code checks
8049 * for this condition & will do extra processing as explained
8050 * above in order to aviod the race conditions.
8051 */
8052 ohci_intr_sts->ohci_intr_flag |= OHCI_INTR_CRITICAL;
8053 ohci_intr_sts->ohci_critical_intr_sts |=
8054 ohci_intr_sts->ohci_missed_intr_sts;
8055
8056 if (ohci_intr_sts->ohci_missed_done_lst) {
8057
8058 ohci_intr_sts->ohci_critical_done_lst =
8059 ohci_intr_sts->ohci_missed_done_lst;
8060 }
8061
8062 ohci_intr_sts->ohci_missed_intr_sts = 0;
8063 ohci_intr_sts->ohci_missed_done_lst = NULL;
8064 ohci_intr_sts->ohci_intr_flag &= ~OHCI_INTR_CRITICAL;
8065
8066 intr = ohci_intr_sts->ohci_critical_intr_sts;
8067 done_head = ohci_intr_sts->ohci_critical_done_lst;
8068
8069 if (intr & HCR_INTR_SOF) {
8070 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8071 "ohci_handle_missed_intr: Start of Frame");
8072
8073 /*
8074 * Call cv_broadcast on every SOF interrupt to wakeup
8075 * all the threads that are waiting the SOF. Calling
8076 * cv_broadcast on every SOF has no effect even if no
8077 * threads are waiting for the SOF.
8078 */
8079 cv_broadcast(&ohcip->ohci_SOF_cv);
8080 }
8081
8082 if ((intr & HCR_INTR_WDH) && (done_head)) {
8083 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8084 "ohci_handle_missed_intr: Done Head");
8085
8086 /* Clear the critical done head field */
8087 ohci_intr_sts->ohci_critical_done_lst = NULL;
8088
8089 ohci_traverse_done_list(ohcip, done_head);
8090 }
8091
8092 /* Clear the critical interrupt event field */
8093 ohci_intr_sts->ohci_critical_intr_sts = 0;
8094 }
8095
8096
8097 /*
8098 * ohci_handle_ue:
8099 *
8100 * Handling of Unrecoverable Error interrupt (UE).
8101 */
8102 static void
ohci_handle_ue(ohci_state_t * ohcip)8103 ohci_handle_ue(ohci_state_t *ohcip)
8104 {
8105 usb_frame_number_t before_frame_number, after_frame_number;
8106
8107 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8108
8109 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8110 "ohci_handle_ue: Handling of UE interrupt");
8111
8112 /*
8113 * First check whether current UE error occured due to USB or
8114 * due to some other subsystem. This can be verified by reading
8115 * usb frame numbers before & after a delay of few milliseconds.
8116 * If usb frame number read after delay is greater than the one
8117 * read before delay, then, USB subsystem is fine. In this case,
8118 * disable UE error interrupt and return without shutdowning the
8119 * USB subsystem.
8120 *
8121 * Otherwise, if usb frame number read after delay is less than
8122 * or equal to one read before the delay, then, current UE error
8123 * occured from USB susbsystem. In this case,go ahead with actual
8124 * UE error recovery procedure.
8125 *
8126 * Get the current usb frame number before waiting for few
8127 * milliseconds.
8128 */
8129 before_frame_number = ohci_get_current_frame_number(ohcip);
8130
8131 /* Wait for few milliseconds */
8132 drv_usecwait(OHCI_TIMEWAIT);
8133
8134 /*
8135 * Get the current usb frame number after waiting for
8136 * milliseconds.
8137 */
8138 after_frame_number = ohci_get_current_frame_number(ohcip);
8139
8140 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8141 "ohci_handle_ue: Before Frm No 0x%llx After Frm No 0x%llx",
8142 (unsigned long long)before_frame_number,
8143 (unsigned long long)after_frame_number);
8144
8145 if (after_frame_number > before_frame_number) {
8146
8147 /* Disable UE interrupt */
8148 Set_OpReg(hcr_intr_disable, HCR_INTR_UE);
8149
8150 return;
8151 }
8152
8153 /*
8154 * This UE is due to USB hardware error. Reset ohci controller
8155 * and reprogram to bring it back to functional state.
8156 */
8157 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) {
8158 USB_DPRINTF_L0(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8159 "Unrecoverable USB Hardware Error");
8160
8161 /* Disable UE interrupt */
8162 Set_OpReg(hcr_intr_disable, HCR_INTR_UE);
8163
8164 /* Set host controller soft state to error */
8165 ohcip->ohci_hc_soft_state = OHCI_CTLR_ERROR_STATE;
8166 }
8167 }
8168
8169
8170 /*
8171 * ohci_handle_frame_number_overflow:
8172 *
8173 * Update software based usb frame number part on every frame number
8174 * overflow interrupt.
8175 *
8176 * NOTE: This function is also called from POLLED MODE.
8177 *
8178 * Refer ohci spec 1.0a, section 5.3, page 81 for more details.
8179 */
8180 void
ohci_handle_frame_number_overflow(ohci_state_t * ohcip)8181 ohci_handle_frame_number_overflow(ohci_state_t *ohcip)
8182 {
8183 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8184 "ohci_handle_frame_number_overflow:");
8185
8186 ohcip->ohci_fno += (0x10000 -
8187 (((Get_HCCA(ohcip->ohci_hccap->HccaFrameNo) &
8188 0xFFFF) ^ ohcip->ohci_fno) & 0x8000));
8189
8190 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8191 "ohci_handle_frame_number_overflow:"
8192 "Frame Number Higher Part 0x%llx\n",
8193 (unsigned long long)(ohcip->ohci_fno));
8194 }
8195
8196
8197 /*
8198 * ohci_handle_endpoint_reclaimation:
8199 *
8200 * Reclamation of Host Controller (HC) Endpoint Descriptors (ED).
8201 */
8202 static void
ohci_handle_endpoint_reclaimation(ohci_state_t * ohcip)8203 ohci_handle_endpoint_reclaimation(ohci_state_t *ohcip)
8204 {
8205 usb_frame_number_t current_frame_number;
8206 usb_frame_number_t endpoint_frame_number;
8207 ohci_ed_t *reclaim_ed;
8208
8209 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8210 "ohci_handle_endpoint_reclaimation:");
8211
8212 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8213
8214 current_frame_number = ohci_get_current_frame_number(ohcip);
8215
8216 /*
8217 * Deallocate all Endpoint Descriptors (ED) which are on the
8218 * reclaimation list. These ED's are already removed from the
8219 * interrupt lattice tree.
8220 */
8221 while (ohcip->ohci_reclaim_list) {
8222 reclaim_ed = ohcip->ohci_reclaim_list;
8223
8224 endpoint_frame_number = (usb_frame_number_t)(uintptr_t)
8225 (OHCI_LOOKUP_ID(Get_ED(reclaim_ed->hced_reclaim_frame)));
8226
8227 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8228 "ohci_handle_endpoint_reclaimation:"
8229 "current frame number 0x%llx endpoint frame number 0x%llx",
8230 (unsigned long long)current_frame_number,
8231 (unsigned long long)endpoint_frame_number);
8232
8233 /*
8234 * Deallocate current endpoint only if endpoint's usb frame
8235 * number is less than or equal to current usb frame number.
8236 *
8237 * If endpoint's usb frame number is greater than the current
8238 * usb frame number, ignore rest of the endpoints in the list
8239 * since rest of the endpoints are inserted into the reclaim
8240 * list later than the current reclaim endpoint.
8241 */
8242 if (endpoint_frame_number > current_frame_number) {
8243 break;
8244 }
8245
8246 /* Get the next endpoint from the rec. list */
8247 ohcip->ohci_reclaim_list = ohci_ed_iommu_to_cpu(ohcip,
8248 Get_ED(reclaim_ed->hced_reclaim_next));
8249
8250 /* Free 32bit ID */
8251 OHCI_FREE_ID((uint32_t)Get_ED(reclaim_ed->hced_reclaim_frame));
8252
8253 /* Deallocate the endpoint */
8254 ohci_deallocate_ed(ohcip, reclaim_ed);
8255 }
8256 }
8257
8258
8259 /*
8260 * ohci_traverse_done_list:
8261 */
8262 static void
ohci_traverse_done_list(ohci_state_t * ohcip,ohci_td_t * head_done_list)8263 ohci_traverse_done_list(
8264 ohci_state_t *ohcip,
8265 ohci_td_t *head_done_list)
8266 {
8267 uint_t state; /* TD state */
8268 ohci_td_t *td, *old_td; /* TD pointers */
8269 usb_cr_t error; /* Error from TD */
8270 ohci_trans_wrapper_t *tw = NULL; /* Transfer wrapper */
8271 ohci_pipe_private_t *pp = NULL; /* Pipe private field */
8272
8273 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8274 "ohci_traverse_done_list:");
8275
8276 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8277
8278 /* Sync ED and TD pool */
8279 Sync_ED_TD_Pool(ohcip);
8280
8281 /* Reverse the done list */
8282 td = ohci_reverse_done_list(ohcip, head_done_list);
8283
8284 /* Traverse the list of transfer descriptors */
8285 while (td) {
8286 /* Check for TD state */
8287 state = Get_TD(td->hctd_state);
8288
8289 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8290 "ohci_traverse_done_list:\n\t"
8291 "td = 0x%p state = 0x%x", (void *)td, state);
8292
8293 /*
8294 * Obtain the transfer wrapper only if the TD is
8295 * not marked as RECLAIM.
8296 *
8297 * A TD that is marked as RECLAIM has had its DMA
8298 * mappings, ED, TD and pipe private structure are
8299 * ripped down. Just deallocate this TD.
8300 */
8301 if (state != HC_TD_RECLAIM) {
8302
8303 tw = (ohci_trans_wrapper_t *)OHCI_LOOKUP_ID(
8304 (uint32_t)Get_TD(td->hctd_trans_wrapper));
8305
8306 ASSERT(tw != NULL);
8307
8308 pp = tw->tw_pipe_private;
8309
8310 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8311 "ohci_traverse_done_list: PP = 0x%p TW = 0x%p",
8312 (void *)pp, (void *)tw);
8313 }
8314
8315 /*
8316 * Don't process the TD if its state is marked as
8317 * either RECLAIM or TIMEOUT.
8318 *
8319 * A TD that is marked as TIMEOUT has already been
8320 * processed by TD timeout handler & client driver
8321 * has been informed through exception callback.
8322 */
8323 if ((state != HC_TD_RECLAIM) && (state != HC_TD_TIMEOUT)) {
8324
8325 /* Look at the error status */
8326 error = ohci_parse_error(ohcip, td);
8327
8328 if (error == USB_CR_OK) {
8329 ohci_handle_normal_td(ohcip, td, tw);
8330 } else {
8331 /* handle the error condition */
8332 ohci_handle_error(ohcip, td, error);
8333 }
8334 } else {
8335 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8336 "ohci_traverse_done_list: TD State = %d", state);
8337 }
8338
8339 /*
8340 * Save a pointer to the current transfer descriptor
8341 */
8342 old_td = td;
8343
8344 td = ohci_td_iommu_to_cpu(ohcip, Get_TD(td->hctd_next_td));
8345
8346 /* Deallocate this transfer descriptor */
8347 ohci_deallocate_td(ohcip, old_td);
8348
8349 /*
8350 * Deallocate the transfer wrapper if there are no more
8351 * TD's for the transfer wrapper. ohci_deallocate_tw_resources()
8352 * will not deallocate the tw for a periodic endpoint
8353 * since it will always have a TD attached to it.
8354 *
8355 * Do not deallocate the TW if it is a isoc or intr pipe in.
8356 * The tw's are reused.
8357 *
8358 * An TD that is marked as reclaim doesn't have a pipe
8359 * or a TW associated with it anymore so don't call this
8360 * function.
8361 */
8362 if (state != HC_TD_RECLAIM) {
8363 ASSERT(tw != NULL);
8364 ohci_deallocate_tw_resources(ohcip, pp, tw);
8365 }
8366 }
8367 }
8368
8369
8370 /*
8371 * ohci_reverse_done_list:
8372 *
8373 * Reverse the order of the Transfer Descriptor (TD) Done List.
8374 */
8375 static ohci_td_t *
ohci_reverse_done_list(ohci_state_t * ohcip,ohci_td_t * head_done_list)8376 ohci_reverse_done_list(
8377 ohci_state_t *ohcip,
8378 ohci_td_t *head_done_list)
8379 {
8380 ohci_td_t *cpu_new_tail, *cpu_new_head, *cpu_save;
8381
8382 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8383 "ohci_reverse_done_list:");
8384
8385 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8386 ASSERT(head_done_list != NULL);
8387
8388 /* At first, both the tail and head pointers point to the same elem */
8389 cpu_new_tail = cpu_new_head =
8390 ohci_td_iommu_to_cpu(ohcip, (uintptr_t)head_done_list);
8391
8392 /* See if the list has only one element */
8393 if (Get_TD(cpu_new_head->hctd_next_td) == NULL) {
8394
8395 return (cpu_new_head);
8396 }
8397
8398 /* Advance the head pointer */
8399 cpu_new_head = (ohci_td_t *)
8400 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td));
8401
8402 /* The new tail now points to nothing */
8403 Set_TD(cpu_new_tail->hctd_next_td, NULL);
8404
8405 cpu_save = (ohci_td_t *)
8406 ohci_td_iommu_to_cpu(ohcip, Get_TD(cpu_new_head->hctd_next_td));
8407
8408 /* Reverse the list and store the pointers as CPU addresses */
8409 while (cpu_save) {
8410 Set_TD(cpu_new_head->hctd_next_td,
8411 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail));
8412
8413 cpu_new_tail = cpu_new_head;
8414 cpu_new_head = cpu_save;
8415
8416 cpu_save = (ohci_td_t *)
8417 ohci_td_iommu_to_cpu(ohcip,
8418 Get_TD(cpu_new_head->hctd_next_td));
8419 }
8420
8421 Set_TD(cpu_new_head->hctd_next_td,
8422 ohci_td_cpu_to_iommu(ohcip, cpu_new_tail));
8423
8424 return (cpu_new_head);
8425 }
8426
8427
8428 /*
8429 * ohci_parse_error:
8430 *
8431 * Parse the result for any errors.
8432 */
8433 static usb_cr_t
ohci_parse_error(ohci_state_t * ohcip,ohci_td_t * td)8434 ohci_parse_error(
8435 ohci_state_t *ohcip,
8436 ohci_td_t *td)
8437 {
8438 uint_t ctrl;
8439 usb_ep_descr_t *eptd;
8440 ohci_trans_wrapper_t *tw;
8441 ohci_pipe_private_t *pp;
8442 uint_t flag;
8443 usb_cr_t error;
8444
8445 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8446 "ohci_parse_error:");
8447
8448 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8449
8450 ASSERT(td != NULL);
8451
8452 /* Obtain the transfer wrapper from the TD */
8453 tw = (ohci_trans_wrapper_t *)
8454 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper));
8455
8456 ASSERT(tw != NULL);
8457
8458 /* Obtain the pipe private structure */
8459 pp = tw->tw_pipe_private;
8460
8461 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8462 "ohci_parse_error: PP 0x%p TW 0x%p", (void *)pp, (void *)tw);
8463
8464 eptd = &pp->pp_pipe_handle->p_ep;
8465
8466 ctrl = (uint_t)Get_TD(td->hctd_ctrl) & (uint32_t)HC_TD_CC;
8467
8468 /*
8469 * Check the condition code of completed TD and report errors
8470 * if any. This checking will be done both for the general and
8471 * the isochronous TDs.
8472 */
8473 if ((error = ohci_check_for_error(ohcip, pp, tw, td, ctrl)) !=
8474 USB_CR_OK) {
8475 flag = OHCI_REMOVE_XFER_ALWAYS;
8476 } else {
8477 flag = OHCI_REMOVE_XFER_IFLAST;
8478 }
8479
8480 /* Stop the the transfer timer */
8481 ohci_stop_xfer_timer(ohcip, tw, flag);
8482
8483 /*
8484 * The isochronous endpoint needs additional error checking
8485 * and special processing.
8486 */
8487 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
8488 USB_EP_ATTR_ISOCH) {
8489
8490 ohci_parse_isoc_error(ohcip, pp, tw, td);
8491
8492 /* always reset error */
8493 error = USB_CR_OK;
8494 }
8495
8496 return (error);
8497 }
8498
8499
8500 /*
8501 * ohci_parse_isoc_error:
8502 *
8503 * Check for any errors in the isochronous data packets. Also fillup
8504 * the status for each of the isochrnous data packets.
8505 */
8506 void
ohci_parse_isoc_error(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td)8507 ohci_parse_isoc_error(
8508 ohci_state_t *ohcip,
8509 ohci_pipe_private_t *pp,
8510 ohci_trans_wrapper_t *tw,
8511 ohci_td_t *td)
8512 {
8513 usb_isoc_req_t *isoc_reqp;
8514 usb_isoc_pkt_descr_t *isoc_pkt_descr;
8515 uint_t toggle = 0, fc, ctrl, psw;
8516 int i;
8517
8518 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8519 "ohci_parse_isoc_error: td 0x%p", (void *)td);
8520
8521 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8522
8523 fc = ((uint_t)Get_TD(td->hctd_ctrl) &
8524 HC_ITD_FC) >> HC_ITD_FC_SHIFT;
8525
8526 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
8527 "ohci_parse_isoc_error: frame count %d", fc);
8528
8529 /*
8530 * Get the address of current usb isochronous request
8531 * and array of packet descriptors.
8532 */
8533 isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
8534 isoc_pkt_descr = isoc_reqp->isoc_pkt_descr;
8535 isoc_pkt_descr += tw->tw_pkt_idx;
8536
8537 for (i = 0; i <= fc; i++) {
8538
8539 psw = Get_TD(td->hctd_offsets[i / 2]);
8540
8541 if (toggle) {
8542 ctrl = psw & HC_ITD_ODD_OFFSET;
8543 toggle = 0;
8544 } else {
8545 ctrl = (psw & HC_ITD_EVEN_OFFSET) <<
8546 HC_ITD_OFFSET_SHIFT;
8547 toggle = 1;
8548 }
8549
8550 isoc_pkt_descr->isoc_pkt_actual_length =
8551 (ctrl >> HC_ITD_OFFSET_SHIFT) & HC_ITD_OFFSET_ADDR;
8552
8553 ctrl = (uint_t)(ctrl & (uint32_t)HC_TD_CC);
8554
8555 /* Write the status of isoc data packet */
8556 isoc_pkt_descr->isoc_pkt_status =
8557 ohci_check_for_error(ohcip, pp, tw, td, ctrl);
8558
8559 if (isoc_pkt_descr->isoc_pkt_status) {
8560 /* Increment isoc data packet error count */
8561 isoc_reqp->isoc_error_count++;
8562 }
8563
8564 /*
8565 * Get the address of next isoc data packet descriptor.
8566 */
8567 isoc_pkt_descr++;
8568 }
8569 tw->tw_pkt_idx = tw->tw_pkt_idx + fc + 1;
8570
8571 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
8572 "ohci_parse_isoc_error: tw_pkt_idx %d", tw->tw_pkt_idx);
8573
8574 }
8575
8576
8577 /*
8578 * ohci_check_for_error:
8579 *
8580 * Check for any errors.
8581 */
8582 static usb_cr_t
ohci_check_for_error(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td,uint_t ctrl)8583 ohci_check_for_error(
8584 ohci_state_t *ohcip,
8585 ohci_pipe_private_t *pp,
8586 ohci_trans_wrapper_t *tw,
8587 ohci_td_t *td,
8588 uint_t ctrl)
8589 {
8590 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
8591 uchar_t ep_attrs = ph->p_ep.bmAttributes;
8592 usb_cr_t error = USB_CR_OK;
8593 usb_req_attrs_t xfer_attrs;
8594
8595 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8596 "ohci_check_for_error: td = 0x%p ctrl = 0x%x",
8597 (void *)td, ctrl);
8598
8599 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8600
8601 switch (ctrl) {
8602 case HC_TD_CC_NO_E:
8603 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8604 "ohci_check_for_error: No Error");
8605 error = USB_CR_OK;
8606 break;
8607 case HC_TD_CC_CRC:
8608 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8609 "ohci_check_for_error: CRC error");
8610 error = USB_CR_CRC;
8611 break;
8612 case HC_TD_CC_BS:
8613 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8614 "ohci_check_for_error: Bit stuffing");
8615 error = USB_CR_BITSTUFFING;
8616 break;
8617 case HC_TD_CC_DTM:
8618 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8619 "ohci_check_for_error: Data Toggle Mismatch");
8620 error = USB_CR_DATA_TOGGLE_MM;
8621 break;
8622 case HC_TD_CC_STALL:
8623 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8624 "ohci_check_for_error: Stall");
8625 error = USB_CR_STALL;
8626 break;
8627 case HC_TD_CC_DNR:
8628 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8629 "ohci_check_for_error: Device not responding");
8630 error = USB_CR_DEV_NOT_RESP;
8631 break;
8632 case HC_TD_CC_PCF:
8633 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8634 "ohci_check_for_error: PID check failure");
8635 error = USB_CR_PID_CHECKFAILURE;
8636 break;
8637 case HC_TD_CC_UPID:
8638 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8639 "ohci_check_for_error: Unexpected PID");
8640 error = USB_CR_UNEXP_PID;
8641 break;
8642 case HC_TD_CC_DO:
8643 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8644 "ohci_check_for_error: Data overrrun");
8645 error = USB_CR_DATA_OVERRUN;
8646 break;
8647 case HC_TD_CC_DU:
8648 /*
8649 * Check whether short packets are acceptable.
8650 * If so don't report error to client drivers
8651 * and restart the endpoint. Otherwise report
8652 * data underrun error to client driver.
8653 */
8654 xfer_attrs = ohci_get_xfer_attrs(ohcip, pp, tw);
8655
8656 if (xfer_attrs & USB_ATTRS_SHORT_XFER_OK) {
8657 error = USB_CR_OK;
8658 if ((ep_attrs & USB_EP_ATTR_MASK) !=
8659 USB_EP_ATTR_ISOCH) {
8660 /*
8661 * Cleanup the remaining resources that may have
8662 * been allocated for this transfer.
8663 */
8664 if (ohci_cleanup_data_underrun(ohcip, pp, tw,
8665 td) == USB_SUCCESS) {
8666 /* Clear the halt bit */
8667 Set_ED(pp->pp_ept->hced_headp,
8668 (Get_ED(pp->pp_ept->hced_headp) &
8669 ~HC_EPT_Halt));
8670 } else {
8671 error = USB_CR_UNSPECIFIED_ERR;
8672 }
8673 }
8674 } else {
8675 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8676 "ohci_check_for_error: Data underrun");
8677
8678 error = USB_CR_DATA_UNDERRUN;
8679 }
8680
8681 break;
8682 case HC_TD_CC_BO:
8683 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8684 "ohci_check_for_error: Buffer overrun");
8685 error = USB_CR_BUFFER_OVERRUN;
8686 break;
8687 case HC_TD_CC_BU:
8688 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8689 "ohci_check_for_error: Buffer underrun");
8690 error = USB_CR_BUFFER_UNDERRUN;
8691 break;
8692 case HC_TD_CC_NA:
8693 default:
8694 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8695 "ohci_check_for_error: Not accessed");
8696 error = USB_CR_NOT_ACCESSED;
8697 break;
8698 }
8699
8700 if (error) {
8701 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl);
8702
8703 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8704 "ohci_check_for_error: Error %d Device address %d "
8705 "Endpoint number %d", error, (hced_ctrl & HC_EPT_FUNC),
8706 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT));
8707 }
8708
8709 return (error);
8710 }
8711
8712
8713 /*
8714 * ohci_handle_error:
8715 *
8716 * Inform USBA about occured transaction errors by calling the USBA callback
8717 * routine.
8718 */
8719 static void
ohci_handle_error(ohci_state_t * ohcip,ohci_td_t * td,usb_cr_t error)8720 ohci_handle_error(
8721 ohci_state_t *ohcip,
8722 ohci_td_t *td,
8723 usb_cr_t error)
8724 {
8725 ohci_trans_wrapper_t *tw;
8726 usba_pipe_handle_data_t *ph;
8727 ohci_pipe_private_t *pp;
8728 mblk_t *mp = NULL;
8729 size_t length = 0;
8730 uchar_t attributes;
8731 usb_intr_req_t *curr_intr_reqp;
8732
8733 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8734 "ohci_handle_error: error = 0x%x", error);
8735
8736 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8737
8738 ASSERT(td != NULL);
8739
8740 /* Print the values in the td */
8741 ohci_print_td(ohcip, td);
8742
8743 /* Obtain the transfer wrapper from the TD */
8744 tw = (ohci_trans_wrapper_t *)
8745 OHCI_LOOKUP_ID((uint32_t)Get_TD(td->hctd_trans_wrapper));
8746
8747 ASSERT(tw != NULL);
8748
8749 /* Obtain the pipe private structure */
8750 pp = tw->tw_pipe_private;
8751
8752 ph = tw->tw_pipe_private->pp_pipe_handle;
8753 attributes = ph->p_ep.bmAttributes & USB_EP_ATTR_MASK;
8754
8755 /*
8756 * Special error handling
8757 */
8758 if (tw->tw_direction == HC_TD_IN) {
8759
8760 switch (attributes) {
8761 case USB_EP_ATTR_CONTROL:
8762 if (((ph->p_ep.bmAttributes &
8763 USB_EP_ATTR_MASK) ==
8764 USB_EP_ATTR_CONTROL) &&
8765 (Get_TD(td->hctd_ctrl_phase) ==
8766 OHCI_CTRL_SETUP_PHASE)) {
8767
8768 break;
8769 }
8770 /* FALLTHROUGH */
8771 case USB_EP_ATTR_BULK:
8772 /*
8773 * Call ohci_sendup_td_message
8774 * to send message to upstream.
8775 */
8776 ohci_sendup_td_message(ohcip, pp, tw, td, error);
8777
8778 return;
8779 case USB_EP_ATTR_INTR:
8780 curr_intr_reqp =
8781 (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
8782
8783 if (curr_intr_reqp->intr_attributes &
8784 USB_ATTRS_ONE_XFER) {
8785
8786 ohci_handle_one_xfer_completion(ohcip, tw);
8787 }
8788
8789 /* Decrement periodic in request count */
8790 pp->pp_cur_periodic_req_cnt--;
8791 break;
8792 case USB_EP_ATTR_ISOCH:
8793 default:
8794 break;
8795 }
8796 } else {
8797 switch (attributes) {
8798 case USB_EP_ATTR_BULK:
8799 case USB_EP_ATTR_INTR:
8800 /*
8801 * If "CurrentBufferPointer" of Transfer
8802 * Descriptor (TD) is not equal to zero,
8803 * then we sent less data to the device
8804 * than requested by client. In that case,
8805 * return the mblk after updating the
8806 * data->r_ptr.
8807 */
8808 if (Get_TD(td->hctd_cbp)) {
8809 usb_opaque_t xfer_reqp = tw->tw_curr_xfer_reqp;
8810 size_t residue;
8811
8812 residue = ohci_get_td_residue(ohcip, td);
8813 length = Get_TD(td->hctd_xfer_offs) +
8814 Get_TD(td->hctd_xfer_len) - residue;
8815
8816 USB_DPRINTF_L2(PRINT_MASK_INTR,
8817 ohcip->ohci_log_hdl,
8818 "ohci_handle_error: requested data %lu "
8819 "sent data %lu", tw->tw_length, length);
8820
8821 if (attributes == USB_EP_ATTR_BULK) {
8822 mp = (mblk_t *)((usb_bulk_req_t *)
8823 (xfer_reqp))->bulk_data;
8824 } else {
8825 mp = (mblk_t *)((usb_intr_req_t *)
8826 (xfer_reqp))->intr_data;
8827 }
8828
8829 /* Increment the read pointer */
8830 mp->b_rptr = mp->b_rptr + length;
8831 }
8832 break;
8833 default:
8834 break;
8835 }
8836 }
8837
8838 /*
8839 * Callback the client with the
8840 * failure reason.
8841 */
8842 ohci_hcdi_callback(ph, tw, error);
8843
8844 /* Check anybody is waiting for transfers completion event */
8845 ohci_check_for_transfers_completion(ohcip, pp);
8846 }
8847
8848 /*
8849 * ohci_cleanup_data_underrun:
8850 *
8851 * Cleans up resources when a short xfer occurs
8852 */
8853 static int
ohci_cleanup_data_underrun(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td)8854 ohci_cleanup_data_underrun(
8855 ohci_state_t *ohcip,
8856 ohci_pipe_private_t *pp,
8857 ohci_trans_wrapper_t *tw,
8858 ohci_td_t *td)
8859 {
8860 ohci_td_t *next_td;
8861 ohci_td_t *last_td;
8862 ohci_td_t *temp_td;
8863 uint32_t last_td_addr;
8864 uint_t hced_head;
8865
8866 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8867 "ohci_cleanup_data_underrun: td 0x%p, tw 0x%p",
8868 (void *)td, (void *)tw);
8869
8870 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8871 ASSERT(tw->tw_hctd_head == td);
8872
8873 /* Check if this TD is the last td in the tw */
8874 last_td = tw->tw_hctd_tail;
8875 if (td == last_td) {
8876 /* There is no need for cleanup */
8877 return (USB_SUCCESS);
8878 }
8879
8880 /*
8881 * Make sure the ED is halted before we change any td's.
8882 * If for some reason it is not halted, return error to client
8883 * driver so they can reset the port.
8884 */
8885 hced_head = Get_ED(pp->pp_ept->hced_headp);
8886 if (!(hced_head & HC_EPT_Halt)) {
8887 uint_t hced_ctrl = Get_ED(pp->pp_ept->hced_ctrl);
8888
8889 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8890 "ohci_cleanup_data_underrun: Unable to clean up a short "
8891 "xfer error. Client might send/receive irrelevant data."
8892 " Device address %d Endpoint number %d",
8893 (hced_ctrl & HC_EPT_FUNC),
8894 ((hced_ctrl & HC_EPT_EP) >> HC_EPT_EP_SHFT));
8895
8896 Set_ED(pp->pp_ept->hced_headp, hced_head | HC_EPT_Halt);
8897
8898 return (USB_FAILURE);
8899 }
8900
8901 /*
8902 * Get the address of the first td of the next transfer (tw).
8903 * This td, may currently be a dummy td, but when a new request
8904 * arrives, it will be transformed into a regular td.
8905 */
8906 last_td_addr = Get_TD(last_td->hctd_next_td);
8907 /* Set ED head to this last td */
8908 Set_ED(pp->pp_ept->hced_headp,
8909 (last_td_addr & HC_EPT_TD_HEAD) |
8910 (hced_head & ~HC_EPT_TD_HEAD));
8911
8912 /*
8913 * Start removing all the unused TD's from the TW,
8914 * but keep the first one.
8915 */
8916 tw->tw_hctd_tail = td;
8917
8918 /*
8919 * Get the last_td, the next td in the tw list.
8920 * Afterwards completely disassociate the current td from other tds
8921 */
8922 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip,
8923 Get_TD(td->hctd_tw_next_td));
8924 Set_TD(td->hctd_tw_next_td, NULL);
8925
8926 /*
8927 * Iterate down the tw list and deallocate them
8928 */
8929 while (next_td != NULL) {
8930 tw->tw_num_tds--;
8931 /* Disassociate this td from it's TW and set to RECLAIM */
8932 Set_TD(next_td->hctd_trans_wrapper, NULL);
8933 Set_TD(next_td->hctd_state, HC_TD_RECLAIM);
8934
8935 temp_td = next_td;
8936
8937 next_td = (ohci_td_t *)ohci_td_iommu_to_cpu(ohcip,
8938 Get_TD(next_td->hctd_tw_next_td));
8939
8940 ohci_deallocate_td(ohcip, temp_td);
8941 }
8942
8943 ASSERT(tw->tw_num_tds == 1);
8944
8945 return (USB_SUCCESS);
8946 }
8947
8948 /*
8949 * ohci_handle_normal_td:
8950 */
8951 static void
ohci_handle_normal_td(ohci_state_t * ohcip,ohci_td_t * td,ohci_trans_wrapper_t * tw)8952 ohci_handle_normal_td(
8953 ohci_state_t *ohcip,
8954 ohci_td_t *td,
8955 ohci_trans_wrapper_t *tw)
8956 {
8957 ohci_pipe_private_t *pp; /* Pipe private field */
8958
8959 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8960 "ohci_handle_normal_td:");
8961
8962 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8963 ASSERT(tw != NULL);
8964
8965 /* Obtain the pipe private structure */
8966 pp = tw->tw_pipe_private;
8967
8968 (*tw->tw_handle_td)(ohcip, pp, tw,
8969 td, tw->tw_handle_callback_value);
8970
8971 /* Check anybody is waiting for transfers completion event */
8972 ohci_check_for_transfers_completion(ohcip, pp);
8973 }
8974
8975
8976 /*
8977 * ohci_handle_ctrl_td:
8978 *
8979 * Handle a control Transfer Descriptor (TD).
8980 */
8981 /* ARGSUSED */
8982 static void
ohci_handle_ctrl_td(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td,void * tw_handle_callback_value)8983 ohci_handle_ctrl_td(
8984 ohci_state_t *ohcip,
8985 ohci_pipe_private_t *pp,
8986 ohci_trans_wrapper_t *tw,
8987 ohci_td_t *td,
8988 void *tw_handle_callback_value)
8989 {
8990 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
8991
8992 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
8993 "ohci_handle_ctrl_td: pp = 0x%p tw = 0x%p td = 0x%p state = 0x%x",
8994 (void *)pp, (void *)tw, (void *)td, Get_TD(td->hctd_ctrl_phase));
8995
8996 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
8997
8998 /*
8999 * Check which control transfer phase got completed.
9000 */
9001 tw->tw_num_tds--;
9002 switch (Get_TD(td->hctd_ctrl_phase)) {
9003 case OHCI_CTRL_SETUP_PHASE:
9004 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9005 "Setup complete: pp 0x%p td 0x%p", (void *)pp, (void *)td);
9006
9007 break;
9008 case OHCI_CTRL_DATA_PHASE:
9009 /*
9010 * If "CurrentBufferPointer" of Transfer Descriptor (TD)
9011 * is not equal to zero, then we received less data from
9012 * the device than requested by us. In that case, get the
9013 * actual received data size.
9014 */
9015 if (Get_TD(td->hctd_cbp)) {
9016 size_t length, residue;
9017
9018 residue = ohci_get_td_residue(ohcip, td);
9019 length = Get_TD(td->hctd_xfer_offs) +
9020 Get_TD(td->hctd_xfer_len) - residue;
9021
9022 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9023 "ohci_handle_ctrl_qtd: requested data %lu "
9024 "received data %lu", tw->tw_length, length);
9025
9026 /* Save actual received data length */
9027 tw->tw_length = length;
9028 }
9029
9030 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9031 "Data complete: pp 0x%p td 0x%p",
9032 (void *)pp, (void *)td);
9033
9034 break;
9035 case OHCI_CTRL_STATUS_PHASE:
9036 if ((tw->tw_length != 0) &&
9037 (tw->tw_direction == HC_TD_IN)) {
9038
9039 /*
9040 * Call ohci_sendup_td_message
9041 * to send message to upstream.
9042 */
9043 ohci_sendup_td_message(ohcip,
9044 pp, tw, td, USB_CR_OK);
9045 } else {
9046 ohci_do_byte_stats(ohcip,
9047 tw->tw_length - OHCI_MAX_TD_BUF_SIZE,
9048 ph->p_ep.bmAttributes,
9049 ph->p_ep.bEndpointAddress);
9050
9051 ohci_hcdi_callback(ph, tw, USB_CR_OK);
9052 }
9053
9054 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9055 "Status complete: pp 0x%p td 0x%p", (void *)pp, (void *)td);
9056
9057 break;
9058 }
9059 }
9060
9061
9062 /*
9063 * ohci_handle_bulk_td:
9064 *
9065 * Handle a bulk Transfer Descriptor (TD).
9066 */
9067 /* ARGSUSED */
9068 static void
ohci_handle_bulk_td(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td,void * tw_handle_callback_value)9069 ohci_handle_bulk_td(
9070 ohci_state_t *ohcip,
9071 ohci_pipe_private_t *pp,
9072 ohci_trans_wrapper_t *tw,
9073 ohci_td_t *td,
9074 void *tw_handle_callback_value)
9075 {
9076 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9077 usb_ep_descr_t *eptd = &ph->p_ep;
9078
9079 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9080 "ohci_handle_bulk_td:");
9081
9082 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9083
9084 /*
9085 * Decrement the TDs counter and check whether all the bulk
9086 * data has been send or received. If TDs counter reaches
9087 * zero then inform client driver about completion current
9088 * bulk request. Other wise wait for completion of other bulk
9089 * TDs or transactions on this pipe.
9090 */
9091 if (--tw->tw_num_tds != 0) {
9092
9093 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9094 "ohci_handle_bulk_td: Number of TDs %d", tw->tw_num_tds);
9095
9096 return;
9097 }
9098
9099 /*
9100 * If this is a bulk in pipe, return the data to the client.
9101 * For a bulk out pipe, there is no need to do anything.
9102 */
9103 if ((eptd->bEndpointAddress &
9104 USB_EP_DIR_MASK) == USB_EP_DIR_OUT) {
9105
9106 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9107 "ohci_handle_bulk_td: Bulk out pipe");
9108
9109 ohci_do_byte_stats(ohcip, tw->tw_length,
9110 eptd->bmAttributes, eptd->bEndpointAddress);
9111
9112 /* Do the callback */
9113 ohci_hcdi_callback(ph, tw, USB_CR_OK);
9114
9115 return;
9116 }
9117
9118 /* Call ohci_sendup_td_message to send message to upstream */
9119 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK);
9120 }
9121
9122
9123 /*
9124 * ohci_handle_intr_td:
9125 *
9126 * Handle a interrupt Transfer Descriptor (TD).
9127 */
9128 /* ARGSUSED */
9129 static void
ohci_handle_intr_td(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td,void * tw_handle_callback_value)9130 ohci_handle_intr_td(
9131 ohci_state_t *ohcip,
9132 ohci_pipe_private_t *pp,
9133 ohci_trans_wrapper_t *tw,
9134 ohci_td_t *td,
9135 void *tw_handle_callback_value)
9136 {
9137 usb_intr_req_t *curr_intr_reqp =
9138 (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
9139 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9140 usb_ep_descr_t *eptd = &ph->p_ep;
9141 usb_req_attrs_t attrs;
9142 int error = USB_SUCCESS;
9143
9144 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9145 "ohci_handle_intr_td: pp=0x%p tw=0x%p td=0x%p"
9146 "intr_reqp=0%p data=0x%p", (void *)pp, (void *)tw, (void *)td,
9147 (void *)curr_intr_reqp, (void *)curr_intr_reqp->intr_data);
9148
9149 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9150
9151 /* Get the interrupt xfer attributes */
9152 attrs = curr_intr_reqp->intr_attributes;
9153
9154 /*
9155 * For a Interrupt OUT pipe, we just callback and we are done
9156 */
9157 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) {
9158
9159 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9160 "ohci_handle_intr_td: Intr out pipe, intr_reqp=0x%p,"
9161 "data=0x%p", (void *)curr_intr_reqp,
9162 (void *)curr_intr_reqp->intr_data);
9163
9164 ohci_do_byte_stats(ohcip, tw->tw_length,
9165 eptd->bmAttributes, eptd->bEndpointAddress);
9166
9167 /* Do the callback */
9168 ohci_hcdi_callback(ph, tw, USB_CR_OK);
9169
9170 return;
9171 }
9172
9173 /* Decrement number of interrupt request count */
9174 pp->pp_cur_periodic_req_cnt--;
9175
9176 /*
9177 * Check usb flag whether USB_FLAGS_ONE_XFER flag is set
9178 * and if so, free duplicate request.
9179 */
9180 if (attrs & USB_ATTRS_ONE_XFER) {
9181 ohci_handle_one_xfer_completion(ohcip, tw);
9182 }
9183
9184 /* Call ohci_sendup_td_message to callback into client */
9185 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK);
9186
9187 /*
9188 * If interrupt pipe state is still active, insert next Interrupt
9189 * request into the Host Controller's Interrupt list. Otherwise
9190 * you are done.
9191 */
9192 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) {
9193 return;
9194 }
9195
9196 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) ==
9197 USB_SUCCESS) {
9198 curr_intr_reqp = (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
9199
9200 ASSERT(curr_intr_reqp != NULL);
9201
9202 tw->tw_num_tds = 1;
9203
9204 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) {
9205 ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9206 error = USB_FAILURE;
9207 } else if (ohci_allocate_tds_for_tw(ohcip, tw,
9208 tw->tw_num_tds) != USB_SUCCESS) {
9209 ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9210 error = USB_FAILURE;
9211 }
9212 }
9213
9214 if (error != USB_SUCCESS) {
9215 /*
9216 * Set pipe state to stop polling and error to no
9217 * resource. Don't insert any more interrupt polling
9218 * requests.
9219 */
9220 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
9221 pp->pp_error = USB_CR_NO_RESOURCES;
9222 } else {
9223 ohci_insert_intr_req(ohcip, pp, tw, 0);
9224
9225 /* Increment number of interrupt request count */
9226 pp->pp_cur_periodic_req_cnt++;
9227
9228 ASSERT(pp->pp_cur_periodic_req_cnt ==
9229 pp->pp_max_periodic_req_cnt);
9230 }
9231 }
9232
9233
9234 /*
9235 * ohci_handle_one_xfer_completion:
9236 */
9237 static void
ohci_handle_one_xfer_completion(ohci_state_t * ohcip,ohci_trans_wrapper_t * tw)9238 ohci_handle_one_xfer_completion(
9239 ohci_state_t *ohcip,
9240 ohci_trans_wrapper_t *tw)
9241 {
9242 usba_pipe_handle_data_t *ph = tw->tw_pipe_private->pp_pipe_handle;
9243 ohci_pipe_private_t *pp = tw->tw_pipe_private;
9244 usb_intr_req_t *curr_intr_reqp =
9245 (usb_intr_req_t *)tw->tw_curr_xfer_reqp;
9246
9247 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9248 "ohci_handle_one_xfer_completion: tw = 0x%p", (void *)tw);
9249
9250 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9251 ASSERT(curr_intr_reqp->intr_attributes & USB_ATTRS_ONE_XFER);
9252
9253 pp->pp_state = OHCI_PIPE_STATE_IDLE;
9254
9255 /*
9256 * For one xfer, we need to copy back data ptr
9257 * and free current request
9258 */
9259 ((usb_intr_req_t *)(pp->pp_client_periodic_in_reqp))->
9260 intr_data = ((usb_intr_req_t *)
9261 (tw->tw_curr_xfer_reqp))->intr_data;
9262
9263 ((usb_intr_req_t *)tw->tw_curr_xfer_reqp)->intr_data = NULL;
9264
9265 /* Now free duplicate current request */
9266 usb_free_intr_req((usb_intr_req_t *)tw-> tw_curr_xfer_reqp);
9267
9268 mutex_enter(&ph->p_mutex);
9269 ph->p_req_count--;
9270 mutex_exit(&ph->p_mutex);
9271
9272 /* Make client's request the current request */
9273 tw->tw_curr_xfer_reqp = pp->pp_client_periodic_in_reqp;
9274 pp->pp_client_periodic_in_reqp = NULL;
9275 }
9276
9277
9278 /*
9279 * ohci_handle_isoc_td:
9280 *
9281 * Handle an isochronous Transfer Descriptor (TD).
9282 */
9283 /* ARGSUSED */
9284 static void
ohci_handle_isoc_td(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td,void * tw_handle_callback_value)9285 ohci_handle_isoc_td(
9286 ohci_state_t *ohcip,
9287 ohci_pipe_private_t *pp,
9288 ohci_trans_wrapper_t *tw,
9289 ohci_td_t *td,
9290 void *tw_handle_callback_value)
9291 {
9292 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9293 usb_ep_descr_t *eptd = &ph->p_ep;
9294 usb_isoc_req_t *curr_isoc_reqp =
9295 (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
9296 int error = USB_SUCCESS;
9297
9298 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9299 "ohci_handle_isoc_td: pp=0x%p tw=0x%p td=0x%p"
9300 "isoc_reqp=0%p data=0x%p", (void *)pp, (void *)tw, (void *)td,
9301 (void *)curr_isoc_reqp, (void *)curr_isoc_reqp->isoc_data);
9302
9303 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9304
9305 /*
9306 * Decrement the TDs counter and check whether all the isoc
9307 * data has been send or received. If TDs counter reaches
9308 * zero then inform client driver about completion current
9309 * isoc request. Otherwise wait for completion of other isoc
9310 * TDs or transactions on this pipe.
9311 */
9312 if (--tw->tw_num_tds != 0) {
9313
9314 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9315 "ohci_handle_isoc_td: Number of TDs %d", tw->tw_num_tds);
9316
9317 return;
9318 }
9319
9320 /*
9321 * If this is a isoc in pipe, return the data to the client.
9322 * For a isoc out pipe, there is no need to do anything.
9323 */
9324 if ((eptd->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_OUT) {
9325 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9326 "ohci_handle_isoc_td: Isoc out pipe, isoc_reqp=0x%p,"
9327 "data=0x%p", (void *)curr_isoc_reqp,
9328 (void *)curr_isoc_reqp->isoc_data);
9329
9330 ohci_do_byte_stats(ohcip, tw->tw_length,
9331 eptd->bmAttributes, eptd->bEndpointAddress);
9332
9333 /* Do the callback */
9334 ohci_hcdi_callback(ph, tw, USB_CR_OK);
9335
9336 return;
9337 }
9338
9339 /* Decrement number of IN isochronous request count */
9340 pp->pp_cur_periodic_req_cnt--;
9341
9342 /* Call ohci_sendup_td_message to send message to upstream */
9343 ohci_sendup_td_message(ohcip, pp, tw, td, USB_CR_OK);
9344
9345 /*
9346 * If isochronous pipe state is still active, insert next isochronous
9347 * request into the Host Controller's isochronous list.
9348 */
9349 if (pp->pp_state != OHCI_PIPE_STATE_ACTIVE) {
9350 return;
9351 }
9352
9353 if ((error = ohci_allocate_periodic_in_resource(ohcip, pp, tw, 0)) ==
9354 USB_SUCCESS) {
9355 curr_isoc_reqp = (usb_isoc_req_t *)tw->tw_curr_xfer_reqp;
9356
9357 ASSERT(curr_isoc_reqp != NULL);
9358
9359 tw->tw_num_tds =
9360 curr_isoc_reqp->isoc_pkts_count / OHCI_ISOC_PKTS_PER_TD;
9361 if (curr_isoc_reqp->isoc_pkts_count % OHCI_ISOC_PKTS_PER_TD) {
9362 tw->tw_num_tds++;
9363 }
9364
9365 if (ohci_tw_rebind_cookie(ohcip, pp, tw) != USB_SUCCESS) {
9366 ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9367 error = USB_FAILURE;
9368 } else if (ohci_allocate_tds_for_tw(ohcip, tw,
9369 tw->tw_num_tds) != USB_SUCCESS) {
9370 ohci_deallocate_periodic_in_resource(ohcip, pp, tw);
9371 error = USB_FAILURE;
9372 }
9373 }
9374
9375 if (error != USB_SUCCESS ||
9376 ohci_insert_isoc_req(ohcip, pp, tw, 0) != USB_SUCCESS) {
9377 /*
9378 * Set pipe state to stop polling and error to no
9379 * resource. Don't insert any more isoch polling
9380 * requests.
9381 */
9382 pp->pp_state = OHCI_PIPE_STATE_STOP_POLLING;
9383 pp->pp_error = USB_CR_NO_RESOURCES;
9384
9385 } else {
9386 /* Increment number of IN isochronous request count */
9387 pp->pp_cur_periodic_req_cnt++;
9388
9389 ASSERT(pp->pp_cur_periodic_req_cnt ==
9390 pp->pp_max_periodic_req_cnt);
9391 }
9392 }
9393
9394
9395 /*
9396 * ohci_tw_rebind_cookie:
9397 *
9398 * If the cookie associated with a DMA buffer has been walked, the cookie
9399 * is not usable any longer. To reuse the DMA buffer, the DMA handle needs
9400 * to rebind for cookies.
9401 */
9402 static int
ohci_tw_rebind_cookie(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)9403 ohci_tw_rebind_cookie(
9404 ohci_state_t *ohcip,
9405 ohci_pipe_private_t *pp,
9406 ohci_trans_wrapper_t *tw)
9407 {
9408 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep;
9409 int rval, i;
9410 uint_t ccount;
9411
9412 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9413 "ohci_tw_rebind_cookie:");
9414
9415 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9416
9417 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH) {
9418 ASSERT(tw->tw_num_tds == tw->tw_ncookies);
9419
9420 for (i = 0; i < tw->tw_num_tds; i++) {
9421 if (tw->tw_isoc_bufs[i].ncookies == 1) {
9422
9423 /*
9424 * no need to rebind when there is
9425 * only one cookie in a buffer
9426 */
9427 continue;
9428 }
9429
9430 /* unbind the DMA handle before rebinding */
9431 rval = ddi_dma_unbind_handle(
9432 tw->tw_isoc_bufs[i].dma_handle);
9433 ASSERT(rval == USB_SUCCESS);
9434 tw->tw_isoc_bufs[i].ncookies = 0;
9435
9436 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9437 "rebind dma_handle %d", i);
9438
9439 /* rebind the handle to get cookies */
9440 rval = ddi_dma_addr_bind_handle(
9441 tw->tw_isoc_bufs[i].dma_handle, NULL,
9442 (caddr_t)tw->tw_isoc_bufs[i].buf_addr,
9443 tw->tw_isoc_bufs[i].length,
9444 DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
9445 DDI_DMA_DONTWAIT, NULL,
9446 &tw->tw_isoc_bufs[i].cookie, &ccount);
9447
9448 if ((rval == DDI_DMA_MAPPED) &&
9449 (ccount <= OHCI_DMA_ATTR_TD_SGLLEN)) {
9450 tw->tw_isoc_bufs[i].ncookies = ccount;
9451 } else {
9452
9453 return (USB_NO_RESOURCES);
9454 }
9455 }
9456 } else {
9457 if (tw->tw_cookie_idx != 0) {
9458 /* unbind the DMA handle before rebinding */
9459 rval = ddi_dma_unbind_handle(tw->tw_dmahandle);
9460 ASSERT(rval == DDI_SUCCESS);
9461 tw->tw_ncookies = 0;
9462
9463 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9464 "rebind dma_handle");
9465
9466 /* rebind the handle to get cookies */
9467 rval = ddi_dma_addr_bind_handle(
9468 tw->tw_dmahandle, NULL,
9469 (caddr_t)tw->tw_buf, tw->tw_length,
9470 DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
9471 DDI_DMA_DONTWAIT, NULL,
9472 &tw->tw_cookie, &ccount);
9473
9474 if (rval == DDI_DMA_MAPPED) {
9475 tw->tw_ncookies = ccount;
9476 tw->tw_dma_offs = 0;
9477 tw->tw_cookie_idx = 0;
9478 } else {
9479
9480 return (USB_NO_RESOURCES);
9481 }
9482 }
9483 }
9484
9485 return (USB_SUCCESS);
9486 }
9487
9488
9489 /*
9490 * ohci_sendup_td_message:
9491 * copy data, if necessary and do callback
9492 */
9493 static void
ohci_sendup_td_message(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,ohci_td_t * td,usb_cr_t error)9494 ohci_sendup_td_message(
9495 ohci_state_t *ohcip,
9496 ohci_pipe_private_t *pp,
9497 ohci_trans_wrapper_t *tw,
9498 ohci_td_t *td,
9499 usb_cr_t error)
9500 {
9501 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep;
9502 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
9503 size_t length = 0, skip_len = 0, residue;
9504 mblk_t *mp;
9505 uchar_t *buf;
9506 usb_opaque_t curr_xfer_reqp = tw->tw_curr_xfer_reqp;
9507
9508 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9509
9510 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9511 "ohci_sendup_td_message:");
9512
9513 ASSERT(tw != NULL);
9514
9515 length = tw->tw_length;
9516
9517 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
9518 case USB_EP_ATTR_CONTROL:
9519 /*
9520 * Get the correct length, adjust it for the setup size
9521 * which is not part of the data length in control end
9522 * points. Update tw->tw_length for future references.
9523 */
9524 if (((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_wLength) {
9525 tw->tw_length = length = length - OHCI_MAX_TD_BUF_SIZE;
9526 } else {
9527 tw->tw_length = length = length - SETUP_SIZE;
9528 }
9529
9530 /* Set the length of the buffer to skip */
9531 skip_len = OHCI_MAX_TD_BUF_SIZE;
9532
9533 if (Get_TD(td->hctd_ctrl_phase) != OHCI_CTRL_DATA_PHASE) {
9534 break;
9535 }
9536 /* FALLTHRU */
9537 case USB_EP_ATTR_BULK:
9538 case USB_EP_ATTR_INTR:
9539 /*
9540 * If error is "data overrun", do not check for the
9541 * "CurrentBufferPointer" and return whatever data
9542 * received to the client driver.
9543 */
9544 if (error == USB_CR_DATA_OVERRUN) {
9545 break;
9546 }
9547
9548 /*
9549 * If "CurrentBufferPointer" of Transfer Descriptor
9550 * (TD) is not equal to zero, then we received less
9551 * data from the device than requested by us. In that
9552 * case, get the actual received data size.
9553 */
9554 if (Get_TD(td->hctd_cbp)) {
9555 residue = ohci_get_td_residue(ohcip, td);
9556 length = Get_TD(td->hctd_xfer_offs) +
9557 Get_TD(td->hctd_xfer_len) - residue - skip_len;
9558
9559 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9560 "ohci_sendup_qtd_message: requested data %lu "
9561 "received data %lu", tw->tw_length, length);
9562 }
9563
9564 break;
9565 case USB_EP_ATTR_ISOCH:
9566 default:
9567 break;
9568 }
9569
9570 /* Copy the data into the mblk_t */
9571 buf = (uchar_t *)tw->tw_buf + skip_len;
9572
9573 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9574 "ohci_sendup_qtd_message: length %lu error %d", length, error);
9575
9576 /* Get the message block */
9577 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
9578 case USB_EP_ATTR_CONTROL:
9579 mp = ((usb_ctrl_req_t *)curr_xfer_reqp)->ctrl_data;
9580 break;
9581 case USB_EP_ATTR_BULK:
9582 mp = ((usb_bulk_req_t *)curr_xfer_reqp)->bulk_data;
9583 break;
9584 case USB_EP_ATTR_INTR:
9585 mp = ((usb_intr_req_t *)curr_xfer_reqp)->intr_data;
9586 break;
9587 case USB_EP_ATTR_ISOCH:
9588 mp = ((usb_isoc_req_t *)curr_xfer_reqp)->isoc_data;
9589 break;
9590 }
9591
9592 ASSERT(mp != NULL);
9593
9594 if (length) {
9595 int i;
9596 uchar_t *p = mp->b_rptr;
9597
9598 /*
9599 * Update kstat byte counts
9600 * The control endpoints don't have direction bits so in
9601 * order for control stats to be counted correctly an in
9602 * bit must be faked on a control read.
9603 */
9604 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
9605 USB_EP_ATTR_CONTROL) {
9606 ohci_do_byte_stats(ohcip, length,
9607 eptd->bmAttributes, USB_EP_DIR_IN);
9608 } else {
9609 ohci_do_byte_stats(ohcip, length,
9610 eptd->bmAttributes, eptd->bEndpointAddress);
9611 }
9612
9613 if ((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
9614 USB_EP_ATTR_ISOCH) {
9615 for (i = 0; i < tw->tw_ncookies; i++) {
9616 Sync_IO_Buffer(
9617 tw->tw_isoc_bufs[i].dma_handle,
9618 tw->tw_isoc_bufs[i].length);
9619
9620 ddi_rep_get8(tw->tw_isoc_bufs[i].mem_handle,
9621 p, (uint8_t *)tw->tw_isoc_bufs[i].buf_addr,
9622 tw->tw_isoc_bufs[i].length,
9623 DDI_DEV_AUTOINCR);
9624 p += tw->tw_isoc_bufs[i].length;
9625 }
9626 tw->tw_pkt_idx = 0;
9627 } else {
9628 /* Sync IO buffer */
9629 Sync_IO_Buffer(tw->tw_dmahandle, (skip_len + length));
9630
9631 /* Copy the data into the message */
9632 ddi_rep_get8(tw->tw_accesshandle,
9633 mp->b_rptr, buf, length, DDI_DEV_AUTOINCR);
9634 }
9635
9636 /* Increment the write pointer */
9637 mp->b_wptr = mp->b_wptr + length;
9638 } else {
9639 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9640 "ohci_sendup_td_message: Zero length packet");
9641 }
9642
9643 ohci_hcdi_callback(ph, tw, error);
9644 }
9645
9646
9647 /*
9648 * ohci_get_td_residue:
9649 *
9650 * Calculate the bytes not transfered by the TD
9651 */
9652 size_t
ohci_get_td_residue(ohci_state_t * ohcip,ohci_td_t * td)9653 ohci_get_td_residue(
9654 ohci_state_t *ohcip,
9655 ohci_td_t *td)
9656 {
9657 uint32_t buf_addr, end_addr;
9658 size_t residue;
9659
9660 buf_addr = Get_TD(td->hctd_cbp);
9661 end_addr = Get_TD(td->hctd_buf_end);
9662
9663 if ((buf_addr & 0xfffff000) ==
9664 (end_addr & 0xfffff000)) {
9665 residue = end_addr - buf_addr + 1;
9666 } else {
9667 residue = OHCI_MAX_TD_BUF_SIZE -
9668 (buf_addr & 0x00000fff) +
9669 (end_addr & 0x00000fff) + 1;
9670 }
9671
9672 return (residue);
9673 }
9674
9675
9676 /*
9677 * Miscellaneous functions
9678 */
9679
9680 /*
9681 * ohci_obtain_state:
9682 * NOTE: This function is also called from POLLED MODE.
9683 */
9684 ohci_state_t *
ohci_obtain_state(dev_info_t * dip)9685 ohci_obtain_state(dev_info_t *dip)
9686 {
9687 int instance = ddi_get_instance(dip);
9688 ohci_state_t *state = ddi_get_soft_state(
9689 ohci_statep, instance);
9690
9691 ASSERT(state != NULL);
9692
9693 return (state);
9694 }
9695
9696
9697 /*
9698 * ohci_state_is_operational:
9699 *
9700 * Check the Host controller state and return proper values.
9701 */
9702 int
ohci_state_is_operational(ohci_state_t * ohcip)9703 ohci_state_is_operational(ohci_state_t *ohcip)
9704 {
9705 int val;
9706
9707 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9708
9709 switch (ohcip->ohci_hc_soft_state) {
9710 case OHCI_CTLR_INIT_STATE:
9711 case OHCI_CTLR_SUSPEND_STATE:
9712 val = USB_FAILURE;
9713 break;
9714 case OHCI_CTLR_OPERATIONAL_STATE:
9715 val = USB_SUCCESS;
9716 break;
9717 case OHCI_CTLR_ERROR_STATE:
9718 val = USB_HC_HARDWARE_ERROR;
9719 break;
9720 default:
9721 val = USB_FAILURE;
9722 break;
9723 }
9724
9725 return (val);
9726 }
9727
9728
9729 /*
9730 * ohci_do_soft_reset
9731 *
9732 * Do soft reset of ohci host controller.
9733 */
9734 int
ohci_do_soft_reset(ohci_state_t * ohcip)9735 ohci_do_soft_reset(ohci_state_t *ohcip)
9736 {
9737 usb_frame_number_t before_frame_number, after_frame_number;
9738 timeout_id_t xfer_timer_id, rh_timer_id;
9739 ohci_regs_t *ohci_save_regs;
9740 ohci_td_t *done_head;
9741
9742 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9743
9744 /* Increment host controller error count */
9745 ohcip->ohci_hc_error++;
9746
9747 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9748 "ohci_do_soft_reset:"
9749 "Reset ohci host controller 0x%x", ohcip->ohci_hc_error);
9750
9751 /*
9752 * Allocate space for saving current Host Controller
9753 * registers. Don't do any recovery if allocation
9754 * fails.
9755 */
9756 ohci_save_regs = (ohci_regs_t *)
9757 kmem_zalloc(sizeof (ohci_regs_t), KM_NOSLEEP);
9758
9759 if (ohci_save_regs == NULL) {
9760 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9761 "ohci_do_soft_reset: kmem_zalloc failed");
9762
9763 return (USB_FAILURE);
9764 }
9765
9766 /* Save current ohci registers */
9767 ohci_save_regs->hcr_control = Get_OpReg(hcr_control);
9768 ohci_save_regs->hcr_cmd_status = Get_OpReg(hcr_cmd_status);
9769 ohci_save_regs->hcr_intr_enable = Get_OpReg(hcr_intr_enable);
9770 ohci_save_regs->hcr_periodic_strt = Get_OpReg(hcr_periodic_strt);
9771 ohci_save_regs->hcr_frame_interval = Get_OpReg(hcr_frame_interval);
9772 ohci_save_regs->hcr_HCCA = Get_OpReg(hcr_HCCA);
9773 ohci_save_regs->hcr_bulk_head = Get_OpReg(hcr_bulk_head);
9774 ohci_save_regs->hcr_ctrl_head = Get_OpReg(hcr_ctrl_head);
9775
9776 USB_DPRINTF_L4(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9777 "ohci_do_soft_reset: Save reg = 0x%p", (void *)ohci_save_regs);
9778
9779 /* Disable all list processing and interrupts */
9780 Set_OpReg(hcr_control, (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
9781 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
9782
9783 Set_OpReg(hcr_intr_disable, HCR_INTR_SO |
9784 HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE |
9785 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE);
9786
9787 /* Wait for few milliseconds */
9788 drv_usecwait(OHCI_TIMEWAIT);
9789
9790 /* Root hub interrupt pipe timeout id */
9791 rh_timer_id = ohcip->ohci_root_hub.rh_intr_pipe_timer_id;
9792
9793 /* Stop the root hub interrupt timer */
9794 if (rh_timer_id) {
9795 ohcip->ohci_root_hub.rh_intr_pipe_timer_id = 0;
9796 ohcip->ohci_root_hub.rh_intr_pipe_state =
9797 OHCI_PIPE_STATE_IDLE;
9798
9799 mutex_exit(&ohcip->ohci_int_mutex);
9800 (void) untimeout(rh_timer_id);
9801 mutex_enter(&ohcip->ohci_int_mutex);
9802 }
9803
9804 /* Transfer timeout id */
9805 xfer_timer_id = ohcip->ohci_timer_id;
9806
9807 /* Stop the global transfer timer */
9808 if (xfer_timer_id) {
9809 ohcip->ohci_timer_id = 0;
9810 mutex_exit(&ohcip->ohci_int_mutex);
9811 (void) untimeout(xfer_timer_id);
9812 mutex_enter(&ohcip->ohci_int_mutex);
9813 }
9814
9815 /* Process any pending HCCA DoneHead */
9816 done_head = (ohci_td_t *)(uintptr_t)
9817 (Get_HCCA(ohcip->ohci_hccap->HccaDoneHead) & HCCA_DONE_HEAD_MASK);
9818
9819 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) {
9820 /* Reset the done head to NULL */
9821 Set_HCCA(ohcip->ohci_hccap->HccaDoneHead, NULL);
9822
9823 ohci_traverse_done_list(ohcip, done_head);
9824 }
9825
9826 /* Process any pending hcr_done_head value */
9827 done_head = (ohci_td_t *)(uintptr_t)
9828 (Get_OpReg(hcr_done_head) & HCCA_DONE_HEAD_MASK);
9829 if (ohci_check_done_head(ohcip, done_head) == USB_SUCCESS) {
9830
9831 ohci_traverse_done_list(ohcip, done_head);
9832 }
9833
9834 /* Do soft reset of ohci host controller */
9835 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
9836
9837 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9838 "ohci_do_soft_reset: Reset in progress");
9839
9840 /* Wait for reset to complete */
9841 drv_usecwait(OHCI_RESET_TIMEWAIT);
9842
9843 /* Reset HCCA HcFrameNumber */
9844 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000);
9845
9846 /*
9847 * Restore previous saved HC register value
9848 * into the current HC registers.
9849 */
9850 Set_OpReg(hcr_periodic_strt, (uint32_t)
9851 ohci_save_regs->hcr_periodic_strt);
9852
9853 Set_OpReg(hcr_frame_interval, (uint32_t)
9854 ohci_save_regs->hcr_frame_interval);
9855
9856 Set_OpReg(hcr_done_head, 0x0);
9857
9858 Set_OpReg(hcr_bulk_curr, 0x0);
9859
9860 Set_OpReg(hcr_bulk_head, (uint32_t)
9861 ohci_save_regs->hcr_bulk_head);
9862
9863 Set_OpReg(hcr_ctrl_curr, 0x0);
9864
9865 Set_OpReg(hcr_ctrl_head, (uint32_t)
9866 ohci_save_regs->hcr_ctrl_head);
9867
9868 Set_OpReg(hcr_periodic_curr, 0x0);
9869
9870 Set_OpReg(hcr_HCCA, (uint32_t)
9871 ohci_save_regs->hcr_HCCA);
9872
9873 Set_OpReg(hcr_intr_status, 0x0);
9874
9875 /*
9876 * Set HcInterruptEnable to enable all interrupts except
9877 * Root Hub Status change interrupt.
9878 */
9879 Set_OpReg(hcr_intr_enable,
9880 HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE |
9881 HCR_INTR_FNO | HCR_INTR_SOF | HCR_INTR_MIE);
9882
9883 /* Start Control and Bulk list processing */
9884 Set_OpReg(hcr_cmd_status, (HCR_STATUS_CLF | HCR_STATUS_BLF));
9885
9886 /*
9887 * Start up Control, Bulk, Periodic and Isochronous lists
9888 * processing.
9889 */
9890 Set_OpReg(hcr_control, (uint32_t)
9891 (ohci_save_regs->hcr_control & (~HCR_CONTROL_HCFS)));
9892
9893 /*
9894 * Deallocate the space that allocated for saving
9895 * HC registers.
9896 */
9897 kmem_free((void *) ohci_save_regs, sizeof (ohci_regs_t));
9898
9899 /* Resume the host controller */
9900 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
9901 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESUME));
9902
9903 /* Wait for resume to complete */
9904 drv_usecwait(OHCI_RESUME_TIMEWAIT);
9905
9906 /* Set the Host Controller Functional State to Operational */
9907 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
9908 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_OPERAT));
9909
9910 /* Wait 10ms for HC to start sending SOF */
9911 drv_usecwait(OHCI_TIMEWAIT);
9912
9913 /*
9914 * Get the current usb frame number before waiting for few
9915 * milliseconds.
9916 */
9917 before_frame_number = ohci_get_current_frame_number(ohcip);
9918
9919 /* Wait for few milliseconds */
9920 drv_usecwait(OHCI_TIMEWAIT);
9921
9922 /*
9923 * Get the current usb frame number after waiting for few
9924 * milliseconds.
9925 */
9926 after_frame_number = ohci_get_current_frame_number(ohcip);
9927
9928 USB_DPRINTF_L3(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9929 "ohci_do_soft_reset: Before Frm No 0x%llx After Frm No 0x%llx",
9930 (unsigned long long)before_frame_number,
9931 (unsigned long long)after_frame_number);
9932
9933 if (after_frame_number <= before_frame_number) {
9934
9935 USB_DPRINTF_L2(PRINT_MASK_INTR, ohcip->ohci_log_hdl,
9936 "ohci_do_soft_reset: Soft reset failed");
9937
9938 return (USB_FAILURE);
9939 }
9940
9941 /* Start the timer for the root hub interrupt pipe polling */
9942 if (rh_timer_id) {
9943 ohcip->ohci_root_hub.rh_intr_pipe_timer_id =
9944 timeout(ohci_handle_root_hub_status_change,
9945 (void *)ohcip, drv_usectohz(OHCI_RH_POLL_TIME));
9946
9947 ohcip->ohci_root_hub.
9948 rh_intr_pipe_state = OHCI_PIPE_STATE_ACTIVE;
9949 }
9950
9951 /* Start the global timer */
9952 if (xfer_timer_id) {
9953 ohcip->ohci_timer_id = timeout(ohci_xfer_timeout_handler,
9954 (void *)ohcip, drv_usectohz(1000000));
9955 }
9956
9957 return (USB_SUCCESS);
9958 }
9959
9960
9961 /*
9962 * ohci_get_current_frame_number:
9963 *
9964 * Get the current software based usb frame number.
9965 */
9966 usb_frame_number_t
ohci_get_current_frame_number(ohci_state_t * ohcip)9967 ohci_get_current_frame_number(ohci_state_t *ohcip)
9968 {
9969 usb_frame_number_t usb_frame_number;
9970 usb_frame_number_t ohci_fno, frame_number;
9971 ohci_save_intr_sts_t *ohci_intr_sts =
9972 &ohcip->ohci_save_intr_sts;
9973
9974 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
9975
9976 /*
9977 * Sync HCCA area only if this function
9978 * is invoked in non interrupt context.
9979 */
9980 if (!(ohci_intr_sts->ohci_intr_flag &
9981 OHCI_INTR_HANDLING)) {
9982
9983 /* Sync HCCA area */
9984 Sync_HCCA(ohcip);
9985 }
9986
9987 ohci_fno = ohcip->ohci_fno;
9988 frame_number = Get_HCCA(ohcip->ohci_hccap->HccaFrameNo);
9989
9990 /*
9991 * Calculate current software based usb frame number.
9992 *
9993 * This code accounts for the fact that frame number is
9994 * updated by the Host Controller before the ohci driver
9995 * gets an FrameNumberOverflow (FNO) interrupt that will
9996 * adjust Frame higher part.
9997 *
9998 * Refer ohci specification 1.0a, section 5.4, page 86.
9999 */
10000 usb_frame_number = ((frame_number & 0x7FFF) | ohci_fno) +
10001 (((frame_number & 0xFFFF) ^ ohci_fno) & 0x8000);
10002
10003 return (usb_frame_number);
10004 }
10005
10006
10007 /*
10008 * ohci_cpr_cleanup:
10009 *
10010 * Cleanup ohci state and other ohci specific informations across
10011 * Check Point Resume (CPR).
10012 */
10013 static void
ohci_cpr_cleanup(ohci_state_t * ohcip)10014 ohci_cpr_cleanup(ohci_state_t *ohcip)
10015 {
10016 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10017
10018 /* Reset software part of usb frame number */
10019 ohcip->ohci_fno = 0;
10020
10021 /* Reset Schedule Overrrun Error Counter */
10022 ohcip->ohci_so_error = 0;
10023
10024 /* Reset HCCA HcFrameNumber */
10025 Set_HCCA(ohcip->ohci_hccap->HccaFrameNo, 0x00000000);
10026 }
10027
10028
10029 /*
10030 * ohci_get_xfer_attrs:
10031 *
10032 * Get the attributes of a particular xfer.
10033 */
10034 static usb_req_attrs_t
ohci_get_xfer_attrs(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)10035 ohci_get_xfer_attrs(
10036 ohci_state_t *ohcip,
10037 ohci_pipe_private_t *pp,
10038 ohci_trans_wrapper_t *tw)
10039 {
10040 usb_ep_descr_t *eptd = &pp->pp_pipe_handle->p_ep;
10041 usb_req_attrs_t attrs = 0;
10042
10043 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10044 "ohci_get_xfer_attrs:");
10045
10046 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10047
10048 switch (eptd->bmAttributes & USB_EP_ATTR_MASK) {
10049 case USB_EP_ATTR_CONTROL:
10050 attrs = ((usb_ctrl_req_t *)
10051 tw->tw_curr_xfer_reqp)->ctrl_attributes;
10052 break;
10053 case USB_EP_ATTR_BULK:
10054 attrs = ((usb_bulk_req_t *)
10055 tw->tw_curr_xfer_reqp)->bulk_attributes;
10056 break;
10057 case USB_EP_ATTR_INTR:
10058 attrs = ((usb_intr_req_t *)
10059 tw->tw_curr_xfer_reqp)->intr_attributes;
10060 break;
10061 case USB_EP_ATTR_ISOCH:
10062 attrs = ((usb_isoc_req_t *)
10063 tw->tw_curr_xfer_reqp)->isoc_attributes;
10064 break;
10065 }
10066
10067 return (attrs);
10068 }
10069
10070
10071 /*
10072 * ohci_allocate_periodic_in_resource
10073 *
10074 * Allocate interrupt/isochronous request structure for the
10075 * interrupt/isochronous IN transfer.
10076 */
10077 static int
ohci_allocate_periodic_in_resource(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw,usb_flags_t flags)10078 ohci_allocate_periodic_in_resource(
10079 ohci_state_t *ohcip,
10080 ohci_pipe_private_t *pp,
10081 ohci_trans_wrapper_t *tw,
10082 usb_flags_t flags)
10083 {
10084 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10085 uchar_t ep_attr = ph->p_ep.bmAttributes;
10086 usb_intr_req_t *curr_intr_reqp;
10087 usb_isoc_req_t *curr_isoc_reqp;
10088 usb_opaque_t client_periodic_in_reqp;
10089 size_t length = 0;
10090
10091 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10092 "ohci_allocate_periodic_in_resource:"
10093 "pp = 0x%p tw = 0x%p flags = 0x%x", (void *)pp, (void *)tw, flags);
10094
10095 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10096 ASSERT(tw->tw_curr_xfer_reqp == NULL);
10097
10098 /* Get the client periodic in request pointer */
10099 client_periodic_in_reqp = pp->pp_client_periodic_in_reqp;
10100
10101 /*
10102 * If it a periodic IN request and periodic request is NULL,
10103 * allocate corresponding usb periodic IN request for the
10104 * current periodic polling request and copy the information
10105 * from the saved periodic request structure.
10106 */
10107 if ((ep_attr & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR) {
10108
10109 if (client_periodic_in_reqp) {
10110
10111 /* Get the interrupt transfer length */
10112 length = ((usb_intr_req_t *)
10113 client_periodic_in_reqp)->intr_len;
10114
10115 curr_intr_reqp = usba_hcdi_dup_intr_req(
10116 ph->p_dip, (usb_intr_req_t *)
10117 client_periodic_in_reqp, length, flags);
10118 } else {
10119 curr_intr_reqp = usb_alloc_intr_req(
10120 ph->p_dip, length, flags);
10121 }
10122
10123 if (curr_intr_reqp == NULL) {
10124
10125 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10126 "ohci_allocate_periodic_in_resource: Interrupt "
10127 "request structure allocation failed");
10128
10129 return (USB_NO_RESOURCES);
10130 }
10131
10132 if (client_periodic_in_reqp == NULL) {
10133 /* For polled mode */
10134 curr_intr_reqp->
10135 intr_attributes = USB_ATTRS_SHORT_XFER_OK;
10136 curr_intr_reqp->
10137 intr_len = ph->p_ep.wMaxPacketSize;
10138 } else {
10139 /* Check and save the timeout value */
10140 tw->tw_timeout = (curr_intr_reqp->intr_attributes &
10141 USB_ATTRS_ONE_XFER) ?
10142 curr_intr_reqp->intr_timeout: 0;
10143 }
10144
10145 tw->tw_curr_xfer_reqp = (usb_opaque_t)curr_intr_reqp;
10146 tw->tw_length = curr_intr_reqp->intr_len;
10147 } else {
10148 ASSERT(client_periodic_in_reqp != NULL);
10149
10150 curr_isoc_reqp = usba_hcdi_dup_isoc_req(ph->p_dip,
10151 (usb_isoc_req_t *)client_periodic_in_reqp, flags);
10152
10153 if (curr_isoc_reqp == NULL) {
10154
10155 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10156 "ohci_allocate_periodic_in_resource: Isochronous"
10157 "request structure allocation failed");
10158
10159 return (USB_NO_RESOURCES);
10160 }
10161
10162 /*
10163 * Save the client's isochronous request pointer and
10164 * length of isochronous transfer in transfer wrapper.
10165 * The dup'ed request is saved in pp_client_periodic_in_reqp
10166 */
10167 tw->tw_curr_xfer_reqp =
10168 (usb_opaque_t)pp->pp_client_periodic_in_reqp;
10169 pp->pp_client_periodic_in_reqp = (usb_opaque_t)curr_isoc_reqp;
10170 }
10171
10172 mutex_enter(&ph->p_mutex);
10173 ph->p_req_count++;
10174 mutex_exit(&ph->p_mutex);
10175
10176 pp->pp_state = OHCI_PIPE_STATE_ACTIVE;
10177
10178 return (USB_SUCCESS);
10179 }
10180
10181
10182 /*
10183 * ohci_wait_for_sof:
10184 *
10185 * Wait for couple of SOF interrupts
10186 */
10187 static int
ohci_wait_for_sof(ohci_state_t * ohcip)10188 ohci_wait_for_sof(ohci_state_t *ohcip)
10189 {
10190 usb_frame_number_t before_frame_number, after_frame_number;
10191 clock_t sof_time_wait;
10192 int rval, sof_wait_count;
10193
10194 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10195 "ohci_wait_for_sof");
10196
10197 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10198
10199 rval = ohci_state_is_operational(ohcip);
10200
10201 if (rval != USB_SUCCESS) {
10202
10203 return (rval);
10204 }
10205
10206 /* Get the number of clock ticks to wait */
10207 sof_time_wait = drv_usectohz(OHCI_MAX_SOF_TIMEWAIT * 1000000);
10208
10209 sof_wait_count = 0;
10210
10211 /*
10212 * Get the current usb frame number before waiting for the
10213 * SOF interrupt event.
10214 */
10215 before_frame_number = ohci_get_current_frame_number(ohcip);
10216
10217 while (sof_wait_count < MAX_SOF_WAIT_COUNT) {
10218 /* Enable the SOF interrupt */
10219 Set_OpReg(hcr_intr_enable, HCR_INTR_SOF);
10220
10221 ASSERT(Get_OpReg(hcr_intr_enable) & HCR_INTR_SOF);
10222
10223 /* Wait for the SOF or timeout event */
10224 rval = cv_reltimedwait(&ohcip->ohci_SOF_cv,
10225 &ohcip->ohci_int_mutex, sof_time_wait, TR_CLOCK_TICK);
10226
10227 /*
10228 * Get the current usb frame number after woken up either
10229 * from SOF interrupt or timer expired event.
10230 */
10231 after_frame_number = ohci_get_current_frame_number(ohcip);
10232
10233 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10234 "ohci_wait_for_sof: before 0x%llx, after 0x%llx",
10235 (unsigned long long)before_frame_number,
10236 (unsigned long long)after_frame_number);
10237
10238 /*
10239 * Return failure, if we are woken up becuase of timer expired
10240 * event and if usb frame number has not been changed.
10241 */
10242 if ((rval == -1) &&
10243 (after_frame_number <= before_frame_number)) {
10244
10245 if ((ohci_do_soft_reset(ohcip)) != USB_SUCCESS) {
10246
10247 USB_DPRINTF_L0(PRINT_MASK_LISTS,
10248 ohcip->ohci_log_hdl, "No SOF interrupts");
10249
10250 /* Set host controller soft state to error */
10251 ohcip->ohci_hc_soft_state =
10252 OHCI_CTLR_ERROR_STATE;
10253
10254 return (USB_FAILURE);
10255 }
10256
10257 /* Get new usb frame number */
10258 after_frame_number = before_frame_number =
10259 ohci_get_current_frame_number(ohcip);
10260 }
10261
10262 ASSERT(after_frame_number >= before_frame_number);
10263
10264 before_frame_number = after_frame_number;
10265 sof_wait_count++;
10266 }
10267
10268 return (USB_SUCCESS);
10269 }
10270
10271
10272 /*
10273 * ohci_pipe_cleanup
10274 *
10275 * Cleanup ohci pipe.
10276 */
10277 static void
ohci_pipe_cleanup(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)10278 ohci_pipe_cleanup(
10279 ohci_state_t *ohcip,
10280 usba_pipe_handle_data_t *ph)
10281 {
10282 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10283 usb_ep_descr_t *eptd = &ph->p_ep;
10284 usb_cr_t completion_reason;
10285 uint_t pipe_state = pp->pp_state;
10286 uint_t bit = 0;
10287
10288 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10289 "ohci_pipe_cleanup: ph = 0x%p", (void *)ph);
10290
10291 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10292
10293 switch (pipe_state) {
10294 case OHCI_PIPE_STATE_CLOSE:
10295 if (OHCI_NON_PERIODIC_ENDPOINT(eptd)) {
10296
10297 bit = ((eptd->bmAttributes &
10298 USB_EP_ATTR_MASK) == USB_EP_ATTR_CONTROL) ?
10299 HCR_CONTROL_CLE: HCR_CONTROL_BLE;
10300
10301 Set_OpReg(hcr_control,
10302 (Get_OpReg(hcr_control) & ~(bit)));
10303
10304 /* Wait for the next SOF */
10305 (void) ohci_wait_for_sof(ohcip);
10306
10307 break;
10308 }
10309 /* FALLTHROUGH */
10310 case OHCI_PIPE_STATE_RESET:
10311 case OHCI_PIPE_STATE_STOP_POLLING:
10312 /*
10313 * Set the sKip bit to stop all transactions on
10314 * this pipe
10315 */
10316 ohci_modify_sKip_bit(ohcip, pp, SET_sKip,
10317 OHCI_FLAGS_SLEEP | OHCI_FLAGS_DMA_SYNC);
10318
10319 break;
10320 default:
10321 return;
10322 }
10323
10324 /*
10325 * Wait for processing all completed transfers and
10326 * to send results to upstream.
10327 */
10328 ohci_wait_for_transfers_completion(ohcip, pp);
10329
10330 /* Save the data toggle information */
10331 ohci_save_data_toggle(ohcip, ph);
10332
10333 /*
10334 * Traverse the list of TD's on this endpoint and
10335 * these TD's have outstanding transfer requests.
10336 * Since the list processing is stopped, these tds
10337 * can be deallocated.
10338 */
10339 ohci_traverse_tds(ohcip, ph);
10340
10341 /*
10342 * If all of the endpoint's TD's have been deallocated,
10343 * then the DMA mappings can be torn down. If not there
10344 * are some TD's on the done list that have not been
10345 * processed. Tag these TD's so that they are thrown
10346 * away when the done list is processed.
10347 */
10348 ohci_done_list_tds(ohcip, ph);
10349
10350 /* Do callbacks for all unfinished requests */
10351 ohci_handle_outstanding_requests(ohcip, pp);
10352
10353 /* Free DMA resources */
10354 ohci_free_dma_resources(ohcip, ph);
10355
10356 switch (pipe_state) {
10357 case OHCI_PIPE_STATE_CLOSE:
10358 completion_reason = USB_CR_PIPE_CLOSING;
10359 break;
10360 case OHCI_PIPE_STATE_RESET:
10361 case OHCI_PIPE_STATE_STOP_POLLING:
10362 /* Set completion reason */
10363 completion_reason = (pipe_state ==
10364 OHCI_PIPE_STATE_RESET) ?
10365 USB_CR_PIPE_RESET: USB_CR_STOPPED_POLLING;
10366
10367 /* Restore the data toggle information */
10368 ohci_restore_data_toggle(ohcip, ph);
10369
10370 /*
10371 * Clear the sKip bit to restart all the
10372 * transactions on this pipe.
10373 */
10374 ohci_modify_sKip_bit(ohcip, pp,
10375 CLEAR_sKip, OHCI_FLAGS_NOSLEEP);
10376
10377 /* Set pipe state to idle */
10378 pp->pp_state = OHCI_PIPE_STATE_IDLE;
10379
10380 break;
10381 }
10382
10383 ASSERT((Get_ED(pp->pp_ept->hced_tailp) & HC_EPT_TD_TAIL) ==
10384 (Get_ED(pp->pp_ept->hced_headp) & HC_EPT_TD_HEAD));
10385
10386 ASSERT((pp->pp_tw_head == NULL) && (pp->pp_tw_tail == NULL));
10387
10388 /*
10389 * Do the callback for the original client
10390 * periodic IN request.
10391 */
10392 if ((OHCI_PERIODIC_ENDPOINT(eptd)) &&
10393 ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) ==
10394 USB_EP_DIR_IN)) {
10395
10396 ohci_do_client_periodic_in_req_callback(
10397 ohcip, pp, completion_reason);
10398 }
10399 }
10400
10401
10402 /*
10403 * ohci_wait_for_transfers_completion:
10404 *
10405 * Wait for processing all completed transfers and to send results
10406 * to upstream.
10407 */
10408 static void
ohci_wait_for_transfers_completion(ohci_state_t * ohcip,ohci_pipe_private_t * pp)10409 ohci_wait_for_transfers_completion(
10410 ohci_state_t *ohcip,
10411 ohci_pipe_private_t *pp)
10412 {
10413 ohci_trans_wrapper_t *head_tw = pp->pp_tw_head;
10414 ohci_trans_wrapper_t *next_tw;
10415 ohci_td_t *tailp, *headp, *nextp;
10416 ohci_td_t *head_td, *next_td;
10417 ohci_ed_t *ept = pp->pp_ept;
10418 int rval;
10419
10420 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10421 "ohci_wait_for_transfers_completion: pp = 0x%p", (void *)pp);
10422
10423 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10424
10425 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10426 Get_ED(ept->hced_headp) & (uint32_t)HC_EPT_TD_HEAD));
10427
10428 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10429 Get_ED(ept->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL));
10430
10431 rval = ohci_state_is_operational(ohcip);
10432
10433 if (rval != USB_SUCCESS) {
10434
10435 return;
10436 }
10437
10438 pp->pp_count_done_tds = 0;
10439
10440 /* Process the transfer wrappers for this pipe */
10441 next_tw = head_tw;
10442 while (next_tw) {
10443 head_td = (ohci_td_t *)next_tw->tw_hctd_head;
10444 next_td = head_td;
10445
10446 if (head_td) {
10447 /*
10448 * Walk through each TD for this transfer
10449 * wrapper. If a TD still exists, then it
10450 * is currently on the done list.
10451 */
10452 while (next_td) {
10453
10454 nextp = headp;
10455
10456 while (nextp != tailp) {
10457
10458 /* TD is on the ED */
10459 if (nextp == next_td) {
10460 break;
10461 }
10462
10463 nextp = (ohci_td_t *)
10464 (ohci_td_iommu_to_cpu(ohcip,
10465 (Get_TD(nextp->hctd_next_td) &
10466 HC_EPT_TD_TAIL)));
10467 }
10468
10469 if (nextp == tailp) {
10470 pp->pp_count_done_tds++;
10471 }
10472
10473 next_td = ohci_td_iommu_to_cpu(ohcip,
10474 Get_TD(next_td->hctd_tw_next_td));
10475 }
10476 }
10477
10478 next_tw = next_tw->tw_next;
10479 }
10480
10481 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10482 "ohci_wait_for_transfers_completion: count_done_tds = 0x%x",
10483 pp->pp_count_done_tds);
10484
10485 if (!pp->pp_count_done_tds) {
10486
10487 return;
10488 }
10489
10490 (void) cv_reltimedwait(&pp->pp_xfer_cmpl_cv, &ohcip->ohci_int_mutex,
10491 drv_usectohz(OHCI_XFER_CMPL_TIMEWAIT * 1000000), TR_CLOCK_TICK);
10492
10493 if (pp->pp_count_done_tds) {
10494
10495 USB_DPRINTF_L2(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10496 "ohci_wait_for_transfers_completion: No transfers "
10497 "completion confirmation received for 0x%x requests",
10498 pp->pp_count_done_tds);
10499 }
10500 }
10501
10502
10503 /*
10504 * ohci_check_for_transfers_completion:
10505 *
10506 * Check whether anybody is waiting for transfers completion event. If so, send
10507 * this event and also stop initiating any new transfers on this pipe.
10508 */
10509 static void
ohci_check_for_transfers_completion(ohci_state_t * ohcip,ohci_pipe_private_t * pp)10510 ohci_check_for_transfers_completion(
10511 ohci_state_t *ohcip,
10512 ohci_pipe_private_t *pp)
10513 {
10514 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10515 "ohci_check_for_transfers_completion: pp = 0x%p", (void *)pp);
10516
10517 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10518
10519 if ((pp->pp_state == OHCI_PIPE_STATE_STOP_POLLING) &&
10520 (pp->pp_error == USB_CR_NO_RESOURCES) &&
10521 (pp->pp_cur_periodic_req_cnt == 0)) {
10522
10523 /* Reset pipe error to zero */
10524 pp->pp_error = 0;
10525
10526 /* Do callback for original request */
10527 ohci_do_client_periodic_in_req_callback(
10528 ohcip, pp, USB_CR_NO_RESOURCES);
10529 }
10530
10531 if (pp->pp_count_done_tds) {
10532
10533 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10534 "ohci_check_for_transfers_completion:"
10535 "count_done_tds = 0x%x", pp->pp_count_done_tds);
10536
10537 /* Decrement the done td count */
10538 pp->pp_count_done_tds--;
10539
10540 if (!pp->pp_count_done_tds) {
10541 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10542 "ohci_check_for_transfers_completion:"
10543 "Sent transfers completion event pp = 0x%p",
10544 (void *)pp);
10545
10546 /* Send the transfer completion signal */
10547 cv_signal(&pp->pp_xfer_cmpl_cv);
10548 }
10549 }
10550 }
10551
10552
10553 /*
10554 * ohci_save_data_toggle:
10555 *
10556 * Save the data toggle information.
10557 */
10558 static void
ohci_save_data_toggle(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)10559 ohci_save_data_toggle(
10560 ohci_state_t *ohcip,
10561 usba_pipe_handle_data_t *ph)
10562 {
10563 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10564 usb_ep_descr_t *eptd = &ph->p_ep;
10565 uint_t data_toggle;
10566 usb_cr_t error = pp->pp_error;
10567 ohci_ed_t *ed = pp->pp_ept;
10568 ohci_td_t *headp, *tailp;
10569
10570 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10571 "ohci_save_data_toggle: ph = 0x%p", (void *)ph);
10572
10573 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10574
10575 /* Reset the pipe error value */
10576 pp->pp_error = USB_CR_OK;
10577
10578 /* Return immediately if it is a control or isoc pipe */
10579 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
10580 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes &
10581 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) {
10582
10583 return;
10584 }
10585
10586 headp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10587 Get_ED(ed->hced_headp) & (uint32_t)HC_EPT_TD_HEAD));
10588
10589 tailp = (ohci_td_t *)(ohci_td_iommu_to_cpu(ohcip,
10590 Get_ED(ed->hced_tailp) & (uint32_t)HC_EPT_TD_TAIL));
10591
10592 /*
10593 * Retrieve the data toggle information either from the endpoint
10594 * (ED) or from the transfer descriptor (TD) depending on the
10595 * situation.
10596 */
10597 if ((Get_ED(ed->hced_headp) & HC_EPT_Halt) || (headp == tailp)) {
10598
10599 /* Get the data toggle information from the endpoint */
10600 data_toggle = (Get_ED(ed->hced_headp) &
10601 HC_EPT_Carry)? DATA1:DATA0;
10602 } else {
10603 /*
10604 * Retrieve the data toggle information depending on the
10605 * master data toggle information saved in the transfer
10606 * descriptor (TD) at the head of the endpoint (ED).
10607 *
10608 * Check for master data toggle information .
10609 */
10610 if (Get_TD(headp->hctd_ctrl) & HC_TD_MS_DT) {
10611 /* Get the data toggle information from td */
10612 data_toggle = (Get_TD(headp->hctd_ctrl) &
10613 HC_TD_DT_1) ? DATA1:DATA0;
10614 } else {
10615 /* Get the data toggle information from the endpoint */
10616 data_toggle = (Get_ED(ed->hced_headp) &
10617 HC_EPT_Carry)? DATA1:DATA0;
10618 }
10619 }
10620
10621 /*
10622 * If error is STALL, then, set
10623 * data toggle to zero.
10624 */
10625 if (error == USB_CR_STALL) {
10626 data_toggle = DATA0;
10627 }
10628
10629 /*
10630 * Save the data toggle information
10631 * in the usb device structure.
10632 */
10633 mutex_enter(&ph->p_mutex);
10634 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress,
10635 data_toggle);
10636 mutex_exit(&ph->p_mutex);
10637 }
10638
10639
10640 /*
10641 * ohci_restore_data_toggle:
10642 *
10643 * Restore the data toggle information.
10644 */
10645 static void
ohci_restore_data_toggle(ohci_state_t * ohcip,usba_pipe_handle_data_t * ph)10646 ohci_restore_data_toggle(
10647 ohci_state_t *ohcip,
10648 usba_pipe_handle_data_t *ph)
10649 {
10650 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10651 usb_ep_descr_t *eptd = &ph->p_ep;
10652 uint_t data_toggle = 0;
10653
10654 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10655 "ohci_restore_data_toggle: ph = 0x%p", (void *)ph);
10656
10657 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10658
10659 /*
10660 * Return immediately if it is a control or isoc pipe.
10661 */
10662 if (((eptd->bmAttributes & USB_EP_ATTR_MASK) ==
10663 USB_EP_ATTR_CONTROL) || ((eptd->bmAttributes &
10664 USB_EP_ATTR_MASK) == USB_EP_ATTR_ISOCH)) {
10665
10666 return;
10667 }
10668
10669 mutex_enter(&ph->p_mutex);
10670
10671 data_toggle = usba_hcdi_get_data_toggle(ph->p_usba_device,
10672 ph->p_ep.bEndpointAddress);
10673 usba_hcdi_set_data_toggle(ph->p_usba_device, ph->p_ep.bEndpointAddress,
10674 0);
10675
10676 mutex_exit(&ph->p_mutex);
10677
10678 /*
10679 * Restore the data toggle bit depending on the
10680 * previous data toggle information.
10681 */
10682 if (data_toggle) {
10683 Set_ED(pp->pp_ept->hced_headp,
10684 Get_ED(pp->pp_ept->hced_headp) | HC_EPT_Carry);
10685 } else {
10686 Set_ED(pp->pp_ept->hced_headp,
10687 Get_ED(pp->pp_ept->hced_headp) & (~HC_EPT_Carry));
10688 }
10689 }
10690
10691
10692 /*
10693 * ohci_handle_outstanding_requests
10694 * NOTE: This function is also called from POLLED MODE.
10695 *
10696 * Deallocate interrupt/isochronous request structure for the
10697 * interrupt/isochronous IN transfer. Do the callbacks for all
10698 * unfinished requests.
10699 */
10700 void
ohci_handle_outstanding_requests(ohci_state_t * ohcip,ohci_pipe_private_t * pp)10701 ohci_handle_outstanding_requests(
10702 ohci_state_t *ohcip,
10703 ohci_pipe_private_t *pp)
10704 {
10705 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10706 usb_ep_descr_t *eptd = &ph->p_ep;
10707 ohci_trans_wrapper_t *curr_tw;
10708 ohci_trans_wrapper_t *next_tw;
10709 usb_opaque_t curr_xfer_reqp;
10710
10711 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10712 "ohci_handle_outstanding_requests: pp = 0x%p", (void *)pp);
10713
10714 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10715
10716 /*
10717 * Deallocate all the pre-allocated interrupt requests
10718 */
10719 next_tw = pp->pp_tw_head;
10720
10721 while (next_tw) {
10722 curr_tw = next_tw;
10723 next_tw = curr_tw->tw_next;
10724
10725 curr_xfer_reqp = curr_tw->tw_curr_xfer_reqp;
10726
10727 /* Deallocate current interrupt request */
10728 if (curr_xfer_reqp) {
10729
10730 if ((OHCI_PERIODIC_ENDPOINT(eptd)) &&
10731 (curr_tw->tw_direction == HC_TD_IN)) {
10732
10733 /* Decrement periodic in request count */
10734 pp->pp_cur_periodic_req_cnt--;
10735
10736 ohci_deallocate_periodic_in_resource(
10737 ohcip, pp, curr_tw);
10738 } else {
10739 ohci_hcdi_callback(ph,
10740 curr_tw, USB_CR_FLUSHED);
10741 }
10742 }
10743 }
10744 }
10745
10746
10747 /*
10748 * ohci_deallocate_periodic_in_resource
10749 *
10750 * Deallocate interrupt/isochronous request structure for the
10751 * interrupt/isochronous IN transfer.
10752 */
10753 static void
ohci_deallocate_periodic_in_resource(ohci_state_t * ohcip,ohci_pipe_private_t * pp,ohci_trans_wrapper_t * tw)10754 ohci_deallocate_periodic_in_resource(
10755 ohci_state_t *ohcip,
10756 ohci_pipe_private_t *pp,
10757 ohci_trans_wrapper_t *tw)
10758 {
10759 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10760 uchar_t ep_attr = ph->p_ep.bmAttributes;
10761 usb_opaque_t curr_xfer_reqp;
10762
10763 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10764 "ohci_deallocate_periodic_in_resource: "
10765 "pp = 0x%p tw = 0x%p", (void *)pp, (void *)tw);
10766
10767 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10768
10769 curr_xfer_reqp = tw->tw_curr_xfer_reqp;
10770
10771 /* Check the current periodic in request pointer */
10772 if (curr_xfer_reqp) {
10773 /*
10774 * Reset periodic in request usb isoch
10775 * packet request pointers to null.
10776 */
10777 tw->tw_curr_xfer_reqp = NULL;
10778 tw->tw_curr_isoc_pktp = NULL;
10779
10780 mutex_enter(&ph->p_mutex);
10781 ph->p_req_count--;
10782 mutex_exit(&ph->p_mutex);
10783
10784 /*
10785 * Free pre-allocated interrupt
10786 * or isochronous requests.
10787 */
10788 switch (ep_attr & USB_EP_ATTR_MASK) {
10789 case USB_EP_ATTR_INTR:
10790 usb_free_intr_req(
10791 (usb_intr_req_t *)curr_xfer_reqp);
10792 break;
10793 case USB_EP_ATTR_ISOCH:
10794 usb_free_isoc_req(
10795 (usb_isoc_req_t *)curr_xfer_reqp);
10796 break;
10797 }
10798 }
10799 }
10800
10801
10802 /*
10803 * ohci_do_client_periodic_in_req_callback
10804 *
10805 * Do callback for the original client periodic IN request.
10806 */
10807 static void
ohci_do_client_periodic_in_req_callback(ohci_state_t * ohcip,ohci_pipe_private_t * pp,usb_cr_t completion_reason)10808 ohci_do_client_periodic_in_req_callback(
10809 ohci_state_t *ohcip,
10810 ohci_pipe_private_t *pp,
10811 usb_cr_t completion_reason)
10812 {
10813 usba_pipe_handle_data_t *ph = pp->pp_pipe_handle;
10814
10815 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10816 "ohci_do_client_periodic_in_req_callback: "
10817 "pp = 0x%p cc = 0x%x", (void *)pp, completion_reason);
10818
10819 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10820
10821 /*
10822 * Check for Interrupt/Isochronous IN, whether we need to do
10823 * callback for the original client's periodic IN request.
10824 */
10825 if (pp->pp_client_periodic_in_reqp) {
10826 ASSERT(pp->pp_cur_periodic_req_cnt == 0);
10827 ohci_hcdi_callback(ph, NULL, completion_reason);
10828 }
10829 }
10830
10831
10832 /*
10833 * ohci_hcdi_callback()
10834 *
10835 * Convenience wrapper around usba_hcdi_cb() other than root hub.
10836 */
10837 static void
ohci_hcdi_callback(usba_pipe_handle_data_t * ph,ohci_trans_wrapper_t * tw,usb_cr_t completion_reason)10838 ohci_hcdi_callback(
10839 usba_pipe_handle_data_t *ph,
10840 ohci_trans_wrapper_t *tw,
10841 usb_cr_t completion_reason)
10842 {
10843 ohci_state_t *ohcip = ohci_obtain_state(
10844 ph->p_usba_device->usb_root_hub_dip);
10845 uchar_t attributes = ph->p_ep.bmAttributes &
10846 USB_EP_ATTR_MASK;
10847 ohci_pipe_private_t *pp = (ohci_pipe_private_t *)ph->p_hcd_private;
10848 usb_opaque_t curr_xfer_reqp;
10849 uint_t pipe_state = 0;
10850
10851 USB_DPRINTF_L4(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
10852 "ohci_hcdi_callback: ph = 0x%p, tw = 0x%p, cr = 0x%x",
10853 (void *)ph, (void *)tw, completion_reason);
10854
10855 ASSERT(mutex_owned(&ohcip->ohci_int_mutex));
10856
10857 /* Set the pipe state as per completion reason */
10858 switch (completion_reason) {
10859 case USB_CR_OK:
10860 pipe_state = pp->pp_state;
10861 break;
10862 case USB_CR_NO_RESOURCES:
10863 case USB_CR_NOT_SUPPORTED:
10864 case USB_CR_STOPPED_POLLING:
10865 case USB_CR_PIPE_RESET:
10866 pipe_state = OHCI_PIPE_STATE_IDLE;
10867 break;
10868 case USB_CR_PIPE_CLOSING:
10869 break;
10870 default:
10871 /*
10872 * Set the pipe state to error
10873 * except for the isoc pipe.
10874 */
10875 if (attributes != USB_EP_ATTR_ISOCH) {
10876 pipe_state = OHCI_PIPE_STATE_ERROR;
10877 pp->pp_error = completion_reason;
10878 }
10879 break;
10880
10881 }
10882
10883 pp->pp_state = pipe_state;
10884
10885 if (tw && tw->tw_curr_xfer_reqp) {
10886 curr_xfer_reqp = tw->tw_curr_xfer_reqp;
10887 tw->tw_curr_xfer_reqp = NULL;
10888 tw->tw_curr_isoc_pktp = NULL;
10889 } else {
10890 ASSERT(pp->pp_client_periodic_in_reqp != NULL);
10891
10892 curr_xfer_reqp = pp->pp_client_periodic_in_reqp;
10893 pp->pp_client_periodic_in_reqp = NULL;
10894 }
10895
10896 ASSERT(curr_xfer_reqp != NULL);
10897
10898 mutex_exit(&ohcip->ohci_int_mutex);
10899
10900 usba_hcdi_cb(ph, curr_xfer_reqp, completion_reason);
10901
10902 mutex_enter(&ohcip->ohci_int_mutex);
10903 }
10904
10905
10906 /*
10907 * ohci kstat functions
10908 */
10909
10910 /*
10911 * ohci_create_stats:
10912 *
10913 * Allocate and initialize the ohci kstat structures
10914 */
10915 static void
ohci_create_stats(ohci_state_t * ohcip)10916 ohci_create_stats(ohci_state_t *ohcip)
10917 {
10918 char kstatname[KSTAT_STRLEN];
10919 const char *dname = ddi_driver_name(ohcip->ohci_dip);
10920 char *usbtypes[USB_N_COUNT_KSTATS] =
10921 {"ctrl", "isoch", "bulk", "intr"};
10922 uint_t instance = ohcip->ohci_instance;
10923 ohci_intrs_stats_t *isp;
10924 int i;
10925
10926 if (OHCI_INTRS_STATS(ohcip) == NULL) {
10927 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,intrs",
10928 dname, instance);
10929 OHCI_INTRS_STATS(ohcip) = kstat_create("usba", instance,
10930 kstatname, "usb_interrupts", KSTAT_TYPE_NAMED,
10931 sizeof (ohci_intrs_stats_t) / sizeof (kstat_named_t),
10932 KSTAT_FLAG_PERSISTENT);
10933
10934 if (OHCI_INTRS_STATS(ohcip)) {
10935 isp = OHCI_INTRS_STATS_DATA(ohcip);
10936 kstat_named_init(&isp->ohci_hcr_intr_total,
10937 "Interrupts Total", KSTAT_DATA_UINT64);
10938 kstat_named_init(&isp->ohci_hcr_intr_not_claimed,
10939 "Not Claimed", KSTAT_DATA_UINT64);
10940 kstat_named_init(&isp->ohci_hcr_intr_so,
10941 "Schedule Overruns", KSTAT_DATA_UINT64);
10942 kstat_named_init(&isp->ohci_hcr_intr_wdh,
10943 "Writeback Done Head", KSTAT_DATA_UINT64);
10944 kstat_named_init(&isp->ohci_hcr_intr_sof,
10945 "Start Of Frame", KSTAT_DATA_UINT64);
10946 kstat_named_init(&isp->ohci_hcr_intr_rd,
10947 "Resume Detected", KSTAT_DATA_UINT64);
10948 kstat_named_init(&isp->ohci_hcr_intr_ue,
10949 "Unrecoverable Error", KSTAT_DATA_UINT64);
10950 kstat_named_init(&isp->ohci_hcr_intr_fno,
10951 "Frame No. Overflow", KSTAT_DATA_UINT64);
10952 kstat_named_init(&isp->ohci_hcr_intr_rhsc,
10953 "Root Hub Status Change", KSTAT_DATA_UINT64);
10954 kstat_named_init(&isp->ohci_hcr_intr_oc,
10955 "Change In Ownership", KSTAT_DATA_UINT64);
10956
10957 OHCI_INTRS_STATS(ohcip)->ks_private = ohcip;
10958 OHCI_INTRS_STATS(ohcip)->ks_update = nulldev;
10959 kstat_install(OHCI_INTRS_STATS(ohcip));
10960 }
10961 }
10962
10963 if (OHCI_TOTAL_STATS(ohcip) == NULL) {
10964 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,total",
10965 dname, instance);
10966 OHCI_TOTAL_STATS(ohcip) = kstat_create("usba", instance,
10967 kstatname, "usb_byte_count", KSTAT_TYPE_IO, 1,
10968 KSTAT_FLAG_PERSISTENT);
10969
10970 if (OHCI_TOTAL_STATS(ohcip)) {
10971 kstat_install(OHCI_TOTAL_STATS(ohcip));
10972 }
10973 }
10974
10975 for (i = 0; i < USB_N_COUNT_KSTATS; i++) {
10976 if (ohcip->ohci_count_stats[i] == NULL) {
10977 (void) snprintf(kstatname, KSTAT_STRLEN, "%s%d,%s",
10978 dname, instance, usbtypes[i]);
10979 ohcip->ohci_count_stats[i] = kstat_create("usba",
10980 instance, kstatname, "usb_byte_count",
10981 KSTAT_TYPE_IO, 1, KSTAT_FLAG_PERSISTENT);
10982
10983 if (ohcip->ohci_count_stats[i]) {
10984 kstat_install(ohcip->ohci_count_stats[i]);
10985 }
10986 }
10987 }
10988 }
10989
10990
10991 /*
10992 * ohci_destroy_stats:
10993 *
10994 * Clean up ohci kstat structures
10995 */
10996 static void
ohci_destroy_stats(ohci_state_t * ohcip)10997 ohci_destroy_stats(ohci_state_t *ohcip)
10998 {
10999 int i;
11000
11001 if (OHCI_INTRS_STATS(ohcip)) {
11002 kstat_delete(OHCI_INTRS_STATS(ohcip));
11003 OHCI_INTRS_STATS(ohcip) = NULL;
11004 }
11005
11006 if (OHCI_TOTAL_STATS(ohcip)) {
11007 kstat_delete(OHCI_TOTAL_STATS(ohcip));
11008 OHCI_TOTAL_STATS(ohcip) = NULL;
11009 }
11010
11011 for (i = 0; i < USB_N_COUNT_KSTATS; i++) {
11012 if (ohcip->ohci_count_stats[i]) {
11013 kstat_delete(ohcip->ohci_count_stats[i]);
11014 ohcip->ohci_count_stats[i] = NULL;
11015 }
11016 }
11017 }
11018
11019
11020 /*
11021 * ohci_do_intrs_stats:
11022 *
11023 * ohci status information
11024 */
11025 static void
ohci_do_intrs_stats(ohci_state_t * ohcip,int val)11026 ohci_do_intrs_stats(
11027 ohci_state_t *ohcip,
11028 int val)
11029 {
11030 if (OHCI_INTRS_STATS(ohcip)) {
11031 OHCI_INTRS_STATS_DATA(ohcip)->ohci_hcr_intr_total.value.ui64++;
11032 switch (val) {
11033 case HCR_INTR_SO:
11034 OHCI_INTRS_STATS_DATA(ohcip)->
11035 ohci_hcr_intr_so.value.ui64++;
11036 break;
11037 case HCR_INTR_WDH:
11038 OHCI_INTRS_STATS_DATA(ohcip)->
11039 ohci_hcr_intr_wdh.value.ui64++;
11040 break;
11041 case HCR_INTR_SOF:
11042 OHCI_INTRS_STATS_DATA(ohcip)->
11043 ohci_hcr_intr_sof.value.ui64++;
11044 break;
11045 case HCR_INTR_RD:
11046 OHCI_INTRS_STATS_DATA(ohcip)->
11047 ohci_hcr_intr_rd.value.ui64++;
11048 break;
11049 case HCR_INTR_UE:
11050 OHCI_INTRS_STATS_DATA(ohcip)->
11051 ohci_hcr_intr_ue.value.ui64++;
11052 break;
11053 case HCR_INTR_FNO:
11054 OHCI_INTRS_STATS_DATA(ohcip)->
11055 ohci_hcr_intr_fno.value.ui64++;
11056 break;
11057 case HCR_INTR_RHSC:
11058 OHCI_INTRS_STATS_DATA(ohcip)->
11059 ohci_hcr_intr_rhsc.value.ui64++;
11060 break;
11061 case HCR_INTR_OC:
11062 OHCI_INTRS_STATS_DATA(ohcip)->
11063 ohci_hcr_intr_oc.value.ui64++;
11064 break;
11065 default:
11066 OHCI_INTRS_STATS_DATA(ohcip)->
11067 ohci_hcr_intr_not_claimed.value.ui64++;
11068 break;
11069 }
11070 }
11071 }
11072
11073
11074 /*
11075 * ohci_do_byte_stats:
11076 *
11077 * ohci data xfer information
11078 */
11079 static void
ohci_do_byte_stats(ohci_state_t * ohcip,size_t len,uint8_t attr,uint8_t addr)11080 ohci_do_byte_stats(
11081 ohci_state_t *ohcip,
11082 size_t len,
11083 uint8_t attr,
11084 uint8_t addr)
11085 {
11086 uint8_t type = attr & USB_EP_ATTR_MASK;
11087 uint8_t dir = addr & USB_EP_DIR_MASK;
11088
11089 if (dir == USB_EP_DIR_IN) {
11090 OHCI_TOTAL_STATS_DATA(ohcip)->reads++;
11091 OHCI_TOTAL_STATS_DATA(ohcip)->nread += len;
11092 switch (type) {
11093 case USB_EP_ATTR_CONTROL:
11094 OHCI_CTRL_STATS(ohcip)->reads++;
11095 OHCI_CTRL_STATS(ohcip)->nread += len;
11096 break;
11097 case USB_EP_ATTR_BULK:
11098 OHCI_BULK_STATS(ohcip)->reads++;
11099 OHCI_BULK_STATS(ohcip)->nread += len;
11100 break;
11101 case USB_EP_ATTR_INTR:
11102 OHCI_INTR_STATS(ohcip)->reads++;
11103 OHCI_INTR_STATS(ohcip)->nread += len;
11104 break;
11105 case USB_EP_ATTR_ISOCH:
11106 OHCI_ISOC_STATS(ohcip)->reads++;
11107 OHCI_ISOC_STATS(ohcip)->nread += len;
11108 break;
11109 }
11110 } else if (dir == USB_EP_DIR_OUT) {
11111 OHCI_TOTAL_STATS_DATA(ohcip)->writes++;
11112 OHCI_TOTAL_STATS_DATA(ohcip)->nwritten += len;
11113 switch (type) {
11114 case USB_EP_ATTR_CONTROL:
11115 OHCI_CTRL_STATS(ohcip)->writes++;
11116 OHCI_CTRL_STATS(ohcip)->nwritten += len;
11117 break;
11118 case USB_EP_ATTR_BULK:
11119 OHCI_BULK_STATS(ohcip)->writes++;
11120 OHCI_BULK_STATS(ohcip)->nwritten += len;
11121 break;
11122 case USB_EP_ATTR_INTR:
11123 OHCI_INTR_STATS(ohcip)->writes++;
11124 OHCI_INTR_STATS(ohcip)->nwritten += len;
11125 break;
11126 case USB_EP_ATTR_ISOCH:
11127 OHCI_ISOC_STATS(ohcip)->writes++;
11128 OHCI_ISOC_STATS(ohcip)->nwritten += len;
11129 break;
11130 }
11131 }
11132 }
11133
11134
11135 /*
11136 * ohci_print_op_regs:
11137 *
11138 * Print Host Controller's (HC) Operational registers.
11139 */
11140 static void
ohci_print_op_regs(ohci_state_t * ohcip)11141 ohci_print_op_regs(ohci_state_t *ohcip)
11142 {
11143 uint_t i;
11144
11145 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11146 "\n\tOHCI%d Operational Registers\n",
11147 ddi_get_instance(ohcip->ohci_dip));
11148
11149 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11150 "\thcr_revision: 0x%x \t\thcr_control: 0x%x",
11151 Get_OpReg(hcr_revision), Get_OpReg(hcr_control));
11152 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11153 "\thcr_cmd_status: 0x%x \t\thcr_intr_enable: 0x%x",
11154 Get_OpReg(hcr_cmd_status), Get_OpReg(hcr_intr_enable));
11155 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11156 "\thcr_intr_disable: 0x%x \thcr_HCCA: 0x%x",
11157 Get_OpReg(hcr_intr_disable), Get_OpReg(hcr_HCCA));
11158 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11159 "\thcr_periodic_curr: 0x%x \t\thcr_ctrl_head: 0x%x",
11160 Get_OpReg(hcr_periodic_curr), Get_OpReg(hcr_ctrl_head));
11161 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11162 "\thcr_ctrl_curr: 0x%x \t\thcr_bulk_head: 0x%x",
11163 Get_OpReg(hcr_ctrl_curr), Get_OpReg(hcr_bulk_head));
11164 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11165 "\thcr_bulk_curr: 0x%x \t\thcr_done_head: 0x%x",
11166 Get_OpReg(hcr_bulk_curr), Get_OpReg(hcr_done_head));
11167 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11168 "\thcr_frame_interval: 0x%x "
11169 "\thcr_frame_remaining: 0x%x", Get_OpReg(hcr_frame_interval),
11170 Get_OpReg(hcr_frame_remaining));
11171 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11172 "\thcr_frame_number: 0x%x \thcr_periodic_strt: 0x%x",
11173 Get_OpReg(hcr_frame_number), Get_OpReg(hcr_periodic_strt));
11174 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11175 "\thcr_transfer_ls: 0x%x \t\thcr_rh_descriptorA: 0x%x",
11176 Get_OpReg(hcr_transfer_ls), Get_OpReg(hcr_rh_descriptorA));
11177 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11178 "\thcr_rh_descriptorB: 0x%x \thcr_rh_status: 0x%x",
11179 Get_OpReg(hcr_rh_descriptorB), Get_OpReg(hcr_rh_status));
11180
11181 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11182 "\tRoot hub port status");
11183
11184 for (i = 0; i < (Get_OpReg(hcr_rh_descriptorA) & HCR_RHA_NDP); i++) {
11185 USB_DPRINTF_L3(PRINT_MASK_ATTA, ohcip->ohci_log_hdl,
11186 "\thcr_rh_portstatus 0x%x: 0x%x ", i,
11187 Get_OpReg(hcr_rh_portstatus[i]));
11188 }
11189 }
11190
11191
11192 /*
11193 * ohci_print_ed:
11194 */
11195 static void
ohci_print_ed(ohci_state_t * ohcip,ohci_ed_t * ed)11196 ohci_print_ed(
11197 ohci_state_t *ohcip,
11198 ohci_ed_t *ed)
11199 {
11200 uint_t ctrl = Get_ED(ed->hced_ctrl);
11201
11202 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11203 "ohci_print_ed: ed = 0x%p", (void *)ed);
11204
11205 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11206 "\thced_ctrl: 0x%x %s", ctrl,
11207 ((Get_ED(ed->hced_headp) & HC_EPT_Halt) ? "halted": ""));
11208 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11209 "\ttoggle carry: 0x%x", Get_ED(ed->hced_headp) & HC_EPT_Carry);
11210
11211 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11212 "\tctrl: 0x%x", Get_ED(ed->hced_ctrl));
11213 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11214 "\ttailp: 0x%x", Get_ED(ed->hced_tailp));
11215 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11216 "\theadp: 0x%x", Get_ED(ed->hced_headp));
11217 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11218 "\tnext: 0x%x", Get_ED(ed->hced_next));
11219 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11220 "\tprev: 0x%x", Get_ED(ed->hced_prev));
11221 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11222 "\tnode: 0x%x", Get_ED(ed->hced_node));
11223 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11224 "\treclaim_next: 0x%x", Get_ED(ed->hced_reclaim_next));
11225 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11226 "\treclaim_frame: 0x%x", Get_ED(ed->hced_reclaim_frame));
11227 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11228 "\tstate: 0x%x", Get_ED(ed->hced_state));
11229 }
11230
11231
11232 /*
11233 * ohci_print_td:
11234 */
11235 static void
ohci_print_td(ohci_state_t * ohcip,ohci_td_t * td)11236 ohci_print_td(
11237 ohci_state_t *ohcip,
11238 ohci_td_t *td)
11239 {
11240 uint_t i;
11241 uint_t ctrl = Get_TD(td->hctd_ctrl);
11242
11243 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11244 "ohci_print_td: td = 0x%p", (void *)td);
11245
11246 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11247 "\tPID: 0x%x ", ctrl & HC_TD_PID);
11248 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11249 "\tDelay Intr: 0x%x ", ctrl & HC_TD_DI);
11250 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11251 "\tData Toggle: 0x%x ", ctrl & HC_TD_DT);
11252 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11253 "\tError Count: 0x%x ", ctrl & HC_TD_EC);
11254
11255 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11256 "\tctrl: 0x%x ", Get_TD(td->hctd_ctrl));
11257 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11258 "\tcbp: 0x%x ", Get_TD(td->hctd_cbp));
11259 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11260 "\tnext_td: 0x%x ", Get_TD(td->hctd_next_td));
11261 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11262 "\tbuf_end: 0x%x ", Get_TD(td->hctd_buf_end));
11263
11264 for (i = 0; i < 4; i++) {
11265 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11266 "\toffset[%d]: 0x%x ", i, Get_TD(td->hctd_offsets[i]));
11267 }
11268
11269 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11270 "\ttrans_wrapper: 0x%x ", Get_TD(td->hctd_trans_wrapper));
11271 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11272 "\tstate: 0x%x ", Get_TD(td->hctd_state));
11273 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11274 "\ttw_next_td: 0x%x ", Get_TD(td->hctd_tw_next_td));
11275 USB_DPRINTF_L3(PRINT_MASK_LISTS, ohcip->ohci_log_hdl,
11276 "\tctrl_phase: 0x%x ", Get_TD(td->hctd_ctrl_phase));
11277 }
11278
11279 /*
11280 * quiesce(9E) entry point.
11281 *
11282 * This function is called when the system is single-threaded at high
11283 * PIL with preemption disabled. Therefore, this function must not be
11284 * blocked.
11285 *
11286 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
11287 * DDI_FAILURE indicates an error condition and should almost never happen.
11288 *
11289 * define as a wrapper for sparc, or warlock will complain.
11290 */
11291 #ifdef __sparc
11292 int
ohci_quiesce(dev_info_t * dip)11293 ohci_quiesce(dev_info_t *dip)
11294 {
11295 return (ddi_quiesce_not_supported(dip));
11296 }
11297 #else
11298 int
ohci_quiesce(dev_info_t * dip)11299 ohci_quiesce(dev_info_t *dip)
11300 {
11301 ohci_state_t *ohcip = ohci_obtain_state(dip);
11302
11303 if (ohcip == NULL)
11304 return (DDI_FAILURE);
11305
11306 #ifndef lint
11307 _NOTE(NO_COMPETING_THREADS_NOW);
11308 #endif
11309
11310 if (ohcip->ohci_flags & OHCI_INTR) {
11311
11312 /* Disable all HC ED list processing */
11313 Set_OpReg(hcr_control,
11314 (Get_OpReg(hcr_control) & ~(HCR_CONTROL_CLE |
11315 HCR_CONTROL_BLE | HCR_CONTROL_PLE | HCR_CONTROL_IE)));
11316
11317 /* Disable all HC interrupts */
11318 Set_OpReg(hcr_intr_disable,
11319 (HCR_INTR_SO | HCR_INTR_WDH | HCR_INTR_RD | HCR_INTR_UE));
11320
11321 /* Disable Master and SOF interrupts */
11322 Set_OpReg(hcr_intr_disable, (HCR_INTR_MIE | HCR_INTR_SOF));
11323
11324 /* Set the Host Controller Functional State to Reset */
11325 Set_OpReg(hcr_control, ((Get_OpReg(hcr_control) &
11326 (~HCR_CONTROL_HCFS)) | HCR_CONTROL_RESET));
11327
11328 /*
11329 * Workaround for ULI1575 chipset. Following OHCI Operational
11330 * Memory Registers are not cleared to their default value
11331 * on reset. Explicitly set the registers to default value.
11332 */
11333 if (ohcip->ohci_vendor_id == PCI_ULI1575_VENID &&
11334 ohcip->ohci_device_id == PCI_ULI1575_DEVID) {
11335 Set_OpReg(hcr_control, HCR_CONTROL_DEFAULT);
11336 Set_OpReg(hcr_intr_enable, HCR_INT_ENABLE_DEFAULT);
11337 Set_OpReg(hcr_HCCA, HCR_HCCA_DEFAULT);
11338 Set_OpReg(hcr_ctrl_head, HCR_CONTROL_HEAD_ED_DEFAULT);
11339 Set_OpReg(hcr_bulk_head, HCR_BULK_HEAD_ED_DEFAULT);
11340 Set_OpReg(hcr_frame_interval,
11341 HCR_FRAME_INTERVAL_DEFAULT);
11342 Set_OpReg(hcr_periodic_strt,
11343 HCR_PERIODIC_START_DEFAULT);
11344 }
11345
11346 ohcip->ohci_hc_soft_state = OHCI_CTLR_SUSPEND_STATE;
11347 }
11348
11349 /* Unmap the OHCI registers */
11350 if (ohcip->ohci_regs_handle) {
11351 /* Reset the host controller */
11352 Set_OpReg(hcr_cmd_status, HCR_STATUS_RESET);
11353 }
11354
11355 #ifndef lint
11356 _NOTE(COMPETING_THREADS_NOW);
11357 #endif
11358 return (DDI_SUCCESS);
11359 }
11360 #endif /* __sparc */
11361