summaryrefslogtreecommitdiffstats
path: root/sbin/atm/fore_dnld
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-09-15 08:23:17 +0000
committerphk <phk@FreeBSD.org>1998-09-15 08:23:17 +0000
commitc3dd1fa899d435ea4bf79897f646a93cb80c94ac (patch)
tree98dfbc96e3c6aa7ff1f322855f6484c4e609819d /sbin/atm/fore_dnld
parent9ed6892f4808d56de443849229e151f8f7ad43b0 (diff)
downloadFreeBSD-src-c3dd1fa899d435ea4bf79897f646a93cb80c94ac.zip
FreeBSD-src-c3dd1fa899d435ea4bf79897f646a93cb80c94ac.tar.gz
Add new files for HARP3
Host ATM Research Platform (HARP), Network Computing Services, Inc. This software was developed with the support of the Defense Advanced Research Projects Agency (DARPA).
Diffstat (limited to 'sbin/atm/fore_dnld')
-rw-r--r--sbin/atm/fore_dnld/Makefile36
-rw-r--r--sbin/atm/fore_dnld/fore_dnld.8108
-rw-r--r--sbin/atm/fore_dnld/fore_dnld.c1245
3 files changed, 1389 insertions, 0 deletions
diff --git a/sbin/atm/fore_dnld/Makefile b/sbin/atm/fore_dnld/Makefile
new file mode 100644
index 0000000..ac7c3a2
--- /dev/null
+++ b/sbin/atm/fore_dnld/Makefile
@@ -0,0 +1,36 @@
+#
+#
+# ===================================
+# 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: Makefile,v 1.5 1998/07/10 16:01:58 jpt Exp $
+#
+#
+
+PROG= fore_dnld
+MAN8= fore_dnld.8
+
+CFLAGS+= -I ${.CURDIR}/../../../sys
+LDADD+= -latm
+
+.include <bsd.prog.mk>
diff --git a/sbin/atm/fore_dnld/fore_dnld.8 b/sbin/atm/fore_dnld/fore_dnld.8
new file mode 100644
index 0000000..770f85d
--- /dev/null
+++ b/sbin/atm/fore_dnld/fore_dnld.8
@@ -0,0 +1,108 @@
+.\"
+.\" ===================================
+.\" 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.1,v 1.4 1997/05/09 17:29:37 mks Exp $
+.\"
+.\"
+.de EX \"Begin example
+.ne 5
+.if n .sp 1
+.if t .sp .5
+.nf
+.in +.5i
+..
+.de EE
+.fi
+.in -.5i
+.if n .sp 1
+.if t .sp .5
+..
+.TH FORE_DNLD 8 "1996-12-03" "HARP"
+.SH NAME
+fore_dnld \- Download FORE Systems' microcode into host ATM adapter
+.SH SYNOPSIS
+.B fore_dnld
+[-i intf]
+[-d path]
+[-f objfile]
+.sp
+.fi
+.SH DESCRIPTION
+.I fore_dnld
+downloads FORE Systems' microcode into the host ATM adapter(s).
+.fi
+.SH OPTIONS
+.TP
+.B \-i intf
+Specify which ATM interface to download microcode to.
+Default is to load microcode into all FORE Systems host adapters.
+.TP
+.B -d path
+Specify the path to prepend to the "objfile" name.
+Default is to use current directory.
+.TP
+.B -f objfile
+Specify the microcode binary file. Defaults are:
+"sba200.obj" for SBA-200 adapters,
+"sba200e.obj" for SBA-200E adapters, and
+"pca200e.bin" for PCA-200E adapters.
+.fi
+.SH NOTES
+.PP
+Microcode as distributed by FORE Systems is not ready for downloading
+directly into SBA host ATM adapters. Instead, the supplied microcode needs
+to be processed with the "objcopy" command to create an image suitable
+for downloading. Arguments to "objcopy" are "-S -l -Fcoff". Microcode as
+distibuted by FORE Systems for the PCA host ATM adapter does not need
+to be processed.
+.SH "SEE ALSO"
+.PP
+~fore/etc/objcopy - command to process FORE Systems supplied microcode.
+.PP
+~fore/etc/sba200*.ucode* - microcode as supplied by FORE Systems for SBA
+adapters.
+.PP
+~fore/i386/pca200e.bin - microcode as supplied by FORE Systems for PCA
+adapters.
+.PP
+~harp/doc/Install - HARP installation instructions.
+.fi
+.SH BUGS
+.PP
+None known.
+.fi
+.SH COPYRIGHT
+Copyright (c) 1994-1998, Network Computing Services, Inc.
+.fi
+.SH AUTHORS
+John Cavanaugh, Minnesota Supercomputer Center, Inc.
+.br
+Mike Spengler, Minnesota Supercomputer Center, Inc.
+.br
+Joe Thomas, Minnesota Supercomputer Center, Inc.
+.fi
+.SH ACKNOWLEDGMENTS
+This software was developed under the sponsorship of the
+Defense Advanced Research Projects Agency (DARPA) under
+contract numbers F19628-92-C-0072 and F19628-95-C-0215.
diff --git a/sbin/atm/fore_dnld/fore_dnld.c b/sbin/atm/fore_dnld/fore_dnld.c
new file mode 100644
index 0000000..6ecafa5
--- /dev/null
+++ b/sbin/atm/fore_dnld/fore_dnld.c
@@ -0,0 +1,1245 @@
+/*
+ *
+ * ===================================
+ * 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.15 1998/08/26 23:29:32 mks 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.15 1998/08/26 23:29:32 mks 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
+sendfile ( 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);
+ 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.
+ */
+ while ( strncmp ( line, "Mon960", 6 ) != 0 &&
+ strncmp ( line, "=>", 2 ) != 0 )
+ getline( verbose ); /* Verbose */
+
+ /*
+ * Autobaud fakery
+ */
+ 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
+ */
+ 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 = sendfile ( 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);
+
+}
+
OpenPOWER on IntegriCloud