~ubuntu-branches/ubuntu/intrepid/raidutils/intrepid

« back to all changes in this revision

Viewing changes to raidutil/flash.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Barak Pearlmutter
  • Date: 2004-05-18 11:33:42 UTC
  • Revision ID: james.westby@ubuntu.com-20040518113342-tyqavmso5q351xi2
Tags: upstream-0.0.4
ImportĀ upstreamĀ versionĀ 0.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 1996-2004, Adaptec Corporation
 
2
 * All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 * - Redistributions of source code must retain the above copyright notice, this
 
8
 *   list of conditions and the following disclaimer.
 
9
 * - Redistributions in binary form must reproduce the above copyright notice,
 
10
 *   this list of conditions and the following disclaimer in the documentation
 
11
 *   and/or other materials provided with the distribution.
 
12
 * - Neither the name of the Adaptec Corporation nor the names of its
 
13
 *   contributors may be used to endorse or promote products derived from this
 
14
 *   software without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
17
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
19
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
20
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
21
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
22
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
23
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
24
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
25
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
26
 * POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/****************************************************************************
 
30
*
 
31
* Created:  10/10/98
 
32
*
 
33
*****************************************************************************
 
34
*
 
35
* File Name:            Flash.cpp
 
36
* Module:
 
37
* Contributors:         Mark Salyzyn
 
38
*                                       David Dillard
 
39
* Description:          This command flashes the specified controller
 
40
* Version Control:
 
41
*
 
42
* $Revision: 68 $
 
43
* $NoKeywords: $
 
44
* $Log: $
 
45
*****************************************************************************/
 
46
 
 
47
/*** INCLUDES ***/
 
48
#include "command.hpp"
 
49
#include "flash.hpp"
 
50
#include "listdev.hpp"
 
51
#include "intlist.hpp"
 
52
#include "rustring.h"
 
53
#include "ctlr_map.hpp"
 
54
#include "status.hpp"
 
55
#include "osd_util.h"
 
56
#include "rscenum.h"
 
57
 
 
58
#include <stdio.h>
 
59
#include <ctype.h>
 
60
#if HAVE_FSTREAM
 
61
#  include <fstream>
 
62
#else
 
63
#  if HAVE_FSTREAM_H
 
64
#    include <fstream.h>
 
65
#  endif
 
66
#endif
 
67
#if defined _DPT_WIN_NT
 
68
#  include <strstrea.h>
 
69
#else
 
70
#  if HAVE_SSTREAM
 
71
#    include <sstream>
 
72
#  else
 
73
#    if HAVE_STRSTREAM_H
 
74
#      include <strstream.h>
 
75
#    endif
 
76
#  endif
 
77
#endif
 
78
 
 
79
extern char* EventStrings[];
 
80
/*** CONSTANTS ***/
 
81
enum output_Type
 
82
{
 
83
   OUTPUT_TAB_HEADER,
 
84
   OUTPUT_MULTI_LINED_TAB_HEADER,
 
85
   OUTPUT_END_OF_TAB_SCOPE,
 
86
   OUTPUT_UNADORNED
 
87
};
 
88
enum display_States
 
89
{
 
90
   STATE_COLUMNAR,
 
91
   STATE_MULTI_LINE_COLUMNAR,
 
92
   STATE_RAW,
 
93
   STATE_ONE_SHOT_RAW
 
94
};
 
95
 
 
96
 
 
97
/*** TYPES ***/
 
98
typedef struct _FW_MODEL_MAPPING
 
99
{
 
100
   char controllerModel[8];
 
101
   char fileDescriptionModel[8];
 
102
} FW_MODEL_MAPPING;
 
103
 
 
104
 
 
105
 
 
106
/*** STATIC DATA ***/
 
107
 
 
108
// This array contains the valid mappings of the model number representing the
 
109
// class of adapters that a firmware file is for and the model numbers which
 
110
// represent that class.  This is used to validate that a firmware file can
 
111
// legitimately be flashed to an adapter before the flash is performed.
 
112
//
 
113
// This mapping does NOT contain the mirror mappings where the fileDescriptionModel
 
114
// is the same as the productIdModel, e.g. "2554" and "2554".
 
115
static FW_MODEL_MAPPING modelMappings[] =
 
116
{
 
117
   "PM1554",      "PM2554",
 
118
   "PM2564",      "PM2554",
 
119
   "PM2654",       "PM2554",
 
120
   "PM25XX",       "PM2554",
 
121
 
 
122
   "PM1564",      "PM2564",
 
123
   "PM2664",      "PM2564",
 
124
   "PM25XX",       "PM2564",
 
125
 
 
126
   "PM3755",      "PM3754",
 
127
   "PM375X",       "PM3754",
 
128
   "2000S",       "2005S",
 
129
};
 
130
 
 
131
 
 
132
 
 
133
/*** MACROS ***/
 
134
#ifndef min
 
135
#define min(x, y)   ((x) < (y) ? (x) : (y))
 
136
#endif
 
137
 
 
138
 
 
139
 
 
140
/*** PROTOTYPES ***/
 
141
extern void Flush( String_List * );
 
142
 
 
143
 
 
144
 
 
145
/*** FUNCTIONS ***/
 
146
Flash::Flash(
 
147
   char * sourceFile,
 
148
   int resync,
 
149
   int hba
 
150
   )
 
151
{
 
152
 
 
153
   ENTER( "Flash::Flash(" );
 
154
 
 
155
   (void)strcpy (source = new char [ strlen (sourceFile) + 1 ], (const char *) sourceFile);
 
156
   Resync = resync;
 
157
   hba_Num = hba;
 
158
   imageSize = 0L;
 
159
   loadInfo = 0L;
 
160
   ScanOffset = 0L;
 
161
   ScanSize = 0L;
 
162
   ScanYear = 0;
 
163
   ScanState = 0;
 
164
   ScanFwId = 0L;
 
165
   ScanMonth = 0;
 
166
   ScanDay = 0;
 
167
   memset (ScanBuild, 0, sizeof(ScanBuild));
 
168
   memset (ScanVersion, 0, sizeof(ScanVersion));
 
169
   memset (ScanType, 0, sizeof(ScanType));
 
170
   memset (ScanDescriptionHba, 0, sizeof(ScanDescriptionHba));
 
171
   ScanDescrIdx = 0;
 
172
   inMode0 = false;
 
173
   EXIT();
 
174
}
 
175
 
 
176
Flash::Flash( const Flash &right )
 
177
{
 
178
   ENTER( "Flash::Flash(" );
 
179
 
 
180
#if defined _DPT_UNIXWARE || defined _DPT_SCO
 
181
   Flash( right.source, right.Resync, right.hba_Num );
 
182
#else
 
183
   Flash::Flash( right.source, right.Resync, right.hba_Num );
 
184
#endif
 
185
 
 
186
   EXIT();
 
187
}
 
188
 
 
189
 
 
190
Flash::~Flash()
 
191
{
 
192
 
 
193
   ENTER( "Flash::~Flash()" );
 
194
 
 
195
   if (source != NULL)
 
196
   {
 
197
      delete [] source;
 
198
      source = (char *) NULL;
 
199
   }
 
200
 
 
201
   EXIT();
 
202
}
 
203
 
 
204
 
 
205
Command::Dpt_Error Flash::execute( String_List **output )
 
206
{
 
207
   ENTER( "Command::Dpt_Error   Flash::execute( String_List **output )" );
 
208
   Dpt_Error err;
 
209
 
 
210
 
 
211
   // allocate this object once for all functions.
 
212
   *output  = new String_List();
 
213
 
 
214
   // Try to open the file specified.  If it can't be opened then output
 
215
   // an error message and return.
 
216
   //
 
217
   // The stupid Borland compiler for DOS sets up an unbuffered stream by
 
218
   // default so under DOS attach a buffer to the stream so that we get
 
219
   // decent performance.  Otherwise, performance is truely abysmal.
 
220
   std::fstream firmwareStream;
 
221
 
 
222
#ifdef _DPT_DOS
 
223
   char firmwareStreamBuf[BYTES_PER_TRANSFER];
 
224
   streambuf *pBuf = firmwareStream.rdbuf();
 
225
   pBuf->setbuf(firmwareStreamBuf, sizeof(firmwareStreamBuf));
 
226
#endif
 
227
 
 
228
#if defined _DPT_BSDI
 
229
   firmwareStream.open(source, std::ios::in | std::ios::bin);
 
230
#elif defined (_DPT_SCO) || defined (_DPT_UNIXWARE)
 
231
   firmwareStream.open(source, std::ios::in);
 
232
#else
 
233
   firmwareStream.open(source, std::ios::in | std::ios::binary);
 
234
#endif
 
235
   if (!firmwareStream.good())
 
236
   {
 
237
      (**output).add_Item(EventStrings[STR_FAILURE]);
 
238
          (**output).add_Item(EventStrings[STR_BLANK]);
 
239
      (**output).add_Item( source );
 
240
      return( err );
 
241
   }
 
242
 
 
243
   // Get the size of the file.
 
244
   firmwareStream.seekg(0, std::ios::end);
 
245
   imageSize = firmwareStream.tellg();
 
246
   firmwareStream.seekg(0);
 
247
 
 
248
   if (imageSize == 0)
 
249
   {
 
250
      (**output).add_Item(EventStrings[STR_FAILURE]);
 
251
          (**output).add_Item(EventStrings[STR_BLANK]);
 
252
      (**output).add_Item( source );
 
253
      return( err );
 
254
   }
 
255
 
 
256
   m_FlashFileProcessorFamily = -1;
 
257
   // Determine the type of file provided.
 
258
   unsigned long InitialOffset = (unsigned long)-1L;
 
259
   unsigned long ScanFwType = 0L;
 
260
//Changed because this initialization isn't supported undes SCO 3.2.4.2
 
261
//      unsigned char InitialType[16] = { 0 };
 
262
   unsigned char InitialType[16];
 
263
   InitialType[0] = 0;
 
264
 
 
265
   unsigned long Offset = 0L;
 
266
   // Apparently 8K is the smallest of any flash size, which can only be NVRAM
 
267
   if (imageSize <= MAX_FLASH_NVRAM_SIZE)
 
268
   //   if ( ( imageSize == 128 ) || ( imageSize == FLASH_NVRAM_SIZE ) )
 
269
   {
 
270
      char Buffer[128];
 
271
      InitialOffset = ScanOffset = FLASH_NVRAM_OFFSET;
 
272
      ScanSize = imageSize;
 
273
      strcpy ( (char *)InitialType, EventStrings[STR_NVRAM] );
 
274
      strcpy ( (char *)ScanType, (const char *)InitialType );
 
275
      sprintf (Buffer, EventStrings[STR_SCAN_TYPE_SIZE], ScanType, ScanSize);
 
276
      (**output).add_Item( Buffer );
 
277
   }
 
278
   else for (unsigned long count = 0;  count < imageSize;  ++count)
 
279
      {
 
280
         uCHAR ch = firmwareStream.get();
 
281
         if (( DetermineOffset(ch))
 
282
            || (( ScanState == 21 ) && (count >= (Offset + ScanSize)))
 
283
            || ((count + 1) == imageSize))
 
284
         {
 
285
            if (InitialOffset == (unsigned long)-1L)
 
286
            {
 
287
               InitialOffset = ScanOffset;
 
288
               strcpy ( (char *)InitialType, (const char *)ScanType );
 
289
            }
 
290
            if (ScanFwType == 0L)
 
291
            {
 
292
               ScanFwType = ScanFwId;
 
293
            }
 
294
            if (( Offset += ScanSize ) > count)
 
295
            {
 
296
               count = (Offset - 1);
 
297
            }
 
298
            if (ScanType[0])
 
299
            {
 
300
               char Buffer[128];
 
301
               char date[11];
 
302
               char version[sizeof(ScanVersion)+sizeof(ScanBuild)+1];
 
303
 
 
304
               memset (date, ' ', sizeof(date)-1);
 
305
               date[sizeof(date)-1] = '\0';
 
306
               if (ScanMonth || ScanDay || ScanYear)
 
307
               {
 
308
                  sprintf (date, EventStrings[STR_FILLIN_DATE],
 
309
                     ScanMonth, ScanDay, ScanYear);
 
310
               }
 
311
               memset (version, 0, sizeof(version));
 
312
               if (ScanVersion[0])
 
313
               {
 
314
                  sprintf (version, EventStrings[STR_FILLIN_VERSION],
 
315
                     ScanVersion, ScanBuild[0] ? "/" : "", ScanBuild);
 
316
               }
 
317
               if (Offset > imageSize)
 
318
               {
 
319
                  ScanSize -= Offset - imageSize;
 
320
               }
 
321
               sprintf (Buffer, EventStrings[STR_SCAN_TYPE_SIZE_DATE_VERSION],
 
322
                  ScanType, ScanSize, date, version);
 
323
               (**output).add_Item( Buffer );
 
324
            }
 
325
            ScanOffset = 0L;
 
326
            ScanSize = 0L;
 
327
            ScanYear = 0;
 
328
            ScanState = 0;
 
329
            ScanFwId = 0L;
 
330
            ScanMonth = 0;
 
331
            ScanDay = 0;
 
332
            memset (ScanBuild, 0, sizeof(ScanBuild));
 
333
            memset (ScanVersion, 0, sizeof(ScanVersion));
 
334
            memset (ScanType, 0, sizeof(ScanType));
 
335
         }
 
336
      }
 
337
 
 
338
   ScanOffset = InitialOffset;
 
339
   strcpy ( (char *)ScanType, (const char *)InitialType );
 
340
 
 
341
   Init_Engine(1); // only scan hbas
 
342
 
 
343
   (**output).add_Item(EventStrings[STR_LIST_DEV_CTLR_HEADER]);
 
344
   (**output).add_Item( STR_DEV_DIVIDING_LINE );
 
345
 
 
346
   bool anyControllerFound = false;
 
347
   bool more_Devs_Left  = true;
 
348
   bool flashedData = false;
 
349
 
 
350
   for (int dev_Index = 0; more_Devs_Left; dev_Index++)
 
351
   {
 
352
           DPT_TAG_T tempHbaTag=Get_HBA_by_Index(dev_Index, &more_Devs_Left);
 
353
      if (more_Devs_Left)
 
354
                  hbaTag = tempHbaTag;
 
355
      else
 
356
         break;
 
357
 
 
358
          if (( hba_Num == -1 ) || ( hba_Num == dev_Index ))
 
359
      {
 
360
         anyControllerFound = true;
 
361
         // if this is firmware, make sure the image matches the hba
 
362
         if (!memcmp(ScanType, EventStrings[STR_FIRMWARE], 8))
 
363
         {
 
364
            // find out the hba type
 
365
            err = engine->Send( MSG_GET_INFO, hbaTag );
 
366
            uSHORT fwType = engine->hbaInfo_P->fwType;
 
367
            char tempStr[7];
 
368
            memset (tempStr, 0, sizeof(tempStr));
 
369
            memcpy (tempStr, Strip_Trailing_Whitespace(engine->devInfo_P->productID), sizeof(tempStr));
 
370
            tempStr[6] = '\0';
 
371
 
 
372
                        err = PrintHBA(**output);
 
373
            if (err.Success())
 
374
            {
 
375
                                if (ScanFwType != 0L)
 
376
                                {
 
377
                                        if (ScanFwType != fwType)
 
378
                                        {
 
379
                                                err = Dpt_Error::DPT_CMD_ERR_INVALID_FLASH_IMAGE;
 
380
                                                (**output).add_Item(EventStrings[STR_FILE_NOT_MATCH_HBA]);
 
381
                                                continue;
 
382
                                        }
 
383
                                        
 
384
                                }
 
385
                else if (((tempStr[0] == '1') || (tempStr[0] == '2') ||
 
386
                                        (tempStr[0] == '3') || (tempStr[0] == '5')) &&
 
387
                                        (tempStr[3] == '0'))
 
388
                                {
 
389
                                        // The second digit matters if it's 2XXX series (ie. Pimento = 2400, Catapult = 2100) E.E. 3/5/2001
 
390
                                        if (ScanDescriptionHba[1] != 'M' && ScanDescriptionHba[0] != '2')
 
391
                                        {
 
392
                                                tempStr[1] = ScanDescriptionHba[1];
 
393
                                        }
 
394
                                        tempStr[5] = '\0';
 
395
                                        
 
396
                                        if (!ValidFlashFileForController(ScanDescriptionHba, tempStr))
 
397
                                        {
 
398
                                                err = Dpt_Error::DPT_CMD_ERR_INVALID_FLASH_IMAGE;
 
399
                                                (**output).add_Item(EventStrings[STR_FILE_NOT_MATCH_HBA]);
 
400
                                                continue;
 
401
                                        }
 
402
                                }
 
403
               
 
404
            }
 
405
         }
 
406
         else
 
407
         {
 
408
            err = PrintHBA(**output);
 
409
         }
 
410
 
 
411
         if (err.Success())
 
412
         {
 
413
            err |= Flash_This_HBA( **output, firmwareStream );
 
414
            flashedData = true;
 
415
                        break;
 
416
         }
 
417
      }
 
418
   }
 
419
 
 
420
   if (!anyControllerFound)
 
421
   {
 
422
      err = Dpt_Error::DPT_CMD_ERR_CANT_FIND_HBA_INDEX;
 
423
      (**output).add_Item(EventStrings[STR_CTLR_NOT_FOUND]);
 
424
   }
 
425
 
 
426
   if (flashedData)
 
427
   {
 
428
      if (err.Success())
 
429
      {
 
430
         (**output).add_Item(EventStrings[STR_FLASH_COMPLETE]);
 
431
      }
 
432
 
 
433
          if (inMode0)
 
434
      {
 
435
         (**output).add_Item(EventStrings[STR_REBOOT]);
 
436
                 (**output).add_Item(EventStrings[STR_REMMODEZERO]);
 
437
      }
 
438
      if (Resync)
 
439
      {
 
440
         Dpt_Error err2;
 
441
                 engine->Reset();
 
442
         engine->Insert ((uLONG) 0x01); // perform a complete init
 
443
         err2 = engine->Send (MSG_I2O_RESYNC, hbaTag);
 
444
         if (err2.Success()){
 
445
                         PrintHBA(**output);
 
446
            (**output).add_Item(EventStrings[STR_RESYNC_SUCCESS_NO_REBOOT]);
 
447
                 }
 
448
         else if (err2 == Dpt_Error::DPT_MSG_RTN_IGNORED)
 
449
            (**output).add_Item(EventStrings[STR_RESYNC_NOT_SUPPORTED_REBOOT]);
 
450
         else
 
451
            (**output).add_Item(EventStrings[STR_RESYNC_FAILED_REBOOT]);
 
452
      }
 
453
   }
 
454
 
 
455
   Flush ( *output );
 
456
 
 
457
   EXIT();
 
458
   return( err );
 
459
}
 
460
 
 
461
 
 
462
 
 
463
bool Flash::ValidFlashFileForController(
 
464
   const char *fileDescriptionModel,
 
465
   const char *controllerModel
 
466
   ) const
 
467
{
 
468
 
 
469
        bool validFlashFileForController = false;
 
470
        
 
471
        // Do the special case check if the two are the same then there is a match.
 
472
        if (strcmp(fileDescriptionModel, controllerModel) == 0)
 
473
        {
 
474
                validFlashFileForController = true;
 
475
        }
 
476
        else
 
477
        {
 
478
                // Loop through the mappings looking for a controller model that matches the controller
 
479
                // model specified.
 
480
                for (unsigned mapIndex = 0; mapIndex < sizeof(modelMappings)/sizeof(modelMappings[0]); mapIndex++)
 
481
                {
 
482
                        if (strcmp(modelMappings[mapIndex].controllerModel, controllerModel) == 0)
 
483
                        {
 
484
                                if (strcmp(modelMappings[mapIndex].fileDescriptionModel, fileDescriptionModel) == 0)
 
485
                                {
 
486
                                        validFlashFileForController = true;
 
487
                                        break;
 
488
                                }
 
489
                        }
 
490
                }
 
491
 
 
492
                #if defined _DPT_DOS
 
493
                if ((validFlashFileForController == false) && (inMode0 == true))
 
494
                {
 
495
                #if defined _DPT_LEGACY // dptutil (only DOS/dptutil defines _DPT_LEGACY)
 
496
                        if ((strcmp(controllerModel, "PM2865") == 0) &&
 
497
                        (fileDescriptionModel[0] == '3') &&
 
498
                        (fileDescriptionModel[2] == '0') && (fileDescriptionModel[3] == '0'))
 
499
                        validFlashFileForController = true;
 
500
                #else // raidutil
 
501
                        if ((strcmp(fileDescriptionModel, "PM2865") == 0) &&
 
502
                        (controllerModel[0] == '3') &&
 
503
                        (controllerModel[2] == '0') && (controllerModel[3] == '0'))
 
504
                        validFlashFileForController = true;
 
505
                #endif
 
506
                }
 
507
                #endif
 
508
        }
 
509
 
 
510
        // Return to the caller.
 
511
        return(validFlashFileForController);
 
512
}
 
513
 
 
514
//      The mother of all state machines.
 
515
//      This state machine will return a value of 1 if all the information
 
516
//      about the file has been determined. The information is the Offset
 
517
//      expected within the flash region, the size of the image (so we could
 
518
//      reset and look at a concatonated image) and the version of the
 
519
//      image.
 
520
int Flash::DetermineOffset(int c)
 
521
{
 
522
   switch (ScanState)
 
523
   {
 
524
      case 0:
 
525
         ScanOffset = 0L;
 
526
         ScanSize = FLASH_FIRMWARE_SIZE;
 
527
         if (c == 0x55)
 
528
         {
 
529
            ScanOffset = 180224L;       // EATA Card
 
530
            (void)strcpy ((char *)ScanType, "SMOR");
 
531
            ++ScanState;
 
532
            break;
 
533
         }
 
534
         if (c == 0x5A)
 
535
         {        // SMOR image
 
536
            ScanOffset = 819200L;       // I2O Card
 
537
            (void)strcpy ((char *)ScanType, "SMOR");
 
538
            ScanState = 17;
 
539
            break;
 
540
         }
 
541
         ScanState = 21;
 
542
         break;
 
543
      case 1:
 
544
         if (c == 0xAA)
 
545
         {        // ROM image, or SMOR compressed image
 
546
            ++ScanState;
 
547
            break;
 
548
         }
 
549
         ScanState = 21;
 
550
         break;
 
551
      case 2:
 
552
         ScanSize = (unsigned long)c;
 
553
         if ((c < 16) || (128 < c) || ((c & 7) != 0))
 
554
         {
 
555
            ScanState = 156; // SMOR compressed image or FCODE image
 
556
         }
 
557
         else
 
558
         {
 
559
            ScanState = 149; // ROM image or SMOR compressed image
 
560
         }
 
561
         break;
 
562
      case 4:
 
563
         if (c == 'v')
 
564
         {
 
565
            ++ScanState;
 
566
            break;
 
567
         }
 
568
         --ScanState;
 
569
         // FALLTHRU
 
570
      case 3:
 
571
         if (c == ' ')
 
572
         {
 
573
            ++ScanState;
 
574
         }
 
575
         break;
 
576
      case 5: // ' v0'
 
577
      case 6: // ' v00'
 
578
      case 7: // ' v00X'
 
579
      case 8: // ' v00X.'
 
580
      case 9: // ' v00X.X'
 
581
         ScanVersion[ScanState-5] = c;
 
582
         ++ScanState;
 
583
         break;
 
584
      case 10:// ' v00X.XX'
 
585
         ScanVersion[5] = c;
 
586
         ScanVersion[6] = '\0';
 
587
         ++ScanState;
 
588
         break;
 
589
      case 11:
 
590
         if (c == ' ')
 
591
         {
 
592
            break;
 
593
         }
 
594
         if (c == '(')
 
595
         {
 
596
            ScanYear = 0;
 
597
            ++ScanState;
 
598
            break;
 
599
         }
 
600
         ScanState = 133;
 
601
         return(1);
 
602
      case 12:
 
603
         if (('0' <= c) && (c <= '9'))
 
604
         {
 
605
            ScanYear *= 10;
 
606
            ScanYear += c - '0';
 
607
            break;
 
608
         }
 
609
         if (c == '/')
 
610
         {
 
611
            ScanMonth = 0;
 
612
            if (ScanYear <= 12)
 
613
            {
 
614
               ScanMonth = (unsigned char)ScanYear;
 
615
               ScanState += 2;
 
616
            }
 
617
            ++ScanState;
 
618
            break;
 
619
         }
 
620
         ScanState = 133;
 
621
         return(1);
 
622
      case 13:
 
623
         if (('0' <= c) && (c <= '9'))
 
624
         {
 
625
            ScanMonth *= 10;
 
626
            ScanMonth += c - '0';
 
627
            break;
 
628
         }
 
629
         if (c == '/')
 
630
         {
 
631
            ScanDay = 0;
 
632
            ++ScanState;
 
633
         }
 
634
      case 14:
 
635
         if (('0' <= c) && (c <= '9'))
 
636
         {
 
637
            ScanDay *= 10;
 
638
            ScanDay += c - '0';
 
639
            break;
 
640
         }
 
641
         ScanState = 133;        // BIOS rom has no build number (yet)
 
642
         return(1);
 
643
      case 15:
 
644
         if (('0' <= c) && (c <= '9'))
 
645
         {
 
646
            ScanDay *= 10;
 
647
            ScanDay += c - '0';
 
648
            break;
 
649
         }
 
650
         ScanYear = 0;
 
651
         ++ScanState;
 
652
         break;
 
653
      case 16:
 
654
         if (('0' <= c) && (c <= '9'))
 
655
         {
 
656
            ScanYear *= 10;
 
657
            ScanYear += c - '0';
 
658
            break;
 
659
         }
 
660
         ScanState = 133;        // BIOS rom has no build number (yet)
 
661
         return(1);
 
662
      case 17:                 // Image
 
663
         if (c != 0x55)
 
664
         {
 
665
            ScanState = 21;     // Some random image ...
 
666
            break;
 
667
         }
 
668
         ++ScanState;
 
669
         break;
 
670
      case 18:
 
671
         ScanSize = (unsigned long)c;
 
672
         ++ScanState;
 
673
         break;
 
674
      case 19:    // SMOR image
 
675
      case 149:   // ROM Image or SMOR compressed image
 
676
      case 156:   // SMOR compressed image
 
677
         ScanSize |= (unsigned long)((unsigned)c << 8);
 
678
         ++ScanState;
 
679
         break;
 
680
      case 20:    // SMOR image
 
681
      case 150:   // ROM image or SMOR compressed image
 
682
      case 157:   // SMOR compressed image
 
683
         ScanSize |= ((unsigned long)c) << 16L;
 
684
         ++ScanState;
 
685
         break;
 
686
      case 158:   // SMOR compressed image
 
687
         ScanSize |= ((unsigned long)c) << 24L;
 
688
         ScanState = 196;
 
689
         break;
 
690
      case 196:
 
691
         if (c != '\0')
 
692
         {  // Could be an FCODE image?
 
693
            ScanSize += 16;
 
694
            ScanState = 21;   // unlikely that a SMOR compressed image could
 
695
            break;          // acquire the DPTSIG structure, but hey!
 
696
         }
 
697
         ScanState = 159;  // FCODE image;
 
698
         break;
 
699
      case 159:
 
700
      case 160:
 
701
      case 161: // SMOR compressed image or FCODE image?
 
702
         if (c != '\0')
 
703
         {
 
704
            ScanSize += 16;
 
705
            ScanState = 21;   // SMOR compressed image.
 
706
            break;
 
707
         }
 
708
         ++ScanState;
 
709
         break;
 
710
      case 162:
 
711
         ScanSize = 0;
 
712
         (void)strcpy ((char *)ScanType, "?");
 
713
      case 163:
 
714
      case 164:
 
715
      case 165:
 
716
      case 166:
 
717
      case 167:
 
718
      case 168:
 
719
      case 169:
 
720
      case 170:
 
721
      case 171:
 
722
      case 172:
 
723
      case 173:
 
724
      case 174:
 
725
      case 175:
 
726
      case 177:
 
727
         if (c != '\0')
 
728
         {
 
729
            ScanState = 21;
 
730
            break;
 
731
         }
 
732
         ++ScanState;
 
733
         break;
 
734
      case 176:
 
735
         if (c != '\032')
 
736
         {
 
737
            ScanState = 21;
 
738
            break;
 
739
         }
 
740
         ++ScanState;
 
741
         break;
 
742
      case 178:
 
743
         if (c != 'P')
 
744
         {
 
745
            ScanState = 21;
 
746
            break;
 
747
         }
 
748
         ++ScanState;
 
749
         break;
 
750
      case 179:
 
751
         if (c != 'C')
 
752
         {
 
753
            ScanState = 21;
 
754
            break;
 
755
         }
 
756
         ++ScanState;
 
757
         break;
 
758
      case 180:
 
759
         if (c != 'I')
 
760
         {
 
761
            ScanState = 21;
 
762
            break;
 
763
         }
 
764
         ++ScanState;
 
765
         break;
 
766
      case 181:
 
767
         if (c != 'R')
 
768
         {
 
769
            ScanState = 21;
 
770
            break;
 
771
         }
 
772
      case 182:
 
773
      case 183:
 
774
      case 184:
 
775
      case 185:
 
776
      case 186:
 
777
      case 187:
 
778
      case 188:
 
779
      case 189:
 
780
      case 190:
 
781
      case 191:
 
782
      case 192:
 
783
      case 193:
 
784
         ++ScanState;
 
785
         break;
 
786
      case 194:   // FCODE length
 
787
         (void)strcpy((char *)ScanType, "FCODE");
 
788
         ScanOffset = FLASH_BIOS_OFFSET;       // I2O Card
 
789
         ScanSize = (unsigned long)c;
 
790
         ++ScanState;
 
791
         break;
 
792
      case 195:   // FCODE length
 
793
         ScanSize |= ((unsigned long)c) << 8L;
 
794
         ScanSize <<= 9;
 
795
         ScanState = 21;   // See if we can get more from a concatenated SIG
 
796
         break;
 
797
      case 151:   // ROM image or SMOR compressed image
 
798
         ScanSize |= ((unsigned long)c) << 24L;
 
799
         ++ScanState;
 
800
         break;
 
801
      case 152:   // ROM image or SMOR compressed image
 
802
         if (c == '\0')
 
803
         {     // SMOR compressed image or FCODE image?
 
804
            ScanState = 159;
 
805
            break;
 
806
         }
 
807
         if (c != 'S')
 
808
         {
 
809
            ScanSize += 16;
 
810
            ScanState = 21;     // SMOR compressed image
 
811
            break;
 
812
         }
 
813
         ++ScanState;
 
814
         break;
 
815
      case 153:   // ROM image
 
816
      case 154:   // ROM image
 
817
         if (c != ' ')
 
818
         {
 
819
            ScanSize += 16;
 
820
            ScanState = 21;     // SMOR compressed image
 
821
            break;
 
822
         }
 
823
         ++ScanState;
 
824
         break;
 
825
      case 155:   // ROM image
 
826
         if (c != '\0')
 
827
         {
 
828
            ScanSize += 16;
 
829
            ScanState = 21;     // SMOR compressed image
 
830
            break;
 
831
         }
 
832
         ScanSize = (ScanSize & 0xFF) * BYTES_PER_TRANSFER;
 
833
         if (ScanSize > 16384L)
 
834
         {
 
835
            ScanOffset = FLASH_BIOS_OFFSET;  // I2O Card
 
836
         }
 
837
         else
 
838
         {
 
839
            ScanOffset = 163840L;       // EATA Card
 
840
         }
 
841
         strcpy ((char *)ScanType, "BIOS");
 
842
         ScanState = 3;          // Get the ROM signature if we can!
 
843
         break;
 
844
      case 22:
 
845
         if (c == 'P')
 
846
         {
 
847
            ++ScanState;
 
848
            break;
 
849
         }
 
850
         // FALLTHRU
 
851
      case 21: // Search for DPTSIG
 
852
         reset:
 
853
         ScanState = 21;
 
854
         if (c == 'd')
 
855
         {
 
856
            ++ScanState;
 
857
         }
 
858
         break;
 
859
      case 23:
 
860
         if (c != 't')
 
861
         {
 
862
            goto reset;
 
863
         }
 
864
         ++ScanState;
 
865
         break;
 
866
      case 24:
 
867
         if (c != 'S')
 
868
         {
 
869
            goto reset;
 
870
         }
 
871
         ++ScanState;
 
872
         break;
 
873
      case 25:
 
874
         if (c != 'i')
 
875
         {
 
876
            goto reset;
 
877
         }
 
878
         ++ScanState;
 
879
         break;
 
880
      case 26:
 
881
         if (c != 'G')
 
882
         {
 
883
            goto reset;
 
884
         }
 
885
         ++ScanState;
 
886
         break;
 
887
      case 28:                                // dsProcessorFamily
 
888
         if ((c == PROC_i960)               // i960
 
889
          || (c == PROC_MIPS))              // MIPS
 
890
         {
 
891
            ScanOffset = 0L;                //  Make doubly sure it
 
892
            (void)strcpy ((char *)ScanType, EventStrings[STR_FIRMWARE]);
 
893
         }                                   //  resides in firmware
 
894
         m_FlashFileProcessorFamily = c;
 
895
      case 27:                                // dsSigVersion
 
896
      case 29:                                // dsProcessor
 
897
      case 31:                                // dsFiletypeFlags
 
898
      case 32:                                // dsOEM
 
899
      case 33:
 
900
      case 34:
 
901
      case 35:
 
902
      case 36:     // dsOS
 
903
      case 37:
 
904
      case 38:                       // dsCapabilities
 
905
      case 39:
 
906
      case 40:                       // dsDeviceSupp
 
907
      case 41:
 
908
      case 42:                       // dsAdapterSupp
 
909
      case 45:                                // dsRequirements
 
910
         ++ScanState;
 
911
         break;
 
912
      case 30:                                // dsFileType
 
913
         if (c == FT_FIRMWARE)
 
914
         {
 
915
            ScanOffset = 0L;                //  Make doubly sure it
 
916
            (void)strcpy ((char *)ScanType, EventStrings[STR_FIRMWARE]);
 
917
         }
 
918
         /* More FT_ flags should be used. */
 
919
         ++ScanState;
 
920
         break;
 
921
      case 43:
 
922
         loadInfo = c;
 
923
         ++ScanState;
 
924
         break;
 
925
      case 44:                                // dsApplication
 
926
         loadInfo |= (c << 8);
 
927
         ++ScanState;
 
928
         break;
 
929
      case 46:                                // dsVersion
 
930
         ScanVersion[0] = (c / 100) + '0';
 
931
         ScanVersion[1] = ((c / 10) % 10) + '0';
 
932
         ScanVersion[2] = (c % 10) + '0';
 
933
         ScanVersion[3] = '.';
 
934
         ++ScanState;
 
935
         break;
 
936
      case 47:                                // dsRevision
 
937
         ScanVersion[4] = c;
 
938
         ++ScanState;
 
939
         break;
 
940
      case 48:                                // dsSubRevision
 
941
         ScanVersion[5] = c;
 
942
         ScanVersion[6] = '\0';
 
943
         ++ScanState;
 
944
         break;
 
945
      case 49:                                // dsMonth
 
946
         ScanMonth = c;
 
947
         ++ScanState;
 
948
         break;
 
949
      case 50:                                // dsDay
 
950
         ScanDay = c;
 
951
         ++ScanState;
 
952
         break;
 
953
      case 51:                                // dsYear
 
954
         ScanYear = c + 1980;
 
955
         ++ScanState;
 
956
         break;
 
957
      case 52:                                // dsDescription
 
958
         if (( c == 'P' ) || ( c == 'p' ))
 
959
         {
 
960
//         ScanDescriptionHba[0] = 'P';
 
961
            ScanDescriptionHba[ScanDescrIdx++] = 'P';
 
962
            ++ScanState;
 
963
            break;
 
964
         }
 
965
      case 53:
 
966
         if (( c == 'M' ) || ( c == 'm' ))
 
967
         {
 
968
//                      ScanDescriptionHba[1] = 'M';
 
969
            ScanDescriptionHba[ScanDescrIdx++] = 'M';
 
970
            ++ScanState;
 
971
            break;
 
972
         }
 
973
      case 54:
 
974
         if (isdigit(c))
 
975
         {
 
976
//                      ScanDescriptionHba[2] = c;
 
977
            ScanDescriptionHba[ScanDescrIdx++] = c;
 
978
            ++ScanState;
 
979
            break;
 
980
         }
 
981
      case 55:
 
982
         if (isdigit(c))
 
983
         {
 
984
//                      ScanDescriptionHba[3] = c;
 
985
            ScanDescriptionHba[ScanDescrIdx++] = c;
 
986
            ++ScanState;
 
987
            break;
 
988
         }
 
989
      case 56:
 
990
                  {
 
991
                 if (isdigit(c))
 
992
 
 
993
 //                     ScanDescriptionHba[4] = c;
 
994
            ScanDescriptionHba[ScanDescrIdx++] = c;
 
995
 
 
996
                 else if (c == 'A' || c == 'a')
 
997
                         ScanDescriptionHba[ScanDescrIdx++] = 'A';
 
998
                 else if (c == 'S' || c == 's')
 
999
                         ScanDescriptionHba[ScanDescrIdx++] = 'S';
 
1000
 
 
1001
                        ++ScanState;
 
1002
            break;
 
1003
                }
 
1004
      case 57:
 
1005
         if (isdigit(c))
 
1006
         {
 
1007
//                      ScanDescriptionHba[5] = c;
 
1008
            ScanDescriptionHba[ScanDescrIdx++] = c;
 
1009
            ++ScanState;
 
1010
            break;
 
1011
         }
 
1012
      case 58:
 
1013
      case 59:
 
1014
      case 60:
 
1015
      case 61:
 
1016
      case 62:
 
1017
      case 63:
 
1018
      case 64:
 
1019
      case 65:
 
1020
      case 66:
 
1021
      case 67:
 
1022
      case 68:
 
1023
      case 69:
 
1024
      case 70:
 
1025
      case 71:
 
1026
      case 72:
 
1027
      case 73:
 
1028
      case 74:
 
1029
      case 75:
 
1030
      case 76:
 
1031
      case 77:
 
1032
      case 78:
 
1033
      case 79:
 
1034
      case 80:
 
1035
      case 81:
 
1036
      case 82:
 
1037
      case 83:
 
1038
      case 84:
 
1039
      case 85:
 
1040
      case 86:
 
1041
      case 87:
 
1042
      case 88:
 
1043
      case 89:
 
1044
      case 90:
 
1045
      case 91:
 
1046
      case 92:
 
1047
      case 93:
 
1048
      case 94:
 
1049
      case 95:
 
1050
      case 96:
 
1051
      case 97:
 
1052
      case 98:
 
1053
      case 99:
 
1054
      case 100:
 
1055
      case 101:
 
1056
      case 102:
 
1057
      case 103:
 
1058
      case 104:
 
1059
      case 105:
 
1060
      case 106:
 
1061
      case 107:
 
1062
      case 108:
 
1063
      case 109:
 
1064
      case 110:
 
1065
      case 111:
 
1066
      case 112:
 
1067
      case 113:
 
1068
      case 114:
 
1069
      case 115:
 
1070
      case 116:
 
1071
      case 117:
 
1072
      case 118:
 
1073
      case 119:
 
1074
      case 120:
 
1075
      case 121:
 
1076
      case 122:
 
1077
      case 123:
 
1078
      case 124:
 
1079
      case 125:
 
1080
      case 126:
 
1081
      case 127:
 
1082
      case 128:
 
1083
      case 129:
 
1084
      case 130:
 
1085
      case 131:
 
1086
      case 132:
 
1087
         if (c == '\0')
 
1088
         {
 
1089
             ScanState = 198;
 
1090
             break;
 
1091
         }
 
1092
         if ((c == 'b') || (c == 'B'))
 
1093
         {
 
1094
            ScanState = 134;
 
1095
            break;
 
1096
         }
 
1097
         if (c == 'V')
 
1098
         {
 
1099
            ScanState = 144;
 
1100
            break;
 
1101
         }
 
1102
         ++ScanState;
 
1103
         break;
 
1104
      case 134:
 
1105
         if (c == 'u')
 
1106
         {
 
1107
            ++ScanState;
 
1108
            break;
 
1109
         }
 
1110
         ScanState = 60;
 
1111
         break;
 
1112
      case 135:
 
1113
         if (c == 'i')
 
1114
         {
 
1115
            ++ScanState;
 
1116
            break;
 
1117
         }
 
1118
         ScanState = 61;
 
1119
         break;
 
1120
      case 136:
 
1121
         if (c == 'l')
 
1122
         {
 
1123
            ++ScanState;
 
1124
            break;
 
1125
         }
 
1126
         ScanState = 62;
 
1127
         break;
 
1128
      case 137:
 
1129
         if (c == 'd')
 
1130
         {
 
1131
            ++ScanState;
 
1132
            break;
 
1133
         }
 
1134
         ScanState = 63;
 
1135
         break;
 
1136
      case 138:
 
1137
         if (c == ' ')
 
1138
         {
 
1139
            ++ScanState;
 
1140
            break;
 
1141
         }
 
1142
         ScanState = 64;
 
1143
         break;
 
1144
      case 139:
 
1145
      case 140:
 
1146
      case 141:
 
1147
      case 142:
 
1148
         if (('0' <= c) && (c <= '9'))
 
1149
         {
 
1150
            ScanBuild[ScanState - 139] = c;
 
1151
            ++ScanState;
 
1152
            break;
 
1153
         }
 
1154
      case 143:
 
1155
         // Convert Build Number to Base 36 value within version string.
 
1156
         {   unsigned char * cp = ScanBuild;
 
1157
            unsigned short  Value = 0;
 
1158
 
 
1159
            while (*cp)
 
1160
            {
 
1161
               Value *= 10;
 
1162
               Value += *cp - '0';
 
1163
               ++cp;
 
1164
            }
 
1165
            // we will overflow at 1296 builds, Historically we manage up
 
1166
            // to about 150 builds before the revision is bumped.
 
1167
            ScanVersion[5] = (Value / 36) + '0';
 
1168
            ScanVersion[6] = (Value % 36) + '0';
 
1169
         }
 
1170
         if (ScanVersion[6] > '9')
 
1171
         {
 
1172
            ScanVersion[6] += 'A' - '9' - 1;
 
1173
         }
 
1174
         if (ScanVersion[5] > '9')
 
1175
         {
 
1176
            ScanVersion[5] += 'A' - '9' - 1;
 
1177
         }
 
1178
         ScanVersion[7] = '\0';
 
1179
         ScanBuild[0] = '\0';
 
1180
         ScanState = 69;
 
1181
         break;
 
1182
      case 197: // Look for the end of the description string.
 
1183
         if (c == '\0') {
 
1184
            ScanState = 198;
 
1185
         }
 
1186
         break;
 
1187
      case 198: // End of the Description String means FwId is here?
 
1188
         if (c == 'F')
 
1189
         {
 
1190
             ++ScanState;
 
1191
             break;
 
1192
         }
 
1193
         ScanState = 133;
 
1194
      case 133: // Ignore remaining, allows us to count size now.
 
1195
         return(1);
 
1196
      case 199: // Discovered the F where we expect the FwId signature.
 
1197
         if (c == 'w')
 
1198
         {
 
1199
             ++ScanState;
 
1200
             break;
 
1201
         }
 
1202
         ScanState = 133;
 
1203
         return (1);
 
1204
      case 200: // Discovered the Fw where we expect the FwId signature.
 
1205
         if (c == 'I')
 
1206
         {
 
1207
             ++ScanState;
 
1208
             break;
 
1209
         }
 
1210
         ScanState = 133;
 
1211
         return (1);
 
1212
      case 201: // Discovered the FwI where we expect the FwId signature.
 
1213
         if (c == 'd')
 
1214
         {
 
1215
             ++ScanState;
 
1216
             break;
 
1217
         }
 
1218
         ScanState = 133;
 
1219
         return (1);
 
1220
      case 202:
 
1221
         ScanFwId = c;
 
1222
         ++ScanState;
 
1223
         break;
 
1224
      case 203:
 
1225
         ScanFwId |= (unsigned short)c << 8;
 
1226
         ++ScanState;
 
1227
         break;
 
1228
      case 204:
 
1229
         ScanFwId |= (unsigned long)c << 16;
 
1230
         ++ScanState;
 
1231
         break;
 
1232
      case 205:
 
1233
         ScanFwId |= (unsigned long)c << 24;
 
1234
         ScanState = 133;
 
1235
         break;
 
1236
      case 144:
 
1237
         if ((('0' <= c) && (c <= '9')) || (c == '.'))
 
1238
         {
 
1239
            break;
 
1240
         }
 
1241
         if (c == '/')
 
1242
         {
 
1243
            ++ScanState;
 
1244
            break;
 
1245
         }
 
1246
         ScanState = 60;
 
1247
         break;
 
1248
      case 145:
 
1249
      case 146:
 
1250
      case 147:
 
1251
      case 148:
 
1252
         if ((('0' <= c) && (c <= '9'))
 
1253
            || (('A' <= c) && (c <= 'F')))
 
1254
         {
 
1255
            ScanBuild[ScanState - 145] = c;
 
1256
            ++ScanState;
 
1257
            break;
 
1258
         }
 
1259
         ScanState = 197;
 
1260
         break;
 
1261
   }
 
1262
   return(0);
 
1263
}
 
1264
 
 
1265
Command::Dpt_Error Flash::GetFlashStatus(
 
1266
   dptFlashStatus_S &flashStatus
 
1267
   )
 
1268
{
 
1269
   // Send the command to the engine to get the flash status of the
 
1270
   // associated controller.
 
1271
   engine->Reset();
 
1272
   Dpt_Error status = engine->Send(MSG_FLASH_STATUS, hbaTag);
 
1273
 
 
1274
   // If the command succeeded then extract the returned data.
 
1275
   if (status.Success())
 
1276
   {
 
1277
      // There really should be a structure which describes ALL
 
1278
      // of the data returned by this command.  Like so many other
 
1279
      // things this was apparently just hacked together (sigh...)
 
1280
      uLONG ioOffset, fwStatus;
 
1281
      engine->Extract(&ioOffset, sizeof(ioOffset));
 
1282
      engine->Extract(&fwStatus, sizeof(fwStatus));
 
1283
      engine->Extract(&flashStatus, sizeof(flashStatus));
 
1284
   }
 
1285
 
 
1286
   // Return the status to the caller.
 
1287
   return(status);
 
1288
}
 
1289
 
 
1290
 
 
1291
Command::Dpt_Error Flash::SetFlashRegion(
 
1292
   FlashRegion region
 
1293
   )
 
1294
{
 
1295
   // Send the command to the engine to set the region of flash memory to use.
 
1296
   engine->Reset();
 
1297
   engine->Insert((uLONG) region);
 
1298
   engine->Insert((uLONG) loadInfo);
 
1299
   engine->Insert((uLONG) imageSize);
 
1300
   Dpt_Error status = engine->Send(MSG_FLASH_SET_REGION, hbaTag);
 
1301
 
 
1302
   // Return the status to the caller.
 
1303
   return(status);
 
1304
}
 
1305
 
 
1306
 
 
1307
Command::Dpt_Error Flash::ReadFlashMemory(
 
1308
   void *buf,
 
1309
   uLONG offset,
 
1310
   uLONG bytesToRead
 
1311
   )
 
1312
{
 
1313
   // Send the command to the engine to read the flash memory.
 
1314
   engine->Reset();
 
1315
   engine->Insert(offset);
 
1316
   engine->Insert(bytesToRead);
 
1317
   Dpt_Error status = engine->Send(MSG_FLASH_READ, hbaTag);
 
1318
 
 
1319
   // If the read succeeded then copy the data that was read from the flash
 
1320
   // memory into the caller's buffer.
 
1321
   if (status.Success())
 
1322
   {
 
1323
      engine->Extract(buf, bytesToRead);
 
1324
   }
 
1325
 
 
1326
   // Return the status to the caller.
 
1327
   return(status);
 
1328
}
 
1329
 
 
1330
 
 
1331
Command::Dpt_Error Flash::WriteFlashMemory(
 
1332
   void *buf,
 
1333
   uLONG bytesToWrite
 
1334
   )
 
1335
{
 
1336
   // Send the command to the engine to read the flash memory.
 
1337
   engine->Reset();
 
1338
   engine->Insert(buf, bytesToWrite);
 
1339
   Dpt_Error status = engine->Send(MSG_FLASH_WR_NO_VERIFY, hbaTag);
 
1340
 
 
1341
   // Return the status to the caller.
 
1342
   return(status);
 
1343
}
 
1344
 
 
1345
 
 
1346
Command::Dpt_Error Flash::WriteFlashMemoryDone(
 
1347
   bool failed
 
1348
   )
 
1349
{
 
1350
   // Send the command to the engine to stop writing flash memory.
 
1351
   engine->Reset();
 
1352
   if (failed)
 
1353
   {
 
1354
      engine->Insert((uCHAR) 1);
 
1355
   }
 
1356
 
 
1357
   Dpt_Error status = engine->Send(MSG_FLASH_WRITE_DONE, hbaTag);
 
1358
 
 
1359
   // Return the status to the caller.
 
1360
   return(status);
 
1361
}
 
1362
 
 
1363
//------------------------------------------------------------------//
 
1364
//                                                                                                                                      //
 
1365
// START OF BIG KLUDGE                                                                                          //
 
1366
//                                                                                                                                      //
 
1367
// Because the 2865 has such a large region for firmware there are      //
 
1368
// several different sizes of firmware files.  Because of how the       //
 
1369
// 2865 is implemented if a firmware file smaller than the total        //
 
1370
// firmware address space of the controller (~1.5MB) is flashed the     //
 
1371
// image that is flashed must be adjusted so that it is aligned         //
 
1372
// with the end of the firmware region, not the beginning.  Because     //
 
1373
// the engine provides no mechanism for seeking when writing to         //
 
1374
// flash the code will read data and then write that data back to       //
 
1375
// the same location.  This makes flashing faster because the flash //
 
1376
// chip won't have to really do anything in that situation.             //
 
1377
//                                                                                                                                      //
 
1378
//------------------------------------------------------------------//
 
1379
Command::Dpt_Error Flash::GetStartingFlashIndex(
 
1380
   const FlashRegion flashRegion,
 
1381
   const uLONG imageSize,
 
1382
   const int flashFileProcessorFamily,
 
1383
   uLONG &startingIndex
 
1384
   )
 
1385
{
 
1386
   Dpt_Error status;
 
1387
 
 
1388
   // Assume the starting index is 0.  Its a special case if its not.
 
1389
   startingIndex = 0;
 
1390
 
 
1391
   // This is only an issue when flashing firmware.
 
1392
   if (( flashRegion == FW ) && (loadInfo & FW_LOAD_TOP))
 
1393
   {
 
1394
      // Get the flash status of the controller.  This contains a field which
 
1395
      // has the size of the firmware region of flash memory.
 
1396
      dptFlashStatus_S flashStatus;
 
1397
      status = GetFlashStatus(flashStatus);
 
1398
 
 
1399
      if (status.Success())
 
1400
      {
 
1401
         // Need the 'burn size' field.  This field is misnamed - it is
 
1402
         // really the size of the firmware region of flash memory.
 
1403
         const uLONG firmwareSize = dptFlashStatus_getBurnSize(&flashStatus);
 
1404
         if (imageSize < firmwareSize)
 
1405
         {
 
1406
            // Calculate the starting index in flash memory.
 
1407
            startingIndex = firmwareSize - imageSize;
 
1408
         }
 
1409
      }
 
1410
   }
 
1411
 
 
1412
   // Return the status to the caller.
 
1413
   return(status);
 
1414
}
 
1415
 
 
1416
Command::Dpt_Error Flash::WriteSeekToIndex(
 
1417
   uLONG seekSize
 
1418
   )
 
1419
{
 
1420
   Dpt_Error status;
 
1421
 
 
1422
   // Create an I/O buffer and zero it out.
 
1423
   char ioBuf[BYTES_PER_TRANSFER];
 
1424
   memset(ioBuf, 0, sizeof(ioBuf));
 
1425
 
 
1426
   // Skip the necessary space by writing zeros up to the specified
 
1427
   // index.  It is ASSUMED that the index is a multiple of 512.
 
1428
   uLONG seekIndex = 0;
 
1429
   while (( status.Success() ) && ( seekIndex < seekSize ))
 
1430
   {
 
1431
      status = WriteFlashMemory(ioBuf, sizeof(ioBuf));
 
1432
      if (status.Success())
 
1433
      {
 
1434
         seekIndex += sizeof(ioBuf);
 
1435
      }
 
1436
   }
 
1437
 
 
1438
   // Return the status to the caller.
 
1439
   return(status);
 
1440
}
 
1441
//------------------------------------------------------------------//
 
1442
//                                                                                                                                      //
 
1443
// END OF BIG KLUDGE                                                                                            //
 
1444
//                                                                                                                                      //
 
1445
//------------------------------------------------------------------//
 
1446
 
 
1447
 
 
1448
 
 
1449
Command::Dpt_Error Flash::PrintHBA(
 
1450
   String_List &output
 
1451
   )
 
1452
{
 
1453
 
 
1454
   Dpt_Error   status;
 
1455
   const long  ONE_K = 1024;
 
1456
 
 
1457
 
 
1458
   status = engine->Send( MSG_GET_INFO, hbaTag );
 
1459
   if (status.Success())
 
1460
   {
 
1461
      dptCaddr_S *addr_P = &engine->devInfo_P->addr;
 
1462
      long cache_Size_in_Mb = -1;
 
1463
 
 
1464
      const int BUF_LEN = 256;
 
1465
      char temp_Buf[ BUF_LEN ];
 
1466
 
 
1467
      dptHBAinfo_S *hba_Info     = engine->hbaInfo_P;
 
1468
      long cache_Size_in_Kb;
 
1469
      cache_Size_in_Kb = hba_Info->memSize;
 
1470
      cache_Size_in_Mb = cache_Size_in_Kb / ONE_K / ONE_K;
 
1471
 
 
1472
 
 
1473
      sprintf ( temp_Buf, "d%d", addr_P->hba );
 
1474
      output.add_Item( temp_Buf );
 
1475
 
 
1476
      DPTControllerMap map;
 
1477
      for (int bus = 0; bus < 3; ++bus)
 
1478
      {
 
1479
         char * String = map.getChannelString(addr_P->hba, bus);
 
1480
 
 
1481
         output.add_Item( ( *String == 'c' ) ? String
 
1482
            : ( hba_Info->chanInfo[bus].flags ? "--" : "  " ));
 
1483
         delete [] String;
 
1484
      }
 
1485
 
 
1486
      output.add_Item(Strip_Trailing_Whitespace(engine->devInfo_P->vendorID));
 
1487
      output.add_Item(Strip_Trailing_Whitespace(engine->devInfo_P->productID));
 
1488
 
 
1489
      sprintf(temp_Buf, "%ld%s", cache_Size_in_Mb, EventStrings[STR_MB]);
 
1490
      output.add_Item(temp_Buf);
 
1491
      output.add_Item(hba_Info->revision);
 
1492
 
 
1493
      engine->Reset();
 
1494
      engine->Insert( (uCHAR)0x2E );   // NVRAM page
 
1495
      engine->Insert( (uCHAR)0x40 );   // Interpret and current
 
1496
 
 
1497
      // get the defaults page
 
1498
      status = engine->Send( MSG_GET_MODE_PAGE, hbaTag );
 
1499
 
 
1500
      temp_Buf[0] = '\0';
 
1501
      if (status.Success())
 
1502
      {
 
1503
         if (( engine->Extract( temp_Buf, 108 ) == 0 )
 
1504
            || ( engine->Extract( temp_Buf, 8 ) == 0 ))
 
1505
         {
 
1506
            temp_Buf[0] = '\0';
 
1507
         }
 
1508
         else
 
1509
         {
 
1510
            temp_Buf[8] = '\0';
 
1511
         }
 
1512
      }
 
1513
      else
 
1514
         inMode0 = true;
 
1515
 
 
1516
      output.add_Item( temp_Buf );
 
1517
 
 
1518
      temp_Buf[0] = '\0';
 
1519
      if (status.Success())
 
1520
      {
 
1521
         if (engine->Extract( temp_Buf, 15 ) == 0)
 
1522
         {
 
1523
            temp_Buf[0] = '\0';
 
1524
         }
 
1525
         else
 
1526
         {
 
1527
            char * String = temp_Buf;
 
1528
 
 
1529
            temp_Buf[15] = '\0';
 
1530
            while (*String && ((('0' <= *String) && (*String <= '9'))
 
1531
               || (*String == '-')))
 
1532
            {
 
1533
               ++String;
 
1534
            }
 
1535
 
 
1536
            *String = '\0';
 
1537
         }
 
1538
      }
 
1539
 
 
1540
      output.add_Item( temp_Buf );
 
1541
 
 
1542
      {
 
1543
         Dpt_Status hbaStatus(hbaTag);
 
1544
         output.add_Item((char *) hbaStatus);
 
1545
      }
 
1546
 
 
1547
      output.add_Item( "\n" );
 
1548
      Flush ( &output );
 
1549
      status = Dpt_Error::DPT_MSG_RTN_COMPLETED;
 
1550
   }
 
1551
 
 
1552
   return(status);
 
1553
}
 
1554
 
 
1555
 
 
1556
 
 
1557
// Flash the file into the HBA
 
1558
Command::Dpt_Error   Flash::Flash_This_HBA(
 
1559
   String_List    &output,
 
1560
   std::istream   &firmwareStream
 
1561
   )
 
1562
{
 
1563
 
 
1564
   ENTER( "Command::Dpt_Error   Flash::Flash_This_HBA(" );
 
1565
   Dpt_Error   status;
 
1566
   const int BUF_LEN = 256;
 
1567
   char temp_Buf[ BUF_LEN ];
 
1568
   // Raptor BIOS rewrite.
 
1569
   char Old_PCI_ID, BIOS_rewrite = 0;
 
1570
   unsigned long BIOSsize;
 
1571
   unsigned PCI_Data_Table_Offset;
 
1572
   // Now, flash this card!
 
1573
 
 
1574
   bool failed = false;
 
1575
   FlashRegion flashRegion = FW;
 
1576
 
 
1577
   if (strcmp ((const char *)ScanType, "SMOR") == 0)
 
1578
   {
 
1579
      flashRegion = SMOR;
 
1580
   }
 
1581
   else
 
1582
      if ((strcmp ((const char *)ScanType, "BIOS") == 0)
 
1583
      || (strcmp ((const char *)ScanType, "FCODE") == 0))
 
1584
   {
 
1585
      flashRegion = I2OBIOS;
 
1586
      engine->Send( MSG_GET_INFO, hbaTag );
 
1587
      if ((strncmp ((const char *)engine->devInfo_P->productID, "2005S", 5) == 0)
 
1588
       || (strncmp ((const char *)engine->devInfo_P->productID, "2000S", 5) == 0))
 
1589
      {
 
1590
        BIOS_rewrite = 1;
 
1591
        BIOSsize = 0L;
 
1592
        PCI_Data_Table_Offset = 0;
 
1593
      }
 
1594
   }
 
1595
   else
 
1596
      if (strcmp ((const char *)ScanType, EventStrings[STR_NVRAM]) == 0)
 
1597
   {
 
1598
      flashRegion = NVRAM;
 
1599
   }
 
1600
   else
 
1601
      if (strcmp ((const char *)ScanType, EventStrings[STR_FIRMWARE]) != 0)
 
1602
   {
 
1603
      status = Dpt_Error::DPT_CMD_ERR_INVALID_FLASH_IMAGE;
 
1604
   }
 
1605
 
 
1606
   uLONG startingFlashMemoryIndex(0);
 
1607
   if (status.Success())
 
1608
   {
 
1609
      status = SetFlashRegion(flashRegion);
 
1610
 
 
1611
      // Kludge for 2865 and potentially other controllers that have
 
1612
      // special needs
 
1613
      if (status.Success())
 
1614
      {
 
1615
         status = GetStartingFlashIndex(flashRegion, imageSize,
 
1616
            m_FlashFileProcessorFamily, startingFlashMemoryIndex);
 
1617
         if (( status.Success() ) && ( startingFlashMemoryIndex != 0 ))
 
1618
         {
 
1619
            // kds taken out per Mark Salyzyn
 
1620
//                              status = WriteSeekToIndex(startingFlashMemoryIndex);
 
1621
         }
 
1622
      }
 
1623
   }
 
1624
 
 
1625
   // Copy the image file to flash memory.
 
1626
   uLONG readSize;
 
1627
   firmwareStream.seekg(0);
 
1628
   for (uLONG imageIndex = 0;  imageIndex < imageSize;  imageIndex += readSize)
 
1629
   {
 
1630
      if (status.Success())
 
1631
      {
 
1632
         char fileBuf[BYTES_PER_TRANSFER];
 
1633
 
 
1634
         // Determine the amount of data to read from the file.
 
1635
         // This is the minimum of the amount of data left in the
 
1636
         // file and the size of a transfer buffer.
 
1637
         readSize = min(sizeof(fileBuf), imageSize - imageIndex);
 
1638
 
 
1639
         // If the amount of data to read from the file is less
 
1640
         // than the size of the transfer buffer then pre-read the
 
1641
         // current contents of the flash memory.  This is
 
1642
         // necessary because data that is to be flashed must be
 
1643
         // written in BYTES_PER_TRANSFER (512) byte chunks.
 
1644
         if (readSize != BYTES_PER_TRANSFER)
 
1645
         {
 
1646
            status = ReadFlashMemory(fileBuf,
 
1647
               startingFlashMemoryIndex + imageIndex,
 
1648
               BYTES_PER_TRANSFER);
 
1649
         }
 
1650
 
 
1651
         // Read in data from the file and if that's successful
 
1652
         // write that data to flash memory.
 
1653
         if (status.Success())
 
1654
         {
 
1655
            firmwareStream.read(fileBuf, readSize);
 
1656
 
 
1657
            if (firmwareStream.good())
 
1658
            {
 
1659
               /* Raptor BIOS rewrite handler */
 
1660
               if (BIOS_rewrite)
 
1661
               {
 
1662
                  if (BIOS_rewrite == 1) /* Work with first signature */
 
1663
                  {
 
1664
                     BIOSsize = (unsigned char)fileBuf[2] * 512L;
 
1665
                     Old_PCI_ID = 0x11;
 
1666
                     PCI_Data_Table_Offset = (unsigned char)fileBuf[24]
 
1667
                                           + ((unsigned char)fileBuf[25] << 8);
 
1668
                     ++BIOS_rewrite;
 
1669
                  }
 
1670
                  /* I know, `oodles' of bugs on readSize boundaries */
 
1671
                  if (BIOS_rewrite == 2) /* Work on the PCI Data table */
 
1672
                  {
 
1673
                     if (PCI_Data_Table_Offset >= readSize)
 
1674
                     {
 
1675
                        PCI_Data_Table_Offset -= readSize;
 
1676
                     }
 
1677
                     else
 
1678
                     {
 
1679
                        if (strncmp((const char *)&fileBuf[PCI_Data_Table_Offset], "PCIR", 4) == 0)
 
1680
                        {
 
1681
                           Old_PCI_ID = fileBuf[PCI_Data_Table_Offset + 6];
 
1682
                           fileBuf[PCI_Data_Table_Offset + 6] = 0x11;
 
1683
                           ++BIOS_rewrite;
 
1684
                        }
 
1685
                        else
 
1686
                        {
 
1687
                           BIOS_rewrite = 0;
 
1688
                        }
 
1689
                     }
 
1690
                  }
 
1691
                  /* Work on correcting the checksum */
 
1692
                  if ((BIOS_rewrite == 3) && (BIOSsize <= readSize))
 
1693
                  {
 
1694
                     fileBuf[BIOSsize - 1] -= 0x11 - Old_PCI_ID;
 
1695
                     BIOS_rewrite = 0;
 
1696
                  }
 
1697
                  if (BIOSsize >= readSize)
 
1698
                  {
 
1699
                     BIOSsize -= readSize;
 
1700
                  }
 
1701
               }
 
1702
               status = WriteFlashMemory(fileBuf, BYTES_PER_TRANSFER);
 
1703
            }
 
1704
            else
 
1705
            {
 
1706
               status = Dpt_Error::DPT_CMD_ERR_INVALID_FLASH_IMAGE;
 
1707
            }
 
1708
         }
 
1709
      }
 
1710
 
 
1711
      if (status.Failure())
 
1712
      {
 
1713
         sprintf(temp_Buf,
 
1714
            EventStrings[STR_FLASH_ERR_MSG],
 
1715
            imageIndex, (int)status, (char *)status);
 
1716
 
 
1717
         output.add_Item (temp_Buf);
 
1718
         Flush (&output);
 
1719
         failed = true;
 
1720
         break;
 
1721
      }
 
1722
   } // for imageIndex
 
1723
 
 
1724
   // If we failed we don't want firmware to write a checksum
 
1725
   // There is no reason to switch out of flash mode either
 
1726
   // (firmware will go right back into it if there is no checksum)
 
1727
   status |= WriteFlashMemoryDone(failed);
 
1728
   if (status.Success() && !failed)
 
1729
   {
 
1730
      engine->Reset();
 
1731
      engine->Send( MSG_FLASH_SWITCH_OUT_OF, hbaTag );
 
1732
 
 
1733
      //
 
1734
      // Verify that the file was written properly.
 
1735
      //
 
1736
/* We don't have to do this because it is done in eata2i2o */
 
1737
#if 0
 
1738
      uLONG flashMemoryIndex = startingFlashMemoryIndex;
 
1739
      firmwareStream.seekg(0);
 
1740
      for ( uLONG imageIndex = 0;  imageIndex < imageSize;  imageIndex += BYTES_PER_TRANSFER )
 
1741
      {
 
1742
         char flashMemoryBuf[BYTES_PER_TRANSFER];
 
1743
         memset(flashMemoryBuf, 0, BYTES_PER_TRANSFER);
 
1744
         char fileBuf[sizeof(flashMemoryBuf)];
 
1745
 
 
1746
 
 
1747
         //
 
1748
         // First, read data from the file.
 
1749
         //
 
1750
         readSize = min(sizeof(fileBuf), imageSize - imageIndex);
 
1751
         firmwareStream.read(fileBuf, readSize);
 
1752
 
 
1753
 
 
1754
 
 
1755
         //
 
1756
         // If that succeeds then read data from flash memory.
 
1757
         //
 
1758
         if ( firmwareStream.good() )
 
1759
         {
 
1760
            //
 
1761
            // Don't verify the top 16K of firmware.  This is the mode 0 boot area
 
1762
            // and according to Mark Salyzyn it shouldn't be verified.
 
1763
            //
 
1764
            if (( flashRegion != FW ) || ( imageIndex < imageSize - Mode0BootSize ))
 
1765
            {
 
1766
               status = ReadFlashMemory(flashMemoryBuf, flashMemoryIndex,
 
1767
                                                sizeof(flashMemoryBuf));
 
1768
            }
 
1769
            else
 
1770
            {
 
1771
               status = Dpt_Error::DPT_MSG_RTN_COMPLETED;
 
1772
               break;
 
1773
            }
 
1774
         }
 
1775
         else
 
1776
         {
 
1777
            status = Dpt_Error::DPT_ERR_FLASH_ENG_VERIFY;
 
1778
         }
 
1779
 
 
1780
 
 
1781
 
 
1782
         //
 
1783
         // If the necessary data was read then compare the data.
 
1784
         // If the data doesn't compare correctly that's a failure.
 
1785
         //
 
1786
         if ( status.Success() )
 
1787
         {
 
1788
            if ( memcmp(flashMemoryBuf, fileBuf, readSize) != 0 )
 
1789
            {
 
1790
               status = Dpt_Error::DPT_ERR_FLASH_ENG_VERIFY;
 
1791
            }
 
1792
 
 
1793
            flashMemoryIndex += sizeof(flashMemoryBuf);
 
1794
         }
 
1795
 
 
1796
 
 
1797
 
 
1798
         //
 
1799
         // If a failure occurred then inform the user.
 
1800
         //
 
1801
         if ( status.Failure() )
 
1802
         {
 
1803
            sprintf (temp_Buf, EventStrings[STR_VERIFYING_ERR_MSG],
 
1804
                 imageIndex, (int)status, (char *)status );
 
1805
            output.add_Item (temp_Buf);
 
1806
            Flush (&output);
 
1807
            failed = true;
 
1808
            break;
 
1809
         }
 
1810
 
 
1811
         status = Dpt_Error::DPT_MSG_RTN_COMPLETED;
 
1812
      } // for imageIndex
 
1813
#endif
 
1814
   }
 
1815
 
 
1816
   EXIT();
 
1817
   return(status);
 
1818
}
 
1819
 
 
1820
Command  &Flash::Clone() const
 
1821
{
 
1822
   ENTER ("Command      &Flash::Clone() const");
 
1823
   EXIT();
 
1824
   return(*new Flash (this->source, this->Resync, this->hba_Num));
 
1825
}
 
1826
 
 
1827
 
 
1828
/*** END OF FILE ***/