SVR5
mdi_get_unit(D3mdi)
mdi_get_unit --
determine if device has been configured
Synopsis
#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);
Description
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).
Arguments
rmkey-
Resource manager key.
unit-
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:
B_FALSE-
This instance has not been configured by the user
and should be ignored.
B_TRUE-
This instance has been configured with the netcfg command.
The driver should read any information
stored at the resource manager key.
Usage
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.
open-
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.
References
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