Print this page
MFV: illumos-gate@2aba3acda67326648fd60aaf2bfb4e18ee8c04ed
9816 Multi-TRB xhci transfers should use event data
9817 xhci needs to always set slot context
8550 increase xhci bulk transfer sgl count
9818 xhci_transfer_get_tdsize can return values that are too large
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Joshua M. Clulow <josh@sysmgr.org>
Author: Robert Mustacchi <rm@joyent.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/usb/hcd/xhci/xhci_usba.c
+++ new/usr/src/uts/common/io/usb/hcd/xhci/xhci_usba.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2016 Joyent, Inc.
13 + * Copyright (c) 2018, Joyent, Inc.
14 14 */
15 15
16 16 /*
17 17 * illumos USB framework endpoints and functions for xHCI.
18 18 *
19 19 * Please see the big theory statement in xhci.c for more information.
20 20 */
21 21
22 22 #include <sys/usb/hcd/xhci/xhci.h>
23 23 #include <sys/sysmacros.h>
24 24 #include <sys/strsun.h>
25 25 #include <sys/strsubr.h>
26 26
27 27 static xhci_t *
28 28 xhci_hcdi_get_xhcip_from_dev(usba_device_t *ud)
29 29 {
30 30 dev_info_t *dip = ud->usb_root_hub_dip;
31 31 xhci_t *xhcip = ddi_get_soft_state(xhci_soft_state,
32 32 ddi_get_instance(dip));
33 33 VERIFY(xhcip != NULL);
34 34 return (xhcip);
35 35 }
36 36
37 37 static xhci_t *
38 38 xhci_hcdi_get_xhcip(usba_pipe_handle_data_t *ph)
39 39 {
40 40 return (xhci_hcdi_get_xhcip_from_dev(ph->p_usba_device));
41 41 }
42 42
43 43 /*
44 44 * While the xHCI hardware is capable of supporting power management, we don't
45 45 * in the driver right now. Note, USBA doesn't seem to end up calling this entry
46 46 * point.
47 47 */
48 48 /* ARGSUSED */
49 49 static int
50 50 xhci_hcdi_pm_support(dev_info_t *dip)
51 51 {
52 52 return (USB_FAILURE);
53 53 }
54 54
55 55 static int
56 56 xhci_hcdi_pipe_open(usba_pipe_handle_data_t *ph, usb_flags_t usb_flags)
57 57 {
58 58 xhci_t *xhcip = xhci_hcdi_get_xhcip(ph);
59 59 xhci_pipe_t *pipe;
60 60 xhci_endpoint_t *xep;
61 61 xhci_device_t *xd;
62 62 int kmflags = usb_flags & USB_FLAGS_SLEEP ? KM_SLEEP : KM_NOSLEEP;
63 63 int ret;
64 64 uint_t epid;
65 65
66 66 mutex_enter(&xhcip->xhci_lock);
67 67 if (xhcip->xhci_state & XHCI_S_ERROR) {
68 68 mutex_exit(&xhcip->xhci_lock);
69 69 return (USB_HC_HARDWARE_ERROR);
70 70 }
71 71 mutex_exit(&xhcip->xhci_lock);
72 72
73 73 /*
74 74 * If we're here, something must be trying to open an already-opened
75 75 * pipe which is bad news.
76 76 */
77 77 if (ph->p_hcd_private != NULL) {
78 78 return (USB_FAILURE);
79 79 }
80 80
81 81 pipe = kmem_zalloc(sizeof (xhci_pipe_t), kmflags);
82 82 if (pipe == NULL) {
83 83 return (USB_NO_RESOURCES);
84 84 }
85 85 pipe->xp_opentime = gethrtime();
86 86 pipe->xp_pipe = ph;
87 87
88 88 /*
89 89 * If this is the root hub, there's nothing special to do on open. Just
90 90 * go ahead and allow it to be opened. All we have to do is add this to
91 91 * the list of our tracking structures for open pipes.
92 92 */
93 93 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
94 94 xep = NULL;
95 95 goto add;
96 96 }
97 97
98 98 /*
99 99 * Now that we're here, we're being asked to open up an endpoint of some
100 100 * kind. Because we've already handled the case of the root hub,
101 101 * everything should have a device.
102 102 */
103 103 epid = xhci_endpoint_pipe_to_epid(ph);
104 104 xd = usba_hcdi_get_device_private(ph->p_usba_device);
105 105 if (xd == NULL) {
106 106 xhci_error(xhcip, "!encountered endpoint (%d) without device "
107 107 "during pipe open", epid);
108 108 kmem_free(pipe, sizeof (xhci_pipe_t));
109 109 return (USB_FAILURE);
110 110 }
111 111
112 112 /*
113 113 * See if this endpoint exists or not, in general endpoints should not
114 114 * exist except for the default control endpoint, which we don't tear
115 115 * down until the device itself is cleaned up. Otherwise, a given pipe
116 116 * can only be open once.
117 117 */
118 118 mutex_enter(&xhcip->xhci_lock);
119 119 if (epid == XHCI_DEFAULT_ENDPOINT) {
120 120 xep = xd->xd_endpoints[epid];
121 121 VERIFY(xep != NULL);
122 122 VERIFY(xep->xep_pipe == NULL);
123 123 xep->xep_pipe = ph;
124 124 mutex_exit(&xhcip->xhci_lock);
125 125 ret = xhci_endpoint_update_default(xhcip, xd, xep);
126 126 if (ret != USB_SUCCESS) {
127 127 kmem_free(pipe, sizeof (xhci_pipe_t));
128 128 return (ret);
129 129 }
130 130 goto add;
131 131 }
132 132
133 133 if (xd->xd_endpoints[epid] != NULL) {
134 134 mutex_exit(&xhcip->xhci_lock);
135 135 kmem_free(pipe, sizeof (xhci_pipe_t));
136 136 xhci_log(xhcip, "!asked to open endpoint %d on slot %d and "
137 137 "port %d, but endpoint already exists", epid, xd->xd_slot,
138 138 xd->xd_port);
139 139 return (USB_FAILURE);
140 140 }
141 141
142 142 /*
143 143 * If we're opening an endpoint other than the default control endpoint,
144 144 * then the device should have had a USB address assigned by the
145 145 * controller. Sanity check that before continuing.
146 146 */
147 147 if (epid != XHCI_DEFAULT_ENDPOINT) {
148 148 VERIFY(xd->xd_addressed == B_TRUE);
149 149 }
150 150
151 151 /*
152 152 * Okay, at this point we need to go create and set up an endpoint.
153 153 * Once we're done, we'll try to install it and make sure that it
154 154 * doesn't conflict with something else going on.
155 155 */
156 156 ret = xhci_endpoint_init(xhcip, xd, ph);
157 157 if (ret != 0) {
158 158 mutex_exit(&xhcip->xhci_lock);
159 159 kmem_free(pipe, sizeof (xhci_pipe_t));
160 160 if (ret == EIO) {
161 161 xhci_error(xhcip, "failed to initialize endpoint %d "
162 162 "on device slot %d and port %d: encountered fatal "
163 163 "FM error, resetting device", epid, xd->xd_slot,
164 164 xd->xd_port);
|
↓ open down ↓ |
141 lines elided |
↑ open up ↑ |
165 165 xhci_fm_runtime_reset(xhcip);
166 166 }
167 167 return (USB_HC_HARDWARE_ERROR);
168 168 }
169 169 xep = xd->xd_endpoints[epid];
170 170
171 171 mutex_enter(&xd->xd_imtx);
172 172 mutex_exit(&xhcip->xhci_lock);
173 173
174 174 /*
175 - * Update the slot and input context for this endpoint.
175 + * Update the slot and input context for this endpoint. We make sure to
176 + * always set the slot as having changed in the context field as the
177 + * specification suggests we should and some hardware requires it.
176 178 */
177 179 xd->xd_input->xic_drop_flags = LE_32(0);
178 - xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1));
180 + xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0) |
181 + XHCI_INCTX_MASK_DCI(epid + 1));
179 182
180 183 if (epid + 1 > XHCI_SCTX_GET_DCI(LE_32(xd->xd_slotin->xsc_info))) {
181 184 uint32_t info;
182 185
183 186 info = xd->xd_slotin->xsc_info;
184 187 info &= ~XHCI_SCTX_DCI_MASK;
185 188 info |= XHCI_SCTX_SET_DCI(epid + 1);
186 189 xd->xd_slotin->xsc_info = info;
187 190 }
188 191
189 192 XHCI_DMA_SYNC(xd->xd_ictx, DDI_DMA_SYNC_FORDEV);
190 193 if (xhci_check_dma_handle(xhcip, &xd->xd_ictx) != DDI_FM_OK) {
191 194 mutex_exit(&xd->xd_imtx);
192 195 xhci_endpoint_fini(xd, epid);
193 196 kmem_free(pipe, sizeof (xhci_pipe_t));
194 197 xhci_error(xhcip, "failed to open pipe on endpoint %d of "
195 198 "device with slot %d and port %d: encountered fatal FM "
196 199 "error syncing device input context, resetting device",
197 200 epid, xd->xd_slot, xd->xd_port);
198 201 xhci_fm_runtime_reset(xhcip);
199 202 return (USB_HC_HARDWARE_ERROR);
200 203 }
201 204
202 205 if ((ret = xhci_command_configure_endpoint(xhcip, xd)) != USB_SUCCESS) {
203 206 mutex_exit(&xd->xd_imtx);
204 207 xhci_endpoint_fini(xd, epid);
205 208 kmem_free(pipe, sizeof (xhci_pipe_t));
206 209 return (ret);
207 210 }
208 211
209 212 mutex_exit(&xd->xd_imtx);
210 213 add:
211 214 pipe->xp_ep = xep;
212 215 ph->p_hcd_private = (usb_opaque_t)pipe;
213 216 mutex_enter(&xhcip->xhci_lock);
214 217 list_insert_tail(&xhcip->xhci_usba.xa_pipes, pipe);
215 218 mutex_exit(&xhcip->xhci_lock);
216 219
217 220 return (USB_SUCCESS);
218 221 }
219 222
220 223 static void
221 224 xhci_hcdi_periodic_free(xhci_t *xhcip, xhci_pipe_t *xp)
222 225 {
223 226 int i;
224 227 xhci_periodic_pipe_t *xpp = &xp->xp_periodic;
225 228
226 229 if (xpp->xpp_tsize == 0)
227 230 return;
228 231
229 232 for (i = 0; i < xpp->xpp_ntransfers; i++) {
230 233 if (xpp->xpp_transfers[i] == NULL)
231 234 continue;
232 235 xhci_transfer_free(xhcip, xpp->xpp_transfers[i]);
233 236 xpp->xpp_transfers[i] = NULL;
234 237 }
235 238
236 239 xpp->xpp_ntransfers = 0;
237 240 xpp->xpp_tsize = 0;
238 241 }
239 242
240 243 /*
241 244 * Iterate over all transfers and free everything on the pipe. Once done, update
242 245 * the ring to basically 'consume' everything. For periodic IN endpoints, we
243 246 * need to handle this somewhat differently and actually close the original
244 247 * request and not deallocate the related pieces as those exist for the lifetime
245 248 * of the endpoint and are constantly reused.
246 249 */
247 250 static void
248 251 xhci_hcdi_pipe_flush(xhci_t *xhcip, xhci_endpoint_t *xep, int intr_code)
249 252 {
250 253 xhci_transfer_t *xt;
251 254
252 255 ASSERT(MUTEX_HELD(&xhcip->xhci_lock));
253 256
254 257 while ((xt = list_remove_head(&xep->xep_transfers)) != NULL) {
255 258 if (xhci_endpoint_is_periodic_in(xep) == B_FALSE) {
256 259 usba_hcdi_cb(xep->xep_pipe, xt->xt_usba_req,
257 260 USB_CR_FLUSHED);
258 261 xhci_transfer_free(xhcip, xt);
259 262 }
260 263 }
261 264
262 265 if (xhci_endpoint_is_periodic_in(xep) == B_TRUE) {
263 266 xhci_pipe_t *xp = (xhci_pipe_t *)xep->xep_pipe->p_hcd_private;
264 267 xhci_periodic_pipe_t *xpp = &xp->xp_periodic;
265 268
266 269 if (xpp->xpp_usb_req != NULL) {
267 270 usba_hcdi_cb(xep->xep_pipe, xpp->xpp_usb_req,
268 271 intr_code);
269 272 xpp->xpp_usb_req = NULL;
270 273 }
271 274 }
272 275 }
273 276
274 277 /*
275 278 * We've been asked to terminate some set of regular I/O on an interrupt pipe.
276 279 * If this is for the root device, e.g. the xhci driver itself, then we remove
277 280 * our interrupt callback. Otherwise we stop the device for interrupt polling as
278 281 * follows:
279 282 *
280 283 * 1. Issue a stop endpoint command
281 284 * 2. Check to make sure that the endpoint stopped and reset it if needed.
282 285 * 3. Any thing that gets resolved can callback in the interim.
283 286 * 4. Ensure that nothing is scheduled on the ring
284 287 * 5. Skip the contents of the ring and set the TR dequeue pointer.
285 288 * 6. Return the original callback with a USB_CR_STOPPED_POLLING, NULL out the
286 289 * callback in the process.
287 290 */
288 291 static int
289 292 xhci_hcdi_pipe_poll_fini(usba_pipe_handle_data_t *ph, boolean_t is_close)
290 293 {
291 294 int ret;
292 295 uint_t epid;
293 296 xhci_t *xhcip = xhci_hcdi_get_xhcip(ph);
294 297 xhci_device_t *xd;
295 298 xhci_endpoint_t *xep;
296 299 xhci_pipe_t *xp;
297 300 xhci_periodic_pipe_t *xpp;
298 301 usb_opaque_t urp;
299 302
300 303 mutex_enter(&xhcip->xhci_lock);
301 304 if (xhcip->xhci_state & XHCI_S_ERROR) {
302 305 mutex_exit(&xhcip->xhci_lock);
303 306 return (USB_HC_HARDWARE_ERROR);
304 307 }
305 308
306 309 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
307 310 xhci_root_hub_intr_root_disable(xhcip);
308 311 ret = USB_SUCCESS;
309 312 mutex_exit(&xhcip->xhci_lock);
310 313 return (ret);
311 314 }
312 315
313 316 xd = usba_hcdi_get_device_private(ph->p_usba_device);
314 317 epid = xhci_endpoint_pipe_to_epid(ph);
315 318 if (xd->xd_endpoints[epid] == NULL) {
316 319 mutex_exit(&xhcip->xhci_lock);
317 320 xhci_error(xhcip, "asked to stop intr polling on slot %d, "
318 321 "port %d, endpoint: %d, but no endpoint structure",
319 322 xd->xd_slot, xd->xd_port, epid);
320 323 return (USB_FAILURE);
321 324 }
322 325 xep = xd->xd_endpoints[epid];
323 326 xp = (xhci_pipe_t *)ph->p_hcd_private;
324 327 if (xp == NULL) {
325 328 mutex_exit(&xhcip->xhci_lock);
326 329 xhci_error(xhcip, "asked to do finish polling on slot %d, "
327 330 "port %d, endpoint: %d, but no pipe structure",
328 331 xd->xd_slot, xd->xd_port, epid);
329 332 return (USB_FAILURE);
330 333 }
331 334 xpp = &xp->xp_periodic;
332 335
333 336 /*
334 337 * Ensure that no other resets or time outs are going on right now.
335 338 */
336 339 while ((xep->xep_state & (XHCI_ENDPOINT_SERIALIZE)) != 0) {
337 340 cv_wait(&xep->xep_state_cv, &xhcip->xhci_lock);
338 341 }
339 342
340 343 if (xpp->xpp_poll_state == XHCI_PERIODIC_POLL_IDLE) {
341 344 mutex_exit(&xhcip->xhci_lock);
342 345 return (USB_SUCCESS);
343 346 }
344 347
345 348 if (xpp->xpp_poll_state == XHCI_PERIODIC_POLL_STOPPING) {
346 349 mutex_exit(&xhcip->xhci_lock);
347 350 return (USB_FAILURE);
348 351 }
349 352
350 353 xpp->xpp_poll_state = XHCI_PERIODIC_POLL_STOPPING;
351 354 xep->xep_state |= XHCI_ENDPOINT_QUIESCE;
352 355 ret = xhci_endpoint_quiesce(xhcip, xd, xep);
353 356 if (ret != USB_SUCCESS) {
354 357 xhci_error(xhcip, "!failed to quiesce endpoint on slot %d, "
355 358 "port %d, endpoint: %d, failed with %d.",
356 359 xd->xd_slot, xd->xd_port, epid, ret);
357 360 xep->xep_state &= ~XHCI_ENDPOINT_QUIESCE;
358 361 cv_broadcast(&xep->xep_state_cv);
359 362 mutex_exit(&xhcip->xhci_lock);
360 363 return (ret);
361 364 }
362 365
363 366 /*
364 367 * Okay, we've stopped this ring time to wrap it all up. Remove all the
365 368 * transfers, note they aren't freed like a pipe reset.
366 369 */
367 370 while (list_is_empty(&xep->xep_transfers) == 0)
368 371 (void) list_remove_head(&xep->xep_transfers);
369 372 xhci_ring_skip(&xep->xep_ring);
370 373 mutex_exit(&xhcip->xhci_lock);
371 374
372 375 if ((ret = xhci_command_set_tr_dequeue(xhcip, xd, xep)) !=
373 376 USB_SUCCESS) {
374 377 xhci_error(xhcip, "!failed to reset endpoint ring on slot %d, "
375 378 "port %d, endpoint: %d, failed with %d.",
376 379 xd->xd_slot, xd->xd_port, epid, ret);
377 380 mutex_enter(&xhcip->xhci_lock);
378 381 xep->xep_state &= ~XHCI_ENDPOINT_QUIESCE;
379 382 cv_broadcast(&xep->xep_state_cv);
380 383 mutex_exit(&xhcip->xhci_lock);
381 384 return (ret);
382 385 }
383 386
384 387 mutex_enter(&xhcip->xhci_lock);
385 388 urp = xpp->xpp_usb_req;
386 389 xpp->xpp_usb_req = NULL;
387 390 xpp->xpp_poll_state = XHCI_PERIODIC_POLL_IDLE;
388 391 xep->xep_state &= ~XHCI_ENDPOINT_PERIODIC;
389 392 mutex_exit(&xhcip->xhci_lock);
390 393
391 394 /*
392 395 * It's possible that with a persistent pipe, we may not actually have
393 396 * anything left to call back on, because we already had.
394 397 */
395 398 if (urp != NULL) {
396 399 usba_hcdi_cb(ph, urp, is_close == B_TRUE ?
397 400 USB_CR_PIPE_CLOSING : USB_CR_STOPPED_POLLING);
398 401 }
399 402
400 403 /*
401 404 * Notify anything waiting for us that we're done quiescing this device.
402 405 */
403 406 mutex_enter(&xhcip->xhci_lock);
404 407 xep->xep_state &= ~XHCI_ENDPOINT_QUIESCE;
405 408 cv_broadcast(&xep->xep_state_cv);
406 409 mutex_exit(&xhcip->xhci_lock);
407 410
408 411 return (USB_SUCCESS);
409 412
410 413 }
411 414
412 415 /*
413 416 * Tear down everything that we did in open. After this, the consumer of this
414 417 * USB device is done.
415 418 */
416 419 /* ARGSUSED */
417 420 static int
418 421 xhci_hcdi_pipe_close(usba_pipe_handle_data_t *ph, usb_flags_t usb_flags)
419 422 {
420 423 xhci_t *xhcip = xhci_hcdi_get_xhcip(ph);
421 424 xhci_pipe_t *xp;
422 425 xhci_device_t *xd;
423 426 xhci_endpoint_t *xep;
424 427 uint32_t info;
425 428 int ret, i;
426 429 uint_t epid;
427 430
428 431 if ((ph->p_ep.bmAttributes & USB_EP_ATTR_MASK) == USB_EP_ATTR_INTR &&
429 432 xhcip->xhci_usba.xa_intr_cb_ph != NULL) {
430 433 if ((ret = xhci_hcdi_pipe_poll_fini(ph, B_TRUE)) !=
431 434 USB_SUCCESS) {
432 435 return (ret);
433 436 }
434 437 }
435 438
436 439 mutex_enter(&xhcip->xhci_lock);
437 440
438 441 xp = (xhci_pipe_t *)ph->p_hcd_private;
439 442 VERIFY(xp != NULL);
440 443
441 444 /*
442 445 * The default endpoint is special. It is created and destroyed with the
443 446 * device. So like with open, closing it is just state tracking. The
444 447 * same is true for the root hub.
445 448 */
446 449 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR)
447 450 goto remove;
448 451
449 452 xd = usba_hcdi_get_device_private(ph->p_usba_device);
450 453 epid = xhci_endpoint_pipe_to_epid(ph);
451 454 if (xd->xd_endpoints[epid] == NULL) {
452 455 mutex_exit(&xhcip->xhci_lock);
453 456 xhci_error(xhcip, "asked to do close pipe on slot %d, "
454 457 "port %d, endpoint: %d, but no endpoint structure",
455 458 xd->xd_slot, xd->xd_port, epid);
456 459 return (USB_FAILURE);
457 460 }
458 461 xep = xd->xd_endpoints[epid];
459 462
460 463 if (xp->xp_ep != NULL && xp->xp_ep->xep_num == XHCI_DEFAULT_ENDPOINT) {
461 464 xep->xep_pipe = NULL;
462 465 goto remove;
463 466 }
|
↓ open down ↓ |
275 lines elided |
↑ open up ↑ |
464 467
465 468 /*
466 469 * We need to clean up the endpoint. So the first thing we need to do is
467 470 * stop it with a configure endpoint command. Once it's stopped, we can
468 471 * free all associated resources.
469 472 */
470 473 mutex_enter(&xd->xd_imtx);
471 474
472 475 /*
473 476 * Potentially update the slot input context about the current max
474 - * endpoint. While we don't update the slot context with this,
475 - * surrounding code expects it to be updated to be consistent.
477 + * endpoint. Make sure to set that the slot context is being updated
478 + * here as it may be changing and some hardware requires it.
476 479 */
477 480 xd->xd_input->xic_drop_flags = LE_32(XHCI_INCTX_MASK_DCI(epid + 1));
478 - xd->xd_input->xic_add_flags = LE_32(0);
481 + xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0));
479 482 for (i = XHCI_NUM_ENDPOINTS - 1; i >= 0; i--) {
480 483 if (xd->xd_endpoints[i] != NULL &&
481 484 xd->xd_endpoints[i] != xep)
482 485 break;
483 486 }
484 487 info = xd->xd_slotin->xsc_info;
485 488 info &= ~XHCI_SCTX_DCI_MASK;
486 489 info |= XHCI_SCTX_SET_DCI(i + 1);
487 490 xd->xd_slotin->xsc_info = info;
488 491
489 492 /*
490 493 * Also zero out our context for this endpoint. Note that we don't
491 494 * bother with syncing DMA memory here as it's not required to be synced
492 495 * for this operation.
493 496 */
494 497 bzero(xd->xd_endin[xep->xep_num], sizeof (xhci_endpoint_context_t));
495 498
496 499 /*
497 500 * Stop the device and kill our timeout. Note, it is safe to hold the
498 501 * device's input mutex across the untimeout, this lock should never be
499 502 * referenced by the timeout code.
500 503 */
501 504 xep->xep_state |= XHCI_ENDPOINT_TEARDOWN;
502 505 mutex_exit(&xhcip->xhci_lock);
503 506 (void) untimeout(xep->xep_timeout);
504 507
505 508 ret = xhci_command_configure_endpoint(xhcip, xd);
506 509 mutex_exit(&xd->xd_imtx);
507 510 if (ret != USB_SUCCESS)
508 511 return (ret);
509 512 mutex_enter(&xhcip->xhci_lock);
510 513
511 514 /*
512 515 * Now that we've unconfigured the endpoint. See if we need to flush any
513 516 * transfers.
514 517 */
515 518 xhci_hcdi_pipe_flush(xhcip, xep, USB_CR_PIPE_CLOSING);
516 519 if ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) {
517 520 xhci_hcdi_periodic_free(xhcip, xp);
518 521 }
519 522
520 523 xhci_endpoint_fini(xd, epid);
521 524
522 525 remove:
523 526 ph->p_hcd_private = NULL;
524 527 list_remove(&xhcip->xhci_usba.xa_pipes, xp);
525 528 kmem_free(xp, sizeof (xhci_pipe_t));
526 529
527 530 mutex_exit(&xhcip->xhci_lock);
528 531
529 532 return (USB_SUCCESS);
530 533 }
531 534
532 535 /*
533 536 * We've been asked to reset a pipe aka an endpoint. This endpoint may be in an
534 537 * arbitrary state, it may be running or it may be halted. In this case, we go
535 538 * through and check whether or not we know it's been halted or not. If it has
536 539 * not, then we stop the endpoint.
537 540 *
538 541 * Once the endpoint has been stopped, walk all transfers and go ahead and
539 542 * basically return them as being flushed. Then finally set the dequeue point
540 543 * for this endpoint.
541 544 */
542 545 /* ARGSUSED */
543 546 static int
544 547 xhci_hcdi_pipe_reset(usba_pipe_handle_data_t *ph, usb_flags_t usb_flags)
545 548 {
546 549 xhci_t *xhcip = xhci_hcdi_get_xhcip(ph);
547 550 xhci_device_t *xd;
548 551 xhci_endpoint_t *xep;
549 552 uint_t epid;
550 553 int ret;
551 554
552 555 mutex_enter(&xhcip->xhci_lock);
553 556 if (xhcip->xhci_state & XHCI_S_ERROR) {
554 557 mutex_exit(&xhcip->xhci_lock);
555 558 return (USB_HC_HARDWARE_ERROR);
556 559 }
557 560
558 561 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
559 562 mutex_exit(&xhcip->xhci_lock);
560 563 return (USB_NOT_SUPPORTED);
561 564 }
562 565
563 566 xd = usba_hcdi_get_device_private(ph->p_usba_device);
564 567 epid = xhci_endpoint_pipe_to_epid(ph);
565 568 if (xd->xd_endpoints[epid] == NULL) {
566 569 mutex_exit(&xhcip->xhci_lock);
567 570 xhci_error(xhcip, "asked to do reset pipe on slot %d, "
568 571 "port %d, endpoint: %d, but no endpoint structure",
569 572 xd->xd_slot, xd->xd_port, epid);
570 573 return (USB_FAILURE);
571 574 }
572 575
573 576 xep = xd->xd_endpoints[epid];
574 577
575 578 /*
576 579 * Ensure that no other resets or time outs are going on right now.
577 580 */
578 581 while ((xep->xep_state & (XHCI_ENDPOINT_SERIALIZE)) != 0) {
579 582 cv_wait(&xep->xep_state_cv, &xhcip->xhci_lock);
580 583 }
581 584
582 585 xep->xep_state |= XHCI_ENDPOINT_QUIESCE;
583 586 ret = xhci_endpoint_quiesce(xhcip, xd, xep);
584 587 if (ret != USB_SUCCESS) {
585 588 /*
586 589 * We failed to quiesce for some reason, remove the flag and let
587 590 * someone else give it a shot.
588 591 */
589 592 xhci_error(xhcip, "!failed to quiesce endpoint on slot %d, "
590 593 "port %d, endpoint: %d, failed with %d.",
591 594 xd->xd_slot, xd->xd_port, epid, ret);
592 595 xep->xep_state &= ~XHCI_ENDPOINT_QUIESCE;
593 596 cv_broadcast(&xep->xep_state_cv);
594 597 mutex_exit(&xhcip->xhci_lock);
595 598 return (ret);
596 599 }
597 600
598 601 xhci_ring_skip(&xep->xep_ring);
599 602
600 603 mutex_exit(&xhcip->xhci_lock);
601 604 if ((ret = xhci_command_set_tr_dequeue(xhcip, xd, xep)) !=
602 605 USB_SUCCESS) {
603 606 xhci_error(xhcip, "!failed to reset endpoint ring on slot %d, "
604 607 "port %d, endpoint: %d, failed setting ring dequeue with "
605 608 "%d.", xd->xd_slot, xd->xd_port, epid, ret);
606 609 mutex_enter(&xhcip->xhci_lock);
607 610 xep->xep_state &= ~XHCI_ENDPOINT_QUIESCE;
608 611 cv_broadcast(&xep->xep_state_cv);
609 612 mutex_exit(&xhcip->xhci_lock);
610 613 return (ret);
611 614 }
612 615
613 616 mutex_enter(&xhcip->xhci_lock);
614 617 xhci_hcdi_pipe_flush(xhcip, xep, USB_CR_PIPE_RESET);
615 618
616 619 /*
617 620 * We need to remove the periodic flag as part of resetting, as if this
618 621 * was used for periodic activity, it no longer is and therefore can now
619 622 * be used for such purposes.
620 623 *
621 624 * Notify anything waiting for us that we're done quiescing this device.
622 625 */
623 626 xep->xep_state &= ~(XHCI_ENDPOINT_QUIESCE | XHCI_ENDPOINT_PERIODIC);
624 627 cv_broadcast(&xep->xep_state_cv);
625 628 mutex_exit(&xhcip->xhci_lock);
626 629
627 630 return (USB_SUCCESS);
628 631 }
629 632
630 633 /*
631 634 * We're asked to reset or change the data toggle, which is used in a few cases.
632 635 * However, there doesn't seem to be a good way to do this in xHCI as the data
633 636 * toggle isn't exposed. It seems that dropping a reset endpoint would
634 637 * theoretically do this; however, that can only be used when in the HALTED
635 638 * state. As such, for now we just return.
636 639 */
637 640 /* ARGSUSED */
638 641 void
639 642 xhci_hcdi_pipe_reset_data_toggle(usba_pipe_handle_data_t *pipe_handle)
640 643 {
641 644 }
642 645
643 646 /*
644 647 * We need to convert the USB request to an 8-byte little endian value. If we
645 648 * didn't have to think about big endian systems, this would be fine.
646 649 * Unfortunately, with them, this is a bit confusing. The problem is that if you
647 650 * think of this as a struct layout, the order that we or things together
648 651 * represents their byte layout. e.g. ctrl_bRequest is at offset 1 in the SETUP
649 652 * STAGE trb. However, when it becomes a part of a 64-bit big endian number, if
650 653 * ends up at byte 7, where as it needs to be at one. Hence why we do a final
651 654 * LE_64 at the end of this, to convert this into the byte order that it's
652 655 * expected to be in.
653 656 */
654 657 static uint64_t
655 658 xhci_hcdi_ctrl_req_to_trb(usb_ctrl_req_t *ucrp)
656 659 {
657 660 uint64_t ret = ucrp->ctrl_bmRequestType |
658 661 (ucrp->ctrl_bRequest << 8) |
659 662 ((uint64_t)LE_16(ucrp->ctrl_wValue) << 16) |
660 663 ((uint64_t)LE_16(ucrp->ctrl_wIndex) << 32) |
661 664 ((uint64_t)LE_16(ucrp->ctrl_wLength) << 48);
662 665 return (LE_64(ret));
663 666 }
664 667
665 668 /*
666 669 * USBA calls us in order to make a specific control type request to a device,
667 670 * potentially even the root hub. If the request is for the root hub, then we
668 671 * need to intercept this and cons up the requested data.
669 672 */
670 673 static int
671 674 xhci_hcdi_pipe_ctrl_xfer(usba_pipe_handle_data_t *ph, usb_ctrl_req_t *ucrp,
672 675 usb_flags_t usb_flags)
673 676 {
674 677 int ret, statusdir, trt;
675 678 uint_t ep;
676 679 xhci_device_t *xd;
677 680 xhci_endpoint_t *xep;
678 681 xhci_transfer_t *xt;
679 682 boolean_t datain;
680 683
681 684 xhci_t *xhcip = xhci_hcdi_get_xhcip(ph);
682 685
683 686 mutex_enter(&xhcip->xhci_lock);
684 687 if (xhcip->xhci_state & XHCI_S_ERROR) {
685 688 mutex_exit(&xhcip->xhci_lock);
686 689 return (USB_HC_HARDWARE_ERROR);
687 690 }
688 691
689 692 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
690 693 ret = xhci_root_hub_ctrl_req(xhcip, ph, ucrp);
691 694 mutex_exit(&xhcip->xhci_lock);
692 695 return (ret);
693 696 }
694 697
695 698 /*
696 699 * Determine the device and endpoint.
697 700 */
698 701 xd = usba_hcdi_get_device_private(ph->p_usba_device);
699 702 ep = xhci_endpoint_pipe_to_epid(ph);
700 703 if (xd->xd_endpoints[ep] == NULL) {
701 704 mutex_exit(&xhcip->xhci_lock);
702 705 xhci_error(xhcip, "asked to do control transfer on slot %d, "
703 706 "port %d, endpoint: %d, but no endpoint structure",
704 707 xd->xd_slot, xd->xd_port, ep);
705 708 return (USB_FAILURE);
706 709 }
707 710 xep = xd->xd_endpoints[ep];
708 711
709 712 /*
710 713 * There are several types of requests that we have to handle in special
711 714 * ways in xHCI. If we have one of those requests, then we don't
712 715 * necessarily go through the normal path. These special cases are all
713 716 * documented in xHCI 1.1 / 4.5.4.
714 717 *
715 718 * Looking at that, you may ask why aren't SET_CONFIGURATION and SET_IF
716 719 * special cased here. This action is a little confusing by default. The
717 720 * xHCI specification requires that we may need to issue a configure
718 721 * endpoint command as part of this. However, the xHCI 1.1 / 4.5.4.2
719 722 * states that we don't actually need to if nothing in the endpoint
720 723 * configuration context has changed. Because nothing in it should have
721 724 * changed as part of this, we don't need to do anything and instead
722 725 * just can issue the request normally. We're also assuming in the
723 726 * USB_REQ_SET_IF case that if something's changing the interface, the
724 727 * non-default endpoint will have yet to be opened.
725 728 */
726 729 if (ucrp->ctrl_bmRequestType == USB_DEV_REQ_HOST_TO_DEV &&
727 730 ucrp->ctrl_bRequest == USB_REQ_SET_ADDRESS) {
728 731 /*
729 732 * As we've defined an explicit set-address endpoint, we should
730 733 * never call this function. If we get here, always fail.
731 734 */
732 735 mutex_exit(&xhcip->xhci_lock);
733 736 usba_hcdi_cb(ph, (usb_opaque_t)ucrp, USB_CR_NOT_SUPPORTED);
734 737 return (USB_SUCCESS);
735 738 }
736 739
737 740 mutex_exit(&xhcip->xhci_lock);
738 741
739 742 /*
740 743 * Allocate the transfer memory, etc.
741 744 */
742 745 xt = xhci_transfer_alloc(xhcip, xep, ucrp->ctrl_wLength, 2, usb_flags);
743 746 if (xt == NULL) {
744 747 return (USB_NO_RESOURCES);
745 748 }
746 749 xt->xt_usba_req = (usb_opaque_t)ucrp;
747 750 xt->xt_timeout = ucrp->ctrl_timeout;
748 751 if (xt->xt_timeout == 0) {
749 752 xt->xt_timeout = HCDI_DEFAULT_TIMEOUT;
750 753 }
751 754
752 755 if (ucrp->ctrl_wLength > 0) {
753 756 if ((ucrp->ctrl_bmRequestType & USB_DEV_REQ_DEV_TO_HOST) != 0) {
754 757 trt = XHCI_TRB_TRT_IN;
755 758 datain = B_TRUE;
756 759 statusdir = 0;
757 760 } else {
758 761 trt = XHCI_TRB_TRT_OUT;
759 762 datain = B_FALSE;
760 763 statusdir = XHCI_TRB_DIR_IN;
761 764
762 765 xhci_transfer_copy(xt, ucrp->ctrl_data->b_rptr,
763 766 ucrp->ctrl_wLength, B_FALSE);
764 767 if (xhci_transfer_sync(xhcip, xt,
765 768 DDI_DMA_SYNC_FORDEV) != DDI_FM_OK) {
766 769 xhci_transfer_free(xhcip, xt);
767 770 xhci_error(xhcip, "failed to synchronize ctrl "
768 771 "transfer DMA memory on endpoint %u of "
769 772 "device on slot %d and port %d: resetting "
770 773 "device", xep->xep_num, xd->xd_slot,
771 774 xd->xd_port);
772 775 xhci_fm_runtime_reset(xhcip);
773 776 return (USB_HC_HARDWARE_ERROR);
774 777 }
775 778 }
776 779 } else {
777 780 trt = 0;
778 781 datain = B_FALSE;
779 782 statusdir = XHCI_TRB_DIR_IN;
780 783 }
781 784
782 785 /*
783 786 * We always fill in the required setup and status TRBs ourselves;
784 787 * however, to minimize our knowledge about how the data has been split
785 788 * across multiple DMA cookies in an SGL, we leave that to the transfer
786 789 * logic to fill in.
787 790 */
788 791 xt->xt_trbs[0].trb_addr = xhci_hcdi_ctrl_req_to_trb(ucrp);
789 792 xt->xt_trbs[0].trb_status = LE_32(XHCI_TRB_LEN(8) | XHCI_TRB_INTR(0));
790 793 xt->xt_trbs[0].trb_flags = LE_32(trt | XHCI_TRB_IDT |
|
↓ open down ↓ |
302 lines elided |
↑ open up ↑ |
791 794 XHCI_TRB_TYPE_SETUP);
792 795
793 796 if (ucrp->ctrl_wLength > 0)
794 797 xhci_transfer_trb_fill_data(xep, xt, 1, datain);
795 798
796 799 xt->xt_trbs[xt->xt_ntrbs - 1].trb_addr = 0;
797 800 xt->xt_trbs[xt->xt_ntrbs - 1].trb_status = LE_32(XHCI_TRB_INTR(0));
798 801 xt->xt_trbs[xt->xt_ntrbs - 1].trb_flags = LE_32(XHCI_TRB_TYPE_STATUS |
799 802 XHCI_TRB_IOC | statusdir);
800 803
804 +
801 805 mutex_enter(&xhcip->xhci_lock);
802 806
803 807 /*
804 808 * Schedule the transfer, allocating resources in the process.
805 809 */
806 810 if (xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE) != 0) {
807 811 xhci_transfer_free(xhcip, xt);
808 812 mutex_exit(&xhcip->xhci_lock);
809 813 return (USB_NO_RESOURCES);
810 814 }
811 815
812 816 mutex_exit(&xhcip->xhci_lock);
813 817
814 818 return (USB_SUCCESS);
815 819 }
816 820
817 821 /*
818 822 * This request is trying to get the upper bound on the amount of data we're
819 823 * willing transfer in one go. Note that this amount can be broken down into
820 824 * multiple SGL entries, this interface doesn't particularly care about that.
821 825 */
822 826 /* ARGSUSED */
823 827 static int
824 828 xhci_hcdi_bulk_transfer_size(usba_device_t *ud, size_t *sizep)
825 829 {
826 830 if (sizep != NULL)
827 831 *sizep = XHCI_MAX_TRANSFER;
828 832 return (USB_SUCCESS);
829 833 }
830 834
831 835 /*
832 836 * Perform a bulk transfer. This is a pretty straightforward action. We
833 837 * basically just allocate the appropriate transfer and try to schedule it,
834 838 * hoping there is enough space.
835 839 */
836 840 static int
837 841 xhci_hcdi_pipe_bulk_xfer(usba_pipe_handle_data_t *ph, usb_bulk_req_t *ubrp,
838 842 usb_flags_t usb_flags)
839 843 {
840 844 uint_t epid;
841 845 xhci_device_t *xd;
842 846 xhci_endpoint_t *xep;
843 847 xhci_transfer_t *xt;
844 848 boolean_t datain;
845 849
846 850 xhci_t *xhcip = xhci_hcdi_get_xhcip(ph);
847 851
848 852 mutex_enter(&xhcip->xhci_lock);
849 853 if (xhcip->xhci_state & XHCI_S_ERROR) {
850 854 mutex_exit(&xhcip->xhci_lock);
851 855 return (USB_HC_HARDWARE_ERROR);
852 856 }
853 857
854 858 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
855 859 mutex_exit(&xhcip->xhci_lock);
856 860 return (USB_NOT_SUPPORTED);
857 861 }
858 862
859 863 xd = usba_hcdi_get_device_private(ph->p_usba_device);
860 864 epid = xhci_endpoint_pipe_to_epid(ph);
861 865 if (xd->xd_endpoints[epid] == NULL) {
862 866 mutex_exit(&xhcip->xhci_lock);
863 867 xhci_error(xhcip, "asked to do control transfer on slot %d, "
864 868 "port %d, endpoint: %d, but no endpoint structure",
865 869 xd->xd_slot, xd->xd_port, epid);
866 870 return (USB_FAILURE);
867 871 }
868 872 xep = xd->xd_endpoints[epid];
869 873 mutex_exit(&xhcip->xhci_lock);
870 874
871 875 if ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) {
872 876 datain = B_TRUE;
873 877 } else {
874 878 datain = B_FALSE;
875 879 }
876 880
877 881 xt = xhci_transfer_alloc(xhcip, xep, ubrp->bulk_len, 0, usb_flags);
878 882 if (xt == NULL) {
879 883 return (USB_NO_RESOURCES);
880 884 }
881 885 xt->xt_usba_req = (usb_opaque_t)ubrp;
882 886 xt->xt_timeout = ubrp->bulk_timeout;
883 887 if (xt->xt_timeout == 0) {
884 888 xt->xt_timeout = HCDI_DEFAULT_TIMEOUT;
885 889 }
886 890
887 891 if (ubrp->bulk_len > 0 && datain == B_FALSE) {
888 892 xhci_transfer_copy(xt, ubrp->bulk_data->b_rptr, ubrp->bulk_len,
889 893 B_FALSE);
890 894 if (xhci_transfer_sync(xhcip, xt, DDI_DMA_SYNC_FORDEV) !=
891 895 DDI_FM_OK) {
892 896 xhci_transfer_free(xhcip, xt);
893 897 xhci_error(xhcip, "failed to synchronize bulk "
894 898 "transfer DMA memory on endpoint %u of "
895 899 "device on slot %d and port %d: resetting "
896 900 "device", xep->xep_num, xd->xd_slot,
897 901 xd->xd_port);
898 902 xhci_fm_runtime_reset(xhcip);
899 903 return (USB_HC_HARDWARE_ERROR);
900 904 }
901 905 }
902 906
903 907 xhci_transfer_trb_fill_data(xep, xt, 0, datain);
904 908 mutex_enter(&xhcip->xhci_lock);
905 909 if (xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE) != 0) {
906 910 xhci_transfer_free(xhcip, xt);
907 911 mutex_exit(&xhcip->xhci_lock);
908 912 return (USB_NO_RESOURCES);
909 913 }
910 914 mutex_exit(&xhcip->xhci_lock);
911 915
912 916 return (USB_SUCCESS);
913 917 }
914 918
915 919 static void
916 920 xhci_hcdi_isoc_transfer_fill(xhci_device_t *xd, xhci_endpoint_t *xep,
917 921 xhci_transfer_t *xt, usb_isoc_req_t *usrp)
918 922 {
919 923 int i;
920 924 uintptr_t buf;
921 925
922 926 buf = xt->xt_buffer.xdb_cookies[0].dmac_laddress;
|
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
923 927 for (i = 0; i < usrp->isoc_pkts_count; i++) {
924 928 int flags;
925 929 uint_t tbc, tlbpc;
926 930
927 931 ushort_t len = usrp->isoc_pkt_descr[i].isoc_pkt_length;
928 932 xhci_trb_t *trb = &xt->xt_trbs[i];
929 933
930 934 trb->trb_addr = LE_64(buf);
931 935
932 936 /*
933 - * Beacuse we know that a single frame can have all of its data
934 - * in a single instance, we know that we don't neeed to do
937 + * Because we know that a single frame can have all of its data
938 + * in a single instance, we know that we don't need to do
935 939 * anything special here.
936 940 */
937 941 trb->trb_status = LE_32(XHCI_TRB_LEN(len) | XHCI_TRB_TDREM(0) |
938 942 XHCI_TRB_INTR(0));
939 943
940 944 /*
941 945 * Always enable SIA to start the frame ASAP. We also always
942 946 * enable an interrupt on a short packet. If this is the last
943 - * trb, then we will set IOC.
947 + * trb, then we will set IOC. Each TRB created here is really
948 + * its own TD. However, we only set an interrupt on the last
949 + * entry to better deal with scheduling.
944 950 */
945 951 flags = XHCI_TRB_SIA | XHCI_TRB_ISP | XHCI_TRB_SET_FRAME(0);
946 952 flags |= XHCI_TRB_TYPE_ISOCH;
947 953
948 954 if (i + 1 == usrp->isoc_pkts_count)
949 955 flags |= XHCI_TRB_IOC;
950 956
951 957 /*
952 958 * Now we need to calculate the TBC and the TLBPC.
953 959 */
954 960 xhci_transfer_calculate_isoc(xd, xep, len, &tbc, &tlbpc);
955 961 flags |= XHCI_TRB_SET_TBC(tbc);
956 962 flags |= XHCI_TRB_SET_TLBPC(tlbpc);
957 963
958 964 trb->trb_flags = LE_32(flags);
959 965 buf += len;
960 966
961 967 /*
962 968 * Go through and copy the required data to our local copy of
963 969 * the isoc descriptor. By default, we assume that all data will
964 970 * be copied and the status set to OK. This mirrors the fact
965 971 * that we won't get a notification unless there's been an
966 972 * error or short packet transfer.
967 973 */
968 974 xt->xt_isoc[i].isoc_pkt_length = len;
969 975 xt->xt_isoc[i].isoc_pkt_actual_length = len;
970 976 xt->xt_isoc[i].isoc_pkt_status = USB_CR_OK;
971 977 }
972 978 }
973 979
974 980 /*
975 981 * Initialize periodic IN requests (both interrupt and isochronous)
976 982 */
977 983 static int
978 984 xhci_hcdi_periodic_init(xhci_t *xhcip, usba_pipe_handle_data_t *ph,
979 985 usb_opaque_t usb_req, size_t len, int usb_flags)
980 986 {
981 987 int i, ret;
982 988 uint_t epid;
983 989 xhci_device_t *xd;
984 990 xhci_endpoint_t *xep;
985 991 xhci_pipe_t *xp;
986 992 xhci_periodic_pipe_t *xpp;
987 993
988 994 mutex_enter(&xhcip->xhci_lock);
989 995 if (xhcip->xhci_state & XHCI_S_ERROR) {
990 996 mutex_exit(&xhcip->xhci_lock);
991 997 return (USB_HC_HARDWARE_ERROR);
992 998 }
993 999
994 1000 xd = usba_hcdi_get_device_private(ph->p_usba_device);
995 1001 epid = xhci_endpoint_pipe_to_epid(ph);
996 1002 if (xd->xd_endpoints[epid] == NULL) {
997 1003 xhci_error(xhcip, "asked to do periodic transfer on slot %d, "
998 1004 "port %d, endpoint: %d, but no endpoint structure",
999 1005 xd->xd_slot, xd->xd_port, epid);
1000 1006 mutex_exit(&xhcip->xhci_lock);
1001 1007 return (USB_FAILURE);
1002 1008 }
1003 1009 xep = xd->xd_endpoints[epid];
1004 1010 xp = (xhci_pipe_t *)ph->p_hcd_private;
1005 1011 if (xp == NULL) {
1006 1012 xhci_error(xhcip, "asked to do periodic transfer on slot %d, "
1007 1013 "port %d, endpoint: %d, but no pipe structure",
1008 1014 xd->xd_slot, xd->xd_port, epid);
1009 1015 mutex_exit(&xhcip->xhci_lock);
1010 1016 return (USB_FAILURE);
1011 1017 }
1012 1018 xpp = &xp->xp_periodic;
1013 1019
1014 1020 /*
1015 1021 * Only allow a single polling request at any given time.
1016 1022 */
1017 1023 if (xpp->xpp_usb_req != NULL) {
1018 1024 mutex_exit(&xhcip->xhci_lock);
1019 1025 return (USB_BUSY);
1020 1026 }
1021 1027
1022 1028 /*
1023 1029 * We keep allocations around in case we restart polling, which most
1024 1030 * devices do (not really caring about a lost event). However, we don't
1025 1031 * support a driver changing that size on us, which it probably won't.
1026 1032 * If we stumble across driver that does, then this will need to become
1027 1033 * a lot more complicated.
1028 1034 */
1029 1035 if (xpp->xpp_tsize > 0 && xpp->xpp_tsize < len) {
1030 1036 mutex_exit(&xhcip->xhci_lock);
1031 1037 return (USB_INVALID_REQUEST);
1032 1038 }
1033 1039
1034 1040 if (xpp->xpp_tsize == 0) {
1035 1041 int ntrbs;
1036 1042 int ntransfers;
1037 1043
1038 1044 /*
1039 1045 * What we allocate varies based on whether or not this is an
1040 1046 * isochronous or interrupt IN periodic.
1041 1047 */
1042 1048 if (xep->xep_type == USB_EP_ATTR_INTR) {
1043 1049 ntrbs = 0;
1044 1050 ntransfers = XHCI_INTR_IN_NTRANSFERS;
1045 1051 } else {
1046 1052 usb_isoc_req_t *usrp;
1047 1053 ASSERT(xep->xep_type == USB_EP_ATTR_ISOCH);
1048 1054
1049 1055 usrp = (usb_isoc_req_t *)usb_req;
1050 1056 ntrbs = usrp->isoc_pkts_count;
1051 1057 ntransfers = XHCI_ISOC_IN_NTRANSFERS;
1052 1058 }
1053 1059
1054 1060 xpp->xpp_tsize = len;
1055 1061 xpp->xpp_ntransfers = ntransfers;
1056 1062
1057 1063 for (i = 0; i < xpp->xpp_ntransfers; i++) {
1058 1064 xhci_transfer_t *xt = xhci_transfer_alloc(xhcip, xep,
1059 1065 len, ntrbs, usb_flags);
1060 1066 if (xt == NULL) {
1061 1067 xhci_hcdi_periodic_free(xhcip, xp);
1062 1068 mutex_exit(&xhcip->xhci_lock);
1063 1069 return (USB_NO_RESOURCES);
1064 1070 }
1065 1071
1066 1072 if (xep->xep_type == USB_EP_ATTR_INTR) {
1067 1073 xhci_transfer_trb_fill_data(xep, xt, 0, B_TRUE);
1068 1074 } else {
1069 1075 usb_isoc_req_t *usrp;
1070 1076 usrp = (usb_isoc_req_t *)usb_req;
1071 1077 xhci_hcdi_isoc_transfer_fill(xd, xep, xt, usrp);
1072 1078 xt->xt_data_tohost = B_TRUE;
1073 1079 }
1074 1080 xpp->xpp_transfers[i] = xt;
1075 1081 }
1076 1082 }
1077 1083
1078 1084 /*
1079 1085 * Mark the endpoint as periodic so we don't have timeouts at play.
1080 1086 */
1081 1087 xep->xep_state |= XHCI_ENDPOINT_PERIODIC;
1082 1088
1083 1089 /*
1084 1090 * Now that we've allocated everything, go ahead and schedule them and
1085 1091 * kick off the ring.
1086 1092 */
1087 1093 for (i = 0; i < xpp->xpp_ntransfers; i++) {
1088 1094 int ret;
1089 1095 ret = xhci_endpoint_schedule(xhcip, xd, xep,
1090 1096 xpp->xpp_transfers[i], B_FALSE);
1091 1097 if (ret != 0) {
1092 1098 (void) xhci_ring_reset(xhcip, &xep->xep_ring);
1093 1099 xep->xep_state &= ~XHCI_ENDPOINT_PERIODIC;
1094 1100 mutex_exit(&xhcip->xhci_lock);
1095 1101 return (ret);
1096 1102 }
1097 1103 }
1098 1104
1099 1105 /*
1100 1106 * Don't worry about freeing memory, it'll be done when the endpoint
1101 1107 * closes and the whole system is reset.
1102 1108 */
1103 1109 xpp->xpp_usb_req = usb_req;
1104 1110 xpp->xpp_poll_state = XHCI_PERIODIC_POLL_ACTIVE;
1105 1111
1106 1112 ret = xhci_endpoint_ring(xhcip, xd, xep);
1107 1113 mutex_exit(&xhcip->xhci_lock);
1108 1114 return (ret);
1109 1115 }
1110 1116
1111 1117 static int
1112 1118 xhci_hcdi_intr_oneshot(xhci_t *xhcip, usba_pipe_handle_data_t *ph,
1113 1119 usb_intr_req_t *uirp, usb_flags_t usb_flags)
1114 1120 {
1115 1121 uint_t epid;
1116 1122 xhci_device_t *xd;
1117 1123 xhci_endpoint_t *xep;
1118 1124 xhci_transfer_t *xt;
1119 1125 boolean_t datain;
1120 1126 mblk_t *mp = NULL;
1121 1127
1122 1128 mutex_enter(&xhcip->xhci_lock);
1123 1129 if (xhcip->xhci_state & XHCI_S_ERROR) {
1124 1130 mutex_exit(&xhcip->xhci_lock);
1125 1131 return (USB_HC_HARDWARE_ERROR);
1126 1132 }
1127 1133
1128 1134 xd = usba_hcdi_get_device_private(ph->p_usba_device);
1129 1135 epid = xhci_endpoint_pipe_to_epid(ph);
1130 1136 if (xd->xd_endpoints[epid] == NULL) {
1131 1137 xhci_error(xhcip, "asked to do interrupt transfer on slot %d, "
1132 1138 "port %d, endpoint: %d, but no endpoint structure",
1133 1139 xd->xd_slot, xd->xd_port, epid);
1134 1140 mutex_exit(&xhcip->xhci_lock);
1135 1141 return (USB_FAILURE);
1136 1142 }
1137 1143 xep = xd->xd_endpoints[epid];
1138 1144
1139 1145 mutex_exit(&xhcip->xhci_lock);
1140 1146
1141 1147 if ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) {
1142 1148 datain = B_TRUE;
1143 1149 } else {
1144 1150 datain = B_FALSE;
1145 1151 }
1146 1152
1147 1153 xt = xhci_transfer_alloc(xhcip, xep, uirp->intr_len, 0, usb_flags);
1148 1154 if (xt == NULL) {
1149 1155 return (USB_NO_RESOURCES);
1150 1156 }
1151 1157
1152 1158 xt->xt_usba_req = (usb_opaque_t)uirp;
1153 1159 xt->xt_timeout = uirp->intr_timeout;
1154 1160 if (xt->xt_timeout == 0) {
1155 1161 xt->xt_timeout = HCDI_DEFAULT_TIMEOUT;
1156 1162 }
1157 1163
1158 1164 /*
1159 1165 * Unlike other request types, USB Interrupt-IN requests aren't required
1160 1166 * to have allocated the message block for data. If they haven't, we
1161 1167 * take care of that now.
1162 1168 */
1163 1169 if (uirp->intr_len > 0 && datain == B_TRUE && uirp->intr_data == NULL) {
1164 1170 if (usb_flags & USB_FLAGS_SLEEP) {
1165 1171 mp = allocb_wait(uirp->intr_len, BPRI_LO, STR_NOSIG,
1166 1172 NULL);
1167 1173 } else {
1168 1174 mp = allocb(uirp->intr_len, 0);
1169 1175 }
1170 1176 if (mp == NULL) {
1171 1177 xhci_transfer_free(xhcip, xt);
1172 1178 mutex_exit(&xhcip->xhci_lock);
1173 1179 return (USB_NO_RESOURCES);
1174 1180 }
1175 1181 uirp->intr_data = mp;
1176 1182 }
1177 1183
1178 1184 if (uirp->intr_len > 0 && datain == B_FALSE) {
1179 1185 xhci_transfer_copy(xt, uirp->intr_data->b_rptr, uirp->intr_len,
1180 1186 B_FALSE);
1181 1187 if (xhci_transfer_sync(xhcip, xt, DDI_DMA_SYNC_FORDEV) !=
1182 1188 DDI_FM_OK) {
1183 1189 xhci_transfer_free(xhcip, xt);
1184 1190 xhci_error(xhcip, "failed to synchronize interrupt "
1185 1191 "transfer DMA memory on endpoint %u of "
1186 1192 "device on slot %d and port %d: resetting "
1187 1193 "device", xep->xep_num, xd->xd_slot,
1188 1194 xd->xd_port);
1189 1195 xhci_fm_runtime_reset(xhcip);
1190 1196 return (USB_HC_HARDWARE_ERROR);
1191 1197 }
1192 1198 }
1193 1199
1194 1200 xhci_transfer_trb_fill_data(xep, xt, 0, datain);
1195 1201 mutex_enter(&xhcip->xhci_lock);
1196 1202 if (xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE) != 0) {
1197 1203 if (mp != NULL) {
1198 1204 uirp->intr_data = NULL;
1199 1205 freemsg(mp);
1200 1206 }
1201 1207 xhci_transfer_free(xhcip, xt);
1202 1208 mutex_exit(&xhcip->xhci_lock);
1203 1209 return (USB_NO_RESOURCES);
1204 1210 }
1205 1211 mutex_exit(&xhcip->xhci_lock);
1206 1212
1207 1213 return (USB_SUCCESS);
1208 1214 }
1209 1215
1210 1216 /*
1211 1217 * We've been asked to perform an interrupt transfer. When this is an interrupt
1212 1218 * IN endpoint, that means that the hcd is being asked to start polling on the
1213 1219 * endpoint. When the endpoint is the root hub, it effectively becomes synthetic
1214 1220 * polling.
1215 1221 *
1216 1222 * When we have an interrupt out endpoint, then this is just a single simple
1217 1223 * interrupt request that we send out and there isn't much special to do beyond
1218 1224 * the normal activity.
1219 1225 */
1220 1226 static int
1221 1227 xhci_hcdi_pipe_intr_xfer(usba_pipe_handle_data_t *ph, usb_intr_req_t *uirp,
1222 1228 usb_flags_t usb_flags)
1223 1229 {
1224 1230 int ret;
1225 1231 xhci_t *xhcip = xhci_hcdi_get_xhcip(ph);
1226 1232
1227 1233 if ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) {
1228 1234 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
1229 1235 ret = xhci_root_hub_intr_root_enable(xhcip, ph, uirp);
1230 1236 } else if (uirp->intr_attributes & USB_ATTRS_ONE_XFER) {
1231 1237 ret = xhci_hcdi_intr_oneshot(xhcip, ph, uirp,
1232 1238 usb_flags);
1233 1239 } else {
1234 1240 ret = xhci_hcdi_periodic_init(xhcip, ph,
1235 1241 (usb_opaque_t)uirp, uirp->intr_len, usb_flags);
1236 1242 }
1237 1243 } else {
1238 1244 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
1239 1245 return (USB_NOT_SUPPORTED);
1240 1246 }
1241 1247 ret = xhci_hcdi_intr_oneshot(xhcip, ph, uirp, usb_flags);
1242 1248 }
1243 1249
1244 1250 return (ret);
1245 1251 }
1246 1252
1247 1253 /* ARGSUSED */
1248 1254 static int
1249 1255 xhci_hcdi_pipe_stop_intr_polling(usba_pipe_handle_data_t *ph,
1250 1256 usb_flags_t usb_flags)
1251 1257 {
1252 1258 return (xhci_hcdi_pipe_poll_fini(ph, B_FALSE));
1253 1259 }
1254 1260
1255 1261 static int
1256 1262 xhci_hcdi_isoc_periodic(xhci_t *xhcip, usba_pipe_handle_data_t *ph,
1257 1263 usb_isoc_req_t *usrp, usb_flags_t usb_flags)
1258 1264 {
1259 1265 int i;
1260 1266 size_t count;
1261 1267
1262 1268 count = 0;
1263 1269 for (i = 0; i < usrp->isoc_pkts_count; i++) {
1264 1270 count += usrp->isoc_pkt_descr[i].isoc_pkt_length;
1265 1271 }
1266 1272
1267 1273 return (xhci_hcdi_periodic_init(xhcip, ph, (usb_opaque_t)usrp, count,
1268 1274 usb_flags));
1269 1275 }
1270 1276
1271 1277 /*
1272 1278 * This is used to create an isochronous request to send data out to the device.
1273 1279 * This is a single one shot request, it is not something that we'll have to
1274 1280 * repeat over and over.
1275 1281 */
1276 1282 static int
1277 1283 xhci_hcdi_isoc_oneshot(xhci_t *xhcip, usba_pipe_handle_data_t *ph,
1278 1284 usb_isoc_req_t *usrp, usb_flags_t usb_flags)
1279 1285 {
1280 1286 int i, ret;
1281 1287 uint_t epid;
1282 1288 size_t count, mblen;
1283 1289 xhci_device_t *xd;
1284 1290 xhci_endpoint_t *xep;
1285 1291 xhci_transfer_t *xt;
1286 1292
1287 1293 count = 0;
1288 1294 for (i = 0; i < usrp->isoc_pkts_count; i++) {
1289 1295 count += usrp->isoc_pkt_descr[i].isoc_pkt_length;
1290 1296 }
1291 1297 mblen = MBLKL(usrp->isoc_data);
1292 1298
1293 1299 if (count != mblen) {
1294 1300 return (USB_INVALID_ARGS);
1295 1301 }
1296 1302
1297 1303 mutex_enter(&xhcip->xhci_lock);
1298 1304 if (xhcip->xhci_state & XHCI_S_ERROR) {
1299 1305 mutex_exit(&xhcip->xhci_lock);
1300 1306 return (USB_HC_HARDWARE_ERROR);
1301 1307 }
1302 1308
1303 1309 xd = usba_hcdi_get_device_private(ph->p_usba_device);
1304 1310 epid = xhci_endpoint_pipe_to_epid(ph);
1305 1311 if (xd->xd_endpoints[epid] == NULL) {
1306 1312 xhci_error(xhcip, "asked to do isochronous transfer on slot "
1307 1313 "%d, port %d, endpoint: %d, but no endpoint structure",
1308 1314 xd->xd_slot, xd->xd_port, epid);
1309 1315 mutex_exit(&xhcip->xhci_lock);
1310 1316 return (USB_FAILURE);
1311 1317 }
1312 1318 xep = xd->xd_endpoints[epid];
1313 1319 mutex_exit(&xhcip->xhci_lock);
1314 1320
1315 1321 xt = xhci_transfer_alloc(xhcip, xep, mblen, usrp->isoc_pkts_count,
1316 1322 usb_flags);
1317 1323 if (xt == NULL) {
1318 1324 return (USB_NO_RESOURCES);
1319 1325 }
1320 1326 xt->xt_usba_req = (usb_opaque_t)usrp;
1321 1327
1322 1328 /*
1323 1329 * USBA doesn't provide any real way for a timeout to be defined for an
1324 1330 * isochronous event. However, since we technically aren't a periodic
1325 1331 * endpoint, go ahead and always set the default timeout. It's better
1326 1332 * than nothing.
1327 1333 */
1328 1334 xt->xt_timeout = HCDI_DEFAULT_TIMEOUT;
1329 1335
1330 1336 xhci_transfer_copy(xt, usrp->isoc_data->b_rptr, mblen, B_FALSE);
1331 1337 if (xhci_transfer_sync(xhcip, xt, DDI_DMA_SYNC_FORDEV) != DDI_FM_OK) {
1332 1338 xhci_transfer_free(xhcip, xt);
1333 1339 xhci_error(xhcip, "failed to synchronize isochronous "
1334 1340 "transfer DMA memory on endpoint %u of "
1335 1341 "device on slot %d and port %d: resetting "
1336 1342 "device", xep->xep_num, xd->xd_slot,
1337 1343 xd->xd_port);
1338 1344 xhci_fm_runtime_reset(xhcip);
1339 1345 return (USB_HC_HARDWARE_ERROR);
1340 1346 }
1341 1347
1342 1348 /*
1343 1349 * Fill in the ISOC data. Note, that we always use ASAP scheduling and
1344 1350 * we don't support specifying the frame at this time, for better or
1345 1351 * worse.
1346 1352 */
1347 1353 xhci_hcdi_isoc_transfer_fill(xd, xep, xt, usrp);
1348 1354
1349 1355 mutex_enter(&xhcip->xhci_lock);
1350 1356 ret = xhci_endpoint_schedule(xhcip, xd, xep, xt, B_TRUE);
1351 1357 mutex_exit(&xhcip->xhci_lock);
1352 1358
1353 1359 return (ret);
1354 1360 }
1355 1361
1356 1362 static int
1357 1363 xhci_hcdi_pipe_isoc_xfer(usba_pipe_handle_data_t *ph, usb_isoc_req_t *usrp,
1358 1364 usb_flags_t usb_flags)
1359 1365 {
1360 1366 int ret;
1361 1367 xhci_t *xhcip;
1362 1368
1363 1369 xhcip = xhci_hcdi_get_xhcip(ph);
1364 1370
1365 1371 /*
1366 1372 * We don't support isochronous transactions on the root hub at all.
1367 1373 * Always fail them if for some reason we end up here.
1368 1374 */
1369 1375 if (ph->p_usba_device->usb_addr == ROOT_HUB_ADDR) {
1370 1376 return (USB_NOT_SUPPORTED);
1371 1377 }
1372 1378
1373 1379 /*
1374 1380 * We do not support being asked to set the frame ID at this time. We
1375 1381 * require that everything specify the attribute
1376 1382 * USB_ATTRS_ISOC_XFER_ASAP.
1377 1383 */
1378 1384 if (!(usrp->isoc_attributes & USB_ATTRS_ISOC_XFER_ASAP)) {
1379 1385 return (USB_NOT_SUPPORTED);
1380 1386 }
1381 1387
1382 1388 if ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) {
1383 1389 /*
1384 1390 * Note, there is no such thing as a non-periodic isochronous
1385 1391 * incoming transfer.
1386 1392 */
1387 1393 ret = xhci_hcdi_isoc_periodic(xhcip, ph, usrp, usb_flags);
1388 1394 } else {
1389 1395 ret = xhci_hcdi_isoc_oneshot(xhcip, ph, usrp, usb_flags);
1390 1396 }
1391 1397
1392 1398 return (ret);
1393 1399 }
1394 1400
1395 1401 /* ARGSUSED */
1396 1402 static int
1397 1403 xhci_hcdi_pipe_stop_isoc_polling(usba_pipe_handle_data_t *ph,
1398 1404 usb_flags_t usb_flags)
1399 1405 {
1400 1406 return (xhci_hcdi_pipe_poll_fini(ph, B_FALSE));
1401 1407 }
1402 1408
1403 1409 /*
1404 1410 * This is asking us for the current frame number. The USBA expects this to
1405 1411 * actually be a bit of a fiction, as it tries to maintain a frame number well
1406 1412 * beyond what the hardware actually contains in its registers. Hardware
1407 1413 * basically has a 14-bit counter, whereas we need to have a constant amount of
1408 1414 * milliseconds.
1409 1415 *
1410 1416 * Today, no client drivers actually use this API and everyone specifies the
1411 1417 * attribute to say that we should schedule things ASAP. So until we have some
1412 1418 * real device that want this functionality, we're going to fail.
1413 1419 */
1414 1420 /* ARGSUSED */
1415 1421 static int
1416 1422 xhci_hcdi_get_current_frame_number(usba_device_t *usba_device,
1417 1423 usb_frame_number_t *frame_number)
1418 1424 {
1419 1425 return (USB_FAILURE);
1420 1426 }
1421 1427
1422 1428 /*
1423 1429 * See the comments around the XHCI_ISOC_MAX_TRB macro for more information.
1424 1430 */
1425 1431 /* ARGSUSED */
1426 1432 static int
1427 1433 xhci_hcdi_get_max_isoc_pkts(usba_device_t *usba_device,
1428 1434 uint_t *max_isoc_pkts_per_request)
1429 1435 {
1430 1436 *max_isoc_pkts_per_request = XHCI_ISOC_MAX_TRB;
1431 1437 return (USB_SUCCESS);
1432 1438 }
1433 1439
1434 1440 /*
1435 1441 * The next series of routines is used for both the OBP console and general USB
1436 1442 * console polled I/O. In general, we opt not to support any of that at this
1437 1443 * time in xHCI. As we have the need of that, we can start plumbing that
1438 1444 * through.
1439 1445 */
1440 1446 /* ARGSUSED */
1441 1447 static int
1442 1448 xhci_hcdi_console_input_init(usba_pipe_handle_data_t *pipe_handle,
1443 1449 uchar_t **obp_buf, usb_console_info_impl_t *console_input_info)
1444 1450 {
1445 1451 return (USB_NOT_SUPPORTED);
1446 1452 }
1447 1453
1448 1454 /* ARGSUSED */
1449 1455 static int
1450 1456 xhci_hcdi_console_input_fini(usb_console_info_impl_t *console_input_info)
1451 1457 {
1452 1458 return (USB_NOT_SUPPORTED);
1453 1459 }
1454 1460
1455 1461 /* ARGSUSED */
1456 1462 static int
1457 1463 xhci_hcdi_console_input_enter(usb_console_info_impl_t *console_input_info)
1458 1464 {
1459 1465 return (USB_NOT_SUPPORTED);
1460 1466 }
1461 1467
1462 1468 /* ARGSUSED */
1463 1469 static int
1464 1470 xhci_hcdi_console_read(usb_console_info_impl_t *console_input_info,
1465 1471 uint_t *num_characters)
1466 1472 {
1467 1473 return (USB_NOT_SUPPORTED);
1468 1474 }
1469 1475
1470 1476 /* ARGSUSED */
1471 1477 static int
1472 1478 xhci_hcdi_console_input_exit(usb_console_info_impl_t *console_input_info)
1473 1479 {
1474 1480 return (USB_NOT_SUPPORTED);
1475 1481 }
1476 1482
1477 1483 /* ARGSUSED */
1478 1484 static int
1479 1485 xhci_hcdi_console_output_init(usba_pipe_handle_data_t *pipe_handle,
1480 1486 usb_console_info_impl_t *console_output_info)
1481 1487 {
1482 1488 return (USB_NOT_SUPPORTED);
1483 1489 }
1484 1490
1485 1491 /* ARGSUSED */
1486 1492 static int
1487 1493 xhci_hcdi_console_output_fini(usb_console_info_impl_t *console_output_info)
1488 1494 {
1489 1495 return (USB_NOT_SUPPORTED);
1490 1496 }
1491 1497
1492 1498 /* ARGSUSED */
1493 1499 static int
1494 1500 xhci_hcdi_console_output_enter(usb_console_info_impl_t *console_output_info)
1495 1501 {
1496 1502 return (USB_NOT_SUPPORTED);
1497 1503 }
1498 1504
1499 1505 /* ARGSUSED */
1500 1506 static int
1501 1507 xhci_hcdi_console_write(usb_console_info_impl_t *console_output_info,
1502 1508 uchar_t *buf, uint_t num_characters, uint_t *num_characters_written)
1503 1509 {
1504 1510 return (USB_NOT_SUPPORTED);
1505 1511 }
1506 1512
1507 1513 /* ARGSUSED */
1508 1514 static int
1509 1515 xhci_hcdi_console_output_exit(usb_console_info_impl_t *console_output_info)
1510 1516 {
1511 1517 return (USB_NOT_SUPPORTED);
1512 1518 }
1513 1519
1514 1520 /*
1515 1521 * VERSION 2 ops and helpers
1516 1522 */
1517 1523
1518 1524 static void
1519 1525 xhci_hcdi_device_free(xhci_device_t *xd)
1520 1526 {
1521 1527 xhci_dma_free(&xd->xd_ictx);
1522 1528 xhci_dma_free(&xd->xd_octx);
1523 1529 mutex_destroy(&xd->xd_imtx);
1524 1530 kmem_free(xd, sizeof (xhci_device_t));
1525 1531 }
1526 1532
1527 1533 /*
1528 1534 * Calculate the device's route string. In USB 3.0 the route string is a 20-bit
1529 1535 * number. Each four bits represent a port number attached to a deeper hub.
1530 1536 * Particularly it represents the port on that current hub that you need to go
1531 1537 * down to reach the next device. Bits 0-3 represent the first *external* hub.
1532 1538 * So a device connected to a root hub has a route string of zero. Imagine the
1533 1539 * following set of devices:
1534 1540 *
1535 1541 * . port 2 . port 5
1536 1542 * . .
1537 1543 * +----------+ . +--------+ . +-------+
1538 1544 * | root hub |-*->| hub 1 |-*->| hub 2 |
1539 1545 * +----------+ +--------+ +-------+
1540 1546 * * . port 12 * . port 8 * . port 1
1541 1547 * v v v
1542 1548 * +-------+ +-------+ +-------+
1543 1549 * | dev a | | dev b | | dev c |
1544 1550 * +-------+ +-------+ +-------+
1545 1551 *
1546 1552 * So, based on the above diagram, device a should have a route string of 0,
1547 1553 * because it's directly connected to the root port. Device b would simply have
1548 1554 * a route string of 8. This is because it travels through one non-root hub, hub
1549 1555 * 1, and it does so on port 8. The root ports basically don't matter. Device c
1550 1556 * would then have a route string of 0x15, as it's first traversing through hub
1551 1557 * 1 on port 2 and then hub 2 on port 5.
1552 1558 *
1553 1559 * Finally, it's worth mentioning that because it's a four bit field, if for
1554 1560 * some reason a device has more than 15 ports, we just treat the value as 15.
1555 1561 *
1556 1562 * Note, as part of this, we also grab what port on the root hub this whole
1557 1563 * chain is on, as we're required to store that information in the slot context.
1558 1564 */
1559 1565 static void
1560 1566 xhci_hcdi_device_route(usba_device_t *ud, uint32_t *routep, uint32_t *root_port)
1561 1567 {
1562 1568 uint32_t route = 0;
1563 1569 usba_device_t *hub = ud->usb_parent_hub;
1564 1570 usba_device_t *port_dev = ud;
1565 1571
1566 1572 ASSERT(hub != NULL);
1567 1573
1568 1574 /*
1569 1575 * Iterate over every hub, updating the route as we go. When we
1570 1576 * encounter a hub without a parent, then we're at the root hub. At
1571 1577 * which point, the port we want is on port_dev (the child of hub).
1572 1578 */
1573 1579 while (hub->usb_parent_hub != NULL) {
1574 1580 uint32_t p;
1575 1581
1576 1582 p = port_dev->usb_port;
1577 1583 if (p > 15)
1578 1584 p = 15;
1579 1585 route <<= 4;
1580 1586 route |= p & 0xf;
1581 1587 port_dev = hub;
1582 1588 hub = hub->usb_parent_hub;
1583 1589 }
1584 1590
1585 1591 ASSERT(port_dev->usb_parent_hub == hub);
1586 1592 *root_port = port_dev->usb_port;
1587 1593 *routep = XHCI_ROUTE_MASK(route);
1588 1594 }
1589 1595
1590 1596 /*
1591 1597 * If a low or full speed device is behind a high-speed device that is not a
1592 1598 * root hub, then we must include the port and slot of that device. USBA already
1593 1599 * stores this device in the usb_hs_hub_usba_dev member.
1594 1600 */
1595 1601 static uint32_t
1596 1602 xhci_hcdi_device_tt(usba_device_t *ud)
1597 1603 {
1598 1604 uint32_t ret;
1599 1605 xhci_device_t *xd;
1600 1606
1601 1607 if (ud->usb_port_status >= USBA_HIGH_SPEED_DEV)
1602 1608 return (0);
1603 1609
1604 1610 if (ud->usb_hs_hub_usba_dev == NULL)
1605 1611 return (0);
1606 1612
1607 1613 ASSERT(ud->usb_hs_hub_usba_dev != NULL);
1608 1614 ASSERT(ud->usb_hs_hub_usba_dev->usb_parent_hub != NULL);
1609 1615 xd = usba_hcdi_get_device_private(ud->usb_hs_hub_usba_dev);
1610 1616 ASSERT(xd != NULL);
1611 1617
1612 1618 ret = XHCI_SCTX_SET_TT_HUB_SID(xd->xd_slot);
1613 1619 ret |= XHCI_SCTX_SET_TT_PORT_NUM(ud->usb_hs_hub_usba_dev->usb_port);
1614 1620
1615 1621 return (ret);
1616 1622 }
1617 1623
1618 1624 /*
1619 1625 * Initialize a new device. This allocates a device slot from the controller,
1620 1626 * which tranfers it to our control.
1621 1627 */
1622 1628 static int
1623 1629 xhci_hcdi_device_init(usba_device_t *ud, usb_port_t port, void **hcdpp)
1624 1630 {
1625 1631 int ret, i;
1626 1632 xhci_device_t *xd;
1627 1633 ddi_device_acc_attr_t acc;
1628 1634 ddi_dma_attr_t attr;
1629 1635 xhci_t *xhcip = xhci_hcdi_get_xhcip_from_dev(ud);
1630 1636 size_t isize, osize, incr;
1631 1637 uint32_t route, rp, info, info2, tt;
1632 1638
1633 1639 xd = kmem_zalloc(sizeof (xhci_device_t), KM_SLEEP);
1634 1640 xd->xd_port = port;
1635 1641 xd->xd_usbdev = ud;
1636 1642 mutex_init(&xd->xd_imtx, NULL, MUTEX_DRIVER,
1637 1643 (void *)(uintptr_t)xhcip->xhci_intr_pri);
1638 1644
1639 1645 /*
1640 1646 * The size of the context structures is based upon the presence of the
1641 1647 * context flag which determines whether we have a 32-byte or 64-byte
1642 1648 * context. Note that the input context always has to account for the
1643 1649 * entire size of the xhci_input_contex_t, which is 32-bytes by default.
1644 1650 */
1645 1651 if (xhcip->xhci_caps.xcap_flags & XCAP_CSZ) {
1646 1652 incr = 64;
1647 1653 osize = XHCI_DEVICE_CONTEXT_64;
1648 1654 isize = XHCI_DEVICE_CONTEXT_64 + incr;
1649 1655 } else {
1650 1656 incr = 32;
1651 1657 osize = XHCI_DEVICE_CONTEXT_32;
1652 1658 isize = XHCI_DEVICE_CONTEXT_32 + incr;
1653 1659 }
1654 1660
1655 1661 xhci_dma_acc_attr(xhcip, &acc);
1656 1662 xhci_dma_dma_attr(xhcip, &attr);
1657 1663 if (xhci_dma_alloc(xhcip, &xd->xd_ictx, &attr, &acc, B_TRUE,
1658 1664 isize, B_FALSE) == B_FALSE) {
1659 1665 xhci_hcdi_device_free(xd);
1660 1666 return (USB_NO_RESOURCES);
1661 1667 }
1662 1668
1663 1669 xd->xd_input = (xhci_input_context_t *)xd->xd_ictx.xdb_va;
1664 1670 xd->xd_slotin = (xhci_slot_context_t *)(xd->xd_ictx.xdb_va + incr);
1665 1671 for (i = 0; i < XHCI_NUM_ENDPOINTS; i++) {
1666 1672 xd->xd_endin[i] =
1667 1673 (xhci_endpoint_context_t *)(xd->xd_ictx.xdb_va +
1668 1674 (i + 2) * incr);
1669 1675 }
1670 1676
1671 1677 if (xhci_dma_alloc(xhcip, &xd->xd_octx, &attr, &acc, B_TRUE,
1672 1678 osize, B_FALSE) == B_FALSE) {
1673 1679 xhci_hcdi_device_free(xd);
1674 1680 return (USB_NO_RESOURCES);
1675 1681 }
1676 1682 xd->xd_slotout = (xhci_slot_context_t *)xd->xd_octx.xdb_va;
1677 1683 for (i = 0; i < XHCI_NUM_ENDPOINTS; i++) {
1678 1684 xd->xd_endout[i] =
1679 1685 (xhci_endpoint_context_t *)(xd->xd_octx.xdb_va +
1680 1686 (i + 1) * incr);
1681 1687 }
1682 1688
1683 1689 ret = xhci_command_enable_slot(xhcip, &xd->xd_slot);
1684 1690 if (ret != USB_SUCCESS) {
1685 1691 xhci_hcdi_device_free(xd);
1686 1692 return (ret);
1687 1693 }
1688 1694
1689 1695 /*
1690 1696 * These are the default slot context and the endpoint zero context that
1691 1697 * we're enabling. See 4.3.3.
1692 1698 */
1693 1699 xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0) |
1694 1700 XHCI_INCTX_MASK_DCI(1));
1695 1701
1696 1702 /*
1697 1703 * Note, we never need to set the MTT bit as illumos never enables the
1698 1704 * alternate MTT interface.
1699 1705 */
1700 1706 xhci_hcdi_device_route(ud, &route, &rp);
1701 1707 info = XHCI_SCTX_SET_ROUTE(route) | XHCI_SCTX_SET_DCI(1);
1702 1708 switch (ud->usb_port_status) {
1703 1709 case USBA_LOW_SPEED_DEV:
1704 1710 info |= XHCI_SCTX_SET_SPEED(XHCI_SPEED_LOW);
1705 1711 break;
1706 1712 case USBA_HIGH_SPEED_DEV:
1707 1713 info |= XHCI_SCTX_SET_SPEED(XHCI_SPEED_HIGH);
1708 1714 break;
1709 1715 case USBA_FULL_SPEED_DEV:
1710 1716 info |= XHCI_SCTX_SET_SPEED(XHCI_SPEED_FULL);
1711 1717 break;
1712 1718 case USBA_SUPER_SPEED_DEV:
1713 1719 default:
1714 1720 info |= XHCI_SCTX_SET_SPEED(XHCI_SPEED_SUPER);
1715 1721 break;
1716 1722 }
1717 1723 info2 = XHCI_SCTX_SET_RHPORT(rp);
1718 1724 tt = XHCI_SCTX_SET_IRQ_TARGET(0);
1719 1725 tt |= xhci_hcdi_device_tt(ud);
1720 1726
1721 1727 xd->xd_slotin->xsc_info = LE_32(info);
1722 1728 xd->xd_slotin->xsc_info2 = LE_32(info2);
1723 1729 xd->xd_slotin->xsc_tt = LE_32(tt);
1724 1730
1725 1731 if ((ret = xhci_endpoint_init(xhcip, xd, NULL)) != 0) {
1726 1732 (void) xhci_command_disable_slot(xhcip, xd->xd_slot);
1727 1733 xhci_hcdi_device_free(xd);
1728 1734 return (USB_HC_HARDWARE_ERROR);
1729 1735 }
1730 1736
1731 1737 if (xhci_context_slot_output_init(xhcip, xd) != B_TRUE) {
1732 1738 (void) xhci_command_disable_slot(xhcip, xd->xd_slot);
1733 1739 xhci_endpoint_fini(xd, 0);
1734 1740 xhci_hcdi_device_free(xd);
1735 1741 return (USB_HC_HARDWARE_ERROR);
1736 1742 }
1737 1743
1738 1744 if ((ret = xhci_command_set_address(xhcip, xd, B_TRUE)) != 0) {
1739 1745 (void) xhci_command_disable_slot(xhcip, xd->xd_slot);
1740 1746 xhci_context_slot_output_fini(xhcip, xd);
1741 1747 xhci_endpoint_fini(xd, 0);
1742 1748 xhci_hcdi_device_free(xd);
1743 1749 return (ret);
1744 1750 }
1745 1751
1746 1752 mutex_enter(&xhcip->xhci_lock);
1747 1753 list_insert_tail(&xhcip->xhci_usba.xa_devices, xd);
1748 1754 mutex_exit(&xhcip->xhci_lock);
1749 1755
1750 1756 *hcdpp = xd;
1751 1757 return (ret);
1752 1758 }
1753 1759
1754 1760 /*
1755 1761 * We're tearing down a device now. That means that the only endpoint context
1756 1762 * that's still valid would be endpoint zero.
1757 1763 */
1758 1764 static void
1759 1765 xhci_hcdi_device_fini(usba_device_t *ud, void *hcdp)
1760 1766 {
1761 1767 int ret;
1762 1768 xhci_endpoint_t *xep;
1763 1769 xhci_device_t *xd;
1764 1770 xhci_t *xhcip;
1765 1771
1766 1772 /*
1767 1773 * Right now, it's theoretically possible that USBA may try and call
1768 1774 * us here even if we hadn't successfully finished the device_init()
1769 1775 * endpoint. We should probably modify the USBA to make sure that this
1770 1776 * can't happen.
1771 1777 */
1772 1778 if (hcdp == NULL)
1773 1779 return;
1774 1780
1775 1781 xd = hcdp;
1776 1782 xhcip = xhci_hcdi_get_xhcip_from_dev(ud);
1777 1783
1778 1784 /*
1779 1785 * Make sure we have no timeout running on the default endpoint still.
1780 1786 */
1781 1787 xep = xd->xd_endpoints[XHCI_DEFAULT_ENDPOINT];
1782 1788 mutex_enter(&xhcip->xhci_lock);
1783 1789 xep->xep_state |= XHCI_ENDPOINT_TEARDOWN;
1784 1790 mutex_exit(&xhcip->xhci_lock);
1785 1791 (void) untimeout(xep->xep_timeout);
1786 1792
1787 1793 /*
1788 1794 * Go ahead and disable the slot. There's no reason to do anything
1789 1795 * special about the default endpoint as it will be disabled as a part
1790 1796 * of the slot disabling. However, if this all fails, we'll leave this
1791 1797 * sitting here in a failed state, eating up a device slot. It is
1792 1798 * unlikely this will occur.
1793 1799 */
1794 1800 ret = xhci_command_disable_slot(xhcip, xd->xd_slot);
1795 1801 if (ret != USB_SUCCESS) {
1796 1802 xhci_error(xhcip, "failed to disable slot %d: %d",
1797 1803 xd->xd_slot, ret);
1798 1804 return;
1799 1805 }
1800 1806
1801 1807 xhci_context_slot_output_fini(xhcip, xd);
1802 1808 xhci_endpoint_fini(xd, XHCI_DEFAULT_ENDPOINT);
1803 1809
1804 1810 mutex_enter(&xhcip->xhci_lock);
1805 1811 list_remove(&xhcip->xhci_usba.xa_devices, xd);
1806 1812 mutex_exit(&xhcip->xhci_lock);
1807 1813
1808 1814 xhci_hcdi_device_free(xd);
1809 1815 }
1810 1816
1811 1817 /*
1812 1818 * Synchronously attempt to set the device address. For xHCI this involves it
1813 1819 * deciding what address to use.
1814 1820 */
1815 1821 static int
1816 1822 xhci_hcdi_device_address(usba_device_t *ud)
1817 1823 {
1818 1824 int ret;
1819 1825 xhci_t *xhcip = xhci_hcdi_get_xhcip_from_dev(ud);
1820 1826 xhci_device_t *xd = usba_hcdi_get_device_private(ud);
1821 1827 xhci_endpoint_t *xep;
1822 1828
1823 1829 mutex_enter(&xhcip->xhci_lock);
1824 1830
1825 1831 /*
1826 1832 * This device may already be addressed from the perspective of the xhci
1827 1833 * controller. For example, the device this represents may have been
1828 1834 * unconfigured, which does not actually remove the slot or other
1829 1835 * information, merely tears down all the active use of it and the child
1830 1836 * driver. In such cases, if we're already addressed, just return
1831 1837 * success. The actual USB address is a fiction for USBA anyways.
1832 1838 */
1833 1839 if (xd->xd_addressed == B_TRUE) {
1834 1840 mutex_exit(&xhcip->xhci_lock);
1835 1841 return (USB_SUCCESS);
1836 1842 }
1837 1843
1838 1844 ASSERT(xd->xd_addressed == B_FALSE);
1839 1845 xd->xd_addressed = B_TRUE;
1840 1846 VERIFY3P(xd->xd_endpoints[XHCI_DEFAULT_ENDPOINT], !=, NULL);
1841 1847 xep = xd->xd_endpoints[XHCI_DEFAULT_ENDPOINT];
1842 1848 mutex_exit(&xhcip->xhci_lock);
1843 1849
1844 1850 if ((ret = xhci_endpoint_setup_default_context(xhcip, xd, xep)) != 0) {
1845 1851 ASSERT(ret == EIO);
1846 1852 return (USB_HC_HARDWARE_ERROR);
1847 1853 }
1848 1854
1849 1855 ret = xhci_command_set_address(xhcip, xd, B_FALSE);
1850 1856
1851 1857 if (ret != USB_SUCCESS) {
1852 1858 mutex_enter(&xhcip->xhci_lock);
1853 1859 xd->xd_addressed = B_FALSE;
1854 1860 mutex_exit(&xhcip->xhci_lock);
1855 1861 }
1856 1862
1857 1863 return (ret);
1858 1864 }
1859 1865
1860 1866 /*
1861 1867 * This is called relatively early on in a hub's life time. At this point, it's
1862 1868 * descriptors have all been pulled and the default control pipe is still open.
1863 1869 * What we need to do is go through and update the slot context to indicate that
1864 1870 * this is a hub, otherwise, the controller will never let us speak to
1865 1871 * downstream ports.
1866 1872 */
1867 1873 static int
1868 1874 xhci_hcdi_hub_update(usba_device_t *ud, uint8_t nports, uint8_t tt)
1869 1875 {
1870 1876 int ret;
1871 1877 xhci_t *xhcip = xhci_hcdi_get_xhcip_from_dev(ud);
1872 1878 xhci_device_t *xd = usba_hcdi_get_device_private(ud);
1873 1879
1874 1880 if (xd == NULL)
1875 1881 return (USB_FAILURE);
1876 1882
1877 1883 if (ud->usb_hubdi == NULL) {
1878 1884 return (USB_FAILURE);
1879 1885 }
1880 1886
1881 1887 mutex_enter(&xd->xd_imtx);
1882 1888
1883 1889 /*
1884 1890 * Note, that usba never sets the interface of a hub to Multi TT. Hence
1885 1891 * why we're never setting the MTT bit in xsc_info.
1886 1892 */
1887 1893 xd->xd_slotin->xsc_info |= LE_32(XHCI_SCTX_SET_HUB(1));
1888 1894 xd->xd_slotin->xsc_info2 |= LE_32(XHCI_SCTX_SET_NPORTS(nports));
1889 1895 if (ud->usb_port_status == USBA_HIGH_SPEED_DEV)
1890 1896 xd->xd_slotin->xsc_tt |= LE_32(XHCI_SCTX_SET_TT_THINK_TIME(tt));
1891 1897
1892 1898 /*
1893 1899 * We're only updating the slot context, no endpoint contexts should be
1894 1900 * touched.
1895 1901 */
1896 1902 xd->xd_input->xic_drop_flags = LE_32(0);
1897 1903 xd->xd_input->xic_add_flags = LE_32(XHCI_INCTX_MASK_DCI(0));
1898 1904
1899 1905 ret = xhci_command_evaluate_context(xhcip, xd);
1900 1906 mutex_exit(&xd->xd_imtx);
1901 1907 return (ret);
1902 1908 }
1903 1909
1904 1910 void
1905 1911 xhci_hcd_fini(xhci_t *xhcip)
1906 1912 {
1907 1913 usba_hcdi_unregister(xhcip->xhci_dip);
1908 1914 usba_free_hcdi_ops(xhcip->xhci_usba.xa_ops);
1909 1915 list_destroy(&xhcip->xhci_usba.xa_pipes);
1910 1916 list_destroy(&xhcip->xhci_usba.xa_devices);
1911 1917 }
1912 1918
1913 1919 int
1914 1920 xhci_hcd_init(xhci_t *xhcip)
1915 1921 {
1916 1922 usba_hcdi_register_args_t hreg;
1917 1923 usba_hcdi_ops_t *ops;
1918 1924
1919 1925 ops = usba_alloc_hcdi_ops();
1920 1926 VERIFY(ops != NULL);
1921 1927
1922 1928 ops->usba_hcdi_ops_version = HCDI_OPS_VERSION;
1923 1929 ops->usba_hcdi_dip = xhcip->xhci_dip;
1924 1930
1925 1931 ops->usba_hcdi_pm_support = xhci_hcdi_pm_support;
1926 1932 ops->usba_hcdi_pipe_open = xhci_hcdi_pipe_open;
1927 1933 ops->usba_hcdi_pipe_close = xhci_hcdi_pipe_close;
1928 1934 ops->usba_hcdi_pipe_reset = xhci_hcdi_pipe_reset;
1929 1935 ops->usba_hcdi_pipe_reset_data_toggle =
1930 1936 xhci_hcdi_pipe_reset_data_toggle;
1931 1937 ops->usba_hcdi_pipe_ctrl_xfer = xhci_hcdi_pipe_ctrl_xfer;
1932 1938 ops->usba_hcdi_bulk_transfer_size = xhci_hcdi_bulk_transfer_size;
1933 1939 ops->usba_hcdi_pipe_bulk_xfer = xhci_hcdi_pipe_bulk_xfer;
1934 1940 ops->usba_hcdi_pipe_intr_xfer = xhci_hcdi_pipe_intr_xfer;
1935 1941 ops->usba_hcdi_pipe_stop_intr_polling =
1936 1942 xhci_hcdi_pipe_stop_intr_polling;
1937 1943 ops->usba_hcdi_pipe_isoc_xfer = xhci_hcdi_pipe_isoc_xfer;
1938 1944 ops->usba_hcdi_pipe_stop_isoc_polling =
1939 1945 xhci_hcdi_pipe_stop_isoc_polling;
1940 1946 ops->usba_hcdi_get_current_frame_number =
1941 1947 xhci_hcdi_get_current_frame_number;
1942 1948 ops->usba_hcdi_get_max_isoc_pkts = xhci_hcdi_get_max_isoc_pkts;
1943 1949 ops->usba_hcdi_console_input_init = xhci_hcdi_console_input_init;
1944 1950 ops->usba_hcdi_console_input_fini = xhci_hcdi_console_input_fini;
1945 1951 ops->usba_hcdi_console_input_enter = xhci_hcdi_console_input_enter;
1946 1952 ops->usba_hcdi_console_read = xhci_hcdi_console_read;
1947 1953 ops->usba_hcdi_console_input_exit = xhci_hcdi_console_input_exit;
1948 1954
1949 1955 ops->usba_hcdi_console_output_init = xhci_hcdi_console_output_init;
1950 1956 ops->usba_hcdi_console_output_fini = xhci_hcdi_console_output_fini;
1951 1957 ops->usba_hcdi_console_output_enter = xhci_hcdi_console_output_enter;
1952 1958 ops->usba_hcdi_console_write = xhci_hcdi_console_write;
1953 1959 ops->usba_hcdi_console_output_exit = xhci_hcdi_console_output_exit;
1954 1960
1955 1961 ops->usba_hcdi_device_init = xhci_hcdi_device_init;
1956 1962 ops->usba_hcdi_device_fini = xhci_hcdi_device_fini;
1957 1963 ops->usba_hcdi_device_address = xhci_hcdi_device_address;
1958 1964 ops->usba_hcdi_hub_update = xhci_hcdi_hub_update;
1959 1965
1960 1966 hreg.usba_hcdi_register_version = HCDI_REGISTER_VERSION;
1961 1967 hreg.usba_hcdi_register_dip = xhcip->xhci_dip;
1962 1968 hreg.usba_hcdi_register_ops = ops;
1963 1969
1964 1970 /*
1965 1971 * We're required to give xhci a set of DMA attributes that it may loan
1966 1972 * out to other devices. Therefore we'll be conservative with what we
1967 1973 * end up giving it.
1968 1974 */
1969 1975 xhci_dma_dma_attr(xhcip, &xhcip->xhci_usba.xa_dma_attr);
1970 1976 hreg.usba_hcdi_register_dma_attr = &xhcip->xhci_usba.xa_dma_attr;
1971 1977
1972 1978 hreg.usba_hcdi_register_iblock_cookie =
1973 1979 (ddi_iblock_cookie_t)(uintptr_t)xhcip->xhci_intr_pri;
1974 1980
1975 1981 if (usba_hcdi_register(&hreg, 0) != DDI_SUCCESS) {
1976 1982 usba_free_hcdi_ops(ops);
1977 1983 return (DDI_FAILURE);
1978 1984 }
1979 1985
1980 1986 xhcip->xhci_usba.xa_ops = ops;
1981 1987
1982 1988 list_create(&xhcip->xhci_usba.xa_devices, sizeof (xhci_device_t),
1983 1989 offsetof(xhci_device_t, xd_link));
1984 1990 list_create(&xhcip->xhci_usba.xa_pipes, sizeof (xhci_pipe_t),
1985 1991 offsetof(xhci_pipe_t, xp_link));
1986 1992
1987 1993
1988 1994 return (DDI_SUCCESS);
1989 1995 }
|
↓ open down ↓ |
1036 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX