Changeset b4b534ac in mainline for uspace/lib/usb


Ignore:
Timestamp:
2016-07-22T08:24:47Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f76d2c2
Parents:
5b18137 (diff), 8351f9a4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jan.vesely/helenos/usb

Location:
uspace/lib/usb
Files:
1 added
3 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/Makefile

    r5b18137 rb4b534ac  
    3636SOURCES = \
    3737        src/class.c \
    38         src/ddfiface.c \
    3938        src/dev.c \
    4039        src/debug.c \
    4140        src/dump.c \
    42         src/hc.c \
    4341        src/usb.c
    4442
  • uspace/lib/usb/include/usb/classes/hub.h

    r5b18137 rb4b534ac  
    4343 */
    4444typedef enum {
     45        USB_HUB_FEATURE_C_HUB_LOCAL_POWER = 0,
     46        USB_HUB_FEATURE_C_HUB_OVER_CURRENT = 1,
    4547        USB_HUB_FEATURE_HUB_LOCAL_POWER = 0,
    4648        USB_HUB_FEATURE_HUB_OVER_CURRENT = 1,
    47         USB_HUB_FEATURE_C_HUB_LOCAL_POWER = 0,
    48         USB_HUB_FEATURE_C_HUB_OVER_CURRENT = 1,
    4949        USB_HUB_FEATURE_PORT_CONNECTION = 0,
    5050        USB_HUB_FEATURE_PORT_ENABLE = 1,
     
    5454        USB_HUB_FEATURE_PORT_POWER = 8,
    5555        USB_HUB_FEATURE_PORT_LOW_SPEED = 9,
     56        USB_HUB_FEATURE_PORT_HIGH_SPEED = 10,
    5657        USB_HUB_FEATURE_C_PORT_CONNECTION = 16,
    5758        USB_HUB_FEATURE_C_PORT_ENABLE = 17,
     
    5960        USB_HUB_FEATURE_C_PORT_OVER_CURRENT = 19,
    6061        USB_HUB_FEATURE_C_PORT_RESET = 20,
     62        USB_HUB_FEATURE_PORT_TEST = 21,
     63        USB_HUB_FEATURE_PORT_INDICATOR = 22
    6164        /* USB_HUB_FEATURE_ = , */
    6265} usb_hub_class_feature_t;
     
    6770        /** Descriptor length. */
    6871        uint8_t length;
     72
    6973        /** Descriptor type (0x29). */
    7074        uint8_t descriptor_type;
     75
    7176        /** Number of downstream ports. */
    7277        uint8_t port_count;
    73         /** Characteristics bitmask. */
     78
     79        /** Characteristics bitmask.
     80         *
     81         *  D1..D0: Logical Power Switching Mode
     82         *  00: Ganged power switching (all ports power at
     83         *  once)
     84         *  01: Individual port power switching
     85         *  1X: Reserved. Used only on 1.0 compliant hubs
     86         *  that implement no power switching.
     87         *  D2: Identifies a Compound Device
     88         *  0: Hub is not part of a compound device
     89         *  1: Hub is part of a compound device
     90         *  D4..D3: Over-current Protection Mode
     91         *  00: Global Over-current Protection. The hub
     92         *  reports over-current as a summation of all
     93         *  ports current draw, without a breakdown of
     94         *  individual port over-current status.
     95         *  01: Individual Port Over-current Protection. The
     96         *  hub reports over-current on a per-port basis.
     97         *  Each port has an over-current indicator.
     98         *  1X: No Over-current Protection. This option is
     99         *  allowed only for bus-powered hubs that do not
     100         *  implement over-current protection.
     101         *  D6..D5: TT think time
     102         *  00: At most 8 FS bit times
     103         *  01: At most 16 FS bit times
     104         *  10: At most 24 FS bit times
     105         *  11: At most 32 FS bit times
     106         *  D7: Port indicators
     107         *  0: Not supported
     108         *  1: Supported
     109         *  D15...D8: Reserved
     110         */
    74111        uint8_t characteristics;
    75 #define HUB_CHAR_POWER_PER_PORT_FLAG  (1 << 0)
    76 #define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1)
    77         /* Unused part of characteristics field */
     112#define HUB_CHAR_POWER_PER_PORT_FLAG    (1 << 0)
     113#define HUB_CHAR_NO_POWER_SWITCH_FLAG   (1 << 1)
     114#define HUB_CHAR_COMPOUND_DEVICE        (1 << 2)
     115#define HUB_CHAR_OC_PER_PORT_FLAG       (1 << 3)
     116#define HUB_CHAR_NO_OC_FLAG             (1 << 4)
     117#define HUB_CHAR_TT_THINK_16            (1 << 5)
     118#define HUB_CHAR_TT_THINK_8             (1 << 6)
     119#define HUB_CHAR_INDICATORS_FLAG        (1 << 7)
     120
     121        /** Unused part of characteristics field */
    78122        uint8_t characteristics_reserved;
    79         /** Time from power-on to stabilization of current on the port. */
     123
     124        /** Time from power-on to stabilization of current on the port.
     125         *
     126         *  Time (in 2ms intervals) from the time the power-on
     127         *  sequence begins on a port until power is good on that
     128         *  port. The USB System Software uses this value to
     129         *  determine how long to wait before accessing a
     130         *  powered-on port.
     131         */
    80132        uint8_t power_good_time;
    81         /** Maximum current requirements in mA. */
     133        /** Maximum current requirements in mA.
     134         *
     135         *  Maximum current requirements of the Hub Controller
     136         *  electronics in mA.
     137         */
    82138        uint8_t max_current;
    83139} __attribute__ ((packed)) usb_hub_descriptor_header_t;
    84140
    85 /**
    86  * @brief usb hub descriptor
    87  *
    88  * For more information see Universal Serial Bus Specification Revision 1.1
    89  * chapter 11.16.2
    90  */
    91 typedef struct usb_hub_descriptor_type {
    92     /** Number of bytes in this descriptor, including this byte */
    93     //uint8_t bDescLength;
    94 
    95     /** Descriptor Type, value: 29H for hub descriptor */
    96     //uint8_t bDescriptorType;
    97 
    98     /** Number of downstream ports that this hub supports */
    99     uint8_t port_count;
    100 
    101     /**
    102             D1...D0: Logical Power Switching Mode
    103             00: Ganged power switching (all ports power at
    104             once)
    105             01: Individual port power switching
    106             1X: Reserved. Used only on 1.0 compliant hubs
    107             that implement no power switching.
    108             D2: Identifies a Compound Device
    109             0: Hub is not part of a compound device
    110             1: Hub is part of a compound device
    111             D4...D3: Over-current Protection Mode
    112             00: Global Over-current Protection. The hub
    113             reports over-current as a summation of all
    114             ports current draw, without a breakdown of
    115             individual port over-current status.
    116             01: Individual Port Over-current Protection. The
    117             hub reports over-current on a per-port basis.
    118             Each port has an over-current indicator.
    119             1X: No Over-current Protection. This option is
    120             allowed only for bus-powered hubs that do not
    121             implement over-current protection.
    122             D15...D5:
    123             Reserved
    124      */
    125     uint16_t hub_characteristics;
    126 
    127     /**
    128             Time (in 2ms intervals) from the time the power-on
    129             sequence begins on a port until power is good on that
    130             port. The USB System Software uses this value to
    131             determine how long to wait before accessing a
    132             powered-on port.
    133      */
    134     uint8_t pwr_on_2_good_time;
    135 
    136     /**
    137             Maximum current requirements of the Hub Controller
    138             electronics in mA.
    139      */
    140     uint8_t current_requirement;
    141 
    142     /**
    143             Indicates if a port has a removable device attached.
    144             This field is reported on byte-granularity. Within a
    145             byte, if no port exists for a given location, the field
    146             representing the port characteristics returns 0.
    147             Bit value definition:
    148             0B - Device is removable
    149             1B - Device is non-removable
    150             This is a bitmap corresponding to the individual ports
    151             on the hub:
    152             Bit 0: Reserved for future use
    153             Bit 1: Port 1
    154             Bit 2: Port 2
    155             ....
    156             Bit n: Port n (implementation-dependent, up to a
    157             maximum of 255 ports).
    158      */
    159     uint8_t devices_removable[32];
    160 
    161     /**
    162             This field exists for reasons of compatibility with
    163             software written for 1.0 compliant devices. All bits in
    164             this field should be set to 1B. This field has one bit for
    165             each port on the hub with additional pad bits, if
    166             necessary, to make the number of bits in the field an
    167             integer multiple of 8.
    168      */
    169     //uint8_t * port_pwr_ctrl_mask;
    170 } usb_hub_descriptor_t;
    171 
    172 
     141/** One bit for the device and one bit for every port */
     142#define STATUS_BYTES(ports) ((1 + ports + 7) / 8)
    173143
    174144/**     @brief usb hub specific request types.
     
    204174    /** */
    205175    USB_HUB_REQUEST_CLEAR_FEATURE = 1,
    206     /** */
     176    /** USB 1.0 only */
    207177    USB_HUB_REQUEST_GET_STATE = 2,
    208178    /** */
     
    211181    USB_HUB_REQUEST_GET_DESCRIPTOR = 6,
    212182    /** */
    213     USB_HUB_REQUEST_SET_DESCRIPTOR = 7
     183    USB_HUB_REQUEST_SET_DESCRIPTOR = 7,
     184    /** */
     185    USB_HUB_REQUEST_CLEAR_TT_BUFFER = 8,
     186    /** */
     187    USB_HUB_REQUEST_RESET_TT = 9,
     188    /** */
     189    USB_HUB_GET_TT_STATE = 10,
     190    /** */
     191    USB_HUB_STOP_TT = 11,
    214192} usb_hub_request_t;
    215193
     
    218196 */
    219197/* 7 (basic size) + 2*32 (port bitmasks) */
    220 #define USB_HUB_MAX_DESCRIPTOR_SIZE 71
     198#define USB_HUB_MAX_DESCRIPTOR_SIZE (7 + 2 * 32)
    221199
    222200#endif
  • uspace/lib/usb/include/usb/classes/massstor.h

    r5b18137 rb4b534ac  
    3636#define LIBUSB_CLASS_MASSSTOR_H_
    3737
    38 #include <sys/types.h>
    39 
    4038/** USB mass storage subclasses. */
    4139typedef enum {
  • uspace/lib/usb/include/usb/debug.h

    r5b18137 rb4b534ac  
    3636#define LIBUSB_DEBUG_H_
    3737#include <stdio.h>
    38 #include <inttypes.h>
    39 #include <usb/usb.h>
     38#include <sys/types.h>
    4039#include <io/log.h>
    41 #include <assert.h>
     40
    4241
    4342void usb_dump_standard_descriptor(FILE *, const char *, const char *,
  • uspace/lib/usb/include/usb/descriptor.h

    r5b18137 rb4b534ac  
    3636#define LIBUSB_DESCRIPTOR_H_
    3737
    38 #include <async.h>
     38#include <sys/types.h>
    3939
    4040/** Descriptor type. */
     
    4545        USB_DESCTYPE_INTERFACE = 4,
    4646        USB_DESCTYPE_ENDPOINT = 5,
     47        /* New in USB2.0 */
     48        USB_DESCTYPE_DEVICE_QUALIFIER = 6,
     49        USB_DESCTYPE_OTHER_SPEED_CONFIGURATION = 7,
     50        USB_DESCTYPE_INTERFACE_POWER = 8,
     51        /* Class specific */
    4752        USB_DESCTYPE_HID = 0x21,
    4853        USB_DESCTYPE_HID_REPORT = 0x22,
     
    8994} __attribute__ ((packed)) usb_standard_device_descriptor_t;
    9095
     96/** USB device qualifier decriptor is basically a cut down version of the device
     97 * descriptor with values that would be valid if the device operated on the
     98 * other speed (HIGH vs. FULL)
     99 */
     100typedef struct {
     101        /** Size of this descriptor in bytes */
     102        uint8_t length;
     103        /** Descriptor type (USB_DESCTYPE_DEVICE_QUALIFIER) */
     104        uint8_t descriptor_type;
     105        /** USB specification release number.
     106         * The number shall be coded as binary-coded decimal (BCD).
     107         */
     108        uint16_t usb_spec_version;
     109        /** Device class. */
     110        uint8_t device_class;
     111        /** Device sub-class. */
     112        uint8_t device_subclass;
     113        /** Device protocol. */
     114        uint8_t device_protocol;
     115        /** Maximum packet size for endpoint zero.
     116         * Valid values are only 8, 16, 32, 64).
     117         */
     118        uint8_t max_packet_size;
     119        /** Number of possible configurations. */
     120        uint8_t configuration_count;
     121        uint8_t reserved;
     122} __attribute__ ((packed)) usb_standard_device_qualifier_descriptor_t;
     123
    91124/** Standard USB configuration descriptor.
    92125 */
     
    116149} __attribute__ ((packed)) usb_standard_configuration_descriptor_t;
    117150
     151/** USB Other Speed Configuration descriptor shows values that would change
     152 * in the configuration descriptor if the device operated at its other
     153 * possible speed (HIGH vs. FULL)
     154 */
     155typedef usb_standard_configuration_descriptor_t
     156    usb_other_speed_configuration_descriptor_t;
     157
    118158/** Standard USB interface descriptor.
    119159 */
     
    157197         */
    158198        uint8_t attributes;
    159         /** Maximum packet size. */
     199        /** Maximum packet size.
     200         * Lower 10 bits represent the actuall size
     201         * Bits 11,12 specify addtional transfer opportunitities for
     202         * HS INT and ISO transfers. */
    160203        uint16_t max_packet_size;
     204#define ED_MPS_PACKET_SIZE_MASK  0x3ff
     205#define ED_MPS_PACKET_SIZE_GET(value) \
     206        ((value) & ED_MPS_PACKET_SIZE_MASK)
     207#define ED_MPS_TRANS_OPPORTUNITIES_GET(value) \
     208        ((((value) >> 10) & 0x3) + 1)
    161209        /** Polling interval in milliseconds.
    162210         * Ignored for bulk and control endpoints.
  • uspace/lib/usb/include/usb/dev.h

    r5b18137 rb4b534ac  
    3636
    3737#include <devman.h>
    38 #include <usb/usb.h>
    3938
    40 int usb_get_info_by_handle(devman_handle_t,
    41     devman_handle_t *, usb_address_t *, int *);
    42 
    43 static inline int usb_get_hc_by_handle(devman_handle_t dev, devman_handle_t *hc)
    44 {
    45         return usb_get_info_by_handle(dev, hc, NULL, NULL);
    46 }
    47 
    48 static inline int usb_get_address_by_handle(
    49     devman_handle_t dev, usb_address_t *address)
    50 {
    51         return usb_get_info_by_handle(dev, NULL, address, NULL);
    52 }
    53 
    54 static inline int usb_get_iface_by_handle(devman_handle_t dev, int *iface)
    55 {
    56         return usb_get_info_by_handle(dev, NULL, NULL, iface);
    57 }
    58 
    59 int usb_resolve_device_handle(const char *, devman_handle_t *, usb_address_t *,
    60     devman_handle_t *);
     39int usb_resolve_device_handle(const char *, devman_handle_t *);
    6140#endif
    6241/**
  • uspace/lib/usb/include/usb/usb.h

    r5b18137 rb4b534ac  
    8484} usb_speed_t;
    8585
     86static inline bool usb_speed_is_11(const usb_speed_t s)
     87{
     88        return (s == USB_SPEED_FULL) || (s == USB_SPEED_LOW);
     89}
     90
    8691const char *usb_str_speed(usb_speed_t);
    8792
     
    110115#define USB_ADDRESS_DEFAULT 0
    111116/** Maximum address number in USB 1.1. */
    112 #define USB11_ADDRESS_MAX 128
     117#define USB11_ADDRESS_MAX 127
     118#define USB_ADDRESS_COUNT (USB11_ADDRESS_MAX + 1)
     119
     120/** Check USB address for allowed values.
     121 *
     122 * @param ep USB address.
     123 * @return True, if value is wihtin limits, false otherwise.
     124 */
     125static inline bool usb_address_is_valid(usb_address_t a)
     126{
     127        return (a >= USB_ADDRESS_DEFAULT) && (a <= USB11_ADDRESS_MAX);
     128}
    113129
    114130/** USB endpoint number type.
     
    117133typedef int16_t usb_endpoint_t;
    118134
    119 /** Maximum endpoint number in USB 1.1.
    120  */
     135/** Default control endpoint */
     136#define USB_ENDPOINT_DEFAULT_CONTROL 0
     137/** Maximum endpoint number in USB 1.1. */
    121138#define USB11_ENDPOINT_MAX 16
     139
     140/** Check USB endpoint for allowed values.
     141 *
     142 * @param ep USB endpoint number.
     143 * @return True, if value is wihtin limits, false otherwise.
     144 */
     145static inline bool usb_endpoint_is_valid(usb_endpoint_t ep)
     146{
     147        return (ep >= USB_ENDPOINT_DEFAULT_CONTROL) &&
     148            (ep < USB11_ENDPOINT_MAX);
     149}
    122150
    123151
     
    133161} usb_target_t;
    134162
     163
    135164/** Check USB target for allowed values (address and endpoint).
    136165 *
     
    140169static inline bool usb_target_is_valid(usb_target_t target)
    141170{
    142         return !(target.endpoint > 15 || target.endpoint < 0
    143             || target.address >= USB11_ADDRESS_MAX || target.address < 0);
     171        return usb_address_is_valid(target.address) &&
     172            usb_endpoint_is_valid(target.endpoint);
    144173}
    145174
  • uspace/lib/usb/src/class.c

    r5b18137 rb4b534ac  
    3434 */
    3535#include <usb/classes/classes.h>
    36 #include <errno.h>
    3736
    3837/** Tell string representation of USB class.
  • uspace/lib/usb/src/debug.c

    r5b18137 rb4b534ac  
    3333 * Debugging and logging support.
    3434 */
    35 #include <adt/list.h>
    3635#include <fibril_synch.h>
    37 #include <errno.h>
    38 #include <stdlib.h>
    39 #include <stdio.h>
    4036#include <ddf/log.h>
    4137#include <usb/debug.h>
  • uspace/lib/usb/src/dev.c

    r5b18137 rb4b534ac  
    2929
    3030#include <usb/dev.h>
    31 #include <usb/hc.h>
    3231#include <errno.h>
    3332#include <usb_iface.h>
    3433#include <str.h>
    3534#include <stdio.h>
    36 
    37 #define MAX_DEVICE_PATH 1024
    38 
    39 /** Find host controller handle, address and iface number for the device.
    40  *
    41  * @param[in] device_handle Device devman handle.
    42  * @param[out] hc_handle Where to store handle of host controller
    43  *      controlling device with @p device_handle handle.
    44  * @param[out] address Place to store the device's address
    45  * @param[out] iface Place to stoer the assigned USB interface number.
    46  * @return Error code.
    47  */
    48 int usb_get_info_by_handle(devman_handle_t device_handle,
    49     devman_handle_t *hc_handle, usb_address_t *address, int *iface)
    50 {
    51         async_sess_t *parent_sess =
    52             devman_parent_device_connect(device_handle, IPC_FLAG_BLOCKING);
    53         if (!parent_sess)
    54                 return ENOMEM;
    55 
    56         async_exch_t *exch = async_exchange_begin(parent_sess);
    57         if (!exch) {
    58                 async_hangup(parent_sess);
    59                 return ENOMEM;
    60         }
    61 
    62         usb_address_t tmp_address;
    63         devman_handle_t tmp_handle;
    64         int tmp_iface;
    65 
    66         if (address) {
    67                 const int ret = usb_get_my_address(exch, &tmp_address);
    68                 if (ret != EOK) {
    69                         async_exchange_end(exch);
    70                         async_hangup(parent_sess);
    71                         return ret;
    72                 }
    73         }
    74 
    75         if (hc_handle) {
    76                 const int ret = usb_get_hc_handle(exch, &tmp_handle);
    77                 if (ret != EOK) {
    78                         async_exchange_end(exch);
    79                         async_hangup(parent_sess);
    80                         return ret;
    81                 }
    82         }
    83 
    84         if (iface) {
    85                 const int ret = usb_get_my_interface(exch, &tmp_iface);
    86                 switch (ret) {
    87                 case ENOTSUP:
    88                         /* Implementing GET_MY_INTERFACE is voluntary. */
    89                         tmp_iface = -1;
    90                 case EOK:
    91                         break;
    92                 default:
    93                         async_exchange_end(exch);
    94                         async_hangup(parent_sess);
    95                         return ret;
    96                 }
    97         }
    98 
    99         if (hc_handle)
    100                 *hc_handle = tmp_handle;
    101 
    102         if (address)
    103                 *address = tmp_address;
    104 
    105         if (iface)
    106                 *iface = tmp_iface;
    107 
    108         async_exchange_end(exch);
    109         async_hangup(parent_sess);
    110 
    111         return EOK;
    112 }
    113 
    114 static bool try_parse_bus_and_address(const char *path,
    115     const char **func_start,
    116     devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
    117 {
    118         uint64_t sid;
    119         size_t address;
    120         int rc;
    121         const char *ptr;
    122 
    123         rc = str_uint64_t(path, &ptr, 10, false, &sid);
    124         if (rc != EOK) {
    125                 return false;
    126         }
    127         if ((*ptr == ':') || (*ptr == '.')) {
    128                 ptr++;
    129         } else {
    130                 return false;
    131         }
    132         rc = str_size_t(ptr, func_start, 10, false, &address);
    133         if (rc != EOK) {
    134                 return false;
    135         }
    136         rc = usb_ddf_get_hc_handle_by_sid(sid, out_hc_handle);
    137         if (rc != EOK) {
    138                 return false;
    139         }
    140         if (out_device_address != NULL) {
    141                 *out_device_address = (usb_address_t) address;
    142         }
    143         return true;
    144 }
    145 
    146 static int get_device_handle_by_address(devman_handle_t hc_handle, int addr,
    147     devman_handle_t *dev_handle)
    148 {
    149         usb_hc_connection_t conn;
    150         usb_hc_connection_initialize(&conn, hc_handle);
    151 
    152         const int rc = usb_hc_get_handle_by_address(&conn, addr, dev_handle);
    153 
    154         return rc;
    155 }
    15635
    15736/** Resolve handle and address of USB device from its path.
     
    17453 * @return Error code.
    17554 */
    176 int usb_resolve_device_handle(const char *dev_path, devman_handle_t *out_hc_handle,
    177     usb_address_t *out_dev_addr, devman_handle_t *out_dev_handle)
     55int usb_resolve_device_handle(const char *dev_path, devman_handle_t *dev_handle)
    17856{
    179         if (dev_path == NULL) {
     57        if (dev_path == NULL || dev_handle == NULL) {
    18058                return EBADMEM;
    18159        }
    18260
    183         bool found_hc = false;
    184         bool found_addr = false;
    185         devman_handle_t hc_handle, dev_handle;
    186         usb_address_t dev_addr = -1;
    187         int rc;
    188         bool is_bus_addr;
    189         const char *func_start = NULL;
    190         char *path = NULL;
     61        /* First, try to get the device handle. */
     62        int rc = devman_fun_get_handle(dev_path, dev_handle, 0);
    19163
    192         /* First try the BUS.ADDR format. */
    193         is_bus_addr = try_parse_bus_and_address(dev_path, &func_start,
    194             &hc_handle, &dev_addr);
    195         if (is_bus_addr) {
    196                 found_hc = true;
    197                 found_addr = true;
    198                 /*
    199                  * Now get the handle of the device. We will need that
    200                  * in both cases. If there is only BUS.ADDR, it will
    201                  * be the handle to be returned to the caller, otherwise
    202                  * we will need it to resolve the path to which the
    203                  * suffix would be appended.
    204                  */
    205                 /* If there is nothing behind the BUS.ADDR, we will
    206                  * get the device handle from the host controller.
    207                  * Otherwise, we will
    208                  */
    209                 rc = get_device_handle_by_address(hc_handle, dev_addr,
    210                     &dev_handle);
    211                 if (rc != EOK) {
    212                         return rc;
    213                 }
    214                 if (str_length(func_start) > 0) {
    215                         char tmp_path[MAX_DEVICE_PATH];
    216                         rc = devman_fun_get_path(dev_handle,
    217                             tmp_path, MAX_DEVICE_PATH);
    218                         if (rc != EOK) {
    219                                 return rc;
    220                         }
    221                         rc = asprintf(&path, "%s%s", tmp_path, func_start);
    222                         if (rc < 0) {
    223                                 return ENOMEM;
    224                         }
    225                 } else {
    226                         /* Everything is resolved. Get out of here. */
    227                         goto copy_out;
    228                 }
    229         } else {
    230                 path = str_dup(dev_path);
    231                 if (path == NULL) {
    232                         return ENOMEM;
    233                 }
     64        /* Next, try parsing dev_handle from the provided string */
     65        if (rc != EOK) {
     66                *dev_handle = strtoul(dev_path, NULL, 10);
     67                //FIXME: check errno
     68                rc = EOK;
    23469        }
    235 
    236         /* First try to get the device handle. */
    237         rc = devman_fun_get_handle(path, &dev_handle, 0);
    238         if (rc != EOK) {
    239                 free(path);
    240                 /* Invalid path altogether. */
    241                 return rc;
    242         }
    243 
    244         /* Remove suffixes and hope that we will encounter device node. */
    245         while (str_length(path) > 0) {
    246                 /* Get device handle first. */
    247                 devman_handle_t tmp_handle;
    248                 rc = devman_fun_get_handle(path, &tmp_handle, 0);
    249                 if (rc != EOK) {
    250                         free(path);
    251                         return rc;
    252                 }
    253 
    254                 /* Try to find its host controller. */
    255                 if (!found_hc) {
    256                         rc = usb_get_hc_by_handle(tmp_handle, &hc_handle);
    257                         if (rc == EOK) {
    258                                 found_hc = true;
    259                         }
    260                 }
    261 
    262                 /* Try to get its address. */
    263                 if (!found_addr) {
    264                         rc = usb_get_address_by_handle(tmp_handle, &dev_addr);
    265                         if (rc == 0) {
    266                                 found_addr = true;
    267                         }
    268                 }
    269 
    270                 /* Speed-up. */
    271                 if (found_hc && found_addr) {
    272                         break;
    273                 }
    274 
    275                 /* Remove the last suffix. */
    276                 char *slash_pos = str_rchr(path, '/');
    277                 if (slash_pos != NULL) {
    278                         *slash_pos = 0;
    279                 }
    280         }
    281 
    282         free(path);
    283 
    284         if (!found_addr || !found_hc) {
    285                 return ENOENT;
    286         }
    287 
    288 copy_out:
    289         if (out_dev_addr != NULL) {
    290                 *out_dev_addr = dev_addr;
    291         }
    292         if (out_hc_handle != NULL) {
    293                 *out_hc_handle = hc_handle;
    294         }
    295         if (out_dev_handle != NULL) {
    296                 *out_dev_handle = dev_handle;
    297         }
    298 
    299         return EOK;
     70        return rc;
    30071}
  • uspace/lib/usb/src/dump.c

    r5b18137 rb4b534ac  
    3333 * Descriptor dumping.
    3434 */
    35 #include <adt/list.h>
    36 #include <fibril_synch.h>
    37 #include <errno.h>
    3835#include <stdlib.h>
    3936#include <stdio.h>
     
    4138#include <usb/descriptor.h>
    4239#include <usb/classes/classes.h>
     40#include <usb/classes/hub.h>
     41#include <usb/usb.h>
    4342
    4443/** Mapping between descriptor id and dumping function. */
     
    276275    const uint8_t *descriptor, size_t descriptor_length)
    277276{
    278         /* TODO */
     277        usb_hub_descriptor_header_t *d =
     278            (usb_hub_descriptor_header_t *) descriptor;
     279        if (descriptor_length < sizeof(d))
     280                return;
     281
     282        PRINTLINE("bDescLength: = %d", d->length);
     283        PRINTLINE("bDescriptorType = 0x%02x", d->descriptor_type);
     284        PRINTLINE("bNbrPorts = %d", d->port_count);
     285        PRINTLINE("bHubCharacteristics = 0x%02x%02x (%s;%s%s)",
     286            d->characteristics_reserved, d->characteristics,
     287            (d->characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG) ?
     288                "No Power Switching" :
     289                ((d->characteristics & HUB_CHAR_POWER_PER_PORT_FLAG) ?
     290                    "Per-Port Switching" : "Ganged Power Switching"),
     291            (d->characteristics & HUB_CHAR_COMPOUND_DEVICE) ?
     292                "Compound Device;" : "",
     293            (d->characteristics & HUB_CHAR_NO_OC_FLAG) ?
     294                "No OC Protection" :
     295                    ((d->characteristics & HUB_CHAR_OC_PER_PORT_FLAG) ?
     296                        "Individual Port OC Protection" :
     297                            "Global OC Protection")
     298        );
     299        PRINTLINE("bPwrOn2PwrGood = %d (%d ms)",
     300            d->power_good_time, d->power_good_time * 2);
     301        PRINTLINE("bHubContrCurrent = %d (%d mA)",
     302            d->max_current, d->max_current);
     303        const size_t port_bytes = (descriptor_length - sizeof(*d)) / 2;
     304        const uint8_t *removable_mask = descriptor + sizeof(*d);
     305        const uint8_t *powered_mask = descriptor + sizeof(*d) + port_bytes;
     306
     307        if (port_bytes == 0
     308            || port_bytes > (((d->port_count / (unsigned)8) + 1) * 2)) {
     309                PRINTLINE("::CORRUPTED DESCRIPTOR:: (%zu bytes remain)",
     310                    port_bytes * 2);
     311        }
     312
     313        fprintf(output, "%sDeviceRemovable = 0x",
     314            line_prefix ? line_prefix : " - ");
     315        for (unsigned i = port_bytes; i > 0; --i)
     316                fprintf(output, "%02x", removable_mask[i - 1]);
     317        fprintf(output, " (0b1 - Device non-removable)%s",
     318            line_suffix ? line_suffix : "\n");
     319
     320        fprintf(output, "%sPortPwrCtrlMask = 0x",
     321            line_prefix ? line_prefix : " - ");
     322        for (unsigned i = port_bytes; i > 0; --i)
     323                fprintf(output, "%02x", powered_mask[i - 1]);
     324        fprintf(output, " (Legacy - All should be 0b1)%s",
     325            line_suffix ? line_suffix : "\n");
    279326}
    280327
  • uspace/lib/usb/src/usb.c

    r5b18137 rb4b534ac  
    3434 */
    3535#include <usb/usb.h>
    36 #include <errno.h>
     36#include <usb/request.h>
    3737
    38 #define ARR_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
     38#include <assert.h>
     39#include <byteorder.h>
     40#include <macros.h>
    3941
    4042static const char *str_speed[] = {
     
    7173const char *usb_str_transfer_type(usb_transfer_type_t t)
    7274{
    73         if (t >= ARR_SIZE(str_transfer_type)) {
     75        if (t >= ARRAY_SIZE(str_transfer_type)) {
    7476                return "invalid";
    7577        }
     
    8486const char *usb_str_transfer_type_short(usb_transfer_type_t t)
    8587{
    86         if (t >= ARR_SIZE(str_transfer_type_short)) {
     88        if (t >= ARRAY_SIZE(str_transfer_type_short)) {
    8789                return "invl";
    8890        }
     
    9799const char *usb_str_direction(usb_direction_t d)
    98100{
    99         if (d >= ARR_SIZE(str_direction)) {
     101        if (d >= ARRAY_SIZE(str_direction)) {
    100102                return "invalid";
    101103        }
     
    110112const char *usb_str_speed(usb_speed_t s)
    111113{
    112         if (s >= ARR_SIZE(str_speed)) {
     114        if (s >= ARRAY_SIZE(str_speed)) {
    113115                return "invalid";
    114116        }
     
    116118}
    117119
     120/** Check setup packet data for signs of toggle reset.
     121 *
     122 * @param[in] requst Setup requst data.
     123 * @retval -1 No endpoints need reset.
     124 * @retval 0 All endpoints need reset.
     125 * @retval >0 Specified endpoint needs reset.
     126 */
     127int usb_request_needs_toggle_reset(
     128    const usb_device_request_setup_packet_t *request)
     129{
     130        assert(request);
     131        switch (request->request)
     132        {
     133        /* Clear Feature ENPOINT_STALL */
     134        case USB_DEVREQ_CLEAR_FEATURE: /*resets only cleared ep */
     135                /* 0x2 ( HOST to device | STANDART | TO ENPOINT) */
     136                if ((request->request_type == 0x2) &&
     137                    (request->value == USB_FEATURE_ENDPOINT_HALT))
     138                        return uint16_usb2host(request->index);
     139                break;
     140        case USB_DEVREQ_SET_CONFIGURATION:
     141        case USB_DEVREQ_SET_INTERFACE:
     142                /* Recipient must be device, this resets all endpoints,
     143                 * In fact there should be no endpoints but EP 0 registered
     144                 * as different interfaces use different endpoints,
     145                 * unless you're changing configuration or alternative
     146                 * interface of an already setup device. */
     147                if (!(request->request_type & SETUP_REQUEST_TYPE_DEVICE_TO_HOST))
     148                        return 0;
     149                break;
     150        default:
     151                break;
     152        }
     153        return -1;
     154}
     155
    118156/**
    119157 * @}
Note: See TracChangeset for help on using the changeset viewer.