Changeset a209648 in mainline for uspace/drv/usbhub/usbhub.c


Ignore:
Timestamp:
2011-04-05T20:27:38Z (14 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e5ccfd1
Parents:
3dba1ca
Message:

some code unmessing

File:
1 edited

Legend:

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

    r3dba1ca ra209648  
    6060        usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
    6161
     62static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);
     63
     64static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info);
     65
     66static int usb_hub_set_configuration(usb_hub_info_t * hub_info);
     67
     68
     69static int usb_hub_trigger_connecting_non_removable_devices(
     70        usb_hub_info_t * hub,
     71        usb_hub_descriptor_t * descriptor);
     72
     73static int usb_hub_release_default_address(usb_hub_info_t * hub);
     74
     75static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     76        usb_speed_t speed);
     77
     78static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
     79        uint16_t port, usb_speed_t speed);
     80
     81static void usb_hub_removed_device(
     82        usb_hub_info_t * hub, uint16_t port);
     83
     84static void usb_hub_port_over_current(usb_hub_info_t * hub,
     85        uint16_t port, uint32_t status);
     86
     87static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     88        uint16_t port);
     89
     90static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
     91        usb_hub_status_t status);
     92
     93static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
     94        usb_hub_status_t status);
     95
     96static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);
     97
     98static int initialize_non_removable(usb_hub_info_t * hub_info,
     99        unsigned int port);
     100
    62101/**
    63102 * control loop running in hub`s fibril
     
    89128//
    90129//  hub driver code, initialization
     130//
     131//*********************************************
     132
     133
     134
     135/**
     136 * Initialize hub device driver fibril
     137 *
     138 * Creates hub representation and fibril that periodically checks hub`s status.
     139 * Hub representation is passed to the fibril.
     140 * @param usb_dev generic usb device information
     141 * @return error code
     142 */
     143int usb_hub_add_device(usb_device_t * usb_dev) {
     144        if (!usb_dev) return EINVAL;
     145        usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
     146        //create hc connection
     147        usb_log_debug("Initializing USB wire abstraction.\n");
     148        int opResult = usb_hc_connection_initialize_from_device(
     149                &hub_info->connection,
     150                hub_info->usb_device->ddf_dev);
     151        if (opResult != EOK) {
     152                usb_log_error("could not initialize connection to device, "
     153                        "errno %d\n",
     154                        opResult);
     155                free(hub_info);
     156                return opResult;
     157        }
     158
     159        usb_pipe_start_session(hub_info->control_pipe);
     160        //set hub configuration
     161        opResult = usb_hub_set_configuration(hub_info);
     162        if (opResult != EOK) {
     163                usb_log_error("could not set hub configuration, errno %d\n",
     164                        opResult);
     165                free(hub_info);
     166                return opResult;
     167        }
     168        //get port count and create attached_devs
     169        opResult = usb_hub_process_hub_specific_info(hub_info);
     170        if (opResult != EOK) {
     171                usb_log_error("could not set hub configuration, errno %d\n",
     172                        opResult);
     173                free(hub_info);
     174                return opResult;
     175        }
     176        usb_pipe_end_session(hub_info->control_pipe);
     177
     178
     179        /// \TODO what is this?
     180        usb_log_debug("Creating `hub' function.\n");
     181        ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
     182                fun_exposed, "hub");
     183        assert(hub_fun != NULL);
     184        hub_fun->ops = NULL;
     185
     186        int rc = ddf_fun_bind(hub_fun);
     187        assert(rc == EOK);
     188        rc = ddf_fun_add_to_class(hub_fun, "hub");
     189        assert(rc == EOK);
     190
     191        //create fibril for the hub control loop
     192        fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
     193        if (fid == 0) {
     194                usb_log_error("failed to start monitoring fibril for new"
     195                        " hub.\n");
     196                return ENOMEM;
     197        }
     198        fibril_add_ready(fid);
     199        usb_log_debug("Hub fibril created.\n");
     200
     201        usb_log_info("Controlling hub `%s' (%d ports).\n",
     202                hub_info->usb_device->ddf_dev->name, hub_info->port_count);
     203        return EOK;
     204}
     205
     206
     207//*********************************************
     208//
     209//  hub driver code, main loop and port handling
     210//
     211//*********************************************
     212
     213/**
     214 * check changes on hub
     215 *
     216 * Handles changes on each port with a status change.
     217 * @param hub_info hub representation
     218 * @return error code
     219 */
     220int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) {
     221        int opResult;
     222        opResult = usb_pipe_start_session(
     223                hub_info->status_change_pipe);
     224        //this might not be necessary - if all non-removables are ok, it is
     225        //not needed here
     226        opResult = usb_pipe_start_session(hub_info->control_pipe);
     227        if (opResult != EOK) {
     228                usb_log_error("could not initialize communication for hub; %d\n",
     229                        opResult);
     230                return opResult;
     231        }
     232
     233        size_t port_count = hub_info->port_count;
     234        //first check non-removable devices
     235        {
     236                unsigned int port;
     237                for (port = 1; port <= port_count; ++port) {
     238                        bool is_non_removable =
     239                                hub_info->not_initialized_non_removables[port/8]
     240                                & (1 << (port % 8));
     241                        if (is_non_removable) {
     242                                opResult = initialize_non_removable(hub_info,
     243                                        port);
     244                        }
     245                }
     246        }
     247
     248
     249        /// FIXME: count properly
     250        size_t byte_length = ((port_count + 1) / 8) + 1;
     251        void *change_bitmap = malloc(byte_length);
     252        size_t actual_size;
     253
     254        /*
     255         * Send the request.
     256         */
     257        opResult = usb_pipe_read(
     258                hub_info->status_change_pipe,
     259                change_bitmap, byte_length, &actual_size
     260                );
     261
     262        if (opResult != EOK) {
     263                free(change_bitmap);
     264                usb_log_warning("something went wrong while getting the"
     265                        "status of hub\n");
     266                usb_pipe_end_session(hub_info->status_change_pipe);
     267                return opResult;
     268        }
     269        unsigned int port;
     270
     271        if (opResult != EOK) {
     272                usb_log_error("could not start control pipe session %d\n",
     273                        opResult);
     274                usb_pipe_end_session(hub_info->status_change_pipe);
     275                return opResult;
     276        }
     277        opResult = usb_hc_connection_open(&hub_info->connection);
     278        if (opResult != EOK) {
     279                usb_log_error("could not start host controller session %d\n",
     280                        opResult);
     281                usb_pipe_end_session(hub_info->control_pipe);
     282                usb_pipe_end_session(hub_info->status_change_pipe);
     283                return opResult;
     284        }
     285
     286        ///todo, opresult check, pre obe konekce
     287        bool interrupt;
     288        interrupt = ((uint8_t*)change_bitmap)[0] & 1;
     289        if(interrupt){
     290                usb_hub_process_global_interrupt(hub_info);
     291        }
     292        for (port = 1; port < port_count + 1; ++port) {
     293                interrupt =
     294                        ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8));
     295                if (interrupt) {
     296                        usb_hub_process_interrupt(
     297                                hub_info, port);
     298                }
     299        }
     300        /// \todo check hub status
     301        usb_hc_connection_close(&hub_info->connection);
     302        usb_pipe_end_session(hub_info->control_pipe);
     303        usb_pipe_end_session(hub_info->status_change_pipe);
     304        free(change_bitmap);
     305        return EOK;
     306}
     307
     308//*********************************************
     309//
     310//  support functions
    91311//
    92312//*********************************************
     
    108328        return result;
    109329}
     330
    110331
    111332/**
     
    226447}
    227448
    228 /**
    229  * Initialize hub device driver fibril
    230  *
    231  * Creates hub representation and fibril that periodically checks hub`s status.
    232  * Hub representation is passed to the fibril.
    233  * @param usb_dev generic usb device information
    234  * @return error code
    235  */
    236 int usb_hub_add_device(usb_device_t * usb_dev) {
    237         if (!usb_dev) return EINVAL;
    238         usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
    239         //create hc connection
    240         usb_log_debug("Initializing USB wire abstraction.\n");
    241         int opResult = usb_hc_connection_initialize_from_device(
    242                 &hub_info->connection,
    243                 hub_info->usb_device->ddf_dev);
    244         if (opResult != EOK) {
    245                 usb_log_error("could not initialize connection to device, "
    246                         "errno %d\n",
    247                         opResult);
    248                 free(hub_info);
    249                 return opResult;
    250         }
    251 
    252         usb_pipe_start_session(hub_info->control_pipe);
    253         //set hub configuration
    254         opResult = usb_hub_set_configuration(hub_info);
    255         if (opResult != EOK) {
    256                 usb_log_error("could not set hub configuration, errno %d\n",
    257                         opResult);
    258                 free(hub_info);
    259                 return opResult;
    260         }
    261         //get port count and create attached_devs
    262         opResult = usb_hub_process_hub_specific_info(hub_info);
    263         if (opResult != EOK) {
    264                 usb_log_error("could not set hub configuration, errno %d\n",
    265                         opResult);
    266                 free(hub_info);
    267                 return opResult;
    268         }
    269         usb_pipe_end_session(hub_info->control_pipe);
    270 
    271 
    272         /// \TODO what is this?
    273         usb_log_debug("Creating `hub' function.\n");
    274         ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
    275                 fun_exposed, "hub");
    276         assert(hub_fun != NULL);
    277         hub_fun->ops = NULL;
    278 
    279         int rc = ddf_fun_bind(hub_fun);
    280         assert(rc == EOK);
    281         rc = ddf_fun_add_to_class(hub_fun, "hub");
    282         assert(rc == EOK);
    283 
    284         //create fibril for the hub control loop
    285         fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
    286         if (fid == 0) {
    287                 usb_log_error("failed to start monitoring fibril for new"
    288                         " hub.\n");
    289                 return ENOMEM;
    290         }
    291         fibril_add_ready(fid);
    292         usb_log_debug("Hub fibril created.\n");
    293 
    294         usb_log_info("Controlling hub `%s' (%d ports).\n",
    295                 hub_info->usb_device->ddf_dev->name, hub_info->port_count);
    296         return EOK;
    297 }
    298 
    299 
    300 //*********************************************
    301 //
    302 //  hub driver code, main loop and port handling
    303 //
    304 //*********************************************
    305449
    306450/**
     
    8751019/**
    8761020 * this is an attempt to initialize non-removable devices in the hub
    877  * 
     1021 *
    8781022 * @param hub_info hub instance
    8791023 * @param port port number, counting from 1
     
    9171061}
    9181062
    919 /**
    920  * check changes on hub
    921  *
    922  * Handles changes on each port with a status change.
    923  * @param hub_info hub representation
    924  * @return error code
    925  */
    926 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) {
    927         int opResult;
    928         opResult = usb_pipe_start_session(
    929                 hub_info->status_change_pipe);
    930         //this might not be necessary - if all non-removables are ok, it is
    931         //not needed here
    932         opResult = usb_pipe_start_session(hub_info->control_pipe);
    933         if (opResult != EOK) {
    934                 usb_log_error("could not initialize communication for hub; %d\n",
    935                         opResult);
    936                 return opResult;
    937         }
    938 
    939         size_t port_count = hub_info->port_count;
    940         //first check non-removable devices
    941         {
    942                 unsigned int port;
    943                 for (port = 1; port <= port_count; ++port) {
    944                         bool is_non_removable =
    945                                 hub_info->not_initialized_non_removables[port/8]
    946                                 & (1 << (port % 8));
    947                         if (is_non_removable) {
    948                                 opResult = initialize_non_removable(hub_info,
    949                                         port);
    950                         }
    951                 }
    952         }
    953 
    954 
    955         /// FIXME: count properly
    956         size_t byte_length = ((port_count + 1) / 8) + 1;
    957         void *change_bitmap = malloc(byte_length);
    958         size_t actual_size;
    959 
    960         /*
    961          * Send the request.
    962          */
    963         opResult = usb_pipe_read(
    964                 hub_info->status_change_pipe,
    965                 change_bitmap, byte_length, &actual_size
    966                 );
    967 
    968         if (opResult != EOK) {
    969                 free(change_bitmap);
    970                 usb_log_warning("something went wrong while getting the"
    971                         "status of hub\n");
    972                 usb_pipe_end_session(hub_info->status_change_pipe);
    973                 return opResult;
    974         }
    975         unsigned int port;
    976 
    977         if (opResult != EOK) {
    978                 usb_log_error("could not start control pipe session %d\n",
    979                         opResult);
    980                 usb_pipe_end_session(hub_info->status_change_pipe);
    981                 return opResult;
    982         }
    983         opResult = usb_hc_connection_open(&hub_info->connection);
    984         if (opResult != EOK) {
    985                 usb_log_error("could not start host controller session %d\n",
    986                         opResult);
    987                 usb_pipe_end_session(hub_info->control_pipe);
    988                 usb_pipe_end_session(hub_info->status_change_pipe);
    989                 return opResult;
    990         }
    991 
    992         ///todo, opresult check, pre obe konekce
    993         bool interrupt;
    994         interrupt = ((uint8_t*)change_bitmap)[0] & 1;
    995         if(interrupt){
    996                 usb_hub_process_global_interrupt(hub_info);
    997         }
    998         for (port = 1; port < port_count + 1; ++port) {
    999                 interrupt =
    1000                         ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8));
    1001                 if (interrupt) {
    1002                         usb_hub_process_interrupt(
    1003                                 hub_info, port);
    1004                 }
    1005         }
    1006         /// \todo check hub status
    1007         usb_hc_connection_close(&hub_info->connection);
    1008         usb_pipe_end_session(hub_info->control_pipe);
    1009         usb_pipe_end_session(hub_info->status_change_pipe);
    1010         free(change_bitmap);
    1011         return EOK;
    1012 }
    1013 
    10141063
    10151064
Note: See TracChangeset for help on using the changeset viewer.