Changeset a8ac368 in mainline for uspace/drv/ohci/root_hub.c


Ignore:
Timestamp:
2011-03-29T20:08:53Z (14 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fc883bb
Parents:
0d92638 (diff), 51e5608 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

development changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/root_hub.c

    r0d92638 ra8ac368  
    3939
    4040#include "root_hub.h"
     41#include "usb/classes/classes.h"
     42#include <usb/request.h>
     43#include <usb/classes/hub.h>
     44
     45/**
     46 *      standart device descriptor for ohci root hub
     47 */
     48static const usb_standard_device_descriptor_t ohci_rh_device_descriptor =
     49{
     50                .configuration_count = 1,
     51                .descriptor_type = USB_DESCTYPE_DEVICE,
     52                .device_class = USB_CLASS_HUB,
     53                .device_protocol = 0,
     54                .device_subclass = 0,
     55                .device_version = 0,
     56                .length = sizeof(usb_standard_device_descriptor_t),
     57                /// \TODO this value is guessed
     58                .max_packet_size = 8,
     59                .vendor_id = 0x16db,
     60                .product_id = 0x0001,
     61                /// \TODO these values migt be different
     62                .str_serial_number = 0,
     63                .usb_spec_version = 0,
     64};
     65
     66/**
     67 * standart configuration descriptor with filled common values
     68 * for ohci root hubs
     69 */
     70static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor =
     71{
     72        /// \TODO some values are default or guessed
     73        .attributes = 1<<7,
     74        .configuration_number = 1,
     75        .descriptor_type = USB_DESCTYPE_CONFIGURATION,
     76        .interface_count = 1,
     77        .length = sizeof(usb_standard_configuration_descriptor_t),
     78        .max_power = 100,
     79        .str_configuration = 0,
     80};
     81
     82/**
     83 * standart ohci root hub interface descriptor
     84 */
     85static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor =
     86{
     87        .alternate_setting = 0,
     88        .descriptor_type = USB_DESCTYPE_INTERFACE,
     89        .endpoint_count = 1,
     90        .interface_class = USB_CLASS_HUB,
     91        /// \TODO is this correct?
     92        .interface_number = 1,
     93        .interface_protocol = 0,
     94        .interface_subclass = 0,
     95        .length = sizeof(usb_standard_interface_descriptor_t),
     96        .str_interface = 0,
     97};
     98
     99/**
     100 * standart ohci root hub endpoint descriptor
     101 */
     102static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor =
     103{
     104        .attributes = USB_TRANSFER_INTERRUPT,
     105        .descriptor_type = USB_DESCTYPE_ENDPOINT,
     106        .endpoint_address = 1 + (1<<7),
     107        .length = sizeof(usb_standard_endpoint_descriptor_t),
     108        .max_packet_size = 8,
     109        .poll_interval = 255,
     110};
    41111
    42112/** Root hub initialization
     
    50120        instance->device = dev;
    51121
     122
    52123        usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff);
    53124
     125        //start generic usb hub driver
     126       
    54127        /* TODO: implement */
    55128        return EOK;
    56129}
    57130/*----------------------------------------------------------------------------*/
     131
     132/**
     133 * create answer to port status_request
     134 *
     135 * Copy content of corresponding port status register to answer buffer.
     136 *
     137 * @param instance root hub instance
     138 * @param port port number, counted from 1
     139 * @param request structure containing both request and response information
     140 * @return error code
     141 */
     142static int process_get_port_status_request(rh_t *instance, uint16_t port,
     143                usb_transfer_batch_t * request){
     144        if(port<1 || port>instance->port_count)
     145                return EINVAL;
     146        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     147        request->transfered_size = 4;
     148        uint32_buffer[0] = instance->registers->rh_port_status[port -1];
     149        return EOK;
     150}
     151
     152/**
     153 * create answer to port status_request
     154 *
     155 * Copy content of hub status register to answer buffer.
     156 *
     157 * @param instance root hub instance
     158 * @param request structure containing both request and response information
     159 * @return error code
     160 */
     161static int process_get_hub_status_request(rh_t *instance,
     162                usb_transfer_batch_t * request){
     163        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     164        //bits, 0,1,16,17
     165        request->transfered_size = 4;
     166        uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
     167        uint32_buffer[0] = mask & instance->registers->rh_status;
     168        return EOK;
     169
     170}
     171
     172/**
     173 * Create hub descriptor used in hub-driver <-> hub communication
     174 *
     175 * This means creating byt array from data in root hub registers. For more
     176 * info see usb hub specification.
     177 *
     178 * @param instance root hub instance
     179 * @param@out out_result pointer to resultant serialized descriptor
     180 * @param@out out_size size of serialized descriptor
     181 */
     182static void usb_create_serialized_hub_descriptor(rh_t *instance,
     183                uint8_t ** out_result,
     184                size_t * out_size) {
     185        //base size
     186        size_t size = 7;
     187        //variable size according to port count
     188        size_t var_size = instance->port_count / 8 +
     189                        ((instance->port_count % 8 > 0) ? 1 : 0);
     190        size += 2 * var_size;
     191        uint8_t * result = (uint8_t*) malloc(size);
     192        bzero(result,size);
     193        //size
     194        result[0] = size;
     195        //descriptor type
     196        result[1] = USB_DESCTYPE_HUB;
     197        result[2] = instance->port_count;
     198        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
     199        result[3] =
     200                        ((hub_desc_reg >> 8) %2) +
     201                        (((hub_desc_reg >> 9) %2) << 1) +
     202                        (((hub_desc_reg >> 10) %2) << 2) +
     203                        (((hub_desc_reg >> 11) %2) << 3) +
     204                        (((hub_desc_reg >> 12) %2) << 4);
     205        result[4] = 0;
     206        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
     207        result[6] = 50;
     208
     209        int port;
     210        for (port = 1; port <= instance->port_count; ++port) {
     211                result[7 + port/8] +=
     212                                ((instance->registers->rh_desc_b >> port)%2) << (port%8);
     213        }
     214        size_t i;
     215        for (i = 0; i < var_size; ++i) {
     216                result[7 + var_size + i] = 255;
     217        }
     218        (*out_result) = result;
     219        (*out_size) = size;
     220}
     221
     222
     223/**
     224 * create answer to status request
     225 *
     226 * This might be either hub status or port status request. If neither,
     227 * ENOTSUP is returned.
     228 * @param instance root hub instance
     229 * @param request structure containing both request and response information
     230 * @return error code
     231 */
     232static int process_get_status_request(rh_t *instance,
     233                usb_transfer_batch_t * request)
     234{
     235        size_t buffer_size = request->buffer_size;
     236        usb_device_request_setup_packet_t * request_packet =
     237                        (usb_device_request_setup_packet_t*)
     238                        request->setup_buffer;
     239
     240        usb_hub_bm_request_type_t request_type = request_packet->request_type;
     241        if(buffer_size<4/*request_packet->length*/){///\TODO
     242                usb_log_warning("requested more data than buffer size\n");
     243                return EINVAL;
     244        }
     245
     246        if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
     247                return process_get_hub_status_request(instance, request);
     248        if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
     249                return process_get_port_status_request(instance, request_packet->index,
     250                                request);
     251        return ENOTSUP;
     252}
     253
     254/**
     255 * create answer to status interrupt consisting of change bitmap
     256 *
     257 * Result contains bitmap where bit 0 indicates change on hub and
     258 * bit i indicates change on i`th port (i>0). For more info see
     259 * Hub and Port status bitmap specification in USB specification.
     260 * @param instance root hub instance
     261 * @param@out buffer pointer to created interrupt mas
     262 * @param@out buffer_size size of created interrupt mask
     263 */
     264static void create_interrupt_mask(rh_t *instance, void ** buffer,
     265                size_t * buffer_size){
     266        int bit_count = instance->port_count + 1;
     267        (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;
     268        (*buffer) = malloc(*buffer_size);
     269        uint8_t * bitmap = (uint8_t*)(*buffer);
     270        uint32_t mask = (1<<16) + (1<<17);
     271        bzero(bitmap,(*buffer_size));
     272        if(instance->registers->rh_status & mask){
     273                bitmap[0] = 1;
     274        }
     275        int port;
     276        mask = 0;
     277        int i;
     278        for(i=16;i<=20;++i)
     279                mask += 1<<i;
     280        for(port = 1; port<=instance->port_count;++port){
     281                if(mask & instance->registers->rh_port_status[port-1]){
     282                        bitmap[(port+1)/8] += 1<<(port%8);
     283                }
     284        }
     285}
     286
     287/**
     288 * create standart configuration descriptor for the root hub instance
     289 * @param instance root hub instance
     290 * @return newly allocated descriptor
     291 */
     292static usb_standard_configuration_descriptor_t *
     293usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){
     294        usb_standard_configuration_descriptor_t * descriptor =
     295                        malloc(sizeof(usb_standard_configuration_descriptor_t));
     296        memcpy(descriptor, &ohci_rh_conf_descriptor,
     297                sizeof(usb_standard_configuration_descriptor_t));
     298        /// \TODO should this include device descriptor?
     299        const size_t hub_descriptor_size = 7 +
     300                        2* (instance->port_count / 8 +
     301                        ((instance->port_count % 8 > 0) ? 1 : 0));
     302        descriptor->total_length =
     303                        sizeof(usb_standard_configuration_descriptor_t)+
     304                        sizeof(usb_standard_endpoint_descriptor_t)+
     305                        sizeof(usb_standard_interface_descriptor_t)+
     306                        hub_descriptor_size;
     307        return descriptor;
     308}
     309
     310/**
     311 * create answer to a descriptor request
     312 *
     313 * This might be a request for standard (configuration, device, endpoint or
     314 * interface) or device specific (hub) descriptor.
     315 * @param instance root hub instance
     316 * @param request structure containing both request and response information
     317 * @return error code
     318 */
     319static int process_get_descriptor_request(rh_t *instance,
     320                usb_transfer_batch_t *request){
     321        usb_device_request_setup_packet_t * setup_request =
     322                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     323        size_t size;
     324        const void * result_descriptor = NULL;
     325        const uint16_t setup_request_value = setup_request->value_high;
     326                        //(setup_request->value_low << 8);
     327        bool del = false;
     328        switch (setup_request_value)
     329        {
     330                case USB_DESCTYPE_HUB: {
     331                        uint8_t * descriptor;
     332                        usb_create_serialized_hub_descriptor(
     333                                instance, &descriptor, &size);
     334                        result_descriptor = descriptor;
     335                        if(result_descriptor) del = true;
     336                        break;
     337                }
     338                case USB_DESCTYPE_DEVICE: {
     339                        usb_log_debug("USB_DESCTYPE_DEVICE\n");
     340                        result_descriptor = &ohci_rh_device_descriptor;
     341                        size = sizeof(ohci_rh_device_descriptor);
     342                        break;
     343                }
     344                case USB_DESCTYPE_CONFIGURATION: {
     345                        usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     346                        usb_standard_configuration_descriptor_t * descriptor =
     347                                        usb_ohci_rh_create_standart_configuration_descriptor(
     348                                                instance);
     349                        result_descriptor = descriptor;
     350                        size = sizeof(usb_standard_configuration_descriptor_t);
     351                        del = true;
     352                        break;
     353                }
     354                case USB_DESCTYPE_INTERFACE: {
     355                        usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     356                        result_descriptor = &ohci_rh_iface_descriptor;
     357                        size = sizeof(ohci_rh_iface_descriptor);
     358                        break;
     359                }
     360                case USB_DESCTYPE_ENDPOINT: {
     361                        usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     362                        result_descriptor = &ohci_rh_ep_descriptor;
     363                        size = sizeof(ohci_rh_ep_descriptor);
     364                        break;
     365                }
     366                default: {
     367                        usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     368                        usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     369                                        setup_request->request_type,
     370                                        setup_request->request,
     371                                        setup_request_value,
     372                                        setup_request->index,
     373                                        setup_request->length
     374                                        );
     375                        return EINVAL;
     376                }
     377        }
     378        if(request->buffer_size < size){
     379                size = request->buffer_size;
     380        }
     381        request->transfered_size = size;
     382        memcpy(request->buffer,result_descriptor,size);
     383        if (del)
     384                free(result_descriptor);
     385        return EOK;
     386}
     387
     388/**
     389 * answer to get configuration request
     390 *
     391 * Root hub works independently on the configuration.
     392 * @param instance root hub instance
     393 * @param request structure containing both request and response information
     394 * @return error code
     395 */
     396static int process_get_configuration_request(rh_t *instance,
     397                usb_transfer_batch_t *request){
     398        //set and get configuration requests do not have any meaning, only dummy
     399        //values are returned
     400        if(request->buffer_size != 1)
     401                return EINVAL;
     402        request->buffer[0] = 1;
     403        request->transfered_size = 1;
     404        return EOK;
     405}
     406
     407/**
     408 * process feature-enabling/disabling request on hub
     409 *
     410 * @param instance root hub instance
     411 * @param feature feature selector
     412 * @param enable enable or disable specified feature
     413 * @return error code
     414 */
     415static int process_hub_feature_set_request(rh_t *instance,
     416                uint16_t feature, bool enable){
     417        if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)
     418                return EINVAL;
     419        instance->registers->rh_status =
     420                        enable ?
     421                        (instance->registers->rh_status | (1<<feature))
     422                        :
     423                        (instance->registers->rh_status & (~(1<<feature)));
     424        /// \TODO any error?
     425        return EOK;
     426}
     427
     428/**
     429 * process feature-enabling/disabling request on hub
     430 *
     431 * @param instance root hub instance
     432 * @param feature feature selector
     433 * @param port port number, counted from 1
     434 * @param enable enable or disable the specified feature
     435 * @return error code
     436 */
     437static int process_port_feature_set_request(rh_t *instance,
     438                uint16_t feature, uint16_t port, bool enable){
     439        if(feature > USB_HUB_FEATURE_C_PORT_RESET)
     440                return EINVAL;
     441        if(port<1 || port>instance->port_count)
     442                return EINVAL;
     443        instance->registers->rh_port_status[port - 1] =
     444                        enable ?
     445                        (instance->registers->rh_port_status[port - 1] | (1<<feature))
     446                        :
     447                        (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));
     448        /// \TODO any error?
     449        return EOK;
     450}
     451
     452/**
     453 * register address to this device
     454 *
     455 * @param instance root hub instance
     456 * @param address new address
     457 * @return error code
     458 */
     459static int process_address_set_request(rh_t *instance,
     460                uint16_t address){
     461        instance->address = address;
     462        return EOK;
     463}
     464
     465/**
     466 * process one of requests that requere output data
     467 *
     468 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or
     469 * USB_DEVREQ_GET_CONFIGURATION.
     470 * @param instance root hub instance
     471 * @param request structure containing both request and response information
     472 * @return error code
     473 */
     474static int process_request_with_output(rh_t *instance,
     475                usb_transfer_batch_t *request){
     476        usb_device_request_setup_packet_t * setup_request =
     477                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     478        if(setup_request->request == USB_DEVREQ_GET_STATUS){
     479                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
     480                return process_get_status_request(instance, request);
     481        }
     482        if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
     483                usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
     484                return process_get_descriptor_request(instance, request);
     485        }
     486        if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
     487                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
     488                return process_get_configuration_request(instance, request);
     489        }
     490        return ENOTSUP;
     491}
     492
     493/**
     494 * process one of requests that carry input data
     495 *
     496 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or
     497 * USB_DEVREQ_SET_CONFIGURATION.
     498 * @param instance root hub instance
     499 * @param request structure containing both request and response information
     500 * @return error code
     501 */
     502static int process_request_with_input(rh_t *instance,
     503                usb_transfer_batch_t *request){
     504        usb_device_request_setup_packet_t * setup_request =
     505                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     506        request->transfered_size = 0;
     507        if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
     508                return ENOTSUP;
     509        }
     510        if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){
     511                //set and get configuration requests do not have any meaning,
     512                //only dummy values are returned
     513                return EOK;
     514        }
     515        return ENOTSUP;
     516}
     517
     518/**
     519 * process one of requests that do not request nor carry additional data
     520 *
     521 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or
     522 * USB_DEVREQ_SET_ADDRESS.
     523 * @param instance root hub instance
     524 * @param request structure containing both request and response information
     525 * @return error code
     526 */
     527static int process_request_without_data(rh_t *instance,
     528                usb_transfer_batch_t *request){
     529        usb_device_request_setup_packet_t * setup_request =
     530                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     531        request->transfered_size = 0;
     532        if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     533                                || setup_request->request == USB_DEVREQ_SET_FEATURE){
     534                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     535                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
     536                        return process_hub_feature_set_request(instance, setup_request->value,
     537                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     538                }
     539                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     540                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
     541                        return process_port_feature_set_request(instance, setup_request->value,
     542                                        setup_request->index,
     543                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     544                }
     545                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
     546                return EINVAL;
     547        }
     548        if(setup_request->request == USB_DEVREQ_SET_ADDRESS){
     549                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
     550                return process_address_set_request(instance, setup_request->value);
     551        }
     552        usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type);
     553        return ENOTSUP;
     554}
     555
     556/**
     557 * process hub control request
     558 *
     559 * If needed, writes answer into the request structure.
     560 * Request can be one of
     561 * USB_DEVREQ_GET_STATUS,
     562 * USB_DEVREQ_GET_DESCRIPTOR,
     563 * USB_DEVREQ_GET_CONFIGURATION,
     564 * USB_DEVREQ_CLEAR_FEATURE,
     565 * USB_DEVREQ_SET_FEATURE,
     566 * USB_DEVREQ_SET_ADDRESS,
     567 * USB_DEVREQ_SET_DESCRIPTOR or
     568 * USB_DEVREQ_SET_CONFIGURATION.
     569 *
     570 * @param instance root hub instance
     571 * @param request structure containing both request and response information
     572 * @return error code
     573 */
     574static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){
     575        int opResult;
     576        if (request->setup_buffer) {
     577                if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     578                        usb_log_error("setup packet too small\n");
     579                        return EINVAL;
     580                }
     581                usb_log_info("CTRL packet: %s.\n",
     582                        usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     583                usb_device_request_setup_packet_t * setup_request =
     584                                (usb_device_request_setup_packet_t*)request->setup_buffer;
     585                if(
     586                        setup_request->request == USB_DEVREQ_GET_STATUS
     587                        || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     588                        || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     589                ){
     590                        usb_log_debug("processing request with output\n");
     591                        opResult = process_request_with_output(instance,request);
     592                }else if(
     593                        setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     594                        || setup_request->request == USB_DEVREQ_SET_FEATURE
     595                        || setup_request->request == USB_DEVREQ_SET_ADDRESS
     596                ){
     597                        usb_log_debug("processing request without additional data\n");
     598                        opResult = process_request_without_data(instance,request);
     599                }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     600                                || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     601                ){
     602                        usb_log_debug("processing request with input\n");
     603                        opResult = process_request_with_input(instance,request);
     604                }else{
     605                        usb_log_warning("received unsuported request: %d\n",
     606                                        setup_request->request
     607                                        );
     608                        opResult = ENOTSUP;
     609                }
     610        }else{
     611                usb_log_error("root hub received empty transaction?");
     612                opResult = EINVAL;
     613        }
     614        return opResult;
     615}
     616
     617/**
     618 * process root hub request
     619 *
     620 * @param instance root hub instance
     621 * @param request structure containing both request and response information
     622 * @return error code
     623 */
    58624int rh_request(rh_t *instance, usb_transfer_batch_t *request)
    59625{
    60626        assert(instance);
    61627        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);
     628        int opResult;
     629        if(request->transfer_type == USB_TRANSFER_CONTROL){
     630                usb_log_info("Root hub got CONTROL packet\n");
     631                opResult = process_ctrl_request(instance,request);
     632        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
     633                usb_log_info("Root hub got INTERRUPT packet\n");
     634                void * buffer;
     635                create_interrupt_mask(instance, &buffer,
     636                        &(request->transfered_size));
     637                memcpy(request->transport_buffer,buffer, request->transfered_size);
     638                opResult = EOK;
     639        }else{
     640                opResult = EINVAL;
     641        }
     642        usb_transfer_batch_finish(request, opResult);
    69643        return EOK;
    70644}
    71645/*----------------------------------------------------------------------------*/
     646
     647
    72648void rh_interrupt(rh_t *instance)
    73649{
    74         usb_log_error("Root hub interrupt not implemented.\n");
    75         /* TODO: implement */
     650        usb_log_info("Whoa whoa wait, I`m not supposed to receive any interrupts, am I?\n");
     651        /* TODO: implement? */
    76652}
    77653/**
Note: See TracChangeset for help on using the changeset viewer.