~ubuntu-branches/ubuntu/lucid/raidutils/lucid

« back to all changes in this revision

Viewing changes to raidutil/expand.cpp

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 1996-2004, Adaptec Corporation
 
2
 * All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 * - Redistributions of source code must retain the above copyright notice, this
 
8
 *   list of conditions and the following disclaimer.
 
9
 * - Redistributions in binary form must reproduce the above copyright notice,
 
10
 *   this list of conditions and the following disclaimer in the documentation
 
11
 *   and/or other materials provided with the distribution.
 
12
 * - Neither the name of the Adaptec Corporation nor the names of its
 
13
 *   contributors may be used to endorse or promote products derived from this
 
14
 *   software without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
17
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
19
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
20
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
21
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
22
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
23
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
24
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
25
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
26
 * POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/****************************************************************************
 
30
*
 
31
* Created:  12/17/99
 
32
*
 
33
*****************************************************************************
 
34
*
 
35
* File Name:            Expand.cpp
 
36
* Module:
 
37
* Contributors: Karla Summers
 
38
* Description:
 
39
* Version Control:
 
40
*
 
41
* $Revision: 4 $
 
42
* $NoKeywords: $
 
43
* $Log: $
 
44
*****************************************************************************/
 
45
 
 
46
/*** INCLUDES ***/
 
47
#include <stdio.h>
 
48
#include "expand.hpp"
 
49
#include "intlist.hpp"
 
50
#include "rustring.h"
 
51
#include "rscenum.h"
 
52
/*** CONSTANTS ***/
 
53
extern int FID_RESET_OUTBUFF;
 
54
extern uSHORT PHYS_LIST_SIZE;
 
55
extern uCHAR SMU_EXPANDING;
 
56
extern char* EventStrings[];
 
57
/*** TYPES ***/
 
58
/*** STATIC DATA ***/
 
59
/*** MACROS ***/
 
60
/*** PROTOTYPES ***/
 
61
/*** FUNCTIONS ***/
 
62
 
 
63
Expand::Expand(
 
64
                SCSI_Address raid,
 
65
                SCSI_Addr_List  *list
 
66
                ):
 
67
                raidToExpandAddr (raid),
 
68
      components (list)
 
69
{
 
70
        ENTER( "Expand::Expand(" );
 
71
        EXIT();
 
72
}
 
73
 
 
74
Expand::Expand (const Expand &new_Expand):
 
75
      raidToExpandAddr (new_Expand.raidToExpandAddr),
 
76
        components (new_Expand.components)
 
77
{
 
78
        ENTER ("Expand::Expand( const Expand &new_Expand):");
 
79
        EXIT ();
 
80
}
 
81
 
 
82
Expand::~Expand()
 
83
{
 
84
        ENTER ("Expand::~Expand()");
 
85
        EXIT ();
 
86
}
 
87
 
 
88
Command::Dpt_Error Expand::RaidExpandable (void)
 
89
{
 
90
        ENTER( "Command::Dpt_Error      Expand::RaidExpandable (void)");
 
91
   bool objFound = false;
 
92
   bool getHidden = false;
 
93
   int numComps;
 
94
   dptID_S *idlist = new dptID_S[PHYS_LIST_SIZE];
 
95
 
 
96
        Dpt_Error err;
 
97
 
 
98
   raidToExpandTag = Get_Log_Dev_by_Address (raidToExpandAddr, 
 
99
      getHidden, &objFound);
 
100
 
 
101
        err = engine->Send (MSG_GET_INFO, raidToExpandTag);
 
102
   raidToExpandType = engine->devInfo_P->raidType;
 
103
 
 
104
   if (!err.Is_Error())
 
105
   {
 
106
      // make sure the raid is a 0 or a 5 and not dual level
 
107
      if ((engine->devInfo_P->raidParent == -1) &&
 
108
          ((raidToExpandType == 5) || (raidToExpandType == 0)))
 
109
      {
 
110
         numComps = EngineFindIDs(FID_RESET_OUTBUFF, 
 
111
            MSG_ID_COMPONENTS, raidToExpandTag, 
 
112
            idlist, PHYS_LIST_SIZE);
 
113
         // save this for later.
 
114
         raidStripeSize = engine->devInfo_P->maxCompStripe;
 
115
         if (raidToExpandType == 5)
 
116
            currStripeSize = numComps * raidStripeSize;
 
117
         else
 
118
            currStripeSize = engine->devInfo_P->maxCompStripe;
 
119
         // get info from hba
 
120
         mgrTag = engine->devInfo_P->hbaTag;
 
121
        err = engine->Send (MSG_GET_INFO, mgrTag);
 
122
 
 
123
         // this value will have to be >= currStripeSize to add in the drive
 
124
         if (!err.Is_Error())
 
125
         {
 
126
            maxStripeSize = engine->hbaInfo_P->maxMajorStripe;
 
127
      
 
128
            if (!maxStripeSize)
 
129
               maxStripeSize = 0x800;
 
130
         
 
131
            if (raidToExpandType == 5)
 
132
              maxStripeSize += raidStripeSize;
 
133
         }
 
134
      }
 
135
      else 
 
136
         err = Dpt_Error::DPT_ERR_INVALID_RAID_TYPE;
 
137
   }
 
138
        EXIT();
 
139
   return (err);
 
140
}
 
141
 
 
142
 
 
143
Command::Dpt_Error Expand::execute( String_List **output )
 
144
{
 
145
        ENTER ("Command::Dpt_Error      Expand::execute (String_List **output)");
 
146
        Dpt_Error err, temp_err;
 
147
        String_List     *out;
 
148
        raidHeader_S raid_hdr;
 
149
        raidCompList_S  comp_list;
 
150
   DPT_TAG_T compTag;
 
151
   uLONG buffSize;
 
152
 
 
153
   *output = out = new String_List();
 
154
 
 
155
        Init_Engine();
 
156
        engine->Reset();
 
157
 
 
158
   // warning to all OSs except NT (and 2000 - same define)
 
159
#if !defined _DPT_WIN_NT
 
160
   out->add_Item (EventStrings[STR_WARN_ONLY_NT_2000]);
 
161
#endif
 
162
 
 
163
   err = RaidExpandable();
 
164
 
 
165
        int             dev_Index = 0;
 
166
        bool    more_Devs_Left = true;
 
167
        bool    first_time_through = true;
 
168
        bool    cluster_ON = false;
 
169
 
 
170
        for(dev_Index = 0; more_Devs_Left && !err.Is_Error(); dev_Index ++){
 
171
 
 
172
                DPT_TAG_T               hba_Tag;
 
173
                
 
174
                hba_Tag = Get_HBA_by_Index(dev_Index, &more_Devs_Left);
 
175
                engine->Reset();
 
176
                engine->Send(MSG_GET_INFO, hba_Tag);
 
177
 
 
178
                //if the cluster bit is enabled, DISABLE this feature
 
179
                if (engine->hbaInfo_P->flags2 & FLG_HBA_CLUSTER_MODE)
 
180
                        cluster_ON = true;
 
181
        }
 
182
 
 
183
        if (cluster_ON)
 
184
                (**output).add_Item ( EventStrings[STR_CLSTR_FEAT_DISABLE]);
 
185
 
 
186
        else if (!err.Is_Error())
 
187
        {
 
188
 
 
189
                dptBuffer_S *deadBuff_P = dptBuffer_S::newBuffer(10);
 
190
                dptBuffer_S *tempBuff_P = dptBuffer_S::newBuffer(1024);
 
191
                smUserBuff_S *smUB_P = (smUserBuff_S *) tempBuff_P->data;
 
192
 
 
193
                memset(&raid_hdr, 0, sizeof(raidHeader_S));
 
194
                memset(&comp_list, 0, sizeof(raidCompList_S));
 
195
 
 
196
                if (components->get_Num_Items())
 
197
                {
 
198
         raid_hdr.refNum = raidToExpandType;
 
199
         buffSize = sizeof(DPT_TAG_T) + sizeof(uCHAR) + 
 
200
            sizeof(raidHeader_S) + 
 
201
            sizeof(raidCompList_S) * components->get_Num_Items();
 
202
         dptBuffer_S *raidBuff_P = dptBuffer_S::newBuffer(buffSize);
 
203
         raidBuff_P->reset ();
 
204
         raidBuff_P->insert ((uLONG) raidToExpandTag);
 
205
         raidBuff_P->insert ((uCHAR) 0);
 
206
         raidBuff_P->insert (&raid_hdr, sizeof(raidHeader_S));
 
207
         // loop on each drive to add
 
208
        bool component_Found = true;
 
209
         bool includeDrive = true;
 
210
         while (component_Found && components->num_Left() &&
 
211
            includeDrive)
 
212
         {
 
213
            includeDrive = true;
 
214
                      compTag = Get_Dev_by_Address_and_Type (GET_SCSI_DASD,
 
215
                              components->get_Next_Item(), &component_Found);
 
216
            if (component_Found)
 
217
            {
 
218
               // must be unarrayed drive, but redirected okay
 
219
                err = engine->Send (MSG_GET_INFO, compTag);
 
220
               // if part o f a logical ...
 
221
               if (engine->devInfo_P->flags & FLG_DEV_RAID_COMPONENT)
 
222
               {
 
223
                  // check the hba ...
 
224
                      err = engine->Send (MSG_GET_INFO, 
 
225
                     engine->devInfo_P->raidParent);
 
226
                  // if not redirected, get out
 
227
                  if (engine->devInfo_P->raidType != RAID_REDIRECT)
 
228
                     includeDrive = false;
 
229
               }
 
230
               if (includeDrive)
 
231
               {
 
232
                  // be sure hba has enough memory to add this drive
 
233
                  if (StripeSizeCapable (compTag))
 
234
                  {
 
235
                     comp_list.tag = compTag;
 
236
                     raidBuff_P->insert (&comp_list, sizeof(raidCompList_S));
 
237
                  }
 
238
                  else
 
239
                  {
 
240
                     err = Dpt_Error::DPT_CMD_ERR_CANT_FIND_COMPONENT;
 
241
                     break;
 
242
                  }
 
243
               }
 
244
            }
 
245
            else
 
246
            {
 
247
               err = Dpt_Error::DPT_CMD_ERR_CANT_FIND_COMPONENT;
 
248
               break;
 
249
            }
 
250
         }
 
251
         if (!err.Is_Error())
 
252
            err = engine->Send(MSG_RAID_CHANGE, mgrTag, deadBuff_P, 
 
253
               raidBuff_P);
 
254
         delete[] raidBuff_P;
 
255
      }
 
256
 
 
257
      if (!err.Is_Error())
 
258
      {
 
259
         tempBuff_P->reset();
 
260
         tempBuff_P->writeIndex = 4;
 
261
         smUB_P->arrayFlags |= SMU_EXPANDING;
 
262
         smUB_P->raidType = (uCHAR) 5;
 
263
         err = engine->Send(MSG_SET_USER_BUFF, raidToExpandTag, 
 
264
            deadBuff_P, tempBuff_P);
 
265
      }
 
266
 
 
267
      delete[] deadBuff_P;
 
268
      delete[] tempBuff_P;
 
269
 
 
270
      if (!err.Is_Error())
 
271
      {
 
272
         engine->Insert (mgrTag);
 
273
         engine->Send (MSG_UPDATE_ALL_STATUS);
 
274
      }
 
275
        }
 
276
 
 
277
   if (err.Is_Error())
 
278
                out->add_Item ((char *) err);
 
279
   else
 
280
   {
 
281
      err = engine->Send (MSG_RAID_HW_ENABLE);
 
282
        if (!err.Is_Error() && !cluster_ON) 
 
283
         PrintRaidAddress(raidToExpandTag, out);
 
284
   }
 
285
        EXIT ();
 
286
        return (err);
 
287
}
 
288
 
 
289
 
 
290
bool Expand::StripeSizeCapable (DPT_TAG_T compTag)
 
291
{
 
292
   bool retval = true;
 
293
 
 
294
   if (raidToExpandType == 5)
 
295
   {
 
296
      if ((currStripeSize + raidStripeSize) > maxStripeSize)
 
297
         retval = false;
 
298
   }
 
299
   else // raid 0
 
300
   {
 
301
      if (currStripeSize > maxStripeSize)
 
302
         retval = false;
 
303
   }
 
304
   return (retval);
 
305
}
 
306
 
 
307
 
 
308
Command &Expand::Clone() const
 
309
{
 
310
        ENTER ("Command &Expand::Clone() const");
 
311
        EXIT ();
 
312
        return (*new Expand (*this));
 
313
}
 
314
 
 
315
/*** END OF FILE ***/