|
|
1.1 ! root 1: /* ! 2: * USB xHCI controller emulation ! 3: * ! 4: * Copyright (c) 2011 Securiforest ! 5: * Date: 2011-05-11 ; Author: Hector Martin <[email protected]> ! 6: * Based on usb-ohci.c, emulates Renesas NEC USB 3.0 ! 7: * ! 8: * This library is free software; you can redistribute it and/or ! 9: * modify it under the terms of the GNU Lesser General Public ! 10: * License as published by the Free Software Foundation; either ! 11: * version 2 of the License, or (at your option) any later version. ! 12: * ! 13: * This library is distributed in the hope that it will be useful, ! 14: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 16: * Lesser General Public License for more details. ! 17: * ! 18: * You should have received a copy of the GNU Lesser General Public ! 19: * License along with this library; if not, see <http://www.gnu.org/licenses/>. ! 20: */ ! 21: #include "hw/hw.h" ! 22: #include "qemu-timer.h" ! 23: #include "hw/usb.h" ! 24: #include "hw/pci.h" ! 25: #include "hw/msi.h" ! 26: ! 27: //#define DEBUG_XHCI ! 28: //#define DEBUG_DATA ! 29: ! 30: #ifdef DEBUG_XHCI ! 31: #define DPRINTF(...) fprintf(stderr, __VA_ARGS__) ! 32: #else ! 33: #define DPRINTF(...) do {} while (0) ! 34: #endif ! 35: #define FIXME() do { fprintf(stderr, "FIXME %s:%d\n", \ ! 36: __func__, __LINE__); abort(); } while (0) ! 37: ! 38: #define MAXSLOTS 8 ! 39: #define MAXINTRS 1 ! 40: ! 41: #define USB2_PORTS 4 ! 42: #define USB3_PORTS 4 ! 43: ! 44: #define MAXPORTS (USB2_PORTS+USB3_PORTS) ! 45: ! 46: #define TD_QUEUE 24 ! 47: #define BG_XFERS 8 ! 48: #define BG_PKTS 8 ! 49: ! 50: /* Very pessimistic, let's hope it's enough for all cases */ ! 51: #define EV_QUEUE (((3*TD_QUEUE)+16)*MAXSLOTS) ! 52: /* Do not deliver ER Full events. NEC's driver does some things not bound ! 53: * to the specs when it gets them */ ! 54: #define ER_FULL_HACK ! 55: ! 56: #define LEN_CAP 0x40 ! 57: #define OFF_OPER LEN_CAP ! 58: #define LEN_OPER (0x400 + 0x10 * MAXPORTS) ! 59: #define OFF_RUNTIME ((OFF_OPER + LEN_OPER + 0x20) & ~0x1f) ! 60: #define LEN_RUNTIME (0x20 + MAXINTRS * 0x20) ! 61: #define OFF_DOORBELL (OFF_RUNTIME + LEN_RUNTIME) ! 62: #define LEN_DOORBELL ((MAXSLOTS + 1) * 0x20) ! 63: ! 64: /* must be power of 2 */ ! 65: #define LEN_REGS 0x2000 ! 66: ! 67: #if (OFF_DOORBELL + LEN_DOORBELL) > LEN_REGS ! 68: # error Increase LEN_REGS ! 69: #endif ! 70: ! 71: #if MAXINTRS > 1 ! 72: # error TODO: only one interrupter supported ! 73: #endif ! 74: ! 75: /* bit definitions */ ! 76: #define USBCMD_RS (1<<0) ! 77: #define USBCMD_HCRST (1<<1) ! 78: #define USBCMD_INTE (1<<2) ! 79: #define USBCMD_HSEE (1<<3) ! 80: #define USBCMD_LHCRST (1<<7) ! 81: #define USBCMD_CSS (1<<8) ! 82: #define USBCMD_CRS (1<<9) ! 83: #define USBCMD_EWE (1<<10) ! 84: #define USBCMD_EU3S (1<<11) ! 85: ! 86: #define USBSTS_HCH (1<<0) ! 87: #define USBSTS_HSE (1<<2) ! 88: #define USBSTS_EINT (1<<3) ! 89: #define USBSTS_PCD (1<<4) ! 90: #define USBSTS_SSS (1<<8) ! 91: #define USBSTS_RSS (1<<9) ! 92: #define USBSTS_SRE (1<<10) ! 93: #define USBSTS_CNR (1<<11) ! 94: #define USBSTS_HCE (1<<12) ! 95: ! 96: ! 97: #define PORTSC_CCS (1<<0) ! 98: #define PORTSC_PED (1<<1) ! 99: #define PORTSC_OCA (1<<3) ! 100: #define PORTSC_PR (1<<4) ! 101: #define PORTSC_PLS_SHIFT 5 ! 102: #define PORTSC_PLS_MASK 0xf ! 103: #define PORTSC_PP (1<<9) ! 104: #define PORTSC_SPEED_SHIFT 10 ! 105: #define PORTSC_SPEED_MASK 0xf ! 106: #define PORTSC_SPEED_FULL (1<<10) ! 107: #define PORTSC_SPEED_LOW (2<<10) ! 108: #define PORTSC_SPEED_HIGH (3<<10) ! 109: #define PORTSC_SPEED_SUPER (4<<10) ! 110: #define PORTSC_PIC_SHIFT 14 ! 111: #define PORTSC_PIC_MASK 0x3 ! 112: #define PORTSC_LWS (1<<16) ! 113: #define PORTSC_CSC (1<<17) ! 114: #define PORTSC_PEC (1<<18) ! 115: #define PORTSC_WRC (1<<19) ! 116: #define PORTSC_OCC (1<<20) ! 117: #define PORTSC_PRC (1<<21) ! 118: #define PORTSC_PLC (1<<22) ! 119: #define PORTSC_CEC (1<<23) ! 120: #define PORTSC_CAS (1<<24) ! 121: #define PORTSC_WCE (1<<25) ! 122: #define PORTSC_WDE (1<<26) ! 123: #define PORTSC_WOE (1<<27) ! 124: #define PORTSC_DR (1<<30) ! 125: #define PORTSC_WPR (1<<31) ! 126: ! 127: #define CRCR_RCS (1<<0) ! 128: #define CRCR_CS (1<<1) ! 129: #define CRCR_CA (1<<2) ! 130: #define CRCR_CRR (1<<3) ! 131: ! 132: #define IMAN_IP (1<<0) ! 133: #define IMAN_IE (1<<1) ! 134: ! 135: #define ERDP_EHB (1<<3) ! 136: ! 137: #define TRB_SIZE 16 ! 138: typedef struct XHCITRB { ! 139: uint64_t parameter; ! 140: uint32_t status; ! 141: uint32_t control; ! 142: dma_addr_t addr; ! 143: bool ccs; ! 144: } XHCITRB; ! 145: ! 146: ! 147: typedef enum TRBType { ! 148: TRB_RESERVED = 0, ! 149: TR_NORMAL, ! 150: TR_SETUP, ! 151: TR_DATA, ! 152: TR_STATUS, ! 153: TR_ISOCH, ! 154: TR_LINK, ! 155: TR_EVDATA, ! 156: TR_NOOP, ! 157: CR_ENABLE_SLOT, ! 158: CR_DISABLE_SLOT, ! 159: CR_ADDRESS_DEVICE, ! 160: CR_CONFIGURE_ENDPOINT, ! 161: CR_EVALUATE_CONTEXT, ! 162: CR_RESET_ENDPOINT, ! 163: CR_STOP_ENDPOINT, ! 164: CR_SET_TR_DEQUEUE, ! 165: CR_RESET_DEVICE, ! 166: CR_FORCE_EVENT, ! 167: CR_NEGOTIATE_BW, ! 168: CR_SET_LATENCY_TOLERANCE, ! 169: CR_GET_PORT_BANDWIDTH, ! 170: CR_FORCE_HEADER, ! 171: CR_NOOP, ! 172: ER_TRANSFER = 32, ! 173: ER_COMMAND_COMPLETE, ! 174: ER_PORT_STATUS_CHANGE, ! 175: ER_BANDWIDTH_REQUEST, ! 176: ER_DOORBELL, ! 177: ER_HOST_CONTROLLER, ! 178: ER_DEVICE_NOTIFICATION, ! 179: ER_MFINDEX_WRAP, ! 180: /* vendor specific bits */ ! 181: CR_VENDOR_VIA_CHALLENGE_RESPONSE = 48, ! 182: CR_VENDOR_NEC_FIRMWARE_REVISION = 49, ! 183: CR_VENDOR_NEC_CHALLENGE_RESPONSE = 50, ! 184: } TRBType; ! 185: ! 186: #define CR_LINK TR_LINK ! 187: ! 188: typedef enum TRBCCode { ! 189: CC_INVALID = 0, ! 190: CC_SUCCESS, ! 191: CC_DATA_BUFFER_ERROR, ! 192: CC_BABBLE_DETECTED, ! 193: CC_USB_TRANSACTION_ERROR, ! 194: CC_TRB_ERROR, ! 195: CC_STALL_ERROR, ! 196: CC_RESOURCE_ERROR, ! 197: CC_BANDWIDTH_ERROR, ! 198: CC_NO_SLOTS_ERROR, ! 199: CC_INVALID_STREAM_TYPE_ERROR, ! 200: CC_SLOT_NOT_ENABLED_ERROR, ! 201: CC_EP_NOT_ENABLED_ERROR, ! 202: CC_SHORT_PACKET, ! 203: CC_RING_UNDERRUN, ! 204: CC_RING_OVERRUN, ! 205: CC_VF_ER_FULL, ! 206: CC_PARAMETER_ERROR, ! 207: CC_BANDWIDTH_OVERRUN, ! 208: CC_CONTEXT_STATE_ERROR, ! 209: CC_NO_PING_RESPONSE_ERROR, ! 210: CC_EVENT_RING_FULL_ERROR, ! 211: CC_INCOMPATIBLE_DEVICE_ERROR, ! 212: CC_MISSED_SERVICE_ERROR, ! 213: CC_COMMAND_RING_STOPPED, ! 214: CC_COMMAND_ABORTED, ! 215: CC_STOPPED, ! 216: CC_STOPPED_LENGTH_INVALID, ! 217: CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29, ! 218: CC_ISOCH_BUFFER_OVERRUN = 31, ! 219: CC_EVENT_LOST_ERROR, ! 220: CC_UNDEFINED_ERROR, ! 221: CC_INVALID_STREAM_ID_ERROR, ! 222: CC_SECONDARY_BANDWIDTH_ERROR, ! 223: CC_SPLIT_TRANSACTION_ERROR ! 224: } TRBCCode; ! 225: ! 226: #define TRB_C (1<<0) ! 227: #define TRB_TYPE_SHIFT 10 ! 228: #define TRB_TYPE_MASK 0x3f ! 229: #define TRB_TYPE(t) (((t).control >> TRB_TYPE_SHIFT) & TRB_TYPE_MASK) ! 230: ! 231: #define TRB_EV_ED (1<<2) ! 232: ! 233: #define TRB_TR_ENT (1<<1) ! 234: #define TRB_TR_ISP (1<<2) ! 235: #define TRB_TR_NS (1<<3) ! 236: #define TRB_TR_CH (1<<4) ! 237: #define TRB_TR_IOC (1<<5) ! 238: #define TRB_TR_IDT (1<<6) ! 239: #define TRB_TR_TBC_SHIFT 7 ! 240: #define TRB_TR_TBC_MASK 0x3 ! 241: #define TRB_TR_BEI (1<<9) ! 242: #define TRB_TR_TLBPC_SHIFT 16 ! 243: #define TRB_TR_TLBPC_MASK 0xf ! 244: #define TRB_TR_FRAMEID_SHIFT 20 ! 245: #define TRB_TR_FRAMEID_MASK 0x7ff ! 246: #define TRB_TR_SIA (1<<31) ! 247: ! 248: #define TRB_TR_DIR (1<<16) ! 249: ! 250: #define TRB_CR_SLOTID_SHIFT 24 ! 251: #define TRB_CR_SLOTID_MASK 0xff ! 252: #define TRB_CR_EPID_SHIFT 16 ! 253: #define TRB_CR_EPID_MASK 0x1f ! 254: ! 255: #define TRB_CR_BSR (1<<9) ! 256: #define TRB_CR_DC (1<<9) ! 257: ! 258: #define TRB_LK_TC (1<<1) ! 259: ! 260: #define EP_TYPE_MASK 0x7 ! 261: #define EP_TYPE_SHIFT 3 ! 262: ! 263: #define EP_STATE_MASK 0x7 ! 264: #define EP_DISABLED (0<<0) ! 265: #define EP_RUNNING (1<<0) ! 266: #define EP_HALTED (2<<0) ! 267: #define EP_STOPPED (3<<0) ! 268: #define EP_ERROR (4<<0) ! 269: ! 270: #define SLOT_STATE_MASK 0x1f ! 271: #define SLOT_STATE_SHIFT 27 ! 272: #define SLOT_STATE(s) (((s)>>SLOT_STATE_SHIFT)&SLOT_STATE_MASK) ! 273: #define SLOT_ENABLED 0 ! 274: #define SLOT_DEFAULT 1 ! 275: #define SLOT_ADDRESSED 2 ! 276: #define SLOT_CONFIGURED 3 ! 277: ! 278: #define SLOT_CONTEXT_ENTRIES_MASK 0x1f ! 279: #define SLOT_CONTEXT_ENTRIES_SHIFT 27 ! 280: ! 281: typedef enum EPType { ! 282: ET_INVALID = 0, ! 283: ET_ISO_OUT, ! 284: ET_BULK_OUT, ! 285: ET_INTR_OUT, ! 286: ET_CONTROL, ! 287: ET_ISO_IN, ! 288: ET_BULK_IN, ! 289: ET_INTR_IN, ! 290: } EPType; ! 291: ! 292: typedef struct XHCIRing { ! 293: dma_addr_t base; ! 294: dma_addr_t dequeue; ! 295: bool ccs; ! 296: } XHCIRing; ! 297: ! 298: typedef struct XHCIPort { ! 299: USBPort port; ! 300: uint32_t portsc; ! 301: } XHCIPort; ! 302: ! 303: struct XHCIState; ! 304: typedef struct XHCIState XHCIState; ! 305: ! 306: typedef struct XHCITransfer { ! 307: XHCIState *xhci; ! 308: USBPacket packet; ! 309: bool running_async; ! 310: bool running_retry; ! 311: bool cancelled; ! 312: bool complete; ! 313: bool backgrounded; ! 314: unsigned int iso_pkts; ! 315: unsigned int slotid; ! 316: unsigned int epid; ! 317: bool in_xfer; ! 318: bool iso_xfer; ! 319: bool bg_xfer; ! 320: ! 321: unsigned int trb_count; ! 322: unsigned int trb_alloced; ! 323: XHCITRB *trbs; ! 324: ! 325: unsigned int data_length; ! 326: unsigned int data_alloced; ! 327: uint8_t *data; ! 328: ! 329: TRBCCode status; ! 330: ! 331: unsigned int pkts; ! 332: unsigned int pktsize; ! 333: unsigned int cur_pkt; ! 334: } XHCITransfer; ! 335: ! 336: typedef struct XHCIEPContext { ! 337: XHCIRing ring; ! 338: unsigned int next_xfer; ! 339: unsigned int comp_xfer; ! 340: XHCITransfer transfers[TD_QUEUE]; ! 341: XHCITransfer *retry; ! 342: bool bg_running; ! 343: bool bg_updating; ! 344: unsigned int next_bg; ! 345: XHCITransfer bg_transfers[BG_XFERS]; ! 346: EPType type; ! 347: dma_addr_t pctx; ! 348: unsigned int max_psize; ! 349: bool has_bg; ! 350: uint32_t state; ! 351: } XHCIEPContext; ! 352: ! 353: typedef struct XHCISlot { ! 354: bool enabled; ! 355: dma_addr_t ctx; ! 356: unsigned int port; ! 357: unsigned int devaddr; ! 358: XHCIEPContext * eps[31]; ! 359: } XHCISlot; ! 360: ! 361: typedef struct XHCIEvent { ! 362: TRBType type; ! 363: TRBCCode ccode; ! 364: uint64_t ptr; ! 365: uint32_t length; ! 366: uint32_t flags; ! 367: uint8_t slotid; ! 368: uint8_t epid; ! 369: } XHCIEvent; ! 370: ! 371: struct XHCIState { ! 372: PCIDevice pci_dev; ! 373: USBBus bus; ! 374: qemu_irq irq; ! 375: MemoryRegion mem; ! 376: const char *name; ! 377: uint32_t msi; ! 378: unsigned int devaddr; ! 379: ! 380: /* Operational Registers */ ! 381: uint32_t usbcmd; ! 382: uint32_t usbsts; ! 383: uint32_t dnctrl; ! 384: uint32_t crcr_low; ! 385: uint32_t crcr_high; ! 386: uint32_t dcbaap_low; ! 387: uint32_t dcbaap_high; ! 388: uint32_t config; ! 389: ! 390: XHCIPort ports[MAXPORTS]; ! 391: XHCISlot slots[MAXSLOTS]; ! 392: ! 393: /* Runtime Registers */ ! 394: uint32_t mfindex; ! 395: /* note: we only support one interrupter */ ! 396: uint32_t iman; ! 397: uint32_t imod; ! 398: uint32_t erstsz; ! 399: uint32_t erstba_low; ! 400: uint32_t erstba_high; ! 401: uint32_t erdp_low; ! 402: uint32_t erdp_high; ! 403: ! 404: dma_addr_t er_start; ! 405: uint32_t er_size; ! 406: bool er_pcs; ! 407: unsigned int er_ep_idx; ! 408: bool er_full; ! 409: ! 410: XHCIEvent ev_buffer[EV_QUEUE]; ! 411: unsigned int ev_buffer_put; ! 412: unsigned int ev_buffer_get; ! 413: ! 414: XHCIRing cmd_ring; ! 415: }; ! 416: ! 417: typedef struct XHCIEvRingSeg { ! 418: uint32_t addr_low; ! 419: uint32_t addr_high; ! 420: uint32_t size; ! 421: uint32_t rsvd; ! 422: } XHCIEvRingSeg; ! 423: ! 424: #ifdef DEBUG_XHCI ! 425: static const char *TRBType_names[] = { ! 426: [TRB_RESERVED] = "TRB_RESERVED", ! 427: [TR_NORMAL] = "TR_NORMAL", ! 428: [TR_SETUP] = "TR_SETUP", ! 429: [TR_DATA] = "TR_DATA", ! 430: [TR_STATUS] = "TR_STATUS", ! 431: [TR_ISOCH] = "TR_ISOCH", ! 432: [TR_LINK] = "TR_LINK", ! 433: [TR_EVDATA] = "TR_EVDATA", ! 434: [TR_NOOP] = "TR_NOOP", ! 435: [CR_ENABLE_SLOT] = "CR_ENABLE_SLOT", ! 436: [CR_DISABLE_SLOT] = "CR_DISABLE_SLOT", ! 437: [CR_ADDRESS_DEVICE] = "CR_ADDRESS_DEVICE", ! 438: [CR_CONFIGURE_ENDPOINT] = "CR_CONFIGURE_ENDPOINT", ! 439: [CR_EVALUATE_CONTEXT] = "CR_EVALUATE_CONTEXT", ! 440: [CR_RESET_ENDPOINT] = "CR_RESET_ENDPOINT", ! 441: [CR_STOP_ENDPOINT] = "CR_STOP_ENDPOINT", ! 442: [CR_SET_TR_DEQUEUE] = "CR_SET_TR_DEQUEUE", ! 443: [CR_RESET_DEVICE] = "CR_RESET_DEVICE", ! 444: [CR_FORCE_EVENT] = "CR_FORCE_EVENT", ! 445: [CR_NEGOTIATE_BW] = "CR_NEGOTIATE_BW", ! 446: [CR_SET_LATENCY_TOLERANCE] = "CR_SET_LATENCY_TOLERANCE", ! 447: [CR_GET_PORT_BANDWIDTH] = "CR_GET_PORT_BANDWIDTH", ! 448: [CR_FORCE_HEADER] = "CR_FORCE_HEADER", ! 449: [CR_NOOP] = "CR_NOOP", ! 450: [ER_TRANSFER] = "ER_TRANSFER", ! 451: [ER_COMMAND_COMPLETE] = "ER_COMMAND_COMPLETE", ! 452: [ER_PORT_STATUS_CHANGE] = "ER_PORT_STATUS_CHANGE", ! 453: [ER_BANDWIDTH_REQUEST] = "ER_BANDWIDTH_REQUEST", ! 454: [ER_DOORBELL] = "ER_DOORBELL", ! 455: [ER_HOST_CONTROLLER] = "ER_HOST_CONTROLLER", ! 456: [ER_DEVICE_NOTIFICATION] = "ER_DEVICE_NOTIFICATION", ! 457: [ER_MFINDEX_WRAP] = "ER_MFINDEX_WRAP", ! 458: [CR_VENDOR_VIA_CHALLENGE_RESPONSE] = "CR_VENDOR_VIA_CHALLENGE_RESPONSE", ! 459: [CR_VENDOR_NEC_FIRMWARE_REVISION] = "CR_VENDOR_NEC_FIRMWARE_REVISION", ! 460: [CR_VENDOR_NEC_CHALLENGE_RESPONSE] = "CR_VENDOR_NEC_CHALLENGE_RESPONSE", ! 461: }; ! 462: ! 463: static const char *lookup_name(uint32_t index, const char **list, uint32_t llen) ! 464: { ! 465: if (index >= llen || list[index] == NULL) { ! 466: return "???"; ! 467: } ! 468: return list[index]; ! 469: } ! 470: ! 471: static const char *trb_name(XHCITRB *trb) ! 472: { ! 473: return lookup_name(TRB_TYPE(*trb), TRBType_names, ! 474: ARRAY_SIZE(TRBType_names)); ! 475: } ! 476: #endif ! 477: ! 478: static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, ! 479: unsigned int epid); ! 480: ! 481: static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high) ! 482: { ! 483: if (sizeof(dma_addr_t) == 4) { ! 484: return low; ! 485: } else { ! 486: return low | (((dma_addr_t)high << 16) << 16); ! 487: } ! 488: } ! 489: ! 490: static inline dma_addr_t xhci_mask64(uint64_t addr) ! 491: { ! 492: if (sizeof(dma_addr_t) == 4) { ! 493: return addr & 0xffffffff; ! 494: } else { ! 495: return addr; ! 496: } ! 497: } ! 498: ! 499: static void xhci_irq_update(XHCIState *xhci) ! 500: { ! 501: int level = 0; ! 502: ! 503: if (xhci->iman & IMAN_IP && xhci->iman & IMAN_IE && ! 504: xhci->usbcmd & USBCMD_INTE) { ! 505: level = 1; ! 506: } ! 507: ! 508: DPRINTF("xhci_irq_update(): %d\n", level); ! 509: ! 510: if (xhci->msi && msi_enabled(&xhci->pci_dev)) { ! 511: if (level) { ! 512: DPRINTF("xhci_irq_update(): MSI signal\n"); ! 513: msi_notify(&xhci->pci_dev, 0); ! 514: } ! 515: } else { ! 516: qemu_set_irq(xhci->irq, level); ! 517: } ! 518: } ! 519: ! 520: static inline int xhci_running(XHCIState *xhci) ! 521: { ! 522: return !(xhci->usbsts & USBSTS_HCH) && !xhci->er_full; ! 523: } ! 524: ! 525: static void xhci_die(XHCIState *xhci) ! 526: { ! 527: xhci->usbsts |= USBSTS_HCE; ! 528: fprintf(stderr, "xhci: asserted controller error\n"); ! 529: } ! 530: ! 531: static void xhci_write_event(XHCIState *xhci, XHCIEvent *event) ! 532: { ! 533: XHCITRB ev_trb; ! 534: dma_addr_t addr; ! 535: ! 536: ev_trb.parameter = cpu_to_le64(event->ptr); ! 537: ev_trb.status = cpu_to_le32(event->length | (event->ccode << 24)); ! 538: ev_trb.control = (event->slotid << 24) | (event->epid << 16) | ! 539: event->flags | (event->type << TRB_TYPE_SHIFT); ! 540: if (xhci->er_pcs) { ! 541: ev_trb.control |= TRB_C; ! 542: } ! 543: ev_trb.control = cpu_to_le32(ev_trb.control); ! 544: ! 545: DPRINTF("xhci_write_event(): [%d] %016"PRIx64" %08x %08x %s\n", ! 546: xhci->er_ep_idx, ev_trb.parameter, ev_trb.status, ev_trb.control, ! 547: trb_name(&ev_trb)); ! 548: ! 549: addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx; ! 550: pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE); ! 551: ! 552: xhci->er_ep_idx++; ! 553: if (xhci->er_ep_idx >= xhci->er_size) { ! 554: xhci->er_ep_idx = 0; ! 555: xhci->er_pcs = !xhci->er_pcs; ! 556: } ! 557: } ! 558: ! 559: static void xhci_events_update(XHCIState *xhci) ! 560: { ! 561: dma_addr_t erdp; ! 562: unsigned int dp_idx; ! 563: bool do_irq = 0; ! 564: ! 565: if (xhci->usbsts & USBSTS_HCH) { ! 566: return; ! 567: } ! 568: ! 569: erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); ! 570: if (erdp < xhci->er_start || ! 571: erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { ! 572: fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp); ! 573: fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n", ! 574: xhci->er_start, xhci->er_size); ! 575: xhci_die(xhci); ! 576: return; ! 577: } ! 578: dp_idx = (erdp - xhci->er_start) / TRB_SIZE; ! 579: assert(dp_idx < xhci->er_size); ! 580: ! 581: /* NEC didn't read section 4.9.4 of the spec (v1.0 p139 top Note) and thus ! 582: * deadlocks when the ER is full. Hack it by holding off events until ! 583: * the driver decides to free at least half of the ring */ ! 584: if (xhci->er_full) { ! 585: int er_free = dp_idx - xhci->er_ep_idx; ! 586: if (er_free <= 0) { ! 587: er_free += xhci->er_size; ! 588: } ! 589: if (er_free < (xhci->er_size/2)) { ! 590: DPRINTF("xhci_events_update(): event ring still " ! 591: "more than half full (hack)\n"); ! 592: return; ! 593: } ! 594: } ! 595: ! 596: while (xhci->ev_buffer_put != xhci->ev_buffer_get) { ! 597: assert(xhci->er_full); ! 598: if (((xhci->er_ep_idx+1) % xhci->er_size) == dp_idx) { ! 599: DPRINTF("xhci_events_update(): event ring full again\n"); ! 600: #ifndef ER_FULL_HACK ! 601: XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR}; ! 602: xhci_write_event(xhci, &full); ! 603: #endif ! 604: do_irq = 1; ! 605: break; ! 606: } ! 607: XHCIEvent *event = &xhci->ev_buffer[xhci->ev_buffer_get]; ! 608: xhci_write_event(xhci, event); ! 609: xhci->ev_buffer_get++; ! 610: do_irq = 1; ! 611: if (xhci->ev_buffer_get == EV_QUEUE) { ! 612: xhci->ev_buffer_get = 0; ! 613: } ! 614: } ! 615: ! 616: if (do_irq) { ! 617: xhci->erdp_low |= ERDP_EHB; ! 618: xhci->iman |= IMAN_IP; ! 619: xhci->usbsts |= USBSTS_EINT; ! 620: xhci_irq_update(xhci); ! 621: } ! 622: ! 623: if (xhci->er_full && xhci->ev_buffer_put == xhci->ev_buffer_get) { ! 624: DPRINTF("xhci_events_update(): event ring no longer full\n"); ! 625: xhci->er_full = 0; ! 626: } ! 627: return; ! 628: } ! 629: ! 630: static void xhci_event(XHCIState *xhci, XHCIEvent *event) ! 631: { ! 632: dma_addr_t erdp; ! 633: unsigned int dp_idx; ! 634: ! 635: if (xhci->er_full) { ! 636: DPRINTF("xhci_event(): ER full, queueing\n"); ! 637: if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) { ! 638: fprintf(stderr, "xhci: event queue full, dropping event!\n"); ! 639: return; ! 640: } ! 641: xhci->ev_buffer[xhci->ev_buffer_put++] = *event; ! 642: if (xhci->ev_buffer_put == EV_QUEUE) { ! 643: xhci->ev_buffer_put = 0; ! 644: } ! 645: return; ! 646: } ! 647: ! 648: erdp = xhci_addr64(xhci->erdp_low, xhci->erdp_high); ! 649: if (erdp < xhci->er_start || ! 650: erdp >= (xhci->er_start + TRB_SIZE*xhci->er_size)) { ! 651: fprintf(stderr, "xhci: ERDP out of bounds: "DMA_ADDR_FMT"\n", erdp); ! 652: fprintf(stderr, "xhci: ER at "DMA_ADDR_FMT" len %d\n", ! 653: xhci->er_start, xhci->er_size); ! 654: xhci_die(xhci); ! 655: return; ! 656: } ! 657: ! 658: dp_idx = (erdp - xhci->er_start) / TRB_SIZE; ! 659: assert(dp_idx < xhci->er_size); ! 660: ! 661: if ((xhci->er_ep_idx+1) % xhci->er_size == dp_idx) { ! 662: DPRINTF("xhci_event(): ER full, queueing\n"); ! 663: #ifndef ER_FULL_HACK ! 664: XHCIEvent full = {ER_HOST_CONTROLLER, CC_EVENT_RING_FULL_ERROR}; ! 665: xhci_write_event(xhci, &full); ! 666: #endif ! 667: xhci->er_full = 1; ! 668: if (((xhci->ev_buffer_put+1) % EV_QUEUE) == xhci->ev_buffer_get) { ! 669: fprintf(stderr, "xhci: event queue full, dropping event!\n"); ! 670: return; ! 671: } ! 672: xhci->ev_buffer[xhci->ev_buffer_put++] = *event; ! 673: if (xhci->ev_buffer_put == EV_QUEUE) { ! 674: xhci->ev_buffer_put = 0; ! 675: } ! 676: } else { ! 677: xhci_write_event(xhci, event); ! 678: } ! 679: ! 680: xhci->erdp_low |= ERDP_EHB; ! 681: xhci->iman |= IMAN_IP; ! 682: xhci->usbsts |= USBSTS_EINT; ! 683: ! 684: xhci_irq_update(xhci); ! 685: } ! 686: ! 687: static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring, ! 688: dma_addr_t base) ! 689: { ! 690: ring->base = base; ! 691: ring->dequeue = base; ! 692: ring->ccs = 1; ! 693: } ! 694: ! 695: static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb, ! 696: dma_addr_t *addr) ! 697: { ! 698: while (1) { ! 699: TRBType type; ! 700: pci_dma_read(&xhci->pci_dev, ring->dequeue, trb, TRB_SIZE); ! 701: trb->addr = ring->dequeue; ! 702: trb->ccs = ring->ccs; ! 703: le64_to_cpus(&trb->parameter); ! 704: le32_to_cpus(&trb->status); ! 705: le32_to_cpus(&trb->control); ! 706: ! 707: DPRINTF("xhci: TRB fetched [" DMA_ADDR_FMT "]: " ! 708: "%016" PRIx64 " %08x %08x %s\n", ! 709: ring->dequeue, trb->parameter, trb->status, trb->control, ! 710: trb_name(trb)); ! 711: ! 712: if ((trb->control & TRB_C) != ring->ccs) { ! 713: return 0; ! 714: } ! 715: ! 716: type = TRB_TYPE(*trb); ! 717: ! 718: if (type != TR_LINK) { ! 719: if (addr) { ! 720: *addr = ring->dequeue; ! 721: } ! 722: ring->dequeue += TRB_SIZE; ! 723: return type; ! 724: } else { ! 725: ring->dequeue = xhci_mask64(trb->parameter); ! 726: if (trb->control & TRB_LK_TC) { ! 727: ring->ccs = !ring->ccs; ! 728: } ! 729: } ! 730: } ! 731: } ! 732: ! 733: static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) ! 734: { ! 735: XHCITRB trb; ! 736: int length = 0; ! 737: dma_addr_t dequeue = ring->dequeue; ! 738: bool ccs = ring->ccs; ! 739: /* hack to bundle together the two/three TDs that make a setup transfer */ ! 740: bool control_td_set = 0; ! 741: ! 742: while (1) { ! 743: TRBType type; ! 744: pci_dma_read(&xhci->pci_dev, dequeue, &trb, TRB_SIZE); ! 745: le64_to_cpus(&trb.parameter); ! 746: le32_to_cpus(&trb.status); ! 747: le32_to_cpus(&trb.control); ! 748: ! 749: DPRINTF("xhci: TRB peeked [" DMA_ADDR_FMT "]: " ! 750: "%016" PRIx64 " %08x %08x\n", ! 751: dequeue, trb.parameter, trb.status, trb.control); ! 752: ! 753: if ((trb.control & TRB_C) != ccs) { ! 754: return -length; ! 755: } ! 756: ! 757: type = TRB_TYPE(trb); ! 758: ! 759: if (type == TR_LINK) { ! 760: dequeue = xhci_mask64(trb.parameter); ! 761: if (trb.control & TRB_LK_TC) { ! 762: ccs = !ccs; ! 763: } ! 764: continue; ! 765: } ! 766: ! 767: length += 1; ! 768: dequeue += TRB_SIZE; ! 769: ! 770: if (type == TR_SETUP) { ! 771: control_td_set = 1; ! 772: } else if (type == TR_STATUS) { ! 773: control_td_set = 0; ! 774: } ! 775: ! 776: if (!control_td_set && !(trb.control & TRB_TR_CH)) { ! 777: return length; ! 778: } ! 779: } ! 780: } ! 781: ! 782: static void xhci_er_reset(XHCIState *xhci) ! 783: { ! 784: XHCIEvRingSeg seg; ! 785: ! 786: /* cache the (sole) event ring segment location */ ! 787: if (xhci->erstsz != 1) { ! 788: fprintf(stderr, "xhci: invalid value for ERSTSZ: %d\n", xhci->erstsz); ! 789: xhci_die(xhci); ! 790: return; ! 791: } ! 792: dma_addr_t erstba = xhci_addr64(xhci->erstba_low, xhci->erstba_high); ! 793: pci_dma_read(&xhci->pci_dev, erstba, &seg, sizeof(seg)); ! 794: le32_to_cpus(&seg.addr_low); ! 795: le32_to_cpus(&seg.addr_high); ! 796: le32_to_cpus(&seg.size); ! 797: if (seg.size < 16 || seg.size > 4096) { ! 798: fprintf(stderr, "xhci: invalid value for segment size: %d\n", seg.size); ! 799: xhci_die(xhci); ! 800: return; ! 801: } ! 802: xhci->er_start = xhci_addr64(seg.addr_low, seg.addr_high); ! 803: xhci->er_size = seg.size; ! 804: ! 805: xhci->er_ep_idx = 0; ! 806: xhci->er_pcs = 1; ! 807: xhci->er_full = 0; ! 808: ! 809: DPRINTF("xhci: event ring:" DMA_ADDR_FMT " [%d]\n", ! 810: xhci->er_start, xhci->er_size); ! 811: } ! 812: ! 813: static void xhci_run(XHCIState *xhci) ! 814: { ! 815: DPRINTF("xhci_run()\n"); ! 816: ! 817: xhci->usbsts &= ~USBSTS_HCH; ! 818: } ! 819: ! 820: static void xhci_stop(XHCIState *xhci) ! 821: { ! 822: DPRINTF("xhci_stop()\n"); ! 823: xhci->usbsts |= USBSTS_HCH; ! 824: xhci->crcr_low &= ~CRCR_CRR; ! 825: } ! 826: ! 827: static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx, ! 828: uint32_t state) ! 829: { ! 830: uint32_t ctx[5]; ! 831: if (epctx->state == state) { ! 832: return; ! 833: } ! 834: ! 835: pci_dma_read(&xhci->pci_dev, epctx->pctx, ctx, sizeof(ctx)); ! 836: ctx[0] &= ~EP_STATE_MASK; ! 837: ctx[0] |= state; ! 838: ctx[2] = epctx->ring.dequeue | epctx->ring.ccs; ! 839: ctx[3] = (epctx->ring.dequeue >> 16) >> 16; ! 840: DPRINTF("xhci: set epctx: " DMA_ADDR_FMT " state=%d dequeue=%08x%08x\n", ! 841: epctx->pctx, state, ctx[3], ctx[2]); ! 842: pci_dma_write(&xhci->pci_dev, epctx->pctx, ctx, sizeof(ctx)); ! 843: epctx->state = state; ! 844: } ! 845: ! 846: static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid, ! 847: unsigned int epid, dma_addr_t pctx, ! 848: uint32_t *ctx) ! 849: { ! 850: XHCISlot *slot; ! 851: XHCIEPContext *epctx; ! 852: dma_addr_t dequeue; ! 853: int i; ! 854: ! 855: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 856: assert(epid >= 1 && epid <= 31); ! 857: ! 858: DPRINTF("xhci_enable_ep(%d, %d)\n", slotid, epid); ! 859: ! 860: slot = &xhci->slots[slotid-1]; ! 861: if (slot->eps[epid-1]) { ! 862: fprintf(stderr, "xhci: slot %d ep %d already enabled!\n", slotid, epid); ! 863: return CC_TRB_ERROR; ! 864: } ! 865: ! 866: epctx = g_malloc(sizeof(XHCIEPContext)); ! 867: memset(epctx, 0, sizeof(XHCIEPContext)); ! 868: ! 869: slot->eps[epid-1] = epctx; ! 870: ! 871: dequeue = xhci_addr64(ctx[2] & ~0xf, ctx[3]); ! 872: xhci_ring_init(xhci, &epctx->ring, dequeue); ! 873: epctx->ring.ccs = ctx[2] & 1; ! 874: ! 875: epctx->type = (ctx[1] >> EP_TYPE_SHIFT) & EP_TYPE_MASK; ! 876: DPRINTF("xhci: endpoint %d.%d type is %d\n", epid/2, epid%2, epctx->type); ! 877: epctx->pctx = pctx; ! 878: epctx->max_psize = ctx[1]>>16; ! 879: epctx->max_psize *= 1+((ctx[1]>>8)&0xff); ! 880: epctx->has_bg = false; ! 881: if (epctx->type == ET_ISO_IN) { ! 882: epctx->has_bg = true; ! 883: } ! 884: DPRINTF("xhci: endpoint %d.%d max transaction (burst) size is %d\n", ! 885: epid/2, epid%2, epctx->max_psize); ! 886: for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) { ! 887: usb_packet_init(&epctx->transfers[i].packet); ! 888: } ! 889: ! 890: epctx->state = EP_RUNNING; ! 891: ctx[0] &= ~EP_STATE_MASK; ! 892: ctx[0] |= EP_RUNNING; ! 893: ! 894: return CC_SUCCESS; ! 895: } ! 896: ! 897: static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid, ! 898: unsigned int epid) ! 899: { ! 900: XHCISlot *slot; ! 901: XHCIEPContext *epctx; ! 902: int i, xferi, killed = 0; ! 903: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 904: assert(epid >= 1 && epid <= 31); ! 905: ! 906: DPRINTF("xhci_ep_nuke_xfers(%d, %d)\n", slotid, epid); ! 907: ! 908: slot = &xhci->slots[slotid-1]; ! 909: ! 910: if (!slot->eps[epid-1]) { ! 911: return 0; ! 912: } ! 913: ! 914: epctx = slot->eps[epid-1]; ! 915: ! 916: xferi = epctx->next_xfer; ! 917: for (i = 0; i < TD_QUEUE; i++) { ! 918: XHCITransfer *t = &epctx->transfers[xferi]; ! 919: if (t->running_async) { ! 920: usb_cancel_packet(&t->packet); ! 921: t->running_async = 0; ! 922: t->cancelled = 1; ! 923: DPRINTF("xhci: cancelling transfer %d, waiting for it to complete...\n", i); ! 924: killed++; ! 925: } ! 926: if (t->running_retry) { ! 927: t->running_retry = 0; ! 928: epctx->retry = NULL; ! 929: } ! 930: if (t->backgrounded) { ! 931: t->backgrounded = 0; ! 932: } ! 933: if (t->trbs) { ! 934: g_free(t->trbs); ! 935: } ! 936: if (t->data) { ! 937: g_free(t->data); ! 938: } ! 939: ! 940: t->trbs = NULL; ! 941: t->data = NULL; ! 942: t->trb_count = t->trb_alloced = 0; ! 943: t->data_length = t->data_alloced = 0; ! 944: xferi = (xferi + 1) % TD_QUEUE; ! 945: } ! 946: if (epctx->has_bg) { ! 947: xferi = epctx->next_bg; ! 948: for (i = 0; i < BG_XFERS; i++) { ! 949: XHCITransfer *t = &epctx->bg_transfers[xferi]; ! 950: if (t->running_async) { ! 951: usb_cancel_packet(&t->packet); ! 952: t->running_async = 0; ! 953: t->cancelled = 1; ! 954: DPRINTF("xhci: cancelling bg transfer %d, waiting for it to complete...\n", i); ! 955: killed++; ! 956: } ! 957: if (t->data) { ! 958: g_free(t->data); ! 959: } ! 960: ! 961: t->data = NULL; ! 962: xferi = (xferi + 1) % BG_XFERS; ! 963: } ! 964: } ! 965: return killed; ! 966: } ! 967: ! 968: static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid, ! 969: unsigned int epid) ! 970: { ! 971: XHCISlot *slot; ! 972: XHCIEPContext *epctx; ! 973: ! 974: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 975: assert(epid >= 1 && epid <= 31); ! 976: ! 977: DPRINTF("xhci_disable_ep(%d, %d)\n", slotid, epid); ! 978: ! 979: slot = &xhci->slots[slotid-1]; ! 980: ! 981: if (!slot->eps[epid-1]) { ! 982: DPRINTF("xhci: slot %d ep %d already disabled\n", slotid, epid); ! 983: return CC_SUCCESS; ! 984: } ! 985: ! 986: xhci_ep_nuke_xfers(xhci, slotid, epid); ! 987: ! 988: epctx = slot->eps[epid-1]; ! 989: ! 990: xhci_set_ep_state(xhci, epctx, EP_DISABLED); ! 991: ! 992: g_free(epctx); ! 993: slot->eps[epid-1] = NULL; ! 994: ! 995: return CC_SUCCESS; ! 996: } ! 997: ! 998: static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned int slotid, ! 999: unsigned int epid) ! 1000: { ! 1001: XHCISlot *slot; ! 1002: XHCIEPContext *epctx; ! 1003: ! 1004: DPRINTF("xhci_stop_ep(%d, %d)\n", slotid, epid); ! 1005: ! 1006: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1007: ! 1008: if (epid < 1 || epid > 31) { ! 1009: fprintf(stderr, "xhci: bad ep %d\n", epid); ! 1010: return CC_TRB_ERROR; ! 1011: } ! 1012: ! 1013: slot = &xhci->slots[slotid-1]; ! 1014: ! 1015: if (!slot->eps[epid-1]) { ! 1016: DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid); ! 1017: return CC_EP_NOT_ENABLED_ERROR; ! 1018: } ! 1019: ! 1020: if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) { ! 1021: fprintf(stderr, "xhci: FIXME: endpoint stopped w/ xfers running, " ! 1022: "data might be lost\n"); ! 1023: } ! 1024: ! 1025: epctx = slot->eps[epid-1]; ! 1026: ! 1027: xhci_set_ep_state(xhci, epctx, EP_STOPPED); ! 1028: ! 1029: return CC_SUCCESS; ! 1030: } ! 1031: ! 1032: static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid, ! 1033: unsigned int epid) ! 1034: { ! 1035: XHCISlot *slot; ! 1036: XHCIEPContext *epctx; ! 1037: USBDevice *dev; ! 1038: ! 1039: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1040: ! 1041: DPRINTF("xhci_reset_ep(%d, %d)\n", slotid, epid); ! 1042: ! 1043: if (epid < 1 || epid > 31) { ! 1044: fprintf(stderr, "xhci: bad ep %d\n", epid); ! 1045: return CC_TRB_ERROR; ! 1046: } ! 1047: ! 1048: slot = &xhci->slots[slotid-1]; ! 1049: ! 1050: if (!slot->eps[epid-1]) { ! 1051: DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid); ! 1052: return CC_EP_NOT_ENABLED_ERROR; ! 1053: } ! 1054: ! 1055: epctx = slot->eps[epid-1]; ! 1056: ! 1057: if (epctx->state != EP_HALTED) { ! 1058: fprintf(stderr, "xhci: reset EP while EP %d not halted (%d)\n", ! 1059: epid, epctx->state); ! 1060: return CC_CONTEXT_STATE_ERROR; ! 1061: } ! 1062: ! 1063: if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) { ! 1064: fprintf(stderr, "xhci: FIXME: endpoint reset w/ xfers running, " ! 1065: "data might be lost\n"); ! 1066: } ! 1067: ! 1068: uint8_t ep = epid>>1; ! 1069: ! 1070: if (epid & 1) { ! 1071: ep |= 0x80; ! 1072: } ! 1073: ! 1074: dev = xhci->ports[xhci->slots[slotid-1].port-1].port.dev; ! 1075: if (!dev) { ! 1076: return CC_USB_TRANSACTION_ERROR; ! 1077: } ! 1078: ! 1079: xhci_set_ep_state(xhci, epctx, EP_STOPPED); ! 1080: ! 1081: return CC_SUCCESS; ! 1082: } ! 1083: ! 1084: static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid, ! 1085: unsigned int epid, uint64_t pdequeue) ! 1086: { ! 1087: XHCISlot *slot; ! 1088: XHCIEPContext *epctx; ! 1089: dma_addr_t dequeue; ! 1090: ! 1091: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1092: ! 1093: if (epid < 1 || epid > 31) { ! 1094: fprintf(stderr, "xhci: bad ep %d\n", epid); ! 1095: return CC_TRB_ERROR; ! 1096: } ! 1097: ! 1098: DPRINTF("xhci_set_ep_dequeue(%d, %d, %016"PRIx64")\n", slotid, epid, pdequeue); ! 1099: dequeue = xhci_mask64(pdequeue); ! 1100: ! 1101: slot = &xhci->slots[slotid-1]; ! 1102: ! 1103: if (!slot->eps[epid-1]) { ! 1104: DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid); ! 1105: return CC_EP_NOT_ENABLED_ERROR; ! 1106: } ! 1107: ! 1108: epctx = slot->eps[epid-1]; ! 1109: ! 1110: ! 1111: if (epctx->state != EP_STOPPED) { ! 1112: fprintf(stderr, "xhci: set EP dequeue pointer while EP %d not stopped\n", epid); ! 1113: return CC_CONTEXT_STATE_ERROR; ! 1114: } ! 1115: ! 1116: xhci_ring_init(xhci, &epctx->ring, dequeue & ~0xF); ! 1117: epctx->ring.ccs = dequeue & 1; ! 1118: ! 1119: xhci_set_ep_state(xhci, epctx, EP_STOPPED); ! 1120: ! 1121: return CC_SUCCESS; ! 1122: } ! 1123: ! 1124: static int xhci_xfer_data(XHCITransfer *xfer, uint8_t *data, ! 1125: unsigned int length, bool in_xfer, bool out_xfer, ! 1126: bool report) ! 1127: { ! 1128: int i; ! 1129: uint32_t edtla = 0; ! 1130: unsigned int transferred = 0; ! 1131: unsigned int left = length; ! 1132: bool reported = 0; ! 1133: bool shortpkt = 0; ! 1134: XHCIEvent event = {ER_TRANSFER, CC_SUCCESS}; ! 1135: XHCIState *xhci = xfer->xhci; ! 1136: ! 1137: DPRINTF("xhci_xfer_data(len=%d, in_xfer=%d, out_xfer=%d, report=%d)\n", ! 1138: length, in_xfer, out_xfer, report); ! 1139: ! 1140: assert(!(in_xfer && out_xfer)); ! 1141: ! 1142: for (i = 0; i < xfer->trb_count; i++) { ! 1143: XHCITRB *trb = &xfer->trbs[i]; ! 1144: dma_addr_t addr; ! 1145: unsigned int chunk = 0; ! 1146: ! 1147: switch (TRB_TYPE(*trb)) { ! 1148: case TR_DATA: ! 1149: if ((!(trb->control & TRB_TR_DIR)) != (!in_xfer)) { ! 1150: fprintf(stderr, "xhci: data direction mismatch for TR_DATA\n"); ! 1151: xhci_die(xhci); ! 1152: return transferred; ! 1153: } ! 1154: /* fallthrough */ ! 1155: case TR_NORMAL: ! 1156: case TR_ISOCH: ! 1157: addr = xhci_mask64(trb->parameter); ! 1158: chunk = trb->status & 0x1ffff; ! 1159: if (chunk > left) { ! 1160: chunk = left; ! 1161: shortpkt = 1; ! 1162: } ! 1163: if (in_xfer || out_xfer) { ! 1164: if (trb->control & TRB_TR_IDT) { ! 1165: uint64_t idata; ! 1166: if (chunk > 8 || in_xfer) { ! 1167: fprintf(stderr, "xhci: invalid immediate data TRB\n"); ! 1168: xhci_die(xhci); ! 1169: return transferred; ! 1170: } ! 1171: idata = le64_to_cpu(trb->parameter); ! 1172: memcpy(data, &idata, chunk); ! 1173: } else { ! 1174: DPRINTF("xhci_xfer_data: r/w(%d) %d bytes at " ! 1175: DMA_ADDR_FMT "\n", in_xfer, chunk, addr); ! 1176: if (in_xfer) { ! 1177: pci_dma_write(&xhci->pci_dev, addr, data, chunk); ! 1178: } else { ! 1179: pci_dma_read(&xhci->pci_dev, addr, data, chunk); ! 1180: } ! 1181: #ifdef DEBUG_DATA ! 1182: unsigned int count = chunk; ! 1183: int i; ! 1184: if (count > 16) { ! 1185: count = 16; ! 1186: } ! 1187: DPRINTF(" ::"); ! 1188: for (i = 0; i < count; i++) { ! 1189: DPRINTF(" %02x", data[i]); ! 1190: } ! 1191: DPRINTF("\n"); ! 1192: #endif ! 1193: } ! 1194: } ! 1195: left -= chunk; ! 1196: data += chunk; ! 1197: edtla += chunk; ! 1198: transferred += chunk; ! 1199: break; ! 1200: case TR_STATUS: ! 1201: reported = 0; ! 1202: shortpkt = 0; ! 1203: break; ! 1204: } ! 1205: ! 1206: if (report && !reported && (trb->control & TRB_TR_IOC || ! 1207: (shortpkt && (trb->control & TRB_TR_ISP)))) { ! 1208: event.slotid = xfer->slotid; ! 1209: event.epid = xfer->epid; ! 1210: event.length = (trb->status & 0x1ffff) - chunk; ! 1211: event.flags = 0; ! 1212: event.ptr = trb->addr; ! 1213: if (xfer->status == CC_SUCCESS) { ! 1214: event.ccode = shortpkt ? CC_SHORT_PACKET : CC_SUCCESS; ! 1215: } else { ! 1216: event.ccode = xfer->status; ! 1217: } ! 1218: if (TRB_TYPE(*trb) == TR_EVDATA) { ! 1219: event.ptr = trb->parameter; ! 1220: event.flags |= TRB_EV_ED; ! 1221: event.length = edtla & 0xffffff; ! 1222: DPRINTF("xhci_xfer_data: EDTLA=%d\n", event.length); ! 1223: edtla = 0; ! 1224: } ! 1225: xhci_event(xhci, &event); ! 1226: reported = 1; ! 1227: } ! 1228: } ! 1229: return transferred; ! 1230: } ! 1231: ! 1232: static void xhci_stall_ep(XHCITransfer *xfer) ! 1233: { ! 1234: XHCIState *xhci = xfer->xhci; ! 1235: XHCISlot *slot = &xhci->slots[xfer->slotid-1]; ! 1236: XHCIEPContext *epctx = slot->eps[xfer->epid-1]; ! 1237: ! 1238: epctx->ring.dequeue = xfer->trbs[0].addr; ! 1239: epctx->ring.ccs = xfer->trbs[0].ccs; ! 1240: xhci_set_ep_state(xhci, epctx, EP_HALTED); ! 1241: DPRINTF("xhci: stalled slot %d ep %d\n", xfer->slotid, xfer->epid); ! 1242: DPRINTF("xhci: will continue at "DMA_ADDR_FMT"\n", epctx->ring.dequeue); ! 1243: } ! 1244: ! 1245: static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, ! 1246: XHCIEPContext *epctx); ! 1247: ! 1248: static void xhci_bg_update(XHCIState *xhci, XHCIEPContext *epctx) ! 1249: { ! 1250: if (epctx->bg_updating) { ! 1251: return; ! 1252: } ! 1253: DPRINTF("xhci_bg_update(%p, %p)\n", xhci, epctx); ! 1254: assert(epctx->has_bg); ! 1255: DPRINTF("xhci: fg=%d bg=%d\n", epctx->comp_xfer, epctx->next_bg); ! 1256: epctx->bg_updating = 1; ! 1257: while (epctx->transfers[epctx->comp_xfer].backgrounded && ! 1258: epctx->bg_transfers[epctx->next_bg].complete) { ! 1259: XHCITransfer *fg = &epctx->transfers[epctx->comp_xfer]; ! 1260: XHCITransfer *bg = &epctx->bg_transfers[epctx->next_bg]; ! 1261: #if 0 ! 1262: DPRINTF("xhci: completing fg %d from bg %d.%d (stat: %d)\n", ! 1263: epctx->comp_xfer, epctx->next_bg, bg->cur_pkt, ! 1264: bg->usbxfer->iso_packet_desc[bg->cur_pkt].status ! 1265: ); ! 1266: #endif ! 1267: assert(epctx->type == ET_ISO_IN); ! 1268: assert(bg->iso_xfer); ! 1269: assert(bg->in_xfer); ! 1270: uint8_t *p = bg->data + bg->cur_pkt * bg->pktsize; ! 1271: #if 0 ! 1272: int len = bg->usbxfer->iso_packet_desc[bg->cur_pkt].actual_length; ! 1273: fg->status = libusb_to_ccode(bg->usbxfer->iso_packet_desc[bg->cur_pkt].status); ! 1274: #else ! 1275: int len = 0; ! 1276: FIXME(); ! 1277: #endif ! 1278: fg->complete = 1; ! 1279: fg->backgrounded = 0; ! 1280: ! 1281: if (fg->status == CC_STALL_ERROR) { ! 1282: xhci_stall_ep(fg); ! 1283: } ! 1284: ! 1285: xhci_xfer_data(fg, p, len, 1, 0, 1); ! 1286: ! 1287: epctx->comp_xfer++; ! 1288: if (epctx->comp_xfer == TD_QUEUE) { ! 1289: epctx->comp_xfer = 0; ! 1290: } ! 1291: DPRINTF("next fg xfer: %d\n", epctx->comp_xfer); ! 1292: bg->cur_pkt++; ! 1293: if (bg->cur_pkt == bg->pkts) { ! 1294: bg->complete = 0; ! 1295: if (xhci_submit(xhci, bg, epctx) < 0) { ! 1296: fprintf(stderr, "xhci: bg resubmit failed\n"); ! 1297: } ! 1298: epctx->next_bg++; ! 1299: if (epctx->next_bg == BG_XFERS) { ! 1300: epctx->next_bg = 0; ! 1301: } ! 1302: DPRINTF("next bg xfer: %d\n", epctx->next_bg); ! 1303: ! 1304: xhci_kick_ep(xhci, fg->slotid, fg->epid); ! 1305: } ! 1306: } ! 1307: epctx->bg_updating = 0; ! 1308: } ! 1309: ! 1310: #if 0 ! 1311: static void xhci_xfer_cb(struct libusb_transfer *transfer) ! 1312: { ! 1313: XHCIState *xhci; ! 1314: XHCITransfer *xfer; ! 1315: ! 1316: xfer = (XHCITransfer *)transfer->user_data; ! 1317: xhci = xfer->xhci; ! 1318: ! 1319: DPRINTF("xhci_xfer_cb(slot=%d, ep=%d, status=%d)\n", xfer->slotid, ! 1320: xfer->epid, transfer->status); ! 1321: ! 1322: assert(xfer->slotid >= 1 && xfer->slotid <= MAXSLOTS); ! 1323: assert(xfer->epid >= 1 && xfer->epid <= 31); ! 1324: ! 1325: if (xfer->cancelled) { ! 1326: DPRINTF("xhci: transfer cancelled, not reporting anything\n"); ! 1327: xfer->running = 0; ! 1328: return; ! 1329: } ! 1330: ! 1331: XHCIEPContext *epctx; ! 1332: XHCISlot *slot; ! 1333: slot = &xhci->slots[xfer->slotid-1]; ! 1334: assert(slot->eps[xfer->epid-1]); ! 1335: epctx = slot->eps[xfer->epid-1]; ! 1336: ! 1337: if (xfer->bg_xfer) { ! 1338: DPRINTF("xhci: background transfer, updating\n"); ! 1339: xfer->complete = 1; ! 1340: xfer->running = 0; ! 1341: xhci_bg_update(xhci, epctx); ! 1342: return; ! 1343: } ! 1344: ! 1345: if (xfer->iso_xfer) { ! 1346: transfer->status = transfer->iso_packet_desc[0].status; ! 1347: transfer->actual_length = transfer->iso_packet_desc[0].actual_length; ! 1348: } ! 1349: ! 1350: xfer->status = libusb_to_ccode(transfer->status); ! 1351: ! 1352: xfer->complete = 1; ! 1353: xfer->running = 0; ! 1354: ! 1355: if (transfer->status == LIBUSB_TRANSFER_STALL) ! 1356: xhci_stall_ep(xhci, epctx, xfer); ! 1357: ! 1358: DPRINTF("xhci: transfer actual length = %d\n", transfer->actual_length); ! 1359: ! 1360: if (xfer->in_xfer) { ! 1361: if (xfer->epid == 1) { ! 1362: xhci_xfer_data(xhci, xfer, xfer->data + 8, ! 1363: transfer->actual_length, 1, 0, 1); ! 1364: } else { ! 1365: xhci_xfer_data(xhci, xfer, xfer->data, ! 1366: transfer->actual_length, 1, 0, 1); ! 1367: } ! 1368: } else { ! 1369: xhci_xfer_data(xhci, xfer, NULL, transfer->actual_length, 0, 0, 1); ! 1370: } ! 1371: ! 1372: xhci_kick_ep(xhci, xfer->slotid, xfer->epid); ! 1373: } ! 1374: ! 1375: static int xhci_hle_control(XHCIState *xhci, XHCITransfer *xfer, ! 1376: uint8_t bmRequestType, uint8_t bRequest, ! 1377: uint16_t wValue, uint16_t wIndex, uint16_t wLength) ! 1378: { ! 1379: uint16_t type_req = (bmRequestType << 8) | bRequest; ! 1380: ! 1381: switch (type_req) { ! 1382: case 0x0000 | USB_REQ_SET_CONFIGURATION: ! 1383: DPRINTF("xhci: HLE switch configuration\n"); ! 1384: return xhci_switch_config(xhci, xfer->slotid, wValue) == 0; ! 1385: case 0x0100 | USB_REQ_SET_INTERFACE: ! 1386: DPRINTF("xhci: HLE set interface altsetting\n"); ! 1387: return xhci_set_iface_alt(xhci, xfer->slotid, wIndex, wValue) == 0; ! 1388: case 0x0200 | USB_REQ_CLEAR_FEATURE: ! 1389: if (wValue == 0) { // endpoint halt ! 1390: DPRINTF("xhci: HLE clear halt\n"); ! 1391: return xhci_clear_halt(xhci, xfer->slotid, wIndex); ! 1392: } ! 1393: case 0x0000 | USB_REQ_SET_ADDRESS: ! 1394: fprintf(stderr, "xhci: warn: illegal SET_ADDRESS request\n"); ! 1395: return 0; ! 1396: default: ! 1397: return 0; ! 1398: } ! 1399: } ! 1400: #endif ! 1401: ! 1402: static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev) ! 1403: { ! 1404: USBEndpoint *ep; ! 1405: int dir; ! 1406: ! 1407: dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT; ! 1408: ep = usb_ep_get(dev, dir, xfer->epid >> 1); ! 1409: usb_packet_setup(&xfer->packet, dir, ep); ! 1410: usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length); ! 1411: DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n", ! 1412: xfer->packet.pid, dev->addr, ep->nr); ! 1413: return 0; ! 1414: } ! 1415: ! 1416: static int xhci_complete_packet(XHCITransfer *xfer, int ret) ! 1417: { ! 1418: if (ret == USB_RET_ASYNC) { ! 1419: xfer->running_async = 1; ! 1420: xfer->running_retry = 0; ! 1421: xfer->complete = 0; ! 1422: xfer->cancelled = 0; ! 1423: return 0; ! 1424: } else if (ret == USB_RET_NAK) { ! 1425: xfer->running_async = 0; ! 1426: xfer->running_retry = 1; ! 1427: xfer->complete = 0; ! 1428: xfer->cancelled = 0; ! 1429: return 0; ! 1430: } else { ! 1431: xfer->running_async = 0; ! 1432: xfer->running_retry = 0; ! 1433: xfer->complete = 1; ! 1434: } ! 1435: ! 1436: if (ret >= 0) { ! 1437: xfer->status = CC_SUCCESS; ! 1438: xhci_xfer_data(xfer, xfer->data, ret, xfer->in_xfer, 0, 1); ! 1439: return 0; ! 1440: } ! 1441: ! 1442: /* error */ ! 1443: switch (ret) { ! 1444: case USB_RET_NODEV: ! 1445: xfer->status = CC_USB_TRANSACTION_ERROR; ! 1446: xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1); ! 1447: xhci_stall_ep(xfer); ! 1448: break; ! 1449: case USB_RET_STALL: ! 1450: xfer->status = CC_STALL_ERROR; ! 1451: xhci_xfer_data(xfer, xfer->data, 0, xfer->in_xfer, 0, 1); ! 1452: xhci_stall_ep(xfer); ! 1453: break; ! 1454: default: ! 1455: fprintf(stderr, "%s: FIXME: ret = %d\n", __FUNCTION__, ret); ! 1456: FIXME(); ! 1457: } ! 1458: return 0; ! 1459: } ! 1460: ! 1461: static USBDevice *xhci_find_device(XHCIPort *port, uint8_t addr) ! 1462: { ! 1463: if (!(port->portsc & PORTSC_PED)) { ! 1464: return NULL; ! 1465: } ! 1466: return usb_find_device(&port->port, addr); ! 1467: } ! 1468: ! 1469: static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer) ! 1470: { ! 1471: XHCITRB *trb_setup, *trb_status; ! 1472: uint8_t bmRequestType; ! 1473: uint16_t wLength; ! 1474: XHCIPort *port; ! 1475: USBDevice *dev; ! 1476: int ret; ! 1477: ! 1478: DPRINTF("xhci_fire_ctl_transfer(slot=%d)\n", xfer->slotid); ! 1479: ! 1480: trb_setup = &xfer->trbs[0]; ! 1481: trb_status = &xfer->trbs[xfer->trb_count-1]; ! 1482: ! 1483: /* at most one Event Data TRB allowed after STATUS */ ! 1484: if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) { ! 1485: trb_status--; ! 1486: } ! 1487: ! 1488: /* do some sanity checks */ ! 1489: if (TRB_TYPE(*trb_setup) != TR_SETUP) { ! 1490: fprintf(stderr, "xhci: ep0 first TD not SETUP: %d\n", ! 1491: TRB_TYPE(*trb_setup)); ! 1492: return -1; ! 1493: } ! 1494: if (TRB_TYPE(*trb_status) != TR_STATUS) { ! 1495: fprintf(stderr, "xhci: ep0 last TD not STATUS: %d\n", ! 1496: TRB_TYPE(*trb_status)); ! 1497: return -1; ! 1498: } ! 1499: if (!(trb_setup->control & TRB_TR_IDT)) { ! 1500: fprintf(stderr, "xhci: Setup TRB doesn't have IDT set\n"); ! 1501: return -1; ! 1502: } ! 1503: if ((trb_setup->status & 0x1ffff) != 8) { ! 1504: fprintf(stderr, "xhci: Setup TRB has bad length (%d)\n", ! 1505: (trb_setup->status & 0x1ffff)); ! 1506: return -1; ! 1507: } ! 1508: ! 1509: bmRequestType = trb_setup->parameter; ! 1510: wLength = trb_setup->parameter >> 48; ! 1511: ! 1512: if (xfer->data && xfer->data_alloced < wLength) { ! 1513: xfer->data_alloced = 0; ! 1514: g_free(xfer->data); ! 1515: xfer->data = NULL; ! 1516: } ! 1517: if (!xfer->data) { ! 1518: DPRINTF("xhci: alloc %d bytes data\n", wLength); ! 1519: xfer->data = g_malloc(wLength+1); ! 1520: xfer->data_alloced = wLength; ! 1521: } ! 1522: xfer->data_length = wLength; ! 1523: ! 1524: port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; ! 1525: dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); ! 1526: if (!dev) { ! 1527: fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, ! 1528: xhci->slots[xfer->slotid-1].port); ! 1529: return -1; ! 1530: } ! 1531: ! 1532: xfer->in_xfer = bmRequestType & USB_DIR_IN; ! 1533: xfer->iso_xfer = false; ! 1534: ! 1535: xhci_setup_packet(xfer, dev); ! 1536: xfer->packet.parameter = trb_setup->parameter; ! 1537: if (!xfer->in_xfer) { ! 1538: xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0); ! 1539: } ! 1540: ! 1541: ret = usb_handle_packet(dev, &xfer->packet); ! 1542: ! 1543: xhci_complete_packet(xfer, ret); ! 1544: if (!xfer->running_async && !xfer->running_retry) { ! 1545: xhci_kick_ep(xhci, xfer->slotid, xfer->epid); ! 1546: } ! 1547: return 0; ! 1548: } ! 1549: ! 1550: static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx) ! 1551: { ! 1552: XHCIPort *port; ! 1553: USBDevice *dev; ! 1554: int ret; ! 1555: ! 1556: DPRINTF("xhci_submit(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); ! 1557: ! 1558: xfer->in_xfer = epctx->type>>2; ! 1559: ! 1560: if (xfer->data && xfer->data_alloced < xfer->data_length) { ! 1561: xfer->data_alloced = 0; ! 1562: g_free(xfer->data); ! 1563: xfer->data = NULL; ! 1564: } ! 1565: if (!xfer->data && xfer->data_length) { ! 1566: DPRINTF("xhci: alloc %d bytes data\n", xfer->data_length); ! 1567: xfer->data = g_malloc(xfer->data_length); ! 1568: xfer->data_alloced = xfer->data_length; ! 1569: } ! 1570: if (epctx->type == ET_ISO_IN || epctx->type == ET_ISO_OUT) { ! 1571: if (!xfer->bg_xfer) { ! 1572: xfer->pkts = 1; ! 1573: } ! 1574: } else { ! 1575: xfer->pkts = 0; ! 1576: } ! 1577: ! 1578: port = &xhci->ports[xhci->slots[xfer->slotid-1].port-1]; ! 1579: dev = xhci_find_device(port, xhci->slots[xfer->slotid-1].devaddr); ! 1580: if (!dev) { ! 1581: fprintf(stderr, "xhci: slot %d port %d has no device\n", xfer->slotid, ! 1582: xhci->slots[xfer->slotid-1].port); ! 1583: return -1; ! 1584: } ! 1585: ! 1586: xhci_setup_packet(xfer, dev); ! 1587: ! 1588: switch(epctx->type) { ! 1589: case ET_INTR_OUT: ! 1590: case ET_INTR_IN: ! 1591: case ET_BULK_OUT: ! 1592: case ET_BULK_IN: ! 1593: break; ! 1594: case ET_ISO_OUT: ! 1595: case ET_ISO_IN: ! 1596: FIXME(); ! 1597: break; ! 1598: default: ! 1599: fprintf(stderr, "xhci: unknown or unhandled EP " ! 1600: "(type %d, in %d, ep %02x)\n", ! 1601: epctx->type, xfer->in_xfer, xfer->epid); ! 1602: return -1; ! 1603: } ! 1604: ! 1605: if (!xfer->in_xfer) { ! 1606: xhci_xfer_data(xfer, xfer->data, xfer->data_length, 0, 1, 0); ! 1607: } ! 1608: ret = usb_handle_packet(dev, &xfer->packet); ! 1609: ! 1610: xhci_complete_packet(xfer, ret); ! 1611: if (!xfer->running_async && !xfer->running_retry) { ! 1612: xhci_kick_ep(xhci, xfer->slotid, xfer->epid); ! 1613: } ! 1614: return 0; ! 1615: } ! 1616: ! 1617: static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx) ! 1618: { ! 1619: int i; ! 1620: unsigned int length = 0; ! 1621: XHCITRB *trb; ! 1622: ! 1623: DPRINTF("xhci_fire_transfer(slotid=%d,epid=%d)\n", xfer->slotid, xfer->epid); ! 1624: ! 1625: for (i = 0; i < xfer->trb_count; i++) { ! 1626: trb = &xfer->trbs[i]; ! 1627: if (TRB_TYPE(*trb) == TR_NORMAL || TRB_TYPE(*trb) == TR_ISOCH) { ! 1628: length += trb->status & 0x1ffff; ! 1629: } ! 1630: } ! 1631: DPRINTF("xhci: total TD length=%d\n", length); ! 1632: ! 1633: if (!epctx->has_bg) { ! 1634: xfer->data_length = length; ! 1635: xfer->backgrounded = 0; ! 1636: return xhci_submit(xhci, xfer, epctx); ! 1637: } else { ! 1638: if (!epctx->bg_running) { ! 1639: for (i = 0; i < BG_XFERS; i++) { ! 1640: XHCITransfer *t = &epctx->bg_transfers[i]; ! 1641: t->xhci = xhci; ! 1642: t->epid = xfer->epid; ! 1643: t->slotid = xfer->slotid; ! 1644: t->pkts = BG_PKTS; ! 1645: t->pktsize = epctx->max_psize; ! 1646: t->data_length = t->pkts * t->pktsize; ! 1647: t->bg_xfer = 1; ! 1648: if (xhci_submit(xhci, t, epctx) < 0) { ! 1649: fprintf(stderr, "xhci: bg submit failed\n"); ! 1650: return -1; ! 1651: } ! 1652: } ! 1653: epctx->bg_running = 1; ! 1654: } ! 1655: xfer->backgrounded = 1; ! 1656: xhci_bg_update(xhci, epctx); ! 1657: return 0; ! 1658: } ! 1659: } ! 1660: ! 1661: static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid) ! 1662: { ! 1663: XHCIEPContext *epctx; ! 1664: int length; ! 1665: int i; ! 1666: ! 1667: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1668: assert(epid >= 1 && epid <= 31); ! 1669: DPRINTF("xhci_kick_ep(%d, %d)\n", slotid, epid); ! 1670: ! 1671: if (!xhci->slots[slotid-1].enabled) { ! 1672: fprintf(stderr, "xhci: xhci_kick_ep for disabled slot %d\n", slotid); ! 1673: return; ! 1674: } ! 1675: epctx = xhci->slots[slotid-1].eps[epid-1]; ! 1676: if (!epctx) { ! 1677: fprintf(stderr, "xhci: xhci_kick_ep for disabled endpoint %d,%d\n", ! 1678: epid, slotid); ! 1679: return; ! 1680: } ! 1681: ! 1682: if (epctx->retry) { ! 1683: /* retry nak'ed transfer */ ! 1684: XHCITransfer *xfer = epctx->retry; ! 1685: int result; ! 1686: ! 1687: DPRINTF("xhci: retry nack'ed transfer ...\n"); ! 1688: assert(xfer->running_retry); ! 1689: xhci_setup_packet(xfer, xfer->packet.ep->dev); ! 1690: result = usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); ! 1691: if (result == USB_RET_NAK) { ! 1692: DPRINTF("xhci: ... xfer still nacked\n"); ! 1693: return; ! 1694: } ! 1695: DPRINTF("xhci: ... result %d\n", result); ! 1696: xhci_complete_packet(xfer, result); ! 1697: assert(!xfer->running_retry); ! 1698: epctx->retry = NULL; ! 1699: } ! 1700: ! 1701: if (epctx->state == EP_HALTED) { ! 1702: DPRINTF("xhci: ep halted, not running schedule\n"); ! 1703: return; ! 1704: } ! 1705: ! 1706: xhci_set_ep_state(xhci, epctx, EP_RUNNING); ! 1707: ! 1708: while (1) { ! 1709: XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer]; ! 1710: if (xfer->running_async || xfer->running_retry || xfer->backgrounded) { ! 1711: DPRINTF("xhci: ep is busy (#%d,%d,%d,%d)\n", ! 1712: epctx->next_xfer, xfer->running_async, ! 1713: xfer->running_retry, xfer->backgrounded); ! 1714: break; ! 1715: } else { ! 1716: DPRINTF("xhci: ep: using #%d\n", epctx->next_xfer); ! 1717: } ! 1718: length = xhci_ring_chain_length(xhci, &epctx->ring); ! 1719: if (length < 0) { ! 1720: DPRINTF("xhci: incomplete TD (%d TRBs)\n", -length); ! 1721: break; ! 1722: } else if (length == 0) { ! 1723: break; ! 1724: } ! 1725: DPRINTF("xhci: fetching %d-TRB TD\n", length); ! 1726: if (xfer->trbs && xfer->trb_alloced < length) { ! 1727: xfer->trb_count = 0; ! 1728: xfer->trb_alloced = 0; ! 1729: g_free(xfer->trbs); ! 1730: xfer->trbs = NULL; ! 1731: } ! 1732: if (!xfer->trbs) { ! 1733: xfer->trbs = g_malloc(sizeof(XHCITRB) * length); ! 1734: xfer->trb_alloced = length; ! 1735: } ! 1736: xfer->trb_count = length; ! 1737: ! 1738: for (i = 0; i < length; i++) { ! 1739: assert(xhci_ring_fetch(xhci, &epctx->ring, &xfer->trbs[i], NULL)); ! 1740: } ! 1741: xfer->xhci = xhci; ! 1742: xfer->epid = epid; ! 1743: xfer->slotid = slotid; ! 1744: ! 1745: if (epid == 1) { ! 1746: if (xhci_fire_ctl_transfer(xhci, xfer) >= 0) { ! 1747: epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE; ! 1748: } else { ! 1749: fprintf(stderr, "xhci: error firing CTL transfer\n"); ! 1750: } ! 1751: } else { ! 1752: if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) { ! 1753: epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE; ! 1754: } else { ! 1755: fprintf(stderr, "xhci: error firing data transfer\n"); ! 1756: } ! 1757: } ! 1758: ! 1759: if (epctx->state == EP_HALTED) { ! 1760: DPRINTF("xhci: ep halted, stopping schedule\n"); ! 1761: break; ! 1762: } ! 1763: if (xfer->running_retry) { ! 1764: DPRINTF("xhci: xfer nacked, stopping schedule\n"); ! 1765: epctx->retry = xfer; ! 1766: break; ! 1767: } ! 1768: } ! 1769: } ! 1770: ! 1771: static TRBCCode xhci_enable_slot(XHCIState *xhci, unsigned int slotid) ! 1772: { ! 1773: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1774: DPRINTF("xhci_enable_slot(%d)\n", slotid); ! 1775: xhci->slots[slotid-1].enabled = 1; ! 1776: xhci->slots[slotid-1].port = 0; ! 1777: memset(xhci->slots[slotid-1].eps, 0, sizeof(XHCIEPContext*)*31); ! 1778: ! 1779: return CC_SUCCESS; ! 1780: } ! 1781: ! 1782: static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid) ! 1783: { ! 1784: int i; ! 1785: ! 1786: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1787: DPRINTF("xhci_disable_slot(%d)\n", slotid); ! 1788: ! 1789: for (i = 1; i <= 31; i++) { ! 1790: if (xhci->slots[slotid-1].eps[i-1]) { ! 1791: xhci_disable_ep(xhci, slotid, i); ! 1792: } ! 1793: } ! 1794: ! 1795: xhci->slots[slotid-1].enabled = 0; ! 1796: return CC_SUCCESS; ! 1797: } ! 1798: ! 1799: static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, ! 1800: uint64_t pictx, bool bsr) ! 1801: { ! 1802: XHCISlot *slot; ! 1803: USBDevice *dev; ! 1804: dma_addr_t ictx, octx, dcbaap; ! 1805: uint64_t poctx; ! 1806: uint32_t ictl_ctx[2]; ! 1807: uint32_t slot_ctx[4]; ! 1808: uint32_t ep0_ctx[5]; ! 1809: unsigned int port; ! 1810: int i; ! 1811: TRBCCode res; ! 1812: ! 1813: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1814: DPRINTF("xhci_address_slot(%d)\n", slotid); ! 1815: ! 1816: dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high); ! 1817: pci_dma_read(&xhci->pci_dev, dcbaap + 8*slotid, &poctx, sizeof(poctx)); ! 1818: ictx = xhci_mask64(pictx); ! 1819: octx = xhci_mask64(le64_to_cpu(poctx)); ! 1820: ! 1821: DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx); ! 1822: DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx); ! 1823: ! 1824: pci_dma_read(&xhci->pci_dev, ictx, ictl_ctx, sizeof(ictl_ctx)); ! 1825: ! 1826: if (ictl_ctx[0] != 0x0 || ictl_ctx[1] != 0x3) { ! 1827: fprintf(stderr, "xhci: invalid input context control %08x %08x\n", ! 1828: ictl_ctx[0], ictl_ctx[1]); ! 1829: return CC_TRB_ERROR; ! 1830: } ! 1831: ! 1832: pci_dma_read(&xhci->pci_dev, ictx+32, slot_ctx, sizeof(slot_ctx)); ! 1833: pci_dma_read(&xhci->pci_dev, ictx+64, ep0_ctx, sizeof(ep0_ctx)); ! 1834: ! 1835: DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n", ! 1836: slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); ! 1837: ! 1838: DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n", ! 1839: ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]); ! 1840: ! 1841: port = (slot_ctx[1]>>16) & 0xFF; ! 1842: dev = xhci->ports[port-1].port.dev; ! 1843: ! 1844: if (port < 1 || port > MAXPORTS) { ! 1845: fprintf(stderr, "xhci: bad port %d\n", port); ! 1846: return CC_TRB_ERROR; ! 1847: } else if (!dev) { ! 1848: fprintf(stderr, "xhci: port %d not connected\n", port); ! 1849: return CC_USB_TRANSACTION_ERROR; ! 1850: } ! 1851: ! 1852: for (i = 0; i < MAXSLOTS; i++) { ! 1853: if (xhci->slots[i].port == port) { ! 1854: fprintf(stderr, "xhci: port %d already assigned to slot %d\n", ! 1855: port, i+1); ! 1856: return CC_TRB_ERROR; ! 1857: } ! 1858: } ! 1859: ! 1860: slot = &xhci->slots[slotid-1]; ! 1861: slot->port = port; ! 1862: slot->ctx = octx; ! 1863: ! 1864: if (bsr) { ! 1865: slot_ctx[3] = SLOT_DEFAULT << SLOT_STATE_SHIFT; ! 1866: } else { ! 1867: slot->devaddr = xhci->devaddr++; ! 1868: slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr; ! 1869: DPRINTF("xhci: device address is %d\n", slot->devaddr); ! 1870: usb_device_handle_control(dev, NULL, ! 1871: DeviceOutRequest | USB_REQ_SET_ADDRESS, ! 1872: slot->devaddr, 0, 0, NULL); ! 1873: } ! 1874: ! 1875: res = xhci_enable_ep(xhci, slotid, 1, octx+32, ep0_ctx); ! 1876: ! 1877: DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", ! 1878: slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); ! 1879: DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n", ! 1880: ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]); ! 1881: ! 1882: pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 1883: pci_dma_write(&xhci->pci_dev, octx+32, ep0_ctx, sizeof(ep0_ctx)); ! 1884: ! 1885: return res; ! 1886: } ! 1887: ! 1888: ! 1889: static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid, ! 1890: uint64_t pictx, bool dc) ! 1891: { ! 1892: dma_addr_t ictx, octx; ! 1893: uint32_t ictl_ctx[2]; ! 1894: uint32_t slot_ctx[4]; ! 1895: uint32_t islot_ctx[4]; ! 1896: uint32_t ep_ctx[5]; ! 1897: int i; ! 1898: TRBCCode res; ! 1899: ! 1900: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1901: DPRINTF("xhci_configure_slot(%d)\n", slotid); ! 1902: ! 1903: ictx = xhci_mask64(pictx); ! 1904: octx = xhci->slots[slotid-1].ctx; ! 1905: ! 1906: DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx); ! 1907: DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx); ! 1908: ! 1909: if (dc) { ! 1910: for (i = 2; i <= 31; i++) { ! 1911: if (xhci->slots[slotid-1].eps[i-1]) { ! 1912: xhci_disable_ep(xhci, slotid, i); ! 1913: } ! 1914: } ! 1915: ! 1916: pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 1917: slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT); ! 1918: slot_ctx[3] |= SLOT_ADDRESSED << SLOT_STATE_SHIFT; ! 1919: DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", ! 1920: slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); ! 1921: pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 1922: ! 1923: return CC_SUCCESS; ! 1924: } ! 1925: ! 1926: pci_dma_read(&xhci->pci_dev, ictx, ictl_ctx, sizeof(ictl_ctx)); ! 1927: ! 1928: if ((ictl_ctx[0] & 0x3) != 0x0 || (ictl_ctx[1] & 0x3) != 0x1) { ! 1929: fprintf(stderr, "xhci: invalid input context control %08x %08x\n", ! 1930: ictl_ctx[0], ictl_ctx[1]); ! 1931: return CC_TRB_ERROR; ! 1932: } ! 1933: ! 1934: pci_dma_read(&xhci->pci_dev, ictx+32, islot_ctx, sizeof(islot_ctx)); ! 1935: pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 1936: ! 1937: if (SLOT_STATE(slot_ctx[3]) < SLOT_ADDRESSED) { ! 1938: fprintf(stderr, "xhci: invalid slot state %08x\n", slot_ctx[3]); ! 1939: return CC_CONTEXT_STATE_ERROR; ! 1940: } ! 1941: ! 1942: for (i = 2; i <= 31; i++) { ! 1943: if (ictl_ctx[0] & (1<<i)) { ! 1944: xhci_disable_ep(xhci, slotid, i); ! 1945: } ! 1946: if (ictl_ctx[1] & (1<<i)) { ! 1947: pci_dma_read(&xhci->pci_dev, ictx+32+(32*i), ep_ctx, ! 1948: sizeof(ep_ctx)); ! 1949: DPRINTF("xhci: input ep%d.%d context: %08x %08x %08x %08x %08x\n", ! 1950: i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2], ! 1951: ep_ctx[3], ep_ctx[4]); ! 1952: xhci_disable_ep(xhci, slotid, i); ! 1953: res = xhci_enable_ep(xhci, slotid, i, octx+(32*i), ep_ctx); ! 1954: if (res != CC_SUCCESS) { ! 1955: return res; ! 1956: } ! 1957: DPRINTF("xhci: output ep%d.%d context: %08x %08x %08x %08x %08x\n", ! 1958: i/2, i%2, ep_ctx[0], ep_ctx[1], ep_ctx[2], ! 1959: ep_ctx[3], ep_ctx[4]); ! 1960: pci_dma_write(&xhci->pci_dev, octx+(32*i), ep_ctx, sizeof(ep_ctx)); ! 1961: } ! 1962: } ! 1963: ! 1964: slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT); ! 1965: slot_ctx[3] |= SLOT_CONFIGURED << SLOT_STATE_SHIFT; ! 1966: slot_ctx[0] &= ~(SLOT_CONTEXT_ENTRIES_MASK << SLOT_CONTEXT_ENTRIES_SHIFT); ! 1967: slot_ctx[0] |= islot_ctx[0] & (SLOT_CONTEXT_ENTRIES_MASK << ! 1968: SLOT_CONTEXT_ENTRIES_SHIFT); ! 1969: DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", ! 1970: slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); ! 1971: ! 1972: pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 1973: ! 1974: return CC_SUCCESS; ! 1975: } ! 1976: ! 1977: ! 1978: static TRBCCode xhci_evaluate_slot(XHCIState *xhci, unsigned int slotid, ! 1979: uint64_t pictx) ! 1980: { ! 1981: dma_addr_t ictx, octx; ! 1982: uint32_t ictl_ctx[2]; ! 1983: uint32_t iep0_ctx[5]; ! 1984: uint32_t ep0_ctx[5]; ! 1985: uint32_t islot_ctx[4]; ! 1986: uint32_t slot_ctx[4]; ! 1987: ! 1988: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 1989: DPRINTF("xhci_evaluate_slot(%d)\n", slotid); ! 1990: ! 1991: ictx = xhci_mask64(pictx); ! 1992: octx = xhci->slots[slotid-1].ctx; ! 1993: ! 1994: DPRINTF("xhci: input context at "DMA_ADDR_FMT"\n", ictx); ! 1995: DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx); ! 1996: ! 1997: pci_dma_read(&xhci->pci_dev, ictx, ictl_ctx, sizeof(ictl_ctx)); ! 1998: ! 1999: if (ictl_ctx[0] != 0x0 || ictl_ctx[1] & ~0x3) { ! 2000: fprintf(stderr, "xhci: invalid input context control %08x %08x\n", ! 2001: ictl_ctx[0], ictl_ctx[1]); ! 2002: return CC_TRB_ERROR; ! 2003: } ! 2004: ! 2005: if (ictl_ctx[1] & 0x1) { ! 2006: pci_dma_read(&xhci->pci_dev, ictx+32, islot_ctx, sizeof(islot_ctx)); ! 2007: ! 2008: DPRINTF("xhci: input slot context: %08x %08x %08x %08x\n", ! 2009: islot_ctx[0], islot_ctx[1], islot_ctx[2], islot_ctx[3]); ! 2010: ! 2011: pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 2012: ! 2013: slot_ctx[1] &= ~0xFFFF; /* max exit latency */ ! 2014: slot_ctx[1] |= islot_ctx[1] & 0xFFFF; ! 2015: slot_ctx[2] &= ~0xFF00000; /* interrupter target */ ! 2016: slot_ctx[2] |= islot_ctx[2] & 0xFF000000; ! 2017: ! 2018: DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", ! 2019: slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); ! 2020: ! 2021: pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 2022: } ! 2023: ! 2024: if (ictl_ctx[1] & 0x2) { ! 2025: pci_dma_read(&xhci->pci_dev, ictx+64, iep0_ctx, sizeof(iep0_ctx)); ! 2026: ! 2027: DPRINTF("xhci: input ep0 context: %08x %08x %08x %08x %08x\n", ! 2028: iep0_ctx[0], iep0_ctx[1], iep0_ctx[2], ! 2029: iep0_ctx[3], iep0_ctx[4]); ! 2030: ! 2031: pci_dma_read(&xhci->pci_dev, octx+32, ep0_ctx, sizeof(ep0_ctx)); ! 2032: ! 2033: ep0_ctx[1] &= ~0xFFFF0000; /* max packet size*/ ! 2034: ep0_ctx[1] |= iep0_ctx[1] & 0xFFFF0000; ! 2035: ! 2036: DPRINTF("xhci: output ep0 context: %08x %08x %08x %08x %08x\n", ! 2037: ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]); ! 2038: ! 2039: pci_dma_write(&xhci->pci_dev, octx+32, ep0_ctx, sizeof(ep0_ctx)); ! 2040: } ! 2041: ! 2042: return CC_SUCCESS; ! 2043: } ! 2044: ! 2045: static TRBCCode xhci_reset_slot(XHCIState *xhci, unsigned int slotid) ! 2046: { ! 2047: uint32_t slot_ctx[4]; ! 2048: dma_addr_t octx; ! 2049: int i; ! 2050: ! 2051: assert(slotid >= 1 && slotid <= MAXSLOTS); ! 2052: DPRINTF("xhci_reset_slot(%d)\n", slotid); ! 2053: ! 2054: octx = xhci->slots[slotid-1].ctx; ! 2055: ! 2056: DPRINTF("xhci: output context at "DMA_ADDR_FMT"\n", octx); ! 2057: ! 2058: for (i = 2; i <= 31; i++) { ! 2059: if (xhci->slots[slotid-1].eps[i-1]) { ! 2060: xhci_disable_ep(xhci, slotid, i); ! 2061: } ! 2062: } ! 2063: ! 2064: pci_dma_read(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 2065: slot_ctx[3] &= ~(SLOT_STATE_MASK << SLOT_STATE_SHIFT); ! 2066: slot_ctx[3] |= SLOT_DEFAULT << SLOT_STATE_SHIFT; ! 2067: DPRINTF("xhci: output slot context: %08x %08x %08x %08x\n", ! 2068: slot_ctx[0], slot_ctx[1], slot_ctx[2], slot_ctx[3]); ! 2069: pci_dma_write(&xhci->pci_dev, octx, slot_ctx, sizeof(slot_ctx)); ! 2070: ! 2071: return CC_SUCCESS; ! 2072: } ! 2073: ! 2074: static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *trb) ! 2075: { ! 2076: unsigned int slotid; ! 2077: slotid = (trb->control >> TRB_CR_SLOTID_SHIFT) & TRB_CR_SLOTID_MASK; ! 2078: if (slotid < 1 || slotid > MAXSLOTS) { ! 2079: fprintf(stderr, "xhci: bad slot id %d\n", slotid); ! 2080: event->ccode = CC_TRB_ERROR; ! 2081: return 0; ! 2082: } else if (!xhci->slots[slotid-1].enabled) { ! 2083: fprintf(stderr, "xhci: slot id %d not enabled\n", slotid); ! 2084: event->ccode = CC_SLOT_NOT_ENABLED_ERROR; ! 2085: return 0; ! 2086: } ! 2087: return slotid; ! 2088: } ! 2089: ! 2090: static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) ! 2091: { ! 2092: dma_addr_t ctx; ! 2093: uint8_t bw_ctx[MAXPORTS+1]; ! 2094: ! 2095: DPRINTF("xhci_get_port_bandwidth()\n"); ! 2096: ! 2097: ctx = xhci_mask64(pctx); ! 2098: ! 2099: DPRINTF("xhci: bandwidth context at "DMA_ADDR_FMT"\n", ctx); ! 2100: ! 2101: /* TODO: actually implement real values here */ ! 2102: bw_ctx[0] = 0; ! 2103: memset(&bw_ctx[1], 80, MAXPORTS); /* 80% */ ! 2104: pci_dma_write(&xhci->pci_dev, ctx, bw_ctx, sizeof(bw_ctx)); ! 2105: ! 2106: return CC_SUCCESS; ! 2107: } ! 2108: ! 2109: static uint32_t rotl(uint32_t v, unsigned count) ! 2110: { ! 2111: count &= 31; ! 2112: return (v << count) | (v >> (32 - count)); ! 2113: } ! 2114: ! 2115: ! 2116: static uint32_t xhci_nec_challenge(uint32_t hi, uint32_t lo) ! 2117: { ! 2118: uint32_t val; ! 2119: val = rotl(lo - 0x49434878, 32 - ((hi>>8) & 0x1F)); ! 2120: val += rotl(lo + 0x49434878, hi & 0x1F); ! 2121: val -= rotl(hi ^ 0x49434878, (lo >> 16) & 0x1F); ! 2122: return ~val; ! 2123: } ! 2124: ! 2125: static void xhci_via_challenge(XHCIState *xhci, uint64_t addr) ! 2126: { ! 2127: uint32_t buf[8]; ! 2128: uint32_t obuf[8]; ! 2129: dma_addr_t paddr = xhci_mask64(addr); ! 2130: ! 2131: pci_dma_read(&xhci->pci_dev, paddr, &buf, 32); ! 2132: ! 2133: memcpy(obuf, buf, sizeof(obuf)); ! 2134: ! 2135: if ((buf[0] & 0xff) == 2) { ! 2136: obuf[0] = 0x49932000 + 0x54dc200 * buf[2] + 0x7429b578 * buf[3]; ! 2137: obuf[0] |= (buf[2] * buf[3]) & 0xff; ! 2138: obuf[1] = 0x0132bb37 + 0xe89 * buf[2] + 0xf09 * buf[3]; ! 2139: obuf[2] = 0x0066c2e9 + 0x2091 * buf[2] + 0x19bd * buf[3]; ! 2140: obuf[3] = 0xd5281342 + 0x2cc9691 * buf[2] + 0x2367662 * buf[3]; ! 2141: obuf[4] = 0x0123c75c + 0x1595 * buf[2] + 0x19ec * buf[3]; ! 2142: obuf[5] = 0x00f695de + 0x26fd * buf[2] + 0x3e9 * buf[3]; ! 2143: obuf[6] = obuf[2] ^ obuf[3] ^ 0x29472956; ! 2144: obuf[7] = obuf[2] ^ obuf[3] ^ 0x65866593; ! 2145: } ! 2146: ! 2147: pci_dma_write(&xhci->pci_dev, paddr, &obuf, 32); ! 2148: } ! 2149: ! 2150: static void xhci_process_commands(XHCIState *xhci) ! 2151: { ! 2152: XHCITRB trb; ! 2153: TRBType type; ! 2154: XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS}; ! 2155: dma_addr_t addr; ! 2156: unsigned int i, slotid = 0; ! 2157: ! 2158: DPRINTF("xhci_process_commands()\n"); ! 2159: if (!xhci_running(xhci)) { ! 2160: DPRINTF("xhci_process_commands() called while xHC stopped or paused\n"); ! 2161: return; ! 2162: } ! 2163: ! 2164: xhci->crcr_low |= CRCR_CRR; ! 2165: ! 2166: while ((type = xhci_ring_fetch(xhci, &xhci->cmd_ring, &trb, &addr))) { ! 2167: event.ptr = addr; ! 2168: switch (type) { ! 2169: case CR_ENABLE_SLOT: ! 2170: for (i = 0; i < MAXSLOTS; i++) { ! 2171: if (!xhci->slots[i].enabled) { ! 2172: break; ! 2173: } ! 2174: } ! 2175: if (i >= MAXSLOTS) { ! 2176: fprintf(stderr, "xhci: no device slots available\n"); ! 2177: event.ccode = CC_NO_SLOTS_ERROR; ! 2178: } else { ! 2179: slotid = i+1; ! 2180: event.ccode = xhci_enable_slot(xhci, slotid); ! 2181: } ! 2182: break; ! 2183: case CR_DISABLE_SLOT: ! 2184: slotid = xhci_get_slot(xhci, &event, &trb); ! 2185: if (slotid) { ! 2186: event.ccode = xhci_disable_slot(xhci, slotid); ! 2187: } ! 2188: break; ! 2189: case CR_ADDRESS_DEVICE: ! 2190: slotid = xhci_get_slot(xhci, &event, &trb); ! 2191: if (slotid) { ! 2192: event.ccode = xhci_address_slot(xhci, slotid, trb.parameter, ! 2193: trb.control & TRB_CR_BSR); ! 2194: } ! 2195: break; ! 2196: case CR_CONFIGURE_ENDPOINT: ! 2197: slotid = xhci_get_slot(xhci, &event, &trb); ! 2198: if (slotid) { ! 2199: event.ccode = xhci_configure_slot(xhci, slotid, trb.parameter, ! 2200: trb.control & TRB_CR_DC); ! 2201: } ! 2202: break; ! 2203: case CR_EVALUATE_CONTEXT: ! 2204: slotid = xhci_get_slot(xhci, &event, &trb); ! 2205: if (slotid) { ! 2206: event.ccode = xhci_evaluate_slot(xhci, slotid, trb.parameter); ! 2207: } ! 2208: break; ! 2209: case CR_STOP_ENDPOINT: ! 2210: slotid = xhci_get_slot(xhci, &event, &trb); ! 2211: if (slotid) { ! 2212: unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT) ! 2213: & TRB_CR_EPID_MASK; ! 2214: event.ccode = xhci_stop_ep(xhci, slotid, epid); ! 2215: } ! 2216: break; ! 2217: case CR_RESET_ENDPOINT: ! 2218: slotid = xhci_get_slot(xhci, &event, &trb); ! 2219: if (slotid) { ! 2220: unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT) ! 2221: & TRB_CR_EPID_MASK; ! 2222: event.ccode = xhci_reset_ep(xhci, slotid, epid); ! 2223: } ! 2224: break; ! 2225: case CR_SET_TR_DEQUEUE: ! 2226: slotid = xhci_get_slot(xhci, &event, &trb); ! 2227: if (slotid) { ! 2228: unsigned int epid = (trb.control >> TRB_CR_EPID_SHIFT) ! 2229: & TRB_CR_EPID_MASK; ! 2230: event.ccode = xhci_set_ep_dequeue(xhci, slotid, epid, ! 2231: trb.parameter); ! 2232: } ! 2233: break; ! 2234: case CR_RESET_DEVICE: ! 2235: slotid = xhci_get_slot(xhci, &event, &trb); ! 2236: if (slotid) { ! 2237: event.ccode = xhci_reset_slot(xhci, slotid); ! 2238: } ! 2239: break; ! 2240: case CR_GET_PORT_BANDWIDTH: ! 2241: event.ccode = xhci_get_port_bandwidth(xhci, trb.parameter); ! 2242: break; ! 2243: case CR_VENDOR_VIA_CHALLENGE_RESPONSE: ! 2244: xhci_via_challenge(xhci, trb.parameter); ! 2245: break; ! 2246: case CR_VENDOR_NEC_FIRMWARE_REVISION: ! 2247: event.type = 48; /* NEC reply */ ! 2248: event.length = 0x3025; ! 2249: break; ! 2250: case CR_VENDOR_NEC_CHALLENGE_RESPONSE: ! 2251: { ! 2252: uint32_t chi = trb.parameter >> 32; ! 2253: uint32_t clo = trb.parameter; ! 2254: uint32_t val = xhci_nec_challenge(chi, clo); ! 2255: event.length = val & 0xFFFF; ! 2256: event.epid = val >> 16; ! 2257: slotid = val >> 24; ! 2258: event.type = 48; /* NEC reply */ ! 2259: } ! 2260: break; ! 2261: default: ! 2262: fprintf(stderr, "xhci: unimplemented command %d\n", type); ! 2263: event.ccode = CC_TRB_ERROR; ! 2264: break; ! 2265: } ! 2266: event.slotid = slotid; ! 2267: xhci_event(xhci, &event); ! 2268: } ! 2269: } ! 2270: ! 2271: static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach) ! 2272: { ! 2273: int nr = port->port.index + 1; ! 2274: ! 2275: port->portsc = PORTSC_PP; ! 2276: if (port->port.dev && port->port.dev->attached && !is_detach) { ! 2277: port->portsc |= PORTSC_CCS; ! 2278: switch (port->port.dev->speed) { ! 2279: case USB_SPEED_LOW: ! 2280: port->portsc |= PORTSC_SPEED_LOW; ! 2281: break; ! 2282: case USB_SPEED_FULL: ! 2283: port->portsc |= PORTSC_SPEED_FULL; ! 2284: break; ! 2285: case USB_SPEED_HIGH: ! 2286: port->portsc |= PORTSC_SPEED_HIGH; ! 2287: break; ! 2288: } ! 2289: } ! 2290: ! 2291: if (xhci_running(xhci)) { ! 2292: port->portsc |= PORTSC_CSC; ! 2293: XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; ! 2294: xhci_event(xhci, &ev); ! 2295: DPRINTF("xhci: port change event for port %d\n", nr); ! 2296: } ! 2297: } ! 2298: ! 2299: static void xhci_reset(void *opaque) ! 2300: { ! 2301: XHCIState *xhci = opaque; ! 2302: int i; ! 2303: ! 2304: DPRINTF("xhci: full reset\n"); ! 2305: if (!(xhci->usbsts & USBSTS_HCH)) { ! 2306: fprintf(stderr, "xhci: reset while running!\n"); ! 2307: } ! 2308: ! 2309: xhci->usbcmd = 0; ! 2310: xhci->usbsts = USBSTS_HCH; ! 2311: xhci->dnctrl = 0; ! 2312: xhci->crcr_low = 0; ! 2313: xhci->crcr_high = 0; ! 2314: xhci->dcbaap_low = 0; ! 2315: xhci->dcbaap_high = 0; ! 2316: xhci->config = 0; ! 2317: xhci->devaddr = 2; ! 2318: ! 2319: for (i = 0; i < MAXSLOTS; i++) { ! 2320: xhci_disable_slot(xhci, i+1); ! 2321: } ! 2322: ! 2323: for (i = 0; i < MAXPORTS; i++) { ! 2324: xhci_update_port(xhci, xhci->ports + i, 0); ! 2325: } ! 2326: ! 2327: xhci->mfindex = 0; ! 2328: xhci->iman = 0; ! 2329: xhci->imod = 0; ! 2330: xhci->erstsz = 0; ! 2331: xhci->erstba_low = 0; ! 2332: xhci->erstba_high = 0; ! 2333: xhci->erdp_low = 0; ! 2334: xhci->erdp_high = 0; ! 2335: ! 2336: xhci->er_ep_idx = 0; ! 2337: xhci->er_pcs = 1; ! 2338: xhci->er_full = 0; ! 2339: xhci->ev_buffer_put = 0; ! 2340: xhci->ev_buffer_get = 0; ! 2341: } ! 2342: ! 2343: static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg) ! 2344: { ! 2345: DPRINTF("xhci_cap_read(0x%x)\n", reg); ! 2346: ! 2347: switch (reg) { ! 2348: case 0x00: /* HCIVERSION, CAPLENGTH */ ! 2349: return 0x01000000 | LEN_CAP; ! 2350: case 0x04: /* HCSPARAMS 1 */ ! 2351: return (MAXPORTS<<24) | (MAXINTRS<<8) | MAXSLOTS; ! 2352: case 0x08: /* HCSPARAMS 2 */ ! 2353: return 0x0000000f; ! 2354: case 0x0c: /* HCSPARAMS 3 */ ! 2355: return 0x00000000; ! 2356: case 0x10: /* HCCPARAMS */ ! 2357: #if TARGET_PHYS_ADDR_BITS > 32 ! 2358: return 0x00081001; ! 2359: #else ! 2360: return 0x00081000; ! 2361: #endif ! 2362: case 0x14: /* DBOFF */ ! 2363: return OFF_DOORBELL; ! 2364: case 0x18: /* RTSOFF */ ! 2365: return OFF_RUNTIME; ! 2366: ! 2367: /* extended capabilities */ ! 2368: case 0x20: /* Supported Protocol:00 */ ! 2369: #if USB3_PORTS > 0 ! 2370: return 0x02000402; /* USB 2.0 */ ! 2371: #else ! 2372: return 0x02000002; /* USB 2.0 */ ! 2373: #endif ! 2374: case 0x24: /* Supported Protocol:04 */ ! 2375: return 0x20425455; /* "USB " */ ! 2376: case 0x28: /* Supported Protocol:08 */ ! 2377: return 0x00000001 | (USB2_PORTS<<8); ! 2378: case 0x2c: /* Supported Protocol:0c */ ! 2379: return 0x00000000; /* reserved */ ! 2380: #if USB3_PORTS > 0 ! 2381: case 0x30: /* Supported Protocol:00 */ ! 2382: return 0x03000002; /* USB 3.0 */ ! 2383: case 0x34: /* Supported Protocol:04 */ ! 2384: return 0x20425455; /* "USB " */ ! 2385: case 0x38: /* Supported Protocol:08 */ ! 2386: return 0x00000000 | (USB2_PORTS+1) | (USB3_PORTS<<8); ! 2387: case 0x3c: /* Supported Protocol:0c */ ! 2388: return 0x00000000; /* reserved */ ! 2389: #endif ! 2390: default: ! 2391: fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", reg); ! 2392: } ! 2393: return 0; ! 2394: } ! 2395: ! 2396: static uint32_t xhci_port_read(XHCIState *xhci, uint32_t reg) ! 2397: { ! 2398: uint32_t port = reg >> 4; ! 2399: if (port >= MAXPORTS) { ! 2400: fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); ! 2401: return 0; ! 2402: } ! 2403: ! 2404: switch (reg & 0xf) { ! 2405: case 0x00: /* PORTSC */ ! 2406: return xhci->ports[port].portsc; ! 2407: case 0x04: /* PORTPMSC */ ! 2408: case 0x08: /* PORTLI */ ! 2409: return 0; ! 2410: case 0x0c: /* reserved */ ! 2411: default: ! 2412: fprintf(stderr, "xhci_port_read (port %d): reg 0x%x unimplemented\n", ! 2413: port, reg); ! 2414: return 0; ! 2415: } ! 2416: } ! 2417: ! 2418: static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val) ! 2419: { ! 2420: uint32_t port = reg >> 4; ! 2421: uint32_t portsc; ! 2422: ! 2423: if (port >= MAXPORTS) { ! 2424: fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port); ! 2425: return; ! 2426: } ! 2427: ! 2428: switch (reg & 0xf) { ! 2429: case 0x00: /* PORTSC */ ! 2430: portsc = xhci->ports[port].portsc; ! 2431: /* write-1-to-clear bits*/ ! 2432: portsc &= ~(val & (PORTSC_CSC|PORTSC_PEC|PORTSC_WRC|PORTSC_OCC| ! 2433: PORTSC_PRC|PORTSC_PLC|PORTSC_CEC)); ! 2434: if (val & PORTSC_LWS) { ! 2435: /* overwrite PLS only when LWS=1 */ ! 2436: portsc &= ~(PORTSC_PLS_MASK << PORTSC_PLS_SHIFT); ! 2437: portsc |= val & (PORTSC_PLS_MASK << PORTSC_PLS_SHIFT); ! 2438: } ! 2439: /* read/write bits */ ! 2440: portsc &= ~(PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE); ! 2441: portsc |= (val & (PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE)); ! 2442: /* write-1-to-start bits */ ! 2443: if (val & PORTSC_PR) { ! 2444: DPRINTF("xhci: port %d reset\n", port); ! 2445: usb_device_reset(xhci->ports[port].port.dev); ! 2446: portsc |= PORTSC_PRC | PORTSC_PED; ! 2447: } ! 2448: xhci->ports[port].portsc = portsc; ! 2449: break; ! 2450: case 0x04: /* PORTPMSC */ ! 2451: case 0x08: /* PORTLI */ ! 2452: default: ! 2453: fprintf(stderr, "xhci_port_write (port %d): reg 0x%x unimplemented\n", ! 2454: port, reg); ! 2455: } ! 2456: } ! 2457: ! 2458: static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg) ! 2459: { ! 2460: DPRINTF("xhci_oper_read(0x%x)\n", reg); ! 2461: ! 2462: if (reg >= 0x400) { ! 2463: return xhci_port_read(xhci, reg - 0x400); ! 2464: } ! 2465: ! 2466: switch (reg) { ! 2467: case 0x00: /* USBCMD */ ! 2468: return xhci->usbcmd; ! 2469: case 0x04: /* USBSTS */ ! 2470: return xhci->usbsts; ! 2471: case 0x08: /* PAGESIZE */ ! 2472: return 1; /* 4KiB */ ! 2473: case 0x14: /* DNCTRL */ ! 2474: return xhci->dnctrl; ! 2475: case 0x18: /* CRCR low */ ! 2476: return xhci->crcr_low & ~0xe; ! 2477: case 0x1c: /* CRCR high */ ! 2478: return xhci->crcr_high; ! 2479: case 0x30: /* DCBAAP low */ ! 2480: return xhci->dcbaap_low; ! 2481: case 0x34: /* DCBAAP high */ ! 2482: return xhci->dcbaap_high; ! 2483: case 0x38: /* CONFIG */ ! 2484: return xhci->config; ! 2485: default: ! 2486: fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", reg); ! 2487: } ! 2488: return 0; ! 2489: } ! 2490: ! 2491: static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val) ! 2492: { ! 2493: DPRINTF("xhci_oper_write(0x%x, 0x%08x)\n", reg, val); ! 2494: ! 2495: if (reg >= 0x400) { ! 2496: xhci_port_write(xhci, reg - 0x400, val); ! 2497: return; ! 2498: } ! 2499: ! 2500: switch (reg) { ! 2501: case 0x00: /* USBCMD */ ! 2502: if ((val & USBCMD_RS) && !(xhci->usbcmd & USBCMD_RS)) { ! 2503: xhci_run(xhci); ! 2504: } else if (!(val & USBCMD_RS) && (xhci->usbcmd & USBCMD_RS)) { ! 2505: xhci_stop(xhci); ! 2506: } ! 2507: xhci->usbcmd = val & 0xc0f; ! 2508: if (val & USBCMD_HCRST) { ! 2509: xhci_reset(xhci); ! 2510: } ! 2511: xhci_irq_update(xhci); ! 2512: break; ! 2513: ! 2514: case 0x04: /* USBSTS */ ! 2515: /* these bits are write-1-to-clear */ ! 2516: xhci->usbsts &= ~(val & (USBSTS_HSE|USBSTS_EINT|USBSTS_PCD|USBSTS_SRE)); ! 2517: xhci_irq_update(xhci); ! 2518: break; ! 2519: ! 2520: case 0x14: /* DNCTRL */ ! 2521: xhci->dnctrl = val & 0xffff; ! 2522: break; ! 2523: case 0x18: /* CRCR low */ ! 2524: xhci->crcr_low = (val & 0xffffffcf) | (xhci->crcr_low & CRCR_CRR); ! 2525: break; ! 2526: case 0x1c: /* CRCR high */ ! 2527: xhci->crcr_high = val; ! 2528: if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) { ! 2529: XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED}; ! 2530: xhci->crcr_low &= ~CRCR_CRR; ! 2531: xhci_event(xhci, &event); ! 2532: DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low); ! 2533: } else { ! 2534: dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val); ! 2535: xhci_ring_init(xhci, &xhci->cmd_ring, base); ! 2536: } ! 2537: xhci->crcr_low &= ~(CRCR_CA | CRCR_CS); ! 2538: break; ! 2539: case 0x30: /* DCBAAP low */ ! 2540: xhci->dcbaap_low = val & 0xffffffc0; ! 2541: break; ! 2542: case 0x34: /* DCBAAP high */ ! 2543: xhci->dcbaap_high = val; ! 2544: break; ! 2545: case 0x38: /* CONFIG */ ! 2546: xhci->config = val & 0xff; ! 2547: break; ! 2548: default: ! 2549: fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); ! 2550: } ! 2551: } ! 2552: ! 2553: static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg) ! 2554: { ! 2555: DPRINTF("xhci_runtime_read(0x%x)\n", reg); ! 2556: ! 2557: switch (reg) { ! 2558: case 0x00: /* MFINDEX */ ! 2559: fprintf(stderr, "xhci_runtime_read: MFINDEX not yet implemented\n"); ! 2560: return xhci->mfindex; ! 2561: case 0x20: /* IMAN */ ! 2562: return xhci->iman; ! 2563: case 0x24: /* IMOD */ ! 2564: return xhci->imod; ! 2565: case 0x28: /* ERSTSZ */ ! 2566: return xhci->erstsz; ! 2567: case 0x30: /* ERSTBA low */ ! 2568: return xhci->erstba_low; ! 2569: case 0x34: /* ERSTBA high */ ! 2570: return xhci->erstba_high; ! 2571: case 0x38: /* ERDP low */ ! 2572: return xhci->erdp_low; ! 2573: case 0x3c: /* ERDP high */ ! 2574: return xhci->erdp_high; ! 2575: default: ! 2576: fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg); ! 2577: } ! 2578: return 0; ! 2579: } ! 2580: ! 2581: static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val) ! 2582: { ! 2583: DPRINTF("xhci_runtime_write(0x%x, 0x%08x)\n", reg, val); ! 2584: ! 2585: switch (reg) { ! 2586: case 0x20: /* IMAN */ ! 2587: if (val & IMAN_IP) { ! 2588: xhci->iman &= ~IMAN_IP; ! 2589: } ! 2590: xhci->iman &= ~IMAN_IE; ! 2591: xhci->iman |= val & IMAN_IE; ! 2592: xhci_irq_update(xhci); ! 2593: break; ! 2594: case 0x24: /* IMOD */ ! 2595: xhci->imod = val; ! 2596: break; ! 2597: case 0x28: /* ERSTSZ */ ! 2598: xhci->erstsz = val & 0xffff; ! 2599: break; ! 2600: case 0x30: /* ERSTBA low */ ! 2601: /* XXX NEC driver bug: it doesn't align this to 64 bytes ! 2602: xhci->erstba_low = val & 0xffffffc0; */ ! 2603: xhci->erstba_low = val & 0xfffffff0; ! 2604: break; ! 2605: case 0x34: /* ERSTBA high */ ! 2606: xhci->erstba_high = val; ! 2607: xhci_er_reset(xhci); ! 2608: break; ! 2609: case 0x38: /* ERDP low */ ! 2610: if (val & ERDP_EHB) { ! 2611: xhci->erdp_low &= ~ERDP_EHB; ! 2612: } ! 2613: xhci->erdp_low = (val & ~ERDP_EHB) | (xhci->erdp_low & ERDP_EHB); ! 2614: break; ! 2615: case 0x3c: /* ERDP high */ ! 2616: xhci->erdp_high = val; ! 2617: xhci_events_update(xhci); ! 2618: break; ! 2619: default: ! 2620: fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg); ! 2621: } ! 2622: } ! 2623: ! 2624: static uint32_t xhci_doorbell_read(XHCIState *xhci, uint32_t reg) ! 2625: { ! 2626: DPRINTF("xhci_doorbell_read(0x%x)\n", reg); ! 2627: /* doorbells always read as 0 */ ! 2628: return 0; ! 2629: } ! 2630: ! 2631: static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val) ! 2632: { ! 2633: DPRINTF("xhci_doorbell_write(0x%x, 0x%08x)\n", reg, val); ! 2634: ! 2635: if (!xhci_running(xhci)) { ! 2636: fprintf(stderr, "xhci: wrote doorbell while xHC stopped or paused\n"); ! 2637: return; ! 2638: } ! 2639: ! 2640: reg >>= 2; ! 2641: ! 2642: if (reg == 0) { ! 2643: if (val == 0) { ! 2644: xhci_process_commands(xhci); ! 2645: } else { ! 2646: fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", val); ! 2647: } ! 2648: } else { ! 2649: if (reg > MAXSLOTS) { ! 2650: fprintf(stderr, "xhci: bad doorbell %d\n", reg); ! 2651: } else if (val > 31) { ! 2652: fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", reg, val); ! 2653: } else { ! 2654: xhci_kick_ep(xhci, reg, val); ! 2655: } ! 2656: } ! 2657: } ! 2658: ! 2659: static uint64_t xhci_mem_read(void *ptr, target_phys_addr_t addr, ! 2660: unsigned size) ! 2661: { ! 2662: XHCIState *xhci = ptr; ! 2663: ! 2664: /* Only aligned reads are allowed on xHCI */ ! 2665: if (addr & 3) { ! 2666: fprintf(stderr, "xhci_mem_read: Mis-aligned read\n"); ! 2667: return 0; ! 2668: } ! 2669: ! 2670: if (addr < LEN_CAP) { ! 2671: return xhci_cap_read(xhci, addr); ! 2672: } else if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) { ! 2673: return xhci_oper_read(xhci, addr - OFF_OPER); ! 2674: } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) { ! 2675: return xhci_runtime_read(xhci, addr - OFF_RUNTIME); ! 2676: } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) { ! 2677: return xhci_doorbell_read(xhci, addr - OFF_DOORBELL); ! 2678: } else { ! 2679: fprintf(stderr, "xhci_mem_read: Bad offset %x\n", (int)addr); ! 2680: return 0; ! 2681: } ! 2682: } ! 2683: ! 2684: static void xhci_mem_write(void *ptr, target_phys_addr_t addr, ! 2685: uint64_t val, unsigned size) ! 2686: { ! 2687: XHCIState *xhci = ptr; ! 2688: ! 2689: /* Only aligned writes are allowed on xHCI */ ! 2690: if (addr & 3) { ! 2691: fprintf(stderr, "xhci_mem_write: Mis-aligned write\n"); ! 2692: return; ! 2693: } ! 2694: ! 2695: if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) { ! 2696: xhci_oper_write(xhci, addr - OFF_OPER, val); ! 2697: } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) { ! 2698: xhci_runtime_write(xhci, addr - OFF_RUNTIME, val); ! 2699: } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) { ! 2700: xhci_doorbell_write(xhci, addr - OFF_DOORBELL, val); ! 2701: } else { ! 2702: fprintf(stderr, "xhci_mem_write: Bad offset %x\n", (int)addr); ! 2703: } ! 2704: } ! 2705: ! 2706: static const MemoryRegionOps xhci_mem_ops = { ! 2707: .read = xhci_mem_read, ! 2708: .write = xhci_mem_write, ! 2709: .valid.min_access_size = 4, ! 2710: .valid.max_access_size = 4, ! 2711: .endianness = DEVICE_LITTLE_ENDIAN, ! 2712: }; ! 2713: ! 2714: static void xhci_attach(USBPort *usbport) ! 2715: { ! 2716: XHCIState *xhci = usbport->opaque; ! 2717: XHCIPort *port = &xhci->ports[usbport->index]; ! 2718: ! 2719: xhci_update_port(xhci, port, 0); ! 2720: } ! 2721: ! 2722: static void xhci_detach(USBPort *usbport) ! 2723: { ! 2724: XHCIState *xhci = usbport->opaque; ! 2725: XHCIPort *port = &xhci->ports[usbport->index]; ! 2726: ! 2727: xhci_update_port(xhci, port, 1); ! 2728: } ! 2729: ! 2730: static void xhci_wakeup(USBPort *usbport) ! 2731: { ! 2732: XHCIState *xhci = usbport->opaque; ! 2733: XHCIPort *port = &xhci->ports[usbport->index]; ! 2734: int nr = port->port.index + 1; ! 2735: XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; ! 2736: uint32_t pls; ! 2737: ! 2738: pls = (port->portsc >> PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK; ! 2739: if (pls != 3) { ! 2740: return; ! 2741: } ! 2742: port->portsc |= 0xf << PORTSC_PLS_SHIFT; ! 2743: if (port->portsc & PORTSC_PLC) { ! 2744: return; ! 2745: } ! 2746: port->portsc |= PORTSC_PLC; ! 2747: xhci_event(xhci, &ev); ! 2748: } ! 2749: ! 2750: static void xhci_complete(USBPort *port, USBPacket *packet) ! 2751: { ! 2752: XHCITransfer *xfer = container_of(packet, XHCITransfer, packet); ! 2753: ! 2754: xhci_complete_packet(xfer, packet->result); ! 2755: xhci_kick_ep(xfer->xhci, xfer->slotid, xfer->epid); ! 2756: } ! 2757: ! 2758: static void xhci_child_detach(USBPort *port, USBDevice *child) ! 2759: { ! 2760: FIXME(); ! 2761: } ! 2762: ! 2763: static USBPortOps xhci_port_ops = { ! 2764: .attach = xhci_attach, ! 2765: .detach = xhci_detach, ! 2766: .wakeup = xhci_wakeup, ! 2767: .complete = xhci_complete, ! 2768: .child_detach = xhci_child_detach, ! 2769: }; ! 2770: ! 2771: static int xhci_find_slotid(XHCIState *xhci, USBDevice *dev) ! 2772: { ! 2773: XHCISlot *slot; ! 2774: int slotid; ! 2775: ! 2776: for (slotid = 1; slotid <= MAXSLOTS; slotid++) { ! 2777: slot = &xhci->slots[slotid-1]; ! 2778: if (slot->devaddr == dev->addr) { ! 2779: return slotid; ! 2780: } ! 2781: } ! 2782: return 0; ! 2783: } ! 2784: ! 2785: static int xhci_find_epid(USBEndpoint *ep) ! 2786: { ! 2787: if (ep->nr == 0) { ! 2788: return 1; ! 2789: } ! 2790: if (ep->pid == USB_TOKEN_IN) { ! 2791: return ep->nr * 2 + 1; ! 2792: } else { ! 2793: return ep->nr * 2; ! 2794: } ! 2795: } ! 2796: ! 2797: static void xhci_wakeup_endpoint(USBBus *bus, USBEndpoint *ep) ! 2798: { ! 2799: XHCIState *xhci = container_of(bus, XHCIState, bus); ! 2800: int slotid; ! 2801: ! 2802: DPRINTF("%s\n", __func__); ! 2803: slotid = xhci_find_slotid(xhci, ep->dev); ! 2804: if (slotid == 0 || !xhci->slots[slotid-1].enabled) { ! 2805: DPRINTF("%s: oops, no slot for dev %d\n", __func__, ep->dev->addr); ! 2806: return; ! 2807: } ! 2808: xhci_kick_ep(xhci, slotid, xhci_find_epid(ep)); ! 2809: } ! 2810: ! 2811: static USBBusOps xhci_bus_ops = { ! 2812: .wakeup_endpoint = xhci_wakeup_endpoint, ! 2813: }; ! 2814: ! 2815: static void usb_xhci_init(XHCIState *xhci, DeviceState *dev) ! 2816: { ! 2817: int i; ! 2818: ! 2819: xhci->usbsts = USBSTS_HCH; ! 2820: ! 2821: usb_bus_new(&xhci->bus, &xhci_bus_ops, &xhci->pci_dev.qdev); ! 2822: ! 2823: for (i = 0; i < MAXPORTS; i++) { ! 2824: memset(&xhci->ports[i], 0, sizeof(xhci->ports[i])); ! 2825: usb_register_port(&xhci->bus, &xhci->ports[i].port, xhci, i, ! 2826: &xhci_port_ops, ! 2827: USB_SPEED_MASK_LOW | ! 2828: USB_SPEED_MASK_FULL | ! 2829: USB_SPEED_MASK_HIGH); ! 2830: } ! 2831: for (i = 0; i < MAXSLOTS; i++) { ! 2832: xhci->slots[i].enabled = 0; ! 2833: } ! 2834: ! 2835: qemu_register_reset(xhci_reset, xhci); ! 2836: } ! 2837: ! 2838: static int usb_xhci_initfn(struct PCIDevice *dev) ! 2839: { ! 2840: int ret; ! 2841: ! 2842: XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev, dev); ! 2843: ! 2844: xhci->pci_dev.config[PCI_CLASS_PROG] = 0x30; /* xHCI */ ! 2845: xhci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */ ! 2846: xhci->pci_dev.config[PCI_CACHE_LINE_SIZE] = 0x10; ! 2847: xhci->pci_dev.config[0x60] = 0x30; /* release number */ ! 2848: ! 2849: usb_xhci_init(xhci, &dev->qdev); ! 2850: ! 2851: xhci->irq = xhci->pci_dev.irq[0]; ! 2852: ! 2853: memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci, ! 2854: "xhci", LEN_REGS); ! 2855: pci_register_bar(&xhci->pci_dev, 0, ! 2856: PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64, ! 2857: &xhci->mem); ! 2858: ! 2859: ret = pcie_cap_init(&xhci->pci_dev, 0xa0, PCI_EXP_TYPE_ENDPOINT, 0); ! 2860: assert(ret >= 0); ! 2861: ! 2862: if (xhci->msi) { ! 2863: ret = msi_init(&xhci->pci_dev, 0x70, 1, true, false); ! 2864: assert(ret >= 0); ! 2865: } ! 2866: ! 2867: return 0; ! 2868: } ! 2869: ! 2870: static void xhci_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, ! 2871: int len) ! 2872: { ! 2873: XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev, dev); ! 2874: ! 2875: pci_default_write_config(dev, addr, val, len); ! 2876: if (xhci->msi) { ! 2877: msi_write_config(dev, addr, val, len); ! 2878: } ! 2879: } ! 2880: ! 2881: static const VMStateDescription vmstate_xhci = { ! 2882: .name = "xhci", ! 2883: .unmigratable = 1, ! 2884: }; ! 2885: ! 2886: static Property xhci_properties[] = { ! 2887: DEFINE_PROP_UINT32("msi", XHCIState, msi, 0), ! 2888: DEFINE_PROP_END_OF_LIST(), ! 2889: }; ! 2890: ! 2891: static void xhci_class_init(ObjectClass *klass, void *data) ! 2892: { ! 2893: PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); ! 2894: DeviceClass *dc = DEVICE_CLASS(klass); ! 2895: ! 2896: dc->vmsd = &vmstate_xhci; ! 2897: dc->props = xhci_properties; ! 2898: k->init = usb_xhci_initfn; ! 2899: k->vendor_id = PCI_VENDOR_ID_NEC; ! 2900: k->device_id = PCI_DEVICE_ID_NEC_UPD720200; ! 2901: k->class_id = PCI_CLASS_SERIAL_USB; ! 2902: k->revision = 0x03; ! 2903: k->is_express = 1; ! 2904: k->config_write = xhci_write_config; ! 2905: } ! 2906: ! 2907: static TypeInfo xhci_info = { ! 2908: .name = "nec-usb-xhci", ! 2909: .parent = TYPE_PCI_DEVICE, ! 2910: .instance_size = sizeof(XHCIState), ! 2911: .class_init = xhci_class_init, ! 2912: }; ! 2913: ! 2914: static void xhci_register_types(void) ! 2915: { ! 2916: type_register_static(&xhci_info); ! 2917: } ! 2918: ! 2919: type_init(xhci_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.