| Index: src/libusb1-glue.c
|
| diff --git a/src/libusb1-glue.c b/src/libusb1-glue.c
|
| index 187c485fd1ded2dcabdda042db56c03284c6c76a..2ae89c415db89e656947fed19f21c6b3fc48c4d7 100644
|
| --- a/src/libusb1-glue.c
|
| +++ b/src/libusb1-glue.c
|
| @@ -77,18 +77,11 @@ struct mtpdevice_list_struct {
|
| };
|
| typedef struct mtpdevice_list_struct mtpdevice_list_t;
|
|
|
| -struct ptp_event_cb_data {
|
| - PTPEventCbFn cb;
|
| - void *user_data;
|
| - PTPParams *params;
|
| -};
|
| -
|
| static const LIBMTP_device_entry_t mtp_device_table[] = {
|
| /* We include an .h file which is shared between us and libgphoto2 */
|
| #include "music-players.h"
|
| };
|
| -static const int mtp_device_table_size =
|
| - sizeof(mtp_device_table) / sizeof(LIBMTP_device_entry_t);
|
| +static const int mtp_device_table_size = sizeof(mtp_device_table) / sizeof(LIBMTP_device_entry_t);
|
|
|
| // Local functions
|
| static LIBMTP_error_number_t init_usb();
|
| @@ -103,14 +96,10 @@ static int find_interface_and_endpoints(libusb_device *dev,
|
| int* outep_maxpacket,
|
| int* intep);
|
| static void clear_stall(PTP_USB* ptp_usb);
|
| -static int init_ptp_usb(PTPParams* params,
|
| - PTP_USB* ptp_usb, libusb_device* dev);
|
| -static short ptp_write_func(unsigned long,
|
| - PTPDataHandler*, void *data, unsigned long*);
|
| -static short ptp_read_func (unsigned long,
|
| - PTPDataHandler*, void *data, unsigned long*, int);
|
| -static int usb_get_endpoint_status(PTP_USB* ptp_usb,
|
| - int ep, uint16_t* status);
|
| +static int init_ptp_usb (PTPParams* params, PTP_USB* ptp_usb, libusb_device* dev);
|
| +static short ptp_write_func (unsigned long,PTPDataHandler*,void *data,unsigned long*);
|
| +static short ptp_read_func (unsigned long,PTPDataHandler*,void *data,unsigned long*,int);
|
| +static int usb_get_endpoint_status(PTP_USB* ptp_usb, int ep, uint16_t* status);
|
|
|
| /**
|
| * Get a list of the supported USB devices.
|
| @@ -130,8 +119,7 @@ static int usb_get_endpoint_status(PTP_USB* ptp_usb,
|
| * @return 0 if the list was successfull retrieved, any other
|
| * value means failure.
|
| */
|
| -int LIBMTP_Get_Supported_Devices_List(LIBMTP_device_entry_t ** const devices,
|
| - int * const numdevs)
|
| +int LIBMTP_Get_Supported_Devices_List(LIBMTP_device_entry_t ** const devices, int * const numdevs)
|
| {
|
| *devices = (LIBMTP_device_entry_t *) &mtp_device_table;
|
| *numdevs = mtp_device_table_size;
|
| @@ -141,38 +129,32 @@ int LIBMTP_Get_Supported_Devices_List(LIBMTP_device_entry_t ** const devices,
|
|
|
| static LIBMTP_error_number_t init_usb()
|
| {
|
| - static int libusb1_initialized = 0;
|
| -
|
| /*
|
| * Some additional libusb debugging please.
|
| * We use the same level debug between MTP and USB.
|
| */
|
| - if (libusb1_initialized)
|
| - return LIBMTP_ERROR_NONE;
|
| -
|
| if (libusb_init(NULL) < 0) {
|
| LIBMTP_ERROR("Libusb1 init failed\n");
|
| return LIBMTP_ERROR_USB_LAYER;
|
| }
|
|
|
| - libusb1_initialized = 1;
|
| -
|
| if ((LIBMTP_debug & LIBMTP_DEBUG_USB) != 0)
|
| libusb_set_debug(NULL,9);
|
| return LIBMTP_ERROR_NONE;
|
| }
|
|
|
| /**
|
| - * Small recursive function to append a new usb_device to the linked
|
| - * list of USB MTP devices
|
| - * @param devlist dynamic linked list of pointers to usb devices with
|
| - * MTP properties, to be extended with new device.
|
| + * Small recursive function to append a new usb_device to the linked list of
|
| + * USB MTP devices
|
| + * @param devlist dynamic linked list of pointers to usb devices with MTP
|
| + * properties, to be extended with new device.
|
| * @param newdevice the new device to add.
|
| * @param bus_location bus for this device.
|
| * @return an extended array or NULL on failure.
|
| */
|
| static mtpdevice_list_t *append_to_mtpdevice_list(mtpdevice_list_t *devlist,
|
| libusb_device *newdevice,
|
| +
|
| uint32_t bus_location)
|
| {
|
| mtpdevice_list_t *new_list_entry;
|
| @@ -310,8 +292,8 @@ static int probe_device_descriptor(libusb_device *dev, FILE *dumpfile)
|
| }
|
|
|
| /*
|
| - * TODO: Check for Still Image Capture class with PIMA 15740
|
| - * protocol, also known as PTP
|
| + * Check for Still Image Capture class with PIMA 15740 protocol,
|
| + * also known as PTP
|
| */
|
| if (intf->bInterfaceClass == LIBUSB_CLASS_PTP
|
| && intf->bInterfaceSubClass == 0x01
|
| @@ -356,7 +338,6 @@ static int probe_device_descriptor(libusb_device *dev, FILE *dumpfile)
|
| LIBUSB_CLASS_MASS_STORAGE) {
|
| LIBMTP_INFO("avoid probing device using attached kernel interface\n");
|
| libusb_free_config_descriptor(config);
|
| - libusb_close(devh);
|
| return 0;
|
| }
|
| }
|
| @@ -590,11 +571,13 @@ int LIBMTP_Check_Specific_Device(int busno, int devno)
|
|
|
| nrofdevs = libusb_get_device_list (NULL, &devs);
|
| for (i = 0; i < nrofdevs ; i++ ) {
|
| +
|
| if (libusb_get_bus_number(devs[i]) != busno)
|
| - continue;
|
| + continue;
|
| if (libusb_get_device_address(devs[i]) != devno)
|
| - continue;
|
| - if (probe_device_descriptor(devs[i], NULL))
|
| + continue;
|
| +
|
| + if (probe_device_descriptor(devs[i], NULL))
|
| return 1;
|
| }
|
| return 0;
|
| @@ -688,7 +671,18 @@ LIBMTP_error_number_t LIBMTP_Detect_Raw_Devices(LIBMTP_raw_device_t ** devices,
|
| }
|
| }
|
| if (!device_known) {
|
| - device_unknown(i, desc.idVendor, desc.idProduct);
|
| + // This device is unknown to the developers
|
| + LIBMTP_ERROR("Device %d (VID=%04x and PID=%04x) is UNKNOWN.\n",
|
| + i,
|
| + desc.idVendor,
|
| + desc.idProduct);
|
| + LIBMTP_ERROR("Please report this VID/PID and the device model to the "
|
| + "libmtp development team\n");
|
| + /*
|
| + * Trying to get iManufacturer or iProduct from the device at this
|
| + * point would require opening a device handle, that we don't want
|
| + * to do right now. (Takes time for no good enough reason.)
|
| + */
|
| }
|
| // Save the location on the bus
|
| retdevs[i].bus_location = libusb_get_bus_number (dev->device);
|
| @@ -830,25 +824,10 @@ ptp_read_func (
|
| int ret = 0;
|
| int xread;
|
| unsigned long curread = 0;
|
| + unsigned long written;
|
| unsigned char *bytes;
|
| int expect_terminator_byte = 0;
|
| - unsigned long usb_inep_maxpacket_size;
|
| - unsigned long context_block_size_1;
|
| - unsigned long context_block_size_2;
|
| - uint16_t ptp_dev_vendor_id = ptp_usb->rawdevice.device_entry.vendor_id;
|
| -
|
| - //"iRiver" device special handling
|
| - if (ptp_dev_vendor_id == 0x4102 || ptp_dev_vendor_id == 0x1006) {
|
| - usb_inep_maxpacket_size = ptp_usb->inep_maxpacket;
|
| - if (usb_inep_maxpacket_size == 0x400) {
|
| - context_block_size_1 = CONTEXT_BLOCK_SIZE_1 - 0x200;
|
| - context_block_size_2 = CONTEXT_BLOCK_SIZE_2 + 0x200;
|
| - }
|
| - else {
|
| - context_block_size_1 = CONTEXT_BLOCK_SIZE_1;
|
| - context_block_size_2 = CONTEXT_BLOCK_SIZE_2;
|
| - }
|
| - }
|
| +
|
| // This is the largest block we'll need to read in.
|
| bytes = malloc(CONTEXT_BLOCK_SIZE);
|
| while (curread < size) {
|
| @@ -866,21 +845,16 @@ ptp_read_func (
|
| expect_terminator_byte = 1;
|
| }
|
| }
|
| - else if (ptp_dev_vendor_id == 0x4102 || ptp_dev_vendor_id == 0x1006) {
|
| - //"iRiver" device special handling
|
| - if (curread == 0)
|
| - // we are first packet, but not last packet
|
| - toread = context_block_size_1;
|
| - else if (toread == context_block_size_1)
|
| - toread = context_block_size_2;
|
| - else if (toread == context_block_size_2)
|
| - toread = context_block_size_1;
|
| - else
|
| - LIBMTP_INFO("unexpected toread size 0x%04x, 0x%04x remaining bytes\n",
|
| - (unsigned int) toread, (unsigned int) (size-curread));
|
| - }
|
| + else if (curread == 0)
|
| + // we are first packet, but not last packet
|
| + toread = CONTEXT_BLOCK_SIZE_1;
|
| + else if (toread == CONTEXT_BLOCK_SIZE_1)
|
| + toread = CONTEXT_BLOCK_SIZE_2;
|
| + else if (toread == CONTEXT_BLOCK_SIZE_2)
|
| + toread = CONTEXT_BLOCK_SIZE_1;
|
| else
|
| - toread = CONTEXT_BLOCK_SIZE;
|
| + LIBMTP_INFO("unexpected toread size 0x%04x, 0x%04x remaining bytes\n",
|
| + (unsigned int) toread, (unsigned int) (size-curread));
|
|
|
| LIBMTP_USB_DEBUG("Reading in 0x%04lx bytes\n", toread);
|
|
|
| @@ -910,7 +884,7 @@ ptp_read_func (
|
| xread--;
|
| }
|
|
|
| - int putfunc_ret = handler->putfunc(NULL, handler->priv, xread, bytes);
|
| + int putfunc_ret = handler->putfunc(NULL, handler->priv, xread, bytes, &written);
|
| if (putfunc_ret != PTP_RC_OK)
|
| return putfunc_ret;
|
|
|
| @@ -984,7 +958,7 @@ ptp_write_func (
|
| }
|
| while (curwrite < size) {
|
| unsigned long usbwritten = 0;
|
| - int xwritten = 0;
|
| + int xwritten;
|
|
|
| towrite = size-curwrite;
|
| if (towrite > CONTEXT_BLOCK_SIZE) {
|
| @@ -1093,7 +1067,8 @@ memory_getfunc(PTPParams* params, void* private,
|
|
|
| static uint16_t
|
| memory_putfunc(PTPParams* params, void* private,
|
| - unsigned long sendlen, unsigned char *data
|
| + unsigned long sendlen, unsigned char *data,
|
| + unsigned long *putlen
|
| ) {
|
| PTPMemHandlerPrivate* priv = (PTPMemHandlerPrivate*)private;
|
|
|
| @@ -1103,6 +1078,7 @@ memory_putfunc(PTPParams* params, void* private,
|
| }
|
| memcpy (priv->data + priv->curoff, data, sendlen);
|
| priv->curoff += sendlen;
|
| + *putlen = sendlen;
|
| return PTP_RC_OK;
|
| }
|
|
|
| @@ -1164,7 +1140,7 @@ ptp_exit_recv_memory_handler (PTPDataHandler *handler,
|
| /* send / receive functions */
|
|
|
| uint16_t
|
| -ptp_usb_sendreq (PTPParams* params, PTPContainer* req, int dataphase)
|
| +ptp_usb_sendreq (PTPParams* params, PTPContainer* req)
|
| {
|
| uint16_t ret;
|
| PTPUSBBulkContainer usbreq;
|
| @@ -1174,7 +1150,7 @@ ptp_usb_sendreq (PTPParams* params, PTPContainer* req, int dataphase)
|
|
|
| char txt[256];
|
|
|
| - (void) ptp_render_ofc (params, req->Code, sizeof(txt), txt);
|
| + (void) ptp_render_opcode (params, req->Code, sizeof(txt), txt);
|
| LIBMTP_USB_DEBUG("REQUEST: 0x%04x, %s\n", req->Code, txt);
|
|
|
| /* build appropriate USB container */
|
| @@ -1213,13 +1189,13 @@ ptp_usb_sendreq (PTPParams* params, PTPContainer* req, int dataphase)
|
|
|
| uint16_t
|
| ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
|
| - uint64_t size, PTPDataHandler *handler
|
| + unsigned long size, PTPDataHandler *handler
|
| ) {
|
| uint16_t ret;
|
| int wlen, datawlen;
|
| unsigned long written;
|
| PTPUSBBulkContainer usbdata;
|
| - uint64_t bytes_left_to_transfer;
|
| + uint32_t bytes_left_to_transfer;
|
| PTPDataHandler memhandler;
|
|
|
|
|
| @@ -1281,10 +1257,6 @@ static uint16_t ptp_usb_getpacket(PTPParams *params,
|
| PTPDataHandler memhandler;
|
| uint16_t ret;
|
| unsigned char *x = NULL;
|
| - unsigned long packet_size;
|
| - PTP_USB *ptp_usb = (PTP_USB *) params->data;
|
| -
|
| - packet_size = ptp_usb->inep_maxpacket;
|
|
|
| /* read the header and potentially the first data */
|
| if (params->response_packet_size > 0) {
|
| @@ -1298,7 +1270,7 @@ static uint16_t ptp_usb_getpacket(PTPParams *params,
|
| return PTP_RC_OK;
|
| }
|
| ptp_init_recv_memory_handler (&memhandler);
|
| - ret = ptp_read_func(packet_size, &memhandler, params->data, rlen, 0);
|
| + ret = ptp_read_func(PTP_USB_BULK_HS_MAX_PACKET_LEN_READ, &memhandler, params->data, rlen, 0);
|
| ptp_exit_recv_memory_handler (&memhandler, &x, rlen);
|
| if (x) {
|
| memcpy (packet, x, *rlen);
|
| @@ -1312,6 +1284,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
|
| {
|
| uint16_t ret;
|
| PTPUSBBulkContainer usbdata;
|
| + unsigned long written;
|
| PTP_USB *ptp_usb = (PTP_USB *) params->data;
|
| int putfunc_ret;
|
|
|
| @@ -1353,11 +1326,12 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
|
| break;
|
| }
|
| }
|
| - if (rlen == ptp_usb->inep_maxpacket) {
|
| + if (usbdata.length == 0xffffffffU) {
|
| /* Copy first part of data to 'data' */
|
| putfunc_ret =
|
| handler->putfunc(
|
| - params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN, usbdata.payload.data
|
| + params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN, usbdata.payload.data,
|
| + &written
|
| );
|
| if (putfunc_ret != PTP_RC_OK)
|
| return putfunc_ret;
|
| @@ -1368,7 +1342,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
|
| uint16_t xret;
|
|
|
| xret = ptp_read_func(
|
| - 0x20000000,
|
| + PTP_USB_BULK_HS_MAX_PACKET_LEN_READ,
|
| handler,
|
| params->data,
|
| &readdata,
|
| @@ -1376,7 +1350,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
|
| );
|
| if (xret != PTP_RC_OK)
|
| return xret;
|
| - if (readdata < 0x20000000)
|
| + if (readdata < PTP_USB_BULK_HS_MAX_PACKET_LEN_READ)
|
| break;
|
| }
|
| return PTP_RC_OK;
|
| @@ -1427,13 +1401,14 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
|
| putfunc_ret =
|
| handler->putfunc(
|
| params, handler->priv, rlen - PTP_USB_BULK_HDR_LEN,
|
| - usbdata.payload.data
|
| + usbdata.payload.data,
|
| + &written
|
| );
|
| if (putfunc_ret != PTP_RC_OK)
|
| return putfunc_ret;
|
|
|
| if (FLAG_NO_ZERO_READS(ptp_usb) &&
|
| - len+PTP_USB_BULK_HDR_LEN == ptp_usb->inep_maxpacket) {
|
| + len+PTP_USB_BULK_HDR_LEN == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ) {
|
|
|
| LIBMTP_USB_DEBUG("Reading in extra terminating byte\n");
|
|
|
| @@ -1448,8 +1423,8 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, PTPDataHandler *handler)
|
| ptp_usb->timeout);
|
|
|
| if (result != 1)
|
| - LIBMTP_INFO("Could not read in extra byte for %d byte long file, return value 0x%04x\n", ptp_usb->inep_maxpacket, result);
|
| - } else if (len+PTP_USB_BULK_HDR_LEN == ptp_usb->inep_maxpacket && params->split_header_data == 0) {
|
| + LIBMTP_INFO("Could not read in extra byte for PTP_USB_BULK_HS_MAX_PACKET_LEN_READ long file, return value 0x%04x\n", result);
|
| + } else if (len+PTP_USB_BULK_HDR_LEN == PTP_USB_BULK_HS_MAX_PACKET_LEN_READ && params->split_header_data == 0) {
|
| int zeroresult = 0, xread;
|
| unsigned char zerobyte = 0;
|
|
|
| @@ -1560,14 +1535,12 @@ ptp_usb_event (PTPParams* params, PTPContainer* event, int wait)
|
| int result, xread;
|
| unsigned long rlen;
|
| PTPUSBEventContainer usbevent;
|
| - PTP_USB *ptp_usb;
|
| + PTP_USB *ptp_usb = (PTP_USB *)(params->data);
|
|
|
| memset(&usbevent,0,sizeof(usbevent));
|
|
|
| if ((params==NULL) || (event==NULL))
|
| return PTP_ERROR_BADPARAM;
|
| - ptp_usb = (PTP_USB *)(params->data);
|
| -
|
| ret = PTP_RC_OK;
|
| switch(wait) {
|
| case PTP_EVENT_CHECK:
|
| @@ -1640,109 +1613,6 @@ ptp_usb_event_wait (PTPParams* params, PTPContainer* event) {
|
| return ptp_usb_event (params, event, PTP_EVENT_CHECK);
|
| }
|
|
|
| -static void
|
| -ptp_usb_event_cb (struct libusb_transfer *t) {
|
| - struct ptp_event_cb_data *data = t->user_data;
|
| - PTPParams *params = data->params;
|
| - PTPUSBEventContainer *usbevent = (void *)t->buffer;
|
| - PTPContainer event = {0,};
|
| - uint16_t code;
|
| -
|
| - switch (t->status) {
|
| - case LIBUSB_TRANSFER_COMPLETED:
|
| - if (t->actual_length < 8) {
|
| - libusb_glue_error (params,
|
| - "PTP: reading event an short read of %ld bytes occurred\n",
|
| - t->actual_length);
|
| - code = PTP_ERROR_IO;
|
| - } else {
|
| - event.Code=dtoh16(usbevent->code);
|
| - event.SessionID=params->session_id;
|
| - event.Transaction_ID=dtoh32(usbevent->trans_id);
|
| - event.Param1=dtoh32(usbevent->param1);
|
| - event.Param2=dtoh32(usbevent->param2);
|
| - event.Param3=dtoh32(usbevent->param3);
|
| - code = PTP_RC_OK;
|
| - }
|
| - break;
|
| - case LIBUSB_TRANSFER_TIMED_OUT:
|
| - code = PTP_ERROR_TIMEOUT;
|
| - break;
|
| - case LIBUSB_TRANSFER_CANCELLED:
|
| - code = PTP_ERROR_CANCEL;
|
| - break;
|
| - case LIBUSB_TRANSFER_STALL:
|
| - code = PTP_ERROR_DATA_EXPECTED;
|
| - break;
|
| - case LIBUSB_TRANSFER_ERROR:
|
| - case LIBUSB_TRANSFER_NO_DEVICE:
|
| - case LIBUSB_TRANSFER_OVERFLOW:
|
| - default:
|
| - code = PTP_ERROR_IO;
|
| - break;
|
| - }
|
| - if (code != PTP_RC_OK) {
|
| - libusb_glue_error (params,
|
| - "PTP: reading event an error 0x%02x occurred\n",
|
| - t->status);
|
| - }
|
| - data->cb(params, code, &event, data->user_data);
|
| - free(data);
|
| -}
|
| -
|
| -uint16_t
|
| -ptp_usb_event_async (PTPParams* params, PTPEventCbFn cb, void *user_data) {
|
| - PTP_USB *ptp_usb;
|
| - PTPUSBEventContainer *usbevent;
|
| - struct ptp_event_cb_data *data;
|
| - struct libusb_transfer *t;
|
| - int ret;
|
| -
|
| - if (params == NULL) {
|
| - return PTP_ERROR_BADPARAM;
|
| - }
|
| -
|
| - usbevent = calloc(1, sizeof(*usbevent));
|
| - if (usbevent == NULL) {
|
| - return PTP_ERROR_IO;
|
| - }
|
| -
|
| - data = malloc(sizeof(*data));
|
| - if (data == NULL) {
|
| - free(usbevent);
|
| - return PTP_ERROR_IO;
|
| - }
|
| -
|
| - t = libusb_alloc_transfer(0);
|
| - if (t == NULL) {
|
| - free(data);
|
| - free(usbevent);
|
| - return PTP_ERROR_IO;
|
| - }
|
| -
|
| - data->cb = cb;
|
| - data->user_data = user_data;
|
| - data->params = params;
|
| -
|
| - ptp_usb = (PTP_USB *)(params->data);
|
| - libusb_fill_interrupt_transfer(t, ptp_usb->handle, ptp_usb->intep,
|
| - (unsigned char *)usbevent, sizeof(*usbevent),
|
| - ptp_usb_event_cb, data, 0);
|
| - t->flags = LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
|
| -
|
| - ret = libusb_submit_transfer(t);
|
| - return ret == 0 ? PTP_RC_OK : PTP_ERROR_IO;
|
| -}
|
| -
|
| -/**
|
| - * Trivial wrapper around the most generic libusb method for polling for events.
|
| - * Can be used to drive asynchronous event detection.
|
| - */
|
| -int LIBMTP_Handle_Events_Timeout_Completed(struct timeval *tv, int *completed) {
|
| - /* Pass NULL for context as libmtp always uses the default context */
|
| - return libusb_handle_events_timeout_completed(NULL, tv, completed);
|
| -}
|
| -
|
| uint16_t
|
| ptp_usb_control_cancel_request (PTPParams *params, uint32_t transactionid) {
|
| PTP_USB *ptp_usb = (PTP_USB *)(params->data);
|
| @@ -1808,22 +1678,11 @@ static int init_ptp_usb(PTPParams* params, PTP_USB* ptp_usb, libusb_device* dev)
|
| * Check if the config is set to something else than what we want
|
| * to use. Only set the configuration if we absolutely have to.
|
| * Also do not bail out if we fail.
|
| - *
|
| - * Note that Darwin will not set the configuration for vendor-specific
|
| - * devices so we need to go in and set it.
|
| */
|
| ret = libusb_get_active_config_descriptor(dev, &config);
|
| if (ret != LIBUSB_SUCCESS) {
|
| perror("libusb_get_active_config_descriptor(1) failed");
|
| - fprintf(stderr, "no active configuration, trying to set configuration\n");
|
| - if (libusb_set_configuration(device_handle, ptp_usb->config) != LIBUSB_SUCCESS) {
|
| - perror("libusb_set_configuration() failed, continuing anyway...");
|
| - }
|
| - ret = libusb_get_active_config_descriptor(dev, &config);
|
| - if (ret != LIBUSB_SUCCESS) {
|
| - perror("libusb_get_active_config_descriptor(2) failed");
|
| - return -1;
|
| - }
|
| + return -1;
|
| }
|
| if (config->bConfigurationValue != ptp_usb->config) {
|
| fprintf(stderr, "desired configuration different from current, trying to set configuration\n");
|
| @@ -1939,7 +1798,7 @@ static void clear_stall(PTP_USB* ptp_usb)
|
| perror("outep: usb_get_endpoint_status()");
|
| } else if (status) {
|
| LIBMTP_INFO("Clearing stall on OUT endpoint\n");
|
| - ret = libusb_clear_halt(ptp_usb->handle, ptp_usb->outep);
|
| + ret = libusb_clear_halt (ptp_usb->handle, ptp_usb->outep);
|
| if (ret != LIBUSB_SUCCESS) {
|
| perror("usb_clear_stall_feature()");
|
| }
|
| @@ -1948,6 +1807,24 @@ static void clear_stall(PTP_USB* ptp_usb)
|
| /* TODO: do we need this for INTERRUPT (ptp_usb->intep) too? */
|
| }
|
|
|
| +static void clear_halt(PTP_USB* ptp_usb)
|
| +{
|
| + int ret;
|
| +
|
| + ret = libusb_clear_halt(ptp_usb->handle,ptp_usb->inep);
|
| + if (ret<0) {
|
| + perror("usb_clear_halt() on IN endpoint");
|
| + }
|
| + ret = libusb_clear_halt(ptp_usb->handle,ptp_usb->outep);
|
| + if (ret<0) {
|
| + perror("usb_clear_halt() on OUT endpoint");
|
| + }
|
| + ret = libusb_clear_halt(ptp_usb->handle,ptp_usb->intep);
|
| + if (ret<0) {
|
| + perror("usb_clear_halt() on INTERRUPT endpoint");
|
| + }
|
| +}
|
| +
|
| static void close_usb(PTP_USB* ptp_usb)
|
| {
|
| if (!FLAG_NO_RELEASE_INTERFACE(ptp_usb)) {
|
| @@ -1962,6 +1839,12 @@ static void close_usb(PTP_USB* ptp_usb)
|
| * STALL is persistant or not).
|
| */
|
| clear_stall(ptp_usb);
|
| + // Clear halts on any endpoints
|
| + clear_halt(ptp_usb);
|
| + // Added to clear some stuff on the OUT endpoint
|
| + // TODO: is this good on the Mac too?
|
| + // HINT: some devices may need that you comment these two out too.
|
| + libusb_clear_halt(ptp_usb->handle, ptp_usb->outep);
|
| libusb_release_interface(ptp_usb->handle, (int) ptp_usb->interface);
|
| }
|
| if (FLAG_FORCE_RESET_ON_CLOSE(ptp_usb)) {
|
| @@ -2003,11 +1886,12 @@ static int find_interface_and_endpoints(libusb_device *dev,
|
| struct libusb_config_descriptor *config;
|
|
|
| ret = libusb_get_config_descriptor(dev, i, &config);
|
| - if (ret != LIBUSB_SUCCESS)
|
| + if (ret != 0)
|
| continue;
|
|
|
| *conf = config->bConfigurationValue;
|
|
|
| + if (ret != LIBUSB_SUCCESS) continue;
|
| // Loop over each configurations interfaces
|
| for (j = 0; j < config->bNumInterfaces; j++) {
|
| uint8_t k, l;
|
| @@ -2147,7 +2031,6 @@ LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
|
|
|
| if (err) {
|
| libusb_free_device_list (devs, 0);
|
| - free (ptp_usb);
|
| LIBMTP_ERROR("LIBMTP PANIC: Unable to find interface & endpoints of device\n");
|
| return LIBMTP_ERROR_CONNECTING;
|
| }
|
| @@ -2157,7 +2040,6 @@ LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
|
|
|
| /* Attempt to initialize this device */
|
| if (init_ptp_usb(params, ptp_usb, ldevice) < 0) {
|
| - free (ptp_usb);
|
| LIBMTP_ERROR("LIBMTP PANIC: Unable to initialize device\n");
|
| libusb_free_device_list (devs, 0);
|
| return LIBMTP_ERROR_CONNECTING;
|
| @@ -2176,7 +2058,6 @@ LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
|
| if(init_ptp_usb(params, ptp_usb, ldevice) <0) {
|
| LIBMTP_ERROR("LIBMTP PANIC: Could not init USB on second attempt\n");
|
| libusb_free_device_list (devs, 0);
|
| - free (ptp_usb);
|
| return LIBMTP_ERROR_CONNECTING;
|
| }
|
|
|
| @@ -2184,7 +2065,6 @@ LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
|
| if ((ret = ptp_opensession(params, 1)) == PTP_ERROR_IO) {
|
| LIBMTP_ERROR("LIBMTP PANIC: failed to open session on second attempt\n");
|
| libusb_free_device_list (devs, 0);
|
| - free (ptp_usb);
|
| return LIBMTP_ERROR_CONNECTING;
|
| }
|
| }
|
| @@ -2202,7 +2082,6 @@ LIBMTP_error_number_t configure_usb_device(LIBMTP_raw_device_t *device,
|
| ret);
|
| libusb_release_interface(ptp_usb->handle, ptp_usb->interface);
|
| libusb_free_device_list (devs, 0);
|
| - free (ptp_usb);
|
| return LIBMTP_ERROR_CONNECTING;
|
| }
|
|
|
|
|