summaryrefslogtreecommitdiffstats
path: root/patches/valgrind-usbdevfs.patch
blob: 9287573b33d6e022c09da7e28f0c00c40b845527 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
diff -ur -x '*~' valgrind-3.4.1/coregrind/m_syswrap/syswrap-generic.c valgrind-3.4.1-mod/coregrind/m_syswrap/syswrap-generic.c
--- valgrind-3.4.1/coregrind/m_syswrap/syswrap-generic.c	2009-03-01 23:01:09.000000000 +0100
+++ valgrind-3.4.1-mod/coregrind/m_syswrap/syswrap-generic.c	2009-04-29 15:44:08.000000000 +0200
@@ -4160,23 +4160,56 @@
          struct vki_usbdevfs_urb *vkuu = (struct vki_usbdevfs_urb *)ARG3;
 
          /* Not the whole struct needs to be initialized */
-         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).ep", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
+         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).endpoint", (Addr)&vkuu->endpoint, sizeof(vkuu->endpoint));
          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).type", (Addr)&vkuu->type, sizeof(vkuu->type));
          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).flags", (Addr)&vkuu->flags, sizeof(vkuu->flags));
          PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)&vkuu->buffer, sizeof(vkuu->buffer));
-         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
-         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).usercontext", (Addr)&vkuu->usercontext, sizeof(vkuu->usercontext));
-         if (vkuu->endpoint & 0x80)
-            PRE_MEM_WRITE( "ioctl(USBDEVFS_URB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
-         else
-            PRE_MEM_READ( "ioctl(USBDEVFS_URB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
-         /* FIXME: Does not handle all cases this ioctl can do, ISOs are missing. */
+         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).signr", (Addr)&vkuu->signr, sizeof(vkuu->signr));
+         PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).status", (Addr)&vkuu->status, sizeof(vkuu->status));
+         if (vkuu->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
+            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)vkuu->buffer;
+            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
+            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.setup_packet", (Addr)vkusp, sizeof(*vkusp));
+            if (vkusp->bRequestType & 0x80)
+               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
+            else
+               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer.data", (Addr)(vkusp+1), vkuu->buffer_length - sizeof(*vkusp));
+            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
+         } else if (vkuu->type == VKI_USBDEVFS_URB_TYPE_ISO) {
+            int total_length = 0;
+            int i;
+            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).number_of_packets", (Addr)&vkuu->number_of_packets, sizeof(vkuu->number_of_packets));
+            for(i=0; i<vkuu->number_of_packets; i++) {
+               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].length", (Addr)&vkuu->iso_frame_desc[i].length, sizeof(vkuu->iso_frame_desc[i].length));
+               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].actual_length", (Addr)&vkuu->iso_frame_desc[i].actual_length, sizeof(vkuu->iso_frame_desc[i].actual_length));
+               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).iso_frame_desc[].status", (Addr)&vkuu->iso_frame_desc[i].status, sizeof(vkuu->iso_frame_desc[i].status));
+               total_length += vkuu->iso_frame_desc[i].length;
+            }
+            if (vkuu->endpoint & 0x80)
+               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
+            else
+               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, total_length);
+            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).error_count", (Addr)&vkuu->error_count, sizeof(vkuu->error_count));
+         } else {
+            PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer_length", (Addr)&vkuu->buffer_length, sizeof(vkuu->buffer_length));
+            if (vkuu->endpoint & 0x80)
+               PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
+            else
+               PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB).buffer", (Addr)vkuu->buffer, vkuu->buffer_length);
+            PRE_MEM_WRITE( "ioctl(USBDEVFS_SUBMITURB).actual_length", (Addr)&vkuu->actual_length, sizeof(vkuu->actual_length));
+         }
          break;
       }
+   case VKI_USBDEVFS_DISCARDURB:
+      break;
    case VKI_USBDEVFS_REAPURB:
+      if ( ARG3 ) {
+         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURB)", ARG3, sizeof(struct vki_usbdevfs_urb **));
+         break;
+      }
    case VKI_USBDEVFS_REAPURBNDELAY:
       if ( ARG3 ) {
-         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB)", ARG3, sizeof(struct vki_usbdevfs_urb *));
+         PRE_MEM_WRITE( "ioctl(USBDEVFS_REAPURBNDELAY)", ARG3, sizeof(struct vki_usbdevfs_urb **));
          break;
       }
    case VKI_USBDEVFS_CONNECTINFO:
@@ -4986,11 +5019,31 @@
    case VKI_USBDEVFS_REAPURBNDELAY:
       if ( ARG3 ) {
          struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
+         POST_MEM_WRITE((Addr)vkuu, sizeof(*vkuu));
          if (!*vkuu)
             break;
          POST_MEM_WRITE((Addr) &((*vkuu)->status),sizeof((*vkuu)->status));
-         if ((*vkuu)->endpoint & 0x80)
-            POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
+         if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_CONTROL) {
+            struct vki_usbdevfs_setuppacket *vkusp = (struct vki_usbdevfs_setuppacket *)(*vkuu)->buffer;
+            if (vkusp->bRequestType & 0x80)
+               POST_MEM_WRITE((Addr)(vkusp+1), (*vkuu)->buffer_length - sizeof(*vkusp));
+            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
+         } else if ((*vkuu)->type == VKI_USBDEVFS_URB_TYPE_ISO) {
+            char *bp = (*vkuu)->buffer;
+            int i;
+            for(i=0; i<(*vkuu)->number_of_packets; i++) {
+               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].actual_length, sizeof((*vkuu)->iso_frame_desc[i].actual_length));
+               POST_MEM_WRITE((Addr)&(*vkuu)->iso_frame_desc[i].status, sizeof((*vkuu)->iso_frame_desc[i].status));
+               if ((*vkuu)->endpoint & 0x80)
+                  POST_MEM_WRITE((Addr)bp, (*vkuu)->iso_frame_desc[i].actual_length);
+               bp += (*vkuu)->iso_frame_desc[i].length; // FIXME: or actual_length??
+            }
+            POST_MEM_WRITE((Addr)&(*vkuu)->error_count, sizeof((*vkuu)->error_count));
+         } else {
+            if ((*vkuu)->endpoint & 0x80)
+               POST_MEM_WRITE((Addr)(*vkuu)->buffer, (*vkuu)->actual_length);
+            POST_MEM_WRITE((Addr)&(*vkuu)->actual_length, sizeof((*vkuu)->actual_length));
+         }
          break;
       }
    case VKI_USBDEVFS_CONNECTINFO:
diff -ur -x '*~' valgrind-3.4.1/include/vki/vki-linux.h valgrind-3.4.1-mod/include/vki/vki-linux.h
--- valgrind-3.4.1/include/vki/vki-linux.h	2009-03-01 22:46:45.000000000 +0100
+++ valgrind-3.4.1-mod/include/vki/vki-linux.h	2009-04-29 15:42:05.000000000 +0200
@@ -2325,11 +2325,26 @@
 #define VKI_USBDEVFS_BULK              _VKI_IOWR('U', 2, struct vki_usbdevfs_bulktransfer)
 #define VKI_USBDEVFS_GETDRIVER         _VKI_IOW('U', 8, struct vki_usbdevfs_getdriver)
 #define VKI_USBDEVFS_SUBMITURB         _VKI_IOR('U', 10, struct vki_usbdevfs_urb)
+#define VKI_USBDEVFS_DISCARDURB        _VKI_IO('U', 11)
 #define VKI_USBDEVFS_REAPURB           _VKI_IOW('U', 12, void *)
 #define VKI_USBDEVFS_REAPURBNDELAY     _VKI_IOW('U', 13, void *)
 #define VKI_USBDEVFS_CONNECTINFO       _VKI_IOW('U', 17, struct vki_usbdevfs_connectinfo)
 #define VKI_USBDEVFS_IOCTL             _VKI_IOWR('U', 18, struct vki_usbdevfs_ioctl)
 
+#define VKI_USBDEVFS_URB_TYPE_ISO              0
+#define VKI_USBDEVFS_URB_TYPE_INTERRUPT        1
+#define VKI_USBDEVFS_URB_TYPE_CONTROL          2
+#define VKI_USBDEVFS_URB_TYPE_BULK             3
+
+// this is missing in usbdevice_fs.h
+struct vki_usbdevfs_setuppacket {
+	__vki_u8 bRequestType;
+	__vki_u8 bRequest;
+	__vki_u16 wValue;
+	__vki_u16 wIndex;
+	__vki_u16 wLength;
+};
+
 //----------------------------------------------------------------------
 // From linux-2.6.20.1/include/linux/i2c.h
 //----------------------------------------------------------------------