Changeset cd4b184 in mainline


Ignore:
Timestamp:
2011-02-25T16:23:20Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc34f32f
Parents:
d493ac17
Message:

fixed use of new usb pipe api
each hub has it`s own fibril

Location:
uspace/drv/usbhub
Files:
4 edited

Legend:

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

    rd493ac17 rcd4b184  
    3434#include <errno.h>
    3535#include <async.h>
     36#include <stdio.h>
    3637
    3738#include "usbhub.h"
     
    5152};
    5253
     54/*
    5355int usb_hub_control_loop(void * noparam){
    5456        while(true){
     
    5860        return 0;
    5961}
    60 
     62*/
    6163
    6264int main(int argc, char *argv[])
    6365{
    6466        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    65        
     67        dprintf(USB_LOG_LEVEL_INFO, "starting hub driver");
     68
     69        //this is probably not needed anymore
    6670        fibril_mutex_initialize(&usb_hub_list_lock);
    6771        fibril_mutex_lock(&usb_hub_list_lock);
    6872        usb_lst_init(&usb_hub_list);
    6973        fibril_mutex_unlock(&usb_hub_list_lock);
    70 
     74       
     75/*
    7176        fid_t fid = fibril_create(usb_hub_control_loop, NULL);
    7277        if (fid == 0) {
     
    7681        }
    7782        fibril_add_ready(fid);
    78 
     83*/
    7984        return ddf_driver_main(&hub_driver);
    8085}
  • uspace/drv/usbhub/port_status.h

    rd493ac17 rcd4b184  
    177177}
    178178
     179/**
     180 * set the device request to be a port disable request
     181 * @param request
     182 * @param port
     183 */
     184static inline void usb_hub_unset_power_port_request(
     185usb_device_request_setup_packet_t * request, uint16_t port
     186){
     187        request->index = port;
     188        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     189        request->request = USB_HUB_REQUEST_CLEAR_FEATURE;
     190        request->value = USB_HUB_FEATURE_PORT_POWER;
     191        request->length = 0;
     192}
     193
    179194/** get i`th bit of port status */
    180195static inline bool usb_port_get_bit(usb_port_status_t * status, int idx)
  • uspace/drv/usbhub/usbhub.c

    rd493ac17 rcd4b184  
    4444#include <usb/request.h>
    4545#include <usb/classes/hub.h>
     46#include <stdio.h>
    4647
    4748#include "usbhub.h"
     
    5657};
    5758
    58 /** Hub status-change endpoint description */
     59/** Hub status-change endpoint description
     60 *
     61 * For more see usb hub specification in 11.15.1 of
     62 */
    5963static usb_endpoint_description_t status_change_endpoint_description = {
    6064        .transfer_type = USB_TRANSFER_INTERRUPT,
    6165        .direction = USB_DIRECTION_IN,
    6266        .interface_class = USB_CLASS_HUB,
     67        .interface_subclass = 0,
     68        .interface_protocol = 0,
    6369        .flags = 0
    6470};
     71
     72int usb_hub_control_loop(void * hub_info_param){
     73        usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
     74        while(true){
     75                usb_hub_check_hub_changes(hub_info);
     76                async_usleep(1000 * 1000 );/// \TODO proper number once
     77        }
     78        return 0;
     79}
    6580
    6681
     
    329344
    330345        //add the hub to list
     346        //is this needed now?
    331347        fibril_mutex_lock(&usb_hub_list_lock);
    332348        usb_lst_append(&usb_hub_list, hub_info);
    333349        fibril_mutex_unlock(&usb_hub_list_lock);
    334 
    335350        dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list");
     351
     352        fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
     353        if (fid == 0) {
     354                dprintf(USB_LOG_LEVEL_ERROR,
     355                                ": failed to start monitoring fibril for new hub");
     356                return ENOMEM;
     357        }
     358        fibril_add_ready(fid);
     359
     360        dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created");
    336361        //(void)hub_info;
    337         usb_hub_check_hub_changes();
     362        //usb_hub_check_hub_changes();
    338363       
    339364        dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
     
    368393        //opResult = usb_drv_reserve_default_address(hc);
    369394        opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
    370 
    371         if (opResult != EOK) {
    372                 dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used");
     395       
     396        if (opResult != EOK) {
     397                dprintf(USB_LOG_LEVEL_WARNING,
     398                                "cannot assign default address, it is probably used %d",opResult);
    373399                return;
    374400        }
     
    381407                        );
    382408        if (opResult != EOK) {
    383                 dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port");
     409                dprintf(USB_LOG_LEVEL_ERROR,
     410                                "something went wrong when reseting a port %d",opResult);
    384411                //usb_hub_release_default_address(hc);
    385412                usb_hc_release_default_address(&hub->connection);
     
    419446
    420447
    421 
    422 
    423 
    424448        /* Request address from host controller. */
    425449        usb_address_t new_device_address = usb_hc_request_address(
     
    436460        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    437461        //    new_device_address);
     462        usb_endpoint_pipe_start_session(&new_device_pipe);
    438463        opResult = usb_request_set_address(&new_device_pipe,new_device_address);
    439 
    440         if (opResult != EOK) {
    441                 dprintf(USB_LOG_LEVEL_ERROR, "could not set address for new device");
     464        usb_endpoint_pipe_end_session(&new_device_pipe);
     465        if (opResult != EOK) {
     466                dprintf(USB_LOG_LEVEL_ERROR,
     467                                "could not set address for new device %d",opResult);
    442468                usb_hc_release_default_address(&hub->connection);
    443469                return;
     
    458484
    459485        if (opResult != EOK) {
    460                 dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device");
     486                dprintf(USB_LOG_LEVEL_ERROR,
     487                                "could not start driver for new device %d",opResult);
    461488                return;
    462489        }
     
    469496                        &hub->attached_devs[port]);
    470497        if (opResult != EOK) {
    471                 dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd");
     498                dprintf(USB_LOG_LEVEL_ERROR,
     499                                "could not assign address of device in hcd %d",opResult);
    472500                return;
    473501        }
     
    511539}
    512540
     541
     542/**
     543 *Process over current condition on port.
     544 *
     545 * Turn off the power on the port.
     546 *
     547 * @param hub
     548 * @param port
     549 */
     550static void usb_hub_over_current( usb_hub_info_t * hub,
     551                uint16_t port){
     552        int opResult;
     553        opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
     554            port, USB_HUB_FEATURE_PORT_POWER);
     555        if(opResult!=EOK){
     556                dprintf(USB_LOG_LEVEL_ERROR, "cannot power off port %d;  %d",
     557                                port, opResult);
     558        }
     559}
     560
    513561/**
    514562 * Process interrupts on given hub port
     
    522570        //determine type of change
    523571        usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
    524         int opResult = usb_endpoint_pipe_start_session(pipe);
     572        //int opResult = usb_endpoint_pipe_start_session(pipe);
    525573       
    526         if(opResult != EOK){
     574        /*if(opResult != EOK){
    527575                dprintf(USB_LOG_LEVEL_ERROR, "cannot open pipe %d", opResult);
    528         }
     576        }*/
     577        int opResult;
    529578
    530579        /*
     
    547596                        );
    548597        if (opResult != EOK) {
    549                 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: could not get port status");
     598                dprintf(USB_LOG_LEVEL_ERROR, "could not get port status");
    550599                return;
    551600        }
    552601        if (rcvd_size != sizeof (usb_port_status_t)) {
    553                 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: received status has incorrect size");
     602                dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size");
    554603                return;
    555604        }
     
    566615                }
    567616        }
     617        //over current
     618        if (usb_port_overcurrent_change(&status)) {
     619                //check if it was not auto-resolved
     620                if(usb_port_over_current(&status)){
     621                        usb_hub_over_current(hub,port);
     622                }else{
     623                        dprintf(USB_LOG_LEVEL_INFO,
     624                                "over current condition was auto-resolved on port %d",port);
     625                }
     626        }
    568627        //port reset
    569628        if (usb_port_reset_completed(&status)) {
     
    572631                        usb_hub_finalize_add_device(hub, port);
    573632                } else {
    574                         dprintf(USB_LOG_LEVEL_WARNING, "ERROR: port reset, but port still not enabled");
     633                        dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled");
    575634                }
    576635        }
     
    586645        /// \TODO handle other changes
    587646        /// \TODO debug log for various situations
    588         usb_endpoint_pipe_end_session(pipe);
    589 
    590 
     647        //usb_endpoint_pipe_end_session(pipe);
     648
     649
     650}
     651
     652/**
     653 * Check changes on particular hub
     654 * @param hub_info_param
     655 */
     656void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
     657        int opResult;
     658        opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
     659        if(opResult != EOK){
     660                dprintf(USB_LOG_LEVEL_ERROR,
     661                                "could not initialize communication for hub; %d", opResult);
     662                return;
     663        }
     664
     665        /*
     666         * Check status change pipe of this hub.
     667         */
     668        /*
     669        usb_target_t target;
     670        target.address = hub_info->address;
     671        target.endpoint = 1;/// \TODO get from endpoint descriptor
     672        dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d",
     673            target.address);
     674        */
     675        size_t port_count = hub_info->port_count;
     676
     677        /*
     678         * Connect to respective HC.
     679         *
     680        int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
     681        if (hc < 0) {
     682        continue;
     683        }*/
     684
     685        /// FIXME: count properly
     686        size_t byte_length = ((port_count+1) / 8) + 1;
     687                void *change_bitmap = malloc(byte_length);
     688        size_t actual_size;
     689
     690        //usb_handle_t handle;
     691        /*
     692         * Send the request.
     693         */
     694        opResult = usb_endpoint_pipe_read(
     695                        &hub_info->endpoints.status_change,
     696                        change_bitmap, byte_length, &actual_size
     697                        );
     698
     699        //usb_drv_async_wait_for(handle);
     700
     701        if (opResult != EOK) {
     702                free(change_bitmap);
     703                dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
     704                return;
     705        }
     706        unsigned int port;
     707        opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
     708        usb_hc_connection_open(&hub_info->connection);
     709
     710        ///todo, opresult check, pre obe konekce
     711        for (port = 1; port < port_count+1; ++port) {
     712                bool interrupt =
     713                                (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
     714                if (interrupt) {
     715                        usb_hub_process_interrupt(
     716                                hub_info, port);
     717                }
     718        }
     719        usb_hc_connection_close(&hub_info->connection);
     720        usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
     721        usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     722        free(change_bitmap);
    591723}
    592724
     
    594726 * Check changes on all known hubs.
    595727 */
     728/*
    596729void usb_hub_check_hub_changes(void) {
    597         /*
    598          * Iterate through all hubs.
    599          */
     730        // Iterate through all hubs.
     731         
    600732        usb_general_list_t * lst_item;
    601733        fibril_mutex_lock(&usb_hub_list_lock);
     
    605737                fibril_mutex_unlock(&usb_hub_list_lock);
    606738                usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
    607                 int opResult;
    608 
    609                 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
    610                 if(opResult != EOK){
    611                         continue;
    612                 }
    613                 /*
    614                  * Check status change pipe of this hub.
    615                  */
    616                 /*
    617                 usb_target_t target;
    618                 target.address = hub_info->address;
    619                 target.endpoint = 1;/// \TODO get from endpoint descriptor
    620                 dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d",
    621                     target.address);
    622                 */
    623                 size_t port_count = hub_info->port_count;
    624 
    625                 /*
    626                  * Connect to respective HC.
    627                  *
    628                 int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
    629                 if (hc < 0) {
    630                         continue;
    631                 }*/
    632 
    633                 /// FIXME: count properly
    634                 size_t byte_length = ((port_count+1) / 8) + 1;
    635 
    636                 void *change_bitmap = malloc(byte_length);
    637                 size_t actual_size;
    638                 //usb_handle_t handle;
    639 
    640                 /*
    641                  * Send the request.
    642                  */
    643                 opResult = usb_endpoint_pipe_read(
    644                                 &hub_info->endpoints.status_change,
    645                                 change_bitmap, byte_length, &actual_size
    646                                 );
    647 
    648                 //usb_drv_async_wait_for(handle);
    649 
    650                 if (opResult != EOK) {
    651                         free(change_bitmap);
    652                         dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
    653                         continue;
    654                 }
    655                 unsigned int port;
    656                 for (port = 1; port < port_count+1; ++port) {
    657                         bool interrupt =
    658                                         (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
    659                         if (interrupt) {
    660                                 usb_hub_process_interrupt(
    661                                         hub_info, port);
    662                         }
    663                 }
    664                 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
    665                 free(change_bitmap);
    666                
    667 
    668                 //async_hangup(hc);
     739                usb_hub_check_hub_changes(hub_info);
    669740                fibril_mutex_lock(&usb_hub_list_lock);
    670741        }
    671742        fibril_mutex_unlock(&usb_hub_list_lock);
    672743}
    673 
     744*/
    674745
    675746
  • uspace/drv/usbhub/usbhub.h

    rd493ac17 rcd4b184  
    7575/**
    7676 * function running the hub-controlling loop.
    77  * @param noparam fundtion does not need any parameters
     77 * @param hub_info_param hub info pointer
    7878 */
    79 int usb_hub_control_loop(void * noparam);
     79int usb_hub_control_loop(void * hub_info_param);
    8080
    8181/** Callback when new hub device is detected.
     
    8989 * check changes on all registered hubs
    9090 */
    91 void usb_hub_check_hub_changes(void);
     91//void usb_hub_check_hub_changes(void);
     92
     93/**
     94 * check changes on specified hub
     95 * @param hub_info_param pointer to usb_hub_info_t structure
     96 */
     97void usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
    9298
    9399
Note: See TracChangeset for help on using the changeset viewer.