Changeset 3e490eb in mainline


Ignore:
Timestamp:
2011-04-09T08:19:55Z (14 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8961c22
Parents:
36cd378
Message:

attempt to merge usb/development hub changes

Location:
uspace/drv/usbhub
Files:
2 edited

Legend:

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

    r36cd378 r3e490eb  
    3737#include <errno.h>
    3838#include <str_error.h>
     39#include <inttypes.h>
    3940
    4041#include <usb_iface.h>
     
    5455
    5556
    56 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
    57         usb_speed_t speed);
     57/** Information for fibril for device discovery. */
     58struct add_device_phase1 {
     59        usb_hub_info_t *hub;
     60        size_t port;
     61        usb_speed_t speed;
     62};
     63
    5864
    5965static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);
     
    6571static int usb_hub_release_default_address(usb_hub_info_t * hub);
    6672
    67 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
    68         usb_speed_t speed);
    69 
    70 static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
    71         uint16_t port, usb_speed_t speed);
     73//static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     74//      usb_speed_t speed);
     75
     76//static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
     77//      uint16_t port, usb_speed_t speed);
    7278
    7379static void usb_hub_removed_device(
     
    7783        uint16_t port, uint32_t status);
    7884
     85static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
     86    usb_port_status_t *status);
     87
     88static int enable_port_callback(int port_no, void *arg);
     89
     90static int add_device_phase1_worker_fibril(void *arg);
     91
     92static int add_device_phase1_new_fibril(usb_hub_info_t *hub, size_t port,
     93    usb_speed_t speed);
     94
    7995static void usb_hub_process_interrupt(usb_hub_info_t * hub,
    8096        uint16_t port);
     
    91107//      unsigned int port);
    92108
    93 static int usb_hub_trigger_connecting_non_removable_devices(
    94         usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
     109//static int usb_hub_trigger_connecting_non_removable_devices(
     110//      usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
    95111
    96112
     
    104120 * @return zero
    105121 */
     122/*
    106123int usb_hub_control_loop(void * hub_info_param) {
    107124        usb_hub_info_t * hub_info = (usb_hub_info_t*) hub_info_param;
     
    117134        return 0;
    118135}
     136 */
    119137/// \TODO malloc checking
    120138
     
    183201        assert(rc == EOK);
    184202
    185         //create fibril for the hub control loop
    186         fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
    187         if (fid == 0) {
    188                 usb_log_error("failed to start monitoring fibril for new"
    189                         " hub.\n");
    190                 return ENOMEM;
    191         }
    192         fibril_add_ready(fid);
    193         usb_log_debug("Hub fibril created.\n");
     203        /*
     204         * The processing will require opened control pipe and connection
     205         * to the host controller.
     206         * It is waste of resources but let's hope there will be less
     207         * hubs than the phone limit.
     208         * FIXME: with some proper locking over pipes and session
     209         * auto destruction, this could work better.
     210         */
     211        rc = usb_pipe_start_session(&usb_dev->ctrl_pipe);
     212        if (rc != EOK) {
     213                usb_log_error("Failed to start session on control pipe: %s.\n",
     214                    str_error(rc));
     215                goto leave;
     216        }
     217        rc = usb_hc_connection_open(&hub_info->connection);
     218        if (rc != EOK) {
     219                usb_pipe_end_session(&usb_dev->ctrl_pipe);
     220                usb_log_error("Failed to open connection to HC: %s.\n",
     221                    str_error(rc));
     222                goto leave;
     223        }
     224
     225        rc = usb_device_auto_poll(hub_info->usb_device, 0,
     226            hub_port_changes_callback, ((hub_info->port_count+1) / 8) + 1,
     227            NULL, hub_info);
     228        if (rc != EOK) {
     229                usb_log_error("Failed to create polling fibril: %s.\n",
     230                    str_error(rc));
     231                free(hub_info);
     232                return rc;
     233        }
    194234
    195235        usb_log_info("Controlling hub `%s' (%d ports).\n",
    196236                hub_info->usb_device->ddf_dev->name, hub_info->port_count);
    197237        return EOK;
     238leave:
     239        free(hub_info);
     240
     241        return rc;
    198242}
    199243
     
    204248//
    205249//*********************************************
     250
     251
     252/** Callback for polling hub for port changes.
     253 *
     254 * @param dev Device where the change occured.
     255 * @param change_bitmap Bitmap of changed ports.
     256 * @param change_bitmap_size Size of the bitmap in bytes.
     257 * @param arg Custom argument, points to @c usb_hub_info_t.
     258 * @return Whether to continue polling.
     259 */
     260bool hub_port_changes_callback(usb_device_t *dev,
     261    uint8_t *change_bitmap, size_t change_bitmap_size, void *arg)
     262{
     263        usb_hub_info_t *hub = (usb_hub_info_t *) arg;
     264
     265        /* FIXME: check that we received enough bytes. */
     266        if (change_bitmap_size == 0) {
     267                goto leave;
     268        }
     269
     270        size_t port;
     271        for (port = 1; port < hub->port_count + 1; port++) {
     272                bool change = (change_bitmap[port / 8] >> (port % 8)) % 2;
     273                if (change) {
     274                        usb_hub_process_interrupt(hub, port);
     275                }
     276        }
     277
     278
     279leave:
     280        /* FIXME: proper interval. */
     281        async_usleep(1000 * 1000 * 10 );
     282
     283        return true;
     284}
     285
    206286
    207287/**
     
    378458        hub_info->port_count = descriptor->ports_count;
    379459        /// \TODO check attached_devices array: this is not semantically correct
    380         hub_info->attached_devs = (usb_hc_attached_device_t*)
    381                 malloc((hub_info->port_count + 1) *
    382                         sizeof (usb_hc_attached_device_t)
    383                 );
    384         int i;
    385         for (i = 1; i <= hub_info->port_count; ++i) {
    386                 hub_info->attached_devs[i].handle = 0;
    387                 hub_info->attached_devs[i].address = 0;
    388                 usb_log_info("powering port %d\n",i);
    389                 opResult = usb_hub_set_port_feature(
    390                         hub_info->control_pipe,
    391                         i,
    392                         USB_HUB_FEATURE_PORT_POWER);
    393                 if(opResult!=EOK)
    394                         usb_log_warning("could not power port %d\n",i);
    395 
     460        //hub_info->attached_devs = (usb_hc_attached_device_t*)
     461//              malloc((hub_info->port_count + 1) *
     462//                      sizeof (usb_hc_attached_device_t)
     463//              );
     464        hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1));
     465        size_t port;
     466        for (port = 0; port < hub_info->port_count + 1; port++) {
     467                usb_hub_port_init(&hub_info->ports[port]);
    396468        }
    397469        //handle non-removable devices
    398         usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
     470        //usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
    399471        usb_log_debug2("freeing data\n");
    400472        free(serialized_descriptor);
    401         //hub_info->descriptor = descriptor;
    402         /*hub_info->not_initialized_non_removables =
    403                 (uint8_t*) malloc((hub_info->port_count + 8) / 8);
    404         memcpy(hub_info->not_initialized_non_removables,
    405                 descriptor->devices_removable,
    406                 (hub_info->port_count + 8) / 8
    407                 );
    408                 */
    409473        free(descriptor->devices_removable);
    410474        free(descriptor);
     
    470534}
    471535
     536#if 0
    472537/**
    473538 * Reset the port with new device and reserve the default address.
     
    517582        return opResult;
    518583}
    519 
     584#endif
     585
     586#if 0
    520587/**
    521588 * Finalize adding new device after port reset
     
    611678                new_device_address, child_handle);
    612679}
     680#endif
    613681
    614682/**
     
    634702
    635703        //close address
    636         if (hub->attached_devs[port].address != 0) {
     704        //if (hub->attached_devs[port].address != 0) {
     705        if(hub->ports[port].attached_device.address >= 0){
    637706                /*uncomment this code to use it when DDF allows device removal
    638707                opResult = usb_hc_unregister_device(
     
    684753}
    685754
     755/** Retrieve port status.
     756 *
     757 * @param[in] ctrl_pipe Control pipe to use.
     758 * @param[in] port Port number (starting at 1).
     759 * @param[out] status Where to store the port status.
     760 * @return Error code.
     761 */
     762static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
     763    usb_port_status_t *status)
     764{
     765        size_t recv_size;
     766        usb_device_request_setup_packet_t request;
     767        usb_port_status_t status_tmp;
     768
     769        usb_hub_set_port_status_request(&request, port);
     770        int rc = usb_pipe_control_read(ctrl_pipe,
     771            &request, sizeof(usb_device_request_setup_packet_t),
     772            &status_tmp, sizeof(status_tmp), &recv_size);
     773        if (rc != EOK) {
     774                return rc;
     775        }
     776
     777        if (recv_size != sizeof (status_tmp)) {
     778                return ELIMIT;
     779        }
     780
     781        if (status != NULL) {
     782                *status = status_tmp;
     783        }
     784
     785        return EOK;
     786}
     787
     788/** Callback for enabling a specific port.
     789 *
     790 * We wait on a CV until port is reseted.
     791 * That is announced via change on interrupt pipe.
     792 *
     793 * @param port_no Port number (starting at 1).
     794 * @param arg Custom argument, points to @c usb_hub_info_t.
     795 * @return Error code.
     796 */
     797static int enable_port_callback(int port_no, void *arg)
     798{
     799        usb_hub_info_t *hub = (usb_hub_info_t *) arg;
     800        int rc;
     801        usb_device_request_setup_packet_t request;
     802        usb_hub_port_t *my_port = hub->ports + port_no;
     803
     804        usb_hub_set_reset_port_request(&request, port_no);
     805        rc = usb_pipe_control_write(hub->control_pipe,
     806            &request, sizeof(request), NULL, 0);
     807        if (rc != EOK) {
     808                usb_log_warning("Port reset failed: %s.\n", str_error(rc));
     809                return rc;
     810        }
     811
     812        /*
     813         * Wait until reset completes.
     814         */
     815        fibril_mutex_lock(&my_port->reset_mutex);
     816        while (!my_port->reset_completed) {
     817                fibril_condvar_wait(&my_port->reset_cv, &my_port->reset_mutex);
     818        }
     819        fibril_mutex_unlock(&my_port->reset_mutex);
     820
     821        /* Clear the port reset change. */
     822        rc = usb_hub_clear_port_feature(hub->control_pipe,
     823            port_no, USB_HUB_FEATURE_C_PORT_RESET);
     824        if (rc != EOK) {
     825                usb_log_error("Failed to clear port %d reset feature: %s.\n",
     826                    port_no, str_error(rc));
     827                return rc;
     828        }
     829
     830        return EOK;
     831}
     832
     833/** Fibril for adding a new device.
     834 *
     835 * Separate fibril is needed because the port reset completion is announced
     836 * via interrupt pipe and thus we cannot block here.
     837 *
     838 * @param arg Pointer to struct add_device_phase1.
     839 * @return 0 Always.
     840 */
     841static int add_device_phase1_worker_fibril(void *arg)
     842{
     843        struct add_device_phase1 *data
     844            = (struct add_device_phase1 *) arg;
     845
     846        usb_address_t new_address;
     847        devman_handle_t child_handle;
     848
     849        int rc = usb_hc_new_device_wrapper(data->hub->usb_device->ddf_dev,
     850            &data->hub->connection, data->speed,
     851            enable_port_callback, (int) data->port, data->hub,
     852            &new_address, &child_handle,
     853            NULL, NULL, NULL);
     854
     855        if (rc != EOK) {
     856                usb_log_error("Failed registering device on port %zu: %s.\n",
     857                    data->port, str_error(rc));
     858                goto leave;
     859        }
     860
     861        data->hub->ports[data->port].attached_device.handle = child_handle;
     862        data->hub->ports[data->port].attached_device.address = new_address;
     863
     864        usb_log_info("Detected new device on `%s' (port %zu), "
     865            "address %d (handle %" PRIun ").\n",
     866            data->hub->usb_device->ddf_dev->name, data->port,
     867            new_address, child_handle);
     868
     869leave:
     870        free(arg);
     871
     872        return EOK;
     873}
     874
     875
     876/** Start device adding when connection change is detected.
     877 *
     878 * This fires a new fibril to complete the device addition.
     879 *
     880 * @param hub Hub where the change occured.
     881 * @param port Port index (starting at 1).
     882 * @param speed Speed of the device.
     883 * @return Error code.
     884 */
     885static int add_device_phase1_new_fibril(usb_hub_info_t *hub, size_t port,
     886    usb_speed_t speed)
     887{
     888        struct add_device_phase1 *data
     889            = malloc(sizeof(struct add_device_phase1));
     890        if (data == NULL) {
     891                return ENOMEM;
     892        }
     893        data->hub = hub;
     894        data->port = port;
     895        data->speed = speed;
     896
     897        usb_hub_port_t *the_port = hub->ports + port;
     898
     899        fibril_mutex_lock(&the_port->reset_mutex);
     900        the_port->reset_completed = false;
     901        fibril_mutex_unlock(&the_port->reset_mutex);
     902
     903        int rc = usb_hub_clear_port_feature(hub->control_pipe, port,
     904            USB_HUB_FEATURE_C_PORT_CONNECTION);
     905        if (rc != EOK) {
     906                free(data);
     907                usb_log_warning("Failed to clear port change flag: %s.\n",
     908                    str_error(rc));
     909                return rc;
     910        }
     911
     912        fid_t fibril = fibril_create(add_device_phase1_worker_fibril, data);
     913        if (fibril == 0) {
     914                free(data);
     915                return ENOMEM;
     916        }
     917        fibril_add_ready(fibril);
     918
     919        return EOK;
     920}
     921
     922
    686923/**
    687924 * Process interrupts on given hub port
     
    695932        usb_log_debug("interrupt at port %d\n", port);
    696933        //determine type of change
    697         usb_pipe_t *pipe = hub->control_pipe;
     934        //usb_pipe_t *pipe = hub->control_pipe;
    698935
    699936        int opResult;
    700937
    701938        usb_port_status_t status;
    702         size_t rcvd_size;
    703         usb_device_request_setup_packet_t request;
    704         //int opResult;
    705         usb_hub_set_port_status_request(&request, port);
    706         //endpoint 0
    707 
    708         opResult = usb_pipe_control_read(
    709                 pipe,
    710                 &request, sizeof (usb_device_request_setup_packet_t),
    711                 &status, 4, &rcvd_size
    712                 );
    713         if (opResult != EOK) {
    714                 usb_log_error("could not get port status\n");
     939        opResult = get_port_status(&hub->usb_device->ctrl_pipe, port, &status);
     940        if (opResult != EOK) {
     941                usb_log_error("Failed to get port %zu status: %s.\n",
     942                    port, str_error(opResult));
    715943                return;
    716944        }
    717         if (rcvd_size != sizeof (usb_port_status_t)) {
    718                 usb_log_error("received status has incorrect size\n");
    719                 return;
    720         }
     945
    721946        //something connected/disconnected
     947        /*
    722948        if (usb_port_connect_change(&status)) {
    723949                usb_log_debug("connection change on port\n");
     
    728954                        usb_hub_removed_device(hub, port);
    729955                }
     956        }*/
     957        if (usb_port_connect_change(&status)) {
     958                bool device_connected = usb_port_dev_connected(&status);
     959                usb_log_debug("Connection change on port %zu: %s.\n", port,
     960                    device_connected ? "device attached" : "device removed");
     961
     962                if (device_connected) {
     963                        opResult = add_device_phase1_new_fibril(hub, port,
     964                            usb_port_speed(&status));
     965                        if (opResult != EOK) {
     966                                usb_log_error(
     967                                    "Cannot handle change on port %zu: %s.\n",
     968                                    str_error(opResult));
     969                        }
     970                } else {
     971                        usb_hub_removed_device(hub, port);
     972                }
    730973        }
    731974        //over current
     
    737980        //port reset
    738981        if (usb_port_reset_completed(&status)) {
     982                /*
    739983                usb_log_debug("port reset complete\n");
    740984                if (usb_port_enabled(&status)) {
     
    744988                        usb_log_warning("port reset, but port still not "
    745989                                "enabled\n");
     990                }
     991                 * */
     992                usb_log_debug("Port %zu reset complete.\n", port);
     993                if (usb_port_enabled(&status)) {
     994                        /* Finalize device adding. */
     995                        usb_hub_port_t *the_port = hub->ports + port;
     996                        fibril_mutex_lock(&the_port->reset_mutex);
     997                        the_port->reset_completed = true;
     998                        fibril_condvar_broadcast(&the_port->reset_cv);
     999                        fibril_mutex_unlock(&the_port->reset_mutex);
     1000                } else {
     1001                        usb_log_warning(
     1002                            "Port %zu reset complete but port not enabled.\n",
     1003                            port);
    7461004                }
    7471005        }
     
    8131071                }
    8141072        }else{//power reestablished on hub- restart ports
    815                 int port;
     1073                size_t port;
    8161074                for(port=0;port<hub_info->port_count;++port){
    8171075                        opResult = usb_hub_set_port_feature(
     
    8681126}
    8691127
    870 //-----------attempts to solve non-removable------------------------
    871 //-----------attempts to solve non-removable------------------------
    872 //-----------attempts to solve non-removable------------------------
    873 //-----------attempts to solve non-removable------------------------
    874 
    875 /**
    876  * this is an attempt to initialize non-removable devices in the hub
    877  *
    878  * @param hub_info hub instance
    879  * @param port port number, counting from 1
    880  * @return error code
    881  */
    882 #if 0
    883 static int initialize_non_removable(usb_hub_info_t * hub_info,
    884         unsigned int port) {
    885         int opResult;
    886         usb_log_debug("there is not pluged in non-removable device on "
    887                 "port %d\n", port
    888                 );
    889         //usb_hub_init_add_device(hub_info, port, usb_port_speed(&status));
    890         usb_port_status_t status;
    891         size_t rcvd_size;
    892         usb_device_request_setup_packet_t request;
    893         //int opResult;
    894         usb_hub_set_port_status_request(&request, port);
    895         //endpoint 0
    896 
    897         opResult = usb_pipe_control_read(
    898                 hub_info->control_pipe,
    899                 &request, sizeof (usb_device_request_setup_packet_t),
    900                 &status, 4, &rcvd_size
    901                 );
    902         if (opResult != EOK) {
    903                 usb_log_error("could not get port status %d\n", opResult);
    904                 return opResult;
    905         }
    906         if (rcvd_size != sizeof (usb_port_status_t)) {
    907                 usb_log_error("received status has incorrect size\n");
    908                 return opResult;
    909         }
    910         usb_log_debug("port status %d, x%x\n", status, status);
    911         if (usb_port_dev_connected(&status)) {
    912                 usb_log_debug("there is connected device on this port\n");
    913                 opResult = usb_hub_init_add_device(hub_info, port,
    914                         usb_port_speed(&status));
    915         }else{
    916                 usb_log_debug("the non-removable device is not connected\n");
    917                 opResult = EINVAL;
    918         }
    919        
    920         return opResult;
    921 }
    922 #endif
    923 /**
    924  * triggers actions to connect non0removable devices
    925  *
    926  * This will trigger operations leading to activated non-removable device.
    927  * Control pipe of the hub must be open fo communication.
    928  * @param hub hub representation
    929  * @param descriptor usb hub descriptor
    930  * @return error code
    931  */
    932 static int usb_hub_trigger_connecting_non_removable_devices(
    933         usb_hub_info_t * hub,
    934         usb_hub_descriptor_t * descriptor) {
    935         usb_log_info("attaching non-removable devices(if any)\n");
    936         //usb_device_request_setup_packet_t request;
    937         int opResult;
    938         //size_t rcvd_size;
    939         //usb_port_status_t status;
    940         uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;
    941         int port;
    942 #if 0
    943         opResult = usb_request_set_configuration(hub->control_pipe,
    944                 1);
    945         if (opResult != EOK) {
    946                 usb_log_error("could not set default configuration, errno %d",
    947                         opResult);
    948                 return opResult;
    949         }
    950 
    951         for (port = 1; port <= descriptor->ports_count; ++port) {
    952                 bool is_non_removable =
    953                         ((non_removable_dev_bitmap[port / 8]) >> (port % 8)) % 2;
    954                 if (is_non_removable) {
    955                         usb_log_debug("non-removable device on port %d\n", port);
    956                         usb_hub_set_port_status_request(&request, port);
    957                         opResult = usb_pipe_control_read(
    958                                 hub->control_pipe,
    959                                 &request,
    960                                 sizeof (usb_device_request_setup_packet_t),
    961                                 &status, 4, &rcvd_size
    962                                 );
    963                         if (opResult != EOK) {
    964                                 usb_log_error("could not get port status of "
    965                                         "port %d errno:%d\n",
    966                                         port, opResult);
    967                                 return opResult;
    968                         }
    969                         //try to reset port
    970                         if (usb_port_dev_connected(&status) || true) {
    971                                 usb_hub_set_enable_port_feature_request(
    972                                         &request, port,
    973                                         USB_HUB_FEATURE_PORT_RESET);
    974                                 opResult = usb_pipe_control_read(
    975                                         hub->control_pipe,
    976                                         &request,
    977                                         sizeof (usb_device_request_setup_packet_t),
    978                                         &status, 4, &rcvd_size
    979                                         );
    980                                 if (opResult != EOK) {
    981                                         usb_log_warning(
    982                                                 "could not reset port %d "
    983                                                 "errno:%d\n",
    984                                                 port, opResult);
    985                                 }
    986                                 usb_log_debug("port reset, should look like "
    987                                         "%d,x%x\n",
    988                                         (1 << USB_HUB_FEATURE_PORT_RESET),
    989                                         (1 << USB_HUB_FEATURE_PORT_RESET)
    990                                         );
    991                         }
    992                         //set the status change bit, so it will be noticed
    993                         //in driver loop
    994                         if (usb_port_dev_connected(&status) && false) {
    995                                 usb_hub_set_disable_port_feature_request(
    996                                         &request, port,
    997                                         USB_HUB_FEATURE_PORT_CONNECTION);
    998                                 opResult = usb_pipe_control_read(
    999                                         hub->control_pipe,
    1000                                         &request,
    1001                                         sizeof (usb_device_request_setup_packet_t),
    1002                                         &status, 4, &rcvd_size
    1003                                         );
    1004                                 if (opResult != EOK) {
    1005                                         usb_log_warning(
    1006                                                 "could not clear port "
    1007                                                 "connection on port %d "
    1008                                                 "errno:%d\n",
    1009                                                 port, opResult);
    1010                                 }
    1011                                 usb_log_debug("cleared port connection\n");
    1012                                 usb_hub_set_enable_port_feature_request(&request,
    1013                                         port,
    1014                                         USB_HUB_FEATURE_PORT_ENABLE);
    1015                                 opResult = usb_pipe_control_read(
    1016                                         hub->control_pipe,
    1017                                         &request,
    1018                                         sizeof (usb_device_request_setup_packet_t),
    1019                                         &status, 4, &rcvd_size
    1020                                         );
    1021                                 if (opResult != EOK) {
    1022                                         usb_log_warning(
    1023                                                 "could not set port enabled "
    1024                                                 "on port %d errno:%d\n",
    1025                                                 port, opResult);
    1026                                 }
    1027                                 usb_log_debug("port set to enabled - "
    1028                                         "should lead to connection change\n");
    1029                         }
    1030                 }
    1031         }
    1032 #endif
    1033 
    1034         /// \TODO this is just a debug code
    1035         for (port = 1; port <= descriptor->ports_count; ++port) {
    1036                 bool is_non_removable =
    1037                         ((non_removable_dev_bitmap[(port-1) / 8]) >> ((port-1) % 8)) % 2;
    1038                 if (is_non_removable) {
    1039                         usb_log_debug("CHECKING port %d is non-removable\n",
    1040                                 port);
    1041                         usb_port_status_t status;
    1042                         size_t rcvd_size;
    1043                         usb_device_request_setup_packet_t request;
    1044                         //int opResult;
    1045                         usb_hub_set_port_status_request(&request, port);
    1046                         //endpoint 0
    1047                         opResult = usb_pipe_control_read(
    1048                                 hub->control_pipe,
    1049                                 &request,
    1050                                 sizeof (usb_device_request_setup_packet_t),
    1051                                 &status, 4, &rcvd_size
    1052                                 );
    1053                         if (opResult != EOK) {
    1054                                 usb_log_error("could not get port status %d\n",
    1055                                         opResult);
    1056                         }
    1057                         if (rcvd_size != sizeof (usb_port_status_t)) {
    1058                                 usb_log_error("received status has incorrect"
    1059                                         " size\n");
    1060                         }
    1061                         //something connected/disconnected
    1062                         if (usb_port_connect_change(&status)) {
    1063                                 usb_log_debug("some connection changed\n");
    1064                         }
    1065                         if(usb_port_dev_connected(&status)){
    1066                                 usb_log_debug("device connected on port\n");
    1067                         }
    1068                         usb_log_debug("status: %s\n", usb_debug_str_buffer(
    1069                                 (uint8_t *) & status, 4, 4));
    1070                 }
    1071         }
    1072         async_usleep(1000*1000*10);
    1073         return EOK;
    1074 }
    10751128
    10761129
  • uspace/drv/usbhub/usbhub.h

    r36cd378 r3e490eb  
    4848#include <usb/devdrv.h>
    4949
     50#include <fibril_synch.h>
     51
     52
     53/** Information about single port on a hub. */
     54typedef struct {
     55        /** Mutex needed by CV for checking port reset. */
     56        fibril_mutex_t reset_mutex;
     57        /** CV for waiting to port reset completion. */
     58        fibril_condvar_t reset_cv;
     59        /** Whether port reset is completed.
     60         * Guarded by @c reset_mutex.
     61         */
     62        bool reset_completed;
     63
     64        /** Information about attached device. */
     65        usb_hc_attached_device_t attached_device;
     66} usb_hub_port_t;
     67
     68/** Initialize hub port information.
     69 *
     70 * @param port Port to be initialized.
     71 */
     72static inline void usb_hub_port_init(usb_hub_port_t *port) {
     73        port->attached_device.address = -1;
     74        port->attached_device.handle = 0;
     75        fibril_mutex_initialize(&port->reset_mutex);
     76        fibril_condvar_initialize(&port->reset_cv);
     77}
     78
    5079/** Information about attached hub. */
    5180typedef struct {
    5281        /** Number of ports. */
    53         int port_count;
     82        size_t port_count;
    5483
    5584        /** attached device handles, for each port one */
    56         usb_hc_attached_device_t * attached_devs;
     85        usb_hub_port_t *ports;
    5786
    5887        /** connection to hcd */
     
    86115} usb_hub_info_t;
    87116
    88 /**
    89  * function running the hub-controlling loop.
    90  * @param hub_info_param hub info pointer
    91  */
    92 int usb_hub_control_loop(void * hub_info_param);
     117//int usb_hub_control_loop(void * hub_info_param);
    93118
    94119int usb_hub_add_device(usb_device_t * usb_dev);
    95120
    96 /**
    97  * Check changes on specified hub
    98  * @param hub_info_param pointer to usb_hub_info_t structure
    99  * @return error code if there is problem when initializing communication with
    100  * hub, EOK otherwise
    101  */
    102121int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
    103122
    104 
     123bool hub_port_changes_callback(usb_device_t *dev,
     124    uint8_t *change_bitmap, size_t change_bitmap_size, void *arg);
    105125#endif
    106126/**
Note: See TracChangeset for help on using the changeset viewer.