Changes in / [8961c22:61727bf] in mainline


Ignore:
Location:
uspace/drv/usbhub
Files:
2 added
2 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhub/Makefile

    r8961c22 r61727bf  
    3434SOURCES = \
    3535        main.c \
     36        ports.c \
    3637        utils.c \
    37         usbhub.c \
    38         usblist.c
     38        usbhub.c
    3939
    4040include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/usbhub/port_status.h

    r8961c22 r61727bf  
    4949
    5050/**
    51  * structure holding hub status and changes flags.
    52  * should not be accessed directly, use supplied getter/setter methods.
    53  *
    54  * For more information refer to table 11.16.2.5 in
    55  * "Universal Serial Bus Specification Revision 1.1"
    56  *
    57  */
    58 typedef uint32_t usb_hub_status_t;
    59 
    60 /**
    6151 * set values in request to be it a port status request
    6252 * @param request
     
    6454 */
    6555static inline void usb_hub_set_port_status_request(
    66         usb_device_request_setup_packet_t * request, uint16_t port
    67         ) {
     56usb_device_request_setup_packet_t * request, uint16_t port
     57){
    6858        request->index = port;
    6959        request->request_type = USB_HUB_REQ_TYPE_GET_PORT_STATUS;
     
    7363}
    7464
    75 /**
    76  * set values in request to be it a port status request
    77  * @param request
    78  * @param port
    79  */
    80 static inline void usb_hub_set_hub_status_request(
    81         usb_device_request_setup_packet_t * request
    82         ) {
    83         request->index = 0;
    84         request->request_type = USB_HUB_REQ_TYPE_GET_HUB_STATUS;
    85         request->request = USB_HUB_REQUEST_GET_STATUS;
    86         request->value = 0;
    87         request->length = 4;
    88 }
    8965
    9066/**
     
    9470 */
    9571static inline usb_device_request_setup_packet_t *
    96 usb_hub_create_port_status_request(uint16_t port) {
     72usb_hub_create_port_status_request(uint16_t port){
    9773        usb_device_request_setup_packet_t * result =
    9874                usb_new(usb_device_request_setup_packet_t);
    99         usb_hub_set_port_status_request(result, port);
     75        usb_hub_set_port_status_request(result,port);
    10076        return result;
    10177}
    10278
     79
    10380/**
    10481 * set the device request to be a port feature enable request
     
    10885 */
    10986static inline void usb_hub_set_enable_port_feature_request(
    110         usb_device_request_setup_packet_t * request, uint16_t port,
    111         uint16_t feature_selector
    112         ) {
     87usb_device_request_setup_packet_t * request, uint16_t port,
     88                uint16_t feature_selector
     89){
    11390        request->index = port;
    11491        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    125102 */
    126103static inline void usb_hub_set_disable_port_feature_request(
    127         usb_device_request_setup_packet_t * request, uint16_t port,
    128         uint16_t feature_selector
    129         ) {
     104usb_device_request_setup_packet_t * request, uint16_t port,
     105                uint16_t feature_selector
     106){
    130107        request->index = port;
    131108        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    141118 */
    142119static inline void usb_hub_set_enable_port_request(
    143         usb_device_request_setup_packet_t * request, uint16_t port
    144         ) {
     120usb_device_request_setup_packet_t * request, uint16_t port
     121){
    145122        request->index = port;
    146123        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    156133 */
    157134static inline usb_device_request_setup_packet_t *
    158 usb_hub_create_enable_port_request(uint16_t port) {
     135usb_hub_create_enable_port_request(uint16_t port){
    159136        usb_device_request_setup_packet_t * result =
    160137                usb_new(usb_device_request_setup_packet_t);
    161         usb_hub_set_enable_port_request(result, port);
     138        usb_hub_set_enable_port_request(result,port);
    162139        return result;
    163140}
     
    169146 */
    170147static inline void usb_hub_set_disable_port_request(
    171         usb_device_request_setup_packet_t * request, uint16_t port
    172         ) {
     148usb_device_request_setup_packet_t * request, uint16_t port
     149){
    173150        request->index = port;
    174151        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    184161 */
    185162static inline usb_device_request_setup_packet_t *
    186 usb_hub_create_disable_port_request(uint16_t port) {
     163usb_hub_create_disable_port_request(uint16_t port){
    187164        usb_device_request_setup_packet_t * result =
    188165                usb_new(usb_device_request_setup_packet_t);
    189         usb_hub_set_disable_port_request(result, port);
     166        usb_hub_set_disable_port_request(result,port);
    190167        return result;
    191168}
     
    197174 */
    198175static inline void usb_hub_set_reset_port_request(
    199         usb_device_request_setup_packet_t * request, uint16_t port
    200         ) {
     176usb_device_request_setup_packet_t * request, uint16_t port
     177){
    201178        request->index = port;
    202179        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    212189 */
    213190static inline usb_device_request_setup_packet_t *
    214 usb_hub_create_reset_port_request(uint16_t port) {
     191usb_hub_create_reset_port_request(uint16_t port){
    215192        usb_device_request_setup_packet_t * result =
    216193                usb_new(usb_device_request_setup_packet_t);
    217         usb_hub_set_reset_port_request(result, port);
     194        usb_hub_set_reset_port_request(result,port);
    218195        return result;
    219196}
     
    225202 */
    226203static inline void usb_hub_set_power_port_request(
    227         usb_device_request_setup_packet_t * request, uint16_t port
    228         ) {
     204usb_device_request_setup_packet_t * request, uint16_t port
     205){
    229206        request->index = port;
    230207        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    240217 */
    241218static inline void usb_hub_unset_power_port_request(
    242         usb_device_request_setup_packet_t * request, uint16_t port
    243         ) {
     219usb_device_request_setup_packet_t * request, uint16_t port
     220){
    244221        request->index = port;
    245222        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    249226}
    250227
    251 /**
    252  * get i`th bit of port status
    253  *
    254  * @param status
    255  * @param idx
    256  * @return
    257  */
    258 static inline bool usb_port_get_bit(usb_port_status_t * status, int idx) {
    259         return ((*status)&(1 << idx))!=0;
    260 }
    261 
    262 /**
    263  * set i`th bit of port status
    264  *
    265  * @param status
    266  * @param idx
    267  * @param value
    268  */
     228
     229/** get i`th bit of port status */
     230static inline bool usb_port_get_bit(usb_port_status_t * status, int idx)
     231{
     232        return (((*status)>>(idx))%2);
     233}
     234
     235/** set i`th bit of port status */
    269236static inline void usb_port_set_bit(
    270         usb_port_status_t * status, int idx, bool value) {
    271         (*status) = value ?
    272                 ((*status) | (1 << (idx))) :
    273                 ((*status)&(~(1 << (idx))));
    274 }
    275 
    276 /**
    277  * get i`th bit of hub status
    278  *
    279  * @param status
    280  * @param idx
    281  * @return
    282  */
    283 static inline bool usb_hub_get_bit(usb_hub_status_t * status, int idx) {
    284         return ((*status)&(1 << idx))!=0;
    285 }
    286 
    287 /**
    288  * set i`th bit of hub status
    289  *
    290  * @param status
    291  * @param idx
    292  * @param value
    293  */
    294 static inline void usb_hub_set_bit(
    295         usb_hub_status_t * status, int idx, bool value) {
    296         (*status) = value ?
    297                 ((*status) | (1 << (idx))) :
    298                 ((*status)&(~(1 << (idx))));
    299 }
    300 
    301 /**
    302  * connection status geter for port status
    303  *
    304  * @param status
    305  * @return true if there is something connected
    306  */
    307 static inline bool usb_port_dev_connected(usb_port_status_t * status) {
    308         return usb_port_get_bit(status, 0);
    309 }
    310 
    311 /**
    312  * set device connected bit in port status
    313  *
    314  * @param status
    315  * @param connected value of the bit
    316  */
    317 static inline void usb_port_set_dev_connected(usb_port_status_t * status, bool connected) {
    318         usb_port_set_bit(status, 0, connected);
     237        usb_port_status_t * status, int idx, bool value)
     238{
     239        (*status) = value?
     240                               ((*status)|(1<<(idx))):
     241                               ((*status)&(~(1<<(idx))));
     242}
     243
     244//device connnected on port
     245static inline bool usb_port_dev_connected(usb_port_status_t * status){
     246        return usb_port_get_bit(status,0);
     247}
     248
     249static inline void usb_port_set_dev_connected(usb_port_status_t * status,bool connected){
     250        usb_port_set_bit(status,0,connected);
    319251}
    320252
    321253//port enabled
    322 
    323 /**
    324  * port enabled getter for port status
    325  *
    326  * @param status
    327  * @return true if the port is enabled
    328  */
    329 static inline bool usb_port_enabled(usb_port_status_t * status) {
    330         return usb_port_get_bit(status, 1);
    331 }
    332 
    333 /**
    334  * set port enabled bit in port status
    335  *
    336  * @param status
    337  * @param enabled value of the bit
    338  */
    339 static inline void usb_port_set_enabled(usb_port_status_t * status, bool enabled) {
    340         usb_port_set_bit(status, 1, enabled);
     254static inline bool usb_port_enabled(usb_port_status_t * status){
     255        return usb_port_get_bit(status,1);
     256}
     257
     258static inline void usb_port_set_enabled(usb_port_status_t * status,bool enabled){
     259        usb_port_set_bit(status,1,enabled);
    341260}
    342261
    343262//port suspended
    344 /**
    345  * port suspended getter for port status
    346  *
    347  * @param status
    348  * @return true if port is suspended
    349  */
    350 static inline bool usb_port_suspended(usb_port_status_t * status) {
    351         return usb_port_get_bit(status, 2);
    352 }
    353 
    354 /**
    355  * set port suspended bit in port status
    356  *
    357  * @param status
    358  * @param suspended value of the bit
    359  */
    360 static inline void usb_port_set_suspended(usb_port_status_t * status, bool suspended) {
    361         usb_port_set_bit(status, 2, suspended);
     263static inline bool usb_port_suspended(usb_port_status_t * status){
     264        return usb_port_get_bit(status,2);
     265}
     266
     267static inline void usb_port_set_suspended(usb_port_status_t * status,bool suspended){
     268        usb_port_set_bit(status,2,suspended);
    362269}
    363270
    364271//over currect
    365 /**
    366  * over current condition indicator getter for port status
    367  *
    368  * @param status
    369  * @return true if there is opver-current condition on the hub
    370  */
    371 static inline bool usb_port_over_current(usb_port_status_t * status) {
    372         return usb_port_get_bit(status, 3);
    373 }
    374 
    375 /**
    376  * set over current indicator bit in port status
    377  *
    378  * @param status
    379  * @param value value of the bit
    380  */
    381 static inline void usb_port_set_over_current(usb_port_status_t * status, bool value) {
    382         usb_port_set_bit(status, 3, value);
     272static inline bool usb_port_over_current(usb_port_status_t * status){
     273        return usb_port_get_bit(status,3);
     274}
     275
     276static inline void usb_port_set_over_current(usb_port_status_t * status,bool value){
     277        usb_port_set_bit(status,3,value);
    383278}
    384279
    385280//port reset
    386 /**
    387  * port reset indicator getter for port status
    388  *
    389  * @param status
    390  * @return true if port is reset
    391  */
    392 static inline bool usb_port_reset(usb_port_status_t * status) {
    393         return usb_port_get_bit(status, 4);
    394 }
    395 
    396 /**
    397  * set port reset bit in port status
    398  *
    399  * @param status
    400  * @param value value of the bit
    401  */
    402 static inline void usb_port_set_reset(usb_port_status_t * status, bool value) {
    403         usb_port_set_bit(status, 4, value);
     281static inline bool usb_port_reset(usb_port_status_t * status){
     282        return usb_port_get_bit(status,4);
     283}
     284
     285static inline void usb_port_set_reset(usb_port_status_t * status,bool value){
     286        usb_port_set_bit(status,4,value);
    404287}
    405288
    406289//powered
    407 /**
    408  * power state getter for port status
    409  *
    410  * @param status
    411  * @return true if port is powered
    412  */
    413 static inline bool usb_port_powered(usb_port_status_t * status) {
    414         return usb_port_get_bit(status, 8);
    415 }
    416 
    417 /**
    418  * set port powered bit in port status
    419  *
    420  * @param status
    421  * @param powered value of the bit
    422  */
    423 static inline void usb_port_set_powered(usb_port_status_t * status, bool powered) {
    424         usb_port_set_bit(status, 8, powered);
     290static inline bool usb_port_powered(usb_port_status_t * status){
     291        return usb_port_get_bit(status,8);
     292}
     293
     294static inline void usb_port_set_powered(usb_port_status_t * status,bool powered){
     295        usb_port_set_bit(status,8,powered);
    425296}
    426297
    427298//low speed device attached
    428 /**
    429  * low speed device on the port indicator
    430  *
    431  * @param status
    432  * @return true if low speed device is attached
    433  */
    434 static inline bool usb_port_low_speed(usb_port_status_t * status) {
    435         return usb_port_get_bit(status, 9);
    436 }
    437 
    438 /**
    439  * set device connected bit in port status
    440  *
    441  * @param status
    442  * @param low_speed value of the bit
    443  */
    444 static inline void usb_port_set_low_speed(usb_port_status_t * status, bool low_speed) {
    445         usb_port_set_bit(status, 9, low_speed);
    446 }
    447 
    448 //high speed device attached
    449 /**
    450  * high speed device on the port indicator
    451  *
    452  * @param status
    453  * @return true if high speed device is on port
    454  */
    455 static inline bool usb_port_high_speed(usb_port_status_t * status) {
    456         return usb_port_get_bit(status, 10);
    457 }
    458 
    459 /**
    460  * set high speed device bit in port status
    461  *
    462  * @param status
    463  * @param high_speed value of the bit
    464  */
    465 static inline void usb_port_set_high_speed(usb_port_status_t * status, bool high_speed) {
    466         usb_port_set_bit(status, 10, high_speed);
    467 }
    468 
    469 /**
    470  * speed getter for port status
    471  *
    472  * @param status
    473  * @return speed of usb device (for more see usb specification)
    474  */
    475 static inline usb_speed_t usb_port_speed(usb_port_status_t * status) {
    476         if (usb_port_low_speed(status))
     299static inline bool usb_port_low_speed(usb_port_status_t * status){
     300        return usb_port_get_bit(status,9);
     301}
     302
     303static inline void usb_port_set_low_speed(usb_port_status_t * status,bool low_speed){
     304        usb_port_set_bit(status,9,low_speed);
     305}
     306
     307//low speed device attached
     308static inline bool usb_port_high_speed(usb_port_status_t * status){
     309        return usb_port_get_bit(status,10);
     310}
     311
     312static inline void usb_port_set_high_speed(usb_port_status_t * status,bool high_speed){
     313        usb_port_set_bit(status,10,high_speed);
     314}
     315
     316static inline usb_speed_t usb_port_speed(usb_port_status_t * status){
     317        if(usb_port_low_speed(status))
    477318                return USB_SPEED_LOW;
    478         if (usb_port_high_speed(status))
     319        if(usb_port_high_speed(status))
    479320                return USB_SPEED_HIGH;
    480321        return USB_SPEED_FULL;
     
    483324
    484325//connect change
    485 /**
    486  * port connect change indicator
    487  *
    488  * @param status
    489  * @return true if connection has changed
    490  */
    491 static inline bool usb_port_connect_change(usb_port_status_t * status) {
    492         return usb_port_get_bit(status, 16);
    493 }
    494 
    495 /**
    496  * set connection change bit in port status
    497  * @param status
    498  * @param change value of the bit
    499  */
    500 static inline void usb_port_set_connect_change(usb_port_status_t * status, bool change) {
    501         usb_port_set_bit(status, 16, change);
     326static inline bool usb_port_connect_change(usb_port_status_t * status){
     327        return usb_port_get_bit(status,16);
     328}
     329
     330static inline void usb_port_set_connect_change(usb_port_status_t * status,bool change){
     331        usb_port_set_bit(status,16,change);
    502332}
    503333
    504334//port enable change
    505 /**
    506  * port enable change for port status
    507  *
    508  * @param status
    509  * @return true if the port has been enabled/disabled
    510  */
    511 static inline bool usb_port_enabled_change(usb_port_status_t * status) {
    512         return usb_port_get_bit(status, 17);
    513 }
    514 
    515 /**
    516  * set port enable change bit in port status
    517  *
    518  * @param status
    519  * @param change value of the bit
    520  */
    521 static inline void usb_port_set_enabled_change(usb_port_status_t * status, bool change) {
    522         usb_port_set_bit(status, 17, change);
     335static inline bool usb_port_enabled_change(usb_port_status_t * status){
     336        return usb_port_get_bit(status,17);
     337}
     338
     339static inline void usb_port_set_enabled_change(usb_port_status_t * status,bool change){
     340        usb_port_set_bit(status,17,change);
    523341}
    524342
    525343//suspend change
    526 /**
    527  * port suspend change for port status
    528  *
    529  * @param status
    530  * @return ture if suspend status has changed
    531  */
    532 static inline bool usb_port_suspend_change(usb_port_status_t * status) {
    533         return usb_port_get_bit(status, 18);
    534 }
    535 
    536 /**
    537  * set port suspend change bit in port status
    538  *
    539  * @param status
    540  * @param change value of the bit
    541  */
    542 static inline void usb_port_set_suspend_change(usb_port_status_t * status, bool change) {
    543         usb_port_set_bit(status, 18, change);
     344static inline bool usb_port_suspend_change(usb_port_status_t * status){
     345        return usb_port_get_bit(status,18);
     346}
     347
     348static inline void usb_port_set_suspend_change(usb_port_status_t * status,bool change){
     349        usb_port_set_bit(status,18,change);
    544350}
    545351
    546352//over current change
    547 /**
    548  * over current change indicator
    549  *
    550  * @param status
    551  * @return true if over-current condition on port has changed
    552  */
    553 static inline bool usb_port_overcurrent_change(usb_port_status_t * status) {
    554         return usb_port_get_bit(status, 19);
    555 }
    556 
    557 /**
    558  * set port over current change bit in port status
    559  *
    560  * @param status
    561  * @param change value of the bit
    562  */
    563 static inline void usb_port_set_overcurrent_change(usb_port_status_t * status, bool change) {
    564         usb_port_set_bit(status, 19, change);
     353static inline bool usb_port_overcurrent_change(usb_port_status_t * status){
     354        return usb_port_get_bit(status,19);
     355}
     356
     357static inline void usb_port_set_overcurrent_change(usb_port_status_t * status,bool change){
     358        usb_port_set_bit(status,19,change);
    565359}
    566360
    567361//reset change
    568 /**
    569  * port reset change indicator
    570  * @param status
    571  * @return true if port has been reset
    572  */
    573 static inline bool usb_port_reset_completed(usb_port_status_t * status) {
    574         return usb_port_get_bit(status, 20);
    575 }
    576 
    577 /**
    578  * set port reset completed bit in port status
    579  *
    580  * @param status
    581  * @param change value of the bit
    582  */
    583 static inline void usb_port_set_reset_completed(usb_port_status_t * status, bool completed) {
    584         usb_port_set_bit(status, 20, completed);
    585 }
    586 
    587 //local power status
    588 /**
    589  * local power lost indicator for hub status
    590  *
    591  * @param status
    592  * @return true if hub is not powered
    593  */
    594 static inline bool usb_hub_local_power_lost(usb_hub_status_t * status) {
    595         return usb_hub_get_bit(status, 0);
    596 }
    597 
    598 /**
    599  * set hub power lost bit in hub status
    600  *
    601  * @param status
    602  * @param change value of the bit
    603  */
    604 static inline void usb_hub_set_local_power_lost(usb_port_status_t * status,
    605         bool power_lost) {
    606         usb_hub_set_bit(status, 0, power_lost);
    607 }
    608 
    609 //over current ocndition
    610 /**
    611  * hub over-current indicator
    612  *
    613  * @param status
    614  * @return true if over-current condition occurred on hub
    615  */
    616 static inline bool usb_hub_over_current(usb_hub_status_t * status) {
    617         return usb_hub_get_bit(status, 1);
    618 }
    619 
    620 /**
    621  * set hub over current bit in hub status
    622  *
    623  * @param status
    624  * @param change value of the bit
    625  */
    626 static inline void usb_hub_set_over_current(usb_port_status_t * status,
    627         bool over_current) {
    628         usb_hub_set_bit(status, 1, over_current);
    629 }
    630 
    631 //local power change
    632 /**
    633  * hub power change indicator
    634  *
    635  * @param status
    636  * @return true if local power status has been changed - power has been
    637  * dropped or re-established
    638  */
    639 static inline bool usb_hub_local_power_change(usb_hub_status_t * status) {
    640         return usb_hub_get_bit(status, 16);
    641 }
    642 
    643 /**
    644  * set hub power change bit in hub status
    645  *
    646  * @param status
    647  * @param change value of the bit
    648  */
    649 static inline void usb_hub_set_local_power_change(usb_port_status_t * status,
    650         bool change) {
    651         usb_hub_set_bit(status, 16, change);
    652 }
    653 
    654 //local power status
    655 /**
    656  * hub over-current condition change indicator
    657  *
    658  * @param status
    659  * @return true if over-current condition has changed
    660  */
    661 static inline bool usb_hub_over_current_change(usb_hub_status_t * status) {
    662         return usb_hub_get_bit(status, 17);
    663 }
    664 
    665 /**
    666  * set hub over current change bit in hub status
    667  *
    668  * @param status
    669  * @param change value of the bit
    670  */
    671 static inline void usb_hub_set_over_current_change(usb_port_status_t * status,
    672         bool change) {
    673         usb_hub_set_bit(status, 17, change);
    674 }
     362static inline bool usb_port_reset_completed(usb_port_status_t * status){
     363        return usb_port_get_bit(status,20);
     364}
     365
     366static inline void usb_port_set_reset_completed(usb_port_status_t * status,bool completed){
     367        usb_port_set_bit(status,20,completed);
     368}
     369
    675370
    676371
  • uspace/drv/usbhub/usbhub.c

    r8961c22 r61727bf  
    3737#include <errno.h>
    3838#include <str_error.h>
    39 #include <inttypes.h>
    4039
    4140#include <usb_iface.h>
     
    5453#include "usb/classes/classes.h"
    5554
    56 
    57 /** Information for fibril for device discovery. */
    58 struct add_device_phase1 {
    59         usb_hub_info_t *hub;
    60         size_t port;
    61         usb_speed_t speed;
    62 };
    63 
    64 
    65 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);
    66 
    67 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info);
    68 
    69 static int usb_hub_set_configuration(usb_hub_info_t * hub_info);
    70 
    71 static int usb_hub_release_default_address(usb_hub_info_t * hub);
    72 
    73 //static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
    74 //      usb_speed_t speed);
    75 
    76 //static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
    77 //      uint16_t port, usb_speed_t speed);
    78 
    79 static void usb_hub_removed_device(
    80         usb_hub_info_t * hub, uint16_t port);
    81 
    82 static void usb_hub_port_over_current(usb_hub_info_t * hub,
    83         uint16_t port, uint32_t status);
    84 
    85 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
    86     usb_port_status_t *status);
    87 
    88 static int enable_port_callback(int port_no, void *arg);
    89 
    90 static int add_device_phase1_worker_fibril(void *arg);
    91 
    92 static int add_device_phase1_new_fibril(usb_hub_info_t *hub, size_t port,
    93     usb_speed_t speed);
    94 
    95 static void usb_hub_process_interrupt(usb_hub_info_t * hub,
    96         uint16_t port);
    97 
    98 static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
    99         usb_hub_status_t status);
    100 
    101 static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
    102         usb_hub_status_t status);
    103 
    104 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);
    105 
    106 //static int initialize_non_removable(usb_hub_info_t * hub_info,
    107 //      unsigned int port);
    108 
    109 //static int usb_hub_trigger_connecting_non_removable_devices(
    110 //      usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
    111 
    112 
    113 /**
    114  * control loop running in hub`s fibril
    115  *
    116  * Hub`s fibril periodically asks for changes on hub and if needded calls
    117  * change handling routine.
    118  * @warning currently hub driver asks for changes once a second
    119  * @param hub_info_param hub representation pointer
    120  * @return zero
    121  */
    122 /*
    123 int usb_hub_control_loop(void * hub_info_param) {
    124         usb_hub_info_t * hub_info = (usb_hub_info_t*) hub_info_param;
    125         int errorCode = EOK;
    126 
    127         while (errorCode == EOK) {
    128                 async_usleep(1000 * 1000 * 10); /// \TODO proper number once
    129                 errorCode = usb_hub_check_hub_changes(hub_info);
    130         }
    131         usb_log_error("something in ctrl loop went wrong, errno %d\n",
    132                 errorCode);
    133 
    134         return 0;
    135 }
    136  */
    137 /// \TODO malloc checking
     55static int usb_hub_trigger_connecting_non_removable_devices(
     56                usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
     57
    13858
    13959//*********************************************
     
    14363//*********************************************
    14464
    145 
     65/**
     66 * create usb_hub_info_t structure
     67 *
     68 * Does only basic copying of known information into new structure.
     69 * @param usb_dev usb device structure
     70 * @return basic usb_hub_info_t structure
     71 */
     72static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
     73        usb_hub_info_t * result = usb_new(usb_hub_info_t);
     74        if(!result) return NULL;
     75        result->usb_device = usb_dev;
     76        result->status_change_pipe = usb_dev->pipes[0].pipe;
     77        result->control_pipe = &usb_dev->ctrl_pipe;
     78        result->is_default_address_used = false;
     79        return result;
     80}
     81
     82/**
     83 * Load hub-specific information into hub_info structure and process if needed
     84 *
     85 * Particularly read port count and initialize structure holding port
     86 * information. If there are non-removable devices, start initializing them.
     87 * This function is hub-specific and should be run only after the hub is
     88 * configured using usb_hub_set_configuration function.
     89 * @param hub_info hub representation
     90 * @return error code
     91 */
     92static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){
     93        // get hub descriptor
     94        usb_log_debug("creating serialized descriptor\n");
     95        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
     96        usb_hub_descriptor_t * descriptor;
     97
     98        /* this was one fix of some bug, should not be needed anymore
     99         * these lines allow to reset hub once more, it can be used as
     100         * brute-force initialization for non-removable devices
     101        int opResult = usb_request_set_configuration(&result->endpoints.control, 1);
     102        if(opResult!=EOK){
     103                usb_log_error("could not set default configuration, errno %d",opResult);
     104                return opResult;
     105        }
     106         */
     107        size_t received_size;
     108        int opResult = usb_request_get_descriptor(&hub_info->usb_device->ctrl_pipe,
     109                        USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     110                        USB_DESCTYPE_HUB,
     111                        0, 0, serialized_descriptor,
     112                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
     113
     114        if (opResult != EOK) {
     115                usb_log_error("failed when receiving hub descriptor, badcode = %d\n",
     116                                opResult);
     117                free(serialized_descriptor);
     118                return opResult;
     119        }
     120        usb_log_debug2("deserializing descriptor\n");
     121        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
     122        if(descriptor==NULL){
     123                usb_log_warning("could not deserialize descriptor \n");
     124                return opResult;
     125        }
     126        usb_log_debug("setting port count to %d\n",descriptor->ports_count);
     127        hub_info->port_count = descriptor->ports_count;
     128        hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1));
     129        size_t port;
     130        for (port = 0; port < hub_info->port_count + 1; port++) {
     131                usb_hub_port_init(&hub_info->ports[port]);
     132        }
     133        //handle non-removable devices
     134        usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
     135        usb_log_debug2("freeing data\n");
     136        free(serialized_descriptor);
     137        free(descriptor->devices_removable);
     138        free(descriptor);
     139        return EOK;
     140}
     141/**
     142 * Set configuration of hub
     143 *
     144 * Check whether there is at least one configuration and sets the first one.
     145 * This function should be run prior to running any hub-specific action.
     146 * @param hub_info hub representation
     147 * @return error code
     148 */
     149static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
     150        //device descriptor
     151        usb_standard_device_descriptor_t *std_descriptor
     152            = &hub_info->usb_device->descriptors.device;
     153        usb_log_debug("hub has %d configurations\n",
     154            std_descriptor->configuration_count);
     155        if(std_descriptor->configuration_count<1){
     156                usb_log_error("there are no configurations available\n");
     157                return EINVAL;
     158        }
     159
     160        usb_standard_configuration_descriptor_t *config_descriptor
     161            = (usb_standard_configuration_descriptor_t *)
     162            hub_info->usb_device->descriptors.configuration;
     163
     164        /* Set configuration. */
     165        int opResult = usb_request_set_configuration(
     166            &hub_info->usb_device->ctrl_pipe,
     167            config_descriptor->configuration_number);
     168
     169        if (opResult != EOK) {
     170                usb_log_error("Failed to set hub configuration: %s.\n",
     171                    str_error(opResult));
     172                return opResult;
     173        }
     174        usb_log_debug("\tused configuration %d\n",
     175                        config_descriptor->configuration_number);
     176
     177        return EOK;
     178}
    146179
    147180/**
     
    153186 * @return error code
    154187 */
    155 int usb_hub_add_device(usb_device_t * usb_dev) {
    156         if (!usb_dev) return EINVAL;
     188int usb_hub_add_device(usb_device_t * usb_dev){
     189        if(!usb_dev) return EINVAL;
    157190        usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
    158191        //create hc connection
    159192        usb_log_debug("Initializing USB wire abstraction.\n");
    160193        int opResult = usb_hc_connection_initialize_from_device(
    161                 &hub_info->connection,
    162                 hub_info->usb_device->ddf_dev);
    163         if (opResult != EOK) {
    164                 usb_log_error("could not initialize connection to device, "
    165                         "errno %d\n",
    166                         opResult);
     194                        &hub_info->connection,
     195                        hub_info->usb_device->ddf_dev);
     196        if(opResult != EOK){
     197                usb_log_error("could not initialize connection to device, errno %d\n",
     198                                opResult);
    167199                free(hub_info);
    168200                return opResult;
    169201        }
    170 
     202       
    171203        usb_pipe_start_session(hub_info->control_pipe);
    172204        //set hub configuration
    173205        opResult = usb_hub_set_configuration(hub_info);
    174         if (opResult != EOK) {
    175                 usb_log_error("could not set hub configuration, errno %d\n",
    176                         opResult);
     206        if(opResult!=EOK){
     207                usb_log_error("could not set hub configuration, errno %d\n",opResult);
    177208                free(hub_info);
    178209                return opResult;
     
    180211        //get port count and create attached_devs
    181212        opResult = usb_hub_process_hub_specific_info(hub_info);
    182         if (opResult != EOK) {
    183                 usb_log_error("could not set hub configuration, errno %d\n",
    184                         opResult);
     213        if(opResult!=EOK){
     214                usb_log_error("could not set hub configuration, errno %d\n",opResult);
    185215                free(hub_info);
    186216                return opResult;
     
    192222        usb_log_debug("Creating `hub' function.\n");
    193223        ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
    194                 fun_exposed, "hub");
     224                        fun_exposed, "hub");
    195225        assert(hub_fun != NULL);
    196226        hub_fun->ops = NULL;
     
    234264
    235265        usb_log_info("Controlling hub `%s' (%d ports).\n",
    236                 hub_info->usb_device->ddf_dev->name, hub_info->port_count);
     266            hub_info->usb_device->ddf_dev->name, hub_info->port_count);
    237267        return EOK;
     268
    238269leave:
    239270        free(hub_info);
     
    249280//*********************************************
    250281
    251 
    252 /** Callback for polling hub for port changes.
    253  *
    254  * @param dev Device where the change occured.
    255  * @param change_bitmap Bitmap of changed ports.
    256  * @param change_bitmap_size Size of the bitmap in bytes.
    257  * @param arg Custom argument, points to @c usb_hub_info_t.
    258  * @return Whether to continue polling.
    259  */
    260 bool hub_port_changes_callback(usb_device_t *dev,
    261     uint8_t *change_bitmap, size_t change_bitmap_size, void *arg)
     282/**
     283 * triggers actions to connect non0removable devices
     284 *
     285 * This will trigger operations leading to activated non-removable device.
     286 * Control pipe of the hub must be open fo communication.
     287 * @param hub hub representation
     288 * @param descriptor usb hub descriptor
     289 * @return error code
     290 */
     291static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub,
     292                usb_hub_descriptor_t * descriptor)
    262293{
    263         usb_hub_info_t *hub = (usb_hub_info_t *) arg;
    264 
    265         /* FIXME: check that we received enough bytes. */
    266         if (change_bitmap_size == 0) {
    267                 goto leave;
    268         }
    269 
    270         size_t port;
    271         for (port = 1; port < hub->port_count + 1; port++) {
    272                 bool change = (change_bitmap[port / 8] >> (port % 8)) % 2;
    273                 if (change) {
    274                         usb_hub_process_interrupt(hub, port);
    275                 }
    276         }
    277 
    278 
    279 leave:
    280         /* FIXME: proper interval. */
    281         async_usleep(1000 * 1000 * 10 );
    282 
    283         return true;
    284 }
    285 
    286 
    287 /**
    288  * check changes on hub
    289  *
    290  * Handles changes on each port with a status change.
    291  * @param hub_info hub representation
    292  * @return error code
    293  */
    294 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) {
     294        usb_log_info("attaching non-removable devices(if any)\n");
     295        usb_device_request_setup_packet_t request;
    295296        int opResult;
    296         opResult = usb_pipe_start_session(
    297                 hub_info->status_change_pipe);
    298         //this might not be necessary - if all non-removables are ok, it is
    299         //not needed here
    300         opResult = usb_pipe_start_session(hub_info->control_pipe);
    301         if (opResult != EOK) {
    302                 usb_log_error("could not initialize communication for hub; %d\n",
    303                         opResult);
    304                 return opResult;
    305         }
    306 
    307         size_t port_count = hub_info->port_count;
    308         //first check non-removable devices
    309         /*
    310         {
    311                 unsigned int port;
    312                 for (port = 0; port < port_count; ++port) {
    313                         bool is_non_removable =
    314                                 hub_info->not_initialized_non_removables[port/8]
    315                                 & (1 << (port-1 % 8));
    316                         if (is_non_removable) {
    317                                 opResult = initialize_non_removable(hub_info,
    318                                         port+1);
     297        size_t rcvd_size;
     298        usb_port_status_t status;
     299        uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;
     300        int port;
     301        for(port=1;port<=descriptor->ports_count;++port){
     302                bool is_non_removable =
     303                                ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;
     304                if(is_non_removable){
     305                        usb_log_debug("non-removable device on port %d\n",port);
     306                        usb_hub_set_port_status_request(&request, port);
     307                        opResult = usb_pipe_control_read(
     308                                        hub->control_pipe,
     309                                        &request, sizeof(usb_device_request_setup_packet_t),
     310                                        &status, 4, &rcvd_size
     311                                        );
     312                        if (opResult != EOK) {
     313                                usb_log_error("could not get port status of port %d errno:%d\n",
     314                                                port, opResult);
     315                                return opResult;
     316                        }
     317                        //set the status change bit, so it will be noticed in driver loop
     318                        if(usb_port_dev_connected(&status)){
     319                                usb_hub_set_disable_port_feature_request(&request, port,
     320                                                USB_HUB_FEATURE_PORT_CONNECTION);
     321                                opResult = usb_pipe_control_read(
     322                                                hub->control_pipe,
     323                                                &request, sizeof(usb_device_request_setup_packet_t),
     324                                                &status, 4, &rcvd_size
     325                                                );
     326                                if (opResult != EOK) {
     327                                        usb_log_warning(
     328                                                        "could not clear port connection on port %d errno:%d\n",
     329                                                        port, opResult);
     330                                }
     331                                usb_log_debug("cleared port connection\n");
     332                                usb_hub_set_enable_port_feature_request(&request, port,
     333                                                USB_HUB_FEATURE_PORT_ENABLE);
     334                                opResult = usb_pipe_control_read(
     335                                                hub->control_pipe,
     336                                                &request, sizeof(usb_device_request_setup_packet_t),
     337                                                &status, 4, &rcvd_size
     338                                                );
     339                                if (opResult != EOK) {
     340                                        usb_log_warning(
     341                                                        "could not set port enabled on port %d errno:%d\n",
     342                                                        port, opResult);
     343                                }
     344                                usb_log_debug("port set to enabled - should lead to connection change\n");
    319345                        }
    320346                }
    321347        }
    322         */
    323 
    324         /// FIXME: count properly
    325         size_t byte_length = ((port_count + 1) / 8) + 1;
    326         void *change_bitmap = malloc(byte_length);
    327         size_t actual_size;
    328 
    329         /*
    330          * Send the request.
    331          */
    332         opResult = usb_pipe_read(
    333                 hub_info->status_change_pipe,
    334                 change_bitmap, byte_length, &actual_size
    335                 );
    336 
    337         if (opResult != EOK) {
    338                 free(change_bitmap);
    339                 usb_log_warning("something went wrong while getting the"
    340                         "status of hub\n");
    341                 usb_pipe_end_session(hub_info->status_change_pipe);
    342                 return opResult;
    343         }
    344         unsigned int port;
    345 
    346         if (opResult != EOK) {
    347                 usb_log_error("could not start control pipe session %d\n",
    348                         opResult);
    349                 usb_pipe_end_session(hub_info->status_change_pipe);
    350                 return opResult;
    351         }
    352         opResult = usb_hc_connection_open(&hub_info->connection);
    353         if (opResult != EOK) {
    354                 usb_log_error("could not start host controller session %d\n",
    355                         opResult);
    356                 usb_pipe_end_session(hub_info->control_pipe);
    357                 usb_pipe_end_session(hub_info->status_change_pipe);
    358                 return opResult;
    359         }
    360 
    361         ///todo, opresult check, pre obe konekce
    362         bool interrupt;
    363         interrupt = ((uint8_t*)change_bitmap)[0] & 1;
    364         if(interrupt){
    365                 usb_hub_process_global_interrupt(hub_info);
    366         }
    367         for (port = 1; port < port_count + 1; ++port) {
    368                 interrupt =
    369                         ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8));
    370                 if (interrupt) {
    371                         usb_hub_process_interrupt(
    372                                 hub_info, port);
     348        /// \TODO this is just a debug code
     349        for(port=1;port<=descriptor->ports_count;++port){
     350                bool is_non_removable =
     351                                ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;
     352                if(is_non_removable){
     353                        usb_log_debug("port %d is non-removable\n",port);
     354                        usb_port_status_t status;
     355                        size_t rcvd_size;
     356                        usb_device_request_setup_packet_t request;
     357                        //int opResult;
     358                        usb_hub_set_port_status_request(&request, port);
     359                        //endpoint 0
     360                        opResult = usb_pipe_control_read(
     361                                        hub->control_pipe,
     362                                        &request, sizeof(usb_device_request_setup_packet_t),
     363                                        &status, 4, &rcvd_size
     364                                        );
     365                        if (opResult != EOK) {
     366                                usb_log_error("could not get port status %d\n",opResult);
     367                        }
     368                        if (rcvd_size != sizeof (usb_port_status_t)) {
     369                                usb_log_error("received status has incorrect size\n");
     370                        }
     371                        //something connected/disconnected
     372                        if (usb_port_connect_change(&status)) {
     373                                usb_log_debug("some connection changed\n");
     374                        }
     375                        usb_log_debug("status: %s\n",usb_debug_str_buffer(
     376                                        (uint8_t *)&status,4,4));
    373377                }
    374378        }
    375         /// \todo check hub status
    376         usb_hc_connection_close(&hub_info->connection);
    377         usb_pipe_end_session(hub_info->control_pipe);
    378         usb_pipe_end_session(hub_info->status_change_pipe);
    379         free(change_bitmap);
    380379        return EOK;
    381380}
    382381
    383 //*********************************************
    384 //
    385 //  support functions
    386 //
    387 //*********************************************
    388 
    389 /**
    390  * create usb_hub_info_t structure
    391  *
    392  * Does only basic copying of known information into new structure.
    393  * @param usb_dev usb device structure
    394  * @return basic usb_hub_info_t structure
    395  */
    396 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
    397         usb_hub_info_t * result = usb_new(usb_hub_info_t);
    398         if (!result) return NULL;
    399         result->usb_device = usb_dev;
    400         result->status_change_pipe = usb_dev->pipes[0].pipe;
    401         result->control_pipe = &usb_dev->ctrl_pipe;
    402         result->is_default_address_used = false;
    403         return result;
    404 }
    405 
    406 
    407 /**
    408  * Load hub-specific information into hub_info structure and process if needed
    409  *
    410  * Particularly read port count and initialize structure holding port
    411  * information. If there are non-removable devices, start initializing them.
    412  * This function is hub-specific and should be run only after the hub is
    413  * configured using usb_hub_set_configuration function.
    414  * @param hub_info hub representation
    415  * @return error code
    416  */
    417 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) {
    418         // get hub descriptor
    419         usb_log_debug("creating serialized descriptor\n");
    420         void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    421         usb_hub_descriptor_t * descriptor;
    422         int opResult;
    423 
    424         /* this was one fix of some bug, should not be needed anymore
    425          * these lines allow to reset hub once more, it can be used as
    426          * brute-force initialization for non-removable devices
    427          *
    428         opResult = usb_request_set_configuration(hub_info->control_pipe,
    429                 1);
    430         if (opResult != EOK) {
    431                 usb_log_error("could not set default configuration, errno %d",
    432                         opResult);
    433                 return opResult;
    434         }*/
    435 
    436 
    437         size_t received_size;
    438         opResult = usb_request_get_descriptor(hub_info->control_pipe,
    439                 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
    440                 USB_DESCTYPE_HUB,
    441                 0, 0, serialized_descriptor,
    442                 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    443 
    444         if (opResult != EOK) {
    445                 usb_log_error("failed when receiving hub descriptor, "
    446                         "badcode = %d\n",
    447                         opResult);
    448                 free(serialized_descriptor);
    449                 return opResult;
    450         }
    451         usb_log_debug2("deserializing descriptor\n");
    452         descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    453         if (descriptor == NULL) {
    454                 usb_log_warning("could not deserialize descriptor \n");
    455                 return opResult;
    456         }
    457         usb_log_debug("setting port count to %d\n", descriptor->ports_count);
    458         hub_info->port_count = descriptor->ports_count;
    459         /// \TODO check attached_devices array: this is not semantically correct
    460         //hub_info->attached_devs = (usb_hc_attached_device_t*)
    461 //              malloc((hub_info->port_count + 1) *
    462 //                      sizeof (usb_hc_attached_device_t)
    463 //              );
    464         hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1));
    465         size_t port;
    466         for (port = 0; port < hub_info->port_count + 1; port++) {
    467                 usb_hub_port_init(&hub_info->ports[port]);
    468         }
    469         //handle non-removable devices
    470         //usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
    471         usb_log_debug2("freeing data\n");
    472         free(serialized_descriptor);
    473         free(descriptor->devices_removable);
    474         free(descriptor);
    475         return EOK;
    476 }
    477 
    478 /**
    479  * Set configuration of hub
    480  *
    481  * Check whether there is at least one configuration and sets the first one.
    482  * This function should be run prior to running any hub-specific action.
    483  * @param hub_info hub representation
    484  * @return error code
    485  */
    486 static int usb_hub_set_configuration(usb_hub_info_t * hub_info) {
    487         //device descriptor
    488         usb_standard_device_descriptor_t *std_descriptor
    489                 = &hub_info->usb_device->descriptors.device;
    490         usb_log_debug("hub has %d configurations\n",
    491                 std_descriptor->configuration_count);
    492         if (std_descriptor->configuration_count < 1) {
    493                 usb_log_error("there are no configurations available\n");
    494                 return EINVAL;
    495         }
    496 
    497         usb_standard_configuration_descriptor_t *config_descriptor
    498                 = (usb_standard_configuration_descriptor_t *)
    499                 hub_info->usb_device->descriptors.configuration;
    500 
    501         /* Set configuration. */
    502         int opResult = usb_request_set_configuration(
    503                 &hub_info->usb_device->ctrl_pipe,
    504                 config_descriptor->configuration_number);
    505 
    506         if (opResult != EOK) {
    507                 usb_log_error("Failed to set hub configuration: %s.\n",
    508                         str_error(opResult));
    509                 return opResult;
    510         }
    511         usb_log_debug("\tused configuration %d\n",
    512                 config_descriptor->configuration_number);
    513 
    514         return EOK;
    515 }
    516382
    517383/**
     
    523389 * @return error code
    524390 */
    525 static int usb_hub_release_default_address(usb_hub_info_t * hub) {
     391static int usb_hub_release_default_address(usb_hub_info_t * hub){
    526392        int opResult = usb_hc_release_default_address(&hub->connection);
    527         if (opResult != EOK) {
    528                 usb_log_error("could not release default address, errno %d\n",
    529                         opResult);
     393        if(opResult!=EOK){
     394                usb_log_error("could not release default address, errno %d\n",opResult);
    530395                return opResult;
    531396        }
     
    533398        return EOK;
    534399}
    535 
    536 #if 0
    537 /**
    538  * Reset the port with new device and reserve the default address.
    539  * @param hub hub representation
    540  * @param port port number, starting from 1
    541  * @param speed transfer speed of attached device, one of low, full or high
    542  * @return error code
    543  */
    544 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
    545         usb_speed_t speed) {
    546         //if this hub already uses default address, it cannot request it once more
    547         if (hub->is_default_address_used) {
    548                 usb_log_info("default address used, another time\n");
    549                 return EREFUSED;
    550         }
    551         usb_log_debug("some connection changed\n");
    552         assert(hub->control_pipe->hc_phone);
    553         int opResult = usb_hub_clear_port_feature(hub->control_pipe,
    554                 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    555         if (opResult != EOK) {
    556                 usb_log_warning("could not clear port-change-connection flag\n");
    557         }
    558         usb_device_request_setup_packet_t request;
    559 
    560         //get default address
    561         opResult = usb_hc_reserve_default_address(&hub->connection, speed);
    562 
    563         if (opResult != EOK) {
    564                 usb_log_warning("cannot assign default address, it is probably "
    565                         "used %d\n",
    566                         opResult);
    567                 return opResult;
    568         }
    569         hub->is_default_address_used = true;
    570         //reset port
    571         usb_hub_set_reset_port_request(&request, port);
    572         opResult = usb_pipe_control_write(
    573                 hub->control_pipe,
    574                 &request, sizeof (usb_device_request_setup_packet_t),
    575                 NULL, 0
    576                 );
    577         if (opResult != EOK) {
    578                 usb_log_error("something went wrong when reseting a port %d\n",
    579                         opResult);
    580                 usb_hub_release_default_address(hub);
    581         }
    582         return opResult;
    583 }
    584 #endif
    585 
    586 #if 0
    587 /**
    588  * Finalize adding new device after port reset
    589  *
    590  * Set device`s address and start it`s driver.
    591  * @param hub hub representation
    592  * @param port port number, starting from 1
    593  * @param speed transfer speed of attached device, one of low, full or high
    594  */
    595 static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
    596         uint16_t port, usb_speed_t speed) {
    597 
    598         int opResult;
    599         usb_log_debug("finalizing add device\n");
    600         opResult = usb_hub_clear_port_feature(hub->control_pipe,
    601                 port, USB_HUB_FEATURE_C_PORT_RESET);
    602 
    603         if (opResult != EOK) {
    604                 usb_log_error("failed to clear port reset feature\n");
    605                 usb_hub_release_default_address(hub);
    606                 return;
    607         }
    608         //create connection to device
    609         usb_pipe_t new_device_pipe;
    610         usb_device_connection_t new_device_connection;
    611         usb_device_connection_initialize_on_default_address(
    612                 &new_device_connection,
    613                 &hub->connection
    614                 );
    615         usb_pipe_initialize_default_control(
    616                 &new_device_pipe,
    617                 &new_device_connection);
    618         usb_pipe_probe_default_control(&new_device_pipe);
    619 
    620         /* Request address from host controller. */
    621         usb_address_t new_device_address = usb_hc_request_address(
    622                 &hub->connection,
    623                 speed
    624                 );
    625         if (new_device_address < 0) {
    626                 usb_log_error("failed to get free USB address\n");
    627                 opResult = new_device_address;
    628                 usb_hub_release_default_address(hub);
    629                 return;
    630         }
    631         usb_log_debug("setting new address %d\n", new_device_address);
    632         //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    633         //    new_device_address);
    634         usb_pipe_start_session(&new_device_pipe);
    635         opResult = usb_request_set_address(&new_device_pipe,
    636                 new_device_address);
    637         usb_pipe_end_session(&new_device_pipe);
    638         if (opResult != EOK) {
    639                 usb_log_error("could not set address for new device %d\n",
    640                         opResult);
    641                 usb_hub_release_default_address(hub);
    642                 return;
    643         }
    644 
    645         //opResult = usb_hub_release_default_address(hc);
    646         opResult = usb_hub_release_default_address(hub);
    647         if (opResult != EOK) {
    648                 return;
    649         }
    650 
    651         devman_handle_t child_handle;
    652         //??
    653         opResult = usb_device_register_child_in_devman(new_device_address,
    654                 hub->connection.hc_handle, hub->usb_device->ddf_dev,
    655                 &child_handle,
    656                 NULL, NULL, NULL);
    657 
    658         if (opResult != EOK) {
    659                 usb_log_error("could not start driver for new device %d\n",
    660                         opResult);
    661                 return;
    662         }
    663         hub->attached_devs[port].handle = child_handle;
    664         hub->attached_devs[port].address = new_device_address;
    665 
    666         //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
    667         opResult = usb_hc_register_device(
    668                 &hub->connection,
    669                 &hub->attached_devs[port]);
    670         if (opResult != EOK) {
    671                 usb_log_error("could not assign address of device in hcd %d\n",
    672                         opResult);
    673                 return;
    674         }
    675         usb_log_info("Detected new device on `%s' (port %d), " \
    676             "address %d (handle %llu).\n",
    677                 hub->usb_device->ddf_dev->name, (int) port,
    678                 new_device_address, child_handle);
    679 }
    680 #endif
    681400
    682401/**
     
    689408 * @param port port number, starting from 1
    690409 */
    691 static void usb_hub_removed_device(
    692         usb_hub_info_t * hub, uint16_t port) {
     410void usb_hub_removed_device(
     411    usb_hub_info_t * hub,uint16_t port) {
    693412
    694413        int opResult = usb_hub_clear_port_feature(hub->control_pipe,
    695                 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    696         if (opResult != EOK) {
     414                                port, USB_HUB_FEATURE_C_PORT_CONNECTION);
     415        if(opResult != EOK){
    697416                usb_log_warning("could not clear port-change-connection flag\n");
    698417        }
     
    700419         * devide manager
    701420         */
    702 
     421       
    703422        //close address
    704         //if (hub->attached_devs[port].address != 0) {
    705423        if(hub->ports[port].attached_device.address >= 0){
    706424                /*uncomment this code to use it when DDF allows device removal
    707425                opResult = usb_hc_unregister_device(
    708                         &hub->connection,
    709                         hub->attached_devs[port].address);
     426                                &hub->connection, hub->attached_devs[port].address);
    710427                if(opResult != EOK) {
    711                         dprintf(USB_LOG_LEVEL_WARNING, "could not release "
    712                                 "address of "
     428                        dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
    713429                            "removed device: %d", opResult);
    714430                }
     
    716432                hub->attached_devs[port].handle = 0;
    717433                 */
    718         } else {
    719                 usb_log_warning("this is strange, disconnected device had "
    720                         "no address\n");
    721                 //device was disconnected before it`s port was reset -
    722                 //return default address
     434        }else{
     435                usb_log_warning("this is strange, disconnected device had no address\n");
     436                //device was disconnected before it`s port was reset - return default address
    723437                usb_hub_release_default_address(hub);
    724438        }
    725439}
    726440
     441
    727442/**
    728443 * Process over current condition on port.
    729  *
     444 * 
    730445 * Turn off the power on the port.
    731446 *
     
    733448 * @param port port number, starting from 1
    734449 */
    735 static void usb_hub_port_over_current(usb_hub_info_t * hub,
    736         uint16_t port, uint32_t status) {
     450void usb_hub_over_current( usb_hub_info_t * hub,
     451                uint16_t port){
    737452        int opResult;
    738         if(usb_port_over_current(&status)){
    739                 opResult = usb_hub_clear_port_feature(hub->control_pipe,
    740                         port, USB_HUB_FEATURE_PORT_POWER);
    741                 if (opResult != EOK) {
    742                         usb_log_error("cannot power off port %d;  %d\n",
     453        opResult = usb_hub_clear_port_feature(hub->control_pipe,
     454            port, USB_HUB_FEATURE_PORT_POWER);
     455        if(opResult!=EOK){
     456                usb_log_error("cannot power off port %d;  %d\n",
    743457                                port, opResult);
    744                 }
    745         }else{
    746                 opResult = usb_hub_set_port_feature(hub->control_pipe,
    747                         port, USB_HUB_FEATURE_PORT_POWER);
    748                 if (opResult != EOK) {
    749                         usb_log_error("cannot power on port %d;  %d\n",
    750                                 port, opResult);
    751                 }
    752         }
    753 }
    754 
    755 /** Retrieve port status.
    756  *
    757  * @param[in] ctrl_pipe Control pipe to use.
    758  * @param[in] port Port number (starting at 1).
    759  * @param[out] status Where to store the port status.
    760  * @return Error code.
    761  */
    762 static int get_port_status(usb_pipe_t *ctrl_pipe, size_t port,
    763     usb_port_status_t *status)
    764 {
    765         size_t recv_size;
    766         usb_device_request_setup_packet_t request;
    767         usb_port_status_t status_tmp;
    768 
    769         usb_hub_set_port_status_request(&request, port);
    770         int rc = usb_pipe_control_read(ctrl_pipe,
    771             &request, sizeof(usb_device_request_setup_packet_t),
    772             &status_tmp, sizeof(status_tmp), &recv_size);
    773         if (rc != EOK) {
    774                 return rc;
    775         }
    776 
    777         if (recv_size != sizeof (status_tmp)) {
    778                 return ELIMIT;
    779         }
    780 
    781         if (status != NULL) {
    782                 *status = status_tmp;
    783         }
    784 
    785         return EOK;
    786 }
    787 
    788 /** Callback for enabling a specific port.
    789  *
    790  * We wait on a CV until port is reseted.
    791  * That is announced via change on interrupt pipe.
    792  *
    793  * @param port_no Port number (starting at 1).
    794  * @param arg Custom argument, points to @c usb_hub_info_t.
    795  * @return Error code.
    796  */
    797 static int enable_port_callback(int port_no, void *arg)
    798 {
    799         usb_hub_info_t *hub = (usb_hub_info_t *) arg;
    800         int rc;
    801         usb_device_request_setup_packet_t request;
    802         usb_hub_port_t *my_port = hub->ports + port_no;
    803 
    804         usb_hub_set_reset_port_request(&request, port_no);
    805         rc = usb_pipe_control_write(hub->control_pipe,
    806             &request, sizeof(request), NULL, 0);
    807         if (rc != EOK) {
    808                 usb_log_warning("Port reset failed: %s.\n", str_error(rc));
    809                 return rc;
    810         }
    811 
    812         /*
    813          * Wait until reset completes.
    814          */
    815         fibril_mutex_lock(&my_port->reset_mutex);
    816         while (!my_port->reset_completed) {
    817                 fibril_condvar_wait(&my_port->reset_cv, &my_port->reset_mutex);
    818         }
    819         fibril_mutex_unlock(&my_port->reset_mutex);
    820 
    821         /* Clear the port reset change. */
    822         rc = usb_hub_clear_port_feature(hub->control_pipe,
    823             port_no, USB_HUB_FEATURE_C_PORT_RESET);
    824         if (rc != EOK) {
    825                 usb_log_error("Failed to clear port %d reset feature: %s.\n",
    826                     port_no, str_error(rc));
    827                 return rc;
    828         }
    829 
    830         return EOK;
    831 }
    832 
    833 /** Fibril for adding a new device.
    834  *
    835  * Separate fibril is needed because the port reset completion is announced
    836  * via interrupt pipe and thus we cannot block here.
    837  *
    838  * @param arg Pointer to struct add_device_phase1.
    839  * @return 0 Always.
    840  */
    841 static int add_device_phase1_worker_fibril(void *arg)
    842 {
    843         struct add_device_phase1 *data
    844             = (struct add_device_phase1 *) arg;
    845 
    846         usb_address_t new_address;
    847         devman_handle_t child_handle;
    848 
    849         int rc = usb_hc_new_device_wrapper(data->hub->usb_device->ddf_dev,
    850             &data->hub->connection, data->speed,
    851             enable_port_callback, (int) data->port, data->hub,
    852             &new_address, &child_handle,
    853             NULL, NULL, NULL);
    854 
    855         if (rc != EOK) {
    856                 usb_log_error("Failed registering device on port %zu: %s.\n",
    857                     data->port, str_error(rc));
    858                 goto leave;
    859         }
    860 
    861         data->hub->ports[data->port].attached_device.handle = child_handle;
    862         data->hub->ports[data->port].attached_device.address = new_address;
    863 
    864         usb_log_info("Detected new device on `%s' (port %zu), "
    865             "address %d (handle %" PRIun ").\n",
    866             data->hub->usb_device->ddf_dev->name, data->port,
    867             new_address, child_handle);
    868 
    869 leave:
    870         free(arg);
    871 
    872         return EOK;
    873 }
    874 
    875 
    876 /** Start device adding when connection change is detected.
    877  *
    878  * This fires a new fibril to complete the device addition.
    879  *
    880  * @param hub Hub where the change occured.
    881  * @param port Port index (starting at 1).
    882  * @param speed Speed of the device.
    883  * @return Error code.
    884  */
    885 static int add_device_phase1_new_fibril(usb_hub_info_t *hub, size_t port,
    886     usb_speed_t speed)
    887 {
    888         struct add_device_phase1 *data
    889             = malloc(sizeof(struct add_device_phase1));
    890         if (data == NULL) {
    891                 return ENOMEM;
    892         }
    893         data->hub = hub;
    894         data->port = port;
    895         data->speed = speed;
    896 
    897         usb_hub_port_t *the_port = hub->ports + port;
    898 
    899         fibril_mutex_lock(&the_port->reset_mutex);
    900         the_port->reset_completed = false;
    901         fibril_mutex_unlock(&the_port->reset_mutex);
    902 
    903         int rc = usb_hub_clear_port_feature(hub->control_pipe, port,
    904             USB_HUB_FEATURE_C_PORT_CONNECTION);
    905         if (rc != EOK) {
    906                 free(data);
    907                 usb_log_warning("Failed to clear port change flag: %s.\n",
    908                     str_error(rc));
    909                 return rc;
    910         }
    911 
    912         fid_t fibril = fibril_create(add_device_phase1_worker_fibril, data);
    913         if (fibril == 0) {
    914                 free(data);
    915                 return ENOMEM;
    916         }
    917         fibril_add_ready(fibril);
    918 
    919         return EOK;
    920 }
    921 
    922 
    923 /**
    924  * Process interrupts on given hub port
    925  *
    926  * Accepts connection, over current and port reset change.
    927  * @param hub hub representation
    928  * @param port port number, starting from 1
    929  */
    930 static void usb_hub_process_interrupt(usb_hub_info_t * hub,
    931         uint16_t port) {
    932         usb_log_debug("interrupt at port %d\n", port);
    933         //determine type of change
    934         //usb_pipe_t *pipe = hub->control_pipe;
    935 
    936         int opResult;
    937 
    938         usb_port_status_t status;
    939         opResult = get_port_status(&hub->usb_device->ctrl_pipe, port, &status);
    940         if (opResult != EOK) {
    941                 usb_log_error("Failed to get port %zu status: %s.\n",
    942                     port, str_error(opResult));
    943                 return;
    944         }
    945 
    946         //something connected/disconnected
    947         /*
    948         if (usb_port_connect_change(&status)) {
    949                 usb_log_debug("connection change on port\n");
    950                 if (usb_port_dev_connected(&status)) {
    951                         usb_hub_init_add_device(hub, port,
    952                                 usb_port_speed(&status));
    953                 } else {
    954                         usb_hub_removed_device(hub, port);
    955                 }
    956         }*/
    957         if (usb_port_connect_change(&status)) {
    958                 bool device_connected = usb_port_dev_connected(&status);
    959                 usb_log_debug("Connection change on port %zu: %s.\n", port,
    960                     device_connected ? "device attached" : "device removed");
    961 
    962                 if (device_connected) {
    963                         opResult = add_device_phase1_new_fibril(hub, port,
    964                             usb_port_speed(&status));
    965                         if (opResult != EOK) {
    966                                 usb_log_error(
    967                                     "Cannot handle change on port %zu: %s.\n",
    968                                     str_error(opResult));
    969                         }
    970                 } else {
    971                         usb_hub_removed_device(hub, port);
    972                 }
    973         }
    974         //over current
    975         if (usb_port_overcurrent_change(&status)) {
    976                 //check if it was not auto-resolved
    977                 usb_log_debug("overcurrent change on port\n");
    978                 usb_hub_port_over_current(hub, port, status);
    979         }
    980         //port reset
    981         if (usb_port_reset_completed(&status)) {
    982                 /*
    983                 usb_log_debug("port reset complete\n");
    984                 if (usb_port_enabled(&status)) {
    985                         usb_hub_finalize_add_device(hub, port,
    986                                 usb_port_speed(&status));
    987                 } else {
    988                         usb_log_warning("port reset, but port still not "
    989                                 "enabled\n");
    990                 }
    991                  * */
    992                 usb_log_debug("Port %zu reset complete.\n", port);
    993                 if (usb_port_enabled(&status)) {
    994                         /* Finalize device adding. */
    995                         usb_hub_port_t *the_port = hub->ports + port;
    996                         fibril_mutex_lock(&the_port->reset_mutex);
    997                         the_port->reset_completed = true;
    998                         fibril_condvar_broadcast(&the_port->reset_cv);
    999                         fibril_mutex_unlock(&the_port->reset_mutex);
    1000                 } else {
    1001                         usb_log_warning(
    1002                             "Port %zu reset complete but port not enabled.\n",
    1003                             port);
    1004                 }
    1005         }
    1006         usb_log_debug("status x%x : %d\n ", status, status);
    1007 
    1008         usb_port_set_connect_change(&status, false);
    1009         usb_port_set_reset(&status, false);
    1010         usb_port_set_reset_completed(&status, false);
    1011         usb_port_set_dev_connected(&status, false);
    1012         usb_port_set_overcurrent_change(&status,false);
    1013         /// \TODO what about port power change?
    1014         if (status >> 16) {
    1015                 usb_log_info("there was unsupported change on port %d: %X\n",
    1016                         port, status);
    1017 
    1018         }
    1019 }
    1020 
    1021 /**
    1022  * process hub over current change
    1023  *
    1024  * This means either to power off the hub or power it on.
    1025  * @param hub_info hub instance
    1026  * @param status hub status bitmask
    1027  * @return error code
    1028  */
    1029 static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
    1030         usb_hub_status_t status)
    1031 {
    1032         int opResult;
    1033         if(usb_hub_over_current(&status)){
    1034                 opResult = usb_hub_clear_feature(hub_info->control_pipe,
    1035                         USB_HUB_FEATURE_PORT_POWER);
    1036                 if (opResult != EOK) {
    1037                         usb_log_error("cannot power off hub: %d\n",
    1038                                 opResult);
    1039                 }
    1040         }else{
    1041                 opResult = usb_hub_set_feature(hub_info->control_pipe,
    1042                         USB_HUB_FEATURE_PORT_POWER);
    1043                 if (opResult != EOK) {
    1044                         usb_log_error("cannot power on hub: %d\n",
    1045                                 opResult);
    1046                 }
    1047         }
    1048         return opResult;
    1049 }
    1050 
    1051 /**
    1052  * process hub power change
    1053  *
    1054  * If the power has been lost, reestablish it.
    1055  * If it was reestablished, re-power all ports.
    1056  * @param hub_info hub instance
    1057  * @param status hub status bitmask
    1058  * @return error code
    1059  */
    1060 static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
    1061         usb_hub_status_t status)
    1062 {
    1063         int opResult;
    1064         if(usb_hub_local_power_lost(&status)){
    1065                 //restart power on hub
    1066                 opResult = usb_hub_set_feature(hub_info->control_pipe,
    1067                         USB_HUB_FEATURE_PORT_POWER);
    1068                 if (opResult != EOK) {
    1069                         usb_log_error("cannot power on hub: %d\n",
    1070                                 opResult);
    1071                 }
    1072         }else{//power reestablished on hub- restart ports
    1073                 size_t port;
    1074                 for(port=0;port<hub_info->port_count;++port){
    1075                         opResult = usb_hub_set_port_feature(
    1076                                 hub_info->control_pipe,
    1077                                 port, USB_HUB_FEATURE_PORT_POWER);
    1078                         if (opResult != EOK) {
    1079                                 usb_log_error("cannot power on port %d;  %d\n",
    1080                                         port, opResult);
    1081                         }
    1082                 }
    1083         }
    1084         return opResult;
    1085 }
    1086 
    1087 /**
    1088  * process hub interrupts
    1089  *
    1090  * The change can be either in the over-current condition or
    1091  * local-power lost condition.
    1092  * @param hub_info hub instance
    1093  */
    1094 static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info){
    1095         usb_log_debug("global interrupt on a hub\n");
    1096         usb_pipe_t *pipe = hub_info->control_pipe;
    1097         int opResult;
    1098 
    1099         usb_port_status_t status;
    1100         size_t rcvd_size;
    1101         usb_device_request_setup_packet_t request;
    1102         //int opResult;
    1103         usb_hub_set_hub_status_request(&request);
    1104         //endpoint 0
    1105 
    1106         opResult = usb_pipe_control_read(
    1107                 pipe,
    1108                 &request, sizeof (usb_device_request_setup_packet_t),
    1109                 &status, 4, &rcvd_size
    1110                 );
    1111         if (opResult != EOK) {
    1112                 usb_log_error("could not get hub status\n");
    1113                 return;
    1114         }
    1115         if (rcvd_size != sizeof (usb_port_status_t)) {
    1116                 usb_log_error("received status has incorrect size\n");
    1117                 return;
    1118         }
    1119         //port reset
    1120         if (usb_hub_over_current_change(&status)) {
    1121                 usb_process_hub_over_current(hub_info,status);
    1122         }
    1123         if (usb_hub_local_power_change(&status)) {
    1124                 usb_process_hub_power_change(hub_info,status);
    1125         }
    1126 }
    1127 
     458        }
     459}
    1128460
    1129461
  • uspace/drv/usbhub/usbhub.h

    r8961c22 r61727bf  
    4343
    4444#include <usb/hub.h>
    45 #include <usb/classes/hub.h>
    4645
    4746#include <usb/pipes.h>
    4847#include <usb/devdrv.h>
    4948
    50 #include <fibril_synch.h>
     49#include "ports.h"
    5150
    5251
    53 /** Information about single port on a hub. */
    54 typedef struct {
    55         /** Mutex needed by CV for checking port reset. */
    56         fibril_mutex_t reset_mutex;
    57         /** CV for waiting to port reset completion. */
    58         fibril_condvar_t reset_cv;
    59         /** Whether port reset is completed.
    60          * Guarded by @c reset_mutex.
    61          */
    62         bool reset_completed;
    63 
    64         /** Information about attached device. */
    65         usb_hc_attached_device_t attached_device;
    66 } usb_hub_port_t;
    67 
    68 /** Initialize hub port information.
    69  *
    70  * @param port Port to be initialized.
    71  */
    72 static inline void usb_hub_port_init(usb_hub_port_t *port) {
    73         port->attached_device.address = -1;
    74         port->attached_device.handle = 0;
    75         fibril_mutex_initialize(&port->reset_mutex);
    76         fibril_condvar_initialize(&port->reset_cv);
    77 }
    7852
    7953/** Information about attached hub. */
     
    8256        size_t port_count;
    8357
    84         /** attached device handles, for each port one */
     58        /** Ports. */
    8559        usb_hub_port_t *ports;
    86 
     60       
    8761        /** connection to hcd */
    8862        usb_hc_connection_t connection;
     
    11589} usb_hub_info_t;
    11690
    117 //int usb_hub_control_loop(void * hub_info_param);
     91/**
     92 * function running the hub-controlling loop.
     93 * @param hub_info_param hub info pointer
     94 */
     95int usb_hub_control_loop(void * hub_info_param);
     96
     97/**
     98 * Check changes on specified hub
     99 * @param hub_info_param pointer to usb_hub_info_t structure
     100 * @return error code if there is problem when initializing communication with
     101 * hub, EOK otherwise
     102 */
     103int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
     104
     105void usb_hub_removed_device(usb_hub_info_t *, uint16_t);
     106void usb_hub_over_current(usb_hub_info_t *, uint16_t);
    118107
    119108int usb_hub_add_device(usb_device_t * usb_dev);
    120109
    121 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
    122 
    123 bool hub_port_changes_callback(usb_device_t *dev,
    124     uint8_t *change_bitmap, size_t change_bitmap_size, void *arg);
    125110#endif
    126111/**
  • uspace/drv/usbhub/usbhub_private.h

    r8961c22 r61727bf  
    3838
    3939#include "usbhub.h"
    40 #include "usblist.h"
    4140
    4241#include <adt/list.h>
     
    111110
    112111/**
    113  * Clear feature on hub port.
    114  *
    115  * @param hc Host controller telephone
    116  * @param address Hub address
    117  * @param port_index Port
    118  * @param feature Feature selector
    119  * @return Operation result
    120  */
    121 static inline int usb_hub_set_port_feature(usb_pipe_t *pipe,
    122     int port_index,
    123     usb_hub_class_feature_t feature) {
    124 
    125         usb_device_request_setup_packet_t clear_request = {
    126                 .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
    127                 .request = USB_DEVREQ_SET_FEATURE,
    128                 .length = 0,
    129                 .index = port_index
    130         };
    131         clear_request.value = feature;
    132         return usb_pipe_control_write(pipe, &clear_request,
    133             sizeof(clear_request), NULL, 0);
    134 }
    135 
    136 
    137 /**
    138  * Clear feature on hub port.
    139  *
    140  * @param pipe pipe to hub control endpoint
    141  * @param feature Feature selector
    142  * @return Operation result
    143  */
    144 static inline int usb_hub_clear_feature(usb_pipe_t *pipe,
    145     usb_hub_class_feature_t feature) {
    146 
    147         usb_device_request_setup_packet_t clear_request = {
    148                 .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,
    149                 .request = USB_DEVREQ_CLEAR_FEATURE,
    150                 .length = 0,
    151                 .index = 0
    152         };
    153         clear_request.value = feature;
    154         return usb_pipe_control_write(pipe, &clear_request,
    155             sizeof(clear_request), NULL, 0);
    156 }
    157 
    158 /**
    159  * Clear feature on hub port.
    160  *
    161  * @param pipe pipe to hub control endpoint
    162  * @param feature Feature selector
    163  * @return Operation result
    164  */
    165 static inline int usb_hub_set_feature(usb_pipe_t *pipe,
    166     usb_hub_class_feature_t feature) {
    167 
    168         usb_device_request_setup_packet_t clear_request = {
    169                 .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,
    170                 .request = USB_DEVREQ_SET_FEATURE,
    171                 .length = 0,
    172                 .index = 0
    173         };
    174         clear_request.value = feature;
    175         return usb_pipe_control_write(pipe, &clear_request,
    176             sizeof(clear_request), NULL, 0);
    177 }
    178 
    179 /**
    180112 * create uint8_t array with serialized descriptor
    181113 *
Note: See TracChangeset for help on using the changeset viewer.