Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 5fd0dc23 in mainline


Ignore:
Timestamp:
2011-07-11T13:10:37Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
1368a6b
Parents:
dbb9663
Message:

usbhub: Fix power switching procedure, get rid of heap allocation.

Location:
uspace
Files:
4 edited

Legend:

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

    rdbb9663 r5fd0dc23  
    220220 * @return error code
    221221 */
    222 static int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info) {
     222int usb_hub_process_hub_specific_info(usb_hub_info_t *hub_info)
     223{
    223224        // get hub descriptor
    224         usb_log_debug("Creating serialized descriptor\n");
     225        usb_log_debug("Retrieving descriptor\n");
    225226        uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE];
    226         usb_hub_descriptor_t * descriptor;
    227227        int opResult;
    228228
     
    234234
    235235        if (opResult != EOK) {
    236                 usb_log_error("Failed when receiving hub descriptor, "
    237                     "%s\n",
    238                     str_error(opResult));
    239                 free(serialized_descriptor);
     236                usb_log_error("Failed to receive hub descriptor: %s.\n",
     237                    str_error(opResult));
    240238                return opResult;
    241239        }
    242         usb_log_debug2("Deserializing descriptor\n");
    243         descriptor = usb_create_deserialized_hub_desriptor(
    244             serialized_descriptor);
    245         if (descriptor == NULL) {
    246                 usb_log_warning("could not deserialize descriptor \n");
    247                 return ENOMEM;
    248         }
    249         usb_log_debug("setting port count to %d\n", descriptor->ports_count);
    250         hub_info->port_count = descriptor->ports_count;
    251         const bool is_power_switched =
    252             ((descriptor->hub_characteristics & 0x2) == 0);
    253         hub_info->ports = malloc(
    254             sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
     240        usb_log_debug2("Parsing descriptor\n");
     241        usb_hub_descriptor_t descriptor;
     242        opResult = usb_deserialize_hub_desriptor(
     243                serialized_descriptor, received_size, &descriptor);
     244        if (opResult != EOK) {
     245                usb_log_error("Could not parse descriptor: %s\n",
     246                    str_error(opResult));
     247                return opResult;
     248        }
     249        usb_log_debug("Setting port count to %d.\n", descriptor.ports_count);
     250        hub_info->port_count = descriptor.ports_count;
     251
     252        hub_info->ports =
     253            malloc(sizeof(usb_hub_port_t) * (hub_info->port_count + 1));
    255254        if (!hub_info->ports) {
    256255                return ENOMEM;
    257256        }
     257
    258258        size_t port;
    259259        for (port = 0; port < hub_info->port_count + 1; ++port) {
    260260                usb_hub_port_init(&hub_info->ports[port]);
    261261        }
     262
     263        const bool is_power_switched =
     264            !(descriptor.hub_characteristics & HUB_CHAR_NO_POWER_SWITCH_FLAG);
    262265        if (is_power_switched) {
    263266                usb_log_debug("Hub power switched\n");
    264                 const bool has_individual_port_powering =
    265                     descriptor->hub_characteristics & 0x1;
    266 
    267                 if (!has_individual_port_powering) {
    268                         //this setting actually makes no difference
    269                         usb_log_debug("Hub has global powering\n");
    270                 }
     267                const bool per_port_power = descriptor.hub_characteristics
     268                    & HUB_CHAR_POWER_PER_PORT_FLAG;
    271269
    272270                for (port = 1; port <= hub_info->port_count; ++port) {
    273271                        usb_log_debug("Powering port %zu.\n", port);
    274                         opResult = usb_hub_set_port_feature(hub_info->control_pipe,
     272                        opResult = usb_hub_set_port_feature(
     273                            hub_info->control_pipe,
    275274                            port, USB_HUB_FEATURE_PORT_POWER);
    276275                        if (opResult != EOK) {
    277276                                usb_log_error("Cannot power on port %zu: %s.\n",
    278277                                    port, str_error(opResult));
     278                        } else {
     279                                if (!per_port_power) {
     280                                        usb_log_debug(
     281                                            "Ganged power switching mode,"
     282                                            "one port is enough.\n");
     283                                        break;
     284                                }
    279285                        }
    280286                }
     
    283289                usb_log_debug("Power not switched, not going to be powered\n");
    284290        }
    285         usb_log_debug2("Freeing data\n");
    286         free(descriptor);
    287291        return EOK;
    288292}
  • uspace/drv/bus/usb/usbhub/usbhub_private.h

    rdbb9663 r5fd0dc23  
    171171    void * serialized_descriptor);
    172172
    173 usb_hub_descriptor_t * usb_create_deserialized_hub_desriptor(
    174     void * serialized_descriptor);
    175 
    176 void usb_deserialize_hub_desriptor(void * serialized_descriptor,
    177     usb_hub_descriptor_t * descriptor);
     173int usb_deserialize_hub_desriptor(
     174    void *serialized_descriptor, size_t size, usb_hub_descriptor_t *descriptor);
    178175
    179176
  • uspace/drv/bus/usb/usbhub/utils.c

    rdbb9663 r5fd0dc23  
    110110}
    111111
     112/*----------------------------------------------------------------------------*/
    112113/**
    113  * create deserialized desriptor structure out of serialized descriptor
     114 * Deserialize descriptor into given pointer
    114115 *
    115  * The serialized descriptor must be proper usb hub descriptor,
    116  * otherwise an eerror might occur.
    117  *
    118  * @param sdescriptor serialized descriptor
    119  * @return newly created deserialized descriptor pointer
    120  */
    121 usb_hub_descriptor_t * usb_create_deserialized_hub_desriptor(
    122     void *serialized_descriptor) {
    123         uint8_t * sdescriptor = serialized_descriptor;
    124 
    125         if (sdescriptor[1] != USB_DESCTYPE_HUB) {
    126                 usb_log_warning("trying to deserialize wrong descriptor %x\n",
    127                     sdescriptor[1]);
    128                 return NULL;
    129         }
    130 
    131         usb_hub_descriptor_t * result = malloc(sizeof (usb_hub_descriptor_t));
    132         if (result)
    133                 usb_deserialize_hub_desriptor(serialized_descriptor, result);
    134         return result;
    135 }
    136 
    137 /**
    138  * deserialize descriptor into given pointer
    139  *
    140116 * @param serialized_descriptor
    141117 * @param descriptor
    142118 * @return
    143119 */
    144 void usb_deserialize_hub_desriptor(
    145     void * serialized_descriptor, usb_hub_descriptor_t *descriptor) {
     120int usb_deserialize_hub_desriptor(
     121    void *serialized_descriptor, size_t size, usb_hub_descriptor_t *descriptor)
     122{
    146123        uint8_t * sdescriptor = serialized_descriptor;
     124
     125        if (sdescriptor[1] != USB_DESCTYPE_HUB) {
     126                usb_log_error("Trying to deserialize wrong descriptor %x\n",
     127                    sdescriptor[1]);
     128                return EINVAL;
     129        }
     130        if (size < 7) {
     131                usb_log_error("Serialized descriptor too small.\n");
     132                return EOVERFLOW;
     133        }
     134
    147135        descriptor->ports_count = sdescriptor[2];
    148         /// @fixme handling of endianness??
    149136        descriptor->hub_characteristics = sdescriptor[3] + 256 * sdescriptor[4];
    150137        descriptor->pwr_on_2_good_time = sdescriptor[5];
    151138        descriptor->current_requirement = sdescriptor[6];
    152         size_t var_size = (descriptor->ports_count + 7) / 8;
     139        const size_t var_size = (descriptor->ports_count + 7) / 8;
    153140        //descriptor->devices_removable = (uint8_t*) malloc(var_size);
    154141
    155         size_t i;
    156         for (i = 0; i < var_size; ++i) {
     142        if (size < (7 + var_size)) {
     143                usb_log_error("Serialized descriptor too small.\n");
     144                return EOVERFLOW;
     145        }
     146        size_t i = 0;
     147        for (; i < var_size; ++i) {
    157148                descriptor->devices_removable[i] = sdescriptor[7 + i];
    158149        }
     150        return EOK;
    159151}
    160 
     152/*----------------------------------------------------------------------------*/
    161153/**
    162154 * @}
  • uspace/lib/usb/include/usb/classes/hub.h

    rdbb9663 r5fd0dc23  
    119119     */
    120120    uint16_t hub_characteristics;
     121#define HUB_CHAR_POWER_PER_PORT_FLAG  (1 << 0)
     122#define HUB_CHAR_NO_POWER_SWITCH_FLAG (1 << 1)
    121123
    122124    /**
Note: See TracChangeset for help on using the changeset viewer.