libusb 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Gemfile +1 -0
  5. data/History.md +10 -0
  6. data/README.md +19 -6
  7. data/Rakefile +1 -1
  8. data/ext/extconf.rb +17 -1
  9. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
  10. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
  11. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
  12. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
  13. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
  14. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
  15. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
  16. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
  17. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
  18. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
  19. data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
  20. data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
  21. data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
  22. data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
  23. data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
  24. data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
  25. data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
  26. data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
  27. data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
  28. data/ext/libusbx-1.0.17/android/README +114 -0
  29. data/ext/libusbx-1.0.17/android/config.h +90 -0
  30. data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
  31. data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
  32. data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
  33. data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
  34. data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
  35. data/ext/libusbx-1.0.17/compile +347 -0
  36. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
  37. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
  38. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
  39. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
  40. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
  41. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
  42. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
  43. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
  44. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
  45. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
  46. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
  47. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
  48. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
  49. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
  50. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
  51. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
  52. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
  53. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
  54. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
  55. data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
  56. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
  57. data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
  58. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
  59. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
  60. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
  61. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
  62. data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
  63. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
  64. data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
  65. data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
  66. data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
  67. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
  68. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
  69. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
  70. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
  71. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
  72. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
  73. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
  74. data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
  75. data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
  76. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
  77. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
  78. data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
  79. data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
  80. data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
  81. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
  82. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
  83. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
  84. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
  85. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
  86. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
  87. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
  88. data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
  89. data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
  90. data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
  91. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
  92. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
  93. data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
  94. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
  95. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
  96. data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
  97. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
  98. data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
  99. data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
  100. data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
  101. data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
  102. data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
  103. data/ext/libusbx-1.0.17/missing +215 -0
  104. data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
  105. data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
  106. data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
  107. data/ext/libusbx-1.0.17/tests/stress.c +160 -0
  108. data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
  109. data/lib/libusb.rb +4 -0
  110. data/lib/libusb/call.rb +43 -1
  111. data/lib/libusb/constants.rb +5 -0
  112. data/lib/libusb/context.rb +100 -0
  113. data/lib/libusb/dev_handle.rb +27 -0
  114. data/lib/libusb/device.rb +10 -4
  115. data/lib/libusb/version_gem.rb +1 -1
  116. data/test/test_libusb_capability.rb +2 -2
  117. data/test/test_libusb_compat.rb +2 -2
  118. data/test/test_libusb_compat_mass_storage.rb +2 -2
  119. data/test/test_libusb_descriptors.rb +4 -2
  120. data/test/test_libusb_event_machine.rb +2 -2
  121. data/test/test_libusb_gc.rb +2 -2
  122. data/test/test_libusb_hotplug.rb +115 -0
  123. data/test/test_libusb_iso_transfer.rb +3 -3
  124. data/test/test_libusb_mass_storage.rb +6 -16
  125. data/test/test_libusb_mass_storage2.rb +26 -3
  126. data/test/test_libusb_structs.rb +2 -2
  127. data/test/test_libusb_threads.rb +2 -2
  128. data/test/test_libusb_version.rb +2 -2
  129. metadata +127 -68
  130. metadata.gz.sig +0 -0
  131. data/ext/libusbx-1.0.14/THANKS +0 -7
  132. data/ext/libusbx-1.0.14/compile +0 -143
  133. data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
  134. data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
  135. data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
  136. data/ext/libusbx-1.0.14/missing +0 -376
@@ -123,6 +123,15 @@ struct usbfs_hub_portinfo {
123
123
  #define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04
124
124
  #define USBFS_CAP_BULK_SCATTER_GATHER 0x08
125
125
 
126
+ #define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01
127
+ #define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02
128
+
129
+ struct usbfs_disconnect_claim {
130
+ unsigned int interface;
131
+ unsigned int flags;
132
+ char driver[USBFS_MAXDRIVERNAME + 1];
133
+ };
134
+
126
135
  #define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer)
127
136
  #define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer)
128
137
  #define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int)
@@ -145,5 +154,28 @@ struct usbfs_hub_portinfo {
145
154
  #define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int)
146
155
  #define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int)
147
156
  #define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32)
157
+ #define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbfs_disconnect_claim)
158
+
159
+ extern usbi_mutex_static_t linux_hotplug_lock;
160
+
161
+ #if defined(HAVE_LIBUDEV)
162
+ int linux_udev_start_event_monitor(void);
163
+ int linux_udev_stop_event_monitor(void);
164
+ int linux_udev_scan_devices(struct libusb_context *ctx);
165
+ void linux_udev_hotplug_poll(void);
166
+ #else
167
+ int linux_netlink_start_event_monitor(void);
168
+ int linux_netlink_stop_event_monitor(void);
169
+ void linux_netlink_hotplug_poll(void);
170
+ #endif
171
+
172
+ void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name);
173
+ void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_name);
174
+
175
+ int linux_get_device_address (struct libusb_context *ctx, int detached,
176
+ uint8_t *busnum, uint8_t *devaddr, const char *dev_node,
177
+ const char *sys_name);
178
+ int linux_enumerate_device(struct libusb_context *ctx,
179
+ uint8_t busnum, uint8_t devaddr, const char *sysfs_dir);
148
180
 
149
181
  #endif
@@ -47,36 +47,36 @@ struct handle_priv {
47
47
  /*
48
48
  * Backend functions
49
49
  */
50
- static int obsd_get_device_list(struct libusb_context *,
50
+ static int netbsd_get_device_list(struct libusb_context *,
51
51
  struct discovered_devs **);
52
- static int obsd_open(struct libusb_device_handle *);
53
- static void obsd_close(struct libusb_device_handle *);
52
+ static int netbsd_open(struct libusb_device_handle *);
53
+ static void netbsd_close(struct libusb_device_handle *);
54
54
 
55
- static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *,
55
+ static int netbsd_get_device_descriptor(struct libusb_device *, unsigned char *,
56
56
  int *);
57
- static int obsd_get_active_config_descriptor(struct libusb_device *,
57
+ static int netbsd_get_active_config_descriptor(struct libusb_device *,
58
58
  unsigned char *, size_t, int *);
59
- static int obsd_get_config_descriptor(struct libusb_device *, uint8_t,
59
+ static int netbsd_get_config_descriptor(struct libusb_device *, uint8_t,
60
60
  unsigned char *, size_t, int *);
61
61
 
62
- static int obsd_get_configuration(struct libusb_device_handle *, int *);
63
- static int obsd_set_configuration(struct libusb_device_handle *, int);
62
+ static int netbsd_get_configuration(struct libusb_device_handle *, int *);
63
+ static int netbsd_set_configuration(struct libusb_device_handle *, int);
64
64
 
65
- static int obsd_claim_interface(struct libusb_device_handle *, int);
66
- static int obsd_release_interface(struct libusb_device_handle *, int);
65
+ static int netbsd_claim_interface(struct libusb_device_handle *, int);
66
+ static int netbsd_release_interface(struct libusb_device_handle *, int);
67
67
 
68
- static int obsd_set_interface_altsetting(struct libusb_device_handle *, int,
68
+ static int netbsd_set_interface_altsetting(struct libusb_device_handle *, int,
69
69
  int);
70
- static int obsd_clear_halt(struct libusb_device_handle *, unsigned char);
71
- static int obsd_reset_device(struct libusb_device_handle *);
72
- static void obsd_destroy_device(struct libusb_device *);
73
-
74
- static int obsd_submit_transfer(struct usbi_transfer *);
75
- static int obsd_cancel_transfer(struct usbi_transfer *);
76
- static void obsd_clear_transfer_priv(struct usbi_transfer *);
77
- static int obsd_handle_events(struct libusb_context *ctx, struct pollfd *,
70
+ static int netbsd_clear_halt(struct libusb_device_handle *, unsigned char);
71
+ static int netbsd_reset_device(struct libusb_device_handle *);
72
+ static void netbsd_destroy_device(struct libusb_device *);
73
+
74
+ static int netbsd_submit_transfer(struct usbi_transfer *);
75
+ static int netbsd_cancel_transfer(struct usbi_transfer *);
76
+ static void netbsd_clear_transfer_priv(struct usbi_transfer *);
77
+ static int netbsd_handle_events(struct libusb_context *ctx, struct pollfd *,
78
78
  nfds_t, int);
79
- static int obsd_clock_gettime(int, struct timespec *);
79
+ static int netbsd_clock_gettime(int, struct timespec *);
80
80
 
81
81
  /*
82
82
  * Private functions
@@ -87,41 +87,44 @@ static int _sync_control_transfer(struct usbi_transfer *);
87
87
  static int _sync_gen_transfer(struct usbi_transfer *);
88
88
  static int _access_endpoint(struct libusb_transfer *);
89
89
 
90
- const struct usbi_os_backend openbsd_backend = {
91
- "Synchronous OpenBSD backend",
90
+ const struct usbi_os_backend netbsd_backend = {
91
+ "Synchronous NetBSD backend",
92
+ 0,
92
93
  NULL, /* init() */
93
94
  NULL, /* exit() */
94
- obsd_get_device_list,
95
- obsd_open,
96
- obsd_close,
95
+ netbsd_get_device_list,
96
+ NULL, /* hotplug_poll */
97
+ netbsd_open,
98
+ netbsd_close,
97
99
 
98
- obsd_get_device_descriptor,
99
- obsd_get_active_config_descriptor,
100
- obsd_get_config_descriptor,
100
+ netbsd_get_device_descriptor,
101
+ netbsd_get_active_config_descriptor,
102
+ netbsd_get_config_descriptor,
103
+ NULL, /* get_config_descriptor_by_value() */
101
104
 
102
- obsd_get_configuration,
103
- obsd_set_configuration,
105
+ netbsd_get_configuration,
106
+ netbsd_set_configuration,
104
107
 
105
- obsd_claim_interface,
106
- obsd_release_interface,
108
+ netbsd_claim_interface,
109
+ netbsd_release_interface,
107
110
 
108
- obsd_set_interface_altsetting,
109
- obsd_clear_halt,
110
- obsd_reset_device,
111
+ netbsd_set_interface_altsetting,
112
+ netbsd_clear_halt,
113
+ netbsd_reset_device,
111
114
 
112
115
  NULL, /* kernel_driver_active() */
113
116
  NULL, /* detach_kernel_driver() */
114
117
  NULL, /* attach_kernel_driver() */
115
118
 
116
- obsd_destroy_device,
119
+ netbsd_destroy_device,
117
120
 
118
- obsd_submit_transfer,
119
- obsd_cancel_transfer,
120
- obsd_clear_transfer_priv,
121
+ netbsd_submit_transfer,
122
+ netbsd_cancel_transfer,
123
+ netbsd_clear_transfer_priv,
121
124
 
122
- obsd_handle_events,
125
+ netbsd_handle_events,
123
126
 
124
- obsd_clock_gettime,
127
+ netbsd_clock_gettime,
125
128
  sizeof(struct device_priv),
126
129
  sizeof(struct handle_priv),
127
130
  0, /* transfer_priv_size */
@@ -129,7 +132,7 @@ const struct usbi_os_backend openbsd_backend = {
129
132
  };
130
133
 
131
134
  int
132
- obsd_get_device_list(struct libusb_context * ctx,
135
+ netbsd_get_device_list(struct libusb_context * ctx,
133
136
  struct discovered_devs **discdevs)
134
137
  {
135
138
  struct libusb_device *dev;
@@ -158,7 +161,9 @@ obsd_get_device_list(struct libusb_context * ctx,
158
161
  session_id = (di.udi_bus << 8 | di.udi_addr);
159
162
  dev = usbi_get_device_by_session_id(ctx, session_id);
160
163
 
161
- if (dev == NULL) {
164
+ if (dev) {
165
+ dev = libusb_ref_device(dev);
166
+ } else {
162
167
  dev = usbi_alloc_device(ctx, session_id);
163
168
  if (dev == NULL)
164
169
  return (LIBUSB_ERROR_NO_MEM);
@@ -189,6 +194,8 @@ obsd_get_device_list(struct libusb_context * ctx,
189
194
 
190
195
  if (discovered_devs_append(*discdevs, dev) == NULL)
191
196
  return (LIBUSB_ERROR_NO_MEM);
197
+
198
+ libusb_unref_device(dev);
192
199
  }
193
200
 
194
201
  return (LIBUSB_SUCCESS);
@@ -200,7 +207,7 @@ error:
200
207
  }
201
208
 
202
209
  int
203
- obsd_open(struct libusb_device_handle *handle)
210
+ netbsd_open(struct libusb_device_handle *handle)
204
211
  {
205
212
  struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
206
213
  struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
@@ -221,7 +228,7 @@ obsd_open(struct libusb_device_handle *handle)
221
228
  }
222
229
 
223
230
  void
224
- obsd_close(struct libusb_device_handle *handle)
231
+ netbsd_close(struct libusb_device_handle *handle)
225
232
  {
226
233
  struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
227
234
  struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
@@ -238,7 +245,7 @@ obsd_close(struct libusb_device_handle *handle)
238
245
  }
239
246
 
240
247
  int
241
- obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
248
+ netbsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
242
249
  int *host_endian)
243
250
  {
244
251
  struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
@@ -253,7 +260,7 @@ obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
253
260
  }
254
261
 
255
262
  int
256
- obsd_get_active_config_descriptor(struct libusb_device *dev,
263
+ netbsd_get_active_config_descriptor(struct libusb_device *dev,
257
264
  unsigned char *buf, size_t len, int *host_endian)
258
265
  {
259
266
  struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
@@ -268,11 +275,11 @@ obsd_get_active_config_descriptor(struct libusb_device *dev,
268
275
 
269
276
  *host_endian = 0;
270
277
 
271
- return (LIBUSB_SUCCESS);
278
+ return len;
272
279
  }
273
280
 
274
281
  int
275
- obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
282
+ netbsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
276
283
  unsigned char *buf, size_t len, int *host_endian)
277
284
  {
278
285
  struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
@@ -306,11 +313,11 @@ obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
306
313
 
307
314
  *host_endian = 0;
308
315
 
309
- return (LIBUSB_SUCCESS);
316
+ return len;
310
317
  }
311
318
 
312
319
  int
313
- obsd_get_configuration(struct libusb_device_handle *handle, int *config)
320
+ netbsd_get_configuration(struct libusb_device_handle *handle, int *config)
314
321
  {
315
322
  struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
316
323
 
@@ -325,7 +332,7 @@ obsd_get_configuration(struct libusb_device_handle *handle, int *config)
325
332
  }
326
333
 
327
334
  int
328
- obsd_set_configuration(struct libusb_device_handle *handle, int config)
335
+ netbsd_set_configuration(struct libusb_device_handle *handle, int config)
329
336
  {
330
337
  struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
331
338
 
@@ -338,7 +345,7 @@ obsd_set_configuration(struct libusb_device_handle *handle, int config)
338
345
  }
339
346
 
340
347
  int
341
- obsd_claim_interface(struct libusb_device_handle *handle, int iface)
348
+ netbsd_claim_interface(struct libusb_device_handle *handle, int iface)
342
349
  {
343
350
  struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
344
351
  int i;
@@ -350,7 +357,7 @@ obsd_claim_interface(struct libusb_device_handle *handle, int iface)
350
357
  }
351
358
 
352
359
  int
353
- obsd_release_interface(struct libusb_device_handle *handle, int iface)
360
+ netbsd_release_interface(struct libusb_device_handle *handle, int iface)
354
361
  {
355
362
  struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
356
363
  int i;
@@ -363,7 +370,7 @@ obsd_release_interface(struct libusb_device_handle *handle, int iface)
363
370
  }
364
371
 
365
372
  int
366
- obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
373
+ netbsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
367
374
  int altsetting)
368
375
  {
369
376
  struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
@@ -383,7 +390,7 @@ obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
383
390
  }
384
391
 
385
392
  int
386
- obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
393
+ netbsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
387
394
  {
388
395
  struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
389
396
  struct usb_ctl_request req;
@@ -403,7 +410,7 @@ obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
403
410
  }
404
411
 
405
412
  int
406
- obsd_reset_device(struct libusb_device_handle *handle)
413
+ netbsd_reset_device(struct libusb_device_handle *handle)
407
414
  {
408
415
  usbi_dbg("");
409
416
 
@@ -411,7 +418,7 @@ obsd_reset_device(struct libusb_device_handle *handle)
411
418
  }
412
419
 
413
420
  void
414
- obsd_destroy_device(struct libusb_device *dev)
421
+ netbsd_destroy_device(struct libusb_device *dev)
415
422
  {
416
423
  struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
417
424
 
@@ -421,7 +428,7 @@ obsd_destroy_device(struct libusb_device *dev)
421
428
  }
422
429
 
423
430
  int
424
- obsd_submit_transfer(struct usbi_transfer *itransfer)
431
+ netbsd_submit_transfer(struct usbi_transfer *itransfer)
425
432
  {
426
433
  struct libusb_transfer *transfer;
427
434
  struct handle_priv *hpriv;
@@ -465,7 +472,7 @@ obsd_submit_transfer(struct usbi_transfer *itransfer)
465
472
  }
466
473
 
467
474
  int
468
- obsd_cancel_transfer(struct usbi_transfer *itransfer)
475
+ netbsd_cancel_transfer(struct usbi_transfer *itransfer)
469
476
  {
470
477
  usbi_dbg("");
471
478
 
@@ -473,7 +480,7 @@ obsd_cancel_transfer(struct usbi_transfer *itransfer)
473
480
  }
474
481
 
475
482
  void
476
- obsd_clear_transfer_priv(struct usbi_transfer *itransfer)
483
+ netbsd_clear_transfer_priv(struct usbi_transfer *itransfer)
477
484
  {
478
485
  usbi_dbg("");
479
486
 
@@ -481,7 +488,7 @@ obsd_clear_transfer_priv(struct usbi_transfer *itransfer)
481
488
  }
482
489
 
483
490
  int
484
- obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
491
+ netbsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
485
492
  int num_ready)
486
493
  {
487
494
  struct libusb_device_handle *handle;
@@ -541,7 +548,7 @@ obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
541
548
  }
542
549
 
543
550
  int
544
- obsd_clock_gettime(int clkid, struct timespec *tp)
551
+ netbsd_clock_gettime(int clkid, struct timespec *tp)
545
552
  {
546
553
  usbi_dbg("clock %d", clkid);
547
554
 
@@ -0,0 +1,823 @@
1
+ /*
2
+ * Copyright © 2011-2013 Martin Pieuchot <mpi@openbsd.org>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2.1 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ */
18
+
19
+ #include <sys/time.h>
20
+ #include <sys/types.h>
21
+
22
+ #include <errno.h>
23
+ #include <fcntl.h>
24
+ #include <stdio.h>
25
+ #include <stdlib.h>
26
+ #include <string.h>
27
+ #include <unistd.h>
28
+
29
+ #include <dev/usb/usb.h>
30
+
31
+ #include "libusb.h"
32
+ #include "libusbi.h"
33
+
34
+ struct device_priv {
35
+ char *devname; /* name of the ugen(4) node */
36
+ int fd; /* device file descriptor */
37
+
38
+ unsigned char *cdesc; /* active config descriptor */
39
+ usb_device_descriptor_t ddesc; /* usb device descriptor */
40
+ };
41
+
42
+ struct handle_priv {
43
+ int pipe[2]; /* for event notification */
44
+ int endpoints[USB_MAX_ENDPOINTS];
45
+ };
46
+
47
+ /*
48
+ * Backend functions
49
+ */
50
+ static int obsd_get_device_list(struct libusb_context *,
51
+ struct discovered_devs **);
52
+ static int obsd_open(struct libusb_device_handle *);
53
+ static void obsd_close(struct libusb_device_handle *);
54
+
55
+ static int obsd_get_device_descriptor(struct libusb_device *, unsigned char *,
56
+ int *);
57
+ static int obsd_get_active_config_descriptor(struct libusb_device *,
58
+ unsigned char *, size_t, int *);
59
+ static int obsd_get_config_descriptor(struct libusb_device *, uint8_t,
60
+ unsigned char *, size_t, int *);
61
+
62
+ static int obsd_get_configuration(struct libusb_device_handle *, int *);
63
+ static int obsd_set_configuration(struct libusb_device_handle *, int);
64
+
65
+ static int obsd_claim_interface(struct libusb_device_handle *, int);
66
+ static int obsd_release_interface(struct libusb_device_handle *, int);
67
+
68
+ static int obsd_set_interface_altsetting(struct libusb_device_handle *, int,
69
+ int);
70
+ static int obsd_clear_halt(struct libusb_device_handle *, unsigned char);
71
+ static int obsd_reset_device(struct libusb_device_handle *);
72
+ static void obsd_destroy_device(struct libusb_device *);
73
+
74
+ static int obsd_submit_transfer(struct usbi_transfer *);
75
+ static int obsd_cancel_transfer(struct usbi_transfer *);
76
+ static void obsd_clear_transfer_priv(struct usbi_transfer *);
77
+ static int obsd_handle_events(struct libusb_context *ctx, struct pollfd *,
78
+ nfds_t, int);
79
+ static int obsd_clock_gettime(int, struct timespec *);
80
+
81
+ /*
82
+ * Private functions
83
+ */
84
+ static int _errno_to_libusb(int);
85
+ static int _cache_active_config_descriptor(struct libusb_device *);
86
+ static int _sync_control_transfer(struct usbi_transfer *);
87
+ static int _sync_gen_transfer(struct usbi_transfer *);
88
+ static int _access_endpoint(struct libusb_transfer *);
89
+
90
+ static int _bus_open(int);
91
+
92
+
93
+ const struct usbi_os_backend openbsd_backend = {
94
+ "Synchronous OpenBSD backend",
95
+ 0,
96
+ NULL, /* init() */
97
+ NULL, /* exit() */
98
+ obsd_get_device_list,
99
+ NULL, /* hotplug_poll */
100
+ obsd_open,
101
+ obsd_close,
102
+
103
+ obsd_get_device_descriptor,
104
+ obsd_get_active_config_descriptor,
105
+ obsd_get_config_descriptor,
106
+ NULL, /* get_config_descriptor_by_value() */
107
+
108
+ obsd_get_configuration,
109
+ obsd_set_configuration,
110
+
111
+ obsd_claim_interface,
112
+ obsd_release_interface,
113
+
114
+ obsd_set_interface_altsetting,
115
+ obsd_clear_halt,
116
+ obsd_reset_device,
117
+
118
+ NULL, /* kernel_driver_active() */
119
+ NULL, /* detach_kernel_driver() */
120
+ NULL, /* attach_kernel_driver() */
121
+
122
+ obsd_destroy_device,
123
+
124
+ obsd_submit_transfer,
125
+ obsd_cancel_transfer,
126
+ obsd_clear_transfer_priv,
127
+
128
+ obsd_handle_events,
129
+
130
+ obsd_clock_gettime,
131
+ sizeof(struct device_priv),
132
+ sizeof(struct handle_priv),
133
+ 0, /* transfer_priv_size */
134
+ 0, /* add_iso_packet_size */
135
+ };
136
+
137
+ #define DEVPATH "/dev/"
138
+ #define USBDEV DEVPATH "usb"
139
+
140
+ int
141
+ obsd_get_device_list(struct libusb_context * ctx,
142
+ struct discovered_devs **discdevs)
143
+ {
144
+ struct discovered_devs *ddd;
145
+ struct libusb_device *dev;
146
+ struct device_priv *dpriv;
147
+ struct usb_device_info di;
148
+ struct usb_device_ddesc dd;
149
+ unsigned long session_id;
150
+ char devices[USB_MAX_DEVICES];
151
+ char busnode[16];
152
+ char *udevname;
153
+ int fd, addr, i, j;
154
+
155
+ usbi_dbg("");
156
+
157
+ for (i = 0; i < 8; i++) {
158
+ snprintf(busnode, sizeof(busnode), USBDEV "%d", i);
159
+
160
+ if ((fd = open(busnode, O_RDWR)) < 0) {
161
+ if (errno != ENOENT && errno != ENXIO)
162
+ usbi_err(ctx, "could not open %s", busnode);
163
+ continue;
164
+ }
165
+
166
+ bzero(devices, sizeof(devices));
167
+ for (addr = 1; addr < USB_MAX_DEVICES; addr++) {
168
+ if (devices[addr])
169
+ continue;
170
+
171
+ di.udi_addr = addr;
172
+ if (ioctl(fd, USB_DEVICEINFO, &di) < 0)
173
+ continue;
174
+
175
+ /*
176
+ * XXX If ugen(4) is attached to the USB device
177
+ * it will be used.
178
+ */
179
+ udevname = NULL;
180
+ for (j = 0; j < USB_MAX_DEVNAMES; j++)
181
+ if (!strncmp("ugen", di.udi_devnames[j], 4)) {
182
+ udevname = strdup(di.udi_devnames[j]);
183
+ break;
184
+ }
185
+
186
+ session_id = (di.udi_bus << 8 | di.udi_addr);
187
+ dev = usbi_get_device_by_session_id(ctx, session_id);
188
+
189
+ if (dev == NULL) {
190
+ dev = usbi_alloc_device(ctx, session_id);
191
+ if (dev == NULL) {
192
+ close(fd);
193
+ return (LIBUSB_ERROR_NO_MEM);
194
+ }
195
+
196
+ dev->bus_number = di.udi_bus;
197
+ dev->device_address = di.udi_addr;
198
+ dev->speed = di.udi_speed;
199
+
200
+ dpriv = (struct device_priv *)dev->os_priv;
201
+ dpriv->fd = -1;
202
+ dpriv->cdesc = NULL;
203
+ dpriv->devname = udevname;
204
+
205
+ dd.udd_bus = di.udi_bus;
206
+ dd.udd_addr = di.udi_addr;
207
+ if (ioctl(fd, USB_DEVICE_GET_DDESC, &dd) < 0) {
208
+ libusb_unref_device(dev);
209
+ continue;
210
+ }
211
+ dpriv->ddesc = dd.udd_desc;
212
+
213
+ if (_cache_active_config_descriptor(dev)) {
214
+ libusb_unref_device(dev);
215
+ continue;
216
+ }
217
+
218
+ if (usbi_sanitize_device(dev))
219
+ libusb_unref_device(dev);
220
+ }
221
+
222
+ ddd = discovered_devs_append(*discdevs, dev);
223
+ if (ddd == NULL) {
224
+ close(fd);
225
+ return (LIBUSB_ERROR_NO_MEM);
226
+ }
227
+
228
+ *discdevs = ddd;
229
+ devices[addr] = 1;
230
+ }
231
+
232
+ close(fd);
233
+ }
234
+
235
+ return (LIBUSB_SUCCESS);
236
+ }
237
+
238
+ int
239
+ obsd_open(struct libusb_device_handle *handle)
240
+ {
241
+ struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
242
+ struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
243
+ char devnode[16];
244
+
245
+ if (dpriv->devname) {
246
+ /*
247
+ * Only open ugen(4) attached devices read-write, all
248
+ * read-only operations are done through the bus node.
249
+ */
250
+ snprintf(devnode, sizeof(devnode), DEVPATH "%s.00",
251
+ dpriv->devname);
252
+ dpriv->fd = open(devnode, O_RDWR);
253
+ if (dpriv->fd < 0)
254
+ return _errno_to_libusb(errno);
255
+
256
+ usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
257
+ }
258
+
259
+ if (pipe(hpriv->pipe) < 0)
260
+ return _errno_to_libusb(errno);
261
+
262
+ return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->pipe[0], POLLIN);
263
+ }
264
+
265
+ void
266
+ obsd_close(struct libusb_device_handle *handle)
267
+ {
268
+ struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
269
+ struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
270
+
271
+ if (dpriv->devname) {
272
+ usbi_dbg("close: fd %d", dpriv->fd);
273
+
274
+ close(dpriv->fd);
275
+ dpriv->fd = -1;
276
+ }
277
+
278
+ usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
279
+
280
+ close(hpriv->pipe[0]);
281
+ close(hpriv->pipe[1]);
282
+ }
283
+
284
+ int
285
+ obsd_get_device_descriptor(struct libusb_device *dev, unsigned char *buf,
286
+ int *host_endian)
287
+ {
288
+ struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
289
+
290
+ usbi_dbg("");
291
+
292
+ memcpy(buf, &dpriv->ddesc, DEVICE_DESC_LENGTH);
293
+
294
+ *host_endian = 0;
295
+
296
+ return (LIBUSB_SUCCESS);
297
+ }
298
+
299
+ int
300
+ obsd_get_active_config_descriptor(struct libusb_device *dev,
301
+ unsigned char *buf, size_t len, int *host_endian)
302
+ {
303
+ struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
304
+ usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc;
305
+
306
+ len = MIN(len, UGETW(ucd->wTotalLength));
307
+
308
+ usbi_dbg("len %d", len);
309
+
310
+ memcpy(buf, dpriv->cdesc, len);
311
+
312
+ *host_endian = 0;
313
+
314
+ return (len);
315
+ }
316
+
317
+ int
318
+ obsd_get_config_descriptor(struct libusb_device *dev, uint8_t idx,
319
+ unsigned char *buf, size_t len, int *host_endian)
320
+ {
321
+ struct usb_device_fdesc udf;
322
+ int fd, err;
323
+
324
+ if ((fd = _bus_open(dev->bus_number)) < 0)
325
+ return _errno_to_libusb(errno);
326
+
327
+ udf.udf_bus = dev->bus_number;
328
+ udf.udf_addr = dev->device_address;
329
+ udf.udf_config_index = idx;
330
+ udf.udf_size = len;
331
+ udf.udf_data = buf;
332
+
333
+ usbi_dbg("index %d, len %d", udf.udf_config_index, len);
334
+
335
+ if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
336
+ err = errno;
337
+ close(fd);
338
+ return _errno_to_libusb(err);
339
+ }
340
+ close(fd);
341
+
342
+ *host_endian = 0;
343
+
344
+ return (len);
345
+ }
346
+
347
+ int
348
+ obsd_get_configuration(struct libusb_device_handle *handle, int *config)
349
+ {
350
+ struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
351
+ usb_config_descriptor_t *ucd = (usb_config_descriptor_t *)dpriv->cdesc;
352
+
353
+ *config = ucd->bConfigurationValue;
354
+
355
+ usbi_dbg("bConfigurationValue %d", *config);
356
+
357
+ return (LIBUSB_SUCCESS);
358
+ }
359
+
360
+ int
361
+ obsd_set_configuration(struct libusb_device_handle *handle, int config)
362
+ {
363
+ struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
364
+
365
+ if (dpriv->devname == NULL)
366
+ return (LIBUSB_ERROR_NOT_SUPPORTED);
367
+
368
+ usbi_dbg("bConfigurationValue %d", config);
369
+
370
+ if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
371
+ return _errno_to_libusb(errno);
372
+
373
+ return _cache_active_config_descriptor(handle->dev);
374
+ }
375
+
376
+ int
377
+ obsd_claim_interface(struct libusb_device_handle *handle, int iface)
378
+ {
379
+ struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
380
+ int i;
381
+
382
+ for (i = 0; i < USB_MAX_ENDPOINTS; i++)
383
+ hpriv->endpoints[i] = -1;
384
+
385
+ return (LIBUSB_SUCCESS);
386
+ }
387
+
388
+ int
389
+ obsd_release_interface(struct libusb_device_handle *handle, int iface)
390
+ {
391
+ struct handle_priv *hpriv = (struct handle_priv *)handle->os_priv;
392
+ int i;
393
+
394
+ for (i = 0; i < USB_MAX_ENDPOINTS; i++)
395
+ if (hpriv->endpoints[i] >= 0)
396
+ close(hpriv->endpoints[i]);
397
+
398
+ return (LIBUSB_SUCCESS);
399
+ }
400
+
401
+ int
402
+ obsd_set_interface_altsetting(struct libusb_device_handle *handle, int iface,
403
+ int altsetting)
404
+ {
405
+ struct device_priv *dpriv = (struct device_priv *)handle->dev->os_priv;
406
+ struct usb_alt_interface intf;
407
+
408
+ if (dpriv->devname == NULL)
409
+ return (LIBUSB_ERROR_NOT_SUPPORTED);
410
+
411
+ usbi_dbg("iface %d, setting %d", iface, altsetting);
412
+
413
+ memset(&intf, 0, sizeof(intf));
414
+
415
+ intf.uai_interface_index = iface;
416
+ intf.uai_alt_no = altsetting;
417
+
418
+ if (ioctl(dpriv->fd, USB_SET_ALTINTERFACE, &intf) < 0)
419
+ return _errno_to_libusb(errno);
420
+
421
+ return (LIBUSB_SUCCESS);
422
+ }
423
+
424
+ int
425
+ obsd_clear_halt(struct libusb_device_handle *handle, unsigned char endpoint)
426
+ {
427
+ struct usb_ctl_request req;
428
+ int fd, err;
429
+
430
+ if ((fd = _bus_open(handle->dev->bus_number)) < 0)
431
+ return _errno_to_libusb(errno);
432
+
433
+ usbi_dbg("");
434
+
435
+ req.ucr_addr = handle->dev->device_address;
436
+ req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
437
+ req.ucr_request.bRequest = UR_CLEAR_FEATURE;
438
+ USETW(req.ucr_request.wValue, UF_ENDPOINT_HALT);
439
+ USETW(req.ucr_request.wIndex, endpoint);
440
+ USETW(req.ucr_request.wLength, 0);
441
+
442
+ if (ioctl(fd, USB_REQUEST, &req) < 0) {
443
+ err = errno;
444
+ close(fd);
445
+ return _errno_to_libusb(err);
446
+ }
447
+ close(fd);
448
+
449
+ return (LIBUSB_SUCCESS);
450
+ }
451
+
452
+ int
453
+ obsd_reset_device(struct libusb_device_handle *handle)
454
+ {
455
+ usbi_dbg("");
456
+
457
+ return (LIBUSB_ERROR_NOT_SUPPORTED);
458
+ }
459
+
460
+ void
461
+ obsd_destroy_device(struct libusb_device *dev)
462
+ {
463
+ struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
464
+
465
+ usbi_dbg("");
466
+
467
+ free(dpriv->cdesc);
468
+ free(dpriv->devname);
469
+ }
470
+
471
+ int
472
+ obsd_submit_transfer(struct usbi_transfer *itransfer)
473
+ {
474
+ struct libusb_transfer *transfer;
475
+ struct handle_priv *hpriv;
476
+ int err = 0;
477
+
478
+ usbi_dbg("");
479
+
480
+ transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
481
+ hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
482
+
483
+ switch (transfer->type) {
484
+ case LIBUSB_TRANSFER_TYPE_CONTROL:
485
+ err = _sync_control_transfer(itransfer);
486
+ break;
487
+ case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
488
+ if (IS_XFEROUT(transfer)) {
489
+ /* Isochronous write is not supported */
490
+ err = LIBUSB_ERROR_NOT_SUPPORTED;
491
+ break;
492
+ }
493
+ err = _sync_gen_transfer(itransfer);
494
+ break;
495
+ case LIBUSB_TRANSFER_TYPE_BULK:
496
+ case LIBUSB_TRANSFER_TYPE_INTERRUPT:
497
+ if (IS_XFEROUT(transfer) &&
498
+ transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
499
+ err = LIBUSB_ERROR_NOT_SUPPORTED;
500
+ break;
501
+ }
502
+ err = _sync_gen_transfer(itransfer);
503
+ break;
504
+ }
505
+
506
+ if (err)
507
+ return (err);
508
+
509
+ if (write(hpriv->pipe[1], &itransfer, sizeof(itransfer)) < 0)
510
+ return _errno_to_libusb(errno);
511
+
512
+ return (LIBUSB_SUCCESS);
513
+ }
514
+
515
+ int
516
+ obsd_cancel_transfer(struct usbi_transfer *itransfer)
517
+ {
518
+ usbi_dbg("");
519
+
520
+ return (LIBUSB_ERROR_NOT_SUPPORTED);
521
+ }
522
+
523
+ void
524
+ obsd_clear_transfer_priv(struct usbi_transfer *itransfer)
525
+ {
526
+ usbi_dbg("");
527
+
528
+ /* Nothing to do */
529
+ }
530
+
531
+ int
532
+ obsd_handle_events(struct libusb_context *ctx, struct pollfd *fds, nfds_t nfds,
533
+ int num_ready)
534
+ {
535
+ struct libusb_device_handle *handle;
536
+ struct handle_priv *hpriv = NULL;
537
+ struct usbi_transfer *itransfer;
538
+ struct pollfd *pollfd;
539
+ int i, err = 0;
540
+
541
+ usbi_dbg("");
542
+
543
+ pthread_mutex_lock(&ctx->open_devs_lock);
544
+ for (i = 0; i < nfds && num_ready > 0; i++) {
545
+ pollfd = &fds[i];
546
+
547
+ if (!pollfd->revents)
548
+ continue;
549
+
550
+ hpriv = NULL;
551
+ num_ready--;
552
+ list_for_each_entry(handle, &ctx->open_devs, list,
553
+ struct libusb_device_handle) {
554
+ hpriv = (struct handle_priv *)handle->os_priv;
555
+
556
+ if (hpriv->pipe[0] == pollfd->fd)
557
+ break;
558
+
559
+ hpriv = NULL;
560
+ }
561
+
562
+ if (NULL == hpriv) {
563
+ usbi_dbg("fd %d is not an event pipe!", pollfd->fd);
564
+ err = ENOENT;
565
+ break;
566
+ }
567
+
568
+ if (pollfd->revents & POLLERR) {
569
+ usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->pipe[0]);
570
+ usbi_handle_disconnect(handle);
571
+ continue;
572
+ }
573
+
574
+ if (read(hpriv->pipe[0], &itransfer, sizeof(itransfer)) < 0) {
575
+ err = errno;
576
+ break;
577
+ }
578
+
579
+ if ((err = usbi_handle_transfer_completion(itransfer,
580
+ LIBUSB_TRANSFER_COMPLETED)))
581
+ break;
582
+ }
583
+ pthread_mutex_unlock(&ctx->open_devs_lock);
584
+
585
+ if (err)
586
+ return _errno_to_libusb(err);
587
+
588
+ return (LIBUSB_SUCCESS);
589
+ }
590
+
591
+ int
592
+ obsd_clock_gettime(int clkid, struct timespec *tp)
593
+ {
594
+ usbi_dbg("clock %d", clkid);
595
+
596
+ if (clkid == USBI_CLOCK_REALTIME)
597
+ return clock_gettime(CLOCK_REALTIME, tp);
598
+
599
+ if (clkid == USBI_CLOCK_MONOTONIC)
600
+ return clock_gettime(CLOCK_MONOTONIC, tp);
601
+
602
+ return (LIBUSB_ERROR_INVALID_PARAM);
603
+ }
604
+
605
+ int
606
+ _errno_to_libusb(int err)
607
+ {
608
+ usbi_dbg("error: %s (%d)", strerror(err), err);
609
+
610
+ switch (err) {
611
+ case EIO:
612
+ return (LIBUSB_ERROR_IO);
613
+ case EACCES:
614
+ return (LIBUSB_ERROR_ACCESS);
615
+ case ENOENT:
616
+ return (LIBUSB_ERROR_NO_DEVICE);
617
+ case ENOMEM:
618
+ return (LIBUSB_ERROR_NO_MEM);
619
+ case ETIMEDOUT:
620
+ return (LIBUSB_ERROR_TIMEOUT);
621
+ }
622
+
623
+ return (LIBUSB_ERROR_OTHER);
624
+ }
625
+
626
+ int
627
+ _cache_active_config_descriptor(struct libusb_device *dev)
628
+ {
629
+ struct device_priv *dpriv = (struct device_priv *)dev->os_priv;
630
+ struct usb_device_cdesc udc;
631
+ struct usb_device_fdesc udf;
632
+ unsigned char* buf;
633
+ int fd, len, err;
634
+
635
+ if ((fd = _bus_open(dev->bus_number)) < 0)
636
+ return _errno_to_libusb(errno);
637
+
638
+ usbi_dbg("fd %d, addr %d", fd, dev->device_address);
639
+
640
+ udc.udc_bus = dev->bus_number;
641
+ udc.udc_addr = dev->device_address;
642
+ udc.udc_config_index = USB_CURRENT_CONFIG_INDEX;
643
+ if (ioctl(fd, USB_DEVICE_GET_CDESC, &udc) < 0) {
644
+ err = errno;
645
+ close(fd);
646
+ return _errno_to_libusb(errno);
647
+ }
648
+
649
+ usbi_dbg("active bLength %d", udc.udc_desc.bLength);
650
+
651
+ len = UGETW(udc.udc_desc.wTotalLength);
652
+ buf = malloc(len);
653
+ if (buf == NULL)
654
+ return (LIBUSB_ERROR_NO_MEM);
655
+
656
+ udf.udf_bus = dev->bus_number;
657
+ udf.udf_addr = dev->device_address;
658
+ udf.udf_config_index = udc.udc_config_index;
659
+ udf.udf_size = len;
660
+ udf.udf_data = buf;
661
+
662
+ usbi_dbg("index %d, len %d", udf.udf_config_index, len);
663
+
664
+ if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
665
+ err = errno;
666
+ close(fd);
667
+ free(buf);
668
+ return _errno_to_libusb(err);
669
+ }
670
+ close(fd);
671
+
672
+ if (dpriv->cdesc)
673
+ free(dpriv->cdesc);
674
+ dpriv->cdesc = buf;
675
+
676
+ return (LIBUSB_SUCCESS);
677
+ }
678
+
679
+ int
680
+ _sync_control_transfer(struct usbi_transfer *itransfer)
681
+ {
682
+ struct libusb_transfer *transfer;
683
+ struct libusb_control_setup *setup;
684
+ struct device_priv *dpriv;
685
+ struct usb_ctl_request req;
686
+
687
+ transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
688
+ dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
689
+ setup = (struct libusb_control_setup *)transfer->buffer;
690
+
691
+ usbi_dbg("type %x request %x value %x index %d length %d timeout %d",
692
+ setup->bmRequestType, setup->bRequest,
693
+ libusb_le16_to_cpu(setup->wValue),
694
+ libusb_le16_to_cpu(setup->wIndex),
695
+ libusb_le16_to_cpu(setup->wLength), transfer->timeout);
696
+
697
+ req.ucr_addr = transfer->dev_handle->dev->device_address;
698
+ req.ucr_request.bmRequestType = setup->bmRequestType;
699
+ req.ucr_request.bRequest = setup->bRequest;
700
+ /* Don't use USETW, libusbx already deals with the endianness */
701
+ (*(uint16_t *)req.ucr_request.wValue) = setup->wValue;
702
+ (*(uint16_t *)req.ucr_request.wIndex) = setup->wIndex;
703
+ (*(uint16_t *)req.ucr_request.wLength) = setup->wLength;
704
+ req.ucr_data = transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE;
705
+
706
+ if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
707
+ req.ucr_flags = USBD_SHORT_XFER_OK;
708
+
709
+ if (dpriv->devname == NULL) {
710
+ /*
711
+ * XXX If the device is not attached to ugen(4) it is
712
+ * XXX still possible to submit a control transfer but
713
+ * XXX with the default timeout only.
714
+ */
715
+ int fd, err;
716
+
717
+ if ((fd = _bus_open(transfer->dev_handle->dev->bus_number)) < 0)
718
+ return _errno_to_libusb(errno);
719
+
720
+ if ((ioctl(fd, USB_REQUEST, &req)) < 0) {
721
+ err = errno;
722
+ close(fd);
723
+ return _errno_to_libusb(err);
724
+ }
725
+ close(fd);
726
+ } else {
727
+ if ((ioctl(dpriv->fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
728
+ return _errno_to_libusb(errno);
729
+
730
+ if ((ioctl(dpriv->fd, USB_DO_REQUEST, &req)) < 0)
731
+ return _errno_to_libusb(errno);
732
+ }
733
+
734
+ itransfer->transferred = req.ucr_actlen;
735
+
736
+ usbi_dbg("transferred %d", itransfer->transferred);
737
+
738
+ return (0);
739
+ }
740
+
741
+ int
742
+ _access_endpoint(struct libusb_transfer *transfer)
743
+ {
744
+ struct handle_priv *hpriv;
745
+ struct device_priv *dpriv;
746
+ char devnode[16];
747
+ int fd, endpt;
748
+ mode_t mode;
749
+
750
+ hpriv = (struct handle_priv *)transfer->dev_handle->os_priv;
751
+ dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
752
+
753
+ endpt = UE_GET_ADDR(transfer->endpoint);
754
+ mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY;
755
+
756
+ usbi_dbg("endpoint %d mode %d", endpt, mode);
757
+
758
+ if (hpriv->endpoints[endpt] < 0) {
759
+ /* Pick the right endpoint node */
760
+ snprintf(devnode, sizeof(devnode), DEVPATH "%s.%02d",
761
+ dpriv->devname, endpt);
762
+
763
+ /* We may need to read/write to the same endpoint later. */
764
+ if (((fd = open(devnode, O_RDWR)) < 0) && (errno == ENXIO))
765
+ if ((fd = open(devnode, mode)) < 0)
766
+ return (-1);
767
+
768
+ hpriv->endpoints[endpt] = fd;
769
+ }
770
+
771
+ return (hpriv->endpoints[endpt]);
772
+ }
773
+
774
+ int
775
+ _sync_gen_transfer(struct usbi_transfer *itransfer)
776
+ {
777
+ struct libusb_transfer *transfer;
778
+ struct device_priv *dpriv;
779
+ int fd, nr = 1;
780
+
781
+ transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
782
+ dpriv = (struct device_priv *)transfer->dev_handle->dev->os_priv;
783
+
784
+ if (dpriv->devname == NULL)
785
+ return (LIBUSB_ERROR_NOT_SUPPORTED);
786
+
787
+ /*
788
+ * Bulk, Interrupt or Isochronous transfer depends on the
789
+ * endpoint and thus the node to open.
790
+ */
791
+ if ((fd = _access_endpoint(transfer)) < 0)
792
+ return _errno_to_libusb(errno);
793
+
794
+ if ((ioctl(fd, USB_SET_TIMEOUT, &transfer->timeout)) < 0)
795
+ return _errno_to_libusb(errno);
796
+
797
+ if (IS_XFERIN(transfer)) {
798
+ if ((transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) == 0)
799
+ if ((ioctl(fd, USB_SET_SHORT_XFER, &nr)) < 0)
800
+ return _errno_to_libusb(errno);
801
+
802
+ nr = read(fd, transfer->buffer, transfer->length);
803
+ } else {
804
+ nr = write(fd, transfer->buffer, transfer->length);
805
+ }
806
+
807
+ if (nr < 0)
808
+ return _errno_to_libusb(errno);
809
+
810
+ itransfer->transferred = nr;
811
+
812
+ return (0);
813
+ }
814
+
815
+ int
816
+ _bus_open(int number)
817
+ {
818
+ char busnode[16];
819
+
820
+ snprintf(busnode, sizeof(busnode), USBDEV "%d", number);
821
+
822
+ return open(busnode, O_RDWR);
823
+ }