[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


17    Data Structures That the Autoconfiguration Software Uses

Autoconfiguration is a process that determines what hardware actually exists during the current instance of the running kernel at static configuration time. The autoconfiguration software creates a configuration tree that represents the current system configuration. In creating this configuration tree, the autoconfiguration software uses the following data structures:

The following sections describe each of these data structures except the driver structure. Section 5.3 describes the driver structure.


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


17.1    The bus Structure

The bus structure represents an instance of a bus entity. A bus is a real or imagined entity to which other buses or controllers are logically attached. All systems have at least one bus, the system bus, even though the bus may not actually exist physically. The term controller here refers both to devices that control slave devices (for example, disk or tape controllers) and to devices that stand alone (for example, terminal or network controllers). Bus adapter driver writers create bus structures by calling the create_bus_struct interface and passing to it a filled-in bus_config structure. The discussion of how to use the create_bus_struct interface and how to fill in the bus_config structure is beyond the scope of this book. However, the descriptions of the bus structure are presented here.

Table 17-1 lists the members of the bus structure along with their associated data types.

Table 17-1: Members of the bus Structure

Member Name Data Type
bus_mbox u_long *
bus_hd struct bus *
nxt_bus struct bus *
ctlr_list struct controller *
bus_list struct bus *
bus_type int
bus_name char *
bus_num int
slot int
connect_bus char *
connect_num int
confl1 int (*confl1)()
confl2 int (*confl2)()
pname char *
port struct port *
intr int (**intr)()
alive int
framework struct bus_framework *
driver_name char *
bus_bridge_dma void *
private void * [8]
conn_priv void * [8]
rsvd void * [7]

The following sections discuss all of these members.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.1    The bus_mbox Member

The bus_mbox member specifies a pointer to the mailbox data structure for hardware platforms that access I/O space through hardware mailboxes. The bus adapter code sets this member. As the adapter code probes the buses, the first bus that has a mailbox allocates the initial software mailbox data structure and sets its bus_mbox pointer to that data structure. As the adapter code continues to probe for buses and controllers, the MBOX_GET macro allocates the ctlr_mbox members for devices accessed by mailboxes. Typically, this macro is called in the controller configuration interface after the controller data structure has been found, but before probing the controller. The following code fragment gives an idea of the tasks that occur prior to calling the MBOX_GET macro:

config_con(name, node, bus)
{
   register struct controller *ctlr;

   if((ctlr = get_ctlr(name, node, bus->bus_name, bus->bus_num)) ||
          /* other wildcards here */
      (ctlr = get_ctlr(name, -1, "*", -99))) {

.
.
.
} /*************************************************** * Found the controller * ***************************************************/ int savebusnum; char *savebusname; int saveslot; if(ctlr->alive & ALV_ALIVE) { printf("config_con: %s%d alive\n", ctlr->ctlr_name, ctlr->ctlr_num); return(stat); } savebusnum = ctlr->bus_num; savebusname = ctlr->bus_name; saveslot = ctlr->slot; ctlr->bus_name = bus->bus_name; ctlr->bus_num = bus->bus_num; ctlr->slot = node; /*************************************************** * Allocate and initialize a software * * mailbox data structure for the * * controller if it is attached to a * * bus that is accessed by mailboxes * ***************************************************/ MBOX_GET(bus, ctlr); /*************************************************** * Now get the controller's driver structure * * and probe * ***************************************************/
.
.
.
}



[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.2    The bus_hd, nxt_bus, ctlr_list, and bus_list Members

The bus_hd member specifies a pointer to the bus structure that this bus is connected to. The nxt_bus member specifies a pointer to the next bus at this level.

The ctlr_list member specifies a linked list of controllers connected to this bus. The bus_list member specifies a linked list of buses connected to this bus.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.3    The bus_type Member

The bus_type member specifies the type of bus. The devdriver.h file defines constants that represent a variety of bus type constants. For example, BUS_PCI represents a PCI bus, BUS_EISA represents an EISA bus, BUS_ISA represents an ISA bus, and so forth.

Device driver writers seldom need to reference this member. However, bus adapter driver writers might reference this member in their bus adapter code.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.4    The bus_name and bus_num Members

The bus_name member specifies the bus name. The bus_num member specifies the bus number of this bus.

The bus name consists of a character string, for example, pci (for PCI bus). The bus number is a number such as 0 (zero), 1, 2, and so forth.

Device driver writers seldom need to reference the bus_name and bus_num members in their device drivers. Instead, driver writers often pass a pointer to a bus structure to the handler interfaces, and the interrupt handlers use the information contained in these members.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.5    The slot, connect_bus, and connect_num Members

The slot member specifies the bus slot or node number. The connect_bus member specifies the name of the bus that this bus is connected to. The connect_num member specifies the number of the bus that this bus is connected to.

The bus name consists of a character string, for example, pci (for PCI bus). The bus number consists of one of the following:

Device driver writers seldom need to reference these members in their device drivers. However, bus adapter driver writers might reference these members in their bus adapter code.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.6    The confl1 and confl2 Members

The confl1 member specifies a pointer to an entry point of the level 1 bus configuration interface. The confl2 member specifies a pointer to an entry point of the level 2 bus configuration interface. Device driver writers do not typically use these interfaces, but systems engineers who want to implement a configuration procedure for a specific bus probably would use them.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.7    The pname and port Members

The pname member specifies a pointer to the port name for this bus, if applicable. The port member specifies a pointer to the port structure for this bus, if applicable.

Device driver writers do not reference these members in their device drivers. However, bus adapter writers use the port structure to implement the initialization for a class of devices or controllers that have common characteristics.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.8    The intr Member

The intr member specifies an array that contains an entry point or points for the bus interrupt handlers.

A device driver knows the name of its bus interrupt interface. A device driver uses the handler_add and handler_enable interfaces to register its interrupt handlers.

Device driver writers seldom need to reference this member in their device drivers. However, bus adapter driver writers might use this member in their bus adapter code to reference the interrupt handlers that handle error interrupts related to the bus.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.9    The alive Member

The alive member specifies a flag word to indicate the current status of the bus. The system sets this member to the bitwise inclusive OR of the valid alive bits defined in devdriver.h.

The ALV_ALIVE bit indicates that the device is present and configured on the system. The following list shows the valid alive bits that bus adapter drivers can use:

ALV_FREE The bus is not yet processed.
ALV_ALIVE The bus is alive and configured.
ALV_PRES The bus is present but not yet configured.
ALV_NOCNFG The bus is not to be configured.
ALV_LOADABLE The bus is present and resolved as loadable.
ALV_NOSIZER The sizer program should ignore these bus structures. This bit is set for dynamically configured drivers. It indicates that this bus structure is not part of the static configuration.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.10    The framework and driver_name Members

The framework member specifies a pointer to the bus_framework structure. This structure contains pointers to bus interfaces for dynamically configured device drivers. These interfaces provide dynamic extensions to bus functionality. They are used in the autoconfiguration of dynamically configured drivers to perform bus-specific tasks, such as the registration of interrupt handlers. The framework member is initialized by the bus adapter driver.

Device driver writers seldom need to reference this member in their device drivers. However, bus adapter driver writers might reference this member in their bus adapter code.

The driver_name member specifies the name of the controlling device driver.

The autoconfiguration software sets the driver_name members to xxdriver, where xx is the driver name as specified by the device driver entry in the sysconfigtab file fragment. The following example shows one such entry:


.
.
.
none:
.
.
.

Device driver writers seldom need to reference this member in their device drivers. However, bus adapter driver writers might reference this member in their bus adapter code.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.11    The bus_bridge_dma Member

The bus_bridge_dma member specifies that the bus adapter has direct memory access (DMA) mapping support. The bus_bridge_dma member is initialized by the bus adapter driver.

Device driver writers seldom need to reference this member in their device drivers. However, bus adapter driver writers might reference this member in their bus adapter code.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.1.12    The private, conn_priv, and rsvd Members

The private member specifies private storage for use by this bus or bus class. The conn_priv member specifies private storage for use by the bus that this bus is connected to. The rsvd member is reserved for future expansion of the data structure.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2    The controller Structure

The controller structure represents an instance of a controller entity, one that connects logically to a bus. A controller can control devices that are directly connected or can perform some other controlling operation, such as a network interface or terminal controller operation.

Device driver writers create controller structures by calling the create_controller_struct interface and passing to it a filled-in controller_config structure. Section 6.6.4.1 discusses the controller_config structure and Section 6.6.4.3 discusses how to call the create_controller_struct interface.

Table 17-2 lists the members of the controller structure, along with their associated data types.

Table 17-2: Members of the controller Structure

Member Name Data Type
ctlr_mbox u_long *
bus_hd struct bus *
nxt_ctlr struct controller *
dev_list struct device *
driver struct driver *
ctlr_type int
ctlr_name char *
ctlr_num int
bus_name char *
bus_num int
rctlr int
slot int
alive int
pname char *
port struct port *
intr int (**intr)()
addr caddr_t
addr2 caddr_t
flags int
bus_priority int
ivnum int
priority int
cmd int
physaddr caddr_t
physaddr2 caddr_t
private void * [8]
conn_priv void * [8]
rsvd void * [8]

The following sections discuss all of these members.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.1    The ctlr_mbox Member

The ctlr_mbox member specifies a pointer to the mailbox data structure for hardware platforms that access I/O space through hardware mailboxes. The bus adapter code sets this member. As the adapter code probes the buses, the first bus that has a mailbox allocates the initial software mailbox data structure and sets its bus_mbox pointer to that data structure. As the adapter code continues to probe for buses and controllers, the MBOX_GET macro allocates the ctlr_mbox members for devices accessed by mailboxes. Typically, this macro is called in the controller configuration interface after the controller data structure has been found, but before probing the controller.


The following code fragment gives an idea of the tasks that occur prior to calling the MBOX_GET macro:

config_con(name, node, bus)
{
   register struct controller *ctlr;

   if((ctlr = get_ctlr(name, node, bus->bus_name, bus->bus_num)) ||
          /* other wildcards here */
      (ctlr = get_ctlr(name, -1, "*", -99))) {

.
.
.
} /*************************************************** * Found the controller * ***************************************************/ int savebusnum; char *savebusname; int saveslot; if(ctlr->alive & ALV_ALIVE) { printf("config_con: %s%d alive\n", ctlr->ctlr_name, ctlr->ctlr_num); return(stat); } savebusnum = ctlr->bus_num; savebusname = ctlr->bus_name; saveslot = ctlr->slot; ctlr->bus_name = bus->bus_name; ctlr->bus_num = bus->bus_num; ctlr->slot = node; /*************************************************** * Allocate and initialize a software * * mailbox data structure for the * * controller if it is attached to a * * bus that is accessed by mailboxes * ***************************************************/ MBOX_GET(bus, ctlr); /*************************************************** * Now get the controller's driver structure * * and probe * ***************************************************/
.
.
.
}


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.2    The bus_hd, nxt_ctlr, and dev_list Members

The bus_hd member specifies a pointer to the bus structure that this controller is connected to. The nxt_ctlr member specifies a pointer to the next controller at this level. The dev_list member specifies a linked list of devices connected to this controller.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.3    The driver Member

The driver member specifies a pointer to the driver structure for this controller. The device driver writer initializes a driver structure, usually in the declarations section of the driver.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.4    The ctlr_type, ctlr_name, and ctlr_num Members

The ctlr_type member specifies the controller type. The ctlr_name member specifies the controller name. The ctlr_num member specifies the controller number.

The ctlr_type member is not currently used by the autoconfiguration software.

The controller name consists of a character string, for example, fb (for graphics frame buffer controller).

Driver writers are unlikely to use the ctlr_name member. Driver writers often use the ctlr_num member as an index to identify which instance of the controller the request is for. The /dev/none device driver illustrates the use of the ctlr_num member.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.5    The bus_name and bus_num Members

The bus_name member specifies the name of the bus to which this controller is connected. The bus_num member specifies the number of the bus to which the controller is connected.

The bus name consists of a character string, for example, pci (for PCI bus).

The bus number consists of one of the following:

Device driver writers seldom need to reference these members in their device drivers. However, bus adapter driver writers might reference these members in their bus adapter code.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.6    The rctlr Member

The rctlr member specifies the remote controller number (for example, the SCSI ID).


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.7    The slot Member

The slot member specifies the bus slot or node number. The kernel can set this member to the value -1 if there are no slots.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.8    The alive Member

The alive member specifies a flag word to indicate the current status of the controller. The autoconfiguration software sets the alive member to the ALV_ALIVE bit if the controller is present on the system. The autoconfiguration software obtains this and the other alive bits in the file devdriver.h. The following list shows the valid alive bits that bus adapter drivers can use:

ALV_FREE The controller is not yet processed.
ALV_ALIVE The controller is alive and configured.
ALV_PRES The controller is present but not yet configured.
ALV_NOCNFG The controller is not to be configured.
ALV_LOADABLE The controller is present and resolved as dynamically configured.
ALV_NOSIZER The sizer program should ignore these controller structures. This bit is set for dynamically configured drivers. It indicates that this controller structure is not part of the static configuration.
ALV_RONLY The device is read only. This bit is set for statically configured drivers if the corresponding entry is specified in the sysconfigtab file fragment. This bit is not supported for dynamically configured drivers.
ALV_WONLY The device is write only. This bit is set for statically configured drivers if the corresponding entry is specified in the sysconfigtab file fragment. This bit is not supported for dynamically configured drivers.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.9    The pname and port Members

The pname member specifies a pointer to the port name for this controller, if applicable. The port member specifies a pointer to the port structure for this controller, if applicable.

Device driver writers do not reference these members in their device drivers. However, bus adapter writers use the port structure to implement the initialization for a class of devices or controllers that have common characteristics.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.10    The intr Member

The intr member specifies an array that contains one or more entry points for the controller interrupt handlers.

For device drivers, the intr members of these data structures would be set up indirectly through calls to the handler_add interface.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.11    The addr and addr2 Members

The addr member specifies the address of the device registers or memory. This address is the first control status register (CSR) for the CPU.

The addr2 member specifies an optional second virtual address for this controller. This member is set if there are two CSR spaces.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.12    The flags Member

The flags member specifies controller-specific flags.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.13    The bus_priority Member

The bus_priority member specifies the configured VMEbus priority level of the device. Only drivers operating on the VMEbus use this member. See Writing VMEbus Device Drivers for additional information on this member.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.14    The ivnum Member

The ivnum member specifies an interrupt vector number. Only drivers operating on the VMEbus use this member. See Writing VMEbus Device Drivers for additional information on this member.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.15    The priority Member

The priority member specifies the system priority level (spl) to block interrupts from this device. Only drivers operating on the VMEbus use this member. Thus, the autoconfiguration software initializes the priority member with an appropriate value based on the value stored in the bus_priority member (if specified) and the system implementation. You use this value as an argument to the splx interface to block interrupts for the device. See Writing VMEbus Device Drivers for additional information on this member.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.16    The cmd Member

The cmd member specifies a field that is not currently used.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.17    The physaddr and physaddr2 Members

The physaddr member specifies the physical address that corresponds to the virtual address set in the addr member.

The physaddr2 member specifies the physical address that corresponds to the virtual address set in the addr2 member.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.2.18    The private, conn_priv, and rsvd Members

The private member specifies private storage for use by this controller or controller type. The code controlling the controller can use these members for any storage purpose.

The conn_priv member specifies private storage for use by the bus that this controller is connected to.

The rsvd member is reserved for future expansion of the data structure.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.3    The device Structure

The device structure represents an instance of a device entity. A device is an entity that connects to and is controlled by a controller. A device does not connect directly to a bus.

Device driver writers create device structures by calling the create_device_struct interface and passing to it a filled-in device_config structure. Section 6.6.4.2 discusses the device_config structure and Section 6.6.4.3 discusses how to call the create_device_struct interface.

Table 17-3 lists the members of the device structure along with their associated data types.

Table 17-3: Members of the device Structure

Member Name Data Type
nxt_dev struct device *
ctlr_hd struct controller *
dev_type char *
dev_name char *
logunit int
unit int
ctlr_name char *
ctlr_num int
alive int
private void * [8]
conn_priv void * [8]
rsvd void * [8]

The following sections discuss all of these members.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.3.1    The nxt_dev and ctlr_hd Members

The nxt_dev member specifies a pointer to the next device at this level. The ctlr_hd member specifies a pointer to the controller structure that this device is connected to.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.3.2    The dev_type and dev_name Members

The dev_type member specifies the device type (for example, disk or tape). The dev_name member specifies the device name type.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.3.3    The logunit and unit Members

The logunit member specifies the device logical unit number. The unit member specifies the device physical unit number.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.3.4    The ctlr_name and ctlr_num Members

The ctlr_name member specifies the name of the controller that this device is connected to. The ctlr_num member specifies the number of the controller that this device is connected to.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.3.5    The alive Member

The alive member specifies a flag word to indicate the current status of the device. The autoconfiguration software obtains this and the other alive bits in the file /usr/sys/include/io/common/devdriver.h.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


17.3.6    The private, conn_priv, and rsvd Members

The private member specifies private storage for use by this device or device class. The conn_priv member specifies private storage for use by the controller that this device is connected to.

The rsvd member is reserved for future expansion of the data structure.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


17.4    The port Structure

The port structure contains information about a port.

Table 17-4 lists the member of the port structure along with its associated data type.

Table 17-4: Member of the port Structure

Member Name Data Type
conf int (*conf) ()

The conf member specifies a pointer to the configuration interface for this port.