⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb-mouse-tablet-status-check

📁 xen 3.2.2 源码
💻
字号:
# HG changeset patch# User kfraser@localhost.localdomain# Node ID 60bbcf799384d779c2a561b9d9ba30f28e31d970# Parent  fb3cb6f52a2905be938559529ae43b6ba990c878[HVM] qemu mouse: Adds support for USB mouse/tablet status check andrestricts Universal Host Controller interrupt generating when receivedNAK in interrupt transfer.According to usb spec, USB mouse/tablet device returns NAK to hostcontroller if its status does not alter in interrupt transfer.And UHC should leave a TD active when receiving NAK and execute thisincompleted TD in a subseqent frame. UHC only generates an interrupton complete after the TD with ICO bit is completed.This patch make UHC & USB mouse/tablet behave consistently with spec.Signed-off-by: Xinmei Huang <xinmei.huang@intel.com>Index: ioemu/hw/usb-hid.c===================================================================--- ioemu.orig/hw/usb-hid.c	2007-05-09 14:11:27.000000000 +0100+++ ioemu/hw/usb-hid.c	2007-05-09 14:12:06.000000000 +0100@@ -39,6 +39,7 @@     int x, y;     int kind;     int mouse_grabbed;+    int status_changed;     QEMUPutMouseEntry *eh_entry; } USBMouseState; @@ -232,6 +233,7 @@     s->dy += dy1;     s->dz += dz1;     s->buttons_state = buttons_state;+    s->status_changed = 1; }  static void usb_tablet_event(void *opaque,@@ -243,6 +245,7 @@     s->y = y;     s->dz += dz;     s->buttons_state = buttons_state;+    s->status_changed = 1; }  static inline int int_clamp(int val, int vmin, int vmax)@@ -485,10 +488,16 @@     switch(p->pid) {     case USB_TOKEN_IN:         if (p->devep == 1) {-	    if (s->kind == USB_MOUSE)-		ret = usb_mouse_poll(s, p->data, p->len);-	    else if (s->kind == USB_TABLET)-		ret = usb_tablet_poll(s, p->data, p->len);+            if (s->kind == USB_MOUSE)+                ret = usb_mouse_poll(s, p->data, p->len);+            else if (s->kind == USB_TABLET)+                ret = usb_tablet_poll(s, p->data, p->len);++            if (!s->status_changed)+                ret = USB_RET_NAK;+            else+                s->status_changed = 0;+         } else {             goto fail;         }@@ -570,6 +579,7 @@     s->dev.handle_data = usb_mouse_handle_data;     s->dev.handle_destroy = usb_mouse_handle_destroy;     s->kind = USB_TABLET;+    s->status_changed = 0;      pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet"); @@ -593,6 +603,7 @@     s->dev.handle_data = usb_mouse_handle_data;     s->dev.handle_destroy = usb_mouse_handle_destroy;     s->kind = USB_MOUSE;+    s->status_changed = 0;      pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse"); Index: ioemu/hw/usb-uhci.c===================================================================--- ioemu.orig/hw/usb-uhci.c	2007-05-09 14:12:05.000000000 +0100+++ ioemu/hw/usb-uhci.c	2007-05-09 14:12:06.000000000 +0100@@ -43,9 +43,15 @@ #define TD_CTRL_IOC     (1 << 24) #define TD_CTRL_ACTIVE  (1 << 23) #define TD_CTRL_STALL   (1 << 22)+#define TD_CTRL_BUFFER  (1 << 21) #define TD_CTRL_BABBLE  (1 << 20) #define TD_CTRL_NAK     (1 << 19) #define TD_CTRL_TIMEOUT (1 << 18)+#define TD_CTRL_BITSTUFF                                 \+                        (1 << 17)+#define TD_CTRL_MASK                                     \+    (TD_CTRL_BITSTUFF | TD_CTRL_TIMEOUT | TD_CTRL_NAK    \+     | TD_CTRL_BABBLE | TD_CTRL_BUFFER | TD_CTRL_STALL)  #define UHCI_PORT_RESET (1 << 9) #define UHCI_PORT_LSDA  (1 << 8)@@ -431,13 +437,13 @@     uint8_t pid;     int len, max_len, err, ret; -    /* ??? This is wrong for async completion.  */-    if (td->ctrl & TD_CTRL_IOC) {-        *int_mask |= 0x01;+    if (!(td->ctrl & TD_CTRL_ACTIVE)) {+        ret = 1;+	goto out;     }-    -    if (!(td->ctrl & TD_CTRL_ACTIVE))-        return 1;++    /* Clear TD's status field explicitly */+    td->ctrl = td->ctrl & (~TD_CTRL_MASK);      /* TD is active */     max_len = ((td->token >> 21) + 1) & 0x7ff;@@ -493,11 +499,13 @@             /* invalid pid : frame interrupted */             s->status |= UHCI_STS_HCPERR;             uhci_update_irq(s);-            return -1;+            ret = -1;+	    goto out;         }     }     if (ret == USB_RET_ASYNC) {-        return 2;+        ret = 2;+	goto out;     }     if (td->ctrl & TD_CTRL_IOS)         td->ctrl &= ~TD_CTRL_ACTIVE;@@ -509,10 +517,12 @@             len < max_len) {             *int_mask |= 0x02;             /* short packet: do not update QH */-            return 1;+            ret = 1;+            goto out;         } else {             /* success */-            return 0;+            ret = 0;+            goto out;         }     } else {         switch(ret) {@@ -531,23 +541,34 @@             }             td->ctrl = (td->ctrl & ~(3 << TD_CTRL_ERROR_SHIFT)) |                  (err << TD_CTRL_ERROR_SHIFT);-            return 1;+            ret = 1;+            goto out;         case USB_RET_NAK:             td->ctrl |= TD_CTRL_NAK;             if (pid == USB_TOKEN_SETUP)                 goto do_timeout;-            return 1;+            ret = 1;+            goto out;         case USB_RET_STALL:             td->ctrl |= TD_CTRL_STALL;             td->ctrl &= ~TD_CTRL_ACTIVE;-            return 1;+            ret = 1;+            goto out;         case USB_RET_BABBLE:             td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;             td->ctrl &= ~TD_CTRL_ACTIVE;             /* frame interrupted */-            return -1;+            ret = -1;+            goto out;         }     }+   +out:+    /* If TD is inactive and IOC bit set to 1 then update int_mask */ +    if ((td->ctrl & TD_CTRL_IOC) && (!(td->ctrl & TD_CTRL_ACTIVE))) {+        *int_mask |= 0x01;+    }+    return ret; }  static void uhci_async_complete_packet(USBPacket * packet, void *opaque)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -