Changeset 72af8da in mainline for uspace/lib


Ignore:
Timestamp:
2011-03-16T18:50:17Z (15 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
42a3a57
Parents:
3e7b7cd (diff), fcf07e6 (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 usb/development

Location:
uspace/lib
Files:
3 added
2 deleted
23 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/block/libblock.c

    r3e7b7cd r72af8da  
    411411        l = hash_table_find(&cache->block_hash, &key);
    412412        if (l) {
     413found:
    413414                /*
    414415                 * We found the block in the cache.
     
    493494                                        fibril_mutex_unlock(&b->lock);
    494495                                        goto retry;
     496                                }
     497                                l = hash_table_find(&cache->block_hash, &key);
     498                                if (l) {
     499                                        /*
     500                                         * Someone else must have already
     501                                         * instantiated the block while we were
     502                                         * not holding the cache lock.
     503                                         * Leave the recycled block on the
     504                                         * freelist and continue as if we
     505                                         * found the block of interest during
     506                                         * the first try.
     507                                         */
     508                                        fibril_mutex_unlock(&b->lock);
     509                                        goto found;
    495510                                }
    496511
  • uspace/lib/drv/generic/remote_usbhc.c

    r3e7b7cd r72af8da  
    5555static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    5656static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     57static void remote_usbhc_register_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     58static void remote_usbhc_unregister_endpoint(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    5759//static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    5860
     
    7375
    7476        remote_usbhc_control_write,
    75         remote_usbhc_control_read
     77        remote_usbhc_control_read,
     78
     79        remote_usbhc_register_endpoint,
     80        remote_usbhc_unregister_endpoint
    7681};
    7782
     
    522527
    523528
     529void remote_usbhc_register_endpoint(ddf_fun_t *fun, void *iface,
     530    ipc_callid_t callid, ipc_call_t *call)
     531{
     532        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     533
     534        if (!usb_iface->register_endpoint) {
     535                async_answer_0(callid, ENOTSUP);
     536                return;
     537        }
     538
     539#define INIT_FROM_HIGH_DATA(type, var, arg_no) \
     540        type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / 256
     541#define INIT_FROM_LOW_DATA(type, var, arg_no) \
     542        type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % 256
     543
     544        INIT_FROM_HIGH_DATA(usb_address_t, address, 1);
     545        INIT_FROM_LOW_DATA(usb_endpoint_t, endpoint, 1);
     546        INIT_FROM_HIGH_DATA(usb_transfer_type_t, transfer_type, 2);
     547        INIT_FROM_LOW_DATA(usb_direction_t, direction, 2);
     548
     549#undef INIT_FROM_HIGH_DATA
     550#undef INIT_FROM_LOW_DATA
     551
     552        size_t max_packet_size = (size_t) DEV_IPC_GET_ARG3(*call);
     553        unsigned int interval  = (unsigned int) DEV_IPC_GET_ARG4(*call);
     554
     555        int rc = usb_iface->register_endpoint(fun, address, endpoint,
     556            transfer_type, direction, max_packet_size, interval);
     557
     558        async_answer_0(callid, rc);
     559}
     560
     561
     562void remote_usbhc_unregister_endpoint(ddf_fun_t *fun, void *iface,
     563    ipc_callid_t callid, ipc_call_t *call)
     564{
     565        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     566
     567        if (!usb_iface->unregister_endpoint) {
     568                async_answer_0(callid, ENOTSUP);
     569                return;
     570        }
     571
     572        usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
     573        usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG2(*call);
     574        usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG3(*call);
     575
     576        int rc = usb_iface->unregister_endpoint(fun,
     577            address, endpoint, direction);
     578
     579        async_answer_0(callid, rc);
     580}
     581
    524582
    525583/**
  • uspace/lib/drv/include/usbhc_iface.h

    r3e7b7cd r72af8da  
    167167        IPC_M_USBHC_CONTROL_READ,
    168168
    169         /* IPC_M_USB_ */
     169        /** Register endpoint attributes at host controller.
     170         * This is used to reserve portion of USB bandwidth.
     171         * Parameters:
     172         * - USB address + endpoint number (ADDR * 256 + EP)
     173         * - transfer type + direction (TYPE * 256 + DIR)
     174         * - maximum packet size
     175         * - interval (in milliseconds)
     176         * Answer:
     177         * - EOK - reservation successful
     178         * - ELIMIT - not enough bandwidth to satisfy the request
     179         */
     180        IPC_M_USBHC_REGISTER_ENDPOINT,
     181
     182        /** Revert endpoint registration.
     183         * Parameters:
     184         * - USB address
     185         * - endpoint number
     186         * - data direction
     187         * Answer:
     188         * - EOK - endpoint unregistered
     189         * - ENOENT - unknown endpoint
     190         */
     191        IPC_M_USBHC_UNREGISTER_ENDPOINT
    170192} usbhc_iface_funcs_t;
    171193
     
    200222        int (*release_address)(ddf_fun_t *, usb_address_t);
    201223
     224        int (*register_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
     225            usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
     226        int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
     227            usb_direction_t);
     228
    202229        usbhc_iface_transfer_out_t interrupt_out;
    203230        usbhc_iface_transfer_in_t interrupt_in;
  • uspace/lib/usb/Makefile

    r3e7b7cd r72af8da  
    3737        src/ddfiface.c \
    3838        src/debug.c \
     39        src/devdrv.c \
     40        src/devpoll.c \
    3941        src/dp.c \
    4042        src/dump.c \
     
    4749        src/request.c \
    4850        src/usb.c \
    49         src/usbdevice.c \
    50         src/usbmem.c
     51        src/usbdevice.c
    5152
    5253include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usb/include/usb/classes/classes.h

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief USB device classes and subclasses.
     33 * USB device classes (generic constants and functions).
    3434 */
    3535#ifndef LIBUSB_CLASSES_H_
  • uspace/lib/usb/include/usb/debug.h

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief Debugging related functions.
     33 * Debugging related functions.
    3434 */
    3535#ifndef LIBUSB_DEBUG_H_
     
    3939#include <assert.h>
    4040
    41 void usb_dprintf(const char *tag, int level, const char *format, ...);
    42 void usb_dprintf_enable(const char *tag, int level);
    43 
    4441void usb_dump_standard_descriptor(FILE *, const char *, const char *,
    4542    const uint8_t *, size_t);
     
    4744/** Logging level. */
    4845typedef enum {
     46        /** Fatal, unrecoverable, error.
     47         * Such error prevents the driver from working at all.
     48         */
    4949        USB_LOG_LEVEL_FATAL,
     50
     51        /** Serious but recoverable error
     52         * Shall be used for errors fatal for single device but not for
     53         * driver itself.
     54         */
    5055        USB_LOG_LEVEL_ERROR,
     56
     57        /** Warning.
     58         * Problems from which the driver is able to recover gracefully.
     59         */
    5160        USB_LOG_LEVEL_WARNING,
     61
     62        /** Information message.
     63         * This should be the last level that is printed by default to
     64         * the screen.
     65         * Typical usage is to inform that new device was found and what
     66         * are its capabilities.
     67         * Do not use for repetitive actions (such as device polling).
     68         */
    5269        USB_LOG_LEVEL_INFO,
     70
     71        /** Debugging message. */
    5372        USB_LOG_LEVEL_DEBUG,
     73
     74        /** More detailed debugging message. */
    5475        USB_LOG_LEVEL_DEBUG2,
     76
     77        /** Terminating constant for logging levels. */
    5578        USB_LOG_LEVEL_MAX
    5679} usb_log_level_t;
     
    6184void usb_log_printf(usb_log_level_t, const char *, ...);
    6285
     86/** Log fatal error. */
    6387#define usb_log_fatal(format, ...) \
    6488        usb_log_printf(USB_LOG_LEVEL_FATAL, format, ##__VA_ARGS__)
    6589
     90/** Log normal (recoverable) error. */
    6691#define usb_log_error(format, ...) \
    6792        usb_log_printf(USB_LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
    6893
     94/** Log warning. */
    6995#define usb_log_warning(format, ...) \
    7096        usb_log_printf(USB_LOG_LEVEL_WARNING, format, ##__VA_ARGS__)
    7197
     98/** Log informational message. */
    7299#define usb_log_info(format, ...) \
    73100        usb_log_printf(USB_LOG_LEVEL_INFO, format, ##__VA_ARGS__)
    74101
     102/** Log debugging message. */
    75103#define usb_log_debug(format, ...) \
    76104        usb_log_printf(USB_LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
    77105
     106/** Log verbose debugging message. */
    78107#define usb_log_debug2(format, ...) \
    79108        usb_log_printf(USB_LOG_LEVEL_DEBUG2, format, ##__VA_ARGS__)
    80109
     110const char *usb_debug_str_buffer(const uint8_t *, size_t, size_t);
    81111
    82112
  • uspace/lib/usb/include/usb/descriptor.h

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief Standard USB descriptors.
     33 * Standard USB descriptors.
    3434 */
    3535#ifndef LIBUSB_DESCRIPTOR_H_
     
    8383        /** Product descriptor index. */
    8484        uint8_t str_product;
    85         /** Device serial number desriptor index. */
     85        /** Device serial number descriptor index. */
    8686        uint8_t str_serial_number;
    8787        /** Number of possible configurations. */
     
    167167} __attribute__ ((packed)) usb_standard_endpoint_descriptor_t;
    168168
    169 
    170 /* TODO: string descriptors. */
    171 
    172169#endif
    173170/**
  • uspace/lib/usb/include/usb/dp.h

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief USB descriptor parser.
     33 * USB descriptor parser.
    3434 */
    3535#ifndef LIBUSB_DP_H_
     
    4040#include <usb/descriptor.h>
    4141
     42/** USB descriptors nesting.
     43 * The nesting describes the logical tree USB descriptors form
     44 * (e.g. that endpoint descriptor belongs to interface or that
     45 * interface belongs to configuration).
     46 *
     47 * See usb_descriptor_type_t for descriptor constants.
     48 */
    4249typedef struct {
     50        /** Child descriptor id. */
    4351        int child;
     52        /** Parent descriptor id. */
    4453        int parent;
    4554} usb_dp_descriptor_nesting_t;
     
    4756extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];
    4857
     58/** Descriptor parser structure. */
    4959typedef struct {
     60        /** Used descriptor nesting. */
    5061        usb_dp_descriptor_nesting_t *nesting;
    5162} usb_dp_parser_t;
    5263
     64/** Descriptor parser data. */
    5365typedef struct {
     66        /** Data to be parsed. */
    5467        uint8_t *data;
     68        /** Size of input data in bytes. */
    5569        size_t size;
     70        /** Custom argument. */
    5671        void *arg;
    5772} usb_dp_parser_data_t;
  • uspace/lib/usb/include/usb/hub.h

    r3e7b7cd r72af8da  
    3232/** @file
    3333 * Functions needed by hub drivers.
     34 *
     35 * For class specific requests, see usb/classes/hub.h.
    3436 */
    3537#ifndef LIBUSB_HUB_H_
  • uspace/lib/usb/include/usb/pipes.h

    r3e7b7cd r72af8da  
    4343#include <ddf/driver.h>
    4444
    45 /**
    46  * Abstraction of a physical connection to the device.
     45/** Abstraction of a physical connection to the device.
    4746 * This type is an abstraction of the USB wire that connects the host and
    4847 * the function (device).
     
    5554} usb_device_connection_t;
    5655
    57 /**
    58  * Abstraction of a logical connection to USB device endpoint.
     56/** Abstraction of a logical connection to USB device endpoint.
    5957 * It encapsulates endpoint attributes (transfer type etc.) as well
    6058 * as information about currently running sessions.
     
    108106        const usb_endpoint_description_t *description;
    109107        /** Interface number the endpoint must belong to (-1 for any). */
    110         const int interface_no;
     108        int interface_no;
    111109        /** Found descriptor fitting the description. */
    112110        usb_standard_endpoint_descriptor_t *descriptor;
    113         /** Interface the endpoint belongs to. */
     111        /** Interface descriptor the endpoint belongs to. */
    114112        usb_standard_interface_descriptor_t *interface;
    115113        /** Whether the endpoint was actually found. */
     
    131129int usb_endpoint_pipe_initialize_default_control(usb_endpoint_pipe_t *,
    132130    usb_device_connection_t *);
     131int usb_endpoint_pipe_probe_default_control(usb_endpoint_pipe_t *);
    133132int usb_endpoint_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
    134133    size_t, uint8_t *, size_t, usb_device_connection_t *);
    135 
     134int usb_endpoint_pipe_register(usb_endpoint_pipe_t *, unsigned int,
     135    usb_hc_connection_t *);
     136int usb_endpoint_pipe_unregister(usb_endpoint_pipe_t *, usb_hc_connection_t *);
    136137
    137138int usb_endpoint_pipe_start_session(usb_endpoint_pipe_t *);
  • uspace/lib/usb/include/usb/request.h

    r3e7b7cd r72af8da  
    7272        union {
    7373                uint16_t value;
    74                 /* FIXME: add #ifdefs according to host endianess */
     74                /* FIXME: add #ifdefs according to host endianness */
    7575                struct {
    7676                        uint8_t value_low;
  • uspace/lib/usb/include/usb/usb.h

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief Base USB types.
     33 * Common USB types and functions.
    3434 */
    3535#ifndef LIBUSB_USB_H_
     
    121121} usb_target_t;
    122122
     123/** Compare USB targets (addresses and endpoints).
     124 *
     125 * @param a First target.
     126 * @param b Second target.
     127 * @return Whether @p a and @p b points to the same pipe on the same device.
     128 */
    123129static inline int usb_target_same(usb_target_t a, usb_target_t b)
    124130{
  • uspace/lib/usb/src/ddfiface.c

    r3e7b7cd r72af8da  
    5656/** Get host controller handle, interface implementation for hub driver.
    5757 *
    58  * @param[in] device Device the operation is running on.
     58 * @param[in] fun Device function the operation is running on.
    5959 * @param[out] handle Storage for the host controller handle.
    6060 * @return Error code.
     
    6969 * a hub driver.
    7070 *
    71  * @param[in] device Device the operation is running on.
     71 * @param[in] fun Device function the operation is running on.
    7272 * @param[out] handle Storage for the host controller handle.
    7373 * @return Error code.
     
    8888            IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle);
    8989
     90        async_hangup(parent_phone);
     91
    9092        if (rc != EOK) {
    9193                return rc;
     
    99101/** Get host controller handle, interface implementation for HC driver.
    100102 *
    101  * @param[in] device Device the operation is running on.
     103 * @param[in] fun Device function the operation is running on.
    102104 * @param[out] handle Storage for the host controller handle.
    103105 * @return Always EOK.
     
    116118/** Get USB device address, interface implementation for hub driver.
    117119 *
    118  * @param[in] device Device the operation is running on.
     120 * @param[in] fun Device function the operation is running on.
    119121 * @param[in] handle Devman handle of USB device we want address of.
    120122 * @param[out] address Storage for USB address of device with handle @p handle.
     
    151153 * a hub driver.
    152154 *
    153  * @param[in] device Device the operation is running on.
     155 * @param[in] fun Device function the operation is running on.
    154156 * @param[in] handle Devman handle of USB device we want address of.
    155157 * @param[out] address Storage for USB address of device with handle @p handle.
  • uspace/lib/usb/src/debug.c

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief Debugging support.
     33 * Debugging and logging support.
    3434 */
    3535#include <adt/list.h>
     
    4040#include <usb/debug.h>
    4141
    42 /** Debugging tag. */
    43 typedef struct {
    44         /** Linked list member. */
    45         link_t link;
    46         /** Tag name.
    47          * We always have a private copy of the name.
    48          */
    49         char *tag;
    50         /** Enabled level of debugging. */
    51         int level;
    52 } usb_debug_tag_t;
    53 
    54 /** Get instance of usb_debug_tag_t from link_t. */
    55 #define USB_DEBUG_TAG_INSTANCE(iterator) \
    56         list_get_instance(iterator, usb_debug_tag_t, link)
    57 
    58 /** List of all known tags. */
    59 static LIST_INITIALIZE(tag_list);
    60 /** Mutex guard for the list of all tags. */
    61 static FIBRIL_MUTEX_INITIALIZE(tag_list_guard);
    62 
    6342/** Level of logging messages. */
    6443static usb_log_level_t log_level = USB_LOG_LEVEL_WARNING;
     44
    6545/** Prefix for logging messages. */
    6646static const char *log_prefix = "usb";
     47
    6748/** Serialization mutex for logging functions. */
    6849static FIBRIL_MUTEX_INITIALIZE(log_serializer);
     50
     51/** File where to store the log. */
    6952static FILE *log_stream = NULL;
    7053
    71 /** Find or create new tag with given name.
    72  *
    73  * @param tagname Tag name.
    74  * @return Debug tag structure.
    75  * @retval NULL Out of memory.
    76  */
    77 static usb_debug_tag_t *get_tag(const char *tagname)
    78 {
    79         link_t *link;
    80         for (link = tag_list.next; \
    81             link != &tag_list; \
    82             link = link->next) {
    83                 usb_debug_tag_t *tag = USB_DEBUG_TAG_INSTANCE(link);
    84                 if (str_cmp(tag->tag, tagname) == 0) {
    85                         return tag;
    86                 }
    87         }
    88 
    89         /*
    90          * Tag not found, we will create a new one.
    91          */
    92         usb_debug_tag_t *new_tag = malloc(sizeof(usb_debug_tag_t));
    93         int rc = asprintf(&new_tag->tag, "%s", tagname);
    94         if (rc < 0) {
    95                 free(new_tag);
    96                 return NULL;
    97         }
    98         list_initialize(&new_tag->link);
    99         new_tag->level = 1;
    100 
    101         /*
    102          * Append it to the end of known tags.
    103          */
    104         list_append(&new_tag->link, &tag_list);
    105 
    106         return new_tag;
    107 }
    108 
    109 /** Print debugging information.
    110  * If the tag is used for the first time, its structures are automatically
    111  * created and initial verbosity level is set to 1.
    112  *
    113  * @param tagname Tag name.
    114  * @param level Level (verbosity) of the message.
    115  * @param format Formatting string for printf().
    116  */
    117 void usb_dprintf(const char *tagname, int level, const char *format, ...)
    118 {
    119         fibril_mutex_lock(&tag_list_guard);
    120         usb_debug_tag_t *tag = get_tag(tagname);
    121         if (tag == NULL) {
    122                 printf("USB debug: FATAL ERROR - failed to create tag.\n");
    123                 goto leave;
    124         }
    125 
    126         if (tag->level < level) {
    127                 goto leave;
    128         }
    129 
    130         va_list args;
    131         va_start(args, format);
    132 
    133         printf("[%s:%d]: ", tagname, level);
    134         vprintf(format, args);
    135 
    136         va_end(args);
    137 
    138 leave:
    139         fibril_mutex_unlock(&tag_list_guard);
    140 }
    141 
    142 /** Enable debugging prints for given tag.
    143  *
    144  * Setting level to <i>n</i> will cause that only printing messages
    145  * with level lower or equal to <i>n</i> will be printed.
    146  *
    147  * @param tagname Tag name.
    148  * @param level Enabled level.
    149  */
    150 void usb_dprintf_enable(const char *tagname, int level)
    151 {
    152         fibril_mutex_lock(&tag_list_guard);
    153         usb_debug_tag_t *tag = get_tag(tagname);
    154         if (tag == NULL) {
    155                 printf("USB debug: FATAL ERROR - failed to create tag.\n");
    156                 goto leave;
    157         }
    158 
    159         tag->level = level;
    160 
    161 leave:
    162         fibril_mutex_unlock(&tag_list_guard);
    163 }
    16454
    16555/** Enable logging.
     
    18272}
    18373
    184 
     74/** Get log level name prefix.
     75 *
     76 * @param level Log level.
     77 * @return String prefix for the message.
     78 */
    18579static const char *log_level_name(usb_log_level_t level)
    18680{
     
    252146}
    253147
     148
     149#define REMAINDER_STR_FMT " (%zu)..."
     150/* string + terminator + number width (enough for 4GB)*/
     151#define REMAINDER_STR_LEN (5 + 1 + 10)
     152
     153/** How many bytes to group together. */
     154#define BUFFER_DUMP_GROUP_SIZE 4
     155
     156/** Size of the string for buffer dumps. */
     157#define BUFFER_DUMP_LEN 240 /* Ought to be enough for everybody ;-). */
     158
     159/** Fibril local storage for the dumped buffer. */
     160static fibril_local char buffer_dump[BUFFER_DUMP_LEN];
     161
     162/** Dump buffer into string.
     163 *
     164 * The function dumps given buffer into hexadecimal format and stores it
     165 * in a static fibril local string.
     166 * That means that you do not have to deallocate the string (actually, you
     167 * can not do that) and you do not have to guard it against concurrent
     168 * calls to it.
     169 * The only limitation is that each call rewrites the buffer again.
     170 * Thus, it is necessary to copy the buffer elsewhere (that includes printing
     171 * to screen or writing to file).
     172 * Since this function is expected to be used for debugging prints only,
     173 * that is not a big limitation.
     174 *
     175 * @warning You cannot use this function twice in the same printf
     176 * (see detailed explanation).
     177 *
     178 * @param buffer Buffer to be printed (can be NULL).
     179 * @param size Size of the buffer in bytes (can be zero).
     180 * @param dumped_size How many bytes to actually dump (zero means all).
     181 * @return Dumped buffer as a static (but fibril local) string.
     182 */
     183const char *usb_debug_str_buffer(const uint8_t *buffer, size_t size,
     184    size_t dumped_size)
     185{
     186        /*
     187         * Remove previous string (that might also reveal double usage of
     188         * this function).
     189         */
     190        bzero(buffer_dump, BUFFER_DUMP_LEN);
     191
     192        if (buffer == NULL) {
     193                return "(null)";
     194        }
     195        if (size == 0) {
     196                return "(empty)";
     197        }
     198        if ((dumped_size == 0) || (dumped_size > size)) {
     199                dumped_size = size;
     200        }
     201
     202        /* How many bytes are available in the output buffer. */
     203        size_t buffer_remaining_size = BUFFER_DUMP_LEN - 1 - REMAINDER_STR_LEN;
     204        char *it = buffer_dump;
     205
     206        size_t index = 0;
     207
     208        while (index < size) {
     209                /* Determine space before the number. */
     210                const char *space_before;
     211                if (index == 0) {
     212                        space_before = "";
     213                } else if ((index % BUFFER_DUMP_GROUP_SIZE) == 0) {
     214                        space_before = "  ";
     215                } else {
     216                        space_before = " ";
     217                }
     218
     219                /*
     220                 * Add the byte as a hexadecimal number plus the space.
     221                 * We do it into temporary buffer to ensure that always
     222                 * the whole byte is printed.
     223                 */
     224                int val = buffer[index];
     225                char current_byte[16];
     226                int printed = snprintf(current_byte, 16,
     227                    "%s%02x", space_before, val);
     228                if (printed < 0) {
     229                        break;
     230                }
     231
     232                if ((size_t) printed > buffer_remaining_size) {
     233                        break;
     234                }
     235
     236                /* We can safely add 1, because space for end 0 is reserved. */
     237                str_append(it, buffer_remaining_size + 1, current_byte);
     238
     239                buffer_remaining_size -= printed;
     240                /* Point at the terminator 0. */
     241                it += printed;
     242                index++;
     243
     244                if (index >= dumped_size) {
     245                        break;
     246                }
     247        }
     248
     249        /* Add how many bytes were not printed. */
     250        if (index < size) {
     251                snprintf(it, REMAINDER_STR_LEN,
     252                    REMAINDER_STR_FMT, size - index);
     253        }
     254
     255        return buffer_dump;
     256}
     257
     258
    254259/**
    255260 * @}
  • uspace/lib/usb/src/dp.c

    r3e7b7cd r72af8da  
    3232/**
    3333 * @file
    34  * @brief USB descriptor parser (implementation).
     34 * USB descriptor parser (implementation).
     35 *
     36 * The descriptor parser is a generic parser for structure, where individual
     37 * items are stored in single buffer and each item begins with length followed
     38 * by type. These types are organized into tree hierarchy.
     39 *
     40 * The parser is able of only two actions: find first child and find next
     41 * sibling.
    3542 */
    3643#include <stdio.h>
  • uspace/lib/usb/src/dump.c

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief Descriptor dumping.
     33 * Descriptor dumping.
    3434 */
    3535#include <adt/list.h>
     
    4343#include <usb/classes/hid.h>
    4444
     45/** Mapping between descriptor id and dumping function. */
    4546typedef struct {
     47        /** Descriptor id. */
    4648        int id;
     49        /** Dumping function. */
    4750        void (*dump)(FILE *, const char *, const char *,
    4851            const uint8_t *, size_t);
     
    6669    const uint8_t *, size_t);
    6770
     71/** Descriptor dumpers mapping. */
    6872static descriptor_dump_t descriptor_dumpers[] = {
    6973        { USB_DESCTYPE_DEVICE, usb_dump_descriptor_device },
     
    273277    const uint8_t *descriptor, size_t descriptor_length)
    274278{
     279        /* TODO */
    275280}
    276281
     
    279284    const uint8_t *descriptor, size_t descriptor_length)
    280285{
     286        /* TODO */
    281287}
    282288
  • uspace/lib/usb/src/hub.c

    r3e7b7cd r72af8da  
    5757 *
    5858 * @param connection Opened connection to host controller.
     59 * @param speed Speed of the device that will respond on the default address.
    5960 * @return Error code.
    6061 */
     
    8687 *
    8788 * @param connection Opened connection to host controller.
     89 * @param speed Speed of the new device (device that will be assigned
     90 *    the returned address).
    8891 * @return Assigned USB address or negative error code.
    8992 */
     
    144147/** Wrapper for registering attached device to the hub.
    145148 *
    146  * The @p enable_port function is expected to enable singalling on given
     149 * The @p enable_port function is expected to enable signaling on given
    147150 * port.
    148151 * The two arguments to it can have arbitrary meaning
     
    152155 *
    153156 * If the @p enable_port fails (i.e. does not return EOK), the device
    154  * addition is cancelled.
     157 * addition is canceled.
    155158 * The return value is then returned (it is good idea to use different
    156159 * error codes than those listed as return codes by this function itself).
    157160 *
    158  * @param parent Parent device (i.e. the hub device).
    159  * @param connection Opened connection to host controller.
    160  * @param dev_speed New device speed.
    161  * @param enable_port Function for enabling signalling through the port the
     161 * @param[in] parent Parent device (i.e. the hub device).
     162 * @param[in] connection Opened connection to host controller.
     163 * @param[in] dev_speed New device speed.
     164 * @param[in] enable_port Function for enabling signaling through the port the
    162165 *      device is attached to.
    163  * @param port_no Port number (passed through to @p enable_port).
    164  * @param arg Any data argument to @p enable_port.
     166 * @param[in] port_no Port number (passed through to @p enable_port).
     167 * @param[in] arg Any data argument to @p enable_port.
    165168 * @param[out] assigned_address USB address of the device.
    166169 * @param[out] assigned_handle Devman handle of the new device.
     170 * @param[in] dev_ops Child device ops.
     171 * @param[in] new_dev_data Arbitrary pointer to be stored in the child
     172 *      as @c driver_data.
     173 * @param[out] new_fun Storage where pointer to allocated child function
     174 *      will be written.
    167175 * @return Error code.
    168176 * @retval ENOENT Connection to HC not opened.
     
    201209
    202210        /*
    203          * Enable the port (i.e. allow signalling through this port).
     211         * Enable the port (i.e. allow signaling through this port).
    204212         */
    205213        rc = enable_port(port_no, arg);
     
    223231        rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe,
    224232            &dev_conn);
     233        if (rc != EOK) {
     234                rc = ENOTCONN;
     235                goto leave_release_default_address;
     236        }
     237        rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe);
    225238        if (rc != EOK) {
    226239                rc = ENOTCONN;
  • uspace/lib/usb/src/pipes.c

    r3e7b7cd r72af8da  
    9999 *
    100100 * @param connection Connection structure to be initialized.
    101  * @param device Generic device backing the USB device.
     101 * @param dev Generic device backing the USB device.
    102102 * @return Error code.
    103103 */
  • uspace/lib/usb/src/pipesinit.c

    r3e7b7cd r72af8da  
    3737#include <usb/pipes.h>
    3838#include <usb/dp.h>
     39#include <usb/request.h>
     40#include <usbhc_iface.h>
    3941#include <errno.h>
    4042#include <assert.h>
     43
     44#define CTRL_PIPE_MIN_PACKET_SIZE 8
     45#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
    4146
    4247
     
    369374
    370375        int rc = usb_endpoint_pipe_initialize(pipe, connection,
    371             0, USB_TRANSFER_CONTROL, 8, USB_DIRECTION_BOTH);
     376            0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE,
     377            USB_DIRECTION_BOTH);
    372378
    373379        return rc;
     380}
     381
     382/** Probe default control pipe for max packet size.
     383 *
     384 * The function tries to get the correct value of max packet size several
     385 * time before giving up.
     386 *
     387 * The session on the pipe shall not be started.
     388 *
     389 * @param pipe Default control pipe.
     390 * @return Error code.
     391 */
     392int usb_endpoint_pipe_probe_default_control(usb_endpoint_pipe_t *pipe)
     393{
     394        assert(pipe);
     395        assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);
     396
     397        if ((pipe->direction != USB_DIRECTION_BOTH) ||
     398            (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
     399            (pipe->endpoint_no != 0)) {
     400                return EINVAL;
     401        }
     402
     403#define TRY_LOOP(attempt_var) \
     404        for (attempt_var = 0; attempt_var < 3; attempt_var++)
     405
     406        size_t failed_attempts;
     407        int rc;
     408
     409        TRY_LOOP(failed_attempts) {
     410                rc = usb_endpoint_pipe_start_session(pipe);
     411                if (rc == EOK) {
     412                        break;
     413                }
     414        }
     415        if (rc != EOK) {
     416                return rc;
     417        }
     418
     419
     420        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
     421        size_t transferred_size;
     422        TRY_LOOP(failed_attempts) {
     423                rc = usb_request_get_descriptor(pipe, USB_REQUEST_TYPE_STANDARD,
     424                    USB_REQUEST_RECIPIENT_DEVICE, USB_DESCTYPE_DEVICE,
     425                    0, 0, dev_descr_start, CTRL_PIPE_MIN_PACKET_SIZE,
     426                    &transferred_size);
     427                if (rc == EOK) {
     428                        if (transferred_size != CTRL_PIPE_MIN_PACKET_SIZE) {
     429                                rc = ELIMIT;
     430                                continue;
     431                        }
     432                        break;
     433                }
     434        }
     435        usb_endpoint_pipe_end_session(pipe);
     436        if (rc != EOK) {
     437                return rc;
     438        }
     439
     440        pipe->max_packet_size
     441            = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
     442
     443        return EOK;
     444}
     445
     446/** Register endpoint with the host controller.
     447 *
     448 * @param pipe Pipe to be registered.
     449 * @param interval Polling interval.
     450 * @param hc_connection Connection to the host controller (must be opened).
     451 * @return Error code.
     452 */
     453int usb_endpoint_pipe_register(usb_endpoint_pipe_t *pipe,
     454    unsigned int interval,
     455    usb_hc_connection_t *hc_connection)
     456{
     457        assert(pipe);
     458        assert(hc_connection);
     459
     460        if (!usb_hc_connection_is_opened(hc_connection)) {
     461                return EBADF;
     462        }
     463
     464#define _PACK(high, low) ((high) * 256 + (low))
     465
     466        return async_req_5_0(hc_connection->hc_phone,
     467            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_REGISTER_ENDPOINT,
     468            _PACK(pipe->wire->address, pipe->endpoint_no),
     469            _PACK(pipe->transfer_type, pipe->direction),
     470            pipe->max_packet_size, interval);
     471
     472#undef _PACK
     473}
     474
     475/** Revert endpoint registration with the host controller.
     476 *
     477 * @param pipe Pipe to be unregistered.
     478 * @param hc_connection Connection to the host controller (must be opened).
     479 * @return Error code.
     480 */
     481int usb_endpoint_pipe_unregister(usb_endpoint_pipe_t *pipe,
     482    usb_hc_connection_t *hc_connection)
     483{
     484        assert(pipe);
     485        assert(hc_connection);
     486
     487        if (!usb_hc_connection_is_opened(hc_connection)) {
     488                return EBADF;
     489        }
     490
     491        return async_req_4_0(hc_connection->hc_phone,
     492            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_UNREGISTER_ENDPOINT,
     493            pipe->wire->address, pipe->endpoint_no, pipe->direction);
    374494}
    375495
  • uspace/lib/usb/src/pipesio.c

    r3e7b7cd r72af8da  
    115115
    116116        if (data_request_rc != EOK) {
    117                 return (int) data_request_rc;
     117                /* Prefer the return code of the opening request. */
     118                if (opening_request_rc != EOK) {
     119                        return (int) opening_request_rc;
     120                } else {
     121                        return (int) data_request_rc;
     122                }
    118123        }
    119124        if (opening_request_rc != EOK) {
     
    331336
    332337        if (data_request_rc != EOK) {
    333                 return (int) data_request_rc;
     338                /* Prefer the return code of the opening request. */
     339                if (opening_request_rc != EOK) {
     340                        return (int) opening_request_rc;
     341                } else {
     342                        return (int) data_request_rc;
     343                }
    334344        }
    335345        if (opening_request_rc != EOK) {
  • uspace/lib/usb/src/recognise.c

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief Functions for recognising kind of attached devices.
     33 * Functions for recognition of attached devices.
    3434 */
    3535#include <sys/types.h>
     
    4444#include <assert.h>
    4545
     46/** Index to append after device name for uniqueness. */
    4647static size_t device_name_index = 0;
     48/** Mutex guard for device_name_index. */
    4749static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);
    4850
     51/** DDF operations of child devices. */
    4952ddf_dev_ops_t child_ops = {
    5053        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    5154};
    5255
     56/** Get integer part from BCD coded number. */
    5357#define BCD_INT(a) (((unsigned int)(a)) / 256)
     58/** Get fraction part from BCD coded number (as an integer, no less). */
    5459#define BCD_FRAC(a) (((unsigned int)(a)) % 256)
    5560
     61/** Format for BCD coded number to be used in printf. */
    5662#define BCD_FMT "%x.%x"
     63/** Arguments to printf for BCD coded number. */
    5764#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
    5865
     
    113120}
    114121
     122/** Add match id to list or return with error code.
     123 *
     124 * @param match_ids List of match ids.
     125 * @param score Match id score.
     126 * @param format Format of the matching string
     127 * @param ... Arguments for the format.
     128 */
    115129#define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
    116130        do { \
     
    124138/** Create device match ids based on its interface.
    125139 *
    126  * @param[in] descriptor Interface descriptor.
     140 * @param[in] desc_device Device descriptor.
     141 * @param[in] desc_interface Interface descriptor.
    127142 * @param[out] matches Initialized list of match ids.
    128143 * @return Error code (the two mentioned are not the only ones).
    129144 * @retval EINVAL Invalid input parameters (expects non NULL pointers).
    130  * @retval ENOENT Interface does not specify class.
     145 * @retval ENOENT Device class is not "use interface".
    131146 */
    132147int usb_device_create_match_ids_from_interface(
     
    319334 * @param[in] parent Parent device.
    320335 * @param[out] child_handle Handle of the child device.
     336 * @param[in] dev_ops Child device ops.
     337 * @param[in] dev_data Arbitrary pointer to be stored in the child
     338 *      as @c driver_data.
     339 * @param[out] child_fun Storage where pointer to allocated child function
     340 *      will be written.
    321341 * @return Error code.
    322342 */
     
    349369                goto failure;
    350370        }
     371        rc = usb_endpoint_pipe_probe_default_control(&ctrl_pipe);
     372        if (rc != EOK) {
     373                goto failure;
     374        }
    351375
    352376        /*
     
    354378         * naming etc., something more descriptive could be created.
    355379         */
    356         rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index);
     380        rc = asprintf(&child_name, "usb%02zu_a%d",
     381            this_device_name_index, address);
    357382        if (rc < 0) {
    358383                goto failure;
  • uspace/lib/usb/src/request.c

    r3e7b7cd r72af8da  
    110110  *     (must be in USB endianness).
    111111  * @param data Buffer where to store data accepted during the DATA stage.
    112   *     (they will come in USB endianess).
     112  *     (they will come in USB endianness).
    113113  * @param data_size Size of the @p data buffer
    114114  *     (in native endianness).
     
    161161 * the new address.
    162162 *
    163  * @see usb_drv_reserve_default_address
    164  * @see usb_drv_release_default_address
    165  * @see usb_drv_request_address
    166  * @see usb_drv_release_address
    167  * @see usb_drv_bind_address
    168  *
    169163 * @param pipe Control endpoint pipe (session must be already started).
    170164 * @param new_address New USB address to be set (in native endianness).
     
    201195 * @param[in] pipe Control endpoint pipe (session must be already started).
    202196 * @param[in] request_type Request type (standard/class/vendor).
     197 * @param[in] recipient Request recipient (device/interface/endpoint).
    203198 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
    204199 * @param[in] descriptor_index Descriptor index.
     
    235230 * @param[in] pipe Control endpoint pipe (session must be already started).
    236231 * @param[in] request_type Request type (standard/class/vendor).
     232 * @param[in] recipient Request recipient (device/interface/endpoint).
    237233 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
    238234 * @param[in] descriptor_index Descriptor index.
     
    528524                return EEMPTY;
    529525        }
    530         /* Substract first 2 bytes (length and descriptor type). */
     526        /* Subtract first 2 bytes (length and descriptor type). */
    531527        string_descriptor_size -= 2;
    532528
     
    548544        size_t i;
    549545        for (i = 0; i < langs_count; i++) {
    550                 /* Language code from the descriptor is in USB endianess. */
     546                /* Language code from the descriptor is in USB endianness. */
    551547                /* FIXME: is this really correct? */
    552548                uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
     
    569565 *
    570566 * @param[in] pipe Control endpoint pipe (session must be already started).
    571  * @param[in] index String index (in native endianess),
     567 * @param[in] index String index (in native endianness),
    572568 *      first index has number 1 (index from descriptors can be used directly).
    573  * @param[in] lang String language (in native endianess).
     569 * @param[in] lang String language (in native endianness).
    574570 * @param[out] string_ptr Where to store allocated string in native encoding.
    575571 * @return Error code.
     
    613609                goto leave;
    614610        }
    615         /* Substract first 2 bytes (length and descriptor type). */
     611        /* Subtract first 2 bytes (length and descriptor type). */
    616612        string_size -= 2;
    617613
  • uspace/lib/usb/src/usb.c

    r3e7b7cd r72af8da  
    3131 */
    3232/** @file
    33  * @brief Base USB types.
     33 * Common USB functions.
    3434 */
    3535#include <usb/usb.h>
     
    3737
    3838
    39 /** String representation for USB transfer type. */
     39/** String representation for USB transfer type.
     40 *
     41 * @param t Transfer type.
     42 * @return Transfer type as a string (in English).
     43 */
    4044const char * usb_str_transfer_type(usb_transfer_type_t t)
    4145{
Note: See TracChangeset for help on using the changeset viewer.