/*
 *	STS_UNITTAB.C
 */

#include "sts_unittab.h"

#ifndef lint
static char unittab_sccsid[] = "@(#)sts_unittab.c	1.42 02/03/98 Copyright (C) 1990-1998 Digi International Inc.";
#endif

/*
 * ctunitinfo
 *
 * Table of device info for each supported unit.
 */
static ctunitinfo ctunittab[] = {
  /* name		#lines	max_pkt	ppci		special func */
  { "ST-1000",		16,	2048,	PCC_16_0_57600,		SFC_STD },
  { "ST-1000/ST-1016",	16,	2048,	PCC_16_0_57600,		SFC_STD },
  { "ST-1000/SC-1016",	16,	2048,	PCC_16_0_57600,		SFC_STD },
  { "ST-1016G",		16,	4096,	PCC_16_0_115200,	SFC_STD },
  { "ST-1616",		16,	4096,	PCC_16_0_115200,	SFC_STD },
  { "ST-1616B",		16,	4096,	PCC_16_0_230400,	SFC_NO_SPLIT },
  { "ST-1000/ST-1616",	16,	4096,	PCC_16_0_115200,	SFC_STD },
  { "ST-1000/ST-1616B",	16,	4096,	PCC_16_0_230400,	SFC_NO_SPLIT },
  { "ST-1002",		3,	2048,	PCC_2_1_57600,		SFC_NO_SPLIT },
  { "ST-1002/ST-1002F",	3,	2048,	PCC_2_1_115200,		SFC_NO_SPLIT },
  { "ST-1002G",		3,	2048,	PCC_2_1_115200,		SFC_STD },
  { "ST-1002S",		3,	4096,	PCC_2_1_230400,		SFC_NO_SPLIT },
  { "SP-1003",		3,	4096,	PCC_0_3_57600,		SFC_1003 },
  { "ST-1008",		9,	2048,	PCC_8_1_57600,		SFC_STD },
  { "ST-1008G",		9,	2048,	PCC_8_1_115200,		SFC_STD },
  { "ST-1008S",		9,	4096,	PCC_8_1_230400,		SFC_NO_SPLIT },
  { "ST-1400A",		4,	2048,	PCC_4_0_115200,		SFC_STD },
  { "ST-1400B",		4,	4096,	PCC_4_0_230400,		SFC_NO_SPLIT },
  { "ST-1620",		16,	4096,	PCC_16_0_230400,	SFC_NO_SPLIT },
  { "ST-1622",		16,	4096,	PCC_16_0_115200,	SFC_NO_SPLIT },
  { "ST-1800A",		8,	2048,	PCC_8_0_115200,		SFC_STD },
  { "ST-1800A+",	9,	2048,	PCC_8_1_115200,		SFC_STD },
  { "ST-1800B",		8,	4096,	PCC_8_0_230400,		SFC_NO_SPLIT },
  { "ST-1800B+",	9,	4096,	PCC_8_1_230400,		SFC_NO_SPLIT },
  { "ST-1008/ST-1400",	4,	2048,	PCC_4_0_115200,		SFC_STD },
  { "ST-1000/Sx-1600",	16,	4096,	PCC_16_0_115200,	SFC_STD },
  { "ST-1000/ST-1600",	16,	4096,	PCC_16_0_115200,	SFC_STD },
  { "ST-1000/SC-1600",	16,	4096,	PCC_16_0_115200,	SFC_STD },
  { "ST-1008/ST-1800",	8,	2048,	PCC_8_0_115200,		SFC_STD },
  { "ST-1008/ST-1800P",	9,	2048,	PCC_8_1_115200,		SFC_STD },
  { "ST-1000/ST-1610",	16,	4096,	PCC_16_0_115200,	SFC_STD },
  { "ST-1008/SM-5008",	8,	2048,	PCC_8_0_115200,		SFC_NO_SPLIT },
  { "ST-1000/SM-5016",	16,	4096,	PCC_16_0_115200,	SFC_NO_SPLIT },
  { "ST-1008/ST-8008",	9,	2048,	PCC_8_1_57600,		SFC_STD },
  { "ST-1008G/ST-8008",	9,	2048,	PCC_8_1_115200,		SFC_STD },
  { "ST-2001/Sx-2001",	126,	4096,	PCC_2001_57600,		SFC_2000 },
  { "ST-2001/ST-2126",	126,	4096,	PCC_2126_115200,	SFC_STD },
  { "Sx-4032",		32,	2048,	PCC_32_0_57600,		SFC_STD },
  { "ST-1032",		32,	4096,	PCC_32_0_115200,	SFC_STD },
  { "ST-1032A",		32,	4096,	PCC_32_0_230400,	SFC_NO_SPLIT },
  /* EtherLite(R) Units */
  { "EL-2",		2,	2048,PCC_2_0_230400,(SFC_ETH | SFC_NO_SPLIT) },
  { "EL-2.1",		2,	2048,PCC_2_0_230400,(SFC_ETH | SFC_NO_SPLIT) },
  { "EL-2.2",		2,	2048,PCC_2_0_230400,(SFC_ETH | SFC_NO_SPLIT) },
  { "EL-2-EIA485",	2,	2048,PCC_2_0_230400,(SFC_ETH | SFC_NO_SPLIT) },
  { "EL-8",		8,	2048,	PCC_8_0_115200,		SFC_ETH },
  { "EL-8+",		9,	2048,	PCC_8_1_115200,		SFC_ETH },
  { "EL-16",		16,	2048,	PCC_16_0_115200,	SFC_ETH },
  { "EL-16A",		16,	2048,	PCC_16_0_230400,	(SFC_ETH | SFC_NO_SPLIT)},
  { "EL-16H",		16,	2048,	PCC_16_0_115200,	SFC_ETH },
  { "EL-32",		32,	2048,	PCC_32_0_115200,	SFC_ETH },
  { "EL-32A",		32,	2048,	PCC_32_0_230400,(SFC_ETH | SFC_NO_SPLIT) },
  { "EM-8",		8,	2048,	PCC_8_0_115200,		SFC_ETH },
  { "EM-16",		16,	2048,	PCC_16_0_115200,	SFC_ETH },
  { "EL-16E1",		16,	2048,PCC_16_0_115200,(SFC_ETH | SFC_MILSPEC) },
  { "EL-160",		16,	2048,PCC_16_0_230400,(SFC_ETH | SFC_NO_SPLIT)},
  { "EL-160-VP",        32,	2048,PCC_16_0_115200,(SFC_ETH | SFC_NO_SPLIT)},
  { "EL-162",		16,	2048,PCC_16_0_115200,(SFC_ETH | SFC_NO_SPLIT)},

  /* Motorola Units */
  { "STS-S8P",		8,	2048,	PCC_8_0_57600,		SFC_STD },
  { "STS-S16P",		16,	2048,	PCC_16_0_57600,		SFC_STD },

  /* PCI entries */
#ifdef PCI
  {"PCI-4", 		4, 	-1,PCC_4_0_115200,SFC_PCI | SFC_NO_SPLIT},
  {"PCI-8", 		8,	-1,PCC_8_0_115200,SFC_PCI | SFC_NO_SPLIT},
#endif

  { NULL }
};

/*
 *	ctm_get_unitinfo
 *	
 *	Returns pointer to unitinfo if a match is found against the
 *	name string.  Accepts a non-null terminated space padded name
 *	such as is returned in inquiry data.  Also handles null terminated
 *	ones.
 *
 *	Returns pointer to unitinfo record is a match is found, null if
 *	no matching unit
 */
ctunitinfo *
ctm_get_unitinfo( name )
	char *name;
{
  int i;
  char name_string[17];
  ctunitinfo *uinfo;
	
  /* copy name til null or space or tab */
  for(i = 0; i < 16 && name[i] != 0 && name[i] != ' ' && name[i] != 0x9; i++)
    name_string[i] = name[i];
  /* make sure null terminated */
  name_string[i] = 0;
	
  /* make sure non-zero length */
  if(i == 0)
    return( NULL );
	
  /* scan unittab for a match */
  for(i = 0; ctunittab[i].name != NULL; i++) {
    uinfo = &ctunittab[i];
    if(strcmp( name_string, uinfo->name ) == 0)
      return( uinfo );
  }
	
  /* fell thru, no match found */
  return( NULL );
}


/*
 *	ctf_port_type
 *	
 *	Returns code indicating type of hardware available at specific
 *
 *	profile is used to determine hardware type.	 That must be fetched
 *	from the unitinfo structure for the product.
 *
 *	See 'sts_unittab.h' for possible return values.
 */
int
ctf_port_type( uinfo, port_num )
	ctunitinfo *uinfo;
	int port_num;
{

  /* decode "personality" type */
  switch( PCC_MATCH(uinfo->port_cap_code) ) {
		
  case PCC_32_0:
    if( port_num >= 0 && port_num < 32 )
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    break;
		
  case PCC_16_0:
    if( port_num >= 0 && port_num < 16 ) 
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    break;
		
		
  case PCC_8_1:
    if( port_num >= 0 && port_num < 8 )
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    if( port_num == 8 )
      return( PT_STD_PARALLEL );
    break;
		
  case PCC_8_0:
    if( port_num >= 0 && port_num < 8 )
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    break;
		
  case PCC_4_0:
    if( port_num >= 0 && port_num < 4 )
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    break;
		
  case PCC_2_0:
    if( port_num == 0 || port_num == 1)
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    break;

  case PCC_2_1:
    if( port_num == 0 || port_num == 1)
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    if( port_num == 2 )
      return( PT_STD_PARALLEL );
    break;

  case PCC_2001:
    if( port_num < 0 || port_num >= STS_MAX_LINES_PER_UNIT )
      break;
    port_num %= 18;
    if( port_num == 8 )
      return( PT_STD_PARALLEL );
    if( port_num < 8 )
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    break;
		
  case PCC_2126:
    if( port_num >= 0 && port_num < STS_MAX_LINES_PER_UNIT )
      return( (PT_SERIAL | PCC_SPEED(uinfo->port_cap_code)) );
    break;
		
  case PCC_0_3:				/* SP-1003 3 parallel one fast */
    if( port_num == 0 || port_num == 2 )
      return( PT_STD_PARALLEL );
    if( port_num == 1 )
      return( PT_FAST_PARALLEL );
    break;
		

  default:
    break;
  }
	
  return( PT_NODEV );
}


/*
 *	ctf_check_baud
 *
 *	
 *	Checks for supported FAS baud code.	 Returns OK if
 *	baud rate is supported, !OK if illegal.
 */
int
ctf_check_baud( uinfo, port_num, fascode )
	ctunitinfo *uinfo;
	int port_num;
	int fascode;
{
  switch( ctf_port_type( uinfo, port_num ) )
    {
    case PT_57600_SERIAL:
      if((fascode > FAS57600) || fascode == FASNOBAUD)
	return( !OK );
      break;
			
    case PT_115200_SERIAL:
      if((fascode > FAS115200)  || fascode == FASNOBAUD)
	return( !OK );
      break;

    case PT_230400_SERIAL:
      if((fascode > FAS230400)  || fascode == FASNOBAUD)
	return( !OK );
      break;

    case PT_460800_SERIAL:
      if((fascode > FAS460800)  || fascode == FASNOBAUD)
	return( !OK );
      break;
			
    case PT_STD_PARALLEL:
    case PT_FAST_PARALLEL:
      break;
			
    case PT_NODEV:
      return( !OK );
    default:
      return( !OK );
    }
  return( OK );
}
