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

« back to all changes in this revision

Viewing changes to raideng/connect.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 - CONNECT.CPP
 
30
//***************************************************************************
 
31
//
 
32
//Description:
 
33
//
 
34
//    This file contains the function definitions for the dptConnection_C
 
35
//class.
 
36
//
 
37
//Author:       Doug Anderson
 
38
//Date:         4/7/93
 
39
//
 
40
//Editors:
 
41
//
 
42
//Remarks:
 
43
//
 
44
//
 
45
//***************************************************************************
 
46
 
 
47
 
 
48
//Include Files -------------------------------------------------------------
 
49
 
 
50
#include        "allfiles.hpp"  // All engine include files
 
51
 
 
52
 
 
53
#if !defined _DPT_UNIX && !defined _DPT_NETWARE && !defined _DPT_DOS
 
54
extern "C" {
 
55
        void osdTargetOffline(uLONG HbaNum, uLONG Channel, uLONG TargetId, uLONG LUN);
 
56
}
 
57
#else
 
58
        void osdTargetOffline(uLONG HbaNum, uLONG Channel, uLONG TargetId, uLONG LUN);
 
59
#endif // _DPT_UNIX
 
60
 
 
61
 
 
62
//Function - dptConnection_C::newMgrZero() - start
 
63
//===========================================================================
 
64
//
 
65
//Description:
 
66
//
 
67
//    This function allocates a new absent driver manager as manager zero.
 
68
//
 
69
//Parameters:
 
70
//
 
71
//Return Value:
 
72
//
 
73
//Global Variables Affected:
 
74
//
 
75
//Remarks: (Side effects, Assumptions, Warnings...)
 
76
//
 
77
//
 
78
//---------------------------------------------------------------------------
 
79
 
 
80
dptCoreMgr_C * dptConnection_C::newMgrZero()
 
81
{
 
82
 
 
83
  // Create a SCSI driver
 
84
dptManager_C *mgr_P = new dptDriver_C;
 
85
  // If an I/O method is supported...
 
86
if ((mgr_P!=NULL) && (ioMethod!=DPT_IO_NONE))
 
87
     // The driver is real
 
88
   mgr_P->status.flags |= FLG_STAT_REAL;
 
89
 
 
90
return (mgr_P);
 
91
 
 
92
}
 
93
//dptConnection_C::newMgrZero() - end
 
94
 
 
95
 
 
96
//Function - dptConnection_C::acquireCCB() - start
 
97
//===========================================================================
 
98
//
 
99
//Description:
 
100
//
 
101
//    This function returns a pointer to an engine CCB.  A pointer to the
 
102
//first CCB not in use is returned.  If all CCBs are in use, a new CCB is
 
103
//created and added to the end of the CCB list.
 
104
//
 
105
//Parameters:
 
106
//
 
107
//Return Value:
 
108
//
 
109
//Global Variables Affected:
 
110
//
 
111
//Remarks: (Side effects, Assumptions, Warnings...)
 
112
//
 
113
//
 
114
//---------------------------------------------------------------------------
 
115
 
 
116
engCCB_C *      dptConnection_C::acquireCCB()
 
117
{
 
118
 
 
119
   engCCB_C     *ccb_P;
 
120
   uSHORT       found = 0;
 
121
 
 
122
  // Get the first available CCB
 
123
ccb_P = (engCCB_C *) ccbList.reset();
 
124
while ((ccb_P!=NULL) && !found) {
 
125
     // Check if the CCB is in use
 
126
   if (!ccb_P->isInUse()) {
 
127
        // Indicate that the CCB is in use
 
128
      ccb_P->setInUse();
 
129
        // Indicate that an available CCB was found
 
130
      found = 1;
 
131
   }
 
132
   else
 
133
        // Get the next CCB
 
134
      ccb_P = (engCCB_C *) ccbList.next();
 
135
}
 
136
 
 
137
if (!found) {
 
138
#ifdef          __DPT_ALLOC
 
139
     // Allocate a new CCB
 
140
   ccb_P = (engCCB_C *) osdAlloc(sizeof(engCCB_C));
 
141
#else
 
142
     // Allocate a new CCB
 
143
   ccb_P = new engCCB_C;
 
144
#endif
 
145
   if (ccb_P!=NULL) {
 
146
        // Initialize the CCB
 
147
      ccb_P->init();
 
148
        // Indicate that the CCB is in use
 
149
      ccb_P->setInUse();
 
150
         // Add the new CCB to the end of the HBA's CCB list
 
151
      if (!ccbList.addEnd(ccb_P)) {
 
152
#ifdef          __DPT_ALLOC
 
153
           // Free the CCB
 
154
         osdFree(ccb_P);
 
155
#else
 
156
         delete (ccb_P);
 
157
#endif
 
158
         ccb_P = NULL;
 
159
      }
 
160
   }
 
161
} // end if (!found)
 
162
 
 
163
if (ccb_P!=NULL)
 
164
     // Re-initialize the CCB
 
165
   ccb_P->reInit();
 
166
 
 
167
return (ccb_P);
 
168
 
 
169
}
 
170
//dptConnection_C::acquireCCB() - end
 
171
 
 
172
 
 
173
//Function - dptConnection_C::reserveEndOfDisks() - start
 
174
//===========================================================================
 
175
//
 
176
//Description:
 
177
//
 
178
//    This function attempts to reserve space at the end of all non-
 
179
//removeable DASD devices.  This space is used by DPT to store
 
180
//configuration information, downloaded FW code...
 
181
//
 
182
//Parameters:
 
183
//
 
184
//Return Value:
 
185
//
 
186
//Global Variables Affected:
 
187
//
 
188
//Remarks: (Side effects, Assumptions, Warnings...)
 
189
//
 
190
//  1. This function assumes that partition information has been obtained
 
191
//
 
192
//---------------------------------------------------------------------------
 
193
 
 
194
void    dptConnection_C::reserveEndOfDisks()
 
195
{
 
196
 
 
197
   uLONG        spaceReserved;
 
198
   dptDevice_C  *dev_P;
 
199
 
 
200
DEBUG_BEGIN(1, dptConnection_C::reserveEndOfDisks());
 
201
 
 
202
dptObject_C *obj_P = (dptObject_C *) objectList.reset();
 
203
while (obj_P!=NULL) {
 
204
        if (obj_P->isDevice()) {
 
205
                dev_P = (dptDevice_C *) obj_P;
 
206
                // If a non-removeable HBA physical DASD device...
 
207
                if ((dev_P->getLevel()==2) && (dev_P->getObjType()==DPT_SCSI_DASD) &&
 
208
                !dev_P->isComponent() && !dev_P->isRemoveable()) {
 
209
 
 
210
                        // Determine how much space is currently reserved
 
211
                        spaceReserved = dev_P->getMaxPhyLBA() - dev_P->getLastLBA();
 
212
 
 
213
                        #ifdef _SINIX_ADDON
 
214
                                // SNI: To keep compatibility with other HBAs (Adaptec, Symbios ..)
 
215
                                // we reserve only 1 block on normal SCSI disks.
 
216
                                // More space is reserved on LSU creation.
 
217
                                // See reserveTempSpace() and enableTempSpace().
 
218
                                if (spaceReserved != 1) {
 
219
                                        dev_P->reserveEndOfDisk(1);
 
220
                                        DEBUG(1, PRT_DADDR(dev_P) << " RESERVED: old=" << spaceReserved << " new=" << \
 
221
                                                (int) (dev_P->getMaxPhyLBA() - dev_P->getLastLBA()));
 
222
                                }
 
223
                                // At this place osdGetLBA() is called only to get the "MP.." name.
 
224
                                // The spaceReserved value of SDI is ignored here. - michiz.
 
225
                                dptHBA_C *hba_P = obj_P->myHBA_P();
 
226
                                spaceReserved = 0;
 
227
                                osdGetLBA(hba_P->getDrvrNum(), dev_P->getChan(), dev_P->getID(), &spaceReserved, dev_P->userBuff, (uLONG) dev_P->getMaxPhyLBA());
 
228
                        #else
 
229
                                // If insufficient blocks have been reserved...
 
230
                                if (spaceReserved < RESERVED_SPACE_DISK) {
 
231
                                        // Determine how much space is not used by a valid
 
232
                                        // partition.
 
233
                                        uLONG availableSpace = dev_P->getMaxPhyLBA() - dev_P->getLastPartBlk();
 
234
 
 
235
                                        uSHORT spaceToReserve = 0;
 
236
                                        // If more space can be reserved...
 
237
                                        if (availableSpace > spaceReserved) {
 
238
                                                // Reserve up to RESERVED_SPACE_DISK blocks
 
239
                                                spaceToReserve = (availableSpace > RESERVED_SPACE_DISK) ? RESERVED_SPACE_DISK : (uSHORT) availableSpace;
 
240
                                                // Reserve the space
 
241
                                                dev_P->reserveEndOfDisk(spaceToReserve);
 
242
                                        }
 
243
 
 
244
                                        // tell the user how much space was reserved at the end of the disk for DPT stuff
 
245
                                        DEBUG(1, PRT_DADDR(dev_P) << " RESERVED: " << spaceToReserve);
 
246
                                }
 
247
                        #endif
 
248
                }
 
249
        }
 
250
        obj_P = (dptObject_C *) objectList.next();
 
251
}
 
252
 
 
253
}
 
254
//dptConnection_C::reserveEndOfDisks() - end
 
255
 
 
256
 
 
257
//Function - dptConnection_C::zapPartitions() - start
 
258
//===========================================================================
 
259
//
 
260
//Description:
 
261
//
 
262
//    This function destroys the partition table on all devices that
 
263
//are flagged for partition table zapping.
 
264
//
 
265
//Parameters:
 
266
//
 
267
//Return Value:
 
268
//
 
269
//Global Variables Affected:
 
270
//
 
271
//Remarks: (Side effects, Assumptions, Warnings...)
 
272
//
 
273
//
 
274
//---------------------------------------------------------------------------
 
275
 
 
276
DPT_RTN_T       dptConnection_C::zapPartitions()
 
277
{
 
278
 
 
279
   DPT_RTN_T    retVal = MSG_RTN_COMPLETED;
 
280
   dptDevice_C  *dev_P;
 
281
 
 
282
dptObject_C *obj_P = (dptObject_C *) objectList.reset();
 
283
while (obj_P!=NULL) {
 
284
        // If this object is a device...
 
285
        if (obj_P->isDevice()) {
 
286
                dev_P = (dptDevice_C *) obj_P;
 
287
 
 
288
                // If the device is marked for partition zapping...
 
289
                if (dev_P->isPartitionMarked() && !dev_P->isComponent()) {
 
290
                        // If a new SW array on a 4th Gen board...
 
291
                        if ((dev_P->getRAIDtype()==0) && (dev_P->getLevel()==0) && !dev_P->myHBA_P()->isI2O())
 
292
                                // Clear the component device partitions
 
293
                                dev_P->zapCompPartitions();
 
294
                        else
 
295
                                // Clear the partition table sector
 
296
                                dev_P->zapPartition();
 
297
                }
 
298
 
 
299
                // Clear the partition table zap indicator
 
300
                dev_P->clrPartitionZap();
 
301
                // Clear the new RAID-0 indicator
 
302
                dev_P->clrNewRAID0();
 
303
        }
 
304
        obj_P = (dptObject_C *) objectList.next();
 
305
}
 
306
 
 
307
return (retVal);
 
308
 
 
309
}
 
310
//dptConnection_C::zapPartitions() - end
 
311
 
 
312
 
 
313
//Function - dptConnection_C::genMagicNum() - start
 
314
//===========================================================================
 
315
//
 
316
//Description:
 
317
//      This function generates a unique magic number and guarantees
 
318
//that no other object in this connection has the same magic number.
 
319
//
 
320
//---------------------------------------------------------------------------
 
321
 
 
322
uLONG   dptConnection_C::genMagicNum()
 
323
{
 
324
 
 
325
uINT    duplicateFound;
 
326
time_t  curTime;
 
327
uLONG   newMagicNum = 0x12345678L;
 
328
 
 
329
time(&curTime);
 
330
srand(curTime);
 
331
 
 
332
do {
 
333
 
 
334
     // Assume no duplicates until one is found
 
335
   duplicateFound = 0;
 
336
     // Create the magic number
 
337
   newMagicNum = rand() & 0x7fff; // Bit #31 reserved by F/W
 
338
   newMagicNum <<= 16;
 
339
   newMagicNum |= rand() & 0xffff;
 
340
 
 
341
     // Insure the new magic number is unique
 
342
   dptObject_C *obj_P = (dptObject_C *) objectList.reset();
 
343
   while (obj_P) {
 
344
      if (newMagicNum == obj_P->getMagicNum()) {
 
345
         duplicateFound = 1;
 
346
         break;
 
347
      }
 
348
      obj_P = (dptObject_C *) objectList.next();
 
349
   }
 
350
 
 
351
} while (duplicateFound);
 
352
 
 
353
return (newMagicNum);
 
354
 
 
355
}
 
356
//dptConnection_C::genMagicNum() - end
 
357
 
 
358
 
 
359
//Function - dptConnection_C::setPrevOsVisibles() - start
 
360
//===========================================================================
 
361
//Description:
 
362
//    This function sets all devices flagged as OS visible to previously
 
363
//OS visible.
 
364
//---------------------------------------------------------------------------
 
365
 
 
366
void    dptConnection_C::setPrevOsVisibles()
 
367
{
 
368
 
 
369
        dptDevice_C     *dev_P;
 
370
 
 
371
        dptObject_C *obj_P = (dptObject_C *) objectList.reset();
 
372
        while (obj_P!=NULL) {
 
373
                if (obj_P->isDevice()) {
 
374
                        dev_P = (dptDevice_C *) obj_P;
 
375
                        if (dev_P->isOsVisible()) {
 
376
                                dev_P->clrOsVisible();
 
377
                                dev_P->setPrevOsVisible();
 
378
                        }
 
379
                        else {
 
380
                                dev_P->clrPrevOsVisible();
 
381
                        }
 
382
                }
 
383
                obj_P = (dptObject_C *) objectList.next();
 
384
        }
 
385
 
 
386
}
 
387
//dptConnection_C::setPrevOsVisibles() - end
 
388
 
 
389
 
 
390
//Function - dptConnection_C::lsuOffline() - start
 
391
//===========================================================================
 
392
//Description:
 
393
//    This function sets all devices flagged as OS visible to previously
 
394
//OS visible.
 
395
//---------------------------------------------------------------------------
 
396
 
 
397
void    dptConnection_C::lsuOffline()
 
398
{
 
399
 
 
400
        dptDevice_C     *dev_P;
 
401
 
 
402
        dptObject_C *obj_P = (dptObject_C *) objectList.reset();
 
403
        while (obj_P!=NULL) {
 
404
                if (obj_P->isDevice()) {
 
405
                        dev_P = (dptDevice_C *) obj_P;
 
406
                        if (!dev_P->isOsVisible() && dev_P->isPrevOsVisible()) {
 
407
                                // Prepare the LSU to go offline
 
408
                                osdTargetOffline((uLONG)dev_P->myHBA_P()->getDrvrNum(), (uLONG)dev_P->getChan(), (uLONG)dev_P->getID(), (uLONG)dev_P->getLUN());
 
409
                        }
 
410
                }
 
411
                obj_P = (dptObject_C *) objectList.next();
 
412
        }
 
413
 
 
414
}
 
415
//dptConnection_C::lsuOffline() - end
 
416
 
 
417
 
 
418
//Function - dptConnection_C::~dptConnection_C() - start
 
419
//===========================================================================
 
420
//
 
421
//Description:
 
422
//
 
423
//    This function is the destructor for the dptConnection_C class.
 
424
//
 
425
//Parameters:
 
426
//
 
427
//Return Value:
 
428
//
 
429
//Global Variables Affected:
 
430
//
 
431
//Remarks: (Side effects, Assumptions, Warnings...)
 
432
//
 
433
//
 
434
//---------------------------------------------------------------------------
 
435
 
 
436
dptConnection_C::~dptConnection_C()
 
437
{
 
438
 
 
439
  // If this connection is capable of I/O
 
440
if (ioMethod!=DPT_IO_NONE)
 
441
     // Let the OS dependent layer know that the connection has
 
442
     // been removed
 
443
   osdDisconnected(ioMethod);
 
444
 
 
445
#ifdef  __DPT_ALLOC
 
446
     // Free all the CCBs
 
447
   engCCB_C *ccb_P = (engCCB_C *) ccbList.reset();
 
448
   while (ccb_P!=NULL) {
 
449
      osdFree(ccb_P);
 
450
      ccb_P = (engCCB_C *) ccbList.next();
 
451
   }
 
452
#else
 
453
   ccbList.kill();
 
454
#endif
 
455
 
 
456
}
 
457
//dptConnection_C::~dptConnection_C() - end
 
458
 
 
459