]> Git Repo - qemu.git/blobdiff - usb-linux.c
Remove debug sample rate slowdown.
[qemu.git] / usb-linux.c
index 53d501d7b975d4bfef6d1a9ce62b7141b05a1084..d3e4e2ef45ce8c28d07eb5356ad978101c773a7c 100644 (file)
@@ -21,7 +21,9 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "vl.h"
+#include "qemu-common.h"
+#include "hw/usb.h"
+#include "console.h"
 
 #if defined(__linux__)
 #include <dirent.h>
@@ -68,6 +70,7 @@ struct endp_data {
 typedef struct USBHostDevice {
     USBDevice dev;
     int fd;
+    int pipe_fds[2];
     USBPacket *packet;
     struct endp_data endp_table[MAX_ENDPOINTS];
     int configuration;
@@ -78,8 +81,6 @@ typedef struct USBHostDevice {
 
 typedef struct PendingURB {
     struct usbdevfs_urb *urb;
-    USBHostDevice *dev;
-    QEMUBH *bh;
     int status;
     struct PendingURB *next;
 } PendingURB;
@@ -91,8 +92,6 @@ static int add_pending_urb(struct usbdevfs_urb *urb)
     PendingURB *purb = qemu_mallocz(sizeof(PendingURB));
     if (purb) {
         purb->urb = urb;
-        purb->dev = NULL;
-        purb->bh = NULL;
         purb->status = 0;
         purb->next = pending_urbs;
         pending_urbs = purb;
@@ -341,16 +340,21 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
 }
 
 #ifdef USE_ASYNCIO
-static void usb_linux_bh_cb(void *opaque)
+static void urb_completion_pipe_read(void *opaque)
 {
-    PendingURB *pending_urb = (PendingURB *)opaque;
-    USBHostDevice *s = pending_urb->dev;
-    struct usbdevfs_urb *purb = NULL;
+    USBHostDevice *s = opaque;
     USBPacket *p = s->packet;
-    int ret;
+    PendingURB *pending_urb = NULL;
+    struct usbdevfs_urb *purb = NULL;
+    int len, ret;
+
+    len = read(s->pipe_fds[0], &pending_urb, sizeof(pending_urb));
+    if (len != sizeof(pending_urb)) {
+        printf("urb_completion: error reading pending_urb, len=%d\n", len);
+        return;
+    }
 
-    /* FIXME: handle purb->status */
-    qemu_free(pending_urb->bh);
+    /* FIXME: handle pending_urb->status */
     del_pending_urb(pending_urb->urb);
 
     if (!p) {
@@ -360,14 +364,14 @@ static void usb_linux_bh_cb(void *opaque)
 
     ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
     if (ret < 0) {
-        printf("usb_linux_bh_cb: REAPURBNDELAY ioctl=%d errno=%d\n",
+        printf("urb_completion: REAPURBNDELAY ioctl=%d errno=%d\n",
                ret, errno);
         return;
     }
 
 #ifdef DEBUG_ISOCH
     if (purb == pending_urb->urb) {
-        printf("usb_linux_bh_cb: urb mismatch reaped=%p pending=%p\n",
+        printf("urb_completion: urb mismatch reaped=%p pending=%p\n",
                purb, urb);
     }
 #endif
@@ -391,12 +395,8 @@ static void isoch_done(int signum, siginfo_t *info, void *context)
 
     purb = get_pending_urb(urb);
     if (purb) {
-        purb->bh = qemu_bh_new(usb_linux_bh_cb, purb);
-        if (purb->bh) {
-            purb->dev = s;
-            purb->status = info->si_errno;
-            qemu_bh_schedule(purb->bh);
-        }
+        purb->status = info->si_errno;
+        write(s->pipe_fds[1], &purb, sizeof(purb));
     }
 }
 #endif
@@ -627,7 +627,7 @@ USBDevice *usb_host_device_open(const char *devname)
     /* read the device description */
     dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
     if (dev->descr_len <= 0) {
-        perror("usb_host_update_interfaces: reading device data failed");
+        perror("usb_host_device_open: reading device data failed");
         goto fail;
     }
 
@@ -650,7 +650,7 @@ USBDevice *usb_host_device_open(const char *devname)
 
     ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
     if (ret < 0) {
-        perror("USBDEVFS_CONNECTINFO");
+        perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
         goto fail;
     }
 
@@ -688,8 +688,17 @@ USBDevice *usb_host_device_open(const char *devname)
     sigact.sa_restorer = 0;
     ret = sigaction(SIG_ISOCOMPLETE, &sigact, NULL);
     if (ret < 0) {
-        printf("sigaction SIG_ISOCOMPLETE=%d errno=%d\n", ret, errno);
+        perror("usb_host_device_open: sigaction failed");
+        goto fail;
+    }
+
+    if (pipe(dev->pipe_fds) < 0) {
+        perror("usb_host_device_open: pipe creation failed");
+        goto fail;
     }
+    fcntl(dev->pipe_fds[0], F_SETFL, O_NONBLOCK | O_ASYNC);
+    fcntl(dev->pipe_fds[1], F_SETFL, O_NONBLOCK);
+    qemu_set_fd_handler(dev->pipe_fds[0], urb_completion_pipe_read, NULL, dev);
 #endif
     dev->urbs_ready = 0;
     return (USBDevice *)dev;
@@ -898,10 +907,10 @@ static const char *usb_class_str(uint8_t class)
     return p->class_name;
 }
 
-void usb_info_device(int bus_num, int addr, int class_id,
-                     int vendor_id, int product_id,
-                     const char *product_name,
-                     int speed)
+static void usb_info_device(int bus_num, int addr, int class_id,
+                            int vendor_id, int product_id,
+                            const char *product_name,
+                            int speed)
 {
     const char *class_str, *speed_str;
 
This page took 0.027484 seconds and 4 git commands to generate.