Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhub/utils.c

    r9ca0013 rf9a0cef  
    3434 */
    3535#include <driver.h>
    36 #include <usb/devreq.h>
     36#include <bool.h>
     37#include <errno.h>
     38
    3739#include <usbhc_iface.h>
    3840#include <usb/usbdrv.h>
    3941#include <usb/descriptor.h>
    40 #include <driver.h>
    41 #include <bool.h>
    42 #include <errno.h>
     42#include <usb/devreq.h>
    4343#include <usb/classes/hub.h>
     44
    4445#include "usbhub.h"
    45 
    46 static void check_hub_changes(void);
     46#include "usbhub_private.h"
     47#include "port_status.h"
     48
    4749
    4850size_t USB_HUB_MAX_DESCRIPTOR_SIZE = 71;
     
    5355//
    5456//*********************************************
     57
     58//hub descriptor utils
    5559
    5660void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
     
    8488usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * serialized_descriptor) {
    8589        uint8_t * sdescriptor = (uint8_t*) serialized_descriptor;
    86         if (sdescriptor[1] != USB_DESCTYPE_HUB) return NULL;
    87         usb_hub_descriptor_t * result = (usb_hub_descriptor_t*) malloc(sizeof (usb_hub_descriptor_t));
    88         //uint8_t size = sdescriptor[0];
     90
     91        if (sdescriptor[1] != USB_DESCTYPE_HUB) {
     92                printf("[usb_hub] wrong descriptor %x\n",sdescriptor[1]);
     93                return NULL;
     94        }
     95
     96        usb_hub_descriptor_t * result = usb_new(usb_hub_descriptor_t);
     97       
     98
    8999        result->ports_count = sdescriptor[2];
    90100        /// @fixme handling of endianness??
     
    94104        size_t var_size = result->ports_count / 8 + ((result->ports_count % 8 > 0) ? 1 : 0);
    95105        result->devices_removable = (uint8_t*) malloc(var_size);
    96 
     106        //printf("[usb_hub] getting removable devices data \n");
    97107        size_t i;
    98108        for (i = 0; i < var_size; ++i) {
     
    102112}
    103113
     114//control transactions
     115
     116int usb_drv_sync_control_read(
     117                int phone, usb_target_t target,
     118                usb_device_request_setup_packet_t * request,
     119                void * rcvd_buffer, size_t rcvd_size, size_t * actual_size
     120                ) {
     121        usb_handle_t handle;
     122        int opResult;
     123        //setup
     124        opResult = usb_drv_async_control_read_setup(phone, target,
     125                        request, sizeof (usb_device_request_setup_packet_t),
     126                        &handle);
     127        if (opResult != EOK) {
     128                return opResult;
     129        }
     130        opResult = usb_drv_async_wait_for(handle);
     131        if (opResult != EOK) {
     132                return opResult;
     133        }
     134        //read
     135        opResult = usb_drv_async_control_read_data(phone, target,
     136                        rcvd_buffer, rcvd_size, actual_size,
     137                        &handle);
     138        if (opResult != EOK) {
     139                return opResult;
     140        }
     141        opResult = usb_drv_async_wait_for(handle);
     142        if (opResult != EOK) {
     143                return opResult;
     144        }
     145        //finalize
     146        opResult = usb_drv_async_control_read_status(phone, target,
     147                        &handle);
     148        if (opResult != EOK) {
     149                return opResult;
     150        }
     151        opResult = usb_drv_async_wait_for(handle);
     152        if (opResult != EOK) {
     153                return opResult;
     154        }
     155        return EOK;
     156}
     157
     158int usb_drv_sync_control_write(
     159                int phone, usb_target_t target,
     160                usb_device_request_setup_packet_t * request,
     161                void * sent_buffer, size_t sent_size
     162                ) {
     163        usb_handle_t handle;
     164        int opResult;
     165        //setup
     166        opResult = usb_drv_async_control_write_setup(phone, target,
     167                        request, sizeof (usb_device_request_setup_packet_t),
     168                        &handle);
     169        if (opResult != EOK) {
     170                return opResult;
     171        }
     172        opResult = usb_drv_async_wait_for(handle);
     173        if (opResult != EOK) {
     174                return opResult;
     175        }
     176        //write
     177        opResult = usb_drv_async_control_write_data(phone, target,
     178                        sent_buffer, sent_size,
     179                        &handle);
     180        if (opResult != EOK) {
     181                return opResult;
     182        }
     183        opResult = usb_drv_async_wait_for(handle);
     184        if (opResult != EOK) {
     185                return opResult;
     186        }
     187        //finalize
     188        opResult = usb_drv_async_control_write_status(phone, target,
     189                        &handle);
     190        if (opResult != EOK) {
     191                return opResult;
     192        }
     193        opResult = usb_drv_async_wait_for(handle);
     194        if (opResult != EOK) {
     195                return opResult;
     196        }
     197        return EOK;
     198}
     199
     200//list implementation
     201
     202usb_general_list_t * usb_lst_create(void) {
     203        usb_general_list_t* result = usb_new(usb_general_list_t);
     204        usb_lst_init(result);
     205        return result;
     206}
     207
     208void usb_lst_init(usb_general_list_t * lst) {
     209        lst->prev = lst;
     210        lst->next = lst;
     211        lst->data = NULL;
     212}
     213
     214void usb_lst_prepend(usb_general_list_t* item, void* data) {
     215        usb_general_list_t* appended = usb_new(usb_general_list_t);
     216        appended->data = data;
     217        appended->next = item;
     218        appended->prev = item->prev;
     219        item->prev->next = appended;
     220        item->prev = appended;
     221}
     222
     223void usb_lst_append(usb_general_list_t* item, void* data) {
     224        usb_general_list_t* appended = usb_new(usb_general_list_t);
     225        appended->data = data;
     226        appended->next = item->next;
     227        appended->prev = item;
     228        item->next->prev = appended;
     229        item->next = appended;
     230}
     231
     232void usb_lst_remove(usb_general_list_t* item) {
     233        item->next->prev = item->prev;
     234        item->prev->next = item->next;
     235}
     236
     237static void usb_hub_test_port_status(void) {
     238        printf("[usb_hub] -------------port status test---------\n");
     239        usb_port_status_t status = 0;
     240
     241        //printf("original status %d (should be 0)\n",(uint32_t)status);
     242        usb_port_set_bit(&status, 1, 1);
     243        //printf("%d =?= 2\n",(uint32_t)status);
     244        if (status != 2) {
     245                printf("[usb_port_status] test failed: wrong set of bit 1\n");
     246                return;
     247        }
     248        usb_port_set_bit(&status, 3, 1);
     249        if (status != 10) {
     250                printf("[usb_port_status] test failed: wrong set of bit 3\n");
     251                return;
     252        }
     253
     254        usb_port_set_bit(&status, 15, 1);
     255        if (status != 10 + (1 << 15)) {
     256                printf("[usb_port_status] test failed: wrong set of bit 15\n");
     257                return;
     258        }
     259        usb_port_set_bit(&status, 1, 0);
     260        if (status != 8 + (1 << 15)) {
     261                printf("[usb_port_status] test failed: wrong unset of bit 1\n");
     262                return;
     263        }
     264        int i;
     265        for (i = 0; i < 32; ++i) {
     266                if (i == 3 || i == 15) {
     267                        if (!usb_port_get_bit(&status, i)) {
     268                                printf("[usb_port_status] test failed: wrong bit at %d\n", i);
     269                        }
     270                } else {
     271                        if (usb_port_get_bit(&status, i)) {
     272                                printf("[usb_port_status] test failed: wrong bit at %d\n", i);
     273                        }
     274                }
     275        }
     276
     277        printf("test ok\n");
     278
     279
     280        //printf("%d =?= 10\n",(uint32_t)status);
     281
     282        //printf("this should be 0: %d \n",usb_port_get_bit(&status,0));
     283        //printf("this should be 1: %d \n",usb_port_get_bit(&status,1));
     284        //printf("this should be 0: %d \n",usb_port_get_bit(&status,2));
     285        //printf("this should be 1: %d \n",usb_port_get_bit(&status,3));
     286        //printf("this should be 0: %d \n",usb_port_get_bit(&status,4));
     287
     288
     289
     290
     291}
    104292
    105293//*********************************************
    106294//
    107 //  hub driver code
     295//  hub driver code, initialization
    108296//
    109297//*********************************************
    110298
    111 usb_hcd_hub_info_t * usb_create_hub_info(device_t * device) {
    112         usb_hcd_hub_info_t* result = (usb_hcd_hub_info_t*) malloc(sizeof (usb_hcd_hub_info_t));
     299usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) {
     300        usb_hub_info_t* result = usb_new(usb_hub_info_t);
     301        //result->device = device;
     302        result->port_count = -1;
     303        /// \TODO is this correct? is the device stored?
     304        result->device = device;
     305
     306
     307        //printf("[usb_hub] phone to hc = %d\n", hc);
     308        if (hc < 0) {
     309                return result;
     310        }
     311        //get some hub info
     312        usb_address_t addr = usb_drv_get_my_address(hc, device);
     313        printf("[usb_hub] addres of newly created hub = %d\n", addr);
     314        /*if(addr<0){
     315                //return result;
     316               
     317        }*/
     318
     319        result->usb_device = usb_new(usb_hcd_attached_device_info_t);
     320        result->usb_device->address = addr;
     321
     322        // get hub descriptor
     323        usb_target_t target;
     324        target.address = addr;
     325        target.endpoint = 0;
     326        usb_device_request_setup_packet_t request;
     327        //printf("[usb_hub] creating descriptor request\n");
     328        usb_hub_set_descriptor_request(&request);
     329
     330        //printf("[usb_hub] creating serialized descriptor\n");
     331        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
     332        usb_hub_descriptor_t * descriptor;
     333        size_t received_size;
     334        int opResult;
     335        //printf("[usb_hub] starting control transaction\n");
     336        opResult = usb_drv_sync_control_read(
     337                        hc, target, &request, serialized_descriptor,
     338                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
     339        if (opResult != EOK) {
     340                printf("[usb_hub] failed when receiving hub descriptor, badcode = %d\n",opResult);
     341                ///\TODO memory leak will occur here!
     342                return result;
     343        }
     344        //printf("[usb_hub] deserializing descriptor\n");
     345        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
     346        if(descriptor==NULL){
     347                printf("[usb_hub] could not deserialize descriptor \n");
     348                result->port_count = 1;///\TODO this code is only for debug!!!
     349                return result;
     350        }
     351        //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
     352        result->port_count = descriptor->ports_count;
     353        result->attached_devs = (usb_hub_attached_device_t*)
     354            malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t));
     355        int i;
     356        for(i=0;i<result->port_count+1;++i){
     357                result->attached_devs[i].devman_handle=0;
     358                result->attached_devs[i].address=0;
     359        }
     360        //printf("[usb_hub] freeing data\n");
     361        free(serialized_descriptor);
     362        free(descriptor->devices_removable);
     363        free(descriptor);
     364
     365        //finish
     366
     367        printf("[usb_hub] hub info created\n");
    113368
    114369        return result;
    115370}
    116371
    117 /** Callback when new hub device is detected.
    118  *
    119  * @param dev New device.
    120  * @return Error code.
    121  */
    122372int usb_add_hub_device(device_t *dev) {
    123373        printf(NAME ": add_hub_device(handle=%d)\n", (int) dev->handle);
    124 
    125         check_hub_changes();
     374        printf("[usb_hub] hub device\n");
    126375
    127376        /*
     
    132381
    133382        //create the hub structure
    134         usb_hcd_hub_info_t * hub_info = usb_create_hub_info(dev);
    135         (void)hub_info;
     383        //get hc connection
     384        /// \TODO correct params
     385        int hc = usb_drv_hc_connect(dev, 0);
     386
     387        usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc);
     388        int port;
     389        int opResult;
     390        usb_device_request_setup_packet_t request;
     391        usb_target_t target;
     392        target.address = hub_info->usb_device->address;
     393        target.endpoint = 0;
     394
     395        //get configuration descriptor
     396        // this is not fully correct - there are more configurations
     397        // and all should be checked
     398        usb_standard_device_descriptor_t std_descriptor;
     399        opResult = usb_drv_req_get_device_descriptor(hc, target.address,
     400    &std_descriptor);
     401        if(opResult!=EOK){
     402                printf("[usb_hub] could not get device descriptor, %d\n",opResult);
     403                return 1;///\TODO some proper error code needed
     404        }
     405        printf("[usb_hub] hub has %d configurations\n",std_descriptor.configuration_count);
     406        if(std_descriptor.configuration_count<1){
     407                printf("[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE\n");
     408        }
     409        usb_standard_configuration_descriptor_t config_descriptor;
     410        opResult = usb_drv_req_get_bare_configuration_descriptor(hc,
     411        target.address, 0,
     412        &config_descriptor);
     413        if(opResult!=EOK){
     414                printf("[usb_hub] could not get configuration descriptor, %d\n",opResult);
     415                return 1;///\TODO some proper error code needed
     416        }
     417        //set configuration
     418        request.request_type = 0;
     419        request.request = USB_DEVREQ_SET_CONFIGURATION;
     420        request.index=0;
     421        request.length=0;
     422        request.value_high=0;
     423        request.value_low = config_descriptor.configuration_number;
     424        opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
     425        if (opResult != EOK) {
     426                printf("[usb_hub]something went wrong when setting hub`s configuration, %d\n", opResult);
     427        }
     428
     429
     430        for (port = 1; port < hub_info->port_count+1; ++port) {
     431                usb_hub_set_power_port_request(&request, port);
     432                opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
     433                printf("[usb_hub] powering port %d\n",port);
     434                if (opResult != EOK) {
     435                        printf("[usb_hub]something went wrong when setting hub`s %dth port\n", port);
     436                }
     437        }
     438        //ports powered, hub seems to be enabled
     439       
     440
     441        ipc_hangup(hc);
     442
     443        //add the hub to list
     444        usb_lst_append(&usb_hub_list, hub_info);
     445        printf("[usb_hub] hub info added to list\n");
     446        //(void)hub_info;
     447        usb_hub_check_hub_changes();
     448
     449        /// \TODO start the check loop, if not already started...
     450
     451        //this is just a test for port status bitmap type
     452        usb_hub_test_port_status();
     453
     454        printf("[usb_hub] hub dev added\n");
     455        printf("\taddress %d, has %d ports \n",
     456                        hub_info->usb_device->address,
     457                        hub_info->port_count);
     458        printf("\tused configuration %d\n",config_descriptor.configuration_number);
    136459
    137460        return EOK;
     
    139462}
    140463
     464//*********************************************
     465//
     466//  hub driver code, main loop
     467//
     468//*********************************************
     469
     470/**
     471 * reset the port with new device and reserve the default address
     472 * @param hc
     473 * @param port
     474 * @param target
     475 */
     476static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
     477        usb_device_request_setup_packet_t request;
     478        int opResult;
     479        printf("[usb_hub] some connection changed\n");
     480        //get default address
     481        opResult = usb_drv_reserve_default_address(hc);
     482        if (opResult != EOK) {
     483                printf("[usb_hub] cannot assign default address, it is probably used\n");
     484                return;
     485        }
     486        //reset port
     487        usb_hub_set_reset_port_request(&request, port);
     488        opResult = usb_drv_sync_control_write(
     489                        hc, target,
     490                        &request,
     491                        NULL, 0
     492                        );
     493        if (opResult != EOK) {
     494                //continue;
     495                printf("[usb_hub] something went wrong when reseting a port\n");
     496        }
     497}
     498
     499/**
     500 * finalize adding new device after port reset
     501 * @param hc
     502 * @param port
     503 * @param target
     504 */
     505static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
     506                int hc, uint16_t port, usb_target_t target) {
     507
     508        int opResult;
     509        printf("[usb_hub] finalizing add device\n");
     510        opResult = usb_hub_clear_port_feature(hc, target.address,
     511            port, USB_HUB_FEATURE_C_PORT_RESET);
     512        if (opResult != EOK) {
     513                goto release;
     514        }
     515
     516        /* Request address at from host controller. */
     517        usb_address_t new_device_address = usb_drv_request_address(hc);
     518        if (new_device_address < 0) {
     519                printf("[usb_hub] failed to get free USB address\n");
     520                opResult = new_device_address;
     521                goto release;
     522        }
     523        printf("[usb_hub] setting new address\n");
     524        opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
     525            new_device_address);
     526
     527        if (opResult != EOK) {
     528                printf("[usb_hub] could not set address for new device\n");
     529                goto release;
     530        }
     531
     532release:
     533        printf("[usb_hub] releasing default address\n");
     534        usb_drv_release_default_address(hc);
     535        if (opResult != EOK) {
     536                return;
     537        }
     538
     539        devman_handle_t child_handle;
     540        opResult = usb_drv_register_child_in_devman(hc, hub->device,
     541            new_device_address, &child_handle);
     542        if (opResult != EOK) {
     543                printf("[usb_hub] could not start driver for new device \n");
     544                return;
     545        }
     546        hub->attached_devs[port].devman_handle = child_handle;
     547        hub->attached_devs[port].address = new_device_address;
     548
     549        opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
     550        if (opResult != EOK) {
     551                printf("[usb_hub] could not assign address of device in hcd \n");
     552                return;
     553        }
     554        printf("[usb_hub] new device address %d, handle %d\n",
     555            new_device_address, child_handle);
     556       
     557}
     558
     559/**
     560 * unregister device address in hc, close the port
     561 * @param hc
     562 * @param port
     563 * @param target
     564 */
     565static void usb_hub_removed_device(
     566    usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {
     567        //usb_device_request_setup_packet_t request;
     568        int opResult;
     569        //disable port
     570        /*usb_hub_set_disable_port_request(&request, port);
     571        opResult = usb_drv_sync_control_write(
     572                        hc, target,
     573                        &request,
     574                        NULL, 0
     575                        );
     576        if (opResult != EOK) {
     577                //continue;
     578                printf("[usb_hub] something went wrong when disabling a port\n");
     579        }*/
     580        /// \TODO remove device
     581
     582        hub->attached_devs[port].devman_handle=0;
     583        //close address
     584        if(hub->attached_devs[port].address!=0){
     585                opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     586                if(opResult != EOK) {
     587                        printf("[usb_hub] could not release address of removed device: %d\n",opResult);
     588                }
     589                hub->attached_devs[port].address = 0;
     590        }else{
     591                printf("[usb_hub] this is strange, disconnected device had no address\n");
     592                //device was disconnected before it`s port was reset - return default address
     593                usb_drv_release_default_address(hc);
     594        }
     595}
     596
     597/**
     598 * process interrupts on given hub port
     599 * @param hc
     600 * @param port
     601 * @param target
     602 */
     603static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,
     604        uint16_t port, usb_address_t address) {
     605        printf("[usb_hub] interrupt at port %d\n", port);
     606        //determine type of change
     607        usb_target_t target;
     608        target.address=address;
     609        target.endpoint=0;
     610        usb_port_status_t status;
     611        size_t rcvd_size;
     612        usb_device_request_setup_packet_t request;
     613        int opResult;
     614        usb_hub_set_port_status_request(&request, port);
     615        //endpoint 0
     616
     617        opResult = usb_drv_sync_control_read(
     618                        hc, target,
     619                        &request,
     620                        &status, 4, &rcvd_size
     621                        );
     622        if (opResult != EOK) {
     623                printf("[usb_hub] ERROR: could not get port status\n");
     624                return;
     625        }
     626        if (rcvd_size != sizeof (usb_port_status_t)) {
     627                printf("[usb_hub] ERROR: received status has incorrect size\n");
     628                return;
     629        }
     630        //something connected/disconnected
     631        if (usb_port_connect_change(&status)) {
     632                opResult = usb_hub_clear_port_feature(hc, target.address,
     633                    port, USB_HUB_FEATURE_C_PORT_CONNECTION);
     634                // TODO: check opResult
     635                if (usb_port_dev_connected(&status)) {
     636                        printf("[usb_hub] some connection changed\n");
     637                        usb_hub_init_add_device(hc, port, target);
     638                } else {
     639                        usb_hub_removed_device(hub, hc, port, target);
     640                }
     641        }
     642        //port reset
     643        if (usb_port_reset_completed(&status)) {
     644                printf("[usb_hub] port reset complete\n");
     645                if (usb_port_enabled(&status)) {
     646                        usb_hub_finalize_add_device(hub, hc, port, target);
     647                } else {
     648                        printf("[usb_hub] ERROR: port reset, but port still not enabled\n");
     649                }
     650        }
     651
     652        usb_port_set_connect_change(&status, false);
     653        usb_port_set_reset(&status, false);
     654        usb_port_set_reset_completed(&status, false);
     655        usb_port_set_dev_connected(&status, false);
     656        if (status) {
     657                printf("[usb_hub]there was some unsupported change on port %d\n",port);
     658        }
     659        /// \TODO handle other changes
     660        /// \TODO debug log for various situations
     661
     662
     663
     664        /*
     665        //configure device
     666        usb_drv_reserve_default_address(hc);
     667
     668        usb_address_t new_device_address = usb_drv_request_address(hc);
     669
     670
     671        usb_drv_release_default_address(hc);
     672         * */
     673}
    141674
    142675/** Check changes on all known hubs.
    143676 */
    144 static void check_hub_changes(void) {
     677void usb_hub_check_hub_changes(void) {
    145678        /*
    146679         * Iterate through all hubs.
    147680         */
    148         for (; false; ) {
     681        usb_general_list_t * lst_item;
     682        for (lst_item = usb_hub_list.next;
     683                        lst_item != &usb_hub_list;
     684                        lst_item = lst_item->next) {
     685                usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
    149686                /*
    150687                 * Check status change pipe of this hub.
    151688                 */
    152                 usb_target_t target = {
    153                         .address = 5,
    154                         .endpoint = 1
    155                 };
    156 
    157                 size_t port_count = 7;
     689
     690                usb_target_t target;
     691                target.address = hub_info->usb_device->address;
     692                target.endpoint = 1;/// \TODO get from endpoint descriptor
     693                printf("[usb_hub] checking changes for hub at addr %d\n",
     694                    target.address);
     695
     696                size_t port_count = hub_info->port_count;
    158697
    159698                /*
    160699                 * Connect to respective HC.
    161700                 */
    162                 int hc = usb_drv_hc_connect(NULL, 0);
     701                int hc = usb_drv_hc_connect(hub_info->device, 0);
    163702                if (hc < 0) {
    164703                        continue;
     
    166705
    167706                // FIXME: count properly
    168                 size_t byte_length = (port_count / 8) + 1;
     707                size_t byte_length = ((port_count+1) / 8) + 1;
    169708
    170709                void *change_bitmap = malloc(byte_length);
     
    174713                /*
    175714                 * Send the request.
    176                  * FIXME: check returned value for possible errors
    177                  */
    178                 usb_drv_async_interrupt_in(hc, target,
     715                 */
     716                int opResult = usb_drv_async_interrupt_in(hc, target,
    179717                                change_bitmap, byte_length, &actual_size,
    180718                                &handle);
    181719
    182720                usb_drv_async_wait_for(handle);
     721
     722                if (opResult != EOK) {
     723                        printf("[usb_hub] something went wrong while getting status of hub\n");
     724                        continue;
     725                }
     726                unsigned int port;
     727                for (port = 1; port < port_count+1; ++port) {
     728                        bool interrupt = (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
     729                        if (interrupt) {
     730                                usb_hub_process_interrupt(
     731                                        hub_info, hc, port, hub_info->usb_device->address);
     732                        }
     733                }
     734
    183735
    184736                /*
Note: See TracChangeset for help on using the changeset viewer.