Changeset cbdb6457 in mainline


Ignore:
Timestamp:
2011-04-15T13:51:46Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
11d2e96a, ab6fdad3
Parents:
8fd4ba0 (diff), be11749 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

interrupts for ohci root hub
hub powering corrected a bit

Location:
uspace
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/root_hub.c

    r8fd4ba0 rcbdb6457  
    198198static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request);
    199199
    200 
     200static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request,
     201    void * change_buffer, size_t buffe_size);
     202
     203static bool is_zeros(void * buffer, size_t size);
    201204
    202205
     
    213216        // set port power mode to no-power-switching
    214217        instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
    215 
     218        instance->unfinished_interrupt_transfer = NULL;
    216219        usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
    217220        return EOK;
     
    233236                usb_log_info("Root hub got CONTROL packet\n");
    234237                opResult = process_ctrl_request(instance, request);
     238                usb_transfer_batch_finish_error(request, opResult);
    235239        } else if (request->ep->transfer_type == USB_TRANSFER_INTERRUPT) {
    236240                usb_log_info("Root hub got INTERRUPT packet\n");
    237241                void * buffer;
     242                size_t buffer_size;
    238243                create_interrupt_mask(instance, &buffer,
    239                         &(request->transfered_size));
    240                 memcpy(request->data_buffer, buffer,
    241                         request->transfered_size);
     244                        &buffer_size);
     245                if(is_zeros(buffer,buffer_size)){
     246                        usb_log_debug("no changes..");
     247                        instance->unfinished_interrupt_transfer=
     248                            request;
     249                        //will be finished later
     250                }else{
     251                        usb_log_debug("processing changes..");
     252                        process_interrupt(instance, request,
     253                            buffer, buffer_size);
     254                }
     255                free(buffer);
    242256                opResult = EOK;
    243257        } else {
    244258                opResult = EINVAL;
    245         }
    246         usb_transfer_batch_finish_error(request, opResult);
     259                usb_transfer_batch_finish_error(request, opResult);
     260        }
    247261        return EOK;
    248262}
     
    252266
    253267void rh_interrupt(rh_t *instance) {
    254         usb_log_info("Whoa whoa wait, I`m not supposed to receive any "
    255                 "interrupts, am I?\n");
    256         /* TODO: implement? */
     268        //usb_log_info("Whoa whoa wait, I`m not supposed to receive any "
     269        //      "interrupts, am I?\n");
     270        if(!instance->unfinished_interrupt_transfer){
     271                return;
     272        }
     273        size_t size;
     274        void * buffer;
     275        create_interrupt_mask(instance, &buffer,
     276                        &size);
     277        process_interrupt(instance,instance->unfinished_interrupt_transfer,
     278            buffer,size);
     279        free(buffer);
    257280}
    258281/*----------------------------------------------------------------------------*/
     
    859882        return opResult;
    860883}
     884/*----------------------------------------------------------------------------*/
     885
     886/**
     887 * process hanging interrupt request
     888 *
     889 * If an interrupt transfer has been received and there was no change,
     890 * the driver stores the transfer information and waits for change to occcur.
     891 * This routine is called when that happens and it finalizes the interrupt
     892 * transfer.
     893 *
     894 * @param instance hub instance
     895 * @param request batch request to be processed
     896 * @param change_buffer chages on hub
     897 * @param buffer_size size of change buffer
     898 *
     899 * @return
     900 */
     901static int process_interrupt(rh_t *instance, usb_transfer_batch_t * request,
     902    void * change_buffer, size_t buffe_size){
     903        create_interrupt_mask(instance, &change_buffer,
     904            &(request->transfered_size));
     905        memcpy(request->data_buffer, change_buffer,request->transfered_size);
     906        instance->unfinished_interrupt_transfer = NULL;
     907        usb_transfer_batch_finish_error(request, EOK);
     908        return EOK;
     909}
     910
     911/*----------------------------------------------------------------------------*/
     912
     913/**
     914 * return whether the buffer is full of zeros
     915 *
     916 * Convenience function.
     917 * @param buffer
     918 * @param size
     919 * @return
     920 */
     921static bool is_zeros(void * buffer, size_t size){
     922        if(!buffer) return true;
     923        if(!size) return true;
     924        size_t i;
     925        for(i=0;i<size;++i){
     926                if(((char*)buffer)[i])
     927                        return false;
     928        }
     929        return true;
     930}
    861931
    862932/**
  • uspace/drv/ohci/root_hub.h

    r8fd4ba0 rcbdb6457  
    5454        /** hubs descriptors */
    5555        usb_device_descriptors_t descriptors;
     56        /** interrupt transfer waiting for an actual interrupt to occur */
     57        usb_transfer_batch_t * unfinished_interrupt_transfer;
    5658} rh_t;
    5759
  • uspace/drv/usbhub/usbhub.c

    r8fd4ba0 rcbdb6457  
    105105        }
    106106
    107         usb_pipe_start_session(hub_info->control_pipe);
     107        //usb_pipe_start_session(hub_info->control_pipe);
    108108        //set hub configuration
    109109        opResult = usb_hub_set_configuration(hub_info);
     
    122122                return opResult;
    123123        }
    124         usb_pipe_end_session(hub_info->control_pipe);
    125 
    126         /// \TODO what is this?
    127         usb_log_debug("Creating `hub' function.\n");
     124        //usb_pipe_end_session(hub_info->control_pipe);
     125
     126
     127        usb_log_debug("Creating 'hub' function in DDF.\n");
    128128        ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
    129129            fun_exposed, "hub");
     
    153153bool hub_port_changes_callback(usb_device_t *dev,
    154154    uint8_t *change_bitmap, size_t change_bitmap_size, void *arg) {
     155        usb_log_debug("hub_port_changes_callback\n");
    155156        usb_hub_info_t *hub = (usb_hub_info_t *) arg;
    156157
     
    217218        // get hub descriptor
    218219        usb_log_debug("creating serialized descriptor\n");
    219         void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
     220        //void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
     221        uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE];
    220222        usb_hub_descriptor_t * descriptor;
    221223        int opResult;
     
    235237        }
    236238        usb_log_debug2("deserializing descriptor\n");
    237         descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
     239        descriptor = usb_create_deserialized_hub_desriptor(
     240            serialized_descriptor);
    238241        if (descriptor == NULL) {
    239242                usb_log_warning("could not deserialize descriptor \n");
    240                 return opResult;
     243                return ENOMEM;
    241244        }
    242245        usb_log_debug("setting port count to %d\n", descriptor->ports_count);
    243246        hub_info->port_count = descriptor->ports_count;
    244247        /// \TODO this is not semantically correct
     248        bool is_power_switched =
     249            ((descriptor->hub_characteristics & 1) ==0);
     250        bool has_individual_port_powering =
     251            ((descriptor->hub_characteristics & 1) !=0);
    245252        hub_info->ports = malloc(
    246253            sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
     
    249256                usb_hub_port_init(&hub_info->ports[port]);
    250257        }
    251         for (port = 0; port < hub_info->port_count; port++) {
    252                 opResult = usb_hub_set_port_feature(hub_info->control_pipe,
    253                     port+1, USB_HUB_FEATURE_PORT_POWER);
    254                 if (opResult != EOK) {
    255                         usb_log_error("cannot power on port %d;  %d\n",
    256                             port+1, opResult);
    257                 }
     258        if(is_power_switched){
     259                usb_log_debug("is_power_switched\n");
     260                if(has_individual_port_powering){
     261                        usb_log_debug("has_individual_port_powering\n");
     262                        for (port = 0; port < hub_info->port_count; port++) {
     263                                opResult = usb_hub_set_port_feature(hub_info->control_pipe,
     264                                    port+1, USB_HUB_FEATURE_PORT_POWER);
     265                                if (opResult != EOK) {
     266                                        usb_log_error("cannot power on port %d;  %d\n",
     267                                            port+1, opResult);
     268                                }
     269                        }
     270                }else{
     271                        usb_log_debug("!has_individual_port_powering\n");
     272                        opResult = usb_hub_set_feature(hub_info->control_pipe,
     273                            USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
     274                        if (opResult != EOK) {
     275                                usb_log_error("cannot power hub;  %d\n",
     276                                  opResult);
     277                        }
     278                }
     279        }else{
     280                usb_log_debug("!is_power_switched\n");
    258281        }
    259282        usb_log_debug2("freeing data\n");
    260         free(serialized_descriptor);
    261         free(descriptor->devices_removable);
     283        //free(serialized_descriptor);
     284        //free(descriptor->devices_removable);
    262285        free(descriptor);
    263286        return EOK;
     
    321344         * auto destruction, this could work better.
    322345         */
    323         int rc = usb_pipe_start_session(hub_info->control_pipe);
     346        int rc = usb_hc_connection_open(&hub_info->connection);
    324347        if (rc != EOK) {
    325                 usb_log_error("Failed to start session on control pipe: %s.\n",
    326                     str_error(rc));
    327                 return rc;
    328         }
    329         rc = usb_hc_connection_open(&hub_info->connection);
    330         if (rc != EOK) {
    331                 usb_pipe_end_session(hub_info->control_pipe);
     348                //usb_pipe_end_session(hub_info->control_pipe);
    332349                usb_log_error("Failed to open connection to HC: %s.\n",
    333350                    str_error(rc));
  • uspace/drv/usbhub/usbhub_private.h

    r8fd4ba0 rcbdb6457  
    113113
    114114        usb_device_request_setup_packet_t clear_request = {
    115                 .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
     115                .request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE,
    116116                .request = USB_DEVREQ_SET_FEATURE,
    117117                .length = 0,
     
    166166}
    167167
    168 /**
    169  * create uint8_t array with serialized descriptor
    170  *
    171  * @param descriptor
    172  * @return newly created serializd descriptor pointer
    173  */
    174 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor);
    175168
    176 /**
    177  * create deserialized desriptor structure out of serialized descriptor
    178  *
    179  * The serialized descriptor must be proper usb hub descriptor,
    180  * otherwise an eerror might occur.
    181  *
    182  * @param sdescriptor serialized descriptor
    183  * @return newly created deserialized descriptor pointer
    184  */
    185 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(void * sdescriptor);
     169void * usb_create_serialized_hub_descriptor(usb_hub_descriptor_t * descriptor);
     170
     171void usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor,
     172    void * serialized_descriptor);
     173
     174usb_hub_descriptor_t * usb_create_deserialized_hub_desriptor(
     175    void * serialized_descriptor);
     176
     177void usb_deserialize_hub_desriptor(void * serialized_descriptor,
     178    usb_hub_descriptor_t * descriptor);
    186179
    187180
  • uspace/drv/usbhub/utils.c

    r8fd4ba0 rcbdb6457  
    5656//hub descriptor utils
    5757
    58 void * usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor) {
     58/**
     59 * create uint8_t array with serialized descriptor
     60 *
     61 * @param descriptor
     62 * @return newly created serializd descriptor pointer
     63 */
     64void * usb_create_serialized_hub_descriptor(usb_hub_descriptor_t * descriptor) {
    5965        //base size
    6066        size_t size = 7;
     
    6470        uint8_t * result = malloc(size);
    6571        //size
    66         result[0] = size;
     72        if(result)
     73                usb_serialize_hub_descriptor(descriptor,result);
     74        return result;
     75}
     76
     77/**
     78 * serialize descriptor into given buffer
     79 *
     80 * The buffer size is not checked.
     81 * @param descriptor
     82 * @param serialized_descriptor
     83 */
     84void usb_serialize_hub_descriptor(usb_hub_descriptor_t * descriptor,
     85    void * serialized_descriptor) {
     86        //base size
     87        uint8_t * sdescriptor = serialized_descriptor;
     88        size_t size = 7;
     89        //variable size according to port count
     90        size_t var_size = (descriptor->ports_count+7)/8;
     91        size += 2 * var_size;
     92        //size
     93        sdescriptor[0] = size;
    6794        //descriptor type
    68         result[1] = USB_DESCTYPE_HUB;
    69         result[2] = descriptor->ports_count;
     95        sdescriptor[1] = USB_DESCTYPE_HUB;
     96        sdescriptor[2] = descriptor->ports_count;
    7097        /// @fixme handling of endianness??
    71         result[3] = descriptor->hub_characteristics / 256;
    72         result[4] = descriptor->hub_characteristics % 256;
    73         result[5] = descriptor->pwr_on_2_good_time;
    74         result[6] = descriptor->current_requirement;
     98        sdescriptor[3] = descriptor->hub_characteristics / 256;
     99        sdescriptor[4] = descriptor->hub_characteristics % 256;
     100        sdescriptor[5] = descriptor->pwr_on_2_good_time;
     101        sdescriptor[6] = descriptor->current_requirement;
    75102
    76103        size_t i;
    77104        for (i = 0; i < var_size; ++i) {
    78                 result[7 + i] = descriptor->devices_removable[i];
     105                sdescriptor[7 + i] = descriptor->devices_removable[i];
    79106        }
    80107        for (i = 0; i < var_size; ++i) {
    81                 result[7 + var_size + i] = 255;
     108                sdescriptor[7 + var_size + i] = 255;
    82109        }
    83         return result;
    84110}
    85111
    86 usb_hub_descriptor_t * usb_deserialize_hub_desriptor(
     112
     113/**
     114 * create deserialized desriptor structure out of serialized descriptor
     115 *
     116 * The serialized descriptor must be proper usb hub descriptor,
     117 * otherwise an eerror might occur.
     118 *
     119 * @param sdescriptor serialized descriptor
     120 * @return newly created deserialized descriptor pointer
     121 */
     122usb_hub_descriptor_t * usb_create_deserialized_hub_desriptor(
    87123void * serialized_descriptor) {
    88124        uint8_t * sdescriptor = serialized_descriptor;
     
    95131
    96132        usb_hub_descriptor_t * result = malloc(sizeof(usb_hub_descriptor_t));
    97        
     133        if(result)
     134                usb_deserialize_hub_desriptor(serialized_descriptor,result);
     135        return result;
     136}
    98137
    99         result->ports_count = sdescriptor[2];
     138/**
     139 * deserialize descriptor into given pointer
     140 *
     141 * @param serialized_descriptor
     142 * @param descriptor
     143 * @return
     144 */
     145void usb_deserialize_hub_desriptor(
     146void * serialized_descriptor, usb_hub_descriptor_t * descriptor) {
     147        uint8_t * sdescriptor = serialized_descriptor;
     148        descriptor->ports_count = sdescriptor[2];
    100149        /// @fixme handling of endianness??
    101         result->hub_characteristics = sdescriptor[4] + 256 * sdescriptor[3];
    102         result->pwr_on_2_good_time = sdescriptor[5];
    103         result->current_requirement = sdescriptor[6];
    104         size_t var_size = (result->ports_count+7) / 8;
    105         result->devices_removable = (uint8_t*) malloc(var_size);
     150        descriptor->hub_characteristics = sdescriptor[4] + 256 * sdescriptor[3];
     151        descriptor->pwr_on_2_good_time = sdescriptor[5];
     152        descriptor->current_requirement = sdescriptor[6];
     153        size_t var_size = (descriptor->ports_count+7) / 8;
     154        //descriptor->devices_removable = (uint8_t*) malloc(var_size);
    106155
    107156        size_t i;
    108157        for (i = 0; i < var_size; ++i) {
    109                 result->devices_removable[i] = sdescriptor[7 + i];
     158                descriptor->devices_removable[i] = sdescriptor[7 + i];
    110159        }
    111         return result;
    112160}
    113 
    114 
    115161
    116162/**
  • uspace/lib/usb/include/usb/classes/hub.h

    r8fd4ba0 rcbdb6457  
    152152            maximum of 255 ports).
    153153     */
    154     uint8_t * devices_removable;
     154    uint8_t devices_removable[32];
    155155
    156156    /**
Note: See TracChangeset for help on using the changeset viewer.