socsvn commit: r254820 - soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb

syuu at FreeBSD.org syuu at FreeBSD.org
Tue Jul 16 04:06:46 UTC 2013


Author: syuu
Date: Tue Jul 16 04:06:45 2013
New Revision: 254820
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254820

Log:
  pci_uhci_softc, debuglog output to /tmp/bhyveusb.log, use legacy intr instead of msi, usb rev version fix, uhci_reset segv fix, readable read/write debug message

Modified:
  soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c

Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c
==============================================================================
--- soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c	Tue Jul 16 03:12:31 2013	(r254819)
+++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c	Tue Jul 16 04:06:45 2013	(r254820)
@@ -43,14 +43,6 @@
 #define PCI_VENDOR_ID_INTEL 0x8086
 #define PCI_DEVICE_ID_INTEL_82801I_UHCI6 0x2939
 
-/*
- * Per-device softc
- */
-struct pci_uhci_softc {
-	struct pci_devinst *sc_pi;
-	pthread_mutex_t sc_mtx;
-};
-
 struct PCIDevice {
 	uint8_t *config;
 };
@@ -62,93 +54,95 @@
 typedef struct PCIDeviceClass PCIDeviceClass;
 typedef struct MemoryRegion MemoryRegion;
 
+FILE *usblog;
+
 #define trace_usb_uhci_queue_add(token) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_queue_add token=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_queue_add token=%x\n", \
 	__func__, __LINE__, token)
 #define trace_usb_uhci_queue_del(token, reason) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_queue_del token=%x reason=%s\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_queue_del token=%x reason=%s\n", \
 	__func__, __LINE__, token, reason)
 #define trace_usb_uhci_packet_add(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_add token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_add token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_packet_del(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_del token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_del token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_packet_cancel(token, td_addr, done) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_cancel token=%x td_addr=%x done=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_cancel token=%x td_addr=%x done=%x\n", \
 	__func__, __LINE__, token, td_addr, done)
 #define trace_usb_uhci_packet_link_async(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_link_async token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_link_async token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_packet_unlink_async(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_unlink_async token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_unlink_async token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_reset() \
-    fprintf(stderr, "%s:%d trace_usb_uhci_reset\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_reset\n", \
 	__func__, __LINE__)
 #define trace_usb_uhci_mmio_writew(addr, val) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_mmio_writew addr=%lx val=%lx\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_mmio_writew addr=%lx val=%lx\n", \
 	__func__, __LINE__, addr, val)
 #define trace_usb_uhci_mmio_readw(addr, val) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_mmio_readw addr=%lx val=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_mmio_readw addr=%lx val=%x\n", \
 	__func__, __LINE__, addr, val)
 #define trace_usb_uhci_schedule_start() \
-    fprintf(stderr, "%s:%d trace_usb_uhci_schedule_start\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_schedule_start\n", \
 	__func__, __LINE__)
 #define trace_usb_uhci_packet_complete_stall(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_stall token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_stall token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_packet_complete_babble(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_babble token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_babble token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_packet_complete_error(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_error token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_error token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_packet_complete_shortxfer(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_shortxfer token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_shortxfer token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_packet_complete_success(token, td_addr) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_success token=%x td_addr=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_success token=%x td_addr=%x\n", \
 	__func__, __LINE__, token, td_addr)
 #define trace_usb_uhci_td_queue(link, ctrl, token) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_td_queue link=%x ctrl=%x token=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_td_queue link=%x ctrl=%x token=%x\n", \
 	__func__, __LINE__, link, ctrl, token)
 #define trace_usb_uhci_frame_stop_bandwidth() \
-    fprintf(stderr, "%s:%d trace_usb_uhci_frame_stop_bandwidth\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_frame_stop_bandwidth\n", \
 	__func__, __LINE__)
 #define trace_usb_uhci_qh_load(link) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_qh_load link=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_qh_load link=%x\n", \
 	__func__, __LINE__, link)
 #define trace_usb_uhci_frame_loop_stop_idle() \
-    fprintf(stderr, "%s:%d trace_usb_uhci_frame_loop_stop_idle\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_frame_loop_stop_idle\n", \
 	__func__, __LINE__)
 #define trace_usb_uhci_frame_loop_continue() \
-    fprintf(stderr, "%s:%d trace_usb_uhci_frame_loop_continue\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_frame_loop_continue\n", \
 	__func__, __LINE__)
 #define trace_usb_uhci_td_load(qh, link, ctrl, token) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_td_load qh=%x link=%x ctrl=%x token=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_td_load qh=%x link=%x ctrl=%x token=%x\n", \
 	__func__, __LINE__, qh, link, ctrl, token)
 #define trace_usb_uhci_td_nextqh(qh, link) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_td_nextqh qh=%x link=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_td_nextqh qh=%x link=%x\n", \
 	__func__, __LINE__, qh, link)
 #define trace_usb_uhci_td_async(qh, link) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_td_async qh=%x link=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_td_async qh=%x link=%x\n", \
 	__func__, __LINE__, qh, link)
 #define trace_usb_uhci_td_complete(qh, link) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_td_complete qh=%x link=%x\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_td_complete qh=%x link=%x\n", \
 	__func__, __LINE__, qh, link)
 #define trace_usb_uhci_schedule_stop() \
-    fprintf(stderr, "%s:%d trace_usb_uhci_schedule_stop\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_schedule_stop\n", \
 	__func__, __LINE__)
 #define trace_usb_uhci_frame_start(num) \
-    fprintf(stderr, "%s:%d trace_usb_uhci_frame_start num=%d\n", \
+    fprintf(usblog, "%s:%d trace_usb_uhci_frame_start num=%d\n", \
 	__func__, __LINE__, num)
 
 //#define DEBUG
 //#define DEBUG_DUMP_DATA
 
 #define	PCI_USBREV		0x60	/* USB protocol revision */
-#define	PCI_USB_REV_1_1		0x11
+#define	PCI_USB_REV_1_0		0x10
 
 #define UHCI_CMD_FGR      (1 << 4)
 #define UHCI_CMD_EGSM     (1 << 3)
@@ -257,6 +251,7 @@
 } UHCIPort;
 
 struct UHCIState {
+    struct pci_uhci_softc *sc;
     PCIDevice dev;
     MemoryRegion io_bar;
     USBBus bus; /* Note unused when we're a companion controller */
@@ -301,8 +296,18 @@
     uint32_t el_link;
 } UHCI_QH;
 
+/*
+ * Per-device softc
+ */
+struct pci_uhci_softc {
+	struct pci_devinst *sc_pi;
+	struct UHCIState sc_st;
+	pthread_mutex_t sc_mtx;
+};
+
 static void uhci_async_cancel(UHCIAsync *async);
 static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td);
+static void uhci_process_frame(UHCIState *s);
 
 static inline int32_t uhci_queue_token(UHCI_TD *td)
 {
@@ -341,7 +346,7 @@
         async = QTAILQ_FIRST(&queue->asyncs);
         uhci_async_cancel(async);
     }
-    usb_device_ep_stopped(queue->ep->dev, queue->ep);
+//    usb_device_ep_stopped(queue->ep->dev, queue->ep);
 
     trace_usb_uhci_queue_del(queue->token, reason);
     QTAILQ_REMOVE(&s->queues, queue, next);
@@ -494,21 +499,23 @@
         level = 0;
     }
 //    qemu_set_irq(s->dev.irq[s->irq_pin], level);
+    if (level)
+        pci_lintr_assert(s->sc->sc_pi);
+    else
+        pci_lintr_deassert(s->sc->sc_pi);
 }
 
 static void uhci_reset(void *opaque)
 {
     UHCIState *s = opaque;
-    uint8_t *pci_conf;
     int i;
     UHCIPort *port;
+    struct pci_uhci_softc *sc = s->sc;
 
     trace_usb_uhci_reset();
 
-    pci_conf = s->dev.config;
-
-    pci_conf[0x6a] = 0x01; /* usb clock */
-    pci_conf[0x6b] = 0x00;
+    pci_set_cfgdata8(sc->sc_pi, 0x6a, 0x01); /* XXX: use macro */
+    pci_set_cfgdata8(sc->sc_pi, 0x6b, 0x00);
     s->cmd = 0;
     s->status = 0;
     s->status2 = 0;
@@ -587,10 +594,11 @@
 {
     UHCIState *s = opaque;
 
-    trace_usb_uhci_mmio_writew(addr, val);
+//    trace_usb_uhci_mmio_writew(addr, val);
 
     switch(addr) {
     case 0x00:
+        fprintf(usblog, "%s USBCMD val:%lx\n", __func__, val);
         if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
             /* start frame processing */
             trace_usb_uhci_schedule_start();
@@ -620,6 +628,7 @@
         s->cmd = val;
         break;
     case 0x02:
+        fprintf(usblog, "%s USBSTS val:%lx\n", __func__, val);
         s->status &= ~val;
         /* XXX: the chip spec is not coherent, so we add a hidden
            register to distinguish between IOC and SPD */
@@ -628,22 +637,27 @@
         uhci_update_irq(s);
         break;
     case 0x04:
+        fprintf(usblog, "%s USBINTR val:%lx\n", __func__, val);
         s->intr = val;
         uhci_update_irq(s);
         break;
     case 0x06:
+        fprintf(usblog, "%s FRNUM val:%lx\n", __func__, val);
         if (s->status & UHCI_STS_HCHALTED)
             s->frnum = val & 0x7ff;
         break;
     case 0x08:
+        fprintf(usblog, "%s FRBASEADD(lo) val:%lx\n", __func__, val);
         s->fl_base_addr &= 0xffff0000;
         s->fl_base_addr |= val & ~0xfff;
         break;
     case 0x0a:
+        fprintf(usblog, "%s FRBASEADD(hi) val:%lx\n", __func__, val);
         s->fl_base_addr &= 0x0000ffff;
         s->fl_base_addr |= (val << 16);
         break;
     case 0x0c:
+        fprintf(usblog, "%s SOFMOD val:%lx\n", __func__, val);
         s->sof_timing = val & 0xff;
         break;
     case 0x10 ... 0x1f:
@@ -653,6 +667,7 @@
             int n;
 
             n = (addr >> 1) & 7;
+            fprintf(usblog, "%s PORTSC%d val:%lx\n", __func__, n, val);
             if (n >= NB_PORTS)
                 return;
             port = &s->ports[n];
@@ -685,24 +700,31 @@
     switch(addr) {
     case 0x00:
         val = s->cmd;
+        fprintf(usblog, "%s USBCMD val:%x\n", __func__, val);
         break;
     case 0x02:
         val = s->status;
+        fprintf(usblog, "%s USBSTS val:%x\n", __func__, val);
         break;
     case 0x04:
         val = s->intr;
+        fprintf(usblog, "%s USBINTR val:%x\n", __func__, val);
         break;
     case 0x06:
         val = s->frnum;
+        fprintf(usblog, "%s FRNUM val:%x\n", __func__, val);
         break;
     case 0x08:
         val = s->fl_base_addr & 0xffff;
+        fprintf(usblog, "%s FRBASEADD(lo) val:%x\n", __func__, val);
         break;
     case 0x0a:
         val = (s->fl_base_addr >> 16) & 0xffff;
+        fprintf(usblog, "%s FRBASEADD(hi) val:%x\n", __func__, val);
         break;
     case 0x0c:
         val = s->sof_timing;
+        fprintf(usblog, "%s SOFMOD val:%x\n", __func__, val);
         break;
     case 0x10 ... 0x1f:
         {
@@ -713,6 +735,7 @@
                 goto read_default;
             port = &s->ports[n];
             val = port->ctrl;
+            fprintf(usblog, "%s PORTSC%d val:%x\n", __func__, n, val);
         }
         break;
     default:
@@ -721,7 +744,7 @@
         break;
     }
 
-    trace_usb_uhci_mmio_readw(addr, val);
+//    trace_usb_uhci_mmio_readw(addr, val);
 
     return val;
 }
@@ -1060,6 +1083,7 @@
     /* Force processing of this packet *now*, needed for migration */
     s->completions_only = true;
 //    qemu_bh_schedule(s->bh);
+    uhci_process_frame(s);
 }
 
 static int is_valid(uint32_t link)
@@ -1542,7 +1566,7 @@
 	struct pci_uhci_softc *sc = pi->pi_arg;
 
 	pthread_mutex_lock(&sc->sc_mtx);
-	printf("%s baridx:%d offset:%lx size:%d value:%lx\n", __func__, baridx, offset, size, value);
+	uhci_port_write(&sc->sc_st, offset, value, size);
 	pthread_mutex_unlock(&sc->sc_mtx);
 }
 
@@ -1555,7 +1579,7 @@
 	uint64_t value;
 
 	pthread_mutex_lock(&sc->sc_mtx);
-	printf("%s baridx:%d offset:%lx size:%d\n", __func__, baridx, offset, size);
+	value = uhci_port_read(&sc->sc_st, offset, size);
 	pthread_mutex_unlock(&sc->sc_mtx);
 
 	return (value);
@@ -1566,8 +1590,13 @@
 {
 	struct pci_uhci_softc *sc;
 
+	usblog = fopen("/tmp/bhyveusb.log", "w");
+	if (!usblog) {
+		perror("fopen");
+		exit(1);
+	}
 	sc = malloc(sizeof(struct pci_uhci_softc));
-	memset(sc, 0, sizeof(struct pci_uhci_softc));
+	memset(sc, 0, sizeof(*sc));
 
 	pi->pi_arg = sc;
 	sc->sc_pi = pi;
@@ -1578,10 +1607,19 @@
 	pci_set_cfgdata16(pi, PCIR_DEVICE, PCI_DEVICE_ID_INTEL_82801I_UHCI6);
 	pci_set_cfgdata16(pi, PCIR_VENDOR, PCI_VENDOR_ID_INTEL);
 	pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SERIALBUS);
-	pci_set_cfgdata8(pi, PCI_USBREV, PCI_USB_REV_1_1);
-	
-	/* MSI support */
-	pci_emul_add_msicap(pi, 1);
+	pci_set_cfgdata8(pi, PCI_USBREV, PCI_USB_REV_1_0);
+
+	if (!pci_is_legacy(pi)) {
+		fprintf(stderr, "hcd-uhci works only in legacy mode\n");
+	} else {
+		pci_lintr_request(pi, 9);
+	}
+		
+	memset(&sc->sc_st, 0, sizeof(sc->sc_st));
+	sc->sc_st.num_ports_vmstate = NB_PORTS;
+	QTAILQ_INIT(&sc->sc_st.queues);
+	sc->sc_st.sc = sc;
+	uhci_reset(&sc->sc_st);
 	
 	pci_emul_alloc_bar(pi, 4, PCIBAR_IO, 0x20);
 


More information about the svn-soc-all mailing list