| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| library fuchsia.device; |
| |
| using zx; |
| using fuchsia.device.manager; |
| |
| /// Maxmium length for a device name |
| const uint64 MAX_DEVICE_NAME_LEN = 32; |
| /// Maximum length of a device path |
| const uint64 MAX_DEVICE_PATH_LEN = 1024; |
| /// Maxmium length for a driver name |
| const uint64 MAX_DRIVER_NAME_LEN = 32; |
| /// Maximum length for a driver path |
| const uint64 MAX_DRIVER_PATH_LEN = 1024; |
| /// Maximum device power states. In future this should account |
| /// for performance states. |
| const uint32 MAX_DEVICE_POWER_STATES = 5; |
| const uint32 MIN_DEVICE_POWER_STATES = 2; // D0 & D3COLD |
| const uint32 MAX_DEVICE_PERFORMANCE_STATES = 20; |
| const uint32 MIN_DEVICE_PERFORMANCE_STATES = 1; |
| |
| /// Signal that will be active on a device event handle if the device's read() method |
| /// will return data. |
| const uint32 DEVICE_SIGNAL_READABLE = 0x01000000; // ZX_USER_SIGNAL_0 |
| /// Signal that will be active on a device event handle if the device has some out-of-band |
| /// mechanism that needs attention. |
| /// This is primarily used by the PTY support. |
| const uint32 DEVICE_SIGNAL_OOB = 0x02000000; // ZX_USER_SIGNAL_1 |
| /// Signal that will be active on a device event handle if the device's write() method |
| /// will accept data. |
| const uint32 DEVICE_SIGNAL_WRITABLE = 0x04000000; // ZX_USER_SIGNAL_2 |
| /// Signal that will be active on a device event handle if the device has encountered an error. |
| /// This is primarily used by the PTY support. |
| const uint32 DEVICE_SIGNAL_ERROR = 0x08000000; // ZX_USER_SIGNAL_3 |
| /// Signal that will be active on a device event handle if the device has been disconnected. |
| /// This is primarily used by the PTY support. |
| const uint32 DEVICE_SIGNAL_HANGUP = 0x10000000; // ZX_USER_SIGNAL_4 |
| |
| enum DevicePowerState : uint8 { |
| /// Mandatory Working state. Device is fully functional, can take I/O, |
| /// issue interrrupts. This state is mandatory for all devices |
| /// The device enters into this state by default, when powered on. |
| DEVICE_POWER_STATE_D0 = 0; |
| /// [OPTIONAL] Device is not working when in this state. It cannot process |
| /// I/O nor issue interrupts, unless it is armed for some special interrupts |
| /// that can wake up the system/device. When in this state, the restore time |
| /// of getting back to working state is less than other low-power states |
| /// Power savings in this state are lesser than other low power states. |
| /// Device may retain some hardware context and full initialization |
| /// may not be needed when resuming from this state. |
| DEVICE_POWER_STATE_D1 = 1; |
| /// [OPTIONAL] Device is not working when in this state. It cannot process |
| /// I/O nor issue interrupts, unless it is armed for some special interrupts |
| /// that can wake up the system/device. When in this state, the restore time |
| /// of getting back to working state is more than DEVICE_POWER_STATE_D1 and |
| /// less than restore time of getting back from DEVICE_POWER_STATE_D3HOT, |
| /// DEVICE_POWER_STATE_D3COLD. Power savings in this state are lesser |
| /// than DEVICE_POWER_STATE_D3COLD, DEVICE_POWER_STATE_D3HOT. |
| /// Device may retain some hardware context and full initialization |
| /// may not be needed when resuming from this state. |
| DEVICE_POWER_STATE_D2 = 2; |
| /// [OPTIONAL] Device is not working when in this state. It cannot process |
| /// I/O nor issue interrupts, unless it is armed for some special interrupts |
| /// that can wake up the system/device. When in this state, the restore time |
| /// of getting back to working state is more than DEVICE_POWER_STATE_D1, |
| /// DEVICE_POWER_STATE_D3HOT and less than restore time of getting back from |
| /// DEVICE_POWER_STATE_D3COLD. Power savings in this state are lesser |
| /// than DEVICE_POWER_STATE_D3COLD. Device has no context and full initialization |
| /// by the device driver when resuming from this state. |
| /// Although the device is completely off, it is still powered on and is enumerable. |
| DEVICE_POWER_STATE_D3HOT = 3; |
| /// [MANDATORY] Device is not working when in this state. It cannot process |
| /// I/O nor issue interrupts, unless it is armed for some special interrupts |
| /// that can wake up the system/device. When in this state, the restore time |
| /// of getting back to working state is more than all other low power states. |
| /// Power savings are more compared to all other low-power states. |
| /// Device has no context and full initialization by the device driver when |
| /// resuming from this state. In this state, the power to this device is turned off. |
| /// Device may be powered by other auxiliary supplies to support wake capability. |
| DEVICE_POWER_STATE_D3COLD = 4; |
| }; |
| |
| /// [MANDATORY] Default performance state when the device is in DEVICE_POWER_STATE_D0 |
| const uint32 DEVICE_PERFORMANCE_STATE_P0 = 0; |
| |
| // TODO(ravoorir): This should be table when the Controller protocol moves off of simple layout. |
| struct DevicePowerStateInfo { |
| DevicePowerState state_id; |
| |
| /// Is this state supported? |
| bool is_supported; |
| |
| /// Restore time for coming out of this state to working D0 state. |
| int64 restore_latency; |
| |
| /// Is this device wakeup_capable? |
| bool wakeup_capable; |
| |
| /// Deepest system system sleep state that the device can wake the system from. |
| int32 system_wake_state; |
| }; |
| |
| /// Performance state info for a device. A performance state is relevant only |
| /// when the device is in non-sleeping working device power state. |
| struct DevicePerformanceStateInfo { |
| int32 state_id; |
| /// Restore time for coming out of this state to fully working performance state. |
| int64 restore_latency; |
| /// Is this state supported? |
| bool is_supported; |
| // TODO(ravoorir): Explore how more device specific metadata can be saved here. |
| // Maybe a union of metadata coming from different devices. |
| }; |
| |
| struct SystemPowerStateInfo { |
| uint32 suspend_flag; |
| /// Should wakeup be enabled from this system state? |
| bool wakeup_enable; |
| |
| /// Device power state that the device should be in for this system power state. |
| DevicePowerState dev_state; |
| }; |
| |
| /// Interface for manipulating a device in a devhost |
| protocol Controller { |
| /// Attempt to bind the requested driver to this device |
| Bind(string:MAX_DRIVER_PATH_LEN driver) -> () error zx.status; |
| |
| /// This api will unbind all the children of this device and bind the |
| /// requested driver. If the driver is empty, it will autobind. |
| /// The Rebind will not return until the bind completes. |
| Rebind(string:MAX_DRIVER_PATH_LEN driver) -> () error zx.status; |
| |
| /// Disconnect this device and allow its parent to be bound again. |
| /// This may not complete before it returns. |
| ScheduleUnbind() -> () error zx.status; |
| |
| /// Return the name of the driver managing this the device |
| GetDriverName() -> (zx.status status, string:MAX_DRIVER_NAME_LEN? name); |
| /// Return the name of the device |
| GetDeviceName() -> (string:MAX_DEVICE_NAME_LEN name); |
| |
| /// Return the topological path for this device |
| GetTopologicalPath() -> (string:MAX_DEVICE_PATH_LEN path) error zx.status; |
| |
| /// Get an event for monitoring device conditions (see `DEVICE_SIGNAL_*` constants) |
| GetEventHandle() -> (zx.status status, handle<event>? event); |
| |
| /// Return the current logging flags for this device's driver |
| GetDriverLogFlags() -> (zx.status status, uint32 flags); |
| /// Set the logging flags for this device's driver. |
| /// Each set bit in `clear_flags` will be cleared in the log flags state. |
| /// Each set bit in `set_flags` will then be set in the log flags state. |
| SetDriverLogFlags(uint32 clear_flags, uint32 set_flags) -> (zx.status status); |
| |
| /// Debug command: execute the device's suspend hook |
| DebugSuspend() -> (zx.status status); |
| /// Debug command: execute the device's resume hook |
| DebugResume() -> (zx.status status); |
| |
| /// Runs compatibility tests for the driver that binds to this device. |
| /// The |hook_wait_time| is the time that the driver expects to take for |
| /// each device hook in nanoseconds. |
| /// Returns whether the driver passed the compatibility check. |
| RunCompatibilityTests(int64 hook_wait_time) -> (uint32 status); |
| |
| /// Gets the device power capabilities. Used by the system wide power manager |
| /// to manage power for this device. |
| GetDevicePowerCaps() -> (array<DevicePowerStateInfo>:MAX_DEVICE_POWER_STATES dpstates) error zx.status; |
| |
| /// Gets the device performance states. Used by the system wide power manager |
| /// to manage power for this device. |
| GetDevicePerformanceStates() -> (array<DevicePerformanceStateInfo>:MAX_DEVICE_PERFORMANCE_STATES states, zx.status status); |
| |
| /// Updates the mapping between system power states to device power states. Used by the system |
| /// wide power manager to manage power for this device |
| UpdatePowerStateMapping(array<SystemPowerStateInfo>:fuchsia.device.manager.MAX_SYSTEM_POWER_STATES mapping) -> () error zx.status; |
| |
| /// Get the mapping between system power states to device power states. Used by the system |
| /// wide power manager to manage power for this device. |
| GetPowerStateMapping() -> (array<SystemPowerStateInfo>:fuchsia.device.manager.MAX_SYSTEM_POWER_STATES mapping) error zx.status; |
| |
| /// Transition this device from a working to a sleep state or from a sleep state to a deeper sleep |
| /// state. |
| // TODO(ravoorir): At the moment, this will call the suspend hook only on this device. |
| // In a future change, this api will result in suspend hook being called on all the children and |
| // descendants before transitioning this device. |
| // On success, the out_state is same as requested_state. |
| // On failure, the out_state is the state the device can go into at this point, depending |
| // on the configuration of its children. For example, a device cannot go into the |
| // requested_state, if the requested_state does not support a descendant's wake configuration. |
| Suspend(DevicePowerState requested_state) -> (zx.status status, DevicePowerState out_state); |
| /// Transition this device from a sleep state to a working state. |
| // TODO(ravoorir): At the moment, this will call the resume hook only on this device. |
| // In a future change, this api will result in resume hook being called on all the children |
| // after the current device is transitioned. |
| // On success, the out_state has the actual state of the device. The out_state could be |
| // different from the requested_state, if the device could not resume to the requested |
| // performance state, but the device could resume to a working state. |
| // Just because the device is not able to transition to a particular performance state, |
| // we do not want to suspend the device back. |
| Resume(DevicePowerState requested_state) -> (DevicePowerState out_state) error zx.status; |
| /// Set the performance state of this device to the requested performance state. This is only |
| /// called for the current device and none of the descendants are aware of the state |
| /// transition. |
| /// On success, the out_state and the requested_state is same. If the device is in a working |
| /// state, the performance state will be changed to requested_state immediately. If the device |
| /// is in non-working state, the performance state will be the requested_state whenever the |
| /// device transitions to working state. |
| /// On failure, the out_state will have the state that the device can go into. |
| SetPerformanceState(uint32 requested_state) -> (zx.status status, uint32 out_state); |
| /// Configure autosuspend of device to this deepest sleep state. |
| ConfigureAutoSuspend(bool enable, |
| DevicePowerState requested_deepest_sleep_state) -> (zx.status status); |
| }; |