|
@@ -1532,10 +1532,10 @@ static void xhci_event_free ( struct xhci_device *xhci ) {
|
1532
|
1532
|
* Handle transfer event
|
1533
|
1533
|
*
|
1534
|
1534
|
* @v xhci xHCI device
|
1535
|
|
- * @v transfer Transfer event TRB
|
|
1535
|
+ * @v trb Transfer event TRB
|
1536
|
1536
|
*/
|
1537
|
1537
|
static void xhci_transfer ( struct xhci_device *xhci,
|
1538
|
|
- struct xhci_trb_transfer *transfer ) {
|
|
1538
|
+ struct xhci_trb_transfer *trb ) {
|
1539
|
1539
|
struct xhci_slot *slot;
|
1540
|
1540
|
struct xhci_endpoint *endpoint;
|
1541
|
1541
|
struct io_buffer *iobuf;
|
|
@@ -1545,20 +1545,20 @@ static void xhci_transfer ( struct xhci_device *xhci,
|
1545
|
1545
|
profile_start ( &xhci_transfer_profiler );
|
1546
|
1546
|
|
1547
|
1547
|
/* Identify slot */
|
1548
|
|
- if ( ( transfer->slot > xhci->slots ) ||
|
1549
|
|
- ( ( slot = xhci->slot[transfer->slot] ) == NULL ) ) {
|
|
1548
|
+ if ( ( trb->slot > xhci->slots ) ||
|
|
1549
|
+ ( ( slot = xhci->slot[trb->slot] ) == NULL ) ) {
|
1550
|
1550
|
DBGC ( xhci, "XHCI %p transfer event invalid slot %d:\n",
|
1551
|
|
- xhci, transfer->slot );
|
1552
|
|
- DBGC_HDA ( xhci, 0, transfer, sizeof ( *transfer ) );
|
|
1551
|
+ xhci, trb->slot );
|
|
1552
|
+ DBGC_HDA ( xhci, 0, trb, sizeof ( *trb ) );
|
1553
|
1553
|
return;
|
1554
|
1554
|
}
|
1555
|
1555
|
|
1556
|
1556
|
/* Identify endpoint */
|
1557
|
|
- if ( ( transfer->endpoint > XHCI_CTX_END ) ||
|
1558
|
|
- ( ( endpoint = slot->endpoint[transfer->endpoint] ) == NULL ) ) {
|
|
1557
|
+ if ( ( trb->endpoint > XHCI_CTX_END ) ||
|
|
1558
|
+ ( ( endpoint = slot->endpoint[trb->endpoint] ) == NULL ) ) {
|
1559
|
1559
|
DBGC ( xhci, "XHCI %p slot %d transfer event invalid epid "
|
1560
|
|
- "%d:\n", xhci, slot->id, transfer->endpoint );
|
1561
|
|
- DBGC_HDA ( xhci, 0, transfer, sizeof ( *transfer ) );
|
|
1560
|
+ "%d:\n", xhci, slot->id, trb->endpoint );
|
|
1561
|
+ DBGC_HDA ( xhci, 0, trb, sizeof ( *trb ) );
|
1562
|
1562
|
return;
|
1563
|
1563
|
}
|
1564
|
1564
|
|
|
@@ -1567,15 +1567,15 @@ static void xhci_transfer ( struct xhci_device *xhci,
|
1567
|
1567
|
assert ( iobuf != NULL );
|
1568
|
1568
|
|
1569
|
1569
|
/* Check for errors */
|
1570
|
|
- if ( ! ( ( transfer->code == XHCI_CMPLT_SUCCESS ) ||
|
1571
|
|
- ( transfer->code == XHCI_CMPLT_SHORT ) ) ) {
|
|
1570
|
+ if ( ! ( ( trb->code == XHCI_CMPLT_SUCCESS ) ||
|
|
1571
|
+ ( trb->code == XHCI_CMPLT_SHORT ) ) ) {
|
1572
|
1572
|
|
1573
|
1573
|
/* Construct error */
|
1574
|
|
- rc = -ECODE ( transfer->code );
|
|
1574
|
+ rc = -ECODE ( trb->code );
|
1575
|
1575
|
DBGC ( xhci, "XHCI %p slot %d ctx %d failed (code %d): %s\n",
|
1576
|
|
- xhci, slot->id, endpoint->ctx, transfer->code,
|
|
1576
|
+ xhci, slot->id, endpoint->ctx, trb->code,
|
1577
|
1577
|
strerror ( rc ) );
|
1578
|
|
- DBGC_HDA ( xhci, 0, transfer, sizeof ( *transfer ) );
|
|
1578
|
+ DBGC_HDA ( xhci, 0, trb, sizeof ( *trb ) );
|
1579
|
1579
|
|
1580
|
1580
|
/* Sanity check */
|
1581
|
1581
|
assert ( ( endpoint->context->state & XHCI_ENDPOINT_STATE_MASK )
|
|
@@ -1587,11 +1587,11 @@ static void xhci_transfer ( struct xhci_device *xhci,
|
1587
|
1587
|
}
|
1588
|
1588
|
|
1589
|
1589
|
/* Record actual transfer size */
|
1590
|
|
- iob_unput ( iobuf, le16_to_cpu ( transfer->residual ) );
|
|
1590
|
+ iob_unput ( iobuf, le16_to_cpu ( trb->residual ) );
|
1591
|
1591
|
|
1592
|
1592
|
/* Sanity check (for successful completions only) */
|
1593
|
1593
|
assert ( xhci_ring_consumed ( &endpoint->ring ) ==
|
1594
|
|
- le64_to_cpu ( transfer->transfer ) );
|
|
1594
|
+ le64_to_cpu ( trb->transfer ) );
|
1595
|
1595
|
|
1596
|
1596
|
/* Report completion to USB core */
|
1597
|
1597
|
usb_complete ( endpoint->ep, iobuf );
|
|
@@ -1602,24 +1602,24 @@ static void xhci_transfer ( struct xhci_device *xhci,
|
1602
|
1602
|
* Handle command completion event
|
1603
|
1603
|
*
|
1604
|
1604
|
* @v xhci xHCI device
|
1605
|
|
- * @v complete Command completion event
|
|
1605
|
+ * @v trb Command completion event
|
1606
|
1606
|
*/
|
1607
|
1607
|
static void xhci_complete ( struct xhci_device *xhci,
|
1608
|
|
- struct xhci_trb_complete *complete ) {
|
|
1608
|
+ struct xhci_trb_complete *trb ) {
|
1609
|
1609
|
int rc;
|
1610
|
1610
|
|
1611
|
1611
|
/* Ignore "command ring stopped" notifications */
|
1612
|
|
- if ( complete->code == XHCI_CMPLT_CMD_STOPPED ) {
|
|
1612
|
+ if ( trb->code == XHCI_CMPLT_CMD_STOPPED ) {
|
1613
|
1613
|
DBGC2 ( xhci, "XHCI %p command ring stopped\n", xhci );
|
1614
|
1614
|
return;
|
1615
|
1615
|
}
|
1616
|
1616
|
|
1617
|
1617
|
/* Ignore unexpected completions */
|
1618
|
1618
|
if ( ! xhci->pending ) {
|
1619
|
|
- rc = -ECODE ( complete->code );
|
|
1619
|
+ rc = -ECODE ( trb->code );
|
1620
|
1620
|
DBGC ( xhci, "XHCI %p unexpected completion (code %d): %s\n",
|
1621
|
|
- xhci, complete->code, strerror ( rc ) );
|
1622
|
|
- DBGC_HDA ( xhci, 0, complete, sizeof ( *complete ) );
|
|
1621
|
+ xhci, trb->code, strerror ( rc ) );
|
|
1622
|
+ DBGC_HDA ( xhci, 0, trb, sizeof ( *trb ) );
|
1623
|
1623
|
return;
|
1624
|
1624
|
}
|
1625
|
1625
|
|
|
@@ -1628,10 +1628,10 @@ static void xhci_complete ( struct xhci_device *xhci,
|
1628
|
1628
|
|
1629
|
1629
|
/* Sanity check */
|
1630
|
1630
|
assert ( xhci_ring_consumed ( &xhci->command ) ==
|
1631
|
|
- le64_to_cpu ( complete->command ) );
|
|
1631
|
+ le64_to_cpu ( trb->command ) );
|
1632
|
1632
|
|
1633
|
1633
|
/* Record completion */
|
1634
|
|
- memcpy ( xhci->pending, complete, sizeof ( *xhci->pending ) );
|
|
1634
|
+ memcpy ( xhci->pending, trb, sizeof ( *xhci->pending ) );
|
1635
|
1635
|
xhci->pending = NULL;
|
1636
|
1636
|
}
|
1637
|
1637
|
|
|
@@ -1639,38 +1639,40 @@ static void xhci_complete ( struct xhci_device *xhci,
|
1639
|
1639
|
* Handle port status event
|
1640
|
1640
|
*
|
1641
|
1641
|
* @v xhci xHCI device
|
1642
|
|
- * @v port Port status event
|
|
1642
|
+ * @v trb Port status event
|
1643
|
1643
|
*/
|
1644
|
1644
|
static void xhci_port_status ( struct xhci_device *xhci,
|
1645
|
|
- struct xhci_trb_port_status *port ) {
|
|
1645
|
+ struct xhci_trb_port_status *trb ) {
|
|
1646
|
+ struct usb_port *port = usb_port ( xhci->bus->hub, trb->port );
|
1646
|
1647
|
uint32_t portsc;
|
1647
|
1648
|
|
1648
|
1649
|
/* Sanity check */
|
1649
|
|
- assert ( ( port->port > 0 ) && ( port->port <= xhci->ports ) );
|
|
1650
|
+ assert ( ( trb->port > 0 ) && ( trb->port <= xhci->ports ) );
|
1650
|
1651
|
|
1651
|
|
- /* Clear port status change bits */
|
1652
|
|
- portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port->port ) );
|
|
1652
|
+ /* Record disconnections and clear changes */
|
|
1653
|
+ portsc = readl ( xhci->op + XHCI_OP_PORTSC ( trb->port ) );
|
|
1654
|
+ port->disconnected |= ( portsc & XHCI_PORTSC_CSC );
|
1653
|
1655
|
portsc &= ( XHCI_PORTSC_PRESERVE | XHCI_PORTSC_CHANGE );
|
1654
|
|
- writel ( portsc, xhci->op + XHCI_OP_PORTSC ( port->port ) );
|
|
1656
|
+ writel ( portsc, xhci->op + XHCI_OP_PORTSC ( trb->port ) );
|
1655
|
1657
|
|
1656
|
1658
|
/* Report port status change */
|
1657
|
|
- usb_port_changed ( usb_port ( xhci->bus->hub, port->port ) );
|
|
1659
|
+ usb_port_changed ( port );
|
1658
|
1660
|
}
|
1659
|
1661
|
|
1660
|
1662
|
/**
|
1661
|
1663
|
* Handle host controller event
|
1662
|
1664
|
*
|
1663
|
1665
|
* @v xhci xHCI device
|
1664
|
|
- * @v host Host controller event
|
|
1666
|
+ * @v trb Host controller event
|
1665
|
1667
|
*/
|
1666
|
1668
|
static void xhci_host_controller ( struct xhci_device *xhci,
|
1667
|
|
- struct xhci_trb_host_controller *host ) {
|
|
1669
|
+ struct xhci_trb_host_controller *trb ) {
|
1668
|
1670
|
int rc;
|
1669
|
1671
|
|
1670
|
1672
|
/* Construct error */
|
1671
|
|
- rc = -ECODE ( host->code );
|
|
1673
|
+ rc = -ECODE ( trb->code );
|
1672
|
1674
|
DBGC ( xhci, "XHCI %p host controller event (code %d): %s\n",
|
1673
|
|
- xhci, host->code, strerror ( rc ) );
|
|
1675
|
+ xhci, trb->code, strerror ( rc ) );
|
1674
|
1676
|
}
|
1675
|
1677
|
|
1676
|
1678
|
/**
|
|
@@ -3014,6 +3016,7 @@ static int xhci_root_speed ( struct usb_hub *hub, struct usb_port *port ) {
|
3014
|
3016
|
unsigned int psiv;
|
3015
|
3017
|
int ccs;
|
3016
|
3018
|
int ped;
|
|
3019
|
+ int csc;
|
3017
|
3020
|
int speed;
|
3018
|
3021
|
int rc;
|
3019
|
3022
|
|
|
@@ -3021,9 +3024,17 @@ static int xhci_root_speed ( struct usb_hub *hub, struct usb_port *port ) {
|
3021
|
3024
|
portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port->address ) );
|
3022
|
3025
|
DBGC2 ( xhci, "XHCI %p port %d status is %08x\n",
|
3023
|
3026
|
xhci, port->address, portsc );
|
3024
|
|
-
|
3025
|
|
- /* Check whether or not port is connected */
|
3026
|
3027
|
ccs = ( portsc & XHCI_PORTSC_CCS );
|
|
3028
|
+ ped = ( portsc & XHCI_PORTSC_PED );
|
|
3029
|
+ csc = ( portsc & XHCI_PORTSC_CSC );
|
|
3030
|
+ psiv = XHCI_PORTSC_PSIV ( portsc );
|
|
3031
|
+
|
|
3032
|
+ /* Record disconnections and clear changes */
|
|
3033
|
+ port->disconnected |= csc;
|
|
3034
|
+ portsc &= ( XHCI_PORTSC_PRESERVE | XHCI_PORTSC_CHANGE );
|
|
3035
|
+ writel ( portsc, xhci->op + XHCI_OP_PORTSC ( port->address ) );
|
|
3036
|
+
|
|
3037
|
+ /* Port speed is not valid unless port is connected */
|
3027
|
3038
|
if ( ! ccs ) {
|
3028
|
3039
|
port->speed = USB_SPEED_NONE;
|
3029
|
3040
|
return 0;
|
|
@@ -3032,14 +3043,12 @@ static int xhci_root_speed ( struct usb_hub *hub, struct usb_port *port ) {
|
3032
|
3043
|
/* For USB2 ports, the PSIV field is not valid until the port
|
3033
|
3044
|
* completes reset and becomes enabled.
|
3034
|
3045
|
*/
|
3035
|
|
- ped = ( portsc & XHCI_PORTSC_PED );
|
3036
|
3046
|
if ( ( port->protocol < USB_PROTO_3_0 ) && ! ped ) {
|
3037
|
3047
|
port->speed = USB_SPEED_FULL;
|
3038
|
3048
|
return 0;
|
3039
|
3049
|
}
|
3040
|
3050
|
|
3041
|
3051
|
/* Get port speed and map to generic USB speed */
|
3042
|
|
- psiv = XHCI_PORTSC_PSIV ( portsc );
|
3043
|
3052
|
speed = xhci_port_speed ( xhci, port->address, psiv );
|
3044
|
3053
|
if ( speed < 0 ) {
|
3045
|
3054
|
rc = speed;
|