Changes in / [889e8e3:9a2923d] in mainline


Ignore:
Files:
19 added
20 deleted
19 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/amd64/Makefile.inc

    r889e8e3 r9a2923d  
    4949        usbflbk \
    5050        usbhub \
    51         usbhid \
     51        usbkbd \
    5252        usbmid \
    5353        usbmouse \
  • kernel/generic/src/mm/as.c

    r889e8e3 r9a2923d  
    19491949sysarg_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
    19501950{
    1951         if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
     1951        if (as_area_create(AS, flags, size, address,
    19521952            AS_AREA_ATTR_NONE, &anon_backend, NULL))
    19531953                return (sysarg_t) address;
  • uspace/Makefile

    r889e8e3 r9a2923d  
    122122                drv/uhci-rhd \
    123123                drv/usbflbk \
    124                 drv/usbhid \
     124                drv/usbkbd \
    125125                drv/usbhub \
    126126                drv/usbmid \
     
    142142                drv/uhci-rhd \
    143143                drv/usbflbk \
    144                 drv/usbhid \
     144                drv/usbkbd \
    145145                drv/usbhub \
    146146                drv/usbmid \
  • uspace/drv/ohci/batch.c

    r889e8e3 r9a2923d  
    118118        instance->next_step = batch_call_in_and_dispose;
    119119        /* TODO: implement */
    120         usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     120        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    121121}
    122122/*----------------------------------------------------------------------------*/
  • uspace/drv/ohci/root_hub.c

    r889e8e3 r9a2923d  
    3939
    4040#include "root_hub.h"
     41#include "usb/classes/classes.h"
     42#include <usb/request.h>
     43#include <usb/classes/hub.h>
     44
    4145
    4246/** Root hub initialization
     
    5054        instance->device = dev;
    5155
     56
    5257        usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff);
    5358
     59        //start generic usb hub driver
     60       
    5461        /* TODO: implement */
    5562        return EOK;
    5663}
    5764/*----------------------------------------------------------------------------*/
     65
     66
     67static int process_get_port_status_request(rh_t *instance, uint16_t port,
     68                usb_transfer_batch_t * request){
     69        if(port<1 || port>instance->port_count)
     70                return EINVAL;
     71        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     72        request->transfered_size = 4;
     73        uint32_buffer[0] = instance->registers->rh_port_status[port -1];
     74        return EOK;
     75}
     76
     77static int process_get_hub_status_request(rh_t *instance,
     78                usb_transfer_batch_t * request){
     79        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     80        //bits, 0,1,16,17
     81        request->transfered_size = 4;
     82        uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
     83        uint32_buffer[0] = mask & instance->registers->rh_status;
     84        return EOK;
     85
     86}
     87
     88static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,
     89                size_t * out_size) {
     90        //base size
     91        size_t size = 7;
     92        //variable size according to port count
     93        size_t var_size = instance->port_count / 8 +
     94                        ((instance->port_count % 8 > 0) ? 1 : 0);
     95        size += 2 * var_size;
     96        uint8_t * result = (uint8_t*) malloc(size);
     97        bzero(result,size);
     98        //size
     99        result[0] = size;
     100        //descriptor type
     101        result[1] = USB_DESCTYPE_HUB;
     102        result[2] = instance->port_count;
     103        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
     104        result[3] =
     105                        ((hub_desc_reg >> 8) %2) +
     106                        (((hub_desc_reg >> 9) %2) << 1) +
     107                        (((hub_desc_reg >> 10) %2) << 2) +
     108                        (((hub_desc_reg >> 11) %2) << 3) +
     109                        (((hub_desc_reg >> 12) %2) << 4);
     110        result[4] = 0;
     111        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
     112        result[6] = 50;
     113
     114        int port;
     115        for (port = 1; port <= instance->port_count; ++port) {
     116                result[7 + port/8] +=
     117                                ((instance->registers->rh_desc_b >> port)%2) << (port%8);
     118        }
     119        size_t i;
     120        for (i = 0; i < var_size; ++i) {
     121                result[7 + var_size + i] = 255;
     122        }
     123        (*out_result) = result;
     124        (*out_size) = size;
     125}
     126
     127
     128static int process_get_status_request(rh_t *instance,
     129                usb_transfer_batch_t * request)
     130{
     131        size_t buffer_size = request->buffer_size;
     132        usb_device_request_setup_packet_t * request_packet =
     133                        (usb_device_request_setup_packet_t*)
     134                        request->setup_buffer;
     135
     136        usb_hub_bm_request_type_t request_type = request_packet->request_type;
     137        if(buffer_size<4/*request_packet->length*/){///\TODO
     138                usb_log_warning("requested more data than buffer size\n");
     139                return EINVAL;
     140        }
     141
     142        if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
     143                return process_get_hub_status_request(instance, request);
     144        if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
     145                return process_get_port_status_request(instance, request_packet->index,
     146                                request);
     147        return ENOTSUP;
     148}
     149
     150static void create_interrupt_mask(rh_t *instance, void ** buffer,
     151                size_t * buffer_size){
     152        int bit_count = instance->port_count + 1;
     153        (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;
     154        (*buffer) = malloc(*buffer_size);
     155        uint8_t * bitmap = (uint8_t*)(*buffer);
     156        uint32_t mask = (1<<16) + (1<<17);
     157        bzero(bitmap,(*buffer_size));
     158        if(instance->registers->rh_status & mask){
     159                bitmap[0] = 1;
     160        }
     161        int port;
     162        mask = 0;
     163        int i;
     164        for(i=16;i<=20;++i)
     165                mask += 1<<i;
     166        for(port = 1; port<=instance->port_count;++port){
     167                if(mask & instance->registers->rh_port_status[port-1]){
     168                        bitmap[(port+1)/8] += 1<<(port%8);
     169                }
     170        }
     171}
     172
     173
     174static int process_get_descriptor_request(rh_t *instance,
     175                usb_transfer_batch_t *request){
     176        /// \TODO
     177        usb_device_request_setup_packet_t * setup_request =
     178                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     179        size_t size;
     180        void * result_descriptor;
     181        uint16_t setup_request_value = setup_request->value_high;
     182                        //(setup_request->value_low << 8);
     183        if(setup_request_value == USB_DESCTYPE_HUB){
     184                usb_log_debug("USB_DESCTYPE_HUB\n");
     185                //create hub descriptor
     186                uint8_t * descriptor;
     187                usb_create_serialized_hub_descriptor(instance,
     188                                &descriptor, &size);
     189                result_descriptor = descriptor;
     190        }else if(setup_request_value == USB_DESCTYPE_DEVICE){
     191                //create std device descriptor
     192                usb_log_debug("USB_DESCTYPE_DEVICE\n");
     193                usb_standard_device_descriptor_t * descriptor =
     194                                (usb_standard_device_descriptor_t*)
     195                                malloc(sizeof(usb_standard_device_descriptor_t));
     196                descriptor->configuration_count = 1;
     197                descriptor->descriptor_type = USB_DESCTYPE_DEVICE;
     198                descriptor->device_class = USB_CLASS_HUB;
     199                descriptor->device_protocol = 0;
     200                descriptor->device_subclass = 0;
     201                descriptor->device_version = 0;
     202                descriptor->length = sizeof(usb_standard_device_descriptor_t);
     203                /// \TODO this value is guessed
     204                descriptor->max_packet_size = 8;
     205                descriptor->product_id = 0x0001;
     206                /// \TODO these values migt be different
     207                descriptor->str_serial_number = 0;
     208                descriptor->str_serial_number = 0;
     209                descriptor->usb_spec_version = 0;
     210                descriptor->vendor_id = 0x16db;
     211                result_descriptor = descriptor;
     212                size = sizeof(usb_standard_device_descriptor_t);
     213        }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){
     214                usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     215                usb_standard_configuration_descriptor_t * descriptor =
     216                                (usb_standard_configuration_descriptor_t*)
     217                                malloc(sizeof(usb_standard_configuration_descriptor_t));
     218                /// \TODO some values are default or guessed
     219                descriptor->attributes = 1<<7;
     220                descriptor->configuration_number = 1;
     221                descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION;
     222                descriptor->interface_count = 1;
     223                descriptor->length = sizeof(usb_standard_configuration_descriptor_t);
     224                descriptor->max_power = 100;
     225                descriptor->str_configuration = 0;
     226                /// \TODO should this include device descriptor?
     227                size_t hub_descriptor_size = 7 +
     228                                2* (instance->port_count / 8 +
     229                                ((instance->port_count % 8 > 0) ? 1 : 0));
     230                descriptor->total_length =
     231                                sizeof(usb_standard_configuration_descriptor_t)+
     232                                sizeof(usb_standard_endpoint_descriptor_t)+
     233                                sizeof(usb_standard_interface_descriptor_t)+
     234                                hub_descriptor_size;
     235                result_descriptor = descriptor;
     236                size = sizeof(usb_standard_configuration_descriptor_t);
     237
     238        }else if(setup_request_value == USB_DESCTYPE_INTERFACE){
     239                usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     240                usb_standard_interface_descriptor_t * descriptor =
     241                                (usb_standard_interface_descriptor_t*)
     242                                malloc(sizeof(usb_standard_interface_descriptor_t));
     243                descriptor->alternate_setting = 0;
     244                descriptor->descriptor_type = USB_DESCTYPE_INTERFACE;
     245                descriptor->endpoint_count = 1;
     246                descriptor->interface_class = USB_CLASS_HUB;
     247                /// \TODO is this correct?
     248                descriptor->interface_number = 1;
     249                descriptor->interface_protocol = 0;
     250                descriptor->interface_subclass = 0;
     251                descriptor->length = sizeof(usb_standard_interface_descriptor_t);
     252                descriptor->str_interface = 0;
     253                result_descriptor = descriptor;
     254                size = sizeof(usb_standard_interface_descriptor_t);
     255        }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){
     256                usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     257                usb_standard_endpoint_descriptor_t * descriptor =
     258                                (usb_standard_endpoint_descriptor_t*)
     259                                malloc(sizeof(usb_standard_endpoint_descriptor_t));
     260                descriptor->attributes = USB_TRANSFER_INTERRUPT;
     261                descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT;
     262                descriptor->endpoint_address = 1 + (1<<7);
     263                descriptor->length = sizeof(usb_standard_endpoint_descriptor_t);
     264                descriptor->max_packet_size = 8;
     265                descriptor->poll_interval = 255;
     266                result_descriptor = descriptor;
     267                size = sizeof(usb_standard_endpoint_descriptor_t);
     268        }else{
     269                usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     270                usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     271                                setup_request->request_type,
     272                                setup_request->request,
     273                                setup_request_value,
     274                                setup_request->index,
     275                                setup_request->length
     276                                );
     277                return EINVAL;
     278        }
     279        if(request->buffer_size < size){
     280                size = request->buffer_size;
     281        }
     282        request->transfered_size = size;
     283        memcpy(request->buffer,result_descriptor,size);
     284        free(result_descriptor);
     285        return EOK;
     286}
     287
     288static int process_get_configuration_request(rh_t *instance,
     289                usb_transfer_batch_t *request){
     290        //set and get configuration requests do not have any meaning, only dummy
     291        //values are returned
     292        if(request->buffer_size != 1)
     293                return EINVAL;
     294        request->buffer[0] = 1;
     295        request->transfered_size = 1;
     296        return EOK;
     297}
     298
     299static int process_hub_feature_set_request(rh_t *instance,
     300                uint16_t feature, bool enable){
     301        if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)
     302                return EINVAL;
     303        instance->registers->rh_status =
     304                        enable ?
     305                        (instance->registers->rh_status | (1<<feature))
     306                        :
     307                        (instance->registers->rh_status & (~(1<<feature)));
     308        /// \TODO any error?
     309        return EOK;
     310}
     311
     312static int process_port_feature_set_request(rh_t *instance,
     313                uint16_t feature, uint16_t port, bool enable){
     314        if(feature > USB_HUB_FEATURE_C_PORT_RESET)
     315                return EINVAL;
     316        if(port<1 || port>instance->port_count)
     317                return EINVAL;
     318        instance->registers->rh_port_status[port - 1] =
     319                        enable ?
     320                        (instance->registers->rh_port_status[port - 1] | (1<<feature))
     321                        :
     322                        (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));
     323        /// \TODO any error?
     324        return EOK;
     325}
     326
     327static int process_address_set_request(rh_t *instance,
     328                uint16_t address){
     329        instance->address = address;
     330        return EOK;
     331}
     332
     333static int process_request_with_output(rh_t *instance,
     334                usb_transfer_batch_t *request){
     335        usb_device_request_setup_packet_t * setup_request =
     336                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     337        if(setup_request->request == USB_DEVREQ_GET_STATUS){
     338                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
     339                return process_get_status_request(instance, request);
     340        }
     341        if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
     342                usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
     343                return process_get_descriptor_request(instance, request);
     344        }
     345        if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
     346                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
     347                return process_get_configuration_request(instance, request);
     348        }
     349        return ENOTSUP;
     350}
     351
     352static int process_request_with_input(rh_t *instance,
     353                usb_transfer_batch_t *request){
     354        usb_device_request_setup_packet_t * setup_request =
     355                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     356        request->transfered_size = 0;
     357        if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
     358                return ENOTSUP;
     359        }
     360        if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){
     361                //set and get configuration requests do not have any meaning,
     362                //only dummy values are returned
     363                return EOK;
     364        }
     365        return ENOTSUP;
     366}
     367
     368
     369static int process_request_without_data(rh_t *instance,
     370                usb_transfer_batch_t *request){
     371        usb_device_request_setup_packet_t * setup_request =
     372                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     373        request->transfered_size = 0;
     374        if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     375                                || setup_request->request == USB_DEVREQ_SET_FEATURE){
     376                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     377                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
     378                        return process_hub_feature_set_request(instance, setup_request->value,
     379                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     380                }
     381                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     382                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
     383                        return process_port_feature_set_request(instance, setup_request->value,
     384                                        setup_request->index,
     385                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     386                }
     387                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
     388                return EINVAL;
     389        }
     390        if(setup_request->request == USB_DEVREQ_SET_ADDRESS){
     391                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
     392                return process_address_set_request(instance, setup_request->value);
     393        }
     394        usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type);
     395        return ENOTSUP;
     396}
     397
     398
     399/**
     400 *
     401 * @param instance
     402 * @param request
     403 * @return
     404 */
    58405int rh_request(rh_t *instance, usb_transfer_batch_t *request)
    59406{
    60407        assert(instance);
    61408        assert(request);
    62         /* TODO: implement */
    63         if (request->setup_buffer) {
    64                 usb_log_info("Root hub got SETUP packet: %s.\n",
    65                     usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
    66         }
    67         usb_log_error("Root hub request processing not implemented.\n");
    68         usb_transfer_batch_finish(request, ENOTSUP);
     409        int opResult;
     410        if(request->transfer_type == USB_TRANSFER_CONTROL){
     411                if (request->setup_buffer) {
     412                        usb_log_info("Root hub got CTRL packet: %s.\n",
     413                                usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     414                        if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     415                                usb_log_error("setup packet too small\n");
     416                                return EINVAL;
     417                        }
     418                        usb_device_request_setup_packet_t * setup_request =
     419                                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     420                        if(
     421                                setup_request->request == USB_DEVREQ_GET_STATUS
     422                                || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     423                                || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     424                        ){
     425                                usb_log_debug("processing request with output\n");
     426                                opResult = process_request_with_output(instance,request);
     427                        }else if(
     428                                setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     429                                || setup_request->request == USB_DEVREQ_SET_FEATURE
     430                                || setup_request->request == USB_DEVREQ_SET_ADDRESS
     431                        ){
     432                                usb_log_debug("processing request without additional data\n");
     433                                opResult = process_request_without_data(instance,request);
     434                        }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     435                                        || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     436                        ){
     437                                usb_log_debug("processing request with input\n");
     438                                opResult = process_request_with_input(instance,request);
     439                        }else{
     440                                usb_log_warning("received unsuported request: %d\n",
     441                                                setup_request->request
     442                                                );
     443                                opResult = ENOTSUP;
     444                        }
     445                }else{
     446                        usb_log_error("root hub received empty transaction?");
     447                        opResult = EINVAL;
     448                }
     449        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
     450                usb_log_info("Root hub got INTERRUPT packet\n");
     451                void * buffer;
     452                create_interrupt_mask(instance, &buffer,
     453                        &(request->transfered_size));
     454                memcpy(request->transport_buffer,buffer, request->transfered_size);
     455                opResult = EOK;
     456        }else{
     457                opResult = EINVAL;
     458        }
     459        usb_transfer_batch_finish(request, opResult);
    69460        return EOK;
    70461}
    71462/*----------------------------------------------------------------------------*/
     463
     464
    72465void rh_interrupt(rh_t *instance)
    73466{
  • uspace/drv/ohci/root_hub.h

    r889e8e3 r9a2923d  
    4545        usb_address_t address;
    4646        ddf_dev_t *device;
     47        int port_count;
    4748} rh_t;
    4849
  • uspace/drv/uhci-hcd/Makefile

    r889e8e3 r9a2923d  
    4040        root_hub.c \
    4141        hw_struct/transfer_descriptor.c \
     42        utils/slab.c \
    4243        pci.c \
    4344        batch.c
  • uspace/drv/uhci-hcd/hc.c

    r889e8e3 r9a2923d  
    223223        ret = instance ? EOK : ENOMEM;
    224224        CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");
    225         usb_log_debug("Initialized frame list.\n");
     225        usb_log_debug("Initialized frame list at %p.\n", instance->frame_list);
    226226
    227227        /* Set all frames to point to the first queue head */
     
    336336            instance->transfers[batch->speed][batch->transfer_type];
    337337        assert(list);
     338        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     339                usb_device_keeper_use_control(
     340                    &instance->manager, batch->target.address);
     341        }
    338342        transfer_list_add_batch(list, batch);
    339343
     
    357361        /* Lower 2 bits are transaction error and transaction complete */
    358362        if (status & 0x3) {
    359                 transfer_list_remove_finished(&instance->transfers_interrupt);
    360                 transfer_list_remove_finished(&instance->transfers_control_slow);
    361                 transfer_list_remove_finished(&instance->transfers_control_full);
    362                 transfer_list_remove_finished(&instance->transfers_bulk_full);
     363                LIST_INITIALIZE(done);
     364                transfer_list_remove_finished(
     365                    &instance->transfers_interrupt, &done);
     366                transfer_list_remove_finished(
     367                    &instance->transfers_control_slow, &done);
     368                transfer_list_remove_finished(
     369                    &instance->transfers_control_full, &done);
     370                transfer_list_remove_finished(
     371                    &instance->transfers_bulk_full, &done);
     372
     373                while (!list_empty(&done)) {
     374                        link_t *item = done.next;
     375                        list_remove(item);
     376                        usb_transfer_batch_t *batch =
     377                            list_get_instance(item, usb_transfer_batch_t, link);
     378                        if (batch->transfer_type == USB_TRANSFER_CONTROL) {
     379                                usb_device_keeper_release_control(
     380                                    &instance->manager, batch->target.address);
     381                        }
     382                        batch->next_step(batch);
     383                }
    363384        }
    364385        /* bits 4 and 5 indicate hc error */
  • uspace/drv/uhci-hcd/transfer_list.c

    r889e8e3 r9a2923d  
    5858        }
    5959        instance->queue_head_pa = addr_to_phys(instance->queue_head);
     60        usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n",
     61            name, instance->queue_head, instance->queue_head_pa);
    6062
    6163        qh_init(instance->queue_head);
     
    118120        qh_set_next_qh(last_qh, pa);
    119121
     122        asm volatile ("": : :"memory");
     123
    120124        /* Add to the driver list */
    121125        list_append(&batch->link, &instance->batch_list);
     
    137141 * this transfer list leading to the deadlock if its done inline.
    138142 */
    139 void transfer_list_remove_finished(transfer_list_t *instance)
    140 {
    141         assert(instance);
    142 
    143         LIST_INITIALIZE(done);
     143void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
     144{
     145        assert(instance);
     146        assert(done);
    144147
    145148        fibril_mutex_lock(&instance->guard);
     
    153156                        /* Save for post-processing */
    154157                        transfer_list_remove_batch(instance, batch);
    155                         list_append(current, &done);
     158                        list_append(current, done);
    156159                }
    157160                current = next;
     
    159162        fibril_mutex_unlock(&instance->guard);
    160163
    161         while (!list_empty(&done)) {
    162                 link_t *item = done.next;
    163                 list_remove(item);
    164                 usb_transfer_batch_t *batch =
    165                     list_get_instance(item, usb_transfer_batch_t, link);
    166                 batch->next_step(batch);
    167         }
    168164}
    169165/*----------------------------------------------------------------------------*/
     
    222218                qpos = "NOT FIRST";
    223219        }
     220        asm volatile ("": : :"memory");
    224221        /* Remove from the batch list */
    225222        list_remove(&batch->link);
  • uspace/drv/uhci-hcd/transfer_list.h

    r889e8e3 r9a2923d  
    6767void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);
    6868
    69 void transfer_list_remove_finished(transfer_list_t *instance);
     69void transfer_list_remove_finished(transfer_list_t *instance, link_t *done);
    7070
    7171void transfer_list_abort_all(transfer_list_t *instance);
  • uspace/drv/uhci-hcd/utils/malloc32.h

    r889e8e3 r9a2923d  
    4040#include <as.h>
    4141
     42#include "slab.h"
     43
    4244#define UHCI_STRCUTURES_ALIGNMENT 16
    4345#define UHCI_REQUIRED_PAGE_SIZE 4096
     46
    4447
    4548/** Get physical address translation
     
    5457
    5558        uintptr_t result;
    56         int ret = as_get_physical_mapping(addr, &result);
     59        const int ret = as_get_physical_mapping(addr, &result);
     60        assert(ret == EOK);
    5761
    5862        if (ret != EOK)
     
    6670 * @return Address of the alligned and big enough memory place, NULL on failure.
    6771 */
    68 static inline void * malloc32(size_t size)
    69         { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); }
     72static inline void * malloc32(size_t size) {
     73        if (size <= SLAB_ELEMENT_SIZE)
     74                return slab_malloc_g();
     75        assert(false);
     76        return memalign(UHCI_STRCUTURES_ALIGNMENT, size);
     77}
    7078/*----------------------------------------------------------------------------*/
    7179/** Physical mallocator simulator
     
    7381 * @param[in] addr Address of the place allocated by malloc32
    7482 */
    75 static inline void free32(void *addr)
    76         { if (addr) free(addr); }
     83static inline void free32(void *addr) {
     84        if (!addr)
     85                return;
     86        if (slab_in_range_g(addr))
     87                return slab_free_g(addr);
     88        free(addr);
     89}
    7790/*----------------------------------------------------------------------------*/
    7891/** Create 4KB page mapping
     
    8295static inline void * get_page(void)
    8396{
    84         void * free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
    85         assert(free_address);
     97        void *free_address = as_get_mappable_page(UHCI_REQUIRED_PAGE_SIZE);
     98        assert(free_address); /* TODO: remove this assert */
    8699        if (free_address == 0)
    87100                return NULL;
    88         void* ret =
    89           as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
     101        void *ret = as_area_create(free_address, UHCI_REQUIRED_PAGE_SIZE,
    90102                  AS_AREA_READ | AS_AREA_WRITE);
    91103        if (ret != free_address)
  • uspace/drv/usbhub/port_status.h

    r889e8e3 r9a2923d  
    3030 */
    3131
    32 #ifndef PORT_STATUS_H
    33 #define PORT_STATUS_H
     32#ifndef HUB_PORT_STATUS_H
     33#define HUB_PORT_STATUS_H
    3434
    3535#include <bool.h>
     
    335335
    336336
    337 #endif  /* PORT_STATUS_H */
     337#endif  /* HUB_PORT_STATUS_H */
    338338
    339339/**
  • uspace/drv/usbhub/usbhub.c

    r889e8e3 r9a2923d  
    162162            std_descriptor->configuration_count);
    163163        if(std_descriptor->configuration_count<1){
    164                 usb_log_error("THERE ARE NO CONFIGURATIONS AVAILABLE\n");
    165                 //shouldn`t I return?
    166                 //definitely
     164                usb_log_error("there are no configurations available\n");
    167165                return EINVAL;
    168166        }
  • uspace/lib/c/generic/malloc.c

    r889e8e3 r9a2923d  
    240240        size_t asize = ALIGN_UP(size, PAGE_SIZE);
    241241       
    242         astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
     242        astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ | AS_AREA_CACHEABLE);
    243243        if (astart == (void *) -1)
    244244                return false;
  • uspace/lib/usb/Makefile

    r889e8e3 r9a2923d  
    5050        src/usb.c \
    5151        src/usbdevice.c \
     52        src/hidreq.c \
     53        src/hidreport.c \
    5254        src/host/device_keeper.c \
    5355        src/host/batch.c
  • uspace/lib/usb/include/usb/classes/hidparser.h

    r889e8e3 r9a2923d  
    7070 * Description of path of usage pages and usages in report descriptor
    7171 */
     72#define USB_HID_PATH_COMPARE_STRICT                             0
     73#define USB_HID_PATH_COMPARE_END                                1
     74#define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY    4
     75
    7276typedef struct {
    7377        int32_t usage_page;
     78        int32_t usage;
     79
     80        link_t link;
     81} usb_hid_report_usage_path_t;
     82
     83typedef struct {
     84        int depth;     
     85        link_t link;
    7486} usb_hid_report_path_t;
    7587
     
    7991typedef struct {
    8092        int32_t id;
    81         int32_t usage_page;
    82         int32_t usage; 
    8393        int32_t usage_minimum;
    8494        int32_t usage_maximum;
     
    107117        uint8_t item_flags;
    108118
     119        usb_hid_report_path_t *usage_path;
    109120        link_t link;
    110121} usb_hid_report_item_t;
     
    117128        link_t feature;
    118129} usb_hid_report_parser_t;     
    119 
    120130
    121131
     
    194204int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    195205    const uint8_t *data, size_t size,
     206    usb_hid_report_path_t *path, int flags,
    196207    const usb_hid_report_in_callbacks_t *callbacks, void *arg);
    197208
    198209int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    199         const usb_hid_report_path_t *path);
     210        usb_hid_report_path_t *path, int flags);
    200211
    201212
     
    204215void usb_hid_descriptor_print(usb_hid_report_parser_t *parser);
    205216
     217/* usage path functions */
     218usb_hid_report_path_t *usb_hid_report_path(void);
     219void usb_hid_report_path_free(usb_hid_report_path_t *path);
     220int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage);
     221void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path);
     222void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path);
     223void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data);
     224int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags);
     225int     usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path);
     226
     227
     228// output
     229//      - funkce co vrati cesty poli v output reportu
     230//      - funkce co pro danou cestu nastavi data
     231//      - finalize
     232
    206233#endif
    207234/**
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r889e8e3 r9a2923d  
    5151        usb_speed_t speed;
    5252        bool occupied;
     53        bool control_used;
    5354        uint16_t toggle_status[2];
    5455        devman_handle_t handle;
     
    6162        struct usb_device_info devices[USB_ADDRESS_COUNT];
    6263        fibril_mutex_t guard;
    63         fibril_condvar_t default_address_occupied;
     64        fibril_condvar_t change;
    6465        usb_address_t last_address;
    6566} usb_device_keeper_t;
     
    9798    usb_address_t address);
    9899
     100void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     101    usb_address_t address);
     102
     103void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     104    usb_address_t address);
     105
    99106#endif
    100107/**
  • uspace/lib/usb/src/hidparser.c

    r889e8e3 r9a2923d  
    4747
    4848int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    49                              usb_hid_report_item_t *report_item);
     49                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5050int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    51                              usb_hid_report_item_t *report_item);
     51                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5252int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    53                              usb_hid_report_item_t *report_item);
     53                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5454int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    55                              usb_hid_report_item_t *report_item);
     55                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path);
    5656
    5757void usb_hid_descriptor_print_list(link_t *head);
     
    6363int usb_pow(int a, int b);
    6464
     65
    6566int usb_pow(int a, int b)
    6667{
     
    8485{
    8586   if(parser == NULL) {
    86         return -1;
     87        return EINVAL;
    8788   }
    8889
     
    110111        int ret;
    111112        usb_hid_report_item_t *report_item=0;
    112         usb_hid_report_item_t *new_report_item;
     113        usb_hid_report_item_t *new_report_item;
     114        usb_hid_report_path_t *usage_path;
     115        usb_hid_report_path_t *tmp_usage_path;
    113116
    114117        size_t offset_input=0;
     
    117120       
    118121
     122        /* parser structure initialization*/
     123        if(usb_hid_parser_init(parser) != EOK) {
     124                return EINVAL;
     125        }
     126       
     127
     128        /*report item initialization*/
    119129        if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){
    120130                return ENOMEM;
    121131        }
    122132        memset(report_item, 0, sizeof(usb_hid_report_item_t));
    123        
    124         link_initialize(&(report_item->link)); 
    125 
     133        list_initialize(&(report_item->link)); 
     134
     135        /* usage path context initialization */
     136        if(!(usage_path=usb_hid_report_path())){
     137                return ENOMEM;
     138        }
     139       
    126140        while(i<size){ 
    127141                if(!USB_HID_ITEM_IS_LONG(data[i])){
    128142
    129143                        if((i+USB_HID_ITEM_SIZE(data[i]))>= size){
    130                                 return -1; // TODO ERROR CODE
     144                                return EINVAL; // TODO ERROR CODE
    131145                        }
    132146                       
     
    141155                       
    142156                        ret = usb_hid_report_parse_tag(tag,class,data+i+1,
    143                                                  item_size,report_item);
     157                                                       item_size,report_item, usage_path);
    144158                        usb_log_debug2("ret: %u\n", ret);
    145159                        switch(ret){
    146160                                case USB_HID_NEW_REPORT_ITEM:
    147161                                        // store report item to report and create the new one
    148                                         usb_log_debug("\nNEW REPORT ITEM: %X",tag);
     162                                        usb_log_debug("\nNEW REPORT ITEM: %X",ret);
     163
     164                                        // store current usage path
     165                                        report_item->usage_path = usage_path;
     166
     167                                        // new current usage path
     168                                        tmp_usage_path = usb_hid_report_path();
     169                                       
     170                                        // copy old path to the new one
     171                                        usb_hid_report_path_clone(tmp_usage_path, usage_path);
     172
     173                                        // swap
     174                                        usage_path = tmp_usage_path;
     175                                        tmp_usage_path = NULL;
     176
    149177                                       
    150178                                        switch(tag) {
     
    184212                                        link_initialize(&(new_report_item->link));
    185213                                        report_item = new_report_item;
    186                                        
     214                                                                               
    187215                                        break;
    188216                                case USB_HID_REPORT_TAG_PUSH:
     
    284312 */
    285313int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size,
    286                              usb_hid_report_item_t *report_item)
     314                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    287315{       
    288316        int ret;
     
    291319                case USB_HID_TAG_CLASS_MAIN:
    292320
    293                         if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item)) == EOK) {
     321                        if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) {
    294322                                return USB_HID_NEW_REPORT_ITEM;
    295323                        }
     
    301329
    302330                case USB_HID_TAG_CLASS_GLOBAL: 
    303                         return usb_hid_report_parse_global_tag(tag,data,item_size,report_item);
     331                        return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path);
    304332                        break;
    305333
    306334                case USB_HID_TAG_CLASS_LOCAL:                   
    307                         return usb_hid_report_parse_local_tag(tag,data,item_size,report_item);
     335                        return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path);
    308336                        break;
    309337                default:
     
    323351
    324352int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    325                              usb_hid_report_item_t *report_item)
    326 {
     353                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
     354{               
    327355        switch(tag)
    328356        {
     
    335363                       
    336364                case USB_HID_REPORT_TAG_COLLECTION:
    337                         // TODO
     365                        usb_hid_report_path_append_item(usage_path, 0, 0);
     366                                               
    338367                        return USB_HID_NO_ACTION;
    339368                        break;
    340369                       
    341370                case USB_HID_REPORT_TAG_END_COLLECTION:
    342                         /* should be ignored */
     371                        // TODO
     372                        // znici posledni uroven ve vsech usage paths
     373                        // otazka jestli nema nicit dve, respektive novou posledni vynulovat?
     374                        usb_hid_report_remove_last_item(usage_path);
    343375                        return USB_HID_NO_ACTION;
    344376                        break;
     
    361393
    362394int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    363                              usb_hid_report_item_t *report_item)
     395                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    364396{
    365397        // TODO take care about the bit length of data
     
    367399        {
    368400                case USB_HID_REPORT_TAG_USAGE_PAGE:
    369                         report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size);
     401                        // zmeni to jenom v poslednim poli aktualni usage path
     402                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL,
     403                                usb_hid_report_tag_data_int32(data,item_size));
    370404                        break;
    371405                case USB_HID_REPORT_TAG_LOGICAL_MINIMUM:
     
    418452 */
    419453int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size,
    420                              usb_hid_report_item_t *report_item)
     454                             usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path)
    421455{
    422456        switch(tag)
    423457        {
    424458                case USB_HID_REPORT_TAG_USAGE:
    425                         report_item->usage = usb_hid_report_tag_data_int32(data,item_size);
     459                        usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL,
     460                                usb_hid_report_tag_data_int32(data,item_size));
    426461                        break;
    427462                case USB_HID_REPORT_TAG_USAGE_MINIMUM:
     
    491526{
    492527        usb_hid_report_item_t *report_item;
     528        usb_hid_report_usage_path_t *path_item;
     529        link_t *path;
    493530        link_t *item;
    494531       
     
    507544                usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags));
    508545                usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags));
    509                 usb_log_debug("\tUSAGE: %X\n", report_item->usage);
    510                 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
     546                usb_log_debug("\tUSAGE PATH:\n");
     547
     548                path = report_item->usage_path->link.next;
     549                while(path != &report_item->usage_path->link)   {
     550                        path_item = list_get_instance(path, usb_hid_report_usage_path_t, link);
     551                        usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage);
     552                        path = path->next;
     553                }
     554               
     555               
     556//              usb_log_debug("\tUSAGE: %X\n", report_item->usage);
     557//              usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page);
    511558                usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum);
    512559                usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum);         
     
    530577void usb_hid_descriptor_print(usb_hid_report_parser_t *parser)
    531578{
     579        if(parser == NULL) {
     580                return;
     581        }
     582       
    532583        usb_log_debug("INPUT:\n");
    533584        usb_hid_descriptor_print_list(&parser->input);
     
    561612       
    562613            report_item = list_get_instance(next, usb_hid_report_item_t, link);
     614
     615                while(!list_empty(&report_item->usage_path->link)) {
     616                        usb_hid_report_remove_last_item(report_item->usage_path);
     617                }
     618
     619               
    563620            next = next->next;
    564621           
     
    600657int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 
    601658    const uint8_t *data, size_t size,
     659    usb_hid_report_path_t *path, int flags,
    602660    const usb_hid_report_in_callbacks_t *callbacks, void *arg)
    603661{
     
    615673        size_t j=0;
    616674
     675        if(parser == NULL) {
     676                return EINVAL;
     677        }
     678
     679       
    617680        // get the size of result keycodes array
    618         usb_hid_report_path_t path;
    619         path.usage_page = BAD_HACK_USAGE_PAGE;
    620         key_count = usb_hid_report_input_length(parser, &path);
     681        key_count = usb_hid_report_input_length(parser, path, flags);
    621682
    622683        if(!(keys = malloc(sizeof(uint8_t) * key_count))){
     
    629690
    630691                item = list_get_instance(list_item, usb_hid_report_item_t, link);
    631                 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
    632                    (item->usage_page == path.usage_page)) {
     692                if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 
     693                   (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
    633694                        for(j=0; j<(size_t)(item->count); j++) {
    634695                                if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) ||
     
    640701                                        // bitmapa
    641702                                        if((item_value = usb_hid_translate_data(item, data, j)) != 0) {
    642                                                 keys[i++] = j + item->usage_minimum;
     703                                                keys[i++] = (item->count - 1 - j) + item->usage_minimum;
    643704                                        }
    644705                                        else {
     
    736797
    737798int usb_hid_report_input_length(const usb_hid_report_parser_t *parser,
    738         const usb_hid_report_path_t *path)
    739 {
     799        usb_hid_report_path_t *path, int flags)
     800{       
    740801        int ret = 0;
    741802        link_t *item;
    742803        usb_hid_report_item_t *report_item;
    743804
     805        if(parser == NULL) {
     806                return EINVAL;
     807        }
     808       
    744809        item = (&parser->input)->next;
    745810        while(&parser->input != item) {
    746811                report_item = list_get_instance(item, usb_hid_report_item_t, link);
    747812                if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) &&
    748                    (report_item->usage_page == path->usage_page)) {
     813                   (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) {
    749814                        ret += report_item->count;
    750815                }
     
    757822
    758823
     824/**
     825 *
     826 */
     827int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path,
     828                                    int32_t usage_page, int32_t usage)
     829{       
     830        usb_hid_report_usage_path_t *item;
     831
     832        if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) {
     833                return ENOMEM;
     834        }
     835        list_initialize(&item->link);
     836
     837        item->usage = usage;
     838        item->usage_page = usage_page;
     839       
     840        list_append (&usage_path->link, &item->link);
     841        usage_path->depth++;
     842        return EOK;
     843}
     844
     845/**
     846 *
     847 */
     848void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path)
     849{
     850        usb_hid_report_usage_path_t *item;
     851       
     852        if(!list_empty(&usage_path->link)){
     853                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);             
     854                list_remove(usage_path->link.prev);
     855                usage_path->depth--;
     856                free(item);
     857        }
     858}
     859
     860/**
     861 *
     862 */
     863void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path)
     864{
     865        usb_hid_report_usage_path_t *item;
     866       
     867        if(!list_empty(&usage_path->link)){     
     868                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
     869                memset(item, 0, sizeof(usb_hid_report_usage_path_t));
     870        }
     871}
     872
     873/**
     874 *
     875 */
     876void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data)
     877{
     878        usb_hid_report_usage_path_t *item;
     879       
     880        if(!list_empty(&usage_path->link)){     
     881                item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link);
     882
     883                switch(tag) {
     884                        case USB_HID_TAG_CLASS_GLOBAL:
     885                                item->usage_page = data;
     886                                break;
     887                        case USB_HID_TAG_CLASS_LOCAL:
     888                                item->usage = data;
     889                                break;
     890                }
     891        }
     892       
     893}
     894
     895/**
     896 *
     897 */
     898int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path,
     899                                      usb_hid_report_path_t *path,
     900                                      int flags)
     901{
     902        usb_hid_report_usage_path_t *report_item;
     903        usb_hid_report_usage_path_t *path_item;
     904
     905        link_t *report_link;
     906        link_t *path_link;
     907
     908        int only_page;
     909
     910        if(path->depth == 0){
     911                return EOK;
     912        }
     913
     914
     915        if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){
     916                flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY;
     917        }
     918       
     919        switch(flags){
     920                /* path must be completly identical */
     921                case USB_HID_PATH_COMPARE_STRICT:
     922                                if(report_path->depth != path->depth){
     923                                        return 1;
     924                                }
     925
     926                                report_link = report_path->link.next;
     927                                path_link = path->link.next;
     928                       
     929                                while((report_link != &report_path->link) && (path_link != &path->link)) {
     930                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     931                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     932
     933                                        if((report_item->usage_page != path_item->usage_page) ||
     934                                           ((only_page == 0) && (report_item->usage != path_item->usage))) {
     935                                                   return 1;
     936                                        } else {
     937                                                report_link = report_link->next;
     938                                                path_link = path_link->next;                   
     939                                        }
     940                       
     941                                }
     942
     943                                if((report_link == &report_path->link) && (path_link == &path->link)) {
     944                                        return EOK;
     945                                }
     946                                else {
     947                                        return 1;
     948                                }                                               
     949                        break;
     950
     951                /* given path must be the end of the report one*/
     952                case USB_HID_PATH_COMPARE_END:
     953                                report_link = report_path->link.prev;
     954                                path_link = path->link.prev;
     955
     956                                if(list_empty(&path->link)){
     957                                        return EOK;
     958                                }
     959                       
     960                                while((report_link != &report_path->link) && (path_link != &path->link)) {
     961                                        report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link);
     962                                        path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);           
     963
     964                                        if((report_item->usage_page != path_item->usage_page) ||
     965                                           ((only_page == 0) && (report_item->usage != path_item->usage))) {
     966                                                   return 1;
     967                                        } else {
     968                                                report_link = report_link->prev;
     969                                                path_link = path_link->prev;                   
     970                                        }
     971                       
     972                                }
     973
     974                                if(path_link == &path->link) {
     975                                        return EOK;
     976                                }
     977                                else {
     978                                        return 1;
     979                                }                                               
     980                       
     981                        break;
     982
     983                default:
     984                        return EINVAL;
     985        }
     986       
     987       
     988       
     989       
     990}
     991
     992/**
     993 *
     994 */
     995usb_hid_report_path_t *usb_hid_report_path(void)
     996{
     997        usb_hid_report_path_t *path;
     998        path = malloc(sizeof(usb_hid_report_path_t));
     999        if(!path){
     1000                return NULL;
     1001        }
     1002        else {
     1003                path->depth = 0;
     1004                list_initialize(&path->link);
     1005                return path;
     1006        }
     1007}
     1008
     1009/**
     1010 *
     1011 */
     1012void usb_hid_report_path_free(usb_hid_report_path_t *path)
     1013{
     1014        while(!list_empty(&path->link)){
     1015                usb_hid_report_remove_last_item(path);
     1016        }
     1017}
     1018
     1019
     1020/**
     1021 *
     1022 */
     1023int     usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path)
     1024{
     1025        usb_hid_report_usage_path_t *path_item;
     1026        link_t *path_link;
     1027
     1028       
     1029        if(list_empty(&usage_path->link)){
     1030                return EOK;
     1031        }
     1032
     1033        path_link = usage_path->link.next;
     1034        while(path_link != &usage_path->link) {
     1035                path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link);
     1036                usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage);
     1037
     1038                path_link = path_link->next;
     1039        }
     1040
     1041        return EOK;
     1042}
     1043
    7591044
    7601045/**
  • uspace/lib/usb/src/host/device_keeper.c

    r889e8e3 r9a2923d  
    4949        assert(instance);
    5050        fibril_mutex_initialize(&instance->guard);
    51         fibril_condvar_initialize(&instance->default_address_occupied);
     51        fibril_condvar_initialize(&instance->change);
    5252        instance->last_address = 0;
    5353        unsigned i = 0;
    5454        for (; i < USB_ADDRESS_COUNT; ++i) {
    5555                instance->devices[i].occupied = false;
     56                instance->devices[i].control_used = false;
    5657                instance->devices[i].handle = 0;
    5758                instance->devices[i].toggle_status[0] = 0;
     
    7172        fibril_mutex_lock(&instance->guard);
    7273        while (instance->devices[USB_ADDRESS_DEFAULT].occupied) {
    73                 fibril_condvar_wait(&instance->default_address_occupied,
    74                     &instance->guard);
     74                fibril_condvar_wait(&instance->change, &instance->guard);
    7575        }
    7676        instance->devices[USB_ADDRESS_DEFAULT].occupied = true;
     
    9090        instance->devices[USB_ADDRESS_DEFAULT].occupied = false;
    9191        fibril_mutex_unlock(&instance->guard);
    92         fibril_condvar_signal(&instance->default_address_occupied);
     92        fibril_condvar_signal(&instance->change);
    9393}
    9494/*----------------------------------------------------------------------------*/
     
    309309        return instance->devices[address].speed;
    310310}
    311 
     311/*----------------------------------------------------------------------------*/
     312void usb_device_keeper_use_control(usb_device_keeper_t *instance,
     313    usb_address_t address)
     314{
     315        assert(instance);
     316        fibril_mutex_lock(&instance->guard);
     317        while (instance->devices[address].control_used) {
     318                fibril_condvar_wait(&instance->change, &instance->guard);
     319        }
     320        instance->devices[address].control_used = true;
     321        fibril_mutex_unlock(&instance->guard);
     322}
     323/*----------------------------------------------------------------------------*/
     324void usb_device_keeper_release_control(usb_device_keeper_t *instance,
     325    usb_address_t address)
     326{
     327        assert(instance);
     328        fibril_mutex_lock(&instance->guard);
     329        instance->devices[address].control_used = false;
     330        fibril_mutex_unlock(&instance->guard);
     331        fibril_condvar_signal(&instance->change);
     332}
    312333/**
    313334 * @}
Note: See TracChangeset for help on using the changeset viewer.