|C H A P T E R 5|
Programming Netra CP2100 Series Board Controlled Devices
The Netra CP2100 series hot-swap software can display the various hot-swap states for a CompactPCI device connected to the system. A device that has been installed and connected to a system's slot can have one of the following states:
Using a pseudo device, an ioctl(), and libdevinfo library interfaces, you can retrieve the device type information (for example, the vendor IDs and the driver names) for every configured CompactPCI card in a system. With this information, you can deduce the type of CompactPCI card configured in each system slot.
The CompactPCI hot-swap controller pseudo device driver, cphsc, maintains the new device state information for all slots in a system. You can access this device state information by using an ioctl() on an instance of the cphsc pseudo device. The cphsc device returns a table containing an entry for each slot within the system's chassis. Each entry contains the new device state, the slot state, the cpci device number, and the logical slot number. Access permission for the /dev/cphsc device is read-write (rw) for superuser only.
Note - See Overview of Hot-Swap Device States for a description of each hot-swap device state (hsc_dev_state_t).
A single HSIOC_GET_INFO ioctl() returns the entire table of hsc_slotinfo_t structures. The structure is defined as 64-bit aligned. Constraining the structure to align to the larger of the two data models enables the structure to have the same format in either a 32-bit or a 64-bit application.
To make full use of the HSIOC_GET_INFO ioctl(), create a header file containing the required preprocessing directives and macros (see CODE EXAMPLE 5-1). After creating the header file, include the file in any application that uses the ioctl().
Note - The hsc_gi_tbl_u.tbl and hsc_gi_tblsize_u.tblsize entries can only be used in 64-bit applications. If you are developing a 32-bit application, use the hsc_gi_tbl_u.tbl64 and the hsc_gi_tblsize_u.tblsize64 entries, which work for either 32-bit or 64-bit applications.
This ioctl() has one argument, arg, which is a pointer to an hsc_gi_arg_t structure. The first field of hsc_gi_arg_t is a pointer to user-allocated storage; the second field is a pointer to the size of this storage in bytes.
To find out how much user storage to allocate for the slot table, call the ioctl() with the first field of hsc_gi_arg_t set to NULL and the second argument defined as a pointer to an integer. Since the tbl field is NULL, the ioctl() returns only the number of elements in the table in the tblsize field.
When both fields have non-NULL values, the slot table is copied into the user-allocated storage if tblsize is large enough to contain the table. The returned table is an array of hsc_slotinfo_t structures where the size of the table is:
Note - In a failed device state--for instance, where a device has failed to be unconfigured--the cfgadm command shows that the device remains configured to the system and the HSIOC_GET_INFO ioctl() reports that the device is in the HSC_DEV_UNCONFIG_FAILED state. In this device state, the card that an operator attempted to extract remains plumbed and connected to the system's resources. When the condition preventing the device from being unconfigured is removed, the operator can unconfigure the device using the cfgadm command. A Reconfiguration Coordination Manager (RCM) script can also be written to automatically shut down applications using the device so that unconfiguration is successful. See Chapter 6 for infomation on RCM.
In CODE EXAMPLE 5-2, a pseudo function finds the device type information for a given slot number (hsc_slotnum) and device number (hsc_devnum). The paragraphs that follow CODE EXAMPLE 5-2 describe how you might implement this function in your application.
The cphsc pseudo driver registers the attachment points (slots) with the hot-swap framework when the user-level system controller daemon, sctrld, activates it. The sctrld daemon plumbs the cphsc driver to the system management controller driver.
The attachment points (slots) are represented as minor nodes of the CompactPCI bus node. The minor number of these nodes corresponds to the PCI device number. This is not a true device tree node because it represents a receptacle rather than the occupant itself. When a device is configured into the slot, a device node is created that represents the configured device. This device node is a child of the system board controller's (SBC) CompactPCI root nexus, and its PCI bus address corresponds to the PCI device number of the corresponding slot.
When an attachment point represents a multifunction device, device nodes are created for each of these functions. In the SBC's device tree, these device nodes appear as children of the attachment point device node. Use interfaces provided by libdevinfo to get the following information for each function (for example, for each child node):
Use the libdevinfo library interfaces to derive the device type information (vendor ID, device ID, subsystem ID, and so on) based on a CompactPCI card's device number. The following example procedure shows how you can implement the find_device_info() routine shown in CODE EXAMPLE 5-2 using the libdevinfo application programmer's interface.
Note - You can use the libdevinfo library interfaces to find information only on devices that are in a configured state. If a device is in an unconfigured state, you cannot retrieve this information.You can use the libdevinfo library interfaces to find information only on devices that are in a configured state. If a device is in an unconfigured state, you cannot retrieve this information.
Since the properties of interest (device-id, subsystem-id, vendor-id, subsystem-vendor-id) are all of type DDI_PROP_TYPE_INT (32-bit integer), you can use the di_prop_lookup_ints() and di_prom_prop_lookup_ints() functions to find the property values.
To get the PROM properties using di_prom_lookup_ints(), call the di_prom_init() and di_prom_fini() functions before accessing the PROM property list, as the list is not included in the snapshot returned by the di_init() function.
Using high availability (HA) signal support, you can write your application to control which CompactPCI slots in an HA chassis are powered on. Before your application can control these signals, you must first set two Netra CP2140 series board OpenBoot PROM configuration variables.
The ha-signal-handler variable indicates whether the system management controller (SMC) module controls the HA signals or if an external application controls these signals. By default, the variable's value is 0, which means that the SMC module controls the HA signals. If you set the variable to 1, an external application can control the HA signals.
The poweron-vector configuration variable is an 8-bit bit-vector that indicates which CompactPCI slots will be powered on during the chassis power-on. By setting this variable, you set which slots in the chassis will be powered on.
TABLE 5-1 defines the poweron-vector variable's 8-bit vector.
If you are developing an application that controls the power of every slot in the chassis, you must shut off the power-on bit-vector for every slot. At the ok prompt, use the setsmcenv command to set the poweron-vector variable to 0xff:
Each slot has BDSEL#, HEALTHY#, and RESET# signals. These HA signals can be controlled and monitored by an application. An extra flag, called slot_flg, is also available that indicates whether a slot is empty or full.
An 8-bit bit-vector represents all the slots within an 8-slot HA CompactPCI chassis. The SBC and the standby SBC (SSBC) are reserved slots in an HA chassis and are not counted in the 8-bit bit-vector. See TABLE 5-1 for the bit number to slot number sequencing.
Use the bdsel, healthy and reset bit-vectors to control a slot's BDSEL#, HEALTHY#, and RESET# signals. When using these bit-vectors, any set bit means that the signal is de-asserted on that slot. Conversely, any clear bit means that the signal is asserted. For example, a slot that is not healthy will have its bit set, which means that the HEALTHY# signal is de-asserted. When a slot has its RESET# signal asserted, the appropriate bit for this slot is cleared, and the board will not be visible on the CompactPCI bus until this RESET# signal is de-asserted or has its bit set.
The bdsel bit-vector has two meanings depending on whether the bit-vector is being written to or read. When the bdsel bit-vector is written, the value of the bit-vector should set the bits for slots that should have BDSEL# disabled, and cleared for slots that have BDSEL# asserted. The value of the bdsel bit-vector that is read has set bits for slots that are requesting BDSEL# to be asserted. For more information about this process, see Bringing a Slot Online.
To power on slot 5, your application should assert the BDSEL# signal on this slot. You can calculate the new value for the bdsel bit-vector by clearing the slot 5 bit from the healthy bit-vector and storing the result in arg.bdsel as follows:
The HSIOC_SETHASIG ioctl() sets both the bdsel and the reset bit-vectors. For slots that are to remain powered off, their bdsel bit should be set to 1. In this example, slot 5 is the only slot powered on, so the bit-vector should be:
The Solaris hot-swap framework recognizes this ENUM# signal, which in this case indicates that the board has been freshly inserted, and then configures the board. Use the cfgadm command at a Solaris command prompt to verify that this slot has been successfully configured.
After a board is successfully removed from the chassis, the slot containing this board should have its BDSEL# and RESET# signals set to 1 so that future hot-swap insertions will be detected within this slot.
The HSIOC_SETHASIG ioctl() simultaneously sets both the bdsel and reset bit-vectors. The bdsel bit-vector should have the bits set for the slots that are not requesting the BDSEL# signal. This bit setting is the complement of the bit pattern returned from the HSIOC_GETHASIG ioctl(). The value returned from the HSIOC_GETHASIG ioctl() indicates which slots have requested the BDSEL# signal.
For example, if the bdsel bit-vector is 0xa8, the chassis slots 5 and 7 are requesting BDSEL# signals (bit 7 is ignored so this is equivalent to a setting of 0x28). Also, the slot configuration flag should be set to 0x28, which indicates that slots 5 and 7 have boards installed in them. If both slots 5 and 7 assert the BDSEL# signal, the value for the bdsel bit-vector (used with the HSIOC_SETHASIG ioctl()) should be the complement of 0xa8 (or 0x57).
You can also use the healthy bit-vector as a guide to setting the bdsel bit-vector. Any bit set in the healthy bit-vector indicates that the HEALTHY# signal is de-asserted, and that the board should not be powered on unless the board was already powered on and then became unhealthy for some reason. To assert the BDSEL# signal on any slot, the bit corresponding to the slot requesting the BDSEL# signal can be cleared in the healthy bit-vector as follows:
Since the HSIOC_SETHASIG ioctl() sets both the bdsel and reset bit-vectors, the correct value for the bdsel bit-vector has to be constructed using the healthy bit-vector. The healthy bit-vector indicates which slots have the BDSEL# signal asserted.
The preceding example assumes that your application controls the powering on of all of the slots. However, if you do not want to control the powering on and off of some of the slots and would prefer to delegate this control to the system (by appropriately setting the OpenBoot PROM variable, poweron-vector), you should only derive the bdsel mask from the healthy status of the slots under your application's control. Taking this action prevents accidentally powering off slots not under your application's control.
Note - Power off a slot only after the board has been unconfigured and the RESET# has been asserted. Do not attempt to control a slot's power while there is a board in the configured state and there is a driver attached as it could lead to a system panic or hang.
CODE EXAMPLE 5-3 displays a header file containing all of the directives, macros, and definitions listed throughout this document. You must use a header file like the one below in order to develop applications using the software described in this document.