Changeset 040ab02 in mainline for uspace/drv/usbhub/usbhub.c


Ignore:
Timestamp:
2011-04-05T19:45:52Z (14 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
90d0522
Parents:
3bb6b35
Message:

usb hub global over-current and power changes

File:
1 edited

Legend:

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

    r3bb6b35 r040ab02  
    8484}
    8585
     86/// \TODO set_port_feature use
    8687
    8788//*********************************************
     
    123124        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    124125        usb_hub_descriptor_t * descriptor;
     126        int opResult;
    125127
    126128        /* this was one fix of some bug, should not be needed anymore
    127129         * these lines allow to reset hub once more, it can be used as
    128130         * brute-force initialization for non-removable devices
    129          */
    130         int opResult = usb_request_set_configuration(hub_info->control_pipe,
     131         *
     132        opResult = usb_request_set_configuration(hub_info->control_pipe,
    131133                1);
    132134        if (opResult != EOK) {
     
    134136                        opResult);
    135137                return opResult;
    136         }
     138        }*/
    137139
    138140
     
    662664 * @param port port number, starting from 1
    663665 */
    664 static void usb_hub_over_current(usb_hub_info_t * hub,
    665         uint16_t port) {
     666static void usb_hub_port_over_current(usb_hub_info_t * hub,
     667        uint16_t port, uint32_t status) {
     668        /// \todo no, this is not proper sollution
     669        /// get affected ports
     670        /// power them off
     671        /// wait until there over-current is cleared
     672        /// power them on
     673
    666674        int opResult;
    667         opResult = usb_hub_clear_port_feature(hub->control_pipe,
    668                 port, USB_HUB_FEATURE_PORT_POWER);
    669         if (opResult != EOK) {
    670                 usb_log_error("cannot power off port %d;  %d\n",
    671                         port, opResult);
     675        if(usb_port_over_current(&status)){
     676                opResult = usb_hub_clear_port_feature(hub->control_pipe,
     677                        port, USB_HUB_FEATURE_PORT_POWER);
     678                if (opResult != EOK) {
     679                        usb_log_error("cannot power off port %d;  %d\n",
     680                                port, opResult);
     681                }
     682        }else{
     683                opResult = usb_hub_set_port_feature(hub->control_pipe,
     684                        port, USB_HUB_FEATURE_PORT_POWER);
     685                if (opResult != EOK) {
     686                        usb_log_error("cannot power on port %d;  %d\n",
     687                                port, opResult);
     688                }
    672689        }
    673690}
     
    723740                //check if it was not auto-resolved
    724741                usb_log_debug("overcurrent change on port\n");
    725                 if (usb_port_over_current(&status)) {
    726                         usb_hub_over_current(hub, port);
    727                 } else {
    728                         usb_log_debug("over current condition was "
    729                                 "auto-resolved on port %d\n",
    730                                 port);
    731                 }
     742                usb_hub_port_over_current(hub, port, status);
    732743        }
    733744        //port reset
     
    752763                        port, status);
    753764
     765        }
     766}
     767
     768static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
     769        usb_hub_status_t status)
     770{
     771        int opResult;
     772        if(usb_hub_over_current(&status)){
     773                opResult = usb_hub_clear_feature(hub_info->control_pipe,
     774                        USB_HUB_FEATURE_PORT_POWER);
     775                if (opResult != EOK) {
     776                        usb_log_error("cannot power off hub: %d\n",
     777                                opResult);
     778                }
     779        }else{
     780                opResult = usb_hub_set_feature(hub_info->control_pipe,
     781                        USB_HUB_FEATURE_PORT_POWER);
     782                if (opResult != EOK) {
     783                        usb_log_error("cannot power on hub: %d\n",
     784                                opResult);
     785                }
     786        }
     787        return opResult;
     788}
     789
     790static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
     791        usb_hub_status_t status)
     792{
     793        int opResult;
     794        if(usb_hub_local_power_lost(&status)){
     795                //restart power on hub
     796                opResult = usb_hub_set_feature(hub_info->control_pipe,
     797                        USB_HUB_FEATURE_PORT_POWER);
     798                if (opResult != EOK) {
     799                        usb_log_error("cannot power on hub: %d\n",
     800                                opResult);
     801                }
     802        }else{//power reestablished on hub- restart ports
     803                int port;
     804                for(port=0;port<hub_info->port_count;++port){
     805                        opResult = usb_hub_set_port_feature(
     806                                hub_info->control_pipe,
     807                                port, USB_HUB_FEATURE_PORT_POWER);
     808                        if (opResult != EOK) {
     809                                usb_log_error("cannot power on port %d;  %d\n",
     810                                        port, opResult);
     811                        }
     812                }
     813        }
     814        return opResult;
     815}
     816
     817
     818static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info){
     819        usb_log_debug("global interrupt on a hub\n");
     820        usb_pipe_t *pipe = hub_info->control_pipe;
     821        int opResult;
     822
     823        usb_port_status_t status;
     824        size_t rcvd_size;
     825        usb_device_request_setup_packet_t request;
     826        //int opResult;
     827        usb_hub_set_hub_status_request(&request);
     828        //endpoint 0
     829
     830        opResult = usb_pipe_control_read(
     831                pipe,
     832                &request, sizeof (usb_device_request_setup_packet_t),
     833                &status, 4, &rcvd_size
     834                );
     835        if (opResult != EOK) {
     836                usb_log_error("could not get hub status\n");
     837                return;
     838        }
     839        if (rcvd_size != sizeof (usb_port_status_t)) {
     840                usb_log_error("received status has incorrect size\n");
     841                return;
     842        }
     843        //port reset
     844        if (usb_hub_over_current_change(&status)) {
     845                usb_process_hub_over_current(hub_info,status);
     846        }
     847        if (usb_hub_local_power_change(&status)) {
     848                usb_process_hub_power_change(hub_info,status);
    754849        }
    755850}
     
    866961
    867962        ///todo, opresult check, pre obe konekce
     963        bool interrupt;
     964        interrupt = ((uint8_t*)change_bitmap)[0] & 1;
     965        if(interrupt){
     966                usb_hub_process_global_interrupt(hub_info);
     967        }
    868968        for (port = 1; port < port_count + 1; ++port) {
    869                 bool interrupt =
    870                         (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
     969                interrupt =
     970                        ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8));
    871971                if (interrupt) {
    872972                        usb_hub_process_interrupt(
     
    874974                }
    875975        }
     976        /// \todo check hub status
    876977        usb_hc_connection_close(&hub_info->connection);
    877978        usb_pipe_end_session(hub_info->control_pipe);
Note: See TracChangeset for help on using the changeset viewer.