summaryrefslogtreecommitdiff
path: root/sanei/sanei_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sanei/sanei_usb.c')
-rw-r--r--sanei/sanei_usb.c427
1 files changed, 124 insertions, 303 deletions
diff --git a/sanei/sanei_usb.c b/sanei/sanei_usb.c
index e4b23dc..6fd6040 100644
--- a/sanei/sanei_usb.c
+++ b/sanei/sanei_usb.c
@@ -1262,6 +1262,77 @@ sanei_usb_set_endpoint (SANE_Int dn, SANE_Int ep_type, SANE_Int ep)
}
}
+#if HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS
+static const char* sanei_usb_transfer_type_desc(SANE_Int transfer_type)
+{
+ switch (transfer_type)
+ {
+ case USB_ENDPOINT_TYPE_INTERRUPT: return "interrupt";
+ case USB_ENDPOINT_TYPE_BULK: return "bulk";
+ case USB_ENDPOINT_TYPE_ISOCHRONOUS: return "isochronous";
+ case USB_ENDPOINT_TYPE_CONTROL: return "control";
+ }
+ return NULL;
+}
+
+// Similar sanei_usb_set_endpoint, but ignors duplicate endpoints
+static void sanei_usb_add_endpoint(device_list_type* device,
+ SANE_Int transfer_type,
+ SANE_Int ep_address,
+ SANE_Int ep_direction)
+{
+ DBG(5, "%s: direction: %d, address: %d, transfer_type: %d\n",
+ __func__, ep_direction, ep_address, transfer_type);
+
+ SANE_Int* ep_in = NULL;
+ SANE_Int* ep_out = NULL;
+ const char* transfer_type_msg = sanei_usb_transfer_type_desc(transfer_type);
+
+ switch (transfer_type)
+ {
+ case USB_ENDPOINT_TYPE_INTERRUPT:
+ ep_in = &device->int_in_ep;
+ ep_out = &device->int_out_ep;
+ break;
+ case USB_ENDPOINT_TYPE_BULK:
+ ep_in = &device->bulk_in_ep;
+ ep_out = &device->bulk_out_ep;
+ break;
+ case USB_ENDPOINT_TYPE_ISOCHRONOUS:
+ ep_in = &device->iso_in_ep;
+ ep_out = &device->iso_out_ep;
+ break;
+ case USB_ENDPOINT_TYPE_CONTROL:
+ ep_in = &device->control_in_ep;
+ ep_out = &device->control_out_ep;
+ break;
+ }
+
+ DBG(5, "%s: found %s-%s endpoint (address 0x%02x)\n",
+ __func__, transfer_type_msg, ep_direction ? "in" : "out",
+ ep_address);
+
+ if (ep_direction) // in
+ {
+ if (*ep_in)
+ DBG(3, "%s: we already have a %s-in endpoint "
+ "(address: 0x%02x), ignoring the new one\n",
+ __func__, transfer_type_msg, *ep_in);
+ else
+ *ep_in = ep_address;
+ }
+ else
+ {
+ if (*ep_out)
+ DBG(3, "%s: we already have a %s-out endpoint "
+ "(address: 0x%02x), ignoring the new one\n",
+ __func__, transfer_type_msg, *ep_out);
+ else
+ *ep_out = ep_address;
+ }
+}
+#endif // HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS
+
SANE_Int
sanei_usb_get_endpoint (SANE_Int dn, SANE_Int ep_type)
{
@@ -1460,132 +1531,12 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)
DBG (5, "sanei_usb_open: endpoint nr: %d\n", num);
transfer_type =
endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK;
- address =
- endpoint->
- bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
direction =
endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
- DBG (5, "sanei_usb_open: direction: %d\n", direction);
-
- DBG (5,
- "sanei_usb_open: address: %d transfertype: %d\n",
- address, transfer_type);
-
-
- /* save the endpoints we need later */
- if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT)
- {
- DBG (5,
- "sanei_usb_open: found interrupt-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].int_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a int-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].int_in_ep);
- else
- devices[devcount].int_in_ep =
- endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].int_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a int-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].int_out_ep);
- else
- devices[devcount].int_out_ep =
- endpoint->bEndpointAddress;
- }
- }
- else if (transfer_type == USB_ENDPOINT_TYPE_BULK)
- {
- DBG (5,
- "sanei_usb_open: found bulk-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].bulk_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a bulk-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].bulk_in_ep);
- else
- devices[devcount].bulk_in_ep =
- endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].bulk_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a bulk-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].bulk_out_ep);
- else
- devices[devcount].bulk_out_ep =
- endpoint->bEndpointAddress;
- }
- }
- else if (transfer_type == USB_ENDPOINT_TYPE_ISOCHRONOUS)
- {
- DBG (5,
- "sanei_usb_open: found isochronous-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].iso_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a isochronous-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].iso_in_ep);
- else
- devices[devcount].iso_in_ep =
- endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].iso_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a isochronous-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].iso_out_ep);
- else
- devices[devcount].iso_out_ep =
- endpoint->bEndpointAddress;
- }
- }
- else if (transfer_type == USB_ENDPOINT_TYPE_CONTROL)
- {
- DBG (5,
- "sanei_usb_open: found control-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].control_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a control-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].control_in_ep);
- else
- devices[devcount].control_in_ep =
- endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].control_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a control-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].control_out_ep);
- else
- devices[devcount].control_out_ep =
- endpoint->bEndpointAddress;
- }
- }
+ sanei_usb_add_endpoint(&devices[devcount], transfer_type,
+ endpoint->bEndpointAddress,
+ direction);
}
}
}
@@ -1769,124 +1720,39 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)
for (num = 0; num < interface->bNumEndpoints; num++)
{
const struct libusb_endpoint_descriptor *endpoint;
- int address, direction, transfer_type;
+ int direction, transfer_type, transfer_type_libusb;
endpoint = &interface->endpoint[num];
DBG (5, "sanei_usb_open: endpoint nr: %d\n", num);
- transfer_type = endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK;
- address = endpoint->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK;
+ transfer_type_libusb =
+ endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK;
direction = endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK;
- DBG (5, "sanei_usb_open: direction: %d\n", direction);
- DBG (5, "sanei_usb_open: address: %d transfertype: %d\n",
- address, transfer_type);
-
- /* save the endpoints we need later */
- if (transfer_type == LIBUSB_TRANSFER_TYPE_INTERRUPT)
- {
- DBG (5,
- "sanei_usb_open: found interrupt-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].int_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a int-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].int_in_ep);
- else
- devices[devcount].int_in_ep = endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].int_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a int-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].int_out_ep);
- else
- devices[devcount].int_out_ep = endpoint->bEndpointAddress;
- }
- }
- else if (transfer_type == LIBUSB_TRANSFER_TYPE_BULK)
- {
- DBG (5,
- "sanei_usb_open: found bulk-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].bulk_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a bulk-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].bulk_in_ep);
- else
- devices[devcount].bulk_in_ep = endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].bulk_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a bulk-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].bulk_out_ep);
- else
- devices[devcount].bulk_out_ep = endpoint->bEndpointAddress;
- }
- }
- else if (transfer_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
- {
- DBG (5,
- "sanei_usb_open: found isochronous-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].iso_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a isochronous-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].iso_in_ep);
- else
- devices[devcount].iso_in_ep = endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].iso_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a isochronous-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].iso_out_ep);
- else
- devices[devcount].iso_out_ep = endpoint->bEndpointAddress;
- }
- }
- else if (transfer_type == LIBUSB_TRANSFER_TYPE_CONTROL)
- {
- DBG (5,
- "sanei_usb_open: found control-%s endpoint (address 0x%02x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].control_in_ep)
- DBG (3,
- "sanei_usb_open: we already have a control-in endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].control_in_ep);
- else
- devices[devcount].control_in_ep = endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].control_out_ep)
- DBG (3,
- "sanei_usb_open: we already have a control-out endpoint "
- "(address: 0x%02x), ignoring the new one\n",
- devices[devcount].control_out_ep);
- else
- devices[devcount].control_out_ep = endpoint->bEndpointAddress;
- }
- }
+ // don't rely on LIBUSB_TRANSFER_TYPE_* mapping to
+ // USB_ENDPOINT_TYPE_* even though they'll most likely be
+ // the same
+ switch (transfer_type_libusb)
+ {
+ case LIBUSB_TRANSFER_TYPE_INTERRUPT:
+ transfer_type = USB_ENDPOINT_TYPE_INTERRUPT;
+ break;
+ case LIBUSB_TRANSFER_TYPE_BULK:
+ transfer_type = USB_ENDPOINT_TYPE_BULK;
+ break;
+ case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
+ transfer_type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
+ break;
+ case LIBUSB_TRANSFER_TYPE_CONTROL:
+ transfer_type = USB_ENDPOINT_TYPE_CONTROL;
+ break;
+
+ }
+
+ sanei_usb_add_endpoint(&devices[devcount],
+ transfer_type,
+ endpoint->bEndpointAddress,
+ direction);
}
}
}
@@ -2016,62 +1882,21 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)
break;
case USB_DT_ENDPOINT:
endpoint = (struct usb_endpoint_descriptor*)pDescHead;
- address = endpoint->bEndpointAddress;
direction = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
transfer_type = endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK;
- /* save the endpoints we need later */
- if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT)
- {
- DBG (5, "sanei_usb_open: found interupt-%s endpoint (address %2x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].int_in_ep)
- DBG (3, "sanei_usb_open: we already have a int-in endpoint "
- "(address: %d), ignoring the new one\n",
- devices[devcount].int_in_ep);
- else
- devices[devcount].int_in_ep = endpoint->bEndpointAddress;
- }
- else
- if (devices[devcount].int_out_ep)
- DBG (3, "sanei_usb_open: we already have a int-out endpoint "
- "(address: %d), ignoring the new one\n",
- devices[devcount].int_out_ep);
- else
- devices[devcount].int_out_ep = endpoint->bEndpointAddress;
- }
- else if (transfer_type == USB_ENDPOINT_TYPE_BULK)
- {
- DBG (5, "sanei_usb_open: found bulk-%s endpoint (address %2x)\n",
- direction ? "in" : "out", address);
- if (direction) /* in */
- {
- if (devices[devcount].bulk_in_ep)
- DBG (3, "sanei_usb_open: we already have a bulk-in endpoint "
- "(address: %d), ignoring the new one\n",
- devices[devcount].bulk_in_ep);
- else
- devices[devcount].bulk_in_ep = endpoint->bEndpointAddress;
- }
- else
- {
- if (devices[devcount].bulk_out_ep)
- DBG (3, "sanei_usb_open: we already have a bulk-out endpoint "
- "(address: %d), ignoring the new one\n",
- devices[devcount].bulk_out_ep);
- else
- devices[devcount].bulk_out_ep = endpoint->bEndpointAddress;
- }
- }
+
+ if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT ||
+ transfer_type == USB_ENDPOINT_TYPE_BULK)
+ {
+ sanei_usb_add_endpoint(&devices[devcount], transfer_type,
+ endpoint->bEndpointAddress, direction);
+ }
/* ignore currently unsupported endpoints */
else {
DBG (5, "sanei_usb_open: ignoring %s-%s endpoint "
"(address: %d)\n",
- transfer_type == USB_ENDPOINT_TYPE_CONTROL ? "control" :
- transfer_type == USB_ENDPOINT_TYPE_ISOCHRONOUS
- ? "isochronous" : "interrupt",
- direction ? "in" : "out", address);
+ sanei_usb_transfer_type_desc(transfer_type),
+ direction ? "in" : "out", address);
continue;
}
break;
@@ -2344,8 +2169,8 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
if (ret < 0)
{
- DBG (1, "sanei_usb_read_bulk: read failed: %s\n",
- sanei_libusb_strerror (ret));
+ DBG (1, "sanei_usb_read_bulk: read failed (still got %d bytes): %s\n",
+ rsize, sanei_libusb_strerror (ret));
read_size = -1;
}
@@ -2372,9 +2197,10 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
#ifdef HAVE_USBCALLS
int rc;
char* buffer_ptr = (char*) buffer;
- while (*size)
+ size_t requested_size = *size;
+ while (requested_size)
{
- ULONG ulToRead = (*size>MAX_RW)?MAX_RW:*size;
+ ULONG ulToRead = (requested_size>MAX_RW)?MAX_RW:requested_size;
ULONG ulNum = ulToRead;
DBG (5, "Entered usbcalls UsbBulkRead with dn = %d\n",dn);
DBG (5, "Entered usbcalls UsbBulkRead with dh = %p\n",dh);
@@ -2392,7 +2218,7 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)
return SANE_STATUS_INVAL;
}
if (rc || (ulNum!=ulToRead)) return SANE_STATUS_INVAL;
- *size -=ulToRead;
+ requested_size -=ulToRead;
buffer_ptr += ulToRead;
read_size += ulToRead;
}
@@ -2529,11 +2355,12 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)
DBG (5, "Entered usbcalls UsbBulkWrite with bulk_out_ep = 0x%02x\n",devices[dn].bulk_out_ep);
DBG (5, "Entered usbcalls UsbBulkWrite with interface_nr = %d\n",devices[dn].interface_nr);
DBG (5, "Entered usbcalls UsbBulkWrite with usbcalls_timeout = %d\n",usbcalls_timeout);
- while (*size)
+ size_t requested_size = *size;
+ while (requested_size)
{
- ULONG ulToWrite = (*size>MAX_RW)?MAX_RW:*size;
+ ULONG ulToWrite = (requested_size>MAX_RW)?MAX_RW:requested_size;
- DBG (5, "size requested to write = %lu, ulToWrite = %lu\n",(unsigned long) *size,ulToWrite);
+ DBG (5, "size requested to write = %lu, ulToWrite = %lu\n",(unsigned long) requested_size,ulToWrite);
if (devices[dn].bulk_out_ep){
rc = UsbBulkWrite (dh, devices[dn].bulk_out_ep, devices[dn].interface_nr,
ulToWrite, (char*) buffer, usbcalls_timeout);
@@ -2545,10 +2372,10 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)
return SANE_STATUS_INVAL;
}
if (rc) return SANE_STATUS_INVAL;
- *size -=ulToWrite;
+ requested_size -=ulToWrite;
buffer += ulToWrite;
write_size += ulToWrite;
- DBG (5, "size = %d, write_size = %d\n",*size, write_size);
+ DBG (5, "size = %d, write_size = %d\n", requested_size, write_size);
}
#else /* not HAVE_USBCALLS */
{
@@ -2619,7 +2446,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
}
if ((rtype & 0x80) && debug_level > 10)
print_buffer (data, len);
- return SANE_STATUS_GOOD;
#elif defined(__BEOS__)
struct usb_scanner_ioctl_ctrlmsg c;
@@ -2638,8 +2464,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
}
if ((rtype & 0x80) && debug_level > 10)
print_buffer (data, len);
-
- return SANE_STATUS_GOOD;
#else /* not __linux__ */
DBG (5, "sanei_usb_control_msg: not supported on this OS\n");
return SANE_STATUS_UNSUPPORTED;
@@ -2661,7 +2485,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
}
if ((rtype & 0x80) && debug_level > 10)
print_buffer (data, len);
- return SANE_STATUS_GOOD;
}
#elif defined(HAVE_LIBUSB)
{
@@ -2678,7 +2501,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
}
if ((rtype & 0x80) && debug_level > 10)
print_buffer (data, len);
- return SANE_STATUS_GOOD;
}
#else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB*/
{
@@ -2702,7 +2524,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
}
if ((rtype & 0x80) && debug_level > 10)
print_buffer (data, len);
- return SANE_STATUS_GOOD;
#else /* not HAVE_USBCALLS */
{
DBG (1, "sanei_usb_control_msg: usbcalls support missing\n");
@@ -2716,6 +2537,7 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,
devices[dn].method);
return SANE_STATUS_UNSUPPORTED;
}
+ return SANE_STATUS_GOOD;
}
SANE_Status
@@ -3160,7 +2982,6 @@ sanei_usb_get_descriptor( SANE_Int dn,
desc->dev_sub_class = usb_descr->bDeviceSubClass;
desc->dev_protocol = usb_descr->bDeviceProtocol;
desc->max_packet_size = usb_descr->bMaxPacketSize0;
- return SANE_STATUS_GOOD;
}
#elif defined(HAVE_LIBUSB)
{
@@ -3185,7 +3006,6 @@ sanei_usb_get_descriptor( SANE_Int dn,
desc->dev_sub_class = lu_desc.bDeviceSubClass;
desc->dev_protocol = lu_desc.bDeviceProtocol;
desc->max_packet_size = lu_desc.bMaxPacketSize0;
- return SANE_STATUS_GOOD;
}
#else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
{
@@ -3193,4 +3013,5 @@ sanei_usb_get_descriptor( SANE_Int dn,
return SANE_STATUS_UNSUPPORTED;
}
#endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */
+ return SANE_STATUS_GOOD;
}