Ignore:
File:
1 edited

Legend:

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

    rad4562c2 r5097bed4  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbhub
     28/** @addtogroup usb hub driver
    2929 * @{
    3030 */
     
    3333 */
    3434
    35 #include <ddf/driver.h>
     35#include <driver.h>
    3636#include <bool.h>
    3737#include <errno.h>
    38 #include <str_error.h>
    3938
    4039#include <usb_iface.h>
    41 #include <usb/ddfiface.h>
     40#include <usb/usbdrv.h>
    4241#include <usb/descriptor.h>
    43 #include <usb/recognise.h>
    44 #include <usb/request.h>
     42#include <usb/devreq.h>
    4543#include <usb/classes/hub.h>
    46 #include <stdio.h>
    4744
    4845#include "usbhub.h"
    4946#include "usbhub_private.h"
    5047#include "port_status.h"
    51 #include "usb/usb.h"
    52 #include "usb/pipes.h"
    53 #include "usb/classes/classes.h"
    54 
    55 static ddf_dev_ops_t hub_device_ops = {
    56         .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
     48
     49static usb_iface_t hub_usb_iface = {
     50        .get_hc_handle = usb_drv_find_hc
    5751};
    5852
    59 /** Hub status-change endpoint description
    60  *
    61  * For more see usb hub specification in 11.15.1 of
    62  */
    63 static 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
     53static device_ops_t hub_device_ops = {
     54        .interfaces[USB_DEV_IFACE] = &hub_usb_iface
    7055};
    71 
    72 int 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 
    8156
    8257//*********************************************
     
    8661//*********************************************
    8762
    88 /**
    89  * Initialize connnections to host controller, device, and device
    90  * control endpoint
    91  * @param hub
    92  * @param device
    93  * @return
    94  */
    95 static 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  */
    129 static 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  */
    231 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
     63usb_hub_info_t * usb_create_hub_info(device_t * device, int hc) {
    23264        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 
    24165        //result->device = device;
    24266        result->port_count = -1;
     67        /// \TODO is this correct? is the device stored?
    24368        result->device = device;
    24469
    245         //result->usb_device = usb_new(usb_hcd_attached_device_info_t);
    246         size_t received_size;
     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;
    24785
    24886        // get hub descriptor
    249         dprintf(USB_LOG_LEVEL_DEBUG, "creating serialized descripton");
     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");
    25095        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    25196        usb_hub_descriptor_t * 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,
     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,
    258102                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    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);
     103        if (opResult != EOK) {
     104                dprintf(1,"[usb_hub] failed when receiving hub descriptor, badcode = %d",opResult);
    263105                free(serialized_descriptor);
    264106                return result;
    265107        }
    266         dprintf(USB_LOG_LEVEL_DEBUG2, "deserializing descriptor");
     108        //printf("[usb_hub] deserializing descriptor\n");
    267109        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    268110        if(descriptor==NULL){
    269                 dprintf(USB_LOG_LEVEL_WARNING, "could not deserialize descriptor ");
     111                dprintf(1,"[usb_hub] could not deserialize descriptor ");
    270112                result->port_count = 1;///\TODO this code is only for debug!!!
    271113                return result;
    272114        }
    273 
    274         dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
     115        //printf("[usb_hub] setting port count to %d\n",descriptor->ports_count);
    275116        result->port_count = descriptor->ports_count;
    276         result->attached_devs = (usb_hc_attached_device_t*)
    277             malloc((result->port_count+1) * sizeof(usb_hc_attached_device_t));
     117        result->attached_devs = (usb_hub_attached_device_t*)
     118            malloc((result->port_count+1) * sizeof(usb_hub_attached_device_t));
    278119        int i;
    279120        for(i=0;i<result->port_count+1;++i){
    280                 result->attached_devs[i].handle=0;
     121                result->attached_devs[i].devman_handle=0;
    281122                result->attached_devs[i].address=0;
    282123        }
    283         dprintf(USB_LOG_LEVEL_DEBUG2, "freeing data");
     124        //printf("[usb_hub] freeing data\n");
    284125        free(serialized_descriptor);
    285126        free(descriptor->devices_removable);
     
    288129        //finish
    289130
    290         dprintf(USB_LOG_LEVEL_INFO, "hub info created");
     131        dprintf(1,"[usb_hub] hub info created");
    291132
    292133        return result;
    293134}
    294135
    295 /**
    296  * Create hub representation and add it into hub list
    297  * @param dev
    298  * @return
    299  */
    300 int 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);
     136int 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);
     155        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);
    317170                return opResult;
    318171        }
    319         //power ports
    320         usb_device_request_setup_packet_t request;
    321         int port;
     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
    322197        for (port = 1; port < hub_info->port_count+1; ++port) {
    323198                usb_hub_set_power_port_request(&request, 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);
     199                opResult = usb_drv_sync_control_write(hc, target, &request, NULL, 0);
     200                dprintf(1,"[usb_hub] powering port %d",port);
    327201                if (opResult != EOK) {
    328                         dprintf(USB_LOG_LEVEL_WARNING, "something went wrong when setting hub`s %dth port", port);
     202                        dprintf(1,"[usb_hub]something went wrong when setting hub`s %dth port", port);
    329203                }
    330204        }
    331205        //ports powered, hub seems to be enabled
    332         usb_endpoint_pipe_end_session(&hub_info->endpoints.control);
     206
     207        ipc_hangup(hc);
    333208
    334209        //add the hub to list
    335         //is this needed now?
    336         fibril_mutex_lock(&usb_hub_list_lock);
     210        futex_down(&usb_hub_list_lock);
    337211        usb_lst_append(&usb_hub_list, hub_info);
    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");
     212        futex_up(&usb_hub_list_lock);
     213
     214        dprintf(1,"[usb_hub] hub info added to list");
    360215        //(void)hub_info;
    361         //usb_hub_check_hub_changes();
     216        usb_hub_check_hub_changes();
     217
    362218       
    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.,
     219
     220        dprintf(1,"[usb_hub] hub dev added");
     221        dprintf(1,"\taddress %d, has %d ports ",
     222                        hub_info->usb_device->address,
    367223                        hub_info->port_count);
     224        dprintf(1,"\tused configuration %d",config_descriptor.configuration_number);
    368225
    369226        return EOK;
    370227        //return ENOTSUP;
    371228}
     229
    372230
    373231
     
    379237
    380238/**
    381  * Reset the port with new device and reserve the default address.
     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 */
     244inline 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
    382256 * @param hc
    383257 * @param port
    384258 * @param target
    385259 */
    386 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port) {
     260static void usb_hub_init_add_device(int hc, uint16_t port, usb_target_t target) {
    387261        usb_device_request_setup_packet_t request;
    388262        int opResult;
    389         dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
    390         assert(hub->endpoints.control.hc_phone);
     263        dprintf(1,"[usb_hub] some connection changed");
    391264        //get default address
    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);
     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");
    398268                return;
    399269        }
    400270        //reset port
    401271        usb_hub_set_reset_port_request(&request, port);
    402         opResult = usb_endpoint_pipe_control_write(
    403                         &hub->endpoints.control,
    404                         &request,sizeof(usb_device_request_setup_packet_t),
     272        opResult = usb_drv_sync_control_write(
     273                        hc, target,
     274                        &request,
    405275                        NULL, 0
    406276                        );
    407277        if (opResult != EOK) {
    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);
     278                dprintf(1,"[usb_hub] something went wrong when reseting a port");
     279                usb_hub_release_default_address(hc);
    412280        }
    413281}
    414282
    415283/**
    416  * Finalize adding new device after port reset
     284 * finalize adding new device after port reset
    417285 * @param hc
    418286 * @param port
     
    420288 */
    421289static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
    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,
     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,
    427295            port, USB_HUB_FEATURE_C_PORT_RESET);
    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                         );
     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);
    453304        if (new_device_address < 0) {
    454                 dprintf(USB_LOG_LEVEL_ERROR, "failed to get free USB address");
     305                dprintf(1,"[usb_hub] failed to get free USB address");
    455306                opResult = new_device_address;
    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);
     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);
    475322        if(opResult!=EOK){
    476323                return;
     
    478325
    479326        devman_handle_t 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;
     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;
    491334        hub->attached_devs[port].address = new_device_address;
    492335
    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",
     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",
    503342            new_device_address, child_handle);
    504343
     
    506345
    507346/**
    508  * Unregister device address in hc
     347 * unregister device address in hc
    509348 * @param hc
    510349 * @param port
     
    512351 */
    513352static void usb_hub_removed_device(
    514     usb_hub_info_t * hub,uint16_t port) {
     353    usb_hub_info_t * hub, int hc, uint16_t port, usb_target_t target) {
    515354        //usb_device_request_setup_packet_t request;
    516355        int opResult;
    517356       
    518         /** \TODO remove device from device manager - not yet implemented in
    519          * devide manager
    520          */
    521        
     357        /// \TODO remove device
     358
     359        hub->attached_devs[port].devman_handle=0;
    522360        //close address
    523361        if(hub->attached_devs[port].address!=0){
    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);
     362                opResult = usb_drv_release_address(hc,hub->attached_devs[port].address);
    527363                if(opResult != EOK) {
    528                         dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
    529                             "removed device: %d", opResult);
     364                        dprintf(1,
     365                                        "[usb_hub] could not release address of removed device: %d"
     366                                        ,opResult);
    530367                }
    531368                hub->attached_devs[port].address = 0;
    532                 hub->attached_devs[port].handle = 0;
    533369        }else{
    534                 dprintf(USB_LOG_LEVEL_WARNING, "this is strange, disconnected device had no address");
     370                dprintf(1,
     371                                "[usb_hub] this is strange, disconnected device had no address");
    535372                //device was disconnected before it`s port was reset - return default address
    536                 //usb_drv_release_default_address(hc);
    537                 usb_hc_release_default_address(&hub->connection);
    538         }
    539 }
    540 
     373                usb_drv_release_default_address(hc);
     374        }
     375}
    541376
    542377/**
    543  *Process over current condition on port.
    544  *
    545  * Turn off the power on the port.
    546  *
    547  * @param hub
    548  * @param port
    549  */
    550 static 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
     378 * process interrupts on given hub port
    563379 * @param hc
    564380 * @param port
    565381 * @param target
    566382 */
    567 static 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);
     383static 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);
    570386        //determine type of change
    571         usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
    572        
    573         int opResult;
    574 
     387        usb_target_t target;
     388        target.address=address;
     389        target.endpoint=0;
    575390        usb_port_status_t status;
    576391        size_t rcvd_size;
    577392        usb_device_request_setup_packet_t request;
    578         //int opResult;
     393        int opResult;
    579394        usb_hub_set_port_status_request(&request, port);
    580395        //endpoint 0
    581396
    582         opResult = usb_endpoint_pipe_control_read(
    583                         pipe,
    584                         &request, sizeof(usb_device_request_setup_packet_t),
     397        opResult = usb_drv_sync_control_read(
     398                        hc, target,
     399                        &request,
    585400                        &status, 4, &rcvd_size
    586401                        );
    587402        if (opResult != EOK) {
    588                 dprintf(USB_LOG_LEVEL_ERROR, "could not get port status");
     403                dprintf(1,"[usb_hub] ERROR: could not get port status");
    589404                return;
    590405        }
    591406        if (rcvd_size != sizeof (usb_port_status_t)) {
    592                 dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size");
     407                dprintf(1,"[usb_hub] ERROR: received status has incorrect size");
    593408                return;
    594409        }
    595410        //something connected/disconnected
    596411        if (usb_port_connect_change(&status)) {
    597                 opResult = usb_hub_clear_port_feature(pipe,
     412                opResult = usb_hub_clear_port_feature(hc, target.address,
    598413                    port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    599414                // TODO: check opResult
    600415                if (usb_port_dev_connected(&status)) {
    601                         dprintf(USB_LOG_LEVEL_INFO, "some connection changed");
    602                         usb_hub_init_add_device(hub, port);
     416                        dprintf(1,"[usb_hub] some connection changed");
     417                        usb_hub_init_add_device(hc, port, target);
    603418                } else {
    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);
     419                        usb_hub_removed_device(hub, hc, port, target);
    615420                }
    616421        }
    617422        //port reset
    618423        if (usb_port_reset_completed(&status)) {
    619                 dprintf(USB_LOG_LEVEL_INFO, "port reset complete");
     424                dprintf(1,"[usb_hub] port reset complete");
    620425                if (usb_port_enabled(&status)) {
    621                         usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status));
     426                        usb_hub_finalize_add_device(hub, hc, port, target);
    622427                } else {
    623                         dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled");
     428                        dprintf(1,"[usb_hub] ERROR: port reset, but port still not enabled");
    624429                }
    625430        }
     
    629434        usb_port_set_reset_completed(&status, false);
    630435        usb_port_set_dev_connected(&status, false);
    631         if (status>>16) {
    632                 dprintf(USB_LOG_LEVEL_INFO, "there was some unsupported change on port %d: %X",port,status);
    633 
     436        if (status) {
     437                dprintf(1,"[usb_hub]there was some unsupported change on port %d",port);
    634438        }
    635439        /// \TODO handle other changes
    636 }
    637 
    638 /**
    639  * Check changes on particular hub
    640  * @param hub_info_param
    641  */
    642 void 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;
     440        /// \TODO debug log for various situations
     441
     442}
     443
     444/* Check changes on all known hubs.
     445 */
     446void usb_hub_check_hub_changes(void) {
     447        /*
     448         * Iterate through all hubs.
     449         */
     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;
     475                }
     476
     477                /// FIXME: count properly
     478                size_t byte_length = ((port_count+1) / 8) + 1;
     479
    655480                void *change_bitmap = malloc(byte_length);
    656         size_t actual_size;
    657 
    658         /*
    659          * Send the request.
    660          */
    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) {
     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                }
    667506                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);
    696                 }
    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 }
     507
     508                ipc_hangup(hc);
     509                futex_down(&usb_hub_list_lock);
     510        }
     511        futex_up(&usb_hub_list_lock);
     512}
     513
     514
    703515
    704516
Note: See TracChangeset for help on using the changeset viewer.