do not test reserved config bits
[qemu] / hw / usb-uhci.c
index 42417fe..f902d46 100644 (file)
@@ -63,7 +63,6 @@
 typedef struct UHCIPort {
     USBPort port;
     uint16_t ctrl;
-    USBDevice *dev; /* connected device */
 } UHCIPort;
 
 typedef struct UHCIState {
@@ -106,7 +105,7 @@ static void uhci_update_irq(UHCIState *s)
     } else {
         level = 0;
     }
-    pci_set_irq(&s->dev, 0, level);
+    pci_set_irq(&s->dev, 3, level);
 }
 
 static void uhci_reset(UHCIState *s)
@@ -128,8 +127,8 @@ static void uhci_reset(UHCIState *s)
     for(i = 0; i < NB_PORTS; i++) {
         port = &s->ports[i];
         port->ctrl = 0x0080;
-        if (port->dev)
-            uhci_attach(&port->port, port->dev);
+        if (port->port.dev)
+            uhci_attach(&port->port, port->port.dev);
     }
 }
 
@@ -154,6 +153,7 @@ static uint32_t uhci_ioport_readb(void *opaque, uint32_t addr)
     switch(addr) {
     case 0x0c:
         val = s->sof_timing;
+        break;
     default:
         val = 0xff;
         break;
@@ -183,7 +183,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
             /* send reset on the USB bus */
             for(i = 0; i < NB_PORTS; i++) {
                 port = &s->ports[i];
-                dev = port->dev;
+                dev = port->port.dev;
                 if (dev) {
                     dev->handle_packet(dev, 
                                        USB_MSG_RESET, 0, 0, NULL, 0);
@@ -192,7 +192,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
             uhci_reset(s);
             return;
         }
-        if (val & UHCI_CMD_GRESET) {
+        if (val & UHCI_CMD_HCRESET) {
             uhci_reset(s);
             return;
         }
@@ -224,7 +224,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
             if (n >= NB_PORTS)
                 return;
             port = &s->ports[n];
-            dev = port->dev;
+            dev = port->port.dev;
             if (dev) {
                 /* port reset */
                 if ( (val & UHCI_PORT_RESET) && 
@@ -320,7 +320,7 @@ static void uhci_attach(USBPort *port1, USBDevice *dev)
     UHCIPort *port = &s->ports[port1->index];
 
     if (dev) {
-        if (port->dev) {
+        if (port->port.dev) {
             usb_attach(port1, NULL);
         }
         /* set connect status */
@@ -332,7 +332,7 @@ static void uhci_attach(USBPort *port1, USBDevice *dev)
             port->ctrl |= UHCI_PORT_LSDA;
         else
             port->ctrl &= ~UHCI_PORT_LSDA;
-        port->dev = dev;
+        port->port.dev = dev;
         /* send the attach message */
         dev->handle_packet(dev, 
                            USB_MSG_ATTACH, 0, 0, NULL, 0);
@@ -346,13 +346,13 @@ static void uhci_attach(USBPort *port1, USBDevice *dev)
             port->ctrl &= ~UHCI_PORT_EN;
             port->ctrl |= UHCI_PORT_ENC;
         }
-        dev = port->dev;
+        dev = port->port.dev;
         if (dev) {
             /* send the detach message */
             dev->handle_packet(dev, 
                                USB_MSG_DETACH, 0, 0, NULL, 0);
         }
-        port->dev = NULL;
+        port->port.dev = NULL;
     }
 }
 
@@ -386,7 +386,7 @@ static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
 #endif
     for(i = 0; i < NB_PORTS; i++) {
         port = &s->ports[i];
-        dev = port->dev;
+        dev = port->port.dev;
         if (dev && (port->ctrl & UHCI_PORT_EN)) {
             ret = dev->handle_packet(dev, pid, 
                                      devaddr, devep,
@@ -642,7 +642,7 @@ void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
 
     s = (UHCIState *)pci_register_device(bus,
                                         "USB-UHCI", sizeof(UHCIState),
-                                        -1, 
+                                        ((PCIDevice *)piix3_state)->devfn + 2, 
                                         NULL, NULL);
     pci_conf = s->dev.config;
     pci_conf[0x00] = 0x86;
@@ -654,7 +654,8 @@ void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
     pci_conf[0x0a] = 0x03;
     pci_conf[0x0b] = 0x0c;
     pci_conf[0x0e] = 0x00; // header_type
-    pci_conf[0x3d] = 1; // interrupt pin 0
+    pci_conf[0x3d] = 4; // interrupt pin 3
+    pci_conf[0x60] = 0x10; // release number
     
     for(i = 0; i < NB_PORTS; i++) {
         port = &s->ports[i];
@@ -667,6 +668,8 @@ void usb_uhci_init(PCIBus *bus, USBPort **usb_ports)
 
     uhci_reset(s);
 
-    pci_register_io_region(&s->dev, 0, 0x20, 
+    /* Use region 4 for consistency with real hardware.  BSD guests seem
+       to rely on this.  */
+    pci_register_io_region(&s->dev, 4, 0x20, 
                            PCI_ADDRESS_SPACE_IO, uhci_map);
 }