Configuring SVR5 MDI drivers

Extended ISA verify support

Enhanced ISA autodetect is used with ISA devices that enable you to read and/or write certain parameter settings from the firmware. This topic summarizes the steps required to implement this functionality.

To implement enhanced ISA autodetection support:

ISAVERIFY parameter

The ISAVERIFY parameter indicates what capabilities the board has for reading and writing specific ISA parameters to NVRAM/EEPROM located on the board. Parameters that are read-only are not listed in the ISAVERIFY parameter.

The ISAVERIFY parameter goes in the #DRIVER section of the bcfg(DSP/4dsp) file:

Only the parameters that are supported by your card need to be listed.

Custom-oriented parameters that are read from the firmware (such as wait-states, media type, media speed) are added in a different manner; see below.

Enhanced ISA support in driver verification

Driver support for enhanced ISA support is implemented in the driver's verification code. For MDI drivers running on DDI version 7, this is the _verify(D2mdi) entry point routine; for MDI drivers running on DDI version 8, this is the CFG_VERIFY subfunction to the config(D2mdi) entry point routine.

The first step is to ensure that an ISA bus is configured on this system. To do so, retrieve the CM_BRDBUSTYPE parameter from the resource manager database with the cm_getval(D3) function. This parameter is documented on the cm_params(D5) manual page:

   cm_args.cm_key = key ;
   cm_args.cm_n = 0 ;
   cm_args.cm_param = CM_BRDBUSTYPE ;
   cm_args.cm_val = &bustype ;
   cm_args.cm_vallen = sizeof(bustype) ;
   if (cm_getval(&cm_args) != 0) {
   cmn_err(CE_WARN, "e3D_verify: no BRDBUSTYPE for key 0x%x\n", key) ;
   return(ENODEV) ;

/* bustype is really a bitmask, but we treat it as a single value here */ if (bustype != CM_BUS_ISA) { cmn_err(CE_CONT, "!e3D_verify: not ISA board\n") ; return(ENODEV) ; }

Next, use the cm_getval(D3) function to retrieve the CM_IOADDR parameter; it is also documented on the cm_params(D5) manual page.
   cm_range_t   range ;
   struct cm_args   cm_args ;

cm_args.cm_key = key ; /* passed in as argument to your xxx_verify routine */ cm_args.cm_n = 0 ; cm_args.cm_param = CM_IOADDR ; cm_args.cm_val = &range ; cm_args.cm_vallen = sizeof(struct cm_addr_rng) ;

if (cm_getval(&cm_args) != 0) { cmn_err(CE_WARN, "xxx_verify: no IOADDR for key 0x%x\n", key); return(ENODEV); }

Now determine if your board's hardware is at this I/O address. Return the EINVAL or ENODEV error code if no board is found.

If you do find your board at this address, call the mdi_AT_verify(D3mdi) function to retrieve the firmware values for these parameters:

   int getset;
   int vector, dma;
   ulong_t scma, ecma, sioa, eioa;

getset = MDI_ISAVERIFY_UNKNOWN; /* must set to this initially */ err = mdi_AT_verify(key, &getset, &sioa, &eioa, &vector, &scma, &ecma, &dmac); if (err) { cmn_err(CE_WARN,"xxx_verify: mdi_AT_verify key=%d failed\n",key) ; return(ENODEV) ; } if (getset == MDI_ISAVERIFY_GET) { /* retrieve firmware parameters for ndcfg */ vector = <you read from I/O address or NULL if not readable> dma = <you read from I/O address or NULL if not readable> (for our example we'll set dma to NULL in call to mdi_AT_verify) scma = <you read from I/O address or NULL if not readable> ecma = <you read from I/O address or NULL if not readable> sioa = <same as IOADDR from resmgr> eioa = <ending byte that your driver uses-don't set this 1 byte too big!>

If the bcfg file has CUSTOM parameters such as cable type, link integrity, or buffer usage, you must read these from the firmware and set the same parameter in the resource manager database that is specified in the bcfg file. Use the key provided to your _verify( ) routine.

Program NVRAM/EEPROM with the values indicated by vector, sioa, eioa, scma, ecma, and dmac. Note that the range sioa-eioa may be different than the range given by CM_IOADDR in the resource manager. If it is, the user wants to change the existing I/O address that the board is using to the new address returned from mdi_AT_verify( ). You can call cmn_err(D3) to indicate to the user if there are any problems.

If any bcfg file used by your driver uses CUSTOM parameters, the driver code must also look for those parameters in the resource manager database and program the firmware accordingly. However, since you don't know which bcfg file the user is manipulating, don't fail if the parameter isn't found in the resource manager database. Instead, call the cmn_err( ) function with CE_NOTE to notify the user of the default setting that is being assumed.

   err = mdi_AT_verify(key, &getset, &sioa, &eioa, &vector,
                                     &scma, &ecma, NULL);
   if (err != 0) {
           cmn_err(CE_CONT,"xxx_verify: mdi_AT_verify returned %d",err);
   } else if (getset == MDI_ISAVERIFY_SET) {
      return(0);    /* to indicate success to ndcfg */
   } else if (getset == MDI_ISAVERIFY_TRADITIONAL) {
      /* the dcu is invoking us.  just confirm that the hardware is
       * present at the io address indicated CM_IOADDR
       * return 0 if found else ENODEV.
   } else {
      cmn_err(CE_WARN, "wdn_verify: unknown mode %d\n",getset);
   }  /* end your your xxx_verify routine */

© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005