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

431 lines
16 KiB
C

#ifndef lint
static char sccsid[] = "@(#)13 1.4 src/bos/usr/lib/methods/cfgasync/utility.c, cfgtty, bos41J, 9520A_all 4/27/95 12:49:41";
#endif
/*
* COMPONENT_NAME: (CFGTTY) VPD functions for adapter config
*
* FUNCTIONS: check_pos2, define_children, chk_lion, query_vpd
*
* ORIGINS: 83
*
*/
/*
* LEVEL 1, 5 Years Bull Confidential Information
*/
#include <stdio.h> /* standard I/O */
#include <stdlib.h> /* standard C library */
#include <sys/types.h> /* standard typedef */
#include <cf.h> /* error messages */
#include <errno.h> /* standard error numbers */
#include <string.h>
#include <sys/cfgdb.h> /* config #define */
#include <sys/sysmacros.h>
#include <sys/sysconfig.h>
#include <sys/device.h>
#include <sys/cfgodm.h> /* config structures */
#include <sys/mdio.h>
#include "cfgdebug.h"
#include "ttycfg.h"
/*
* ==============================================================================
* defines and strutures
* ==============================================================================
*/
/* defines for attributes search */
/* These defines MUST be in coherence with ODM database attribute names */
#define AUTOCONFIG_ATT "autoconfig"
/*
* =============================================================================
* LOCAL UTILITY ROUTINES
* =============================================================================
*/
/*
* -----------------------------------------------------------------------------
* CHECK_POS2
* -----------------------------------------------------------------------------
* Check pos reg 2 for 64 port problem
*
* This routine implement the check of pos reg 2 on a 64
* port to determine if it has the bus memory problem.
* This check is performed by writing 0 to POS 2 and
* then reading it back.
*
* Return code: Exits with 0 on success, ODM error code otherwise.
* -----------------------------------------------------------------------------
*/
static int check_pos2(cusDev, value, busDev)
struct CuDv * cusDev;
uchar * value;
struct CuDv * busDev;
{
int return_code;
int file_desc; /* File descriptor for bus */
uchar pos_reg; /* Pos register */
char sstring[50];
/* ODM structures declarations */
struct Class * cus_dev_class; /* customized devices class ptr */
MACH_DD_IO mdd; /* mach dd ioctl struct for POS access */
/* open customized devices object class (CuDv) */
if ((int)(cus_dev_class = odm_open_class(CuDv_CLASS)) == -1) {
DEBUG_0("check_pos2: CuDv open class error\n");
return(E_ODMOPEN);
};
/* ================================================= */
/* Must get the bus this card is attached to */
/* ================================================= */
if (return_code = Get_Parent_Bus(cus_dev_class, cusDev->parent, busDev)) {
DEBUG_1("check_pos2: Error getting parent bus, return code = %d\n",
return_code);
return(return_code);
};
/* If adapter is directly on the bus, use machdd to write */
/* and read tp POS registers */
if (!strcmp(cusDev->parent, busDev->name)) {
DEBUG_1("check_pos2: Card is directly on %s\n", busDev->name);
sprintf(sstring, "/dev/%s", busDev->name);
if ((file_desc = open(sstring, O_RDWR)) < 0) {
DEBUG_1("check_pos2: open of %s failed\n", sstring);
return(E_BUSRESOURCE);
}
else {
mdd.md_size = 1 ;
mdd.md_incr = MV_BYTE ;
mdd.md_data = &pos_reg;
mdd.md_addr = (POSREG(2, atoi(cusDev->connwhere) - 1)) ;
pos_reg = 0 ;
if (ioctl(file_desc, MIOCCPUT, &mdd) < 0) {
DEBUG_0("check_pos2: write to POS_2 failed\n");
return(E_BUSRESOURCE);
};
if (ioctl(file_desc, MIOCCGET, &mdd) < 0) {
DEBUG_0("check_pos2: read to POS_2 failed\n");
return(E_BUSRESOURCE);
};
/* Get the POS data back */
DEBUG_1("check_pos2: POS reg 2 = 0x%02x\n", pos_reg);
*value = pos_reg;
} /* End if ((file_desc = open(...)) < 0) */
};
if (close(file_desc) < 0) {
DEBUG_1("check_pos2: close of %s failed\n", sstring);
};
/* That's OK */
return(E_OK);
} /* End static int check_pos2(...) */
/*
* =============================================================================
* FUNCTIONS USED BY CONFIGURATION METHOD
* =============================================================================
*
* All these functions are used for adapters configuration
*
* =============================================================================
*/
/*
* -----------------------------------------------------------------------------
* DEFINE_CHILDREN
* -----------------------------------------------------------------------------
* This fucntion detects and manages children of the asynchronous
* adapters.
*
* Children that need to be configured are detected by an
* autoconfig attribute value of "available".
* All children to be configured are returned via stdout to the
* configuration manager which in turn will eventually invoke the
* configure method for these child devices.
*
* Return code: Exits with 0 on success, ODM error code otherwise.
* -----------------------------------------------------------------------------
*/
int define_children(logical_name,phase)
char * logical_name; /* logical name of parent device */
int phase; /* IPL or runtime flag */
{
int return_code;
int odm_search; /* flag for used in getting objects */
char auto_config[ATTRVALSIZE]; /* auto config value */
char sstring[256]; /* search criteria */
/* ODM structures declarations */
struct Class * cus_dev_class; /* customized devices class ptr */
struct Class * cus_att_class; /* customized attribute class ptr */
struct Class * pre_att_class; /* predefined attribute class ptr */
struct CuDv cus_dev; /* customized device object storage */
/* open customized devices object class (CuDv) */
if ((int)(cus_dev_class = odm_open_class(CuDv_CLASS)) == -1) {
DEBUG_0("define_children: CuDv open class error\n");
return(E_ODMOPEN);
};
/* open customized devices attribute class (CuAt) */
if ((int)(cus_att_class = odm_open_class(CuAt_CLASS)) == -1) {
DEBUG_0("define_children: CuAt open class error\n");
return(E_ODMOPEN);
};
/* open predifined devices attribute class (PdAt) */
if ((int)(pre_att_class = odm_open_class(PdAt_CLASS)) == -1) {
DEBUG_0("define_children: PdAt open class error\n");
return(E_ODMOPEN);
};
/* ===================================== */
/* Loop until no more children are found */
/* ===================================== */
/* Search for customized object with parent = device */
sprintf(sstring, "parent = '%s'", logical_name);
odm_search = ODM_FIRST;
while ((return_code =
(int)odm_get_obj(cus_dev_class, sstring, &cus_dev, odm_search)) > 0) {
DEBUG_1("define_children: found child %s\n", cus_dev.name);
odm_search = ODM_NEXT;
/* If child is to be 'autoconfigured' */
auto_config[0] = '\0';
if (return_code = getatt(auto_config, 's', cus_att_class, pre_att_class,
cus_dev.name, cus_dev.PdDvLn_Lvalue,
AUTOCONFIG_ATT, NULL)) {
DEBUG_3("define_children: getatt '%s' for %s fails with error %x\n",
AUTOCONFIG_ATT, cus_dev.name, return_code);
return(return_code);
};
if (!strcmp(auto_config, "available")) {
fprintf(stdout, "%s\n", cus_dev.name);
};
} /* End while ((return_code = (int)odm_get_obj(...))) */
/* Check for error */
if (return_code) {
DEBUG_1("define_children: odm_get_obj fails for %s\n", sstring);
};
/* close object classes */
if (odm_close_class(cus_dev_class) < 0) {
return(E_ODMCLOSE);
};
if (odm_close_class(pre_att_class) < 0) {
return(E_ODMCLOSE);
};
if (odm_close_class(cus_att_class) < 0) {
return(E_ODMCLOSE);
};
/* That's OK */
return(E_OK);
} /* End int define_children(...) */
/*
* -----------------------------------------------------------------------------
* chk_lion
* -----------------------------------------------------------------------------
* This function checks for conflicts in 64 ports card.
*
* Nothing is done in ODM database.
*
* Return code: Exits with 0 on success, ODM error code otherwise.
* -----------------------------------------------------------------------------
*/
int chk_lion(cusObjPtr, kmid, devno)
struct CuDv * cusObjPtr; /* Customized Device object pointer */
mid_t kmid; /* Kernel module I.D. for Dev Driver */
dev_t devno; /* Concatenated Major & Minor No.s */
{
int return_code;
uchar pos_reg; /* Pos register */
char sstring[128]; /* string for searches */
/* ODM structures declarations */
struct CuDv bus_obj; /* customized devices class ptr */
struct CuDv *adp_list; /* CuDv ptr for adapter list */
struct listinfo adp_lst_info; /* ODM list info for adaptr list*/
/* ========================================== */
/* The following definition is to allocate */
/* space for the 64 port table required */
/* by routines in the cfgchk_64p.c unit. */
/* The format of the area is irrelevant to */
/* this funciton, but space must be provided */
/* by this function. This approach was taken */
/* for expedency in resolving defect 43992. */
/* I know it is not the best way to do it. */
/* ========================================== */
char p64_tbl[128];
/* ============================== */
/* set up initial variable values */
/* ============================== */
return_code = 0;
/* ============================================================ */
/* In order to handle a 64 port problem of ingoring the high */
/* order 8 bits of the 32 bit bus memory address, the following */
/* has been implemented to check for conflicts. The checks */
/* are only done if the card is a 64 port. */
/* ============================================================ */
if (!strcmp(cusObjPtr->PdDvLn_Lvalue, "adapter/mca/64p232")) {
DEBUG_1("chk_lion: card (%s) is a 64 port adapter\n", cusObjPtr->name);
if (return_code = check_pos2(cusObjPtr, &pos_reg, &bus_obj)) {
DEBUG_1("chk_lion: error from check_pos2 = %d\n", return_code);
}
else {
if ((pos_reg & 0x20) == 0) {
DEBUG_0("chk_lion: Card is BAD\n");
/* Card is BAD. Must know get a list of */
/* all adapters currently in this bus and */
/* check for conflicts between this 64 */
/* port and each of the other adapters. */
sprintf(sstring, "parent=%s and chgstatus!=%d and chgstatus!=%d",
bus_obj.name, MISSING, DONT_CARE);
/* Expected number of objects to be returned set to 8 */
/* Number of level to recurse for objects with ODM_LINK */
/* descriptors is set to 1 (only the top level) */
adp_list = odm_get_list(CuDv_CLASS, sstring,
&adp_lst_info, 8, 1);
if ((int)adp_list != -1) {
DEBUG_1("chk_lion: got adp_list, count = %d\n",
adp_lst_info.num);
bld_64p_tbl(cusObjPtr, 1, &p64_tbl);
if (chk_adapters(adp_list, adp_lst_info.num,
&p64_tbl, 1, sstring)) {
DEBUG_0("chk_lion: CONFLICTS found!!\n");
return_code = E_BUSRESOURCE;
}
else {
DEBUG_0("chk_lion: No conflicts\n");
} /* End if (chk_adapters(...)) */
odm_free_list(adp_list, &adp_lst_info);
}
else {
DEBUG_0("chk_lion: ODM error getting adpater list\n");
return_code = E_ODMGET;
} /* End if ((int)adp_list != -1) */
}; /* End if ((pos_reg & 0x20) == 0) */
} /* End if (return_code = check_pos2(...)) */
}; /* End if (!strcmp(...)) */
return(return_code);
} /* End int chk_lion(...) */
/*
* -----------------------------------------------------------------------------
* query_vpd
* -----------------------------------------------------------------------------
*
* This function extracts the adapters VPD data from the POS registers
* via the bus.
*
* Return code: Exits with 0 on success, ODM error code otherwise.
* -----------------------------------------------------------------------------
*/
int query_vpd(cusDev,ret_vpd)
struct CuDv * cusDev; /* Customized Device object pointer */
char *ret_vpd; /* return vpd buffer */
{
MACH_DD_IO read_record, /* machdd ioctl access struct, for */
write_record; /* POS access */
int rc;
int fd;
int len;
int vpd_index;
char vpd_data[256];
uchar tmpbyte;
char devname[32];
/* ODM structures declarations */
struct Class * cus_dev_class; /* customized devices class ptr */
struct CuDv busDev; /* Bus Device object */
/* open customized devices object class (CuDv) */
if ((int)(cus_dev_class = odm_open_class(CuDv_CLASS)) == -1) {
DEBUG_0("check_pos2: CuDv open class error\n");
return(E_ODMOPEN);
};
/* ================================================= */
/* Must get the bus this card is attached to */
/* ================================================= */
DEBUG_1("query_vpd: cusDev->parent= %s\n", cusDev->parent);
DEBUG_1("query_vpd: cusDev->name= %s\n", cusDev->name);
DEBUG_1("query_vpd: cusDev->name= %s\n", cusDev->connwhere);
if (rc = Get_Parent_Bus(cus_dev_class, cusDev->parent, &busDev)) {
DEBUG_1("query_vpd: Error getting parent bus, return code = %d\n", rc);
return(rc);
};
/* build bus's dev name */
sprintf(devname, "/dev/%s" ,busDev.name);
if((fd = open( devname, O_RDWR )) < 0 ){
return(E_OPEN);
};
/* write 0x01 - 0xFF to pos reg 6 */
/* read related vpd byte back from pos reg 3 */
write_record.md_size = 1; /* write 1 byte */
write_record.md_incr = MV_BYTE;
write_record.md_data = &tmpbyte;
write_record.md_addr = (POSREG(6, atoi(cusDev->connwhere) - 1)) ;
read_record.md_size = 1; /* Transfer 1 byte */
read_record.md_incr = MV_BYTE;
read_record.md_data = &tmpbyte;
read_record.md_addr = (POSREG(3, atoi(cusDev->connwhere) - 1)) ;
for (vpd_index = 0x01; vpd_index <= 0xFF; vpd_index++) {
tmpbyte = (uchar)vpd_index;
/* write to pos reg 6 */
if( ioctl( fd, MIOCCPUT, &write_record ) < 0 ) {
close(fd);
return (E_VPD);
}
/* read from pos reg 3 */
if( ioctl( fd, MIOCCGET, &read_record ) < 0 ) {
close(fd);
return (E_VPD);
}
vpd_data[vpd_index-1] = tmpbyte;
}
close(fd);
#if 0
#ifdef CFGDEBUG
dump_dds(vpd_data,VPDSIZE * 4);
#endif CFGDEBUG
#endif
put_vpd (ret_vpd, vpd_data, VPDSIZE-1 );
return(0);
}