Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

1365 lines
42 KiB
C

/* static char sccsid[] = "@(#)45 1.19 src/bos/usr/lib/methods/cfg_graphics/cfg_graphics.c, dispcfg, bos41J, 9513A_all 3/28/95 11:21:39"; */
/*
* COMPONENT_NAME: DISPCFG
*
* FUNCTIONS: main
*
*
* ORIGINS: 27
*
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
* combined with the aggregated modules for this product)
* SOURCE MATERIALS
*
* (C) COPYRIGHT International Business Machines Corp. 1985, 1993
* All Rights Reserved
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/*****************************************************************************
********************** MODULE HEADER TOP ************************************
*****************************************************************************
PURPOSE:
This routine is part of a problem-state process that
is executed by the system during configuration and by
the system when certain configuration commands are
invoked. The functions it contains are the standard
functions used by the AIX devices configuration architecture.
Typically, device specific configuration methods are
compiled into a ".o" which are linked with a standard
"main.o". This is because the configuration process is
relatively standard. However, for display devices, there
are sufficient reasons to have a separate "main" that
has been design just for graphics.
This software therefore is called from routines in
the companion file "cfg_graphics.c".
The interface between this problem-state process and the
AIX device drivers it requires are generally found
in the AIX system call "sysconfig( )". There are some
front end tools in "cfgraphics.c" and in "graphicstools.c"
which assist in the management of the sysconfig( ) call.
This routine provides the standard functions to build a
define-device-structure and to query the VPD. It also
has device specific code in it, to decide which type of
GTy adapter has been installed on the bus. It updates
the customized attributes accordingly.
This routine also supports the common character mode
VDD device driver in addition to the regular full function
VDD. See design 13588 for additional details.
MODULE ORGANIZATION:
The executable config method for any graphics device is composed
of several modules that are linked together. The following
is a list of the required and the optional modules:
cfg_graphics.o This module provides the "main" routine.
It contains the control flow and the
device independent front end. It manages
most of the interface with the ODM.
The module contains static internal routines
that it alone uses.
The module also contains some global data
available to all of the other modules.
The module uses a "call by name" interface
to access the other required modules.
cfg_graphics_tools.o A set of device independent tools that support
the cfg_graphics programs but are useful to
other configuration methods and to device
dependent mehtods as well.
chkslot.o This is a system module that does checking
of the MicroChannel slot.
cfgtools.o This is a system module that provides a
basic set of configuration tools for use
by the other pieces of the configuration
method executable.
cfg_ccmdd.o This module contains the common character
mode substitutes that are used instead
of the per-device entry points. The
"main" routine will either route its
device cfg method calls to the device
method or to cfg_ccmdd.o, depending on
the presence of a working device vdd and
a working device ucode file.
cfgXXXX.o For device XXXX, there must be one or more
device specific objects. The recommended
practise is to have the "call by name"
entry points in cfgXXXX.o and to have the
device specific subroutines in a separate
file.
In the system makefile environment, the following environment
variable is useful:
GRAPHBASE = cfg_graphics.o cfg_graphics_tools.o \
chkslot.o cfgtools.o cfg_ccmdd.o
PROGRAMMING INTERFACE:
cfgXXX -l <logical_name> [- < 1 | 2 > ] [ -D ]
*****************************************************************************
********************** MODULE HEADER BOTTOM *********************************
*****************************************************************************/
/*==========================================================================
|
| Define some useful constants
|
|==========================================================================*/
#define PASS 0
#define FAIL -1
#ifdef CFGDEBUG
# define STATIC
#else
# define STATIC static
#endif
/*==========================================================================
|
| System include files required by all cfg method main programs
|
|==========================================================================*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/lockl.h>
#include <sys/cfgdb.h>
#include <sys/cfgodm.h>
#include <cf.h>
#include <sys/sysconfig.h>
#include <sys/sysmacros.h>
#include <sys/device.h>
#include <errno.h>
/*==========================================================================
|
| Local debug routines are defined here
|
|==========================================================================*/
#include "cfgdebug.h"
/*==========================================================================
|
| Include files which describe the common character mode interface and
| the video ROM scan interface
|
|==========================================================================*/
#define Boolean unsigned int /* need by aixfont.h */
#define Bool unsigned int /* need by aixfont.h */
#include <sys/aixfont.h>
#include <sys/dir.h> /* needed by ccm_dds.h */
#include <sys/mdio.h> /* needed by cdd_macros.h */
#include <sys/file.h> /* needed by ccm.h */
#include <sys/intr.h> /* needed by vt.h */
#include <sys/ioacc.h> /* needed by ccm_dds.h */
#include <sys/adspace.h> /* needed by ccm_dds.h */
#include <sys/display.h>
#include "vt.h"
#include "cdd.h"
#include "cdd_macros.h"
#include "cdd_intr.h"
#include "cdd_intr_macros.h"
#include "ccm.h"
#include "ccm_macros.h"
#include "frs.h"
#include "frs_macs.h"
#include "frs_display.h"
#include "frs_display_macs.h"
/*==========================================================================
|
| include a file which defines the cfg macros used by our cfg methods
|
|==========================================================================*/
#include "cfg_graphics.h"
#include "cfg_graphics_frs.h"
#include "cfg_graphics_macros.h"
/*==========================================================================
|
| Define function references
|
|==========================================================================*/
/*--- from libc.a ---*/
extern int getopt( );
extern void exit( );
extern int strcmp( );
extern int atoi( );
extern long strtol( );
extern int strncmp( );
/*--- from libcfg.a ---*/
extern int busresolve ();
/*--- from cfg_graphics_tools.o ----*/
extern int Get_Custom_Object( );
extern int Get_Predef_Object( );
extern int cfg_svcs_error( );
extern int cfg_svcs_bus_get_l( );
extern int cfg_svcs_bus_get_s( );
extern int cfg_svcs_bus_get_c( );
extern int cfg_svcs_bus_put_l( );
extern int cfg_svcs_bus_put_s( );
extern int cfg_svcs_bus_put_c( );
extern int cfg_svcs_bus_cpy( );
extern int FRS_Find_Video_Device( );
extern int FRS_Make_Temp_File( );
extern int FRS_Add_File_to_ODM( );
extern int FRS_Add_File_to_Methods( );
extern int FRS_Update_ODM_From_File( );
extern int FRS_Copy_File( );
/*--- from chkslot.o ----*/
extern int chkslot ();
/*---- from cfgtools.o ----*/
extern int Get_Parent_Bus( );
extern int getatt( );
extern int convert_att( );
extern int convert_seq( );
extern struct attr * att_changed( );
extern int mk_sp_file( );
extern char * read_descriptor( );
extern void add_descriptor( );
extern void put_vpd( );
/*---- from cfgXXXX.o, the actual device specific code ----
extern int generate_minor( );
extern int build_dds( );
extern int query_vpd( );
extern int download_microcode( );
----------------------------------------------------------*/
/*---- from cfg_ccmdd.o, the ccm dd version of dev specific code ---*/
extern int ccm_generate_minor( );
extern int ccm_build_dds( );
extern int ccm_query_vpd( );
extern int ccm_download_ucode( );
/*--- from AIX BOS runtime environment ---*/
extern int odm_initialize ( );
extern int odm_lock( );
extern void setleds( );
/*==========================================================================
|
| Define some data global to these functions, so that it can be readily
| shared and accessed by the functions and by the "main" and other functions
| in "cfg_graphics.c" and the functions in cfgyyy.c
|
|==========================================================================*/
extern char * optarg; /* for getopt function */
extern int optind; /* for getopt function */
/*=========================================================
|
| Define the anchor pointer used for cfg_graphics macros
| to access various pieces of global data required by
| the config methods and their device specific pieces
|
|==========================================================*/
cfg_graphics_data_t __GLOBAL_DATA;
cfg_graphics_data_t * __GLOBAL_DATA_PTR = &__GLOBAL_DATA;
/*==========================================================
|
| One of these anchors is filled in by the device config
| method, and the other is filled in by the CCM config
| method.
|
|===========================================================*/
/*----------------------------------------------------------------------------------------
|
| lft architecture requires display graphics drivers to create special files for
| the device. All of this will be true in 4.1. However for 325, GTX150/100 (bbldd) is the
| first driver to do that. Therefore a function pointer, "make_special_file", has been
| added to cfg_graphics_funcs_t.
|
| In ccm/cdd mode, there is no special file to make. Thus, set the function pointer to NULL
| Before calling "make_special_file" we'll check for NULL pointer first!
|
----------------------------------------------------------------------------------------*/
cfg_graphics_funcs_t _CCM_FUNCS = { ccm_generate_minor,
ccm_build_dds,
ccm_download_ucode,
ccm_query_vpd,
NULL /* 601_CHANGE */
};
int Dflag; /* flag for defining children */
/*===========================================================================
|
| Because we have divided "main( )" into pieces, with local subroutines
| that are static and that act on data known to main, we need to declare
| all of the data that "main" would use inside its {...} scope as
| static data to this module but place it outside the scope of main( ).
| This lets the other static routines have access to the data.
|
|===========================================================================*/
STATIC struct cfg_dd cfg_dd; /* sysconfig command structure */
STATIC struct cfg_load cfg_load; /* sysconfig command structure */
STATIC char *logical_name; /* logical name to configure */
STATIC char sstring[MAXNAMLEN]; /* search criteria pointer */
STATIC char odm_vpd[ VPDSIZE ]; /* used for ODM interface */
STATIC char conflist[1024];/* busresolve() configured devices */
STATIC char not_resolved[1024]; /* busresolve() not resolved
* devices */
STATIC char mcabus_type[] = "mca";
STATIC char sgabus_type[] = "sgabus";
STATIC char buc601_type[] = "sysplanar3"; /* 601 Bus Unit Controller type */
/* Feature #117983 forced this to be */
/* changed from sysplanar1 to sysplanar3 */
STATIC struct Class *p_Class_CuAt; /* customized Attributes class ptr */
STATIC struct Class *p_Class_PdAt; /* predefined Attributes class ptr */
STATIC struct Class *p_Class_CuDv; /* customized devices class ptr */
STATIC struct Class *p_Class_PdDv; /* predefined devices class ptr */
STATIC struct Class *p_Class_vpd; /* customized vpd class ptr */
STATIC struct CuDv s_CuDv_object; /* customized device object storage */
STATIC struct PdDv s_PdDv_object; /* predefined device object storage */
STATIC struct CuDv s_CuDv_parent; /* customized device object storage */
STATIC struct PdDv s_PdDv_parent; /* predefined device object storage */
STATIC struct CuDv s_CuDv_temp; /* customized device object storage */
STATIC struct CuVPD s_CuVPD_object;/* customized vpd object */
STATIC int major_num; /* major number assigned to device */
STATIC int minor_num; /* minor number assigned to device */
STATIC int device_num; /* composed w. makedev(maj,min) */
STATIC long *minor_list; /* list returned by getminor */
STATIC int how_many; /* number of minors in list */
STATIC int lock_id; /* odm_lock id returned by odm_lock */
STATIC ushort devid; /* Device id - used at run-time */
STATIC int ipl_phase; /* ipl phase: 0=run,1=phase1,2=phase2 */
STATIC int slot; /* slot of adapters */
STATIC int rc; /* return codes go here */
STATIC int errflg,
c; /* used in parsing parameters */
STATIC ulong bus_id;
STATIC char *phase1,
*phase2; /* ipl phase flags */
STATIC void * p1; /* temp pointer */
STATIC char path1[ MAXNAMLEN ];
STATIC char path2[ MAXNAMLEN ];
STATIC int sysconfig_cmd; /* used when loading dd */
STATIC char tmp_cfg_meth[ MAXNAMLEN ];
STATIC char tmp_ucode[ MAXNAMLEN ];
STATIC char tmp_cdd[ MAXNAMLEN ];
STATIC char tmp_cdd_pin[ MAXNAMLEN ];
STATIC mid_t temp_kmid;
STATIC void * p_rom_kmod;
STATIC ulong rom_kmod_length;
STATIC void * p_video_head;
STATIC char driver_name[10] = "ccmdd" ;
/*==========================================================================
|
| include the private subroutine files here
|
| This set of subroutines is declared "static" and is used by
| "main" and not by any other part of the graphics config method
| set of object files
|
|===========================================================================*/
#include "cfg_graphics_priv.c"
/*****************************************************************************
********************** FUNCTION HEADER TOP***********************************
*****************************************************************************
FUNCTION NAME: main( )
TITLE: Run by the various config commands and config libs.
Causes the device to be configured, the ODM database
to be updated, and the device driver to be loaded
------------------------------------------------------------------------
FUNCTION:
The routine first parse argc and argv for any input flags. In particular,
it looks for the logical name of the device.
Next, the routine reads opens, initializes, and locks the ODM. It then
opens the customized object class, searches for a match of a customized
object to the input logical name, and, if it finds a match, checks that
the predefined object also exists.
Having found the predefined object, the function sets the front panel
LEDs to the value stored in the predefined object.
The function then tests whether the logical device has already been
configured. Typically, it has not. If the device is DEFINED and therefore
not configured, a long if branch is taken to configure the device.
In this if branch, the parent of the object is checked. The parent
must be AVAILABLE.
Next, the addressability is resolved for the device, if the config method
has been invoked during RUNTIME_CFG. During the address resolution, the
parent device is obtained to find out if we are dealing with an adapter
or device on the system planar. If the device is an adapter and its
parent device is a bus the following occurs:
1). The bus_id is obtained.
2). The slot is checked, to make sure that no other device has already
been defined, for the slot taken by the adapter. The slot is tested
to make sure that the card is actually plugged in.
3). Busresolve is called, to update the customized bus attributes.
Also in this branch, the VPD is read from the adapter. This is done,
because many IBM graphics adapters do not comply with extended VPD
rules. The VPD is required by the device drivers and by the
config methods, and it is even used to select or tailor the
microcode.
Finally, in this branch the device driver defined in the predefined object
is checked and loaded. This is done by calling the "load_dvdr"
routine, then building the DDS structure, then calling the sysconfig
routine to init the device driver, then loading the microcode.
EXECUTION ENVIRONMENT:
This routine executes under the device configuration process and
is called from the device independent configuration routine.
INPUTS:
argc, argv, envp
RETURNS:
On exit, returns an integer error value
*****************************************************************************
********************** FUNCTION HEADER BOTTOM *******************************
*****************************************************************************/
main (int argc,
char **argv,
char **envp)
{
/*----------------------------------------------
|
| DATA DECLARATIONS
|
| all of the data for main are declared as static
| and placed outside of the bounds of "main"
|
|-----------------------------------------------*/
/*-----------------------------------------------
|
| START OF SOURCE CODE
|
|-----------------------------------------------*/
/*----------------------------------------------------------------
| check if environment variable set to install all packages
|----------------------------------------------------------------*/
if ( (!strcmp(getenv("DEV_PKGNAME"),"ALL") )
/* || (DD_Not_Found(driver_name)) */ )
{
DEBUG_0 ("cfg_graphics: install device.graphics \n")
printf(":devices.graphics ");
}
/*----------------------------------------------------------------
| clear the global data and set it up
|----------------------------------------------------------------*/
bzero( (char *) __GLOBAL_DATA_PTR, sizeof( cfg_graphics_data_t ) );
CFGGRAPH_use_dev_vdd = FALSE;
CFGGRAPH_use_ccm_vdd = FALSE;
CFGGRAPH_use_device_ucode = FALSE;
CFGGRAPH_use_ccm_ucode = FALSE;
/*----------------------------------------------------------------
| Initialize the cfg_func pointer in the GLOBAL DATA STRUCTURE
|----------------------------------------------------------------*/
CFGGRAPH_cfg_func = &__GLOBAL_DATA.s_cfg_func;
/*----------------------------------------------------------------------------------------
|
| bbldd is the first driver which creates the special file for the device. Ped,
| wga, sga don't (probably it might in 4.1). Since a function pointer, make_special_file
| has been added to cfg_graphics_funcs structure, and not all drivers initialize this
| pointer in their xx_cfg_load.c except bbldd (bbl_cfg_load.c), we want to initialize
| all functions the function pointers to NULL. Actually, only "make_special_file is
| sufficient but it is not clear. Later before calling "make_special_file" we'll check
| for NULL pointer first!
|
---------------------------------------------------------------------------------------- */
CFG_gen_minor_dev_num(CFGGRAPH_cfg_func) = NULL;
CFG_build_dds(CFGGRAPH_cfg_func) = NULL;
CFG_download_ucode(CFGGRAPH_cfg_func) = NULL;
CFG_query_vpd(CFGGRAPH_cfg_func) = NULL ;
CFG_make_special_file(CFGGRAPH_cfg_func) = NULL;
/*----------------------------------------------------------------
| Preset variables before parsing inputs
|----------------------------------------------------------------*/
ipl_phase = RUNTIME_CFG;
errflg = 0;
logical_name = NULL;
Dflag = FALSE;
/*------------------------------------------------------------------
| process the argc and argv for valid flags
|-----------------------------------------------------------------*/
Check_Input_Parms( argc, argv, envp );
/*-----------------------------------------------------------------
| Inputs are OK. Now we start up the ODM. We also get the
| customized and predefined objects, the parent object, the bus,
| and the dynamic bind object defined in the PdAt cfg_method_load.
| This is used to dynamically load device dependent config method
| routines.
|-----------------------------------------------------------------*/
Open_ODM_and_Get_Objects( );
/*----------------------------------------------------------------
| If this device is being configured during an ipl phase, then
| display this device's LED value on the system LEDs.
|---------------------------------------------------------------*/
if (ipl_phase != RUNTIME_CFG)
{
setleds (s_PdDv_object.led);
}
/*-----------------------------------------------------------------
| Check to see if the device is already configured (AVAILABLE). The
| other possible state is DEFINED (not configured). e actually go
| about the business of configuring the device only if the device is
| not configured yet. Configuring the device in this case refers to
| the process of checking parent status, checking
| for attribute consistency, building a DDS, loading the driver,
| etc...
|-------------------------------------------------------------------*/
if (s_CuDv_object.status == DEFINED)
{
/*-----------------------------------------------------------------
| The device is not available to the system yet. Now check
| to make sure that the device's relations will allow it to
| be configured. In particular, make sure that the parent is
| configured (AVAILABLE), and that no other devices are
| configured at the same location.
|-------------------------------------------------------------------*/
DEBUG_0 ("cfg_graphics: device not available yet\n")
/*----------------------------------------------------------
| make sure that the parent is AVAILABLE
-----------------------------------------------------------*/
if (s_CuDv_parent.status != AVAILABLE)
{
DEBUG_0 ("cfg_graphics: parent is not AVAILABLE")
err_exit (E_PARENTSTATE);
}
/*---------------------------------------------------------
| if this graphics device is a bus adapter make sure that
| no other device is configured at the same location.
| The ODM permits duplicate objects to be defined for the
| same adapter slot
|
| Different types of adapter bus types require different checking
| and preparation.
|
|----------------------------------------------------------*/
if (strncmp( s_PdDv_parent.type,
&mcabus_type[0],
sizeof(mcabus_type)) == 0)
{
DEBUG_0("cfg_graphics: Call Prepare_MCAbus_Type_Device\n")
Prepare_MCAbus_Type_Device( );
}
else if (strncmp( s_PdDv_parent.type,
&sgabus_type[0],
sizeof(sgabus_type)) == 0)
{
/*--------------------------------------------------
| insert code for SGA bus devices here
| and match it to the logic above
|--------------------------------------------------*/
DEBUG_0("cfg_graphics: Call Prepare_SGAbus_Type_Device\n")
Prepare_SGAbus_Type_Device( );
}
else if (strncmp( s_PdDv_parent.type,
buc601_type,
sizeof(buc601_type)) == 0)
{
/*--------------------------------------------------
| 601 Bus device
|--------------------------------------------------*/
DEBUG_0("cfg_graphics: Call Prepare_601bus_Type_Device\n")
Prepare_601bus_Type_Device( );
}
else
{
/*-------------------------------------------------
| error condition -- parent bus type not correct
|-------------------------------------------------*/
DEBUG_0("cfg_graphics: parent.type mismatch\n")
err_exit( E_PARENTSTATE );
}
/*---------------------------------------------------------
| Perform all of the additional generic processing
| that doesn't depend on bus or sys level adapters
|-------------------------------------------------------*/
Prepare_Device( );
/*----------------------------------------------------------
| fall through to here means status == DEFINED
| and the device driver selection is already done
| and recorded in the global data
|
| The next step is to load the bottom half of the configuration
| We use a "replacement of pointers to functions" technique.
| There are standard entry points into the bottom half. We
| either use the ones supplied in the module as the device
| specific ones, or we use the ones supplied by us for the
| common character mode.
|
| THIS IS THE GANG SWITCH BETWEEN DEV AND CCM MODES!
|
|-----------------------------------------------------------*/
if ( CFGGRAPH_use_dev_vdd )
{
/*-------------------------------------------------
| this is the case of FULL FUNCTION vdd and ucode
| load the device dependent config methods
|--------------------------------------------------*/
/*
* NOTE: Don't have to check to see if config method
* exists since we now look for it in PrepareDevice()
* to fix defect #154212.
*/
/*------------------------------------------------------
| Use the load command to dynamically bind the
| object into this runtime environment
|------------------------------------------------------*/
CFGGRAPH_methods_entry_init = load( CFGGRAPH_cfg_methods,
0,
NULL );
if ( CFGGRAPH_methods_entry_init == NULL )
{
DEBUG_0("cfg_graphics: load failed on device dependent congiguration methods\n")
err_exit( E_LOADEXT );
}
/*---- intialize the device dependent configuration
method function pointers ----*/
if (CFGGRAPH_methods_entry(CFGGRAPH_funcs) != 0)
{
DEBUG_0("cfg_graphics: device dependent config method function initialization error\n")
err_exit ( E_SYSTEM );
}
/*---- the device routine will malloc the DDS ----*/
CFGGRAPH_dev_dds = NULL;
CFGGRAPH_dds_length = 0;
/*---- set up the pointer to the dds ----*/
CFGGRAPH_dds_ptr_init = &CFGGRAPH_dev_dds;
/*----- set the global ddname ----*/
(void) strcpy( CFGGRAPH_ddname, CFGGRAPH_dev_dd_name );
/*----- set the global pinned ddname ----*/
(void) strcpy( CFGGRAPH_dd_pin, CFGGRAPH_dev_dd_pin );
}
else if ( CFGGRAPH_use_ccm_vdd )
{
/*-------------------------------------------------
| this is the case of COMMON CHARACTER MODE
| we will need to do more processing than for the
| full function case
|--------------------------------------------------*/
/*---- extract cdd driver from device's ROM ----*/
Prepare_Feature_ROM_Files( );
/*---- copy the function pointers structure ----*/
*CFGGRAPH_cfg_func = *(&(_CCM_FUNCS));
/*---- we have already allocated the ccm DDS ----*/
CFGGRAPH_ccm_dds = &(__GLOBAL_DATA_PTR -> ccm_dds_struc);
CFGGRAPH_dds_length = sizeof( ccm_dds_t );
/*---- set up the pointer to the dds ----*/
CFGGRAPH_dds_ptr_init = (void *) &CFGGRAPH_ccm_dds;
/*----- set the global ddname ----*/
(void) strcpy( CFGGRAPH_ddname, CFGGRAPH_ccm_dd_name );
/*----- set the global ddname ----*/
(void) strcpy( CFGGRAPH_dd_pin, CFGGRAPH_ccm_dd_pin );
/*----- preset the kmids ------*/
CCM_DDS_cdd_ext_kmid( CFGGRAPH_ccm_dds ) = 0;
CCM_DDS_cdd_ext_pin_kmid( CFGGRAPH_ccm_dds ) = 0;
/*--------------------------------------------------
|
| additional processing for the CCM case
| is too verbose to include here, so we call to
| a separate function
|
|--------------------------------------------------*/
Set_Up_CCM_DD_Case( );
/*------------------------------------------------------------
|
| Load the CDD non-pinned kernel extension
| Look for them in the filesystem first, then out on the adapter.
| Use sysconfig() with SYS_KLOAD to load multiple instances
| current versions cannot be depended on for re-entrant
|
| When Set_Up_CCM_DD_Case returns, we know that the
| string held in "path1" is good and points to the CDD module
|
|--------------------------------------------------------------*/
cfg_load.path = path1;
cfg_load.libpath = (char *) NULL;
rc = sysconfig( SYS_KLOAD,
(void *) &cfg_load,
(int) sizeof( struct cfg_load) );
if ( rc != 0 )
{
DEBUG_1 ("cfg_graphics: loadext failed on %s.\n",
CFGGRAPH_cdd_name )
err_exit (E_LOADEXT);
}
CCM_DDS_cdd_kmid( CFGGRAPH_ccm_dds ) = cfg_load.kmid;
/*------------------------------------------------------------
|
| Load the CDD pinned kernel extension
| Look for them in the filesystem first, then out on the adapter.
| Use sysconfig() with SYS_KLOAD to load multiple instances
| current versions cannot be depended on for re-entrant
|
|-------------------------------------------------------------*/
memset (path1, '\0', sizeof(path1));
/*-----------------------------------------
| Check to see if optional cdd_pin is indicated
| If there is a name, then either ODM told us the name
| or FRS found a file.
|------------------------------------------*/
if ( 0 != ( strcmp ( CFGGRAPH_cdd_pin , "" ) ) )
{
/*----------------------------------------------
| convert to full path if not already
|-----------------------------------------------*/
if ( ( strncmp( "./", CFGGRAPH_cdd_pin, 2 ))
&& ( strncmp( "../", CFGGRAPH_cdd_pin, 3 ))
&& ( CFGGRAPH_cdd_pin[ 0 ] != '/' ) )
{
(void) strcat( ( strcpy( path1, "/usr/lib/drivers/") ),
CFGGRAPH_cdd_pin );
}
else
{
strcpy( path1, CFGGRAPH_cdd_pin );
}
/*----------------------------------------------
| make sure that the file is really there
| We need to do this in case ODM lied to us
|----------------------------------------------*/
if ( DD_Not_Found ( CFGGRAPH_cdd_pin ) )
{
memset (path1, '\0', sizeof(path1));
}
}
/*-----------------------------------------------
| fall through to here whether or not there was a name
| So, we test the name again
| If we have a good name, we know that it has been
| validated, and we load it
|----------------------------------------------*/
if ( 0 != strcmp ( path1, "" ) )
{
cfg_load.path = path1;
cfg_load.libpath = (char *) NULL;
rc = sysconfig( SYS_KLOAD,
(void *) &cfg_load,
(int) sizeof( struct cfg_load) );
if ( rc != 0 )
{
DEBUG_1 ("cfg_graphics: loadext failed on %s.\n",
CFGGRAPH_cdd_pin )
err_exit (E_LOADEXT);
}
CCM_DDS_cdd_pin_kmid( CFGGRAPH_ccm_dds ) = cfg_load.kmid;
}
/*-------------------------------------------------------
| Fall through to here means we loaded the option cdd_pin
| if it was present. Now process the CCM DD PIN case
|--------------------------------------------------------*/
if ( 0 != strcmp( "", CFGGRAPH_ccm_dd_pin ) )
{
/*-------------------------------------------------------
| If the ccmdd has a valid interrupt handler, then
| Load the dd pin code as an AIX kernel extension
|------------------------------------------------------*/
strcat( (strcpy( path1, "/usr/lib/drivers/")),
CFGGRAPH_ccm_dd_pin);
cfg_load.path = path1;
cfg_load.libpath = (char *) NULL;
rc = sysconfig( SYS_KLOAD,
(void *) &cfg_load,
(int) sizeof( struct cfg_load) );
if ( rc != 0 )
{
DEBUG_1 ("cfg_graphics: loadext failed on %s.\n",
CFGGRAPH_ccm_dd_pin )
err_undo_kmods ();
err_exit (E_LOADEXT);
}
CCM_DDS_ccmdd_pin_kmid(CFGGRAPH_ccm_dds) = cfg_load.kmid;
}
}
else
{
DEBUG_0("cfg_graphics: cfg_func selection error!\n")
err_exit ( E_SYSTEM );
}
/*------------------------------------------------------------
|
| Load the device driver as an AIX kernel extension
| If the device driver has a seperate pinned (interrupt) handler
| the dd is responsible for loading the pinned part itself.
|
|-------------------------------------------------------------*/
if ( CFGGRAPH_use_dev_vdd ) { sysconfig_cmd = SYS_SINGLELOAD; }
else { sysconfig_cmd = SYS_KLOAD; }
( void ) strcat( (strcpy( path1, "/usr/lib/drivers/")), ( CFGGRAPH_ddname ) );
cfg_load.path = path1;
cfg_load.libpath = (char *) NULL;
rc = sysconfig( sysconfig_cmd,
(void *) &cfg_load,
(int) sizeof( struct cfg_load) );
if ( rc != 0 )
{
DEBUG_1 ("cfg_graphics: loadext failed on %s.\n",
CFGGRAPH_ddname )
err_undo_kmods ();
err_exit (E_LOADEXT);
}
cfg_dd.kmid = cfg_load.kmid;
if ( cfg_dd.kmid == NULL )
{
DEBUG_1 ("cfg_graphics: loadext NULL kmid on %s.\n",
CFGGRAPH_ddname )
err_undo_kmods ();
err_exit (E_LOADEXT);
}
if ( CFGGRAPH_use_ccm_vdd )
{
CCM_DDS_ccmdd_kmid(CFGGRAPH_ccm_dds) = cfg_dd.kmid;
}
/*-------------------------------------------------------
|
| Generate the major device number
|
|-------------------------------------------------------*/
/*
major_num = genmajor( CFGGRAPH_ddname );
*/
major_num = genmajor( CFGGRAPH_dev_dd_name );
if ( major_num == -1 )
{
DEBUG_0("cfg_graphics: bad major_num.\n")
err_undo_kmods ();
err_exit( E_MAJORNO );
}
DEBUG_1("cfg_graphics: major_num is %d.\n", major_num )
/*-------------------------------------------------------
|
| Generate the minor device number
|
|-------------------------------------------------------*/
minor_list = getminor( major_num,
&how_many,
logical_name );
if ( ( minor_list == NULL )
|| ( how_many == 0 ) )
{
/*----------------------------------------------
| No minors were found by system, need to make
| one up in this config method
|----------------------------------------------*/
DEBUG_0("cfg_graphics: calling generate_minor.\n")
rc = CFGGRAPH_gen_minor_dev_num( logical_name,
major_num,
&minor_num );
if ( rc != E_OK )
{
DEBUG_1("cfg_graphics: minor_num error rc=%d.\n",
rc )
reldevno( logical_name, TRUE );
err_undo_kmods ();
if ( ( rc < 0 )
|| ( rc > 255 ) )
{ err_exit( E_MINORNO ); }
else
{ err_exit( rc ); }
}
}
else
{
/*------------------------------------------------
| use the minor number supplied by the system
|------------------------------------------------*/
minor_num = *minor_list;
}
DEBUG_1("cfg_graphics: minor_num is %d.\n", minor_num )
/*----------------------------------------------------------
|
| There are no special files for graphics, so we do not call
| a "make_special_files" entry point
|
| No longer true! bbldd creates special file now. We
| only do that when loading the full function driver but not cdd
|
|-----------------------------------------------------------*/
/*------------------------------------------------------------
|
| build the "define device structure"
|
|------------------------------------------------------------*/
rc = CFGGRAPH_build_dds( logical_name,
CFGGRAPH_dds_ptr_init,
&CFGGRAPH_dds_length );
if ( rc != E_OK )
{
DEBUG_1("cfg_graphics: error on build dds rc=%d.\n",rc)
err_undo_kmods ();
if ( ( rc < 0 )
|| ( rc > 255 ) )
{ err_exit( E_DDS ); }
else
{ err_exit( rc ); }
}
cfg_dd.ddsptr = CFGGRAPH_dds;
cfg_dd.ddslen = CFGGRAPH_dds_length;
/*-----------------------------------------------------------
|
| save the device number
|
|------------------------------------------------------------*/
device_num = makedev( major_num , minor_num );
cfg_dd.devno = device_num;
if ( CFGGRAPH_use_ccm_vdd )
{
CCM_DDS_device_num( ((ccm_dds_t *)CFGGRAPH_dds) ) = device_num;
}
/*-----------------------------------------------------------
|
| call sysconfig to send the define device structure
| to the already loaded device driver. This call
| invokes the entry point of the device driver, which is
| the config entry point. This is typically the first
| time program control is passed into the device driver.
|
| The command cause the config entry point of the device
| driver to take the "CFG_INIT" case.
|
|-----------------------------------------------------------*/
cfg_dd.cmd = CFG_INIT;
rc = sysconfig ( SYS_CFGDD,
&cfg_dd,
sizeof (struct cfg_dd) );
if (rc != E_OK )
{
if ( p1 != NULL)
{
free(p1); /* Free the ddf memory */
}
DEBUG_0 ("cfg_graphics: error configuring device\n")
err_undo_kmods ();
err_exit (E_CFGINIT);
}
/*----------------------------------------------------------
|
| query the vpd from the adapter IF:
| the PdDv claims it supports VPD and
| it is not a neptune (GXT150M) in CCM mode.
|
|----------------------------------------------------------*/
DEBUG_0 ("cfg_graphics: Checking for vpd\n")
DEBUG_1("cfg_graphics: logical_name = %s\n", logical_name) ;
DEBUG_1("cfg_graphics: length = %d\n", strlen(logical_name)) ;
if ( (s_PdDv_object.has_vpd == TRUE)
&& ! ( (CFGGRAPH_use_ccm_vdd)
&& (strncmp(logical_name, "nep",
(strlen(logical_name)-1)) == 0) )
)
{
DEBUG_0("cfg_graphics: Call Proc_Dev_Customized_VPD\n");
Process_Device_Customized_VPD( );
}
/*----------------------------------------------------------
|
| download the microcode into the adapter
|
|---------------------------------------------------------*/
DEBUG_0 ("cfg_graphics: Calling download_microcode()\n")
rc = CFGGRAPH_download_ucode(logical_name);
if ( rc != E_OK )
{
DEBUG_1 ("cfg_graphics: download ucode, rc=%d\n", rc)
err_undo_kmods ();
if ( ( rc < 0 )
|| ( rc > 255 ) )
{ err_exit( E_UCODE ); }
else
{ err_exit( rc ); }
}
DEBUG_0 ("cfg_graphics: Returned from download_microcode()\n")
/*----------------------------------------------------------
|
| device object can now be marked as AVAILABLE
| update customized device object with a change operation
|
|-----------------------------------------------------------*/
s_CuDv_object.status = AVAILABLE;
strcpy(s_CuDv_object.ddins, CFGGRAPH_dev_dd_name);
rc = odm_change_obj( p_Class_CuDv,
&s_CuDv_object );
if ( rc == FAIL)
{
DEBUG_0 ("cfg_graphics: ODM failure updating CuDv object\n")
err_undo_kmods ();
err_exit (E_ODMUPDATE);
}
} /* end if (device is DEFINED) */
/*--------------------------------------------------------------------
|
| When we get here, the device either already was AVAILABLE or we
| just made it AVAILABLE without any errors
|
|-------------------------------------------------------------------*/
/*
* DON'T make special file when running ccm/cdd mode or driver
* which does not supply one (i.e. its xx_cfg_load.c does not
* initialize the make_special_file field of the structure.
*/
if ( CFG_make_special_file(CFGGRAPH_funcs) != NULL ) /* 601_CHANGE */
{
DEBUG_0 ("cfg_graphics: make special file\n")
rc = CFGGRAPH_make_special_file(logical_name,device_num);
}
else
{
DEBUG_0 ("cfg_graphics: not calling make_special file\n")
}
/*--------------------------------------------------------------------
| this is where one would call the device specific routine to
| manage and configure child devices. (This routine is
| unnecesary given the present design of the VDD and config
| methods. It is kept for future compatibility issues)
|-------------------------------------------------------------------*/
/*-------------------------------------------------------------------
| Free memory and unload the modules loaded earlier
--------------------------------------------------------------------*/
if ( p1 != NULL)
{
free(p1); /* Free the ddf memory */
}
if ( p_video_head != NULL)
{
free(p_video_head); /* Free the FRS allocated memory */
}
if ( CDD_procs( CFGGRAPH_cdd)->entry_point != NULL )
{
rc = unload(CDD_procs( CFGGRAPH_cdd)->entry_point);
if ( rc == FAIL )
{
DEBUG_0 ("cfg_graphics: unload of cdd failed")
}
}
if ( CFGGRAPH_methods_entry_init != NULL )
{
rc = unload(CFGGRAPH_methods_entry_init);
if ( rc == FAIL )
{
DEBUG_0 ("cfg_graphics: unload of methods load module failed")
}
}
/*--------------------------------------------------------------------
| Close the customized and predefined object classes and terminate
| the ODM
|-------------------------------------------------------------------*/
rc = odm_close_class( p_Class_PdDv );
if ( rc == FAIL )
{
DEBUG_0 ("cfg_graphics: close object class PdDv failed")
err_undo_kmods ();
err_exit (E_ODMCLOSE);
}
rc = odm_close_class( p_Class_CuDv );
if ( rc == FAIL )
{
DEBUG_0 ("cfg_graphics: close object class CuDv failed")
err_undo_kmods ();
err_exit (E_ODMCLOSE);
}
rc = odm_close_class( p_Class_PdAt );
if ( rc == FAIL )
{
DEBUG_0 ("cfg_graphics: close object class PdAt failed")
err_undo_kmods ();
err_exit (E_ODMCLOSE);
}
rc = odm_close_class( p_Class_CuAt );
if ( rc == FAIL )
{
DEBUG_0 ("cfg_graphics: error closing CuAt object class\n")
err_undo_kmods ();
err_exit (E_ODMCLOSE);
}
odm_unlock(lock_id);
odm_terminate( );
unlink_tmp_files( );
exit (0);
}