Changeset 0212751 in mainline


Ignore:
Timestamp:
2011-09-23T19:06:37Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
aefa0d5
Parents:
4559d89
Message:

usbhub: IMplement some easy TODOs

Convert process_intterrupt to use usb_hub_port_t structure instead of index.

Location:
uspace
Files:
4 edited

Legend:

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

    r4559d89 r0212751  
    128128 * @param port port number, starting from 1
    129129 */
    130 void usb_hub_port_process_interrupt(usb_hub_info_t *hub, size_t port)
    131 {
    132         usb_log_debug("Interrupt at port %zu\n", port);
     130void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub)
     131{
     132        assert(port);
     133        assert(hub);
     134        usb_log_debug("Interrupt at port %zu\n", port->port_number);
    133135
    134136        usb_port_status_t status;
    135         const int opResult =
    136             get_port_status(&hub->ports[port], &status);
     137        const int opResult = get_port_status(port, &status);
    137138        if (opResult != EOK) {
    138139                usb_log_error("Failed to get port %zu status: %s.\n",
    139                     port, str_error(opResult));
     140                    port->port_number, str_error(opResult));
    140141                return;
    141142        }
     
    143144        /* Connection change */
    144145        if (status & USB_HUB_PORT_C_STATUS_CONNECTION) {
    145                 const bool device_connected =
     146                const bool connected =
    146147                    (status & USB_HUB_PORT_STATUS_CONNECTION) != 0;
    147148                usb_log_debug("Connection change on port %zu: device %s.\n",
    148                     port, device_connected ? "attached" : "removed");
     149                    port->port_number, connected ? "attached" : "removed");
    149150                /* ACK the change */
    150                 const int opResult =
    151                     usb_hub_port_clear_feature(&hub->ports[port],
    152                         USB_HUB_FEATURE_C_PORT_CONNECTION);
     151                const int opResult = usb_hub_port_clear_feature(port,
     152                    USB_HUB_FEATURE_C_PORT_CONNECTION);
    153153                if (opResult != EOK) {
    154                         usb_log_warning("Failed to clear "
    155                             "port-change-connection flag: %s.\n",
    156                             str_error(opResult));
    157                 }
    158 
    159                 if (device_connected) {
    160                         const int opResult = create_add_device_fibril(hub, port,
    161                             usb_port_speed(status));
     154                        usb_log_warning("Failed to clear port-change-connection"
     155                            " flag: %s.\n", str_error(opResult));
     156                }
     157
     158                if (connected) {
     159                        const int opResult = create_add_device_fibril(hub,
     160                            port->port_number, usb_port_speed(status));
    162161                        if (opResult != EOK) {
    163162                                usb_log_error(
    164163                                    "Cannot handle change on port %zu: %s.\n",
    165                                     port, str_error(opResult));
     164                                    port->port_number, str_error(opResult));
    166165                        }
    167166                } else {
    168                         usb_hub_port_removed_device(&hub->ports[port]);
     167                        usb_hub_port_removed_device(port);
    169168                }
    170169        }
     
    172171        /* Enable change, ports are automatically disabled on errors. */
    173172        if (status & USB_HUB_PORT_C_STATUS_ENABLED) {
    174                 // TODO: Remove device that was connected
    175                 // TODO: Clear feature C_PORT_ENABLE
     173                usb_hub_port_removed_device(port);
     174                const int rc = usb_hub_port_clear_feature(port,
     175                        USB_HUB_FEATURE_C_PORT_ENABLE);
     176                if (rc != EOK) {
     177                        usb_log_error(
     178                            "Failed to clear port %zu enable change feature: "
     179                            "%s.\n", port->port_number, str_error(rc));
     180                }
    176181
    177182        }
     
    180185        if (status & USB_HUB_PORT_C_STATUS_SUSPEND) {
    181186                usb_log_error("Port %zu went to suspend state, this should"
    182                     "NOT happen as we do not support suspend state!", port);
    183                 // TODO: Clear feature C_PORT_SUSPEND
     187                    "NOT happen as we do not support suspend state!",
     188                    port->port_number);
     189                const int rc = usb_hub_port_clear_feature(port,
     190                        USB_HUB_FEATURE_C_PORT_SUSPEND);
     191                if (rc != EOK) {
     192                        usb_log_error(
     193                            "Failed to clear port %zu suspend change feature: "
     194                            "%s.\n", port->port_number, str_error(rc));
     195                }
    184196        }
    185197
     
    190202                 * Hub device is responsible for putting port in power off
    191203                 * mode. USB system software is responsible for powering port
    192                  * back on when the over-curent condition is gone */
     204                 * back on when the over-current condition is gone */
     205                const int rc = usb_hub_port_clear_feature(port,
     206                    USB_HUB_FEATURE_C_PORT_OVER_CURRENT);
     207                if (rc != EOK) {
     208                        usb_log_error(
     209                            "Failed to clear port %zu OC change feature: %s.\n",
     210                            port->port_number, str_error(rc));
     211                }
    193212                if (!(status & ~USB_HUB_PORT_STATUS_OC)) {
    194                         // TODO: Power port on, this will cause connect
    195                         // change and device initialization.
    196                 }
    197                 // TODO: Ack over-power change.
     213                        const int rc = usb_hub_port_set_feature(
     214                            port, USB_HUB_FEATURE_PORT_POWER);
     215                        if (rc != EOK) {
     216                                usb_log_error(
     217                                    "Failed to set port %d power after OC:"
     218                                    " %s.\n", port->port_number, str_error(rc));
     219                        }
     220                }
    198221        }
    199222
    200223        /* Port reset, set on port reset complete. */
    201224        if (status & USB_HUB_PORT_C_STATUS_RESET) {
    202                 usb_hub_port_reset_completed(&hub->ports[port], status);
    203         }
    204 
    205         usb_log_debug("Port %zu status 0x%08" PRIx32 "\n", port, status);
     225                usb_hub_port_reset_completed(port, status);
     226        }
     227
     228        usb_log_debug("Port %zu status 0x%08" PRIx32 "\n",
     229            port->port_number, status);
    206230}
    207231
  • uspace/drv/bus/usb/usbhub/port.h

    r4559d89 r0212751  
    7979
    8080void usb_hub_port_reset_fail(usb_hub_port_t *port);
    81 void usb_hub_port_process_interrupt(usb_hub_info_t *hub, size_t port);
     81void usb_hub_port_process_interrupt(usb_hub_port_t *port, usb_hub_info_t *hub);
    8282int usb_hub_port_clear_feature(
    8383    usb_hub_port_t *port, usb_hub_class_feature_t feature);
  • uspace/drv/bus/usb/usbhub/usbhub.c

    r4559d89 r0212751  
    170170        usb_log_debug("hub_port_changes_callback\n");
    171171        usb_hub_info_t *hub = arg;
    172 
    173         /* FIXME: check that we received enough bytes. */
     172        assert(hub);
     173
     174        /* It is an error condition if we didn't receive enough data */
    174175        if (change_bitmap_size == 0) {
    175                 goto leave;
     176                return false;
    176177        }
    177178
     
    187188                const bool change = (change_bitmap[port / 8] >> (port % 8)) & 1;
    188189                if (change) {
    189                         usb_hub_port_process_interrupt(hub, port);
     190                        usb_hub_port_process_interrupt(&hub->ports[port], hub);
    190191                }
    191192        }
    192 leave:
    193         /* FIXME: proper interval. */
    194         // TODO Interval should be handled by USB HC scheduler not here
    195         async_usleep(1000 * 250);
    196 
    197193        return true;
    198194}
     
    256252        hub_info->port_count = descriptor.port_count;
    257253
    258         // TODO Why +1 ?
     254        // TODO: +1 hack is no longer necessary
    259255        hub_info->ports =
    260256            malloc(sizeof(usb_hub_port_t) * (hub_info->port_count + 1));
     
    349345{
    350346        if (status & USB_HUB_STATUS_OVER_CURRENT) {
    351                 /* Over-current detected on one or all ports,
    352                  * switch them all off to prevent damage. */
    353                 //TODO Consider ganged power switching here.
    354                 //TODO Hub should have turned the ports off already,
    355                 //this is redundant.
    356                 size_t port;
    357                 for (port = 1; port <= hub_info->port_count; ++port) {
    358                         const int opResult = usb_hub_port_clear_feature(
    359                             &hub_info->ports[port], USB_HUB_FEATURE_PORT_POWER);
    360                         if (opResult != EOK) {
    361                                 usb_log_warning(
    362                                     "HUB OVER-CURRENT: Cannot power off port"
    363                                     " %d:  %s\n",
    364                                     port, str_error(opResult));
    365                         }
    366                 }
     347                /* Hub should remove power from all ports if it detects OC */
     348                usb_log_warning("Detected hub over-current condition, "
     349                    "all ports should be powered off.");
    367350        } else {
    368351                /* Over-current condition is gone, it is safe to turn the
     
    379362                        }
    380363                }
     364        }
     365        const int opResult = usb_request_clear_feature(
     366            &hub_info->usb_device->ctrl_pipe, USB_REQUEST_TYPE_CLASS,
     367            USB_REQUEST_RECIPIENT_DEVICE,
     368            USB_HUB_FEATURE_C_HUB_LOCAL_POWER, 0);
     369        if (opResult != EOK) {
     370                usb_log_error(
     371                    "Failed to clear hub over-current change flag: %s.\n",
     372                    str_error(opResult));
    381373        }
    382374}
  • uspace/lib/usb/include/usb/classes/hub.h

    r4559d89 r0212751  
    7676#define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1)
    7777        /* Unused part of characteristics field */
    78         uint8_t characteristics_reservered;
     78        uint8_t characteristics_reserved;
    7979        /** Time from power-on to stabilization of current on the port. */
    8080        uint8_t power_good_time;
Note: See TracChangeset for help on using the changeset viewer.