mdi_get_unit -- determine if device has been configured


   #include <sys/types.h>
   #include <sys/stream.h>
   #include <sys/stropt.h>
   #include <sys/mdi.h>
   #include <sys/ddi.h>

boolean_t mdi_get_unit(rm_key_t rmkey, uint_t *unit);


The mdi_get_unit( ) function determines if the driver has been configured by the user running netcfg.

For DDI versions prior to version 8, this function also returns a unit number that can be used to uniquely identify the driver instance that has been configured. This unit number does not change when additional devices are added to or removed from the system and is used to establish the relationship between the minor number being opened and the instance number of the device. In this case, device instances range from 0 to one less than the return value of cm_getnbrd(D3).


Resource manager key.

Pointer to the unit number, set when mdi_get_unit( ) returns B_TRUE. DDI 8 drivers should pass in (uint_t *)NULL for the unit.

Return values

mdi_get_unit( ) returns the following values:

This instance has not been configured by the user and should be ignored.

This instance has been configured with the netcfg command. The driver should read any information stored at the resource manager key.


The mdi_get_unit( ) function is used in the following ways:

CFG_ADD time
DDI 8 drivers call mdi_get_unit( ) from the CFG_ADD subfunction of their config(D2mdi) entry point routine. Because CFG_ADD can be called multiple times with the same rmkey value, it is acceptable to return an error for the initial call. When netcfg sets MODNAME to your driver's name in the Resource Manager, the driver's CFG_ADD code will be invoked again, and mdi_get_unit( ) will succeed.

load time
DDI 7 drivers call mdi_get_unit( ) from the _load(D2mdi) entry point routine immediately after calling cm_getbrdkey(D3) in a loop. If mdi_get_unit( ) returns B_FALSE, then set unit to -1 and continue on to the next instance. If it returns B_TRUE, save the unit number to be used in the open( ) and intr( ) routines.

interrupt time
DDI 7 drivers check the return value of mdi_get_unit( ) (stored in the the per-device structures) from the intr(D2mdi) routine to identify any devices to skip when walking through the list of possible devices. This is done when trying to match the IRQ to the adapter that generated the interrupt passed into the intr(D2mdi) routine.

In the open(D2mdi) routine, it does not matter what the minor number is as long as there is a match in the array of per-device structures with a previously-saved unit number and the minor number. If the minor number passed into the open( ) routine is set to -1, then return ENXIO to indicate a bogus minor number.

Drivers should use code similar to the following in the open( ) routine:

   for (boardnum = 0; board < cm_getnbrd number; boardnum++) {
   	if (myarray[boardnum].unit == minor number) break;
   if boardnum == 0; {
   	return ENXIO			/* no match found */
   boardpointer = &myarray[boardnum];
This replaces existing code that checks if minor is larger than the value returned by the cm_getnbrd(D3) function and returns ENXIO if it is, along with code such as:
   	boardpointer = &myarray[minor_number];

CFG_ADD is the only subfunction of the config( ) entry point routine that can call mdi_get_unit( ); it must not be called from the CFG_SUSPEND subfunction.

DDI 8 drivers should pass in a NULL unit parameter.

DDI 7 network drivers must not compare the minor number passed in at open( ) time with the value returned from cm_getnbrd(D3), because this number changes as boards are added and removed from the system. When user programs open a device with the same minor number, they expect that the device open( ) will succeed and that frames will not be sent on the wrong network device.

mdi_get_unit( ) does not read or manipulate the CM_UNIT parameter that contains driver-dependent information.

When testing a network driver, you should use the netcfg command to install and configure the driver. If the driver is installed in some other way, this function always returns B_FALSE.

mdi_get_unit( ) solves a problem with multiple smart-bus network adapter cards that depend on device names corresponding to the same physical hardware. DDI 7 drivers that call cm_getnbrd(D3) and use that number as the highest minor number will fail as additional cards of the same type are dynamically added and removed from the system, skewing the value returned by cm_getnbrd( ). This causes the driver to send frames out to the wrong interface and sometimes to refuse to open a device that does not exist any longer.

mdi_get_unit( ) also resolves problems that occur when multiple network cards of the same type exist on the system and not all have been configured. The value passed to mdi_printcfg(D3mdi) and the cmn_err(D3) functions may supply extraneous messages that are confusing to users.

NOTE: mdi_get_unit( ) assumes that there will be one resource manager entry for each transceiver on the network device. If you have a device that has multiple transceivers (for example, one for Token Ring and another for Ethernet) where each transceiver can operate independently at the same time, and each transceiver does not have its own resource manager entry, you cannot use mdi_get_unit( ).

Context and synchronization

Blockable context

Hardware applicability

All especially smart-bus (PCI, EISA, and MCA) cards.

Version applicability

mdi: 2, 2.1

Differences between versions

This function is not supported in MDI on SCO OpenServer systems.


cm_args(D4), cm_getnbrd(D3), cm_getbrdkey(D3), config(D2mdi), _load(D2mdi), open(D2mdi), resmgr
19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005