Quantcast

wrap up of issues

classic Classic list List threaded Threaded
296 messages Options
1234 ... 15
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

wrap up of issues

frits vanderlinden-3

hi sophia,

it might be a good idea if you could post an updated libusb.h again
before monday morning so we can see where we are and it may be less of a
shock this time (last week, I was a bit shocked to see the changes and
consequently irritated in my response)

you can hopefully assume that if there is no firm NO on an issue, you
can include the changes.

Personally, I would like to see a webrev (sophia will explain how it
works) to review the changes but you can also post the diffs.

I still have the AI to come up with new topology functions (I think we
can take much simpler approach but I don't have a firm proposal yet).

We made quite a bit of progress in cleaning up the API and I do see
light at the end of the tunnel. However, only more prototyping and
implementation will confirm that we are on the right track. I am very
pleased with the simplifications that you have suggested.

cheers


fritS



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
frits vanderlinden wrote:

> hi sophia,
>
> it might be a good idea if you could post an updated libusb.h again
> before monday morning so we can see where we are and it may be less of a
> shock this time (last week, I was a bit shocked to see the changes and
> consequently irritated in my response)
>
> you can hopefully assume that if there is no firm NO on an issue, you
> can include the changes.
>
> Personally, I would like to see a webrev (sophia will explain how it
> works) to review the changes but you can also post the diffs.
>
> I still have the AI to come up with new topology functions (I think we
> can take much simpler approach but I don't have a firm proposal yet).
>
> We made quite a bit of progress in cleaning up the API and I do see
> light at the end of the tunnel. However, only more prototyping and
> implementation will confirm that we are on the right track. I am very
> pleased with the simplifications that you have suggested.
>
I've updated libusb.h.in with most of the comments, except the license
body and the array/pointer issue. Please check if I missed anything else.

Frits,

There is a limit in the size of attached file to the list. So I cannot
send the webrev by email. I'll send it to you offline.

Thanks to all!

Sophia


#ifndef __USB_H__
#define __USB_H__

/*
 * Prototypes, structure definitions and macros.
 *
 * Copyright 2000-2005 Johannes Erdfelt <[hidden email]>
 * Copyright 2004-2007 Sun Microsystems, Inc.  All rights reserved.
 *
 * This file (and only this file) may alternatively be licensed under the
 * BSD license as well, read LICENSE for details.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <inttypes.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>

/*
 *********************************************************************
 * USB spec information
 *
 * This is all stuff grabbed from various USB specs and is pretty much
 * not subject to change
 *********************************************************************
 */

/*
 * Device and/or Interface Class codes
 */
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
#define USB_CLASS_AUDIO 1
#define USB_CLASS_COMM 2
#define USB_CLASS_HID 3
#define USB_CLASS_PHYSICAL 5
#define USB_CLASS_STILL_IMAGE 6
#define USB_CLASS_PRINTER 7
#define USB_CLASS_MASS_STORAGE 8
#define USB_CLASS_HUB 9
#define USB_CLASS_CDC_DATA 10
#define USB_CLASS_SMART_CARD 11
#define USB_CLASS_CONT_SECURITY 13
#define USB_CLASS_VIDEO 14
#define USB_CLASS_DIAGNOSTIC 0xdc
#define USB_CLASS_WIRELESS 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPEC 0xfe
#define USB_CLASS_VENDOR_SPEC 0xff

/*
 * Descriptor types
 */
#define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIG 0x02
#define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06
#define USB_DESC_TYPE_OTHER_SPEED_CONFIG 0x07
#define USB_DESC_TYPE_INTERFACE_POWER 0x08
#define USB_DESC_TYPE_OTG 0x09
#define USB_DESC_TYPE_DEBUG 0x0a
#define USB_DESC_TYPE_INTERFACE_ASSOCIATION 0x0b

/* Device descriptor */
typedef struct usb_device_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint16_t bcdUSB;
  uint8_t  bDeviceClass;
  uint8_t  bDeviceSubClass;
  uint8_t  bDeviceProtocol;
  uint8_t  bMaxPacketSize0;
  uint16_t idVendor;
  uint16_t idProduct;
  uint16_t bcdDevice;
  uint8_t  iManufacturer;
  uint8_t  iProduct;
  uint8_t  iSerialNumber;
  uint8_t  bNumConfigurations;
} usb_device_desc_t;

/* Configuration & other speed configuration descriptor */
typedef struct usb_config_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint16_t wTotalLength;
  uint8_t  bNumInterfaces;
  uint8_t  bConfigurationValue;
  uint8_t  iConfiguration;
  uint8_t  bmAttributes;
  uint8_t  bMaxPower;
} usb_config_desc_t;

/* bmAttributes for configuration desc */
#define USB_CFG_ATTR_SELFPWR 0x40
#define USB_CFG_ATTR_REMOTE_WAKEUP 0x20

/* Interface descriptor */
typedef struct usb_interface_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint8_t  bInterfaceNumber;
  uint8_t  bAlternateSetting;
  uint8_t  bNumEndpoints;
  uint8_t  bInterfaceClass;
  uint8_t  bInterfaceSubClass;
  uint8_t  bInterfaceProtocol;
  uint8_t  iInterface;
} usb_interface_desc_t;

/* Endpoint descriptor */
typedef struct usb_endpoint_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint8_t  bEndpointAddress;
  uint8_t  bmAttributes;
  uint16_t wMaxPacketSize;
  uint8_t  bInterval;
  uint8_t  bRefresh;
  uint8_t  bSynchAddress;
} usb_endpoint_desc_t;

/* bEndpointAddress for endpoint desc */
#define USB_ENDPOINT_NUM_MASK 0x0f /* endpoint number mask */
#define USB_ENDPOINT_DIR_MASK 0x80 /* direction mask */
#define USB_ENDPOINT_IN 0x80 /* IN endpoint */
#define USB_ENDPOINT_OUT 0x00 /* OUT endpoint */

/* bmAttributes for endpoint desc */
#define USB_ENDPOINT_TYPE_MASK 0x03 /* transfer type mask */
#define USB_ENDPOINT_TYPE_CONTROL 0x00 /* control transfer */
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 /* isochronous transfer */
#define USB_ENDPOINT_TYPE_BULK 0x02 /* bulk transfer */
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 /* interrupt transfer */

#define USB_ENDPOINT_SYNC_MASK 0x0c /* synchronization mask */
#define USB_ENDPOINT_SYNC_NONE 0x00 /* no synchronization */
#define USB_ENDPOINT_SYNC_ASYNC 0x04 /* asynchronous */
#define USB_ENDPOINT_SYNC_ADPT 0x08 /* adaptive */
#define USB_ENDPOINT_SYNC_SYNC 0x0c /* synchronous */

#define USB_ENDPOINT_USAGE_MASK 0x30 /* sync feedback mask */
#define USB_ENDPOINT_USAGE_DATA 0x00 /* data endpoint */
#define USB_ENDPOINT_USAGE_FEED 0x10 /* feedback endpoint */
#define USB_ENDPOINT_USAGE_IMPL_FEED 0x20 /* implicit feedback ep */

/* wMaxPacketSize for endpoint desc */
#define USB_ENDPOINT_MAX_PKTSZ_MASK 0x03ff /* Mask for packetsize bits */
#define USB_ENDPOINT_MAX_XACTS_MASK 0x0c00 /* Max Transactns/microframe */
#define USB_ENDPOINT_MAX_XACTS_SHIFT 11 /* 11 bits from end */

/* String descriptor */
typedef struct usb_string_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint8_t  bString[1];
} usb_string_desc_t;

/* Device qualifier descriptor */
typedef struct usb_device_qualif_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint16_t bcdUSB;
  uint8_t  bDeviceClass;
  uint8_t  bDeviceSubClass;
  uint8_t  bDeviceProtocol;
  uint8_t  bMaxPacketSize0;
  uint8_t  bNumConfigurations;
  uint8_t  bReserved;
} usb_device_qualif_desc_t;

/* OTG descriptor */
typedef struct usb_otg_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint8_t  bmAttributes;
} usb_otg_desc_t;

/* bmAttributes for OTG desc */
#define USB_OTG_SRP 0x00
#define USB_OTG_HNP 0x01

/* Debug descriptor */
typedef struct usb_debug_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint8_t  bDebugInEndpoint;
  uint8_t  bDebugOutEndpoint;
} usb_debug_desc_t;

/* Interface association descriptor */
typedef struct usb_interface_association_desc {
  uint8_t  bLength;
  uint8_t  bDescriptorType;
  uint8_t  bFirstInterface;
  uint8_t  bInterfaceCount;
  uint8_t  bFunctionClass;
  uint8_t  bFunctionSubClass;
  uint8_t  bFunctionProtocol;
  uint8_t  iFunction;
} usb_interface_association_desc_t;

/*
 * Standard requests
 */
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
/* 0x02 is reserved */
#define USB_REQ_SET_FEATURE 0x03
/* 0x04 is reserved */
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0a
#define USB_REQ_SET_INTERFACE 0x0b
#define USB_REQ_SYNCH_FRAME 0x0c

/* Bitmaps for bmRequestType */
#define USB_REQ_HOST_TO_DEV 0x00
#define USB_REQ_DEV_TO_HOST 0x80
#define USB_REQ_DIR_MASK 0x80

#define USB_REQ_TYPE_STANDARD (0x00 << 5)
#define USB_REQ_TYPE_CLASS (0x01 << 5)
#define USB_REQ_TYPE_VENDOR (0x02 << 5)
#define USB_REQ_TYPE_RESERVED (0x03 << 5)
#define USB_REQ_TYPE_MASK 0x60

#define USB_REQ_RECIP_DEVICE 0x00
#define USB_REQ_RECIP_INTERFACE 0x01
#define USB_REQ_RECIP_ENDPOINT 0x02
#define USB_REQ_RECIP_OTHER 0x03
#define USB_REQ_RECIP_MASK 0x1f

/* Feature selector */
#define USB_FEATURE_EP_HALT 0
#define USB_FEATURE_DEV_REMOTE_WAKEUP 1

/* Bits returned by GET_STATUS request */
#define USB_DEVICE_STATUS_SELFPWR 0x0001
#define USB_DEVICE_STATUS_REMOTE_WAKEUP 0x0002
#define USB_ENDPOINT_STATUS_HALT 0x0001

/*
 * All libusb functions return an OS independent error code
 * (ie. no OS specific errno).
 * XXX more needed
 */
#define LIBUSB_SUCCESS 0 /* Call success */
#define LIBUSB_DRIVER_FAILURE -1 /* Unspecified driver error */
#define LIBUSB_NO_RESOURCES -2 /* No resources available */
#define LIBUSB_NO_BANDWIDTH -3 /* No bandwidth available */
#define LIBUSB_NOT_SUPPORTED -4 /* Not supported by HCD */
#define LIBUSB_HC_HARDWARE_ERROR -5 /* USB host controller error */
#define LIBUSB_INVALID_PERM -6 /* Privileged operation */
#define LIBUSB_BUSY -7 /* Busy condition */
#define LIBUSB_BADARG -8 /* Invalid parameter */
#define LIBUSB_NOACCESS -9 /* Access to device denied */
#define LIBUSB_PARSE_ERROR -10 /* Data could not be parsed */
#define LIBUSB_UNKNOWN_DEVICE -11 /* Device id is stale or invalid */

#define LIBUSB_IO_STALL -50 /* Endpoint stalled */
#define LIBUSB_IO_CRC_ERROR -51 /* CRC error */
#define LIBUSB_IO_DEVICE_HUNG -52 /* Device hung */
#define LIBUSB_IO_REQ_TOO_BIG -53 /* Request too big */
#define LIBUSB_IO_BIT_STUFFING -54 /* Bit stuffing error */
#define LIBUSB_IO_UNEXPECTED_PID -55 /* Unexpected PID */
#define LIBUSB_IO_DATA_OVERRUN -56 /* Data overrun */
#define LIBUSB_IO_DATA_UNDERRUN -57 /* Data underrun */
#define LIBUSB_IO_BUFFER_OVERRUN -58 /* Buffer overrun */
#define LIBUSB_IO_BUFFER_UNDERRUN -59 /* Buffer underrun */
#define LIBUSB_IO_PID_CHECK_FAILURE -60 /* PID check failure */
#define LIBUSB_IO_DATA_TOGGLE_MISMATCH -61 /* Data toggle mismatch */
#define LIBUSB_IO_TIMEOUT -62 /* I/O timeout */
#define LIBUSB_IO_CANCELED -63 /* I/O was canceled */


/*
 ********************************
 * Library specific data types
 ********************************
 */

typedef unsigned long long libusb_device_id_t;
typedef unsigned int libusb_bus_id_t;

typedef unsigned long long libusb_dev_handle_t;

typedef enum libusb_event_type {
  USB_ATTACH = 0,
  USB_DETACH,
} libusb_event_type_t;

typedef enum libusb_transfer_type {
  USB_TYPE_ALL = 0,
  USB_TYPE_CONTROL,
  USB_TYPE_INTERRUPT,
  USB_TYPE_BULK,
  USB_TYPE_ISOCHRONOUS,
} libusb_transfer_type_t;

typedef struct libusb_handle *libusb_handle_t;
typedef struct libusb_cfg_handle *libusb_cfg_handle_t;

typedef void (*libusb_event_callback_t)(libusb_handle_t handle,
        libusb_device_id_t devid, libusb_event_type_t event_type, void *arg);

typedef void (*libusb_debug_callback_t)(libusb_handle_t handle,
        const char *fmt, va_list args);

/* Data types for I/O */

typedef struct libusb_request_result {
  int status;
  size_t transferred_bytes;
} libusb_request_result_t;

typedef struct libusb_ctrl_request {
  libusb_dev_handle_t dev;
  unsigned char interface;
  unsigned char endpoint;

  struct libusb_ctrl_setup {
    uint8_t bRequestType;
    uint8_t bRequest;
    uint16_t wValue;
    uint16_t wIndex;
    /* wLength set automatically based on buflen */
  } setup;

  void *buf;
  size_t buflen;
  long timeout;
  unsigned long flags;
} libusb_ctrl_request_t;

typedef struct libusb_intr_request {
  libusb_dev_handle_t dev;
  unsigned char interface;
  unsigned char endpoint;
  unsigned int interval; /* Can this work?? If not, better remove */
  void *buf;
  size_t buflen;
  long timeout;
  unsigned long flags;
} libusb_intr_request_t;

typedef struct libusb_bulk_request {
  libusb_dev_handle_t dev;
  unsigned char interface;
  unsigned char endpoint;
  void *buf;
  size_t buflen;
  long timeout;
  unsigned long flags;
} libusb_bulk_request_t;

typedef struct libusb_isoc_pkts {
  unsigned int num_packets;
  struct libusb_isoc_packet {
    void *buf;
    size_t buflen;
  } *packets;
} libusb_isoc_pkts_t;

typedef struct libusb_isoc_request {
  libusb_dev_handle_t dev;
  unsigned char interface;
  unsigned char endpoint;
  unsigned int start_frame;
  unsigned long flags;
  libusb_isoc_pkts_t pkts;
} libusb_isoc_request_t;

struct libusb_request_handle {
  libusb_transfer_type_t type;

  union libusb_request {
    libusb_ctrl_request_t *ctrl;
    libusb_intr_request_t *intr;
    libusb_bulk_request_t *bulk;
    libusb_isoc_request_t *isoc;
  } req;

  void (*cb)(struct libusb_request_handle *handle); /* callback */
  void *arg; /* additional arg for callback */

  libusb_request_result_t result; /* for non-isoc requests */
  libusb_request_result_t *isoc_results; /* pointer to isoc result array */
  int isoc_status; /* overall isoc transfer completion status */
};

typedef struct libusb_request_handle *libusb_request_handle_t;


/*
 ****************************************
 * Library function prototypes
 ****************************************
 */

/*
 *  libusb_init()
 *
 *   Arguments:
 * handle          - Libusb handle
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE   - Unspecified failure in kernel driver
 * LIBUSB_BADARG           - Invalid structure data
 * LIBUSB_NO_RESOURCES     - Memory allocation failures
 *
 *   Notes:
 * This function must be called before any other libusb function, and
 * it returns one libusb handle upon each call
 */
int libusb_init(libusb_handle_t *handle);

/*
 * Cleanup resources
 *
 *  libusb_fini()
 *
 *   Arguments:
 * handle          - Libusb handle
 *   Return Values:
 * none
 *
 *   Notes:
 * This function must be called at the end of each libusb application.
 * Each call to libusb_init() needs a call to libusb_fini()
 */
void libusb_fini(libusb_handle_t handle);

/*
 * Register with libusb framework for event callbacks
 *
 *  libusb_set_event_callback()  ........... Set event callback
 *
 *   Arguments:
 * handle          - Libusb handle
 * type            - Event type
 * callback        - Pointer to event callback handler or NULL to unset
 * arg             - User specified argument
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_BADARG           - Invalid structure data
 * LIBUSB_NO_RESOURCES     - Memory allocation failures
 */
int libusb_set_event_callback(libusb_handle_t handle,
        libusb_event_type_t type,
        libusb_event_callback_t callback, void *arg);

/*
 *  libusb_set_debug() ............... Specify debug level
 *
 *   Arguments:
 * handle          - Libusb handle
 * level - Debug level
 * flags - TBD
 * callback - Callback for user defined debug function
 *  If NULL, the library embedded debug function is
 *  is used and the messages will go to stderr
 *
 *   Return Values:
 * none
 *
 * Notes:
 * This function enables tracing of libusb with increasing level of detail
 */
void libusb_set_debug(libusb_handle_t handle, int level,
        int flags, libusb_debug_callback_t callback);

/*
 * Set default timeout:
 *
 *  libusb_set_default_timeout() .. Set default timeout for a request type
 *
 *   Arguments:
 * handle          - Libusb handle
 * type            - Type of transfer
 * timeout         - Timeout in milliseconds (-1 == infinite)
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES     - Memory allocation failures
 * LIBUSB_IO_*             - USB host controller errors
 */
int libusb_set_default_timeout(libusb_handle_t handle,
        libusb_transfer_type_t type, long timeout);

/*
 * Endianness conversion functions:
 *
 *  libusb_le16_to_cpu() ..... Convert LE 16 bit quantity to CPU endianess
 *  libusb_le32_to_cpu() ..... Convert LE 32 bit quantity to CPU endianess
 *
 *   Arguments:
 * data        - Pointer to data
 *
 *   Return Values  - Converted data
 */
uint16_t libusb_le16_to_cpu(uint16_t data);
uint32_t libusb_le32_to_cpu(uint32_t data);
#define libusb_cpu_to_le16 libusb_le16_to_cpu
#define libusb_cpu_to_le32 libusb_le32_to_cpu

/*
 *  libusb_strerror() ........ Return english text representation of error code
 *
 *   Arguments:
 * err         - Error code
 *
 *   Return Values  - Pointer to english text representation
 */
const char *libusb_strerror(int err);

/*
 * Unpack arbitrary little endian data (ie. descriptors)
 *  
 *  libusb_parse_data()
 *
 *   Arguments:
 * format          - String indicating the format in b, w, d, eg. "2b4dw"
 *                        which describes 2 bytes, 4 dwords, one word.
 *                        A byte (b) is 8-bits, word (w) is 16-bits,
 *                        dword (w) is 32-bits. The character '.' skips one
 *                        byte in the source. The number prefix indicates
 *                        the number of items of the subsequent type.
 * data            - Pointer to the LE data buffer
 * datalen         - Length of the data
 * structure       - Pointer to return structure where the unpacked data
 *                        will be written
 * structlen       - Length of the return structure
 * count           - Number of bytes parsed
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_PARSE_ERROR      - Data could not be parsed successfully
 *
 *   Notes:
 * for example to parse a descriptor such as:
 * struct {
 *              uint8_t         a;
 *              uint16_t        b;
 *              uint8_t         c;
 *              uint32_t        d;
 * };
 *
 * the application would call:
 *
 * rv = libusb_parse_data("bwbd", buffer, sizeof (buffer),
 *              (void *)my_descr, sizeof (my_descr), &count);
 *
 * this would result in inserting some padding to align structure
 * members on natural boundaries (this is necessary on some processors such
 * as SPARC). If you would dump memory of this structure on SPARC, you would
 * see this:
 *              uint8_t         a;
 *              uint8_t         unused;
 *              uint16_t        b;
 *              uint8_t         c;
 *              uint8_t         unused[3];
 *              uint32_t        d;
 */
int libusb_parse_data(char *format, unsigned char *data, size_t datalen,
        void *structure, size_t structlen, size_t *count);

/*
 * Bus enumeration functions:
 *
 *  libusb_get_first_bus_id() ........... Return first bus from unordered list
 *  libusb_get_next_bus_id() ............ Return next bus in unordered list
 *  libusb_get_prev_bus_id() ............ Return prev bus in unordered list
 *
 *   Arguments:
 * handle           - Libusb handle
 * busid            - Pointer to bus id token
 *                         libusb writes back the first, next or previous
 *                         busid or 0 (end of list, or error)
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE   - Bus id is no longer valid
 */
int libusb_get_first_bus_id(libusb_handle_t handle, libusb_bus_id_t *busid);
int libusb_get_next_bus_id(libusb_handle_t handle, libusb_bus_id_t *busid);
int libusb_get_prev_bus_id(libusb_handle_t handle, libusb_bus_id_t *busid);

/*
 * Device enumeration functions:
 *
 *  libusb_get_first_device_id() ........ Return 1st device from unordered list
 *  libusb_get_next_device_id() ......... Return next device in unordered list
 *  libusb_get_prev_device_id() ......... Return prev device in unordered list
 *  
 *   Arguments:
 * handle           - Libusb handle
 * busid            - Which bus, (0 all busses)
 * devid            - Pointer to device id
 *                         libusb writes back the first, next, or previous
 *                         device id or 0 (end of list or error)
 *  
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES     - Memory allocation failures
 */
int libusb_get_first_device_id(libusb_handle_t handle,
        libusb_bus_id_t busid, libusb_device_id_t *devid);
int libusb_get_next_device_id(libusb_handle_t handle,
        libusb_device_id_t *devid);
int libusb_get_prev_device_id(libusb_handle_t handle,
        libusb_device_id_t *devid);

/*
 * Get bus ID from device ID:
 *
 *  libusb_get_bus_id()
 *
 *   Arguments:
 * handle           - Libusb handle
 * devid            - Device id
 * busid            - Pointer to bus id
 *                        libusb writes back busid or 0
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 */
int libusb_get_bus_id(libusb_handle_t handle,
        libusb_device_id_t devid, libusb_bus_id_t *busid);

/*
 * Get child count:
 *
 *  libusb_get_child_count()
 *
 *   Arguments:
 * handle           - Libusb handle
 * devid            - Hub's device id
 * count            - Pointer to count where the number of children
 *                         will be returned
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_BADARG         - The device is not a hub
 */
int libusb_get_child_count(libusb_handle_t handle,
        libusb_device_id_t devid, unsigned char *count);

/*
 * Get child ID  (return ID of device at specified hub port):
 *
 *  libusb_get_child_device_id()
 *
 *   Arguments:
 * handle           - Libusb handle
 * hub_devid        - Hub's device id
 * port             - Port number (> 0 and < 128)
 * child_devid      - Pointer to child's device id
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_BADARG         - The device is not a hub
 *
 *   Notes:
 * are all devices accessible? Solaris will not allow unconstrained
 * access
 */
int libusb_get_child_device_id(libusb_handle_t handle,
        libusb_device_id_t hub_devid, int port,
        libusb_device_id_t *child_devid);

/*
 * Get device's parent's ID
 *
 *  libusb_get_parent_device_id()
 *
 *   Arguments:
 * handle           - Libusb handle
 * child_devid      - Child's device id
 * hub_devid        - Pointer to the parent's (hub's) device id
 *                         libusb writes back device id or 0
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_BADARG         - The device is a root hub
 */
int libusb_get_parent_device_id(libusb_handle_t handle,
        libusb_device_id_t child_devid,
        libusb_device_id_t *hub_devid);

/*
 * Topological depiction:
 *
 *  libusb_get_hub_path()
 *
 *   Arguments:
 * handle           - Libusb handle
 * devid            - Device id
 * buffer           - Buffer for returning path as an array of
 *                         port numbers (eg. 1.2.0 reflects port 1
 *                         on the root hub, port 2 on the external hub, and
 *                         0 terminates the list
 * buflen           - Length of buffer
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 */
int libusb_get_hub_path(libusb_handle_t handle,
        libusb_device_id_t devid, unsigned char *buffer, size_t buflen);

/*
 * Get device number:
 *
 *  libusb_get_devnum()
 *
 *   Arguments:
 * handle           - Libusb handle
 * devid            - Device id
 * devnum           - Device number
 *
 *   Return Value:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *
 *   Notes:
 * to be defined clearly
 */
int libusb_get_devnum(libusb_handle_t handle,
        libusb_device_id_t devid, unsigned char *devnum);

/*
 * Hardware pseudonyms:
 *
 *  libusb_get_device_designator() ... Return pseudonym for device
 *  libusb_get_bus_designator() ...... Return pseudonym for bus
 *
 *   Arguments:
 * handle           - Libusb handle
 * devid            - Device id
 * buffer           - Buffer for returning device id
 * buflen           - Length of buffer
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 *
 *   Notes:
 * to be defined clearly
 */
int libusb_get_device_designator(libusb_handle_t handle,
        libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
int libusb_get_bus_designator(libusb_handle_t handle,
        libusb_device_id_t devid, unsigned char *buffer, size_t buflen);

/*
 * Functions for searching for devices:
 *
 *  libusb_match_devices_by_vendor() ..... Match on vid, pid
 *  libusb_match_devices_by_class() ...... Match on class, subclass, protocol
 *  libusb_free_device_list() ............ Free the matched devid list
 *
 *   Arguments:
 * handle            - Libusb handle
 * vendor            - Vendor id
 * product           - Product id
 * devclass          - Device class
 * subclass          - Subclass
 * protocol          - Protocol
 * devids            - Pointer to the list of matched device ids
 * num_devices       - Number of devices in the list
 *
 *   Return Values
 * LIBUSB_SUCCESS
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 */
int libusb_match_devices_by_vendor(libusb_handle_t handle, int vendor,
        int product, libusb_device_id_t *devids, unsigned int *num_devices);
int libusb_match_devices_by_class(libusb_handle_t handle, int devclass,
        int subclass, int protocol, libusb_device_id_t *devids,
        unsigned int *num_devices);
void libusb_free_device_list(libusb_device_id_t *devids);

/*
 * Descriptor accessors:
 *
 * Getting standard descriptors from device
 *  libusb_get_raw_desc()
 *
 * These are for parsing the raw descriptors getting above
 *  libusb_parse_device_desc() ......... Get cooked device desc.
 *  libusb_parse_config_desc() ......... Get cooked configuration desc.
 *  libusb_parse_interface_desc() ...... Get cooked interface desc.
 *  libusb_parse_endpoint_desc() ....... Get cooked endpoint desc.
 *
 *   Arguments:
 * handle           - Libusb handle
 * devid            - Device id
 * type             - descriptor type
 * descidx          - index for config/string desc., zero for others
 * langid           - language ID for string desc., zero for others
 * buffer           - Data buffer for raw desc.
 * buflen           - Length of raw desc.
 * devdesc          - Pointer to device desc.
 * cfgidx           - Configuration index
 * cfgdesc          - Pointer to configuration desc.
 * ifcidx           - Interface index
 * alt              - Alternate setting number
 * ifcdesc          - Pointer to interface desc.
 * eptidx           - Endpoint index
 * eptdesc          - Pointer to endpoint desc.
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE   - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES     - Memory allocation failures
 * LIBUSB_IO_*             - USB host controller errors
 *
 *   Notes:
 * libusb_get_raw_desc() must be called before one can
 * get cooked descriptors. And the raw data buffer and buflen
 * are then passed to the parsing functions
 */
int libusb_get_raw_desc(libusb_handle_t handle,
        libusb_device_id_t devid, int type, int descidx,
        int langid, unsigned char *buffer, size_t buflen);
int libusb_parse_device_desc(libusb_handle_t handle,
        unsigned char *buffer, size_t buflen,
        usb_device_desc_t *devdesc);
int libusb_parse_config_desc(libusb_handle_t handle,
        unsigned char *buffer, size_t buflen,
        int cfgidx, usb_config_desc_t *cfgdesc);
int libusb_parse_interface_desc(libusb_handle_t handle,
        unsigned char *buffer, size_t buflen,
        int cfgidx, int ifcidx, int alt,
        usb_interface_desc_t *ifcdesc);
int libusb_parse_endpoint_desc(libusb_handle_t handle,
        unsigned char *buffer, size_t buflen,
        int cfgidx, int ifcidx, int alt, int eptidx,
        usb_endpoint_desc_t *eptdesc);

/*
 * Function for getting max data transfer size:
 *
 *  Arguments:
 * handle            - Libusb handle
 * bus               - Bus id
 * type              - Transfer type
 * bytes             - Max data transfer size
 *
 *  Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Bus id is not valid
 * LIBUSB_NOT_SUPPORTED  - Operation not supported
 */
int libusb_get_max_xfer_size(libusb_handle_t handle,
        libusb_bus_id_t bus, libusb_transfer_type_t type, size_t *bytes);

/*
 * Function for preparing device and making it accessable to libusb
 *
 * libusb_init_device() ......... Prepare device for using by libusb
 * libusb_fini_device() ......... Return device to original state
 *
 *  Arguments:
 * handle            - Libusb handle
 * devid             - Device id
 * flags             - TBD
 * arg               - User specified argument
 *      cfg_handle        - Handle for user to do extra configuration
 *
 *  Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Devid id is not valid
 * LIBUSB_NOT_SUPPORTED  - Operation not supported
 * More TBD
 */
int libusb_init_device(libusb_handle_t handle, libusb_device_id_t devid,
        int flags, void *arg, libusb_cfg_handle_t *cfg_handle);
int libusb_fini_device(libusb_cfg_handle_t cfg_handle);

/*
 * Device handle management:
 *
 *  libusb_open() ................ Get device handle for device_id
 *  libusb_close() ............... Free device handle
 *
 *   Arguments:
 * handle           - Libusb handle
 * devid            - Device id
 * dev              - Device handle
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_open(libusb_handle_t handle, libusb_device_id_t devid,
        libusb_dev_handle_t *dev);
int libusb_close(libusb_dev_handle_t dev);

/*
 * Extract device ID from device handle:
 *
 *  libusb_get_device_id()
 *
 *   Arguments:
 * dev              - Device handle
 * devid            - Pointer to device handle
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Device handle is no longer valid
 */
int libusb_get_device_id(libusb_dev_handle_t dev, libusb_device_id_t *devid);

/*
 * Extract libusb handle from device handle:
 *
 *  libusb_get_lib_handle()
 *
 *   Arguments:
 * dev              - Device handle
 * lib_handle       - Pointer to libusb handle
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_UNKNOWN_DEVICE - Device handle is no longer valid
 */
int libusb_get_lib_handle(libusb_dev_handle_t dev,
        libusb_handle_t *lib_handle);

/*  
 * Configuration selection:
 *  
 *  libusb_get_configuration() .... Return bConfigurationValue
 *  libusb_set_configuration() .... Set the configuration
 *
 *   Arguments:
 * dev             - Device handle
 * cfg             - Configuration value
 *      
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 *
 *   Notes:
 * libusb_set_configuration() must be called before any interface
 * on the device is claimed
 */
int libusb_get_configuration(libusb_dev_handle_t dev, int *cfg);
int libusb_set_configuration(libusb_dev_handle_t dev, int cfg);

/*
 * Interface claiming:
 *
 *  libusb_claim_interface() ........ Claim interface exclusively
 *  libusb_release_interface() ...... Release interface
 *  libusb_is_interface_claimed() ... Check if interface has been claimed
 *
 *   Arguments:
 * dev              - Device handle
 * ifc              - Interface number
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_claim_interface(libusb_dev_handle_t dev, int ifc);
int libusb_release_interface(libusb_dev_handle_t dev, int ifc);
int libusb_is_interface_claimed(libusb_dev_handle_t dev, int ifc);

/*
 * Alternate interface selection:
 *
 *  libusb_get_altsetting() ....... Get alternate setting number
 *  libusb_set_altsetting() ....... Set alternate setting
 *
 *   Arguments:
 * dev              - Device handle
 * ifc              - Interface number
 * alt              - Alternate setting number
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_get_altsetting(libusb_dev_handle_t dev, int ifc, int *alt);
int libusb_set_altsetting(libusb_dev_handle_t dev, int ifc, int alt);

/*
 * Intervention functions:
 *
 *  libusb_reset() ......... Reset device by resetting port
 *                           (Full reset not guaranteed)
 *   Arguments:
 * dev              - Device handle
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_reset(libusb_dev_handle_t dev);

/*
 * I/O functions:
 *
 *  libusb_xfer_wait()             .... Issue synchronous I/O request
 *  libusb_xfer_aio()              .... Issue asynchronous I/O request
 *
 *   Arguments:
 * handle            - Pointer to request handle
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_xfer_wait(libusb_request_handle_t handle);
int libusb_xfer_aio(libusb_request_handle_t handle);

/*
 * Abort I/O request:
 *
 *  libusb_abort() ................ Abort previously submitted I/O request
 *
 *   Arguments:
 * handle            - Pointer to request handle
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_abort(libusb_request_handle_t handle);

/*
 * I/O Support:
 *
 *  libusb_wait() ................. Wait for I/O request completion
 *  libusb_poll() ................. Poll I/O request completion status
 *
 *   Arguments:
 * num_reqs          - Number of req handles in list
 * handles           - Pointer to list of request handles
 * handle            - Request handle that has completed
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_wait(unsigned int num_reqs, libusb_request_handle_t *handles,
        libusb_request_handle_t *handle);
int libusb_poll(unsigned int num_reqs, libusb_request_handle_t *handles,
        libusb_request_handle_t *handle);


/*
 *********************************************************
 * The following data types and functions are to support
 * one request/multi-xfer mode
 *********************************************************
 */

typedef struct libusb_multi_intr_request {
  libusb_dev_handle_t dev;
  unsigned char interface;
  unsigned char endpoint;
  char **bufs; /* array of buffer pointers */
  size_t *buflens; /* array of buffer lengths */
  unsigned int num_bufs; /* buffer numbers */
  unsigned int rp; /* index of buffer to read */
  unsigned int wp; /* index of buffer to write */
  long timeout;
  unsigned long flags;
} libusb_multi_intr_request_t;

typedef struct libusb_multi_bulk_request {
  libusb_dev_handle_t dev;
  unsigned char interface;
  unsigned char endpoint;
  char **bufs; /* array of buffer pointers */
  size_t *buflens; /* array of buffer lengths */
  unsigned int num_bufs; /* buffer numbers */
  unsigned int rp; /* index of buffer to read */
  unsigned int wp; /* index of buffer to write */
  long timeout;
  unsigned long flags;
} libusb_multi_bulk_request_t;

typedef struct libusb_multi_isoc_request {
  libusb_dev_handle_t dev;
  unsigned char interface;
  unsigned char endpoint;
  unsigned int start_frame;
  unsigned long flags;
  libusb_isoc_pkts_t *pkts; /* array of pkts pointers */
  unsigned int num_pkts; /* number of pkts pointers */
  unsigned int rp; /* index of pkts to read */
  unsigned int wp; /* index of pkts to write */
} libusb_multi_isoc_request_t;

struct libusb_multi_request_handle {
  libusb_transfer_type_t type;

  union libusb_multi_request {
    libusb_multi_intr_request_t *intr;
    libusb_multi_bulk_request_t *bulk;
    libusb_multi_isoc_request_t *isoc;
  } req;

  /* callback function */
  void (*cb)(struct libusb_multi_request_handle *handle,
        unsigned int bufidx, libusb_request_result_t *result);

  void *arg; /* additional arg for callback */
};

typedef struct libusb_multi_request_handle *libusb_multi_request_handle_t;

/*
 * one request/multi-xfer I/O functions:
 *
 *  libusb_start()               .... Start multi-xfer mode I/O
 *  libusb_stop()                .... Stop multi-xfer mode I/O
 *
 *   Arguments:
 * handle            - Pointer to multi-xfer request handle
 *
 *   Return Values:
 * LIBUSB_SUCCESS
 * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
 * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 * LIBUSB_NO_RESOURCES   - Memory allocation failures
 * LIBUSB_IO_*           - USB host controller errors
 */
int libusb_start(libusb_multi_request_handle_t handle);
int libusb_stop(libusb_multi_request_handle_t handle);

#ifdef __cplusplus
}
#endif

#endif /* __USB_H__ */



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

frits vanderlinden-3
Sophia Li wrote:

>
> I've updated libusb.h.in with most of the comments, except the license

if anything, Sun's copyright needs to go. I am not quite sure why I put
it there (if I did)


> body and the array/pointer issue. Please check if I missed anything else.
>

looks good, a few comments inserted



> /* Device qualifier descriptor */
> typedef struct usb_device_qualif_desc {
>   uint8_t  bLength;
>   uint8_t  bDescriptorType;
>   uint16_t bcdUSB;
>   uint8_t  bDeviceClass;
>   uint8_t  bDeviceSubClass;
>   uint8_t  bDeviceProtocol;
>   uint8_t  bMaxPacketSize0;
>   uint8_t  bNumConfigurations;
>   uint8_t  bReserved;
> } usb_device_qualif_desc_t;
>
> /* OTG descriptor */
> typedef struct usb_otg_desc {
>   uint8_t  bLength;
>   uint8_t  bDescriptorType;
>   uint8_t  bmAttributes;
> } usb_otg_desc_t;
>
> /* bmAttributes for OTG desc */
> #define USB_OTG_SRP 0x00
> #define USB_OTG_HNP 0x01
>
> /* Debug descriptor */
> typedef struct usb_debug_desc {
>   uint8_t  bLength;
>   uint8_t  bDescriptorType;
>   uint8_t  bDebugInEndpoint;
>   uint8_t  bDebugOutEndpoint;
> } usb_debug_desc_t;
>
> /* Interface association descriptor */
> typedef struct usb_interface_association_desc {
>   uint8_t  bLength;
>   uint8_t  bDescriptorType;
>   uint8_t  bFirstInterface;
>   uint8_t  bInterfaceCount;
>   uint8_t  bFunctionClass;
>   uint8_t  bFunctionSubClass;
>   uint8_t  bFunctionProtocol;
>   uint8_t  iFunction;
> } usb_interface_association_desc_t;
>
thanks for adding these.  I would really like to avoid the situation
that an app has to include generic USB definitions from platform header
files (most likely some defines will clash with macros here)

did you check all OSs that we care about or just Solaris?



> #define LIBUSB_DRIVER_FAILURE -1 /* Unspecified driver error */

this can also be kernel failures, right?


> typedef unsigned long long libusb_device_id_t;
> typedef unsigned int libusb_bus_id_t;
>
> typedef unsigned long long libusb_dev_handle_t;
>
> typedef enum libusb_event_type {
>   USB_ATTACH = 0,
>   USB_DETACH,
> } libusb_event_type_t;

can we rename this to USB_HOT_INSERTION and USB_HOT_REMOVAL.

ATTACH and DETACH indicate driver attach, I assume, and it is quite
possible that there is no driver.

>
> typedef enum libusb_transfer_type {
>   USB_TYPE_ALL = 0,
>   USB_TYPE_CONTROL,
>   USB_TYPE_INTERRUPT,
>   USB_TYPE_BULK,
>   USB_TYPE_ISOCHRONOUS,
> } libusb_transfer_type_t;
>
> typedef struct libusb_handle *libusb_handle_t;
> typedef struct libusb_cfg_handle *libusb_cfg_handle_t;
this is not a useful handle, see below.

>
> typedef void (*libusb_event_callback_t)(libusb_handle_t handle,
> libusb_device_id_t devid, libusb_event_type_t event_type, void *arg);
>
> typedef void (*libusb_debug_callback_t)(libusb_handle_t handle,
> const char *fmt, va_list args);
>
> /* Data types for I/O */
>
> typedef struct libusb_request_result {
>   int status;
>   size_t transferred_bytes;
> } libusb_request_result_t;
>
> typedef struct libusb_ctrl_request {
>   libusb_dev_handle_t dev;
>   unsigned char interface;
>   unsigned char endpoint;
>
remove the above 3 fields (dev, interface, endpoint) and move to request
handle, see below

>   struct libusb_ctrl_setup {
>     uint8_t bRequestType;
>     uint8_t bRequest;
>     uint16_t wValue;
>     uint16_t wIndex;
>     /* wLength set automatically based on buflen */
>   } setup;
>
>   void *buf;
>   size_t buflen;
>   long timeout;
>   unsigned long flags;
> } libusb_ctrl_request_t;
>
can you add to each request:

        libusb_*_request_t *next;
        libusb_*_request_t *previous;

this allows submitting a bunch of requests in a single operation. This
is useful when the app has to breakup the request into smaller chunks.
Callbacks can either be on each request or on the last request of the
linked list.


> typedef struct libusb_intr_request {
>   libusb_dev_handle_t dev;
>   unsigned char interface;
>   unsigned char endpoint;
>   unsigned int interval; /* Can this work?? If not, better remove */

I believe we do allow this in Solaris so it is possible?  it should be
possible to poll at a lower rate than specified in the endpoint
descriptor? *HCI drivers can easily do this, that is not the issue.


>   void *buf;
>   size_t buflen;
>   long timeout;
>   unsigned long flags;
> } libusb_intr_request_t;
>
> typedef struct libusb_bulk_request {
>   libusb_dev_handle_t dev;
>   unsigned char interface;
>   unsigned char endpoint;
>   void *buf;
>   size_t buflen;
>   long timeout;
>   unsigned long flags;
> } libusb_bulk_request_t;
>
> typedef struct libusb_isoc_pkts {
>   unsigned int num_packets;
>   struct libusb_isoc_packet {
>     void *buf;
>     size_t buflen;
>   } *packets;
> } libusb_isoc_pkts_t;
>
> typedef struct libusb_isoc_request {
>   libusb_dev_handle_t dev;
>   unsigned char interface;
>   unsigned char endpoint;
>   unsigned int start_frame;
>   unsigned long flags;
>   libusb_isoc_pkts_t pkts;
> } libusb_isoc_request_t;
>
> struct libusb_request_handle {
can you move from the requests all destination info to the handle:

   libusb_dev_handle_t dev;
   unsigned char interface;
   unsigned char endpoint;


this allows using the handle repeatedly for requests to the same
endpoint and not having to set these again in each request. Also saves
bytes and code when setting up a linked list of requests

>   libusb_transfer_type_t type;
>
>   union libusb_request {
>     libusb_ctrl_request_t *ctrl;
>     libusb_intr_request_t *intr;
>     libusb_bulk_request_t *bulk;
>     libusb_isoc_request_t *isoc;
>   } req;
>
>   void (*cb)(struct libusb_request_handle *handle); /* callback */
>   void *arg; /* additional arg for callback */
>
>   libusb_request_result_t result; /* for non-isoc requests */
>   libusb_request_result_t *isoc_results; /* pointer to isoc result array */
>   int isoc_status; /* overall isoc transfer completion status */
> };
>
> typedef struct libusb_request_handle *libusb_request_handle_t;
>

>
> /*
>  ****************************************
>  * Library function prototypes
>  ****************************************
>  */
>
> /*
>  *  libusb_init()
>  *
>  *   Arguments:
>  * handle          - Libusb handle
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_DRIVER_FAILURE   - Unspecified failure in kernel driver
>  * LIBUSB_BADARG           - Invalid structure data
>  * LIBUSB_NO_RESOURCES     - Memory allocation failures
>  *
>  *   Notes:
>  * This function must be called before any other libusb function, and
>  * it returns one libusb handle upon each call
>  */
> int libusb_init(libusb_handle_t *handle);
add flags for future expansion?


> int libusb_get_first_bus_id(libusb_handle_t handle, libusb_bus_id_t *busid);
> int libusb_get_next_bus_id(libusb_handle_t handle, libusb_bus_id_t *busid);
> int libusb_get_prev_bus_id(libusb_handle_t handle, libusb_bus_id_t *busid);

replace with a single function that returns all busids


>
> /*
>  * Device enumeration functions:
>  *
>  *  libusb_get_first_device_id() ........ Return 1st device from unordered list
>  *  libusb_get_next_device_id() ......... Return next device in unordered list
>  *  libusb_get_prev_device_id() ......... Return prev device in unordered list
>  *  
>  *   Arguments:
>  * handle           - Libusb handle
>  * busid            - Which bus, (0 all busses)
>  * devid            - Pointer to device id
>  *                         libusb writes back the first, next, or previous
>  *                         device id or 0 (end of list or error)
>  *  
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
>  * LIBUSB_NO_RESOURCES     - Memory allocation failures
>  */
> int libusb_get_first_device_id(libusb_handle_t handle,
> libusb_bus_id_t busid, libusb_device_id_t *devid);
> int libusb_get_next_device_id(libusb_handle_t handle,
> libusb_device_id_t *devid);
> int libusb_get_prev_device_id(libusb_handle_t handle,
> libusb_device_id_t *devid);
replace with a single function that returns all devids


how are you going to handle that the buffer is too small. how is the app
going to find out how big its buffer should be?


> /*
>  * Get child count:
>  *
>  *  libusb_get_child_count()
>  *
>  *   Arguments:
>  * handle           - Libusb handle
>  * devid            - Hub's device id
>  * count            - Pointer to count where the number of children
>  *                         will be returned
>  *
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
>  * LIBUSB_BADARG         - The device is not a hub
>  */
> int libusb_get_child_count(libusb_handle_t handle,
> libusb_device_id_t devid, unsigned char *count);
>
is this really useful? you still don't know on which port they are

> /*
>  * Get child ID  (return ID of device at specified hub port):
>  *
>  *  libusb_get_child_device_id()
>  *
>  *   Arguments:
>  * handle           - Libusb handle
>  * hub_devid        - Hub's device id
>  * port             - Port number (> 0 and < 128)
>  * child_devid      - Pointer to child's device id
>  *
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
>  * LIBUSB_BADARG         - The device is not a hub
>  *
>  *   Notes:
>  * are all devices accessible? Solaris will not allow unconstrained
>  * access
>  */
> int libusb_get_child_device_id(libusb_handle_t handle,
> libusb_device_id_t hub_devid, int port,
> libusb_device_id_t *child_devid);
>
> /*
>  * Get device's parent's ID
>  *
>  *  libusb_get_parent_device_id()
>  *
>  *   Arguments:
>  * handle           - Libusb handle
>  * child_devid      - Child's device id
>  * hub_devid        - Pointer to the parent's (hub's) device id
>  *                         libusb writes back device id or 0
>  *
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
>  * LIBUSB_BADARG         - The device is a root hub
>  */
> int libusb_get_parent_device_id(libusb_handle_t handle,
> libusb_device_id_t child_devid,
> libusb_device_id_t *hub_devid);
>
> /*
>  * Topological depiction:
>  *
>  *  libusb_get_hub_path()
>  *
>  *   Arguments:
>  * handle           - Libusb handle
>  * devid            - Device id
>  * buffer           - Buffer for returning path as an array of
>  *                         port numbers (eg. 1.2.0 reflects port 1
>  *                         on the root hub, port 2 on the external hub, and
>  *                         0 terminates the list
>  * buflen           - Length of buffer
>  *
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
>  * LIBUSB_NO_RESOURCES   - Memory allocation failures
>  */
> int libusb_get_hub_path(libusb_handle_t handle,
> libusb_device_id_t devid, unsigned char *buffer, size_t buflen);

it seems more useful to have a single function that returns the logical
or physical pathname (whatever the platform can supply).

libusb_get_path(handle, devid, buffer, buflen)


why special-case the hub?


> int libusb_get_devnum(libusb_handle_t handle,
> libusb_device_id_t devid, unsigned char *devnum);
>

> int libusb_get_device_designator(libusb_handle_t handle,
> libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
> int libusb_get_bus_designator(libusb_handle_t handle,
> libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>

remove these, I don't see the point anymore. An app can figure out the
topology by starting at the root hub and look at each port using devids.
why introduce devnums and designators?



> /*
>  * Functions for searching for devices:
>  *
>  *  libusb_match_devices_by_vendor() ..... Match on vid, pid
>  *  libusb_match_devices_by_class() ...... Match on class, subclass, protocol
>  *  libusb_free_device_list() ............ Free the matched devid list
>  *
>  *   Arguments:
>  * handle            - Libusb handle
>  * vendor            - Vendor id
>  * product           - Product id
>  * devclass          - Device class
>  * subclass          - Subclass
>  * protocol          - Protocol
>  * devids            - Pointer to the list of matched device ids
>  * num_devices       - Number of devices in the list
>  *
>  *   Return Values
>  * LIBUSB_SUCCESS
>  * LIBUSB_NO_RESOURCES   - Memory allocation failures
>  */
> int libusb_match_devices_by_vendor(libusb_handle_t handle, int vendor,
> int product, libusb_device_id_t *devids, unsigned int *num_devices);
> int libusb_match_devices_by_class(libusb_handle_t handle, int devclass,
> int subclass, int protocol, libusb_device_id_t *devids,
> unsigned int *num_devices);
> void libusb_free_device_list(libusb_device_id_t *devids);
remove.  see above. A single function that either returns all devids or
devids which match vid/pid or class/protocol


>
> /*
>  * Descriptor accessors:
>  *
>  * Getting standard descriptors from device
>  *  libusb_get_raw_desc()
>  *
>  * These are for parsing the raw descriptors getting above
>  *  libusb_parse_device_desc() ......... Get cooked device desc.
>  *  libusb_parse_config_desc() ......... Get cooked configuration desc.
>  *  libusb_parse_interface_desc() ...... Get cooked interface desc.
>  *  libusb_parse_endpoint_desc() ....... Get cooked endpoint desc.
>  *
>  *   Arguments:
>  * handle           - Libusb handle
>  * devid            - Device id
>  * type             - descriptor type
>  * descidx          - index for config/string desc., zero for others
>  * langid           - language ID for string desc., zero for others
>  * buffer           - Data buffer for raw desc.
>  * buflen           - Length of raw desc.
>  * devdesc          - Pointer to device desc.
>  * cfgidx           - Configuration index
>  * cfgdesc          - Pointer to configuration desc.
>  * ifcidx           - Interface index
>  * alt              - Alternate setting number
>  * ifcdesc          - Pointer to interface desc.
>  * eptidx           - Endpoint index
>  * eptdesc          - Pointer to endpoint desc.
>  *
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_DRIVER_FAILURE   - Unspecified failure in kernel driver
>  * LIBUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
>  * LIBUSB_NO_RESOURCES     - Memory allocation failures
>  * LIBUSB_IO_*             - USB host controller errors
>  *
>  *   Notes:
>  * libusb_get_raw_desc() must be called before one can
>  * get cooked descriptors. And the raw data buffer and buflen
>  * are then passed to the parsing functions
>  */
> int libusb_get_raw_desc(libusb_handle_t handle,
> libusb_device_id_t devid, int type, int descidx,
> int langid, unsigned char *buffer, size_t buflen);
so how do I get the config cloud with this function?



>
> /*
>  * Function for preparing device and making it accessable to libusb
>  *
>  * libusb_init_device() ......... Prepare device for using by libusb
>  * libusb_fini_device() ......... Return device to original state
>  *
>  *  Arguments:
>  * handle            - Libusb handle
>  * devid             - Device id
>  * flags             - TBD
>  * arg               - User specified argument
>  *      cfg_handle        - Handle for user to do extra configuration
>  *
>  *  Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_UNKNOWN_DEVICE - Devid id is not valid
>  * LIBUSB_NOT_SUPPORTED  - Operation not supported
>  * More TBD
>  */
> int libusb_init_device(libusb_handle_t handle, libusb_device_id_t devid,
> int flags, void *arg, libusb_cfg_handle_t *cfg_handle);
> int libusb_fini_device(libusb_cfg_handle_t cfg_handle);
I would prefer the device handle returned.

>
> /*
>  * Device handle management:
>  *
>  *  libusb_open() ................ Get device handle for device_id
>  *  libusb_close() ............... Free device handle
>  *
>  *   Arguments:
>  * handle           - Libusb handle
>  * devid            - Device id
>  * dev              - Device handle
>  *
>  *   Return Values:
>  * LIBUSB_SUCCESS
>  * LIBUSB_DRIVER_FAILURE - Unspecified failure in kernel driver
>  * LIBUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
>  * LIBUSB_NO_RESOURCES   - Memory allocation failures
>  * LIBUSB_IO_*           - USB host controller errors
>  */
> int libusb_open(libusb_handle_t handle, libusb_device_id_t devid,
> libusb_dev_handle_t *dev);
> int libusb_close(libusb_dev_handle_t dev);
these functions will now take the device handle as argument instead of devid

as far as I can tell, you don't use the cfg handle anywhere so what is
the point?



> int libusb_xfer_wait(libusb_request_handle_t handle);
> int libusb_xfer_aio(libusb_request_handle_t handle);

I would still like to see the wrapper functions for those apps that just
use sync I/O and do not want to bother with the request handle
(the wrapper functions just allocate a handle, initialize it, and then
call libusb_xfer_wait()
On completion, the wrapper function deletes the handle again.


please post the new file asap before we delve into new issues.

thanks


fritS



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
frits vanderlinden wrote:
> Sophia Li wrote:
>
>>
>> I've updated libusb.h.in with most of the comments, except the license
>
>
> if anything, Sun's copyright needs to go. I am not quite sure why I put
> it there (if I did)

The license body in libusb.h.in file is BSD license. The original
license term means the file and only this file can be either licensed
under LGPL or under BSD. All other files should be licensed under LGPL.

No matter LGPL or BSD license is used, both require the copyright
statement as part of the license body. If we take the copyright
statements away, how can we keep the license consistent to its original
form? Does anyone observe such a real practice?

IMHO, anyone who contributed to the codebase should be considered as a
copyright holder even if there is no explicit copyright statement. But
that doesn't mean the project is not open, since all contributions are
done under the license terms. So long as the license terms speak in
opensource spirit, we don't need to worry about the copyrights and the
project openness.


>>
>> /* Interface association descriptor */
>> typedef struct usb_interface_association_desc {
>>   uint8_t  bLength;
>>   uint8_t  bDescriptorType;
>>   uint8_t  bFirstInterface;
>>   uint8_t  bInterfaceCount;
>>   uint8_t  bFunctionClass;
>>   uint8_t  bFunctionSubClass;
>>   uint8_t  bFunctionProtocol;
>>   uint8_t  iFunction;
>> } usb_interface_association_desc_t;
>>
>
> thanks for adding these.  I would really like to avoid the situation
> that an app has to include generic USB definitions from platform header
> files (most likely some defines will clash with macros here)
>
> did you check all OSs that we care about or just Solaris?

It is very implicit to me what the platform header files are and what we
should care about. I believe those header files include many OS specific
stuff that we don't want to include in this API file. I do look at some
of the header files for Windows, Linux and Solaris. But I've only
included all definitions for the standard device descriptor and request
operations because they are common among applications. The class
descriptors and requests are excluded. There are too many of those and I
don't think this API file is a suitable place for doing all that. It
should be handled by each client application.


>> #define    LIBUSB_DRIVER_FAILURE        -1    /* Unspecified driver
>> error */
>
> this can also be kernel failures, right?

Failure returned by kernel driver. I guess the answer is yes.

>
>
>> typedef unsigned long long libusb_device_id_t;
>> typedef unsigned int libusb_bus_id_t;
>>
>> typedef unsigned long long libusb_dev_handle_t;
>>
>> typedef enum libusb_event_type {
>>   USB_ATTACH = 0,
>>   USB_DETACH,
>> } libusb_event_type_t;
>
>
> can we rename this to USB_HOT_INSERTION and USB_HOT_REMOVAL.
>
> ATTACH and DETACH indicate driver attach, I assume, and it is quite
> possible that there is no driver.

Fine.


>> typedef struct libusb_cfg_handle *libusb_cfg_handle_t;
>
> this is not a useful handle, see below.
>

>>
>> typedef struct libusb_ctrl_request {
>>   libusb_dev_handle_t dev;
>>   unsigned char interface;
>>   unsigned char endpoint;
>>
>
> remove the above 3 fields (dev, interface, endpoint) and move to request
> handle, see below

ok

> can you add to each request:
>
>     libusb_*_request_t *next;
>     libusb_*_request_t *previous;
>
> this allows submitting a bunch of requests in a single operation. This
> is useful when the app has to breakup the request into smaller chunks.
> Callbacks can either be on each request or on the last request of the
> linked list.

Isn't this similar to the one-request/multi-response model? Shall we mix
the functionality?

>
>
>> typedef struct libusb_intr_request {
>>   libusb_dev_handle_t dev;
>>   unsigned char interface;
>>   unsigned char endpoint;
>>   unsigned int interval; /* Can this work?? If not, better remove */
>
>
> I believe we do allow this in Solaris so it is possible?  it should be
> possible to poll at a lower rate than specified in the endpoint
> descriptor? *HCI drivers can easily do this, that is not the issue.

Fine, we can keep it. But I have a question then, this structure is only
used in libusb_xfer_wait/async() functions which are suggested to be
separate with the one request/multiple response model. It means no
polling interval is necessary for this structure.

BTW: Solaris kernel doesn't support user defined interval at least now.
Seems Linux kernel supports it.

>>
>> struct libusb_request_handle {
>
>
> can you move from the requests all destination info to the handle:
>
>    libusb_dev_handle_t dev;
>    unsigned char interface;
>    unsigned char endpoint;
>
>
> this allows using the handle repeatedly for requests to the same
> endpoint and not having to set these again in each request. Also saves
> bytes and code when setting up a linked list of requests

ok.


>> int libusb_init(libusb_handle_t *handle);
>
>
> add flags for future expansion?

ok.


>
>
>> int libusb_get_first_bus_id(libusb_handle_t handle, libusb_bus_id_t
>> *busid);
>> int libusb_get_next_bus_id(libusb_handle_t handle, libusb_bus_id_t
>> *busid);
>> int libusb_get_prev_bus_id(libusb_handle_t handle, libusb_bus_id_t
>> *busid);
>
>
> replace with a single function that returns all busids

ok.

>>  */ int libusb_get_first_device_id(libusb_handle_t handle,
>>     libusb_bus_id_t busid, libusb_device_id_t *devid);
>> int libusb_get_next_device_id(libusb_handle_t handle,
>>     libusb_device_id_t *devid);
>> int libusb_get_prev_device_id(libusb_handle_t handle,
>>     libusb_device_id_t *devid);
>
>
> replace with a single function that returns all devids

We need a function to return the root-hub device id, anyway. Or it will
take extra effort for the user to find out.

Do you expect to use the single function to return all devids and make
an explicit rule that the first devid in the list should be the root-hub
device?

>
> how are you going to handle that the buffer is too small. how is the app
> going to find out how big its buffer should be?

My thought is to have the library allocate the buffer and ask the
application to free the buffer after using it. How about:

int libusb_get_bus_ids(libusb_handle_t handle,
        libusb_bus_id_t *busses, unsigned int *num_busses);
void libusb_free_bus_list(libusb_bus_id_t *busses);

int libusb_get_device_ids(libusb_handle_t handle,
        libusb_bus_id_t busid, libusb_device_id_t *devids,
        unsigned int *num_devices);
void libusb_free_device_list(libusb_device_id_t *devids);

 >> int libusb_match_devices_by_vendor(libusb_handle_t handle, int
 >> vendor, int product, libusb_device_id_t *devids,
 >> unsigned int *num_devices);
 >> int libusb_match_devices_by_class(libusb_handle_t handle, int
 >> devclass, int subclass, int protocol,
 >> libusb_device_id_t *devids, unsigned int *num_devices);
 >> void libusb_free_device_list(libusb_device_id_t *devids);
 >
 >
 > remove.  see above. A single function that either returns all devids or
 > devids which match vid/pid or class/protocol

How can we combine all the functions in one single function? We'd better
separate the functions, one to return all devids on a bus, one to return
all devids that match vid/pid, one to return all devids that match
class/protocol.



>> int libusb_get_child_count(libusb_handle_t handle,
>>     libusb_device_id_t devid, unsigned char *count);
>>
>
> is this really useful? you still don't know on which port they are

I think yes. You can know the port number by using this function first,
then call libusb_get_child_device_id().


>> int libusb_get_child_device_id(libusb_handle_t handle,
>>     libusb_device_id_t hub_devid, int port,
                                         ^^^^^ note this argument
>>     libusb_device_id_t *child_devid);
>>


>> int libusb_get_hub_path(libusb_handle_t handle,
>>     libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>
> it seems more useful to have a single function that returns the logical
> or physical pathname (whatever the platform can supply).
>
> libusb_get_path(handle, devid, buffer, buflen)
>
> why special-case the hub?

If the function returns logical path, the child device path can be
derived from the hub path, so it is not necessary to generate a path for
each device, I guess.


>
>> int libusb_get_devnum(libusb_handle_t handle,
>>     libusb_device_id_t devid, unsigned char *devnum);
>>
>
>> int libusb_get_device_designator(libusb_handle_t handle,
>>     libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>> int libusb_get_bus_designator(libusb_handle_t handle,
>>     libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>>
>
> remove these, I don't see the point anymore. An app can figure out the
> topology by starting at the root hub and look at each port using devids.
> why introduce devnums and designators?
>

I see devnum corresponds to usb address on Linux. Not sure if it is
worth to export this value to user applications. But the latter two
functions aren't meaningful at all.



>> int libusb_get_raw_desc(libusb_handle_t handle,
>>     libusb_device_id_t devid, int type, int descidx,
>>     int langid, unsigned char *buffer, size_t buflen);
>
>
> so how do I get the config cloud with this function?

*    descidx          - index for config/string desc., zero for others
*    langid           - language ID for string desc., zero for others
So, config cloud can be got by:
libusb_get_raw_desc(handle, devid, USB_DESC_TYPE_CONFIG, configidx, 0,
buffer, buflen);


>> int libusb_init_device(libusb_handle_t handle, libusb_device_id_t devid,
>>     int flags, void *arg, libusb_cfg_handle_t *cfg_handle);
>> int libusb_fini_device(libusb_cfg_handle_t cfg_handle);
>
>
> I would prefer the device handle returned.

Please be more specific in what the functions are expected to do. I
don't quite understand them right now.


>> int libusb_open(libusb_handle_t handle, libusb_device_id_t devid,
>>     libusb_dev_handle_t *dev);
>> int libusb_close(libusb_dev_handle_t dev);
>
>
> these functions will now take the device handle as argument instead of
> devid
>
> as far as I can tell, you don't use the cfg handle anywhere so what is
> the point?

Perhaps you are right. But I don't know what to do with the handle
returned by libusb_init_device() either before the device is opened.

>
>
>> int libusb_xfer_wait(libusb_request_handle_t handle);
>> int libusb_xfer_aio(libusb_request_handle_t handle);
>
>
> I would still like to see the wrapper functions for those apps that just
> use sync I/O and do not want to bother with the request handle
> (the wrapper functions just allocate a handle, initialize it, and then
> call libusb_xfer_wait()
> On completion, the wrapper function deletes the handle again.

Why make the difference? I really don't understand. This would confuse
the application programmers.

>
> please post the new file asap before we delve into new issues.

Sorry, I was working on some bugs. I'll do it tomorrow. But before I can
  post the new file, I need some answers to the above questions.


Thanks,
Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
In reply to this post by Sophia Li - Sun Microsystems - Beijing China
Robert Marquardt wrote:

> Sophia Li wrote:
>
>> /*
>>  *********************************************************************
>>  * USB spec information
>>  *
>>  * This is all stuff grabbed from various USB specs and is pretty much
>>  * not subject to change
>>  *********************************************************************
>>  */
>
>
> So why is it not extracted into a separate header file?
> I would count this as a basic design flaw.

(Please post to the list)

Some people do like to see only one file. And we are not defining header
file for general purpose. We are defining header file for just this
library. The USB spec information is a necessary part of this library.

Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
In reply to this post by Sophia Li - Sun Microsystems - Beijing China
Greg Troxel wrote:

> I do not really have time to pay attention, but I found this odd:
>
>   * This file (and only this file) may alternatively be licensed under the
>   * BSD license as well, read LICENSE for details.
>
> and then the license that follows looks like 3-clause BSD.
>
> I'm not sure what Sun's goals are, but I'd think the whole thing being
> BSD (or BSDish, but GPL-compatible) would be best.
>

We have no particular goal. This is an opensource project. We just hope
to better express the project is the effort of all community members who
contribute to it, not limited to certain people listed in the copyright
header. And the copyright statement doesn't look very nice in opensource
spirit. If we can take the copyright statement away, it would look
better. But I am not sure if we can do that.


Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Greg Troxel
  We have no particular goal. This is an opensource project. We just
  hope to better express the project is the effort of all community
  members who contribute to it, not limited to certain people listed in
  the copyright header.

Projects like FreeBSD, NetBSD, and OpenBSD avoid GPLd code, particularly
in the kernel.  So if the project intends to be broadly accepted, a BSD
license may be a better choice, at least for interface files.  On the
other hand, the GPL prohibits proprietary works, so that's the key
tradeoff - hence my query about goals.  I don't see much harm from
proprietary derivate works of a USB library, so I'd tend to BSD to make
it more widely adopted.

  And the copyright statement doesn't look very
  nice in opensource spirit. If we can take the copyright statement
  away, it would look better. But I am not sure if we can do that.

Documents simply are copyrighted, unless they are placed in the public
domain.  Absent a license to copy, people can't.  So just leaving it off
doesn't work.  You probably should talk to corporate counsel about
marking/licensing issues, and consider public domain, just granting
permission under a BSD (or GPL if you don't like that) license, or
assigning copyright to FSF (but that may result in GPL).


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

frits vanderlinden-3
In reply to this post by Sophia Li - Sun Microsystems - Beijing China
Sophia Li wrote:

>
>>
>> if anything, Sun's copyright needs to go. I am not quite sure why I
>> put it there (if I did)
>
> The license body in libusb.h.in file is BSD license. The original
> license term means the file and only this file can be either licensed
> under LGPL or under BSD. All other files should be licensed under LGPL.
>
> No matter LGPL or BSD license is used, both require the copyright
> statement as part of the license body. If we take the copyright
> statements away, how can we keep the license consistent to its original
> form? Does anyone observe such a real practice?
>
I don't follow you and don't see why removing the Sun copyright is an
issue. The "All rights reserved" is not appropriate for LGPL/BSD license

> IMHO, anyone who contributed to the codebase should be considered as a
> copyright holder even if there is no explicit copyright statement. But
> that doesn't mean the project is not open, since all contributions are
> done under the license terms. So long as the license terms speak in
> opensource spirit, we don't need to worry about the copyrights and the
> project openness.
>

Please talk to a legal person at Sun what the license should be for an
opensource project


> operations because they are common among applications. The class
> descriptors and requests are excluded. There are too many of those and I
> don't think this API file is a suitable place for doing all that. It
> should be handled by each client application.
>

that's fine. We only need to include what is in usb2.0 spec, not in
class specs


>
>>> #define    LIBUSB_DRIVER_FAILURE        -1    /* Unspecified driver
>>> error */
>>
>> this can also be kernel failures, right?
>
> Failure returned by kernel driver. I guess the answer is yes.
>

so I am still not happy with this name



>> can you add to each request:
>>
>>     libusb_*_request_t *next;
>>     libusb_*_request_t *previous;
>>
>> this allows submitting a bunch of requests in a single operation. This
>> is useful when the app has to breakup the request into smaller chunks.
>> Callbacks can either be on each request or on the last request of the
>> linked list.
>
> Isn't this similar to the one-request/multi-response model? Shall we mix
> the functionality?
>
no, this will allow you to xfer a few megabytes easily. the one-request
model can in theory go on forever.

I don't think we need the previous field. A single linked list is good
enough

>>
>>
>>> typedef struct libusb_intr_request {
>>>   libusb_dev_handle_t dev;
>>>   unsigned char interface;
>>>   unsigned char endpoint;
>>>   unsigned int interval; /* Can this work?? If not, better remove */
>>
>>
>> I believe we do allow this in Solaris so it is possible?  it should be
>> possible to poll at a lower rate than specified in the endpoint
>> descriptor? *HCI drivers can easily do this, that is not the issue.
>
> Fine, we can keep it. But I have a question then, this structure is only
> used in libusb_xfer_wait/async() functions which are suggested to be
> separate with the one request/multiple response model. It means no
> polling interval is necessary for this structure.
>

I don't understand


> BTW: Solaris kernel doesn't support user defined interval at least now.
> Seems Linux kernel supports it.
>

then we should support it



>>>  */ int libusb_get_first_device_id(libusb_handle_t handle,
>>>     libusb_bus_id_t busid, libusb_device_id_t *devid);
>>> int libusb_get_next_device_id(libusb_handle_t handle,
>>>     libusb_device_id_t *devid);
>>> int libusb_get_prev_device_id(libusb_handle_t handle,
>>>     libusb_device_id_t *devid);
>>
>>
>> replace with a single function that returns all devids
>
> We need a function to return the root-hub device id, anyway. Or it will
> take extra effort for the user to find out.
>
good idea

> Do you expect to use the single function to return all devids and make
> an explicit rule that the first devid in the list should be the root-hub
> device?
>
there are multiple root hubs because there are multiple host controllers




>>
>> how are you going to handle that the buffer is too small. how is the
>> app going to find out how big its buffer should be?
>
> My thought is to have the library allocate the buffer and ask the
> application to free the buffer after using it. How about:
>

that is leak-prone

I would prefer a simple function that returns the total number of devices


>  >
>  > remove.  see above. A single function that either returns all devids or
>  > devids which match vid/pid or class/protocol
>
> How can we combine all the functions in one single function? We'd better
> separate the functions, one to return all devids on a bus, one to return
> all devids that match vid/pid, one to return all devids that match
> class/protocol.
>

int libusb_get_devids(handle, busid, vid, pid, class, protocol, flags);

flags will indicate what the matching criteria will be

>
>
>>> int libusb_get_child_count(libusb_handle_t handle,
>>>     libusb_device_id_t devid, unsigned char *count);
>>>
>>
>> is this really useful? you still don't know on which port they are
>
> I think yes. You can know the port number by using this function first,
> then call libusb_get_child_device_id().
>

it still does not make sense to me. Even if you know the number of
children, you still have to check each port to figure out where they are.

>
>>> int libusb_get_child_device_id(libusb_handle_t handle,
>>>     libusb_device_id_t hub_devid, int port,
>                                         ^^^^^ note this argument
>>>     libusb_device_id_t *child_devid);
>>>
>

sure, but what can an app do with just knowing the number of children?

>
>>> int libusb_get_hub_path(libusb_handle_t handle,
>>>     libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>>
>> it seems more useful to have a single function that returns the
>> logical or physical pathname (whatever the platform can supply).
>>
>> libusb_get_path(handle, devid, buffer, buflen)
>>
>> why special-case the hub?
>
> If the function returns logical path, the child device path can be
> derived from the hub path, so it is not necessary to generate a path for
> each device, I guess.
>
>

I think it would be useful to get a pathname or some other platform
specific name for each device


>>
>>> int libusb_get_devnum(libusb_handle_t handle,
>>>     libusb_device_id_t devid, unsigned char *devnum);
>>>
>>
>>> int libusb_get_device_designator(libusb_handle_t handle,
>>>     libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>>> int libusb_get_bus_designator(libusb_handle_t handle,
>>>     libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>>>
>>
>> remove these, I don't see the point anymore. An app can figure out the
>> topology by starting at the root hub and look at each port using
>> devids. why introduce devnums and designators?
>>
>
> I see devnum corresponds to usb address on Linux. Not sure if it is
> worth to export this value to user applications. But the latter two
> functions aren't meaningful at all.
>
>
then call it that way

libusb_get_device_bus_address()


>>> int libusb_init_device(libusb_handle_t handle, libusb_device_id_t devid,
>>>     int flags, void *arg, libusb_cfg_handle_t *cfg_handle);
>>> int libusb_fini_device(libusb_cfg_handle_t cfg_handle);
>>
>>
>> I would prefer the device handle returned.
>
> Please be more specific in what the functions are expected to do. I
> don't quite understand them right now.
>

libusb_init_device() returns a device handle
libusb_open() takes the device handle and then opens the device
libusb_claim_interface() adds an interface to the handle

>
>>> int libusb_open(libusb_handle_t handle, libusb_device_id_t devid,
>>>     libusb_dev_handle_t *dev);
>>> int libusb_close(libusb_dev_handle_t dev);
>>
>>
>> these functions will now take the device handle as argument instead of
>> devid
>>
>> as far as I can tell, you don't use the cfg handle anywhere so what is
>> the point?
>
> Perhaps you are right. But I don't know what to do with the handle
> returned by libusb_init_device() either before the device is opened.
>

the device handle can be used to change the configuration or open the
device so you don't need to open the device in order to open it.


>>> int libusb_xfer_wait(libusb_request_handle_t handle);
>>> int libusb_xfer_aio(libusb_request_handle_t handle);
>>
>>
>> I would still like to see the wrapper functions for those apps that
>> just use sync I/O and do not want to bother with the request handle
>> (the wrapper functions just allocate a handle, initialize it, and then
>> call libusb_xfer_wait()
>> On completion, the wrapper function deletes the handle again.
>
> Why make the difference? I really don't understand. This would confuse
> the application programmers.
>
no, it makes the library much easier to use for simple applications


int libusb_cntrl_xfer(dev_handle, interface, endpoint, cntrl_request);
int libusb_bulk_xfer(dev_handle, interface, endpoint, bulk_request);
etc.

it save allocating a libusb_request handle which is really pointless for
blocking requests that will never be aborted.


>>
>> please post the new file asap before we delve into new issues.
>
> Sorry, I was working on some bugs. I'll do it tomorrow. But before I can
>  post the new file, I need some answers to the above questions.
>

yes, let's make sure that we are on the same page


fritS


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
frits vanderlinden wrote:

> Sophia Li wrote:
>
>>>if anything, Sun's copyright needs to go. I am not quite sure why I
>>>put it there (if I did)
>>
>>The license body in libusb.h.in file is BSD license. The original
>>license term means the file and only this file can be either licensed
>>under LGPL or under BSD. All other files should be licensed under LGPL.
>>
>>No matter LGPL or BSD license is used, both require the copyright
>>statement as part of the license body. If we take the copyright
>>statements away, how can we keep the license consistent to its original
>>form? Does anyone observe such a real practice?
>>
>
> I don't follow you and don't see why removing the Sun copyright is an
> issue. The "All rights reserved" is not appropriate for LGPL/BSD license

I am not speaking about removing Sun copyright. That is not my problem.
I wonder what to do with other contributors. Add copyright statements
for them or just list them in the contributor list? What about
Johannes's copyright? Leave it or ask Johannes if he agrees to remove
it? If all copyright notices are removed, what to do with the copyright
part of the license body? Leave it blank?

In fact, the BSD license itself includes "All rights reserved" phrase.


>
>>>>#define    LIBUSB_DRIVER_FAILURE        -1    /* Unspecified driver
>>>>error */
>>>
>>>this can also be kernel failures, right?
>>
>>Failure returned by kernel driver. I guess the answer is yes.
>>
> so I am still not happy with this name

What do you like then?


>>>can you add to each request:
>>>
>>>    libusb_*_request_t *next;
>>>    libusb_*_request_t *previous;
>>>
>>>this allows submitting a bunch of requests in a single operation. This
>>>is useful when the app has to breakup the request into smaller chunks.
>>>Callbacks can either be on each request or on the last request of the
>>>linked list.
>>
>>Isn't this similar to the one-request/multi-response model? Shall we mix
>>the functionality?
>>
>
> no, this will allow you to xfer a few megabytes easily. the one-request
> model can in theory go on forever.

But this can be done with the one-request/multi-response model. By
separating the functionality, libusb_xfer_wait/async() can be simplified
to only support one response request.

If we make the change, two sets of functions can be used to implement
the functionanity you described. I just feel that is not necessary.

>
> I don't think we need the previous field. A single linked list is good
> enough
>
>
>>>
>>>>typedef struct libusb_intr_request {
>>>>  libusb_dev_handle_t dev;
>>>>  unsigned char interface;
>>>>  unsigned char endpoint;
>>>>  unsigned int interval; /* Can this work?? If not, better remove */
>>>
>>>
>>>I believe we do allow this in Solaris so it is possible?  it should be
>>>possible to poll at a lower rate than specified in the endpoint
>>>descriptor? *HCI drivers can easily do this, that is not the issue.
>>
>>Fine, we can keep it. But I have a question then, this structure is only
>>used in libusb_xfer_wait/async() functions which are suggested to be
>>separate with the one request/multiple response model. It means no
>>polling interval is necessary for this structure.
>>
> I don't understand

Well, I know what the problem is. This interval value is used to
schedule the interval between microframes/frames, not the interval
between requests.

>
>>BTW: Solaris kernel doesn't support user defined interval at least now.
>>Seems Linux kernel supports it.
>>
> then we should support it

Lots of work, I am afraid.



>>>> */ int libusb_get_first_device_id(libusb_handle_t handle,
>>>>    libusb_bus_id_t busid, libusb_device_id_t *devid);
>>>>int libusb_get_next_device_id(libusb_handle_t handle,
>>>>    libusb_device_id_t *devid);
>>>>int libusb_get_prev_device_id(libusb_handle_t handle,
>>>>    libusb_device_id_t *devid);
>>>
>>>
>>>replace with a single function that returns all devids
>>
>>We need a function to return the root-hub device id, anyway. Or it will
>>take extra effort for the user to find out.
>>
>
> good idea
>
>
>>Do you expect to use the single function to return all devids and make
>>an explicit rule that the first devid in the list should be the root-hub
>>device?
>>
>
> there are multiple root hubs because there are multiple host controllers

Each bus should contain only one PCI host controller. We return all
devids for one bus, so it is possible to use the first devid as the
root-hub device. But I am not against to make a separate function to
return the root-hub device for a certain bus.


>
>>>how are you going to handle that the buffer is too small. how is the
>>>app going to find out how big its buffer should be?
>>
>>My thought is to have the library allocate the buffer and ask the
>>application to free the buffer after using it. How about:
>>
> that is leak-prone

But that is not the library fault. Every malloc function is leak-prone.

>
> I would prefer a simple function that returns the total number of devices

In this way, the device list needs to be walked twice, not reasonable.

>> >
>> > remove.  see above. A single function that either returns all devids or
>> > devids which match vid/pid or class/protocol
>>
>>How can we combine all the functions in one single function? We'd better
>>separate the functions, one to return all devids on a bus, one to return
>>all devids that match vid/pid, one to return all devids that match
>>class/protocol.
>>
> int libusb_get_devids(handle, busid, vid, pid, class, protocol, flags);
>
> flags will indicate what the matching criteria will be

missing subclass IN argument and the OUT arguments: device list/number.

The number of parameters is too much.


>>
>>>>int libusb_get_child_count(libusb_handle_t handle,
>>>>    libusb_device_id_t devid, unsigned char *count);
>>>>
>>>
>>>is this really useful? you still don't know on which port they are
>>
>>I think yes. You can know the port number by using this function first,
>>then call libusb_get_child_device_id().
>>
>
> it still does not make sense to me. Even if you know the number of
> children, you still have to check each port to figure out where they are.
>
>
>>>>int libusb_get_child_device_id(libusb_handle_t handle,
>>>>    libusb_device_id_t hub_devid, int port,
>>
>>                                        ^^^^^ note this argument
>>
>>>>    libusb_device_id_t *child_devid);
>>>>
>>
>
> sure, but what can an app do with just knowing the number of children?

The application can know the number of ports of a hub device, and then
in a for loop, get the devid of each port with the two functions.

I think that is enough. What else do you expect the functions to do?


>
>
>>>>int libusb_get_hub_path(libusb_handle_t handle,
>>>>    libusb_device_id_t devid, unsigned char *buffer, size_t buflen);
>>>
>>>it seems more useful to have a single function that returns the
>>>logical or physical pathname (whatever the platform can supply).
>>>
>>>libusb_get_path(handle, devid, buffer, buflen)
>>>
>>>why special-case the hub?
>>
>>If the function returns logical path, the child device path can be
>>derived from the hub path, so it is not necessary to generate a path for
>>each device, I guess.
>>
>
> I think it would be useful to get a pathname or some other platform
> specific name for each device

If we are sure this is useful, we can add the function. Perhaps a flag
can do, we specify LOGICAL_PATH or PHYSICAL_PATH with the flag.


>>I see devnum corresponds to usb address on Linux. Not sure if it is
>>worth to export this value to user applications. But the latter two
>>functions aren't meaningful at all.
>>
>>
> then call it that way
>
> libusb_get_device_bus_address()

ok.


  > libusb_init_device() returns a device handle
> libusb_open() takes the device handle and then opens the device
> libusb_claim_interface() adds an interface to the handle

Doesn't explain what libusb_init_device() does internally.

And can libusb_claim_interface() be called before libusb_open()? We even
need to check if libusb_open() has been called for all other functions
taking dev handle argument.

>
>
>>>>int libusb_open(libusb_handle_t handle, libusb_device_id_t devid,
>>>>    libusb_dev_handle_t *dev);
>>>>int libusb_close(libusb_dev_handle_t dev);
>>>
>>>
>>>these functions will now take the device handle as argument instead of
>>>devid
>>>
>>>as far as I can tell, you don't use the cfg handle anywhere so what is
>>>the point?
>>
>>Perhaps you are right. But I don't know what to do with the handle
>>returned by libusb_init_device() either before the device is opened.
>>
>
>
> the device handle can be used to change the configuration or open the
> device so you don't need to open the device in order to open it.

What is the benefit of doing this?

>
>>>>int libusb_xfer_wait(libusb_request_handle_t handle);
>>>>int libusb_xfer_aio(libusb_request_handle_t handle);
>>>
>
> no, it makes the library much easier to use for simple applications
>
>
> int libusb_cntrl_xfer(dev_handle, interface, endpoint, cntrl_request);
> int libusb_bulk_xfer(dev_handle, interface, endpoint, bulk_request);
> etc.
>
> it save allocating a libusb_request handle which is really pointless for
> blocking requests that will never be aborted.
>

This doesn't look any easier to me. And by moving the first 3 fields out
of the request structure, we need three more arguments in the functions.

Anyway, if you insist, I can do it. Not a big deal on my side.


Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Peter Stuge-2
On Thu, Apr 19, 2007 at 01:20:48PM +0800, Sophia Li wrote:
> I am not speaking about removing Sun copyright. That is not my
> problem.

I definately think Sun holds copyright for some of libusb.h.in.
My only problem is with "All rights reserved."


> I wonder what to do with other contributors. Add copyright
> statements for them or just list them in the contributor list?

This should be decided on amongst the contributors.

Some projects are careful to include all authors copyright lines
because files may be copied around. That makes sense.


> What about Johannes's copyright? Leave it or ask Johannes if he
> agrees to remove it?

He's one of the contributors so what goes for others goes for him
too.


> If all copyright notices are removed, what to do with the copyright
> part of the license body? Leave it blank?

I think we should keep the copyright lines.


> In fact, the BSD license itself includes "All rights reserved"
> phrase.

Yes, in old versions. I like what OpenBSD prefer for new code:
http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/share/misc/license.template?rev=1.2

For corporate copyright holders, we've used this form in another
project:

Copyright (c) CCYY MegaCorp Inc
Written by John Doe <[hidden email]> for MegaCorp Inc.

At first it feels a bit verbose, but it grows on you, it's virtue is
excellent documentation.


> > sure, but what can an app do with just knowing the number of
> > children?
>
> The application can know the number of ports of a hub device, and
> then in a for loop, get the devid of each port with the two
> functions.
>
> I think that is enough. What else do you expect the functions to
> do?

An alternative is for us to invent a more complete topology API. I
don't know if one exists in any operating system.

This brings us to device pathnames.

No two OS:es will use the same path structure for identifying
devices. If the library gives that back to the user, it's not
very portable. Again we could invent, a topology path syntax.


//Peter

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
Peter Stuge wrote:

>>If all copyright notices are removed, what to do with the copyright
>>part of the license body? Leave it blank?
>
>
> I think we should keep the copyright lines.
>
>>In fact, the BSD license itself includes "All rights reserved"
>>phrase.
>
> Yes, in old versions. I like what OpenBSD prefer for new code:
> http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/share/misc/license.template?rev=1.2
>
> For corporate copyright holders, we've used this form in another
> project:
>
> Copyright (c) CCYY MegaCorp Inc
> Written by John Doe <[hidden email]> for MegaCorp Inc.
>
> At first it feels a bit verbose, but it grows on you, it's virtue is
> excellent documentation.
>

It will be troublesome to relicense the project under another license
like the OpenBSD license, since we need to get agreement from the
original copyright holders. Can we identify all the copyright holders? I
doubt we want to get into that kind of trouble. For libusb.h.in file
solely, it is possible if Johannes agrees to relicense it.

But we need an agreement first what to change. Seems everyone has his
own preference. :-(


>
>
>>>sure, but what can an app do with just knowing the number of
>>>children?
>>
>>The application can know the number of ports of a hub device, and
>>then in a for loop, get the devid of each port with the two
>>functions.
>>
>>I think that is enough. What else do you expect the functions to
>>do?
>
>
> An alternative is for us to invent a more complete topology API. I
> don't know if one exists in any operating system.
>
> This brings us to device pathnames.
>
> No two OS:es will use the same path structure for identifying
> devices. If the library gives that back to the user, it's not
> very portable. Again we could invent, a topology path syntax.
>

The original API proposed a path syntax, i.e., to return path as an
array of port numbers (eg. 1.2.0 reflects port 1 on the root hub, port 2
on the external hub, and 0 terminates the list). The path is a relative
path to the root hub, since the bus id will be different across
platform. It depends on the order in which an OS enumerates the USB host
controllers. This might be the best we can do for portability.

Physical path sometimes might also be useful when the application wants
to give descriptive information about the device path. Though physical
path would not be the same on different OSes, it is still meaningful to
users.

Sophia

Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
In reply to this post by Sophia Li - Sun Microsystems - Beijing China
> frits vanderlinden wrote:
>
>>>>>int libusb_xfer_wait(libusb_request_handle_t handle);
>>>>>int libusb_xfer_aio(libusb_request_handle_t handle);
>>>>
>>no, it makes the library much easier to use for simple applications
>>
>>
>>int libusb_cntrl_xfer(dev_handle, interface, endpoint, cntrl_request);
>>int libusb_bulk_xfer(dev_handle, interface, endpoint, bulk_request);
>>etc.
>>
>>it save allocating a libusb_request handle which is really pointless for
>>blocking requests that will never be aborted.
>>
>
>
> This doesn't look any easier to me. And by moving the first 3 fields out
> of the request structure, we need three more arguments in the functions.
>

Another problem is:
the request result is placed in request handle structure now, the
libusb_xxx_xfer() function needs to add transfer result to the arguments
again.


Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

frits vanderlinden-3
In reply to this post by Sophia Li - Sun Microsystems - Beijing China
Sophia Li wrote:

> I am not speaking about removing Sun copyright. That is not my problem.
> I wonder what to do with other contributors. Add copyright statements
> for them or just list them in the contributor list? What about
> Johannes's copyright? Leave it or ask Johannes if he agrees to remove
> it? If all copyright notices are removed, what to do with the copyright
> part of the license body? Leave it blank?
>
> In fact, the BSD license itself includes "All rights reserved" phrase.
>
we agreed offline that sophia will ask the opensource/legal folks for
advice and then make a proposal

>
>>
>>>>> #define    LIBUSB_DRIVER_FAILURE        -1    /* Unspecified driver
>>>>> error */
>>>>
>>>> this can also be kernel failures, right?
>>>
>>> Failure returned by kernel driver. I guess the answer is yes.
>>>
>> so I am still not happy with this name
>
> What do you like then?

LIBUSB_PLATFORM_FAILURE  /* unspecified kernel/driver failure */

Not a lot better. I hope it will only be used for failures that are
unique to the platform and do not fall in any other basket.


>
>
>>>> can you add to each request:
>>>>
>>>>    libusb_*_request_t *next;
>>>>    libusb_*_request_t *previous;
>>>>
>>>> this allows submitting a bunch of requests in a single operation.
>>>> This is useful when the app has to breakup the request into smaller
>>>> chunks. Callbacks can either be on each request or on the last
>>>> request of the linked list.
>>>
>>> Isn't this similar to the one-request/multi-response model? Shall we
>>> mix the functionality?
>>>
>>
>> no, this will allow you to xfer a few megabytes easily. the
>> one-request model can in theory go on forever.
>
> But this can be done with the one-request/multi-response model. By
> separating the functionality, libusb_xfer_wait/async() can be simplified
> to only support one response request.
>
> If we make the change, two sets of functions can be used to implement
> the functionanity you described. I just feel that is not necessary.
>

I don't agree. The linked list allows you to easily do a larger transfer
  that has to be broken up because of max transfer restrictions and all
data is available upfront. This is still light weight and can be used
synchronously/blocking, ie no callbacks and no state machine to get you
through the entire xfer.

The one-request model is pretty heavy weight and only for aio.



> Well, I know what the problem is. This interval value is used to
> schedule the interval between microframes/frames, not the interval
> between requests.
>

exactly

>>
>>> BTW: Solaris kernel doesn't support user defined interval at least
>>> now. Seems Linux kernel supports it.
>>>
>> then we should support it
>
> Lots of work, I am afraid.
>

but doable (quite frankly, I don't think it is a lot of work though).



>> there are multiple root hubs because there are multiple host controllers
>
> Each bus should contain only one PCI host controller. We return all
> devids for one bus, so it is possible to use the first devid as the
> root-hub device. But I am not against to make a separate function to
> return the root-hub device for a certain bus.
>

huh? the roothub is either on ehci, ohci, or uhci. I don't see what PCI
has to do with it

Most apps don't care on which bus the device is

>
>>
>>>> how are you going to handle that the buffer is too small. how is the
>>>> app going to find out how big its buffer should be?
>>>
>>> My thought is to have the library allocate the buffer and ask the
>>> application to free the buffer after using it. How about:
>>>
>> that is leak-prone
>
> But that is not the library fault. Every malloc function is leak-prone.
>

that is different.  The app calls malloc() and then has to call free().
  If libusb implicitly return buffers that have to be freed by the
caller it is often overlooked.
(solaris bug reports document a zillion leaks because of this (bad)
model, please check some of the DDI calls).



>> int libusb_get_devids(handle, busid, vid, pid, class, protocol, flags);
>>
>> flags will indicate what the matching criteria will be
>
> missing subclass IN argument and the OUT arguments: device list/number.
>
> The number of parameters is too much.
>
OK, break it up in 2 or 3 simple functions then

>
>>>
>>>>> int libusb_get_child_count(libusb_handle_t handle,
>>>>>    libusb_device_id_t devid, unsigned char *count);
>>>>>
>>>>
>
> The application can know the number of ports of a hub device, and then
> in a for loop, get the devid of each port with the two functions.
>
> I think that is enough. What else do you expect the functions to do?
>

You don't need libusb_get_child_count() in order to walk all the ports.

Even if you do use the count, it might be stale by the time you are
walking the ports (ie. a child may have disappeared).


>> I think it would be useful to get a pathname or some other platform
>> specific name for each device
>
> If we are sure this is useful, we can add the function. Perhaps a flag
> can do, we specify LOGICAL_PATH or PHYSICAL_PATH with the flag.
>

Logical and Physical path may be Solaris only (do they make sense on all
platforms?).  I was suggesting that the implementation just returns a
name for the device and each implementation can decide which name makes
the most sense




>  > libusb_init_device() returns a device handle
>> libusb_open() takes the device handle and then opens the device
>> libusb_claim_interface() adds an interface to the handle
>
> Doesn't explain what libusb_init_device() does internally.
>

huh?  We had weeks of discussion on this...

Each platform will do what ever it takes to make the device ready for
use by libusb (including detaching drivers or switching drivers).

> And can libusb_claim_interface() be called before libusb_open()? We even

of course not

> need to check if libusb_open() has been called for all other functions
> taking dev handle argument.
>
absolutely, that is just a flag in the device handle

>>
>>
>>>>> int libusb_open(libusb_handle_t handle, libusb_device_id_t devid,
>>>>>    libusb_dev_handle_t *dev);
>>>>> int libusb_close(libusb_dev_handle_t dev);
>>>>
>>>>
>>>> these functions will now take the device handle as argument instead
>>>> of devid
>>>>
>>>> as far as I can tell, you don't use the cfg handle anywhere so what
>>>> is the point?
>>>
>>> Perhaps you are right. But I don't know what to do with the handle
>>> returned by libusb_init_device() either before the device is opened.
>>>
>>
>>
>> the device handle can be used to change the configuration or open the
>> device so you don't need to open the device in order to open it.
>
> What is the benefit of doing this?

it forces the app to first do a libusb_init_device() and the
implementation can get the device ready for libusb (or tell the app why
the device cannot be used).

You will then take the device handle to open the device.
If you don't return a handle in libusb_init_device(), how are you going
to keep track whether the app has actually called libusb_init_device()
(it is just more work).

>
>>
>>>>> int libusb_xfer_wait(libusb_request_handle_t handle);
>>>>> int libusb_xfer_aio(libusb_request_handle_t handle);
>>>>
>>
>> no, it makes the library much easier to use for simple applications
>>
>>
>> int libusb_cntrl_xfer(dev_handle, interface, endpoint, cntrl_request);
>> int libusb_bulk_xfer(dev_handle, interface, endpoint, bulk_request);
>> etc.
>>
>> it save allocating a libusb_request handle which is really pointless
>> for blocking requests that will never be aborted.
>>
>
> This doesn't look any easier to me. And by moving the first 3 fields out
> of the request structure, we need three more arguments in the functions.

you also need to return residue/transferred bytes but you do not need to
allocate and initialize the request handle nor free it later

The functions are close to what libusb 0.* has so it makes it easier to
port applications to the new interfaces.

>
> Anyway, if you insist, I can do it. Not a big deal on my side.
>
>
these 4 functions are just thin wrappers around libusb_xfer_wait().
These wrappers
allocate the request handle and initialize it under the hood.


cheers


fritS




-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

frits vanderlinden-3
In reply to this post by Peter Stuge-2
Peter Stuge wrote:

> For corporate copyright holders, we've used this form in another
> project:
>
> Copyright (c) CCYY MegaCorp Inc
> Written by John Doe <[hidden email]> for MegaCorp Inc.
>
> At first it feels a bit verbose, but it grows on you, it's virtue is
> excellent documentation.
>
>
email addresses get stale pretty quickly


>>> sure, but what can an app do with just knowing the number of
>>> children?
>> The application can know the number of ports of a hub device, and
>> then in a for loop, get the devid of each port with the two
>> functions.
>>
>> I think that is enough. What else do you expect the functions to
>> do?
>
> An alternative is for us to invent a more complete topology API. I
> don't know if one exists in any operating system.
>
> This brings us to device pathnames.
>
> No two OS:es will use the same path structure for identifying
> devices. If the library gives that back to the user, it's not
> very portable. Again we could invent, a topology path syntax.
>
>

that was not my intention.  Each platform can return a name for the
device that makes sense for that platform (eg /dev/usb/hid1 or
/devices/pci<unit address>/usb<unit address>/hid<unit address> or
whatever.  The app should not parse this name, just use it in a message
to the user to help the user find the device, for example

cheers

fritS


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Michael Lewis
In reply to this post by frits vanderlinden-3
On 4/18/07, frits vanderlinden <[hidden email]> wrote:
Sophia Li wrote:
>

>> can you add to each request:
>>
>>     libusb_*_request_t *next;
>>     libusb_*_request_t *previous;
>>
>> this allows submitting a bunch of requests in a single operation. This
>> is useful when the app has to breakup the request into smaller chunks.
>> Callbacks can either be on each request or on the last request of the
>> linked list.
>
> Isn't this similar to the one-request/multi-response model? Shall we mix
> the functionality?
>
no, this will allow you to xfer a few megabytes easily. the one-request
model can in theory go on forever.

I don't think we need the previous field. A single linked list is good
enough

I agree this functionality should be included as it does make things much simpler from an application perspective. A single linked list should be good enough.

>>> int libusb_xfer_wait(libusb_request_handle_t handle);

>>> int libusb_xfer_aio(libusb_request_handle_t handle);
>>
>>
>> I would still like to see the wrapper functions for those apps that
>> just use sync I/O and do not want to bother with the request handle
>> (the wrapper functions just allocate a handle, initialize it, and then
>> call libusb_xfer_wait()
>> On completion, the wrapper function deletes the handle again.
>
> Why make the difference? I really don't understand. This would confuse
> the application programmers.
>
no, it makes the library much easier to use for simple applications


int libusb_cntrl_xfer(dev_handle, interface, endpoint, cntrl_request);
int libusb_bulk_xfer(dev_handle, interface, endpoint, bulk_request);
etc.

it save allocating a libusb_request handle which is really pointless for
blocking requests that will never be aborted.

From an application perspective, I don't see how this really helps. Generally I would prefer to use the same function to submit all types of requests. If I had a choice, I wouldn't include these.
 



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

frits vanderlinden-3
Michael Lewis wrote:

>     int libusb_cntrl_xfer(dev_handle, interface, endpoint, cntrl_request);
>     int libusb_bulk_xfer(dev_handle, interface, endpoint, bulk_request);
>     etc.
>
>     it save allocating a libusb_request handle which is really pointless for
>     blocking requests that will never be aborted.
>
>
>  From an application perspective, I don't see how this really helps.
> Generally I would prefer to use the same function to submit all types of
> requests. If I had a choice, I wouldn't include these.
>  
>
>

instead of

rval = libusb_cntrl_xfer(dev_handle, iface, ep,
        cntrl_req, &count);

you have to do

hdl = malloc(sizeof (libusb_request_handle));
bzero(hdl);

hdl->type = USB_TYPE_CTRL;
hdl->dev = dev_handle;
hdl->interface = iface;
hdl->endpoint = ep;
hdl->req.ctrl = cntrl_req;

rval = libusb_xfer_wait(hdl);

count = hdl->result->transferred;

free(hdl);

The first seems a lot less typing to me

cheers

fritS



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
In reply to this post by frits vanderlinden-3
frits vanderlinden wrote:
  > LIBUSB_PLATFORM_FAILURE  /* unspecified kernel/driver failure */
>
> Not a lot better. I hope it will only be used for failures that are
> unique to the platform and do not fall in any other basket.
>

ok.

>>>>> can you add to each request:
>>>>>
>>>>>    libusb_*_request_t *next;
>>>>>
>>>>> this allows submitting a bunch of requests in a single operation.
>>>>> This is useful when the app has to breakup the request into smaller
>>>>> chunks. Callbacks can either be on each request or on the last
>>>>> request of the linked list.
>
> I don't agree. The linked list allows you to easily do a larger transfer
>   that has to be broken up because of max transfer restrictions and all
> data is available upfront. This is still light weight and can be used
> synchronously/blocking, ie no callbacks and no state machine to get you
> through the entire xfer.

The request structure cannot support multiple requests now, since it
only returns transfer result for one request. If you do like the
function, we may need to move the result area back to each request
structure.

And more things to be considered:
1. Shall we continue to execute next request if the previous request fails?
2. If it is used for asynchronous io, we must ensure each callback is
finished before doing next request, or the callback may not find the
right request. So in this scenario, we don't care about performance. Is
that all right?


> The one-request model is pretty heavy weight and only for aio.
>
>> Well, I know what the problem is. This interval value is used to
>> schedule the interval between microframes/frames, not the interval
>> between requests.
>>
>
> exactly
>
>>>
>>>> BTW: Solaris kernel doesn't support user defined interval at least
>>>> now. Seems Linux kernel supports it.
>>>>
>>> then we should support it
>>
>>
>> Lots of work, I am afraid.
>>
>
> but doable (quite frankly, I don't think it is a lot of work though).

Frankly speaking, I am still not very clear how Solaris does interval
management. But it is definitely an RFE and needs an ARC case.


>> there are multiple root hubs because there are multiple host controllers
>>
>>
>> Each bus should contain only one PCI host controller. We return all
>> devids for one bus, so it is possible to use the first devid as the
>> root-hub device. But I am not against to make a separate function to
>> return the root-hub device for a certain bus.
>>
>
> huh? the roothub is either on ehci, ohci, or uhci. I don't see what PCI
> has to do with it
>
> Most apps don't care on which bus the device is

Yes, I should say each bus contains only one host controller.

>>>
>>>>> how are you going to handle that the buffer is too small. how is
>>>>> the app going to find out how big its buffer should be?
>>>>
>>>>
>>>> My thought is to have the library allocate the buffer and ask the
>>>> application to free the buffer after using it. How about:
>>>>
>>> that is leak-prone
>>
>>
>> But that is not the library fault. Every malloc function is leak-prone.
>>
>
> that is different.  The app calls malloc() and then has to call free().
>   If libusb implicitly return buffers that have to be freed by the
> caller it is often overlooked.
> (solaris bug reports document a zillion leaks because of this (bad)
> model, please check some of the DDI calls).

We can document the rules just like malloc() and free(), or the
application programmer should be responsible for the memory leak. And I
think modern operating systems would always free the memory after the
application quited. Memory leak is not that big a issue as in kernel.

Just like what you mentioned below for child count, if we first call a
function to get the device numbers, then call the match function to get
the real device ids, the device list might have changed. So I don't
think that is a good method.


>
>>> int libusb_get_devids(handle, busid, vid, pid, class, protocol, flags);
>>>
>>> flags will indicate what the matching criteria will be
>>
>>
>> missing subclass IN argument and the OUT arguments: device list/number.
>>
>> The number of parameters is too much.
>>
> OK, break it up in 2 or 3 simple functions then
>

I tend to keep the function of getting all devids by bus(one way for
application to navigate all devices if he doesn't want to match vid/pid
or class/protocol), but not to use vid=0/pid=0 as wildcard to match all
devices, because no spec specifies that vid/pid cannot be 0 or ffff.
Some user designed devices might use these values. So I would like to
suggest we use the following functions:

int libusb_match_devices_by_bus(libusb_handle_t handle,
        libusb_bus_id_t busid, libusb_device_id_t *devids,
        unsigned int *num_devids);
int libusb_match_devices_by_vendor(libusb_handle_t handle,
        int vendor, int product, libusb_device_id_t *devids,
        unsigned int *num_devices);
int libusb_match_devices_by_class(libusb_handle_t handle, int devclass,
        int subclass, int protocol, libusb_device_id_t *devids,
        unsigned int *num_devices);
void libusb_free_device_list(libusb_device_id_t *devids);

(Since we haven't come to a conclusion who to allocate the devid buffer,
  I still use the previous method.)

>>
>>>>
>>>>>> int libusb_get_child_count(libusb_handle_t handle,
>>>>>>    libusb_device_id_t devid, unsigned char *count);
>>>>>>
>>>>>
>>
>> The application can know the number of ports of a hub device, and then
>> in a for loop, get the devid of each port with the two functions.
>>
>> I think that is enough. What else do you expect the functions to do?
>>
>
> You don't need libusb_get_child_count() in order to walk all the ports.
>
> Even if you do use the count, it might be stale by the time you are
> walking the ports (ie. a child may have disappeared).

I think the child count is better renamed port number, which is a static
  property for a hub device. If there is not a child device on a port,
libusb_get_child_device_id() should return NULL.

Does that make sense?


>>> I think it would be useful to get a pathname or some other platform
>>> specific name for each device
>>
>>
>> If we are sure this is useful, we can add the function. Perhaps a flag
>> can do, we specify LOGICAL_PATH or PHYSICAL_PATH with the flag.
>>
>
> Logical and Physical path may be Solaris only (do they make sense on all
> platforms?).  I was suggesting that the implementation just returns a
> name for the device and each implementation can decide which name makes
> the most sense
>

The original function is designed to return path as an array of port
numbers (eg. 1.2.0 reflects port 1 on the root hub, port 2 on the
external hub, and 0 terminates the list). This is a convenient function
for topological depiction. So you are suggesting we don't need the
topology function?

I suggest we keep this one but have another function to do what you
described.

>
>
>>  > libusb_init_device() returns a device handle
>>
>>> libusb_open() takes the device handle and then opens the device
>>> libusb_claim_interface() adds an interface to the handle
>>
>>
>> Doesn't explain what libusb_init_device() does internally.
>>
>
> huh?  We had weeks of discussion on this...
>
> Each platform will do what ever it takes to make the device ready for
> use by libusb (including detaching drivers or switching drivers).
>
>> And can libusb_claim_interface() be called before libusb_open()? We even
>
>
> of course not
>
>> need to check if libusb_open() has been called for all other functions
>> taking dev handle argument.
>>
> absolutely, that is just a flag in the device handle


> it forces the app to first do a libusb_init_device() and the
> implementation can get the device ready for libusb (or tell the app why
> the device cannot be used).
>
> You will then take the device handle to open the device.
> If you don't return a handle in libusb_init_device(), how are you going
> to keep track whether the app has actually called libusb_init_device()
> (it is just more work).
>

I didn't expect all applications to call libusb_init_device() before
libusb_open(). I thought it was only called when necessary.

In your proposal, libusb_init_device() needs to be able to tell if a
device has been correctly configured for use by libusb. Don't know if it
is feasible on all OS.

And if libsub_init_device() must be called, I really don't see the need
of libusb_open(). Part of its function can be moved to
libsub_init_device(), and part to libusb_claim_interface().


>>>
>>>>>> int libusb_xfer_wait(libusb_request_handle_t handle);
>>>>>> int libusb_xfer_aio(libusb_request_handle_t handle);
>>>>>
>>>>>
>>>
>>> no, it makes the library much easier to use for simple applications
>>>
>>>
>>> int libusb_cntrl_xfer(dev_handle, interface, endpoint, cntrl_request);
>>> int libusb_bulk_xfer(dev_handle, interface, endpoint, bulk_request);
>>> etc.
>>>
>>> it save allocating a libusb_request handle which is really pointless
>>> for blocking requests that will never be aborted.
>>>
>>
>> This doesn't look any easier to me. And by moving the first 3 fields
>> out of the request structure, we need three more arguments in the
>> functions.
>
>
> you also need to return residue/transferred bytes but you do not need to
> allocate and initialize the request handle nor free it later

If we move the result area back to each request structure, we don't need
to return residue/transferred bytes then.

>
> The functions are close to what libusb 0.* has so it makes it easier to
> port applications to the new interfaces.
>
>>
>> Anyway, if you insist, I can do it. Not a big deal on my side.
>>
>>
> these 4 functions are just thin wrappers around libusb_xfer_wait().
> These wrappers
> allocate the request handle and initialize it under the hood.

In that case, we wouldn't need the libusb_xfer_wait() function in the
API. That is just internal implementation, I think.


Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

frits vanderlinden-3
Sophia Li wrote:

> The request structure cannot support multiple requests now, since it
> only returns transfer result for one request. If you do like the
> function, we may need to move the result area back to each request
> structure.

yes

>
> And more things to be considered:
> 1. Shall we continue to execute next request if the previous request fails?

probably not

> 2. If it is used for asynchronous io, we must ensure each callback is
> finished before doing next request, or the callback may not find the
> right request. So in this scenario, we don't care about performance. Is
> that all right?
>
it might be used for sync and async I/O.


> Frankly speaking, I am still not very clear how Solaris does interval
> management. But it is definitely an RFE and needs an ARC case.
>
not necessarily (it can be a private interface between ugen and usba).


>
>
> We can document the rules just like malloc() and free(), or the
> application programmer should be responsible for the memory leak. And I
> think modern operating systems would always free the memory after the
> application quited. Memory leak is not that big a issue as in kernel.
>

it is just not a very good model and it creates confusion. Furthermore,
it is not necessary

> Just like what you mentioned below for child count, if we first call a
> function to get the device numbers, then call the match function to get
> the real device ids, the device list might have changed. So I don't
> think that is a good method.
>

yes, a sensible app would allocate a slightly bigger buffer. And even if
the count exceeds the buffer nothing bad happens


>
> I tend to keep the function of getting all devids by bus(one way for
> application to navigate all devices if he doesn't want to match vid/pid
> or class/protocol), but not to use vid=0/pid=0 as wildcard to match all
> devices, because no spec specifies that vid/pid cannot be 0 or ffff.
> Some user designed devices might use these values. So I would like to
> suggest we use the following functions:
>
> int libusb_match_devices_by_bus(libusb_handle_t handle,
>     libusb_bus_id_t busid, libusb_device_id_t *devids,
>     unsigned int *num_devids);
> int libusb_match_devices_by_vendor(libusb_handle_t handle,
>     int vendor, int product, libusb_device_id_t *devids,
>     unsigned int *num_devices);
> int libusb_match_devices_by_class(libusb_handle_t handle, int devclass,
>     int subclass, int protocol, libusb_device_id_t *devids,
>     unsigned int *num_devices);
> void libusb_free_device_list(libusb_device_id_t *devids);
>
> (Since we haven't come to a conclusion who to allocate the devid buffer,
>  I still use the previous method.)
>
you would need the length of the devid list in the last function


>> Even if you do use the count, it might be stale by the time you are
>> walking the ports (ie. a child may have disappeared).
>
> I think the child count is better renamed port number, which is a static
>  property for a hub device. If there is not a child device on a port,
> libusb_get_child_device_id() should return NULL.
>
> Does that make sense?
>
it will save the app one control request to get the hub descriptor. I am
not sure if that is worth it

>
>
> The original function is designed to return path as an array of port
> numbers (eg. 1.2.0 reflects port 1 on the root hub, port 2 on the
> external hub, and 0 terminates the list). This is a convenient function
> for topological depiction. So you are suggesting we don't need the
> topology function?
>
> I suggest we keep this one but have another function to do what you
> described.

OK


> I didn't expect all applications to call libusb_init_device() before
> libusb_open(). I thought it was only called when necessary.

that would defeat its purpose. It might be NOP on some platforms

>
> In your proposal, libusb_init_device() needs to be able to tell if a
> device has been correctly configured for use by libusb. Don't know if it
> is feasible on all OS.

surely, the implementation can do some tests to see if all the plumbing
is in place.

>
> And if libsub_init_device() must be called, I really don't see the need
> of libusb_open(). Part of its function can be moved to
> libsub_init_device(), and part to libusb_claim_interface().
>

I would like to keep "making the device available to usb" separate from
"opening the device"


>> these 4 functions are just thin wrappers around libusb_xfer_wait().
>> These wrappers
>> allocate the request handle and initialize it under the hood.
>
> In that case, we wouldn't need the libusb_xfer_wait() function in the
> API. That is just internal implementation, I think.
>

you need the libusb_request handle if you ever intend to abort the request.


cheers

fritS


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

Sophia Li - Sun Microsystems - Beijing China
frits vanderlinden wrote:
>>Frankly speaking, I am still not very clear how Solaris does interval
>>management. But it is definitely an RFE and needs an ARC case.
>>
>
> not necessarily (it can be a private interface between ugen and usba).

Are you proposing to add new private interface between ugen and usba
instead of using existing usba functions?


>>
>>We can document the rules just like malloc() and free(), or the
>>application programmer should be responsible for the memory leak. And I
>>think modern operating systems would always free the memory after the
>>application quited. Memory leak is not that big a issue as in kernel.
>>
>
>
> it is just not a very good model and it creates confusion. Furthermore,
> it is not necessary
>
>
>>Just like what you mentioned below for child count, if we first call a
>>function to get the device numbers, then call the match function to get
>>the real device ids, the device list might have changed. So I don't
>>think that is a good method.
>>
>
>
> yes, a sensible app would allocate a slightly bigger buffer. And even if
> the count exceeds the buffer nothing bad happens
>

I am afraid this would be more confusing to users. It is easier for an
application to know it needs to free the buffer than making it know it
needs to allocate a slightly bigger buffer than the size libusb tells it.


>
>>I tend to keep the function of getting all devids by bus(one way for
>>application to navigate all devices if he doesn't want to match vid/pid
>>or class/protocol), but not to use vid=0/pid=0 as wildcard to match all
>>devices, because no spec specifies that vid/pid cannot be 0 or ffff.
>>Some user designed devices might use these values. So I would like to
>>suggest we use the following functions:
>>
>>int libusb_match_devices_by_bus(libusb_handle_t handle,
>>    libusb_bus_id_t busid, libusb_device_id_t *devids,
>>    unsigned int *num_devids);
>>int libusb_match_devices_by_vendor(libusb_handle_t handle,
>>    int vendor, int product, libusb_device_id_t *devids,
>>    unsigned int *num_devices);
>>int libusb_match_devices_by_class(libusb_handle_t handle, int devclass,
>>    int subclass, int protocol, libusb_device_id_t *devids,
>>    unsigned int *num_devices);
>>void libusb_free_device_list(libusb_device_id_t *devids);
>>
>>(Since we haven't come to a conclusion who to allocate the devid buffer,
>> I still use the previous method.)
>>
>
> you would need the length of the devid list in the last function

It is just a wrapper for free(). In fact, the application can directly
call free() to free the buffer that contains the devid list.


>
>>>Even if you do use the count, it might be stale by the time you are
>>>walking the ports (ie. a child may have disappeared).
>>
>>I think the child count is better renamed port number, which is a static
>> property for a hub device. If there is not a child device on a port,
>>libusb_get_child_device_id() should return NULL.
>>
>>Does that make sense?
>>
>
> it will save the app one control request to get the hub descriptor. I am
> not sure if that is worth it

An ordinary libusb app wouldn't care about hub descriptor except it is a
hub driver. So it is useful to supply a function for ordinary app to get
the hub port number directly.


>>In your proposal, libusb_init_device() needs to be able to tell if a
>>device has been correctly configured for use by libusb. Don't know if it
>>is feasible on all OS.
>
>
> surely, the implementation can do some tests to see if all the plumbing
> is in place.

I believe opening device is a common way to tell if all the plumbing is
in place. So opening device can be a natural part of the init operation.

>
>
>>And if libsub_init_device() must be called, I really don't see the need
>>of libusb_open(). Part of its function can be moved to
>>libsub_init_device(), and part to libusb_claim_interface().
>>
>
> I would like to keep "making the device available to usb" separate from
> "opening the device"
>

libusb_open() originally existed because it was needed to give other
functions a device handle. However, the function itself doesn't have a
strong meaning. Think of how ugen works. There is not a single device to
open, but different endpoints. In fact, libusb application needs to
operate device by interface even if it owns the whole device.

So it seems libusb_open() doesn't have a necessity to exist now with
libusb_init_device() returning the device handle.

But I won't argue more on this point. I can accept to have both functions.


>
>>>these 4 functions are just thin wrappers around libusb_xfer_wait().
>>>These wrappers
>>>allocate the request handle and initialize it under the hood.
>>
>>In that case, we wouldn't need the libusb_xfer_wait() function in the
>>API. That is just internal implementation, I think.
>>
>
>
> you need the libusb_request handle if you ever intend to abort the request.

I only remembered we discussed libusb_wait/poll/abort() for async io.
I've almost forgot we need to abort sync io.

So you mean if application doesn't need to abort sync request, it can
use libusb_xxx_xfer(). If it wants to abort sync request, it can use
libusb_xfer_wait().

This is really not necessary. Why should libusb attend to this special
usage difference? It is actually the application's responsibility to
decide whether to make such wrappers.


Sophia

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: wrap up of issues

frits vanderlinden-3

> Are you proposing to add new private interface between ugen and usba
> instead of using existing usba functions?
>
we can discuss this off-list later



> I am afraid this would be more confusing to users. It is easier for an
> application to know it needs to free the buffer than making it know it
> needs to allocate a slightly bigger buffer than the size libusb tells it.
>

I am not going to argue any longer on this. It is not a good model that
libusb allocates and the caller frees but if nobody else feels strongly
about this, you can go ahead and do it this way

Peter/Tim/Mike?



>> it will save the app one control request to get the hub descriptor. I
>> am not sure if that is worth it
>
> An ordinary libusb app wouldn't care about hub descriptor except it is a
> hub driver. So it is useful to supply a function for ordinary app to get
> the hub port number directly.
>
OK


>> I would like to keep "making the device available to usb" separate
>> from "opening the device"
>>
>
> libusb_open() originally existed because it was needed to give other
> functions a device handle. However, the function itself doesn't have a
> strong meaning. Think of how ugen works. There is not a single device to
> open, but different endpoints. In fact, libusb application needs to
> operate device by interface even if it owns the whole device.
>
> So it seems libusb_open() doesn't have a necessity to exist now with
> libusb_init_device() returning the device handle.
>
> But I won't argue more on this point. I can accept to have both functions.
>

that is not quite the issue. The issues are:

- which function returns the handle
- how can we enforce that libusb_init_device() will be called. If it is
not called then the app may not run on some platforms and this reduces
portability

My suggestion was return the dev_handle with libusb_init_device().

But if you can just make sure that libusb_open() fails without an
libusb_init_device(), I am fine with keeping libusb_open() returning the
dev_handle and we can move on.
Stuffing libusb_open() functionality into libusb_init_device() or vice
versa is a bad idea so we have to keep both functions.


>> you need the libusb_request handle if you ever intend to abort the
>> request.
>
> I only remembered we discussed libusb_wait/poll/abort() for async io.
> I've almost forgot we need to abort sync io.
>
> So you mean if application doesn't need to abort sync request, it can
> use libusb_xxx_xfer(). If it wants to abort sync request, it can use
> libusb_xfer_wait().

these are 4 convenience wrapper functions to save typing (see below).

>
> This is really not necessary. Why should libusb attend to this special
> usage difference? It is actually the application's responsibility to
> decide whether to make such wrappers.
>

it makes libusb easier to use for the very simple applications that do
everything synchronously. It also makes porting a libusb 0.* application
to libusb 1.0 easier because 3 of these wrapper functions are close to
what we use to have in libusb 0.*


Peter/Tim/Mike: can you help us out here and provide a deciding vote so
we can move on:


This is what sophia proposes:

hdl = malloc(sizeof (libusb_request_handle));
bzero(hdl);

hdl->type = USB_TYPE_CTRL;
hdl->dev = dev_handle;
hdl->interface = iface;
hdl->endpoint = ep;
hdl->req.ctrl = cntrl_req;

rval = libusb_xfer_wait(hdl);

count = hdl->result->transferred;

free(hdl);



This is the wrapper that I propose:

rval = libusb_cntrl_xfer(dev_handle, iface, ep,
        cntrl_req, &count);


We will keep libusb_xfer_wait() for the more sophisticated apps that
might have to abort the request.

cheers


fritS



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
1234 ... 15
Loading...