1
/* Copyright (c) 1996-2004, Adaptec Corporation
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
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.
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.
30
//***************************************************************************
34
// This file contains function definitions for the dptDriver_C
37
//Author: Doug Anderson
45
//***************************************************************************
47
#include "allfiles.hpp"
52
void LogEvent(CHAR *);
53
extern uLONG osdBadInterpretFW;
57
//#define _DUMP_EATA_CP
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);
66
#if !defined _DPT_UNIX && !defined _DPT_NETWARE && !defined _DPT_DOS
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);
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);
78
//Function - dptDriver_C::passCCB() - start
79
//===========================================================================
83
// This function passes the CCB to the OS dependent layer for output
90
//Global Variables Affected:
92
//Remarks: (Side effects, Assumptions, Warnings...)
95
//---------------------------------------------------------------------------
97
DPT_RTN_T dptDriver_C::passCCB(engCCB_C *ccb_P)
100
DPT_RTN_T retVal = MSG_RTN_FAILED;
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
107
#ifdef ENABLE_SCSI_TRACE
108
cout << "CMD=" << hex << setw(2) << (uSHORT) ccb_P->eataCP.scsiCDB[0] << ", ";
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();
117
cout << hex << setw(4) << ccb_P->hba_P->getISAaddr();
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)
129
if (ccb_P->eataCP.flags & CP_DATA_OUT)
133
if (ccb_P->eataCP.flags & CP_INTERPRET)
134
cout << " -Interpret";
137
if (ccb_P->eataCP.physical & 0x1)
138
cout << " -Physical";
141
if (ccb_P->eataCP.nestedFW & 0x1)
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();
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());
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;
163
// If this is not an event logger command...
164
if (!ccb_P->isLoggerCmd()) {
169
// Send the CCB to hardware
170
retVal = osdSendCCB(myConn_P()->getIOmethod(),ccb_P);
173
DumpRtnCommand(ccb_P, retVal);
176
else if (ccb_P->eataCP.scsiCDB[1] & 0x01)
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);
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);
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);
194
#ifdef ENABLE_SCSI_TRACE
195
if ((retVal==MSG_RTN_COMPLETED) && ccb_P->ok())
205
//dptDriver_C::passCCB() - end
208
//Function - dptDriver_C::handleMessage() - start
209
//===========================================================================
213
// This function processes messages for a SCSI driver.
219
//Global Variables Affected:
221
//Remarks: (Side effects, Assumptions, Warnings...)
224
//---------------------------------------------------------------------------
226
DPT_RTN_T dptDriver_C::handleMessage(DPT_MSG_T message,
227
dptBuffer_S *fromEng_P,
232
DPT_RTN_T retVal = MSG_RTN_IGNORED;
236
// Scan system hardware for all physical and logical objects
237
case MSG_IO_SCAN_SYSTEM:
238
retVal = scanSystem();
241
// Scan system hardware for all HBA objects
242
case MSG_IO_SCAN_HBAS:
243
retVal = scanSystem(3);
246
// Scan system hardware for all physical objects
247
case MSG_IO_SCAN_PHYSICALS:
248
retVal = scanSystem(1);
251
// Scan system hardware for all logical objects
252
case MSG_IO_SCAN_LOGICALS:
253
retVal = scanSystem(2);
256
// Enable the current configuration in hardware
257
case MSG_RAID_HW_ENABLE:
258
retVal = raidHwEnable();
261
// get the count of MSG_RAID_HW_ENABLE
262
case MSG_GET_NUM_HW_ENABLES: {
264
retVal = MSG_RTN_DATA_OVERFLOW;
267
uLONG numSets = osdGetEnableCount();
273
if (fromEng_P->insert(numSets))
274
retVal = MSG_RTN_COMPLETED;
277
// Delete all objects
280
retVal = MSG_RTN_COMPLETED;
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
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
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:
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
328
//dz retVal = osdLoggerCmd(message,toEng_P,0,0,0);
329
retVal = osdLoggerCmd(message,(void*)toEng_P,(dptData_S*)fromEng_P,0,0,0);
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
338
//dz retVal = osdLoggerCmd(message,fromEng_P,0,0,0);
339
retVal = osdLoggerCmd(message,(void*)toEng_P,(dptData_S*)fromEng_P,0,0,0);
342
// Delete all emulated drives from the system
343
case MSG_DEL_ALL_EMULATION:
344
retVal = delAllEmulation();
347
// Call base class message handler
349
retVal = dptRAIDdrvr_C::handleMessage(message,fromEng_P,toEng_P);
356
//dptSCSIdrvr_C::handleMessage() - end
359
//Function - dptDriver_C::raidHwEnable() - start
360
//===========================================================================
362
// This function is the message handler for MSG_RAID_HW_ENABLE.
363
//---------------------------------------------------------------------------
365
DPT_RTN_T dptDriver_C::raidHwEnable()
368
DPT_RTN_T retVal = MSG_RTN_COMPLETED;
370
// Set the OS visible flags appropriately
371
myConn_P()->setPrevOsVisibles();
374
// Prepare deleted devices to go offline
376
// Prepare newly hidden devices to go offline
377
myConn_P()->lsuOffline();
379
// Enable the current configuration
380
retVal = enableConfig();
382
// Zap parition tables
383
if (myConn_P()->zapPartitions()==MSG_RTN_FAILED)
384
retVal = MSG_RTN_FAILED;
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());
394
// Get the next logical device
395
dev_P = (dptDevice_C *) logList.next();
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);
404
hbaIt_P->clrBusResetDesired();
405
hbaIt_P = (dptHBA_C *) phyList.next();
408
// Increment the enable count
409
osdIncrementEnableCount();
414
//dptDriver_C::raidHwEnable() - end
417
//Function - dptDriver_C::scanSystem() - start
418
//===========================================================================
420
// This function scans the system hardware for all SCSI objects in
422
//---------------------------------------------------------------------------
424
DPT_RTN_T dptDriver_C::scanSystem(uSHORT searchType)
427
DPT_RTN_T retVal = MSG_RTN_COMPLETED;
429
// If not a logical device search only...
431
// Delete the current configuration
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;
441
// Initialize all physical objects found
443
if (retVal == MSG_RTN_COMPLETED) {
444
retVal = MSG_RTN_FAILED | ERR_INIT_PHYSICALS;
449
// If not a physical device only or HBA only search...
450
if ((searchType!=1) && (searchType!=3)) {
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;
459
// Initialize all logical objects found
461
if (retVal == MSG_RTN_COMPLETED) {
462
retVal = MSG_RTN_FAILED | ERR_INIT_LOGICALS;
466
// Check for valid partition tables
468
// Attempt to reserve space at the end of every non-removeable
469
// disk for use by DPT
470
myConn_P()->reserveEndOfDisks();
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();
479
// Flag the OS visible devices
482
// Initialize the device busy checking code
483
osdTargetBusy(0, 0, 0, 0);
489
//dptDriver_C::scanSystem() - end
492
//Function - dptDriver_C::findMyPhysicals() - start
493
//===========================================================================
497
// This function finds all of the SCSI HBAs visible to the driver.
506
//Global Variables Affected:
508
//Remarks: (Side effects, Assumptions, Warnings...)
511
//---------------------------------------------------------------------------
513
uSHORT dptDriver_C::findMyPhysicals()
516
uSHORT numCtlrs,index;
517
dptCoreList_C tempList;
519
drvrHBAinfo_S *hbaInfo_P;
520
oldDrvrHBAinfo_S *oldInfo_P;
521
eataRdConfig_S *rdCfg_P = NULL;
525
DEBUG_BEGIN(8, dptDriver_C::findMyPhysicals());
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();
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
537
if (osdGetCtlrs(myConn_P()->getIOmethod(),&numCtlrs,hbaInfo_P) == MSG_RTN_COMPLETED) {
538
// Indicate a successful scan
543
// Create objects for each controller found
544
for (index=0;index<numCtlrs;index++,hbaInfo_P++,oldInfo_P++) {
546
hbaIt_P = (dptHBA_C *) newObject(DPT_SCSI_HBA);
548
// Indicate that the HBA is real
549
hbaIt_P->status.flags |= FLG_STAT_REAL;
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;
558
if (hbaInfo_P->hbaFlags & FLG_OSD_I2O)
559
// Set the I2O indicator flag
560
hbaIt_P->hbaFlags2 |= FLG_HBA_I2O;
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;
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;
574
hbaIt_P->busNum = hbaInfo_P->pciBusNum;
575
hbaIt_P->devFnNum = hbaInfo_P->pciDeviceNum;
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;
591
// If in any other blink LED mode...
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;
600
// If not in blink LED or flash mode...
601
if (!hbaIt_P->isBlinkLED()) {
602
// Determine if the flash commands are supported...
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) {
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;
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;
624
// Get the standard inquiry information
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) {
631
// Initialize the HBA using the inquiry data
632
hbaIt_P->inquiryInit((sdInquiry_S *)ccb_P->defData);
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;
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]);
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;
659
// If not in blink LED or flash mode...
660
if (!hbaIt_P->isBlinkLED() && !hbaIt_P->isFlashMode()) {
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) {
669
rdCfg_P = (eataRdConfig_S *) ccb_P->dataBuff_P;
671
rdCfg_P->andLength(0xff);
676
// If valid read config. info
677
if (rdCfg_P != NULL) {
679
uCHAR flag1 = rdCfg_P->getFlag1();
680
uCHAR flag2 = rdCfg_P->getFlag2();
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());
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());
697
// If a primary HBA...
698
if (!(flag2 & RDCFG_PRIORITY)) {
699
hbaIt_P->setPrimary();
701
// Set the controller's SCSI ID
702
if (flag1 & RDCFG_HBA_ADDR)
703
hbaIt_P->addr.id = rdCfg_P->getScsiIDs()[3];
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;
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;
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;
736
hbaIt_P->busType = HBA_BUS_ISA;
738
else if (hbaIt_P->ioAddr.pci >= 0x1000)
739
hbaIt_P->busType = HBA_BUS_EISA;
741
hbaIt_P->busType = HBA_BUS_ISA;
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;
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
755
bitToSet <<= hbaIt_P->raidSWid;
756
usedRAIDids |= bitToSet;
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;
766
hbaIt_P->ioAddr.std.isa = 0x170;
769
} // end if (rdCfg_P != NULL)
771
// Add the HBA to the physical device list
774
} // end if (hbaIt_P!=NULL)
777
} // end if (buff_P!=NULL)
780
// Delete the HBA description buffer
790
//dptDriver_C::findMyPhysicals() - end
793
//Function - dptDriver_C::setOsVisibles() - start
794
//===========================================================================
796
// This function flags all devices in the driver's logical device
797
//list as OS visible.
798
//---------------------------------------------------------------------------
800
void dptDriver_C::setOsVisibles()
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();
812
//dptDriver_C::setOsVisibles() - end
815
//Function - dptDriver_C::initHBAs() - start
816
//===========================================================================
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.
828
//Global Variables Affected:
830
//Remarks: (Side effects, Assumptions, Warnings...)
833
//---------------------------------------------------------------------------
835
void dptDriver_C::initHBAs()
838
#ifdef ENABLE_SCSI_TRACE
839
cout << "Initializing HBAs..." << endl;
842
dptObject_C *obj_P = (dptObject_C *) phyList.reset();
843
while (obj_P!=NULL) {
844
// Initialize the HBA
847
obj_P = (dptObject_C *) phyList.next();
850
// Assign RAID ID numbers to the HBA's that don't have one
854
//dptDriver_C::initHBAs() - end
857
//Function - dptDriver_C::assignRAIDids() - start
858
//===========================================================================
862
// This function assigns a unique RAID ID to each HBA in the system.
864
//---------------------------------------------------------------------------
866
void dptDriver_C::assignRAIDids()
872
engCCB_C *ccb_P = getCCB();
874
dptHBA_C *hbaIt_P = (dptHBA_C *) phyList.reset();
875
while (hbaIt_P != NULL) {
877
//--------------------------------
878
// Assign the selectable RAID ID #
879
//--------------------------------
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))
890
// Issue the multi-function command
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) {
897
hbaIt_P->raidSWid = idNum;
898
// Indicate that the HBA ID # is used
900
bitToCheck <<= idNum;
901
usedRAIDids |= bitToCheck;
906
//-----------------------------------
907
// Assign the slot specific RAID ID #
908
//-----------------------------------
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();
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;
925
hbaIt_P = (dptHBA_C *) phyList.next();
934
//dptDriver_C::assignRAIDids() - end
937
//Function - dptDriver_C::findMyLogicals() - start
938
//===========================================================================
942
// This function finds all driver level logical devices in the system.
951
//Global Variables Affected:
953
//Remarks: (Side effects, Assumptions, Warnings...)
956
//---------------------------------------------------------------------------
958
uSHORT dptDriver_C::findMyLogicals()
964
hbaIt_P = (dptHBA_C *) phyList.reset();
966
while (hbaIt_P!=NULL) {
967
// If the HBA supports RAID...
968
if (hbaIt_P->isRAIDcapable()) {
972
// Initialize the CCB to do a log sense
973
ccb_P->logSense(0x36);
974
// Indicate that this is a RAID command
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);
985
} // end if (ccb_P!=NULL)
986
} // end if (isRAIDcapable())
988
hbaIt_P = (dptHBA_C *) phyList.next();
989
} // end while (hbaIt_P!=NULL)
995
//dptSCSIdriver_C::findMyLogicals() - end
998
//Function - dptDriver_C::findComponent() - start
999
//===========================================================================
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 #.
1011
//Global Variables Affected:
1013
//Remarks: (Side effects, Assumptions, Warnings...)
1016
//---------------------------------------------------------------------------
1018
dptDevice_C * dptDriver_C::findComponent(dptAddr_S inAddr,uSHORT method,uLONG inMagicNum, dptCoreList_C *list_P)
1021
dptHBA_C *hbaIt_P = NULL;
1022
dptDevice_C *comp_P = NULL;
1024
// If a magic number was specified...
1026
// list_P should only be valid for 5th Gen. controllers to limit the component search to
1027
// the HBA's logical list.
1029
// Find the component in the HBA's logical list
1030
comp_P = (dptDevice_C *) ::findMagicObject(*list_P, inMagicNum, 1);
1033
// Find the component on any HBA
1034
comp_P = (dptDevice_C *) myConn_P()->findMagicObject(inMagicNum);
1036
// If the object was found...
1038
// Use the object's HBA
1039
hbaIt_P = comp_P->myHBA_P();
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)))
1051
// If the HBA # equals the components HBA #
1052
else if ((method==1) && (hbaIt_P->getHBA()==inAddr.hba))
1056
hbaIt_P = (dptHBA_C *) phyList.next();
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)
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);
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);
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);
1100
//dptDriver_C::findComponent() - end
1103
//Function - dptDriver_C::setPAPinfo() - start
1104
//===========================================================================
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.
1116
//Global Variables Affected:
1118
//Remarks: (Side effects, Assumptions, Warnings...)
1121
//---------------------------------------------------------------------------
1123
DPT_RTN_T dptDriver_C::setPAPinfo(dptDevice_C *dev_P)
1126
DPT_RTN_T retVal = MSG_RTN_FAILED | ERR_GET_CCB;
1130
engCCB_C *ccb_P = getCCB();
1132
retVal = MSG_RTN_IGNORED;
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);
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;
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);
1154
hbaIt_P = (dptHBA_C *) phyList.next();
1165
//dptDriver_C::setPAPinfo() - end
1168
//Function - dptDriver_C::delAllEmulation() - start
1169
//===========================================================================
1173
// This function deletes all emulation drives from the system.
1179
//Global Variables Affected:
1181
//Remarks: (Side effects, Assumptions, Warnings...)
1184
//---------------------------------------------------------------------------
1186
DPT_RTN_T dptDriver_C::delAllEmulation()
1189
DPT_RTN_T retVal = MSG_RTN_COMPLETED;
1190
DPT_RTN_T tempStatus;
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;
1200
hbaIt_P = (dptHBA_C *) phyList.next();
1206
//dptDriver_C::delAllEmulation() - end
1209
//Function - dptDriver_C::findLSUpartitions() - start
1210
//===========================================================================
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
1222
//Global Variables Affected:
1224
//Remarks: (Side effects, Assumptions, Warnings...)
1227
//---------------------------------------------------------------------------
1229
void dptDriver_C::findLSUpartitions()
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();
1237
dev_P = (dptDevice_C *) logList.next();
1241
//dptDriver_C::findLSUpartitions() - end
1244
#ifdef _DUMP_EATA_CP
1245
//Function - DumpCommand() - start
1246
//===========================================================================
1250
// This function dumps relevant information from the EATA CP to a file.
1252
//---------------------------------------------------------------------------
1254
void DumpCommand(engCCB_C *ccb_P)
1260
odebug << "Target=";
1262
odebug << setw(2) << (uSHORT)(ccb_P->hba_P->getDrvrNum());
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) << " ";
1271
if (ccb_P->eataCP.flags & CP_DATA_IN)
1276
if (ccb_P->eataCP.flags & CP_DATA_OUT)
1281
if (ccb_P->eataCP.flags & CP_INTERPRET)
1286
if (ccb_P->eataCP.physical & 0x1)
1290
if (ccb_P->eataCP.nestedFW & 0x1)
1297
for (i=0; i<12; i++)
1298
odebug << hex << setw(2) << (uSHORT)ccb_P->eataCP.scsiCDB[i] << ' ';
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) {
1314
//DumpCommand() - end
1317
//Function - DumpRtnCommand() - start
1318
//===========================================================================
1322
// This function dumps the results of an EATA CP.
1324
//---------------------------------------------------------------------------
1326
void DumpRtnCommand(engCCB_C *ccb_P, DPT_RTN_T retVal)
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) {
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];
1355
//DumpCommand() - end