Sun Apr 10 22:16:00 2016 UTC ()
Simplify xhci_do_command*


(skrll)
diff -r1.28.2.64 -r1.28.2.65 src/sys/dev/usb/xhci.c

cvs diff -r1.28.2.64 -r1.28.2.65 src/sys/dev/usb/xhci.c (expand / switch to unified diff)

--- src/sys/dev/usb/xhci.c 2016/04/10 21:30:41 1.28.2.64
+++ src/sys/dev/usb/xhci.c 2016/04/10 22:16:00 1.28.2.65
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xhci.c,v 1.28.2.64 2016/04/10 21:30:41 skrll Exp $ */ 1/* $NetBSD: xhci.c,v 1.28.2.65 2016/04/10 22:16:00 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2013 Jonathan A. Kollasch 4 * Copyright (c) 2013 Jonathan A. Kollasch
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -26,27 +26,27 @@ @@ -26,27 +26,27 @@
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * USB rev 3.1 specification 30 * USB rev 3.1 specification
31 * http://www.usb.org/developers/docs/usb_31_040315.zip 31 * http://www.usb.org/developers/docs/usb_31_040315.zip
32 * USB rev 2.0 specification 32 * USB rev 2.0 specification
33 * http://www.usb.org/developers/docs/usb20_docs/usb_20_031815.zip 33 * http://www.usb.org/developers/docs/usb20_docs/usb_20_031815.zip
34 * xHCI rev 1.1 specification 34 * xHCI rev 1.1 specification
35 * http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf 35 * http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf
36 */ 36 */
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.64 2016/04/10 21:30:41 skrll Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.65 2016/04/10 22:16:00 skrll Exp $");
40 40
41#include "opt_usb.h" 41#include "opt_usb.h"
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/select.h> 48#include <sys/select.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/queue.h> 50#include <sys/queue.h>
51#include <sys/mutex.h> 51#include <sys/mutex.h>
52#include <sys/condvar.h> 52#include <sys/condvar.h>
@@ -136,28 +136,26 @@ static usbd_status xhci_new_device(devic @@ -136,28 +136,26 @@ static usbd_status xhci_new_device(devic
136 struct usbd_port *); 136 struct usbd_port *);
137static int xhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *, 137static int xhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
138 void *, int); 138 void *, int);
139 139
140static usbd_status xhci_configure_endpoint(struct usbd_pipe *); 140static usbd_status xhci_configure_endpoint(struct usbd_pipe *);
141//static usbd_status xhci_unconfigure_endpoint(struct usbd_pipe *); 141//static usbd_status xhci_unconfigure_endpoint(struct usbd_pipe *);
142static usbd_status xhci_reset_endpoint(struct usbd_pipe *); 142static usbd_status xhci_reset_endpoint(struct usbd_pipe *);
143static usbd_status xhci_stop_endpoint(struct usbd_pipe *); 143static usbd_status xhci_stop_endpoint(struct usbd_pipe *);
144 144
145static usbd_status xhci_set_dequeue(struct usbd_pipe *); 145static usbd_status xhci_set_dequeue(struct usbd_pipe *);
146 146
147static usbd_status xhci_do_command(struct xhci_softc * const, 147static usbd_status xhci_do_command(struct xhci_softc * const,
148 struct xhci_trb * const, int); 148 struct xhci_trb * const, int);
149static usbd_status xhci_do_command1(struct xhci_softc * const, 
150 struct xhci_trb * const, int, int); 
151static usbd_status xhci_do_command_locked(struct xhci_softc * const, 149static usbd_status xhci_do_command_locked(struct xhci_softc * const,
152 struct xhci_trb * const, int); 150 struct xhci_trb * const, int);
153static usbd_status xhci_init_slot(struct usbd_device *, uint32_t, uint32_t, int); 151static usbd_status xhci_init_slot(struct usbd_device *, uint32_t, uint32_t, int);
154static usbd_status xhci_enable_slot(struct xhci_softc * const, 152static usbd_status xhci_enable_slot(struct xhci_softc * const,
155 uint8_t * const); 153 uint8_t * const);
156static usbd_status xhci_disable_slot(struct xhci_softc * const, uint8_t); 154static usbd_status xhci_disable_slot(struct xhci_softc * const, uint8_t);
157static usbd_status xhci_address_device(struct xhci_softc * const, 155static usbd_status xhci_address_device(struct xhci_softc * const,
158 uint64_t, uint8_t, bool); 156 uint64_t, uint8_t, bool);
159static void xhci_set_dcba(struct xhci_softc * const, uint64_t, int); 157static void xhci_set_dcba(struct xhci_softc * const, uint64_t, int);
160static usbd_status xhci_update_ep0_mps(struct xhci_softc * const, 158static usbd_status xhci_update_ep0_mps(struct xhci_softc * const,
161 struct xhci_slot * const, u_int); 159 struct xhci_slot * const, u_int);
162static usbd_status xhci_ring_init(struct xhci_softc * const, 160static usbd_status xhci_ring_init(struct xhci_softc * const,
163 struct xhci_ring * const, size_t, size_t); 161 struct xhci_ring * const, size_t, size_t);
@@ -2465,40 +2463,38 @@ xhci_ring_put(struct xhci_softc * const  @@ -2465,40 +2463,38 @@ xhci_ring_put(struct xhci_softc * const
2465 xr->xr_cs = cs; 2463 xr->xr_cs = cs;
2466 2464
2467 DPRINTFN(12, "%p xr_ep 0x%x xr_cs %u", xr, xr->xr_ep, xr->xr_cs, 0); 2465 DPRINTFN(12, "%p xr_ep 0x%x xr_cs %u", xr, xr->xr_ep, xr->xr_cs, 0);
2468} 2466}
2469 2467
2470/* 2468/*
2471 * Put a command on command ring, ring bell, set timer, and cv_timedwait. 2469 * Put a command on command ring, ring bell, set timer, and cv_timedwait.
2472 * Command completion is notified by cv_signal from xhci_handle_event 2470 * Command completion is notified by cv_signal from xhci_handle_event
2473 * (called from interrupt from xHCI), or timed-out. 2471 * (called from interrupt from xHCI), or timed-out.
2474 * Command validation is performed in xhci_handle_event by checking if 2472 * Command validation is performed in xhci_handle_event by checking if
2475 * trb_0 in CMD_COMPLETE TRB and sc->sc_command_addr are identical. 2473 * trb_0 in CMD_COMPLETE TRB and sc->sc_command_addr are identical.
2476 */ 2474 */
2477static usbd_status 2475static usbd_status
2478xhci_do_command1(struct xhci_softc * const sc, struct xhci_trb * const trb, 2476xhci_do_command_locked(struct xhci_softc * const sc, struct xhci_trb * const trb,
2479 int timeout, int locked) 2477 int timeout)
2480{ 2478{
2481 struct xhci_ring * const cr = &sc->sc_cr; 2479 struct xhci_ring * const cr = &sc->sc_cr;
2482 usbd_status err; 2480 usbd_status err;
2483 2481
2484 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 2482 XHCIHIST_FUNC(); XHCIHIST_CALLED();
2485 DPRINTFN(12, "input: 0x%016"PRIx64" 0x%08"PRIx32" 0x%08"PRIx32, 2483 DPRINTFN(12, "input: 0x%016"PRIx64" 0x%08"PRIx32" 0x%08"PRIx32,
2486 trb->trb_0, trb->trb_2, trb->trb_3, 0); 2484 trb->trb_0, trb->trb_2, trb->trb_3, 0);
2487 2485
2488 KASSERTMSG(!cpu_intr_p() && !cpu_softintr_p(), "called from intr ctx"); 2486 KASSERTMSG(!cpu_intr_p() && !cpu_softintr_p(), "called from intr ctx");
2489 2487 KASSERT(mutex_owned(&sc->sc_lock));
2490 if (!locked) 
2491 mutex_enter(&sc->sc_lock); 
2492 2488
2493 /* XXX KASSERT may fire when cv_timedwait unlocks sc_lock */ 2489 /* XXX KASSERT may fire when cv_timedwait unlocks sc_lock */
2494 KASSERT(sc->sc_command_addr == 0); 2490 KASSERT(sc->sc_command_addr == 0);
2495 sc->sc_command_addr = xhci_ring_trbp(cr, cr->xr_ep); 2491 sc->sc_command_addr = xhci_ring_trbp(cr, cr->xr_ep);
2496 2492
2497 mutex_enter(&cr->xr_lock); 2493 mutex_enter(&cr->xr_lock);
2498 xhci_ring_put(sc, cr, NULL, trb, 1); 2494 xhci_ring_put(sc, cr, NULL, trb, 1);
2499 mutex_exit(&cr->xr_lock); 2495 mutex_exit(&cr->xr_lock);
2500 2496
2501 xhci_db_write_4(sc, XHCI_DOORBELL(0), 0); 2497 xhci_db_write_4(sc, XHCI_DOORBELL(0), 0);
2502 2498
2503 if (cv_timedwait(&sc->sc_command_cv, &sc->sc_lock, 2499 if (cv_timedwait(&sc->sc_command_cv, &sc->sc_lock,
2504 MAX(1, mstohz(timeout))) == EWOULDBLOCK) { 2500 MAX(1, mstohz(timeout))) == EWOULDBLOCK) {
@@ -2518,48 +2514,39 @@ xhci_do_command1(struct xhci_softc * con @@ -2518,48 +2514,39 @@ xhci_do_command1(struct xhci_softc * con
2518 err = USBD_NORMAL_COMPLETION; 2514 err = USBD_NORMAL_COMPLETION;
2519 break; 2515 break;
2520 default: 2516 default:
2521 case 192 ... 223: 2517 case 192 ... 223:
2522 err = USBD_IOERROR; 2518 err = USBD_IOERROR;
2523 break; 2519 break;
2524 case 224 ... 255: 2520 case 224 ... 255:
2525 err = USBD_NORMAL_COMPLETION; 2521 err = USBD_NORMAL_COMPLETION;
2526 break; 2522 break;
2527 } 2523 }
2528 2524
2529timedout: 2525timedout:
2530 sc->sc_command_addr = 0; 2526 sc->sc_command_addr = 0;
2531 if (!locked) 
2532 mutex_exit(&sc->sc_lock); 
2533 return err; 2527 return err;
2534} 2528}
2535 2529
2536static usbd_status 2530static usbd_status
2537xhci_do_command(struct xhci_softc * const sc, struct xhci_trb * const trb, 2531xhci_do_command(struct xhci_softc * const sc, struct xhci_trb * const trb,
2538 int timeout) 2532 int timeout)
2539{ 2533{
2540 return xhci_do_command1(sc, trb, timeout, 0); 
2541} 
2542 2534
2543/* 2535 mutex_enter(&sc->sc_lock);
2544 * This allows xhci_do_command with already sc_lock held. 2536 int ret = xhci_do_command_locked(sc, trb, timeout);
2545 * This is needed as USB stack calls close methods with sc_lock_held. 2537 mutex_exit(&sc->sc_lock);
2546 * (see usbdivar.h) 2538
2547 */ 2539 return ret;
2548static usbd_status 
2549xhci_do_command_locked(struct xhci_softc * const sc, 
2550 struct xhci_trb * const trb, int timeout) 
2551{ 
2552 return xhci_do_command1(sc, trb, timeout, 1); 
2553} 2540}
2554 2541
2555static usbd_status 2542static usbd_status
2556xhci_enable_slot(struct xhci_softc * const sc, uint8_t * const slotp) 2543xhci_enable_slot(struct xhci_softc * const sc, uint8_t * const slotp)
2557{ 2544{
2558 struct xhci_trb trb; 2545 struct xhci_trb trb;
2559 usbd_status err; 2546 usbd_status err;
2560 2547
2561 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 2548 XHCIHIST_FUNC(); XHCIHIST_CALLED();
2562 2549
2563 trb.trb_0 = 0; 2550 trb.trb_0 = 0;
2564 trb.trb_2 = 0; 2551 trb.trb_2 = 0;
2565 trb.trb_3 = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_ENABLE_SLOT); 2552 trb.trb_3 = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_ENABLE_SLOT);