The elxu_mgmt.c file contains helper functions for accessing the driver's device management API. Functions are provided to retrieve the various lists, parse and display results, and get individual status and configuration values.
The OneCore Storage drivers provide an interface for managing the driver and the controlled device. This device management API consists of a set of seven IOCTL commands which can be used to query the driver for current state, update configuration values, and request that the driver perform management actions.
A Status item is read-only information provided by the driver. This might include information about the driver, about the device being controlled by the driver, or dynamic information, such as currently open connections.
The IOCTLs used to list and get status include:
Configuration items are those which can be written or updated by the user. This might include debug settings, MAC addresses, world wide names, port speed, topology, and so on.
The IOCTLs used to list, get status, and set values include:
Actions are functions which the driver can perform when requested by the user. Examples include firmware download, dump retrieval, and the starting and stopping of links.
The IOCTLs used to list and perform actions include:
Information passed from the driver to the user is presented in the form of an XML document. The user provides a buffer into which to store the response and the driver fills in the buffer. The structure of the XML document mirrors that of the OneCore Storage driver stack, which is a hierarchy of ocs, domain, node, sport, and IO.
The XML document is made up of two kinds of elements: “section” and “property”. A “section” represents a collection of other elements, and can contain properties and other sections. A “property” has a name and a value.
The section tag contains the name of the section as an attribute, and is used to represent a level in the driver hierarchy: ocs, domain, node, and so on. The section name may have a number designating a particular instance of that type of section. For example, a sport could have three nodes named node0, node1, and node2.
<section name="ocs">
<section name="node2">
The property tag has a name attribute that indicates the name of the property. The contents of the tag are optional and, if present, contain the value of the property. Values can be in one of three formats: integer, boolean, or text. A text value is surrounded by quotes, a boolean is either “false” or “true”, and an integer value is a number with an optional leading “0x” to indicate hexadecimal.
Examples of Property Tags with Values
<property name="is_loop">false</property>
<property name="pci_vendor">0x10df</property>
<property name="sn”>”FC23130739"</property>
Examples of Property Tags without Values
<property name="ox_id" />
<property name="wwpn" />
The APIs that request a list of items (OCS_IOCTL_CMD_GET_STATUS_LIST(), OCS_IOCTL_CMD_GET_CONFIG_LIST(), OCS_IOCTL_CMD_GET_ACTION_LIST()) return a document which contains all of the available section names and property names, but no values. Example
Example
The following figure shows the driver's structure
The following list shows the result of OCS_IOCTL_CMD_GET_STATUS_LIST() for the driver structure:
<section name="ocs">
<property name="desc" />
<property name="fw_rev" />
<property name="wwnn" />
<property name="wwpn" />
<property name="sn" />
<section name="domain0">
<property name="indicator" />
<property name="attached" />
<property name="is_loop" />
<property name="display_name" />
<section name="sport0">
<property name="display_name" />
<property name="is_vport" />
<property name="enable_ini" />
<property name="enable_tgt" />
<property name="p2p" />
<section name="node0">
<property name="display_name" />
<property name="indicator" />
<property name="fc_id" />
<property name="attached" />
</section>
<section name="node1">
<property name="display_name" />
<property name="indicator" />
<property name="fc_id" />
<property name="attached" />
</section>
</section>
</section>
</section>
The user can specify a particular property in the structure by listing the path to that property, using a period as a level separator. Using the example in Lists of Properties, the user can refer to the display_name property for node1 as “ocs.domain0.sport0.node1.display_name”. This is used for OCS_IOCTL_CMD_GET_STATUS(), OCS_IOCTL_CMD_GET_CONFIG(), OCS_IOCTL_CMD_SET_CONFIG(), and OCS_IOCTL_CMD_DO_ACTION() functions.
The following data structures are used to pass data between the user application and the driver.
typedef struct {
uint8_t *user_buffer;
uint32_t user_buffer_len;
uint32_t bytes_written;
} ocs_ioctl_mgmt_buffer_t;
This structure is used by the list functions OCS_IOCTL_CMD_GET_STATUS_LIST(), OCS_IOCTL_CMD_GET_CONFIG_LIST(), and OCS_IOCTL_CMD_GET_ACTION_LIST() functions. The user provides a pointer to a buffer and the length of the buffer. The ioctl writes an XML document into the buffer and set bytes_written to the size of the response.
typedef struct {
uint8_t *name;
uint8_t *value;
uint32_t value_length;
} ocs_ioctl_cmd_get_t;
This structure is used by the OCS_IOCTL_CMD_GET_STATUS() and OCS_IOCTL_CMD_GET_CONFIG() functions. The user provides the name of the property to retrieve, a buffer into which to put the response, and the size of the buffer. The ioctl fills the buffer with an XML document containing only that property along with its containing hierarchy.
typedef struct {
uint8_t *name;
uint8_t *value;
uint32_tresult;
} ocs_ioctl_cmd_set_t;
This structure is used by the OCS_IOCTL_CMD_SET_CONFIG() function. The user provides the name of a property and the new value for that property. The function sets the result field to 0 on success or non-zero if the operation failed.
typedef struct {
uint8_t*name;
void*arg_in;
uint32_targ_in_length;
void*arg_out;
uint32_targ_out_length;
uint32_tresult;
} ocs_ioctl_action_t;
This structure is used by the OCS_IOCTL_CMD_DO_ACTION() function. The user provides the name of the action, a buffer with input arguments, and a buffer for output arguments. Depending on the action the buffers may be NULL if they are not used. For example, the “gendump” action requires no arguments so arg_in and arg_out are NULL. The “firmware_write” action requires a firmware image so arg_in points to that image and arg_out is NULL.
On completion of the action, the result field is 0 for success and non-zero for an error.