Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 05 Aug 1999 15:14:21 +0200
From:      Thierry Herbelot <thierry.herbelot@alcatel.fr>
To:        Mike Spengler <mks@networkcs.com>
Cc:        atm@freebsd.org, harp@magic.net
Subject:   fore_dnld
Message-ID:  <37A98E2D.D015F6CD@alcatel.fr>
References:  <199908041857.NAA45021@us.networkcs.com>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------9989C7D3BEBE615C2248EBCE
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

hello,

we have investigated the download problem, with another PC and a
cooked-up program, which gives verbose error messages (see enclosed
fore_dnld.c), and a slightly modified /etc/rc.atm.

the enclosed dmesg.atm is an extract of the messages printed on the
console when the machine is booting up. (dmesg.boot being the full dmesg
- giving all peripherals in the machine).

To sum up : 
- we still do not succeed in loading the fore microcode in a PCA200e on
a CompaQ PC when /sbin/fore_dnld is called in /etc/rc.atm at startup.
- the same is happening on an old P5-75 from HP
- we **generally** can load the microcode by invoking two times
/sbin/fore_dnld -d /etc "by hand", after the machine is up and running.

	TfH

PS : the microcode file we use has the following size :
-rw-r--r--  1 root  wheel  40984 Aug  3 18:13 pca200e.bin
PS2 : we are obviously open to running any new version of fore_dnld,
with more debugging features
PS3 : this is under FreeBSD 3.2-Release
--------------9989C7D3BEBE615C2248EBCE
Content-Type: text/plain; charset=us-ascii;
 name="fore_dnld.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="fore_dnld.c"

/*
 *
 * ===================================
 * HARP  |  Host ATM Research Platform
 * ===================================
 *
 *
 * This Host ATM Research Platform ("HARP") file (the "Software") is
 * made available by Network Computing Services, Inc. ("NetworkCS")
 * "AS IS".  NetworkCS does not provide maintenance, improvements or
 * support of any kind.
 *
 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
 * In no event shall NetworkCS be responsible for any damages, including
 * but not limited to consequential damages, arising from or relating to
 * any use of the Software or related support.
 *
 * Copyright 1994-1998 Network Computing Services, Inc.
 *
 * Copies of this Software may be made, however, the above copyright
 * notice must be reproduced on all copies.
 *
 *	@(#) $Id: fore_dnld.c,v 1.2 1998/10/30 16:17:43 dg Exp $
 *
 */

/*
 * User utilities
 * --------------
 *
 * Download (pre)processed microcode into Fore Series-200 host adapter
 * Interact with i960 uart on Fore Series-200 host adapter
 *
 */

#ifndef lint
static char *RCSid = "@(#) $Id: fore_dnld.c,v 1.2 1998/10/30 16:17:43 dg Exp $";
#endif

#include <sys/types.h>
#include <sys/param.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/stat.h>
#include <netatm/atm.h>
#include <netatm/atm_if.h>
#include <netatm/atm_sap.h>
#include <netatm/atm_sys.h>
#include <netatm/atm_ioctl.h>

#include <dev/hfa/fore.h>
#include <dev/hfa/fore_aali.h>
#include <dev/hfa/fore_slave.h>

#if (defined(BSD) && (BSD >= 199103))
#include <termios.h>
#else
#include <termio.h>
#endif	/* !BSD */

#ifdef sun
#define	DEV_NAME "/dev/sbus%d"
#endif	/* sun */
#if (defined(BSD) && (BSD >= 199103))
#define	DEV_NAME "/dev/kmem"
#endif	/* BSD */

#define	MAX_CHECK	60

int	comm_mode = 0;
char	*progname;

int	tty;
cc_t	vmin, vtime;
#if (defined(BSD) && (BSD >= 199103))
struct termios sgtty;
#define	TCSETA	TIOCSETA
#define	TCGETA	TIOCGETA
#else
struct termio sgtty;
#endif	/* !BSD */

int	endian = 0;
int	verbose = 0;
int	reset = 0;

char	line[132];
int	lineptr = 0;

Mon960 *Uart;

delay(cnt)
	int	cnt;
{
	usleep(cnt);
}

unsigned long
CP_READ ( val )
unsigned long val;
{
	if ( endian )
		return ( ntohl ( val ) );
	else
		return ( val );
}

unsigned long
CP_WRITE ( val )
unsigned long val;
{
	if ( endian )
		return ( htonl ( val ) );
	else
		return ( val );
}

/*
 * Print an error message and exit.
 *
 * Arguments:
 *	none
 *
 * Returns:
 *	none
 */
void
error ( msg )
char *msg;
{
	printf ( "%s\n", msg );
	exit (1);
}

/*
 * Get a byte for the uart and if printing, display it.
 *
 * Arguments:
 *	prn				Are we displaying characters
 *
 * Returns:
 *	c				Character from uart
 */
char
getbyte ( prn )
int prn;
{
	int	c;

	while ( ! ( CP_READ(Uart->mon_xmithost) & UART_VALID ) )
		delay(10);

	c = ( CP_READ(Uart->mon_xmithost) & UART_DATAMASK );
	Uart->mon_xmithost = CP_WRITE(UART_READY);

	/*
	 * We need to introduce a delay in here or things tend to hang...
	 */
	delay(10);

	if ( lineptr >= sizeof(line) )
		lineptr = 0;

	/*
	 * Save character into line
	 */
	line[lineptr++] = c;

	if (verbose) {
		if (isprint(c) || (c == '\n') || (c == '\r'))
			putc(c, stdout);
	}
	return ( c & 0xff );
}

/*
 * Loop getting characters from uart into static string until eol. If printing,
 * display the line retrieved.
 *
 * Arguments:
 *	prn				Are we displaying characters
 *
 * Returns:
 *	none				Line in global string 'line[]'
 */
void
getline ( prn )
int prn;
{
	char	c = '\0';
	int	i = 0;

	while ( c != '>' && c != '\n' && c != '\r' )
	{
		c = getbyte(0);
		if ( ++i >= sizeof(line) )
		{
			if ( prn )
				printf ( "%s", line );
			i = 0;
		}
	}

	/*
	 * Terminate line
	 */
	line[lineptr] = 0;
	lineptr = 0;

}

/*
 * Send a byte to the i960
 *
 * Arguments:
 *	c				Character to send
 *
 * Returns:
 *	none
 */
void
xmit_byte ( c, dn )
unsigned char c;
int dn;
{
	int	val;

	while ( CP_READ(Uart->mon_xmitmon) != UART_READY )
	{
		if ( CP_READ(Uart->mon_xmithost) & UART_VALID )
			getbyte ( 0 );
		if ( !dn ) delay ( 1000 );
	}
	val = ( c | UART_VALID );
	Uart->mon_xmitmon = CP_WRITE( val );

}

/*
 * Transmit a line to the i960. Eol must be included as part of text to transmit.
 *
 * Arguments:
 *	line			Character string to transmit
 *	len			len of string. This allows us to include NULL's
 *					in the string/block to be transmitted.
 *
 * Returns:
 *	none
 */
xmit_to_i960 ( line, len, dn )
char *line;
int len;
int dn;
{
	int	i;

        for ( i = 0; i < len; i++ )
		xmit_byte ( line[i], dn );
}

/*
 * Send autobaud sequence to i960 monitor
 *
 * Arguments:
 *	none
 *
 * Returns:
 *	none
 */
void
autobaud()
{
	if ( strncmp ( line, "Mon960", 6 ) == 0 )
		xmit_to_i960 ( "\r\n\r\n\r\n\r\n", 8, 0 );
}

/*
 * Reset tty to initial state
 *
 * Arguments:
 *	ret		error code for exit()
 *
 * Returns:
 *	none
 *
 */
void
finish ( ret )
{
	sgtty.c_lflag |= ( ICANON | ECHO );
	sgtty.c_cc[VMIN] = vmin;
	sgtty.c_cc[VTIME] = vtime;
	ioctl ( tty, TCSETA, &sgtty );
	exit ( ret );
}

/*
 * Utility to strip off any leading path information from a filename
 *
 * Arguments:
 *	path		pathname to strip
 *
 * Returns:
 *	fname		striped filename
 *
 */
char *
basename ( path )
	char *path;
{
	char *fname;

	if ( ( fname = strrchr ( path, '/' ) ) != NULL )
		fname++;
	else
		fname = path;

	return ( fname );
}

/*
 * ASCII constants
 */
#define		SOH		001
#define		STX		002
#define		ETX		003
#define		EOT		004
#define		ENQ		005
#define		ACK		006
#define		LF		012
#define		CR		015
#define		NAK		025
#define		SYN		026
#define		CAN		030
#define		ESC		033

#define		NAKMAX		2
#define		ERRORMAX	10
#define		RETRYMAX	5

#define		CRCCHR		'C'
#define		CTRLZ		032

#define		BUFSIZE		128

#define		W		16
#define		B		8

/*
 * crctab - CRC-16 constant array...
 *     from Usenet contribution by Mark G. Mendel, Network Systems Corp.
 *     (ihnp4!umn-cs!hyper!mark)
 */
unsigned short crctab[1<<B] = {
    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
    };

/*
 * Hacked up xmodem protocol. Transmits the file 'filename' down to the i960
 * using the xmodem protocol.
 *
 * Arguments:
 *	filename			name of file to transmit
 *
 * Returns:
 *	0				file transmitted
 *	-1				unable to send file
 */
int
xmitfile ( filename )
char *filename;
{
	int	fd;
	int	numsect;
	int	sectnum;
	struct stat stb;
	char	c;
	char	sendresp;
	int	crcmode = 0;
	int	attempts = 0;
	int	errors;
	int	sendfin;
	int	extrachr;
	char	buf[BUFSIZE + 6];
	char	blockbuf[BUFSIZE + 6];
	int	bufcntr;
	int	bbufcntr;
	int	bufsize = BUFSIZE;
	int	checksum;

	/*
	 * Try opening file
	 */
	if ( ( fd = open ( filename, O_RDONLY ) ) < 0 )
	{
		return -1;
	}
	stat ( filename, &stb );

	/*
	 * Determine number of 128 bytes sectors to transmit
	 */
	numsect = ( stb.st_size / 128 ) + 1;

	if ( verbose )
		fprintf ( stderr, "Downloading %d sectors from %s\n",
			numsect, filename );

	/*
	 * Send DO'wnload' command to i960
	 */
	xmit_to_i960 ( "do\r\n", 4, 0 );
	/*
	 * Wait for response from i960 indicating download in progress
	 */
	while ( strncmp ( line, "Downloading", 11 ) != 0 )
		getline ( verbose );
	

	/*
	 * Get startup character from i960
	 */
	do {
		while ( ( c = getbyte(0) ) != NAK && c != CRCCHR )
			if ( ++attempts > NAKMAX )
				error ( "Remote system not responding" );

		if ( c == CRCCHR )
			crcmode = 1;

	} while ( c != NAK && c != CRCCHR );

	sectnum = 1;
	attempts = errors = sendfin = extrachr = 0;

	/*
	 * Loop over each sector to be sent
	 */
	do {
		if ( extrachr >= 128 )
		{
			extrachr = 0;
			numsect++;
		}

		if ( sectnum > 0 )
		{
			/*
			 * Read a sectors worth of data from the file into
			 * an internal buffer.
			 */
			for ( bufcntr = 0; bufcntr < bufsize; )
			{
				int n;
				/*
				 * Check for EOF
				 */
				if ( ( n = read ( fd, &c, 1 ) ) == 0 )
				{
					sendfin = 1;
					if ( !bufcntr )
						break;
					buf[bufcntr++] = CTRLZ;
					continue;
				}
				buf[bufcntr++] = c;
			}
			if ( !bufcntr )
				break;
		}

		/*
		 * Fill in xmodem protocol values. Block size and sector number
		 */
		bbufcntr = 0;
		blockbuf[bbufcntr++] = (bufsize == 1024) ? STX : SOH;
		blockbuf[bbufcntr++] = sectnum;
		blockbuf[bbufcntr++] = ~sectnum;

		checksum = 0;

		/*
		 * Loop over the internal buffer computing the checksum of the
		 * sector
		 */
		for ( bufcntr = 0; bufcntr < bufsize; bufcntr++ )
		{
			blockbuf[bbufcntr++] = buf[bufcntr];

			if ( crcmode )
				checksum = (checksum<<B) ^ crctab[(checksum>>(W-B)) ^ buf[bufcntr]];
			else
				checksum = ((checksum + buf[bufcntr]) & 0xff);

		}

		/*
		 * Place the checksum at the end of the transmit buffer
		 */
		if ( crcmode )
		{
			checksum &= 0xffff;
			blockbuf[bbufcntr++] = ((checksum >> 8) & 0xff);
			blockbuf[bbufcntr++] = (checksum & 0xff);
		} else
			blockbuf[bbufcntr++] = checksum;

		attempts = 0;

		/*
		 * Make several attempts to send the data to the i960
		 */
		do
		{
			/*
			 * Transmit the sector + protocol to the i960
			 */
			xmit_to_i960 ( blockbuf, bbufcntr, 1 );

			/*
			 * Inform user where we're at
			 */
			if ( verbose )
				printf ( "Sector %3d %3dk\r",
				    sectnum, (sectnum * bufsize) / 1024 );

			attempts++;
			/*
			 * Get response from i960
			 */
			sendresp = getbyte(0);

			/*
			 * If i960 didn't like the sector
			 */
			if ( sendresp != ACK )
			{
				errors++;

				/*
				 * Are we supposed to cancel the transfer?
				 */
				if ( ( sendresp & 0x7f ) == CAN )
					if ( getbyte(0) == CAN )
						error ( "Send canceled at user's request" );
			}

		} while ( ( sendresp != ACK ) && ( attempts < RETRYMAX ) && ( errors < ERRORMAX ) );

		/*
		 * Next sector
		 */
		sectnum++;

	} while ( !sendfin && ( attempts < RETRYMAX ) && ( errors < ERRORMAX ) );

	/*
	 * Did we expire all our allows attempts?
	 */
	if ( attempts >= RETRYMAX )
	{
		xmit_byte ( CAN, 1 ), xmit_byte ( CAN, 1 ), xmit_byte ( CAN, 1 );
		error ( "Remote system not responding" );
	}

	/*
	 * Check for too many transmission errors
	 */
	if ( errors >= ERRORMAX )
	{
		xmit_byte ( CAN, 1 ), xmit_byte ( CAN, 1 ), xmit_byte ( CAN, 1 );
		error ( "Too many errors in transmission" );
	}

	attempts = 0;

	/*
	 * Indicate the transfer is complete
	 */
	xmit_byte ( EOT, 1 );

	/*
	 * Wait until i960 acknowledges us
	 */
	while ( ( c = getbyte(0) ) != ACK && ( ++attempts < RETRYMAX ) )
		xmit_byte ( EOT, 1 );

	if ( attempts >= RETRYMAX )
		error ( "Remote system not responding on completion" );

	/*
	 * After download, we'll see a few more command 
	 * prompts as the CP does its stuff. Ignore them.
	 */
	while ( strncmp ( line, "=>", 2 ) != 0 )
		getline ( verbose );

	while ( strncmp ( line, "=>", 2 ) != 0 )
		getline ( verbose );

	while ( strncmp ( line, "=>", 2 ) != 0 )
		getline ( verbose );

	/*
	 * Tell the i960 to start executing the downloaded code
	 */
	xmit_to_i960 ( "go\r\n", 4, 0 );

	/*
	 * Get the messages the CP will spit out
	 * after the GO command.
	 */
	getline ( verbose );
	getline ( verbose );

	close ( fd );

	return ( 0 );
}


int
sendbinfile ( fname, ram )
char *fname;
u_char *ram;
{
	struct {
		u_long	Id;
		u_long	fver;
		u_long	start;
		u_long	entry;
	} binhdr;
	union {
		u_long	w;
		char	c[4];
	} w1, w2;
	int	fd;
	int	n;
	int	cnt = 0;
	u_char	*bufp;
	long	buffer[1024];

	/*
	 * Try opening file
	 */
	if ( ( fd = open ( fname, O_RDONLY ) ) < 0 )
		return ( -1 );

	/*
	 * Read the .bin header from the file
	 */
	if ( ( read ( fd, &binhdr, sizeof(binhdr) ) ) != sizeof(binhdr) )
	{
		close ( fd );
		return ( -1 );
	}

	/*
	 * Check that we understand this header
	 */
	if ( strncmp ( (caddr_t)&binhdr.Id, "fore", 4 ) != 0 ) {
		fprintf ( stderr, "Unrecognized format in micorcode file." );
		close ( fd );
		return ( -1 );
	}

#ifdef	sun
	/*
	 * We always swap the SunOS microcode file...
	 */
	endian = 1;

	/*
	 * We need to swap the header start/entry words...
	 */
	w1.w = binhdr.start;
	for ( n = 0; n < sizeof(u_long); n++ )
		w2.c[3-n] = w1.c[n];
	binhdr.start = w2.w;
	w1.w = binhdr.entry;
	for ( n = 0; n < sizeof(u_long); n++ )
		w2.c[3-n] = w1.c[n];
	binhdr.entry = w2.w;
#endif	/* sun */

	/*
	 * Rewind the file
	 */
	lseek ( fd, 0, 0 );

	/*
	 * Set pointer to RAM load location
	 */
	bufp = (ram + binhdr.start);

	/*
	 * Load file
	 */
	if ( endian ) {
		/*
		 * Need to swap longs - copy file into temp buffer
		 */
		while ( ( n = read ( fd, (char *)buffer, sizeof(buffer))) > 0 )
		{
			int	i;

			/* Swap buffer */
			for ( i = 0; i < sizeof(buffer) / sizeof(long); i++ )
#ifndef	sun
				buffer[i] = CP_WRITE(buffer[i]);
#else
			{
				int	j;

				w1.w = buffer[i];
				for ( j = 0; j < 4; j++ )
					w2.c[3-j] = w1.c[j];
				buffer[i] = w2.w;
			}
#endif

			/*
			 * Copy swapped buffer into CP RAM
			 */
			cnt++;
			bcopy ( (caddr_t)buffer, bufp, n );
			if ( verbose )
				printf ( "%d\r", cnt );
			bufp += n;
		}
	} else {
	    while ( ( n = read ( fd, bufp, 128 ) ) > 0 )
	    {
		cnt++;
		if ( verbose )
			printf ( "%d\r", cnt );
		bufp += n;
	    }
	}

	/*
	 * With .bin extension, we need to specify start address on 'go'
	 * command.
	 */
	{
		char	cmd[80];
		char	c;

		sprintf ( cmd, "go %x\r\n", binhdr.entry );

		xmit_to_i960 ( cmd, strlen ( cmd ), 0 );

		while ( strncmp ( line, cmd, strlen(cmd) - 3 ) != 0 )
			getline ( verbose );

		if ( verbose )
			printf("\n");
	}

	close ( fd );
	return ( 0 );
}


/*
 * Program to download previously processed microcode to series-200 host adapter
 */
main( argc, argv )
int argc;
char *argv[];
{
	int	fd;			/* mmap for Uart */
	u_char	*ram;			/* pointer to RAM */
	Mon960	*Mon;			/* Uart */
	Aali	*aap;
	char	c;
	int	i, err;
	int	binary = 0;		/* Send binary file */
	caddr_t	buf;			/* Ioctl buffer */
	Atm_config *adp;		/* Adapter config */
	char	bus_dev[80];		/* Bus device to mmap on */
	struct atminfreq req;
	struct air_cfg_rsp *air;	/* Config info response structure */
	int	buf_len;		/* Size of ioctl buffer */
	char	*devname = "\0";	/* Device to download */
	char	*dirname = NULL;	/* Directory path to objd files */
	char	*objfile = NULL;	/* Command line object filename */
	char	*sndfile;		/* Object filename to download */
	char	filename[64];		/* Constructed object filename */
	char	base[64];		/* sba200/sba200e/pca200e basename */
	int	ext = 0;		/* 0 == bin 1 == objd */
	struct stat sbuf;		/* Used to find if .bin or .objd */
	extern char *optarg;

	progname = (char *)basename(argv[0]);
	comm_mode = strcmp ( progname, "fore_comm" ) == 0;

	while ( ( c = getopt ( argc, argv, "i:d:f:berv" ) ) != EOF )
	    switch ( c ) {
		case 'b':
			binary++;
			break;
		case 'd':
			dirname = (char *)strdup ( optarg );
			break;
		case 'e':
			endian++;
			break;
		case 'i':
			devname = (char *)strdup ( optarg );
			break;
		case 'f':
			objfile = (char *)strdup ( optarg );
			break;
		case 'v':
			verbose++;
			break;
		case 'r':
			reset++;
			break;
		case '?':
			printf ( "usage: %s [-v] [-i intf] [-d dirname] [-f objfile]\n", argv[0] );
			exit ( 2 );
	    }
	
	/*
	 * Unbuffer stdout
	 */
	setbuf ( stdout, NULL );
		
	if ( ( fd = socket ( AF_ATM, SOCK_DGRAM, 0 ) ) < 0 )
	{
		perror ( "Cannot create ATM socket" );
		exit ( 1 );
	}
	/*
	 * Over allocate memory for returned data. This allows
	 * space for IOCTL reply info as well as config info.
	 */
	buf_len = 4 * sizeof(struct air_cfg_rsp);
	if ( ( buf = (caddr_t)malloc(buf_len) ) == NULL )
	{
		perror ( "Cannot allocate memory for reply" );
		exit ( 1 );
	}
	/*
	 * Fill in request paramaters
	 */
	req.air_opcode = AIOCS_INF_CFG;
	req.air_buf_addr = buf;
	req.air_buf_len = buf_len;

	/*
	 * Copy interface name into ioctl request
	 */
	strcpy ( req.air_cfg_intf, devname );

	/*
	 * Issue ioctl
	 */
	if ( ( ioctl ( fd, AIOCINFO, (caddr_t)&req ) ) ) {
		perror ( "ioctl (AIOCSINFO)" );
		exit ( 1 );
	}
	/*
	 * Reset buffer pointer
	 */
	req.air_buf_addr = buf;

	/*
	 * Close socket
	 */
	close ( fd );

	/*
	 * Loop through all attached adapters
	 */
	for (; req.air_buf_len >= sizeof(struct air_cfg_rsp); 
			buf += sizeof(struct air_cfg_rsp),
			req.air_buf_len -= sizeof(struct air_cfg_rsp)) {

		/*
		 * Point to vendor info
		 */
		air = (struct air_cfg_rsp *)buf;

		if (air->acp_vendor == VENDOR_FORE )
		{
			/*
			 * Create /dev name
			 */
			sprintf ( bus_dev, DEV_NAME, air->acp_busslot );

			/*
			 * Setup signal handlers
			 */
			signal ( SIGINT, SIG_IGN );
			signal ( SIGQUIT, SIG_IGN );
		
			/*
			 * If comm_mode, setup terminal for single char I/O
			 */
			if ( comm_mode ) {
				tty = open ( "/dev/tty", O_RDWR );
				ioctl ( tty, TCGETA, &sgtty );
				sgtty.c_lflag &= ~( ICANON | ECHO );
				vmin = sgtty.c_cc[VMIN];
				vtime = sgtty.c_cc[VTIME];
				sgtty.c_cc[VMIN] = 0;
				sgtty.c_cc[VTIME] = 0;
				ioctl ( tty, TCSETA, &sgtty );
			}

			/*
			 * Open bus for memory access
			 */
			if ( ( fd = open ( bus_dev, O_RDWR ) ) < 0 )
			{
				perror ( "open bus_dev" );
				fprintf(stderr, "%s download failed (%s)\n",
					air->acp_intf, bus_dev);
				continue;
			}

			/*
			 * Map in the RAM memory to get access to the Uart
			 */
#ifdef __FreeBSD__ /*XXX*/
			ram = (u_char *) mmap(0, PCA200E_MMAP_SIZE,
#else
			ram = (u_char *) mmap(0, air->acp_ramsize,
#endif
				PROT_READ | PROT_WRITE, MAP_SHARED,
				fd, air->acp_ram);
			if (ram == (u_char *)-1) {
				perror ( "mmap ram" );
				fprintf(stderr, "%s download failed\n",
					air->acp_intf);
				(void) close(fd);
				continue;
			}
			Mon = (Mon960 *)(ram + MON960_BASE);
			Uart = (Mon960 *)&(Mon->mon_xmitmon);

			/*
			 * Determine endianess
			 */
			switch ( Mon->mon_bstat ) {
			case BOOT_COLDSTART:
			case BOOT_MONREADY:
			case BOOT_FAILTEST:
			case BOOT_RUNNING:
				break;

			default:
				switch (ntohl(Mon->mon_bstat)) {
				case BOOT_COLDSTART:
				case BOOT_MONREADY:
				case BOOT_FAILTEST:
				case BOOT_RUNNING:
					endian++;
					break;

				default:
					fprintf(stderr, "%s unknown status\n",
						air->acp_intf);
					(void) close(fd);
					continue;
				}
				break;
			}

#ifdef __FreeBSD__
			if (reset) {
				u_int	*hcr = (u_int *)(ram + PCA200E_HCR_OFFSET);

				if ( verbose )
					printf( "fore_dnld: reset\n" );

				PCA200E_HCR_INIT(*hcr, PCA200E_RESET_BD);
				delay(10000);
				PCA200E_HCR_CLR(*hcr, PCA200E_RESET_BD);
				delay(10000);
			}
#endif

			if ( comm_mode ) {
			    static struct timeval timeout = { 0, 0 };
			    int	esc_seen = 0;

			    /*
			     * We want to talk with the i960 monitor
			     */

			    /*
			     * Loop forever accepting characters
			     */
			    for ( ; ; ) {
				fd_set	fdr;
				int	ns;

				/*
				 * Check for data from the terminal
				 */
				FD_ZERO ( &fdr );
				FD_SET ( fileno(stdin), &fdr );

				if ( ( ns = select ( FD_SETSIZE, &fdr, NULL, NULL,
					&timeout ) ) < 0 ) {
						perror ( "select" );
						finish( -1 );
				}

				if ( ns ) {
					int	c;
					int	nr;

					nr = read ( fileno(stdin), &c, 1 );
					c &= 0xff;
					if ( !esc_seen ) {
					    if ( c == 27 )
						esc_seen++;
					    else
						xmit_byte ( c, 0 );
					} else {
					    if ( c == 27 ) 
						finish( -1 );
					    else {
						xmit_byte ( 27, 0 );
						esc_seen = 0;
					    }
					    xmit_byte ( c, 0 );
					}
				}

				/*
				 * Check for data from the i960
				 */
				if ( CP_READ(Uart->mon_xmithost) & UART_VALID ) {
					c = getbyte(0);
					putchar ( c );
				}
				if ( strcmp ( line, "Mon960" )  == 0 )
					autobaud();

			    }
			} else {
			    /*
			     * Make sure the driver is loaded and that the CP
			     * is ready for commands
			     */
			    if ( CP_READ(Mon->mon_bstat) == BOOT_RUNNING )
			    {
				fprintf ( stderr, 
				"%s is up and running - no download allowed.\n",
					air->acp_intf );
				(void) close(fd);
				continue;
			    }
		
			    if ( CP_READ(Mon->mon_bstat) != BOOT_MONREADY )
			    {
				fprintf ( stderr, 
					"%s is not ready for downloading.\n", 
					air->acp_intf );
				(void) close(fd);
				continue;
			    }
		
			    /*
			     * Indicate who we're downloading
			     */
			    if ( verbose )
				printf ( "Downloading code for %s\n",
					air->acp_intf );

			    /*
			     * Look for the i960 monitor message. 
			     * We should see this after a board reset.
			     */
			    if ( verbose ) {
				printf( "fore_dnld: Look for the i960 monitor message\n" );
				printf( "           We should see this after a board reset\n" );
			    }
 
			    while ( strncmp ( line, "Mon960", 6 ) != 0 && 
				strncmp ( line, "=>", 2 ) != 0 )
				getline( verbose );	/* Verbose */
		
			    /*
			     * Autobaud fakery
			     */
			    if ( verbose )
				printf( "fore_dnld: Autobaud fakery\n" );

			    if ( strncmp ( line, "Mon960", 6 ) == 0 ) {
				xmit_to_i960 ( "\r\n\r\n\r\n\r\n", 8, 0 );
				delay ( 10000 );
			    }

			    /*
			     * Keep reading until we get a command prompt
			     */
			    if ( verbose )
				printf( "fore_dnld: Keep reading until we get a command prompt\n" );

			    while ( strncmp ( line, "=>", 2 ) != 0 )
				getline( verbose );	/* Verbose */

			    /*
			     * Choose the correct microcode file based on the
			     * adapter type the card claims to be.
			     */
			    switch ( air->acp_device )
			    {
			    case DEV_FORE_SBA200:
				sprintf ( base, "sba200" );
				break;

			    case DEV_FORE_SBA200E:
				sprintf ( base, "sba200e" );
				break;

			    case DEV_FORE_PCA200E:
				sprintf ( base, "pca200e" );
				break;
 
			    default:
				err = 1;
				fprintf(stderr, "Unknown adapter type: %d\n", 
					air->acp_device );
			    }

			    sndfile = NULL;

			    if ( objfile == NULL ) {
				switch ( air->acp_device ) {
				case DEV_FORE_SBA200:
				case DEV_FORE_SBA200E:
				    sprintf ( filename, "%s.bin%d", base,
					air->acp_bustype );
				    if ( stat ( filename, &sbuf ) == -1 ) {
					sprintf ( filename, "%s/%s.bin%d",
					    dirname, base,
						air->acp_bustype );
					if ( stat ( filename, &sbuf ) == -1 ) {
					    ext = 1;
					    sprintf ( filename, "%s.objd%d",
						base, air->acp_bustype );
					    if ( stat(filename, &sbuf) == -1 ) {
						sprintf ( filename,
						    "%s/%s.objd%d", dirname,
							base,
							    air->acp_bustype );
						if ( stat ( filename, &sbuf ) != -1 )
						    sndfile = filename;
					    } else
						sndfile = filename;
					} else
					    sndfile = filename;
				    } else
					sndfile = filename;
				    break;
				case DEV_FORE_PCA200E:
				    sprintf ( filename, "%s.bin", base );
				    if ( stat ( filename, &sbuf ) == -1 ) {
					sprintf ( filename, "%s/%s.bin",
					    dirname, base );
					if ( stat ( filename, &sbuf ) != -1 ) {
						sndfile = filename;
					}
				    } else
					sndfile = filename;
				    break;
			        }
			    } else
				sndfile = objfile;

			    if ( ext && !binary )
				err = xmitfile ( sndfile );
			    else
				err = sendbinfile ( sndfile, ram );

			    if ( err ) {
				fprintf(stderr, "%s download failed\n",
					air->acp_intf);
				(void) close(fd);
				continue;
			    }

			    /*
			     * Download completed - wait around a while for
			     * the driver to initialize the adapter
			     */
			     aap = (Aali *)(ram + CP_READ(Mon->mon_appl));
			     for (i = 0; i < MAX_CHECK; i++, sleep(1)) {
				u_long	hb1, hb2;

				if (CP_READ(Mon->mon_bstat) != BOOT_RUNNING)
					continue;

				hb1 = CP_READ(aap->aali_heartbeat);
				delay(1);
				hb2 = CP_READ(aap->aali_heartbeat);
				if (hb1 < hb2)
					break;
			     }
			}

			close ( fd );
		}
	}

	/*
	 * Exit
	 */
	exit (0);

}


--------------9989C7D3BEBE615C2248EBCE
Content-Type: text/plain; charset=us-ascii;
 name="rc.atm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="rc.atm"

#!/bin/sh
#

# ATM networking startup script
#
#	$Id: rc.atm,v 1.2 1998/10/08 08:56:01 phk Exp $

#
# Initial interface configuration.
# N.B. /usr is not mounted.
#
atm_pass1() {
    # Locate all probed ATM adapters
    atmdev=`atm sh stat int | while read dev junk; do
	case ${dev} in
	hea[0-9]|hea[0-9][0-9])
		echo "${dev} "
		;;
	hfa[0-9]|hfa[0-9][0-9])
		echo "${dev} "
		;;
	*)
		continue
		;;
	esac
    done`

    if [ -z "${atmdev}" ]; then
	echo "No ATM adapters found."
	return 0
    fi

    # Load microcode into FORE adapters (if needed)
    if [ `expr "${atmdev}" : '.*hfa.*'` -ne 0 ]; then
	echo "${atmdev}"
	echo "Download fore microcode"
	#/sbin/fore_dnld -v -i hfa0 -f /etc/pca200e.bin
	/sbin/fore_dnld -v -r
	/sbin/fore_dnld -v -d /etc &
    fi

    # Configure physical interfaces
    ilmid=0
    for phy in ${atmdev}; do
	echo -n "Configuring ATM device ${phy}:"

	# Define network interfaces
	eval netif_args=\$atm_netif_${phy}
	if [ -n "${netif_args}" ]; then
		atm set netif ${phy} ${netif_args} || continue
	else
		echo "missing network interface definition"
		continue
	fi

	# Override physical MAC address
	eval macaddr_args=\$atm_macaddr_${phy}
	if [ -n "${macaddr_args}" -a "${macaddr_args}" != "NO" ]; then
		atm set mac ${phy} ${macaddr_args} || continue
	fi

	# Configure signalling manager
	eval sigmgr_args=\$atm_sigmgr_${phy}
	if [ -n "${sigmgr_args}" ]; then
		atm attach ${phy} ${sigmgr_args} || continue
	else
		echo "missing signalling manager definition"
		continue
	fi

	# Configure UNI NSAP prefix
	eval prefix_args=\$atm_prefix_${phy}
	if [ `expr "${sigmgr_args}" : '[uU][nN][iI].*'` -ne 0 ]; then
		if [ -z "${prefix_args}" ]; then
			echo "missing NSAP prefix for UNI interface"
			continue
		fi
		if [ "${prefix_args}" = "ILMI" ]; then
			ilmid=1
		else
			atm set prefix ${phy} ${prefix_args} || continue
		fi
	fi

	atm_phy="${atm_phy} ${phy}"
	echo "."
    done

    echo -n "Starting initial ATM daemons:"
    # Start ILMI daemon (if needed)
    if [ ${ilmid} -eq 1 ]; then
	echo -n " ilmid"
	ilmid
    fi

    echo "."
    atm_pass1_done=YES
}

#
# Finish up configuration.
# N.B. /usr is not mounted.
#
atm_pass2() {
    echo -n "Configuring ATM network interfaces:"

    atm_scspd=0
    atm_atmarpd=""

    # Configure network interfaces
    for phy in ${atm_phy}; do
	eval netif_args=\$atm_netif_${phy}
	set -- ${netif_args}
	netname=$1
	netcnt=$2
	netindx=0
	while [ ${netindx} -lt ${netcnt} ]; do

		net="${netname}${netindx}"
		netindx=`expr ${netindx} + 1`
		echo -n " ${net}"

		# Configure atmarp server
		eval atmarp_args=\$atm_arpserver_${net}
		if [ -n "${atmarp_args}" ]; then
			atm set arpserver ${net} ${atmarp_args} || continue
		fi
		eval scsparp_args=\$atm_scsparp_${net}
		if [ "X${scsparp_args}" = X"YES" ]; then
			if [ "${atmarp_args}" != "local" ]; then
				echo "local arpserver required for SCSP"
				continue
			fi
			atm_atmarpd="${atm_atmarpd} ${net}"
			atm_scspd=1
		fi
	done
    done
    echo "."

    # Define any PVCs.
    if [ "X${atm_pvcs}" != "X" ]; then
	for i in ${atm_pvcs}; do
		eval pvc_args=\$atm_pvc_${i}
		atm add pvc ${pvc_args}
	done
    fi

    # Define any permanent ARP entries.
    if [ "X${atm_arps}" != "X" ]; then
	for i in ${atm_arps}; do
		eval arp_args=\$atm_arp_${i}
		atm add arp ${arp_args}
	done
    fi
    atm_pass2_done=YES
}

#
# Start any necessary daemons.
#
atm_pass3() {
    # Start SCSP daemon (if needed)
    if [ ${atm_scspd} -eq 1 ]; then
	echo -n " scspd"
	scspd
    fi

    # Start ATMARP daemon (if needed)
    if [ -n "${atm_atmarpd}" ]; then
	echo -n " atmarpd"
	atmarpd ${atm_atmarpd}
    fi

    atm_pass3_done=YES
}

--------------9989C7D3BEBE615C2248EBCE
Content-Type: text/plain; charset=us-ascii;
 name="dmesg.atm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="dmesg.atm"

Doing initial network setup: hostname.
hfa0
Download fore microcode
fore_dnld: reset
Downloading code for hfa0
fore_dnld: Look for the i960 monitor message
           We should see this after a board reset

fore_dnld: Autobaud fakery

fore_dnld: Keep reading until we get a command prompt

Mon960 monitor for the Intel i960 CA (step 04)
Version 1.0        PCA-200E rev A (1.0), FORE Systems, Inc. Feb 11 1997
Copyright 1992, Intel Corporation
=>hfa0 download failed
Configuring ATM device hfa0:Downloading code for hfa0
fore_dnld: Look for the i960 monitor message
           We should see this after a board reset
unisig: attached to interface hfa0
uni: set address 0x39.0348.80.01bc90.0001.0186.2c70.000000000000.00 on interface
 hfa0
atm: Ioctl (AIOCSET) NSAP prefix Essai: Input/output error
Starting initial ATM daemons:.


--------------9989C7D3BEBE615C2248EBCE
Content-Type: text/plain; charset=us-ascii;
 name="dmesg.boot"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="dmesg.boot"

Copyright (c) 1992-1999 FreeBSD Inc.
Copyright (c) 1982, 1986, 1989, 1991, 1993
	The Regents of the University of California. All rights reserved.
FreeBSD 3.2-RELEASE #0: Mon Aug  2 18:01:39 CEST 1999
    herbelot@pc-bsd5.val-9900.telspace.alcatel.fr:/usr/src/sys/compile/Pontium_ATM
Timecounter "i8254"  frequency 1193182 Hz
Timecounter "TSC"  frequency 448054594 Hz
CPU: Pentium III (448.05-MHz 686-class CPU)
  Origin = "GenuineIntel"  Id = 0x672  Stepping=2
  Features=0x383f9ff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,<b24>,<b25>>
real memory  = 67108864 (65536K bytes)
config> q
avail memory = 62373888 (60912K bytes)
Preloaded elf kernel "kernel" at 0xc02ad000.
Preloaded userconfig_script "/boot/kernel.conf" at 0xc02ad09c.
Probing for devices on PCI bus 0:
chip0: <Intel 82443BX host to PCI bridge> rev 0x03 on pci0.0.0
chip1: <Intel 82443BX host to AGP bridge> rev 0x03 on pci0.1.0
xl0: <3Com 3c900B-TPO Etherlink XL> rev 0x04 int a irq 11 on pci0.13.0
xl0: Ethernet address: 00:50:04:3f:08:ea
xl0: autonegotiation not supported
hfa0: <FORE Systems PCA-200E ATM> rev 0x00 int a irq 10 on pci0.14.0
chip2: <Intel 82371AB PCI to ISA bridge> rev 0x02 on pci0.20.0
ide_pci0: <Intel PIIX4 Bus-master IDE controller> rev 0x01 on pci0.20.1
chip3: <Intel 82371AB Power management controller> rev 0x02 on pci0.20.3
Probing for devices on PCI bus 1:
vga0: <Matrox model 0521 graphics accelerator> rev 0x03 int a irq 11 on pci1.0.0
Probing for devices on the ISA bus:
sc0 on isa
sc0: VGA color <16 virtual consoles, flags=0x0>
atkbdc0 at 0x60-0x6f on motherboard
atkbd0 irq 1 on isa
psm0 irq 12 on isa
psm0: model Generic PS/2 mouse, device ID 0
sio0 at 0x3f8-0x3ff irq 4 flags 0x10 on isa
sio0: type 16550A
sio1 at 0x2f8-0x2ff irq 3 on isa
sio1: type 16550A
fdc0 at 0x3f0-0x3f7 irq 6 drq 2 on isa
fdc0: FIFO enabled, 8 bytes threshold
fd0: 1.44MB 3.5in
wdc0 at 0x1f0-0x1f7 irq 14 flags 0xa0ffa0ff on isa
wdc0: unit 0 (wd0): <ST36423A>, DMA, 32-bit, multi-block-16
wd0: 6149MB (12594960 sectors), 13328 cyls, 15 heads, 63 S/T, 512 B/S
wdc1 at 0x170-0x177 irq 15 on isa
wdc1: unit 0 (atapi): <Compaq  CRD-8322B/1.06>, removable, accel, dma, iordis
acd0: drive speed 5500KB/sec, 128KB cache
acd0: supported read types: CD-R, CD-RW, CD-DA, packet track
acd0: Audio: play, 255 volume levels
acd0: Mechanism: ejectable tray
acd0: Medium: no/blank disc inside, unlocked, lock protected
vga0 at 0x3b0-0x3df maddr 0xa0000 msize 131072 on isa
npx0 on motherboard
npx0: INT 16 interface
IP packet filtering initialized, divert enabled, rule-based forwarding enabled, default to accept, logging limited to 100 packets/entry
changing root device to wd0s2a

--------------9989C7D3BEBE615C2248EBCE--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-atm" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?37A98E2D.D015F6CD>