Changes in / [9d06563:a4e18e1] in mainline


Ignore:
Files:
9 added
2 deleted
33 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r9d06563 ra4e18e1  
    9393./uspace/drv/usbhub/usbhub
    9494./uspace/drv/usbhid/usbhid
     95./uspace/drv/usbkbd/usbkbd
    9596./uspace/drv/usbmid/usbmid
    9697./uspace/drv/usbmouse/usbmouse
  • uspace/drv/ohci/batch.c

    r9d06563 ra4e18e1  
    7373        CHECK_NULL_DISPOSE_RETURN(instance,
    7474            "Failed to allocate batch instance.\n");
    75         usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size,
    76             buffer, NULL, buffer_size, NULL, setup_size, func_in,
    77             func_out, arg, fun, NULL);
     75        usb_transfer_batch_init(instance, target, transfer_type, speed,
     76            max_packet_size, buffer, NULL, buffer_size, NULL, setup_size,
     77            func_in, func_out, arg, fun, NULL, NULL);
    7878
    7979        if (buffer_size > 0) {
  • uspace/drv/ohci/hc.c

    r9d06563 ra4e18e1  
    9292        instance->ddf_instance = fun;
    9393        usb_device_keeper_init(&instance->manager);
    94         ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,
    95             bandwidth_count_usb11);
    96         CHECK_RET_RETURN(ret, "Failed to initialize bandwidth allocator: %s.\n",
     94        ret = usb_endpoint_manager_init(&instance->ep_manager,
     95            BANDWIDTH_AVAILABLE_USB11);
     96        CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",
    9797            ret, str_error(ret));
    9898
     
    183183         * maintain reset for at least the time specified in USB spec (50 ms)*/
    184184        async_usleep(50000);
     185
     186        /* turn off legacy emulation */
     187        volatile uint32_t *ohci_emulation_reg =
     188            (uint32_t*)((char*)instance->registers + 0x100);
     189        usb_log_info("OHCI legacy register status %p: %x.\n",
     190                ohci_emulation_reg, *ohci_emulation_reg);
     191        *ohci_emulation_reg = 0;
     192
    185193}
    186194/*----------------------------------------------------------------------------*/
  • uspace/drv/ohci/hc.h

    r9d06563 ra4e18e1  
    4242#include <usb/usb.h>
    4343#include <usb/host/device_keeper.h>
    44 #include <usb/host/bandwidth.h>
     44#include <usb/host/usb_endpoint_manager.h>
    4545#include <usbhc_iface.h>
    4646
     
    4848#include "ohci_regs.h"
    4949#include "root_hub.h"
     50#include "hw_struct/hcca.h"
    5051
    5152typedef struct hc {
     
    5556        ddf_fun_t *ddf_instance;
    5657        usb_device_keeper_t manager;
    57         bandwidth_t bandwidth;
     58        usb_endpoint_manager_t ep_manager;
    5859        fid_t interrupt_emulator;
    5960} hc_t;
  • uspace/drv/ohci/iface.c

    r9d06563 ra4e18e1  
    162162            address, endpoint, usb_str_transfer_type(transfer_type),
    163163            usb_str_speed(speed), direction, size, max_packet_size, interval);
    164         return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction,
    165             speed, transfer_type, max_packet_size, size, interval);
     164        // TODO use real endpoint here!
     165        return usb_endpoint_manager_register_ep(&hc->ep_manager,NULL, 0);
    166166}
    167167/*----------------------------------------------------------------------------*/
     
    183183        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    184184            address, endpoint, direction);
    185         return bandwidth_release(&hc->bandwidth, address, endpoint, direction);
    186 
    187         return ENOTSUP;
     185        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
     186            endpoint, direction);
    188187}
    189188/*----------------------------------------------------------------------------*/
  • uspace/drv/pciintel/pci.c

    r9d06563 ra4e18e1  
    107107        }
    108108
    109         size_t i;
    110         for (i = 0; i < dev_data->hw_resources.count; i++) {
    111                 if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
    112                         int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
    113                         int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     109        size_t i = 0;
     110        hw_resource_list_t *res = &dev_data->hw_resources;
     111        for (; i < res->count; i++) {
     112                if (res->resources[i].type == INTERRUPT) {
     113                        const int irq = res->resources[i].res.interrupt.irq;
     114                        const int rc =
     115                            async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq);
    114116                        if (rc != EOK) {
    115117                                async_hangup(irc_phone);
  • uspace/drv/uhci-hcd/batch.c

    r9d06563 ra4e18e1  
    4949        td_t *tds;
    5050        size_t transfers;
    51         usb_device_keeper_t *manager;
    5251} uhci_batch_t;
    5352
     
    7372 * @param[in] func_out function to call on outbound transaction completion
    7473 * @param[in] arg additional parameter to func_in or func_out
    75  * @param[in] manager Pointer to toggle management structure.
     74 * @param[in] ep Pointer to endpoint toggle management structure.
    7675 * @return Valid pointer if all substructures were successfully created,
    7776 * NULL otherwise.
     
    8685    char* setup_buffer, size_t setup_size,
    8786    usbhc_iface_transfer_in_callback_t func_in,
    88     usbhc_iface_transfer_out_callback_t func_out, void *arg,
    89     usb_device_keeper_t *manager
     87    usbhc_iface_transfer_out_callback_t func_out, void *arg, endpoint_t *ep
    9088    )
    9189{
     
    105103        CHECK_NULL_DISPOSE_RETURN(instance,
    106104            "Failed to allocate batch instance.\n");
    107         usb_transfer_batch_init(instance, target, transfer_type, speed, max_packet_size,
     105        usb_transfer_batch_init(instance, target,
     106            transfer_type, speed, max_packet_size,
    108107            buffer, NULL, buffer_size, NULL, setup_size, func_in,
    109             func_out, arg, fun, NULL);
     108            func_out, arg, fun, ep, NULL);
    110109
    111110
     
    114113            "Failed to allocate batch instance.\n");
    115114        bzero(data, sizeof(uhci_batch_t));
    116         data->manager = manager;
    117115        instance->private_data = data;
    118116
     
    180178                            instance, i, data->tds[i].status);
    181179                        td_print_status(&data->tds[i]);
    182 
    183                         usb_device_keeper_set_toggle(data->manager,
    184                             instance->target, instance->direction,
    185                             td_toggle(&data->tds[i]));
     180                        if (instance->ep != NULL)
     181                                endpoint_toggle_set(instance->ep,
     182                                    td_toggle(&data->tds[i]));
    186183                        if (i > 0)
    187184                                goto substract_ret;
     
    310307
    311308        const bool low_speed = instance->speed == USB_SPEED_LOW;
    312         int toggle = usb_device_keeper_get_toggle(
    313             data->manager, instance->target, instance->direction);
     309        int toggle = endpoint_toggle_get(instance->ep);
    314310        assert(toggle == 0 || toggle == 1);
    315311
     
    342338        }
    343339        td_set_ioc(&data->tds[transfer - 1]);
    344         usb_device_keeper_set_toggle(data->manager, instance->target,
    345             instance->direction, toggle);
     340        endpoint_toggle_set(instance->ep, toggle);
    346341}
    347342/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-hcd/batch.h

    r9d06563 ra4e18e1  
    3535#define DRV_UHCI_BATCH_H
    3636
    37 #include <adt/list.h>
    38 
    3937#include <usbhc_iface.h>
    4038#include <usb/usb.h>
    4139#include <usb/host/device_keeper.h>
     40#include <usb/host/endpoint.h>
    4241#include <usb/host/batch.h>
    4342
     
    5756    usbhc_iface_transfer_out_callback_t func_out,
    5857                void *arg,
    59                 usb_device_keeper_t *manager
     58                endpoint_t *ep
    6059                );
    6160
  • uspace/drv/uhci-hcd/hc.c

    r9d06563 ra4e18e1  
    6666static int hc_interrupt_emulator(void *arg);
    6767static int hc_debug_checker(void *arg);
    68 
     68#if 0
    6969static bool usb_is_allowed(
    7070    bool low_speed, usb_transfer_type_t transfer, size_t size);
     71#endif
    7172/*----------------------------------------------------------------------------*/
    7273/** Initialize UHCI hcd driver structure
     
    239240        usb_log_debug("Initialized device manager.\n");
    240241
    241         ret = bandwidth_init(&instance->bandwidth, BANDWIDTH_AVAILABLE_USB11,
    242             bandwidth_count_usb11);
     242        ret =
     243            usb_endpoint_manager_init(&instance->ep_manager,
     244                BANDWIDTH_AVAILABLE_USB11);
    243245        assert(ret == EOK);
    244246
     
    326328        assert(instance);
    327329        assert(batch);
    328         const int low_speed = (batch->speed == USB_SPEED_LOW);
    329         if (!usb_is_allowed(
    330             low_speed, batch->transfer_type, batch->max_packet_size)) {
    331                 usb_log_error("Invalid USB transfer specified %s %d %zu.\n",
    332                     usb_str_speed(batch->speed), batch->transfer_type,
    333                     batch->max_packet_size);
    334                 return ENOTSUP;
    335         }
    336         /* Check available bandwidth */
    337         if (batch->transfer_type == USB_TRANSFER_INTERRUPT ||
    338             batch->transfer_type == USB_TRANSFER_ISOCHRONOUS) {
    339                 int ret =
    340                     bandwidth_use(&instance->bandwidth, batch->target.address,
    341                     batch->target.endpoint, batch->direction);
    342                 if (ret != EOK) {
    343                         usb_log_warning("Failed(%d) to use reserved bw: %s.\n",
    344                             ret, str_error(ret));
    345                 }
    346         }
    347330
    348331        transfer_list_t *list =
     
    398381                        case USB_TRANSFER_INTERRUPT:
    399382                        case USB_TRANSFER_ISOCHRONOUS: {
     383/*
    400384                                int ret = bandwidth_free(&instance->bandwidth,
    401385                                    batch->target.address,
     
    406390                                            "reserved bw: %s.\n", ret,
    407391                                            str_error(ret));
     392*/
    408393                                }
    409394                        default:
     
    529514 * @return True if transaction is allowed by USB specs, false otherwise
    530515 */
     516#if 0
    531517bool usb_is_allowed(
    532518    bool low_speed, usb_transfer_type_t transfer, size_t size)
     
    546532        return false;
    547533}
     534#endif
    548535/**
    549536 * @}
  • uspace/drv/uhci-hcd/hc.h

    r9d06563 ra4e18e1  
    4343#include <usbhc_iface.h>
    4444#include <usb/host/device_keeper.h>
    45 #include <usb/host/bandwidth.h>
     45#include <usb/host/usb_endpoint_manager.h>
    4646
    4747#include "batch.h"
     
    8585typedef struct hc {
    8686        usb_device_keeper_t manager;
    87         bandwidth_t bandwidth;
     87        usb_endpoint_manager_t ep_manager;
    8888
    8989        regs_t *registers;
  • uspace/drv/uhci-hcd/hw_struct/queue_head.h

    r9d06563 ra4e18e1  
    3939
    4040#include "link_pointer.h"
    41 #include "utils/malloc32.h"
    4241
    4342typedef struct queue_head {
  • uspace/drv/uhci-hcd/iface.c

    r9d06563 ra4e18e1  
    3636
    3737#include <usb/debug.h>
     38#include <usb/host/endpoint.h>
    3839
    3940#include "iface.h"
     
    5455        usb_device_keeper_reserve_default_address(&hc->manager, speed);
    5556        return EOK;
     57#if 0
     58        endpoint_t *ep = malloc(sizeof(endpoint_t));
     59        if (ep == NULL)
     60                return ENOMEM;
     61        const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;
     62        endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);
     63        int ret;
     64try_retgister:
     65        ret = usb_endpoint_manager_register_ep(&hc->ep_manager,
     66            USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);
     67        if (ret == EEXISTS) {
     68                async_usleep(1000);
     69                goto try_retgister;
     70        }
     71        if (ret != EOK) {
     72                endpoint_destroy(ep);
     73        }
     74        return ret;
     75#endif
    5676}
    5777/*----------------------------------------------------------------------------*/
     
    6787        assert(hc);
    6888        usb_log_debug("Default address release.\n");
     89//      return usb_endpoint_manager_unregister_ep(&hc->ep_manager,
     90//          USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);
    6991        usb_device_keeper_release_default_address(&hc->manager);
    7092        return EOK;
     
    137159        const usb_speed_t speed =
    138160            usb_device_keeper_get_speed(&hc->manager, address);
    139         size_t size = max_packet_size;
     161        const size_t size =
     162            (transfer_type == USB_TRANSFER_INTERRUPT
     163            || transfer_type == USB_TRANSFER_ISOCHRONOUS) ?
     164            max_packet_size : 0;
     165        int ret;
     166
     167        endpoint_t *ep = malloc(sizeof(endpoint_t));
     168        if (ep == NULL)
     169                return ENOMEM;
     170        ret = endpoint_init(ep, address, endpoint, direction,
     171            transfer_type, speed, max_packet_size);
     172        if (ret != EOK) {
     173                free(ep);
     174                return ret;
     175        }
    140176
    141177        usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",
    142178            address, endpoint, usb_str_transfer_type(transfer_type),
    143179            usb_str_speed(speed), direction, size, max_packet_size, interval);
    144         return bandwidth_reserve(&hc->bandwidth, address, endpoint, direction,
    145             speed, transfer_type, max_packet_size, size, interval);
     180
     181        ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size);
     182        if (ret != EOK) {
     183                endpoint_destroy(ep);
     184        } else {
     185                usb_device_keeper_add_ep(&hc->manager, address, ep);
     186        }
     187        return ret;
    146188}
    147189/*----------------------------------------------------------------------------*/
     
    154196        usb_log_debug("Unregister endpoint %d:%d %d.\n",
    155197            address, endpoint, direction);
    156         return bandwidth_release(&hc->bandwidth, address, endpoint, direction);
     198        return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address,
     199            endpoint, direction);
    157200}
    158201/*----------------------------------------------------------------------------*/
     
    175218        hc_t *hc = fun_to_hc(fun);
    176219        assert(hc);
    177         usb_speed_t speed =
    178             usb_device_keeper_get_speed(&hc->manager, target.address);
    179220
    180221        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
    181222            target.address, target.endpoint, size, max_packet_size);
    182223
     224        size_t res_bw;
     225        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     226            target.address, target.endpoint, USB_DIRECTION_OUT, &res_bw);
     227        if (ep == NULL) {
     228                usb_log_error("Endpoint(%d:%d) not registered for INT OUT.\n",
     229                        target.address, target.endpoint);
     230                return ENOENT;
     231        }
     232        const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
     233            size, ep->max_packet_size);
     234        if (res_bw < bw)
     235        {
     236                usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
     237                    "but only %zu is reserved.\n",
     238                    target.address, target.endpoint, bw, res_bw);
     239                return ENOENT;
     240        }
     241        assert(ep->speed ==
     242            usb_device_keeper_get_speed(&hc->manager, target.address));
     243        assert(ep->max_packet_size == max_packet_size);
     244        assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
     245
    183246        usb_transfer_batch_t *batch =
    184             batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
    185                 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     247            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     248                ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    186249        if (!batch)
    187250                return ENOMEM;
     
    212275        hc_t *hc = fun_to_hc(fun);
    213276        assert(hc);
    214         usb_speed_t speed =
    215             usb_device_keeper_get_speed(&hc->manager, target.address);
     277
    216278        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
    217279            target.address, target.endpoint, size, max_packet_size);
    218280
     281        size_t res_bw;
     282        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     283            target.address, target.endpoint, USB_DIRECTION_IN, &res_bw);
     284        if (ep == NULL) {
     285                usb_log_error("Endpoint(%d:%d) not registered for INT IN.\n",
     286                    target.address, target.endpoint);
     287                return ENOENT;
     288        }
     289        const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
     290            size, ep->max_packet_size);
     291        if (res_bw < bw)
     292        {
     293                usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
     294                    "but only %zu bw is reserved.\n",
     295                    target.address, target.endpoint, bw, res_bw);
     296                return ENOENT;
     297        }
     298
     299        assert(ep->speed ==
     300            usb_device_keeper_get_speed(&hc->manager, target.address));
     301        assert(ep->max_packet_size == max_packet_size);
     302        assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
     303
    219304        usb_transfer_batch_t *batch =
    220             batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size,
    221                 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     305            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     306                ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    222307        if (!batch)
    223308                return ENOMEM;
     
    248333        hc_t *hc = fun_to_hc(fun);
    249334        assert(hc);
    250         usb_speed_t speed =
    251             usb_device_keeper_get_speed(&hc->manager, target.address);
    252335
    253336        usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
    254337            target.address, target.endpoint, size, max_packet_size);
    255338
     339        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     340            target.address, target.endpoint, USB_DIRECTION_OUT, NULL);
     341        if (ep == NULL) {
     342                usb_log_error("Endpoint(%d:%d) not registered for BULK OUT.\n",
     343                        target.address, target.endpoint);
     344                return ENOENT;
     345        }
     346        assert(ep->speed ==
     347            usb_device_keeper_get_speed(&hc->manager, target.address));
     348        assert(ep->max_packet_size == max_packet_size);
     349        assert(ep->transfer_type == USB_TRANSFER_BULK);
     350
    256351        usb_transfer_batch_t *batch =
    257             batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
    258                 data, size, NULL, 0, NULL, callback, arg, &hc->manager);
     352            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     353                ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    259354        if (!batch)
    260355                return ENOMEM;
     
    285380        hc_t *hc = fun_to_hc(fun);
    286381        assert(hc);
    287         usb_speed_t speed =
    288             usb_device_keeper_get_speed(&hc->manager, target.address);
    289382        usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
    290383            target.address, target.endpoint, size, max_packet_size);
    291384
     385        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     386            target.address, target.endpoint, USB_DIRECTION_IN, NULL);
     387        if (ep == NULL) {
     388                usb_log_error("Endpoint(%d:%d) not registered for BULK IN.\n",
     389                        target.address, target.endpoint);
     390                return ENOENT;
     391        }
     392        assert(ep->speed ==
     393            usb_device_keeper_get_speed(&hc->manager, target.address));
     394        assert(ep->max_packet_size == max_packet_size);
     395        assert(ep->transfer_type == USB_TRANSFER_BULK);
     396
    292397        usb_transfer_batch_t *batch =
    293             batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed,
    294                 data, size, NULL, 0, callback, NULL, arg, &hc->manager);
     398            batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
     399                ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    295400        if (!batch)
    296401                return ENOMEM;
     
    328433        usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
    329434            speed, target.address, target.endpoint, size, max_packet_size);
     435        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     436            target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
     437        if (ep == NULL) {
     438                usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
     439                        target.address, target.endpoint);
     440        }
    330441
    331442        if (setup_size != 8)
     
    334445        usb_transfer_batch_t *batch =
    335446            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    336                 data, size, setup_data, setup_size, NULL, callback, arg,
    337                 &hc->manager);
     447                data, size, setup_data, setup_size, NULL, callback, arg, ep);
    338448        if (!batch)
    339449                return ENOMEM;
     
    373483        usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
    374484            speed, target.address, target.endpoint, size, max_packet_size);
     485        endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
     486            target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
     487        if (ep == NULL) {
     488                usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
     489                        target.address, target.endpoint);
     490        }
    375491        usb_transfer_batch_t *batch =
    376492            batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    377                 data, size, setup_data, setup_size, callback, NULL, arg,
    378                 &hc->manager);
     493                data, size, setup_data, setup_size, callback, NULL, arg, ep);
    379494        if (!batch)
    380495                return ENOMEM;
  • uspace/drv/uhci-hcd/transfer_list.h

    r9d06563 ra4e18e1  
    3939#include "batch.h"
    4040#include "hw_struct/queue_head.h"
     41#include "utils/malloc32.h"
    4142
    4243typedef struct transfer_list
  • uspace/drv/uhci-hcd/utils/malloc32.h

    r9d06563 ra4e18e1  
    3636
    3737#include <assert.h>
     38#include <errno.h>
    3839#include <malloc.h>
    3940#include <mem.h>
  • uspace/drv/uhci-rhd/main.c

    r9d06563 ra4e18e1  
    4444
    4545#define NAME "uhci-rhd"
     46
    4647static int hc_get_my_registers(ddf_dev_t *dev,
    4748    uintptr_t *io_reg_address, size_t *io_reg_size);
    48 #if 0
    4949/*----------------------------------------------------------------------------*/
    50 static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
    51 {
    52         assert(fun);
    53         assert(fun->driver_data);
    54         assert(handle);
    55 
    56         *handle = ((uhci_root_hub_t*)fun->driver_data)->hc_handle;
    57 
    58         return EOK;
    59 }
    60 /*----------------------------------------------------------------------------*/
    61 static usb_iface_t uhci_rh_usb_iface = {
    62         .get_hc_handle = usb_iface_get_hc_handle,
    63         .get_address = usb_iface_get_address_hub_impl
    64 };
    65 /*----------------------------------------------------------------------------*/
    66 static ddf_dev_ops_t uhci_rh_ops = {
    67         .interfaces[USB_DEV_IFACE] = &uhci_rh_usb_iface,
    68 };
    69 #endif
    70 /*----------------------------------------------------------------------------*/
    71 /** Initialize a new ddf driver instance of UHCI root hub.
    72  *
    73  * @param[in] device DDF instance of the device to initialize.
    74  * @return Error code.
    75  */
    76 static int uhci_rh_add_device(ddf_dev_t *device)
    77 {
    78         if (!device)
    79                 return ENOTSUP;
    80 
    81         usb_log_debug2("%s called device %d\n", __FUNCTION__, device->handle);
    82 
    83         //device->ops = &uhci_rh_ops;
    84         uintptr_t io_regs = 0;
    85         size_t io_size = 0;
    86 
    87         int ret = hc_get_my_registers(device, &io_regs, &io_size);
    88         if (ret != EOK) {
    89                 usb_log_error("Failed to get registers from parent HC: %s.\n",
    90                     str_error(ret));
    91         }
    92         usb_log_debug("I/O regs at %#X (size %zu).\n", io_regs, io_size);
    93 
    94         uhci_root_hub_t *rh = malloc(sizeof(uhci_root_hub_t));
    95         if (!rh) {
    96                 usb_log_error("Failed to allocate driver instance.\n");
    97                 return ENOMEM;
    98         }
    99 
    100         ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
    101         if (ret != EOK) {
    102                 usb_log_error("Failed to initialize driver instance: %s.\n",
    103                     str_error(ret));
    104                 free(rh);
    105                 return ret;
    106         }
    107 
    108         device->driver_data = rh;
    109         usb_log_info("Controlling root hub `%s' (%llu).\n",
    110             device->name, device->handle);
    111         return EOK;
    112 }
     50static int uhci_rh_add_device(ddf_dev_t *device);
    11351/*----------------------------------------------------------------------------*/
    11452static driver_ops_t uhci_rh_driver_ops = {
     
    13270{
    13371        printf(NAME ": HelenOS UHCI root hub driver.\n");
     72        usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
     73        return ddf_driver_main(&uhci_rh_driver);
     74}
     75/*----------------------------------------------------------------------------*/
     76/** Initialize a new ddf driver instance of UHCI root hub.
     77 *
     78 * @param[in] device DDF instance of the device to initialize.
     79 * @return Error code.
     80 */
     81static int uhci_rh_add_device(ddf_dev_t *device)
     82{
     83        if (!device)
     84                return EINVAL;
    13485
    135         usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
     86        usb_log_debug2("%s called device %d\n", __FUNCTION__, device->handle);
    13687
    137         return ddf_driver_main(&uhci_rh_driver);
     88        uintptr_t io_regs = 0;
     89        size_t io_size = 0;
     90        uhci_root_hub_t *rh = NULL;
     91        int ret = EOK;
     92
     93#define CHECK_RET_FREE_RH_RETURN(ret, message...) \
     94if (ret != EOK) { \
     95        usb_log_error(message); \
     96        if (rh) \
     97                free(rh); \
     98        return ret; \
     99} else (void)0
     100
     101        ret = hc_get_my_registers(device, &io_regs, &io_size);
     102        CHECK_RET_FREE_RH_RETURN(ret,
     103            "Failed(%d) to get registers from HC: %s.\n", ret, str_error(ret));
     104        usb_log_debug("I/O regs at %#x (size %zu).\n", io_regs, io_size);
     105
     106        rh = malloc(sizeof(uhci_root_hub_t));
     107        ret = (rh == NULL) ? ENOMEM : EOK;
     108        CHECK_RET_FREE_RH_RETURN(ret,
     109            "Failed to allocate rh driver instance.\n");
     110
     111        ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
     112        CHECK_RET_FREE_RH_RETURN(ret,
     113            "Failed(%d) to initialize rh driver instance: %s.\n",
     114            ret, str_error(ret));
     115
     116        device->driver_data = rh;
     117        usb_log_info("Controlling root hub '%s' (%llu).\n",
     118            device->name, device->handle);
     119        return EOK;
    138120}
    139121/*----------------------------------------------------------------------------*/
     
    156138        }
    157139
    158         int rc;
    159 
    160140        hw_resource_list_t hw_resources;
    161         rc = hw_res_get_resource_list(parent_phone, &hw_resources);
    162         if (rc != EOK) {
    163                 goto leave;
     141        int ret = hw_res_get_resource_list(parent_phone, &hw_resources);
     142        if (ret != EOK) {
     143                async_hangup(parent_phone);
     144                return ret;
    164145        }
    165146
     
    168149        bool io_found = false;
    169150
    170         size_t i;
    171         for (i = 0; i < hw_resources.count; i++) {
     151        size_t i = 0;
     152        for (; i < hw_resources.count; i++) {
    172153                hw_resource_t *res = &hw_resources.resources[i];
    173                 switch (res->type)
    174                 {
    175                 case IO_RANGE:
    176                         io_address = (uintptr_t) res->res.io_range.address;
     154                if (res->type == IO_RANGE) {
     155                        io_address = res->res.io_range.address;
    177156                        io_size = res->res.io_range.size;
    178157                        io_found = true;
    179 
    180                 default:
    181                         break;
    182158                }
    183159        }
     160        async_hangup(parent_phone);
    184161
    185162        if (!io_found) {
    186                 rc = ENOENT;
    187                 goto leave;
     163                return ENOENT;
    188164        }
    189 
    190165        if (io_reg_address != NULL) {
    191166                *io_reg_address = io_address;
     
    194169                *io_reg_size = io_size;
    195170        }
    196         rc = EOK;
    197 
    198 leave:
    199         async_hangup(parent_phone);
    200         return rc;
     171        return EOK;
    201172}
    202173/**
  • uspace/drv/uhci-rhd/port.c

    r9d06563 ra4e18e1  
    4343#include "port.h"
    4444
     45static int uhci_port_check(void *port);
     46static int uhci_port_reset_enable(int portno, void *arg);
    4547static int uhci_port_new_device(uhci_port_t *port, usb_speed_t speed);
    4648static int uhci_port_remove_device(uhci_port_t *port);
    4749static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
    48 static int uhci_port_check(void *port);
    49 static int uhci_port_reset_enable(int portno, void *arg);
    5050static void uhci_port_print_status(
    5151    uhci_port_t *port, const port_status_t value);
     
    7474        pio_write_16(port->address, value);
    7575}
    76 
    7776/*----------------------------------------------------------------------------*/
    7877/** Initialize UHCI root hub port instance.
     
    259258
    260259        usb_address_t dev_addr;
    261         int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
     260        int ret = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    262261            speed, uhci_port_reset_enable, port->number, port,
    263262            &dev_addr, &port->attached_device, NULL, NULL, NULL);
    264263
    265         if (rc != EOK) {
     264        if (ret != EOK) {
    266265                usb_log_error("%s: Failed(%d) to add device: %s.\n",
    267                     port->id_string, rc, str_error(rc));
     266                    port->id_string, ret, str_error(ret));
    268267                uhci_port_set_enabled(port, false);
    269                 return rc;
     268                return ret;
    270269        }
    271270
     
    287286int uhci_port_remove_device(uhci_port_t *port)
    288287{
    289         usb_log_error("%s: Don't know how to remove device %d.\n",
    290             port->id_string, (unsigned int)port->attached_device);
    291         return EOK;
     288        usb_log_error("%s: Don't know how to remove device %llu.\n",
     289            port->id_string, port->attached_device);
     290        return ENOTSUP;
    292291}
    293292/*----------------------------------------------------------------------------*/
     
    341340            (value & STATUS_CONNECTED_CHANGED) ? " CONNECTED-CHANGE," : "",
    342341            (value & STATUS_CONNECTED) ? " CONNECTED," : "",
    343             (value & STATUS_ALWAYS_ONE) ? " ALWAYS ONE" : " ERROR: NO ALWAYS ONE"
     342            (value & STATUS_ALWAYS_ONE) ? " ALWAYS ONE" : " ERR: NO ALWAYS ONE"
    344343        );
    345344}
  • uspace/drv/uhci-rhd/root_hub.c

    r9d06563 ra4e18e1  
    5151        assert(instance);
    5252        assert(rh);
    53         int ret;
    5453
    5554        /* Allow access to root hub port registers */
    5655        assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT <= size);
    5756        port_status_t *regs;
    58         ret = pio_enable(addr, size, (void**)&regs);
     57        int ret = pio_enable(addr, size, (void**)&regs);
    5958        if (ret < 0) {
    6059                usb_log_error(
     
    8483 *
    8584 * @param[in] instance Root hub structure to use.
    86  * @return Error code.
    8785 */
    88 int uhci_root_hub_fini(uhci_root_hub_t* instance)
     86void uhci_root_hub_fini(uhci_root_hub_t* instance)
    8987{
    9088        assert(instance);
     
    9391                uhci_port_fini(&instance->ports[i]);
    9492        }
    95         return EOK;
    9693}
    9794/*----------------------------------------------------------------------------*/
  • uspace/drv/uhci-rhd/root_hub.h

    r9d06563 ra4e18e1  
    5050  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh);
    5151
    52 int uhci_root_hub_fini(uhci_root_hub_t *instance);
     52void uhci_root_hub_fini(uhci_root_hub_t *instance);
    5353#endif
    5454/**
  • uspace/drv/usbmid/explore.c

    r9d06563 ra4e18e1  
    4848};
    4949
    50 /** Find starting indexes of all interface descriptors in a configuration.
    51  *
    52  * @param config_descriptor Full configuration descriptor.
    53  * @param config_descriptor_size Size of @p config_descriptor in bytes.
    54  * @param interface_positions Array where to store indexes of interfaces.
    55  * @param interface_count Size of @p interface_positions array.
    56  * @return Number of found interfaces.
    57  * @retval (size_t)-1 Error occured.
    58  */
    59 static size_t find_interface_descriptors(uint8_t *config_descriptor,
    60     size_t config_descriptor_size,
    61     size_t *interface_positions, size_t interface_count)
     50/** Tell whether given interface is already in the list.
     51 *
     52 * @param list List of usbmid_interface_t members to be searched.
     53 * @param interface_no Interface number caller is looking for.
     54 * @return Interface @p interface_no is already present in the list.
     55 */
     56static bool interface_in_list(link_t *list, int interface_no)
    6257{
    63         if (interface_count == 0) {
    64                 return (size_t) -1;
    65         }
    66 
     58        link_t *l;
     59        for (l = list->next; l != list; l = l->next) {
     60                usbmid_interface_t *iface
     61                    = list_get_instance(l, usbmid_interface_t, link);
     62                if (iface->interface_no == interface_no) {
     63                        return true;
     64                }
     65        }
     66
     67        return false;
     68}
     69
     70/** Create list of interfaces from configuration descriptor.
     71 *
     72 * @param config_descriptor Configuration descriptor.
     73 * @param config_descriptor_size Size of configuration descriptor in bytes.
     74 * @param list List where to add the interfaces.
     75 */
     76static void create_interfaces(uint8_t *config_descriptor,
     77    size_t config_descriptor_size, link_t *list)
     78{
    6779        usb_dp_parser_data_t data = {
    6880                .data = config_descriptor,
     
    7587        };
    7688
    77         uint8_t *interface = usb_dp_get_nested_descriptor(&parser, &data,
     89        uint8_t *interface_ptr = usb_dp_get_nested_descriptor(&parser, &data,
    7890            data.data);
    79         if (interface == NULL) {
    80                 return (size_t) -1;
    81         }
    82         if (interface[1] != USB_DESCTYPE_INTERFACE) {
    83                 return (size_t) -1;
    84         }
    85 
    86         size_t found_interfaces = 0;
    87         interface_positions[found_interfaces] = interface - config_descriptor;
    88         found_interfaces++;
    89 
    90         while (interface != NULL) {
    91                 interface = usb_dp_get_sibling_descriptor(&parser, &data,
    92                     data.data, interface);
    93                 if ((interface != NULL)
    94                     && (found_interfaces < interface_count)
    95                     && (interface[1] == USB_DESCTYPE_INTERFACE)) {
    96                         interface_positions[found_interfaces]
    97                             = interface - config_descriptor;
    98                         found_interfaces++;
    99                 }
    100         }
    101 
    102         return found_interfaces;
     91        if (interface_ptr == NULL) {
     92                return;
     93        }
     94
     95        do {
     96                if (interface_ptr[1] != USB_DESCTYPE_INTERFACE) {
     97                        goto next_descriptor;
     98                }
     99
     100                usb_standard_interface_descriptor_t *interface
     101                    = (usb_standard_interface_descriptor_t *) interface_ptr;
     102
     103                /* Skip alternate interfaces. */
     104                if (!interface_in_list(list, interface->interface_number)) {
     105                        usbmid_interface_t *iface
     106                            = malloc(sizeof(usbmid_interface_t));
     107                        if (iface == NULL) {
     108                                break;
     109                        }
     110                        link_initialize(&iface->link);
     111                        iface->fun = NULL;
     112                        iface->interface_no = interface->interface_number;
     113                        iface->interface = interface;
     114
     115                        list_append(&iface->link, list);
     116                }
     117
     118                /* TODO: add the alternatives and create match ids from them
     119                 * as well.
     120                 */
     121
     122next_descriptor:
     123                interface_ptr = usb_dp_get_sibling_descriptor(&parser, &data,
     124                    data.data, interface_ptr);
     125
     126        } while (interface_ptr != NULL);
     127
    103128}
    104129
     
    130155            (usb_standard_configuration_descriptor_t *) config_descriptor_raw;
    131156
    132         size_t *interface_descriptors
    133             = malloc(sizeof(size_t) * config_descriptor->interface_count);
    134         if (interface_descriptors == NULL) {
    135                 usb_log_error("Out of memory (wanted %zuB).\n",
    136                     sizeof(size_t) * config_descriptor->interface_count);
    137                 free(config_descriptor_raw);
    138                 return false;
    139         }
    140         size_t interface_descriptors_count
    141             = find_interface_descriptors(
    142             config_descriptor_raw, config_descriptor_size,
    143             interface_descriptors, config_descriptor->interface_count);
    144 
    145         if (interface_descriptors_count == (size_t) -1) {
    146                 usb_log_error("Problem parsing configuration descriptor.\n");
    147                 free(interface_descriptors);
    148                 return false;
    149         }
    150 
    151157        /* Select the first configuration */
    152158        rc = usb_request_set_configuration(&dev->ctrl_pipe,
     
    155161                usb_log_error("Failed to set device configuration: %s.\n",
    156162                    str_error(rc));
    157                 free(interface_descriptors);
    158                 return false;
    159         }
    160 
     163                return false;
     164        }
    161165
    162166        /* Create control function */
     
    164168        if (ctl_fun == NULL) {
    165169                usb_log_error("Failed to create control function.\n");
    166                 free(interface_descriptors);
    167170                return false;
    168171        }
     
    174177                usb_log_error("Failed to bind control function: %s.\n",
    175178                    str_error(rc));
    176                 free(interface_descriptors);
    177                 return false;
    178         }
    179 
    180         /* Spawn interface children */
    181         size_t i;
    182         for (i = 0; i < interface_descriptors_count; i++) {
    183                 usb_standard_interface_descriptor_t *interface
    184                     = (usb_standard_interface_descriptor_t *)
    185                     (config_descriptor_raw + interface_descriptors[i]);
    186                 usb_log_debug2("Interface descriptor at index %zu (type %d).\n",
    187                     interface_descriptors[i], (int) interface->descriptor_type);
     179                return false;
     180        }
     181
     182        /* Create interface children. */
     183        link_t interface_list;
     184        list_initialize(&interface_list);
     185        create_interfaces(config_descriptor_raw, config_descriptor_size,
     186            &interface_list);
     187
     188        link_t *link;
     189        for (link = interface_list.next; link != &interface_list;
     190            link = link->next) {
     191                usbmid_interface_t *iface = list_get_instance(link,
     192                    usbmid_interface_t, link);
     193
    188194                usb_log_info("Creating child for interface %d (%s).\n",
    189                     (int) interface->interface_number,
    190                     usb_str_class(interface->interface_class));
    191                 rc = usbmid_spawn_interface_child(dev, &dev->descriptors.device,
    192                     interface);
     195                    (int) iface->interface_no,
     196                    usb_str_class(iface->interface->interface_class));
     197
     198                rc = usbmid_spawn_interface_child(dev, iface,
     199                    &dev->descriptors.device, iface->interface);
    193200                if (rc != EOK) {
    194201                        usb_log_error("Failed to create interface child: %s.\n",
  • uspace/drv/usbmid/usbmid.c

    r9d06563 ra4e18e1  
    7979};
    8080
    81 /** Create new interface for USB MID device.
    82  *
    83  * @param fun Backing generic DDF device function (representing interface).
    84  * @param iface_no Interface number.
    85  * @return New interface.
    86  * @retval NULL Error occured.
    87  */
    88 usbmid_interface_t *usbmid_interface_create(ddf_fun_t *fun, int iface_no)
    89 {
    90         usbmid_interface_t *iface = malloc(sizeof(usbmid_interface_t));
    91         if (iface == NULL) {
    92                 usb_log_error("Out of memory (wanted %zuB).\n",
    93                     sizeof(usbmid_interface_t));
    94                 return NULL;
    95         }
    96 
    97         iface->fun = fun;
    98         iface->interface_no = iface_no;
    99 
    100         return iface;
    101 }
    102 
    10381
    10482/** Spawn new child device from one interface.
    10583 *
    10684 * @param parent Parent MID device.
     85 * @param iface Interface information.
    10786 * @param device_descriptor Device descriptor.
    10887 * @param interface_descriptor Interface descriptor.
     
    11089 */
    11190int usbmid_spawn_interface_child(usb_device_t *parent,
     91    usbmid_interface_t *iface,
    11292    const usb_standard_device_descriptor_t *device_descriptor,
    11393    const usb_standard_interface_descriptor_t *interface_descriptor)
     
    11595        ddf_fun_t *child = NULL;
    11696        char *child_name = NULL;
    117         usbmid_interface_t *child_as_interface = NULL;
    11897        int rc;
    11998
     
    137116        }
    138117
     118        iface->fun = child;
    139119
    140 
    141         child_as_interface = usbmid_interface_create(child,
    142             (int) interface_descriptor->interface_number);
    143         if (child_as_interface == NULL) {
    144                 rc = ENOMEM;
    145                 goto error_leave;
    146         }
    147 
    148         child->driver_data = child_as_interface;
     120        child->driver_data = iface;
    149121        child->ops = &child_device_ops;
    150122
     
    172144                free(child_name);
    173145        }
    174         if (child_as_interface != NULL) {
    175                 free(child_as_interface);
    176         }
    177146
    178147        return rc;
  • uspace/drv/usbmid/usbmid.h

    r9d06563 ra4e18e1  
    3737#define USBMID_H_
    3838
     39#include <adt/list.h>
    3940#include <ddf/driver.h>
    4041#include <usb/usb.h>
     
    4950        /** Function container. */
    5051        ddf_fun_t *fun;
    51 
     52        /** Interface descriptor. */
     53        usb_standard_interface_descriptor_t *interface;
    5254        /** Interface number. */
    5355        int interface_no;
     56        /** List link. */
     57        link_t link;
    5458} usbmid_interface_t;
    5559
    56 usbmid_interface_t *usbmid_interface_create(ddf_fun_t *, int);
    5760bool usbmid_explore_device(usb_device_t *);
    58 int usbmid_spawn_interface_child(usb_device_t *,
     61int usbmid_spawn_interface_child(usb_device_t *, usbmid_interface_t *,
    5962    const usb_standard_device_descriptor_t *,
    6063    const usb_standard_interface_descriptor_t *);
  • uspace/lib/usb/Makefile

    r9d06563 ra4e18e1  
    5454        src/host/device_keeper.c \
    5555        src/host/batch.c \
    56         src/host/bandwidth.c
     56        src/host/endpoint.c \
     57        src/host/usb_endpoint_manager.c
    5758
    5859include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usb/include/usb/devdrv.h

    r9d06563 ra4e18e1  
    4747} usb_device_descriptors_t;
    4848
     49/** Wrapper for data related to alternate interface setting.
     50 * The pointers will typically point inside configuration descriptor and
     51 * thus you shall not deallocate them.
     52 */
     53typedef struct {
     54        /** Interface descriptor. */
     55        usb_standard_interface_descriptor_t *interface;
     56        /** Pointer to start of descriptor tree bound with this interface. */
     57        uint8_t *nested_descriptors;
     58        /** Size of data pointed by nested_descriptors in bytes. */
     59        size_t nested_descriptors_size;
     60} usb_alternate_interface_descriptors_t;
     61
     62/** Alternate interface settings. */
     63typedef struct {
     64        /** Array of alternate interfaces descriptions. */
     65        usb_alternate_interface_descriptors_t *alternatives;
     66        /** Size of @c alternatives array. */
     67        size_t alternative_count;
     68        /** Index of currently selected one. */
     69        size_t current;
     70} usb_alternate_interfaces_t;
     71
    4972/** USB device structure. */
    5073typedef struct {
     
    5679         */
    5780        usb_endpoint_mapping_t *pipes;
     81        /** Number of other endpoint pipes. */
     82        size_t pipes_count;
    5883        /** Current interface.
    5984         * Usually, drivers operate on single interface only.
     
    6186         */
    6287        int interface_no;
     88
     89        /** Alternative interfaces.
     90         * Set to NULL when the driver controls whole device
     91         * (i.e. more (or any) interfaces).
     92         */
     93        usb_alternate_interfaces_t *alternate_interfaces;
    6394
    6495        /** Some useful descriptors. */
     
    92123         */
    93124        const char *name;
    94         /** Expected endpoints description, excluding default control endpoint.
     125        /** Expected endpoints description.
     126         * This description shall exclude default control endpoint (pipe zero)
     127         * and must be NULL terminated.
     128         * When only control endpoint is expected, you may set NULL directly
     129         * without creating one item array containing NULL.
    95130         *
    96          * It MUST be of size expected_enpoints_count(excluding default ctrl) + 1
    97          * where the last record MUST BE NULL, otherwise catastrophic things may
    98          * happen.
     131         * When the driver expect single interrupt in endpoint,
     132         * the initialization may look like this:
     133\code
     134static usb_endpoint_description_t poll_endpoint_description = {
     135        .transfer_type = USB_TRANSFER_INTERRUPT,
     136        .direction = USB_DIRECTION_IN,
     137        .interface_class = USB_CLASS_HUB,
     138        .interface_subclass = 0,
     139        .interface_protocol = 0,
     140        .flags = 0
     141};
     142
     143static usb_endpoint_description_t *hub_endpoints[] = {
     144        &poll_endpoint_description,
     145        NULL
     146};
     147
     148static usb_driver_t hub_driver = {
     149        .endpoints = hub_endpoints,
     150        ...
     151};
     152\endcode
    99153         */
    100154        usb_endpoint_description_t **endpoints;
     
    105159int usb_driver_main(usb_driver_t *);
    106160
     161int usb_device_select_interface(usb_device_t *, uint8_t,
     162    usb_endpoint_description_t **);
     163
    107164typedef bool (*usb_polling_callback_t)(usb_device_t *,
    108165    uint8_t *, size_t, void *);
    109166typedef void (*usb_polling_terminted_callback_t)(usb_device_t *, bool, void *);
    110 
    111167
    112168int usb_device_auto_poll(usb_device_t *, size_t,
  • uspace/lib/usb/include/usb/host/batch.h

    r9d06563 ra4e18e1  
    3939#include <usbhc_iface.h>
    4040#include <usb/usb.h>
     41#include <usb/host/endpoint.h>
    4142
    4243typedef struct usb_transfer_batch usb_transfer_batch_t;
     
    6061        ddf_fun_t *fun;
    6162        void *arg;
     63        endpoint_t *ep;
    6264        void *private_data;
    6365};
     
    7880    void *arg,
    7981    ddf_fun_t *fun,
     82                endpoint_t *ep,
    8083    void *private_data
    8184);
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r9d06563 ra4e18e1  
    4040#ifndef LIBUSB_HOST_DEVICE_KEEPER_H
    4141#define LIBUSB_HOST_DEVICE_KEEPER_H
     42
     43#include <adt/list.h>
    4244#include <devman.h>
    4345#include <fibril_synch.h>
    4446#include <usb/usb.h>
     47#include <usb/host/endpoint.h>
    4548
    4649/** Number of USB address for array dimensions. */
     
    5154        usb_speed_t speed;
    5255        bool occupied;
     56        link_t endpoints;
    5357        uint16_t control_used;
    54         uint16_t toggle_status[2];
    5558        devman_handle_t handle;
    5659};
     
    6871void usb_device_keeper_init(usb_device_keeper_t *instance);
    6972
    70 void usb_device_keeper_reserve_default_address(usb_device_keeper_t *instance,
    71     usb_speed_t speed);
     73void usb_device_keeper_add_ep(
     74    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);
     75
     76void usb_device_keeper_reserve_default_address(
     77    usb_device_keeper_t *instance, usb_speed_t speed);
    7278
    7379void usb_device_keeper_release_default_address(usb_device_keeper_t *instance);
    7480
    7581void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance,
    76     usb_target_t target,
    77     const uint8_t *setup_data);
    78 
    79 int usb_device_keeper_get_toggle(usb_device_keeper_t *instance,
    80     usb_target_t target, usb_direction_t direction);
    81 
    82 int usb_device_keeper_set_toggle(usb_device_keeper_t *instance,
    83     usb_target_t target, usb_direction_t direction, bool toggle);
     82    usb_target_t target, const uint8_t *setup_data);
    8483
    8584usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance,
  • uspace/lib/usb/include/usb/pipes.h

    r9d06563 ra4e18e1  
    107107        /** Interface number the endpoint must belong to (-1 for any). */
    108108        int interface_no;
     109        /** Alternate interface setting to choose. */
     110        int interface_setting;
    109111        /** Found descriptor fitting the description. */
    110112        usb_standard_endpoint_descriptor_t *descriptor;
  • uspace/lib/usb/src/devdrv.c

    r9d06563 ra4e18e1  
    3636#include <usb/request.h>
    3737#include <usb/debug.h>
     38#include <usb/dp.h>
    3839#include <errno.h>
    3940#include <str_error.h>
     
    8687 * @return Number of pipes (excluding default control pipe).
    8788 */
    88 static size_t count_other_pipes(usb_driver_t *drv)
     89static size_t count_other_pipes(usb_endpoint_description_t **endpoints)
    8990{
    9091        size_t count = 0;
    91         if (drv->endpoints == NULL) {
     92        if (endpoints == NULL) {
    9293                return 0;
    9394        }
    9495
    95         while (drv->endpoints[count] != NULL) {
     96        while (endpoints[count] != NULL) {
    9697                count++;
    9798        }
     
    106107 * @return Error code.
    107108 */
    108 static int initialize_other_pipes(usb_driver_t *drv, usb_device_t *dev)
     109static int initialize_other_pipes(usb_endpoint_description_t **endpoints,
     110    usb_device_t *dev)
    109111{
    110112        int rc;
    111         dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
    112 
    113         size_t pipe_count = count_other_pipes(drv);
     113
     114        size_t pipe_count = count_other_pipes(endpoints);
     115        if (pipe_count == 0) {
     116                return EOK;
     117        }
     118
    114119        dev->pipes = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
    115120        if (dev->pipes == NULL) {
     
    133138                }
    134139
    135                 dev->pipes[i].description = drv->endpoints[i];
     140                dev->pipes[i].description = endpoints[i];
    136141                dev->pipes[i].interface_no = dev->interface_no;
     142                dev->pipes[i].interface_setting = 0;
    137143        }
    138144
     
    178184        usb_hc_connection_close(&hc_conn);
    179185
     186        dev->pipes_count = pipe_count;
     187
    180188        return EOK;
    181189
     
    227235        }
    228236
     237        /* Get our interface. */
     238        dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
     239
    229240        /*
    230241         * For further actions, we need open session on default control pipe.
     
    257268
    258269        if (driver->endpoints != NULL) {
    259                 rc = initialize_other_pipes(driver, dev);
     270                rc = initialize_other_pipes(driver->endpoints, dev);
    260271        }
    261272
     
    271282
    272283        return rc;
     284}
     285
     286/** Count number of alternate settings of a interface.
     287 *
     288 * @param config_descr Full configuration descriptor.
     289 * @param config_descr_size Size of @p config_descr in bytes.
     290 * @param interface_no Interface number.
     291 * @return Number of alternate interfaces for @p interface_no interface.
     292 */
     293static size_t count_alternate_interfaces(uint8_t *config_descr,
     294    size_t config_descr_size, int interface_no)
     295{
     296        assert(config_descr != NULL);
     297        usb_dp_parser_t dp_parser = {
     298                .nesting = usb_dp_standard_descriptor_nesting
     299        };
     300        usb_dp_parser_data_t dp_data = {
     301                .data = config_descr,
     302                .size = config_descr_size,
     303                .arg = NULL
     304        };
     305
     306        size_t alternate_count = 0;
     307
     308        uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
     309            &dp_data, config_descr);
     310        while (iface_ptr != NULL) {
     311                usb_standard_interface_descriptor_t *iface
     312                    = (usb_standard_interface_descriptor_t *) iface_ptr;
     313                if (iface->descriptor_type == USB_DESCTYPE_INTERFACE) {
     314                        if (iface->interface_number == interface_no) {
     315                                alternate_count++;
     316                        }
     317                }
     318                iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
     319                    config_descr, iface_ptr);
     320        }
     321
     322        return alternate_count;
     323}
     324
     325/** Initialize structures related to alternate interfaces.
     326 *
     327 * @param dev Device where alternate settings shall be initialized.
     328 * @return Error code.
     329 */
     330static int initialize_alternate_interfaces(usb_device_t *dev)
     331{
     332        if (dev->interface_no < 0) {
     333                dev->alternate_interfaces = NULL;
     334                return EOK;
     335        }
     336
     337        usb_alternate_interfaces_t *alternates
     338            = malloc(sizeof(usb_alternate_interfaces_t));
     339
     340        if (alternates == NULL) {
     341                return ENOMEM;
     342        }
     343
     344        alternates->alternative_count
     345            = count_alternate_interfaces(dev->descriptors.configuration,
     346            dev->descriptors.configuration_size, dev->interface_no);
     347
     348        if (alternates->alternative_count == 0) {
     349                free(alternates);
     350                return ENOENT;
     351        }
     352
     353        alternates->alternatives = malloc(alternates->alternative_count
     354            * sizeof(usb_alternate_interface_descriptors_t));
     355        if (alternates->alternatives == NULL) {
     356                free(alternates);
     357                return ENOMEM;
     358        }
     359
     360        alternates->current = 0;
     361
     362        usb_dp_parser_t dp_parser = {
     363                .nesting = usb_dp_standard_descriptor_nesting
     364        };
     365        usb_dp_parser_data_t dp_data = {
     366                .data = dev->descriptors.configuration,
     367                .size = dev->descriptors.configuration_size,
     368                .arg = NULL
     369        };
     370
     371        usb_alternate_interface_descriptors_t *cur_alt_iface
     372            = &alternates->alternatives[0];
     373
     374        uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
     375            &dp_data, dp_data.data);
     376        while (iface_ptr != NULL) {
     377                usb_standard_interface_descriptor_t *iface
     378                    = (usb_standard_interface_descriptor_t *) iface_ptr;
     379                if ((iface->descriptor_type != USB_DESCTYPE_INTERFACE)
     380                    || (iface->interface_number != dev->interface_no)) {
     381                        iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser,
     382                            &dp_data,
     383                            dp_data.data, iface_ptr);
     384                        continue;
     385                }
     386
     387                cur_alt_iface->interface = iface;
     388                cur_alt_iface->nested_descriptors = iface_ptr + sizeof(*iface);
     389
     390                /* Find next interface to count size of nested descriptors. */
     391                iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
     392                    dp_data.data, iface_ptr);
     393                if (iface_ptr == NULL) {
     394                        uint8_t *next = dp_data.data + dp_data.size;
     395                        cur_alt_iface->nested_descriptors_size
     396                            = next - cur_alt_iface->nested_descriptors;
     397                } else {
     398                        cur_alt_iface->nested_descriptors_size
     399                            = iface_ptr - cur_alt_iface->nested_descriptors;
     400                }
     401
     402                cur_alt_iface++;
     403        }
     404
     405        dev->alternate_interfaces = alternates;
     406
     407        return EOK;
    273408}
    274409
     
    301436        dev->descriptors.configuration = NULL;
    302437
     438        dev->pipes_count = 0;
     439        dev->pipes = NULL;
     440
    303441        rc = initialize_pipes(dev);
    304442        if (rc != EOK) {
     
    307445        }
    308446
     447        (void) initialize_alternate_interfaces(dev);
     448
    309449        return driver->ops->add_device(dev);
     450}
     451
     452/** Destroy existing pipes of a USB device.
     453 *
     454 * @param dev Device where to destroy the pipes.
     455 * @return Error code.
     456 */
     457static int destroy_current_pipes(usb_device_t *dev)
     458{
     459        size_t i;
     460        int rc;
     461
     462        /* TODO: this shall be done under some device mutex. */
     463
     464        /* First check that no session is opened. */
     465        for (i = 0; i < dev->pipes_count; i++) {
     466                if (usb_pipe_is_session_started(dev->pipes[i].pipe)) {
     467                        return EBUSY;
     468                }
     469        }
     470
     471        /* Prepare connection to HC. */
     472        usb_hc_connection_t hc_conn;
     473        rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev);
     474        if (rc != EOK) {
     475                return rc;
     476        }
     477        rc = usb_hc_connection_open(&hc_conn);
     478        if (rc != EOK) {
     479                return rc;
     480        }
     481
     482        /* Destroy the pipes. */
     483        for (i = 0; i < dev->pipes_count; i++) {
     484                usb_pipe_unregister(dev->pipes[i].pipe, &hc_conn);
     485                free(dev->pipes[i].pipe);
     486        }
     487
     488        usb_hc_connection_close(&hc_conn);
     489
     490        free(dev->pipes);
     491        dev->pipes = NULL;
     492        dev->pipes_count = 0;
     493
     494        return EOK;
     495}
     496
     497/** Change interface setting of a device.
     498 * This function selects new alternate setting of an interface by issuing
     499 * proper USB command to the device and also creates new USB pipes
     500 * under @c dev->pipes.
     501 *
     502 * @warning This function is intended for drivers working at interface level.
     503 * For drivers controlling the whole device, you need to change interface
     504 * manually using usb_request_set_interface() and creating new pipes
     505 * with usb_pipe_initialize_from_configuration().
     506 *
     507 * @param dev USB device.
     508 * @param alternate_setting Alternate setting to choose.
     509 * @param endpoints New endpoint descriptions.
     510 * @return Error code.
     511 */
     512int usb_device_select_interface(usb_device_t *dev, uint8_t alternate_setting,
     513    usb_endpoint_description_t **endpoints)
     514{
     515        if (dev->interface_no < 0) {
     516                return EINVAL;
     517        }
     518
     519        int rc;
     520
     521        /* TODO: more transactional behavior. */
     522
     523        /* Destroy existing pipes. */
     524        rc = destroy_current_pipes(dev);
     525        if (rc != EOK) {
     526                return rc;
     527        }
     528
     529        /* Change the interface itself. */
     530        rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
     531            alternate_setting);
     532        if (rc != EOK) {
     533                return rc;
     534        }
     535
     536        /* Create new pipes. */
     537        rc = initialize_other_pipes(endpoints, dev);
     538
     539        return rc;
    310540}
    311541
  • uspace/lib/usb/src/host/batch.c

    r9d06563 ra4e18e1  
    5454    void *arg,
    5555    ddf_fun_t *fun,
     56                endpoint_t *ep,
    5657    void *private_data
    5758    )
     
    7778        instance->next_step = NULL;
    7879        instance->error = EOK;
    79 
     80        instance->ep = ep;
    8081}
    8182/*----------------------------------------------------------------------------*/
  • uspace/lib/usb/src/host/device_keeper.c

    r9d06563 ra4e18e1  
    5656                instance->devices[i].control_used = 0;
    5757                instance->devices[i].handle = 0;
    58                 instance->devices[i].toggle_status[0] = 0;
    59                 instance->devices[i].toggle_status[1] = 0;
    60         }
     58                list_initialize(&instance->devices[i].endpoints);
     59        }
     60}
     61/*----------------------------------------------------------------------------*/
     62void usb_device_keeper_add_ep(
     63    usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)
     64{
     65        assert(instance);
     66        fibril_mutex_lock(&instance->guard);
     67        assert(instance->devices[address].occupied);
     68        list_append(&ep->same_device_eps, &instance->devices[address].endpoints);
     69        fibril_mutex_unlock(&instance->guard);
    6170}
    6271/*----------------------------------------------------------------------------*/
     
    6675 * @param[in] speed Speed of the device requesting default address.
    6776 */
    68 void usb_device_keeper_reserve_default_address(usb_device_keeper_t *instance,
    69     usb_speed_t speed)
     77void usb_device_keeper_reserve_default_address(
     78    usb_device_keeper_t *instance, usb_speed_t speed)
    7079{
    7180        assert(instance);
     
    101110 * Really ugly one.
    102111 */
    103 void usb_device_keeper_reset_if_need(usb_device_keeper_t *instance,
    104     usb_target_t target, const uint8_t *data)
     112void usb_device_keeper_reset_if_need(
     113    usb_device_keeper_t *instance, usb_target_t target, const uint8_t *data)
    105114{
    106115        assert(instance);
     
    119128                /* recipient is endpoint, value is zero (ENDPOINT_STALL) */
    120129                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     130                        link_t *current =
     131                            instance->devices[target.address].endpoints.next;
     132                        while (current !=
     133                           &instance->devices[target.address].endpoints)
     134                        {
    121135                        /* endpoint number is < 16, thus first byte is enough */
    122                         instance->devices[target.address].toggle_status[0] &=
    123                             ~(1 << data[4]);
    124                         instance->devices[target.address].toggle_status[1] &=
    125                             ~(1 << data[4]);
     136                                endpoint_toggle_reset_filtered(
     137                                    current, data[4]);
     138                                current = current->next;
     139                        }
    126140                }
    127141        break;
     
    131145                /* target must be device */
    132146                if ((data[0] & 0xf) == 0) {
    133                         instance->devices[target.address].toggle_status[0] = 0;
    134                         instance->devices[target.address].toggle_status[1] = 0;
     147                        link_t *current =
     148                            instance->devices[target.address].endpoints.next;
     149                        while (current !=
     150                           &instance->devices[target.address].endpoints)
     151                        {
     152                                endpoint_toggle_reset(current);
     153                                current = current->next;
     154                        }
    135155                }
    136156        break;
    137157        }
    138158        fibril_mutex_unlock(&instance->guard);
    139 }
    140 /*----------------------------------------------------------------------------*/
    141 /** Get current value of endpoint toggle.
    142  *
    143  * @param[in] instance Device keeper structure to use.
    144  * @param[in] target Device and endpoint used.
    145  * @return Error code
    146  */
    147 int usb_device_keeper_get_toggle(usb_device_keeper_t *instance,
    148     usb_target_t target, usb_direction_t direction)
    149 {
    150         assert(instance);
    151         /* only control pipes are bi-directional and those do not need toggle */
    152         if (direction == USB_DIRECTION_BOTH)
    153                 return ENOENT;
    154         int ret;
    155         fibril_mutex_lock(&instance->guard);
    156         if (target.endpoint > 15 || target.endpoint < 0
    157             || target.address >= USB_ADDRESS_COUNT || target.address < 0
    158             || !instance->devices[target.address].occupied) {
    159                 usb_log_error("Invalid data when asking for toggle value.\n");
    160                 ret = EINVAL;
    161         } else {
    162                 ret = (instance->devices[target.address].toggle_status[direction]
    163                         >> target.endpoint) & 1;
    164         }
    165         fibril_mutex_unlock(&instance->guard);
    166         return ret;
    167 }
    168 /*----------------------------------------------------------------------------*/
    169 /** Set current value of endpoint toggle.
    170  *
    171  * @param[in] instance Device keeper structure to use.
    172  * @param[in] target Device and endpoint used.
    173  * @param[in] toggle Toggle value.
    174  * @return Error code.
    175  */
    176 int usb_device_keeper_set_toggle(usb_device_keeper_t *instance,
    177     usb_target_t target, usb_direction_t direction, bool toggle)
    178 {
    179         assert(instance);
    180         /* only control pipes are bi-directional and those do not need toggle */
    181         if (direction == USB_DIRECTION_BOTH)
    182                 return ENOENT;
    183         int ret;
    184         fibril_mutex_lock(&instance->guard);
    185         if (target.endpoint > 15 || target.endpoint < 0
    186             || target.address >= USB_ADDRESS_COUNT || target.address < 0
    187             || !instance->devices[target.address].occupied) {
    188                 usb_log_error("Invalid data when setting toggle value.\n");
    189                 ret = EINVAL;
    190         } else {
    191                 if (toggle) {
    192                         instance->devices[target.address].toggle_status[direction]
    193                             |= (1 << target.endpoint);
    194                 } else {
    195                         instance->devices[target.address].toggle_status[direction]
    196                             &= ~(1 << target.endpoint);
    197                 }
    198                 ret = EOK;
    199         }
    200         fibril_mutex_unlock(&instance->guard);
    201         return ret;
    202159}
    203160/*----------------------------------------------------------------------------*/
     
    208165 * @return Free address, or error code.
    209166 */
    210 usb_address_t device_keeper_get_free_address(usb_device_keeper_t *instance,
    211     usb_speed_t speed)
     167usb_address_t device_keeper_get_free_address(
     168    usb_device_keeper_t *instance, usb_speed_t speed)
    212169{
    213170        assert(instance);
     
    229186        instance->devices[new_address].occupied = true;
    230187        instance->devices[new_address].speed = speed;
    231         instance->devices[new_address].toggle_status[0] = 0;
    232         instance->devices[new_address].toggle_status[1] = 0;
    233188        instance->last_address = new_address;
    234189        fibril_mutex_unlock(&instance->guard);
     
    259214 * @param[in] address Device address
    260215 */
    261 void usb_device_keeper_release(usb_device_keeper_t *instance,
    262     usb_address_t address)
     216void usb_device_keeper_release(
     217    usb_device_keeper_t *instance, usb_address_t address)
    263218{
    264219        assert(instance);
     
    278233 * @return USB Address, or error code.
    279234 */
    280 usb_address_t usb_device_keeper_find(usb_device_keeper_t *instance,
    281     devman_handle_t handle)
     235usb_address_t usb_device_keeper_find(
     236    usb_device_keeper_t *instance, devman_handle_t handle)
    282237{
    283238        assert(instance);
     
    301256 * @return USB speed.
    302257 */
    303 usb_speed_t usb_device_keeper_get_speed(usb_device_keeper_t *instance,
    304     usb_address_t address)
     258usb_speed_t usb_device_keeper_get_speed(
     259    usb_device_keeper_t *instance, usb_address_t address)
    305260{
    306261        assert(instance);
     
    310265}
    311266/*----------------------------------------------------------------------------*/
    312 void usb_device_keeper_use_control(usb_device_keeper_t *instance,
    313     usb_target_t target)
     267void usb_device_keeper_use_control(
     268    usb_device_keeper_t *instance, usb_target_t target)
    314269{
    315270        assert(instance);
     
    323278}
    324279/*----------------------------------------------------------------------------*/
    325 void usb_device_keeper_release_control(usb_device_keeper_t *instance,
    326     usb_target_t target)
     280void usb_device_keeper_release_control(
     281    usb_device_keeper_t *instance, usb_target_t target)
    327282{
    328283        assert(instance);
  • uspace/lib/usb/src/hub.c

    r9d06563 ra4e18e1  
    142142            DEV_IFACE_ID(USBHC_DEV_IFACE),
    143143            IPC_M_USBHC_RELEASE_ADDRESS, address);
     144}
     145
     146static void unregister_control_endpoint_on_default_address(
     147    usb_hc_connection_t *connection)
     148{
     149        usb_device_connection_t dev_conn;
     150        int rc = usb_device_connection_initialize_on_default_address(&dev_conn,
     151            connection);
     152        if (rc != EOK) {
     153                return;
     154        }
     155
     156        usb_pipe_t ctrl_pipe;
     157        rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
     158        if (rc != EOK) {
     159                return;
     160        }
     161
     162        usb_pipe_unregister(&ctrl_pipe, connection);
    144163}
    145164
     
    235254                goto leave_release_default_address;
    236255        }
     256
     257        /* Before sending any traffic, we need to register this
     258         * endpoint.
     259         */
     260        rc = usb_pipe_register(&ctrl_pipe, 0, connection);
     261        if (rc != EOK) {
     262                rc = EREFUSED;
     263                goto leave_release_default_address;
     264        }
    237265        rc = usb_pipe_probe_default_control(&ctrl_pipe);
    238266        if (rc != EOK) {
     
    244272        if (rc != EOK) {
    245273                rc = ENOTCONN;
    246                 goto leave_release_default_address;
     274                goto leave_unregister_endpoint;
    247275        }
    248276
     
    256284
    257285        /*
     286         * Register the control endpoint for the new device.
     287         */
     288        rc = usb_pipe_register(&ctrl_pipe, 0, connection);
     289        if (rc != EOK) {
     290                rc = EREFUSED;
     291                goto leave_unregister_endpoint;
     292        }
     293
     294        /*
     295         * Release the original endpoint.
     296         */
     297        unregister_control_endpoint_on_default_address(connection);
     298
     299        /*
    258300         * Once the address is changed, we can return the default address.
    259301         */
    260302        usb_hc_release_default_address(connection);
     303
    261304
    262305        /*
     
    273316        }
    274317
     318
     319
    275320        /*
    276321         * And now inform the host controller about the handle.
     
    308353        usb_pipe_end_session(&ctrl_pipe);
    309354
     355leave_unregister_endpoint:
     356        usb_pipe_unregister(&ctrl_pipe, connection);
     357
    310358leave_release_default_address:
    311359        usb_hc_release_default_address(connection);
  • uspace/lib/usb/src/pipesinit.c

    r9d06563 ra4e18e1  
    121121    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    122122    usb_endpoint_description_t *found_endpoint,
    123     int interface_number)
     123    int interface_number, int interface_setting)
    124124{
    125125        while (mapping_count > 0) {
     
    127127                    || (mapping->interface_no == interface_number);
    128128
     129                bool interface_setting_fits = (mapping->interface_setting < 0)
     130                    || (mapping->interface_setting == interface_setting);
     131
    129132                bool endpoint_descriptions_fits = endpoint_fits_description(
    130133                    mapping->description, found_endpoint);
    131134
    132                 if (interface_number_fits && endpoint_descriptions_fits) {
     135                if (interface_number_fits
     136                    && interface_setting_fits
     137                    && endpoint_descriptions_fits) {
    133138                        return mapping;
    134139                }
     
    181186         */
    182187        usb_endpoint_mapping_t *ep_mapping = find_endpoint_mapping(mapping,
    183             mapping_count, &description, interface->interface_number);
     188            mapping_count, &description,
     189            interface->interface_number, interface->alternate_setting);
    184190        if (ep_mapping == NULL) {
    185191                return ENOENT;
  • uspace/srv/hw/irc/apic/apic.c

    r9d06563 ra4e18e1  
    8787                        async_answer_0(callid, EOK);
    8888                        break;
     89                case IPC_M_PHONE_HUNGUP:
     90                        /* The other side has hung up. */
     91                        async_answer_0(callid, EOK);
     92                        return;
    8993                default:
    9094                        async_answer_0(callid, EINVAL);
  • uspace/srv/hw/irc/i8259/i8259.c

    r9d06563 ra4e18e1  
    121121                        async_answer_0(callid, EOK);
    122122                        break;
     123                case IPC_M_PHONE_HUNGUP:
     124                        /* The other side has hung up. */
     125                        async_answer_0(callid, EOK);
     126                        return;
    123127                default:
    124128                        async_answer_0(callid, EINVAL);
Note: See TracChangeset for help on using the changeset viewer.