diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 36c858e5b529..9012098add6b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1071,6 +1071,15 @@ bandwidth_change: | |||
1071 | xhci_warn(xhci, "Reset device command completion " | 1071 | xhci_warn(xhci, "Reset device command completion " |
1072 | "for disabled slot %u\n", slot_id); | 1072 | "for disabled slot %u\n", slot_id); |
1073 | break; | 1073 | break; |
1074 | case TRB_TYPE(TRB_NEC_GET_FW): | ||
1075 | if (!(xhci->quirks & XHCI_NEC_HOST)) { | ||
1076 | xhci->error_bitmask |= 1 << 6; | ||
1077 | break; | ||
1078 | } | ||
1079 | xhci_dbg(xhci, "NEC firmware version %2x.%02x\n", | ||
1080 | NEC_FW_MAJOR(event->status), | ||
1081 | NEC_FW_MINOR(event->status)); | ||
1082 | break; | ||
1074 | default: | 1083 | default: |
1075 | /* Skip over unknown commands on the event ring */ | 1084 | /* Skip over unknown commands on the event ring */ |
1076 | xhci->error_bitmask |= 1 << 6; | 1085 | xhci->error_bitmask |= 1 << 6; |
@@ -1079,6 +1088,17 @@ bandwidth_change: | |||
1079 | inc_deq(xhci, xhci->cmd_ring, false); | 1088 | inc_deq(xhci, xhci->cmd_ring, false); |
1080 | } | 1089 | } |
1081 | 1090 | ||
1091 | static void handle_vendor_event(struct xhci_hcd *xhci, | ||
1092 | union xhci_trb *event) | ||
1093 | { | ||
1094 | u32 trb_type; | ||
1095 | |||
1096 | trb_type = TRB_FIELD_TO_TYPE(event->generic.field[3]); | ||
1097 | xhci_dbg(xhci, "Vendor specific event TRB type = %u\n", trb_type); | ||
1098 | if (trb_type == TRB_NEC_CMD_COMP && (xhci->quirks & XHCI_NEC_HOST)) | ||
1099 | handle_cmd_completion(xhci, &event->event_cmd); | ||
1100 | } | ||
1101 | |||
1082 | static void handle_port_status(struct xhci_hcd *xhci, | 1102 | static void handle_port_status(struct xhci_hcd *xhci, |
1083 | union xhci_trb *event) | 1103 | union xhci_trb *event) |
1084 | { | 1104 | { |
@@ -1659,7 +1679,10 @@ void xhci_handle_event(struct xhci_hcd *xhci) | |||
1659 | update_ptrs = 0; | 1679 | update_ptrs = 0; |
1660 | break; | 1680 | break; |
1661 | default: | 1681 | default: |
1662 | xhci->error_bitmask |= 1 << 3; | 1682 | if ((event->event_cmd.flags & TRB_TYPE_BITMASK) >= TRB_TYPE(48)) |
1683 | handle_vendor_event(xhci, event); | ||
1684 | else | ||
1685 | xhci->error_bitmask |= 1 << 3; | ||
1663 | } | 1686 | } |
1664 | /* Any of the above functions may drop and re-acquire the lock, so check | 1687 | /* Any of the above functions may drop and re-acquire the lock, so check |
1665 | * to make sure a watchdog timer didn't mark the host as non-responsive. | 1688 | * to make sure a watchdog timer didn't mark the host as non-responsive. |
@@ -2378,6 +2401,12 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
2378 | false); | 2401 | false); |
2379 | } | 2402 | } |
2380 | 2403 | ||
2404 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, | ||
2405 | u32 field1, u32 field2, u32 field3, u32 field4) | ||
2406 | { | ||
2407 | return queue_command(xhci, field1, field2, field3, field4, false); | ||
2408 | } | ||
2409 | |||
2381 | /* Queue a reset device command TRB */ | 2410 | /* Queue a reset device command TRB */ |
2382 | int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id) | 2411 | int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id) |
2383 | { | 2412 | { |