Changes in / [d477734:d2fc1c2] in mainline


Ignore:
Files:
5 added
3 deleted
54 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    rd477734 rd2fc1c2  
    8484./uspace/drv/test1/test1
    8585./uspace/drv/test2/test2
     86./uspace/drv/ehci-hcd/ehci-hcd
    8687./uspace/drv/uhci-hcd/uhci-hcd
    8788./uspace/drv/uhci-rhd/uhci-rhd
  • boot/arch/amd64/Makefile.inc

    rd477734 rd2fc1c2  
    4343        isa \
    4444        ns8250 \
     45        ehci-hcd \
    4546        uhci-hcd \
    4647        uhci-rhd \
  • boot/arch/mips32/src/asm.S

    rd477734 rd2fc1c2  
    4141
    4242start:
    43         /* Setup CPU map (on msim this code
    44            is executed in parallel on all CPUs,
    45            but it not an issue) */
     43        /*
     44         * Setup the CP0 configuration
     45         *  - Disable 64-bit kernel addressing mode
     46         *  - DIsable 64-bit supervisor adressing mode
     47         *  - Disable 64-bit user addressing mode
     48         */
     49        mfc0 $a0, $status
     50        la $a1, 0xffffff1f
     51        and $a0, $a1, $a0
     52        mtc0 $a0, $status
     53       
     54        /*
     55         * Setup CPU map (on msim this code
     56         * is executed in parallel on all CPUs,
     57         * but it not an issue).
     58         */
    4659        la $a0, PA2KA(CPUMAP_OFFSET)
    4760       
     
    94107        lw $k1, ($k0)
    95108       
    96         /* If we are not running on BSP
    97            then end in an infinite loop  */
     109        /*
     110         * If we are not running on BSP
     111         * then end in an infinite loop.
     112         */
    98113        beq $k1, $zero, bsp
    99114        nop
     
    127142
    128143jump_to_kernel:
    129         #
    130         # TODO:
    131         # Make sure that the I-cache, D-cache and memory are mutually coherent
    132         # before passing control to the copied code.
    133         #
     144        /*
     145         * TODO:
     146         *
     147         * Make sure that the I-cache, D-cache and memory are mutually
     148         * coherent before passing control to the copied code.
     149         */
    134150        j $a0
    135151        nop
  • uspace/Makefile

    rd477734 rd2fc1c2  
    117117                srv/hw/irc/apic \
    118118                srv/hw/irc/i8259 \
     119                drv/ehci-hcd \
    119120                drv/uhci-hcd \
    120121                drv/uhci-rhd \
     
    134135                srv/hw/irc/apic \
    135136                srv/hw/irc/i8259 \
     137                drv/ehci-hcd \
    136138                drv/uhci-hcd \
    137139                drv/uhci-rhd \
  • uspace/app/bdsh/cmds/modules/mkfile/mkfile.c

    rd477734 rd2fc1c2  
    125125
    126126        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    127                 c = getopt_long(argc, argv, "pvhVfm:", long_options, &opt_ind);
     127                c = getopt_long(argc, argv, "s:h", long_options, &opt_ind);
    128128                switch (c) {
    129129                case 'h':
  • uspace/doc/doxygroups.h

    rd477734 rd2fc1c2  
    256256         */
    257257
     258        /**
     259         * @defgroup drvusbehci EHCI driver
     260         * @ingroup usb
     261         * @brief Driver for EHCI host controller.
     262         */
     263
     264
  • uspace/drv/pciintel/pci.c

    rd477734 rd2fc1c2  
    127127}
    128128
    129 static int pci_config_space_write_16(ddf_fun_t *fun, uint32_t address, uint16_t data)
     129static int pci_config_space_write_32(
     130    ddf_fun_t *fun, uint32_t address, uint32_t data)
     131{
     132        if (address > 252)
     133                return EINVAL;
     134        pci_conf_write_32(PCI_FUN(fun), address, data);
     135        return EOK;
     136}
     137
     138static int pci_config_space_write_16(
     139    ddf_fun_t *fun, uint32_t address, uint16_t data)
    130140{
    131141        if (address > 254)
     
    135145}
    136146
     147static int pci_config_space_write_8(
     148    ddf_fun_t *fun, uint32_t address, uint8_t data)
     149{
     150        if (address > 255)
     151                return EINVAL;
     152        pci_conf_write_8(PCI_FUN(fun), address, data);
     153        return EOK;
     154}
     155
     156static int pci_config_space_read_32(
     157    ddf_fun_t *fun, uint32_t address, uint32_t *data)
     158{
     159        if (address > 252)
     160                return EINVAL;
     161        *data = pci_conf_read_32(PCI_FUN(fun), address);
     162        return EOK;
     163}
     164
     165static int pci_config_space_read_16(
     166    ddf_fun_t *fun, uint32_t address, uint16_t *data)
     167{
     168        if (address > 254)
     169                return EINVAL;
     170        *data = pci_conf_read_16(PCI_FUN(fun), address);
     171        return EOK;
     172}
     173
     174static int pci_config_space_read_8(
     175    ddf_fun_t *fun, uint32_t address, uint8_t *data)
     176{
     177        if (address > 255)
     178                return EINVAL;
     179        *data = pci_conf_read_8(PCI_FUN(fun), address);
     180        return EOK;
     181}
    137182
    138183static hw_res_ops_t pciintel_hw_res_ops = {
     
    142187
    143188static pci_dev_iface_t pci_dev_ops = {
    144         .config_space_read_8 = NULL,
    145         .config_space_read_16 = NULL,
    146         .config_space_read_32 = NULL,
    147         .config_space_write_8 = NULL,
     189        .config_space_read_8 = &pci_config_space_read_8,
     190        .config_space_read_16 = &pci_config_space_read_16,
     191        .config_space_read_32 = &pci_config_space_read_32,
     192        .config_space_write_8 = &pci_config_space_write_8,
    148193        .config_space_write_16 = &pci_config_space_write_16,
    149         .config_space_write_32 = NULL
     194        .config_space_write_32 = &pci_config_space_write_32
    150195};
    151196
  • uspace/drv/uhci-hcd/batch.c

    rd477734 rd2fc1c2  
    5454static void batch_call_in_and_dispose(batch_t *instance);
    5555static void batch_call_out_and_dispose(batch_t *instance);
    56 
    57 
     56static void batch_dispose(batch_t *instance);
     57
     58
     59/** Allocates memory and initializes internal data structures.
     60 *
     61 * @param[in] fun DDF function to pass to callback.
     62 * @param[in] target Device and endpoint target of the transaction.
     63 * @param[in] transfer_type Interrupt, Control or Bulk.
     64 * @param[in] max_packet_size maximum allowed size of data packets.
     65 * @param[in] speed Speed of the transaction.
     66 * @param[in] buffer Data source/destination.
     67 * @param[in] size Size of the buffer.
     68 * @param[in] setup_buffer Setup data source (if not NULL)
     69 * @param[in] setup_size Size of setup_buffer (should be always 8)
     70 * @param[in] func_in function to call on inbound transaction completion
     71 * @param[in] func_out function to call on outbound transaction completion
     72 * @param[in] arg additional parameter to func_in or func_out
     73 * @param[in] manager Pointer to toggle management structure.
     74 * @return False, if there is an active TD, true otherwise.
     75 */
    5876batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    5977    usb_transfer_type_t transfer_type, size_t max_packet_size,
     
    6179    char* setup_buffer, size_t setup_size,
    6280    usbhc_iface_transfer_in_callback_t func_in,
    63     usbhc_iface_transfer_out_callback_t func_out, void *arg)
     81    usbhc_iface_transfer_out_callback_t func_out, void *arg,
     82    device_keeper_t *manager
     83    )
    6484{
    6585        assert(func_in == NULL || func_out == NULL);
    6686        assert(func_in != NULL || func_out != NULL);
    6787
     88#define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \
     89        if (ptr == NULL) { \
     90                usb_log_error(message); \
     91                if (instance) { \
     92                        batch_dispose(instance); \
     93                } \
     94                return NULL; \
     95        } else (void)0
     96
    6897        batch_t *instance = malloc(sizeof(batch_t));
    69         if (instance == NULL) {
    70                 usb_log_error("Failed to allocate batch instance.\n");
    71                 return NULL;
    72         }
    73 
    74         instance->qh = queue_head_get();
    75         if (instance->qh == NULL) {
    76                 usb_log_error("Failed to allocate queue head.\n");
    77                 free(instance);
    78                 return NULL;
    79         }
     98        CHECK_NULL_DISPOSE_RETURN(instance,
     99            "Failed to allocate batch instance.\n");
     100        bzero(instance, sizeof(batch_t));
     101
     102        instance->qh = malloc32(sizeof(queue_head_t));
     103        CHECK_NULL_DISPOSE_RETURN(instance->qh,
     104            "Failed to allocate batch queue head.\n");
     105        queue_head_init(instance->qh);
    80106
    81107        instance->packets = (size + max_packet_size - 1) / max_packet_size;
     
    85111
    86112        instance->tds = malloc32(sizeof(td_t) * instance->packets);
    87         if (instance->tds == NULL) {
    88                 usb_log_error("Failed to allocate transfer descriptors.\n");
    89                 queue_head_dispose(instance->qh);
    90                 free(instance);
    91                 return NULL;
    92         }
     113        CHECK_NULL_DISPOSE_RETURN(
     114            instance->tds, "Failed to allocate transfer descriptors.\n");
    93115        bzero(instance->tds, sizeof(td_t) * instance->packets);
    94116
    95         const size_t transport_size = max_packet_size * instance->packets;
    96 
    97         instance->transport_buffer =
    98            (size > 0) ? malloc32(transport_size) : NULL;
    99 
    100         if ((size > 0) && (instance->transport_buffer == NULL)) {
    101                 usb_log_error("Failed to allocate device accessible buffer.\n");
    102                 queue_head_dispose(instance->qh);
    103                 free32(instance->tds);
    104                 free(instance);
    105                 return NULL;
    106         }
    107 
    108         instance->setup_buffer = setup_buffer ? malloc32(setup_size) : NULL;
    109         if ((setup_size > 0) && (instance->setup_buffer == NULL)) {
    110                 usb_log_error("Failed to allocate device accessible setup buffer.\n");
    111                 queue_head_dispose(instance->qh);
    112                 free32(instance->tds);
    113                 free32(instance->transport_buffer);
    114                 free(instance);
    115                 return NULL;
    116         }
    117         if (instance->setup_buffer) {
     117//      const size_t transport_size = max_packet_size * instance->packets;
     118
     119        if (size > 0) {
     120                instance->transport_buffer = malloc32(size);
     121                CHECK_NULL_DISPOSE_RETURN(instance->transport_buffer,
     122                    "Failed to allocate device accessible buffer.\n");
     123        }
     124
     125        if (setup_size > 0) {
     126                instance->setup_buffer = malloc32(setup_size);
     127                CHECK_NULL_DISPOSE_RETURN(instance->setup_buffer,
     128                    "Failed to allocate device accessible setup buffer.\n");
    118129                memcpy(instance->setup_buffer, setup_buffer, setup_size);
    119130        }
    120131
     132
     133        link_initialize(&instance->link);
     134
    121135        instance->max_packet_size = max_packet_size;
    122 
    123         link_initialize(&instance->link);
    124 
    125136        instance->target = target;
    126137        instance->transfer_type = transfer_type;
    127 
    128         if (func_out)
    129                 instance->callback_out = func_out;
    130         if (func_in)
    131                 instance->callback_in = func_in;
    132 
    133138        instance->buffer = buffer;
    134139        instance->buffer_size = size;
     
    137142        instance->arg = arg;
    138143        instance->speed = speed;
    139 
    140         queue_head_element_td(instance->qh, addr_to_phys(instance->tds));
     144        instance->manager = manager;
     145
     146        if (func_out)
     147                instance->callback_out = func_out;
     148        if (func_in)
     149                instance->callback_in = func_in;
     150
     151        queue_head_set_element_td(instance->qh, addr_to_phys(instance->tds));
     152
    141153        usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",
    142154            instance, target.address, target.endpoint);
     
    144156}
    145157/*----------------------------------------------------------------------------*/
     158/** Checks batch TDs for activity.
     159 *
     160 * @param[in] instance Batch structure to use.
     161 * @return False, if there is an active TD, true otherwise.
     162 */
    146163bool batch_is_complete(batch_t *instance)
    147164{
     
    160177                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
    161178                            instance, i, instance->tds[i].status);
     179
     180                        device_keeper_set_toggle(instance->manager,
     181                            instance->target, td_toggle(&instance->tds[i]));
    162182                        if (i > 0)
    163183                                goto substract_ret;
     
    174194}
    175195/*----------------------------------------------------------------------------*/
     196/** Prepares control write transaction.
     197 *
     198 * @param[in] instance Batch structure to use.
     199 */
    176200void batch_control_write(batch_t *instance)
    177201{
    178202        assert(instance);
    179203        /* we are data out, we are supposed to provide data */
    180         memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
     204        memcpy(instance->transport_buffer, instance->buffer,
     205            instance->buffer_size);
    181206        batch_control(instance, USB_PID_OUT, USB_PID_IN);
    182207        instance->next_step = batch_call_out_and_dispose;
     
    185210}
    186211/*----------------------------------------------------------------------------*/
     212/** Prepares control read transaction.
     213 *
     214 * @param[in] instance Batch structure to use.
     215 */
    187216void batch_control_read(batch_t *instance)
    188217{
     
    194223}
    195224/*----------------------------------------------------------------------------*/
     225/** Prepares interrupt in transaction.
     226 *
     227 * @param[in] instance Batch structure to use.
     228 */
    196229void batch_interrupt_in(batch_t *instance)
    197230{
     
    203236}
    204237/*----------------------------------------------------------------------------*/
     238/** Prepares interrupt out transaction.
     239 *
     240 * @param[in] instance Batch structure to use.
     241 */
    205242void batch_interrupt_out(batch_t *instance)
    206243{
    207244        assert(instance);
     245        /* we are data out, we are supposed to provide data */
    208246        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    209247        batch_data(instance, USB_PID_OUT);
     
    213251}
    214252/*----------------------------------------------------------------------------*/
     253/** Prepares bulk in transaction.
     254 *
     255 * @param[in] instance Batch structure to use.
     256 */
    215257void batch_bulk_in(batch_t *instance)
    216258{
     
    222264}
    223265/*----------------------------------------------------------------------------*/
     266/** Prepares bulk out transaction.
     267 *
     268 * @param[in] instance Batch structure to use.
     269 */
    224270void batch_bulk_out(batch_t *instance)
    225271{
     
    232278}
    233279/*----------------------------------------------------------------------------*/
    234 static void batch_data(batch_t *instance, usb_packet_id pid)
     280/** Prepares generic data transaction
     281 *
     282 * @param[in] instance Batch structure to use.
     283 * @param[in] pid to use for data packets.
     284 */
     285void batch_data(batch_t *instance, usb_packet_id pid)
    235286{
    236287        assert(instance);
    237288        const bool low_speed = instance->speed == USB_SPEED_LOW;
    238         int toggle = 1;
     289        int toggle =
     290            device_keeper_get_toggle(instance->manager, instance->target);
     291        assert(toggle == 0 || toggle == 1);
    239292
    240293        size_t packet = 0;
     
    245298                    - remain_size;
    246299
    247                 toggle = 1 - toggle;
    248 
    249300                const size_t packet_size =
    250301                    (instance->max_packet_size > remain_size) ?
    251302                    remain_size : instance->max_packet_size;
    252303
    253                 td_init(&instance->tds[packet],
    254                     DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
    255                     instance->target, pid, data,
    256                     &instance->tds[packet + 1]);
    257 
     304                td_t *next_packet = (packet + 1 < instance->packets)
     305                    ? &instance->tds[packet + 1] : NULL;
     306
     307                assert(packet < instance->packets);
     308                assert(packet_size <= remain_size);
     309
     310                td_init(
     311                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     312                    toggle, false, low_speed, instance->target, pid, data,
     313                    next_packet);
     314
     315
     316                toggle = 1 - toggle;
     317                remain_size -= packet_size;
    258318                ++packet;
    259                 assert(packet <= instance->packets);
    260                 assert(packet_size <= remain_size);
    261                 remain_size -= packet_size;
    262         }
    263 
    264         instance->tds[packet - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    265         instance->tds[packet - 1].next = 0 | LINK_POINTER_TERMINATE_FLAG;
    266 }
    267 /*----------------------------------------------------------------------------*/
    268 static void batch_control(batch_t *instance,
     319        }
     320        device_keeper_set_toggle(instance->manager, instance->target, toggle);
     321}
     322/*----------------------------------------------------------------------------*/
     323/** Prepares generic control transaction
     324 *
     325 * @param[in] instance Batch structure to use.
     326 * @param[in] data_stage to use for data packets.
     327 * @param[in] status_stage to use for data packets.
     328 */
     329void batch_control(batch_t *instance,
    269330   usb_packet_id data_stage, usb_packet_id status_stage)
    270331{
     
    292353                    remain_size : instance->max_packet_size;
    293354
    294                 td_init(&instance->tds[packet],
    295                     DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed,
    296                     instance->target, data_stage, data,
    297                     &instance->tds[packet + 1]);
     355                td_init(
     356                    &instance->tds[packet], DEFAULT_ERROR_COUNT, packet_size,
     357                    toggle, false, low_speed, instance->target, data_stage,
     358                    data, &instance->tds[packet + 1]);
    298359
    299360                ++packet;
     
    314375}
    315376/*----------------------------------------------------------------------------*/
     377/** Prepares data, gets error status and calls callback in.
     378 *
     379 * @param[in] instance Batch structure to use.
     380 */
    316381void batch_call_in(batch_t *instance)
    317382{
     
    319384        assert(instance->callback_in);
    320385
    321         memcpy(instance->buffer, instance->transport_buffer, instance->buffer_size);
     386        /* we are data in, we need data */
     387        memcpy(instance->buffer, instance->transport_buffer,
     388            instance->buffer_size);
    322389
    323390        int err = instance->error;
     
    326393            instance->transfered_size);
    327394
    328         instance->callback_in(instance->fun,
    329             err, instance->transfered_size,
    330             instance->arg);
    331 }
    332 /*----------------------------------------------------------------------------*/
     395        instance->callback_in(
     396            instance->fun, err, instance->transfered_size, instance->arg);
     397}
     398/*----------------------------------------------------------------------------*/
     399/** Gets error status and calls callback out.
     400 *
     401 * @param[in] instance Batch structure to use.
     402 */
    333403void batch_call_out(batch_t *instance)
    334404{
     
    343413}
    344414/*----------------------------------------------------------------------------*/
     415/** Prepares data, gets error status, calls callback in and dispose.
     416 *
     417 * @param[in] instance Batch structure to use.
     418 */
    345419void batch_call_in_and_dispose(batch_t *instance)
    346420{
    347421        assert(instance);
    348422        batch_call_in(instance);
     423        batch_dispose(instance);
     424}
     425/*----------------------------------------------------------------------------*/
     426/** Gets error status, calls callback out and dispose.
     427 *
     428 * @param[in] instance Batch structure to use.
     429 */
     430void batch_call_out_and_dispose(batch_t *instance)
     431{
     432        assert(instance);
     433        batch_call_out(instance);
     434        batch_dispose(instance);
     435}
     436/*----------------------------------------------------------------------------*/
     437/** Correctly disposes all used data structures.
     438 *
     439 * @param[in] instance Batch structure to use.
     440 */
     441void batch_dispose(batch_t *instance)
     442{
     443        assert(instance);
    349444        usb_log_debug("Batch(%p) disposing.\n", instance);
     445        /* free32 is NULL safe */
    350446        free32(instance->tds);
    351447        free32(instance->qh);
     
    355451}
    356452/*----------------------------------------------------------------------------*/
    357 void batch_call_out_and_dispose(batch_t *instance)
    358 {
    359         assert(instance);
    360         batch_call_out(instance);
    361         usb_log_debug("Batch(%p) disposing.\n", instance);
    362         free32(instance->tds);
    363         free32(instance->qh);
    364         free32(instance->setup_buffer);
    365         free32(instance->transport_buffer);
    366         free(instance);
    367 }
    368 /*----------------------------------------------------------------------------*/
    369453int batch_schedule(batch_t *instance)
    370454{
  • uspace/drv/uhci-hcd/batch.h

    rd477734 rd2fc1c2  
    4242#include "uhci_struct/transfer_descriptor.h"
    4343#include "uhci_struct/queue_head.h"
     44#include "utils/device_keeper.h"
    4445
    4546typedef struct batch
     
    6768        td_t *tds;
    6869        void (*next_step)(struct batch*);
     70        device_keeper_t *manager;
    6971} batch_t;
    7072
     
    7476                char *setup_buffer, size_t setup_size,
    7577    usbhc_iface_transfer_in_callback_t func_in,
    76     usbhc_iface_transfer_out_callback_t func_out, void *arg);
     78    usbhc_iface_transfer_out_callback_t func_out, void *arg,
     79                device_keeper_t *manager
     80                );
    7781
    7882bool batch_is_complete(batch_t *instance);
  • uspace/drv/uhci-hcd/iface.c

    rd477734 rd2fc1c2  
    4343#include "utils/device_keeper.h"
    4444
     45/** Reserve default address interface function
     46 *
     47 * @param[in] fun DDF function that was called.
     48 * @param[in] speed Speed to associate with the new default address.
     49 * @return Error code.
     50 */
    4551/*----------------------------------------------------------------------------*/
    4652static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)
     
    5460}
    5561/*----------------------------------------------------------------------------*/
     62/** Release default address interface function
     63 *
     64 * @param[in] fun DDF function that was called.
     65 * @return Error code.
     66 */
    5667static int release_default_address(ddf_fun_t *fun)
    5768{
     
    6475}
    6576/*----------------------------------------------------------------------------*/
     77/** Request address interface function
     78 *
     79 * @param[in] fun DDF function that was called.
     80 * @param[in] speed Speed to associate with the new default address.
     81 * @param[out] address Place to write a new address.
     82 * @return Error code.
     83 */
    6684static int request_address(ddf_fun_t *fun, usb_speed_t speed,
    6785    usb_address_t *address)
     
    8098}
    8199/*----------------------------------------------------------------------------*/
     100/** Bind address interface function
     101 *
     102 * @param[in] fun DDF function that was called.
     103 * @param[in] address Address of the device
     104 * @param[in] handle Devman handle of the device driver.
     105 * @return Error code.
     106 */
    82107static int bind_address(
    83108  ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     
    91116}
    92117/*----------------------------------------------------------------------------*/
     118/** Release address interface function
     119 *
     120 * @param[in] fun DDF function that was called.
     121 * @param[in] address USB address to be released.
     122 * @return Error code.
     123 */
    93124static int release_address(ddf_fun_t *fun, usb_address_t address)
    94125{
     
    101132}
    102133/*----------------------------------------------------------------------------*/
     134/** Interrupt out transaction interface function
     135 *
     136 * @param[in] fun DDF function that was called.
     137 * @param[in] target USB device to write to.
     138 * @param[in] max_packet_size maximum size of data packet the device accepts
     139 * @param[in] data Source of data.
     140 * @param[in] size Size of data source.
     141 * @param[in] callback Function to call on transaction completion
     142 * @param[in] arg Additional for callback function.
     143 * @return Error code.
     144 */
    103145static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    104146    size_t max_packet_size, void *data, size_t size,
     
    114156
    115157        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    116             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
     158            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     159            &hc->device_manager);
    117160        if (!batch)
    118161                return ENOMEM;
     
    121164}
    122165/*----------------------------------------------------------------------------*/
     166/** Interrupt in transaction interface function
     167 *
     168 * @param[in] fun DDF function that was called.
     169 * @param[in] target USB device to write to.
     170 * @param[in] max_packet_size maximum size of data packet the device accepts
     171 * @param[out] data Data destination.
     172 * @param[in] size Size of data source.
     173 * @param[in] callback Function to call on transaction completion
     174 * @param[in] arg Additional for callback function.
     175 * @return Error code.
     176 */
    123177static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    124178    size_t max_packet_size, void *data, size_t size,
     
    133187
    134188        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
    135             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
     189            max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     190                        &hc->device_manager);
    136191        if (!batch)
    137192                return ENOMEM;
     
    140195}
    141196/*----------------------------------------------------------------------------*/
     197/** Bulk out transaction interface function
     198 *
     199 * @param[in] fun DDF function that was called.
     200 * @param[in] target USB device to write to.
     201 * @param[in] max_packet_size maximum size of data packet the device accepts
     202 * @param[in] data Source of data.
     203 * @param[in] size Size of data source.
     204 * @param[in] callback Function to call on transaction completion
     205 * @param[in] arg Additional for callback function.
     206 * @return Error code.
     207 */
    142208static int bulk_out(ddf_fun_t *fun, usb_target_t target,
    143209    size_t max_packet_size, void *data, size_t size,
     
    153219
    154220        batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    155             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
     221            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,
     222            &hc->device_manager);
    156223        if (!batch)
    157224                return ENOMEM;
     
    160227}
    161228/*----------------------------------------------------------------------------*/
     229/** Bulk in transaction interface function
     230 *
     231 * @param[in] fun DDF function that was called.
     232 * @param[in] target USB device to write to.
     233 * @param[in] max_packet_size maximum size of data packet the device accepts
     234 * @param[out] data Data destination.
     235 * @param[in] size Size of data source.
     236 * @param[in] callback Function to call on transaction completion
     237 * @param[in] arg Additional for callback function.
     238 * @return Error code.
     239 */
    162240static int bulk_in(ddf_fun_t *fun, usb_target_t target,
    163241    size_t max_packet_size, void *data, size_t size,
     
    172250
    173251        batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,
    174             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
     252            max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,
     253            &hc->device_manager);
    175254        if (!batch)
    176255                return ENOMEM;
     
    179258}
    180259/*----------------------------------------------------------------------------*/
     260/** Control write transaction interface function
     261 *
     262 * @param[in] fun DDF function that was called.
     263 * @param[in] target USB device to write to.
     264 * @param[in] max_packet_size maximum size of data packet the device accepts.
     265 * @param[in] setup_data Data to send with SETUP packet.
     266 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     267 * @param[in] data Source of data.
     268 * @param[in] size Size of data source.
     269 * @param[in] callback Function to call on transaction completion.
     270 * @param[in] arg Additional for callback function.
     271 * @return Error code.
     272 */
    181273static int control_write(ddf_fun_t *fun, usb_target_t target,
    182274    size_t max_packet_size,
     
    191283            target.address, target.endpoint, size, max_packet_size);
    192284
     285        if (setup_size != 8)
     286                return EINVAL;
     287
    193288        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    194289            max_packet_size, speed, data, size, setup_data, setup_size,
    195             NULL, callback, arg);
    196         if (!batch)
    197                 return ENOMEM;
     290            NULL, callback, arg, &hc->device_manager);
     291        if (!batch)
     292                return ENOMEM;
     293        device_keeper_reset_if_need(&hc->device_manager, target, setup_data);
    198294        batch_control_write(batch);
    199295        return EOK;
    200296}
    201297/*----------------------------------------------------------------------------*/
     298/** Control read transaction interface function
     299 *
     300 * @param[in] fun DDF function that was called.
     301 * @param[in] target USB device to write to.
     302 * @param[in] max_packet_size maximum size of data packet the device accepts.
     303 * @param[in] setup_data Data to send with SETUP packet.
     304 * @param[in] setup_size Size of data to send with SETUP packet (should be 8B).
     305 * @param[out] data Source of data.
     306 * @param[in] size Size of data source.
     307 * @param[in] callback Function to call on transaction completion.
     308 * @param[in] arg Additional for callback function.
     309 * @return Error code.
     310 */
    202311static int control_read(ddf_fun_t *fun, usb_target_t target,
    203312    size_t max_packet_size,
     
    214323        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    215324            max_packet_size, speed, data, size, setup_data, setup_size, callback,
    216             NULL, arg);
     325            NULL, arg, &hc->device_manager);
    217326        if (!batch)
    218327                return ENOMEM;
  • uspace/drv/uhci-hcd/main.c

    rd477734 rd2fc1c2  
    6060};
    6161/*----------------------------------------------------------------------------*/
     62/** IRQ handling callback, identifies devic
     63 *
     64 * @param[in] dev DDF instance of the device to use.
     65 * @param[in] iid (Unused).
     66 * @param[in] call Pointer to the call that represents interrupt.
     67 */
    6268static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    6369{
     
    6975}
    7076/*----------------------------------------------------------------------------*/
    71 static int uhci_add_device(ddf_dev_t *device)
     77/** Initializes a new ddf driver instance of UHCI hcd.
     78 *
     79 * @param[in] device DDF instance of the device to initialize.
     80 * @return Error code.
     81 *
     82 * Gets and initialies hardware resources, disables any legacy support,
     83 * and reports root hub device.
     84 */
     85int uhci_add_device(ddf_dev_t *device)
    7286{
    7387        assert(device);
     
    96110        ret = pci_disable_legacy(device);
    97111        CHECK_RET_FREE_HC_RETURN(ret,
    98             "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
     112            "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
    99113
    100114#if 0
     
    113127
    114128        ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size);
    115         CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n",
    116             ret);
     129        CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret);
    117130#undef CHECK_RET_FREE_HC_RETURN
    118131
     
    155168}
    156169/*----------------------------------------------------------------------------*/
     170/** Initializes global driver structures (NONE).
     171 *
     172 * @param[in] argc Nmber of arguments in argv vector (ignored).
     173 * @param[in] argv Cmdline argument vector (ignored).
     174 * @return Error code.
     175 *
     176 * Driver debug level is set here.
     177 */
    157178int main(int argc, char *argv[])
    158179{
  • uspace/drv/uhci-hcd/pci.c

    rd477734 rd2fc1c2  
    6565
    6666        int rc;
    67 
    6867        hw_resource_list_t hw_resources;
    6968        rc = hw_res_get_resource_list(parent_phone, &hw_resources);
     
    8281        for (i = 0; i < hw_resources.count; i++) {
    8382                hw_resource_t *res = &hw_resources.resources[i];
    84                 switch (res->type) {
    85                         case INTERRUPT:
    86                                 irq = res->res.interrupt.irq;
    87                                 irq_found = true;
    88                                 usb_log_debug2("Found interrupt: %d.\n", irq);
    89                                 break;
    90                         case IO_RANGE:
    91                                 io_address = res->res.io_range.address;
    92                                 io_size = res->res.io_range.size;
    93                                 usb_log_debug2("Found io: %llx %zu.\n",
    94                                     res->res.io_range.address, res->res.io_range.size);
    95                                 io_found = true;
    96                                 break;
    97                         default:
    98                                 break;
     83                switch (res->type)
     84                {
     85                case INTERRUPT:
     86                        irq = res->res.interrupt.irq;
     87                        irq_found = true;
     88                        usb_log_debug2("Found interrupt: %d.\n", irq);
     89                        break;
     90
     91                case IO_RANGE:
     92                        io_address = res->res.io_range.address;
     93                        io_size = res->res.io_range.size;
     94                        usb_log_debug2("Found io: %llx %zu.\n",
     95                            res->res.io_range.address, res->res.io_range.size);
     96                        io_found = true;
     97
     98                default:
     99                        break;
    99100                }
    100101        }
    101102
    102         if (!io_found) {
    103                 rc = ENOENT;
    104                 goto leave;
    105         }
    106 
    107         if (!irq_found) {
     103        if (!io_found || !irq_found) {
    108104                rc = ENOENT;
    109105                goto leave;
     
    121117}
    122118/*----------------------------------------------------------------------------*/
     119/** Calls the PCI driver with a request to enable interrupts
     120 *
     121 * @param[in] device Device asking for interrupts
     122 * @return Error code.
     123 */
    123124int pci_enable_interrupts(ddf_dev_t *device)
    124125{
     
    130131}
    131132/*----------------------------------------------------------------------------*/
     133/** Calls the PCI driver with a request to clear legacy support register
     134 *
     135 * @param[in] device Device asking to disable interrupts
     136 * @return Error code.
     137 */
    132138int pci_disable_legacy(ddf_dev_t *device)
    133139{
    134140        assert(device);
    135         int parent_phone = devman_parent_device_connect(device->handle,
    136                 IPC_FLAG_BLOCKING);
     141        int parent_phone =
     142            devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
    137143        if (parent_phone < 0) {
    138144                return parent_phone;
     
    144150        sysarg_t value = 0x8f00;
    145151
    146   int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
     152        int rc = async_req_3_0(parent_phone, DEV_IFACE_ID(PCI_DEV_IFACE),
    147153            IPC_M_CONFIG_SPACE_WRITE_16, address, value);
    148154        async_hangup(parent_phone);
    149155
    150   return rc;
     156        return rc;
    151157}
    152158/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/root_hub.c

    rd477734 rd2fc1c2  
    4545
    4646/*----------------------------------------------------------------------------*/
    47 static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
    48     devman_handle_t *handle)
     47/** Gets handle of the respective hc (parent device).
     48 *
     49 * @param[in] root_hub_fun Root hub function seeking hc handle.
     50 * @param[out] handle Place to write the handle.
     51 * @return Error code.
     52 */
     53static int usb_iface_get_hc_handle_rh_impl(
     54    ddf_fun_t *root_hub_fun, devman_handle_t *handle)
    4955{
     56        /* TODO: Can't this use parent pointer? */
    5057        ddf_fun_t *hc_fun = root_hub_fun->driver_data;
    5158        assert(hc_fun != NULL);
     
    5663}
    5764/*----------------------------------------------------------------------------*/
    58 static int usb_iface_get_address_rh_impl(ddf_fun_t *fun, devman_handle_t handle,
    59     usb_address_t *address)
     65/** Gets USB address of the calling device.
     66 *
     67 * @param[in] fun Root hub function.
     68 * @param[in] handle Handle of the device seeking address.
     69 * @param[out] address Place to store found address.
     70 * @return Error code.
     71 */
     72static int usb_iface_get_address_rh_impl(
     73    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
    6074{
     75        /* TODO: What does this do? Is it neccessary? Can't it use implemented
     76         * hc function?*/
    6177        assert(fun);
    6278        ddf_fun_t *hc_fun = fun->driver_data;
     
    6581        assert(hc);
    6682
    67         usb_address_t addr = device_keeper_find(&hc->device_manager,
    68             handle);
     83        usb_address_t addr = device_keeper_find(&hc->device_manager, handle);
    6984        if (addr < 0) {
    7085                return addr;
     
    8398};
    8499/*----------------------------------------------------------------------------*/
     100/** Gets root hub hw resources.
     101 *
     102 * @param[in] fun Root hub function.
     103 * @return Pointer to the resource list used by the root hub.
     104 */
    85105static hw_resource_list_t *get_resource_list(ddf_fun_t *dev)
    86106{
     
    91111        assert(hc);
    92112
    93         //TODO: fix memory leak
     113        /* TODO: fix memory leak */
    94114        hw_resource_list_t *resource_list = malloc(sizeof(hw_resource_list_t));
    95115        assert(resource_list);
  • uspace/drv/uhci-hcd/transfer_list.c

    rd477734 rd2fc1c2  
    3838#include "transfer_list.h"
    3939
     40static void transfer_list_remove_batch(
     41    transfer_list_t *instance, batch_t *batch);
     42/*----------------------------------------------------------------------------*/
     43/** Initializes transfer list structures.
     44 *
     45 * @param[in] instance Memory place to use.
     46 * @param[in] name Name of te new list.
     47 * @return Error code
     48 *
     49 * Allocates memory for internat queue_head_t structure.
     50 */
    4051int transfer_list_init(transfer_list_t *instance, const char *name)
    4152{
     
    4354        instance->next = NULL;
    4455        instance->name = name;
    45         instance->queue_head = queue_head_get();
     56        instance->queue_head = malloc32(sizeof(queue_head_t));
    4657        if (!instance->queue_head) {
    4758                usb_log_error("Failed to allocate queue head.\n");
    4859                return ENOMEM;
    4960        }
    50         instance->queue_head_pa = (uintptr_t)addr_to_phys(instance->queue_head);
     61        instance->queue_head_pa = addr_to_phys(instance->queue_head);
    5162
    5263        queue_head_init(instance->queue_head);
     
    5667}
    5768/*----------------------------------------------------------------------------*/
     69/** Set the next list in chain.
     70 *
     71 * @param[in] instance List to lead.
     72 * @param[in] next List to append.
     73 * @return Error code
     74 */
    5875void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)
    5976{
     
    6683}
    6784/*----------------------------------------------------------------------------*/
     85/** Submits a new transfer batch to list and queue.
     86 *
     87 * @param[in] instance List to use.
     88 * @param[in] batch Transfer batch to submit.
     89 * @return Error code
     90 */
    6891void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch)
    6992{
    7093        assert(instance);
    7194        assert(batch);
    72         usb_log_debug2("Adding batch(%p) to queue %s.\n", batch, instance->name);
     95        usb_log_debug2(
     96            "Adding batch(%p) to queue %s.\n", batch, instance->name);
    7397
    7498        uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);
     
    97121        queue_head_append_qh(last->qh, pa);
    98122        list_append(&batch->link, &instance->batch_list);
     123
    99124        usb_log_debug("Batch(%p) added to queue %s last, first is %p.\n",
    100                 batch, instance->name, first );
     125                batch, instance->name, first);
    101126        fibril_mutex_unlock(&instance->guard);
    102127}
    103128/*----------------------------------------------------------------------------*/
    104 static void transfer_list_remove_batch(
    105     transfer_list_t *instance, batch_t *batch)
     129/** Removes a transfer batch from list and queue.
     130 *
     131 * @param[in] instance List to use.
     132 * @param[in] batch Transfer batch to remove.
     133 * @return Error code
     134 */
     135void transfer_list_remove_batch(transfer_list_t *instance, batch_t *batch)
    106136{
    107137        assert(instance);
     
    109139        assert(instance->queue_head);
    110140        assert(batch->qh);
    111         usb_log_debug2("Removing batch(%p) from queue %s.\n", batch, instance->name);
     141        usb_log_debug2(
     142            "Removing batch(%p) from queue %s.\n", batch, instance->name);
    112143
    113         /* I'm the first one here */
    114144        if (batch->link.prev == &instance->batch_list) {
    115                 usb_log_debug("Batch(%p) removed (FIRST) from queue %s, next element %x.\n",
    116                         batch, instance->name, batch->qh->next_queue);
     145                /* I'm the first one here */
     146                usb_log_debug(
     147                    "Batch(%p) removed (FIRST) from %s, next element %x.\n",
     148                    batch, instance->name, batch->qh->next_queue);
    117149                instance->queue_head->element = batch->qh->next_queue;
    118150        } else {
    119                 usb_log_debug("Batch(%p) removed (NOT FIRST) from queue, next element %x.\n",
    120                         batch, instance->name, batch->qh->next_queue);
    121                 batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
     151                usb_log_debug(
     152                    "Batch(%p) removed (FIRST:NO) from %s, next element %x.\n",
     153                    batch, instance->name, batch->qh->next_queue);
     154                batch_t *prev =
     155                    list_get_instance(batch->link.prev, batch_t, link);
    122156                prev->qh->next_queue = batch->qh->next_queue;
    123157        }
     
    125159}
    126160/*----------------------------------------------------------------------------*/
     161/** Checks list for finished transfers.
     162 *
     163 * @param[in] instance List to use.
     164 * @return Error code
     165 */
    127166void transfer_list_remove_finished(transfer_list_t *instance)
    128167{
  • uspace/drv/uhci-hcd/transfer_list.h

    rd477734 rd2fc1c2  
    5858{
    5959        assert(instance);
    60         queue_head_dispose(instance->queue_head);
     60        free32(instance->queue_head);
    6161}
    6262void transfer_list_remove_finished(transfer_list_t *instance);
  • uspace/drv/uhci-hcd/uhci.c

    rd477734 rd2fc1c2  
    6161};
    6262
    63 static int usb_iface_get_address(ddf_fun_t *fun, devman_handle_t handle,
    64     usb_address_t *address)
     63/** Gets USB address of the calling device.
     64 *
     65 * @param[in] fun UHCI hc function.
     66 * @param[in] handle Handle of the device seeking address.
     67 * @param[out] address Place to store found address.
     68 * @return Error code.
     69 */
     70static int usb_iface_get_address(
     71    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
    6572{
    6673        assert(fun);
     
    99106
    100107static bool allowed_usb_packet(
    101         bool low_speed, usb_transfer_type_t, size_t size);
    102 
    103 
     108    bool low_speed, usb_transfer_type_t transfer, size_t size);
     109/*----------------------------------------------------------------------------*/
     110/** Initializes UHCI hcd driver structure
     111 *
     112 * @param[in] instance Memory place to initialize.
     113 * @param[in] dev DDF device.
     114 * @param[in] regs Address of I/O control registers.
     115 * @param[in] size Size of I/O control registers.
     116 * @return Error code.
     117 * @note Should be called only once on any structure.
     118 */
    104119int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size)
    105120{
     
    156171}
    157172/*----------------------------------------------------------------------------*/
     173/** Initializes UHCI hcd hw resources.
     174 *
     175 * @param[in] instance UHCI structure to use.
     176 */
    158177void uhci_init_hw(uhci_t *instance)
    159178{
    160179        assert(instance);
    161 
    162         /* reset everything, who knows what touched it before us */
    163         pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
     180        regs_t *registers = instance->registers;
     181
     182        /* Reset everything, who knows what touched it before us */
     183        pio_write_16(&registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
    164184        async_usleep(10000); /* 10ms according to USB spec */
    165         pio_write_16(&instance->registers->usbcmd, 0);
    166 
    167         /* reset hc, all states and counters */
    168         pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);
    169         while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)
    170                 { async_usleep(10); }
    171 
    172         /* set framelist pointer */
     185        pio_write_16(&registers->usbcmd, 0);
     186
     187        /* Reset hc, all states and counters */
     188        pio_write_16(&registers->usbcmd, UHCI_CMD_HCRESET);
     189        do { async_usleep(10); }
     190        while ((pio_read_16(&registers->usbcmd) & UHCI_CMD_HCRESET) != 0);
     191
     192        /* Set framelist pointer */
    173193        const uint32_t pa = addr_to_phys(instance->frame_list);
    174         pio_write_32(&instance->registers->flbaseadd, pa);
    175 
    176         /* enable all interrupts, but resume interrupt */
    177         pio_write_16(&instance->registers->usbintr,
    178             UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     194        pio_write_32(&registers->flbaseadd, pa);
     195
     196        /* Enable all interrupts, but resume interrupt */
     197//      pio_write_16(&instance->registers->usbintr,
     198//          UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     199
     200        uint16_t status = pio_read_16(&registers->usbcmd);
     201        if (status != 0)
     202                usb_log_warning("Previous command value: %x.\n", status);
    179203
    180204        /* Start the hc with large(64B) packet FSBR */
    181         pio_write_16(&instance->registers->usbcmd,
     205        pio_write_16(&registers->usbcmd,
    182206            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
    183207}
    184208/*----------------------------------------------------------------------------*/
     209/** Initializes UHCI hcd memory structures.
     210 *
     211 * @param[in] instance UHCI structure to use.
     212 * @return Error code
     213 * @note Should be called only once on any structure.
     214 */
    185215int uhci_init_mem_structures(uhci_t *instance)
    186216{
     
    194224        } else (void) 0
    195225
    196         /* init interrupt code */
     226        /* Init interrupt code */
    197227        instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds));
    198228        int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK;
    199         CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to allocate interrupt cmds space.\n");
     229        CHECK_RET_DEST_CMDS_RETURN(ret,
     230            "Failed to allocate interrupt cmds space.\n");
    200231
    201232        {
    202233                irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds;
    203234                memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
    204                 interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
    205                 interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
     235                interrupt_commands[0].addr =
     236                    (void*)&instance->registers->usbsts;
     237                interrupt_commands[1].addr =
     238                    (void*)&instance->registers->usbsts;
    206239                instance->interrupt_code.cmdcount =
    207240                    sizeof(uhci_cmds) / sizeof(irq_cmd_t);
    208241        }
    209242
    210         /* init transfer lists */
     243        /* Init transfer lists */
    211244        ret = uhci_init_transfer_lists(instance);
    212         CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to initialize transfer lists.\n");
     245        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n");
    213246        usb_log_debug("Initialized transfer lists.\n");
    214247
    215         /* frame list initialization */
     248        /* Init USB frame list page*/
    216249        instance->frame_list = get_page();
    217250        ret = instance ? EOK : ENOMEM;
     
    219252        usb_log_debug("Initialized frame list.\n");
    220253
    221         /* initialize all frames to point to the first queue head */
     254        /* Set all frames to point to the first queue head */
    222255        const uint32_t queue =
    223256          instance->transfers_interrupt.queue_head_pa
     
    229262        }
    230263
    231         /* init address keeper(libusb) */
     264        /* Init device keeper*/
    232265        device_keeper_init(&instance->device_manager);
    233266        usb_log_debug("Initialized device manager.\n");
     
    237270}
    238271/*----------------------------------------------------------------------------*/
     272/** Initializes UHCI hcd transfer lists.
     273 *
     274 * @param[in] instance UHCI structure to use.
     275 * @return Error code
     276 * @note Should be called only once on any structure.
     277 */
    239278int uhci_init_transfer_lists(uhci_t *instance)
    240279{
     
    255294        CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list.");
    256295
    257         ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL");
     296        ret = transfer_list_init(
     297            &instance->transfers_control_full, "CONTROL_FULL");
    258298        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list.");
    259299
    260         ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW");
     300        ret = transfer_list_init(
     301            &instance->transfers_control_slow, "CONTROL_SLOW");
    261302        CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list.");
    262303
     
    277318#endif
    278319
    279         instance->transfers[0][USB_TRANSFER_INTERRUPT] =
     320        /* Assign pointers to be used during scheduling */
     321        instance->transfers[USB_SPEED_FULL][USB_TRANSFER_INTERRUPT] =
    280322          &instance->transfers_interrupt;
    281         instance->transfers[1][USB_TRANSFER_INTERRUPT] =
     323        instance->transfers[USB_SPEED_LOW][USB_TRANSFER_INTERRUPT] =
    282324          &instance->transfers_interrupt;
    283         instance->transfers[0][USB_TRANSFER_CONTROL] =
     325        instance->transfers[USB_SPEED_FULL][USB_TRANSFER_CONTROL] =
    284326          &instance->transfers_control_full;
    285         instance->transfers[1][USB_TRANSFER_CONTROL] =
     327        instance->transfers[USB_SPEED_LOW][USB_TRANSFER_CONTROL] =
    286328          &instance->transfers_control_slow;
    287         instance->transfers[0][USB_TRANSFER_BULK] =
     329        instance->transfers[USB_SPEED_FULL][USB_TRANSFER_BULK] =
    288330          &instance->transfers_bulk_full;
    289331
     
    292334}
    293335/*----------------------------------------------------------------------------*/
     336/** Schedules batch for execution.
     337 *
     338 * @param[in] instance UHCI structure to use.
     339 * @param[in] batch Transfer batch to schedule.
     340 * @return Error code
     341 */
    294342int uhci_schedule(uhci_t *instance, batch_t *batch)
    295343{
     
    299347        if (!allowed_usb_packet(
    300348            low_speed, batch->transfer_type, batch->max_packet_size)) {
    301                 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",
     349                usb_log_warning(
     350                    "Invalid USB packet specified %s SPEED %d %zu.\n",
    302351                    low_speed ? "LOW" : "FULL" , batch->transfer_type,
    303352                    batch->max_packet_size);
     
    314363}
    315364/*----------------------------------------------------------------------------*/
     365/** Takes action based on the interrupt cause.
     366 *
     367 * @param[in] instance UHCI structure to use.
     368 * @param[in] status Value of the stsatus regiser at the time of interrupt.
     369 */
    316370void uhci_interrupt(uhci_t *instance, uint16_t status)
    317371{
    318372        assert(instance);
     373        /* TODO: Check interrupt cause here */
    319374        transfer_list_remove_finished(&instance->transfers_interrupt);
    320375        transfer_list_remove_finished(&instance->transfers_control_slow);
     
    323378}
    324379/*----------------------------------------------------------------------------*/
     380/** Polling function, emulates interrupts.
     381 *
     382 * @param[in] arg UHCI structure to use.
     383 * @return EOK
     384 */
    325385int uhci_interrupt_emulator(void* arg)
    326386{
     
    341401}
    342402/*---------------------------------------------------------------------------*/
     403/** Debug function, checks consistency of memory structures.
     404 *
     405 * @param[in] arg UHCI structure to use.
     406 * @return EOK
     407 */
    343408int uhci_debug_checker(void *arg)
    344409{
     
    399464                async_usleep(UHCI_DEBUGER_TIMEOUT);
    400465        }
    401         return 0;
     466        return EOK;
    402467#undef QH
    403468}
    404469/*----------------------------------------------------------------------------*/
     470/** Checks transfer packets, for USB validity
     471 *
     472 * @param[in] low_speed Transfer speed.
     473 * @param[in] transfer Transer type
     474 * @param[in] size Maximum size of used packets
     475 * @return EOK
     476 */
    405477bool allowed_usb_packet(
    406478    bool low_speed, usb_transfer_type_t transfer, size_t size)
  • uspace/drv/uhci-hcd/uhci.h

    rd477734 rd2fc1c2  
    8484        device_keeper_t device_manager;
    8585
    86         volatile regs_t *registers;
     86        regs_t *registers;
    8787
    8888        link_pointer_t *frame_list;
  • uspace/drv/uhci-hcd/uhci_struct/queue_head.h

    rd477734 rd2fc1c2  
    7171}
    7272
    73 static inline void queue_head_element_td(queue_head_t *instance, uint32_t pa)
     73static inline void queue_head_set_element_td(queue_head_t *instance, uint32_t pa)
    7474{
    7575        if (pa) {
     
    7878}
    7979
    80 static inline queue_head_t * queue_head_get() {
    81         queue_head_t *ret = malloc32(sizeof(queue_head_t));
    82         if (ret)
    83                 queue_head_init(ret);
    84         return ret;
    85 }
    86 
    87 static inline void queue_head_dispose(queue_head_t *head)
    88         { free32(head); }
    89 
    90 
    9180#endif
    9281/**
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    rd477734 rd2fc1c2  
    3838#include "utils/malloc32.h"
    3939
     40/** Initializes Transfer Descriptor
     41 *
     42 * @param[in] instance Memory place to initialize.
     43 * @param[in] err_count Number of retries hc should attempt.
     44 * @param[in] size Size of data source.
     45 * @param[in] toggle Value of toggle bit.
     46 * @param[in] iso True if TD is for Isochronous transfer.
     47 * @param[in] low_speed Target device's speed.
     48 * @param[in] target Address and endpoint receiving the transfer.
     49 * @param[in] pid Packet identification (SETUP, IN or OUT).
     50 * @param[in] buffer Source of data.
     51 * @param[in] next Net TD in transaction.
     52 * @return Error code.
     53 */
    4054void td_init(td_t *instance, int err_count, size_t size, bool toggle, bool iso,
    41     bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, td_t *next)
     55    bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer,
     56    td_t *next)
    4257{
    4358        assert(instance);
    4459        assert(size < 1024);
    45         assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN) || (pid == USB_PID_OUT));
     60        assert((pid == USB_PID_SETUP) || (pid == USB_PID_IN)
     61            || (pid == USB_PID_OUT));
    4662
    4763        instance->next = 0
     
    7591            instance->next, instance->status, instance->device,
    7692            instance->buffer_ptr, buffer);
     93        if (pid == USB_PID_SETUP) {
     94                usb_log_debug("SETUP BUFFER: %s\n",
     95                        usb_debug_str_buffer(buffer, 8, 8));
     96        }
    7797}
    7898/*----------------------------------------------------------------------------*/
     99/** Converts TD status into standard error code
     100 *
     101 * @param[in] instance TD structure to use.
     102 * @return Error code.
     103 */
    79104int td_status(td_t *instance)
    80105{
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    rd477734 rd2fc1c2  
    115115}
    116116
     117static inline int td_toggle(td_t *instance)
     118{
     119        assert(instance);
     120        return ((instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) != 0)
     121            ? 1 : 0;
     122}
     123
    117124static inline bool td_is_active(td_t *instance)
    118125{
  • uspace/drv/uhci-hcd/utils/device_keeper.c

    rd477734 rd2fc1c2  
    3939
    4040/*----------------------------------------------------------------------------*/
     41/** Initializes device keeper structure.
     42 *
     43 * @param[in] instance Memory place to initialize.
     44 */
    4145void device_keeper_init(device_keeper_t *instance)
    4246{
     
    4953                instance->devices[i].occupied = false;
    5054                instance->devices[i].handle = 0;
    51         }
    52 }
    53 /*----------------------------------------------------------------------------*/
    54 void device_keeper_reserve_default(
    55     device_keeper_t *instance, usb_speed_t speed)
     55                instance->devices[i].toggle_status = 0;
     56        }
     57}
     58/*----------------------------------------------------------------------------*/
     59/** Attempts to obtain address 0, blocks.
     60 *
     61 * @param[in] instance Device keeper structure to use.
     62 * @param[in] speed Speed of the device requesting default address.
     63 */
     64void device_keeper_reserve_default(device_keeper_t *instance, usb_speed_t speed)
    5665{
    5766        assert(instance);
     
    6675}
    6776/*----------------------------------------------------------------------------*/
     77/** Attempts to obtain address 0, blocks.
     78 *
     79 * @param[in] instance Device keeper structure to use.
     80 * @param[in] speed Speed of the device requesting default address.
     81 */
    6882void device_keeper_release_default(device_keeper_t *instance)
    6983{
     
    7589}
    7690/*----------------------------------------------------------------------------*/
     91/** Checks setup data for signs of toggle reset.
     92 *
     93 * @param[in] instance Device keeper structure to use.
     94 * @param[in] target Device to receive setup packet.
     95 * @param[in] data Setup packet data.
     96 */
     97void device_keeper_reset_if_need(
     98    device_keeper_t *instance, usb_target_t target, const unsigned char *data)
     99{
     100        assert(instance);
     101        fibril_mutex_lock(&instance->guard);
     102        if (target.endpoint > 15 || target.endpoint < 0
     103            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     104            || !instance->devices[target.address].occupied) {
     105                fibril_mutex_unlock(&instance->guard);
     106                return;
     107        }
     108
     109        switch (data[1])
     110        {
     111        case 0x01: /*clear feature*/
     112                /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
     113                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     114                        /* endpoint number is < 16, thus first byte is enough */
     115                        instance->devices[target.address].toggle_status &=
     116                            ~(1 << data[4]);
     117                }
     118        break;
     119
     120        case 0x9: /* set configuration */
     121        case 0x11: /* set interface */
     122                instance->devices[target.address].toggle_status = 0;
     123        break;
     124        }
     125        fibril_mutex_unlock(&instance->guard);
     126}
     127/*----------------------------------------------------------------------------*/
     128/** Gets current value of endpoint toggle.
     129 *
     130 * @param[in] instance Device keeper structure to use.
     131 * @param[in] target Device and endpoint used.
     132 * @return Error code
     133 */
     134int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target)
     135{
     136        assert(instance);
     137        int ret;
     138        fibril_mutex_lock(&instance->guard);
     139        if (target.endpoint > 15 || target.endpoint < 0
     140            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     141            || !instance->devices[target.address].occupied) {
     142                ret = EINVAL;
     143        } else {
     144                ret =
     145                    (instance->devices[target.address].toggle_status
     146                        >> target.endpoint) & 1;
     147        }
     148        fibril_mutex_unlock(&instance->guard);
     149        return ret;
     150}
     151/*----------------------------------------------------------------------------*/
     152/** Sets current value of endpoint toggle.
     153 *
     154 * @param[in] instance Device keeper structure to use.
     155 * @param[in] target Device and endpoint used.
     156 * @param[in] toggle Current toggle value.
     157 * @return Error code.
     158 */
     159int device_keeper_set_toggle(
     160    device_keeper_t *instance, usb_target_t target, bool toggle)
     161{
     162        assert(instance);
     163        int ret;
     164        fibril_mutex_lock(&instance->guard);
     165        if (target.endpoint > 15 || target.endpoint < 0
     166            || target.address >= USB_ADDRESS_COUNT || target.address < 0
     167            || !instance->devices[target.address].occupied) {
     168                ret = EINVAL;
     169        } else {
     170                if (toggle) {
     171                        instance->devices[target.address].toggle_status |= (1 << target.endpoint);
     172                } else {
     173                        instance->devices[target.address].toggle_status &= ~(1 << target.endpoint);
     174                }
     175                ret = EOK;
     176        }
     177        fibril_mutex_unlock(&instance->guard);
     178        return ret;
     179}
     180/*----------------------------------------------------------------------------*/
     181/** Gets a free USB address
     182 *
     183 * @param[in] instance Device keeper structure to use.
     184 * @param[in] speed Speed of the device requiring address.
     185 * @return Free address, or error code.
     186 */
    77187usb_address_t device_keeper_request(
    78188    device_keeper_t *instance, usb_speed_t speed)
     
    96206        instance->devices[new_address].occupied = true;
    97207        instance->devices[new_address].speed = speed;
     208        instance->devices[new_address].toggle_status = 0;
    98209        instance->last_address = new_address;
    99210        fibril_mutex_unlock(&instance->guard);
     
    101212}
    102213/*----------------------------------------------------------------------------*/
     214/** Binds USB address to devman handle.
     215 *
     216 * @param[in] instance Device keeper structure to use.
     217 * @param[in] address Device address
     218 * @param[in] handle Devman handle of the device.
     219 */
    103220void device_keeper_bind(
    104221    device_keeper_t *instance, usb_address_t address, devman_handle_t handle)
     
    113230}
    114231/*----------------------------------------------------------------------------*/
     232/** Releases used USB address.
     233 *
     234 * @param[in] instance Device keeper structure to use.
     235 * @param[in] address Device address
     236 */
    115237void device_keeper_release(device_keeper_t *instance, usb_address_t address)
    116238{
     
    125247}
    126248/*----------------------------------------------------------------------------*/
     249/** Finds USB address associated with the device
     250 *
     251 * @param[in] instance Device keeper structure to use.
     252 * @param[in] handle Devman handle of the device seeking its address.
     253 * @return USB Address, or error code.
     254 */
    127255usb_address_t device_keeper_find(
    128256    device_keeper_t *instance, devman_handle_t handle)
     
    142270}
    143271/*----------------------------------------------------------------------------*/
     272/** Gets speed associated with the address
     273 *
     274 * @param[in] instance Device keeper structure to use.
     275 * @param[in] address Address of the device.
     276 * @return USB speed.
     277 */
    144278usb_speed_t device_keeper_speed(
    145279    device_keeper_t *instance, usb_address_t address)
  • uspace/drv/uhci-hcd/utils/device_keeper.h

    rd477734 rd2fc1c2  
    4444        usb_speed_t speed;
    4545        bool occupied;
     46        uint16_t toggle_status;
    4647        devman_handle_t handle;
    4748};
     
    5556
    5657void device_keeper_init(device_keeper_t *instance);
     58
    5759void device_keeper_reserve_default(
    5860    device_keeper_t *instance, usb_speed_t speed);
     61
    5962void device_keeper_release_default(device_keeper_t *instance);
     63
     64void device_keeper_reset_if_need(
     65    device_keeper_t *instance, usb_target_t target, const unsigned char *setup_data);
     66
     67int device_keeper_get_toggle(device_keeper_t *instance, usb_target_t target);
     68
     69int device_keeper_set_toggle(
     70    device_keeper_t *instance, usb_target_t target, bool toggle);
    6071
    6172usb_address_t device_keeper_request(
    6273    device_keeper_t *instance, usb_speed_t speed);
     74
    6375void device_keeper_bind(
    6476    device_keeper_t *instance, usb_address_t address, devman_handle_t handle);
     77
    6578void device_keeper_release(device_keeper_t *instance, usb_address_t address);
     79
    6680usb_address_t device_keeper_find(
    6781    device_keeper_t *instance, devman_handle_t handle);
  • uspace/drv/uhci-hcd/utils/malloc32.h

    rd477734 rd2fc1c2  
    3434#ifndef DRV_UHCI_TRANSLATOR_H
    3535#define DRV_UHCI_TRANSLATOR_H
    36 
    37 #include <usb/usbmem.h>
    3836
    3937#include <assert.h>
  • uspace/drv/uhci-rhd/main.c

    rd477734 rd2fc1c2  
    3535#include <devman.h>
    3636#include <device/hw_res.h>
     37#include <errno.h>
    3738#include <usb_iface.h>
    3839#include <usb/ddfiface.h>
     40#include <usb/debug.h>
    3941
    40 #include <errno.h>
    4142
    42 #include <usb/debug.h>
    4343
    4444#include "root_hub.h"
     
    4747static int hc_get_my_registers(ddf_dev_t *dev,
    4848    uintptr_t *io_reg_address, size_t *io_reg_size);
    49 
     49/*----------------------------------------------------------------------------*/
    5050static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
    5151{
     
    5858        return EOK;
    5959}
    60 
     60/*----------------------------------------------------------------------------*/
    6161static usb_iface_t uhci_rh_usb_iface = {
    6262        .get_hc_handle = usb_iface_get_hc_handle,
    6363        .get_address = usb_iface_get_address_hub_impl
    6464};
    65 
     65/*----------------------------------------------------------------------------*/
    6666static ddf_dev_ops_t uhci_rh_ops = {
    6767        .interfaces[USB_DEV_IFACE] = &uhci_rh_usb_iface,
    6868};
    69 
     69/*----------------------------------------------------------------------------*/
     70/** Initializes a new ddf driver instance of UHCI root hub.
     71 *
     72 * @param[in] device DDF instance of the device to initialize.
     73 * @return Error code.
     74 */
    7075static int uhci_rh_add_device(ddf_dev_t *device)
    7176{
     
    104109        return EOK;
    105110}
    106 
     111/*----------------------------------------------------------------------------*/
    107112static driver_ops_t uhci_rh_driver_ops = {
    108113        .add_device = uhci_rh_add_device,
    109114};
    110 
     115/*----------------------------------------------------------------------------*/
    111116static driver_t uhci_rh_driver = {
    112117        .name = NAME,
     
    114119};
    115120/*----------------------------------------------------------------------------*/
     121/** Initializes global driver structures (NONE).
     122 *
     123 * @param[in] argc Nmber of arguments in argv vector (ignored).
     124 * @param[in] argv Cmdline argument vector (ignored).
     125 * @return Error code.
     126 *
     127 * Driver debug level is set here.
     128 */
    116129int main(int argc, char *argv[])
    117130{
     
    120133}
    121134/*----------------------------------------------------------------------------*/
    122 int hc_get_my_registers(ddf_dev_t *dev,
    123     uintptr_t *io_reg_address, size_t *io_reg_size)
     135/** Get address of I/O registers.
     136 *
     137 * @param[in] dev Device asking for the addresses.
     138 * @param[out] io_reg_address Base address of the memory range.
     139 * @param[out] io_reg_size Size of the memory range.
     140 * @return Error code.
     141 */
     142int hc_get_my_registers(
     143    ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)
    124144{
    125145        assert(dev != NULL);
     
    146166        for (i = 0; i < hw_resources.count; i++) {
    147167                hw_resource_t *res = &hw_resources.resources[i];
    148                 switch (res->type) {
    149                         case IO_RANGE:
    150                                 io_address = (uintptr_t)
    151                                     res->res.io_range.address;
    152                                 io_size = res->res.io_range.size;
    153                                 io_found = true;
    154                                 break;
    155                         default:
    156                                 break;
     168                switch (res->type)
     169                {
     170                case IO_RANGE:
     171                        io_address = (uintptr_t) res->res.io_range.address;
     172                        io_size = res->res.io_range.size;
     173                        io_found = true;
     174
     175                default:
     176                        break;
    157177                }
    158178        }
     
    170190        }
    171191        rc = EOK;
     192
    172193leave:
    173194        async_hangup(parent_phone);
    174 
    175195        return rc;
    176196}
  • uspace/drv/uhci-rhd/port.c

    rd477734 rd2fc1c2  
    4646#include "port_status.h"
    4747
    48 static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
     48static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
    4949static int uhci_port_remove_device(uhci_port_t *port);
    5050static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
    5151static int uhci_port_check(void *port);
    52 static int new_device_enable_port(int portno, void *arg);
    53 
    54 int uhci_port_init(
    55   uhci_port_t *port, port_status_t *address, unsigned number,
    56   unsigned usec, ddf_dev_t *rh)
     52static int uhci_port_reset_enable(int portno, void *arg);
     53/*----------------------------------------------------------------------------*/
     54/** Initializes UHCI root hub port instance.
     55 *
     56 * @param[in] port Memory structure to use.
     57 * @param[in] addr Address of I/O register.
     58 * @param[in] number Port number.
     59 * @param[in] usec Polling interval.
     60 * @param[in] rh Pointer to ddf instance fo the root hub driver.
     61 * @return Error code.
     62 *
     63 * Starts the polling fibril.
     64 */
     65int uhci_port_init(uhci_port_t *port,
     66    port_status_t *address, unsigned number, unsigned usec, ddf_dev_t *rh)
    5767{
    5868        assert(port);
     69
    5970        port->address = address;
    6071        port->number = number;
     
    6273        port->attached_device = 0;
    6374        port->rh = rh;
     75
    6476        int rc = usb_hc_connection_initialize_from_device(
    6577            &port->hc_connection, rh);
     
    7587                return ENOMEM;
    7688        }
     89
    7790        fibril_add_ready(port->checker);
    7891        usb_log_debug("Port(%p - %d): Added fibril. %x\n",
     
    8194}
    8295/*----------------------------------------------------------------------------*/
     96/** Finishes UHCI root hub port instance.
     97 *
     98 * @param[in] port Memory structure to use.
     99 *
     100 * Stops the polling fibril.
     101 */
    83102void uhci_port_fini(uhci_port_t *port)
    84103{
    85 // TODO: destroy fibril
    86 // TODO: hangup phone
    87 //      fibril_teardown(port->checker);
     104        /* TODO: Kill fibril here */
    88105        return;
    89106}
    90107/*----------------------------------------------------------------------------*/
     108/** Periodically checks port status and reports new devices.
     109 *
     110 * @param[in] port Memory structure to use.
     111 * @return Error code.
     112 */
    91113int uhci_port_check(void *port)
    92114{
    93         uhci_port_t *port_instance = port;
    94         assert(port_instance);
    95 //      port_status_write(port_instance->address, 0);
    96 
     115        uhci_port_t *instance = port;
     116        assert(instance);
     117
     118        /* Iteration count, for debug purposes only */
    97119        unsigned count = 0;
    98120
    99121        while (1) {
    100                 async_usleep(port_instance->wait_period_usec);
     122                async_usleep(instance->wait_period_usec);
    101123
    102124                /* read register value */
    103                 port_status_t port_status =
    104                         port_status_read(port_instance->address);
    105 
    106                 /* debug print */
    107                 static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
     125                port_status_t port_status = port_status_read(instance->address);
     126
     127                /* debug print mutex */
     128                static fibril_mutex_t dbg_mtx =
     129                    FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
    108130                fibril_mutex_lock(&dbg_mtx);
    109131                usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n",
    110                   port_instance->address, port_instance->number, port_status, count++);
     132                  instance->address, instance->number, port_status, count++);
    111133//              print_port_status(port_status);
    112134                fibril_mutex_unlock(&dbg_mtx);
    113135
    114                 if ((port_status & STATUS_CONNECTED_CHANGED) != 0) {
    115                         usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
    116                             port_instance->address, port_instance->number, port_status);
    117 
    118 
    119                         int rc = usb_hc_connection_open(
    120                             &port_instance->hc_connection);
    121                         if (rc != EOK) {
    122                                 usb_log_error("Port(%p - %d): Failed to connect to HC.",
    123                                     port_instance->address, port_instance->number);
    124                                 continue;
    125                         }
    126 
    127                         /* remove any old device */
    128                         if (port_instance->attached_device) {
    129                                 usb_log_debug("Port(%p - %d): Removing device.\n",
    130                                     port_instance->address, port_instance->number);
    131                                 uhci_port_remove_device(port_instance);
    132                         }
    133 
    134                         if ((port_status & STATUS_CONNECTED) != 0) {
    135                                 /* new device */
    136                                 uhci_port_new_device(port_instance, port_status);
    137                         } else {
    138                                 /* ack changes by writing one to WC bits */
    139                                 port_status_write(port_instance->address, port_status);
    140                                 usb_log_debug("Port(%p - %d): Change status ACK.\n",
    141                                                 port_instance->address, port_instance->number);
    142                         }
    143 
    144                         rc = usb_hc_connection_close(
    145                             &port_instance->hc_connection);
    146                         if (rc != EOK) {
    147                                 usb_log_error("Port(%p - %d): Failed to disconnect from HC.",
    148                                     port_instance->address, port_instance->number);
    149                         }
    150                 }
    151         }
    152         return EOK;
    153 }
    154 
     136                if ((port_status & STATUS_CONNECTED_CHANGED) == 0)
     137                        continue;
     138
     139                usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
     140                    instance->address, instance->number, port_status);
     141
     142                int rc =
     143                    usb_hc_connection_open(&instance->hc_connection);
     144                if (rc != EOK) {
     145                        usb_log_error("Port(%p - %d): Failed to connect to HC.",
     146                            instance->address, instance->number);
     147                        continue;
     148                }
     149
     150                /* Remove any old device */
     151                if (instance->attached_device) {
     152                        usb_log_debug2("Port(%p - %d): Removing device.\n",
     153                            instance->address, instance->number);
     154                        uhci_port_remove_device(instance);
     155                }
     156
     157                if ((port_status & STATUS_CONNECTED) != 0) {
     158                        /* New device */
     159                        const usb_speed_t speed =
     160                            ((port_status & STATUS_LOW_SPEED) != 0) ?
     161                            USB_SPEED_LOW : USB_SPEED_FULL;
     162                        uhci_port_new_device(instance, speed);
     163                } else {
     164                        /* Write one to WC bits, to ack changes */
     165                        port_status_write(instance->address, port_status);
     166                        usb_log_debug("Port(%p - %d): Change status ACK.\n",
     167                            instance->address, instance->number);
     168                }
     169
     170                rc = usb_hc_connection_close(&instance->hc_connection);
     171                if (rc != EOK) {
     172                        usb_log_error("Port(%p - %d): Failed to disconnect.",
     173                            instance->address, instance->number);
     174                }
     175        }
     176        return EOK;
     177}
     178/*----------------------------------------------------------------------------*/
    155179/** Callback for enabling port during adding a new device.
    156180 *
     
    159183 * @return Error code.
    160184 */
    161 static int new_device_enable_port(int portno, void *arg)
     185int uhci_port_reset_enable(int portno, void *arg)
    162186{
    163187        uhci_port_t *port = (uhci_port_t *) arg;
     
    184208                port_status_write(port->address, port_status);
    185209                async_usleep(10000);
    186                 port_status =
    187                         port_status_read(port->address);
     210                port_status = port_status_read(port->address);
    188211                port_status &= ~STATUS_IN_RESET;
    189212                port_status_write(port->address, port_status);
     
    194217        /* Enable the port. */
    195218        uhci_port_set_enabled(port, true);
    196 
    197         return EOK;
    198 }
    199 
    200 /*----------------------------------------------------------------------------*/
    201 static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
     219        return EOK;
     220}
     221/*----------------------------------------------------------------------------*/
     222/** Initializes and reports connected device.
     223 *
     224 * @param[in] port Memory structure to use.
     225 * @param[in] speed Detected speed.
     226 * @return Error code.
     227 *
     228 * Uses libUSB function to do the actual work.
     229 */
     230int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed)
    202231{
    203232        assert(port);
     
    209238        usb_address_t dev_addr;
    210239        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    211             ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
    212             new_device_enable_port, port->number, port,
     240            speed, uhci_port_reset_enable, port->number, port,
    213241            &dev_addr, &port->attached_device, NULL, NULL, NULL);
    214242
    215243        if (rc != EOK) {
    216                 usb_log_error("Port(%p-%d): Failed(%d) adding new device: %s.\n",
     244                usb_log_error("Port(%p-%d): Failed(%d) to add device: %s.\n",
    217245                    port->address, port->number, rc, str_error(rc));
    218246                uhci_port_set_enabled(port, false);
     
    225253        return EOK;
    226254}
    227 
    228 /*----------------------------------------------------------------------------*/
    229 static int uhci_port_remove_device(uhci_port_t *port)
     255/*----------------------------------------------------------------------------*/
     256/** Removes device.
     257 *
     258 * @param[in] port Memory structure to use.
     259 * @return Error code.
     260 *
     261 * Does not work DDF does not support device removal.
     262 */
     263int uhci_port_remove_device(uhci_port_t *port)
    230264{
    231265        usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n",
    232                 port->address, port->number, (unsigned int)port->attached_device);
    233 //      uhci_port_set_enabled(port, false);
    234         return EOK;
    235 }
    236 /*----------------------------------------------------------------------------*/
    237 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
     266            port->address, port->number, (unsigned int)port->attached_device);
     267        return EOK;
     268}
     269/*----------------------------------------------------------------------------*/
     270/** Enables and disables port.
     271 *
     272 * @param[in] port Memory structure to use.
     273 * @return Error code. (Always EOK)
     274 */
     275int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
    238276{
    239277        assert(port);
    240278
    241         /* read register value */
    242         port_status_t port_status
    243                 = port_status_read(port->address);
    244 
    245         /* enable port: register write */
     279        /* Read register value */
     280        port_status_t port_status = port_status_read(port->address);
     281
     282        /* Set enabled bit */
    246283        if (enabled) {
    247284                port_status |= STATUS_ENABLED;
     
    249286                port_status &= ~STATUS_ENABLED;
    250287        }
     288
     289        /* Write new value. */
    251290        port_status_write(port->address, port_status);
    252291
  • uspace/drv/uhci-rhd/port_status.c

    rd477734 rd2fc1c2  
    6060};
    6161
     62/** Prints portr status in a human readable way.
     63 *
     64 * @param[in] value Port value to print.
     65 * @return Error code.
     66 */
    6267void print_port_status(port_status_t value)
    6368{
  • uspace/drv/uhci-rhd/root_hub.c

    rd477734 rd2fc1c2  
    4040#include "root_hub.h"
    4141
     42/** Initializes UHCI root hub instance.
     43 *
     44 * @param[in] instance Driver memory structure to use.
     45 * @param[in] addr Address of I/O registers.
     46 * @param[in] size Size of available I/O space.
     47 * @param[in] rh Pointer to ddf instance fo the root hub driver.
     48 * @return Error code.
     49 */
    4250int uhci_root_hub_init(
    4351  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh)
     
    4755        int ret;
    4856
    49         /* allow access to root hub registers */
    50         assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT == size);
     57        /* Allow access to root hub port registers */
     58        assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT <= size);
    5159        port_status_t *regs;
    5260        ret = pio_enable(addr, size, (void**)&regs);
    53 
    5461        if (ret < 0) {
    55                 usb_log_error("Failed to gain access to port registers at %p\n", regs);
     62                usb_log_error(
     63                    "Failed to gain access to port registers at %p\n", regs);
    5664                return ret;
    5765        }
     
    6068        unsigned i = 0;
    6169        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    62                 /* mind pointer arithmetics */
     70                /* NOTE: mind pointer arithmetics here */
    6371                ret = uhci_port_init(
    64                   &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
     72                    &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
    6573                if (ret != EOK) {
    6674                        unsigned j = 0;
     
    7482}
    7583/*----------------------------------------------------------------------------*/
    76 int uhci_root_hub_fini( uhci_root_hub_t* instance )
     84/** Finishes UHCI root hub instance.
     85 *
     86 * @param[in] instance Driver memory structure to use.
     87 * @return Error code.
     88 */
     89int uhci_root_hub_fini(uhci_root_hub_t* instance)
    7790{
    78         assert( instance );
    79         // TODO:
    80         //destroy fibril here
    81         //disable access to registers
     91        assert(instance);
     92        unsigned i = 0;
     93        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
     94                uhci_port_fini(&instance->ports[i]);
     95        }
    8296        return EOK;
    8397}
  • uspace/drv/usbmid/main.c

    rd477734 rd2fc1c2  
    4444#include "usbmid.h"
    4545
     46/** Callback when new MID device is attached to the host.
     47 *
     48 * @param gen_dev Generic DDF device representing the new device.
     49 * @return Error code.
     50 */
    4651static int usbmid_add_device(ddf_dev_t *gen_dev)
    4752{
     
    8691}
    8792
     93/** USB MID driver ops. */
    8894static driver_ops_t mid_driver_ops = {
    8995        .add_device = usbmid_add_device,
    9096};
    9197
     98/** USB MID driver. */
    9299static driver_t mid_driver = {
    93100        .name = NAME,
  • uspace/drv/usbmid/usbmid.c

    rd477734 rd2fc1c2  
    6767}
    6868
     69/** DDF interface of the child - interface function. */
    6970static usb_iface_t child_usb_iface = {
    7071        .get_hc_handle = usb_iface_get_hc_handle_hub_child_impl,
     
    7374};
    7475
    75 
     76/** Operations for children - interface functions. */
    7677static ddf_dev_ops_t child_device_ops = {
    7778        .interfaces[USB_DEV_IFACE] = &child_usb_iface
    7879};
    7980
     81/** Operations of the device itself. */
    8082static ddf_dev_ops_t mid_device_ops = {
    8183        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
     
    123125/** Create new interface for USB MID device.
    124126 *
    125  * @param dev Backing generic DDF child device (representing interface).
     127 * @param fun Backing generic DDF device function (representing interface).
    126128 * @param iface_no Interface number.
    127129 * @return New interface.
  • uspace/drv/usbmid/usbmid.h

    rd477734 rd2fc1c2  
    4444#define NAME "usbmid"
    4545
     46/** USB MID device container. */
    4647typedef struct {
    4748        /** Device container. */
     
    5455} usbmid_device_t;
    5556
     57
     58/** Container for single interface in a MID device. */
    5659typedef struct {
    5760        /** Function container. */
  • uspace/drv/usbmouse/init.c

    rd477734 rd2fc1c2  
    101101
    102102static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
     103/** Device ops for USB mouse. */
    103104static ddf_dev_ops_t mouse_ops = {
    104105        .default_handler = default_connection_handler
     
    107108/** Default handler for IPC methods not handled by DDF.
    108109 *
    109  * @param dev Device handling the call.
     110 * @param fun Device function handling the call.
    110111 * @param icallid Call id.
    111112 * @param icall Call data.
     
    135136}
    136137
    137 
     138/** Create USB mouse device.
     139 *
     140 * The mouse device is stored into <code>dev-&gt;driver_data</code>.
     141 *
     142 * @param dev Generic device.
     143 * @return Error code.
     144 */
    138145int usb_mouse_create(ddf_dev_t *dev)
    139146{
  • uspace/drv/usbmouse/main.c

    rd477734 rd2fc1c2  
    3939#include <str_error.h>
    4040
     41/** Callback when new mouse device is attached and recognised by DDF.
     42 *
     43 * @param dev Representation of a generic DDF device.
     44 * @return Error code.
     45 */
    4146static int usbmouse_add_device(ddf_dev_t *dev)
    4247{
     
    6368}
    6469
     70/** USB mouse driver ops. */
    6571static driver_ops_t mouse_driver_ops = {
    6672        .add_device = usbmouse_add_device,
    6773};
    6874
     75/** USB mouse driver. */
    6976static driver_t mouse_driver = {
    7077        .name = NAME,
     
    7481int main(int argc, char *argv[])
    7582{
    76         usb_log_enable(USB_LOG_LEVEL_DEBUG2, NAME);
     83        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    7784
    7885        return ddf_driver_main(&mouse_driver);
  • uspace/drv/usbmouse/mouse.c

    rd477734 rd2fc1c2  
    4040#include <ipc/mouse.h>
    4141
     42/** Fibril function for polling the mouse device.
     43 *
     44 * This function shall not terminate unless the device breaks and fails
     45 * to send data (e.g. stalls on data request).
     46 *
     47 * @param arg ddf_dev_t type representing the mouse device.
     48 * @return EOK Always.
     49 */
    4250int usb_mouse_polling_fibril(void *arg)
    4351{
  • uspace/drv/usbmouse/mouse.h

    rd477734 rd2fc1c2  
    4343#define NAME "usbmouse"
    4444
     45/** Container for USB mouse device. */
    4546typedef struct {
     47        /** Generic device container. */
    4648        ddf_dev_t *device;
     49        /** Function representing the device. */
    4750        ddf_fun_t *mouse_fun;
     51        /** Representation of connection to the device. */
    4852        usb_device_connection_t wire;
     53        /** Default (zero) control pipe. */
    4954        usb_endpoint_pipe_t ctrl_pipe;
     55        /** Polling (in) pipe. */
    5056        usb_endpoint_pipe_t poll_pipe;
     57        /** Polling interval in microseconds. */
    5158        suseconds_t poll_interval_us;
     59        /** IPC phone to console (consumer). */
    5260        int console_phone;
    5361} usb_mouse_t;
  • uspace/drv/vhc/conndev.c

    rd477734 rd2fc1c2  
    110110/** Callback for DDF when client disconnects.
    111111 *
    112  * @param d Device the client was connected to.
     112 * @param fun Device function the client was connected to.
    113113 */
    114114void on_client_close(ddf_fun_t *fun)
  • uspace/lib/usb/Makefile

    rd477734 rd2fc1c2  
    4747        src/request.c \
    4848        src/usb.c \
    49         src/usbdevice.c \
    50         src/usbmem.c
     49        src/usbdevice.c
    5150
    5251include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usb/include/usb/classes/classes.h

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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__)
  • uspace/lib/usb/include/usb/descriptor.h

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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.
     
    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. */
  • uspace/lib/usb/include/usb/request.h

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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{
     
    256150/* string + terminator + number width (enough for 4GB)*/
    257151#define REMAINDER_STR_LEN (5 + 1 + 10)
     152
     153/** How many bytes to group together. */
    258154#define BUFFER_DUMP_GROUP_SIZE 4
     155
     156/** Size of the string for buffer dumps. */
    259157#define BUFFER_DUMP_LEN 240 /* Ought to be enough for everybody ;-). */
     158
     159/** Fibril local storage for the dumped buffer. */
    260160static fibril_local char buffer_dump[BUFFER_DUMP_LEN];
    261161
     
    265165 * in a static fibril local string.
    266166 * That means that you do not have to deallocate the string (actually, you
    267  * can not do that) and you do not have to save it agains concurrent
     167 * can not do that) and you do not have to guard it against concurrent
    268168 * calls to it.
    269169 * The only limitation is that each call rewrites the buffer again.
  • uspace/lib/usb/src/dp.c

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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);
  • uspace/lib/usb/src/pipes.c

    rd477734 rd2fc1c2  
    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/pipesio.c

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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 */
  • uspace/lib/usb/src/request.c

    rd477734 rd2fc1c2  
    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

    rd477734 rd2fc1c2  
    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.