Changeset 442fa6b in mainline


Ignore:
Timestamp:
2011-09-23T14:17:59Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3b617579
Parents:
c0587d90
Message:

usbhub: More functions use new usb_hub_port_t elements.

Use per port mutex, for more than just waiting for reset to complete.
Remove shared port_mutex from the hub structure.

Location:
uspace/drv/bus/usb/usbhub
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhub/port.c

    rc0587d90 r442fa6b  
    5454};
    5555
    56 static void usb_hub_removed_device(usb_hub_info_t *hub, size_t port);
    57 static void usb_hub_port_reset_completed(const usb_hub_info_t *hub,
    58     size_t port, usb_port_status_t status);
    59 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
    60     usb_port_status_t *status);
     56static void usb_hub_port_removed_device(usb_hub_port_t *port);
     57static void usb_hub_port_reset_completed(usb_hub_port_t *port,
     58    usb_port_status_t status);
     59static int get_port_status(usb_hub_port_t *port, usb_port_status_t *status);
    6160static int enable_port_callback(int port_no, void *arg);
    6261static int add_device_phase1_worker_fibril(void *arg);
     
    7372 * @return Operation result
    7473 */
    75 int usb_hub_clear_port_feature(
     74int usb_hub_port_clear_feature(
    7675    usb_hub_port_t *port, usb_hub_class_feature_t feature)
    7776{
     
    9796 * @return Operation result
    9897 */
    99 int usb_hub_set_port_feature(
     98int usb_hub_port_set_feature(
    10099    usb_hub_port_t *port, usb_hub_class_feature_t feature)
    101100{
     
    111110            sizeof(clear_request), NULL, 0);
    112111}
    113 
     112/*----------------------------------------------------------------------------*/
     113void usb_hub_port_reset_fail(usb_hub_port_t *port)
     114{
     115        assert(port);
     116        fibril_mutex_lock(&port->mutex);
     117        port->reset_completed = true;
     118        port->reset_okay = false;
     119        fibril_condvar_broadcast(&port->reset_cv);
     120        fibril_mutex_unlock(&port->mutex);
     121}
     122/*----------------------------------------------------------------------------*/
    114123/**
    115124 * Process interrupts on given hub port
     
    119128 * @param port port number, starting from 1
    120129 */
    121 void usb_hub_process_port_interrupt(usb_hub_info_t *hub, size_t port)
     130void usb_hub_port_process_interrupt(usb_hub_info_t *hub, size_t port)
    122131{
    123132        usb_log_debug("Interrupt at port %zu\n", port);
     
    125134        usb_port_status_t status;
    126135        const int opResult =
    127             get_port_status(&hub->usb_device->ctrl_pipe, port, &status);
     136            get_port_status(&hub->ports[port], &status);
    128137        if (opResult != EOK) {
    129138                usb_log_error("Failed to get port %zu status: %s.\n",
     
    140149                /* ACK the change */
    141150                const int opResult =
    142                     usb_hub_clear_port_feature(&hub->ports[port],
     151                    usb_hub_port_clear_feature(&hub->ports[port],
    143152                        USB_HUB_FEATURE_C_PORT_CONNECTION);
    144153                if (opResult != EOK) {
     
    157166                        }
    158167                } else {
    159                         usb_hub_removed_device(hub, port);
     168                        usb_hub_port_removed_device(&hub->ports[port]);
    160169                }
    161170        }
     
    191200        /* Port reset, set on port reset complete. */
    192201        if (status & USB_HUB_PORT_C_STATUS_RESET) {
    193                 usb_hub_port_reset_completed(hub, port, status);
     202                usb_hub_port_reset_completed(&hub->ports[port], status);
    194203        }
    195204
     
    206215 * @param port port number, starting from 1
    207216 */
    208 static void usb_hub_removed_device(usb_hub_info_t *hub, size_t port)
    209 {
    210         /** \TODO remove device from device manager - not yet implemented in
    211          * devide manager
    212          */
    213         usb_hub_port_t *the_port = hub->ports + port;
    214 
    215         fibril_mutex_lock(&hub->port_mutex);
    216 
    217         if (the_port->attached_device.address >= 0) {
     217static void usb_hub_port_removed_device(usb_hub_port_t *port)
     218{
     219        assert(port);
     220        // TODO remove device from device manager
     221
     222
     223        if (port->attached_device.address >= 0) {
     224#if 0
    218225                usb_log_warning("Device unplug on `%s' (port %zu): " \
    219226                    "not implemented.\n", hub->usb_device->ddf_dev->name,
    220227                    (size_t) port);
    221                 the_port->attached_device.address = -1;
    222                 the_port->attached_device.handle = 0;
     228#endif
     229                fibril_mutex_lock(&port->mutex);
     230                port->attached_device.address = -1;
     231                port->attached_device.handle = 0;
     232                fibril_mutex_unlock(&port->mutex);
    223233        } else {
    224234                usb_log_warning("Device removed before being registered.\n");
     
    229239                 * port reset callback from new device wrapper.
    230240                 */
    231                 fibril_mutex_lock(&the_port->reset_mutex);
    232                 the_port->reset_completed = true;
    233                 the_port->reset_okay = false;
    234                 fibril_condvar_broadcast(&the_port->reset_cv);
    235                 fibril_mutex_unlock(&the_port->reset_mutex);
    236         }
    237 
    238         fibril_mutex_unlock(&hub->port_mutex);
     241                usb_hub_port_reset_fail(port);
     242        }
    239243}
    240244
     
    248252 * @param status
    249253 */
    250 static void usb_hub_port_reset_completed(const usb_hub_info_t *hub,
    251     size_t port, usb_port_status_t status)
    252 {
    253         usb_hub_port_t *the_port = hub->ports + port;
    254         fibril_mutex_lock(&the_port->reset_mutex);
     254static void usb_hub_port_reset_completed(usb_hub_port_t *port,
     255    usb_port_status_t status)
     256{
     257        assert(port);
     258        fibril_mutex_lock(&port->mutex);
    255259        /* Finalize device adding. */
    256         the_port->reset_completed = true;
    257         the_port->reset_okay = (status & USB_HUB_PORT_STATUS_ENABLED) != 0;
    258 
    259         if (the_port->reset_okay) {
    260                 usb_log_debug("Port %zu reset complete.\n", port);
     260        port->reset_completed = true;
     261        port->reset_okay = (status & USB_HUB_PORT_STATUS_ENABLED) != 0;
     262
     263        if (port->reset_okay) {
     264                usb_log_debug("Port %zu reset complete.\n", port->port_number);
    261265        } else {
    262266                usb_log_warning(
    263                     "Port %zu reset complete but port not enabled.\n", port);
    264         }
    265         fibril_condvar_broadcast(&the_port->reset_cv);
    266         fibril_mutex_unlock(&the_port->reset_mutex);
     267                    "Port %zu reset complete but port not enabled.\n",
     268                    port->port_number);
     269        }
     270        fibril_condvar_broadcast(&port->reset_cv);
     271        fibril_mutex_unlock(&port->mutex);
    267272
    268273        /* Clear the port reset change. */
    269         int rc = usb_hub_clear_port_feature(&hub->ports[port],
    270             USB_HUB_FEATURE_C_PORT_RESET);
     274        int rc = usb_hub_port_clear_feature(port, USB_HUB_FEATURE_C_PORT_RESET);
    271275        if (rc != EOK) {
    272                 usb_log_error("Failed to clear port %d reset feature: %s.\n",
    273                     port, str_error(rc));
     276                usb_log_error(
     277                    "Failed to clear port %d reset change feature: %s.\n",
     278                    port->port_number, str_error(rc));
    274279        }
    275280}
     
    282287 * @return Error code.
    283288 */
    284 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
    285     usb_port_status_t *status)
    286 {
    287         size_t recv_size;
    288         usb_port_status_t status_tmp;
     289static int get_port_status(usb_hub_port_t *port, usb_port_status_t *status)
     290{
     291        assert(port);
    289292        /* USB hub specific GET_PORT_STATUS request. See USB Spec 11.16.2.6
    290293         * Generic GET_STATUS request cannot be used because of the difference
     
    294297                .request = USB_HUB_REQUEST_GET_STATUS,
    295298                .value = 0,
    296                 .index = port,
     299                .index = port->port_number,
    297300                .length = sizeof(usb_port_status_t),
    298301        };
    299 
    300         const int rc = usb_pipe_control_read(ctrl_pipe,
     302        size_t recv_size;
     303        usb_port_status_t status_tmp;
     304
     305        const int rc = usb_pipe_control_read(port->control_pipe,
    301306            &request, sizeof(usb_device_request_setup_packet_t),
    302307            &status_tmp, sizeof(status_tmp), &recv_size);
     
    329334        usb_hub_port_t *port = arg;
    330335        const int rc =
    331             usb_hub_set_port_feature(port, USB_HUB_FEATURE_PORT_RESET);
     336            usb_hub_port_set_feature(port, USB_HUB_FEATURE_PORT_RESET);
    332337        if (rc != EOK) {
    333338                usb_log_warning("Port reset failed: %s.\n", str_error(rc));
     
    338343         * Wait until reset completes.
    339344         */
    340         fibril_mutex_lock(&port->reset_mutex);
     345        fibril_mutex_lock(&port->mutex);
    341346        while (!port->reset_completed) {
    342                 fibril_condvar_wait(&port->reset_cv, &port->reset_mutex);
    343         }
    344         fibril_mutex_unlock(&port->reset_mutex);
     347                fibril_condvar_wait(&port->reset_cv, &port->mutex);
     348        }
     349        fibril_mutex_unlock(&port->mutex);
    345350
    346351        if (port->reset_okay) {
     
    380385        }
    381386
    382         fibril_mutex_lock(&data->hub->port_mutex);
     387        fibril_mutex_lock(&data->hub->ports[data->port].mutex);
    383388        data->hub->ports[data->port].attached_device.handle = child_handle;
    384389        data->hub->ports[data->port].attached_device.address = new_address;
    385         fibril_mutex_unlock(&data->hub->port_mutex);
     390        fibril_mutex_unlock(&data->hub->ports[data->port].mutex);
    386391
    387392        usb_log_info("Detected new device on `%s' (port %zu), "
     
    426431        usb_hub_port_t *the_port = hub->ports + port;
    427432
    428         fibril_mutex_lock(&the_port->reset_mutex);
     433        fibril_mutex_lock(&the_port->mutex);
    429434        the_port->reset_completed = false;
    430         fibril_mutex_unlock(&the_port->reset_mutex);
     435        fibril_mutex_unlock(&the_port->mutex);
    431436
    432437        fid_t fibril = fibril_create(add_device_phase1_worker_fibril, data);
  • uspace/drv/bus/usb/usbhub/port.h

    rc0587d90 r442fa6b  
    4646        size_t port_number;
    4747        usb_pipe_t *control_pipe;
    48         /** Mutex needed by CV for checking port reset. */
    49         fibril_mutex_t reset_mutex;
     48        /** Mutex needed not only by CV for checking port reset. */
     49        fibril_mutex_t mutex;
    5050        /** CV for waiting to port reset completion. */
    5151        fibril_condvar_t reset_cv;
     
    7373        port->port_number = port_number;
    7474        port->control_pipe = control_pipe;
    75         fibril_mutex_initialize(&port->reset_mutex);
     75        fibril_mutex_initialize(&port->mutex);
    7676        fibril_condvar_initialize(&port->reset_cv);
    7777}
    7878
     79void usb_hub_port_reset_fail(usb_hub_port_t *port);
    7980
    80 void usb_hub_process_port_interrupt(usb_hub_info_t *hub, size_t port);
    81 int usb_hub_clear_port_feature(
     81void usb_hub_port_process_interrupt(usb_hub_info_t *hub, size_t port);
     82int usb_hub_port_clear_feature(
    8283    usb_hub_port_t *port, usb_hub_class_feature_t feature);
    83 int usb_hub_set_port_feature(
     84int usb_hub_port_set_feature(
    8485    usb_hub_port_t *port, usb_hub_class_feature_t feature);
    8586
  • uspace/drv/bus/usb/usbhub/usbhub.c

    rc0587d90 r442fa6b  
    187187                const bool change = (change_bitmap[port / 8] >> (port % 8)) & 1;
    188188                if (change) {
    189                         usb_hub_process_port_interrupt(hub, port);
     189                        usb_hub_port_process_interrupt(hub, port);
    190190                }
    191191        }
     
    217217        info->ports = NULL;
    218218        info->port_count = -1;
    219         fibril_mutex_initialize(&info->port_mutex);
    220219        fibril_mutex_initialize(&info->pending_ops_mutex);
    221220        fibril_condvar_initialize(&info->pending_ops_cv);
     
    289288                for (port = 1; port <= hub_info->port_count; ++port) {
    290289                        usb_log_debug("Powering port %zu.\n", port);
    291                         opResult = usb_hub_set_port_feature(
     290                        opResult = usb_hub_port_set_feature(
    292291                            &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER);
    293292                        if (opResult != EOK) {
     
    365364                 * switch them all off to prevent damage. */
    366365                //TODO Consider ganged power switching here.
     366                //TODO Hub should have turned the ports off already,
     367                //this is redundant.
    367368                size_t port;
    368369                for (port = 1; port <= hub_info->port_count; ++port) {
    369                         const int opResult = usb_hub_clear_port_feature(
     370                        const int opResult = usb_hub_port_clear_feature(
    370371                            &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER);
    371372                        if (opResult != EOK) {
     
    381382                size_t port;
    382383                for (port = 1; port <= hub_info->port_count; ++port) {
    383                         const int opResult = usb_hub_set_port_feature(
     384                        const int opResult = usb_hub_port_set_feature(
    384385                            &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER);
    385386                        if (opResult != EOK) {
     
    478479         */
    479480        if (hub->pending_ops_count > 0) {
    480                 fibril_mutex_lock(&hub->port_mutex);
    481481                size_t port;
    482482                for (port = 0; port < hub->port_count; port++) {
    483                         usb_hub_port_t *the_port = hub->ports + port;
    484                         fibril_mutex_lock(&the_port->reset_mutex);
    485                         the_port->reset_completed = true;
    486                         the_port->reset_okay = false;
    487                         fibril_condvar_broadcast(&the_port->reset_cv);
    488                         fibril_mutex_unlock(&the_port->reset_mutex);
     483                        usb_hub_port_reset_fail(&hub->ports[port]);
    489484                }
    490                 fibril_mutex_unlock(&hub->port_mutex);
    491485        }
    492486        /* And now wait for them. */
  • uspace/drv/bus/usb/usbhub/usbhub.h

    rc0587d90 r442fa6b  
    5959        usb_hub_port_t *ports;
    6060
    61         fibril_mutex_t port_mutex;
    62 
    6361        /** Connection to hcd */
    6462        usb_hc_connection_t connection;
Note: See TracChangeset for help on using the changeset viewer.