3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
21 * Copyright 1994-1998 Network Computing Services, Inc.
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
26 * @(#) $FreeBSD: src/sbin/atm/fore_dnld/fore_dnld.c,v 1.6.2.2 2000/12/11 01:03:24 obrien Exp $
27 * @(#) $DragonFly: src/sbin/atm/fore_dnld/fore_dnld.c,v 1.8 2006/10/16 00:15:35 pavalos Exp $
34 * Download (pre)processed microcode into Fore Series-200 host adapter
35 * Interact with i960 uart on Fore Series-200 host adapter
39 #include <sys/param.h>
41 #include <sys/socket.h>
44 #include <netatm/atm.h>
45 #include <netatm/atm_if.h>
46 #include <netatm/atm_sap.h>
47 #include <netatm/atm_sys.h>
48 #include <netatm/atm_ioctl.h>
49 #include <dev/atm/hfa/fore.h>
50 #include <dev/atm/hfa/fore_aali.h>
51 #include <dev/atm/hfa/fore_slave.h>
59 #if (defined(BSD) && (BSD >= 199103))
66 extern u_char pca200e_microcode
[];
67 extern int pca200e_microcode_size
;
70 #define DEV_NAME "/dev/sbus%d"
72 #if (defined(BSD) && (BSD >= 199103))
73 #define DEV_NAME _PATH_KMEM
83 #if (defined(BSD) && (BSD >= 199103))
85 #define TCSETA TIOCSETA
86 #define TCGETA TIOCGETA
96 unsigned int lineptr
= 0;
108 CP_READ ( unsigned long val
)
111 return ( ntohl ( val
) );
117 CP_WRITE ( unsigned long val
)
120 return ( htonl ( val
) );
126 * Print an error message and exit.
135 error ( const char *msg
)
137 printf ( "%s\n", msg
);
142 * Get a byte for the uart and if printing, display it.
145 * c Character from uart
152 while ( ! ( CP_READ(Uart
->mon_xmithost
) & UART_VALID
) )
155 c
= ( CP_READ(Uart
->mon_xmithost
) & UART_DATAMASK
);
156 Uart
->mon_xmithost
= CP_WRITE(UART_READY
);
159 * We need to introduce a delay in here or things tend to hang...
163 if ( lineptr
>= sizeof(line
) )
167 * Save character into line
172 if (isprint(c
) || (c
== '\n') || (c
== '\r'))
179 * Loop getting characters from uart into static string until eol. If printing,
180 * display the line retrieved.
183 * prn Are we displaying characters
186 * none Line in global string 'line[]'
194 while ( c
!= '>' && c
!= '\n' && c
!= '\r' )
197 if ( ++i
>= sizeof(line
) )
200 printf ( "%s", line
);
214 * Send a byte to the i960
217 * c Character to send
223 xmit_byte ( unsigned char c
, int dn
)
227 while ( CP_READ(Uart
->mon_xmitmon
) != UART_READY
)
229 if ( CP_READ(Uart
->mon_xmithost
) & UART_VALID
)
231 if ( !dn
) delay ( 10000 );
233 val
= ( c
| UART_VALID
);
234 Uart
->mon_xmitmon
= CP_WRITE( val
);
235 if ( !dn
) delay ( 10000 );
236 if ( CP_READ(Uart
->mon_xmithost
) & UART_VALID
)
242 * Transmit a line to the i960. Eol must be included as part of text to transmit.
245 * str Character string to transmit
246 * len len of string. This allows us to include NULL's
247 * in the string/block to be transmitted.
253 xmit_to_i960 ( const char *str
, int len
, int dn
)
257 for ( i
= 0; i
< len
; i
++ )
258 xmit_byte ( str
[i
], dn
);
262 * Send autobaud sequence to i960 monitor
273 if ( strncmp ( line
, "Mon960", 6 ) == 0 )
274 xmit_to_i960 ( "\r\n\r\n\r\n\r\n", 8, 0 );
278 * Reset tty to initial state
281 * ret error code for exit()
290 sgtty
.c_lflag
|= ( ICANON
| ECHO
);
291 sgtty
.c_cc
[VMIN
] = vmin
;
292 sgtty
.c_cc
[VTIME
] = vtime
;
293 ioctl ( tty
, TCSETA
, &sgtty
);
298 * Utility to strip off any leading path information from a filename
301 * path pathname to strip
304 * fname striped filename
308 basename ( char *path
)
312 if ( ( fname
= strrchr ( path
, '/' ) ) != NULL
)
349 * crctab - CRC-16 constant array...
350 * from Usenet contribution by Mark G. Mendel, Network Systems Corp.
351 * (ihnp4!umn-cs!hyper!mark)
353 unsigned short crctab
[1<<B
] = {
354 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
355 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
356 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
357 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
358 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
359 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
360 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
361 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
362 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
363 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
364 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
365 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
366 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
367 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
368 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
369 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
370 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
371 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
372 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
373 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
374 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
375 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
376 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
377 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
378 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
379 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
380 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
381 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
382 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
383 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
384 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
385 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
389 * Hacked up xmodem protocol. Transmits the file 'filename' down to the i960
390 * using the xmodem protocol.
393 * filename name of file to transmit
397 * -1 unable to send file
400 xmitfile ( char *filename
)
413 char buf
[BUFSIZE
+ 6];
414 char blockbuf
[BUFSIZE
+ 6];
417 int bufsize
= BUFSIZE
;
423 if ( ( fd
= open ( filename
, O_RDONLY
) ) < 0 )
427 stat ( filename
, &stb
);
430 * Determine number of 128 bytes sectors to transmit
432 numsect
= ( stb
.st_size
/ 128 ) + 1;
435 fprintf ( stderr
, "Downloading %d sectors from %s\n",
439 * Send DO'wnload' command to i960
441 xmit_to_i960 ( "do\r\n", 4, 0 );
443 * Wait for response from i960 indicating download in progress
445 while ( strncmp ( line
, "Downloading", 11 ) != 0 )
450 * Get startup character from i960
453 while ( ( c
= getbyte() ) != NAK
&& c
!= CRCCHR
)
454 if ( ++attempts
> NAKMAX
)
455 error ( "Remote system not responding" );
460 } while ( c
!= NAK
&& c
!= CRCCHR
);
463 attempts
= errors
= sendfin
= extrachr
= 0;
466 * Loop over each sector to be sent
469 if ( extrachr
>= 128 )
478 * Read a sectors worth of data from the file into
479 * an internal buffer.
481 for ( bufcntr
= 0; bufcntr
< bufsize
; )
487 if ( ( n
= read ( fd
, &c
, 1 ) ) == 0 )
492 buf
[bufcntr
++] = CTRLZ
;
502 * Fill in xmodem protocol values. Block size and sector number
505 blockbuf
[bbufcntr
++] = (bufsize
== 1024) ? STX
: SOH
;
506 blockbuf
[bbufcntr
++] = sectnum
;
507 blockbuf
[bbufcntr
++] = ~sectnum
;
512 * Loop over the internal buffer computing the checksum of the
515 for ( bufcntr
= 0; bufcntr
< bufsize
; bufcntr
++ )
517 blockbuf
[bbufcntr
++] = buf
[bufcntr
];
520 checksum
= (checksum
<<B
) ^ crctab
[(checksum
>>(W
-B
)) ^ buf
[bufcntr
]];
522 checksum
= ((checksum
+ buf
[bufcntr
]) & 0xff);
527 * Place the checksum at the end of the transmit buffer
532 blockbuf
[bbufcntr
++] = ((checksum
>> 8) & 0xff);
533 blockbuf
[bbufcntr
++] = (checksum
& 0xff);
535 blockbuf
[bbufcntr
++] = checksum
;
540 * Make several attempts to send the data to the i960
545 * Transmit the sector + protocol to the i960
547 xmit_to_i960 ( blockbuf
, bbufcntr
, 1 );
550 * Inform user where we're at
553 printf ( "Sector %3d %3dk\r",
554 sectnum
, (sectnum
* bufsize
) / 1024 );
558 * Get response from i960
560 sendresp
= getbyte();
563 * If i960 didn't like the sector
565 if ( sendresp
!= ACK
)
570 * Are we supposed to cancel the transfer?
572 if ( ( sendresp
& 0x7f ) == CAN
)
573 if ( getbyte() == CAN
)
574 error ( "Send canceled at user's request" );
577 } while ( ( sendresp
!= ACK
) && ( attempts
< RETRYMAX
) && ( errors
< ERRORMAX
) );
584 } while ( !sendfin
&& ( attempts
< RETRYMAX
) && ( errors
< ERRORMAX
) );
587 * Did we expire all our allows attempts?
589 if ( attempts
>= RETRYMAX
)
591 xmit_byte ( CAN
, 1 ), xmit_byte ( CAN
, 1 ), xmit_byte ( CAN
, 1 );
592 error ( "Remote system not responding" );
596 * Check for too many transmission errors
598 if ( errors
>= ERRORMAX
)
600 xmit_byte ( CAN
, 1 ), xmit_byte ( CAN
, 1 ), xmit_byte ( CAN
, 1 );
601 error ( "Too many errors in transmission" );
607 * Indicate the transfer is complete
609 xmit_byte ( EOT
, 1 );
612 * Wait until i960 acknowledges us
614 while ( ( c
= getbyte() ) != ACK
&& ( ++attempts
< RETRYMAX
) )
615 xmit_byte ( EOT
, 1 );
617 if ( attempts
>= RETRYMAX
)
618 error ( "Remote system not responding on completion" );
621 * After download, we'll see a few more command
622 * prompts as the CP does its stuff. Ignore them.
624 while ( strncmp ( line
, "=>", 2 ) != 0 )
627 while ( strncmp ( line
, "=>", 2 ) != 0 )
630 while ( strncmp ( line
, "=>", 2 ) != 0 )
634 * Tell the i960 to start executing the downloaded code
636 xmit_to_i960 ( "go\r\n", 4, 0 );
639 * Get the messages the CP will spit out
640 * after the GO command.
652 loadmicrocode ( u_char
*ucode
, int size
, u_char
*ram
)
671 * Check that we understand this header
673 memcpy(&binhdr
, ucode
, sizeof(binhdr
));
674 if ( strncmp ( (caddr_t
)&binhdr
.Id
, "fore", 4 ) != 0 ) {
675 fprintf ( stderr
, "Unrecognized format in micorcode file." );
681 * We always swap the SunOS microcode file...
686 * We need to swap the header start/entry words...
689 for ( n
= 0; n
< sizeof(u_long
); n
++ )
693 for ( n
= 0; n
< sizeof(u_long
); n
++ )
699 * Set pointer to RAM load location
701 bufp
= (ram
+ binhdr
.start
);
709 lp
= (u_long
*) ucode
;
711 for ( i
= 0; i
< size
/ sizeof(long); i
++ )
713 lp
[i
] = CP_WRITE(lp
[i
]);
719 for ( j
= 0; j
< 4; j
++ )
725 bcopy ( (caddr_t
)ucode
, bufp
, size
);
728 * With .bin extension, we need to specify start address on 'go'
734 sprintf ( cmd
, "go %lx\r\n", binhdr
.entry
);
736 xmit_to_i960 ( cmd
, strlen ( cmd
), 0 );
738 while ( strncmp ( line
, cmd
, strlen(cmd
) - 3 ) != 0 )
748 sendbinfile ( char *fname
, u_char
*ram
)
771 if ( ( fd
= open ( fname
, O_RDONLY
) ) < 0 )
775 * Read the .bin header from the file
777 if ( ( read ( fd
, &binhdr
, sizeof(binhdr
) ) ) != sizeof(binhdr
) )
784 * Check that we understand this header
786 if ( strncmp ( (caddr_t
)&binhdr
.Id
, "fore", 4 ) != 0 ) {
787 fprintf ( stderr
, "Unrecognized format in micorcode file." );
794 * We always swap the SunOS microcode file...
799 * We need to swap the header start/entry words...
802 for ( n
= 0; n
< sizeof(u_long
); n
++ )
806 for ( n
= 0; n
< sizeof(u_long
); n
++ )
817 * Set pointer to RAM load location
819 bufp
= (ram
+ binhdr
.start
);
826 * Need to swap longs - copy file into temp buffer
828 while ( ( n
= read ( fd
, (char *)buffer
, sizeof(buffer
))) > 0 )
833 for ( i
= 0; i
< sizeof(buffer
) / sizeof(long); i
++ )
835 buffer
[i
] = CP_WRITE(buffer
[i
]);
841 for ( j
= 0; j
< 4; j
++ )
848 * Copy swapped buffer into CP RAM
851 bcopy ( (caddr_t
)buffer
, bufp
, n
);
853 printf ( "%d\r", cnt
);
857 while ( ( n
= read ( fd
, bufp
, 128 ) ) > 0 )
861 printf ( "%d\r", cnt
);
867 * With .bin extension, we need to specify start address on 'go'
873 sprintf ( cmd
, "go %lx\r\n", binhdr
.entry
);
875 xmit_to_i960 ( cmd
, strlen ( cmd
), 0 );
877 while ( strncmp ( line
, cmd
, strlen(cmd
) - 3 ) != 0 )
890 * Program to download previously processed microcode to series-200 host adapter
893 main( int argc
, char **argv
)
895 int fd
; /* mmap for Uart */
896 u_char
*ram
; /* pointer to RAM */
897 Mon960
*Mon
; /* Uart */
901 int binary
= 0; /* Send binary file */
902 caddr_t buf
; /* Ioctl buffer */
903 char bus_dev
[80]; /* Bus device to mmap on */
904 struct atminfreq req
;
905 struct air_cfg_rsp
*air
; /* Config info response structure */
906 int buf_len
; /* Size of ioctl buffer */
907 const char *dev
= "\0"; /* Device to download */
908 char *dirname
= NULL
; /* Directory path to objd files */
909 char *objfile
= NULL
; /* Command line object filename */
910 u_char
*ucode
= NULL
; /* Pointer to microcode */
911 int ucode_size
= 0; /* Length of microcode */
912 char *sndfile
= NULL
; /* Object filename to download */
913 char filename
[64]; /* Constructed object filename */
914 char base
[64]; /* sba200/sba200e/pca200e basename */
915 int ext
= 0; /* 0 == bin 1 == objd */
916 struct stat sbuf
; /* Used to find if .bin or .objd */
918 progname
= (char *)basename(argv
[0]);
919 comm_mode
= strcmp ( progname
, "fore_comm" ) == 0;
921 while ( ( c
= getopt ( argc
, argv
, "i:d:f:berv" ) ) != -1 )
927 dirname
= (char *)strdup ( optarg
);
933 dev
= (char *)strdup ( optarg
);
936 objfile
= (char *)strdup ( optarg
);
945 printf ( "usage: %s [-v] [-i intf] [-d dirname] [-f objfile]\n", argv
[0] );
952 setbuf ( stdout
, NULL
);
954 if ( ( fd
= socket ( AF_ATM
, SOCK_DGRAM
, 0 ) ) < 0 )
956 perror ( "Cannot create ATM socket" );
960 * Over allocate memory for returned data. This allows
961 * space for IOCTL reply info as well as config info.
963 buf_len
= 4 * sizeof(struct air_cfg_rsp
);
964 if ( ( buf
= (caddr_t
)malloc(buf_len
) ) == NULL
)
966 perror ( "Cannot allocate memory for reply" );
970 * Fill in request paramaters
972 req
.air_opcode
= AIOCS_INF_CFG
;
973 req
.air_buf_addr
= buf
;
974 req
.air_buf_len
= buf_len
;
977 * Copy interface name into ioctl request
979 strcpy ( req
.air_cfg_intf
, dev
);
984 if ( ( ioctl ( fd
, AIOCINFO
, (caddr_t
)&req
) ) ) {
985 perror ( "ioctl (AIOCSINFO)" );
989 * Reset buffer pointer
991 req
.air_buf_addr
= buf
;
999 * Loop through all attached adapters
1001 for (; (size_t)req
.air_buf_len
>= sizeof(struct air_cfg_rsp
);
1002 buf
+= sizeof(struct air_cfg_rsp
),
1003 req
.air_buf_len
-= sizeof(struct air_cfg_rsp
)) {
1006 * Point to vendor info
1008 air
= (struct air_cfg_rsp
*)buf
;
1010 if (air
->acp_vendor
== VENDOR_FORE
)
1016 sprintf ( bus_dev
, DEV_NAME
, air
->acp_busslot
);
1018 sprintf ( bus_dev
, DEV_NAME
);
1022 * Setup signal handlers
1024 signal ( SIGINT
, SIG_IGN
);
1025 signal ( SIGQUIT
, SIG_IGN
);
1028 * If comm_mode, setup terminal for single char I/O
1031 tty
= open ( _PATH_TTY
, O_RDWR
);
1032 ioctl ( tty
, TCGETA
, &sgtty
);
1033 sgtty
.c_lflag
&= ~( ICANON
| ECHO
);
1034 vmin
= sgtty
.c_cc
[VMIN
];
1035 vtime
= sgtty
.c_cc
[VTIME
];
1036 sgtty
.c_cc
[VMIN
] = 0;
1037 sgtty
.c_cc
[VTIME
] = 0;
1038 ioctl ( tty
, TCSETA
, &sgtty
);
1042 * Open bus for memory access
1044 if ( ( fd
= open ( bus_dev
, O_RDWR
) ) < 0 )
1046 perror ( "open bus_dev" );
1047 fprintf(stderr
, "%s download failed (%s)\n",
1048 air
->acp_intf
, bus_dev
);
1053 * Map in the RAM memory to get access to the Uart
1055 #ifdef __FreeBSD__ /*XXX*/
1056 ram
= (u_char
*) mmap(0, PCA200E_MMAP_SIZE
,
1058 ram
= (u_char
*) mmap(0, air
->acp_ramsize
,
1060 PROT_READ
| PROT_WRITE
, MAP_SHARED
| MAP_HASSEMAPHORE
,
1062 if (ram
== (u_char
*)-1) {
1063 perror ( "mmap ram" );
1064 fprintf(stderr
, "%s download failed\n",
1069 Mon
= (Mon960
*)(ram
+ MON960_BASE
);
1070 Uart
= (Mon960
*)&(Mon
->mon_xmitmon
);
1073 * Determine endianess
1075 switch ( Mon
->mon_bstat
) {
1076 case BOOT_COLDSTART
:
1083 switch (ntohl(Mon
->mon_bstat
)) {
1084 case BOOT_COLDSTART
:
1092 fprintf(stderr
, "%s unknown status\n",
1102 u_int
*hcr
= (u_int
*)(ram
+ PCA200E_HCR_OFFSET
);
1103 PCA200E_HCR_INIT(*hcr
, PCA200E_RESET_BD
);
1105 PCA200E_HCR_CLR(*hcr
, PCA200E_RESET_BD
);
1111 static struct timeval timeout
= { 0, 0 };
1115 * We want to talk with the i960 monitor
1119 * Loop forever accepting characters
1126 * Check for data from the terminal
1129 FD_SET ( fileno(stdin
), &fdr
);
1131 if ( ( ns
= select ( FD_SETSIZE
, &fdr
, NULL
, NULL
,
1132 &timeout
) ) < 0 ) {
1133 perror ( "select" );
1141 nr
= read ( fileno(stdin
), &c1
, 1 );
1147 xmit_byte ( c1
, 0 );
1152 xmit_byte ( 27, 0 );
1155 xmit_byte ( c1
, 0 );
1160 * Check for data from the i960
1162 if ( CP_READ(Uart
->mon_xmithost
) & UART_VALID
) {
1166 if ( strcmp ( line
, "Mon960" ) == 0 )
1172 * Make sure the driver is loaded and that the CP
1173 * is ready for commands
1175 if ( CP_READ(Mon
->mon_bstat
) == BOOT_RUNNING
)
1178 "%s is up and running - no download allowed.\n",
1184 if ( CP_READ(Mon
->mon_bstat
) != BOOT_MONREADY
)
1187 "%s is not ready for downloading.\n",
1194 * Indicate who we're downloading
1197 printf ( "Downloading code for %s\n",
1201 * Look for the i960 monitor message.
1202 * We should see this after a board reset.
1204 while ( strncmp ( line
, "Mon960", 6 ) != 0 &&
1205 strncmp ( line
, "=>", 2 ) != 0 )
1206 getline( verbose
); /* Verbose */
1211 if ( strncmp ( line
, "Mon960", 6 ) == 0 ) {
1212 xmit_to_i960 ( "\r\n\r\n\r\n\r\n", 8, 0 );
1217 * Keep reading until we get a command prompt
1219 while ( strncmp ( line
, "=>", 2 ) != 0 )
1220 getline( verbose
); /* Verbose */
1223 * Choose the correct microcode file based on the
1224 * adapter type the card claims to be.
1226 switch ( air
->acp_device
)
1228 case DEV_FORE_SBA200
:
1229 sprintf ( base
, "sba200" );
1232 case DEV_FORE_SBA200E
:
1233 sprintf ( base
, "sba200e" );
1236 case DEV_FORE_PCA200E
:
1237 sprintf ( base
, "pca200e" );
1242 fprintf(stderr
, "Unknown adapter type: %d\n",
1248 if ( objfile
== NULL
) {
1249 switch ( air
->acp_device
) {
1250 case DEV_FORE_SBA200
:
1251 case DEV_FORE_SBA200E
:
1252 sprintf ( filename
, "%s.bin%d", base
,
1254 if ( stat ( filename
, &sbuf
) == -1 ) {
1255 sprintf ( filename
, "%s/%s.bin%d",
1258 if ( stat ( filename
, &sbuf
) == -1 ) {
1260 sprintf ( filename
, "%s.objd%d",
1261 base
, air
->acp_bustype
);
1262 if ( stat(filename
, &sbuf
) == -1 ) {
1264 "%s/%s.objd%d", dirname
,
1267 if ( stat ( filename
, &sbuf
) != -1 )
1276 case DEV_FORE_PCA200E
:
1277 /* Use compiled in microcode */
1278 ucode
= pca200e_microcode
;
1279 ucode_size
= pca200e_microcode_size
;
1287 if ( ext
&& !binary
)
1288 err
= xmitfile ( sndfile
);
1289 else if (sndfile
!= NULL
)
1290 err
= sendbinfile ( sndfile
, ram
);
1292 err
= loadmicrocode( ucode
, ucode_size
, ram
);
1295 fprintf(stderr
, "%s download failed\n",
1302 * Download completed - wait around a while for
1303 * the driver to initialize the adapter
1305 aap
= (Aali
*)(ram
+ CP_READ(Mon
->mon_appl
));
1306 for (i
= 0; i
< MAX_CHECK
; i
++, sleep(1)) {
1307 u_long hb1
, hb2
, hb3
;
1309 hb3
= CP_READ(Mon
->mon_bstat
);
1310 if (hb3
!= BOOT_RUNNING
) {
1312 printf("bstat %lx\n", hb3
);
1316 hb1
= CP_READ(aap
->aali_heartbeat
);
1318 hb2
= CP_READ(aap
->aali_heartbeat
);
1320 printf("hb %lx %lx\n", hb1
, hb2
);