Ignore:
File:
1 edited

Legend:

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

    r5097bed4 rad4562c2  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup usb hub driver
     28/** @addtogroup drvusbhub
    2929 * @{
    3030 */
     
    3333 */
    3434
    35 #include <driver.h>
     35#include <ddf/driver.h>
    3636#include <bool.h>
    3737#include <errno.h>
     38#include <str_error.h>
    3839
    3940#include <usb_iface.h>
    40 #include <usb/usbdrv.h>
     41#include <usb/ddfiface.h>
    4142#include <usb/descriptor.h>
    42 #include <usb/devreq.h>
     43#include <usb/recognise.h>
     44#include <usb/request.h>
    4345#include <usb/classes/hub.h>
     46#include <stdio.h>
    4447
    4548#include "usbhub.h"
    4649#include "usbhub_private.h"
    4750#include "port_status.h"
    48 
    49 static usb_iface_t hub_usb_iface = {
    50         .get_hc_handle = usb_drv_find_hc
     51#include "usb/usb.h"
     52#include "usb/pipes.h"
     53#include "usb/classes/classes.h"
     54
     55static ddf_dev_ops_t hub_device_ops = {
     56        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
    5157};
    5258
    53 static device_ops_t hub_device_ops = {
    54         .interfaces[USB_DEV_IFACE] = &hub_usb_iface
     59/** Hub status-change endpoint description
     60 *
     61 * For more see usb hub specification in 11.15.1 of
     62 */
     63static usb_endpoint_description_t status_change_endpoint_description = {
     64        .transfer_type = USB_TRANSFER_INTERRUPT,
     65        .direction = USB_DIRECTION_IN,
     66        .interface_class = USB_CLASS_HUB,
     67        .interface_subclass = 0,
     68        .interface_protocol = 0,
     69        .flags = 0
    5570};
     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}
     80
    5681
    5782//*********************************************
     
    6186//*********************************************
    6287
    63 usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) {
     88/**
     89 * Initialize connnections to host controller, device, and device
     90 * control endpoint
     91 * @param hub
     92 * @param device
     93 * @return
     94 */
     95static int usb_hub_init_communication(usb_hub_info_t * hub){
     96        usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle);
     97        int opResult;
     98        opResult = usb_device_connection_initialize_from_device(
     99                        &hub->device_connection,
     100                        hub->device);
     101        if(opResult != EOK){
     102                dprintf(USB_LOG_LEVEL_ERROR,
     103                                "could not initialize connection to hc, errno %d",opResult);
     104                return opResult;
     105        }
     106        usb_log_debug("Initializing USB wire abstraction.\n");
     107        opResult = usb_hc_connection_initialize_from_device(&hub->connection,
     108                        hub->device);
     109        if(opResult != EOK){
     110                dprintf(USB_LOG_LEVEL_ERROR,
     111                                "could not initialize connection to device, errno %d",opResult);
     112                return opResult;
     113        }
     114        usb_log_debug("Initializing default control pipe.\n");
     115        opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
     116            &hub->device_connection);
     117        if(opResult != EOK){
     118                dprintf(USB_LOG_LEVEL_ERROR,
     119                                "could not initialize connection to device endpoint, errno %d",opResult);
     120        }
     121        return opResult;
     122}
     123
     124/**
     125 * When entering this function, hub->endpoints.control should be active.
     126 * @param hub
     127 * @return
     128 */
     129static int usb_hub_process_configuration_descriptors(
     130        usb_hub_info_t * hub){
     131        if(hub==NULL) {
     132                return EINVAL;
     133        }
     134        int opResult;
     135       
     136        //device descriptor
     137        usb_standard_device_descriptor_t std_descriptor;
     138        opResult = usb_request_get_device_descriptor(&hub->endpoints.control,
     139            &std_descriptor);
     140        if(opResult!=EOK){
     141                dprintf(USB_LOG_LEVEL_ERROR, "could not get device descriptor, %d",opResult);
     142                return opResult;
     143        }
     144        dprintf(USB_LOG_LEVEL_INFO, "hub has %d configurations",
     145                        std_descriptor.configuration_count);
     146        if(std_descriptor.configuration_count<1){
     147                dprintf(USB_LOG_LEVEL_ERROR, "THERE ARE NO CONFIGURATIONS AVAILABLE");
     148                //shouldn`t I return?
     149        }
     150
     151        //configuration descriptor
     152        /// \TODO check other configurations?
     153        usb_standard_configuration_descriptor_t config_descriptor;
     154        opResult = usb_request_get_bare_configuration_descriptor(
     155            &hub->endpoints.control, 0,
     156        &config_descriptor);
     157        if(opResult!=EOK){
     158                dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult);
     159                return opResult;
     160        }
     161        //set configuration
     162        opResult = usb_request_set_configuration(&hub->endpoints.control,
     163                config_descriptor.configuration_number);
     164
     165        if (opResult != EOK) {
     166                dprintf(USB_LOG_LEVEL_ERROR,
     167                                "something went wrong when setting hub`s configuration, %d",
     168                                opResult);
     169                return opResult;
     170        }
     171        dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d",
     172                        config_descriptor.configuration_number);
     173
     174        //full configuration descriptor
     175        size_t transferred = 0;
     176        uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length);
     177        if (descriptors == NULL) {
     178                dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory");
     179                return ENOMEM;
     180        }
     181        opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control,
     182            0, descriptors,
     183            config_descriptor.total_length, &transferred);
     184        if(opResult!=EOK){
     185                free(descriptors);
     186                dprintf(USB_LOG_LEVEL_ERROR,
     187                                "could not get full configuration descriptor, %d",opResult);
     188                return opResult;
     189        }
     190        if (transferred != config_descriptor.total_length) {
     191                dprintf(USB_LOG_LEVEL_ERROR,
     192                                "received incorrect full configuration descriptor");
     193                return ELIMIT;
     194        }
     195
     196        usb_endpoint_mapping_t endpoint_mapping[1] = {
     197                {
     198                        .pipe = &hub->endpoints.status_change,
     199                        .description = &status_change_endpoint_description,
     200                        .interface_no =
     201                            usb_device_get_assigned_interface(hub->device)
     202                }
     203        };
     204        opResult = usb_endpoint_pipe_initialize_from_configuration(
     205            endpoint_mapping, 1,
     206            descriptors, config_descriptor.total_length,
     207            &hub->device_connection);
     208        if (opResult != EOK) {
     209                dprintf(USB_LOG_LEVEL_ERROR,
     210                                "Failed to initialize status change pipe: %s",
     211                    str_error(opResult));
     212                return opResult;
     213        }
     214        if (!endpoint_mapping[0].present) {
     215                dprintf(USB_LOG_LEVEL_ERROR,"Not accepting device, " \
     216                    "cannot understand what is happenning");
     217                return EREFUSED;
     218        }
     219
     220        free(descriptors);
     221        return EOK;
     222       
     223}
     224
     225
     226/**
     227 * Create hub representation from device information.
     228 * @param device
     229 * @return pointer to created structure or NULL in case of error
     230 */
     231usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
    64232        usb_hub_info_t* result = usb_new(usb_hub_info_t);
     233        result->device = device;
     234        int opResult;
     235        opResult = usb_hub_init_communication(result);
     236        if(opResult != EOK){
     237                free(result);
     238                return NULL;
     239        }
     240
    65241        //result->device = device;
    66242        result->port_count = -1;
    67         /// \TODO is this correct? is the device stored?
    68243        result->device = device;
    69244
    70 
    71         //printf("[usb_hub] phone to hc = %d\n", hc);
    72         if (hc < 0) {
    73                 return result;
    74         }
    75         //get some hub info
    76         usb_address_t addr = usb_drv_get_my_address(hc, device);
    77         dprintf(1,"[usb_hub] address of newly created hub = %d", addr);
    78         /*if(addr<0){
    79                 //return result;
    80 
    81         }*/
    82 
    83         result->usb_device = usb_new(usb_hcd_attached_device_info_t);
    84         result->usb_device->address = addr;
     245        //result->usb_device = usb_new(usb_hcd_attached_device_info_t);
     246        size_t received_size;
    85247
    86248        // get hub descriptor
    87         usb_target_t target;
    88         target.address = addr;
    89         target.endpoint = 0;
    90         usb_device_request_setup_packet_t request;
    91         //printf("[usb_hub] creating descriptor request\n");
    92         usb_hub_set_descriptor_request(&request);
    93 
    94         //printf("[usb_hub] creating serialized descriptor\n");
     249        dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton");
    95250        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    96251        usb_hub_descriptor_t * descriptor;
    97         size_t received_size;
    98         int opResult;
    99         //printf("[usb_hub] starting control transaction\n");
    100         opResult = usb_drv_sync_control_read(
    101                         hc, target, &request, serialized_descriptor,
     252        dprintf(USB_LOG_LEVEL_DEBUG, "starting control transaction");
     253        usb_endpoint_pipe_start_session(&result->endpoints.control);
     254        opResult = usb_request_get_descriptor(&result->endpoints.control,
     255                        USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     256                        USB_DESCTYPE_HUB,
     257                        0, 0, serialized_descriptor,
    102258                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    103         if (opResult != EOK) {
    104                 dprintf(1,"[usb_hub] failed when receiving hub descriptor, badcode = %d",opResult);
     259        usb_endpoint_pipe_end_session(&result->endpoints.control);
     260
     261        if (opResult != EOK) {
     262                dprintf(USB_LOG_LEVEL_ERROR, "failed when receiving hub descriptor, badcode = %d",opResult);
    105263                free(serialized_descriptor);
    106264                return result;
    107265        }
    108         //printf("[usb_hub] deserializing descriptor\n");
     266        dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor");
    109267        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    110268        if(descriptor==NULL){
    111                 dprintf(1,"[usb_hub] could not deserialize descriptor ");
     269                dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor ");
    112270                result->port_count = 1;///\TODO this code is only for debug!!!
    113271                return result;
    114272        }
    115         //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
     273
     274        dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
    116275        result->port_count = descriptor->ports_count;
    117         result->attached_devs = (usb_hub_attached_device_t*)
    118             malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t));
     276        result->attached_devs = (usb_hc_attached_device_t*)
     277            malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t));
    119278        int i;
    120279        for(i=0;i<result->port_count+1;++i){
    121                 result->attached_devs[i].devman_handle=0;
     280                result->attached_devs[i].handle=0;
    122281                result->attached_devs[i].address=0;
    123282        }
    124         //printf("[usb_hub] freeing data\n");
     283        dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data");
    125284        free(serialized_descriptor);
    126285        free(descriptor->devices_removable);
     
    129288        //finish
    130289
    131         dprintf(1,"[usb_hub] hub info created");
     290        dprintf(USB_LOG_LEVEL_INFO, "hub info created");
    132291
    133292        return result;
    134293}
    135294
    136 int usb_add_hub_device(device_t *dev) {
    137         dprintf(1, "add_hub_device(handle=%d)", (int) dev->handle);
    138         dprintf(1,"[usb_hub] hub device");
    139 
    140         /*
    141          * We are some (probably deeply nested) hub.
    142          * Thus, assign our own operations and explore already
    143          * connected devices.
    144          */
    145         dev->ops = &hub_device_ops;
    146 
    147         //create the hub structure
    148         //get hc connection
    149         int hc = usb_drv_hc_connect_auto(dev, 0);
    150         if (hc < 0) {
    151                 return hc;
    152         }
    153 
    154         usb_hub_info_t * hub_info = usb_create_hub_info(dev, hc);
     295/**
     296 * Create hub representation and add it into hub list
     297 * @param dev
     298 * @return
     299 */
     300int usb_add_hub_device(ddf_dev_t *dev) {
     301        dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle);
     302
     303        //dev->ops = &hub_device_ops;
     304        (void) hub_device_ops;
     305
     306        usb_hub_info_t * hub_info = usb_create_hub_info(dev);
     307
     308        int opResult;
     309
     310        //perform final configurations
     311        usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
     312        // process descriptors
     313        opResult = usb_hub_process_configuration_descriptors(hub_info);
     314        if(opResult != EOK){
     315                dprintf(USB_LOG_LEVEL_ERROR,"could not get condiguration descriptors, %d",
     316                                opResult);
     317                return opResult;
     318        }
     319        //power ports
     320        usb_device_request_setup_packet_t request;
    155321        int port;
    156         int opResult;
    157         usb_device_request_setup_packet_t request;
    158         usb_target_t target;
    159         target.address = hub_info->usb_device->address;
    160         target.endpoint = 0;
    161 
    162         //get configuration descriptor
    163         // this is not fully correct - there are more configurations
    164         // and all should be checked
    165         usb_standard_device_descriptor_t std_descriptor;
    166         opResult = usb_drv_req_get_device_descriptor(hc, target.address,
    167     &std_descriptor);
    168         if(opResult!=EOK){
    169                 dprintf(1,"[usb_hub] could not get device descriptor, %d",opResult);
    170                 return opResult;
    171         }
    172         dprintf(1,"[usb_hub] hub has %d configurations",std_descriptor.configuration_count);
    173         if(std_descriptor.configuration_count<1){
    174                 dprintf(1,"[usb_hub] THERE ARE NO CONFIGURATIONS AVAILABLE");
    175         }
    176         /// \TODO check other configurations
    177         usb_standard_configuration_descriptor_t config_descriptor;
    178         opResult = usb_drv_req_get_bare_configuration_descriptor(hc,
    179         target.address, 0,
    180         &config_descriptor);
    181         if(opResult!=EOK){
    182                 dprintf(1,"[usb_hub] could not get configuration descriptor, %d",opResult);
    183                 return opResult;
    184         }
    185         //set configuration
    186         request.request_type = 0;
    187         request.request = USB_DEVREQ_SET_CONFIGURATION;
    188         request.index=0;
    189         request.length=0;
    190         request.value_high=0;
    191         request.value_low = config_descriptor.configuration_number;
    192         opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
    193         if (opResult != EOK) {
    194                 dprintf(1,"[usb_hub]something went wrong when setting hub`s configuration, %d", opResult);
    195         }
    196 
    197322        for (port = 1; port < hub_info->port_count+1; ++port) {
    198323                usb_hub_set_power_port_request(&request, port);
    199                 opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
    200                 dprintf(1,"[usb_hub] powering port %d",port);
     324                opResult = usb_endpoint_pipe_control_write(&hub_info->endpoints.control,
     325                                &request,sizeof(usb_device_request_setup_packet_t), NULL, 0);
     326                dprintf(USB_LOG_LEVEL_INFO, "powering port %d",port);
    201327                if (opResult != EOK) {
    202                         dprintf(1,"[usb_hub]something went wrong when setting hub`s %dth port", port);
     328                        dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port);
    203329                }
    204330        }
    205331        //ports powered, hub seems to be enabled
    206 
    207         ipc_hangup(hc);
     332        usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
    208333
    209334        //add the hub to list
    210         futex_down(&usb_hub_list_lock);
     335        //is this needed now?
     336        fibril_mutex_lock(&usb_hub_list_lock);
    211337        usb_lst_append(&usb_hub_list, hub_info);
    212         futex_up(&usb_hub_list_lock);
    213 
    214         dprintf(1,"[usb_hub] hub info added to list");
     338        fibril_mutex_unlock(&usb_hub_list_lock);
     339        dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list");
     340
     341        dprintf(USB_LOG_LEVEL_DEBUG, "adding to ddf");
     342        ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub");
     343        assert(hub_fun != NULL);
     344        hub_fun->ops = NULL;
     345
     346        int rc = ddf_fun_bind(hub_fun);
     347        assert(rc == EOK);
     348        rc = ddf_fun_add_to_class(hub_fun, "hub");
     349        assert(rc == EOK);
     350
     351        fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
     352        if (fid == 0) {
     353                dprintf(USB_LOG_LEVEL_ERROR,
     354                                ": failed to start monitoring fibril for new hub");
     355                return ENOMEM;
     356        }
     357        fibril_add_ready(fid);
     358
     359        dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created");
    215360        //(void)hub_info;
    216         usb_hub_check_hub_changes();
    217 
     361        //usb_hub_check_hub_changes();
    218362       
    219 
    220         dprintf(1,"[usb_hub] hub dev added");
    221         dprintf(1,"\taddress %d, has %d ports ",
    222                         hub_info->usb_device->address,
     363        dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
     364        //address is lost...
     365        dprintf(USB_LOG_LEVEL_DEBUG, "\taddress %d, has %d ports ",
     366                        //hub_info->endpoints.control.,
    223367                        hub_info->port_count);
    224         dprintf(1,"\tused configuration %d",config_descriptor.configuration_number);
    225368
    226369        return EOK;
    227370        //return ENOTSUP;
    228371}
    229 
    230372
    231373
     
    237379
    238380/**
    239  * convenience function for releasing default address and writing debug info
    240  * (these few lines are used too often to be written again and again)
    241  * @param hc
    242  * @return
    243  */
    244 inline static int usb_hub_release_default_address(int hc){
    245         int opResult;
    246         dprintf(1,"[usb_hub] releasing default address");
    247         opResult = usb_drv_release_default_address(hc);
    248         if (opResult != EOK) {
    249                 dprintf(1,"[usb_hub] failed to release default address");
    250         }
    251         return opResult;
    252 }
    253 
    254 /**
    255  * reset the port with new device and reserve the default address
     381 * Reset the port with new device and reserve the default address.
    256382 * @param hc
    257383 * @param port
    258384 * @param target
    259385 */
    260 static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
     386static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) {
    261387        usb_device_request_setup_packet_t request;
    262388        int opResult;
    263         dprintf(1,"[usb_hub] some connection changed");
     389        dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
     390        assert(hub->endpoints.control.hc_phone);
    264391        //get default address
    265         opResult = usb_drv_reserve_default_address(hc);
    266         if (opResult != EOK) {
    267                 dprintf(1,"[usb_hub] cannot assign default address, it is probably used");
     392        //opResult = usb_drv_reserve_default_address(hc);
     393        opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
     394       
     395        if (opResult != EOK) {
     396                dprintf(USB_LOG_LEVEL_WARNING,
     397                                "cannot assign default address, it is probably used %d",opResult);
    268398                return;
    269399        }
    270400        //reset port
    271401        usb_hub_set_reset_port_request(&request, port);
    272         opResult = usb_drv_sync_control_write(
    273                         hc, target,
    274                         &request,
     402        opResult = usb_endpoint_pipe_control_write(
     403                        &hub->endpoints.control,
     404                        &request,sizeof(usb_device_request_setup_packet_t),
    275405                        NULL, 0
    276406                        );
    277407        if (opResult != EOK) {
    278                 dprintf(1,"[usb_hub] something went wrong when reseting a port");
    279                 usb_hub_release_default_address(hc);
    280         }
    281 }
    282 
    283 /**
    284  * finalize adding new device after port reset
     408                dprintf(USB_LOG_LEVEL_ERROR,
     409                                "something went wrong when reseting a port %d",opResult);
     410                //usb_hub_release_default_address(hc);
     411                usb_hc_release_default_address(&hub->connection);
     412        }
     413}
     414
     415/**
     416 * Finalize adding new device after port reset
    285417 * @param hc
    286418 * @param port
     
    288420 */
    289421static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
    290                 int hc, uint16_t port, usb_target_t target) {
    291 
    292         int opResult;
    293         dprintf(1,"[usb_hub] finalizing add device");
    294         opResult = usb_hub_clear_port_feature(hc, target.address,
     422                uint16_t port, bool isLowSpeed) {
     423
     424        int opResult;
     425        dprintf(USB_LOG_LEVEL_INFO, "finalizing add device");
     426        opResult = usb_hub_clear_port_feature(&hub->endpoints.control,
    295427            port, USB_HUB_FEATURE_C_PORT_RESET);
    296         if (opResult != EOK) {
    297                 dprintf(1,"[usb_hub] failed to clear port reset feature");
    298                 usb_hub_release_default_address(hc);
    299                 return;
    300         }
    301 
    302         /* Request address at from host controller. */
    303         usb_address_t new_device_address = usb_drv_request_address(hc);
     428
     429        if (opResult != EOK) {
     430                dprintf(USB_LOG_LEVEL_ERROR, "failed to clear port reset feature");
     431                usb_hc_release_default_address(&hub->connection);
     432                return;
     433        }
     434        //create connection to device
     435        usb_endpoint_pipe_t new_device_pipe;
     436        usb_device_connection_t new_device_connection;
     437        usb_device_connection_initialize_on_default_address(
     438                        &new_device_connection,
     439                        &hub->connection
     440                        );
     441        usb_endpoint_pipe_initialize_default_control(
     442                        &new_device_pipe,
     443                        &new_device_connection);
     444        /// \TODO get highspeed info
     445        usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
     446
     447
     448        /* Request address from host controller. */
     449        usb_address_t new_device_address = usb_hc_request_address(
     450                        &hub->connection,
     451                        speed/// \TODO fullspeed??
     452                        );
    304453        if (new_device_address < 0) {
    305                 dprintf(1,"[usb_hub] failed to get free USB address");
     454                dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address");
    306455                opResult = new_device_address;
    307                 usb_hub_release_default_address(hc);
    308                 return;
    309         }
    310         dprintf(1,"[usb_hub] setting new address");
    311         opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    312             new_device_address);
    313 
    314         if (opResult != EOK) {
    315                 dprintf(1,"[usb_hub] could not set address for new device");
    316                 usb_hub_release_default_address(hc);
    317                 return;
    318         }
    319 
    320 
    321         opResult = usb_hub_release_default_address(hc);
     456                usb_hc_release_default_address(&hub->connection);
     457                return;
     458        }
     459        dprintf(USB_LOG_LEVEL_INFO, "setting new address %d",new_device_address);
     460        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
     461        //    new_device_address);
     462        usb_endpoint_pipe_start_session(&new_device_pipe);
     463        opResult = usb_request_set_address(&new_device_pipe,new_device_address);
     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);
     468                usb_hc_release_default_address(&hub->connection);
     469                return;
     470        }
     471
     472
     473        //opResult = usb_hub_release_default_address(hc);
     474        opResult = usb_hc_release_default_address(&hub->connection);
    322475        if(opResult!=EOK){
    323476                return;
     
    325478
    326479        devman_handle_t child_handle;
    327         opResult = usb_drv_register_child_in_devman(hc, hub->device,
    328             new_device_address, &child_handle);
    329         if (opResult != EOK) {
    330                 dprintf(1,"[usb_hub] could not start driver for new device");
    331                 return;
    332         }
    333         hub->attached_devs[port].devman_handle = child_handle;
     480        //??
     481    opResult = usb_device_register_child_in_devman(new_device_address,
     482            hub->connection.hc_handle, hub->device, &child_handle,
     483            NULL, NULL, NULL);
     484
     485        if (opResult != EOK) {
     486                dprintf(USB_LOG_LEVEL_ERROR,
     487                                "could not start driver for new device %d",opResult);
     488                return;
     489        }
     490        hub->attached_devs[port].handle = child_handle;
    334491        hub->attached_devs[port].address = new_device_address;
    335492
    336         opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
    337         if (opResult != EOK) {
    338                 dprintf(1,"[usb_hub] could not assign address of device in hcd");
    339                 return;
    340         }
    341         dprintf(1,"[usb_hub] new device address %d, handle %zu",
     493        //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
     494        opResult = usb_hc_register_device(
     495                        &hub->connection,
     496                        &hub->attached_devs[port]);
     497        if (opResult != EOK) {
     498                dprintf(USB_LOG_LEVEL_ERROR,
     499                                "could not assign address of device in hcd %d",opResult);
     500                return;
     501        }
     502        dprintf(USB_LOG_LEVEL_INFO, "new device address %d, handle %zu",
    342503            new_device_address, child_handle);
    343504
     
    345506
    346507/**
    347  * unregister device address in hc
     508 * Unregister device address in hc
    348509 * @param hc
    349510 * @param port
     
    351512 */
    352513static void usb_hub_removed_device(
    353     usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {
     514    usb_hub_info_t * hub,uint16_t port) {
    354515        //usb_device_request_setup_packet_t request;
    355516        int opResult;
    356517       
    357         /// \TODO remove device
    358 
    359         hub->attached_devs[port].devman_handle=0;
     518        /** \TODO remove device from device manager - not yet implemented in
     519         * devide manager
     520         */
     521       
    360522        //close address
    361523        if(hub->attached_devs[port].address!=0){
    362                 opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     524                //opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
     525                opResult = usb_hc_unregister_device(
     526                                &hub->connection, hub->attached_devs[port].address);
    363527                if(opResult != EOK) {
    364                         dprintf(1,
    365                                         "[usb_hub] could not release address of removed device: %d"
    366                                         ,opResult);
     528                        dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
     529                            "removed device: %d", opResult);
    367530                }
    368531                hub->attached_devs[port].address = 0;
     532                hub->attached_devs[port].handle = 0;
    369533        }else{
    370                 dprintf(1,
    371                                 "[usb_hub] this is strange, disconnected device had no address");
     534                dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address");
    372535                //device was disconnected before it`s port was reset - return default address
    373                 usb_drv_release_default_address(hc);
    374         }
    375 }
    376 
    377 /**
    378  * process interrupts on given hub port
     536                //usb_drv_release_default_address(hc);
     537                usb_hc_release_default_address(&hub->connection);
     538        }
     539}
     540
     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
     561/**
     562 * Process interrupts on given hub port
    379563 * @param hc
    380564 * @param port
    381565 * @param target
    382566 */
    383 static void usb_hub_process_interrupt(usb_hub_info_t * hub, int hc,
    384         uint16_t port, usb_address_t address) {
    385         dprintf(1,"[usb_hub] interrupt at port %d", port);
     567static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     568        uint16_t port) {
     569        dprintf(USB_LOG_LEVEL_DEBUG, "interrupt at port %d", port);
    386570        //determine type of change
    387         usb_target_t target;
    388         target.address=address;
    389         target.endpoint=0;
     571        usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
     572       
     573        int opResult;
     574
    390575        usb_port_status_t status;
    391576        size_t rcvd_size;
    392577        usb_device_request_setup_packet_t request;
    393         int opResult;
     578        //int opResult;
    394579        usb_hub_set_port_status_request(&request, port);
    395580        //endpoint 0
    396581
    397         opResult = usb_drv_sync_control_read(
    398                         hc, target,
    399                         &request,
     582        opResult = usb_endpoint_pipe_control_read(
     583                        pipe,
     584                        &request, sizeof(usb_device_request_setup_packet_t),
    400585                        &status, 4, &rcvd_size
    401586                        );
    402587        if (opResult != EOK) {
    403                 dprintf(1,"[usb_hub] ERROR: could not get port status");
     588                dprintf(USB_LOG_LEVEL_ERROR, "could not get port status");
    404589                return;
    405590        }
    406591        if (rcvd_size != sizeof (usb_port_status_t)) {
    407                 dprintf(1,"[usb_hub] ERROR: received status has incorrect size");
     592                dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size");
    408593                return;
    409594        }
    410595        //something connected/disconnected
    411596        if (usb_port_connect_change(&status)) {
    412                 opResult = usb_hub_clear_port_feature(hc, target.address,
     597                opResult = usb_hub_clear_port_feature(pipe,
    413598                    port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    414599                // TODO: check opResult
    415600                if (usb_port_dev_connected(&status)) {
    416                         dprintf(1,"[usb_hub] some connection changed");
    417                         usb_hub_init_add_device(hc, port, target);
     601                        dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
     602                        usb_hub_init_add_device(hub, port);
    418603                } else {
    419                         usb_hub_removed_device(hub, hc, port, target);
     604                        usb_hub_removed_device(hub, port);
     605                }
     606        }
     607        //over current
     608        if (usb_port_overcurrent_change(&status)) {
     609                //check if it was not auto-resolved
     610                if(usb_port_over_current(&status)){
     611                        usb_hub_over_current(hub,port);
     612                }else{
     613                        dprintf(USB_LOG_LEVEL_INFO,
     614                                "over current condition was auto-resolved on port %d",port);
    420615                }
    421616        }
    422617        //port reset
    423618        if (usb_port_reset_completed(&status)) {
    424                 dprintf(1,"[usb_hub] port reset complete");
     619                dprintf(USB_LOG_LEVEL_INFO, "port reset complete");
    425620                if (usb_port_enabled(&status)) {
    426                         usb_hub_finalize_add_device(hub, hc, port, target);
     621                        usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status));
    427622                } else {
    428                         dprintf(1,"[usb_hub] ERROR: port reset, but port still not enabled");
     623                        dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled");
    429624                }
    430625        }
     
    434629        usb_port_set_reset_completed(&status, false);
    435630        usb_port_set_dev_connected(&status, false);
    436         if (status) {
    437                 dprintf(1,"[usb_hub]there was some unsupported change on port %d",port);
     631        if (status>>16) {
     632                dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status);
     633
    438634        }
    439635        /// \TODO handle other changes
    440         /// \TODO debug log for various situations
    441 
    442 }
    443 
    444 /* Check changes on all known hubs.
    445  */
    446 void usb_hub_check_hub_changes(void) {
     636}
     637
     638/**
     639 * Check changes on particular hub
     640 * @param hub_info_param
     641 */
     642void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
     643        int opResult;
     644        opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change);
     645        if(opResult != EOK){
     646                dprintf(USB_LOG_LEVEL_ERROR,
     647                                "could not initialize communication for hub; %d", opResult);
     648                return;
     649        }
     650
     651        size_t port_count = hub_info->port_count;
     652
     653        /// FIXME: count properly
     654        size_t byte_length = ((port_count+1) / 8) + 1;
     655                void *change_bitmap = malloc(byte_length);
     656        size_t actual_size;
     657
    447658        /*
    448          * Iterate through all hubs.
     659         * Send the request.
    449660         */
    450         usb_general_list_t * lst_item;
    451         futex_down(&usb_hub_list_lock);
    452         for (lst_item = usb_hub_list.next;
    453                         lst_item != &usb_hub_list;
    454                         lst_item = lst_item->next) {
    455                 futex_up(&usb_hub_list_lock);
    456                 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data);
    457                 /*
    458                  * Check status change pipe of this hub.
    459                  */
    460 
    461                 usb_target_t target;
    462                 target.address = hub_info->usb_device->address;
    463                 target.endpoint = 1;/// \TODO get from endpoint descriptor
    464                 dprintf(1,"[usb_hub] checking changes for hub at addr %d",
    465                     target.address);
    466 
    467                 size_t port_count = hub_info->port_count;
    468 
    469                 /*
    470                  * Connect to respective HC.
    471                  */
    472                 int hc = usb_drv_hc_connect_auto(hub_info->device, 0);
    473                 if (hc < 0) {
    474                         continue;
     661        opResult = usb_endpoint_pipe_read(
     662                        &hub_info->endpoints.status_change,
     663                        change_bitmap, byte_length, &actual_size
     664                        );
     665
     666        if (opResult != EOK) {
     667                free(change_bitmap);
     668                dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub");
     669                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     670                return;
     671        }
     672        unsigned int port;
     673        opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control);
     674        if(opResult!=EOK){
     675                dprintf(USB_LOG_LEVEL_ERROR, "could not start control pipe session %d",
     676                                opResult);
     677                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     678                return;
     679        }
     680        opResult = usb_hc_connection_open(&hub_info->connection);
     681        if(opResult!=EOK){
     682                dprintf(USB_LOG_LEVEL_ERROR, "could not start host controller session %d",
     683                                opResult);
     684                usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
     685                usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     686                return;
     687        }
     688
     689        ///todo, opresult check, pre obe konekce
     690        for (port = 1; port < port_count+1; ++port) {
     691                bool interrupt =
     692                                (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
     693                if (interrupt) {
     694                        usb_hub_process_interrupt(
     695                                hub_info, port);
    475696                }
    476 
    477                 /// FIXME: count properly
    478                 size_t byte_length = ((port_count+1) / 8) + 1;
    479 
    480                 void *change_bitmap = malloc(byte_length);
    481                 size_t actual_size;
    482                 usb_handle_t handle;
    483 
    484                 /*
    485                  * Send the request.
    486                  */
    487                 int opResult = usb_drv_async_interrupt_in(hc, target,
    488                                 change_bitmap, byte_length, &actual_size,
    489                                 &handle);
    490 
    491                 usb_drv_async_wait_for(handle);
    492 
    493                 if (opResult != EOK) {
    494                         dprintf(1,"[usb_hub] something went wrong while getting status of hub");
    495                         continue;
    496                 }
    497                 unsigned int port;
    498                 for (port = 1; port < port_count+1; ++port) {
    499                         bool interrupt =
    500                                         (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;
    501                         if (interrupt) {
    502                                 usb_hub_process_interrupt(
    503                                         hub_info, hc, port, hub_info->usb_device->address);
    504                         }
    505                 }
    506                 free(change_bitmap);
    507 
    508                 ipc_hangup(hc);
    509                 futex_down(&usb_hub_list_lock);
    510         }
    511         futex_up(&usb_hub_list_lock);
    512 }
    513 
    514 
     697        }
     698        usb_hc_connection_close(&hub_info->connection);
     699        usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
     700        usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change);
     701        free(change_bitmap);
     702}
    515703
    516704
Note: See TracChangeset for help on using the changeset viewer.