Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f12f257dd1 |
13 changed files with 847 additions and 21 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/libusb-*.tar.bz2
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
From 1cc5b4a9fb984e83681ae5c797fa6b22bc20f809 Mon Sep 17 00:00:00 2001
|
||||
From: Ludovic Rousseau <ludovic.rousseau+github@gmail.com>
|
||||
Date: Fri, 16 Sep 2011 18:07:56 +0200
|
||||
Subject: [PATCH 01/40] Correctly handle LIBUSB_TRANSFER_OVERFLOW in
|
||||
libusb_control_transfer()
|
||||
|
||||
sync.c: In function `libusb_control_transfer':
|
||||
sync.c:122: warning: enumeration value `LIBUSB_TRANSFER_OVERFLOW' not
|
||||
handled in switch
|
||||
|
||||
Fixes #120.
|
||||
---
|
||||
libusb/sync.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/libusb/sync.c b/libusb/sync.c
|
||||
index d50413b..8eed47b 100644
|
||||
--- a/libusb/sync.c
|
||||
+++ b/libusb/sync.c
|
||||
@@ -132,6 +132,9 @@ int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
|
||||
case LIBUSB_TRANSFER_NO_DEVICE:
|
||||
r = LIBUSB_ERROR_NO_DEVICE;
|
||||
break;
|
||||
+ case LIBUSB_TRANSFER_OVERFLOW:
|
||||
+ r = LIBUSB_ERROR_OVERFLOW;
|
||||
+ break;
|
||||
default:
|
||||
usbi_warn(HANDLE_CTX(dev_handle),
|
||||
"unrecognised status code %d", transfer->status);
|
||||
--
|
||||
1.7.9.3
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
From 52508a86e26f0bc74b0a7a3b05ed08a29996b44c Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 20 Feb 2012 16:05:48 +0100
|
||||
Subject: [PATCH 1/6] linux: Fix cancel_transfer return value when cancelling
|
||||
a multi-urb transfer
|
||||
|
||||
If we fail to cancel the last urb of a multi-urb transfer because it
|
||||
has already completed (errno == EINVAL on DISCARD_URB), then the entire
|
||||
transfer has already completed, so returning NOT_FOUND is consistent with what
|
||||
the documentation for libusb_cancel_transfer says.
|
||||
|
||||
But if we've successfully cancelled the last urb, and then another urb
|
||||
fails with errno == EINVAL, this means that we've still cancelled the
|
||||
transfer, as it has only *partially* completed.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/os/linux_usbfs.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
|
||||
index 2b81189..099fc61 100644
|
||||
--- a/libusb/os/linux_usbfs.c
|
||||
+++ b/libusb/os/linux_usbfs.c
|
||||
@@ -1466,7 +1466,8 @@ static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plu
|
||||
|
||||
if (EINVAL == errno) {
|
||||
usbi_dbg("URB not found --> assuming ready to be reaped");
|
||||
- ret = LIBUSB_ERROR_NOT_FOUND;
|
||||
+ if (i == (last_plus_one - 1))
|
||||
+ ret = LIBUSB_ERROR_NOT_FOUND;
|
||||
} else if (ENODEV == errno) {
|
||||
usbi_dbg("Device not found for URB --> assuming ready to be reaped");
|
||||
ret = LIBUSB_ERROR_NO_DEVICE;
|
||||
--
|
||||
1.7.9.3
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
From e8c0b72bf8cc6d89c3546bbdbcc85b2c63086578 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Mon, 20 Feb 2012 16:12:19 +0100
|
||||
Subject: [PATCH 2/6] Don't print errors when cancel_transfer fails with
|
||||
NOT_FOUND
|
||||
|
||||
As stated in the documentation for libusb_cancel_transfer,
|
||||
LIBUSB_ERROR_NOT_FOUND is an expected return value for
|
||||
libusb_cancel_transfer (under certain circumstances) printing
|
||||
an error each time this happens therefor is undesirable.
|
||||
|
||||
More so because under Linux IOCTL_USBFS_DISCARDURB sets errno
|
||||
to EINVAL when the kernel could not find the urb in the kernels
|
||||
urbs in flight list. Which means that the urb has already completed
|
||||
at the host controller level, but it has not necessarily already
|
||||
been reaped. IOW under Linux libusb_cancel_transfer may yield a
|
||||
result of LIBUSB_ERROR_NOT_FOUND *before* the transfer's callback
|
||||
has been called! So there is no way for an application to avoid
|
||||
calling libusb_cancel_transfer on already completed transfers.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/io.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libusb/io.c b/libusb/io.c
|
||||
index bb6e275..9f46cf0 100644
|
||||
--- a/libusb/io.c
|
||||
+++ b/libusb/io.c
|
||||
@@ -1351,8 +1351,11 @@ int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer)
|
||||
usbi_mutex_lock(&itransfer->lock);
|
||||
r = usbi_backend->cancel_transfer(itransfer);
|
||||
if (r < 0) {
|
||||
- usbi_err(TRANSFER_CTX(transfer),
|
||||
- "cancel transfer failed error %d", r);
|
||||
+ if (r != LIBUSB_ERROR_NOT_FOUND)
|
||||
+ usbi_err(TRANSFER_CTX(transfer),
|
||||
+ "cancel transfer failed error %d", r);
|
||||
+ else
|
||||
+ usbi_dbg("cancel transfer failed error %d", r);
|
||||
|
||||
if (r == LIBUSB_ERROR_NO_DEVICE)
|
||||
itransfer->flags |= USBI_TRANSFER_DEVICE_DISAPPEARED;
|
||||
--
|
||||
1.7.9.3
|
||||
|
||||
92
0004-linux-Fix-handling-of-urb-status-codes.patch
Normal file
92
0004-linux-Fix-handling-of-urb-status-codes.patch
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
From 3b6ed16cd2f098dd3920853d20940b3560c20ece Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 24 Feb 2012 10:24:00 +0100
|
||||
Subject: [PATCH 3/6] linux: Fix handling of urb status codes
|
||||
|
||||
During testing of my usbredir code I hit a case where EOVERFLOW was not handled
|
||||
in handle_control_completion. Instead of just fixing this one case I've audited
|
||||
(and fixed where necessary) all handle_foo_completion functions to know about
|
||||
all errors documented in linux/Documentation/usb/error-codes.txt.
|
||||
|
||||
Note that for handle_iso_completion this patch actually removes the handling
|
||||
of some codes, since these can never occur on an iso urb (they can only
|
||||
occur on the iso packets included in the urb, see the next patch in this
|
||||
series). Also in case an unknown status is encountered on an iso urb, this
|
||||
patch actually sets the urb's status to ERROR, rather then leaving it at
|
||||
completed.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/os/linux_usbfs.c | 17 ++++++++++++-----
|
||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
|
||||
index 099fc61..36d37a4 100644
|
||||
--- a/libusb/os/linux_usbfs.c
|
||||
+++ b/libusb/os/linux_usbfs.c
|
||||
@@ -1952,6 +1952,7 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
|
||||
case -ENOENT: /* cancelled */
|
||||
case -ECONNRESET:
|
||||
break;
|
||||
+ case -ENODEV:
|
||||
case -ESHUTDOWN:
|
||||
usbi_dbg("device removed");
|
||||
tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE;
|
||||
@@ -1970,6 +1971,8 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
|
||||
case -ETIME:
|
||||
case -EPROTO:
|
||||
case -EILSEQ:
|
||||
+ case -ECOMM:
|
||||
+ case -ENOSR:
|
||||
usbi_dbg("low level error %d", urb->status);
|
||||
tpriv->reap_action = ERROR;
|
||||
goto cancel_remaining;
|
||||
@@ -2081,19 +2084,16 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
||||
case 0:
|
||||
break;
|
||||
case -ENOENT: /* cancelled */
|
||||
+ case -ECONNRESET:
|
||||
break;
|
||||
case -ESHUTDOWN:
|
||||
usbi_dbg("device removed");
|
||||
status = LIBUSB_TRANSFER_NO_DEVICE;
|
||||
break;
|
||||
- case -ETIME:
|
||||
- case -EPROTO:
|
||||
- case -EILSEQ:
|
||||
- usbi_dbg("low-level USB error %d", urb->status);
|
||||
- break;
|
||||
default:
|
||||
usbi_warn(TRANSFER_CTX(transfer),
|
||||
"unrecognised urb status %d", urb->status);
|
||||
+ status = LIBUSB_TRANSFER_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2139,6 +2139,7 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
|
||||
case -ENOENT: /* cancelled */
|
||||
status = LIBUSB_TRANSFER_CANCELLED;
|
||||
break;
|
||||
+ case -ENODEV:
|
||||
case -ESHUTDOWN:
|
||||
usbi_dbg("device removed");
|
||||
status = LIBUSB_TRANSFER_NO_DEVICE;
|
||||
@@ -2147,9 +2148,15 @@ static int handle_control_completion(struct usbi_transfer *itransfer,
|
||||
usbi_dbg("unsupported control request");
|
||||
status = LIBUSB_TRANSFER_STALL;
|
||||
break;
|
||||
+ case -EOVERFLOW:
|
||||
+ usbi_dbg("control overflow error");
|
||||
+ status = LIBUSB_TRANSFER_OVERFLOW;
|
||||
+ break;
|
||||
case -ETIME:
|
||||
case -EPROTO:
|
||||
case -EILSEQ:
|
||||
+ case -ECOMM:
|
||||
+ case -ENOSR:
|
||||
usbi_dbg("low-level bus error occurred");
|
||||
status = LIBUSB_TRANSFER_ERROR;
|
||||
break;
|
||||
--
|
||||
1.7.9.3
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
From 4c3e7f9818c0d1d0462fde6f219da65fb102a434 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 24 Feb 2012 11:15:30 +0100
|
||||
Subject: [PATCH 4/6] linux: Translate linux iso pkt status codes to libusb
|
||||
transfer status codes
|
||||
|
||||
During testing of my usbredir code I hit a scenario where my libusb app
|
||||
was seeing EXDEV as status in the transfer's iso_packet_desc
|
||||
|
||||
This happened because we don't translate linux negative errno errors
|
||||
stored in iso pkts status to libusb transfer status codes at all! So this
|
||||
patch adds translation for this.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/os/linux_usbfs.c | 36 +++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 35 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
|
||||
index 36d37a4..a7d8298 100644
|
||||
--- a/libusb/os/linux_usbfs.c
|
||||
+++ b/libusb/os/linux_usbfs.c
|
||||
@@ -2053,7 +2053,41 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
|
||||
struct usbfs_iso_packet_desc *urb_desc = &urb->iso_frame_desc[i];
|
||||
struct libusb_iso_packet_descriptor *lib_desc =
|
||||
&transfer->iso_packet_desc[tpriv->iso_packet_offset++];
|
||||
- lib_desc->status = urb_desc->status;
|
||||
+ lib_desc->status = LIBUSB_TRANSFER_COMPLETED;
|
||||
+ switch (urb_desc->status) {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case -ENOENT: /* cancelled */
|
||||
+ case -ECONNRESET:
|
||||
+ break;
|
||||
+ case -ENODEV:
|
||||
+ case -ESHUTDOWN:
|
||||
+ usbi_dbg("device removed");
|
||||
+ lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE;
|
||||
+ break;
|
||||
+ case -EPIPE:
|
||||
+ usbi_dbg("detected endpoint stall");
|
||||
+ lib_desc->status = LIBUSB_TRANSFER_STALL;
|
||||
+ break;
|
||||
+ case -EOVERFLOW:
|
||||
+ usbi_dbg("overflow error");
|
||||
+ lib_desc->status = LIBUSB_TRANSFER_OVERFLOW;
|
||||
+ break;
|
||||
+ case -ETIME:
|
||||
+ case -EPROTO:
|
||||
+ case -EILSEQ:
|
||||
+ case -ECOMM:
|
||||
+ case -ENOSR:
|
||||
+ case -EXDEV:
|
||||
+ usbi_dbg("low-level USB error %d", urb_desc->status);
|
||||
+ lib_desc->status = LIBUSB_TRANSFER_ERROR;
|
||||
+ break;
|
||||
+ default:
|
||||
+ usbi_warn(TRANSFER_CTX(transfer),
|
||||
+ "unrecognised urb status %d", urb_desc->status);
|
||||
+ lib_desc->status = LIBUSB_TRANSFER_ERROR;
|
||||
+ break;
|
||||
+ }
|
||||
lib_desc->actual_length = urb_desc->actual_length;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.3
|
||||
|
||||
117
0006-linux_usbfs-Add-support-for-the-new-get_capabilities.patch
Normal file
117
0006-linux_usbfs-Add-support-for-the-new-get_capabilities.patch
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
From 1fabeefda0fb31aa36203aa8b3f07debdc83d22a Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Thu, 28 Jun 2012 16:40:52 +0200
|
||||
Subject: [PATCH 1/6] linux_usbfs: Add support for the new get_capabilities
|
||||
ioctl
|
||||
|
||||
There were a few (new) usbdevfs capabilities which libusbx could not
|
||||
discover in any other way then checking the kernel version. There are 3
|
||||
problems with this:
|
||||
1) It is just not very pretty
|
||||
2) Given the tendency of enterprise distros to backport stuff it is not
|
||||
reliable
|
||||
3) Some of these features turn out to not work with certain host controllers,
|
||||
making depending on them based on the kernel version not a good idea
|
||||
|
||||
Therefor a new USBDEVFS_GET_CAPABILITIES ioctl has been added to the kernel
|
||||
to offer a better way to find out a device's capabilities (technically
|
||||
the capabilities of the host controller to which the device is attached,
|
||||
but that does not matter).
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/os/linux_usbfs.c | 24 ++++++++++++++++++++----
|
||||
libusb/os/linux_usbfs.h | 10 ++++++++++
|
||||
2 files changed, 30 insertions(+), 4 deletions(-)
|
||||
|
||||
diff -up libusb-1.0.8/libusb/os/linux_usbfs.c.caps libusb-1.0.8/libusb/os/linux_usbfs.c
|
||||
--- libusb-1.0.8/libusb/os/linux_usbfs.c.caps 2012-08-22 15:32:34.677822979 +0200
|
||||
+++ libusb-1.0.8/libusb/os/linux_usbfs.c 2012-08-22 15:39:27.526002251 +0200
|
||||
@@ -107,6 +107,7 @@ struct linux_device_priv {
|
||||
|
||||
struct linux_device_handle_priv {
|
||||
int fd;
|
||||
+ __u32 caps;
|
||||
};
|
||||
|
||||
enum reap_action {
|
||||
@@ -1139,6 +1140,7 @@ static int op_open(struct libusb_device_
|
||||
{
|
||||
struct linux_device_handle_priv *hpriv = __device_handle_priv(handle);
|
||||
char filename[PATH_MAX];
|
||||
+ int r;
|
||||
|
||||
__get_usbfs_path(handle->dev, filename);
|
||||
usbi_dbg("opening %s", filename);
|
||||
@@ -1161,6 +1163,18 @@ static int op_open(struct libusb_device_
|
||||
}
|
||||
}
|
||||
|
||||
+ r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps);
|
||||
+ if (r < 0) {
|
||||
+ if (errno == ENOTTY)
|
||||
+ usbi_dbg("%s: getcap not available", filename);
|
||||
+ else
|
||||
+ usbi_err(HANDLE_CTX(handle),
|
||||
+ "%s: getcap failed (%d)", filename, errno);
|
||||
+ hpriv->caps = 0;
|
||||
+ if (supports_flag_bulk_continuation)
|
||||
+ hpriv->caps |= USBFS_CAP_BULK_CONTINUATION;
|
||||
+ }
|
||||
+
|
||||
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
|
||||
}
|
||||
|
||||
@@ -1544,7 +1558,7 @@ static int submit_bulk_transfer(struct u
|
||||
urb->type = urb_type;
|
||||
urb->endpoint = transfer->endpoint;
|
||||
urb->buffer = transfer->buffer + (i * MAX_BULK_BUFFER_LENGTH);
|
||||
- if (supports_flag_bulk_continuation && !is_out)
|
||||
+ if ((dpriv->caps & USBFS_CAP_BULK_CONTINUATION) && !is_out)
|
||||
urb->flags = USBFS_URB_SHORT_NOT_OK;
|
||||
if (i == num_urbs - 1 && last_urb_partial)
|
||||
urb->buffer_length = transfer->length % MAX_BULK_BUFFER_LENGTH;
|
||||
@@ -1553,7 +1567,7 @@ static int submit_bulk_transfer(struct u
|
||||
else
|
||||
urb->buffer_length = MAX_BULK_BUFFER_LENGTH;
|
||||
|
||||
- if (i > 0 && supports_flag_bulk_continuation)
|
||||
+ if (i > 0 && (dpriv->caps & USBFS_CAP_BULK_CONTINUATION))
|
||||
urb->flags |= USBFS_URB_BULK_CONTINUATION;
|
||||
|
||||
r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
|
||||
diff -up libusb-1.0.8/libusb/os/linux_usbfs.h.caps libusb-1.0.8/libusb/os/linux_usbfs.h
|
||||
--- libusb-1.0.8/libusb/os/linux_usbfs.h.caps 2011-02-07 11:53:41.000000000 +0100
|
||||
+++ libusb-1.0.8/libusb/os/linux_usbfs.h 2012-08-22 15:33:21.224843100 +0200
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef __LIBUSB_USBFS_H__
|
||||
#define __LIBUSB_USBFS_H__
|
||||
|
||||
+#include <linux/types.h>
|
||||
+
|
||||
#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices"
|
||||
|
||||
struct usbfs_ctrltransfer {
|
||||
@@ -115,6 +117,11 @@ struct usbfs_hub_portinfo {
|
||||
unsigned char port[127]; /* port to device num mapping */
|
||||
};
|
||||
|
||||
+#define USBFS_CAP_ZERO_PACKET 0x01
|
||||
+#define USBFS_CAP_BULK_CONTINUATION 0x02
|
||||
+#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04
|
||||
+#define USBFS_CAP_BULK_SCATTER_GATHER 0x08
|
||||
+
|
||||
#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer)
|
||||
#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer)
|
||||
#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int)
|
||||
@@ -134,5 +141,8 @@ struct usbfs_hub_portinfo {
|
||||
#define IOCTL_USBFS_CLEAR_HALT _IOR('U', 21, unsigned int)
|
||||
#define IOCTL_USBFS_DISCONNECT _IO('U', 22)
|
||||
#define IOCTL_USBFS_CONNECT _IO('U', 23)
|
||||
+#define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int)
|
||||
+#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int)
|
||||
+#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32)
|
||||
|
||||
#endif
|
||||
--
|
||||
1.7.11.4
|
||||
141
0007-linux_usbfs-Avoid-unnecessary-splitting-of-bulk-tran.patch
Normal file
141
0007-linux_usbfs-Avoid-unnecessary-splitting-of-bulk-tran.patch
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
From 9b1b7e0acd9f41e6df213e9eeb744e970bdc1544 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 29 Jun 2012 12:16:11 +0200
|
||||
Subject: [PATCH 2/6] linux_usbfs: Avoid unnecessary splitting of bulk
|
||||
transfers (v2)
|
||||
|
||||
With the latest kernels it is no longer needed to always split large bulk
|
||||
transfers into multiple urbs. This patch takes advantage of this by not
|
||||
splitting when not necessary. Note that the non-split code path is in essence
|
||||
using the old split code path with an urb count which is always 1.
|
||||
|
||||
This leads to more sane handling of large transfers with recent kernels,
|
||||
although our splitting code is well tested, not splitting at all still is
|
||||
a lot better :)
|
||||
|
||||
When used with a recent kernel, this also fixes the problems, on XHCI attached
|
||||
devices, when a large bulk-in transfer ends with a short read in an urb other
|
||||
then the last urb. For details on this see the mailinglist thread titled
|
||||
"usbdevfs: BULK_CONTINUATION flag does not work with XHCI controller".
|
||||
|
||||
Changes in v2:
|
||||
-avoid a divide by 0 on 0 size packets
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/os/linux_usbfs.c | 69 ++++++++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 57 insertions(+), 12 deletions(-)
|
||||
|
||||
diff -up libusb-1.0.8/libusb/os/linux_usbfs.c.bulk libusb-1.0.8/libusb/os/linux_usbfs.c
|
||||
--- libusb-1.0.8/libusb/os/linux_usbfs.c.bulk 2012-08-22 15:40:51.814038955 +0200
|
||||
+++ libusb-1.0.8/libusb/os/linux_usbfs.c 2012-08-22 15:43:26.788106690 +0200
|
||||
@@ -1519,6 +1519,7 @@ static int submit_bulk_transfer(struct u
|
||||
struct usbfs_urb *urbs;
|
||||
int is_out = (transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK)
|
||||
== LIBUSB_ENDPOINT_OUT;
|
||||
+ int bulk_buffer_len, use_bulk_continuation;
|
||||
int r;
|
||||
int i;
|
||||
size_t alloc_size;
|
||||
@@ -1526,16 +1527,54 @@ static int submit_bulk_transfer(struct u
|
||||
if (tpriv->urbs)
|
||||
return LIBUSB_ERROR_BUSY;
|
||||
|
||||
- /* usbfs places a 16kb limit on bulk URBs. we divide up larger requests
|
||||
- * into smaller units to meet such restriction, then fire off all the
|
||||
- * units at once. it would be simpler if we just fired one unit at a time,
|
||||
- * but there is a big performance gain through doing it this way. */
|
||||
- int num_urbs = transfer->length / MAX_BULK_BUFFER_LENGTH;
|
||||
+ /*
|
||||
+ * Older versions of usbfs place a 16kb limit on bulk URBs. We work
|
||||
+ * around this by splitting large transfers into 16k blocks, and then
|
||||
+ * submit all urbs at once. it would be simpler to submit one urb at
|
||||
+ * a time, but there is a big performance gain doing it this way.
|
||||
+ *
|
||||
+ * Newer versions lift the 16k limit (USBFS_CAP_NO_PACKET_SIZE_LIM),
|
||||
+ * using arbritary large transfers can still be a bad idea though, as
|
||||
+ * the kernel needs to allocate physical contiguous memory for this,
|
||||
+ * which may fail for large buffers.
|
||||
+ *
|
||||
+ * The kernel solves this problem by splitting the transfer into
|
||||
+ * blocks itself when the host-controller is scatter-gather capable
|
||||
+ * (USBFS_CAP_BULK_SCATTER_GATHER), which most controllers are.
|
||||
+ *
|
||||
+ * Last, there is the issue of short-transfers when splitting, for
|
||||
+ * short split-transfers to work reliable USBFS_CAP_BULK_CONTINUATION
|
||||
+ * is needed, but this is not always available.
|
||||
+ */
|
||||
+ if (dpriv->caps & USBFS_CAP_BULK_SCATTER_GATHER) {
|
||||
+ /* Good! Just submit everything in one go */
|
||||
+ bulk_buffer_len = transfer->length ? transfer->length : 1;
|
||||
+ use_bulk_continuation = 0;
|
||||
+ } else if (dpriv->caps & USBFS_CAP_BULK_CONTINUATION) {
|
||||
+ /* Split the transfers and use bulk-continuation to
|
||||
+ avoid issues with short-transfers */
|
||||
+ bulk_buffer_len = MAX_BULK_BUFFER_LENGTH;
|
||||
+ use_bulk_continuation = 1;
|
||||
+ } else if (dpriv->caps & USBFS_CAP_NO_PACKET_SIZE_LIM) {
|
||||
+ /* Don't split, assume the kernel can alloc the buffer
|
||||
+ (otherwise the submit will fail with -ENOMEM) */
|
||||
+ bulk_buffer_len = transfer->length ? transfer->length : 1;
|
||||
+ use_bulk_continuation = 0;
|
||||
+ } else {
|
||||
+ /* Bad, splitting without bulk-continuation, short transfers
|
||||
+ which end before the last urb will not work reliable! */
|
||||
+ /* Note we don't warn here as this is "normal" on kernels <
|
||||
+ 2.6.32 and not a problem for most applications */
|
||||
+ bulk_buffer_len = MAX_BULK_BUFFER_LENGTH;
|
||||
+ use_bulk_continuation = 0;
|
||||
+ }
|
||||
+
|
||||
+ int num_urbs = transfer->length / bulk_buffer_len;
|
||||
int last_urb_partial = 0;
|
||||
|
||||
if (transfer->length == 0) {
|
||||
num_urbs = 1;
|
||||
- } else if ((transfer->length % MAX_BULK_BUFFER_LENGTH) > 0) {
|
||||
+ } else if ((transfer->length % bulk_buffer_len) > 0) {
|
||||
last_urb_partial = 1;
|
||||
num_urbs++;
|
||||
}
|
||||
@@ -1557,17 +1596,17 @@ static int submit_bulk_transfer(struct u
|
||||
urb->usercontext = itransfer;
|
||||
urb->type = urb_type;
|
||||
urb->endpoint = transfer->endpoint;
|
||||
- urb->buffer = transfer->buffer + (i * MAX_BULK_BUFFER_LENGTH);
|
||||
- if ((dpriv->caps & USBFS_CAP_BULK_CONTINUATION) && !is_out)
|
||||
+ urb->buffer = transfer->buffer + (i * bulk_buffer_len);
|
||||
+ if (use_bulk_continuation && !is_out)
|
||||
urb->flags = USBFS_URB_SHORT_NOT_OK;
|
||||
if (i == num_urbs - 1 && last_urb_partial)
|
||||
- urb->buffer_length = transfer->length % MAX_BULK_BUFFER_LENGTH;
|
||||
+ urb->buffer_length = transfer->length % bulk_buffer_len;
|
||||
else if (transfer->length == 0)
|
||||
urb->buffer_length = 0;
|
||||
else
|
||||
- urb->buffer_length = MAX_BULK_BUFFER_LENGTH;
|
||||
+ urb->buffer_length = bulk_buffer_len;
|
||||
|
||||
- if (i > 0 && (dpriv->caps & USBFS_CAP_BULK_CONTINUATION))
|
||||
+ if (i > 0 && use_bulk_continuation)
|
||||
urb->flags |= USBFS_URB_BULK_CONTINUATION;
|
||||
|
||||
r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb);
|
||||
@@ -1649,7 +1688,13 @@ static int submit_iso_transfer(struct us
|
||||
/* usbfs places a 32kb limit on iso URBs. we divide up larger requests
|
||||
* into smaller units to meet such restriction, then fire off all the
|
||||
* units at once. it would be simpler if we just fired one unit at a time,
|
||||
- * but there is a big performance gain through doing it this way. */
|
||||
+ * but there is a big performance gain through doing it this way.
|
||||
+ *
|
||||
+ * Newer kernels lift the 32k limit (USBFS_CAP_NO_PACKET_SIZE_LIM),
|
||||
+ * using arbritary large transfers is still be a bad idea though, as
|
||||
+ * the kernel needs to allocate physical contiguous memory for this,
|
||||
+ * which may fail for large buffers.
|
||||
+ */
|
||||
|
||||
/* calculate how many URBs we need */
|
||||
for (i = 0; i < num_packets; i++) {
|
||||
--
|
||||
1.7.11.4
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
From daa923ac06cbf5bcac6922a9520aa7fc9919134e Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Sat, 28 Jul 2012 11:43:52 +0200
|
||||
Subject: [PATCH 3/6] detach-kernel-driver: return ERROR_NOT_FOUND if usbfs is
|
||||
already bound (v3)
|
||||
|
||||
Currently applications for devices which only are accessed from userspace
|
||||
can use claim / release interface to make sure they don't get in each others
|
||||
way. The same however does not work for applications which first need to detach
|
||||
a "native" / in kernel driver, as this detach will not only detach native
|
||||
drivers but also the usbfs driver, thus stealing the device from another
|
||||
userspace / libusbx app.
|
||||
|
||||
This patch fixes libusb_detach_kernel_driver to only detach "real" kernel
|
||||
drivers and not the special usbfs driver used for userspace access to
|
||||
USB devices. If the usbfs driver is found LIBUSB_ERROR_NOT_FOUND will be
|
||||
returned to indicate no driver was detached.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/core.c | 4 ++++
|
||||
libusb/os/linux_usbfs.c | 6 ++++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/libusb/core.c b/libusb/core.c
|
||||
index 7c2f4d7..4c513f7 100644
|
||||
--- a/libusb/core.c
|
||||
+++ b/libusb/core.c
|
||||
@@ -1513,6 +1513,10 @@ int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev,
|
||||
*
|
||||
* This functionality is not available on Darwin or Windows.
|
||||
*
|
||||
+ * Note that libusb itself also talks to the device through a special kernel
|
||||
+ * driver, if this driver is already attached to the device, this call will
|
||||
+ * not detach it and return LIBUSB_ERROR_NOT_FOUND.
|
||||
+ *
|
||||
* \param dev a device handle
|
||||
* \param interface_number the interface to detach the driver from
|
||||
* \returns 0 on success
|
||||
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
|
||||
index 839ebde..1407866 100644
|
||||
--- a/libusb/os/linux_usbfs.c
|
||||
+++ b/libusb/os/linux_usbfs.c
|
||||
@@ -1538,12 +1538,18 @@ static int op_detach_kernel_driver(struct libusb_device_handle *handle,
|
||||
{
|
||||
int fd = __device_handle_priv(handle)->fd;
|
||||
struct usbfs_ioctl command;
|
||||
+ struct usbfs_getdriver getdrv;
|
||||
int r;
|
||||
|
||||
command.ifno = interface;
|
||||
command.ioctl_code = IOCTL_USBFS_DISCONNECT;
|
||||
command.data = NULL;
|
||||
|
||||
+ getdrv.interface = interface;
|
||||
+ r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv);
|
||||
+ if (r == 0 && strcmp(getdrv.driver, "usbfs") == 0)
|
||||
+ return LIBUSB_ERROR_NOT_FOUND;
|
||||
+
|
||||
r = ioctl(fd, IOCTL_USBFS_IOCTL, &command);
|
||||
if (r) {
|
||||
if (errno == ENODATA)
|
||||
--
|
||||
1.7.11.4
|
||||
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
From 78a150bfbbd84eb524e878bf05101c1ad2eac0b8 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Fri, 6 Jul 2012 14:35:53 +0200
|
||||
Subject: [PATCH 3/3] linux_usbfs: Work around a driver binding race in reset
|
||||
handling
|
||||
|
||||
I've been seeing these intermittent failures to reclaim an interface after
|
||||
a device reset. After much debugging and inserting sleeps in strategic
|
||||
places to make the race window larger I've found the following race:
|
||||
1) A user is running some software using libusb which will automatically
|
||||
detect, and "bind" to, any newly plugged in USB-devices. For example
|
||||
a virtual machine viewer with automatic USB-redirection
|
||||
2) The user plugs in a new usb-storage device
|
||||
3) The usb-storage driver is not yet loaded, udev spawns
|
||||
"modprobe usb-storage", this blocks on disk-io
|
||||
4) The libusb app opens the device, claims all interfaces, does a device-reset
|
||||
5) While the IOCTL_USBFS_RESET is running the modprobe completes
|
||||
6) The driver registration blocks on an USB lock held by the reset code path
|
||||
7) When the reset finishes the driver registration completes and the driver
|
||||
binds itself to the device, before IOCTL_USBFS_RESET returns to userspace
|
||||
8) libusb tries to re-claim all interfaces it had claimed before the reset
|
||||
9) libusb fails as usb-storage is now bound to it
|
||||
|
||||
This patch works around this issue by simply unbinding the driver for all
|
||||
interfaces which were claimed before the reset. Normally this is a no-op as
|
||||
no driver (other then usbfs) can be bound for claimed interfaces before the
|
||||
reset.
|
||||
|
||||
But as the above example shows, the exception is a driver completing
|
||||
registration, and as part of this binding to any elegible devices, between
|
||||
IOCTL_USBFS_RESET and our re-claiming of the interface. The largest part
|
||||
of the race window here is the time IOCTL_USBFS_RESET takes, as that does a
|
||||
fair amount of IO with the device. This part of the race window is
|
||||
worked around by this patch.
|
||||
|
||||
This still leaves a theoretical race window where the driver registration
|
||||
finishes between our driver-unbind and interface-reclaim, I'm afraid there
|
||||
is nothing we can against this.
|
||||
|
||||
This patch also improves the error logging, and makes libusb_device_reset
|
||||
properly return an error when re-claiming fails.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
libusb/os/linux_usbfs.c | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
|
||||
index 3894554..10d138a 100644
|
||||
--- a/libusb/os/linux_usbfs.c
|
||||
+++ b/libusb/os/linux_usbfs.c
|
||||
@@ -108,6 +108,9 @@ static int sysfs_can_relate_devices = 0;
|
||||
/* do we have a descriptors file? */
|
||||
static int sysfs_has_descriptors = 0;
|
||||
|
||||
+static int op_detach_kernel_driver(struct libusb_device_handle *handle,
|
||||
+ int interface);
|
||||
+
|
||||
struct linux_device_priv {
|
||||
char *sysfs_dir;
|
||||
unsigned char *dev_descriptor;
|
||||
@@ -1497,11 +1500,20 @@ static int op_reset_device(struct libusb_device_handle *handle)
|
||||
/* And re-claim any interfaces which were claimed before the reset */
|
||||
for (i = 0; i < USB_MAXINTERFACES; i++) {
|
||||
if (handle->claimed_interfaces & (1L << i)) {
|
||||
+ /*
|
||||
+ * A driver may have completed modprobing during
|
||||
+ * IOCTL_USBFS_RESET, and bound itself as soon as
|
||||
+ * IOCTL_USBFS_RESET released the device lock
|
||||
+ */
|
||||
+ op_detach_kernel_driver(handle, i);
|
||||
+
|
||||
r = op_claim_interface(handle, i);
|
||||
if (r) {
|
||||
usbi_warn(HANDLE_CTX(handle),
|
||||
- "failed to re-claim interface %d after reset", i);
|
||||
+ "failed to re-claim interface %d after reset: %s",
|
||||
+ i, libusb_error_name(r));
|
||||
handle->claimed_interfaces &= ~(1L << i);
|
||||
+ ret = LIBUSB_ERROR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.11.2
|
||||
|
||||
21
Makefile
21
Makefile
|
|
@ -1,21 +0,0 @@
|
|||
# Makefile for source rpm: libusb1
|
||||
# $Id$
|
||||
NAME := libusb1
|
||||
SPECFILE = $(firstword $(wildcard *.spec))
|
||||
|
||||
define find-makefile-common
|
||||
for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
|
||||
endef
|
||||
|
||||
MAKEFILE_COMMON := $(shell $(find-makefile-common))
|
||||
|
||||
ifeq ($(MAKEFILE_COMMON),)
|
||||
# attept a checkout
|
||||
define checkout-makefile-common
|
||||
test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
|
||||
endef
|
||||
|
||||
MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
|
||||
endif
|
||||
|
||||
include $(MAKEFILE_COMMON)
|
||||
161
libusb1.spec
Normal file
161
libusb1.spec
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
Summary: A library which allows userspace access to USB devices
|
||||
Name: libusb1
|
||||
Version: 1.0.9
|
||||
Release: 0.6.rc1%{?dist}
|
||||
Source0: libusb-1.0.9-rc1.tar.bz2
|
||||
#Source0: http://downloads.sourceforge.net/libusb/libusb-%{version}.tar.bz2
|
||||
|
||||
Patch1: 0001-Correctly-handle-LIBUSB_TRANSFER_OVERFLOW-in-libusb_.patch
|
||||
Patch2: 0002-linux-Fix-cancel_transfer-return-value-when-cancelli.patch
|
||||
Patch3: 0003-Don-t-print-errors-when-cancel_transfer-fails-with-N.patch
|
||||
Patch4: 0004-linux-Fix-handling-of-urb-status-codes.patch
|
||||
Patch5: 0005-linux-Translate-linux-iso-pkt-status-codes-to-libusb.patch
|
||||
# For rhbz#830751
|
||||
Patch6: 0006-linux_usbfs-Add-support-for-the-new-get_capabilities.patch
|
||||
Patch7: 0007-linux_usbfs-Avoid-unnecessary-splitting-of-bulk-tran.patch
|
||||
# For rhbz#820205
|
||||
Patch8: 0008-detach-kernel-driver-return-ERROR_NOT_FOUND-if-usbfs.patch
|
||||
Patch9: 0009-linux_usbfs-Work-around-a-driver-binding-race-in-res.patch
|
||||
|
||||
License: LGPLv2+
|
||||
Group: System Environment/Libraries
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
URL: http://libusb.wiki.sourceforge.net/Libusb1.0
|
||||
ExcludeArch: s390 s390x
|
||||
BuildRequires: doxygen
|
||||
|
||||
%description
|
||||
This package provides a way for applications to access USB devices. Note that
|
||||
this library is not compatible with the original libusb-0.1 series.
|
||||
|
||||
%package devel
|
||||
Summary: Development files for libusb
|
||||
Group: Development/Libraries
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
Requires: pkgconfig
|
||||
|
||||
%description devel
|
||||
This package contains the header files, libraries and documentation needed to
|
||||
develop applications that use libusb1.
|
||||
|
||||
%package static
|
||||
Summary: Static development files for libusb
|
||||
Group: Development/Libraries
|
||||
Requires: %{name}-devel = %{version}-%{release}
|
||||
|
||||
%description static
|
||||
This package contains static libraries to develop applications that use libusb1.
|
||||
|
||||
%prep
|
||||
%setup -q -n libusb-1.0.8
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
|
||||
%build
|
||||
%configure
|
||||
make CFLAGS="$RPM_OPT_FLAGS"
|
||||
pushd doc
|
||||
make docs
|
||||
popd
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make install DESTDIR=$RPM_BUILD_ROOT
|
||||
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
|
||||
|
||||
# Our snapshot reports itself as 1.0.8, change the pkg-config file version to
|
||||
# 1.0.9 so that configure checks by apps who need the new 1.0.9 succeed
|
||||
sed -i 's/1\.0\.8/1.0.9/' %{buildroot}/%{_libdir}/pkgconfig/libusb-1.0.pc
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc AUTHORS COPYING README NEWS ChangeLog
|
||||
%{_libdir}/*.so.*
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
%doc doc/html examples/*.c
|
||||
%{_libdir}/pkgconfig/libusb-1.0.pc
|
||||
%{_includedir}/*
|
||||
%{_libdir}/*.so
|
||||
|
||||
%files static
|
||||
%defattr(-,root,root)
|
||||
%{_libdir}/*.a
|
||||
|
||||
%changelog
|
||||
* Wed Aug 22 2012 Hans de Goede <hdegoede@redhat.com> - 1.0.9-0.6.rc1
|
||||
- Don't split bulk transfers unnecessary
|
||||
- Resolves: rhbz#830751
|
||||
- Don't let disconnect_kernel_driver detach the usbfs driver
|
||||
- Resolves: rhbz#820205
|
||||
|
||||
* Wed Mar 14 2012 Hans de Goede <hdegoede@redhat.com> - 1.0.9-0.5.rc1
|
||||
- Add some small error handling fixes
|
||||
- Related: rhbz#758094
|
||||
|
||||
* Tue Jan 17 2012 Hans de Goede <hdegoede@redhat.com> - 1.0.9-0.4.rc1
|
||||
- Fix previous changelog entry to refer to the right bug
|
||||
- Related: rhbz#758094
|
||||
|
||||
* Wed Jan 11 2012 Marc-Andre Lureau <marcandre.lureau@redhat.com> 1.0.9-0.3.rc1
|
||||
- update to 1.0.9rc1, sync with f16
|
||||
- Resolves: rhbz#758094
|
||||
|
||||
* Mon Sep 28 2009 Jindrich Novy <jnovy@redhat.com> 1.0.3-1
|
||||
- update to 1.0.3
|
||||
|
||||
* Sat Jul 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.0.2-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
|
||||
|
||||
* Mon Jun 15 2009 Jindrich Novy <jnovy@redhat.com> 1.0.2-1
|
||||
- update to 1.0.2
|
||||
|
||||
* Wed May 13 2009 Jindrich Novy <jnovy@redhat.com> 1.0.1-1
|
||||
- update to 1.0.1
|
||||
|
||||
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.0.0-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Mon Dec 15 2008 - Bastien Nocera <bnocera@redhat.com> - 1.0.0-1
|
||||
- Update to 1.0.0
|
||||
|
||||
* Fri Nov 21 2008 - Bastien Nocera <bnocera@redhat.com> - 0.9.4-1
|
||||
- Update to 0.9.4
|
||||
|
||||
* Tue Sep 23 2008 Jindrich Novy <jnovy@redhat.com> 0.9.3-0.1
|
||||
- update to 0.9.3
|
||||
|
||||
* Sun Jul 06 2008 - Bastien Nocera <bnocera@redhat.com> - 0.9.1
|
||||
- Update to 0.9.1
|
||||
|
||||
* Mon May 26 2008 Jindrich Novy <jnovy@redhat.com> 0.9.0-0.4
|
||||
- update to official beta
|
||||
|
||||
* Thu May 23 2008 Jindrich Novy <jnovy@redhat.com> 0.9.0-0.3.gitbef33bb
|
||||
- update comment on how the tarball was created
|
||||
- use abbreviated git hash within package name to avoid conflicts
|
||||
- add to %%description that libusb1 is incompatible with libsub-0.1
|
||||
|
||||
* Thu May 22 2008 Jindrich Novy <jnovy@redhat.com> 0.9.0-0.2.gitbef33bb
|
||||
- add info on how the snapshot tarball was created
|
||||
|
||||
* Wed May 21 2008 Jindrich Novy <jnovy@redhat.com> 0.9.0-0.1.gitbef33bb
|
||||
- use proper version to denote it is a git snapshot
|
||||
|
||||
* Thu May 15 2008 Jindrich Novy <jnovy@redhat.com> 0.9.0-0.1
|
||||
- initial packaging
|
||||
1
sources
1
sources
|
|
@ -0,0 +1 @@
|
|||
389dd12f7da1411aac2524c5de35e2f5 libusb-1.0.9-rc1.tar.bz2
|
||||
Loading…
Add table
Add a link
Reference in a new issue