gencon(7) — SPECIAL FILES AND DEVICES
NAME
gencon − STREAMS-based generic console interface
DESCRIPTION
gencon is a STREAMS software driver which sits between the console chip driver(s) and the system software. Its purpose is to act as an intelligent switch between the hardware console ports and the rest of the system. gencon is responsible for dual-console operation and the support of multiple console drivers.
Dual-console operation is the logical connection of two hardware ports such that they both appear to be the system console. Console input is received concurrently from the two ports while console output is sent to both ports. This functionality is most commonly used by field service for remote system debugging. For more information see the dcon(1M) manpage.
gencon also allows multiple drivers to control different hardware ports on the same chip. This is accomplished by having all console streams and console chip interrupts flow through gencon. This allows gencon to do all the bookkeeping concerning port ownership. For example, gencon will route all console interrupts from port 2 to the driver which currently owns port 2. As well, all STREAMS services directed at port 2 will be routed by gencon to the correct driver.
In order to add a driver under gencon, the following steps should be performed.
o Write a STREAMS based driver for the specific console chip. The only routine entry point which can match the prefix<routine name> naming convention should be the init routine. For example, if the PREFIX field listed in the driver’s master file is a1x7, the init routine within the driver should be named a1x7init while all other routines should begin with some other prefix. This is easily done by using prefix_<routine name> as the naming convention for all of the other entry points (e.g. a1x7_open, a1x7_close, etc.).
o In the driver, add an integer array declaration which consists of the addresses of the interrupt routines within that driver. The address of this array should be the second element listed in the driver’s protocol entry within the gencon master file. See the Protocol Entry table for a more precise description of the protocol entry format. The following table describes how the entries are assigned:
| Array Index | MVME188 Based Systems | MVME1x7 Based Systems |
| 0 | All console interrupts | receive exception interrupts |
| 1 | 0 | modem interrupts |
| 2 | 0 | transmit interrupts |
| 3 | 0 | receive interrupts |
| 4 | 0 | port 4 ring interrupts (M8120 systems only) |
| 5 | 0 | port 5 ring interrupts (M8120 systems only) |
Notice that ring interrupts are only valid on M8120 systems. There is no harm in specifying these entries if the system is not an M8120 since gencon will not attempt to call the routine unless the system is an M8120.
o (OPTIONAL) In the driver, add a routine which requires no arguments and returns an integer mask describing on which ports the driver can operate. For each port n which the driver is valid, bit n of the return value should be 1 (e.g. If a driver is only valid on ports 4 and 5 the return value should be 0x30). This routine is used when gathering information about which device nodes should be made. If the routine is not present, it will be assumed that the driver can operate on all ports and device nodes will be made accordingly. The address of this routine should be the third element listed in the driver’s protocol entry within the gencon master file. See the Protocol Entry table below for a more precise description of the protocol entry format.
o (OPTIONAL) In the driver, add a routine which requires as an argument a pointer to a dev_t and returns an int. If the driver requires port locking for the given port, the routine should return 1. Otherwise, it should return 0. Port locking refers to the following: if a port is open by one driver, any open attempted by another driver fails if either driver requires port locking. As a result of this failure, open() returns -1 and sets errno to EACCES. If this routine is not present, locking will be enforced. The address of this routine should be the fourth element listed in the driver’s protocol entry within the gencon master file. See the Protocol Entry table below for a more precise description of the protocol entry format.
o (OPTIONAL) The driver may register a routine with gencon that will be called to provide more detailed support to the consdriverinfo() routine. The driver calls:
cons_register_port_driverinfo( int port; int (∗func)() );
to register func for port. func will be called with the following arguments:
func( int port, int cmd, int arg1, int arg2, cred_t ∗cred_p, int ∗errno_p);
port provides the context for this call, cmd can be any command listed in driverinfo(D2DK), but currently only the following are used by gencon: DXGETEDT D_FRU_STATUS If cmd is DXGETEDT, arg1 is a pointer to struct xedt. func() must fill in the elements of this structure and gencon will return it to the user process. If cmd is D_FRU_STATUS, arg1 is a pointer to struct dinfo_fru_status. func() must fill in the elements of this structure and gencon will return it to the user process. The return value should be 0 if cmd is implemented in func or -1 if it is not. If cmd is not implemented then gencon will provide defaults. If cmd is implemented and there is an error, then ∗errno_p should be set to the appropriate error value.
o (OPTIONAL) gencon makes the global struct driver_diagnostic_info ∗cons_diag_info available for boot-time diagnostics coverage and output. Drivers are free of course to obtain their own specific driver_diagnostic_info via drv_getparm(DDI/DDK).
o Since drivers under gencon are configured as software drivers, those drivers are always included in the kernel. In order to protect the driver from running on a device which it does not understand, the open() and init() routines within the driver should verify that the cpu board is correct for the driver. For example, the open() routine in an asynchronous 1x7 console driver should verify that the hardware is actually 1x7 based. If it is not 1x7 based, the routine would return ENXIO. The necessary information can be obtained by using the drv_getparm(CPUBOARD,...) DKI routine.
o Create a master file for the driver. The file should specify that the driver is a STREAMS based software driver and is statically bound to CPU 0 (see example below). The major number field should be set to ’-’ allowing drvinstall to fill in the field with some unused major number. The assigned major number is not important since there is no direct connection to the driver (i.e. STREAMS services and console chip interrupts all flow through gencon). See the master(4) manpage for a more detailed explanation of the fields in a master file. The following is an example of a master file used for a driver under gencon:
FLAGPREFIXMAJOR#DEVDEPENDENCIES/VARIABLES
0osnfa1x7--
o Use /usr/sbin/drvinstall to add the driver to the system. See drvinstall(1M) for information on how to use the drvinstall command.
o Add a protocol entry in the cons_switch declaration found in the gencon master file. Entries 0-7 are reserved for MOTOROLA use. Entries 8-15 are reserved for customer use. Each entry consists of four items. The items should be defined as follows:
| Protocol Entry | |
| Entry | Description |
| 0 | The address of the streamtab structure defined in the new driver. In most cases this will be "&prefixinfo" |
| 1 | The address of the array of interrupt routine addresses described previously. |
| 2 | The address of the port mask routine described previously. If this value is 0, the protocol will be assumed to be valid for all ports. |
| 3 | The address of the locking info routine described previously. If this value is 0, port locking will be enforced for this driver. |
The following is an example of a protocol entry in the gencon master file:
&a1x7info,&a1x7vecinfo,0,&a1x7_locking
Device Nodes
The device nodes used to access the protocols are created by the mvmecpu(1M) namer. The nodes are created as /dev/conttyxx_pyy. where xx is a decimal representation of the port number and yy is a decimal representation of the protocol number. For example: port 2, protocol 1 would be accessed through /dev/contty02_p01.
FILES
/dev/console
/dev/contty
/dev/contty∗
/dev/edt/console
/etc/master.d/gencon
NOTES
When the hardware specific console driver is iuart and a carrier change (DCD) interrupt occurs, bits 4-7 of the Input Port Change register and bit 7 of the Interrupt Status register will be reset while gencon is in the process of routing the interrupt to the correct driver. This is due to the fact that these particular registers on the MC68681 duart are automatically reset whenever read. Therefore bits 4-7 of the Input Port Change register and bit 7 of the Interrupt Status register should not be used to determine if the interrupt was caused by a change in carrier. There are two driver implementations which will circumvent this problem. The first is to implement a scan routine which periodically scans the current state of the DCD input lines. With this implementation the interrupt routine does not have to deal with carrier change interrupts since the correct state is maintained by the scan routine. The second implementation involves keeping track of the known DCD state and when an interrupt arrives checking to see if the states are different, if they are different then the interrupt is a DCD change.
SEE ALSO
dcon(1M), mvmecpu(1M), drvinstall(1M), master(4), cons1x7(7), iuart(7), driverinfo(D2DK), drv_getparm(DDI/DDK)