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