Annotation of qemu/hw/usb/hcd-xhci.c, revision 1.1

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)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.