]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Merge r6411 (usb ioctl handling)
authorJulian Seward <jseward@acm.org>
Tue, 26 Dec 2006 04:08:39 +0000 (04:08 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 26 Dec 2006 04:08:39 +0000 (04:08 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_3_2_BRANCH@6433

coregrind/m_syswrap/syswrap-generic.c
include/vki-linux.h

index 5801afce17f119b408b54fa5076da916e3ee309d..b380e5307f135350941ba40d03755bdd88cbb0b4 100644 (file)
@@ -4015,7 +4015,80 @@ PRE(sys_ioctl)
    case VKI_VT_UNLOCKSWITCH:
       break;
 
-      
+   case VKI_USBDEVFS_CONTROL:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
+         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequestType", (Addr)&vkuc->bRequestType, sizeof(vkuc->bRequestType));
+         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).bRequest", (Addr)&vkuc->bRequest, sizeof(vkuc->bRequest));
+         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wValue", (Addr)&vkuc->wValue, sizeof(vkuc->wValue));
+         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wIndex", (Addr)&vkuc->wIndex, sizeof(vkuc->wIndex));
+         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).wLength", (Addr)&vkuc->wLength, sizeof(vkuc->wLength));
+         PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).timeout", (Addr)&vkuc->timeout, sizeof(vkuc->timeout));
+         if (vkuc->bRequestType & 0x80)
+            PRE_MEM_WRITE( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
+         else
+            PRE_MEM_READ( "ioctl(USBDEVFS_CONTROL).data", (Addr)vkuc->data, vkuc->wLength);
+      }
+      break;
+   case VKI_USBDEVFS_BULK:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
+         PRE_MEM_READ( "ioctl(USBDEVFS_BULK)", ARG3, sizeof(struct vki_usbdevfs_bulktransfer));
+         if (vkub->ep & 0x80)
+            PRE_MEM_WRITE( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
+         else
+            PRE_MEM_READ( "ioctl(USBDEVFS_BULK).data", (Addr)vkub->data, vkub->len);
+         break;
+      }
+   case VKI_USBDEVFS_GETDRIVER:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *) ARG3;
+         PRE_MEM_WRITE( "ioctl(USBDEVFS_GETDRIVER)", (Addr)&vkugd->driver, sizeof(vkugd->driver));
+         break;
+      }
+   case VKI_USBDEVFS_SUBMITURB:
+      if ( ARG3 ) {
+         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).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. */
+         break;
+      }
+   case VKI_USBDEVFS_REAPURB:
+   case VKI_USBDEVFS_REAPURBNDELAY:
+      if ( ARG3 ) {
+         PRE_MEM_READ( "ioctl(USBDEVFS_SUBMITURB)", ARG3, sizeof(struct vki_usbdevfs_urb *));
+         break;
+      }
+   case VKI_USBDEVFS_CONNECTINFO:
+      PRE_MEM_WRITE( "ioctl(USBDEVFS_CONNECTINFO)", ARG3, sizeof(struct vki_usbdevfs_connectinfo));
+      break;
+   case VKI_USBDEVFS_IOCTL:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
+         UInt dir2, size2;
+         PRE_MEM_READ("ioctl(USBDEVFS_IOCTL)", (Addr)vkui, sizeof(struct vki_usbdevfs_ioctl));
+         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
+         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
+         if (size2 > 0) {
+            if (dir2 & _VKI_IOC_WRITE)
+               PRE_MEM_READ("ioctl(USBDEVFS_IOCTL).dataWrite", (Addr)vkui->data, size2);
+            else if (dir2 & _VKI_IOC_READ)
+               PRE_MEM_WRITE("ioctl(USBDEVFS_IOCTL).dataRead", (Addr)vkui->data, size2);
+         }
+      }
+      break;
+
       /* We don't have any specific information on it, so
         try to do something reasonable based on direction and
         size bits.  The encoding scheme is described in
@@ -4676,7 +4749,53 @@ POST(sys_ioctl)
    case VKI_VT_LOCKSWITCH:
    case VKI_VT_UNLOCKSWITCH:
       break;
-      
+
+   case VKI_USBDEVFS_CONTROL:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_ctrltransfer *vkuc = (struct vki_usbdevfs_ctrltransfer *)ARG3;
+         if (vkuc->bRequestType & 0x80)
+            POST_MEM_WRITE((Addr)vkuc->data, RES);
+         break;
+      }
+   case VKI_USBDEVFS_BULK:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_bulktransfer *vkub = (struct vki_usbdevfs_bulktransfer *)ARG3;
+         if (vkub->ep & 0x80)
+            POST_MEM_WRITE((Addr)vkub->data, RES);
+         break;
+      }
+   case VKI_USBDEVFS_GETDRIVER:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_getdriver *vkugd = (struct vki_usbdevfs_getdriver *)ARG3;
+         POST_MEM_WRITE((Addr)&vkugd->driver, sizeof(vkugd->driver));
+         break;
+      }
+   case VKI_USBDEVFS_REAPURB:
+   case VKI_USBDEVFS_REAPURBNDELAY:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_urb **vkuu = (struct vki_usbdevfs_urb**)ARG3;
+         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);
+         break;
+      }
+   case VKI_USBDEVFS_CONNECTINFO:
+      POST_MEM_WRITE(ARG3, sizeof(struct vki_usbdevfs_connectinfo));
+      break;
+   case VKI_USBDEVFS_IOCTL:
+      if ( ARG3 ) {
+         struct vki_usbdevfs_ioctl *vkui = (struct vki_usbdevfs_ioctl *)ARG3;
+         UInt dir2, size2;
+         dir2  = _VKI_IOC_DIR(vkui->ioctl_code);
+         size2 = _VKI_IOC_SIZE(vkui->ioctl_code);
+         if (size2 > 0) {
+            if (dir2 & _VKI_IOC_READ) 
+               POST_MEM_WRITE((Addr)vkui->data, size2);
+         }
+      }
+      break;
 
       /* We don't have any specific information on it, so
         try to do something reasonable based on direction and
index 9de6eb3715226962c6bd644e5c473e2a8290f35f..46c41d6bdd493cb2a73a58afebaa2f9538b1217e 100644 (file)
@@ -2224,6 +2224,77 @@ struct vki_vt_consize {
 # define VKI_PR_ENDIAN_LITTLE  1       /* True little endian mode */
 # define VKI_PR_ENDIAN_PPC_LITTLE      2       /* "PowerPC" pseudo little endian */
 
+//----------------------------------------------------------------------
+// From linux-2.6.19/include/linux/usbdevice_fs.h
+//----------------------------------------------------------------------
+
+struct vki_usbdevfs_ctrltransfer {
+       __vki_u8 bRequestType;
+       __vki_u8 bRequest;
+       __vki_u16 wValue;
+       __vki_u16 wIndex;
+       __vki_u16 wLength;
+       __vki_u32 timeout;  /* in milliseconds */
+       void __user *data;
+};
+
+struct vki_usbdevfs_bulktransfer {
+       unsigned int ep;
+       unsigned int len;
+       unsigned int timeout; /* in milliseconds */
+       void __user *data;
+};
+
+#define VKI_USBDEVFS_MAXDRIVERNAME 255
+
+struct vki_usbdevfs_getdriver {
+       unsigned int interface;
+       char driver[VKI_USBDEVFS_MAXDRIVERNAME + 1];
+};
+
+struct vki_usbdevfs_connectinfo {
+       unsigned int devnum;
+       unsigned char slow;
+};
+
+struct vki_usbdevfs_iso_packet_desc {
+       unsigned int length;
+       unsigned int actual_length;
+       unsigned int status;
+};
+
+struct vki_usbdevfs_urb {
+       unsigned char type;
+       unsigned char endpoint;
+       int status;
+       unsigned int flags;
+       void __user *buffer;
+       int buffer_length;
+       int actual_length;
+       int start_frame;
+       int number_of_packets;
+       int error_count;
+       unsigned int signr;  /* signal to be sent on error, -1 if none should be sent */
+       void *usercontext;
+       struct vki_usbdevfs_iso_packet_desc iso_frame_desc[0];
+};
+
+struct vki_usbdevfs_ioctl {
+       int     ifno;           /* interface 0..N ; negative numbers reserved */
+       int     ioctl_code;     /* MUST encode size + direction of data so the
+                                * macros in <asm/ioctl.h> give correct values */
+       void __user *data;      /* param buffer (in, or out) */
+};
+
+#define VKI_USBDEVFS_CONTROL          _VKI_IOWR('U', 0, struct vki_usbdevfs_ctrltransfer)
+#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_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)
+
 #endif // __VKI_LINUX_H
 
 /*--------------------------------------------------------------------*/