Patch by Denis Peter, 19 Mai 2003:
[oweals/u-boot.git] / board / mpl / common / common_util.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  */
24
25 #include <common.h>
26 #include <command.h>
27 #include <video_fb.h>
28 #include "common_util.h"
29 #include <asm/processor.h>
30 #include <asm/byteorder.h>
31 #include <i2c.h>
32 #include <devices.h>
33 #include <pci.h>
34
35 #ifdef CONFIG_PIP405
36 #include "../pip405/pip405.h"
37 #include <405gp_pci.h>
38 #endif
39 #ifdef CONFIG_MIP405
40 #include "../mip405/mip405.h"
41 #include <405gp_pci.h>
42 #endif
43
44 extern int  gunzip (void *, int, unsigned char *, int *);
45 extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
46
47 #define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
48 #define IMAGE_SIZE 0x80000
49
50 extern flash_info_t flash_info[];       /* info for FLASH chips */
51
52 static image_header_t header;
53
54
55
56 int mpl_prg(unsigned long src,unsigned long size)
57 {
58         unsigned long start;
59         flash_info_t *info;
60         int i,rc;
61 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
62         unsigned long *magic = (unsigned long *)src;
63 #endif
64
65         info = &flash_info[0];
66
67 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
68         if(ntohl(magic[0]) != IH_MAGIC) {
69                 printf("Bad Magic number\n");
70                 return -1;
71         }
72
73         start = 0 - size;
74         for(i=info->sector_count-1;i>0;i--)
75         {
76                 info->protect[i] = 0; /* unprotect this sector */
77                 if(start>=info->start[i])
78                 break;
79         }
80         /* set-up flash location */
81         /* now erase flash */
82         printf("Erasing at %lx (sector %d) (start %lx)\n",
83                                 start,i,info->start[i]);
84         flash_erase (info, i, info->sector_count-1);
85
86 #elif defined(CONFIG_VCMA9)
87         start = 0;
88         for (i = 0; i <info->sector_count; i++)
89         {
90                 info->protect[i] = 0; /* unprotect this sector */
91                 if (size < info->start[i])
92                     break;
93         }
94         /* set-up flash location */
95         /* now erase flash */
96         printf("Erasing at %lx (sector %d) (start %lx)\n",
97                                 start,0,info->start[0]);
98         flash_erase (info, 0, i);
99
100 #endif
101         printf("flash erased, programming from 0x%lx 0x%lx Bytes\n",src,size);
102         if ((rc = flash_write ((uchar *)src, start, size)) != 0) {
103                 puts ("ERROR ");
104                 flash_perror (rc);
105                 return (1);
106         }
107         puts ("OK programming done\n");
108         return 0;
109 }
110
111
112 int mpl_prg_image(unsigned long ld_addr)
113 {
114         unsigned long data,len,checksum;
115         image_header_t *hdr=&header;
116         /* Copy header so we can blank CRC field for re-calculation */
117         memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
118         if (ntohl(hdr->ih_magic)  != IH_MAGIC) {
119                 printf ("Bad Magic Number\n");
120                 return 1;
121         }
122         print_image_hdr(hdr);
123         if (hdr->ih_os  != IH_OS_U_BOOT) {
124                 printf ("No U-Boot Image\n");
125                 return 1;
126         }
127         if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
128                 printf ("No Firmware Image\n");
129                 return 1;
130         }
131         data = (ulong)&header;
132         len  = sizeof(image_header_t);
133         checksum = ntohl(hdr->ih_hcrc);
134         hdr->ih_hcrc = 0;
135         if (crc32 (0, (char *)data, len) != checksum) {
136                 printf ("Bad Header Checksum\n");
137                 return 1;
138         }
139         data = ld_addr + sizeof(image_header_t);
140         len  = ntohl(hdr->ih_size);
141         printf ("Verifying Checksum ... ");
142         if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
143                 printf ("Bad Data CRC\n");
144                 return 1;
145         }
146         switch (hdr->ih_comp) {
147         case IH_COMP_NONE:
148                 break;
149         case IH_COMP_GZIP:
150                 printf ("  Uncompressing  ... ");
151                 if (gunzip ((void *)(data+0x100000), 0x400000,
152                             (uchar *)data, (int *)&len) != 0) {
153                         printf ("GUNZIP ERROR\n");
154                         return 1;
155                 }
156                 data+=0x100000;
157                 break;
158         default:
159                 printf ("   Unimplemented compression type %d\n", hdr->ih_comp);
160                 return 1;
161         }
162
163         printf ("  OK\n");
164         return(mpl_prg(data,len));
165 }
166
167
168 void get_backup_values(backup_t *buf)
169 {
170         i2c_read(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)buf,sizeof(backup_t));
171 }
172
173 void set_backup_values(int overwrite)
174 {
175         backup_t back;
176         int i;
177
178         get_backup_values(&back);
179         if(!overwrite) {
180                 if(strncmp(back.signature,"MPL\0",4)==0) {
181                         printf("Not possible to write Backup\n");
182                         return;
183                 }
184         }
185         memcpy(back.signature,"MPL\0",4);
186         i = getenv_r("serial#",back.serial_name,16);
187         if(i < 0) {
188                 printf("Not possible to write Backup\n");
189                 return;
190         }
191         back.serial_name[16]=0;
192         i = getenv_r("ethaddr",back.eth_addr,20);
193         if(i < 0) {
194                 printf("Not possible to write Backup\n");
195                 return;
196         }
197         back.eth_addr[20]=0;
198         i2c_write(CFG_DEF_EEPROM_ADDR, I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
199 }
200
201 void clear_env_values(void)
202 {
203         backup_t back;
204         unsigned char env_crc[4];
205
206         memset(&back,0xff,sizeof(backup_t));
207         memset(env_crc,0x00,4);
208         i2c_write(CFG_DEF_EEPROM_ADDR,I2C_BACKUP_ADDR,2,(void *)&back,sizeof(backup_t));
209         i2c_write(CFG_DEF_EEPROM_ADDR,CFG_ENV_OFFSET,2,(void *)env_crc,4);
210 }
211
212 /*
213  * check crc of "older" environment
214  */
215 int check_env_old_size(ulong oldsize)
216 {
217         ulong crc, len, new;
218         unsigned off;
219         uchar buf[64];
220
221         /* read old CRC */
222         eeprom_read (CFG_DEF_EEPROM_ADDR,
223                      CFG_ENV_OFFSET,
224                      (uchar *)&crc, sizeof(ulong));
225
226         new = 0;
227         len = oldsize;
228         off = sizeof(long);
229         len = oldsize-off;
230         while (len > 0) {
231                 int n = (len > sizeof(buf)) ? sizeof(buf) : len;
232
233                 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, buf, n);
234                 new = crc32 (new, buf, n);
235                 len -= n;
236                 off += n;
237         }
238
239         return (crc == new);
240 }
241
242 static ulong oldsizes[] = {
243         0x200,
244         0x800,
245         0
246 };
247
248 void copy_old_env(ulong size)
249 {
250         uchar name_buf[64];
251         uchar value_buf[0x800];
252         uchar c;
253         ulong len;
254         unsigned off;
255         uchar *name, *value;
256
257         name=&name_buf[0];
258         value=&value_buf[0];
259         len=size;
260         off = sizeof(long);
261         while (len > off) {
262                 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
263                 if(c != '=') {
264                         *name++=c;
265                         off++;
266                 }
267                 else {
268                         *name++='\0';
269                         off++;
270                         do {
271                                 eeprom_read (CFG_DEF_EEPROM_ADDR, CFG_ENV_OFFSET+off, &c, 1);
272                                 *value++=c;
273                                 off++;
274                                 if(c == '\0')
275                                         break;
276                         } while(len > off);
277                         name=&name_buf[0];
278                         value=&value_buf[0];
279                         if(strncmp(name,"baudrate",8)!=0) {
280                                 setenv(name,value);
281                         }
282
283                 }
284         }
285 }
286
287
288 void check_env(void)
289 {
290         unsigned char *s;
291         int i=0;
292         char buf[32];
293         backup_t back;
294
295         s=getenv("serial#");
296         if(!s) {
297                 while(oldsizes[i]) {
298                         if(check_env_old_size(oldsizes[i]))
299                                 break;
300                         i++;
301                 }
302                 if(!oldsizes[i]) {
303                         /* no old environment has been found */
304                         get_backup_values (&back);
305                         if (strncmp (back.signature, "MPL\0", 4) == 0) {
306                                 sprintf (buf, "%s", back.serial_name);
307                                 setenv ("serial#", buf);
308                                 sprintf (buf, "%s", back.eth_addr);
309                                 setenv ("ethaddr", buf);
310                                 printf ("INFO:  serial# and ethaddr recovered, use saveenv\n");
311                                 return;
312                         }
313                 }
314                 else {
315                         copy_old_env(oldsizes[i]);
316                         printf ("INFO:  old environment ajusted, use saveenv\n");
317                 }
318         }
319         else {
320                 /* check if back up is set */
321                 get_backup_values(&back);
322                 if(strncmp(back.signature,"MPL\0",4)!=0) {
323                         set_backup_values(0);
324                 }
325         }
326 }
327
328
329
330 extern device_t *stdio_devices[];
331 extern char *stdio_names[];
332
333 void show_stdio_dev(void)
334 {
335         /* Print information */
336         printf ("In:    ");
337         if (stdio_devices[stdin] == NULL) {
338                 printf ("No input devices available!\n");
339         } else {
340                 printf ("%s\n", stdio_devices[stdin]->name);
341         }
342
343         printf ("Out:   ");
344         if (stdio_devices[stdout] == NULL) {
345                 printf ("No output devices available!\n");
346         } else {
347                 printf ("%s\n", stdio_devices[stdout]->name);
348         }
349
350         printf ("Err:   ");
351         if (stdio_devices[stderr] == NULL) {
352                 printf ("No error devices available!\n");
353         } else {
354                 printf ("%s\n", stdio_devices[stderr]->name);
355         }
356 }
357
358 /* ------------------------------------------------------------------------- */
359
360         /* switches the cs0 and the cs1 to the locations.
361            When boot is TRUE, the the mapping is switched
362            to the boot configuration, If it is FALSE, the
363            flash will be switched in the boot area */
364
365 #undef SW_CS_DBG
366 #ifdef SW_CS_DBG
367 #define SW_CS_PRINTF(fmt,args...)       printf (fmt ,##args)
368 #else
369 #define SW_CS_PRINTF(fmt,args...)
370 #endif
371
372 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)
373 int switch_cs(unsigned char boot)
374 {
375         unsigned long pbcr;
376         int mode;
377
378         mode=get_boot_mode();
379         mtdcr(ebccfga, pb0cr);
380         pbcr = mfdcr (ebccfgd);
381         if (mode & BOOT_MPS) {
382                 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
383                 /* we need only to switch if boot from MPS */
384                 /* printf(" MPS boot mode detected. ");*/
385                 /* printf("cs0 cfg: %lx\n",pbcr); */
386                 if(boot) {
387                         /* switch to boot configuration */
388                         /* this is a 8bit boot, switch cs0 to flash location */
389                         SW_CS_PRINTF("switch to boot mode (MPS on High address\n");
390                         pbcr&=0x000FFFFF; /*mask base address of the cs0 */
391                         pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
392                         mtdcr(ebccfga, pb0cr);
393                         mtdcr(ebccfgd, pbcr);
394                         SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
395                         mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
396                         pbcr = mfdcr(ebccfgd);
397                         SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr);
398                         pbcr&=0x000FFFFF; /*mask base address of the cs1 */
399                         pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
400                         mtdcr(ebccfga, pb1cr);
401                         mtdcr(ebccfgd, pbcr);
402                         SW_CS_PRINTF("  new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
403                 }
404                 else {
405                         /* map flash to boot area, */
406                         SW_CS_PRINTF("map Flash to boot area\n");
407                         pbcr&=0x000FFFFF; /*mask base address of the cs0 */
408                         pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
409                         mtdcr(ebccfga, pb0cr);
410                         mtdcr(ebccfgd, pbcr);
411                         SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr);
412                         mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
413                         pbcr = mfdcr(ebccfgd);
414                         SW_CS_PRINTF("  cs1 cfg: %lx\n",pbcr);
415                         pbcr&=0x000FFFFF; /*mask base address of the cs1 */
416                         pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
417                         mtdcr(ebccfga, pb1cr);
418                         mtdcr(ebccfgd, pbcr);
419                         SW_CS_PRINTF("  new cs1 cfg: %lx Flash is on High Address\n",pbcr);
420                 }
421                 return 1;
422         }
423         else {
424                 SW_CS_PRINTF("Normal boot, no switching necessary\n");
425                 return 0;
426         }
427
428 }
429
430 int get_boot_mode(void)
431 {
432         unsigned long pbcr;
433         int res = 0;
434         pbcr = mfdcr (strap);
435         if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) 
436                 /* boot via MPS or MPS mapping */
437                 res = BOOT_MPS;
438         if(pbcr & PSR_ROM_LOC) 
439                 /* boot via PCI.. */
440                 res |= BOOT_PCI;
441          return res;
442 }
443
444 /* Setup cs0 parameter finally.
445    Map the flash high (in boot area)
446    This code can only be executed from SDRAM (after relocation).
447 */
448 void setup_cs_reloc(void)
449 {
450         unsigned long pbcr;
451         /* Since we are relocated, we can set-up the CS finaly
452          * but first of all, switch off PCI mapping (in case it was a PCI boot) */
453         out32r(PMM0MA,0L);
454         icache_enable (); /* we are relocated */
455         /* for PCI Boot, we have to set-up the remaining CS correctly */
456         pbcr = mfdcr (strap);
457         if(pbcr & PSR_ROM_LOC) {
458                 /* boot via PCI.. */
459                 if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) {
460                 /* Boot width = 8 bit MPS Boot, set up MPS on CS0 */
461                         #ifdef DEBUG
462                         printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000));
463                         #endif
464                         mtdcr (ebccfga, pb0ap);
465                         mtdcr (ebccfgd, MPS_AP);
466                         mtdcr (ebccfga, pb0cr);
467                         mtdcr (ebccfgd, MPS_CR_B);
468                 }
469                 else {
470                         /* Flash boot, set up the Flash on CS0 */
471                         #ifdef DEBUG
472                         printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000));
473                         #endif
474                         mtdcr (ebccfga, pb0ap);
475                         mtdcr (ebccfgd, FLASH_AP);
476                         mtdcr (ebccfga, pb0cr);
477                         mtdcr (ebccfgd, FLASH_CR_B);
478                 }
479         }
480         switch_cs(0); /* map Flash High */
481 }
482
483
484 #elif defined(CONFIG_VCMA9)
485 int switch_cs(unsigned char boot)
486 {
487     return 0;
488 }
489 #endif /* CONFIG_VCMA9 */
490
491 int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
492 {
493         ulong size,src,ld_addr;
494         int result;
495         backup_t back;
496         src = MULTI_PURPOSE_SOCKET_ADDR;
497         size = IMAGE_SIZE;
498
499         if (strcmp(argv[1], "flash") == 0)
500         {
501 #if (CONFIG_COMMANDS & CFG_CMD_FDC)
502                 if (strcmp(argv[2], "floppy") == 0) {
503                         char *local_args[3];
504                         extern int do_fdcboot (cmd_tbl_t *, int, int, char *[]);
505                         printf ("\nupdating bootloader image from floppy\n");
506                         local_args[0] = argv[0];
507                         if(argc==4) {
508                                 local_args[1] = argv[3];
509                                 local_args[2] = NULL;
510                                 ld_addr=simple_strtoul(argv[3], NULL, 16);
511                                 result=do_fdcboot(cmdtp, 0, 2, local_args);
512                         }
513                         else {
514                                 local_args[1] = NULL;
515                                 ld_addr=CFG_LOAD_ADDR;
516                                 result=do_fdcboot(cmdtp, 0, 1, local_args);
517                         }
518                         result=mpl_prg_image(ld_addr);
519                         return result;
520                 }
521 #endif /* (CONFIG_COMMANDS & CFG_CMD_FDC) */
522                 if (strcmp(argv[2], "mem") == 0) {
523                         if(argc==4) {
524                                 ld_addr=simple_strtoul(argv[3], NULL, 16);
525                         }
526                         else {
527                                 ld_addr=load_addr;
528                         }
529                         printf ("\nupdating bootloader image from memory at %lX\n",ld_addr);
530                         result=mpl_prg_image(ld_addr);
531                         return result;
532                 }
533                 if (strcmp(argv[2], "mps") == 0) {
534                         printf ("\nupdating bootloader image from MPS\n");
535                         result=mpl_prg(src,size);
536                         return result;
537                 }
538         }
539         if (strcmp(argv[1], "mem") == 0)
540         {
541                 result=0;
542                 if(argc==3)
543                 {
544                         result = (int)simple_strtol(argv[2], NULL, 16);
545             }
546             src=(unsigned long)&result;
547             src-=CFG_MEMTEST_START;
548             src-=(100*1024); /* - 100k */
549             src&=0xfff00000;
550             size=0;
551             do {
552                 size++;
553                         printf("\n\nPass %ld\n",size);
554                         mem_test(CFG_MEMTEST_START,src,1);
555                         if(ctrlc())
556                                 break;
557                         if(result>0)
558                                 result--;
559
560                 }while(result);
561                 return 0;
562         }
563         if (strcmp(argv[1], "clearenvvalues") == 0)
564         {
565                 if (strcmp(argv[2], "yes") == 0)
566                 {
567                         clear_env_values();
568                         return 0;
569                 }
570         }
571         if (strcmp(argv[1], "getback") == 0) {
572                 get_backup_values(&back);
573                 back.signature[3]=0;
574                 back.serial_name[16]=0;
575                 back.eth_addr[20]=0;
576                 printf("GetBackUp: signature: %s\n",back.signature);
577                 printf("           serial#:   %s\n",back.serial_name);
578                 printf("           ethaddr:   %s\n",back.eth_addr);
579                 return 0;
580         }
581         if (strcmp(argv[1], "setback") == 0) {
582                 set_backup_values(1);
583                 return 0;
584         }
585         printf("Usage:\n%s\n", cmdtp->usage);
586         return 1;
587 }
588
589
590 #if (CONFIG_COMMANDS & CFG_CMD_DOC)
591 extern void doc_probe(ulong physadr);
592 void doc_init (void)
593 {
594   doc_probe(MULTI_PURPOSE_SOCKET_ADDR);
595 }
596 #endif
597
598
599 #ifdef CONFIG_VIDEO
600 /******************************************************
601  * Routines to display the Board information
602  * to the screen (since the VGA will be initialized as last,
603  * we must resend the infos)
604  */
605
606 #ifdef CONFIG_CONSOLE_EXTRA_INFO
607 extern GraphicDevice ctfb;
608
609 void video_get_info_str (int line_number, char *info)
610 {
611         /* init video info strings for graphic console */
612         DECLARE_GLOBAL_DATA_PTR;
613         PPC405_SYS_INFO sys_info;
614         char rev;
615         int i,boot;
616         unsigned long pvr;
617         char buf[64];
618         char tmp[16];
619         char cpustr[16];
620         unsigned char *s, *e, bc;
621         switch (line_number)
622         {
623         case 2:
624                 /* CPU and board infos */
625                 pvr=get_pvr();
626                 get_sys_info (&sys_info);
627                 switch (pvr) {
628                         case PVR_405GP_RB: rev='B'; break;
629                         case PVR_405GP_RC: rev='C'; break;
630                         case PVR_405GP_RD: rev='D'; break;
631                         case PVR_405GP_RE: rev='E'; break;
632                         case PVR_405GPR_RB: rev='B'; break;
633                         default:           rev='?'; break;
634                 }
635                 if(pvr==PVR_405GPR_RB)
636                         sprintf(cpustr,"PPC405GPr %c",rev);
637                 else
638                         sprintf(cpustr,"PPC405GP %c",rev);
639                 /* Board info */
640                 i=0;
641                 s=getenv ("serial#");
642 #ifdef CONFIG_PIP405
643                 if (!s || strncmp (s, "PIP405", 6)) {
644                         sprintf(buf,"### No HW ID - assuming PIP405");
645                 }
646 #endif
647 #ifdef CONFIG_MIP405
648                 if (!s || strncmp (s, "MIP405", 6)) {
649                         sprintf(buf,"### No HW ID - assuming MIP405");
650                 }
651 #endif
652                 else {
653                         for (e = s; *e; ++e) {
654                                 if (*e == ' ')
655                                         break;
656                         }
657                         for (; s < e; ++s) {
658                                 if (*s == '_') {
659                                         ++s;
660                                         break;
661                                 }
662                                 buf[i++]=*s;
663                         }
664                         sprintf(&buf[i]," SN ");
665                         i+=4;
666                         for (; s < e; ++s) {
667                                 buf[i++]=*s;
668                         }
669                         buf[i++]=0;
670                 }
671                 sprintf (info," %s %s %s MHz (%lu/%lu/%lu MHz)",
672                         buf, cpustr,
673                         strmhz (tmp, gd->cpu_clk), sys_info.freqPLB / 1000000,
674                         sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
675                         sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
676                 return;
677         case 3:
678                 /* Memory Info */
679                 boot = get_boot_mode();
680                 bc = in8 (CONFIG_PORT_ADDR);
681                 sprintf(info, " %luMB RAM, %luMB Flash Cfg 0x%02X %s %s",
682                         gd->bd->bi_memsize / 0x100000,
683                         gd->bd->bi_flashsize / 0x100000,
684                         bc,
685                         (boot & BOOT_MPS) ? "MPS boot" : "Flash boot",
686                         ctfb.modeIdent);
687                 return;
688         case 1:
689                 sprintf (buf, "%s",CONFIG_IDENT_STRING);
690                 sprintf (info, " %s", &buf[1]);
691                 return;
692     }
693     /* no more info lines */
694     *info = 0;
695     return;
696 }
697 #endif /* CONFIG_CONSOLE_EXTRA_INFO */
698
699 #endif /* CONFIG_VIDEO */