1*f1ae32a1SGerd Hoffmann /* 2*f1ae32a1SGerd Hoffmann * QEMU USB OHCI Emulation 3*f1ae32a1SGerd Hoffmann * Copyright (c) 2004 Gianni Tedesco 4*f1ae32a1SGerd Hoffmann * Copyright (c) 2006 CodeSourcery 5*f1ae32a1SGerd Hoffmann * Copyright (c) 2006 Openedhand Ltd. 6*f1ae32a1SGerd Hoffmann * 7*f1ae32a1SGerd Hoffmann * This library is free software; you can redistribute it and/or 8*f1ae32a1SGerd Hoffmann * modify it under the terms of the GNU Lesser General Public 9*f1ae32a1SGerd Hoffmann * License as published by the Free Software Foundation; either 10*f1ae32a1SGerd Hoffmann * version 2 of the License, or (at your option) any later version. 11*f1ae32a1SGerd Hoffmann * 12*f1ae32a1SGerd Hoffmann * This library is distributed in the hope that it will be useful, 13*f1ae32a1SGerd Hoffmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*f1ae32a1SGerd Hoffmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*f1ae32a1SGerd Hoffmann * Lesser General Public License for more details. 16*f1ae32a1SGerd Hoffmann * 17*f1ae32a1SGerd Hoffmann * You should have received a copy of the GNU Lesser General Public 18*f1ae32a1SGerd Hoffmann * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19*f1ae32a1SGerd Hoffmann * 20*f1ae32a1SGerd Hoffmann * TODO: 21*f1ae32a1SGerd Hoffmann * o Isochronous transfers 22*f1ae32a1SGerd Hoffmann * o Allocate bandwidth in frames properly 23*f1ae32a1SGerd Hoffmann * o Disable timers when nothing needs to be done, or remove timer usage 24*f1ae32a1SGerd Hoffmann * all together. 25*f1ae32a1SGerd Hoffmann * o Handle unrecoverable errors properly 26*f1ae32a1SGerd Hoffmann * o BIOS work to boot from USB storage 27*f1ae32a1SGerd Hoffmann */ 28*f1ae32a1SGerd Hoffmann 29*f1ae32a1SGerd Hoffmann #include "hw/hw.h" 30*f1ae32a1SGerd Hoffmann #include "qemu-timer.h" 31*f1ae32a1SGerd Hoffmann #include "hw/usb.h" 32*f1ae32a1SGerd Hoffmann #include "hw/pci.h" 33*f1ae32a1SGerd Hoffmann #include "hw/usb-ohci.h" 34*f1ae32a1SGerd Hoffmann #include "hw/sysbus.h" 35*f1ae32a1SGerd Hoffmann #include "hw/qdev-addr.h" 36*f1ae32a1SGerd Hoffmann 37*f1ae32a1SGerd Hoffmann //#define DEBUG_OHCI 38*f1ae32a1SGerd Hoffmann /* Dump packet contents. */ 39*f1ae32a1SGerd Hoffmann //#define DEBUG_PACKET 40*f1ae32a1SGerd Hoffmann //#define DEBUG_ISOCH 41*f1ae32a1SGerd Hoffmann /* This causes frames to occur 1000x slower */ 42*f1ae32a1SGerd Hoffmann //#define OHCI_TIME_WARP 1 43*f1ae32a1SGerd Hoffmann 44*f1ae32a1SGerd Hoffmann #ifdef DEBUG_OHCI 45*f1ae32a1SGerd Hoffmann #define DPRINTF printf 46*f1ae32a1SGerd Hoffmann #else 47*f1ae32a1SGerd Hoffmann #define DPRINTF(...) 48*f1ae32a1SGerd Hoffmann #endif 49*f1ae32a1SGerd Hoffmann 50*f1ae32a1SGerd Hoffmann /* Number of Downstream Ports on the root hub. */ 51*f1ae32a1SGerd Hoffmann 52*f1ae32a1SGerd Hoffmann #define OHCI_MAX_PORTS 15 53*f1ae32a1SGerd Hoffmann 54*f1ae32a1SGerd Hoffmann static int64_t usb_frame_time; 55*f1ae32a1SGerd Hoffmann static int64_t usb_bit_time; 56*f1ae32a1SGerd Hoffmann 57*f1ae32a1SGerd Hoffmann typedef struct OHCIPort { 58*f1ae32a1SGerd Hoffmann USBPort port; 59*f1ae32a1SGerd Hoffmann uint32_t ctrl; 60*f1ae32a1SGerd Hoffmann } OHCIPort; 61*f1ae32a1SGerd Hoffmann 62*f1ae32a1SGerd Hoffmann typedef struct { 63*f1ae32a1SGerd Hoffmann USBBus bus; 64*f1ae32a1SGerd Hoffmann qemu_irq irq; 65*f1ae32a1SGerd Hoffmann MemoryRegion mem; 66*f1ae32a1SGerd Hoffmann int num_ports; 67*f1ae32a1SGerd Hoffmann const char *name; 68*f1ae32a1SGerd Hoffmann 69*f1ae32a1SGerd Hoffmann QEMUTimer *eof_timer; 70*f1ae32a1SGerd Hoffmann int64_t sof_time; 71*f1ae32a1SGerd Hoffmann 72*f1ae32a1SGerd Hoffmann /* OHCI state */ 73*f1ae32a1SGerd Hoffmann /* Control partition */ 74*f1ae32a1SGerd Hoffmann uint32_t ctl, status; 75*f1ae32a1SGerd Hoffmann uint32_t intr_status; 76*f1ae32a1SGerd Hoffmann uint32_t intr; 77*f1ae32a1SGerd Hoffmann 78*f1ae32a1SGerd Hoffmann /* memory pointer partition */ 79*f1ae32a1SGerd Hoffmann uint32_t hcca; 80*f1ae32a1SGerd Hoffmann uint32_t ctrl_head, ctrl_cur; 81*f1ae32a1SGerd Hoffmann uint32_t bulk_head, bulk_cur; 82*f1ae32a1SGerd Hoffmann uint32_t per_cur; 83*f1ae32a1SGerd Hoffmann uint32_t done; 84*f1ae32a1SGerd Hoffmann int done_count; 85*f1ae32a1SGerd Hoffmann 86*f1ae32a1SGerd Hoffmann /* Frame counter partition */ 87*f1ae32a1SGerd Hoffmann uint32_t fsmps:15; 88*f1ae32a1SGerd Hoffmann uint32_t fit:1; 89*f1ae32a1SGerd Hoffmann uint32_t fi:14; 90*f1ae32a1SGerd Hoffmann uint32_t frt:1; 91*f1ae32a1SGerd Hoffmann uint16_t frame_number; 92*f1ae32a1SGerd Hoffmann uint16_t padding; 93*f1ae32a1SGerd Hoffmann uint32_t pstart; 94*f1ae32a1SGerd Hoffmann uint32_t lst; 95*f1ae32a1SGerd Hoffmann 96*f1ae32a1SGerd Hoffmann /* Root Hub partition */ 97*f1ae32a1SGerd Hoffmann uint32_t rhdesc_a, rhdesc_b; 98*f1ae32a1SGerd Hoffmann uint32_t rhstatus; 99*f1ae32a1SGerd Hoffmann OHCIPort rhport[OHCI_MAX_PORTS]; 100*f1ae32a1SGerd Hoffmann 101*f1ae32a1SGerd Hoffmann /* PXA27x Non-OHCI events */ 102*f1ae32a1SGerd Hoffmann uint32_t hstatus; 103*f1ae32a1SGerd Hoffmann uint32_t hmask; 104*f1ae32a1SGerd Hoffmann uint32_t hreset; 105*f1ae32a1SGerd Hoffmann uint32_t htest; 106*f1ae32a1SGerd Hoffmann 107*f1ae32a1SGerd Hoffmann /* SM501 local memory offset */ 108*f1ae32a1SGerd Hoffmann target_phys_addr_t localmem_base; 109*f1ae32a1SGerd Hoffmann 110*f1ae32a1SGerd Hoffmann /* Active packets. */ 111*f1ae32a1SGerd Hoffmann uint32_t old_ctl; 112*f1ae32a1SGerd Hoffmann USBPacket usb_packet; 113*f1ae32a1SGerd Hoffmann uint8_t usb_buf[8192]; 114*f1ae32a1SGerd Hoffmann uint32_t async_td; 115*f1ae32a1SGerd Hoffmann int async_complete; 116*f1ae32a1SGerd Hoffmann 117*f1ae32a1SGerd Hoffmann } OHCIState; 118*f1ae32a1SGerd Hoffmann 119*f1ae32a1SGerd Hoffmann /* Host Controller Communications Area */ 120*f1ae32a1SGerd Hoffmann struct ohci_hcca { 121*f1ae32a1SGerd Hoffmann uint32_t intr[32]; 122*f1ae32a1SGerd Hoffmann uint16_t frame, pad; 123*f1ae32a1SGerd Hoffmann uint32_t done; 124*f1ae32a1SGerd Hoffmann }; 125*f1ae32a1SGerd Hoffmann 126*f1ae32a1SGerd Hoffmann static void ohci_bus_stop(OHCIState *ohci); 127*f1ae32a1SGerd Hoffmann static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev); 128*f1ae32a1SGerd Hoffmann 129*f1ae32a1SGerd Hoffmann /* Bitfields for the first word of an Endpoint Desciptor. */ 130*f1ae32a1SGerd Hoffmann #define OHCI_ED_FA_SHIFT 0 131*f1ae32a1SGerd Hoffmann #define OHCI_ED_FA_MASK (0x7f<<OHCI_ED_FA_SHIFT) 132*f1ae32a1SGerd Hoffmann #define OHCI_ED_EN_SHIFT 7 133*f1ae32a1SGerd Hoffmann #define OHCI_ED_EN_MASK (0xf<<OHCI_ED_EN_SHIFT) 134*f1ae32a1SGerd Hoffmann #define OHCI_ED_D_SHIFT 11 135*f1ae32a1SGerd Hoffmann #define OHCI_ED_D_MASK (3<<OHCI_ED_D_SHIFT) 136*f1ae32a1SGerd Hoffmann #define OHCI_ED_S (1<<13) 137*f1ae32a1SGerd Hoffmann #define OHCI_ED_K (1<<14) 138*f1ae32a1SGerd Hoffmann #define OHCI_ED_F (1<<15) 139*f1ae32a1SGerd Hoffmann #define OHCI_ED_MPS_SHIFT 16 140*f1ae32a1SGerd Hoffmann #define OHCI_ED_MPS_MASK (0x7ff<<OHCI_ED_MPS_SHIFT) 141*f1ae32a1SGerd Hoffmann 142*f1ae32a1SGerd Hoffmann /* Flags in the head field of an Endpoint Desciptor. */ 143*f1ae32a1SGerd Hoffmann #define OHCI_ED_H 1 144*f1ae32a1SGerd Hoffmann #define OHCI_ED_C 2 145*f1ae32a1SGerd Hoffmann 146*f1ae32a1SGerd Hoffmann /* Bitfields for the first word of a Transfer Desciptor. */ 147*f1ae32a1SGerd Hoffmann #define OHCI_TD_R (1<<18) 148*f1ae32a1SGerd Hoffmann #define OHCI_TD_DP_SHIFT 19 149*f1ae32a1SGerd Hoffmann #define OHCI_TD_DP_MASK (3<<OHCI_TD_DP_SHIFT) 150*f1ae32a1SGerd Hoffmann #define OHCI_TD_DI_SHIFT 21 151*f1ae32a1SGerd Hoffmann #define OHCI_TD_DI_MASK (7<<OHCI_TD_DI_SHIFT) 152*f1ae32a1SGerd Hoffmann #define OHCI_TD_T0 (1<<24) 153*f1ae32a1SGerd Hoffmann #define OHCI_TD_T1 (1<<25) 154*f1ae32a1SGerd Hoffmann #define OHCI_TD_EC_SHIFT 26 155*f1ae32a1SGerd Hoffmann #define OHCI_TD_EC_MASK (3<<OHCI_TD_EC_SHIFT) 156*f1ae32a1SGerd Hoffmann #define OHCI_TD_CC_SHIFT 28 157*f1ae32a1SGerd Hoffmann #define OHCI_TD_CC_MASK (0xf<<OHCI_TD_CC_SHIFT) 158*f1ae32a1SGerd Hoffmann 159*f1ae32a1SGerd Hoffmann /* Bitfields for the first word of an Isochronous Transfer Desciptor. */ 160*f1ae32a1SGerd Hoffmann /* CC & DI - same as in the General Transfer Desciptor */ 161*f1ae32a1SGerd Hoffmann #define OHCI_TD_SF_SHIFT 0 162*f1ae32a1SGerd Hoffmann #define OHCI_TD_SF_MASK (0xffff<<OHCI_TD_SF_SHIFT) 163*f1ae32a1SGerd Hoffmann #define OHCI_TD_FC_SHIFT 24 164*f1ae32a1SGerd Hoffmann #define OHCI_TD_FC_MASK (7<<OHCI_TD_FC_SHIFT) 165*f1ae32a1SGerd Hoffmann 166*f1ae32a1SGerd Hoffmann /* Isochronous Transfer Desciptor - Offset / PacketStatusWord */ 167*f1ae32a1SGerd Hoffmann #define OHCI_TD_PSW_CC_SHIFT 12 168*f1ae32a1SGerd Hoffmann #define OHCI_TD_PSW_CC_MASK (0xf<<OHCI_TD_PSW_CC_SHIFT) 169*f1ae32a1SGerd Hoffmann #define OHCI_TD_PSW_SIZE_SHIFT 0 170*f1ae32a1SGerd Hoffmann #define OHCI_TD_PSW_SIZE_MASK (0xfff<<OHCI_TD_PSW_SIZE_SHIFT) 171*f1ae32a1SGerd Hoffmann 172*f1ae32a1SGerd Hoffmann #define OHCI_PAGE_MASK 0xfffff000 173*f1ae32a1SGerd Hoffmann #define OHCI_OFFSET_MASK 0xfff 174*f1ae32a1SGerd Hoffmann 175*f1ae32a1SGerd Hoffmann #define OHCI_DPTR_MASK 0xfffffff0 176*f1ae32a1SGerd Hoffmann 177*f1ae32a1SGerd Hoffmann #define OHCI_BM(val, field) \ 178*f1ae32a1SGerd Hoffmann (((val) & OHCI_##field##_MASK) >> OHCI_##field##_SHIFT) 179*f1ae32a1SGerd Hoffmann 180*f1ae32a1SGerd Hoffmann #define OHCI_SET_BM(val, field, newval) do { \ 181*f1ae32a1SGerd Hoffmann val &= ~OHCI_##field##_MASK; \ 182*f1ae32a1SGerd Hoffmann val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \ 183*f1ae32a1SGerd Hoffmann } while(0) 184*f1ae32a1SGerd Hoffmann 185*f1ae32a1SGerd Hoffmann /* endpoint descriptor */ 186*f1ae32a1SGerd Hoffmann struct ohci_ed { 187*f1ae32a1SGerd Hoffmann uint32_t flags; 188*f1ae32a1SGerd Hoffmann uint32_t tail; 189*f1ae32a1SGerd Hoffmann uint32_t head; 190*f1ae32a1SGerd Hoffmann uint32_t next; 191*f1ae32a1SGerd Hoffmann }; 192*f1ae32a1SGerd Hoffmann 193*f1ae32a1SGerd Hoffmann /* General transfer descriptor */ 194*f1ae32a1SGerd Hoffmann struct ohci_td { 195*f1ae32a1SGerd Hoffmann uint32_t flags; 196*f1ae32a1SGerd Hoffmann uint32_t cbp; 197*f1ae32a1SGerd Hoffmann uint32_t next; 198*f1ae32a1SGerd Hoffmann uint32_t be; 199*f1ae32a1SGerd Hoffmann }; 200*f1ae32a1SGerd Hoffmann 201*f1ae32a1SGerd Hoffmann /* Isochronous transfer descriptor */ 202*f1ae32a1SGerd Hoffmann struct ohci_iso_td { 203*f1ae32a1SGerd Hoffmann uint32_t flags; 204*f1ae32a1SGerd Hoffmann uint32_t bp; 205*f1ae32a1SGerd Hoffmann uint32_t next; 206*f1ae32a1SGerd Hoffmann uint32_t be; 207*f1ae32a1SGerd Hoffmann uint16_t offset[8]; 208*f1ae32a1SGerd Hoffmann }; 209*f1ae32a1SGerd Hoffmann 210*f1ae32a1SGerd Hoffmann #define USB_HZ 12000000 211*f1ae32a1SGerd Hoffmann 212*f1ae32a1SGerd Hoffmann /* OHCI Local stuff */ 213*f1ae32a1SGerd Hoffmann #define OHCI_CTL_CBSR ((1<<0)|(1<<1)) 214*f1ae32a1SGerd Hoffmann #define OHCI_CTL_PLE (1<<2) 215*f1ae32a1SGerd Hoffmann #define OHCI_CTL_IE (1<<3) 216*f1ae32a1SGerd Hoffmann #define OHCI_CTL_CLE (1<<4) 217*f1ae32a1SGerd Hoffmann #define OHCI_CTL_BLE (1<<5) 218*f1ae32a1SGerd Hoffmann #define OHCI_CTL_HCFS ((1<<6)|(1<<7)) 219*f1ae32a1SGerd Hoffmann #define OHCI_USB_RESET 0x00 220*f1ae32a1SGerd Hoffmann #define OHCI_USB_RESUME 0x40 221*f1ae32a1SGerd Hoffmann #define OHCI_USB_OPERATIONAL 0x80 222*f1ae32a1SGerd Hoffmann #define OHCI_USB_SUSPEND 0xc0 223*f1ae32a1SGerd Hoffmann #define OHCI_CTL_IR (1<<8) 224*f1ae32a1SGerd Hoffmann #define OHCI_CTL_RWC (1<<9) 225*f1ae32a1SGerd Hoffmann #define OHCI_CTL_RWE (1<<10) 226*f1ae32a1SGerd Hoffmann 227*f1ae32a1SGerd Hoffmann #define OHCI_STATUS_HCR (1<<0) 228*f1ae32a1SGerd Hoffmann #define OHCI_STATUS_CLF (1<<1) 229*f1ae32a1SGerd Hoffmann #define OHCI_STATUS_BLF (1<<2) 230*f1ae32a1SGerd Hoffmann #define OHCI_STATUS_OCR (1<<3) 231*f1ae32a1SGerd Hoffmann #define OHCI_STATUS_SOC ((1<<6)|(1<<7)) 232*f1ae32a1SGerd Hoffmann 233*f1ae32a1SGerd Hoffmann #define OHCI_INTR_SO (1<<0) /* Scheduling overrun */ 234*f1ae32a1SGerd Hoffmann #define OHCI_INTR_WD (1<<1) /* HcDoneHead writeback */ 235*f1ae32a1SGerd Hoffmann #define OHCI_INTR_SF (1<<2) /* Start of frame */ 236*f1ae32a1SGerd Hoffmann #define OHCI_INTR_RD (1<<3) /* Resume detect */ 237*f1ae32a1SGerd Hoffmann #define OHCI_INTR_UE (1<<4) /* Unrecoverable error */ 238*f1ae32a1SGerd Hoffmann #define OHCI_INTR_FNO (1<<5) /* Frame number overflow */ 239*f1ae32a1SGerd Hoffmann #define OHCI_INTR_RHSC (1<<6) /* Root hub status change */ 240*f1ae32a1SGerd Hoffmann #define OHCI_INTR_OC (1<<30) /* Ownership change */ 241*f1ae32a1SGerd Hoffmann #define OHCI_INTR_MIE (1<<31) /* Master Interrupt Enable */ 242*f1ae32a1SGerd Hoffmann 243*f1ae32a1SGerd Hoffmann #define OHCI_HCCA_SIZE 0x100 244*f1ae32a1SGerd Hoffmann #define OHCI_HCCA_MASK 0xffffff00 245*f1ae32a1SGerd Hoffmann 246*f1ae32a1SGerd Hoffmann #define OHCI_EDPTR_MASK 0xfffffff0 247*f1ae32a1SGerd Hoffmann 248*f1ae32a1SGerd Hoffmann #define OHCI_FMI_FI 0x00003fff 249*f1ae32a1SGerd Hoffmann #define OHCI_FMI_FSMPS 0xffff0000 250*f1ae32a1SGerd Hoffmann #define OHCI_FMI_FIT 0x80000000 251*f1ae32a1SGerd Hoffmann 252*f1ae32a1SGerd Hoffmann #define OHCI_FR_RT (1<<31) 253*f1ae32a1SGerd Hoffmann 254*f1ae32a1SGerd Hoffmann #define OHCI_LS_THRESH 0x628 255*f1ae32a1SGerd Hoffmann 256*f1ae32a1SGerd Hoffmann #define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */ 257*f1ae32a1SGerd Hoffmann #define OHCI_RHA_PSM (1<<8) 258*f1ae32a1SGerd Hoffmann #define OHCI_RHA_NPS (1<<9) 259*f1ae32a1SGerd Hoffmann #define OHCI_RHA_DT (1<<10) 260*f1ae32a1SGerd Hoffmann #define OHCI_RHA_OCPM (1<<11) 261*f1ae32a1SGerd Hoffmann #define OHCI_RHA_NOCP (1<<12) 262*f1ae32a1SGerd Hoffmann #define OHCI_RHA_POTPGT_MASK 0xff000000 263*f1ae32a1SGerd Hoffmann 264*f1ae32a1SGerd Hoffmann #define OHCI_RHS_LPS (1<<0) 265*f1ae32a1SGerd Hoffmann #define OHCI_RHS_OCI (1<<1) 266*f1ae32a1SGerd Hoffmann #define OHCI_RHS_DRWE (1<<15) 267*f1ae32a1SGerd Hoffmann #define OHCI_RHS_LPSC (1<<16) 268*f1ae32a1SGerd Hoffmann #define OHCI_RHS_OCIC (1<<17) 269*f1ae32a1SGerd Hoffmann #define OHCI_RHS_CRWE (1<<31) 270*f1ae32a1SGerd Hoffmann 271*f1ae32a1SGerd Hoffmann #define OHCI_PORT_CCS (1<<0) 272*f1ae32a1SGerd Hoffmann #define OHCI_PORT_PES (1<<1) 273*f1ae32a1SGerd Hoffmann #define OHCI_PORT_PSS (1<<2) 274*f1ae32a1SGerd Hoffmann #define OHCI_PORT_POCI (1<<3) 275*f1ae32a1SGerd Hoffmann #define OHCI_PORT_PRS (1<<4) 276*f1ae32a1SGerd Hoffmann #define OHCI_PORT_PPS (1<<8) 277*f1ae32a1SGerd Hoffmann #define OHCI_PORT_LSDA (1<<9) 278*f1ae32a1SGerd Hoffmann #define OHCI_PORT_CSC (1<<16) 279*f1ae32a1SGerd Hoffmann #define OHCI_PORT_PESC (1<<17) 280*f1ae32a1SGerd Hoffmann #define OHCI_PORT_PSSC (1<<18) 281*f1ae32a1SGerd Hoffmann #define OHCI_PORT_OCIC (1<<19) 282*f1ae32a1SGerd Hoffmann #define OHCI_PORT_PRSC (1<<20) 283*f1ae32a1SGerd Hoffmann #define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \ 284*f1ae32a1SGerd Hoffmann |OHCI_PORT_OCIC|OHCI_PORT_PRSC) 285*f1ae32a1SGerd Hoffmann 286*f1ae32a1SGerd Hoffmann #define OHCI_TD_DIR_SETUP 0x0 287*f1ae32a1SGerd Hoffmann #define OHCI_TD_DIR_OUT 0x1 288*f1ae32a1SGerd Hoffmann #define OHCI_TD_DIR_IN 0x2 289*f1ae32a1SGerd Hoffmann #define OHCI_TD_DIR_RESERVED 0x3 290*f1ae32a1SGerd Hoffmann 291*f1ae32a1SGerd Hoffmann #define OHCI_CC_NOERROR 0x0 292*f1ae32a1SGerd Hoffmann #define OHCI_CC_CRC 0x1 293*f1ae32a1SGerd Hoffmann #define OHCI_CC_BITSTUFFING 0x2 294*f1ae32a1SGerd Hoffmann #define OHCI_CC_DATATOGGLEMISMATCH 0x3 295*f1ae32a1SGerd Hoffmann #define OHCI_CC_STALL 0x4 296*f1ae32a1SGerd Hoffmann #define OHCI_CC_DEVICENOTRESPONDING 0x5 297*f1ae32a1SGerd Hoffmann #define OHCI_CC_PIDCHECKFAILURE 0x6 298*f1ae32a1SGerd Hoffmann #define OHCI_CC_UNDEXPETEDPID 0x7 299*f1ae32a1SGerd Hoffmann #define OHCI_CC_DATAOVERRUN 0x8 300*f1ae32a1SGerd Hoffmann #define OHCI_CC_DATAUNDERRUN 0x9 301*f1ae32a1SGerd Hoffmann #define OHCI_CC_BUFFEROVERRUN 0xc 302*f1ae32a1SGerd Hoffmann #define OHCI_CC_BUFFERUNDERRUN 0xd 303*f1ae32a1SGerd Hoffmann 304*f1ae32a1SGerd Hoffmann #define OHCI_HRESET_FSBIR (1 << 0) 305*f1ae32a1SGerd Hoffmann 306*f1ae32a1SGerd Hoffmann /* Update IRQ levels */ 307*f1ae32a1SGerd Hoffmann static inline void ohci_intr_update(OHCIState *ohci) 308*f1ae32a1SGerd Hoffmann { 309*f1ae32a1SGerd Hoffmann int level = 0; 310*f1ae32a1SGerd Hoffmann 311*f1ae32a1SGerd Hoffmann if ((ohci->intr & OHCI_INTR_MIE) && 312*f1ae32a1SGerd Hoffmann (ohci->intr_status & ohci->intr)) 313*f1ae32a1SGerd Hoffmann level = 1; 314*f1ae32a1SGerd Hoffmann 315*f1ae32a1SGerd Hoffmann qemu_set_irq(ohci->irq, level); 316*f1ae32a1SGerd Hoffmann } 317*f1ae32a1SGerd Hoffmann 318*f1ae32a1SGerd Hoffmann /* Set an interrupt */ 319*f1ae32a1SGerd Hoffmann static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr) 320*f1ae32a1SGerd Hoffmann { 321*f1ae32a1SGerd Hoffmann ohci->intr_status |= intr; 322*f1ae32a1SGerd Hoffmann ohci_intr_update(ohci); 323*f1ae32a1SGerd Hoffmann } 324*f1ae32a1SGerd Hoffmann 325*f1ae32a1SGerd Hoffmann /* Attach or detach a device on a root hub port. */ 326*f1ae32a1SGerd Hoffmann static void ohci_attach(USBPort *port1) 327*f1ae32a1SGerd Hoffmann { 328*f1ae32a1SGerd Hoffmann OHCIState *s = port1->opaque; 329*f1ae32a1SGerd Hoffmann OHCIPort *port = &s->rhport[port1->index]; 330*f1ae32a1SGerd Hoffmann uint32_t old_state = port->ctrl; 331*f1ae32a1SGerd Hoffmann 332*f1ae32a1SGerd Hoffmann /* set connect status */ 333*f1ae32a1SGerd Hoffmann port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC; 334*f1ae32a1SGerd Hoffmann 335*f1ae32a1SGerd Hoffmann /* update speed */ 336*f1ae32a1SGerd Hoffmann if (port->port.dev->speed == USB_SPEED_LOW) { 337*f1ae32a1SGerd Hoffmann port->ctrl |= OHCI_PORT_LSDA; 338*f1ae32a1SGerd Hoffmann } else { 339*f1ae32a1SGerd Hoffmann port->ctrl &= ~OHCI_PORT_LSDA; 340*f1ae32a1SGerd Hoffmann } 341*f1ae32a1SGerd Hoffmann 342*f1ae32a1SGerd Hoffmann /* notify of remote-wakeup */ 343*f1ae32a1SGerd Hoffmann if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) { 344*f1ae32a1SGerd Hoffmann ohci_set_interrupt(s, OHCI_INTR_RD); 345*f1ae32a1SGerd Hoffmann } 346*f1ae32a1SGerd Hoffmann 347*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: Attached port %d\n", port1->index); 348*f1ae32a1SGerd Hoffmann 349*f1ae32a1SGerd Hoffmann if (old_state != port->ctrl) { 350*f1ae32a1SGerd Hoffmann ohci_set_interrupt(s, OHCI_INTR_RHSC); 351*f1ae32a1SGerd Hoffmann } 352*f1ae32a1SGerd Hoffmann } 353*f1ae32a1SGerd Hoffmann 354*f1ae32a1SGerd Hoffmann static void ohci_detach(USBPort *port1) 355*f1ae32a1SGerd Hoffmann { 356*f1ae32a1SGerd Hoffmann OHCIState *s = port1->opaque; 357*f1ae32a1SGerd Hoffmann OHCIPort *port = &s->rhport[port1->index]; 358*f1ae32a1SGerd Hoffmann uint32_t old_state = port->ctrl; 359*f1ae32a1SGerd Hoffmann 360*f1ae32a1SGerd Hoffmann ohci_async_cancel_device(s, port1->dev); 361*f1ae32a1SGerd Hoffmann 362*f1ae32a1SGerd Hoffmann /* set connect status */ 363*f1ae32a1SGerd Hoffmann if (port->ctrl & OHCI_PORT_CCS) { 364*f1ae32a1SGerd Hoffmann port->ctrl &= ~OHCI_PORT_CCS; 365*f1ae32a1SGerd Hoffmann port->ctrl |= OHCI_PORT_CSC; 366*f1ae32a1SGerd Hoffmann } 367*f1ae32a1SGerd Hoffmann /* disable port */ 368*f1ae32a1SGerd Hoffmann if (port->ctrl & OHCI_PORT_PES) { 369*f1ae32a1SGerd Hoffmann port->ctrl &= ~OHCI_PORT_PES; 370*f1ae32a1SGerd Hoffmann port->ctrl |= OHCI_PORT_PESC; 371*f1ae32a1SGerd Hoffmann } 372*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: Detached port %d\n", port1->index); 373*f1ae32a1SGerd Hoffmann 374*f1ae32a1SGerd Hoffmann if (old_state != port->ctrl) { 375*f1ae32a1SGerd Hoffmann ohci_set_interrupt(s, OHCI_INTR_RHSC); 376*f1ae32a1SGerd Hoffmann } 377*f1ae32a1SGerd Hoffmann } 378*f1ae32a1SGerd Hoffmann 379*f1ae32a1SGerd Hoffmann static void ohci_wakeup(USBPort *port1) 380*f1ae32a1SGerd Hoffmann { 381*f1ae32a1SGerd Hoffmann OHCIState *s = port1->opaque; 382*f1ae32a1SGerd Hoffmann OHCIPort *port = &s->rhport[port1->index]; 383*f1ae32a1SGerd Hoffmann uint32_t intr = 0; 384*f1ae32a1SGerd Hoffmann if (port->ctrl & OHCI_PORT_PSS) { 385*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: port %d: wakeup\n", port1->index); 386*f1ae32a1SGerd Hoffmann port->ctrl |= OHCI_PORT_PSSC; 387*f1ae32a1SGerd Hoffmann port->ctrl &= ~OHCI_PORT_PSS; 388*f1ae32a1SGerd Hoffmann intr = OHCI_INTR_RHSC; 389*f1ae32a1SGerd Hoffmann } 390*f1ae32a1SGerd Hoffmann /* Note that the controller can be suspended even if this port is not */ 391*f1ae32a1SGerd Hoffmann if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) { 392*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: remote-wakeup: SUSPEND->RESUME\n"); 393*f1ae32a1SGerd Hoffmann /* This is the one state transition the controller can do by itself */ 394*f1ae32a1SGerd Hoffmann s->ctl &= ~OHCI_CTL_HCFS; 395*f1ae32a1SGerd Hoffmann s->ctl |= OHCI_USB_RESUME; 396*f1ae32a1SGerd Hoffmann /* In suspend mode only ResumeDetected is possible, not RHSC: 397*f1ae32a1SGerd Hoffmann * see the OHCI spec 5.1.2.3. 398*f1ae32a1SGerd Hoffmann */ 399*f1ae32a1SGerd Hoffmann intr = OHCI_INTR_RD; 400*f1ae32a1SGerd Hoffmann } 401*f1ae32a1SGerd Hoffmann ohci_set_interrupt(s, intr); 402*f1ae32a1SGerd Hoffmann } 403*f1ae32a1SGerd Hoffmann 404*f1ae32a1SGerd Hoffmann static void ohci_child_detach(USBPort *port1, USBDevice *child) 405*f1ae32a1SGerd Hoffmann { 406*f1ae32a1SGerd Hoffmann OHCIState *s = port1->opaque; 407*f1ae32a1SGerd Hoffmann 408*f1ae32a1SGerd Hoffmann ohci_async_cancel_device(s, child); 409*f1ae32a1SGerd Hoffmann } 410*f1ae32a1SGerd Hoffmann 411*f1ae32a1SGerd Hoffmann static USBDevice *ohci_find_device(OHCIState *ohci, uint8_t addr) 412*f1ae32a1SGerd Hoffmann { 413*f1ae32a1SGerd Hoffmann USBDevice *dev; 414*f1ae32a1SGerd Hoffmann int i; 415*f1ae32a1SGerd Hoffmann 416*f1ae32a1SGerd Hoffmann for (i = 0; i < ohci->num_ports; i++) { 417*f1ae32a1SGerd Hoffmann if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) { 418*f1ae32a1SGerd Hoffmann continue; 419*f1ae32a1SGerd Hoffmann } 420*f1ae32a1SGerd Hoffmann dev = usb_find_device(&ohci->rhport[i].port, addr); 421*f1ae32a1SGerd Hoffmann if (dev != NULL) { 422*f1ae32a1SGerd Hoffmann return dev; 423*f1ae32a1SGerd Hoffmann } 424*f1ae32a1SGerd Hoffmann } 425*f1ae32a1SGerd Hoffmann return NULL; 426*f1ae32a1SGerd Hoffmann } 427*f1ae32a1SGerd Hoffmann 428*f1ae32a1SGerd Hoffmann /* Reset the controller */ 429*f1ae32a1SGerd Hoffmann static void ohci_reset(void *opaque) 430*f1ae32a1SGerd Hoffmann { 431*f1ae32a1SGerd Hoffmann OHCIState *ohci = opaque; 432*f1ae32a1SGerd Hoffmann OHCIPort *port; 433*f1ae32a1SGerd Hoffmann int i; 434*f1ae32a1SGerd Hoffmann 435*f1ae32a1SGerd Hoffmann ohci_bus_stop(ohci); 436*f1ae32a1SGerd Hoffmann ohci->ctl = 0; 437*f1ae32a1SGerd Hoffmann ohci->old_ctl = 0; 438*f1ae32a1SGerd Hoffmann ohci->status = 0; 439*f1ae32a1SGerd Hoffmann ohci->intr_status = 0; 440*f1ae32a1SGerd Hoffmann ohci->intr = OHCI_INTR_MIE; 441*f1ae32a1SGerd Hoffmann 442*f1ae32a1SGerd Hoffmann ohci->hcca = 0; 443*f1ae32a1SGerd Hoffmann ohci->ctrl_head = ohci->ctrl_cur = 0; 444*f1ae32a1SGerd Hoffmann ohci->bulk_head = ohci->bulk_cur = 0; 445*f1ae32a1SGerd Hoffmann ohci->per_cur = 0; 446*f1ae32a1SGerd Hoffmann ohci->done = 0; 447*f1ae32a1SGerd Hoffmann ohci->done_count = 7; 448*f1ae32a1SGerd Hoffmann 449*f1ae32a1SGerd Hoffmann /* FSMPS is marked TBD in OCHI 1.0, what gives ffs? 450*f1ae32a1SGerd Hoffmann * I took the value linux sets ... 451*f1ae32a1SGerd Hoffmann */ 452*f1ae32a1SGerd Hoffmann ohci->fsmps = 0x2778; 453*f1ae32a1SGerd Hoffmann ohci->fi = 0x2edf; 454*f1ae32a1SGerd Hoffmann ohci->fit = 0; 455*f1ae32a1SGerd Hoffmann ohci->frt = 0; 456*f1ae32a1SGerd Hoffmann ohci->frame_number = 0; 457*f1ae32a1SGerd Hoffmann ohci->pstart = 0; 458*f1ae32a1SGerd Hoffmann ohci->lst = OHCI_LS_THRESH; 459*f1ae32a1SGerd Hoffmann 460*f1ae32a1SGerd Hoffmann ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports; 461*f1ae32a1SGerd Hoffmann ohci->rhdesc_b = 0x0; /* Impl. specific */ 462*f1ae32a1SGerd Hoffmann ohci->rhstatus = 0; 463*f1ae32a1SGerd Hoffmann 464*f1ae32a1SGerd Hoffmann for (i = 0; i < ohci->num_ports; i++) 465*f1ae32a1SGerd Hoffmann { 466*f1ae32a1SGerd Hoffmann port = &ohci->rhport[i]; 467*f1ae32a1SGerd Hoffmann port->ctrl = 0; 468*f1ae32a1SGerd Hoffmann if (port->port.dev && port->port.dev->attached) { 469*f1ae32a1SGerd Hoffmann usb_port_reset(&port->port); 470*f1ae32a1SGerd Hoffmann } 471*f1ae32a1SGerd Hoffmann } 472*f1ae32a1SGerd Hoffmann if (ohci->async_td) { 473*f1ae32a1SGerd Hoffmann usb_cancel_packet(&ohci->usb_packet); 474*f1ae32a1SGerd Hoffmann ohci->async_td = 0; 475*f1ae32a1SGerd Hoffmann } 476*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: Reset %s\n", ohci->name); 477*f1ae32a1SGerd Hoffmann } 478*f1ae32a1SGerd Hoffmann 479*f1ae32a1SGerd Hoffmann /* Get an array of dwords from main memory */ 480*f1ae32a1SGerd Hoffmann static inline int get_dwords(OHCIState *ohci, 481*f1ae32a1SGerd Hoffmann uint32_t addr, uint32_t *buf, int num) 482*f1ae32a1SGerd Hoffmann { 483*f1ae32a1SGerd Hoffmann int i; 484*f1ae32a1SGerd Hoffmann 485*f1ae32a1SGerd Hoffmann addr += ohci->localmem_base; 486*f1ae32a1SGerd Hoffmann 487*f1ae32a1SGerd Hoffmann for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { 488*f1ae32a1SGerd Hoffmann cpu_physical_memory_read(addr, buf, sizeof(*buf)); 489*f1ae32a1SGerd Hoffmann *buf = le32_to_cpu(*buf); 490*f1ae32a1SGerd Hoffmann } 491*f1ae32a1SGerd Hoffmann 492*f1ae32a1SGerd Hoffmann return 1; 493*f1ae32a1SGerd Hoffmann } 494*f1ae32a1SGerd Hoffmann 495*f1ae32a1SGerd Hoffmann /* Put an array of dwords in to main memory */ 496*f1ae32a1SGerd Hoffmann static inline int put_dwords(OHCIState *ohci, 497*f1ae32a1SGerd Hoffmann uint32_t addr, uint32_t *buf, int num) 498*f1ae32a1SGerd Hoffmann { 499*f1ae32a1SGerd Hoffmann int i; 500*f1ae32a1SGerd Hoffmann 501*f1ae32a1SGerd Hoffmann addr += ohci->localmem_base; 502*f1ae32a1SGerd Hoffmann 503*f1ae32a1SGerd Hoffmann for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { 504*f1ae32a1SGerd Hoffmann uint32_t tmp = cpu_to_le32(*buf); 505*f1ae32a1SGerd Hoffmann cpu_physical_memory_write(addr, &tmp, sizeof(tmp)); 506*f1ae32a1SGerd Hoffmann } 507*f1ae32a1SGerd Hoffmann 508*f1ae32a1SGerd Hoffmann return 1; 509*f1ae32a1SGerd Hoffmann } 510*f1ae32a1SGerd Hoffmann 511*f1ae32a1SGerd Hoffmann /* Get an array of words from main memory */ 512*f1ae32a1SGerd Hoffmann static inline int get_words(OHCIState *ohci, 513*f1ae32a1SGerd Hoffmann uint32_t addr, uint16_t *buf, int num) 514*f1ae32a1SGerd Hoffmann { 515*f1ae32a1SGerd Hoffmann int i; 516*f1ae32a1SGerd Hoffmann 517*f1ae32a1SGerd Hoffmann addr += ohci->localmem_base; 518*f1ae32a1SGerd Hoffmann 519*f1ae32a1SGerd Hoffmann for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { 520*f1ae32a1SGerd Hoffmann cpu_physical_memory_read(addr, buf, sizeof(*buf)); 521*f1ae32a1SGerd Hoffmann *buf = le16_to_cpu(*buf); 522*f1ae32a1SGerd Hoffmann } 523*f1ae32a1SGerd Hoffmann 524*f1ae32a1SGerd Hoffmann return 1; 525*f1ae32a1SGerd Hoffmann } 526*f1ae32a1SGerd Hoffmann 527*f1ae32a1SGerd Hoffmann /* Put an array of words in to main memory */ 528*f1ae32a1SGerd Hoffmann static inline int put_words(OHCIState *ohci, 529*f1ae32a1SGerd Hoffmann uint32_t addr, uint16_t *buf, int num) 530*f1ae32a1SGerd Hoffmann { 531*f1ae32a1SGerd Hoffmann int i; 532*f1ae32a1SGerd Hoffmann 533*f1ae32a1SGerd Hoffmann addr += ohci->localmem_base; 534*f1ae32a1SGerd Hoffmann 535*f1ae32a1SGerd Hoffmann for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { 536*f1ae32a1SGerd Hoffmann uint16_t tmp = cpu_to_le16(*buf); 537*f1ae32a1SGerd Hoffmann cpu_physical_memory_write(addr, &tmp, sizeof(tmp)); 538*f1ae32a1SGerd Hoffmann } 539*f1ae32a1SGerd Hoffmann 540*f1ae32a1SGerd Hoffmann return 1; 541*f1ae32a1SGerd Hoffmann } 542*f1ae32a1SGerd Hoffmann 543*f1ae32a1SGerd Hoffmann static inline int ohci_read_ed(OHCIState *ohci, 544*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_ed *ed) 545*f1ae32a1SGerd Hoffmann { 546*f1ae32a1SGerd Hoffmann return get_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2); 547*f1ae32a1SGerd Hoffmann } 548*f1ae32a1SGerd Hoffmann 549*f1ae32a1SGerd Hoffmann static inline int ohci_read_td(OHCIState *ohci, 550*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_td *td) 551*f1ae32a1SGerd Hoffmann { 552*f1ae32a1SGerd Hoffmann return get_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2); 553*f1ae32a1SGerd Hoffmann } 554*f1ae32a1SGerd Hoffmann 555*f1ae32a1SGerd Hoffmann static inline int ohci_read_iso_td(OHCIState *ohci, 556*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_iso_td *td) 557*f1ae32a1SGerd Hoffmann { 558*f1ae32a1SGerd Hoffmann return (get_dwords(ohci, addr, (uint32_t *)td, 4) && 559*f1ae32a1SGerd Hoffmann get_words(ohci, addr + 16, td->offset, 8)); 560*f1ae32a1SGerd Hoffmann } 561*f1ae32a1SGerd Hoffmann 562*f1ae32a1SGerd Hoffmann static inline int ohci_read_hcca(OHCIState *ohci, 563*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_hcca *hcca) 564*f1ae32a1SGerd Hoffmann { 565*f1ae32a1SGerd Hoffmann cpu_physical_memory_read(addr + ohci->localmem_base, hcca, sizeof(*hcca)); 566*f1ae32a1SGerd Hoffmann return 1; 567*f1ae32a1SGerd Hoffmann } 568*f1ae32a1SGerd Hoffmann 569*f1ae32a1SGerd Hoffmann static inline int ohci_put_ed(OHCIState *ohci, 570*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_ed *ed) 571*f1ae32a1SGerd Hoffmann { 572*f1ae32a1SGerd Hoffmann return put_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2); 573*f1ae32a1SGerd Hoffmann } 574*f1ae32a1SGerd Hoffmann 575*f1ae32a1SGerd Hoffmann static inline int ohci_put_td(OHCIState *ohci, 576*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_td *td) 577*f1ae32a1SGerd Hoffmann { 578*f1ae32a1SGerd Hoffmann return put_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2); 579*f1ae32a1SGerd Hoffmann } 580*f1ae32a1SGerd Hoffmann 581*f1ae32a1SGerd Hoffmann static inline int ohci_put_iso_td(OHCIState *ohci, 582*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_iso_td *td) 583*f1ae32a1SGerd Hoffmann { 584*f1ae32a1SGerd Hoffmann return (put_dwords(ohci, addr, (uint32_t *)td, 4) && 585*f1ae32a1SGerd Hoffmann put_words(ohci, addr + 16, td->offset, 8)); 586*f1ae32a1SGerd Hoffmann } 587*f1ae32a1SGerd Hoffmann 588*f1ae32a1SGerd Hoffmann static inline int ohci_put_hcca(OHCIState *ohci, 589*f1ae32a1SGerd Hoffmann uint32_t addr, struct ohci_hcca *hcca) 590*f1ae32a1SGerd Hoffmann { 591*f1ae32a1SGerd Hoffmann cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca)); 592*f1ae32a1SGerd Hoffmann return 1; 593*f1ae32a1SGerd Hoffmann } 594*f1ae32a1SGerd Hoffmann 595*f1ae32a1SGerd Hoffmann /* Read/Write the contents of a TD from/to main memory. */ 596*f1ae32a1SGerd Hoffmann static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td, 597*f1ae32a1SGerd Hoffmann uint8_t *buf, int len, int write) 598*f1ae32a1SGerd Hoffmann { 599*f1ae32a1SGerd Hoffmann uint32_t ptr; 600*f1ae32a1SGerd Hoffmann uint32_t n; 601*f1ae32a1SGerd Hoffmann 602*f1ae32a1SGerd Hoffmann ptr = td->cbp; 603*f1ae32a1SGerd Hoffmann n = 0x1000 - (ptr & 0xfff); 604*f1ae32a1SGerd Hoffmann if (n > len) 605*f1ae32a1SGerd Hoffmann n = len; 606*f1ae32a1SGerd Hoffmann cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write); 607*f1ae32a1SGerd Hoffmann if (n == len) 608*f1ae32a1SGerd Hoffmann return; 609*f1ae32a1SGerd Hoffmann ptr = td->be & ~0xfffu; 610*f1ae32a1SGerd Hoffmann buf += n; 611*f1ae32a1SGerd Hoffmann cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write); 612*f1ae32a1SGerd Hoffmann } 613*f1ae32a1SGerd Hoffmann 614*f1ae32a1SGerd Hoffmann /* Read/Write the contents of an ISO TD from/to main memory. */ 615*f1ae32a1SGerd Hoffmann static void ohci_copy_iso_td(OHCIState *ohci, 616*f1ae32a1SGerd Hoffmann uint32_t start_addr, uint32_t end_addr, 617*f1ae32a1SGerd Hoffmann uint8_t *buf, int len, int write) 618*f1ae32a1SGerd Hoffmann { 619*f1ae32a1SGerd Hoffmann uint32_t ptr; 620*f1ae32a1SGerd Hoffmann uint32_t n; 621*f1ae32a1SGerd Hoffmann 622*f1ae32a1SGerd Hoffmann ptr = start_addr; 623*f1ae32a1SGerd Hoffmann n = 0x1000 - (ptr & 0xfff); 624*f1ae32a1SGerd Hoffmann if (n > len) 625*f1ae32a1SGerd Hoffmann n = len; 626*f1ae32a1SGerd Hoffmann cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write); 627*f1ae32a1SGerd Hoffmann if (n == len) 628*f1ae32a1SGerd Hoffmann return; 629*f1ae32a1SGerd Hoffmann ptr = end_addr & ~0xfffu; 630*f1ae32a1SGerd Hoffmann buf += n; 631*f1ae32a1SGerd Hoffmann cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write); 632*f1ae32a1SGerd Hoffmann } 633*f1ae32a1SGerd Hoffmann 634*f1ae32a1SGerd Hoffmann static void ohci_process_lists(OHCIState *ohci, int completion); 635*f1ae32a1SGerd Hoffmann 636*f1ae32a1SGerd Hoffmann static void ohci_async_complete_packet(USBPort *port, USBPacket *packet) 637*f1ae32a1SGerd Hoffmann { 638*f1ae32a1SGerd Hoffmann OHCIState *ohci = container_of(packet, OHCIState, usb_packet); 639*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 640*f1ae32a1SGerd Hoffmann DPRINTF("Async packet complete\n"); 641*f1ae32a1SGerd Hoffmann #endif 642*f1ae32a1SGerd Hoffmann ohci->async_complete = 1; 643*f1ae32a1SGerd Hoffmann ohci_process_lists(ohci, 1); 644*f1ae32a1SGerd Hoffmann } 645*f1ae32a1SGerd Hoffmann 646*f1ae32a1SGerd Hoffmann #define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b))) 647*f1ae32a1SGerd Hoffmann 648*f1ae32a1SGerd Hoffmann static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, 649*f1ae32a1SGerd Hoffmann int completion) 650*f1ae32a1SGerd Hoffmann { 651*f1ae32a1SGerd Hoffmann int dir; 652*f1ae32a1SGerd Hoffmann size_t len = 0; 653*f1ae32a1SGerd Hoffmann #ifdef DEBUG_ISOCH 654*f1ae32a1SGerd Hoffmann const char *str = NULL; 655*f1ae32a1SGerd Hoffmann #endif 656*f1ae32a1SGerd Hoffmann int pid; 657*f1ae32a1SGerd Hoffmann int ret; 658*f1ae32a1SGerd Hoffmann int i; 659*f1ae32a1SGerd Hoffmann USBDevice *dev; 660*f1ae32a1SGerd Hoffmann USBEndpoint *ep; 661*f1ae32a1SGerd Hoffmann struct ohci_iso_td iso_td; 662*f1ae32a1SGerd Hoffmann uint32_t addr; 663*f1ae32a1SGerd Hoffmann uint16_t starting_frame; 664*f1ae32a1SGerd Hoffmann int16_t relative_frame_number; 665*f1ae32a1SGerd Hoffmann int frame_count; 666*f1ae32a1SGerd Hoffmann uint32_t start_offset, next_offset, end_offset = 0; 667*f1ae32a1SGerd Hoffmann uint32_t start_addr, end_addr; 668*f1ae32a1SGerd Hoffmann 669*f1ae32a1SGerd Hoffmann addr = ed->head & OHCI_DPTR_MASK; 670*f1ae32a1SGerd Hoffmann 671*f1ae32a1SGerd Hoffmann if (!ohci_read_iso_td(ohci, addr, &iso_td)) { 672*f1ae32a1SGerd Hoffmann printf("usb-ohci: ISO_TD read error at %x\n", addr); 673*f1ae32a1SGerd Hoffmann return 0; 674*f1ae32a1SGerd Hoffmann } 675*f1ae32a1SGerd Hoffmann 676*f1ae32a1SGerd Hoffmann starting_frame = OHCI_BM(iso_td.flags, TD_SF); 677*f1ae32a1SGerd Hoffmann frame_count = OHCI_BM(iso_td.flags, TD_FC); 678*f1ae32a1SGerd Hoffmann relative_frame_number = USUB(ohci->frame_number, starting_frame); 679*f1ae32a1SGerd Hoffmann 680*f1ae32a1SGerd Hoffmann #ifdef DEBUG_ISOCH 681*f1ae32a1SGerd Hoffmann printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n" 682*f1ae32a1SGerd Hoffmann "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" 683*f1ae32a1SGerd Hoffmann "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" 684*f1ae32a1SGerd Hoffmann "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" 685*f1ae32a1SGerd Hoffmann "frame_number 0x%.8x starting_frame 0x%.8x\n" 686*f1ae32a1SGerd Hoffmann "frame_count 0x%.8x relative %d\n" 687*f1ae32a1SGerd Hoffmann "di 0x%.8x cc 0x%.8x\n", 688*f1ae32a1SGerd Hoffmann ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK, 689*f1ae32a1SGerd Hoffmann iso_td.flags, iso_td.bp, iso_td.next, iso_td.be, 690*f1ae32a1SGerd Hoffmann iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3], 691*f1ae32a1SGerd Hoffmann iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7], 692*f1ae32a1SGerd Hoffmann ohci->frame_number, starting_frame, 693*f1ae32a1SGerd Hoffmann frame_count, relative_frame_number, 694*f1ae32a1SGerd Hoffmann OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC)); 695*f1ae32a1SGerd Hoffmann #endif 696*f1ae32a1SGerd Hoffmann 697*f1ae32a1SGerd Hoffmann if (relative_frame_number < 0) { 698*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number); 699*f1ae32a1SGerd Hoffmann return 1; 700*f1ae32a1SGerd Hoffmann } else if (relative_frame_number > frame_count) { 701*f1ae32a1SGerd Hoffmann /* ISO TD expired - retire the TD to the Done Queue and continue with 702*f1ae32a1SGerd Hoffmann the next ISO TD of the same ED */ 703*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number, 704*f1ae32a1SGerd Hoffmann frame_count); 705*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN); 706*f1ae32a1SGerd Hoffmann ed->head &= ~OHCI_DPTR_MASK; 707*f1ae32a1SGerd Hoffmann ed->head |= (iso_td.next & OHCI_DPTR_MASK); 708*f1ae32a1SGerd Hoffmann iso_td.next = ohci->done; 709*f1ae32a1SGerd Hoffmann ohci->done = addr; 710*f1ae32a1SGerd Hoffmann i = OHCI_BM(iso_td.flags, TD_DI); 711*f1ae32a1SGerd Hoffmann if (i < ohci->done_count) 712*f1ae32a1SGerd Hoffmann ohci->done_count = i; 713*f1ae32a1SGerd Hoffmann ohci_put_iso_td(ohci, addr, &iso_td); 714*f1ae32a1SGerd Hoffmann return 0; 715*f1ae32a1SGerd Hoffmann } 716*f1ae32a1SGerd Hoffmann 717*f1ae32a1SGerd Hoffmann dir = OHCI_BM(ed->flags, ED_D); 718*f1ae32a1SGerd Hoffmann switch (dir) { 719*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_IN: 720*f1ae32a1SGerd Hoffmann #ifdef DEBUG_ISOCH 721*f1ae32a1SGerd Hoffmann str = "in"; 722*f1ae32a1SGerd Hoffmann #endif 723*f1ae32a1SGerd Hoffmann pid = USB_TOKEN_IN; 724*f1ae32a1SGerd Hoffmann break; 725*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_OUT: 726*f1ae32a1SGerd Hoffmann #ifdef DEBUG_ISOCH 727*f1ae32a1SGerd Hoffmann str = "out"; 728*f1ae32a1SGerd Hoffmann #endif 729*f1ae32a1SGerd Hoffmann pid = USB_TOKEN_OUT; 730*f1ae32a1SGerd Hoffmann break; 731*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_SETUP: 732*f1ae32a1SGerd Hoffmann #ifdef DEBUG_ISOCH 733*f1ae32a1SGerd Hoffmann str = "setup"; 734*f1ae32a1SGerd Hoffmann #endif 735*f1ae32a1SGerd Hoffmann pid = USB_TOKEN_SETUP; 736*f1ae32a1SGerd Hoffmann break; 737*f1ae32a1SGerd Hoffmann default: 738*f1ae32a1SGerd Hoffmann printf("usb-ohci: Bad direction %d\n", dir); 739*f1ae32a1SGerd Hoffmann return 1; 740*f1ae32a1SGerd Hoffmann } 741*f1ae32a1SGerd Hoffmann 742*f1ae32a1SGerd Hoffmann if (!iso_td.bp || !iso_td.be) { 743*f1ae32a1SGerd Hoffmann printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be); 744*f1ae32a1SGerd Hoffmann return 1; 745*f1ae32a1SGerd Hoffmann } 746*f1ae32a1SGerd Hoffmann 747*f1ae32a1SGerd Hoffmann start_offset = iso_td.offset[relative_frame_number]; 748*f1ae32a1SGerd Hoffmann next_offset = iso_td.offset[relative_frame_number + 1]; 749*f1ae32a1SGerd Hoffmann 750*f1ae32a1SGerd Hoffmann if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) || 751*f1ae32a1SGerd Hoffmann ((relative_frame_number < frame_count) && 752*f1ae32a1SGerd Hoffmann !(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) { 753*f1ae32a1SGerd Hoffmann printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n", 754*f1ae32a1SGerd Hoffmann start_offset, next_offset); 755*f1ae32a1SGerd Hoffmann return 1; 756*f1ae32a1SGerd Hoffmann } 757*f1ae32a1SGerd Hoffmann 758*f1ae32a1SGerd Hoffmann if ((relative_frame_number < frame_count) && (start_offset > next_offset)) { 759*f1ae32a1SGerd Hoffmann printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n", 760*f1ae32a1SGerd Hoffmann start_offset, next_offset); 761*f1ae32a1SGerd Hoffmann return 1; 762*f1ae32a1SGerd Hoffmann } 763*f1ae32a1SGerd Hoffmann 764*f1ae32a1SGerd Hoffmann if ((start_offset & 0x1000) == 0) { 765*f1ae32a1SGerd Hoffmann start_addr = (iso_td.bp & OHCI_PAGE_MASK) | 766*f1ae32a1SGerd Hoffmann (start_offset & OHCI_OFFSET_MASK); 767*f1ae32a1SGerd Hoffmann } else { 768*f1ae32a1SGerd Hoffmann start_addr = (iso_td.be & OHCI_PAGE_MASK) | 769*f1ae32a1SGerd Hoffmann (start_offset & OHCI_OFFSET_MASK); 770*f1ae32a1SGerd Hoffmann } 771*f1ae32a1SGerd Hoffmann 772*f1ae32a1SGerd Hoffmann if (relative_frame_number < frame_count) { 773*f1ae32a1SGerd Hoffmann end_offset = next_offset - 1; 774*f1ae32a1SGerd Hoffmann if ((end_offset & 0x1000) == 0) { 775*f1ae32a1SGerd Hoffmann end_addr = (iso_td.bp & OHCI_PAGE_MASK) | 776*f1ae32a1SGerd Hoffmann (end_offset & OHCI_OFFSET_MASK); 777*f1ae32a1SGerd Hoffmann } else { 778*f1ae32a1SGerd Hoffmann end_addr = (iso_td.be & OHCI_PAGE_MASK) | 779*f1ae32a1SGerd Hoffmann (end_offset & OHCI_OFFSET_MASK); 780*f1ae32a1SGerd Hoffmann } 781*f1ae32a1SGerd Hoffmann } else { 782*f1ae32a1SGerd Hoffmann /* Last packet in the ISO TD */ 783*f1ae32a1SGerd Hoffmann end_addr = iso_td.be; 784*f1ae32a1SGerd Hoffmann } 785*f1ae32a1SGerd Hoffmann 786*f1ae32a1SGerd Hoffmann if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) { 787*f1ae32a1SGerd Hoffmann len = (end_addr & OHCI_OFFSET_MASK) + 0x1001 788*f1ae32a1SGerd Hoffmann - (start_addr & OHCI_OFFSET_MASK); 789*f1ae32a1SGerd Hoffmann } else { 790*f1ae32a1SGerd Hoffmann len = end_addr - start_addr + 1; 791*f1ae32a1SGerd Hoffmann } 792*f1ae32a1SGerd Hoffmann 793*f1ae32a1SGerd Hoffmann if (len && dir != OHCI_TD_DIR_IN) { 794*f1ae32a1SGerd Hoffmann ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len, 0); 795*f1ae32a1SGerd Hoffmann } 796*f1ae32a1SGerd Hoffmann 797*f1ae32a1SGerd Hoffmann if (completion) { 798*f1ae32a1SGerd Hoffmann ret = ohci->usb_packet.result; 799*f1ae32a1SGerd Hoffmann } else { 800*f1ae32a1SGerd Hoffmann dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); 801*f1ae32a1SGerd Hoffmann ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); 802*f1ae32a1SGerd Hoffmann usb_packet_setup(&ohci->usb_packet, pid, ep); 803*f1ae32a1SGerd Hoffmann usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len); 804*f1ae32a1SGerd Hoffmann ret = usb_handle_packet(dev, &ohci->usb_packet); 805*f1ae32a1SGerd Hoffmann if (ret == USB_RET_ASYNC) { 806*f1ae32a1SGerd Hoffmann return 1; 807*f1ae32a1SGerd Hoffmann } 808*f1ae32a1SGerd Hoffmann } 809*f1ae32a1SGerd Hoffmann 810*f1ae32a1SGerd Hoffmann #ifdef DEBUG_ISOCH 811*f1ae32a1SGerd Hoffmann printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n", 812*f1ae32a1SGerd Hoffmann start_offset, end_offset, start_addr, end_addr, str, len, ret); 813*f1ae32a1SGerd Hoffmann #endif 814*f1ae32a1SGerd Hoffmann 815*f1ae32a1SGerd Hoffmann /* Writeback */ 816*f1ae32a1SGerd Hoffmann if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) { 817*f1ae32a1SGerd Hoffmann /* IN transfer succeeded */ 818*f1ae32a1SGerd Hoffmann ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret, 1); 819*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, 820*f1ae32a1SGerd Hoffmann OHCI_CC_NOERROR); 821*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret); 822*f1ae32a1SGerd Hoffmann } else if (dir == OHCI_TD_DIR_OUT && ret == len) { 823*f1ae32a1SGerd Hoffmann /* OUT transfer succeeded */ 824*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, 825*f1ae32a1SGerd Hoffmann OHCI_CC_NOERROR); 826*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0); 827*f1ae32a1SGerd Hoffmann } else { 828*f1ae32a1SGerd Hoffmann if (ret > (ssize_t) len) { 829*f1ae32a1SGerd Hoffmann printf("usb-ohci: DataOverrun %d > %zu\n", ret, len); 830*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, 831*f1ae32a1SGerd Hoffmann OHCI_CC_DATAOVERRUN); 832*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 833*f1ae32a1SGerd Hoffmann len); 834*f1ae32a1SGerd Hoffmann } else if (ret >= 0) { 835*f1ae32a1SGerd Hoffmann printf("usb-ohci: DataUnderrun %d\n", ret); 836*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, 837*f1ae32a1SGerd Hoffmann OHCI_CC_DATAUNDERRUN); 838*f1ae32a1SGerd Hoffmann } else { 839*f1ae32a1SGerd Hoffmann switch (ret) { 840*f1ae32a1SGerd Hoffmann case USB_RET_IOERROR: 841*f1ae32a1SGerd Hoffmann case USB_RET_NODEV: 842*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, 843*f1ae32a1SGerd Hoffmann OHCI_CC_DEVICENOTRESPONDING); 844*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 845*f1ae32a1SGerd Hoffmann 0); 846*f1ae32a1SGerd Hoffmann break; 847*f1ae32a1SGerd Hoffmann case USB_RET_NAK: 848*f1ae32a1SGerd Hoffmann case USB_RET_STALL: 849*f1ae32a1SGerd Hoffmann printf("usb-ohci: got NAK/STALL %d\n", ret); 850*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, 851*f1ae32a1SGerd Hoffmann OHCI_CC_STALL); 852*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 853*f1ae32a1SGerd Hoffmann 0); 854*f1ae32a1SGerd Hoffmann break; 855*f1ae32a1SGerd Hoffmann default: 856*f1ae32a1SGerd Hoffmann printf("usb-ohci: Bad device response %d\n", ret); 857*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, 858*f1ae32a1SGerd Hoffmann OHCI_CC_UNDEXPETEDPID); 859*f1ae32a1SGerd Hoffmann break; 860*f1ae32a1SGerd Hoffmann } 861*f1ae32a1SGerd Hoffmann } 862*f1ae32a1SGerd Hoffmann } 863*f1ae32a1SGerd Hoffmann 864*f1ae32a1SGerd Hoffmann if (relative_frame_number == frame_count) { 865*f1ae32a1SGerd Hoffmann /* Last data packet of ISO TD - retire the TD to the Done Queue */ 866*f1ae32a1SGerd Hoffmann OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR); 867*f1ae32a1SGerd Hoffmann ed->head &= ~OHCI_DPTR_MASK; 868*f1ae32a1SGerd Hoffmann ed->head |= (iso_td.next & OHCI_DPTR_MASK); 869*f1ae32a1SGerd Hoffmann iso_td.next = ohci->done; 870*f1ae32a1SGerd Hoffmann ohci->done = addr; 871*f1ae32a1SGerd Hoffmann i = OHCI_BM(iso_td.flags, TD_DI); 872*f1ae32a1SGerd Hoffmann if (i < ohci->done_count) 873*f1ae32a1SGerd Hoffmann ohci->done_count = i; 874*f1ae32a1SGerd Hoffmann } 875*f1ae32a1SGerd Hoffmann ohci_put_iso_td(ohci, addr, &iso_td); 876*f1ae32a1SGerd Hoffmann return 1; 877*f1ae32a1SGerd Hoffmann } 878*f1ae32a1SGerd Hoffmann 879*f1ae32a1SGerd Hoffmann /* Service a transport descriptor. 880*f1ae32a1SGerd Hoffmann Returns nonzero to terminate processing of this endpoint. */ 881*f1ae32a1SGerd Hoffmann 882*f1ae32a1SGerd Hoffmann static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) 883*f1ae32a1SGerd Hoffmann { 884*f1ae32a1SGerd Hoffmann int dir; 885*f1ae32a1SGerd Hoffmann size_t len = 0, pktlen = 0; 886*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 887*f1ae32a1SGerd Hoffmann const char *str = NULL; 888*f1ae32a1SGerd Hoffmann #endif 889*f1ae32a1SGerd Hoffmann int pid; 890*f1ae32a1SGerd Hoffmann int ret; 891*f1ae32a1SGerd Hoffmann int i; 892*f1ae32a1SGerd Hoffmann USBDevice *dev; 893*f1ae32a1SGerd Hoffmann USBEndpoint *ep; 894*f1ae32a1SGerd Hoffmann struct ohci_td td; 895*f1ae32a1SGerd Hoffmann uint32_t addr; 896*f1ae32a1SGerd Hoffmann int flag_r; 897*f1ae32a1SGerd Hoffmann int completion; 898*f1ae32a1SGerd Hoffmann 899*f1ae32a1SGerd Hoffmann addr = ed->head & OHCI_DPTR_MASK; 900*f1ae32a1SGerd Hoffmann /* See if this TD has already been submitted to the device. */ 901*f1ae32a1SGerd Hoffmann completion = (addr == ohci->async_td); 902*f1ae32a1SGerd Hoffmann if (completion && !ohci->async_complete) { 903*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 904*f1ae32a1SGerd Hoffmann DPRINTF("Skipping async TD\n"); 905*f1ae32a1SGerd Hoffmann #endif 906*f1ae32a1SGerd Hoffmann return 1; 907*f1ae32a1SGerd Hoffmann } 908*f1ae32a1SGerd Hoffmann if (!ohci_read_td(ohci, addr, &td)) { 909*f1ae32a1SGerd Hoffmann fprintf(stderr, "usb-ohci: TD read error at %x\n", addr); 910*f1ae32a1SGerd Hoffmann return 0; 911*f1ae32a1SGerd Hoffmann } 912*f1ae32a1SGerd Hoffmann 913*f1ae32a1SGerd Hoffmann dir = OHCI_BM(ed->flags, ED_D); 914*f1ae32a1SGerd Hoffmann switch (dir) { 915*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_OUT: 916*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_IN: 917*f1ae32a1SGerd Hoffmann /* Same value. */ 918*f1ae32a1SGerd Hoffmann break; 919*f1ae32a1SGerd Hoffmann default: 920*f1ae32a1SGerd Hoffmann dir = OHCI_BM(td.flags, TD_DP); 921*f1ae32a1SGerd Hoffmann break; 922*f1ae32a1SGerd Hoffmann } 923*f1ae32a1SGerd Hoffmann 924*f1ae32a1SGerd Hoffmann switch (dir) { 925*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_IN: 926*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 927*f1ae32a1SGerd Hoffmann str = "in"; 928*f1ae32a1SGerd Hoffmann #endif 929*f1ae32a1SGerd Hoffmann pid = USB_TOKEN_IN; 930*f1ae32a1SGerd Hoffmann break; 931*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_OUT: 932*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 933*f1ae32a1SGerd Hoffmann str = "out"; 934*f1ae32a1SGerd Hoffmann #endif 935*f1ae32a1SGerd Hoffmann pid = USB_TOKEN_OUT; 936*f1ae32a1SGerd Hoffmann break; 937*f1ae32a1SGerd Hoffmann case OHCI_TD_DIR_SETUP: 938*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 939*f1ae32a1SGerd Hoffmann str = "setup"; 940*f1ae32a1SGerd Hoffmann #endif 941*f1ae32a1SGerd Hoffmann pid = USB_TOKEN_SETUP; 942*f1ae32a1SGerd Hoffmann break; 943*f1ae32a1SGerd Hoffmann default: 944*f1ae32a1SGerd Hoffmann fprintf(stderr, "usb-ohci: Bad direction\n"); 945*f1ae32a1SGerd Hoffmann return 1; 946*f1ae32a1SGerd Hoffmann } 947*f1ae32a1SGerd Hoffmann if (td.cbp && td.be) { 948*f1ae32a1SGerd Hoffmann if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) { 949*f1ae32a1SGerd Hoffmann len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff); 950*f1ae32a1SGerd Hoffmann } else { 951*f1ae32a1SGerd Hoffmann len = (td.be - td.cbp) + 1; 952*f1ae32a1SGerd Hoffmann } 953*f1ae32a1SGerd Hoffmann 954*f1ae32a1SGerd Hoffmann pktlen = len; 955*f1ae32a1SGerd Hoffmann if (len && dir != OHCI_TD_DIR_IN) { 956*f1ae32a1SGerd Hoffmann /* The endpoint may not allow us to transfer it all now */ 957*f1ae32a1SGerd Hoffmann pktlen = (ed->flags & OHCI_ED_MPS_MASK) >> OHCI_ED_MPS_SHIFT; 958*f1ae32a1SGerd Hoffmann if (pktlen > len) { 959*f1ae32a1SGerd Hoffmann pktlen = len; 960*f1ae32a1SGerd Hoffmann } 961*f1ae32a1SGerd Hoffmann if (!completion) { 962*f1ae32a1SGerd Hoffmann ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen, 0); 963*f1ae32a1SGerd Hoffmann } 964*f1ae32a1SGerd Hoffmann } 965*f1ae32a1SGerd Hoffmann } 966*f1ae32a1SGerd Hoffmann 967*f1ae32a1SGerd Hoffmann flag_r = (td.flags & OHCI_TD_R) != 0; 968*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 969*f1ae32a1SGerd Hoffmann DPRINTF(" TD @ 0x%.8x %" PRId64 " of %" PRId64 970*f1ae32a1SGerd Hoffmann " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n", 971*f1ae32a1SGerd Hoffmann addr, (int64_t)pktlen, (int64_t)len, str, flag_r, td.cbp, td.be); 972*f1ae32a1SGerd Hoffmann 973*f1ae32a1SGerd Hoffmann if (pktlen > 0 && dir != OHCI_TD_DIR_IN) { 974*f1ae32a1SGerd Hoffmann DPRINTF(" data:"); 975*f1ae32a1SGerd Hoffmann for (i = 0; i < pktlen; i++) { 976*f1ae32a1SGerd Hoffmann printf(" %.2x", ohci->usb_buf[i]); 977*f1ae32a1SGerd Hoffmann } 978*f1ae32a1SGerd Hoffmann DPRINTF("\n"); 979*f1ae32a1SGerd Hoffmann } 980*f1ae32a1SGerd Hoffmann #endif 981*f1ae32a1SGerd Hoffmann if (completion) { 982*f1ae32a1SGerd Hoffmann ret = ohci->usb_packet.result; 983*f1ae32a1SGerd Hoffmann ohci->async_td = 0; 984*f1ae32a1SGerd Hoffmann ohci->async_complete = 0; 985*f1ae32a1SGerd Hoffmann } else { 986*f1ae32a1SGerd Hoffmann if (ohci->async_td) { 987*f1ae32a1SGerd Hoffmann /* ??? The hardware should allow one active packet per 988*f1ae32a1SGerd Hoffmann endpoint. We only allow one active packet per controller. 989*f1ae32a1SGerd Hoffmann This should be sufficient as long as devices respond in a 990*f1ae32a1SGerd Hoffmann timely manner. 991*f1ae32a1SGerd Hoffmann */ 992*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 993*f1ae32a1SGerd Hoffmann DPRINTF("Too many pending packets\n"); 994*f1ae32a1SGerd Hoffmann #endif 995*f1ae32a1SGerd Hoffmann return 1; 996*f1ae32a1SGerd Hoffmann } 997*f1ae32a1SGerd Hoffmann dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA)); 998*f1ae32a1SGerd Hoffmann ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN)); 999*f1ae32a1SGerd Hoffmann usb_packet_setup(&ohci->usb_packet, pid, ep); 1000*f1ae32a1SGerd Hoffmann usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen); 1001*f1ae32a1SGerd Hoffmann ret = usb_handle_packet(dev, &ohci->usb_packet); 1002*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 1003*f1ae32a1SGerd Hoffmann DPRINTF("ret=%d\n", ret); 1004*f1ae32a1SGerd Hoffmann #endif 1005*f1ae32a1SGerd Hoffmann if (ret == USB_RET_ASYNC) { 1006*f1ae32a1SGerd Hoffmann ohci->async_td = addr; 1007*f1ae32a1SGerd Hoffmann return 1; 1008*f1ae32a1SGerd Hoffmann } 1009*f1ae32a1SGerd Hoffmann } 1010*f1ae32a1SGerd Hoffmann if (ret >= 0) { 1011*f1ae32a1SGerd Hoffmann if (dir == OHCI_TD_DIR_IN) { 1012*f1ae32a1SGerd Hoffmann ohci_copy_td(ohci, &td, ohci->usb_buf, ret, 1); 1013*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 1014*f1ae32a1SGerd Hoffmann DPRINTF(" data:"); 1015*f1ae32a1SGerd Hoffmann for (i = 0; i < ret; i++) 1016*f1ae32a1SGerd Hoffmann printf(" %.2x", ohci->usb_buf[i]); 1017*f1ae32a1SGerd Hoffmann DPRINTF("\n"); 1018*f1ae32a1SGerd Hoffmann #endif 1019*f1ae32a1SGerd Hoffmann } else { 1020*f1ae32a1SGerd Hoffmann ret = pktlen; 1021*f1ae32a1SGerd Hoffmann } 1022*f1ae32a1SGerd Hoffmann } 1023*f1ae32a1SGerd Hoffmann 1024*f1ae32a1SGerd Hoffmann /* Writeback */ 1025*f1ae32a1SGerd Hoffmann if (ret == pktlen || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) { 1026*f1ae32a1SGerd Hoffmann /* Transmission succeeded. */ 1027*f1ae32a1SGerd Hoffmann if (ret == len) { 1028*f1ae32a1SGerd Hoffmann td.cbp = 0; 1029*f1ae32a1SGerd Hoffmann } else { 1030*f1ae32a1SGerd Hoffmann if ((td.cbp & 0xfff) + ret > 0xfff) { 1031*f1ae32a1SGerd Hoffmann td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff); 1032*f1ae32a1SGerd Hoffmann } else { 1033*f1ae32a1SGerd Hoffmann td.cbp += ret; 1034*f1ae32a1SGerd Hoffmann } 1035*f1ae32a1SGerd Hoffmann } 1036*f1ae32a1SGerd Hoffmann td.flags |= OHCI_TD_T1; 1037*f1ae32a1SGerd Hoffmann td.flags ^= OHCI_TD_T0; 1038*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR); 1039*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_EC, 0); 1040*f1ae32a1SGerd Hoffmann 1041*f1ae32a1SGerd Hoffmann if ((dir != OHCI_TD_DIR_IN) && (ret != len)) { 1042*f1ae32a1SGerd Hoffmann /* Partial packet transfer: TD not ready to retire yet */ 1043*f1ae32a1SGerd Hoffmann goto exit_no_retire; 1044*f1ae32a1SGerd Hoffmann } 1045*f1ae32a1SGerd Hoffmann 1046*f1ae32a1SGerd Hoffmann /* Setting ED_C is part of the TD retirement process */ 1047*f1ae32a1SGerd Hoffmann ed->head &= ~OHCI_ED_C; 1048*f1ae32a1SGerd Hoffmann if (td.flags & OHCI_TD_T0) 1049*f1ae32a1SGerd Hoffmann ed->head |= OHCI_ED_C; 1050*f1ae32a1SGerd Hoffmann } else { 1051*f1ae32a1SGerd Hoffmann if (ret >= 0) { 1052*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: Underrun\n"); 1053*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN); 1054*f1ae32a1SGerd Hoffmann } else { 1055*f1ae32a1SGerd Hoffmann switch (ret) { 1056*f1ae32a1SGerd Hoffmann case USB_RET_IOERROR: 1057*f1ae32a1SGerd Hoffmann case USB_RET_NODEV: 1058*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING); 1059*f1ae32a1SGerd Hoffmann case USB_RET_NAK: 1060*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: got NAK\n"); 1061*f1ae32a1SGerd Hoffmann return 1; 1062*f1ae32a1SGerd Hoffmann case USB_RET_STALL: 1063*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: got STALL\n"); 1064*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL); 1065*f1ae32a1SGerd Hoffmann break; 1066*f1ae32a1SGerd Hoffmann case USB_RET_BABBLE: 1067*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: got BABBLE\n"); 1068*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN); 1069*f1ae32a1SGerd Hoffmann break; 1070*f1ae32a1SGerd Hoffmann default: 1071*f1ae32a1SGerd Hoffmann fprintf(stderr, "usb-ohci: Bad device response %d\n", ret); 1072*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID); 1073*f1ae32a1SGerd Hoffmann OHCI_SET_BM(td.flags, TD_EC, 3); 1074*f1ae32a1SGerd Hoffmann break; 1075*f1ae32a1SGerd Hoffmann } 1076*f1ae32a1SGerd Hoffmann } 1077*f1ae32a1SGerd Hoffmann ed->head |= OHCI_ED_H; 1078*f1ae32a1SGerd Hoffmann } 1079*f1ae32a1SGerd Hoffmann 1080*f1ae32a1SGerd Hoffmann /* Retire this TD */ 1081*f1ae32a1SGerd Hoffmann ed->head &= ~OHCI_DPTR_MASK; 1082*f1ae32a1SGerd Hoffmann ed->head |= td.next & OHCI_DPTR_MASK; 1083*f1ae32a1SGerd Hoffmann td.next = ohci->done; 1084*f1ae32a1SGerd Hoffmann ohci->done = addr; 1085*f1ae32a1SGerd Hoffmann i = OHCI_BM(td.flags, TD_DI); 1086*f1ae32a1SGerd Hoffmann if (i < ohci->done_count) 1087*f1ae32a1SGerd Hoffmann ohci->done_count = i; 1088*f1ae32a1SGerd Hoffmann exit_no_retire: 1089*f1ae32a1SGerd Hoffmann ohci_put_td(ohci, addr, &td); 1090*f1ae32a1SGerd Hoffmann return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR; 1091*f1ae32a1SGerd Hoffmann } 1092*f1ae32a1SGerd Hoffmann 1093*f1ae32a1SGerd Hoffmann /* Service an endpoint list. Returns nonzero if active TD were found. */ 1094*f1ae32a1SGerd Hoffmann static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) 1095*f1ae32a1SGerd Hoffmann { 1096*f1ae32a1SGerd Hoffmann struct ohci_ed ed; 1097*f1ae32a1SGerd Hoffmann uint32_t next_ed; 1098*f1ae32a1SGerd Hoffmann uint32_t cur; 1099*f1ae32a1SGerd Hoffmann int active; 1100*f1ae32a1SGerd Hoffmann 1101*f1ae32a1SGerd Hoffmann active = 0; 1102*f1ae32a1SGerd Hoffmann 1103*f1ae32a1SGerd Hoffmann if (head == 0) 1104*f1ae32a1SGerd Hoffmann return 0; 1105*f1ae32a1SGerd Hoffmann 1106*f1ae32a1SGerd Hoffmann for (cur = head; cur; cur = next_ed) { 1107*f1ae32a1SGerd Hoffmann if (!ohci_read_ed(ohci, cur, &ed)) { 1108*f1ae32a1SGerd Hoffmann fprintf(stderr, "usb-ohci: ED read error at %x\n", cur); 1109*f1ae32a1SGerd Hoffmann return 0; 1110*f1ae32a1SGerd Hoffmann } 1111*f1ae32a1SGerd Hoffmann 1112*f1ae32a1SGerd Hoffmann next_ed = ed.next & OHCI_DPTR_MASK; 1113*f1ae32a1SGerd Hoffmann 1114*f1ae32a1SGerd Hoffmann if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) { 1115*f1ae32a1SGerd Hoffmann uint32_t addr; 1116*f1ae32a1SGerd Hoffmann /* Cancel pending packets for ED that have been paused. */ 1117*f1ae32a1SGerd Hoffmann addr = ed.head & OHCI_DPTR_MASK; 1118*f1ae32a1SGerd Hoffmann if (ohci->async_td && addr == ohci->async_td) { 1119*f1ae32a1SGerd Hoffmann usb_cancel_packet(&ohci->usb_packet); 1120*f1ae32a1SGerd Hoffmann ohci->async_td = 0; 1121*f1ae32a1SGerd Hoffmann } 1122*f1ae32a1SGerd Hoffmann continue; 1123*f1ae32a1SGerd Hoffmann } 1124*f1ae32a1SGerd Hoffmann 1125*f1ae32a1SGerd Hoffmann while ((ed.head & OHCI_DPTR_MASK) != ed.tail) { 1126*f1ae32a1SGerd Hoffmann #ifdef DEBUG_PACKET 1127*f1ae32a1SGerd Hoffmann DPRINTF("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u " 1128*f1ae32a1SGerd Hoffmann "h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur, 1129*f1ae32a1SGerd Hoffmann OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN), 1130*f1ae32a1SGerd Hoffmann OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0, 1131*f1ae32a1SGerd Hoffmann (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0, 1132*f1ae32a1SGerd Hoffmann OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0, 1133*f1ae32a1SGerd Hoffmann (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK, 1134*f1ae32a1SGerd Hoffmann ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK); 1135*f1ae32a1SGerd Hoffmann #endif 1136*f1ae32a1SGerd Hoffmann active = 1; 1137*f1ae32a1SGerd Hoffmann 1138*f1ae32a1SGerd Hoffmann if ((ed.flags & OHCI_ED_F) == 0) { 1139*f1ae32a1SGerd Hoffmann if (ohci_service_td(ohci, &ed)) 1140*f1ae32a1SGerd Hoffmann break; 1141*f1ae32a1SGerd Hoffmann } else { 1142*f1ae32a1SGerd Hoffmann /* Handle isochronous endpoints */ 1143*f1ae32a1SGerd Hoffmann if (ohci_service_iso_td(ohci, &ed, completion)) 1144*f1ae32a1SGerd Hoffmann break; 1145*f1ae32a1SGerd Hoffmann } 1146*f1ae32a1SGerd Hoffmann } 1147*f1ae32a1SGerd Hoffmann 1148*f1ae32a1SGerd Hoffmann ohci_put_ed(ohci, cur, &ed); 1149*f1ae32a1SGerd Hoffmann } 1150*f1ae32a1SGerd Hoffmann 1151*f1ae32a1SGerd Hoffmann return active; 1152*f1ae32a1SGerd Hoffmann } 1153*f1ae32a1SGerd Hoffmann 1154*f1ae32a1SGerd Hoffmann /* Generate a SOF event, and set a timer for EOF */ 1155*f1ae32a1SGerd Hoffmann static void ohci_sof(OHCIState *ohci) 1156*f1ae32a1SGerd Hoffmann { 1157*f1ae32a1SGerd Hoffmann ohci->sof_time = qemu_get_clock_ns(vm_clock); 1158*f1ae32a1SGerd Hoffmann qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time); 1159*f1ae32a1SGerd Hoffmann ohci_set_interrupt(ohci, OHCI_INTR_SF); 1160*f1ae32a1SGerd Hoffmann } 1161*f1ae32a1SGerd Hoffmann 1162*f1ae32a1SGerd Hoffmann /* Process Control and Bulk lists. */ 1163*f1ae32a1SGerd Hoffmann static void ohci_process_lists(OHCIState *ohci, int completion) 1164*f1ae32a1SGerd Hoffmann { 1165*f1ae32a1SGerd Hoffmann if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) { 1166*f1ae32a1SGerd Hoffmann if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head) { 1167*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: head %x, cur %x\n", 1168*f1ae32a1SGerd Hoffmann ohci->ctrl_head, ohci->ctrl_cur); 1169*f1ae32a1SGerd Hoffmann } 1170*f1ae32a1SGerd Hoffmann if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) { 1171*f1ae32a1SGerd Hoffmann ohci->ctrl_cur = 0; 1172*f1ae32a1SGerd Hoffmann ohci->status &= ~OHCI_STATUS_CLF; 1173*f1ae32a1SGerd Hoffmann } 1174*f1ae32a1SGerd Hoffmann } 1175*f1ae32a1SGerd Hoffmann 1176*f1ae32a1SGerd Hoffmann if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) { 1177*f1ae32a1SGerd Hoffmann if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) { 1178*f1ae32a1SGerd Hoffmann ohci->bulk_cur = 0; 1179*f1ae32a1SGerd Hoffmann ohci->status &= ~OHCI_STATUS_BLF; 1180*f1ae32a1SGerd Hoffmann } 1181*f1ae32a1SGerd Hoffmann } 1182*f1ae32a1SGerd Hoffmann } 1183*f1ae32a1SGerd Hoffmann 1184*f1ae32a1SGerd Hoffmann /* Do frame processing on frame boundary */ 1185*f1ae32a1SGerd Hoffmann static void ohci_frame_boundary(void *opaque) 1186*f1ae32a1SGerd Hoffmann { 1187*f1ae32a1SGerd Hoffmann OHCIState *ohci = opaque; 1188*f1ae32a1SGerd Hoffmann struct ohci_hcca hcca; 1189*f1ae32a1SGerd Hoffmann 1190*f1ae32a1SGerd Hoffmann ohci_read_hcca(ohci, ohci->hcca, &hcca); 1191*f1ae32a1SGerd Hoffmann 1192*f1ae32a1SGerd Hoffmann /* Process all the lists at the end of the frame */ 1193*f1ae32a1SGerd Hoffmann if (ohci->ctl & OHCI_CTL_PLE) { 1194*f1ae32a1SGerd Hoffmann int n; 1195*f1ae32a1SGerd Hoffmann 1196*f1ae32a1SGerd Hoffmann n = ohci->frame_number & 0x1f; 1197*f1ae32a1SGerd Hoffmann ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]), 0); 1198*f1ae32a1SGerd Hoffmann } 1199*f1ae32a1SGerd Hoffmann 1200*f1ae32a1SGerd Hoffmann /* Cancel all pending packets if either of the lists has been disabled. */ 1201*f1ae32a1SGerd Hoffmann if (ohci->async_td && 1202*f1ae32a1SGerd Hoffmann ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) { 1203*f1ae32a1SGerd Hoffmann usb_cancel_packet(&ohci->usb_packet); 1204*f1ae32a1SGerd Hoffmann ohci->async_td = 0; 1205*f1ae32a1SGerd Hoffmann } 1206*f1ae32a1SGerd Hoffmann ohci->old_ctl = ohci->ctl; 1207*f1ae32a1SGerd Hoffmann ohci_process_lists(ohci, 0); 1208*f1ae32a1SGerd Hoffmann 1209*f1ae32a1SGerd Hoffmann /* Frame boundary, so do EOF stuf here */ 1210*f1ae32a1SGerd Hoffmann ohci->frt = ohci->fit; 1211*f1ae32a1SGerd Hoffmann 1212*f1ae32a1SGerd Hoffmann /* Increment frame number and take care of endianness. */ 1213*f1ae32a1SGerd Hoffmann ohci->frame_number = (ohci->frame_number + 1) & 0xffff; 1214*f1ae32a1SGerd Hoffmann hcca.frame = cpu_to_le16(ohci->frame_number); 1215*f1ae32a1SGerd Hoffmann 1216*f1ae32a1SGerd Hoffmann if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) { 1217*f1ae32a1SGerd Hoffmann if (!ohci->done) 1218*f1ae32a1SGerd Hoffmann abort(); 1219*f1ae32a1SGerd Hoffmann if (ohci->intr & ohci->intr_status) 1220*f1ae32a1SGerd Hoffmann ohci->done |= 1; 1221*f1ae32a1SGerd Hoffmann hcca.done = cpu_to_le32(ohci->done); 1222*f1ae32a1SGerd Hoffmann ohci->done = 0; 1223*f1ae32a1SGerd Hoffmann ohci->done_count = 7; 1224*f1ae32a1SGerd Hoffmann ohci_set_interrupt(ohci, OHCI_INTR_WD); 1225*f1ae32a1SGerd Hoffmann } 1226*f1ae32a1SGerd Hoffmann 1227*f1ae32a1SGerd Hoffmann if (ohci->done_count != 7 && ohci->done_count != 0) 1228*f1ae32a1SGerd Hoffmann ohci->done_count--; 1229*f1ae32a1SGerd Hoffmann 1230*f1ae32a1SGerd Hoffmann /* Do SOF stuff here */ 1231*f1ae32a1SGerd Hoffmann ohci_sof(ohci); 1232*f1ae32a1SGerd Hoffmann 1233*f1ae32a1SGerd Hoffmann /* Writeback HCCA */ 1234*f1ae32a1SGerd Hoffmann ohci_put_hcca(ohci, ohci->hcca, &hcca); 1235*f1ae32a1SGerd Hoffmann } 1236*f1ae32a1SGerd Hoffmann 1237*f1ae32a1SGerd Hoffmann /* Start sending SOF tokens across the USB bus, lists are processed in 1238*f1ae32a1SGerd Hoffmann * next frame 1239*f1ae32a1SGerd Hoffmann */ 1240*f1ae32a1SGerd Hoffmann static int ohci_bus_start(OHCIState *ohci) 1241*f1ae32a1SGerd Hoffmann { 1242*f1ae32a1SGerd Hoffmann ohci->eof_timer = qemu_new_timer_ns(vm_clock, 1243*f1ae32a1SGerd Hoffmann ohci_frame_boundary, 1244*f1ae32a1SGerd Hoffmann ohci); 1245*f1ae32a1SGerd Hoffmann 1246*f1ae32a1SGerd Hoffmann if (ohci->eof_timer == NULL) { 1247*f1ae32a1SGerd Hoffmann fprintf(stderr, "usb-ohci: %s: qemu_new_timer_ns failed\n", ohci->name); 1248*f1ae32a1SGerd Hoffmann /* TODO: Signal unrecoverable error */ 1249*f1ae32a1SGerd Hoffmann return 0; 1250*f1ae32a1SGerd Hoffmann } 1251*f1ae32a1SGerd Hoffmann 1252*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: %s: USB Operational\n", ohci->name); 1253*f1ae32a1SGerd Hoffmann 1254*f1ae32a1SGerd Hoffmann ohci_sof(ohci); 1255*f1ae32a1SGerd Hoffmann 1256*f1ae32a1SGerd Hoffmann return 1; 1257*f1ae32a1SGerd Hoffmann } 1258*f1ae32a1SGerd Hoffmann 1259*f1ae32a1SGerd Hoffmann /* Stop sending SOF tokens on the bus */ 1260*f1ae32a1SGerd Hoffmann static void ohci_bus_stop(OHCIState *ohci) 1261*f1ae32a1SGerd Hoffmann { 1262*f1ae32a1SGerd Hoffmann if (ohci->eof_timer) 1263*f1ae32a1SGerd Hoffmann qemu_del_timer(ohci->eof_timer); 1264*f1ae32a1SGerd Hoffmann ohci->eof_timer = NULL; 1265*f1ae32a1SGerd Hoffmann } 1266*f1ae32a1SGerd Hoffmann 1267*f1ae32a1SGerd Hoffmann /* Sets a flag in a port status register but only set it if the port is 1268*f1ae32a1SGerd Hoffmann * connected, if not set ConnectStatusChange flag. If flag is enabled 1269*f1ae32a1SGerd Hoffmann * return 1. 1270*f1ae32a1SGerd Hoffmann */ 1271*f1ae32a1SGerd Hoffmann static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val) 1272*f1ae32a1SGerd Hoffmann { 1273*f1ae32a1SGerd Hoffmann int ret = 1; 1274*f1ae32a1SGerd Hoffmann 1275*f1ae32a1SGerd Hoffmann /* writing a 0 has no effect */ 1276*f1ae32a1SGerd Hoffmann if (val == 0) 1277*f1ae32a1SGerd Hoffmann return 0; 1278*f1ae32a1SGerd Hoffmann 1279*f1ae32a1SGerd Hoffmann /* If CurrentConnectStatus is cleared we set 1280*f1ae32a1SGerd Hoffmann * ConnectStatusChange 1281*f1ae32a1SGerd Hoffmann */ 1282*f1ae32a1SGerd Hoffmann if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) { 1283*f1ae32a1SGerd Hoffmann ohci->rhport[i].ctrl |= OHCI_PORT_CSC; 1284*f1ae32a1SGerd Hoffmann if (ohci->rhstatus & OHCI_RHS_DRWE) { 1285*f1ae32a1SGerd Hoffmann /* TODO: CSC is a wakeup event */ 1286*f1ae32a1SGerd Hoffmann } 1287*f1ae32a1SGerd Hoffmann return 0; 1288*f1ae32a1SGerd Hoffmann } 1289*f1ae32a1SGerd Hoffmann 1290*f1ae32a1SGerd Hoffmann if (ohci->rhport[i].ctrl & val) 1291*f1ae32a1SGerd Hoffmann ret = 0; 1292*f1ae32a1SGerd Hoffmann 1293*f1ae32a1SGerd Hoffmann /* set the bit */ 1294*f1ae32a1SGerd Hoffmann ohci->rhport[i].ctrl |= val; 1295*f1ae32a1SGerd Hoffmann 1296*f1ae32a1SGerd Hoffmann return ret; 1297*f1ae32a1SGerd Hoffmann } 1298*f1ae32a1SGerd Hoffmann 1299*f1ae32a1SGerd Hoffmann /* Set the frame interval - frame interval toggle is manipulated by the hcd only */ 1300*f1ae32a1SGerd Hoffmann static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val) 1301*f1ae32a1SGerd Hoffmann { 1302*f1ae32a1SGerd Hoffmann val &= OHCI_FMI_FI; 1303*f1ae32a1SGerd Hoffmann 1304*f1ae32a1SGerd Hoffmann if (val != ohci->fi) { 1305*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: %s: FrameInterval = 0x%x (%u)\n", 1306*f1ae32a1SGerd Hoffmann ohci->name, ohci->fi, ohci->fi); 1307*f1ae32a1SGerd Hoffmann } 1308*f1ae32a1SGerd Hoffmann 1309*f1ae32a1SGerd Hoffmann ohci->fi = val; 1310*f1ae32a1SGerd Hoffmann } 1311*f1ae32a1SGerd Hoffmann 1312*f1ae32a1SGerd Hoffmann static void ohci_port_power(OHCIState *ohci, int i, int p) 1313*f1ae32a1SGerd Hoffmann { 1314*f1ae32a1SGerd Hoffmann if (p) { 1315*f1ae32a1SGerd Hoffmann ohci->rhport[i].ctrl |= OHCI_PORT_PPS; 1316*f1ae32a1SGerd Hoffmann } else { 1317*f1ae32a1SGerd Hoffmann ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS| 1318*f1ae32a1SGerd Hoffmann OHCI_PORT_CCS| 1319*f1ae32a1SGerd Hoffmann OHCI_PORT_PSS| 1320*f1ae32a1SGerd Hoffmann OHCI_PORT_PRS); 1321*f1ae32a1SGerd Hoffmann } 1322*f1ae32a1SGerd Hoffmann } 1323*f1ae32a1SGerd Hoffmann 1324*f1ae32a1SGerd Hoffmann /* Set HcControlRegister */ 1325*f1ae32a1SGerd Hoffmann static void ohci_set_ctl(OHCIState *ohci, uint32_t val) 1326*f1ae32a1SGerd Hoffmann { 1327*f1ae32a1SGerd Hoffmann uint32_t old_state; 1328*f1ae32a1SGerd Hoffmann uint32_t new_state; 1329*f1ae32a1SGerd Hoffmann 1330*f1ae32a1SGerd Hoffmann old_state = ohci->ctl & OHCI_CTL_HCFS; 1331*f1ae32a1SGerd Hoffmann ohci->ctl = val; 1332*f1ae32a1SGerd Hoffmann new_state = ohci->ctl & OHCI_CTL_HCFS; 1333*f1ae32a1SGerd Hoffmann 1334*f1ae32a1SGerd Hoffmann /* no state change */ 1335*f1ae32a1SGerd Hoffmann if (old_state == new_state) 1336*f1ae32a1SGerd Hoffmann return; 1337*f1ae32a1SGerd Hoffmann 1338*f1ae32a1SGerd Hoffmann switch (new_state) { 1339*f1ae32a1SGerd Hoffmann case OHCI_USB_OPERATIONAL: 1340*f1ae32a1SGerd Hoffmann ohci_bus_start(ohci); 1341*f1ae32a1SGerd Hoffmann break; 1342*f1ae32a1SGerd Hoffmann case OHCI_USB_SUSPEND: 1343*f1ae32a1SGerd Hoffmann ohci_bus_stop(ohci); 1344*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: %s: USB Suspended\n", ohci->name); 1345*f1ae32a1SGerd Hoffmann break; 1346*f1ae32a1SGerd Hoffmann case OHCI_USB_RESUME: 1347*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: %s: USB Resume\n", ohci->name); 1348*f1ae32a1SGerd Hoffmann break; 1349*f1ae32a1SGerd Hoffmann case OHCI_USB_RESET: 1350*f1ae32a1SGerd Hoffmann ohci_reset(ohci); 1351*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: %s: USB Reset\n", ohci->name); 1352*f1ae32a1SGerd Hoffmann break; 1353*f1ae32a1SGerd Hoffmann } 1354*f1ae32a1SGerd Hoffmann } 1355*f1ae32a1SGerd Hoffmann 1356*f1ae32a1SGerd Hoffmann static uint32_t ohci_get_frame_remaining(OHCIState *ohci) 1357*f1ae32a1SGerd Hoffmann { 1358*f1ae32a1SGerd Hoffmann uint16_t fr; 1359*f1ae32a1SGerd Hoffmann int64_t tks; 1360*f1ae32a1SGerd Hoffmann 1361*f1ae32a1SGerd Hoffmann if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL) 1362*f1ae32a1SGerd Hoffmann return (ohci->frt << 31); 1363*f1ae32a1SGerd Hoffmann 1364*f1ae32a1SGerd Hoffmann /* Being in USB operational state guarnatees sof_time was 1365*f1ae32a1SGerd Hoffmann * set already. 1366*f1ae32a1SGerd Hoffmann */ 1367*f1ae32a1SGerd Hoffmann tks = qemu_get_clock_ns(vm_clock) - ohci->sof_time; 1368*f1ae32a1SGerd Hoffmann 1369*f1ae32a1SGerd Hoffmann /* avoid muldiv if possible */ 1370*f1ae32a1SGerd Hoffmann if (tks >= usb_frame_time) 1371*f1ae32a1SGerd Hoffmann return (ohci->frt << 31); 1372*f1ae32a1SGerd Hoffmann 1373*f1ae32a1SGerd Hoffmann tks = muldiv64(1, tks, usb_bit_time); 1374*f1ae32a1SGerd Hoffmann fr = (uint16_t)(ohci->fi - tks); 1375*f1ae32a1SGerd Hoffmann 1376*f1ae32a1SGerd Hoffmann return (ohci->frt << 31) | fr; 1377*f1ae32a1SGerd Hoffmann } 1378*f1ae32a1SGerd Hoffmann 1379*f1ae32a1SGerd Hoffmann 1380*f1ae32a1SGerd Hoffmann /* Set root hub status */ 1381*f1ae32a1SGerd Hoffmann static void ohci_set_hub_status(OHCIState *ohci, uint32_t val) 1382*f1ae32a1SGerd Hoffmann { 1383*f1ae32a1SGerd Hoffmann uint32_t old_state; 1384*f1ae32a1SGerd Hoffmann 1385*f1ae32a1SGerd Hoffmann old_state = ohci->rhstatus; 1386*f1ae32a1SGerd Hoffmann 1387*f1ae32a1SGerd Hoffmann /* write 1 to clear OCIC */ 1388*f1ae32a1SGerd Hoffmann if (val & OHCI_RHS_OCIC) 1389*f1ae32a1SGerd Hoffmann ohci->rhstatus &= ~OHCI_RHS_OCIC; 1390*f1ae32a1SGerd Hoffmann 1391*f1ae32a1SGerd Hoffmann if (val & OHCI_RHS_LPS) { 1392*f1ae32a1SGerd Hoffmann int i; 1393*f1ae32a1SGerd Hoffmann 1394*f1ae32a1SGerd Hoffmann for (i = 0; i < ohci->num_ports; i++) 1395*f1ae32a1SGerd Hoffmann ohci_port_power(ohci, i, 0); 1396*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: powered down all ports\n"); 1397*f1ae32a1SGerd Hoffmann } 1398*f1ae32a1SGerd Hoffmann 1399*f1ae32a1SGerd Hoffmann if (val & OHCI_RHS_LPSC) { 1400*f1ae32a1SGerd Hoffmann int i; 1401*f1ae32a1SGerd Hoffmann 1402*f1ae32a1SGerd Hoffmann for (i = 0; i < ohci->num_ports; i++) 1403*f1ae32a1SGerd Hoffmann ohci_port_power(ohci, i, 1); 1404*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: powered up all ports\n"); 1405*f1ae32a1SGerd Hoffmann } 1406*f1ae32a1SGerd Hoffmann 1407*f1ae32a1SGerd Hoffmann if (val & OHCI_RHS_DRWE) 1408*f1ae32a1SGerd Hoffmann ohci->rhstatus |= OHCI_RHS_DRWE; 1409*f1ae32a1SGerd Hoffmann 1410*f1ae32a1SGerd Hoffmann if (val & OHCI_RHS_CRWE) 1411*f1ae32a1SGerd Hoffmann ohci->rhstatus &= ~OHCI_RHS_DRWE; 1412*f1ae32a1SGerd Hoffmann 1413*f1ae32a1SGerd Hoffmann if (old_state != ohci->rhstatus) 1414*f1ae32a1SGerd Hoffmann ohci_set_interrupt(ohci, OHCI_INTR_RHSC); 1415*f1ae32a1SGerd Hoffmann } 1416*f1ae32a1SGerd Hoffmann 1417*f1ae32a1SGerd Hoffmann /* Set root hub port status */ 1418*f1ae32a1SGerd Hoffmann static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) 1419*f1ae32a1SGerd Hoffmann { 1420*f1ae32a1SGerd Hoffmann uint32_t old_state; 1421*f1ae32a1SGerd Hoffmann OHCIPort *port; 1422*f1ae32a1SGerd Hoffmann 1423*f1ae32a1SGerd Hoffmann port = &ohci->rhport[portnum]; 1424*f1ae32a1SGerd Hoffmann old_state = port->ctrl; 1425*f1ae32a1SGerd Hoffmann 1426*f1ae32a1SGerd Hoffmann /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */ 1427*f1ae32a1SGerd Hoffmann if (val & OHCI_PORT_WTC) 1428*f1ae32a1SGerd Hoffmann port->ctrl &= ~(val & OHCI_PORT_WTC); 1429*f1ae32a1SGerd Hoffmann 1430*f1ae32a1SGerd Hoffmann if (val & OHCI_PORT_CCS) 1431*f1ae32a1SGerd Hoffmann port->ctrl &= ~OHCI_PORT_PES; 1432*f1ae32a1SGerd Hoffmann 1433*f1ae32a1SGerd Hoffmann ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES); 1434*f1ae32a1SGerd Hoffmann 1435*f1ae32a1SGerd Hoffmann if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS)) { 1436*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: port %d: SUSPEND\n", portnum); 1437*f1ae32a1SGerd Hoffmann } 1438*f1ae32a1SGerd Hoffmann 1439*f1ae32a1SGerd Hoffmann if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) { 1440*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: port %d: RESET\n", portnum); 1441*f1ae32a1SGerd Hoffmann usb_device_reset(port->port.dev); 1442*f1ae32a1SGerd Hoffmann port->ctrl &= ~OHCI_PORT_PRS; 1443*f1ae32a1SGerd Hoffmann /* ??? Should this also set OHCI_PORT_PESC. */ 1444*f1ae32a1SGerd Hoffmann port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC; 1445*f1ae32a1SGerd Hoffmann } 1446*f1ae32a1SGerd Hoffmann 1447*f1ae32a1SGerd Hoffmann /* Invert order here to ensure in ambiguous case, device is 1448*f1ae32a1SGerd Hoffmann * powered up... 1449*f1ae32a1SGerd Hoffmann */ 1450*f1ae32a1SGerd Hoffmann if (val & OHCI_PORT_LSDA) 1451*f1ae32a1SGerd Hoffmann ohci_port_power(ohci, portnum, 0); 1452*f1ae32a1SGerd Hoffmann if (val & OHCI_PORT_PPS) 1453*f1ae32a1SGerd Hoffmann ohci_port_power(ohci, portnum, 1); 1454*f1ae32a1SGerd Hoffmann 1455*f1ae32a1SGerd Hoffmann if (old_state != port->ctrl) 1456*f1ae32a1SGerd Hoffmann ohci_set_interrupt(ohci, OHCI_INTR_RHSC); 1457*f1ae32a1SGerd Hoffmann 1458*f1ae32a1SGerd Hoffmann return; 1459*f1ae32a1SGerd Hoffmann } 1460*f1ae32a1SGerd Hoffmann 1461*f1ae32a1SGerd Hoffmann static uint64_t ohci_mem_read(void *opaque, 1462*f1ae32a1SGerd Hoffmann target_phys_addr_t addr, 1463*f1ae32a1SGerd Hoffmann unsigned size) 1464*f1ae32a1SGerd Hoffmann { 1465*f1ae32a1SGerd Hoffmann OHCIState *ohci = opaque; 1466*f1ae32a1SGerd Hoffmann uint32_t retval; 1467*f1ae32a1SGerd Hoffmann 1468*f1ae32a1SGerd Hoffmann /* Only aligned reads are allowed on OHCI */ 1469*f1ae32a1SGerd Hoffmann if (addr & 3) { 1470*f1ae32a1SGerd Hoffmann fprintf(stderr, "usb-ohci: Mis-aligned read\n"); 1471*f1ae32a1SGerd Hoffmann return 0xffffffff; 1472*f1ae32a1SGerd Hoffmann } else if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) { 1473*f1ae32a1SGerd Hoffmann /* HcRhPortStatus */ 1474*f1ae32a1SGerd Hoffmann retval = ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS; 1475*f1ae32a1SGerd Hoffmann } else { 1476*f1ae32a1SGerd Hoffmann switch (addr >> 2) { 1477*f1ae32a1SGerd Hoffmann case 0: /* HcRevision */ 1478*f1ae32a1SGerd Hoffmann retval = 0x10; 1479*f1ae32a1SGerd Hoffmann break; 1480*f1ae32a1SGerd Hoffmann 1481*f1ae32a1SGerd Hoffmann case 1: /* HcControl */ 1482*f1ae32a1SGerd Hoffmann retval = ohci->ctl; 1483*f1ae32a1SGerd Hoffmann break; 1484*f1ae32a1SGerd Hoffmann 1485*f1ae32a1SGerd Hoffmann case 2: /* HcCommandStatus */ 1486*f1ae32a1SGerd Hoffmann retval = ohci->status; 1487*f1ae32a1SGerd Hoffmann break; 1488*f1ae32a1SGerd Hoffmann 1489*f1ae32a1SGerd Hoffmann case 3: /* HcInterruptStatus */ 1490*f1ae32a1SGerd Hoffmann retval = ohci->intr_status; 1491*f1ae32a1SGerd Hoffmann break; 1492*f1ae32a1SGerd Hoffmann 1493*f1ae32a1SGerd Hoffmann case 4: /* HcInterruptEnable */ 1494*f1ae32a1SGerd Hoffmann case 5: /* HcInterruptDisable */ 1495*f1ae32a1SGerd Hoffmann retval = ohci->intr; 1496*f1ae32a1SGerd Hoffmann break; 1497*f1ae32a1SGerd Hoffmann 1498*f1ae32a1SGerd Hoffmann case 6: /* HcHCCA */ 1499*f1ae32a1SGerd Hoffmann retval = ohci->hcca; 1500*f1ae32a1SGerd Hoffmann break; 1501*f1ae32a1SGerd Hoffmann 1502*f1ae32a1SGerd Hoffmann case 7: /* HcPeriodCurrentED */ 1503*f1ae32a1SGerd Hoffmann retval = ohci->per_cur; 1504*f1ae32a1SGerd Hoffmann break; 1505*f1ae32a1SGerd Hoffmann 1506*f1ae32a1SGerd Hoffmann case 8: /* HcControlHeadED */ 1507*f1ae32a1SGerd Hoffmann retval = ohci->ctrl_head; 1508*f1ae32a1SGerd Hoffmann break; 1509*f1ae32a1SGerd Hoffmann 1510*f1ae32a1SGerd Hoffmann case 9: /* HcControlCurrentED */ 1511*f1ae32a1SGerd Hoffmann retval = ohci->ctrl_cur; 1512*f1ae32a1SGerd Hoffmann break; 1513*f1ae32a1SGerd Hoffmann 1514*f1ae32a1SGerd Hoffmann case 10: /* HcBulkHeadED */ 1515*f1ae32a1SGerd Hoffmann retval = ohci->bulk_head; 1516*f1ae32a1SGerd Hoffmann break; 1517*f1ae32a1SGerd Hoffmann 1518*f1ae32a1SGerd Hoffmann case 11: /* HcBulkCurrentED */ 1519*f1ae32a1SGerd Hoffmann retval = ohci->bulk_cur; 1520*f1ae32a1SGerd Hoffmann break; 1521*f1ae32a1SGerd Hoffmann 1522*f1ae32a1SGerd Hoffmann case 12: /* HcDoneHead */ 1523*f1ae32a1SGerd Hoffmann retval = ohci->done; 1524*f1ae32a1SGerd Hoffmann break; 1525*f1ae32a1SGerd Hoffmann 1526*f1ae32a1SGerd Hoffmann case 13: /* HcFmInterretval */ 1527*f1ae32a1SGerd Hoffmann retval = (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi); 1528*f1ae32a1SGerd Hoffmann break; 1529*f1ae32a1SGerd Hoffmann 1530*f1ae32a1SGerd Hoffmann case 14: /* HcFmRemaining */ 1531*f1ae32a1SGerd Hoffmann retval = ohci_get_frame_remaining(ohci); 1532*f1ae32a1SGerd Hoffmann break; 1533*f1ae32a1SGerd Hoffmann 1534*f1ae32a1SGerd Hoffmann case 15: /* HcFmNumber */ 1535*f1ae32a1SGerd Hoffmann retval = ohci->frame_number; 1536*f1ae32a1SGerd Hoffmann break; 1537*f1ae32a1SGerd Hoffmann 1538*f1ae32a1SGerd Hoffmann case 16: /* HcPeriodicStart */ 1539*f1ae32a1SGerd Hoffmann retval = ohci->pstart; 1540*f1ae32a1SGerd Hoffmann break; 1541*f1ae32a1SGerd Hoffmann 1542*f1ae32a1SGerd Hoffmann case 17: /* HcLSThreshold */ 1543*f1ae32a1SGerd Hoffmann retval = ohci->lst; 1544*f1ae32a1SGerd Hoffmann break; 1545*f1ae32a1SGerd Hoffmann 1546*f1ae32a1SGerd Hoffmann case 18: /* HcRhDescriptorA */ 1547*f1ae32a1SGerd Hoffmann retval = ohci->rhdesc_a; 1548*f1ae32a1SGerd Hoffmann break; 1549*f1ae32a1SGerd Hoffmann 1550*f1ae32a1SGerd Hoffmann case 19: /* HcRhDescriptorB */ 1551*f1ae32a1SGerd Hoffmann retval = ohci->rhdesc_b; 1552*f1ae32a1SGerd Hoffmann break; 1553*f1ae32a1SGerd Hoffmann 1554*f1ae32a1SGerd Hoffmann case 20: /* HcRhStatus */ 1555*f1ae32a1SGerd Hoffmann retval = ohci->rhstatus; 1556*f1ae32a1SGerd Hoffmann break; 1557*f1ae32a1SGerd Hoffmann 1558*f1ae32a1SGerd Hoffmann /* PXA27x specific registers */ 1559*f1ae32a1SGerd Hoffmann case 24: /* HcStatus */ 1560*f1ae32a1SGerd Hoffmann retval = ohci->hstatus & ohci->hmask; 1561*f1ae32a1SGerd Hoffmann break; 1562*f1ae32a1SGerd Hoffmann 1563*f1ae32a1SGerd Hoffmann case 25: /* HcHReset */ 1564*f1ae32a1SGerd Hoffmann retval = ohci->hreset; 1565*f1ae32a1SGerd Hoffmann break; 1566*f1ae32a1SGerd Hoffmann 1567*f1ae32a1SGerd Hoffmann case 26: /* HcHInterruptEnable */ 1568*f1ae32a1SGerd Hoffmann retval = ohci->hmask; 1569*f1ae32a1SGerd Hoffmann break; 1570*f1ae32a1SGerd Hoffmann 1571*f1ae32a1SGerd Hoffmann case 27: /* HcHInterruptTest */ 1572*f1ae32a1SGerd Hoffmann retval = ohci->htest; 1573*f1ae32a1SGerd Hoffmann break; 1574*f1ae32a1SGerd Hoffmann 1575*f1ae32a1SGerd Hoffmann default: 1576*f1ae32a1SGerd Hoffmann fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr); 1577*f1ae32a1SGerd Hoffmann retval = 0xffffffff; 1578*f1ae32a1SGerd Hoffmann } 1579*f1ae32a1SGerd Hoffmann } 1580*f1ae32a1SGerd Hoffmann 1581*f1ae32a1SGerd Hoffmann return retval; 1582*f1ae32a1SGerd Hoffmann } 1583*f1ae32a1SGerd Hoffmann 1584*f1ae32a1SGerd Hoffmann static void ohci_mem_write(void *opaque, 1585*f1ae32a1SGerd Hoffmann target_phys_addr_t addr, 1586*f1ae32a1SGerd Hoffmann uint64_t val, 1587*f1ae32a1SGerd Hoffmann unsigned size) 1588*f1ae32a1SGerd Hoffmann { 1589*f1ae32a1SGerd Hoffmann OHCIState *ohci = opaque; 1590*f1ae32a1SGerd Hoffmann 1591*f1ae32a1SGerd Hoffmann /* Only aligned reads are allowed on OHCI */ 1592*f1ae32a1SGerd Hoffmann if (addr & 3) { 1593*f1ae32a1SGerd Hoffmann fprintf(stderr, "usb-ohci: Mis-aligned write\n"); 1594*f1ae32a1SGerd Hoffmann return; 1595*f1ae32a1SGerd Hoffmann } 1596*f1ae32a1SGerd Hoffmann 1597*f1ae32a1SGerd Hoffmann if (addr >= 0x54 && addr < 0x54 + ohci->num_ports * 4) { 1598*f1ae32a1SGerd Hoffmann /* HcRhPortStatus */ 1599*f1ae32a1SGerd Hoffmann ohci_port_set_status(ohci, (addr - 0x54) >> 2, val); 1600*f1ae32a1SGerd Hoffmann return; 1601*f1ae32a1SGerd Hoffmann } 1602*f1ae32a1SGerd Hoffmann 1603*f1ae32a1SGerd Hoffmann switch (addr >> 2) { 1604*f1ae32a1SGerd Hoffmann case 1: /* HcControl */ 1605*f1ae32a1SGerd Hoffmann ohci_set_ctl(ohci, val); 1606*f1ae32a1SGerd Hoffmann break; 1607*f1ae32a1SGerd Hoffmann 1608*f1ae32a1SGerd Hoffmann case 2: /* HcCommandStatus */ 1609*f1ae32a1SGerd Hoffmann /* SOC is read-only */ 1610*f1ae32a1SGerd Hoffmann val = (val & ~OHCI_STATUS_SOC); 1611*f1ae32a1SGerd Hoffmann 1612*f1ae32a1SGerd Hoffmann /* Bits written as '0' remain unchanged in the register */ 1613*f1ae32a1SGerd Hoffmann ohci->status |= val; 1614*f1ae32a1SGerd Hoffmann 1615*f1ae32a1SGerd Hoffmann if (ohci->status & OHCI_STATUS_HCR) 1616*f1ae32a1SGerd Hoffmann ohci_reset(ohci); 1617*f1ae32a1SGerd Hoffmann break; 1618*f1ae32a1SGerd Hoffmann 1619*f1ae32a1SGerd Hoffmann case 3: /* HcInterruptStatus */ 1620*f1ae32a1SGerd Hoffmann ohci->intr_status &= ~val; 1621*f1ae32a1SGerd Hoffmann ohci_intr_update(ohci); 1622*f1ae32a1SGerd Hoffmann break; 1623*f1ae32a1SGerd Hoffmann 1624*f1ae32a1SGerd Hoffmann case 4: /* HcInterruptEnable */ 1625*f1ae32a1SGerd Hoffmann ohci->intr |= val; 1626*f1ae32a1SGerd Hoffmann ohci_intr_update(ohci); 1627*f1ae32a1SGerd Hoffmann break; 1628*f1ae32a1SGerd Hoffmann 1629*f1ae32a1SGerd Hoffmann case 5: /* HcInterruptDisable */ 1630*f1ae32a1SGerd Hoffmann ohci->intr &= ~val; 1631*f1ae32a1SGerd Hoffmann ohci_intr_update(ohci); 1632*f1ae32a1SGerd Hoffmann break; 1633*f1ae32a1SGerd Hoffmann 1634*f1ae32a1SGerd Hoffmann case 6: /* HcHCCA */ 1635*f1ae32a1SGerd Hoffmann ohci->hcca = val & OHCI_HCCA_MASK; 1636*f1ae32a1SGerd Hoffmann break; 1637*f1ae32a1SGerd Hoffmann 1638*f1ae32a1SGerd Hoffmann case 7: /* HcPeriodCurrentED */ 1639*f1ae32a1SGerd Hoffmann /* Ignore writes to this read-only register, Linux does them */ 1640*f1ae32a1SGerd Hoffmann break; 1641*f1ae32a1SGerd Hoffmann 1642*f1ae32a1SGerd Hoffmann case 8: /* HcControlHeadED */ 1643*f1ae32a1SGerd Hoffmann ohci->ctrl_head = val & OHCI_EDPTR_MASK; 1644*f1ae32a1SGerd Hoffmann break; 1645*f1ae32a1SGerd Hoffmann 1646*f1ae32a1SGerd Hoffmann case 9: /* HcControlCurrentED */ 1647*f1ae32a1SGerd Hoffmann ohci->ctrl_cur = val & OHCI_EDPTR_MASK; 1648*f1ae32a1SGerd Hoffmann break; 1649*f1ae32a1SGerd Hoffmann 1650*f1ae32a1SGerd Hoffmann case 10: /* HcBulkHeadED */ 1651*f1ae32a1SGerd Hoffmann ohci->bulk_head = val & OHCI_EDPTR_MASK; 1652*f1ae32a1SGerd Hoffmann break; 1653*f1ae32a1SGerd Hoffmann 1654*f1ae32a1SGerd Hoffmann case 11: /* HcBulkCurrentED */ 1655*f1ae32a1SGerd Hoffmann ohci->bulk_cur = val & OHCI_EDPTR_MASK; 1656*f1ae32a1SGerd Hoffmann break; 1657*f1ae32a1SGerd Hoffmann 1658*f1ae32a1SGerd Hoffmann case 13: /* HcFmInterval */ 1659*f1ae32a1SGerd Hoffmann ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16; 1660*f1ae32a1SGerd Hoffmann ohci->fit = (val & OHCI_FMI_FIT) >> 31; 1661*f1ae32a1SGerd Hoffmann ohci_set_frame_interval(ohci, val); 1662*f1ae32a1SGerd Hoffmann break; 1663*f1ae32a1SGerd Hoffmann 1664*f1ae32a1SGerd Hoffmann case 15: /* HcFmNumber */ 1665*f1ae32a1SGerd Hoffmann break; 1666*f1ae32a1SGerd Hoffmann 1667*f1ae32a1SGerd Hoffmann case 16: /* HcPeriodicStart */ 1668*f1ae32a1SGerd Hoffmann ohci->pstart = val & 0xffff; 1669*f1ae32a1SGerd Hoffmann break; 1670*f1ae32a1SGerd Hoffmann 1671*f1ae32a1SGerd Hoffmann case 17: /* HcLSThreshold */ 1672*f1ae32a1SGerd Hoffmann ohci->lst = val & 0xffff; 1673*f1ae32a1SGerd Hoffmann break; 1674*f1ae32a1SGerd Hoffmann 1675*f1ae32a1SGerd Hoffmann case 18: /* HcRhDescriptorA */ 1676*f1ae32a1SGerd Hoffmann ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK; 1677*f1ae32a1SGerd Hoffmann ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK; 1678*f1ae32a1SGerd Hoffmann break; 1679*f1ae32a1SGerd Hoffmann 1680*f1ae32a1SGerd Hoffmann case 19: /* HcRhDescriptorB */ 1681*f1ae32a1SGerd Hoffmann break; 1682*f1ae32a1SGerd Hoffmann 1683*f1ae32a1SGerd Hoffmann case 20: /* HcRhStatus */ 1684*f1ae32a1SGerd Hoffmann ohci_set_hub_status(ohci, val); 1685*f1ae32a1SGerd Hoffmann break; 1686*f1ae32a1SGerd Hoffmann 1687*f1ae32a1SGerd Hoffmann /* PXA27x specific registers */ 1688*f1ae32a1SGerd Hoffmann case 24: /* HcStatus */ 1689*f1ae32a1SGerd Hoffmann ohci->hstatus &= ~(val & ohci->hmask); 1690*f1ae32a1SGerd Hoffmann 1691*f1ae32a1SGerd Hoffmann case 25: /* HcHReset */ 1692*f1ae32a1SGerd Hoffmann ohci->hreset = val & ~OHCI_HRESET_FSBIR; 1693*f1ae32a1SGerd Hoffmann if (val & OHCI_HRESET_FSBIR) 1694*f1ae32a1SGerd Hoffmann ohci_reset(ohci); 1695*f1ae32a1SGerd Hoffmann break; 1696*f1ae32a1SGerd Hoffmann 1697*f1ae32a1SGerd Hoffmann case 26: /* HcHInterruptEnable */ 1698*f1ae32a1SGerd Hoffmann ohci->hmask = val; 1699*f1ae32a1SGerd Hoffmann break; 1700*f1ae32a1SGerd Hoffmann 1701*f1ae32a1SGerd Hoffmann case 27: /* HcHInterruptTest */ 1702*f1ae32a1SGerd Hoffmann ohci->htest = val; 1703*f1ae32a1SGerd Hoffmann break; 1704*f1ae32a1SGerd Hoffmann 1705*f1ae32a1SGerd Hoffmann default: 1706*f1ae32a1SGerd Hoffmann fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr); 1707*f1ae32a1SGerd Hoffmann break; 1708*f1ae32a1SGerd Hoffmann } 1709*f1ae32a1SGerd Hoffmann } 1710*f1ae32a1SGerd Hoffmann 1711*f1ae32a1SGerd Hoffmann static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev) 1712*f1ae32a1SGerd Hoffmann { 1713*f1ae32a1SGerd Hoffmann if (ohci->async_td && 1714*f1ae32a1SGerd Hoffmann usb_packet_is_inflight(&ohci->usb_packet) && 1715*f1ae32a1SGerd Hoffmann ohci->usb_packet.ep->dev == dev) { 1716*f1ae32a1SGerd Hoffmann usb_cancel_packet(&ohci->usb_packet); 1717*f1ae32a1SGerd Hoffmann ohci->async_td = 0; 1718*f1ae32a1SGerd Hoffmann } 1719*f1ae32a1SGerd Hoffmann } 1720*f1ae32a1SGerd Hoffmann 1721*f1ae32a1SGerd Hoffmann static const MemoryRegionOps ohci_mem_ops = { 1722*f1ae32a1SGerd Hoffmann .read = ohci_mem_read, 1723*f1ae32a1SGerd Hoffmann .write = ohci_mem_write, 1724*f1ae32a1SGerd Hoffmann .endianness = DEVICE_LITTLE_ENDIAN, 1725*f1ae32a1SGerd Hoffmann }; 1726*f1ae32a1SGerd Hoffmann 1727*f1ae32a1SGerd Hoffmann static USBPortOps ohci_port_ops = { 1728*f1ae32a1SGerd Hoffmann .attach = ohci_attach, 1729*f1ae32a1SGerd Hoffmann .detach = ohci_detach, 1730*f1ae32a1SGerd Hoffmann .child_detach = ohci_child_detach, 1731*f1ae32a1SGerd Hoffmann .wakeup = ohci_wakeup, 1732*f1ae32a1SGerd Hoffmann .complete = ohci_async_complete_packet, 1733*f1ae32a1SGerd Hoffmann }; 1734*f1ae32a1SGerd Hoffmann 1735*f1ae32a1SGerd Hoffmann static USBBusOps ohci_bus_ops = { 1736*f1ae32a1SGerd Hoffmann }; 1737*f1ae32a1SGerd Hoffmann 1738*f1ae32a1SGerd Hoffmann static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, 1739*f1ae32a1SGerd Hoffmann int num_ports, uint32_t localmem_base, 1740*f1ae32a1SGerd Hoffmann char *masterbus, uint32_t firstport) 1741*f1ae32a1SGerd Hoffmann { 1742*f1ae32a1SGerd Hoffmann int i; 1743*f1ae32a1SGerd Hoffmann 1744*f1ae32a1SGerd Hoffmann if (usb_frame_time == 0) { 1745*f1ae32a1SGerd Hoffmann #ifdef OHCI_TIME_WARP 1746*f1ae32a1SGerd Hoffmann usb_frame_time = get_ticks_per_sec(); 1747*f1ae32a1SGerd Hoffmann usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ/1000); 1748*f1ae32a1SGerd Hoffmann #else 1749*f1ae32a1SGerd Hoffmann usb_frame_time = muldiv64(1, get_ticks_per_sec(), 1000); 1750*f1ae32a1SGerd Hoffmann if (get_ticks_per_sec() >= USB_HZ) { 1751*f1ae32a1SGerd Hoffmann usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ); 1752*f1ae32a1SGerd Hoffmann } else { 1753*f1ae32a1SGerd Hoffmann usb_bit_time = 1; 1754*f1ae32a1SGerd Hoffmann } 1755*f1ae32a1SGerd Hoffmann #endif 1756*f1ae32a1SGerd Hoffmann DPRINTF("usb-ohci: usb_bit_time=%" PRId64 " usb_frame_time=%" PRId64 "\n", 1757*f1ae32a1SGerd Hoffmann usb_frame_time, usb_bit_time); 1758*f1ae32a1SGerd Hoffmann } 1759*f1ae32a1SGerd Hoffmann 1760*f1ae32a1SGerd Hoffmann ohci->num_ports = num_ports; 1761*f1ae32a1SGerd Hoffmann if (masterbus) { 1762*f1ae32a1SGerd Hoffmann USBPort *ports[OHCI_MAX_PORTS]; 1763*f1ae32a1SGerd Hoffmann for(i = 0; i < num_ports; i++) { 1764*f1ae32a1SGerd Hoffmann ports[i] = &ohci->rhport[i].port; 1765*f1ae32a1SGerd Hoffmann } 1766*f1ae32a1SGerd Hoffmann if (usb_register_companion(masterbus, ports, num_ports, 1767*f1ae32a1SGerd Hoffmann firstport, ohci, &ohci_port_ops, 1768*f1ae32a1SGerd Hoffmann USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) { 1769*f1ae32a1SGerd Hoffmann return -1; 1770*f1ae32a1SGerd Hoffmann } 1771*f1ae32a1SGerd Hoffmann } else { 1772*f1ae32a1SGerd Hoffmann usb_bus_new(&ohci->bus, &ohci_bus_ops, dev); 1773*f1ae32a1SGerd Hoffmann for (i = 0; i < num_ports; i++) { 1774*f1ae32a1SGerd Hoffmann usb_register_port(&ohci->bus, &ohci->rhport[i].port, 1775*f1ae32a1SGerd Hoffmann ohci, i, &ohci_port_ops, 1776*f1ae32a1SGerd Hoffmann USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); 1777*f1ae32a1SGerd Hoffmann } 1778*f1ae32a1SGerd Hoffmann } 1779*f1ae32a1SGerd Hoffmann 1780*f1ae32a1SGerd Hoffmann memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256); 1781*f1ae32a1SGerd Hoffmann ohci->localmem_base = localmem_base; 1782*f1ae32a1SGerd Hoffmann 1783*f1ae32a1SGerd Hoffmann ohci->name = object_get_typename(OBJECT(dev)); 1784*f1ae32a1SGerd Hoffmann usb_packet_init(&ohci->usb_packet); 1785*f1ae32a1SGerd Hoffmann 1786*f1ae32a1SGerd Hoffmann ohci->async_td = 0; 1787*f1ae32a1SGerd Hoffmann qemu_register_reset(ohci_reset, ohci); 1788*f1ae32a1SGerd Hoffmann 1789*f1ae32a1SGerd Hoffmann return 0; 1790*f1ae32a1SGerd Hoffmann } 1791*f1ae32a1SGerd Hoffmann 1792*f1ae32a1SGerd Hoffmann typedef struct { 1793*f1ae32a1SGerd Hoffmann PCIDevice pci_dev; 1794*f1ae32a1SGerd Hoffmann OHCIState state; 1795*f1ae32a1SGerd Hoffmann char *masterbus; 1796*f1ae32a1SGerd Hoffmann uint32_t num_ports; 1797*f1ae32a1SGerd Hoffmann uint32_t firstport; 1798*f1ae32a1SGerd Hoffmann } OHCIPCIState; 1799*f1ae32a1SGerd Hoffmann 1800*f1ae32a1SGerd Hoffmann static int usb_ohci_initfn_pci(struct PCIDevice *dev) 1801*f1ae32a1SGerd Hoffmann { 1802*f1ae32a1SGerd Hoffmann OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev); 1803*f1ae32a1SGerd Hoffmann 1804*f1ae32a1SGerd Hoffmann ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */ 1805*f1ae32a1SGerd Hoffmann ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */ 1806*f1ae32a1SGerd Hoffmann 1807*f1ae32a1SGerd Hoffmann if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0, 1808*f1ae32a1SGerd Hoffmann ohci->masterbus, ohci->firstport) != 0) { 1809*f1ae32a1SGerd Hoffmann return -1; 1810*f1ae32a1SGerd Hoffmann } 1811*f1ae32a1SGerd Hoffmann ohci->state.irq = ohci->pci_dev.irq[0]; 1812*f1ae32a1SGerd Hoffmann 1813*f1ae32a1SGerd Hoffmann /* TODO: avoid cast below by using dev */ 1814*f1ae32a1SGerd Hoffmann pci_register_bar(&ohci->pci_dev, 0, 0, &ohci->state.mem); 1815*f1ae32a1SGerd Hoffmann return 0; 1816*f1ae32a1SGerd Hoffmann } 1817*f1ae32a1SGerd Hoffmann 1818*f1ae32a1SGerd Hoffmann void usb_ohci_init_pci(struct PCIBus *bus, int devfn) 1819*f1ae32a1SGerd Hoffmann { 1820*f1ae32a1SGerd Hoffmann pci_create_simple(bus, devfn, "pci-ohci"); 1821*f1ae32a1SGerd Hoffmann } 1822*f1ae32a1SGerd Hoffmann 1823*f1ae32a1SGerd Hoffmann typedef struct { 1824*f1ae32a1SGerd Hoffmann SysBusDevice busdev; 1825*f1ae32a1SGerd Hoffmann OHCIState ohci; 1826*f1ae32a1SGerd Hoffmann uint32_t num_ports; 1827*f1ae32a1SGerd Hoffmann target_phys_addr_t dma_offset; 1828*f1ae32a1SGerd Hoffmann } OHCISysBusState; 1829*f1ae32a1SGerd Hoffmann 1830*f1ae32a1SGerd Hoffmann static int ohci_init_pxa(SysBusDevice *dev) 1831*f1ae32a1SGerd Hoffmann { 1832*f1ae32a1SGerd Hoffmann OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev); 1833*f1ae32a1SGerd Hoffmann 1834*f1ae32a1SGerd Hoffmann /* Cannot fail as we pass NULL for masterbus */ 1835*f1ae32a1SGerd Hoffmann usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0); 1836*f1ae32a1SGerd Hoffmann sysbus_init_irq(dev, &s->ohci.irq); 1837*f1ae32a1SGerd Hoffmann sysbus_init_mmio(dev, &s->ohci.mem); 1838*f1ae32a1SGerd Hoffmann 1839*f1ae32a1SGerd Hoffmann return 0; 1840*f1ae32a1SGerd Hoffmann } 1841*f1ae32a1SGerd Hoffmann 1842*f1ae32a1SGerd Hoffmann static Property ohci_pci_properties[] = { 1843*f1ae32a1SGerd Hoffmann DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus), 1844*f1ae32a1SGerd Hoffmann DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3), 1845*f1ae32a1SGerd Hoffmann DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0), 1846*f1ae32a1SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 1847*f1ae32a1SGerd Hoffmann }; 1848*f1ae32a1SGerd Hoffmann 1849*f1ae32a1SGerd Hoffmann static void ohci_pci_class_init(ObjectClass *klass, void *data) 1850*f1ae32a1SGerd Hoffmann { 1851*f1ae32a1SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 1852*f1ae32a1SGerd Hoffmann PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); 1853*f1ae32a1SGerd Hoffmann 1854*f1ae32a1SGerd Hoffmann k->init = usb_ohci_initfn_pci; 1855*f1ae32a1SGerd Hoffmann k->vendor_id = PCI_VENDOR_ID_APPLE; 1856*f1ae32a1SGerd Hoffmann k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB; 1857*f1ae32a1SGerd Hoffmann k->class_id = PCI_CLASS_SERIAL_USB; 1858*f1ae32a1SGerd Hoffmann dc->desc = "Apple USB Controller"; 1859*f1ae32a1SGerd Hoffmann dc->props = ohci_pci_properties; 1860*f1ae32a1SGerd Hoffmann } 1861*f1ae32a1SGerd Hoffmann 1862*f1ae32a1SGerd Hoffmann static TypeInfo ohci_pci_info = { 1863*f1ae32a1SGerd Hoffmann .name = "pci-ohci", 1864*f1ae32a1SGerd Hoffmann .parent = TYPE_PCI_DEVICE, 1865*f1ae32a1SGerd Hoffmann .instance_size = sizeof(OHCIPCIState), 1866*f1ae32a1SGerd Hoffmann .class_init = ohci_pci_class_init, 1867*f1ae32a1SGerd Hoffmann }; 1868*f1ae32a1SGerd Hoffmann 1869*f1ae32a1SGerd Hoffmann static Property ohci_sysbus_properties[] = { 1870*f1ae32a1SGerd Hoffmann DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3), 1871*f1ae32a1SGerd Hoffmann DEFINE_PROP_TADDR("dma-offset", OHCISysBusState, dma_offset, 3), 1872*f1ae32a1SGerd Hoffmann DEFINE_PROP_END_OF_LIST(), 1873*f1ae32a1SGerd Hoffmann }; 1874*f1ae32a1SGerd Hoffmann 1875*f1ae32a1SGerd Hoffmann static void ohci_sysbus_class_init(ObjectClass *klass, void *data) 1876*f1ae32a1SGerd Hoffmann { 1877*f1ae32a1SGerd Hoffmann DeviceClass *dc = DEVICE_CLASS(klass); 1878*f1ae32a1SGerd Hoffmann SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); 1879*f1ae32a1SGerd Hoffmann 1880*f1ae32a1SGerd Hoffmann sbc->init = ohci_init_pxa; 1881*f1ae32a1SGerd Hoffmann dc->desc = "OHCI USB Controller"; 1882*f1ae32a1SGerd Hoffmann dc->props = ohci_sysbus_properties; 1883*f1ae32a1SGerd Hoffmann } 1884*f1ae32a1SGerd Hoffmann 1885*f1ae32a1SGerd Hoffmann static TypeInfo ohci_sysbus_info = { 1886*f1ae32a1SGerd Hoffmann .name = "sysbus-ohci", 1887*f1ae32a1SGerd Hoffmann .parent = TYPE_SYS_BUS_DEVICE, 1888*f1ae32a1SGerd Hoffmann .instance_size = sizeof(OHCISysBusState), 1889*f1ae32a1SGerd Hoffmann .class_init = ohci_sysbus_class_init, 1890*f1ae32a1SGerd Hoffmann }; 1891*f1ae32a1SGerd Hoffmann 1892*f1ae32a1SGerd Hoffmann static void ohci_register_types(void) 1893*f1ae32a1SGerd Hoffmann { 1894*f1ae32a1SGerd Hoffmann type_register_static(&ohci_pci_info); 1895*f1ae32a1SGerd Hoffmann type_register_static(&ohci_sysbus_info); 1896*f1ae32a1SGerd Hoffmann } 1897*f1ae32a1SGerd Hoffmann 1898*f1ae32a1SGerd Hoffmann type_init(ohci_register_types) 1899