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

Changeset 266d0871 in mainline


Ignore:
Timestamp:
2010-12-15T13:25:20Z (11 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master
Children:
1840e0d
Parents:
d5e7668
Message:

usbvirt: add callback when device changes state

The virtual root hub uses this to suspend power source to all
ports when entering `configured' state.

Location:
uspace
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/vhc/hubops.c

    rd5e7668 r266d0871  
    5959static int on_get_descriptor(struct usbvirt_device *dev,
    6060    usb_device_request_setup_packet_t *request, uint8_t *data);
    61 static int on_set_configuration(struct usbvirt_device *dev,
    62     usb_device_request_setup_packet_t *request, uint8_t *data);
    6361static int on_data_request(struct usbvirt_device *dev,
    6462    usb_endpoint_t endpoint,
     
    8381}
    8482
    85 /** Callback for SET_CONFIGURATION request. */
    86 int on_set_configuration(struct usbvirt_device *dev,
    87     usb_device_request_setup_packet_t *request, uint8_t *data)
    88 {
    89         /* We must suspend power source to all ports. */
     83static void change_all_ports_state(hub_device_t *hub, hub_port_state_t state)
     84{
    9085        size_t i;
    9186        for (i = 0; i < HUB_PORT_COUNT; i++) {
    92                 hub_port_t *port = &hub_dev.ports[i];
    93                
    94                 set_port_state(port, HUB_PORT_STATE_POWERED_OFF);
    95         }
    96        
    97         /* Let the framework handle the rest of the job. */
    98         return EFORWARD;
     87                hub_port_t *port = &hub->ports[i];
     88                set_port_state(port, state);
     89        }
     90}
     91
     92/** Callback when device changes states. */
     93static void on_state_change(struct usbvirt_device *dev,
     94    usbvirt_device_state_t old_state, usbvirt_device_state_t new_state)
     95{
     96        switch (new_state) {
     97                case USBVIRT_STATE_CONFIGURED:
     98                        change_all_ports_state(&hub_dev,
     99                            HUB_PORT_STATE_POWERED_OFF);
     100                        break;
     101                case USBVIRT_STATE_ADDRESS:
     102                        change_all_ports_state(&hub_dev,
     103                            HUB_PORT_STATE_NOT_CONFIGURED);
     104                        break;
     105                default:
     106                        break;
     107        }
    99108}
    100109
     
    518527static usbvirt_control_transfer_handler_t endpoint_zero_handlers[] = {
    519528        {
    520                 STD_REQ(DIR_OUT, REC_DEVICE, USB_DEVREQ_SET_CONFIGURATION),
    521                 .name = "SetConfiguration",
    522                 .callback = on_set_configuration
    523         },
    524         {
    525529                STD_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
    526530                .name = "GetDescriptor",
     
    585589        .control_transfer_handlers = endpoint_zero_handlers,
    586590        .on_data = NULL,
    587         .on_data_request = on_data_request
     591        .on_data_request = on_data_request,
     592        .on_state_change = on_state_change,
    588593};
    589594
  • uspace/lib/usbvirt/include/usbvirt/device.h

    rd5e7668 r266d0871  
    5252} usbvirt_request_recipient_t;
    5353
     54/** Possible states of virtual USB device.
     55 * Notice that these are not 1:1 mappings to those in USB specification.
     56 */
     57typedef enum {
     58        USBVIRT_STATE_DEFAULT,
     59        USBVIRT_STATE_ADDRESS,
     60        USBVIRT_STATE_CONFIGURED
     61} usbvirt_device_state_t;
     62
    5463typedef struct usbvirt_device usbvirt_device_t;
    5564struct usbvirt_control_transfer;
     
    96105        usb_direction_t (*decide_control_transfer_direction)(
    97106            usb_endpoint_t endpoint, void *buffer, size_t size);
     107
     108        /** Callback when device changes its state.
     109         *
     110         * It is correct that this function is called when both states
     111         * are equal (e.g. this function is called during SET_CONFIGURATION
     112         * request done on already configured device).
     113         *
     114         * @warning The value of <code>dev->state</code> before calling
     115         * this function is not specified (i.e. can be @p old_state or
     116         * @p new_state).
     117         */
     118        void (*on_state_change)(usbvirt_device_t *dev,
     119            usbvirt_device_state_t old_state, usbvirt_device_state_t new_state);
    98120} usbvirt_device_ops_t;
    99121
     
    130152        uint8_t current_configuration;
    131153} usbvirt_descriptors_t;
    132 
    133 /** Possible states of virtual USB device.
    134  * Notice that these are not 1:1 mappings to those in USB specification.
    135  */
    136 typedef enum {
    137         USBVIRT_STATE_DEFAULT,
    138         USBVIRT_STATE_ADDRESS,
    139         USBVIRT_STATE_CONFIGURED
    140 } usbvirt_device_state_t;
    141154
    142155/** Information about on-going control transfer.
  • uspace/lib/usbvirt/src/ctrlpipe.c

    rd5e7668 r266d0871  
    154154                 * setting address when in configured state).
    155155                 */
     156                usbvirt_device_state_t new_state;
    156157                if (device->new_address == 0) {
    157                         device->state = USBVIRT_STATE_DEFAULT;
     158                        new_state = USBVIRT_STATE_DEFAULT;
    158159                } else {
    159                         device->state = USBVIRT_STATE_ADDRESS;
     160                        new_state = USBVIRT_STATE_ADDRESS;
    160161                }
    161162                device->address = device->new_address;
     
    163164                device->new_address = -1;
    164165               
     166                if (DEVICE_HAS_OP(device, on_state_change)) {
     167                        device->ops->on_state_change(device, device->state,
     168                            new_state);
     169                }
     170                device->state = new_state;
     171
    165172                device->lib_debug(device, 2, USBVIRT_DEBUGTAG_CONTROL_PIPE_ZERO,
    166173                    "device address changed to %d (state %s)",
  • uspace/lib/usbvirt/src/stdreq.c

    rd5e7668 r266d0871  
    157157       
    158158        if (configuration_value == 0) {
     159                if (DEVICE_HAS_OP(device, on_state_change)) {
     160                        device->ops->on_state_change(device, device->state,
     161                            USBVIRT_STATE_ADDRESS);
     162                }
    159163                device->state = USBVIRT_STATE_ADDRESS;
    160164        } else {
     
    163167                * user selected existing configuration.
    164168                */
     169                if (DEVICE_HAS_OP(device, on_state_change)) {
     170                        device->ops->on_state_change(device, device->state,
     171                            USBVIRT_STATE_CONFIGURED);
     172                }
    165173                device->state = USBVIRT_STATE_CONFIGURED;
    166174                if (device->descriptors) {
Note: See TracChangeset for help on using the changeset viewer.