OpenSDE Packages Database (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.3 KiB

  1. # --- T2-COPYRIGHT-NOTE-BEGIN ---
  2. # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  3. #
  4. # T2 SDE: package/.../libusb/speedup-v2.patch
  5. # Copyright (C) 2006 The T2 SDE Project
  6. #
  7. # More information can be found in the files COPYING and README.
  8. #
  9. # This patch file is dual-licensed. It is available under the license the
  10. # patched project is licensed under, as long as it is an OpenSource license
  11. # as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
  12. # of the GNU General Public License as published by the Free Software
  13. # Foundation; either version 2 of the License, or (at your option) any later
  14. # version.
  15. # --- T2-COPYRIGHT-NOTE-END ---
  16. 2x speedup for the SANE/Avision driver.
  17. - Rene Rebe <rene@exactcode.de>
  18. --- libusb-0.1.11/linux.c 2006-03-02 15:33:58.000000000 +0000
  19. +++ libusb-0.1.11-improved/linux.c 2006-03-03 08:26:55.000000000 +0000
  20. @@ -162,11 +162,14 @@
  21. static int usb_urb_transfer(usb_dev_handle *dev, int ep, int urbtype,
  22. char *bytes, int size, int timeout)
  23. {
  24. - struct usb_urb urb;
  25. + int nurbs;
  26. + struct usb_urb* urbs;
  27. unsigned int bytesdone = 0, requested;
  28. struct timeval tv, tv_ref, tv_now;
  29. struct usb_urb *context;
  30. - int ret, waiting;
  31. + int rc = 0, ret = 0, waiting, i;
  32. +
  33. + fd_set writefds;
  34. /*
  35. * HACK: The use of urb.usercontext is a hack to get threaded applications
  36. @@ -190,36 +193,47 @@
  37. tv_ref.tv_sec++;
  38. }
  39. - do {
  40. - fd_set writefds;
  41. + /* allocate and fill all URBs */
  42. + nurbs = (size + MAX_READ_WRITE - 1) / MAX_READ_WRITE;
  43. + //fprintf (stderr, "nurbs: %d\n", nurbs);
  44. + urbs = malloc (sizeof(struct usb_urb) * nurbs);
  45. + for (i = 0; i < nurbs; ++i) {
  46. - requested = size - bytesdone;
  47. + requested = size - i * MAX_READ_WRITE;
  48. if (requested > MAX_READ_WRITE)
  49. requested = MAX_READ_WRITE;
  50. - urb.type = urbtype;
  51. - urb.endpoint = ep;
  52. - urb.flags = 0;
  53. - urb.buffer = bytes + bytesdone;
  54. - urb.buffer_length = requested;
  55. - urb.signr = 0;
  56. - urb.actual_length = 0;
  57. - urb.number_of_packets = 0; /* don't do isochronous yet */
  58. - urb.usercontext = NULL;
  59. + urbs[i].type = urbtype;
  60. + urbs[i].endpoint = ep;
  61. + urbs[i].flags = 0;
  62. + urbs[i].buffer = bytes + i * MAX_READ_WRITE;
  63. + urbs[i].buffer_length = requested;
  64. + urbs[i].signr = 0;
  65. + urbs[i].actual_length = 0;
  66. + urbs[i].number_of_packets = 0; /* don't do isochronous yet */
  67. + urbs[i].usercontext = NULL;
  68. - ret = ioctl(dev->fd, IOCTL_USB_SUBMITURB, &urb);
  69. + //fprintf (stderr, "submitting urb %d\n", i);
  70. + ret = ioctl(dev->fd, IOCTL_USB_SUBMITURB, &urbs[i]);
  71. if (ret < 0) {
  72. USB_ERROR_STR(-errno, "error submitting URB: %s", strerror(errno));
  73. - return ret;
  74. + rc = ret;
  75. + goto end;
  76. }
  77. + }
  78. - FD_ZERO(&writefds);
  79. - FD_SET(dev->fd, &writefds);
  80. + FD_ZERO(&writefds);
  81. + FD_SET(dev->fd, &writefds);
  82. -restart:
  83. + /* wait 'till all URBs completed */
  84. + for (i = 0; i < nurbs; ) {
  85. waiting = 1;
  86. context = NULL;
  87. - while (!urb.usercontext && ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) {
  88. + //fprintf (stderr, "waiting for URB %d\n", i);
  89. +
  90. + while (!urbs[i].usercontext &&
  91. + ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) &&
  92. + waiting) {
  93. tv.tv_sec = 0;
  94. tv.tv_usec = 1000; // 1 msec
  95. select(dev->fd + 1, NULL, &writefds, NULL, &tv); //sub second wait
  96. @@ -229,52 +243,66 @@
  97. gettimeofday(&tv_now, NULL);
  98. if ((tv_now.tv_sec > tv_ref.tv_sec) ||
  99. - ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
  100. + ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
  101. waiting = 0;
  102. }
  103. }
  104. - if (context && context != &urb) {
  105. + /* mark done */
  106. + if (context) {
  107. + //fprintf (stderr, "marking URB %p done.\n", context);
  108. context->usercontext = URB_USERCONTEXT_COOKIE;
  109. - /* We need to restart since we got a successful URB, but not ours */
  110. - goto restart;
  111. +
  112. + /* is it ours? */
  113. + //if (context && context == &urbs[i])
  114. + //fprintf (stderr, "which was the one we have been waiting for.\n");
  115. }
  116. + /* done= */
  117. + if (urbs[i].usercontext) {
  118. + bytesdone += context->actual_length;
  119. + ++i; /* next URB */
  120. + continue;
  121. + }
  122. +
  123. + fprintf (stderr, "here, error?\n");
  124. +
  125. /*
  126. * If there was an error, that wasn't EAGAIN (no completion), then
  127. * something happened during the reaping and we should return that
  128. * error now
  129. */
  130. - if (ret < 0 && !urb.usercontext && errno != EAGAIN)
  131. + if (ret < 0 && !urbs[i].usercontext && errno != EAGAIN)
  132. USB_ERROR_STR(-errno, "error reaping URB: %s", strerror(errno));
  133. - bytesdone += urb.actual_length;
  134. - } while ((ret == 0 || urb.usercontext) && bytesdone < size && urb.actual_length == requested);
  135. + /* If the URB didn't complete in success or error, then let's unlink it */
  136. + if (ret < 0 && !urbs[i].usercontext) {
  137. - /* If the URB didn't complete in success or error, then let's unlink it */
  138. - if (ret < 0 && !urb.usercontext) {
  139. - int rc;
  140. + if (!waiting)
  141. + rc = -ETIMEDOUT;
  142. + else
  143. + rc = urbs[i].status;
  144. +
  145. + ret = ioctl(dev->fd, IOCTL_USB_DISCARDURB, &urbs[i]);
  146. + if (ret < 0 && errno != EINVAL && usb_debug >= 1)
  147. + fprintf(stderr, "error discarding URB: %s", strerror(errno));
  148. +
  149. + /*
  150. + * When the URB is unlinked, it gets moved to the completed list and
  151. + * then we need to reap it or else the next time we call this function,
  152. + * we'll get the previous completion and exit early
  153. + */
  154. + ioctl(dev->fd, IOCTL_USB_REAPURB, &context);
  155. - if (!waiting)
  156. - rc = -ETIMEDOUT;
  157. - else
  158. - rc = urb.status;
  159. -
  160. - ret = ioctl(dev->fd, IOCTL_USB_DISCARDURB, &urb);
  161. - if (ret < 0 && errno != EINVAL && usb_debug >= 1)
  162. - fprintf(stderr, "error discarding URB: %s", strerror(errno));
  163. -
  164. - /*
  165. - * When the URB is unlinked, it gets moved to the completed list and
  166. - * then we need to reap it or else the next time we call this function,
  167. - * we'll get the previous completion and exit early
  168. - */
  169. - ioctl(dev->fd, IOCTL_USB_REAPURB, &context);
  170. -
  171. - return rc;
  172. + goto end;
  173. + }
  174. }
  175. - return bytesdone;
  176. + rc = bytesdone;
  177. +
  178. + end:
  179. + free (urbs);
  180. + return rc;
  181. }
  182. int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,