opensd-files

package: opensd

title: opensd-files(5)

summary: OpenSD configuration file formats

text:
# opensd-files(5)

## NAME
opensd-files - OpenSD configuration file formats

## SYNOPSIS
${XDG_CONFIG_HOME}/opensd/config.ini

${XDG_CONFIG_HOME}/opensd/profiles/*.profile

## DESCRIPTION
These files are used to configure the OpenSD daemon. This manpage is generated from the opensd documentation, which can be found online at <https://open-sd.gitlab.io/opensd-docs>. An offline version in html format can be found with your installation (usually in /usr/share/doc/opensd or /usr/local/share/doc).

## CONFIGURATION FILES
OpenSD uses two types of configuration files. The first type being the Daemon Configuration, and the second type are gamepad Profiles which are loaded by the daemon.

All files use an ini-style <https://en.wikipedia.org/wiki/INI_file> format and are easily created or modified with any text editor.

Since OpenSD is a userspace daemon, configuration files are stored in $XDG_CONFIG_HOME/opensd/ which, on most systems, will be ~/.config/opensd/. Gamepad profiles are stored in the profile subdirectory, (example: ~/.config/opensd/profiles/). If the OpenSD user config directory does not exist, a new one will be created and populated with the default configuration files when the daemon is run.

Note OpenSD follows the XDG specification, so environments which set / change $XDG_HOME or $XDG_CONFIG_HOME should behave correctly. For the purposes of this documentation we’ll refer to the default XDG paths for user configuration files (example: ~/.config/opensd/).

Basic format rules:

•Parsing is line-based and space delimited.

•The files are broken into braced enclosed sections and keys.

•Names of sections and keys are not case-sensitive, but values can be, such as file names.

•Sections are enclosed in square brackets (example: [SectionName])

•Keys must be contained within a section.

•Key assignment must be separated by whitespace. (example: key = value1 value2 value3)

•Comments are preceeded by a # or ; at the beginning of the line.

•Placing a value in quotes " treats the value as a literal string which allows whitespace. (example: key = "A string with spaces")

## DAEMON CONFIGURATION FILE (CONFIG.INI)
This single file contains a small group of options that pertain to the daemon itself. The default configuration file for the daemon can be found at ~/.config/opensd/config.ini. An unmodified copy of this file will be installed to /usr/local/share/opensd/config/config.ini or /usr/share/opensd/config/config.ini.

An example config.ini can be found in this documentation if you want to see what a complete file might look like.

### [Daemon] Section

Note This section is required.

### Profile
This tells the daemon which profile to load when it starts up. Profiles are only loaded from the ~./config/opensd/profiles/ directory, so only specify the filename here. OpenSD also has other methods for loading profiles once the daemon is running, this setting is only for the default profile you wish to use.

Format:

```
Profile = <filename>
```

Example:

```
[Daemon]
Profile = default.profile
```

### AllowClients

Note This feature is not yet fully implemented.

This setting enables or disables the use of the CLI and GUI utilities which connect to the daemon. If set to false, the daemon will not listen for clients. This can be useful if you want to "lock down" a configuration so it cannot be changed while it is running. The default is true.

Format:

```
AllowClients = <true | false>
```

Example:

```
[Daemon]
AllowClients = true
```

## PROFILE CONFIGURATION FILES (*.PROFILE)
These files are used to configure the gamepad driver features and bindings. A default profile is configured in the config.ini file to be loaded at startup, but you can also switch between them at any time while the daemon is running using any of several possible methods.

Gamepad profiles can be found in ~/.config/opensd/profiles/. The file extension is *.profile.

An example profile can be found in this documentation if you want to see what a complete file might look like.

A default profile (cleverly named default.profile) is provided which includes documentation in the comments on how to configure it. It is not recommended to modify this file, instead you should make a copy of it, renaming it to whatever_you_want.profile and edit that file instead. If the default profile is deleted, it will be recreated when the daemon is run, so if you need a clean or updated copy of the default.profile, simply delete it and restart the OpenSD daemon.

An unmodified copy of this file will be installed to /usr/local/share/opensd/profiles/default.profile or /usr/share/opensd/profiles/default.profile.

### Name
The profile name as it will appear in the GUI and through the CLI query. Should be unique for each profile to avoid confusion.

Format:

```
Name = <profile_name>
```

•profile_name: Any unique name. Should be enclosed in quotes "" to preserve spaces.

Example:

```
[Profile]
Name = "My favourite gamepad profile"
```

Note Prior to version 0.47, quoted literal strings were not supported. It’s recommended, but not necessary to update old profiles to put this value in quotes.

### Description
A breif description of the profile for use in the GUI and CLI query. Does not affect anything else, just intended as a hint for users.

Format:

```
Description = <description>
```

•description: A brief, helpful description of what your profile does. Should be enclosed in quotes "" to preserve spaces.

Example:

```
[Profile]
Description = "Just a profile I use for most applications."
```

Note Prior to version 0.47, quoted literal strings were not supported. It’s recommended, but not necessary to update old profiles to put this value in quotes.

### ForceFeedback
Enable or disables haptic / force-feedback events for the gamepad device. It’s worth mentioning that only the Gamepad device can receive force-feedback events; the Motion or Mouse devices will not receive these events.

Format:

```
ForceFeedback = <true | false>
```

Example:

```
[Features]
ForceFeedback = true
```

If unspecified, this value defaults to false.

Note This feature is not yet fully implemented

### MotionDevice
If this is set to true, an additional input device will be created which will report motion control data. Motion axes need to have thier ranges and bindings defined. If this is disabled, any Motion device bindings will be ignored.

Format:

```
MotionDevice = <true | false>
```

Example:

```
[Features]
MotionDevice = true
```

If unspecified, this value defaults to false.

Note While it’s possible to combine gamepad and motion input into a single input device, Linux kernel and uinput specifications state that motion control devices should be separate from other gamepad / joystick input. Not separating these can also make it difficult to configure controls in most applications.

### MouseDevice
If this is set to true, an additional input device will be created which will be used to send mouse / trackpad events. Mouse events still need to have thier bindings defined. If this is disabled, any Mouse device bindings will be ignored.

Format:

```
MouseDevice = <true | false>
```

Example:

```
[Features]
MouseDevice = true
```

If unspecified, this value defaults to true.

### LizardMode
The Steam Controller and the Steam Deck both have a kind of fallback "BIOS" mode which emulates some keyboard and mouse input using the gamepad. Valve refers to this as "Lizard Mode". This mode cannot be redefined. It sends events IN ADDITION to the gamepad events created by the OpenSD driver, so it should always be disabled. If you would like mouse or keyboard emulation, they should be configured with bindings. When OpenSD exits, Lizard Mode is re-enabled.

If this is set to false "Lizard Mode" will be disabled (recommended).

Format:

```
LizardMode = <true | false>
```

Example:

```
[Features]
LizardMode = false
```

If unspecified, this value defaults to false.

### StickFiltering
The thumbsticks on the Steam Deck have a circular range but return square-ish data, which makes it feel odd and complicated to apply radial deadzones to. Because of this, OpenSD vectorizes the stick position and returns "cleaner", round stick ranges, as well as being able to create clean deadzone rescaling. If you disable this setting, axis ranges are still internally normalized and rescaled to the the uinput device, but no vectorization will be applied and any deadzones will be ignored.

If set to true thumbsticks will be filtered (recommended).

Format:

```
StickFiltering  = <true | false>
```

Example:

```
[Features]
StickFiltering  = true
```

If unspecified this value defaults to true.

Note This must be enabled for thumbstick deadzones to work.

### TrackpadFiltering
Similar to StickFiltering, but matches the square shape of the trackpad. Filtering is only applied to absolute values. This setting must be enabled to apply deadzones to the trackpad absolute axes. Relative values (*PadRelX and *PadRelY) are unaffected, therefore deadzones do not affect mouse movement with the pads.

If set to true trackpads will be filtered (recommended).

Format:

```
TrackpadFiltering  = <true | false>
```

Example:

```
[Features]
TrackpadFiltering  = true
```

If unspecified, this value defaults to true.

Note This must be enabled for trackpad deadzones to work.

### [DeviceInfo] Section
This section is used to optionally configure the USB identification of each device OpenSD creates. While OpenSD has its own defaults, they can be overridden to make these devices appear as a different hardware. This can be useful when some very poorly written games only look for / support specific gamepads, rather than a universal API. Shame. Often, these games filter out all input devices which don’t match the device name string and/or the USB VID:PID. These settings enable the gamepad to mimic the appearance of a device which the software does recognise.

Format:

```
<device>    = <vid> <pid> <ver> <name>
```

•device: Any OpenSD input device: Gamepad, Motion, or Mouse.

•vid: The USB device VendorID to use. Format must be in hexidecimal.

•pid: The USB device ProductID to use. Format must be in hexidecimal.

•ver: The USB device version to use. Format must be in hexidecimal.

•name: The USB device name string to use. Should be enclosed in quotes "" if it contains any whitespace characters.

Example:

```
[DeviceInfo]
Gamepad     = 0xDEAD 0xBEEF 0x0001 "OpenSD Gamepad Device"
Motion      = 0xDEAD 0xBEEF 0x0001 "OpenSD Motion Control Device"
Mouse       = 0xC475 0xF00D 0x0101 "OpenSD Mouse / Trackpad Device"
```

Note Some software may also perform gamepad detection based on button and axis configuration. Axis settings can also be configured in the [GamepadAxes] Section and [MotionAxes] Section for this very purpose.

### [Deadzones] Section
These values are double precision floating point and represent the percentage of the total axis range to ignore. A value of 0.05 would be a 5% deadzone. Deadzones are capped at 0.9 (90%). A value of 0 is considered disabled. If StickFiltering is disabled, LStick and RStick deadzones will be ignored. If TrackpadFiltering is disabled, LPad and RPad deadzones will be ignored.

Format:

```
<axis>      = <value>
```

•axis: Any of the supported gamepad axes, which are: * LStick, RStick, LPad, RPad, LTrigg and RTrigg.

•value: A double-precision floating point value between 0 and 0.9.

Example:

```
[Deadzones]
LStick      = 0.1
RStick      = 0.1
LPad        = 0
RPad        = 0
LTrigg      = 0
RTrigg      = 0
```

Any undefined axis deadzone will default to 0 (disabled).

Note Because the Steam Deck thumbsticks tend not to return to center completely (at least on current revisions), a small deadzone of around 0.10 (10%) is generally recommended.

### [GamepadAxes] Section
Gamepad absolute axes must have a defined range or they will not be created. Any Gamepad ABS_* events which are configured in the Gamepad Bindings section must be defined here first, or they will be ignored.

Internally, the axis values are normalized and rescaled between the actual hardware and the value seen by applications, so no clipping or "dead extremes" will occur. There is no "right" or "wrong" value here that you need to know, but it may be useful to precisely emulate other hardware so it can be detected as such by certain applications which try to guess what kind of device you have.

The Steam Deck hardware uses signed 16-bit integers (-32767 to 32767) for its thumbstick, trackpad, trigger and motion axes, so there’s no reason to use a larger or smaller range for those inputs, unless you are trying to emulate a specific device.

Hat-type <https://en.wikipedia.org/wiki/Joystick#Hat_switch> axes (ABS_HAT*) should typically use a range of -1 to 1 because of thier historical purpose, but this is not strictly enforced.

Triggers should typically have minumum value of 0 so that they rest at zero when released.

Format:

```
<abs_event>     = <min> <max> [fuzz] [res]
```

•abs_event: Any absolute axis event code you wish to bind. Absolute event codes begin with ABS_. A full list of input event codes can be found at linux/input-event-codes.h <https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h> from the Linux kernel.

•min: A value representing the minimum range of the axis. This is a signed 32-bit integer.

•max: A value representing the maximum range of the axis. This is a signed 32-bit integer.

•fuzz: Optional value representing the fuzziness of the axis values. This is a signed 32-bit integer.

•res: Optional value representing the resolution of the axis in units/mm (units/radian for rotational axes). This is a signed 32-bit integer.

Example:

```
[GamepadAxes]
ABS_HAT0X       = -1        1
ABS_HAT0Y       = -1        1
ABS_X           = -32767    32767
ABS_Y           = -32767    32767
ABS_RX          = -32767    32767
ABS_RY          = -32767    32767
ABS_Z           = 0         32767
ABS_RZ          = 0         32767
```

### [MotionAxes] Section
Motion control absolute axes, as with the gamepad device, must have a defined range or they will not be created. Any Motion ABS_* events which are configured in the Motion Bindings must be defined here first, or they will be ignored.

Internally, the axis values are normalized and rescaled between the actual hardware and the value seen by applications, so no clipping or "dead extremes" will occur. There is no "right" or "wrong" value here that you need to know, but it may be useful to precisely emulate other hardware so it can be detected as such by certain applications which try to guess what kind of device you have.

The Steam Deck hardware uses signed 16-bit integers (-32767 to 32767) for its thumbstick, trackpad, trigger and motion axes, so there’s no reason to use a larger or smaller range for those inputs, unless you are trying to emulate a specific device.

Format:

```
<abs_event>     = <min>     <max>
```

•abs_event: Any absolute axis event code you wish to bind. Absolute event codes begin with ABS_. A full list of input event codes can be found at linux/input-event-codes.h <https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h> from the Linux kernel.

•min: An integer representing the minimum range of the axis. This is a signed 32-bit integer.

•max: An integer representing the maximum range of the axis. This is a signed 32-bit integer.

Example:

```
[MotionAxes]
ABS_X           = -32767    32767
ABS_Y           = -32767    32767
ABS_Z           = -32767    32767
ABS_RX          = -32767    32767
ABS_RY          = -32767    32767
ABS_RZ          = -32767    32767
```

Note Motion controls are not yet fully implemented.

### [Bindings] Section
This should be a list of all the physical gamepad buttons/sticks/pads/motion inputs you want to bind to a virtual input event or command. Anything not specified here will be considered "unbound" and not emit any event.

There are currently four basic binding types: device bindings, Command bindings, Profile bindings and None.

Device bindings

Represent input events which are generated by pressing buttons, keys, moving the mouse, thumbsticks, motion control, etc. Event bindings are tied to specific input devices, which include Gamepad, Motion and Mouse. Applications read events from these different device types in different ways so they should generally be separated.

Command bindings

Executes a given command inside a shell environment.

Profile bindings

Used to switch to a different profile when triggered.

None

This is used to indicate that a particular input has no binding. (default)

Input binding names which this document will refer to as input or <input>, are represent physical buttons, triggers, axes, etc. on the physical gamepad portion of the Steam Deck. They can be broken down into a several categories for simplicity:

Directional Pad

DPad{Up|Down|Left|Right}

Buttons

A B X Y L1 L2 L3 L4 L5 R1 R2 R3 R4 R5 Menu Options Steam QuickAccess

Triggers

{L|R}Trigg

Thumbsticks

{L|R}Stick{Up|Down|Left|Right|Touch|Force}

Trackpads

{L|R}Pad{Up|Down|Left|Right|RelX|RelY|Touch|Press|Force}

Accelerometers

Accel{X|Y}{Plus|Minus}

Attitude / gyros

{Roll|Pitch|Yaw}{Plus|Minus}

Input names prefixed with L or R indicate left and right controls (example: LStickLeft vs RStickLeft)

Additionally, trackpads are mapped out into several button layouts simultaneously. This means that when pressed, specific areas of the trackpad behave like individual buttons. There are several "maps" which can be used non-exclusively. These are

Quadrant button maps

{L|R}PadPressQuad{Up|Down|Left|Right}

Orthogonal button maps

{L|R}PadPressOrth{Up|Down|Left|Right}

2x2 grid maps

{L|R}PadPressGrid2x2_{1|2|3|4}

3x3 grid maps

{L|R}PadPressGrid3x3_{1|2|3|4|5|6|7|8|9}

A full list of available input codes can be seen in the example profile section, as well as in default.profile file from your installation.

A detailed explanation of each of these inputs can be found in the Input Types section.

### Gamepad Bindings
The Gamepad device binding is used to generate input events for a joystick / gamepad-type device. This generally means buttons (BTN_*) and absolute axis (ABS_*) events. KEY_* events are allowed, but many programs will not read KEY_* events from a joystick device, instead try binding key events to the Mouse device.

The syntax for bindings differs slightly depending on the event type. Absolute axis (EV_ABS) events are prefixed with ABS_ and key / button events (EV_KEY) are prefixed with KEY_ and BTN_ respectively. OpenSD supports most event codes. For a full list of event codes, see linux/input-event-codes.h <https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h> from the Linux kernel.

When bound to a button-type input (example: the A button), the bind is triggered when the button is pressed. When bound to an axis-type input (example: LStickUp), the event is emitted when the axis is in a non-zero position and leaves the deadzone (if any).

For KEY / BTN events:

Format:

```
input = Gamepad <event_code>
```

•input: Any one of the input binding names.

•event_code: Any EV_KEY type event. These events are prefixed with BTN_ or KEY_. (example: BTN_START or KEY_ESCAPE)

Example:

```
[Bindings]
Menu = Gamepad BTN_START
```

For ABS events:

Format:

```
input = Gamepad <event_code> <direction>
```

•input: Any one of the input binding names.

•event_code: Any EV_ABS type event. These events are prefixed with ABS_. (example: ABS_X)

•direction: Indicates the direction that the axis is moved in. Values may be + or -. For centered axes, like thubsticks, - represents moving the axis up or left, and + represents moving the axis down or right. For ramped axes, like triggers and pressure sensors, + represents applying pressure.

When binding a button-type input like a DPad direction or, say, the B button to an ABS event, the button will push the axis to its maximum extent in the given direction. When binding an analog axis, like a thumbstick, to an ABS value, the range of motion is mapped to the axis value in the given direction.

Examples:

```
[Bindings]
# Button mapped to an axis
DPadUp          = Gamepad   ABS_HAT0Y   -
# Analogue stick mapped to an axis
RStickUp        = Gamepad   ABS_Y       -
RStickDown      = Gamepad   ABS_Y       +
# Analogue trigger mapped to an axis
LTrigg          = Gamepad   ABS_Z       +
```

A full list of gamepad input names can be seen in the example profile.

A detailed explanation of inputs can be found in the Input Types section of this documentation.

Note ABS events must have a defined range in the [GamepadAxes] Section

### Motion Bindings
The Motion device binding is used to generate input events for a motion control-type device. While OpenSD does not strictly enforce this, the Linux kernel and uinput specify that motion control events should be emitted by separate devices. Not doing so can create a lot of "noise", especially when configuring controls within another application. As per this spec, the Motion device only supports EV_ABS type events. These events are prefixed with ABS_ (example: ABS_Z). For a full list of event codes, see linux/input-event-codes.h <https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h> from the Linux kernel.

The syntax and behaviour for binding Motion device events is the same as binding ABS events with the Gamepad device in the previous section.

Also, the Motion device is a completely separate context and namespace from the Gamepad and Mouse devices, much in the same way that two players with identical controllers will have the same buttons, but very different meanings to the game. For example, pressing A on controller #1 does not affect player #2. Its up the the end-user’s software to decide the the context and meaning of the individual events.

Format:

```
input = Motion <event_code> <direction>
```

•input: Any one of the input binding names.

•event_code: Any EV_ABS type event. These events are prefixed with ABS_. (example: ABS_X)

•direction: Indicates the direction that the axis is moved in. Values may be + or -.

Examples:

```
[Bindings]
# Bind roll attitude to Motion device
RollPlus        = Motion    ABS_X       +
RollMinus       = Motion    ABS_X       -
```

A full list of motion contol input names can be seen in the example profile.

A detailed explanation of motion input be found in the Input Types Section of this document.

Note ABS events must have a defined range in the [MotionAxes] Section

Note This feature is not yet fully implemented.

### Mouse Bindings
The Mouse device binding is used to generate input events which will be interpreted as events coming from a pointer-type device such as a physical mouse. This binding type supports button / key and relative axis events. The Mouse device can also function a bit like a keyboard, so it’s advised to bind any key events to this device.

The syntax for bindings differs slightly depending on the event type. Relative axis (EV_REL) events are prefixed with REL_ and key / button events (EV_KEY) are prefixed with KEY_ and BTN_ respectively. OpenSD supports most event codes. For a full list of event codes, see linux/input-event-codes.h <https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/input-event-codes.h> from the Linux kernel.

For KEY / BTN events:

```
input = Mouse <event_code>
```

•input: Any one of the input binding names.

•event_code: Any EV_KEY type event. These events are prefixed with BTN_ or KEY_. (example: BTN_LEFT or KEY_ESCAPE)

Example:

```
[Bindings]
RPadPress       = Mouse BTN_LEFT
QuickAccess     = Mouse BTN_RIGHT
```

For REL events:

```
[Bindings]
RPadRelX        = Mouse REL_X
RPadRelY        = Mouse REL_Y
```

•input: Any one of the input binding names.

•event_code: Any EV_REL type event. These events are prefixed with REL_. (example: REL_X)

Please see the Trackpad input type section of this documentation for a better explanation of how {L|R}PadRel{X|Y} relative inputs work.

### Command Bindings
The Command binding allows you to execute external programs or scripts by forking them off as a child process. These processes run concurrently, do not return any usable exit code, and will not interrupt the driver.

Format:

```
input = Command <wait_for_exit> <repeat_delay_ms> <command_to_execute>
```

•input: Any one of the input binding names. Best suited to button-types.

•wait_for_exit: a true or false value which specifies if the command should complete before the binding can be triggered again.

•repeat_delay_ms: The amount of time in milliseconds that must elapse before the binding can be triggered again. The timer starts when the binding is successfully triggered.

•command_to_execute: The name of the command / script you want to run, same as you would from a terminal. The command executes normally inside a shell, so variable expansion should work. Arguments may be specfied by placing them after the command as usual.

Example:

```
[Bindings]
QuickAccess     = Command   true    0   rofi -show run
```

### Profile Bindings
The Profile binding type allows you to switch to a different profile using just the gamepad input. Profiles are loaded from the user profile directory. There is a 2 second delay after profile switching before the profile can be changed again, to prevent undesirable rapid cycling. If a profile fails to load, the process will be aborted and the profile currently in use will remain so.

Format:

```
input = Profile <profile_name>
```

•input: Any one of the input binding names. Best suited to button-types.

•profile_name: Filename of the profile ini you want to load. Path is fixed to the user profile directory, so only specify the filename itself.

Example:

```
[Bindings]
L5      = Profile   left_hand_mouse.profile
```

## INPUT TYPES
As briefly described in the Bindings section, the gamepad has multiple input components which can be categorized by their interface, but also by a primitive type. For example, the thumbsticks on the Steam Deck have a pair of X / Y axes (example: LStickUp, LStickLeft), which, as a primitive type are absolute, but the thumbsticks also have a touch sensor at the top which can be read as a binary button primitive (LStickTouch) as well as a pressure level (LStickForce) which is read as a single absolute axis like a trigger would be.

The intent is for each input name to be as simple and intuitive as possible, but that’s always going to be pretty subjective. This section intends to provide a painfully detailed explanation for every individual input that can have a binding ; )

### Directional Pad
The directional pad is just a set of four buttons which are diametrically exclusive — you can press up and left simultaneously but you cannot press left and right simultaneously.

Naming Convention

•DPad{Up|Down|Left|Right}

Descriptions

•DPadUp: The top button on the directional pad.

•DPadDown: The botton button on the directional pad.

•DPadLeft: The left button on the directional pad.

•DPadRight: The right button on the directional pad.

Use

While you can bind them to nearly anything, these buttons are usually bound to pair of Hat <https://en.wikipedia.org/wiki/Joystick#Hat_switch> axes, which are typically axes with a range of -1 to 1 and 0 when resting / released.

•Button bindings to KEY_ and BTN_ events work directly as you might expect.

•Buttons bound to ABS_ events emit the axis limit in the given direction.

A common configuration, as seen in the example profile, might look like this:

```
[Bindings]
DpadUp              = Gamepad   ABS_HAT0Y   -
DpadDown            = Gamepad   ABS_HAT0Y   +
DpadLeft            = Gamepad   ABS_HAT0X   -
DpadRight           = Gamepad   ABS_HAT0X   +
```

### Buttons
These are pretty straightforward. As you probably expect, buttons have two states. They’re true when pressed and false when released. The Steam Deck borrows common names for most buttons, but also adds a few of it’s own. It’s debatable how to organize or classify these, so I’ll just sorta go by the legacy naming standards.

Naming conventions

•A B X Y {L|R}{1|2|3|4|5} Menu Options Steam QuickAccess

Descriptions

•A: Same as it appears on the front of the Steam Deck.

•B: Same as it appears on the front of the Steam Deck.

•X: Same as it appears on the front of the Steam Deck.

•Y: Same as it appears on the front of the Steam Deck.

•L1: The top left bumper / shoulder button.

•R1: The top right bumper / shoulder button.

•L2: Button nested inside the pressure sensor of the left trigger.

•R2: Button nested inside the pressure sensor of the right trigger.

•L3: Button nested at the bottom of the left stick. Activated by pressing down until it clicks.

•R3: Button nested at the bottom of the right stick. Activated by pressing down until it clicks.

•L4: Upper paddle button located on the back-left side of the Steam Deck.

•R4: Upper paddle button located on the back-right side of the Steam Deck.

•L5: Lower paddle button located on the back-left side of the Steam Deck.

•R5: Lower paddle button located on the back-right side of the Steam Deck.

•Menu: Raised hamburger button <https://en.wikipedia.org/wiki/Hamburger_button> (☰) located above the *right *thumbstick.

•Options: Raised overlapped rectangle button (⮻) located above the left thumbstick.

•Steam: Flat button of the same name (STEAM), located below the left trackpad.

•QuickAccess: Flat button with three interpuncts (···), located below the right trackpad.

Use

Binding buttons is simple.

•Button bindings to KEY_ and BTN_ events work directly.

•Buttons bound to ABS_ events emit the axis limit in the given direction. For example, if you create a binding like A = ABS_X +, then when you press the A button, it will emit an ABS_X event for whatever the maximum axis limit for ABS_X is, whereas A = ABS_X - will emit the minimum axis limit.

•A/B/X/Y have respective input codes for Gamepad devices: BTN_SOUTH, BTN_EAST, BTN_WEST and BTN_NORTH.

•{L|R}{1|2} have respective input codes for Gamepad devices: BTN_TL BTN_TL2 BTN_TR and BTN_TR2.

•{L|R}3 have respective input codes for Gamepad devices: BTN_THUMBL and BTN_THUMBR

•Menu has a respective (based on location and common use) input code for Gamepad devices: BTN_START.

•Options has a respective (based on location and common use) input code for Gamepad devices: BTN_SELECT.

•Steam is probably closest to a PS or HOME button on a Gamepad device; possibly use BTN_MODE.

### Thumbsticks
The thumbsticks on the Steam Deck are associated with six different inputs in OpenSD. As you would expect, there is an X/Y axis pair for each stick, but there are also touch and pressure (well, sorta) sensors located on the top of each one. The directional axes are broken into halves such that each direction can emit different events if desired.

Axis values from thumbsticks are normalized internally so they can be rescaled to the defined ABS event ranges. The hardware returns signed 16-bit integer values for axis values in the HID reports. The "pressure sensor" component has a very short numerical range, but is quite sensitive.

If Stick Filtering is enabled the full axis is internally normalized as a unit vector and a radial deadzone may be applied.

Naming convention

•{L|R}Stick{Up|Down|Left|Right|Touch|Force}

Descriptions

•LStickUp: Represents the top half of the Y-axis of the left thumbstick.

•LStickDown: Represents the bottom half of the Y-axis of the left thumbstick.

•LStickLeft: Represents the left half of the X-axis of the left thumbstick.

•LStickRight: Represents the right half of the X-axis of the left thumbstick.

•LStickTouch: This is a binary button that return true when the top of the left thumbstick is touched.

•LStickForce: Capacitive touch sensor at the top of the left thumbstick. It is very sensitive and can register if your hand is near, without actually touching it. At a hardware level, the sensitivity ranges from 0 to ~112, which is an odd number. This value is returned as an normalized axis (0 to 1.0), just like a trigger.

•RStickUp: Represents the top half of the Y axis of the right thumbstick.

•RStickDown: Represents the bottom half of the Y axis of the right thumbstick.

•RStickLeft: Represents the left half of the X axis of the right thumbstick.

•RStickRight: Represents the right half of the X axis of the right thumbstick.

•RStickTouch: This is a binary button that return true when the top of the right thumbstick is touched.

•RStickForce: Capacitive touch sensor at the top of the right thumbstick. It is very sensitive and can register if your hand is near, without actually touching it. At a hardware level, the sensitivity ranges from 0 to ~112, which is an odd number. This value is returned as an normalized axis (0 to 1.0), just like a trigger.

Use

Directional inputs are treated like axis halves. You typically want to map Up and Down onto the same ABS event code, but in opposite directions. Doing so will perfectly map the full range of motion to an event code. An example of this, as demonstrated in the [Bindings] section of the example profile:

```
# Left Stick
LStickUp            = Gamepad   ABS_Y       -
LStickDown          = Gamepad   ABS_Y       +
LStickLeft          = Gamepad   ABS_X       -
LStickRight         = Gamepad   ABS_X       +
# Right Stick
RStickUp            = Gamepad   ABS_RY      -
RStickDown          = Gamepad   ABS_RY      +
RStickLeft          = Gamepad   ABS_RX      -
RStickRight         = Gamepad   ABS_RX      +
```

You’re also able to treat each axis half like a button if you bind it to a key or button event code, in which case it will trigger the binding when the stick leaves the center / deadzone. You can use the deadzone in this case to determine how far the stick must be pushed from center before the binding is triggered.

•LStickLeft & LStickRight are typically bound to the ABS_X event code on Gamepad devices.

•LStickUp & LStickDown are typically bound to the ABS_Y event code on Gamepad devices.

•RStickLeft & RStickRight are typically bound to the ABS_RX event code on Gamepad devices.

•RStickUp & RStickDown are typically bound to the ABS_RY event code on Gamepad devices.

•Use LStickTouch / RStickTouch to detect if a players hands are on the controls.

•Use LStickForce / RStickForce if you want to write a tiny electric theremin simulator? If this sensor is bound to an absolute axis, a range of 0 to 100 is recommened.

### Triggers
Triggers are pressure sensors that are also treated a bit like a thumbstick’s half-axis, with the difference being there’s no complement half. Triggers have a resting position of the defined axis minimum limit and move toward the maximum limit when actuated. Typically the minimum limit is zero, so the axis does not return non-zero values when released / resting, but you can do any weird thing you want.

Axis values from triggers are normalized internally so they can be rescaled to the defined ABS event ranges. Internally, the HID reports return trigger values as unsigned 16-bit integers.

Triggers also have a binary button component: L2 and R2. Information about these buttons can be found in the Buttons section.

Linear deadzones can be applied to triggers, if desired in the Deadzones Section of a profile.

Naming convention

•{L|R}Trigg

Descriptions

•LTrigg: Represents a pressure sensor value for the left trigger on the top-rear of the device.

•RTrigg: Represents a pressure sensor value for the right trigger on the top-rear of the device.

Use

These inputs are absolute axes and can be mapped to ABS event codes as well as KEY / BTN event codes. One possible reason to use the axis itself as a button-type binding would be to use L2 / R2 buttons on partial actuation, and use a deadzone to emit another event code on full actuation.

•LTrigg is typically bound to ABS_Z.

•RTrigg is typically bound to ABS_RZ.

### Trackpads
At the core, trackpads are absolute axis devices have with an X / Y pair, as well as a pressure sensor Z-axis and a slightly tactile button. A number of inputs can be extrapolated from the data those basic types provide. That includes touch sensors, press / button sensors, pressure / force sensors, absolute coordinates, relative movement tracking as well as the ability to map out regions of the pad and treat them as individual buttons. OpenSD trackpads have the most input bindings out of all the components.

As with the Thumbsticks, directional axes are broken into halves such that each direction can emit different events if desired. These halves can be mapped on to a whole ABS event code, or use separately.

Trackpads support radial deadzones for absolute axis inputs, and can be configured in the Deadzones Section of a profile.

Relative trackpad input, such as LPadRelX or LPadRelY, are not affected by deadzones and return data suitable for pointing devices like mice. These return the difference in positional movement calculated between HID frames. Some filtering is always applied to this process to reduce jitter and a small amount of intertia is also applied. The typical value range returned by these inputs is usually between -5 and +5. Binding RelX and *RelY inputs to anything other than REL_ event codes on the Mouse device is probably not useful.

Touchpads are non-multitouch devices so they only relay a single X / Y coordinate pair. I’ve read that, at a hardware level, they are supposedly multi-touch capable, but I don’t have any information on reading that data yet. If true, it will probably be supported in a future version.

OpenSD provides multiple "button maps", any of which can be used non-exclusively with each other. These "button maps" break the full area of the trackpad into logical sections which, when pressed (as opposed to being merely touched) act as individual buttons. If so desired, trackpads can be used to create "button clusters", which can be used to emulate a Directional Pad, arrow keys, run scripts, launch applications, etc. For the sake of readability, button maps are described separately below the main input descriptions.

Naming convention

•{L|R}Pad{Up|Down|Left|Right|Touch|Press|Force|RelX|RelY}

•{L|R}PadPressQuad{Up|Down|Left|Right}

•{L|R}PadPressOrth{Up|Down|Left|Right}

•{L|R}PadPressGrid2x2_{1|2|3|4}

•{L|R}PadPressGrid3x3_{1|2|3|4|5|6|7|8|9}

Descriptions

•LPadUp: Represents the top half of the Y-axis of the left trackpad.

•LPadDown: Represents the bottom half of the Y-axis of the left trackpad.

•LPadLeft: Represents the left half of the X-axis of the left trackpad.

•LPadRight: Represents the right half of the X-axis of the left trackpad.

•LPadTouch: This is a button sensor which detects if the left pad is being touched. Quite sensitive.

•LPadPress: This is also a button which detects if the left pad is being pressed down like a button. Actuation has a slight tactile bump.

•LPadForce: This is a pressure sensor which returns a normalized value of how much force is being used to press down on the left trackpad. This is an absolute axis value and behaves the same as Triggers.

•LPadRelX: This is a derived relative axis value that measures the amount of relative X-axis movement between update frames of the left trackpad. This represents the same kind of input data that mice use. This input is unaffected by deadzones. Typical values returned fall inside the range of -5 to +5.

•LPadRelY: This is a derived relative axis value that measures the amount of relative Y-axis movement between update frames of the left trackpad. This represents the same kind of input data that mice use. This input is unaffected by deadzones. Typical values returned fall inside the range of -5 to +5.

•RPadUp: Represents the top half of the Y-axis of the right trackpad.

•RPadDown: Represents the bottom half of the Y-axis of the right trackpad.

•RPadLeft: Represents the left half of the X-axis of the right trackpad.

•RPadRight: Represents the right half of the X-axis of the right trackpad.

•RPadTouch: This is a button sensor which detects if the right pad is being touched. Quite sensitive.

•RPadPress: This is also a button which detects if the right pad is being pressed down like a button. Actuation has a slight tactile bump.

•RPadForce: This is a pressure sensor which returns a normalized value of how much force is being used to press down on the right trackpad. This is an absolute axis value and behaves the same as Triggers.

•RPadRelX: This is a derived relative axis value that measures the amount of relative X-axis movement between update frames of the right trackpad. This represents the same kind of input data that mice use. This input is unaffected by deadzones. Typical values returned fall inside the range of -5 to +5.

•RPadRelY: This is a derived relative axis value that measures the amount of relative Y-axis movement between update frames of the right trackpad. This represents the same kind of input data that mice use. This input is unaffected by deadzones. Typical values returned fall inside the range of -5 to +5.

### Quadrant Button Map
The quadrant map (PadPressQuad*) provides a way to treat each touchpad as being composed of four non-overlapping triagular quadrants, as depicted in the figure 1 below. Each button is inherently exclusive to the others in this map since the X / Y coordinate can only fall inside of one of these regions at a time. This means that this map will not detect any overlapping presses, like a and b when you press in the upper-left region.

Fig. 1

```
┌─────────────┐
│ \         / │
│  \   a   /  │
│   \     /   │
│    \   /    │
│     \ /     │
│ b    X    c │
│     / \     │
│    /   \    │
│   /     \   │
│  /   d   \  │
│ /         \ │
└─────────────┘
```

•LPadPressQuadUp: The logical button on the left trackpad corresponding to fig. 1, region "a".

•LPadPressQuadDown: The logical button on the left trackpad corresponding to fig. 1, region "d".

•LPadPressQuadLeft: The logical button on the left trackpad corresponding to fig. 1, region "b".

•LPadPressQuadRight: The logical button on the left trackpad corresponding to fig. 1, region "c".

•RPadPressQuadUp: The logical button on the right trackpad corresponding to fig. 1, region "a".

•RPadPressQuadDown: The logical button on the right trackpad corresponding to fig. 1, region "d".

•RPadPressQuadLeft: The logical button on the right trackpad corresponding to fig. 1, region "b".

•RPadPressQuadRight: The logical button on the right trackpad corresponding to fig. 1, region "c".

### Orthogonal Button Map
The orthogonal map (PadPressOrth*) works similarly to a Directional Pad. As you can see below in figure 2, it demonstrates how the "a", "b", "c" and "d" regions represent orthogonal directions which are not strictly exclusive as they are with the Quadrant Button Map. If a diagonal corner is pressed, it triggers both orthogonally adjacent buttons. For example, pressing the upper-middle of the pad only triggers "a", but pressing the upper-left of the pad will trigger both "a" and "b".

Fig. 2

```
┌─────┬─────┬─────┐
│     │     │     │
│  ab │  a  │  ac │
│     │     │     │
├─────┼─────┼─────┤
│     │     │     │
│  b  │     │  c  │
│     │     │     │
├─────┼─────┼─────┤
│     │     │     │
│  db │  d  │  dc │
│     │     │     │
└─────┴─────┴─────┘
```

•LPadPressOrthUp: The logical button on the left trackpad corresponding to fig. 2 regions containing "a".

•LPadPressOrthDown: The logical button on the left trackpad corresponding to fig. 2 regions containing d".

•LPadPressOrthLeft: The logical button on the left trackpad corresponding to fig. 2 regions containing "b".

•LPadPressOrthRight: The logical button on the left trackpad corresponding to fig. 2 regions containing "c".

•RPadPressOrthUp: The logical button on the right trackpad corresponding to fig. 2 regions containing "a".

•RPadPressOrthDown: The logical button on the right trackpad corresponding to fig. 2 regions containing d".

•RPadPressOrthLeft: The logical button on the right trackpad corresponding to fig. 2 regions containing "b".

•RPadPressOrthRight: The logical button on the right trackpad corresponding to fig. 2 regions containing "c".

### 2x2 Grid Button Map
This button map divides the pad into regions along the center axes, resulting in four square buttons in each corner, as depicted in figure 3. Buttons are naturally exclusive, so only one can be pressed at a time. Buttons are enumerated left-to-right, top-to-bottom.

Fig. 3

```
┌────────┬────────┐
│        │        │
│        │        │
│   a    │    c   │
│        │        │
│        │        │
├────────┼────────┤
│        │        │
│        │        │
│   c    │    d   │
│        │        │
│        │        │
└────────┴────────┘
```

•LPadPressGrid2x2_1: The logical button on the left trackpad corresponding to fig. 3, region "a".

•LPadPressGrid2x2_2: The logical button on the left trackpad corresponding to fig. 3, region "b".

•LPadPressGrid2x2_3: The logical button on the left trackpad corresponding to fig. 3, region "c".

•LPadPressGrid2x2_4: The logical button on the left trackpad corresponding to fig. 3, region "d".

•RPadPressGrid2x2_1: The logical button on the right trackpad corresponding to fig. 3, region "a".

•RPadPressGrid2x2_2: The logical button on the right trackpad corresponding to fig. 3, region "b".

•RPadPressGrid2x2_3: The logical button on the right trackpad corresponding to fig. 3, region "c".

•RPadPressGrid2x2_4: The logical button on the right trackpad corresponding to fig. 3, region "d".

### 3x3 Grid Button Map
This button map divides the pad into thirds along both axes, resulting in a 3x3 grid of nine square buttons, as depicted in figure 4. These buttons are naturally exclusive to one another, so only one can be pressed at a time. Buttons are enumerated left-to-right, top-to-bottom.

Note The resulting size of each button will be fairly small, so it may require a little practice and small thumbs to manipulate them precisely.

Fig. 4

```
┌─────┬─────┬─────┐
│     │     │     │
│  a  │  b  │  c  │
│     │     │     │
├─────┼─────┼─────┤
│     │     │     │
│  d  │  e  │  f  │
│     │     │     │
├─────┼─────┼─────┤
│     │     │     │
│  g  │  h  │  i  │
│     │     │     │
└─────┴─────┴─────┘
```

•LPadPressGrid3x3_1: The logical button on the left trackpad corresponding to fig. 4, region "a".

•LPadPressGrid3x3_2: The logical button on the left trackpad corresponding to fig. 4, region "b".

•LPadPressGrid3x3_3: The logical button on the left trackpad corresponding to fig. 4, region "c".

•LPadPressGrid3x3_4: The logical button on the left trackpad corresponding to fig. 4, region "d".

•LPadPressGrid3x3_5: The logical button on the left trackpad corresponding to fig. 4, region "e".

•LPadPressGrid3x3_6: The logical button on the left trackpad corresponding to fig. 4, region "f".

•LPadPressGrid3x3_7: The logical button on the left trackpad corresponding to fig. 4, region "g".

•LPadPressGrid3x3_8: The logical button on the left trackpad corresponding to fig. 4, region "h".

•LPadPressGrid3x3_9: The logical button on the left trackpad corresponding to fig. 4, region "i".

•RPadPressGrid3x3_1: The logical button on the right trackpad corresponding to fig. 4, region "a".

•RPadPressGrid3x3_2: The logical button on the right trackpad corresponding to fig. 4, region "b".

•RPadPressGrid3x3_3: The logical button on the right trackpad corresponding to fig. 4, region "c".

•RPadPressGrid3x3_4: The logical button on the right trackpad corresponding to fig. 4, region "d".

•RPadPressGrid3x3_5: The logical button on the right trackpad corresponding to fig. 4, region "e".

•RPadPressGrid3x3_6: The logical button on the right trackpad corresponding to fig. 4, region "f".

•RPadPressGrid3x3_7: The logical button on the right trackpad corresponding to fig. 4, region "g".

•RPadPressGrid3x3_8: The logical button on the right trackpad corresponding to fig. 4, region "h".

•RPadPressGrid3x3_9: The logical button on the right trackpad corresponding to fig. 4, region "i".

## TROUBLESHOOTING
TODO: This section <<<

## EXAMPLE CONFIG.INI

```
[Daemon]
# The gamepad profile to be loaded on startup
Profile = default.profile
# Allow client connections from CLI and GUI configuration tools
AllowClients = true
```

## EXAMPLE PROFILE

```
[Profile]
Name            = Example Profile
Description     = Just an example profile to show basic use
[Features]
ForceFeedback      = true
MotionDevice       = true
MouseDevice        = true
LizardMode         = false
StickFiltering     = true
TrackpadFiltering  = true
[Deadzones]
LStick    = 0.1
RStick    = 0.1
LPad      = 0
RPad      = 0
LTrigg    = 0
RTrigg    = 0
[GamepadAxes]
ABS_HAT0X    = -1        1
ABS_HAT0Y    = -1        1
ABS_X        = -32767    32767
ABS_Y        = -32767    32767
ABS_RX       = -32767    32767
ABS_RY       = -32767    32767
ABS_Z        = 0         32767
ABS_RZ       = 0         32767
[MotionAxes]
ABS_X        = -32767    32767
ABS_Y        = -32767    32767
ABS_Z        = -32767    32767
ABS_RX       = -32767    32767
ABS_RY       = -32767    32767
ABS_RZ       = -32767    32767
[Bindings]
DpadUp              = Gamepad   ABS_HAT0Y   -
DpadDown            = Gamepad   ABS_HAT0Y   +
DpadLeft            = Gamepad   ABS_HAT0X   -
DpadRight           = Gamepad   ABS_HAT0X   +
# Buttons
A                   = Gamepad   BTN_SOUTH
B                   = Gamepad   BTN_EAST
X                   = Gamepad   BTN_WEST
Y                   = Gamepad   BTN_NORTH
L1                  = Gamepad   BTN_TL
R1                  = Gamepad   BTN_TR
L2                  = Gamepad   BTN_TL2
R2                  = Gamepad   BTN_TR2
L3                  = Gamepad   BTN_THUMBL
R3                  = Gamepad   BTN_THUMBR
L4                  = None
R4                  = None
L5                  = None
R5                  = None
Menu                = Gamepad   BTN_START
Options             = Gamepad   BTN_SELECT
Steam               = Gamepad   BTN_MODE
QuickAccess         = Command   true        0   rofi -show drun
# Triggers
LTrigg              = Gamepad   ABS_Z       +
RTrigg              = Gamepad   ABS_RZ      +
# Left Stick
LStickUp            = Gamepad   ABS_Y       -
LStickDown          = Gamepad   ABS_Y       +
LStickLeft          = Gamepad   ABS_X       -
LStickRight         = Gamepad   ABS_X       +
LStickTouch         = None
LStickForce         = None
# Right Stick
RStickUp            = Gamepad   ABS_RY      -
RStickDown          = Gamepad   ABS_RY      +
RStickLeft          = Gamepad   ABS_RX      -
RStickRight         = Gamepad   ABS_RX      +
RStickTouch         = None
RStickForce         = None
# Left Trackpad
LPadUp              = None
LPadDown            = None
LPadLeft            = None
LPadRight           = None
LPadRelX            = None
LPadRelY            = None
LPadTouch           = None
LPadPress           = Mouse     BTN_LEFT
LPadForce           = None
LPadPressQuadUp     = None
LPadPressQuadDown   = None
LPadPressQuadLeft   = None
LPadPressQuadRight  = None
LPadPressOrthUp     = None
LPadPressOrthDown   = None
LPadPressOrthLeft   = None
LPadPressOrthRight  = None
LPadPressGrid2x2_1  = None
LPadPressGrid2x2_2  = None
LPadPressGrid2x2_3  = None
LPadPressGrid2x2_4  = None
LPadPressGrid3x3_1  = None
LPadPressGrid3x3_2  = None
LPadPressGrid3x3_3  = None
LPadPressGrid3x3_4  = None
LPadPressGrid3x3_5  = None
LPadPressGrid3x3_6  = None
LPadPressGrid3x3_7  = None
LPadPressGrid3x3_8  = None
LPadPressGrid3x3_9  = None
# Right Trackpad
RPadUp              = None
RPadDown            = None
RPadLeft            = None
RPadRight           = None
RPadRelX            = Mouse     REL_X
RPadRelY            = Mouse     REL_Y
RPadTouch           = None
RPadPress           = Mouse     BTN_RIGHT
RPadForce           = None
RPadPressQuadUp     = None
RPadPressQuadDown   = None
RPadPressQuadLeft   = None
RPadPressQuadRight  = None
RPadPressOrthUp     = None
RPadPressOrthDown   = None
RPadPressOrthLeft   = None
RPadPressOrthRight  = None
RPadPressGrid2x2_1  = None
RPadPressGrid2x2_2  = None
RPadPressGrid2x2_3  = None
RPadPressGrid2x2_4  = None
RPadPressGrid3x3_1  = None
RPadPressGrid3x3_2  = None
RPadPressGrid3x3_3  = None
RPadPressGrid3x3_4  = None
RPadPressGrid3x3_5  = None
RPadPressGrid3x3_6  = None
RPadPressGrid3x3_7  = None
RPadPressGrid3x3_8  = None
RPadPressGrid3x3_9  = None
# Accelerometers
AccelXPlus          = Motion    ABS_RX      +
AccelXMinus         = Motion    ABS_RX      -
AccelYPlus          = Motion    ABS_RY      +
AccelYMinus         = Motion    ABS_RY      -
AccelZPlus          = Motion    ABS_RZ      +
AccelZMinus         = Motion    ABS_RZ      -
# Gyro / Attitude
RollPlus            = Motion    ABS_X       +
RollMinus           = Motion    ABS_X       -
PitchPlus           = Motion    ABS_Y       +
PitchMinus          = Motion    ABS_Y       -
YawPlus             = Motion    ABS_Z       +
YawMinus            = Motion    ABS_Z       -
```

### PROJECT HOME
<https://gitlab.com/open-sd/opensd>

### AUTHOR
seek ( <https://gitlab.com/seek-dev>)

### SEE ALSO
opensdd(1)

## AUTHOR
seek


package: opensm

title: torus-2QoS.conf(5)

text:
# torus-2QoS.conf(5)

## NAME
torus-2QoS.conf - Torus-2QoS configuration for OpenSM subnet manager

## DESCRIPTION
The file torus-2QoS.conf contains configuration information that is specific to the OpenSM routing engine torus-2QoS. Blank lines and lines where the first non-whitespace character is "#" are ignored. A token is any contiguous group of non-whitespace characters. Any tokens on a line following the recognized configuration tokens described below are ignored.

[torus|mesh] x_radix[m|M|t|T] y_radix[m|M|t|T] z_radix[m|M|t|T]

Either torus or mesh must be the first keyword in the configuration, and sets the topology that torus-2QoS will try to construct. A 2D topology can be configured by specifying one of x_radix, y_radix, or z_radix as 1. An individual dimension can be configured as mesh (open) or torus (looped) by suffixing its radix specification with one of m, M, t, or T. Thus, "mesh 3T 4 5" and "torus 3 4M 5M" both specify the same topology. Note that although torus-2QoS can route mesh fabrics, its ability to route around failed components is severely compromised on such fabrics. A failed fabric component is very likely to cause a disjoint ring; see UNICAST ROUTING in torus-2QoS(8).

xp_link sw0_GUID sw1_GUID

yp_link sw0_GUID sw1_GUID

zp_link sw0_GUID sw1_GUID

xm_link sw0_GUID sw1_GUID

ym_link sw0_GUID sw1_GUID

zm_link sw0_GUID sw1_GUID

These keywords are used to seed the torus/mesh topology. For example, "xp_link 0x2000 0x2001" specifies that a link from the switch with node GUID 0x2000 to the switch with node GUID 0x2001 would point in the positive x direction, while "xm_link 0x2000 0x2001" specifies that a link from the switch with node GUID 0x2000 to the switch with node GUID 0x2001 would point in the negative x direction. All the link keywords for a given seed must specify the same "from" switch. In general, it is not necessary to configure both the positive and negative directions for a given coordinate; either is sufficient. However, the algorithm used for topology discovery needs extra information for torus dimensions of radix four (see TOPOLOGY DISCOVERY in torus-2QoS(8)). For such cases both the positive and negative coordinate directions must be specified.

Based on the topology specified via the torus/mesh keyword, torus-2QoS will detect and log when it has insufficient seed configuration.

x_dateline position

y_dateline position

z_dateline position

In order for torus-2QoS to provide the guarantee that path SL values do not change under any conditions for which it can still route the fabric, its idea of dateline position must not change relative to physical switch locations. The dateline keywords provide the means to configure such behavior. The dateline for a torus dimension is always between the switch with coordinate 0 and the switch with coordinate radix-1 for that dimension. By default, the common switch in a torus seed is taken as the origin of the coordinate system used to describe switch location. The position parameter for a dateline keyword moves the origin (and hence the dateline) the specified amount relative to the common switch in a torus seed.

next_seed

If any of the switches used to specify a seed were to fail torus-2QoS would be unable to complete topology discovery successfully. The next_seed keyword specifies that the following link and dateline keywords apply to a new seed specification. For maximum resiliency, no seed specification should share a switch with any other seed specification. Multiple seed specifications should use dateline configuration to ensure that torus-2QoS can grant path SL values that are constant, regardless of which seed was used to initiate topology discovery.

portgroup_max_ports max_ports

This keyword specifies the maximum number of parallel inter-switch links, and also the maximum number of host ports per switch, that torus-2QoS can accommodate. The default value is 16. Torus-2QoS will log an error message during topology discovery if this parameter needs to be increased. If this keyword appears multiple times, the last instance prevails. Note that the switch management port (switch port 0) gets put into the same port group with the host ports, so if you have 16 host ports per switch, portgroup_max_ports would need to be at least 17.

port_order p1 p2 p3 ...

This keyword specifies the order in which CA ports on a destination switch are visited when computing routes. When the fabric contains switches connected with multiple parallel links, routes are distributed in a round-robin fashion across such links, and so changing the order that CA ports are visited changes the distribution of routes across such links. This may be advantageous for some specific traffic patterns. The default is to visit CA ports in increasing port order on destination switches.

Duplicate values in the list will be ignored.

max_changes max

This keyword specifies the maximum number of torus changes reported. The default value is 32.

## EXAMPLE

```
# Look for a 2D (since x radix is one) 4x5 torus.
torus 1 4 5
# y is radix-4 torus dimension, need both
# ym_link and yp_link configuration.
yp_link 0x200000 0x200005  # sw @ y=0,z=0 -> sw @ y=1,z=0
ym_link 0x200000 0x20000f  # sw @ y=0,z=0 -> sw @ y=3,z=0
# z is not radix-4 torus dimension, only need one of
# zm_link or zp_link configuration.
zp_link 0x200000 0x200001  # sw @ y=0,z=0 -> sw @ y=0,z=1
next_seed
yp_link 0x20000b 0x200010  # sw @ y=2,z=1 -> sw @ y=3,z=1
ym_link 0x20000b 0x200006  # sw @ y=2,z=1 -> sw @ y=1,z=1
zp_link 0x20000b 0x20000c  # sw @ y=2,z=1 -> sw @ y=2,z=2
y_dateline -2  # Move the dateline for this seed
z_dateline -1  # back to its original position.
# If OpenSM failover is configured, for maximum resiliency
# one instance should run on a host attached to a switch
# from the first seed, and another instance should run
# on a host attached to a switch from the second seed.
# Both instances should use this torus-2QoS.conf to ensure
# path SL values do not change in the event of SM failover.
# port_order defines the order on which the ports would be
# chosen for routing.
port_order 7 10 8 11 9 12 25 28 26 29 27 30
```

## FILES
/etc/rdma/torus-2QoS.conf

Default torus-2QoS config file.

## SEE ALSO
opensm(8), torus-2QoS(8).

branch: sisyphus