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

« back to all changes in this revision

Viewing changes to raideng/driver.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
//File - DRIVER.CPP
 
30
//***************************************************************************
 
31
//
 
32
//Description:
 
33
//
 
34
//    This file contains function definitions for the dptDriver_C
 
35
//class.
 
36
//
 
37
//Author:       Doug Anderson
 
38
//Date:         4/8/93
 
39
//
 
40
//Editors:
 
41
//
 
42
//Remarks:
 
43
//
 
44
//
 
45
//***************************************************************************
 
46
 
 
47
#include  "allfiles.hpp"
 
48
 
 
49
#ifdef    _DPT_WIN_NT
 
50
   #include    <stdio.h>
 
51
   extern "C" {
 
52
         void          LogEvent(CHAR *);
 
53
         extern uLONG  osdBadInterpretFW;
 
54
   };
 
55
#endif
 
56
 
 
57
//#define       _DUMP_EATA_CP
 
58
#ifdef  _DUMP_EATA_CP
 
59
        #include                <fstream.h>
 
60
        ofstream                odebug("engdebug.txt", ios::trunc);
 
61
        void    DumpCommand(engCCB_C *ccb_P);
 
62
        void    DumpRtnCommand(engCCB_C *ccb_P, DPT_RTN_T retVal);
 
63
#endif
 
64
 
 
65
 
 
66
#if !defined _DPT_UNIX && !defined _DPT_NETWARE && !defined _DPT_DOS
 
67
extern "C" {
 
68
        uLONG osdTargetBusy(uLONG HbaNum, uLONG Channel, uLONG TargetId, uLONG LUN);
 
69
        void osdTargetCheck(uLONG HbaNum, uLONG Channel, uLONG TargetId, uLONG LUN);
 
70
        void osdResetBus(uLONG HbaNum);
 
71
};
 
72
#else
 
73
        uLONG osdTargetBusy(uLONG HbaNum, uLONG Channel, uLONG TargetId, uLONG LUN);
 
74
        void osdTargetCheck(uLONG HbaNum, uLONG Channel, uLONG TargetId, uLONG LUN);
 
75
        void osdResetBus(uLONG HbaNum);
 
76
#endif // _DPT_UNIX
 
77
 
 
78
//Function - dptDriver_C::passCCB() - start
 
79
//===========================================================================
 
80
//
 
81
//Description:
 
82
//
 
83
//    This function passes the CCB to the OS dependent layer for output
 
84
//to an HBA.
 
85
//
 
86
//Parameters:
 
87
//
 
88
//Return Value:
 
89
//
 
90
//Global Variables Affected:
 
91
//
 
92
//Remarks: (Side effects, Assumptions, Warnings...)
 
93
//
 
94
//
 
95
//---------------------------------------------------------------------------
 
96
 
 
97
DPT_RTN_T dptDriver_C::passCCB(engCCB_C *ccb_P)
 
98
{
 
99
 
 
100
   DPT_RTN_T   retVal = MSG_RTN_FAILED;
 
101
 
 
102
  // If this is a RAID command from a logical device...
 
103
if ( ccb_P->isRAIDcmd() && (ccb_P->isLog() || ccb_P->isMgr()) )
 
104
        // Set the SW RAID bits
 
105
   ccb_P->setSW();
 
106
 
 
107
#ifdef          ENABLE_SCSI_TRACE
 
108
cout << "CMD=" << hex << setw(2) << (uSHORT) ccb_P->eataCP.scsiCDB[0] << ", ";
 
109
cout << "To ==> ";
 
110
 
 
111
 
 
112
if ((ccb_P->hba_P->getPCIaddr()>=0x1000) && (ccb_P->hba_P->busType & HBA_BUS_PCI))
 
113
   cout << hex << setw(8) << ccb_P->hba_P->getPCIaddr();
 
114
else if (ccb_P->hba_P->getEISAaddr()>=0x1000)
 
115
   cout << hex << setw(4) << ccb_P->hba_P->getEISAaddr();
 
116
else
 
117
   cout << hex << setw(4) << ccb_P->hba_P->getISAaddr();
 
118
 
 
119
cout << " - (";
 
120
 
 
121
// SNI: Fixed SCSI channel bits - only bit 7-5 are valid
 
122
cout << hex << (uSHORT)(ccb_P->eataCP.devAddr >> 5) << ',';
 
123
cout << hex << (uSHORT)(ccb_P->eataCP.devAddr & 0x1f) << ',';
 
124
cout << hex << (uSHORT)(ccb_P->eataCP.message[0] & 0x7) << "), ";
 
125
if (ccb_P->eataCP.flags & CP_DATA_IN)
 
126
   cout << " -Din";
 
127
else
 
128
   cout << "     ";
 
129
if (ccb_P->eataCP.flags & CP_DATA_OUT)
 
130
   cout << " -Dout";
 
131
else
 
132
   cout << "     ";
 
133
if (ccb_P->eataCP.flags & CP_INTERPRET)
 
134
   cout << " -Interpret";
 
135
else
 
136
   cout << "           ";
 
137
if (ccb_P->eataCP.physical & 0x1)
 
138
   cout << " -Physical";
 
139
else
 
140
   cout << "          ";
 
141
if (ccb_P->eataCP.nestedFW & 0x1)
 
142
   cout << " -NFW";
 
143
else
 
144
   cout << "     ";
 
145
#endif
 
146
 
 
147
// if its a multi initiator command we need to reset the ccb a little
 
148
if(ccb_P->isMultiInitiatorCmd()) {
 
149
        ccb_P->clrInterpret();
 
150
        ccb_P->setPhysical();
 
151
}
 
152
 
 
153
// if its an interpreted mode select then strip the mode header of any value
 
154
if ((ccb_P->eataCP.scsiCDB[0] == 0x55) && (ccb_P->eataCP.flags & CP_INTERPRET)) {
 
155
        memset(ccb_P->dataBuff_P, 0, modeHeader_S::size());
 
156
}
 
157
 
 
158
// if its a synch cache with a DPT bit set strip the physical bit
 
159
if (ccb_P->eataCP.scsiCDB[0] == 0x35 && ccb_P->eataCP.scsiCDB[9] == 0x80)
 
160
        ccb_P->eataCP.physical = 0;
 
161
 
 
162
 
 
163
  // If this is not an event logger command...
 
164
if (!ccb_P->isLoggerCmd()) {
 
165
        #ifdef  _DUMP_EATA_CP
 
166
        // DEBUG ONLY
 
167
        DumpCommand(ccb_P);
 
168
        #endif
 
169
        // Send the CCB to hardware
 
170
   retVal = osdSendCCB(myConn_P()->getIOmethod(),ccb_P);
 
171
        #ifdef  _DUMP_EATA_CP
 
172
        // DEBUG ONLY
 
173
        DumpRtnCommand(ccb_P, retVal);
 
174
        #endif
 
175
}
 
176
else if (ccb_P->eataCP.scsiCDB[1] & 0x01)
 
177
 
 
178
          // Send the Read log command
 
179
//dz    retVal = osdLoggerCmd(MSG_LOG_READ,ccb_P,myConn_P()->getIOmethod(),
 
180
//dz                     ccb_P->logOffset,ccb_P->ctlrNum);
 
181
          // Send the Read log command
 
182
        retVal = osdLoggerCmd((DPT_MSG_T)MSG_LOG_READ,(void*)ccb_P,NULL,(uSHORT)myConn_P()->getIOmethod(),
 
183
                         (uLONG)ccb_P->logOffset,(uLONG)ccb_P->ctlrNum);
 
184
else
 
185
 
 
186
          // Send the Clear log command
 
187
//dz    retVal = osdLoggerCmd(MSG_LOG_CLEAR,ccb_P,myConn_P()->getIOmethod(),
 
188
//dz                     ccb_P->logOffset,ccb_P->ctlrNum);
 
189
         
 
190
   // Send the Clear log command
 
191
        retVal = osdLoggerCmd((DPT_MSG_T)MSG_LOG_CLEAR,(void*)ccb_P,NULL,(uSHORT)myConn_P()->getIOmethod(),
 
192
                         (uLONG)ccb_P->logOffset,(uLONG) ccb_P->ctlrNum);
 
193
 
 
194
#ifdef          ENABLE_SCSI_TRACE
 
195
   if ((retVal==MSG_RTN_COMPLETED) && ccb_P->ok())
 
196
         cout << " OK ";
 
197
   else
 
198
         cout << " ***";
 
199
   cout << endl;
 
200
#endif
 
201
 
 
202
return (retVal);
 
203
 
 
204
}
 
205
//dptDriver_C::passCCB() - end
 
206
 
 
207
 
 
208
//Function - dptDriver_C::handleMessage() - start
 
209
//===========================================================================
 
210
//
 
211
//Description:
 
212
//
 
213
//    This function processes messages for a SCSI driver.
 
214
//
 
215
//Parameters:
 
216
//
 
217
//Return Value:
 
218
//
 
219
//Global Variables Affected:
 
220
//
 
221
//Remarks: (Side effects, Assumptions, Warnings...)
 
222
//
 
223
//
 
224
//---------------------------------------------------------------------------
 
225
 
 
226
DPT_RTN_T dptDriver_C::handleMessage(DPT_MSG_T   message,
 
227
                                           dptBuffer_S *fromEng_P,
 
228
                                           dptBuffer_S *toEng_P
 
229
                                          )
 
230
{
 
231
 
 
232
   DPT_RTN_T   retVal = MSG_RTN_IGNORED;
 
233
 
 
234
switch (message) {
 
235
 
 
236
        // Scan system hardware for all physical and logical objects
 
237
   case MSG_IO_SCAN_SYSTEM:
 
238
        retVal = scanSystem();
 
239
        break;
 
240
 
 
241
        // Scan system hardware for all HBA objects
 
242
   case MSG_IO_SCAN_HBAS:
 
243
        retVal = scanSystem(3);
 
244
        break;
 
245
 
 
246
        // Scan system hardware for all physical objects
 
247
   case MSG_IO_SCAN_PHYSICALS:
 
248
        retVal = scanSystem(1);
 
249
        break;
 
250
 
 
251
        // Scan system hardware for all logical objects
 
252
   case MSG_IO_SCAN_LOGICALS:
 
253
        retVal = scanSystem(2);
 
254
        break;
 
255
 
 
256
        // Enable the current configuration in hardware
 
257
   case MSG_RAID_HW_ENABLE:
 
258
        retVal = raidHwEnable();
 
259
        break;
 
260
 
 
261
        // get the count of MSG_RAID_HW_ENABLE
 
262
        case MSG_GET_NUM_HW_ENABLES: {
 
263
 
 
264
                retVal = MSG_RTN_DATA_OVERFLOW;
 
265
 
 
266
                // get the count                                                  
 
267
                uLONG numSets = osdGetEnableCount();
 
268
 
 
269
                // swap it
 
270
                osdSwap4(&numSets);
 
271
 
 
272
                // see if it fits
 
273
                if (fromEng_P->insert(numSets))                                                    
 
274
                        retVal = MSG_RTN_COMPLETED;
 
275
        } break;
 
276
 
 
277
        // Delete all objects
 
278
   case MSG_DELETE_ALL:
 
279
        delAllObjects();
 
280
        retVal = MSG_RTN_COMPLETED;
 
281
        break;
 
282
 
 
283
        // Event Logger Messages - Data input to the logger or no data xfr
 
284
   case MSG_LOG_REGISTER:       // Indicate that the logger exists
 
285
   case MSG_LOG_UNREGISTER:     // Indicate that the logger does not exist
 
286
   case MSG_LOG_LOAD:           // Bring the logger online
 
287
   case MSG_LOG_UNLOAD:         // Remove the logger
 
288
   case MSG_LOG_START:          // Start loggin events
 
289
   case MSG_LOG_STOP:           // Stop loggin events
 
290
   case MSG_LOG_SET_STATUS:     // Set the event log filter
 
291
        case MSG_LOG_SAVE_PARMS:     // Save logger parameters
 
292
 
 
293
        // messages to control the broadcaster
 
294
        case MSG_ID_BROADCASTERS:          // id broadcast modules ot broadcasters inside the modules
 
295
        case MSG_ID_ALL_BROADCASTERS:      // id all broadcasting devices
 
296
        case MSG_GET_BROADCASTER_INFO:     // get broadcaster setup
 
297
        case MSG_SET_BROADCASTER_INFO:   // set broadcaster setup
 
298
        case MSG_LOAD_BROADCAST_MODULE:  // load a module on the fly
 
299
        case MSG_DELETE_BROADCASTER:     // delete an individual broadcaster
 
300
        case MSG_UNLOAD_BROADCAST_MODULE:// unload a module on the fly
 
301
        case MSG_CREATE_BROADCASTER:       // create a new broadcaster
 
302
 
 
303
        // Messages for the stats logger
 
304
        case MSG_STATS_LOG_REGISTER:                 // stats logger is registering
 
305
        case MSG_STATS_LOG_UNREGISTER:               // stats logger is unregistering
 
306
        case MSG_GET_BROADCASTER_SIG:
 
307
 
 
308
        // messages for the alert manager
 
309
        case MSG_ALMS_DELETE:                                           // tell the alms to delete a resource
 
310
        case MSG_ALMS_LINK:                                                     // tell the alms to link to resources together
 
311
        case MSG_ALMS_UNLINK:                                           // tell the alms to break the link between two resources
 
312
        case MSG_ALMS_ID_ALERTS:                                        // id the alms alerts
 
313
        case MSG_ALMS_ID_EVENT_FOLDER:                          // id event folders
 
314
        case MSG_ALMS_ID_SERVER_LOCATIONS:                      // id server locations
 
315
        case MSG_ALMS_ID_MOVEABLE_RESOURCES:            // id moveable resources
 
316
        case MSG_ALMS_ID_MOVEABLE_RESOURCE_FOLDER:      // id moveable resource folders
 
317
        case MSG_ALMS_ACTIVATE:                                         // tell the alms to perform final checking and activate an alert
 
318
        case MSG_ALMS_ID_USERS:                                         // id users
 
319
        case MSG_ALMS_ID_EVENTS:                                        // id events
 
320
        case MSG_ALMS_ID_SERVERS:                                       // id servers
 
321
        case MSG_ALMS_ID_ALERT_SCHEDULE:                        // id broadcast schedules
 
322
        case MSG_ALMS_GET_INFO:                                         // get info on a resource
 
323
        case MSG_ALMS_SET_INFO:                                         // set the info of a resource
 
324
        case MSG_ALMS_CREATE:                                           // create a resource
 
325
 
 
326
 
 
327
// transition phase
 
328
//dz    retVal = osdLoggerCmd(message,toEng_P,0,0,0);
 
329
        retVal = osdLoggerCmd(message,(void*)toEng_P,(dptData_S*)fromEng_P,0,0,0);
 
330
 
 
331
        break;
 
332
 
 
333
          // Event Logger Messages - Data output from the logger
 
334
        case MSG_LOG_GET_SIG:        // Get the logger's DPT signature
 
335
        case MSG_LOG_GET_STATUS:     // Get the logger status
 
336
 
 
337
// transition phase
 
338
//dz    retVal = osdLoggerCmd(message,fromEng_P,0,0,0);
 
339
        retVal = osdLoggerCmd(message,(void*)toEng_P,(dptData_S*)fromEng_P,0,0,0);
 
340
        break;
 
341
 
 
342
        // Delete all emulated drives from the system
 
343
   case MSG_DEL_ALL_EMULATION:
 
344
        retVal = delAllEmulation();
 
345
        break;
 
346
 
 
347
        // Call base class message handler
 
348
   default:
 
349
        retVal = dptRAIDdrvr_C::handleMessage(message,fromEng_P,toEng_P);
 
350
        break;
 
351
} // end switch
 
352
 
 
353
return(retVal);
 
354
 
 
355
}
 
356
//dptSCSIdrvr_C::handleMessage() - end
 
357
 
 
358
 
 
359
//Function - dptDriver_C::raidHwEnable() - start
 
360
//===========================================================================
 
361
//Description:
 
362
//    This function is the message handler for MSG_RAID_HW_ENABLE.
 
363
//---------------------------------------------------------------------------
 
364
 
 
365
DPT_RTN_T dptDriver_C::raidHwEnable()
 
366
{
 
367
 
 
368
        DPT_RTN_T   retVal = MSG_RTN_COMPLETED;
 
369
 
 
370
        // Set the OS visible flags appropriately
 
371
        myConn_P()->setPrevOsVisibles();
 
372
        setOsVisibles();
 
373
 
 
374
        // Prepare deleted devices to go offline
 
375
        lsuOffline();
 
376
        // Prepare newly hidden devices to go offline
 
377
        myConn_P()->lsuOffline();
 
378
 
 
379
        // Enable the current configuration
 
380
        retVal = enableConfig();
 
381
 
 
382
        // Zap parition tables
 
383
        if (myConn_P()->zapPartitions()==MSG_RTN_FAILED)
 
384
                retVal = MSG_RTN_FAILED;
 
385
 
 
386
        // osdTargetCheck() loop
 
387
        dptDevice_C *dev_P = (dptDevice_C *) logList.reset();
 
388
        while (dev_P!=NULL) {
 
389
                // If a new OS visible device...
 
390
                if (dev_P->isOsVisible() && !dev_P->isPrevOsVisible()) {
 
391
                        // Perform OS specific initialization (partition is created under Solaris)
 
392
                        osdTargetCheck((uLONG)dev_P->myHBA_P()->getDrvrNum(), (uLONG)dev_P->getChan(), (uLONG)dev_P->getID(), (uLONG)dev_P->getLUN());
 
393
                }
 
394
                // Get the next logical device
 
395
                dev_P = (dptDevice_C *) logList.next();
 
396
        }
 
397
 
 
398
        // Reset all buses on cluster mode enabled HBAs that had logical configuration changes
 
399
        dptHBA_C *hbaIt_P = (dptHBA_C *) phyList.reset();
 
400
        while (hbaIt_P != NULL) {
 
401
                if (hbaIt_P->isClusterMode() && hbaIt_P->isBusResetDesired()) {
 
402
                        osdResetBus(hbaIt_P->drvrRefNum);
 
403
                }
 
404
                hbaIt_P->clrBusResetDesired();
 
405
                hbaIt_P = (dptHBA_C *) phyList.next();
 
406
        }
 
407
 
 
408
        // Increment the enable count
 
409
        osdIncrementEnableCount();
 
410
 
 
411
        return (retVal);
 
412
 
 
413
}
 
414
//dptDriver_C::raidHwEnable() - end
 
415
 
 
416
 
 
417
//Function - dptDriver_C::scanSystem() - start
 
418
//===========================================================================
 
419
//Description:
 
420
//    This function scans the system hardware for all SCSI objects in
 
421
//the system.
 
422
//---------------------------------------------------------------------------
 
423
 
 
424
DPT_RTN_T dptDriver_C::scanSystem(uSHORT searchType)
 
425
{
 
426
 
 
427
   DPT_RTN_T   retVal = MSG_RTN_COMPLETED;
 
428
 
 
429
        // If not a logical device search only...
 
430
        if (searchType!=2) {
 
431
                // Delete the current configuration
 
432
                delAllObjects();
 
433
 
 
434
                // Find all physical objects in the system
 
435
                if (!scanPhysicals(searchType)) {
 
436
                        if (retVal == MSG_RTN_COMPLETED) {
 
437
                                retVal = MSG_RTN_FAILED | ERR_SCAN_PHYSICALS;
 
438
                        }
 
439
                }
 
440
 
 
441
                // Initialize all physical objects found
 
442
                if (!scanInit(1)) {
 
443
                        if (retVal == MSG_RTN_COMPLETED) {
 
444
                                retVal = MSG_RTN_FAILED | ERR_INIT_PHYSICALS;
 
445
                        }
 
446
                }
 
447
        }
 
448
 
 
449
        // If not a physical device only or HBA only search...
 
450
        if ((searchType!=1) && (searchType!=3)) {
 
451
 
 
452
                // Find all logical devices in the system
 
453
                if (!scanLogicals()) {
 
454
                        if (retVal == MSG_RTN_COMPLETED) {
 
455
                                retVal = MSG_RTN_FAILED | ERR_SCAN_LOGICALS;
 
456
                        }
 
457
                }
 
458
 
 
459
                // Initialize all logical objects found
 
460
                if (!scanInit(2)) {
 
461
                        if (retVal == MSG_RTN_COMPLETED) {
 
462
                                retVal = MSG_RTN_FAILED | ERR_INIT_LOGICALS;
 
463
                        }
 
464
                }
 
465
 
 
466
                // Check for valid partition tables
 
467
                findLSUpartitions();
 
468
                // Attempt to reserve space at the end of every non-removeable
 
469
                // disk for use by DPT
 
470
                myConn_P()->reserveEndOfDisks();
 
471
 
 
472
                // Set the magic number of all unarrayed physical DASD devices
 
473
                dptHBA_C *hbaIt_P = (dptHBA_C *) phyList.reset();
 
474
                while (hbaIt_P != NULL) {
 
475
                        hbaIt_P->setPhyMagicNums();
 
476
                        hbaIt_P = (dptHBA_C *) phyList.next();
 
477
                }
 
478
 
 
479
                // Flag the OS visible devices
 
480
                setOsVisibles();
 
481
 
 
482
                // Initialize the device busy checking code
 
483
                osdTargetBusy(0, 0, 0, 0);
 
484
        }
 
485
 
 
486
        return (retVal);
 
487
 
 
488
}
 
489
//dptDriver_C::scanSystem() - end
 
490
 
 
491
 
 
492
//Function - dptDriver_C::findMyPhysicals() - start
 
493
//===========================================================================
 
494
//
 
495
//Description:
 
496
//
 
497
//    This function finds all of the SCSI HBAs visible to the driver.
 
498
//
 
499
//Parameters:
 
500
//
 
501
//Return Value:
 
502
//
 
503
//   1 = OK
 
504
//   0 = Failure
 
505
//
 
506
//Global Variables Affected:
 
507
//
 
508
//Remarks: (Side effects, Assumptions, Warnings...)
 
509
//
 
510
//
 
511
//---------------------------------------------------------------------------
 
512
 
 
513
uSHORT    dptDriver_C::findMyPhysicals()
 
514
{
 
515
 
 
516
   uSHORT               numCtlrs,index;
 
517
   dptCoreList_C    tempList;
 
518
   dptHBA_C             *hbaIt_P;
 
519
   drvrHBAinfo_S        *hbaInfo_P;
 
520
   oldDrvrHBAinfo_S *oldInfo_P;
 
521
   eataRdConfig_S   *rdCfg_P = NULL;
 
522
   uSHORT      retVal = 0;
 
523
 
 
524
 
 
525
DEBUG_BEGIN(8, dptDriver_C::findMyPhysicals());
 
526
 
 
527
  // Allocate a buffer for the OSD layer's HBA list
 
528
uCHAR *buff_P = new uCHAR[2048];
 
529
  // Get the EATA read config. info
 
530
engCCB_C *ccb_P = getCCB();
 
531
 
 
532
if ((buff_P != NULL) && (ccb_P != NULL)) {
 
533
   hbaInfo_P = (drvrHBAinfo_S *) buff_P;
 
534
   oldInfo_P = (oldDrvrHBAinfo_S *) buff_P;
 
535
        // Get the HBA description list
 
536
 
 
537
   if (osdGetCtlrs(myConn_P()->getIOmethod(),&numCtlrs,hbaInfo_P) == MSG_RTN_COMPLETED) {
 
538
        // Indicate a successful scan
 
539
         retVal = 1;
 
540
        // Prevent overflow
 
541
         if (numCtlrs>16)
 
542
         numCtlrs = 16;
 
543
        // Create objects for each controller found
 
544
         for (index=0;index<numCtlrs;index++,hbaInfo_P++,oldInfo_P++) {
 
545
           // Create a new HBA
 
546
         hbaIt_P = (dptHBA_C *) newObject(DPT_SCSI_HBA);
 
547
         if (hbaIt_P!=NULL) {
 
548
                 // Indicate that the HBA is real
 
549
            hbaIt_P->status.flags  |= FLG_STAT_REAL;
 
550
 
 
551
                 // If the new format...
 
552
            if ((*((uSHORT *) buff_P) == sizeof(drvrHBAinfo_S)-2) ||
 
553
                (*((uSHORT *) buff_P) == 0)) {
 
554
                  hbaIt_P->drvrRefNum = hbaInfo_P->drvrHBAnum;
 
555
                  hbaIt_P->ioAddr.pci = hbaInfo_P->baseAddr;
 
556
 
 
557
                  // If an I2O HBA...
 
558
                  if (hbaInfo_P->hbaFlags & FLG_OSD_I2O)
 
559
                          // Set the I2O indicator flag
 
560
                          hbaIt_P->hbaFlags2 |= FLG_HBA_I2O;
 
561
 
 
562
                 // If in flash command mode...
 
563
                  if (hbaInfo_P->blinkState == 0x69) {
 
564
                  hbaIt_P->status.main = SMAIN_FLASH_MODE;
 
565
                  hbaIt_P->status.sub = SSUB_FLASH_INIT;
 
566
                  hbaIt_P->status.display = DSPLY_STAT_WARNING;
 
567
                  }
 
568
                 // If any other blink LED code...
 
569
                  else if (hbaInfo_P->blinkState) {
 
570
                  hbaIt_P->status.main = SMAIN_BLINK_LED;
 
571
                  hbaIt_P->status.sub = (uCHAR) hbaInfo_P->blinkState;
 
572
                  hbaIt_P->status.display = DSPLY_STAT_FAILED;
 
573
                  }
 
574
                  hbaIt_P->busNum          = hbaInfo_P->pciBusNum;
 
575
                  hbaIt_P->devFnNum        = hbaInfo_P->pciDeviceNum;
 
576
            }
 
577
            else {
 
578
                  hbaIt_P->drvrRefNum = oldInfo_P->ctlrNum;
 
579
                  hbaIt_P->ioAddr.pci = oldInfo_P->baseAddr;
 
580
                 // If the controller is in a blink LED state...
 
581
                  if (oldInfo_P->idPAL.u16[0]==0xbbbb) {
 
582
                    // If in flash command mode or production test mode...
 
583
                  if ((oldInfo_P->idPAL.u8[3] == 0x69) ||
 
584
                         (oldInfo_P->idPAL.u8[3] == 0x6a)) {
 
585
                        hbaIt_P->status.main = SMAIN_FLASH_MODE;
 
586
                        hbaIt_P->status.sub = SSUB_FLASH_INIT;
 
587
                        hbaIt_P->status.display = DSPLY_STAT_WARNING;
 
588
                          // Indicate that the HBA has flash memory
 
589
                        hbaIt_P->flags |= FLG_HBA_FLASH_MEM;
 
590
                  }
 
591
                    // If in any other blink LED mode...
 
592
                  else {
 
593
                        hbaIt_P->status.main = SMAIN_BLINK_LED;
 
594
                        hbaIt_P->status.sub = oldInfo_P->idPAL.u8[3];
 
595
                        hbaIt_P->status.display = DSPLY_STAT_FAILED;
 
596
                  }
 
597
                  }
 
598
            }
 
599
 
 
600
                 // If not in blink LED or flash mode...
 
601
            if (!hbaIt_P->isBlinkLED()) {
 
602
                 // Determine if the flash commands are supported...
 
603
                  ccb_P->reInit();
 
604
                  ccb_P->flashCmd(FLASH_CMD_STATUS);
 
605
                  ccb_P->setInterpret();
 
606
                  ccb_P->ctlrNum = hbaIt_P->drvrRefNum;
 
607
                  ccb_P->eataCP.devAddr = hbaIt_P->getID();
 
608
                  if (passCCB(ccb_P) == MSG_RTN_COMPLETED) {
 
609
                  if (ccb_P->ok()) {
 
610
                          // Indicate that the HBA has flash memory
 
611
                        hbaIt_P->flags |= FLG_HBA_FLASH_MEM;
 
612
                        dptFlashStatus_S *stat_P = (dptFlashStatus_S *) ccb_P->defData;
 
613
                        stat_P->scsiSwap();
 
614
                        hbaIt_P->fwType = stat_P->getFWtype();
 
615
                        if (stat_P->getFlags1() & FLASH_FLG_FLASH_MODE) {
 
616
                        hbaIt_P->status.main = SMAIN_FLASH_MODE;
 
617
                        hbaIt_P->status.sub = SSUB_FLASH_INIT;
 
618
                        hbaIt_P->status.display = DSPLY_STAT_WARNING;
 
619
                        }
 
620
                  }
 
621
                  }
 
622
 
 
623
                  ccb_P->reInit();
 
624
                 // Get the standard inquiry information
 
625
                  ccb_P->inquiry();
 
626
                  ccb_P->setInterpret();
 
627
                  ccb_P->ctlrNum = hbaIt_P->drvrRefNum;
 
628
                  ccb_P->eataCP.devAddr = hbaIt_P->getID();
 
629
                  if (passCCB(ccb_P) == MSG_RTN_COMPLETED) {
 
630
                  if (ccb_P->ok()) {
 
631
                          // Initialize the HBA using the inquiry data
 
632
                        hbaIt_P->inquiryInit((sdInquiry_S *)ccb_P->defData);
 
633
#ifdef    _DPT_WIN_NT
 
634
                        // Check for F/W with the "interpret command"
 
635
                        // scatter/gather bug
 
636
                        if ((memcmp(hbaIt_P->descr.revision,"07BQ",4) < 0) ||
 
637
                         ((memcmp(hbaIt_P->descr.revision,"07C1",4) >= 0) &&
 
638
                          (memcmp(hbaIt_P->descr.revision,"07C8",4) <= 0))) {
 
639
                        uLONG hbaBitFlag = 1L << hbaIt_P->drvrRefNum;
 
640
                        if (!(osdBadInterpretFW & hbaBitFlag)) {
 
641
                           osdBadInterpretFW |= hbaBitFlag;
 
642
                           char   logBuff[256];
 
643
                           sprintf(logBuff,"DPT %s has downgraded firmware(%c%c.%c%c).  Please contact DPT technical support for a firmware upgrade.  In USA Phone: (407) 830-5522",
 
644
                                   hbaIt_P->descr.productID,hbaIt_P->descr.revision[0],hbaIt_P->descr.revision[1],
 
645
                                   hbaIt_P->descr.revision[2],hbaIt_P->descr.revision[3]);
 
646
                           LogEvent(logBuff);
 
647
                        }
 
648
                          // Fake up a blink LED state
 
649
                        hbaIt_P->status.main = SMAIN_BLINK_LED;
 
650
                        hbaIt_P->status.sub  = 0x40;
 
651
                        hbaIt_P->status.display = DSPLY_STAT_FAILED;
 
652
                        }
 
653
#endif
 
654
                  }
 
655
                  }
 
656
            }
 
657
 
 
658
            rdCfg_P = NULL;
 
659
                 // If not in blink LED or flash mode...
 
660
            if (!hbaIt_P->isBlinkLED() && !hbaIt_P->isFlashMode()) {
 
661
                  ccb_P->reInit();
 
662
                 // Get the EATA Read Config. data
 
663
                  ccb_P->inquiry(0xc1);
 
664
                  ccb_P->setInterpret();
 
665
                  ccb_P->ctlrNum = hbaIt_P->drvrRefNum;
 
666
                  ccb_P->eataCP.devAddr = hbaIt_P->getID();
 
667
                  if (passCCB(ccb_P) == MSG_RTN_COMPLETED) {
 
668
                  if (ccb_P->ok()) {
 
669
                        rdCfg_P = (eataRdConfig_S *) ccb_P->dataBuff_P;
 
670
                        rdCfg_P->scsiSwap();
 
671
                        rdCfg_P->andLength(0xff);
 
672
                  }
 
673
                  }
 
674
            }
 
675
 
 
676
                 // If valid read config. info
 
677
            if (rdCfg_P != NULL) {
 
678
                 // Optimization
 
679
                 uCHAR flag1 = rdCfg_P->getFlag1();
 
680
                 uCHAR flag2 = rdCfg_P->getFlag2();
 
681
                 
 
682
               DEBUG(8, PRT_DADDR(hbaIt_P) << "HBA " << hbaIt_P->drvrRefNum << \
 
683
                        " rd cfg ok -" << hex << " flags[1-4]: 0x" << (int) flag1 << \
 
684
                        " 0x" << (int) flag2 << " 0x" << (int) rdCfg_P->getFlag3() << \
 
685
                        " 0x" << (int) rdCfg_P->getFlag4());
 
686
 
 
687
               DEBUG(8, "len=" << (int) rdCfg_P->getLength() << " rdCfg sz=" \
 
688
                        << sizeof(eataRdConfig_S) << " maxID=" << \
 
689
                        (int) rdCfg_P->getMaxChanID() << " maxLUN=" << \
 
690
                        (int) rdCfg_P->getMaxLun() << " IDs=(" << hex << \
 
691
                        (int) rdCfg_P->getScsiIDs()[0] << "," << \
 
692
                        (int) rdCfg_P->getScsiIDs()[1] << "," << \
 
693
                        (int) rdCfg_P->getScsiIDs()[2] << "," << \
 
694
                        (int) rdCfg_P->getScsiIDs()[3] << ")" << \
 
695
                        " rNum=" << (int) rdCfg_P->getRaidNum());
 
696
 
 
697
                 // If a primary HBA...
 
698
                  if (!(flag2 & RDCFG_PRIORITY)) {
 
699
                        hbaIt_P->setPrimary();
 
700
                  }
 
701
                 // Set the controller's SCSI ID
 
702
                  if (flag1 & RDCFG_HBA_ADDR)
 
703
                        hbaIt_P->addr.id = rdCfg_P->getScsiIDs()[3];
 
704
                 // Set the DRQ #
 
705
                  hbaIt_P->drqNum    = 0xffff;
 
706
                  if (flag1 & RDCFG_DRQ_VALID) {
 
707
                    // Set the DRQ number
 
708
                  switch (flag2 & RDCFG_DRQ_NUM) {
 
709
                        case 0x40: hbaIt_P->drqNum = 7; break;
 
710
                        case 0x80: hbaIt_P->drqNum = 6; break;
 
711
                        case 0xc0: hbaIt_P->drqNum = 5; break;
 
712
                  }
 
713
                  }
 
714
                 // Set the IRQ #
 
715
                  hbaIt_P->irqNum = flag2 & RDCFG_IRQ_NUM;
 
716
                  if (flag2 & RDCFG_IRQ_TRIG)
 
717
                  hbaIt_P->irqNum |= 0x0100;
 
718
                 // Set the various HBA flags
 
719
                  if (flag1 & RDCFG_OVERLAP)
 
720
                  hbaIt_P->flags |= FLG_HBA_OVERLAP;
 
721
                  if (flag1 & RDCFG_TGT_MODE)
 
722
                  hbaIt_P->flags |= FLG_HBA_TGT_MODE;
 
723
                  if (flag1 & RDCFG_DMA)
 
724
                  hbaIt_P->flags |= FLG_HBA_DMA;
 
725
                  if (rdCfg_P->getLength() >= 0x20) {
 
726
                    uCHAR flag4 = rdCfg_P->getFlag4();
 
727
                    // Set more HBA flags
 
728
                  if (flag4 & RDCFG_SCAM)
 
729
                        hbaIt_P->hbaFlags2 |= FLG_HBA_SCAM;
 
730
                    // Set the bus type
 
731
                  if (flag4 & RDCFG_EISA_BUS)
 
732
                        hbaIt_P->busType = HBA_BUS_EISA;
 
733
                  else if (flag4 & RDCFG_PCI_BUS)
 
734
                        hbaIt_P->busType = HBA_BUS_PCI;
 
735
                  else
 
736
                        hbaIt_P->busType = HBA_BUS_ISA;
 
737
                  }
 
738
                  else if (hbaIt_P->ioAddr.pci >= 0x1000)
 
739
                  hbaIt_P->busType = HBA_BUS_EISA;
 
740
                  else
 
741
                  hbaIt_P->busType = HBA_BUS_ISA;
 
742
 
 
743
                 // If an ISA board...
 
744
                  if (hbaIt_P->busType == HBA_BUS_ISA)
 
745
                    // Move the I/O address into the ISA addr field
 
746
                  hbaIt_P->ioAddr.pci <<= 16;
 
747
 
 
748
                  if (rdCfg_P->getLength() >= 0x22) {
 
749
                    // Set this HBA's RAID ID number
 
750
                  if ((rdCfg_P->getRaidNum() >= 20) && (rdCfg_P->getRaidNum() <= 31)) {
 
751
                          // Set the HBA's RAID ID number
 
752
                        hbaIt_P->raidSWid = rdCfg_P->getRaidNum();
 
753
                          // Indicate that the RAID ID number is used
 
754
                        uLONG bitToSet = 1;
 
755
                        bitToSet <<= hbaIt_P->raidSWid;
 
756
                        usedRAIDids |= bitToSet;
 
757
                  }
 
758
                  }
 
759
#ifndef SNI_MIPS
 
760
               // On mips EISA controller does not respond to ISA address
 
761
                  if ((hbaIt_P->busType == HBA_BUS_EISA) &&
 
762
                   !(rdCfg_P->getFlag3() & RDCFG_NO_ISA)) {
 
763
                  if (hbaIt_P->isPrimary())
 
764
                        hbaIt_P->ioAddr.std.isa = 0x1f0;
 
765
                  else
 
766
                        hbaIt_P->ioAddr.std.isa = 0x170;
 
767
                  }
 
768
#endif
 
769
            } // end if (rdCfg_P != NULL)
 
770
 
 
771
                 // Add the HBA to the physical device list
 
772
            enterPhy(hbaIt_P);
 
773
 
 
774
         } // end if (hbaIt_P!=NULL)
 
775
         } // end for (index)
 
776
   }
 
777
} // end if (buff_P!=NULL)
 
778
 
 
779
if (buff_P != NULL)
 
780
        // Delete the HBA description buffer
 
781
   delete[] buff_P;
 
782
 
 
783
if (ccb_P != NULL)
 
784
        // Free the CCB
 
785
   ccb_P->clrInUse();
 
786
 
 
787
return (retVal);
 
788
 
 
789
}
 
790
//dptDriver_C::findMyPhysicals() - end
 
791
 
 
792
 
 
793
//Function - dptDriver_C::setOsVisibles() - start
 
794
//===========================================================================
 
795
//Description:
 
796
//   This function flags all devices in the driver's logical device
 
797
//list as OS visible.
 
798
//---------------------------------------------------------------------------
 
799
 
 
800
void    dptDriver_C::setOsVisibles()
 
801
{
 
802
 
 
803
dptDevice_C *dev_P = (dptDevice_C *) logList.reset();
 
804
while (dev_P!=NULL) {
 
805
        // Perform OS specific initialization
 
806
        dev_P->setOsVisible();
 
807
        // Get the next logical device
 
808
        dev_P = (dptDevice_C *) logList.next();
 
809
}
 
810
 
 
811
}
 
812
//dptDriver_C::setOsVisibles() - end
 
813
 
 
814
 
 
815
//Function - dptDriver_C::initHBAs() - start
 
816
//===========================================================================
 
817
//
 
818
//Description:
 
819
//
 
820
//   This function initializes all HBAs.  HBA initialization is seperated
 
821
//from device initialization so that the capabilities of the HBA are
 
822
//known prior to scanning for sub-objects.
 
823
//
 
824
//Parameters:
 
825
//
 
826
//Return Value:
 
827
//
 
828
//Global Variables Affected:
 
829
//
 
830
//Remarks: (Side effects, Assumptions, Warnings...)
 
831
//
 
832
//
 
833
//---------------------------------------------------------------------------
 
834
 
 
835
void    dptDriver_C::initHBAs()
 
836
{
 
837
 
 
838
#ifdef          ENABLE_SCSI_TRACE
 
839
   cout << "Initializing HBAs..." << endl;
 
840
#endif
 
841
 
 
842
dptObject_C *obj_P = (dptObject_C *) phyList.reset();
 
843
while (obj_P!=NULL) {
 
844
        // Initialize the HBA
 
845
   obj_P->realInit();
 
846
        // Get the next HBA
 
847
   obj_P = (dptObject_C *) phyList.next();
 
848
}
 
849
 
 
850
  // Assign RAID ID numbers to the HBA's that don't have one
 
851
assignRAIDids();
 
852
 
 
853
}
 
854
//dptDriver_C::initHBAs() - end
 
855
 
 
856
 
 
857
//Function - dptDriver_C::assignRAIDids() - start
 
858
//===========================================================================
 
859
//
 
860
//Description:
 
861
//
 
862
//   This function assigns a unique RAID ID to each HBA in the system.
 
863
//
 
864
//---------------------------------------------------------------------------
 
865
 
 
866
void dptDriver_C::assignRAIDids()
 
867
{
 
868
 
 
869
   uLONG  bitToCheck;
 
870
   uCHAR  idNum;
 
871
 
 
872
engCCB_C *ccb_P = getCCB();
 
873
if (ccb_P != NULL) {
 
874
        dptHBA_C *hbaIt_P = (dptHBA_C *) phyList.reset();
 
875
        while (hbaIt_P != NULL) {
 
876
 
 
877
                //--------------------------------
 
878
                // Assign the selectable RAID ID #
 
879
                //--------------------------------
 
880
 
 
881
                if (!hbaIt_P->raidSWid && !hbaIt_P->isBlinkLED()) {
 
882
                        // Find the first available address independent HBA ID #
 
883
                        bitToCheck = 0x00100000L;
 
884
                        for (idNum = 20;idNum <= 31;idNum++) {
 
885
                                if (!(usedRAIDids & bitToCheck))
 
886
                                        break;
 
887
                                else
 
888
                                        bitToCheck <<= 1;
 
889
                        }
 
890
                        // Issue the multi-function command
 
891
                        ccb_P->reInit();
 
892
                        ccb_P->mfCmd(0x09,idNum);
 
893
                        ccb_P->setInterpret();
 
894
                        ccb_P->ctlrNum = hbaIt_P->drvrRefNum;
 
895
                        if (passCCB(ccb_P) == MSG_RTN_COMPLETED) {
 
896
                                if (ccb_P->ok()) {
 
897
                                        hbaIt_P->raidSWid = idNum;
 
898
                                        // Indicate that the HBA ID # is used
 
899
                                        bitToCheck = 1;
 
900
                                        bitToCheck <<= idNum;
 
901
                                        usedRAIDids |= bitToCheck;
 
902
                                }
 
903
                        }
 
904
                }
 
905
 
 
906
                //-----------------------------------
 
907
                // Assign the slot specific RAID ID #
 
908
                //-----------------------------------
 
909
 
 
910
                if (hbaIt_P->busType == HBA_BUS_EISA) {
 
911
                        // If there is a valid EISA address...
 
912
                        if (hbaIt_P->ioAddr.std.eisa!=0)
 
913
                                // Use the EISA slot #
 
914
                                hbaIt_P->raidSlotID = (uCHAR) hbaIt_P->getEISAslot();
 
915
                }
 
916
                else if (hbaIt_P->busType == HBA_BUS_ISA) {
 
917
                        switch (hbaIt_P->ioAddr.std.isa) {
 
918
                                case 0x1f0:  hbaIt_P->raidSlotID = 0x10;   break;
 
919
                                case 0x170:  hbaIt_P->raidSlotID = 0x11;   break;
 
920
                                case 0x330:  hbaIt_P->raidSlotID = 0x12;   break;
 
921
                                default:     hbaIt_P->raidSlotID = 0x13;   break;
 
922
                        }
 
923
                }
 
924
 
 
925
                hbaIt_P = (dptHBA_C *) phyList.next();
 
926
 
 
927
        } // while()
 
928
 
 
929
        // Free the CCB
 
930
        ccb_P->clrInUse();
 
931
}
 
932
 
 
933
}
 
934
//dptDriver_C::assignRAIDids() - end
 
935
 
 
936
 
 
937
//Function - dptDriver_C::findMyLogicals() - start
 
938
//===========================================================================
 
939
//
 
940
//Description:
 
941
//
 
942
//    This function finds all driver level logical devices in the system.
 
943
//
 
944
//Parameters:
 
945
//
 
946
//Return Value:
 
947
//
 
948
//   1 = OK
 
949
//   0 = Failure
 
950
//
 
951
//Global Variables Affected:
 
952
//
 
953
//Remarks: (Side effects, Assumptions, Warnings...)
 
954
//
 
955
//
 
956
//---------------------------------------------------------------------------
 
957
 
 
958
uSHORT    dptDriver_C::findMyLogicals()
 
959
{
 
960
 
 
961
   dptHBA_C             *hbaIt_P;
 
962
   engCCB_C             *ccb_P;
 
963
 
 
964
hbaIt_P = (dptHBA_C *) phyList.reset();
 
965
  // For all HBAs...
 
966
while (hbaIt_P!=NULL) {
 
967
        // If the HBA supports RAID...
 
968
   if (hbaIt_P->isRAIDcapable()) {
 
969
        // Get a CCB
 
970
         ccb_P = getCCB();
 
971
         if (ccb_P!=NULL) {
 
972
           // Initialize the CCB to do a log sense
 
973
         ccb_P->logSense(0x36);
 
974
           // Indicate that this is a RAID command
 
975
         ccb_P->setRAIDcmd();
 
976
           // Target the HBA - SW logical
 
977
         ccb_P->target(hbaIt_P->getAddr(),hbaIt_P,CCB_ORIG_LOG);
 
978
           // Send the CCB to hardware
 
979
         if (launchCCB(ccb_P)==MSG_RTN_COMPLETED) {
 
980
                 // Create SCSI devices for the logical addresses returned
 
981
            newLP36Devices(ccb_P,hbaIt_P);
 
982
         }
 
983
           // Free the CCB
 
984
         ccb_P->clrInUse();
 
985
         } // end if (ccb_P!=NULL)
 
986
   } // end if (isRAIDcapable())
 
987
        // Get the next HBA
 
988
   hbaIt_P = (dptHBA_C *) phyList.next();
 
989
} // end while (hbaIt_P!=NULL)
 
990
 
 
991
  // Return success
 
992
return (1);
 
993
 
 
994
}
 
995
//dptSCSIdriver_C::findMyLogicals() - end
 
996
 
 
997
 
 
998
//Function - dptDriver_C::findComponent() - start
 
999
//===========================================================================
 
1000
//
 
1001
//Description:
 
1002
//
 
1003
//    This function finds a component device with the specified SCSI
 
1004
//address.  The HBA field of the SCSI address is assumed to be set to
 
1005
//the HBA's index #.
 
1006
//
 
1007
//Parameters:
 
1008
//
 
1009
//Return Value:
 
1010
//
 
1011
//Global Variables Affected:
 
1012
//
 
1013
//Remarks: (Side effects, Assumptions, Warnings...)
 
1014
//
 
1015
//
 
1016
//---------------------------------------------------------------------------
 
1017
 
 
1018
dptDevice_C *   dptDriver_C::findComponent(dptAddr_S inAddr,uSHORT method,uLONG inMagicNum, dptCoreList_C *list_P)
 
1019
{
 
1020
 
 
1021
   dptHBA_C             *hbaIt_P = NULL;
 
1022
   dptDevice_C          *comp_P = NULL;
 
1023
 
 
1024
  // If a magic number was specified...
 
1025
if (inMagicNum) {
 
1026
        // list_P should only be valid for 5th Gen. controllers to limit the component search to
 
1027
        // the HBA's logical list.
 
1028
        if (list_P) {
 
1029
                // Find the component in the HBA's logical list
 
1030
                comp_P = (dptDevice_C *) ::findMagicObject(*list_P, inMagicNum, 1);
 
1031
        }
 
1032
        else {
 
1033
                // Find the component on any HBA
 
1034
                comp_P = (dptDevice_C *) myConn_P()->findMagicObject(inMagicNum);
 
1035
        }
 
1036
        // If the object was found...
 
1037
        if (comp_P) {
 
1038
                // Use the object's HBA
 
1039
                 hbaIt_P = comp_P->myHBA_P();
 
1040
        }
 
1041
}
 
1042
 
 
1043
  // If we haven't found the HBA yet...
 
1044
if (hbaIt_P == NULL) {
 
1045
   hbaIt_P = (dptHBA_C *) phyList.reset();
 
1046
   while (hbaIt_P!=NULL) {
 
1047
        // If the HBA's RAID ID equals the component's RAID ID
 
1048
         if ((method==0) && ((hbaIt_P->getSWid()==inAddr.hba) ||
 
1049
                          (hbaIt_P->getSlotID()==inAddr.hba)))
 
1050
         break;
 
1051
        // If the HBA # equals the components HBA #
 
1052
         else if ((method==1) && (hbaIt_P->getHBA()==inAddr.hba))
 
1053
         break;
 
1054
         else
 
1055
           // Get the next HBA
 
1056
         hbaIt_P = (dptHBA_C *) phyList.next();
 
1057
   }
 
1058
}
 
1059
  // If an HBA was not found...
 
1060
if (hbaIt_P == NULL) {
 
1061
        // Create an absent HBA
 
1062
   hbaIt_P = (dptHBA_C *) newObject(DPT_SCSI_HBA);
 
1063
   if (hbaIt_P!=NULL) {
 
1064
        // Get the HBA's base address from the index number
 
1065
         hbaIt_P->setBaseFromRAIDid(inAddr.hba);
 
1066
        // Set the HBA's status to missing
 
1067
         hbaIt_P->status.display = DSPLY_STAT_MISSING;
 
1068
        // Add the absent HBA to the physical device list
 
1069
         if (enterPhy(hbaIt_P) != MSG_RTN_COMPLETED)
 
1070
         hbaIt_P = NULL;
 
1071
   }
 
1072
}
 
1073
  // If we haven't already found the desired component (via magic #)...
 
1074
else if (comp_P == NULL) {
 
1075
        // Get the HBA's sequence #
 
1076
   inAddr.hba = hbaIt_P->getHBA();
 
1077
        // Attempt to find the component device
 
1078
   comp_P = (dptDevice_C *) findObjectAt(hbaIt_P->logList,inAddr);
 
1079
}
 
1080
 
 
1081
  // If an HBA exists but no component exists...
 
1082
if ((comp_P==NULL) && (hbaIt_P!=NULL)) {
 
1083
        // Create an absent device
 
1084
   comp_P = (dptDevice_C *) newObject(DPT_SCSI_DASD);
 
1085
   if (comp_P!=NULL) {
 
1086
        // Get the HBA's sequence #
 
1087
         inAddr.hba = hbaIt_P->getHBA();
 
1088
        // Set the absent device's SCSI address
 
1089
         comp_P->addr = inAddr;
 
1090
        // Set the component's status to missing
 
1091
         comp_P->status.display = DSPLY_STAT_MISSING;
 
1092
        // Add the component to the HBA's logical device list
 
1093
         hbaIt_P->enterLog(comp_P);
 
1094
   }
 
1095
}
 
1096
 
 
1097
return (comp_P);
 
1098
 
 
1099
}
 
1100
//dptDriver_C::findComponent() - end
 
1101
 
 
1102
 
 
1103
//Function - dptDriver_C::setPAPinfo() - start
 
1104
//===========================================================================
 
1105
//
 
1106
//Description:
 
1107
//
 
1108
//    If a device is specified, this function sets the physical array
 
1109
//page status for that device.  If no device is specified, the status
 
1110
//of all physical devices attached to this manager are updated.
 
1111
//
 
1112
//Parameters:
 
1113
//
 
1114
//Return Value:
 
1115
//
 
1116
//Global Variables Affected:
 
1117
//
 
1118
//Remarks: (Side effects, Assumptions, Warnings...)
 
1119
//
 
1120
//
 
1121
//---------------------------------------------------------------------------
 
1122
 
 
1123
DPT_RTN_T dptDriver_C::setPAPinfo(dptDevice_C *dev_P)
 
1124
{
 
1125
 
 
1126
   DPT_RTN_T   retVal = MSG_RTN_FAILED | ERR_GET_CCB;
 
1127
   dptHBA_C     *hbaIt_P;
 
1128
 
 
1129
  // Get a CCB
 
1130
engCCB_C *ccb_P = getCCB();
 
1131
if (ccb_P!=NULL) {
 
1132
        retVal = MSG_RTN_IGNORED;
 
1133
        if (dev_P!=NULL) {
 
1134
                hbaIt_P = dev_P->myHBA_P();
 
1135
                // Send SW level RAID cmd to the specified device's HBA
 
1136
                ccb_P->target(hbaIt_P->getAddr(),hbaIt_P,CCB_ORIG_MGR);
 
1137
                if (getPAP(ccb_P)==MSG_RTN_COMPLETED)
 
1138
                        // Set the specified device's PAP status
 
1139
                        retVal = dev_P->setPAPstatus(ccb_P);
 
1140
        }
 
1141
        else {
 
1142
                hbaIt_P = (dptHBA_C *) phyList.reset();
 
1143
                while (hbaIt_P!=NULL) {
 
1144
                        // If the HBA is real && supports RAID...
 
1145
                        if (hbaIt_P->isReal() && hbaIt_P->isRAIDcapable()) {
 
1146
                                retVal = MSG_RTN_COMPLETED;
 
1147
                                // Target the HBA
 
1148
                                ccb_P->target(hbaIt_P->getAddr(),hbaIt_P,CCB_ORIG_MGR);
 
1149
                                // If the physical array page was retrieved...
 
1150
                                if (getPAP(ccb_P)==MSG_RTN_COMPLETED)
 
1151
                                        // Set the HBA's logical devices' PAP status
 
1152
                                        hbaIt_P->setLogPAP(ccb_P);
 
1153
                        }
 
1154
                        hbaIt_P = (dptHBA_C *) phyList.next();
 
1155
                }
 
1156
 
 
1157
        }
 
1158
        // Free the CCB
 
1159
        ccb_P->clrInUse();
 
1160
}
 
1161
 
 
1162
return (retVal);
 
1163
 
 
1164
}
 
1165
//dptDriver_C::setPAPinfo() - end
 
1166
 
 
1167
 
 
1168
//Function - dptDriver_C::delAllEmulation() - start
 
1169
//===========================================================================
 
1170
//
 
1171
//Description:
 
1172
//
 
1173
//    This function deletes all emulation drives from the system.
 
1174
//
 
1175
//Parameters:
 
1176
//
 
1177
//Return Value:
 
1178
//
 
1179
//Global Variables Affected:
 
1180
//
 
1181
//Remarks: (Side effects, Assumptions, Warnings...)
 
1182
//
 
1183
//
 
1184
//---------------------------------------------------------------------------
 
1185
 
 
1186
DPT_RTN_T dptDriver_C::delAllEmulation()
 
1187
{
 
1188
 
 
1189
   DPT_RTN_T   retVal = MSG_RTN_COMPLETED;
 
1190
   DPT_RTN_T   tempStatus;
 
1191
 
 
1192
  // For all HBAs...
 
1193
dptHBA_C *hbaIt_P = (dptHBA_C *) phyList.reset();
 
1194
while (hbaIt_P!=NULL) {
 
1195
        // Delete emulated drives
 
1196
   tempStatus = hbaIt_P->delEmulation();
 
1197
   if (retVal == MSG_RTN_COMPLETED)
 
1198
         retVal = tempStatus;
 
1199
        // Get the next HBA
 
1200
   hbaIt_P = (dptHBA_C *) phyList.next();
 
1201
}
 
1202
 
 
1203
return (retVal);
 
1204
 
 
1205
}
 
1206
//dptDriver_C::delAllEmulation() - end
 
1207
 
 
1208
 
 
1209
//Function - dptDriver_C::findLSUpartitions() - start
 
1210
//===========================================================================
 
1211
//
 
1212
//Description:
 
1213
//
 
1214
//    This function checks all LSUs for a valid partition table.  If a
 
1215
//valid partition is found, the last block used by a partition is
 
1216
//recorded.
 
1217
//
 
1218
//Parameters:
 
1219
//
 
1220
//Return Value:
 
1221
//
 
1222
//Global Variables Affected:
 
1223
//
 
1224
//Remarks: (Side effects, Assumptions, Warnings...)
 
1225
//
 
1226
//
 
1227
//---------------------------------------------------------------------------
 
1228
 
 
1229
void    dptDriver_C::findLSUpartitions()
 
1230
{
 
1231
 
 
1232
dptDevice_C *dev_P = (dptDevice_C *) logList.reset();
 
1233
while (dev_P!=NULL) {
 
1234
        // Check for a valid partition table
 
1235
   dev_P->checkForPartition();
 
1236
        // Get the next LSU
 
1237
   dev_P = (dptDevice_C *) logList.next();
 
1238
}
 
1239
 
 
1240
}
 
1241
//dptDriver_C::findLSUpartitions() - end
 
1242
 
 
1243
 
 
1244
#ifdef  _DUMP_EATA_CP
 
1245
//Function - DumpCommand() - start
 
1246
//===========================================================================
 
1247
//
 
1248
//Description:
 
1249
//
 
1250
//    This function dumps relevant information from the EATA CP to a file.
 
1251
//
 
1252
//---------------------------------------------------------------------------
 
1253
 
 
1254
void    DumpCommand(engCCB_C *ccb_P)
 
1255
{
 
1256
 
 
1257
int             i;
 
1258
 
 
1259
odebug.fill('0');
 
1260
odebug << "Target=";
 
1261
if (ccb_P->hba_P)
 
1262
        odebug << setw(2) << (uSHORT)(ccb_P->hba_P->getDrvrNum());
 
1263
else
 
1264
        odebug << "??";
 
1265
odebug << '-';
 
1266
odebug << hex << setw(2) << (uSHORT)(ccb_P->eataCP.devAddr >> 5) << ',';
 
1267
odebug << hex << setw(2) << (uSHORT)(ccb_P->eataCP.devAddr & 0x1f) << ',';
 
1268
odebug << hex << setw(2) << (uSHORT)(ccb_P->eataCP.message[0] & 0x7) << " ";
 
1269
 
 
1270
odebug.fill(' ');
 
1271
if (ccb_P->eataCP.flags & CP_DATA_IN)
 
1272
   odebug << " -Din";
 
1273
else
 
1274
   odebug << "     ";
 
1275
 
 
1276
if (ccb_P->eataCP.flags & CP_DATA_OUT)
 
1277
   odebug << " -Dout";
 
1278
else
 
1279
   odebug << "      ";
 
1280
 
 
1281
if (ccb_P->eataCP.flags & CP_INTERPRET)
 
1282
   odebug << " -Int";
 
1283
else
 
1284
   odebug << "     ";
 
1285
 
 
1286
if (ccb_P->eataCP.physical & 0x1)
 
1287
   odebug << " -Phy";
 
1288
else
 
1289
   odebug << "     ";
 
1290
if (ccb_P->eataCP.nestedFW & 0x1)
 
1291
   odebug << " -NFW";
 
1292
else
 
1293
   odebug << "     ";
 
1294
 
 
1295
odebug.fill('0');
 
1296
odebug << " CDB: ";
 
1297
for (i=0; i<12; i++)
 
1298
        odebug << hex << setw(2) << (uSHORT)ccb_P->eataCP.scsiCDB[i] << ' ';
 
1299
 
 
1300
odebug << endl;
 
1301
 
 
1302
if (ccb_P->eataCP.flags & CP_DATA_OUT) {
 
1303
        odebug << "    outdata: ";
 
1304
        for (i=0; i<28; i++) {
 
1305
                odebug << hex << setw(2) << (uSHORT)ccb_P->dataBuff_P[i];
 
1306
                if ((i & 0x03) == 0x03) {
 
1307
                        odebug << "  ";
 
1308
                }
 
1309
        }
 
1310
        odebug << endl;
 
1311
}
 
1312
 
 
1313
}
 
1314
//DumpCommand() - end
 
1315
 
 
1316
 
 
1317
//Function - DumpRtnCommand() - start
 
1318
//===========================================================================
 
1319
//
 
1320
//Description:
 
1321
//
 
1322
//    This function dumps the results of an EATA CP.
 
1323
//
 
1324
//---------------------------------------------------------------------------
 
1325
 
 
1326
void    DumpRtnCommand(engCCB_C *ccb_P, DPT_RTN_T retVal)
 
1327
{
 
1328
 
 
1329
int             i;
 
1330
 
 
1331
odebug.fill('0');
 
1332
if (ccb_P->eataCP.flags & CP_DATA_IN) {
 
1333
        odebug << "     indata: ";
 
1334
        for (i=0; i<28; i++) {
 
1335
                odebug << hex << setw(2) << (uSHORT)ccb_P->dataBuff_P[i];
 
1336
                if ((i & 0x03) == 0x03) {
 
1337
                        odebug << "  ";
 
1338
                }
 
1339
        }
 
1340
        odebug << endl;
 
1341
}
 
1342
 
 
1343
odebug << "    retVal=0x" << hex << setw(8) << retVal << "  ctlrStatus=0x" << hex << setw(2) << (uSHORT) ccb_P->ctlrStatus << "  scsiStatus=0x" << hex << setw(2) << (uSHORT) ccb_P->scsiStatus << endl;
 
1344
if (ccb_P->scsiStatus == 0x02) {
 
1345
        odebug << "    sensekey=0x" << hex << setw(2) << (uSHORT) ccb_P->defReqSense[2];
 
1346
        odebug << "  asc=0x" << hex << setw(2) << (uSHORT) ccb_P->defReqSense[12];
 
1347
        odebug << "  ascq=0x" << hex << setw(2) << (uSHORT) ccb_P->defReqSense[13];
 
1348
        odebug << "  sense[15, 16, 17]= " << hex << setw(2) << (uSHORT)ccb_P->defReqSense[15] << "  " << setw(2) << (uSHORT)ccb_P->defReqSense[16] << "  " << setw(2) << (uSHORT)ccb_P->defReqSense[17];
 
1349
        odebug << endl;
 
1350
}
 
1351
 
 
1352
odebug << endl;
 
1353
 
 
1354
}
 
1355
//DumpCommand() - end
 
1356
#endif
 
1357
 
 
1358