OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [block/] [DAC960.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 
3
  Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
4
 
5
  Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
6
 
7
  This program is free software; you may redistribute and/or modify it under
8
  the terms of the GNU General Public License Version 2 as published by the
9
  Free Software Foundation.
10
 
11
  This program is distributed in the hope that it will be useful, but
12
  WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13
  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
  for complete details.
15
 
16
  The author respectfully requests that any modifications to this software be
17
  sent directly to him for evaluation and testing.
18
 
19
*/
20
 
21
 
22
#define DAC960_DriverVersion                    "2.4.11"
23
#define DAC960_DriverDate                       "11 October 2001"
24
 
25
 
26
#include <linux/version.h>
27
#include <linux/module.h>
28
#include <linux/types.h>
29
#include <linux/blk.h>
30
#include <linux/blkdev.h>
31
#include <linux/completion.h>
32
#include <linux/delay.h>
33
#include <linux/hdreg.h>
34
#include <linux/blkpg.h>
35
#include <linux/interrupt.h>
36
#include <linux/ioport.h>
37
#include <linux/locks.h>
38
#include <linux/mm.h>
39
#include <linux/slab.h>
40
#include <linux/proc_fs.h>
41
#include <linux/reboot.h>
42
#include <linux/spinlock.h>
43
#include <linux/timer.h>
44
#include <linux/pci.h>
45
#include <linux/init.h>
46
#include <asm/io.h>
47
#include <asm/segment.h>
48
#include <asm/uaccess.h>
49
#include "DAC960.h"
50
 
51
 
52
/*
53
  DAC960_ControllerCount is the number of DAC960 Controllers detected.
54
*/
55
 
56
static int
57
  DAC960_ControllerCount =                      0;
58
 
59
 
60
/*
61
  DAC960_ActiveControllerCount is the number of active DAC960 Controllers
62
  detected.
63
*/
64
 
65
static int
66
  DAC960_ActiveControllerCount =                0;
67
 
68
 
69
/*
70
  DAC960_Controllers is an array of pointers to the DAC960 Controller
71
  structures.
72
*/
73
 
74
static DAC960_Controller_T
75
  *DAC960_Controllers[DAC960_MaxControllers] =  { NULL };
76
 
77
 
78
/*
79
  DAC960_BlockDeviceOperations is the Block Device Operations structure for
80
  DAC960 Logical Disk Devices.
81
*/
82
 
83
static BlockDeviceOperations_T
84
  DAC960_BlockDeviceOperations =
85
    { owner:                THIS_MODULE,
86
      open:                 DAC960_Open,
87
      release:              DAC960_Release,
88
      ioctl:                DAC960_IOCTL };
89
 
90
 
91
/*
92
  DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry.
93
*/
94
 
95
static PROC_DirectoryEntry_T
96
  *DAC960_ProcDirectoryEntry;
97
 
98
 
99
/*
100
  DAC960_NotifierBlock is the Notifier Block structure for DAC960 Driver.
101
*/
102
 
103
static NotifierBlock_T
104
  DAC960_NotifierBlock =    { DAC960_Notifier, NULL, 0 };
105
 
106
 
107
/*
108
  DAC960_AnnounceDriver announces the Driver Version and Date, Author's Name,
109
  Copyright Notice, and Electronic Mail Address.
110
*/
111
 
112
static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller)
113
{
114
  DAC960_Announce("***** DAC960 RAID Driver Version "
115
                  DAC960_DriverVersion " of "
116
                  DAC960_DriverDate " *****\n", Controller);
117
  DAC960_Announce("Copyright 1998-2001 by Leonard N. Zubkoff "
118
                  "<lnz@dandelion.com>\n", Controller);
119
}
120
 
121
 
122
/*
123
  DAC960_Failure prints a standardized error message, and then returns false.
124
*/
125
 
126
static boolean DAC960_Failure(DAC960_Controller_T *Controller,
127
                              unsigned char *ErrorMessage)
128
{
129
  DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
130
               Controller);
131
  if (Controller->IO_Address == 0)
132
    DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
133
                 "PCI Address 0x%X\n", Controller,
134
                 Controller->Bus, Controller->Device,
135
                 Controller->Function, Controller->PCI_Address);
136
  else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
137
                    "0x%X PCI Address 0x%X\n", Controller,
138
                    Controller->Bus, Controller->Device,
139
                    Controller->Function, Controller->IO_Address,
140
                    Controller->PCI_Address);
141
  DAC960_Error("%s FAILED - DETACHING\n", Controller, ErrorMessage);
142
  return false;
143
}
144
 
145
 
146
/*
147
  DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary
148
  data structures for Controller.  It returns true on success and false on
149
  failure.
150
*/
151
 
152
static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
153
{
154
  int CommandAllocationLength, CommandAllocationGroupSize;
155
  int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
156
  void *AllocationPointer = NULL;
157
  if (Controller->FirmwareType == DAC960_V1_Controller)
158
    {
159
      CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
160
      CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
161
    }
162
  else
163
    {
164
      CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
165
      CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
166
    }
167
  Controller->CommandAllocationGroupSize = CommandAllocationGroupSize;
168
  Controller->FreeCommands = NULL;
169
  for (CommandIdentifier = 1;
170
       CommandIdentifier <= Controller->DriverQueueDepth;
171
       CommandIdentifier++)
172
    {
173
      DAC960_Command_T *Command;
174
      if (--CommandsRemaining <= 0)
175
        {
176
          CommandsRemaining =
177
            Controller->DriverQueueDepth - CommandIdentifier + 1;
178
          if (CommandsRemaining > CommandAllocationGroupSize)
179
            CommandsRemaining = CommandAllocationGroupSize;
180
          CommandGroupByteCount =
181
            CommandsRemaining * CommandAllocationLength;
182
          AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
183
          if (AllocationPointer == NULL)
184
            return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
185
          memset(AllocationPointer, 0, CommandGroupByteCount);
186
        }
187
      Command = (DAC960_Command_T *) AllocationPointer;
188
      AllocationPointer += CommandAllocationLength;
189
      Command->CommandIdentifier = CommandIdentifier;
190
      Command->Controller = Controller;
191
      Command->Next = Controller->FreeCommands;
192
      Controller->FreeCommands = Command;
193
      Controller->Commands[CommandIdentifier-1] = Command;
194
    }
195
  return true;
196
}
197
 
198
 
199
/*
200
  DAC960_DestroyAuxiliaryStructures deallocates the auxiliary data
201
  structures for Controller.
202
*/
203
 
204
static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
205
{
206
  int i;
207
  Controller->FreeCommands = NULL;
208
  for (i = 0; i < Controller->DriverQueueDepth; i++)
209
    {
210
      DAC960_Command_T *Command = Controller->Commands[i];
211
      if (Command != NULL &&
212
          (Command->CommandIdentifier
213
           % Controller->CommandAllocationGroupSize) == 1)
214
        kfree(Command);
215
      Controller->Commands[i] = NULL;
216
    }
217
  if (Controller->CombinedStatusBuffer != NULL)
218
    {
219
      kfree(Controller->CombinedStatusBuffer);
220
      Controller->CombinedStatusBuffer = NULL;
221
      Controller->CurrentStatusBuffer = NULL;
222
    }
223
  if (Controller->FirmwareType == DAC960_V1_Controller) return;
224
  for (i = 0; i < DAC960_MaxLogicalDrives; i++)
225
    if (Controller->V2.LogicalDeviceInformation[i] != NULL)
226
      {
227
        kfree(Controller->V2.LogicalDeviceInformation[i]);
228
        Controller->V2.LogicalDeviceInformation[i] = NULL;
229
      }
230
  for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
231
    {
232
      if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
233
        {
234
          kfree(Controller->V2.PhysicalDeviceInformation[i]);
235
          Controller->V2.PhysicalDeviceInformation[i] = NULL;
236
        }
237
      if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
238
        {
239
          kfree(Controller->V2.InquiryUnitSerialNumber[i]);
240
          Controller->V2.InquiryUnitSerialNumber[i] = NULL;
241
        }
242
    }
243
}
244
 
245
 
246
/*
247
  DAC960_V1_ClearCommand clears critical fields of Command for DAC960 V1
248
  Firmware Controllers.
249
*/
250
 
251
static inline void DAC960_V1_ClearCommand(DAC960_Command_T *Command)
252
{
253
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
254
  memset(CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T));
255
  Command->V1.CommandStatus = 0;
256
}
257
 
258
 
259
/*
260
  DAC960_V2_ClearCommand clears critical fields of Command for DAC960 V2
261
  Firmware Controllers.
262
*/
263
 
264
static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command)
265
{
266
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
267
  memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
268
  Command->V2.CommandStatus = 0;
269
}
270
 
271
 
272
/*
273
  DAC960_AllocateCommand allocates a Command structure from Controller's
274
  free list.  During driver initialization, a special initialization command
275
  has been placed on the free list to guarantee that command allocation can
276
  never fail.
277
*/
278
 
279
static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
280
                                                       *Controller)
281
{
282
  DAC960_Command_T *Command = Controller->FreeCommands;
283
  if (Command == NULL) return NULL;
284
  Controller->FreeCommands = Command->Next;
285
  Command->Next = NULL;
286
  return Command;
287
}
288
 
289
 
290
/*
291
  DAC960_DeallocateCommand deallocates Command, returning it to Controller's
292
  free list.
293
*/
294
 
295
static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command)
296
{
297
  DAC960_Controller_T *Controller = Command->Controller;
298
  Command->Next = Controller->FreeCommands;
299
  Controller->FreeCommands = Command;
300
}
301
 
302
 
303
/*
304
  DAC960_WaitForCommand waits for a wake_up on Controller's Command Wait Queue.
305
*/
306
 
307
static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
308
{
309
  spin_unlock_irq(&io_request_lock);
310
  __wait_event(Controller->CommandWaitQueue, Controller->FreeCommands);
311
  spin_lock_irq(&io_request_lock);
312
}
313
 
314
 
315
/*
316
  DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
317
*/
318
 
319
static void DAC960_BA_QueueCommand(DAC960_Command_T *Command)
320
{
321
  DAC960_Controller_T *Controller = Command->Controller;
322
  void *ControllerBaseAddress = Controller->BaseAddress;
323
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
324
  DAC960_V2_CommandMailbox_T *NextCommandMailbox =
325
    Controller->V2.NextCommandMailbox;
326
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
327
  DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
328
  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
329
      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
330
    DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress);
331
  Controller->V2.PreviousCommandMailbox2 =
332
    Controller->V2.PreviousCommandMailbox1;
333
  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
334
  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
335
    NextCommandMailbox = Controller->V2.FirstCommandMailbox;
336
  Controller->V2.NextCommandMailbox = NextCommandMailbox;
337
}
338
 
339
 
340
/*
341
  DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers.
342
*/
343
 
344
static void DAC960_LP_QueueCommand(DAC960_Command_T *Command)
345
{
346
  DAC960_Controller_T *Controller = Command->Controller;
347
  void *ControllerBaseAddress = Controller->BaseAddress;
348
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
349
  DAC960_V2_CommandMailbox_T *NextCommandMailbox =
350
    Controller->V2.NextCommandMailbox;
351
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
352
  DAC960_LP_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
353
  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
354
      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
355
    DAC960_LP_MemoryMailboxNewCommand(ControllerBaseAddress);
356
  Controller->V2.PreviousCommandMailbox2 =
357
    Controller->V2.PreviousCommandMailbox1;
358
  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
359
  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
360
    NextCommandMailbox = Controller->V2.FirstCommandMailbox;
361
  Controller->V2.NextCommandMailbox = NextCommandMailbox;
362
}
363
 
364
 
365
/*
366
  DAC960_LA_QueueCommandDualMode queues Command for DAC960 LA Series
367
  Controllers with Dual Mode Firmware.
368
*/
369
 
370
static void DAC960_LA_QueueCommandDualMode(DAC960_Command_T *Command)
371
{
372
  DAC960_Controller_T *Controller = Command->Controller;
373
  void *ControllerBaseAddress = Controller->BaseAddress;
374
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
375
  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
376
    Controller->V1.NextCommandMailbox;
377
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
378
  DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
379
  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
380
      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
381
    DAC960_LA_MemoryMailboxNewCommand(ControllerBaseAddress);
382
  Controller->V1.PreviousCommandMailbox2 =
383
    Controller->V1.PreviousCommandMailbox1;
384
  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
385
  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
386
    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
387
  Controller->V1.NextCommandMailbox = NextCommandMailbox;
388
}
389
 
390
 
391
/*
392
  DAC960_LA_QueueCommandSingleMode queues Command for DAC960 LA Series
393
  Controllers with Single Mode Firmware.
394
*/
395
 
396
static void DAC960_LA_QueueCommandSingleMode(DAC960_Command_T *Command)
397
{
398
  DAC960_Controller_T *Controller = Command->Controller;
399
  void *ControllerBaseAddress = Controller->BaseAddress;
400
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
401
  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
402
    Controller->V1.NextCommandMailbox;
403
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
404
  DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
405
  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
406
      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
407
    DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
408
  Controller->V1.PreviousCommandMailbox2 =
409
    Controller->V1.PreviousCommandMailbox1;
410
  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
411
  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
412
    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
413
  Controller->V1.NextCommandMailbox = NextCommandMailbox;
414
}
415
 
416
 
417
/*
418
  DAC960_PG_QueueCommandDualMode queues Command for DAC960 PG Series
419
  Controllers with Dual Mode Firmware.
420
*/
421
 
422
static void DAC960_PG_QueueCommandDualMode(DAC960_Command_T *Command)
423
{
424
  DAC960_Controller_T *Controller = Command->Controller;
425
  void *ControllerBaseAddress = Controller->BaseAddress;
426
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
427
  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
428
    Controller->V1.NextCommandMailbox;
429
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
430
  DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
431
  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
432
      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
433
    DAC960_PG_MemoryMailboxNewCommand(ControllerBaseAddress);
434
  Controller->V1.PreviousCommandMailbox2 =
435
    Controller->V1.PreviousCommandMailbox1;
436
  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
437
  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
438
    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
439
  Controller->V1.NextCommandMailbox = NextCommandMailbox;
440
}
441
 
442
 
443
/*
444
  DAC960_PG_QueueCommandSingleMode queues Command for DAC960 PG Series
445
  Controllers with Single Mode Firmware.
446
*/
447
 
448
static void DAC960_PG_QueueCommandSingleMode(DAC960_Command_T *Command)
449
{
450
  DAC960_Controller_T *Controller = Command->Controller;
451
  void *ControllerBaseAddress = Controller->BaseAddress;
452
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
453
  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
454
    Controller->V1.NextCommandMailbox;
455
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
456
  DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
457
  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
458
      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
459
    DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
460
  Controller->V1.PreviousCommandMailbox2 =
461
    Controller->V1.PreviousCommandMailbox1;
462
  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
463
  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
464
    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
465
  Controller->V1.NextCommandMailbox = NextCommandMailbox;
466
}
467
 
468
 
469
/*
470
  DAC960_PD_QueueCommand queues Command for DAC960 PD Series Controllers.
471
*/
472
 
473
static void DAC960_PD_QueueCommand(DAC960_Command_T *Command)
474
{
475
  DAC960_Controller_T *Controller = Command->Controller;
476
  void *ControllerBaseAddress = Controller->BaseAddress;
477
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
478
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
479
  while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
480
    udelay(1);
481
  DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
482
  DAC960_PD_NewCommand(ControllerBaseAddress);
483
}
484
 
485
 
486
/*
487
  DAC960_P_QueueCommand queues Command for DAC960 P Series Controllers.
488
*/
489
 
490
static void DAC960_P_QueueCommand(DAC960_Command_T *Command)
491
{
492
  DAC960_Controller_T *Controller = Command->Controller;
493
  void *ControllerBaseAddress = Controller->BaseAddress;
494
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
495
  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
496
  switch (CommandMailbox->Common.CommandOpcode)
497
    {
498
    case DAC960_V1_Enquiry:
499
      CommandMailbox->Common.CommandOpcode = DAC960_V1_Enquiry_Old;
500
      break;
501
    case DAC960_V1_GetDeviceState:
502
      CommandMailbox->Common.CommandOpcode = DAC960_V1_GetDeviceState_Old;
503
      break;
504
    case DAC960_V1_Read:
505
      CommandMailbox->Common.CommandOpcode = DAC960_V1_Read_Old;
506
      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
507
      break;
508
    case DAC960_V1_Write:
509
      CommandMailbox->Common.CommandOpcode = DAC960_V1_Write_Old;
510
      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
511
      break;
512
    case DAC960_V1_ReadWithScatterGather:
513
      CommandMailbox->Common.CommandOpcode =
514
        DAC960_V1_ReadWithScatterGather_Old;
515
      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
516
      break;
517
    case DAC960_V1_WriteWithScatterGather:
518
      CommandMailbox->Common.CommandOpcode =
519
        DAC960_V1_WriteWithScatterGather_Old;
520
      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
521
      break;
522
    default:
523
      break;
524
    }
525
  while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
526
    udelay(1);
527
  DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
528
  DAC960_PD_NewCommand(ControllerBaseAddress);
529
}
530
 
531
 
532
/*
533
  DAC960_ExecuteCommand executes Command and waits for completion.
534
*/
535
 
536
static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
537
{
538
  DAC960_Controller_T *Controller = Command->Controller;
539
  DECLARE_COMPLETION(Completion);
540
  unsigned long ProcessorFlags;
541
  Command->Completion = &Completion;
542
  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
543
  DAC960_QueueCommand(Command);
544
  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
545
  if (in_interrupt()) return;
546
  wait_for_completion(&Completion);
547
}
548
 
549
 
550
/*
551
  DAC960_V1_ExecuteType3 executes a DAC960 V1 Firmware Controller Type 3
552
  Command and waits for completion.  It returns true on success and false
553
  on failure.
554
*/
555
 
556
static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
557
                                      DAC960_V1_CommandOpcode_T CommandOpcode,
558
                                      void *DataPointer)
559
{
560
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
561
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
562
  DAC960_V1_CommandStatus_T CommandStatus;
563
  DAC960_V1_ClearCommand(Command);
564
  Command->CommandType = DAC960_ImmediateCommand;
565
  CommandMailbox->Type3.CommandOpcode = CommandOpcode;
566
  CommandMailbox->Type3.BusAddress = Virtual_to_Bus32(DataPointer);
567
  DAC960_ExecuteCommand(Command);
568
  CommandStatus = Command->V1.CommandStatus;
569
  DAC960_DeallocateCommand(Command);
570
  return (CommandStatus == DAC960_V1_NormalCompletion);
571
}
572
 
573
 
574
/*
575
  DAC960_V1_ExecuteTypeB executes a DAC960 V1 Firmware Controller Type 3B
576
  Command and waits for completion.  It returns true on success and false
577
  on failure.
578
*/
579
 
580
static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
581
                                       DAC960_V1_CommandOpcode_T CommandOpcode,
582
                                       unsigned char CommandOpcode2,
583
                                       void *DataPointer)
584
{
585
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
586
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
587
  DAC960_V1_CommandStatus_T CommandStatus;
588
  DAC960_V1_ClearCommand(Command);
589
  Command->CommandType = DAC960_ImmediateCommand;
590
  CommandMailbox->Type3B.CommandOpcode = CommandOpcode;
591
  CommandMailbox->Type3B.CommandOpcode2 = CommandOpcode2;
592
  CommandMailbox->Type3B.BusAddress = Virtual_to_Bus32(DataPointer);
593
  DAC960_ExecuteCommand(Command);
594
  CommandStatus = Command->V1.CommandStatus;
595
  DAC960_DeallocateCommand(Command);
596
  return (CommandStatus == DAC960_V1_NormalCompletion);
597
}
598
 
599
 
600
/*
601
  DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
602
  Command and waits for completion.  It returns true on success and false
603
  on failure.
604
*/
605
 
606
static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
607
                                       DAC960_V1_CommandOpcode_T CommandOpcode,
608
                                       unsigned char Channel,
609
                                       unsigned char TargetID,
610
                                       void *DataPointer)
611
{
612
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
613
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
614
  DAC960_V1_CommandStatus_T CommandStatus;
615
  DAC960_V1_ClearCommand(Command);
616
  Command->CommandType = DAC960_ImmediateCommand;
617
  CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
618
  CommandMailbox->Type3D.Channel = Channel;
619
  CommandMailbox->Type3D.TargetID = TargetID;
620
  CommandMailbox->Type3D.BusAddress = Virtual_to_Bus32(DataPointer);
621
  DAC960_ExecuteCommand(Command);
622
  CommandStatus = Command->V1.CommandStatus;
623
  DAC960_DeallocateCommand(Command);
624
  return (CommandStatus == DAC960_V1_NormalCompletion);
625
}
626
 
627
 
628
/*
629
  DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information
630
  Reading IOCTL Command and waits for completion.  It returns true on success
631
  and false on failure.
632
*/
633
 
634
static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
635
                                     DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
636
                                     void *DataPointer,
637
                                     unsigned int DataByteCount)
638
{
639
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
640
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
641
  DAC960_V2_CommandStatus_T CommandStatus;
642
  DAC960_V2_ClearCommand(Command);
643
  Command->CommandType = DAC960_ImmediateCommand;
644
  CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
645
  CommandMailbox->Common.CommandControlBits
646
                        .DataTransferControllerToHost = true;
647
  CommandMailbox->Common.CommandControlBits
648
                        .NoAutoRequestSense = true;
649
  CommandMailbox->Common.DataTransferSize = DataByteCount;
650
  CommandMailbox->Common.IOCTL_Opcode = IOCTL_Opcode;
651
  CommandMailbox->Common.DataTransferMemoryAddress
652
                        .ScatterGatherSegments[0]
653
                        .SegmentDataPointer =
654
    Virtual_to_Bus64(DataPointer);
655
  CommandMailbox->Common.DataTransferMemoryAddress
656
                        .ScatterGatherSegments[0]
657
                        .SegmentByteCount =
658
    CommandMailbox->Common.DataTransferSize;
659
  DAC960_ExecuteCommand(Command);
660
  CommandStatus = Command->V2.CommandStatus;
661
  DAC960_DeallocateCommand(Command);
662
  return (CommandStatus == DAC960_V2_NormalCompletion);
663
}
664
 
665
 
666
/*
667
  DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller
668
  Information Reading IOCTL Command and waits for completion.  It returns
669
  true on success and false on failure.
670
*/
671
 
672
static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
673
                                        DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
674
                                        void *DataPointer,
675
                                        unsigned int DataByteCount)
676
{
677
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
678
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
679
  DAC960_V2_CommandStatus_T CommandStatus;
680
  DAC960_V2_ClearCommand(Command);
681
  Command->CommandType = DAC960_ImmediateCommand;
682
  CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
683
  CommandMailbox->ControllerInfo.CommandControlBits
684
                                .DataTransferControllerToHost = true;
685
  CommandMailbox->ControllerInfo.CommandControlBits
686
                                .NoAutoRequestSense = true;
687
  CommandMailbox->ControllerInfo.DataTransferSize = DataByteCount;
688
  CommandMailbox->ControllerInfo.ControllerNumber = 0;
689
  CommandMailbox->ControllerInfo.IOCTL_Opcode = IOCTL_Opcode;
690
  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
691
                                .ScatterGatherSegments[0]
692
                                .SegmentDataPointer =
693
    Virtual_to_Bus64(DataPointer);
694
  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
695
                                .ScatterGatherSegments[0]
696
                                .SegmentByteCount =
697
    CommandMailbox->ControllerInfo.DataTransferSize;
698
  DAC960_ExecuteCommand(Command);
699
  CommandStatus = Command->V2.CommandStatus;
700
  DAC960_DeallocateCommand(Command);
701
  return (CommandStatus == DAC960_V2_NormalCompletion);
702
}
703
 
704
 
705
/*
706
  DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical
707
  Device Information Reading IOCTL Command and waits for completion.  It
708
  returns true on success and false on failure.
709
*/
710
 
711
static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
712
                                           DAC960_V2_IOCTL_Opcode_T
713
                                             IOCTL_Opcode,
714
                                           unsigned short
715
                                             LogicalDeviceNumber,
716
                                           void *DataPointer,
717
                                           unsigned int DataByteCount)
718
{
719
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
720
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
721
  DAC960_V2_CommandStatus_T CommandStatus;
722
  DAC960_V2_ClearCommand(Command);
723
  Command->CommandType = DAC960_ImmediateCommand;
724
  CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
725
  CommandMailbox->LogicalDeviceInfo.CommandControlBits
726
                                   .DataTransferControllerToHost = true;
727
  CommandMailbox->LogicalDeviceInfo.CommandControlBits
728
                                   .NoAutoRequestSense = true;
729
  CommandMailbox->LogicalDeviceInfo.DataTransferSize = DataByteCount;
730
  CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
731
    LogicalDeviceNumber;
732
  CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
733
  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
734
                                   .ScatterGatherSegments[0]
735
                                   .SegmentDataPointer =
736
    Virtual_to_Bus64(DataPointer);
737
  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
738
                                   .ScatterGatherSegments[0]
739
                                   .SegmentByteCount =
740
    CommandMailbox->LogicalDeviceInfo.DataTransferSize;
741
  DAC960_ExecuteCommand(Command);
742
  CommandStatus = Command->V2.CommandStatus;
743
  DAC960_DeallocateCommand(Command);
744
  return (CommandStatus == DAC960_V2_NormalCompletion);
745
}
746
 
747
 
748
/*
749
  DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical
750
  Device Information Reading IOCTL Command and waits for completion.  It
751
  returns true on success and false on failure.
752
*/
753
 
754
static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
755
                                            DAC960_V2_IOCTL_Opcode_T
756
                                              IOCTL_Opcode,
757
                                            unsigned char Channel,
758
                                            unsigned char TargetID,
759
                                            unsigned char LogicalUnit,
760
                                            void *DataPointer,
761
                                            unsigned int DataByteCount)
762
{
763
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
764
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
765
  DAC960_V2_CommandStatus_T CommandStatus;
766
  DAC960_V2_ClearCommand(Command);
767
  Command->CommandType = DAC960_ImmediateCommand;
768
  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
769
  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
770
                                    .DataTransferControllerToHost = true;
771
  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
772
                                    .NoAutoRequestSense = true;
773
  CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount;
774
  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit;
775
  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
776
  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
777
  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
778
  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
779
                                    .ScatterGatherSegments[0]
780
                                    .SegmentDataPointer =
781
    Virtual_to_Bus64(DataPointer);
782
  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
783
                                    .ScatterGatherSegments[0]
784
                                    .SegmentByteCount =
785
    CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
786
  DAC960_ExecuteCommand(Command);
787
  CommandStatus = Command->V2.CommandStatus;
788
  DAC960_DeallocateCommand(Command);
789
  return (CommandStatus == DAC960_V2_NormalCompletion);
790
}
791
 
792
 
793
/*
794
  DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device
795
  Operation IOCTL Command and waits for completion.  It returns true on
796
  success and false on failure.
797
*/
798
 
799
static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
800
                                         DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
801
                                         DAC960_V2_OperationDevice_T
802
                                           OperationDevice)
803
{
804
  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
805
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
806
  DAC960_V2_CommandStatus_T CommandStatus;
807
  DAC960_V2_ClearCommand(Command);
808
  Command->CommandType = DAC960_ImmediateCommand;
809
  CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL;
810
  CommandMailbox->DeviceOperation.CommandControlBits
811
                                 .DataTransferControllerToHost = true;
812
  CommandMailbox->DeviceOperation.CommandControlBits
813
                                 .NoAutoRequestSense = true;
814
  CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode;
815
  CommandMailbox->DeviceOperation.OperationDevice = OperationDevice;
816
  DAC960_ExecuteCommand(Command);
817
  CommandStatus = Command->V2.CommandStatus;
818
  DAC960_DeallocateCommand(Command);
819
  return (CommandStatus == DAC960_V2_NormalCompletion);
820
}
821
 
822
 
823
/*
824
  DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
825
  for DAC960 V1 Firmware Controllers.
826
*/
827
 
828
static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
829
                                                      *Controller)
830
{
831
  void *ControllerBaseAddress = Controller->BaseAddress;
832
  DAC960_V1_CommandMailbox_T *CommandMailboxesMemory;
833
  DAC960_V1_StatusMailbox_T *StatusMailboxesMemory;
834
  DAC960_V1_CommandMailbox_T CommandMailbox;
835
  DAC960_V1_CommandStatus_T CommandStatus;
836
  unsigned long MemoryMailboxPagesAddress;
837
  unsigned long MemoryMailboxPagesOrder;
838
  unsigned long MemoryMailboxPagesSize;
839
  void *SavedMemoryMailboxesAddress = NULL;
840
  short NextCommandMailboxIndex = 0;
841
  short NextStatusMailboxIndex = 0;
842
  int TimeoutCounter = 1000000, i;
843
  MemoryMailboxPagesOrder = 0;
844
  MemoryMailboxPagesSize =
845
    DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) +
846
    DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
847
  while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
848
    MemoryMailboxPagesOrder++;
849
  if (Controller->HardwareType == DAC960_LA_Controller)
850
    DAC960_LA_RestoreMemoryMailboxInfo(Controller,
851
                                       &SavedMemoryMailboxesAddress,
852
                                       &NextCommandMailboxIndex,
853
                                       &NextStatusMailboxIndex);
854
  else DAC960_PG_RestoreMemoryMailboxInfo(Controller,
855
                                          &SavedMemoryMailboxesAddress,
856
                                          &NextCommandMailboxIndex,
857
                                          &NextStatusMailboxIndex);
858
  if (SavedMemoryMailboxesAddress == NULL)
859
    {
860
      MemoryMailboxPagesAddress =
861
        __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
862
      Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
863
      CommandMailboxesMemory =
864
        (DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
865
    }
866
  else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
867
  if (CommandMailboxesMemory == NULL) return false;
868
  Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
869
  memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
870
  Controller->V1.FirstCommandMailbox = CommandMailboxesMemory;
871
  CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1;
872
  Controller->V1.LastCommandMailbox = CommandMailboxesMemory;
873
  Controller->V1.NextCommandMailbox =
874
    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
875
  if (--NextCommandMailboxIndex < 0)
876
    NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
877
  Controller->V1.PreviousCommandMailbox1 =
878
    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
879
  if (--NextCommandMailboxIndex < 0)
880
    NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
881
  Controller->V1.PreviousCommandMailbox2 =
882
    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
883
  StatusMailboxesMemory =
884
    (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1);
885
  Controller->V1.FirstStatusMailbox = StatusMailboxesMemory;
886
  StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1;
887
  Controller->V1.LastStatusMailbox = StatusMailboxesMemory;
888
  Controller->V1.NextStatusMailbox =
889
    &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex];
890
  if (SavedMemoryMailboxesAddress != NULL) return true;
891
  /* Enable the Memory Mailbox Interface. */
892
  Controller->V1.DualModeMemoryMailboxInterface = true;
893
  CommandMailbox.TypeX.CommandOpcode = 0x2B;
894
  CommandMailbox.TypeX.CommandIdentifier = 0;
895
  CommandMailbox.TypeX.CommandOpcode2 = 0x14;
896
  CommandMailbox.TypeX.CommandMailboxesBusAddress =
897
    Virtual_to_Bus32(Controller->V1.FirstCommandMailbox);
898
  CommandMailbox.TypeX.StatusMailboxesBusAddress =
899
    Virtual_to_Bus32(Controller->V1.FirstStatusMailbox);
900
  for (i = 0; i < 2; i++)
901
    switch (Controller->HardwareType)
902
      {
903
      case DAC960_LA_Controller:
904
        while (--TimeoutCounter >= 0)
905
          {
906
            if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
907
              break;
908
            udelay(10);
909
          }
910
        if (TimeoutCounter < 0) return false;
911
        DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
912
        DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
913
        while (--TimeoutCounter >= 0)
914
          {
915
            if (DAC960_LA_HardwareMailboxStatusAvailableP(
916
                  ControllerBaseAddress))
917
              break;
918
            udelay(10);
919
          }
920
        if (TimeoutCounter < 0) return false;
921
        CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress);
922
        DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
923
        DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
924
        if (CommandStatus == DAC960_V1_NormalCompletion) return true;
925
        Controller->V1.DualModeMemoryMailboxInterface = false;
926
        CommandMailbox.TypeX.CommandOpcode2 = 0x10;
927
        break;
928
      case DAC960_PG_Controller:
929
        while (--TimeoutCounter >= 0)
930
          {
931
            if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
932
              break;
933
            udelay(10);
934
          }
935
        if (TimeoutCounter < 0) return false;
936
        DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
937
        DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
938
        while (--TimeoutCounter >= 0)
939
          {
940
            if (DAC960_PG_HardwareMailboxStatusAvailableP(
941
                  ControllerBaseAddress))
942
              break;
943
            udelay(10);
944
          }
945
        if (TimeoutCounter < 0) return false;
946
        CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress);
947
        DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
948
        DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
949
        if (CommandStatus == DAC960_V1_NormalCompletion) return true;
950
        Controller->V1.DualModeMemoryMailboxInterface = false;
951
        CommandMailbox.TypeX.CommandOpcode2 = 0x10;
952
        break;
953
      default:
954
        break;
955
      }
956
  return false;
957
}
958
 
959
 
960
/*
961
  DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
962
  for DAC960 V2 Firmware Controllers.
963
*/
964
 
965
static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
966
                                                      *Controller)
967
{
968
  void *ControllerBaseAddress = Controller->BaseAddress;
969
  DAC960_V2_CommandMailbox_T *CommandMailboxesMemory;
970
  DAC960_V2_StatusMailbox_T *StatusMailboxesMemory;
971
  DAC960_V2_CommandMailbox_T CommandMailbox;
972
  DAC960_V2_CommandStatus_T CommandStatus = 0;
973
  unsigned long MemoryMailboxPagesAddress;
974
  unsigned long MemoryMailboxPagesOrder;
975
  unsigned long MemoryMailboxPagesSize;
976
  MemoryMailboxPagesOrder = 0;
977
  MemoryMailboxPagesSize =
978
    DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) +
979
    DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) +
980
    sizeof(DAC960_V2_HealthStatusBuffer_T);
981
  while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
982
    MemoryMailboxPagesOrder++;
983
  MemoryMailboxPagesAddress =
984
    __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
985
  Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
986
  CommandMailboxesMemory =
987
    (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress;
988
  if (CommandMailboxesMemory == NULL) return false;
989
  Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
990
  memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
991
  Controller->V2.FirstCommandMailbox = CommandMailboxesMemory;
992
  CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1;
993
  Controller->V2.LastCommandMailbox = CommandMailboxesMemory;
994
  Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox;
995
  Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox;
996
  Controller->V2.PreviousCommandMailbox2 =
997
    Controller->V2.LastCommandMailbox - 1;
998
  StatusMailboxesMemory =
999
    (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1);
1000
  Controller->V2.FirstStatusMailbox = StatusMailboxesMemory;
1001
  StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1;
1002
  Controller->V2.LastStatusMailbox = StatusMailboxesMemory;
1003
  Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox;
1004
  Controller->V2.HealthStatusBuffer =
1005
    (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1);
1006
  /* Enable the Memory Mailbox Interface. */
1007
  memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
1008
  CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1;
1009
  CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
1010
  CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
1011
  CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB =
1012
    (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10;
1013
  CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB =
1014
    (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10;
1015
  CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
1016
  CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
1017
  CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0;
1018
  CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
1019
  CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
1020
  CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress =
1021
    Virtual_to_Bus64(Controller->V2.HealthStatusBuffer);
1022
  CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
1023
    Virtual_to_Bus64(Controller->V2.FirstCommandMailbox);
1024
  CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
1025
    Virtual_to_Bus64(Controller->V2.FirstStatusMailbox);
1026
  switch (Controller->HardwareType)
1027
    {
1028
    case DAC960_BA_Controller:
1029
      while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
1030
        udelay(1);
1031
      DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
1032
      DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress);
1033
      while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
1034
        udelay(1);
1035
      CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress);
1036
      DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
1037
      DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
1038
      break;
1039
    case DAC960_LP_Controller:
1040
      while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress))
1041
        udelay(1);
1042
      DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
1043
      DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress);
1044
      while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
1045
        udelay(1);
1046
      CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress);
1047
      DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
1048
      DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
1049
      break;
1050
    default:
1051
      break;
1052
    }
1053
  return (CommandStatus == DAC960_V2_NormalCompletion);
1054
}
1055
 
1056
 
1057
/*
1058
  DAC960_V1_ReadControllerConfiguration reads the Configuration Information
1059
  from DAC960 V1 Firmware Controllers and initializes the Controller structure.
1060
*/
1061
 
1062
static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
1063
                                                     *Controller)
1064
{
1065
  DAC960_V1_Enquiry2_T Enquiry2;
1066
  DAC960_V1_Config2_T Config2;
1067
  int LogicalDriveNumber, Channel, TargetID;
1068
  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
1069
                              &Controller->V1.Enquiry))
1070
    return DAC960_Failure(Controller, "ENQUIRY");
1071
  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
1072
    return DAC960_Failure(Controller, "ENQUIRY2");
1073
  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
1074
    return DAC960_Failure(Controller, "READ CONFIG2");
1075
  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation,
1076
                              &Controller->V1.LogicalDriveInformation))
1077
    return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
1078
  for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
1079
    for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++)
1080
      if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState,
1081
                                   Channel, TargetID,
1082
                                   &Controller->V1.DeviceState
1083
                                                   [Channel][TargetID]))
1084
        return DAC960_Failure(Controller, "GET DEVICE STATE");
1085
  /*
1086
    Initialize the Controller Model Name and Full Model Name fields.
1087
  */
1088
  switch (Enquiry2.HardwareID.SubModel)
1089
    {
1090
    case DAC960_V1_P_PD_PU:
1091
      if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
1092
        strcpy(Controller->ModelName, "DAC960PU");
1093
      else strcpy(Controller->ModelName, "DAC960PD");
1094
      break;
1095
    case DAC960_V1_PL:
1096
      strcpy(Controller->ModelName, "DAC960PL");
1097
      break;
1098
    case DAC960_V1_PG:
1099
      strcpy(Controller->ModelName, "DAC960PG");
1100
      break;
1101
    case DAC960_V1_PJ:
1102
      strcpy(Controller->ModelName, "DAC960PJ");
1103
      break;
1104
    case DAC960_V1_PR:
1105
      strcpy(Controller->ModelName, "DAC960PR");
1106
      break;
1107
    case DAC960_V1_PT:
1108
      strcpy(Controller->ModelName, "DAC960PT");
1109
      break;
1110
    case DAC960_V1_PTL0:
1111
      strcpy(Controller->ModelName, "DAC960PTL0");
1112
      break;
1113
    case DAC960_V1_PRL:
1114
      strcpy(Controller->ModelName, "DAC960PRL");
1115
      break;
1116
    case DAC960_V1_PTL1:
1117
      strcpy(Controller->ModelName, "DAC960PTL1");
1118
      break;
1119
    case DAC960_V1_1164P:
1120
      strcpy(Controller->ModelName, "DAC1164P");
1121
      break;
1122
    default:
1123
      return DAC960_Failure(Controller, "MODEL VERIFICATION");
1124
    }
1125
  strcpy(Controller->FullModelName, "Mylex ");
1126
  strcat(Controller->FullModelName, Controller->ModelName);
1127
  /*
1128
    Initialize the Controller Firmware Version field and verify that it
1129
    is a supported firmware version.  The supported firmware versions are:
1130
 
1131
    DAC1164P                5.06 and above
1132
    DAC960PTL/PRL/PJ/PG     4.06 and above
1133
    DAC960PU/PD/PL          3.51 and above
1134
    DAC960PU/PD/PL/P        2.73 and above
1135
  */
1136
  if (Enquiry2.FirmwareID.MajorVersion == 0)
1137
    {
1138
      Enquiry2.FirmwareID.MajorVersion =
1139
        Controller->V1.Enquiry.MajorFirmwareVersion;
1140
      Enquiry2.FirmwareID.MinorVersion =
1141
        Controller->V1.Enquiry.MinorFirmwareVersion;
1142
      Enquiry2.FirmwareID.FirmwareType = '0';
1143
      Enquiry2.FirmwareID.TurnID = 0;
1144
    }
1145
  sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
1146
          Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
1147
          Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
1148
  if (!((Controller->FirmwareVersion[0] == '5' &&
1149
         strcmp(Controller->FirmwareVersion, "5.06") >= 0) ||
1150
        (Controller->FirmwareVersion[0] == '4' &&
1151
         strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
1152
        (Controller->FirmwareVersion[0] == '3' &&
1153
         strcmp(Controller->FirmwareVersion, "3.51") >= 0) ||
1154
        (Controller->FirmwareVersion[0] == '2' &&
1155
         strcmp(Controller->FirmwareVersion, "2.73") >= 0)))
1156
    {
1157
      DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
1158
      DAC960_Error("Firmware Version = '%s'\n", Controller,
1159
                   Controller->FirmwareVersion);
1160
      return false;
1161
    }
1162
  /*
1163
    Initialize the Controller Channels, Targets, Memory Size, and SAF-TE
1164
    Enclosure Management Enabled fields.
1165
  */
1166
  Controller->Channels = Enquiry2.ActualChannels;
1167
  Controller->Targets = Enquiry2.MaxTargets;
1168
  Controller->MemorySize = Enquiry2.MemorySize >> 20;
1169
  Controller->V1.SAFTE_EnclosureManagementEnabled =
1170
    (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
1171
  /*
1172
    Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
1173
    Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
1174
    Driver Scatter/Gather Limit.  The Driver Queue Depth must be at most one
1175
    less than the Controller Queue Depth to allow for an automatic drive
1176
    rebuild operation.
1177
  */
1178
  Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands;
1179
  Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
1180
  if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
1181
    Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
1182
  Controller->LogicalDriveCount =
1183
    Controller->V1.Enquiry.NumberOfLogicalDrives;
1184
  Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
1185
  Controller->ControllerScatterGatherLimit = Enquiry2.MaxScatterGatherEntries;
1186
  Controller->DriverScatterGatherLimit =
1187
    Controller->ControllerScatterGatherLimit;
1188
  if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit)
1189
    Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit;
1190
  /*
1191
    Initialize the Stripe Size, Segment Size, and Geometry Translation.
1192
  */
1193
  Controller->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
1194
                              >> (10 - DAC960_BlockSizeBits);
1195
  Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
1196
                               >> (10 - DAC960_BlockSizeBits);
1197
  switch (Config2.DriveGeometry)
1198
    {
1199
    case DAC960_V1_Geometry_128_32:
1200
      Controller->V1.GeometryTranslationHeads = 128;
1201
      Controller->V1.GeometryTranslationSectors = 32;
1202
      break;
1203
    case DAC960_V1_Geometry_255_63:
1204
      Controller->V1.GeometryTranslationHeads = 255;
1205
      Controller->V1.GeometryTranslationSectors = 63;
1206
      break;
1207
    default:
1208
      return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
1209
    }
1210
  /*
1211
    Initialize the Background Initialization Status.
1212
  */
1213
  if ((Controller->FirmwareVersion[0] == '4' &&
1214
      strcmp(Controller->FirmwareVersion, "4.08") >= 0) ||
1215
      (Controller->FirmwareVersion[0] == '5' &&
1216
       strcmp(Controller->FirmwareVersion, "5.08") >= 0))
1217
    {
1218
      Controller->V1.BackgroundInitializationStatusSupported = true;
1219
      DAC960_V1_ExecuteType3B(Controller,
1220
                              DAC960_V1_BackgroundInitializationControl, 0x20,
1221
                              &Controller->
1222
                               V1.LastBackgroundInitializationStatus);
1223
    }
1224
  /*
1225
    Initialize the Logical Drive Initially Accessible flag.
1226
  */
1227
  for (LogicalDriveNumber = 0;
1228
       LogicalDriveNumber < Controller->LogicalDriveCount;
1229
       LogicalDriveNumber++)
1230
    if (Controller->V1.LogicalDriveInformation
1231
                       [LogicalDriveNumber].LogicalDriveState !=
1232
        DAC960_V1_LogicalDrive_Offline)
1233
      Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
1234
  Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
1235
  return true;
1236
}
1237
 
1238
 
1239
/*
1240
  DAC960_V2_ReadControllerConfiguration reads the Configuration Information
1241
  from DAC960 V2 Firmware Controllers and initializes the Controller structure.
1242
*/
1243
 
1244
static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
1245
                                                     *Controller)
1246
{
1247
  DAC960_V2_ControllerInfo_T *ControllerInfo =
1248
    &Controller->V2.ControllerInformation;
1249
  unsigned short LogicalDeviceNumber = 0;
1250
  int ModelNameLength;
1251
  if (!DAC960_V2_ControllerInfo(Controller, DAC960_V2_GetControllerInfo,
1252
                                ControllerInfo,
1253
                                sizeof(DAC960_V2_ControllerInfo_T)))
1254
    return DAC960_Failure(Controller, "GET CONTROLLER INFO");
1255
  if (!DAC960_V2_GeneralInfo(Controller, DAC960_V2_GetHealthStatus,
1256
                             Controller->V2.HealthStatusBuffer,
1257
                             sizeof(DAC960_V2_HealthStatusBuffer_T)))
1258
    return DAC960_Failure(Controller, "GET HEALTH STATUS");
1259
  /*
1260
    Initialize the Controller Model Name and Full Model Name fields.
1261
  */
1262
  ModelNameLength = sizeof(ControllerInfo->ControllerName);
1263
  if (ModelNameLength > sizeof(Controller->ModelName)-1)
1264
    ModelNameLength = sizeof(Controller->ModelName)-1;
1265
  memcpy(Controller->ModelName, ControllerInfo->ControllerName,
1266
         ModelNameLength);
1267
  ModelNameLength--;
1268
  while (Controller->ModelName[ModelNameLength] == ' ' ||
1269
         Controller->ModelName[ModelNameLength] == '\0')
1270
    ModelNameLength--;
1271
  Controller->ModelName[++ModelNameLength] = '\0';
1272
  strcpy(Controller->FullModelName, "Mylex ");
1273
  strcat(Controller->FullModelName, Controller->ModelName);
1274
  /*
1275
    Initialize the Controller Firmware Version field.
1276
  */
1277
  sprintf(Controller->FirmwareVersion, "%d.%02d-%02d",
1278
          ControllerInfo->FirmwareMajorVersion,
1279
          ControllerInfo->FirmwareMinorVersion,
1280
          ControllerInfo->FirmwareTurnNumber);
1281
  if (ControllerInfo->FirmwareMajorVersion == 6 &&
1282
      ControllerInfo->FirmwareMinorVersion == 0 &&
1283
      ControllerInfo->FirmwareTurnNumber < 1)
1284
    {
1285
      DAC960_Info("FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n",
1286
                  Controller, Controller->FirmwareVersion);
1287
      DAC960_Info("STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n",
1288
                  Controller);
1289
      DAC960_Info("PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n",
1290
                  Controller);
1291
    }
1292
  /*
1293
    Initialize the Controller Channels, Targets, and Memory Size.
1294
  */
1295
  Controller->Channels = ControllerInfo->NumberOfPhysicalChannelsPresent;
1296
  Controller->Targets =
1297
    ControllerInfo->MaximumTargetsPerChannel
1298
                    [ControllerInfo->NumberOfPhysicalChannelsPresent-1];
1299
  Controller->MemorySize = ControllerInfo->MemorySizeMB;
1300
  /*
1301
    Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
1302
    Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
1303
    Driver Scatter/Gather Limit.  The Driver Queue Depth must be at most one
1304
    less than the Controller Queue Depth to allow for an automatic drive
1305
    rebuild operation.
1306
  */
1307
  Controller->ControllerQueueDepth = ControllerInfo->MaximumParallelCommands;
1308
  Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
1309
  if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
1310
    Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
1311
  Controller->LogicalDriveCount = ControllerInfo->LogicalDevicesPresent;
1312
  Controller->MaxBlocksPerCommand =
1313
    ControllerInfo->MaximumDataTransferSizeInBlocks;
1314
  Controller->ControllerScatterGatherLimit =
1315
    ControllerInfo->MaximumScatterGatherEntries;
1316
  Controller->DriverScatterGatherLimit =
1317
    Controller->ControllerScatterGatherLimit;
1318
  if (Controller->DriverScatterGatherLimit > DAC960_V2_ScatterGatherLimit)
1319
    Controller->DriverScatterGatherLimit = DAC960_V2_ScatterGatherLimit;
1320
  /*
1321
    Initialize the Logical Device Information.
1322
  */
1323
  while (true)
1324
    {
1325
      DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
1326
        &Controller->V2.NewLogicalDeviceInformation;
1327
      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo;
1328
      DAC960_V2_PhysicalDevice_T PhysicalDevice;
1329
      if (!DAC960_V2_LogicalDeviceInfo(Controller,
1330
                                       DAC960_V2_GetLogicalDeviceInfoValid,
1331
                                       LogicalDeviceNumber,
1332
                                       NewLogicalDeviceInfo,
1333
                                       sizeof(DAC960_V2_LogicalDeviceInfo_T)))
1334
        break;
1335
      LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
1336
      if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
1337
        panic("DAC960: Logical Drive Number %d not supported\n",
1338
                       LogicalDeviceNumber);
1339
      if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
1340
        panic("DAC960: Logical Drive Block Size %d not supported\n",
1341
              NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
1342
      PhysicalDevice.Controller = 0;
1343
      PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
1344
      PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
1345
      PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
1346
      Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
1347
        PhysicalDevice;
1348
      if (NewLogicalDeviceInfo->LogicalDeviceState !=
1349
          DAC960_V2_LogicalDevice_Offline)
1350
        Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
1351
      LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
1352
        kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
1353
      if (LogicalDeviceInfo == NULL)
1354
        return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
1355
      Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
1356
        LogicalDeviceInfo;
1357
      memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
1358
             sizeof(DAC960_V2_LogicalDeviceInfo_T));
1359
      LogicalDeviceNumber++;
1360
    }
1361
  return true;
1362
}
1363
 
1364
 
1365
/*
1366
  DAC960_ReportControllerConfiguration reports the Configuration Information
1367
  for Controller.
1368
*/
1369
 
1370
static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
1371
                                                    *Controller)
1372
{
1373
  DAC960_Info("Configuring Mylex %s PCI RAID Controller\n",
1374
              Controller, Controller->ModelName);
1375
  DAC960_Info("  Firmware Version: %s, Channels: %d, Memory Size: %dMB\n",
1376
              Controller, Controller->FirmwareVersion,
1377
              Controller->Channels, Controller->MemorySize);
1378
  DAC960_Info("  PCI Bus: %d, Device: %d, Function: %d, I/O Address: ",
1379
              Controller, Controller->Bus,
1380
              Controller->Device, Controller->Function);
1381
  if (Controller->IO_Address == 0)
1382
    DAC960_Info("Unassigned\n", Controller);
1383
  else DAC960_Info("0x%X\n", Controller, Controller->IO_Address);
1384
  DAC960_Info("  PCI Address: 0x%X mapped at 0x%lX, IRQ Channel: %d\n",
1385
              Controller, Controller->PCI_Address,
1386
              (unsigned long) Controller->BaseAddress,
1387
              Controller->IRQ_Channel);
1388
  DAC960_Info("  Controller Queue Depth: %d, "
1389
              "Maximum Blocks per Command: %d\n",
1390
              Controller, Controller->ControllerQueueDepth,
1391
              Controller->MaxBlocksPerCommand);
1392
  DAC960_Info("  Driver Queue Depth: %d, "
1393
              "Scatter/Gather Limit: %d of %d Segments\n",
1394
              Controller, Controller->DriverQueueDepth,
1395
              Controller->DriverScatterGatherLimit,
1396
              Controller->ControllerScatterGatherLimit);
1397
  if (Controller->FirmwareType == DAC960_V1_Controller)
1398
    {
1399
      DAC960_Info("  Stripe Size: %dKB, Segment Size: %dKB, "
1400
                  "BIOS Geometry: %d/%d\n", Controller,
1401
                  Controller->V1.StripeSize,
1402
                  Controller->V1.SegmentSize,
1403
                  Controller->V1.GeometryTranslationHeads,
1404
                  Controller->V1.GeometryTranslationSectors);
1405
      if (Controller->V1.SAFTE_EnclosureManagementEnabled)
1406
        DAC960_Info("  SAF-TE Enclosure Management Enabled\n", Controller);
1407
    }
1408
  return true;
1409
}
1410
 
1411
 
1412
/*
1413
  DAC960_V1_ReadDeviceConfiguration reads the Device Configuration Information
1414
  for DAC960 V1 Firmware Controllers by requesting the SCSI Inquiry and SCSI
1415
  Inquiry Unit Serial Number information for each device connected to
1416
  Controller.
1417
*/
1418
 
1419
static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
1420
                                                 *Controller)
1421
{
1422
  DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
1423
  Completion_T Completions[DAC960_V1_MaxChannels], *Completion;
1424
  unsigned long ProcessorFlags;
1425
  int Channel, TargetID;
1426
  for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
1427
    {
1428
      for (Channel = 0; Channel < Controller->Channels; Channel++)
1429
        {
1430
          DAC960_Command_T *Command = Controller->Commands[Channel];
1431
          DAC960_SCSI_Inquiry_T *InquiryStandardData =
1432
            &Controller->V1.InquiryStandardData[Channel][TargetID];
1433
          InquiryStandardData->PeripheralDeviceType = 0x1F;
1434
          Completion = &Completions[Channel];
1435
          init_completion(Completion);
1436
          DCDB = &DCDBs[Channel];
1437
          DAC960_V1_ClearCommand(Command);
1438
          Command->CommandType = DAC960_ImmediateCommand;
1439
          Command->Completion = Completion;
1440
          Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
1441
          Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus32(DCDB);
1442
          DCDB->Channel = Channel;
1443
          DCDB->TargetID = TargetID;
1444
          DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
1445
          DCDB->EarlyStatus = false;
1446
          DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
1447
          DCDB->NoAutomaticRequestSense = false;
1448
          DCDB->DisconnectPermitted = true;
1449
          DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
1450
          DCDB->BusAddress = Virtual_to_Bus32(InquiryStandardData);
1451
          DCDB->CDBLength = 6;
1452
          DCDB->TransferLengthHigh4 = 0;
1453
          DCDB->SenseLength = sizeof(DCDB->SenseData);
1454
          DCDB->CDB[0] = 0x12; /* INQUIRY */
1455
          DCDB->CDB[1] = 0; /* EVPD = 0 */
1456
          DCDB->CDB[2] = 0; /* Page Code */
1457
          DCDB->CDB[3] = 0; /* Reserved */
1458
          DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
1459
          DCDB->CDB[5] = 0; /* Control */
1460
          DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
1461
          DAC960_QueueCommand(Command);
1462
          DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
1463
        }
1464
      for (Channel = 0; Channel < Controller->Channels; Channel++)
1465
        {
1466
          DAC960_Command_T *Command = Controller->Commands[Channel];
1467
          DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1468
            &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
1469
          InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
1470
          Completion = &Completions[Channel];
1471
          wait_for_completion(Completion);
1472
          if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
1473
            continue;
1474
          Command->Completion = Completion;
1475
          DCDB = &DCDBs[Channel];
1476
          DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1477
          DCDB->BusAddress = Virtual_to_Bus32(InquiryUnitSerialNumber);
1478
          DCDB->SenseLength = sizeof(DCDB->SenseData);
1479
          DCDB->CDB[0] = 0x12; /* INQUIRY */
1480
          DCDB->CDB[1] = 1; /* EVPD = 1 */
1481
          DCDB->CDB[2] = 0x80; /* Page Code */
1482
          DCDB->CDB[3] = 0; /* Reserved */
1483
          DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1484
          DCDB->CDB[5] = 0; /* Control */
1485
          DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
1486
          DAC960_QueueCommand(Command);
1487
          DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
1488
          wait_for_completion(Completion);
1489
        }
1490
    }
1491
  return true;
1492
}
1493
 
1494
 
1495
/*
1496
  DAC960_V2_ReadDeviceConfiguration reads the Device Configuration Information
1497
  for DAC960 V2 Firmware Controllers by requesting the Physical Device
1498
  Information and SCSI Inquiry Unit Serial Number information for each
1499
  device connected to Controller.
1500
*/
1501
 
1502
static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
1503
                                                 *Controller)
1504
{
1505
  unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
1506
  unsigned short PhysicalDeviceIndex = 0;
1507
  while (true)
1508
    {
1509
      DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
1510
        &Controller->V2.NewPhysicalDeviceInformation;
1511
      DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo;
1512
      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
1513
      DAC960_Command_T *Command;
1514
      DAC960_V2_CommandMailbox_T *CommandMailbox;
1515
      if (!DAC960_V2_PhysicalDeviceInfo(Controller,
1516
                                        DAC960_V2_GetPhysicalDeviceInfoValid,
1517
                                        Channel,
1518
                                        TargetID,
1519
                                        LogicalUnit,
1520
                                        NewPhysicalDeviceInfo,
1521
                                        sizeof(DAC960_V2_PhysicalDeviceInfo_T)))
1522
          break;
1523
      Channel = NewPhysicalDeviceInfo->Channel;
1524
      TargetID = NewPhysicalDeviceInfo->TargetID;
1525
      LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
1526
      PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
1527
        kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
1528
      if (PhysicalDeviceInfo == NULL)
1529
        return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
1530
      Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
1531
        PhysicalDeviceInfo;
1532
      memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
1533
             sizeof(DAC960_V2_PhysicalDeviceInfo_T));
1534
      InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
1535
        kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
1536
      if (InquiryUnitSerialNumber == NULL)
1537
        return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
1538
      Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] =
1539
        InquiryUnitSerialNumber;
1540
      memset(InquiryUnitSerialNumber, 0,
1541
             sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
1542
      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
1543
      Command = DAC960_AllocateCommand(Controller);
1544
      CommandMailbox = &Command->V2.CommandMailbox;
1545
      DAC960_V2_ClearCommand(Command);
1546
      Command->CommandType = DAC960_ImmediateCommand;
1547
      CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
1548
      CommandMailbox->SCSI_10.CommandControlBits
1549
                             .DataTransferControllerToHost = true;
1550
      CommandMailbox->SCSI_10.CommandControlBits
1551
                             .NoAutoRequestSense = true;
1552
      CommandMailbox->SCSI_10.DataTransferSize =
1553
        sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1554
      CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
1555
      CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
1556
      CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
1557
      CommandMailbox->SCSI_10.CDBLength = 6;
1558
      CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
1559
      CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
1560
      CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
1561
      CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
1562
      CommandMailbox->SCSI_10.SCSI_CDB[4] =
1563
        sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
1564
      CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
1565
      CommandMailbox->SCSI_10.DataTransferMemoryAddress
1566
                             .ScatterGatherSegments[0]
1567
                             .SegmentDataPointer =
1568
        Virtual_to_Bus64(InquiryUnitSerialNumber);
1569
      CommandMailbox->SCSI_10.DataTransferMemoryAddress
1570
                             .ScatterGatherSegments[0]
1571
                             .SegmentByteCount =
1572
        CommandMailbox->SCSI_10.DataTransferSize;
1573
      DAC960_ExecuteCommand(Command);
1574
      DAC960_DeallocateCommand(Command);
1575
      PhysicalDeviceIndex++;
1576
      LogicalUnit++;
1577
    }
1578
  return true;
1579
}
1580
 
1581
 
1582
/*
1583
  DAC960_SanitizeInquiryData sanitizes the Vendor, Model, Revision, and
1584
  Product Serial Number fields of the Inquiry Standard Data and Inquiry
1585
  Unit Serial Number structures.
1586
*/
1587
 
1588
static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
1589
                                         *InquiryStandardData,
1590
                                       DAC960_SCSI_Inquiry_UnitSerialNumber_T
1591
                                         *InquiryUnitSerialNumber,
1592
                                       unsigned char *Vendor,
1593
                                       unsigned char *Model,
1594
                                       unsigned char *Revision,
1595
                                       unsigned char *SerialNumber)
1596
{
1597
  int SerialNumberLength, i;
1598
  if (InquiryStandardData->PeripheralDeviceType == 0x1F) return;
1599
  for (i = 0; i < sizeof(InquiryStandardData->VendorIdentification); i++)
1600
    {
1601
      unsigned char VendorCharacter =
1602
        InquiryStandardData->VendorIdentification[i];
1603
      Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
1604
                   ? VendorCharacter : ' ');
1605
    }
1606
  Vendor[sizeof(InquiryStandardData->VendorIdentification)] = '\0';
1607
  for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++)
1608
    {
1609
      unsigned char ModelCharacter =
1610
        InquiryStandardData->ProductIdentification[i];
1611
      Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
1612
                  ? ModelCharacter : ' ');
1613
    }
1614
  Model[sizeof(InquiryStandardData->ProductIdentification)] = '\0';
1615
  for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++)
1616
    {
1617
      unsigned char RevisionCharacter =
1618
        InquiryStandardData->ProductRevisionLevel[i];
1619
      Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
1620
                     ? RevisionCharacter : ' ');
1621
    }
1622
  Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = '\0';
1623
  if (InquiryUnitSerialNumber->PeripheralDeviceType == 0x1F) return;
1624
  SerialNumberLength = InquiryUnitSerialNumber->PageLength;
1625
  if (SerialNumberLength >
1626
      sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
1627
    SerialNumberLength = sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
1628
  for (i = 0; i < SerialNumberLength; i++)
1629
    {
1630
      unsigned char SerialNumberCharacter =
1631
        InquiryUnitSerialNumber->ProductSerialNumber[i];
1632
      SerialNumber[i] =
1633
        (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
1634
         ? SerialNumberCharacter : ' ');
1635
    }
1636
  SerialNumber[SerialNumberLength] = '\0';
1637
}
1638
 
1639
 
1640
/*
1641
  DAC960_V1_ReportDeviceConfiguration reports the Device Configuration
1642
  Information for DAC960 V1 Firmware Controllers.
1643
*/
1644
 
1645
static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
1646
                                                   *Controller)
1647
{
1648
  int LogicalDriveNumber, Channel, TargetID;
1649
  DAC960_Info("  Physical Devices:\n", Controller);
1650
  for (Channel = 0; Channel < Controller->Channels; Channel++)
1651
    for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
1652
      {
1653
        DAC960_SCSI_Inquiry_T *InquiryStandardData =
1654
          &Controller->V1.InquiryStandardData[Channel][TargetID];
1655
        DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1656
          &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
1657
        DAC960_V1_DeviceState_T *DeviceState =
1658
          &Controller->V1.DeviceState[Channel][TargetID];
1659
        DAC960_V1_ErrorTableEntry_T *ErrorEntry =
1660
          &Controller->V1.ErrorTable.ErrorTableEntries[Channel][TargetID];
1661
        char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
1662
        char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
1663
        char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
1664
        char SerialNumber[1+sizeof(InquiryUnitSerialNumber
1665
                                   ->ProductSerialNumber)];
1666
        if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
1667
        DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
1668
                                   Vendor, Model, Revision, SerialNumber);
1669
        DAC960_Info("    %d:%d%s Vendor: %s  Model: %s  Revision: %s\n",
1670
                    Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
1671
                    Vendor, Model, Revision);
1672
        if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
1673
          DAC960_Info("         Serial Number: %s\n", Controller, SerialNumber);
1674
        if (DeviceState->Present &&
1675
            DeviceState->DeviceType == DAC960_V1_DiskType)
1676
          {
1677
            if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
1678
              DAC960_Info("         Disk Status: %s, %u blocks, %d resets\n",
1679
                          Controller,
1680
                          (DeviceState->DeviceState == DAC960_V1_Device_Dead
1681
                           ? "Dead"
1682
                           : DeviceState->DeviceState
1683
                             == DAC960_V1_Device_WriteOnly
1684
                             ? "Write-Only"
1685
                             : DeviceState->DeviceState
1686
                               == DAC960_V1_Device_Online
1687
                               ? "Online" : "Standby"),
1688
                          DeviceState->DiskSize,
1689
                          Controller->V1.DeviceResetCount[Channel][TargetID]);
1690
            else
1691
              DAC960_Info("         Disk Status: %s, %u blocks\n", Controller,
1692
                          (DeviceState->DeviceState == DAC960_V1_Device_Dead
1693
                           ? "Dead"
1694
                           : DeviceState->DeviceState
1695
                             == DAC960_V1_Device_WriteOnly
1696
                             ? "Write-Only"
1697
                             : DeviceState->DeviceState
1698
                               == DAC960_V1_Device_Online
1699
                               ? "Online" : "Standby"),
1700
                          DeviceState->DiskSize);
1701
          }
1702
        if (ErrorEntry->ParityErrorCount > 0 ||
1703
            ErrorEntry->SoftErrorCount > 0 ||
1704
            ErrorEntry->HardErrorCount > 0 ||
1705
            ErrorEntry->MiscErrorCount > 0)
1706
          DAC960_Info("         Errors - Parity: %d, Soft: %d, "
1707
                      "Hard: %d, Misc: %d\n", Controller,
1708
                      ErrorEntry->ParityErrorCount,
1709
                      ErrorEntry->SoftErrorCount,
1710
                      ErrorEntry->HardErrorCount,
1711
                      ErrorEntry->MiscErrorCount);
1712
      }
1713
  DAC960_Info("  Logical Drives:\n", Controller);
1714
  for (LogicalDriveNumber = 0;
1715
       LogicalDriveNumber < Controller->LogicalDriveCount;
1716
       LogicalDriveNumber++)
1717
    {
1718
      DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
1719
        &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
1720
      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %u blocks, %s\n",
1721
                  Controller, Controller->ControllerNumber, LogicalDriveNumber,
1722
                  LogicalDriveInformation->RAIDLevel,
1723
                  (LogicalDriveInformation->LogicalDriveState
1724
                   == DAC960_V1_LogicalDrive_Online
1725
                   ? "Online"
1726
                   : LogicalDriveInformation->LogicalDriveState
1727
                     == DAC960_V1_LogicalDrive_Critical
1728
                     ? "Critical" : "Offline"),
1729
                  LogicalDriveInformation->LogicalDriveSize,
1730
                  (LogicalDriveInformation->WriteBack
1731
                   ? "Write Back" : "Write Thru"));
1732
    }
1733
  return true;
1734
}
1735
 
1736
 
1737
/*
1738
  DAC960_V2_ReportDeviceConfiguration reports the Device Configuration
1739
  Information for DAC960 V2 Firmware Controllers.
1740
*/
1741
 
1742
static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
1743
                                                   *Controller)
1744
{
1745
  int PhysicalDeviceIndex, LogicalDriveNumber;
1746
  DAC960_Info("  Physical Devices:\n", Controller);
1747
  for (PhysicalDeviceIndex = 0;
1748
       PhysicalDeviceIndex < DAC960_V2_MaxPhysicalDevices;
1749
       PhysicalDeviceIndex++)
1750
    {
1751
      DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
1752
        Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
1753
      DAC960_SCSI_Inquiry_T *InquiryStandardData =
1754
        (DAC960_SCSI_Inquiry_T *) &PhysicalDeviceInfo->SCSI_InquiryData;
1755
      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
1756
        Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
1757
      char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
1758
      char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
1759
      char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
1760
      char SerialNumber[1+sizeof(InquiryUnitSerialNumber->ProductSerialNumber)];
1761
      if (PhysicalDeviceInfo == NULL) break;
1762
      DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
1763
                                 Vendor, Model, Revision, SerialNumber);
1764
      DAC960_Info("    %d:%d%s Vendor: %s  Model: %s  Revision: %s\n",
1765
                  Controller,
1766
                  PhysicalDeviceInfo->Channel,
1767
                  PhysicalDeviceInfo->TargetID,
1768
                  (PhysicalDeviceInfo->TargetID < 10 ? " " : ""),
1769
                  Vendor, Model, Revision);
1770
      if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0)
1771
        DAC960_Info("         %sAsynchronous\n", Controller,
1772
                    (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1773
                     ? "Wide " :""));
1774
      else
1775
        DAC960_Info("         %sSynchronous at %d MB/sec\n", Controller,
1776
                    (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1777
                     ? "Wide " :""),
1778
                    (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers
1779
                     * (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
1780
                        ? 2 : 1)));
1781
      if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
1782
        DAC960_Info("         Serial Number: %s\n", Controller, SerialNumber);
1783
      if (PhysicalDeviceInfo->PhysicalDeviceState ==
1784
          DAC960_V2_Device_Unconfigured)
1785
        continue;
1786
      DAC960_Info("         Disk Status: %s, %u blocks\n", Controller,
1787
                  (PhysicalDeviceInfo->PhysicalDeviceState
1788
                   == DAC960_V2_Device_Online
1789
                   ? "Online"
1790
                   : PhysicalDeviceInfo->PhysicalDeviceState
1791
                     == DAC960_V2_Device_Rebuild
1792
                     ? "Rebuild"
1793
                     : PhysicalDeviceInfo->PhysicalDeviceState
1794
                       == DAC960_V2_Device_Missing
1795
                       ? "Missing"
1796
                       : PhysicalDeviceInfo->PhysicalDeviceState
1797
                         == DAC960_V2_Device_Critical
1798
                         ? "Critical"
1799
                         : PhysicalDeviceInfo->PhysicalDeviceState
1800
                           == DAC960_V2_Device_Dead
1801
                           ? "Dead"
1802
                           : PhysicalDeviceInfo->PhysicalDeviceState
1803
                             == DAC960_V2_Device_SuspectedDead
1804
                             ? "Suspected-Dead"
1805
                             : PhysicalDeviceInfo->PhysicalDeviceState
1806
                               == DAC960_V2_Device_CommandedOffline
1807
                               ? "Commanded-Offline"
1808
                               : PhysicalDeviceInfo->PhysicalDeviceState
1809
                                 == DAC960_V2_Device_Standby
1810
                                 ? "Standby" : "Unknown"),
1811
                  PhysicalDeviceInfo->ConfigurableDeviceSize);
1812
      if (PhysicalDeviceInfo->ParityErrors == 0 &&
1813
          PhysicalDeviceInfo->SoftErrors == 0 &&
1814
          PhysicalDeviceInfo->HardErrors == 0 &&
1815
          PhysicalDeviceInfo->MiscellaneousErrors == 0 &&
1816
          PhysicalDeviceInfo->CommandTimeouts == 0 &&
1817
          PhysicalDeviceInfo->Retries == 0 &&
1818
          PhysicalDeviceInfo->Aborts == 0 &&
1819
          PhysicalDeviceInfo->PredictedFailuresDetected == 0)
1820
        continue;
1821
      DAC960_Info("         Errors - Parity: %d, Soft: %d, "
1822
                  "Hard: %d, Misc: %d\n", Controller,
1823
                  PhysicalDeviceInfo->ParityErrors,
1824
                  PhysicalDeviceInfo->SoftErrors,
1825
                  PhysicalDeviceInfo->HardErrors,
1826
                  PhysicalDeviceInfo->MiscellaneousErrors);
1827
      DAC960_Info("                  Timeouts: %d, Retries: %d, "
1828
                  "Aborts: %d, Predicted: %d\n", Controller,
1829
                  PhysicalDeviceInfo->CommandTimeouts,
1830
                  PhysicalDeviceInfo->Retries,
1831
                  PhysicalDeviceInfo->Aborts,
1832
                  PhysicalDeviceInfo->PredictedFailuresDetected);
1833
    }
1834
  DAC960_Info("  Logical Drives:\n", Controller);
1835
  for (LogicalDriveNumber = 0;
1836
       LogicalDriveNumber < DAC960_MaxLogicalDrives;
1837
       LogicalDriveNumber++)
1838
    {
1839
      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
1840
        Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
1841
      unsigned char *ReadCacheStatus[] = { "Read Cache Disabled",
1842
                                           "Read Cache Enabled",
1843
                                           "Read Ahead Enabled",
1844
                                           "Intelligent Read Ahead Enabled",
1845
                                           "-", "-", "-", "-" };
1846
      unsigned char *WriteCacheStatus[] = { "Write Cache Disabled",
1847
                                            "Logical Device Read Only",
1848
                                            "Write Cache Enabled",
1849
                                            "Intelligent Write Cache Enabled",
1850
                                            "-", "-", "-", "-" };
1851
      unsigned char *GeometryTranslation;
1852
      if (LogicalDeviceInfo == NULL) continue;
1853
      switch (LogicalDeviceInfo->DriveGeometry)
1854
        {
1855
        case DAC960_V2_Geometry_128_32:
1856
          GeometryTranslation = "128/32";
1857
          break;
1858
        case DAC960_V2_Geometry_255_63:
1859
          GeometryTranslation = "255/63";
1860
          break;
1861
        default:
1862
          GeometryTranslation = "Invalid";
1863
          DAC960_Error("Illegal Logical Device Geometry %d\n",
1864
                       Controller, LogicalDeviceInfo->DriveGeometry);
1865
          break;
1866
        }
1867
      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %u blocks\n",
1868
                  Controller, Controller->ControllerNumber, LogicalDriveNumber,
1869
                  LogicalDeviceInfo->RAIDLevel,
1870
                  (LogicalDeviceInfo->LogicalDeviceState
1871
                   == DAC960_V2_LogicalDevice_Online
1872
                   ? "Online"
1873
                   : LogicalDeviceInfo->LogicalDeviceState
1874
                     == DAC960_V2_LogicalDevice_Critical
1875
                     ? "Critical" : "Offline"),
1876
                  LogicalDeviceInfo->ConfigurableDeviceSize);
1877
      DAC960_Info("                  Logical Device %s, BIOS Geometry: %s\n",
1878
                  Controller,
1879
                  (LogicalDeviceInfo->LogicalDeviceControl
1880
                                     .LogicalDeviceInitialized
1881
                   ? "Initialized" : "Uninitialized"),
1882
                  GeometryTranslation);
1883
      if (LogicalDeviceInfo->StripeSize == 0)
1884
        {
1885
          if (LogicalDeviceInfo->CacheLineSize == 0)
1886
            DAC960_Info("                  Stripe Size: N/A, "
1887
                        "Segment Size: N/A\n", Controller);
1888
          else
1889
            DAC960_Info("                  Stripe Size: N/A, "
1890
                        "Segment Size: %dKB\n", Controller,
1891
                        1 << (LogicalDeviceInfo->CacheLineSize - 2));
1892
        }
1893
      else
1894
        {
1895
          if (LogicalDeviceInfo->CacheLineSize == 0)
1896
            DAC960_Info("                  Stripe Size: %dKB, "
1897
                        "Segment Size: N/A\n", Controller,
1898
                        1 << (LogicalDeviceInfo->StripeSize - 2));
1899
          else
1900
            DAC960_Info("                  Stripe Size: %dKB, "
1901
                        "Segment Size: %dKB\n", Controller,
1902
                        1 << (LogicalDeviceInfo->StripeSize - 2),
1903
                        1 << (LogicalDeviceInfo->CacheLineSize - 2));
1904
        }
1905
      DAC960_Info("                  %s, %s\n", Controller,
1906
                  ReadCacheStatus[
1907
                    LogicalDeviceInfo->LogicalDeviceControl.ReadCache],
1908
                  WriteCacheStatus[
1909
                    LogicalDeviceInfo->LogicalDeviceControl.WriteCache]);
1910
      if (LogicalDeviceInfo->SoftErrors > 0 ||
1911
          LogicalDeviceInfo->CommandsFailed > 0 ||
1912
          LogicalDeviceInfo->DeferredWriteErrors)
1913
        DAC960_Info("                  Errors - Soft: %d, Failed: %d, "
1914
                    "Deferred Write: %d\n", Controller,
1915
                    LogicalDeviceInfo->SoftErrors,
1916
                    LogicalDeviceInfo->CommandsFailed,
1917
                    LogicalDeviceInfo->DeferredWriteErrors);
1918
 
1919
    }
1920
  return true;
1921
}
1922
 
1923
 
1924
/*
1925
  DAC960_BackMergeFunction is the Back Merge Function for the DAC960 driver.
1926
*/
1927
 
1928
static int DAC960_BackMergeFunction(RequestQueue_T *RequestQueue,
1929
                                    IO_Request_T *Request,
1930
                                    BufferHeader_T *BufferHeader,
1931
                                    int MaxSegments)
1932
{
1933
  DAC960_Controller_T *Controller =
1934
    (DAC960_Controller_T *) RequestQueue->queuedata;
1935
  if (Request->bhtail->b_data + Request->bhtail->b_size == BufferHeader->b_data)
1936
    return true;
1937
  if (Request->nr_segments < MaxSegments &&
1938
      Request->nr_segments < Controller->DriverScatterGatherLimit)
1939
    {
1940
      Request->nr_segments++;
1941
      return true;
1942
    }
1943
  return false;
1944
}
1945
 
1946
 
1947
/*
1948
  DAC960_FrontMergeFunction is the Front Merge Function for the DAC960 driver.
1949
*/
1950
 
1951
static int DAC960_FrontMergeFunction(RequestQueue_T *RequestQueue,
1952
                                     IO_Request_T *Request,
1953
                                     BufferHeader_T *BufferHeader,
1954
                                     int MaxSegments)
1955
{
1956
  DAC960_Controller_T *Controller =
1957
    (DAC960_Controller_T *) RequestQueue->queuedata;
1958
  if (BufferHeader->b_data + BufferHeader->b_size == Request->bh->b_data)
1959
    return true;
1960
  if (Request->nr_segments < MaxSegments &&
1961
      Request->nr_segments < Controller->DriverScatterGatherLimit)
1962
    {
1963
      Request->nr_segments++;
1964
      return true;
1965
    }
1966
  return false;
1967
}
1968
 
1969
 
1970
/*
1971
  DAC960_MergeRequestsFunction is the Merge Requests Function for the
1972
  DAC960 driver.
1973
*/
1974
 
1975
static int DAC960_MergeRequestsFunction(RequestQueue_T *RequestQueue,
1976
                                        IO_Request_T *Request,
1977
                                        IO_Request_T *NextRequest,
1978
                                        int MaxSegments)
1979
{
1980
  DAC960_Controller_T *Controller =
1981
    (DAC960_Controller_T *) RequestQueue->queuedata;
1982
  int TotalSegments = Request->nr_segments + NextRequest->nr_segments;
1983
  if (Request->bhtail->b_data + Request->bhtail->b_size
1984
      == NextRequest->bh->b_data)
1985
    TotalSegments--;
1986
  if (TotalSegments > MaxSegments ||
1987
      TotalSegments > Controller->DriverScatterGatherLimit)
1988
    return false;
1989
  Request->nr_segments = TotalSegments;
1990
  return true;
1991
}
1992
 
1993
 
1994
/*
1995
  DAC960_RegisterBlockDevice registers the Block Device structures
1996
  associated with Controller.
1997
*/
1998
 
1999
static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
2000
{
2001
  int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
2002
  RequestQueue_T *RequestQueue;
2003
  int MinorNumber;
2004
  /*
2005
    Register the Block Device Major Number for this DAC960 Controller.
2006
  */
2007
  if (devfs_register_blkdev(MajorNumber, "dac960",
2008
                            &DAC960_BlockDeviceOperations) < 0)
2009
    {
2010
      DAC960_Error("UNABLE TO ACQUIRE MAJOR NUMBER %d - DETACHING\n",
2011
                   Controller, MajorNumber);
2012
      return false;
2013
    }
2014
  /*
2015
    Initialize the I/O Request Queue.
2016
  */
2017
  RequestQueue = BLK_DEFAULT_QUEUE(MajorNumber);
2018
  blk_init_queue(RequestQueue, DAC960_RequestFunction);
2019
  blk_queue_headactive(RequestQueue, 0);
2020
  RequestQueue->back_merge_fn = DAC960_BackMergeFunction;
2021
  RequestQueue->front_merge_fn = DAC960_FrontMergeFunction;
2022
  RequestQueue->merge_requests_fn = DAC960_MergeRequestsFunction;
2023
  RequestQueue->queuedata = Controller;
2024
  Controller->RequestQueue = RequestQueue;
2025
  /*
2026
    Initialize the Max Sectors per Request array.
2027
  */
2028
  for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
2029
    Controller->MaxSectorsPerRequest[MinorNumber] =
2030
      Controller->MaxBlocksPerCommand;
2031
  Controller->GenericDiskInfo.part = Controller->DiskPartitions;
2032
  Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
2033
  blksize_size[MajorNumber] = Controller->BlockSizes;
2034
  max_sectors[MajorNumber] = Controller->MaxSectorsPerRequest;
2035
  /*
2036
    Initialize Read Ahead to 128 sectors.
2037
  */
2038
  read_ahead[MajorNumber] = 128;
2039
  /*
2040
    Complete initialization of the Generic Disk Information structure.
2041
  */
2042
  Controller->GenericDiskInfo.major = MajorNumber;
2043
  Controller->GenericDiskInfo.major_name = "rd";
2044
  Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
2045
  Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
2046
  Controller->GenericDiskInfo.nr_real = DAC960_MaxLogicalDrives;
2047
  Controller->GenericDiskInfo.real_devices = Controller;
2048
  Controller->GenericDiskInfo.next = NULL;
2049
  Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
2050
  /*
2051
    Install the Generic Disk Information structure at the end of the list.
2052
  */
2053
  add_gendisk(&Controller->GenericDiskInfo);
2054
  /*
2055
    Indicate the Block Device Registration completed successfully,
2056
  */
2057
  return true;
2058
}
2059
 
2060
 
2061
/*
2062
  DAC960_UnregisterBlockDevice unregisters the Block Device structures
2063
  associated with Controller.
2064
*/
2065
 
2066
static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
2067
{
2068
  int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
2069
  /*
2070
    Unregister the Block Device Major Number for this DAC960 Controller.
2071
  */
2072
  devfs_unregister_blkdev(MajorNumber, "dac960");
2073
  /*
2074
    Remove the I/O Request Queue.
2075
  */
2076
  blk_cleanup_queue(BLK_DEFAULT_QUEUE(MajorNumber));
2077
  /*
2078
    Remove the Disk Partitions array, Partition Sizes array, Block Sizes
2079
    array, Max Sectors per Request array, and Max Segments per Request array.
2080
  */
2081
  Controller->GenericDiskInfo.part = NULL;
2082
  Controller->GenericDiskInfo.sizes = NULL;
2083
  blk_size[MajorNumber] = NULL;
2084
  blksize_size[MajorNumber] = NULL;
2085
  max_sectors[MajorNumber] = NULL;
2086
  /*
2087
    Remove the Generic Disk Information structure from the list.
2088
  */
2089
  del_gendisk(&Controller->GenericDiskInfo);
2090
}
2091
 
2092
 
2093
/*
2094
  DAC960_ComputeGenericDiskInfo computes the values for the Generic Disk
2095
  Information Partition Sector Counts and Block Sizes.
2096
*/
2097
 
2098
static void DAC960_ComputeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
2099
{
2100
  DAC960_Controller_T *Controller =
2101
    (DAC960_Controller_T *) GenericDiskInfo->real_devices;
2102
  int LogicalDriveNumber, i;
2103
  for (LogicalDriveNumber = 0;
2104
       LogicalDriveNumber < DAC960_MaxLogicalDrives;
2105
       LogicalDriveNumber++)
2106
    {
2107
      int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber, 0);
2108
      if (Controller->FirmwareType == DAC960_V1_Controller)
2109
        {
2110
          if (LogicalDriveNumber < Controller->LogicalDriveCount)
2111
            GenericDiskInfo->part[MinorNumber].nr_sects =
2112
              Controller->V1.LogicalDriveInformation
2113
                             [LogicalDriveNumber].LogicalDriveSize;
2114
          else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
2115
        }
2116
      else
2117
        {
2118
          DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
2119
            Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
2120
          if (LogicalDeviceInfo != NULL)
2121
            GenericDiskInfo->part[MinorNumber].nr_sects =
2122
              LogicalDeviceInfo->ConfigurableDeviceSize;
2123
          else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
2124
        }
2125
      for (i = 0; i < DAC960_MaxPartitions; i++)
2126
        if (GenericDiskInfo->part[MinorNumber].nr_sects > 0)
2127
          Controller->BlockSizes[MinorNumber + i] = BLOCK_SIZE;
2128
        else Controller->BlockSizes[MinorNumber + i] = 0;
2129
    }
2130
}
2131
 
2132
 
2133
/*
2134
  DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
2135
  Drive Number if it exists.
2136
*/
2137
 
2138
static void DAC960_RegisterDisk(DAC960_Controller_T *Controller,
2139
                                int LogicalDriveNumber)
2140
{
2141
  if (Controller->FirmwareType == DAC960_V1_Controller)
2142
    {
2143
      if (LogicalDriveNumber > Controller->LogicalDriveCount - 1) return;
2144
      register_disk(&Controller->GenericDiskInfo,
2145
                    DAC960_KernelDevice(Controller->ControllerNumber,
2146
                                        LogicalDriveNumber, 0),
2147
                    DAC960_MaxPartitions,
2148
                    &DAC960_BlockDeviceOperations,
2149
                    Controller->V1.LogicalDriveInformation
2150
                                   [LogicalDriveNumber].LogicalDriveSize);
2151
    }
2152
  else
2153
    {
2154
      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
2155
        Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
2156
      if (LogicalDeviceInfo == NULL) return;
2157
      register_disk(&Controller->GenericDiskInfo,
2158
                    DAC960_KernelDevice(Controller->ControllerNumber,
2159
                                        LogicalDriveNumber, 0),
2160
                    DAC960_MaxPartitions,
2161
                    &DAC960_BlockDeviceOperations,
2162
                    LogicalDeviceInfo->ConfigurableDeviceSize);
2163
    }
2164
}
2165
 
2166
 
2167
/*
2168
  DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
2169
  the Error Status Register when the driver performs the BIOS handshaking.
2170
  It returns true for fatal errors and false otherwise.
2171
*/
2172
 
2173
static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
2174
                                        unsigned char ErrorStatus,
2175
                                        unsigned char Parameter0,
2176
                                        unsigned char Parameter1)
2177
{
2178
  switch (ErrorStatus)
2179
    {
2180
    case 0x00:
2181
      DAC960_Notice("Physical Device %d:%d Not Responding\n",
2182
                    Controller, Parameter1, Parameter0);
2183
      break;
2184
    case 0x08:
2185
      if (Controller->DriveSpinUpMessageDisplayed) break;
2186
      DAC960_Notice("Spinning Up Drives\n", Controller);
2187
      Controller->DriveSpinUpMessageDisplayed = true;
2188
      break;
2189
    case 0x30:
2190
      DAC960_Notice("Configuration Checksum Error\n", Controller);
2191
      break;
2192
    case 0x60:
2193
      DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
2194
      break;
2195
    case 0x70:
2196
      DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
2197
      break;
2198
    case 0x90:
2199
      DAC960_Notice("Physical Device %d:%d COD Mismatch\n",
2200
                    Controller, Parameter1, Parameter0);
2201
      break;
2202
    case 0xA0:
2203
      DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
2204
      break;
2205
    case 0xB0:
2206
      DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
2207
      break;
2208
    case 0xD0:
2209
      DAC960_Notice("New Controller Configuration Found\n", Controller);
2210
      break;
2211
    case 0xF0:
2212
      DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
2213
      return true;
2214
    default:
2215
      DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
2216
                   Controller, ErrorStatus);
2217
      return true;
2218
    }
2219
  return false;
2220
}
2221
 
2222
 
2223
/*
2224
  DAC960_DetectControllers detects Mylex DAC960/AcceleRAID/eXtremeRAID
2225
  PCI RAID Controllers by interrogating the PCI Configuration Space for
2226
  Controller Type.
2227
*/
2228
 
2229
static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
2230
{
2231
  void (*InterruptHandler)(int, void *, Registers_T *) = NULL;
2232
  DAC960_FirmwareType_T FirmwareType = 0;
2233
  unsigned short VendorID = 0, DeviceID = 0;
2234
  unsigned int MemoryWindowSize = 0;
2235
  PCI_Device_T *PCI_Device = NULL;
2236
  switch (HardwareType)
2237
    {
2238
    case DAC960_BA_Controller:
2239
      VendorID = PCI_VENDOR_ID_MYLEX;
2240
      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_BA;
2241
      FirmwareType = DAC960_V2_Controller;
2242
      InterruptHandler = DAC960_BA_InterruptHandler;
2243
      MemoryWindowSize = DAC960_BA_RegisterWindowSize;
2244
      break;
2245
    case DAC960_LP_Controller:
2246
      VendorID = PCI_VENDOR_ID_MYLEX;
2247
      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_LP;
2248
      FirmwareType = DAC960_LP_Controller;
2249
      InterruptHandler = DAC960_LP_InterruptHandler;
2250
      MemoryWindowSize = DAC960_LP_RegisterWindowSize;
2251
      break;
2252
    case DAC960_LA_Controller:
2253
      VendorID = PCI_VENDOR_ID_DEC;
2254
      DeviceID = PCI_DEVICE_ID_DEC_21285;
2255
      FirmwareType = DAC960_V1_Controller;
2256
      InterruptHandler = DAC960_LA_InterruptHandler;
2257
      MemoryWindowSize = DAC960_LA_RegisterWindowSize;
2258
      break;
2259
    case DAC960_PG_Controller:
2260
      VendorID = PCI_VENDOR_ID_MYLEX;
2261
      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PG;
2262
      FirmwareType = DAC960_V1_Controller;
2263
      InterruptHandler = DAC960_PG_InterruptHandler;
2264
      MemoryWindowSize = DAC960_PG_RegisterWindowSize;
2265
      break;
2266
    case DAC960_PD_Controller:
2267
      VendorID = PCI_VENDOR_ID_MYLEX;
2268
      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PD;
2269
      FirmwareType = DAC960_V1_Controller;
2270
      InterruptHandler = DAC960_PD_InterruptHandler;
2271
      MemoryWindowSize = DAC960_PD_RegisterWindowSize;
2272
      break;
2273
    case DAC960_P_Controller:
2274
      VendorID = PCI_VENDOR_ID_MYLEX;
2275
      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_P;
2276
      FirmwareType = DAC960_V1_Controller;
2277
      InterruptHandler = DAC960_P_InterruptHandler;
2278
      MemoryWindowSize = DAC960_PD_RegisterWindowSize;
2279
      break;
2280
    }
2281
  while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
2282
    {
2283
      DAC960_Controller_T *Controller = NULL;
2284
      DAC960_IO_Address_T IO_Address = 0;
2285
      DAC960_PCI_Address_T PCI_Address = 0;
2286
      unsigned char Bus = PCI_Device->bus->number;
2287
      unsigned char DeviceFunction = PCI_Device->devfn;
2288
      unsigned char Device = DeviceFunction >> 3;
2289
      unsigned char Function = DeviceFunction & 0x7;
2290
      unsigned char ErrorStatus, Parameter0, Parameter1;
2291
      unsigned int IRQ_Channel = PCI_Device->irq;
2292
      void *BaseAddress;
2293
      if (pci_enable_device(PCI_Device) != 0) continue;
2294
      switch (HardwareType)
2295
        {
2296
        case DAC960_BA_Controller:
2297
          PCI_Address = pci_resource_start(PCI_Device, 0);
2298
          break;
2299
        case DAC960_LP_Controller:
2300
          PCI_Address = pci_resource_start(PCI_Device, 0);
2301
          break;
2302
        case DAC960_LA_Controller:
2303
          if (!(PCI_Device->subsystem_vendor == PCI_VENDOR_ID_MYLEX &&
2304
                PCI_Device->subsystem_device == PCI_DEVICE_ID_MYLEX_DAC960_LA))
2305
            continue;
2306
          PCI_Address = pci_resource_start(PCI_Device, 0);
2307
          break;
2308
        case DAC960_PG_Controller:
2309
          PCI_Address = pci_resource_start(PCI_Device, 0);
2310
          break;
2311
        case DAC960_PD_Controller:
2312
          IO_Address = pci_resource_start(PCI_Device, 0);
2313
          PCI_Address = pci_resource_start(PCI_Device, 1);
2314
          break;
2315
        case DAC960_P_Controller:
2316
          IO_Address = pci_resource_start(PCI_Device, 0);
2317
          PCI_Address = pci_resource_start(PCI_Device, 1);
2318
          break;
2319
        }
2320
      if (DAC960_ControllerCount == DAC960_MaxControllers)
2321
        {
2322
          DAC960_Error("More than %d DAC960 Controllers detected - "
2323
                       "ignoring from Controller at\n",
2324
                       NULL, DAC960_MaxControllers);
2325
          goto Failure;
2326
        }
2327
      Controller = (DAC960_Controller_T *)
2328
        kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
2329
      if (Controller == NULL)
2330
        {
2331
          DAC960_Error("Unable to allocate Controller structure for "
2332
                       "Controller at\n", NULL);
2333
          goto Failure;
2334
        }
2335
      memset(Controller, 0, sizeof(DAC960_Controller_T));
2336
      Controller->ControllerNumber = DAC960_ControllerCount;
2337
      init_waitqueue_head(&Controller->CommandWaitQueue);
2338
      init_waitqueue_head(&Controller->HealthStatusWaitQueue);
2339
      DAC960_Controllers[DAC960_ControllerCount++] = Controller;
2340
      DAC960_AnnounceDriver(Controller);
2341
      Controller->FirmwareType = FirmwareType;
2342
      Controller->HardwareType = HardwareType;
2343
      Controller->IO_Address = IO_Address;
2344
      Controller->PCI_Address = PCI_Address;
2345
      Controller->Bus = Bus;
2346
      Controller->Device = Device;
2347
      Controller->Function = Function;
2348
      /*
2349
        Map the Controller Register Window.
2350
      */
2351
      if (MemoryWindowSize < PAGE_SIZE)
2352
        MemoryWindowSize = PAGE_SIZE;
2353
      Controller->MemoryMappedAddress =
2354
        ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
2355
      Controller->BaseAddress =
2356
        Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
2357
      if (Controller->MemoryMappedAddress == NULL)
2358
        {
2359
          DAC960_Error("Unable to map Controller Register Window for "
2360
                       "Controller at\n", Controller);
2361
          goto Failure;
2362
        }
2363
      BaseAddress = Controller->BaseAddress;
2364
      switch (HardwareType)
2365
        {
2366
        case DAC960_BA_Controller:
2367
          DAC960_BA_DisableInterrupts(Controller->BaseAddress);
2368
          DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
2369
          udelay(1000);
2370
          while (DAC960_BA_InitializationInProgressP(BaseAddress))
2371
            {
2372
              if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus,
2373
                                            &Parameter0, &Parameter1) &&
2374
                  DAC960_ReportErrorStatus(Controller, ErrorStatus,
2375
                                           Parameter0, Parameter1))
2376
                goto Failure;
2377
              udelay(10);
2378
            }
2379
          if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
2380
            {
2381
              DAC960_Error("Unable to Enable Memory Mailbox Interface "
2382
                           "for Controller at\n", Controller);
2383
              goto Failure;
2384
            }
2385
          DAC960_BA_EnableInterrupts(Controller->BaseAddress);
2386
          Controller->QueueCommand = DAC960_BA_QueueCommand;
2387
          Controller->ReadControllerConfiguration =
2388
            DAC960_V2_ReadControllerConfiguration;
2389
          Controller->ReadDeviceConfiguration =
2390
            DAC960_V2_ReadDeviceConfiguration;
2391
          Controller->ReportDeviceConfiguration =
2392
            DAC960_V2_ReportDeviceConfiguration;
2393
          Controller->QueueReadWriteCommand =
2394
            DAC960_V2_QueueReadWriteCommand;
2395
          break;
2396
        case DAC960_LP_Controller:
2397
          DAC960_LP_DisableInterrupts(Controller->BaseAddress);
2398
          DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
2399
          udelay(1000);
2400
          while (DAC960_LP_InitializationInProgressP(BaseAddress))
2401
            {
2402
              if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus,
2403
                                            &Parameter0, &Parameter1) &&
2404
                  DAC960_ReportErrorStatus(Controller, ErrorStatus,
2405
                                           Parameter0, Parameter1))
2406
                goto Failure;
2407
              udelay(10);
2408
            }
2409
          if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
2410
            {
2411
              DAC960_Error("Unable to Enable Memory Mailbox Interface "
2412
                           "for Controller at\n", Controller);
2413
              goto Failure;
2414
            }
2415
          DAC960_LP_EnableInterrupts(Controller->BaseAddress);
2416
          Controller->QueueCommand = DAC960_LP_QueueCommand;
2417
          Controller->ReadControllerConfiguration =
2418
            DAC960_V2_ReadControllerConfiguration;
2419
          Controller->ReadDeviceConfiguration =
2420
            DAC960_V2_ReadDeviceConfiguration;
2421
          Controller->ReportDeviceConfiguration =
2422
            DAC960_V2_ReportDeviceConfiguration;
2423
          Controller->QueueReadWriteCommand =
2424
            DAC960_V2_QueueReadWriteCommand;
2425
          break;
2426
        case DAC960_LA_Controller:
2427
          DAC960_LA_DisableInterrupts(Controller->BaseAddress);
2428
          DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
2429
          udelay(1000);
2430
          while (DAC960_LA_InitializationInProgressP(BaseAddress))
2431
            {
2432
              if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus,
2433
                                            &Parameter0, &Parameter1) &&
2434
                  DAC960_ReportErrorStatus(Controller, ErrorStatus,
2435
                                           Parameter0, Parameter1))
2436
                goto Failure;
2437
              udelay(10);
2438
            }
2439
          if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
2440
            {
2441
              DAC960_Error("Unable to Enable Memory Mailbox Interface "
2442
                           "for Controller at\n", Controller);
2443
              goto Failure;
2444
            }
2445
          DAC960_LA_EnableInterrupts(Controller->BaseAddress);
2446
          if (Controller->V1.DualModeMemoryMailboxInterface)
2447
            Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
2448
          else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
2449
          Controller->ReadControllerConfiguration =
2450
            DAC960_V1_ReadControllerConfiguration;
2451
          Controller->ReadDeviceConfiguration =
2452
            DAC960_V1_ReadDeviceConfiguration;
2453
          Controller->ReportDeviceConfiguration =
2454
            DAC960_V1_ReportDeviceConfiguration;
2455
          Controller->QueueReadWriteCommand =
2456
            DAC960_V1_QueueReadWriteCommand;
2457
          break;
2458
        case DAC960_PG_Controller:
2459
          DAC960_PG_DisableInterrupts(Controller->BaseAddress);
2460
          DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
2461
          udelay(1000);
2462
          while (DAC960_PG_InitializationInProgressP(BaseAddress))
2463
            {
2464
              if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus,
2465
                                            &Parameter0, &Parameter1) &&
2466
                  DAC960_ReportErrorStatus(Controller, ErrorStatus,
2467
                                           Parameter0, Parameter1))
2468
                goto Failure;
2469
              udelay(10);
2470
            }
2471
          if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
2472
            {
2473
              DAC960_Error("Unable to Enable Memory Mailbox Interface "
2474
                           "for Controller at\n", Controller);
2475
              goto Failure;
2476
            }
2477
          DAC960_PG_EnableInterrupts(Controller->BaseAddress);
2478
          if (Controller->V1.DualModeMemoryMailboxInterface)
2479
            Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
2480
          else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
2481
          Controller->ReadControllerConfiguration =
2482
            DAC960_V1_ReadControllerConfiguration;
2483
          Controller->ReadDeviceConfiguration =
2484
            DAC960_V1_ReadDeviceConfiguration;
2485
          Controller->ReportDeviceConfiguration =
2486
            DAC960_V1_ReportDeviceConfiguration;
2487
          Controller->QueueReadWriteCommand =
2488
            DAC960_V1_QueueReadWriteCommand;
2489
          break;
2490
        case DAC960_PD_Controller:
2491
          if (!request_region(Controller->IO_Address, 0x80,
2492
                              Controller->FullModelName)) {
2493
                DAC960_Error("IO port 0x%d busy for Controller at\n",
2494
                             Controller, Controller->IO_Address);
2495
                goto Failure;
2496
          }
2497
          DAC960_PD_DisableInterrupts(BaseAddress);
2498
          DAC960_PD_AcknowledgeStatus(BaseAddress);
2499
          udelay(1000);
2500
          while (DAC960_PD_InitializationInProgressP(BaseAddress))
2501
            {
2502
              if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
2503
                                            &Parameter0, &Parameter1) &&
2504
                  DAC960_ReportErrorStatus(Controller, ErrorStatus,
2505
                                           Parameter0, Parameter1))
2506
                goto Failure1;
2507
              udelay(10);
2508
            }
2509
          DAC960_PD_EnableInterrupts(Controller->BaseAddress);
2510
          Controller->QueueCommand = DAC960_PD_QueueCommand;
2511
          Controller->ReadControllerConfiguration =
2512
            DAC960_V1_ReadControllerConfiguration;
2513
          Controller->ReadDeviceConfiguration =
2514
            DAC960_V1_ReadDeviceConfiguration;
2515
          Controller->ReportDeviceConfiguration =
2516
            DAC960_V1_ReportDeviceConfiguration;
2517
          Controller->QueueReadWriteCommand =
2518
            DAC960_V1_QueueReadWriteCommand;
2519
          break;
2520
        case DAC960_P_Controller:
2521
          if (!request_region(Controller->IO_Address, 0x80,
2522
                              Controller->FullModelName)){
2523
                DAC960_Error("IO port 0x%d busy for Controller at\n",
2524
                             Controller, Controller->IO_Address);
2525
                goto Failure;
2526
          }
2527
          DAC960_PD_DisableInterrupts(BaseAddress);
2528
          DAC960_PD_AcknowledgeStatus(BaseAddress);
2529
          udelay(1000);
2530
          while (DAC960_PD_InitializationInProgressP(BaseAddress))
2531
            {
2532
              if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
2533
                                            &Parameter0, &Parameter1) &&
2534
                  DAC960_ReportErrorStatus(Controller, ErrorStatus,
2535
                                           Parameter0, Parameter1))
2536
                goto Failure1;
2537
              udelay(10);
2538
            }
2539
          DAC960_PD_EnableInterrupts(Controller->BaseAddress);
2540
          Controller->QueueCommand = DAC960_P_QueueCommand;
2541
          Controller->ReadControllerConfiguration =
2542
            DAC960_V1_ReadControllerConfiguration;
2543
          Controller->ReadDeviceConfiguration =
2544
            DAC960_V1_ReadDeviceConfiguration;
2545
          Controller->ReportDeviceConfiguration =
2546
            DAC960_V1_ReportDeviceConfiguration;
2547
          Controller->QueueReadWriteCommand =
2548
            DAC960_V1_QueueReadWriteCommand;
2549
          break;
2550
        }
2551
      /*
2552
        Acquire shared access to the IRQ Channel.
2553
      */
2554
      if (IRQ_Channel == 0)
2555
        {
2556
          DAC960_Error("IRQ Channel %d illegal for Controller at\n",
2557
                       Controller, IRQ_Channel);
2558
          goto Failure1;
2559
        }
2560
      strcpy(Controller->FullModelName, "DAC960");
2561
      if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
2562
                      Controller->FullModelName, Controller) < 0)
2563
        {
2564
          DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
2565
                       Controller, IRQ_Channel);
2566
          goto Failure1;
2567
        }
2568
      Controller->IRQ_Channel = IRQ_Channel;
2569
      DAC960_ActiveControllerCount++;
2570
      Controller->InitialCommand.CommandIdentifier = 1;
2571
      Controller->InitialCommand.Controller = Controller;
2572
      Controller->Commands[0] = &Controller->InitialCommand;
2573
      Controller->FreeCommands = &Controller->InitialCommand;
2574
      Controller->ControllerDetectionSuccessful = true;
2575
      continue;
2576
    Failure1:
2577
      if (Controller->IO_Address) release_region(Controller->IO_Address, 0x80);
2578
    Failure:
2579
      if (IO_Address == 0)
2580
        DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
2581
                     "PCI Address 0x%X\n", Controller,
2582
                     Bus, Device, Function, PCI_Address);
2583
      else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
2584
                        "0x%X PCI Address 0x%X\n", Controller,
2585
                        Bus, Device, Function, IO_Address, PCI_Address);
2586
      if (Controller == NULL) break;
2587
      if (Controller->MemoryMappedAddress != NULL)
2588
        iounmap(Controller->MemoryMappedAddress);
2589
      if (Controller->IRQ_Channel > 0)
2590
        free_irq(IRQ_Channel, Controller);
2591
    }
2592
}
2593
 
2594
 
2595
/*
2596
  DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
2597
*/
2598
 
2599
static void DAC960_SortControllers(void)
2600
{
2601
  int ControllerNumber, LastInterchange, Bound, j;
2602
  LastInterchange = DAC960_ControllerCount-1;
2603
  while (LastInterchange > 0)
2604
    {
2605
      Bound = LastInterchange;
2606
      LastInterchange = 0;
2607
      for (j = 0; j < Bound; j++)
2608
        {
2609
          DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
2610
          DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
2611
          if (Controller1->Bus > Controller2->Bus ||
2612
              (Controller1->Bus == Controller2->Bus &&
2613
               (Controller1->Device > Controller2->Device)))
2614
            {
2615
              Controller2->ControllerNumber = j;
2616
              DAC960_Controllers[j] = Controller2;
2617
              Controller1->ControllerNumber = j+1;
2618
              DAC960_Controllers[j+1] = Controller1;
2619
              LastInterchange = j;
2620
            }
2621
        }
2622
    }
2623
  for (ControllerNumber = 0;
2624
       ControllerNumber < DAC960_ControllerCount;
2625
       ControllerNumber++)
2626
    {
2627
      DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
2628
      if (!Controller->ControllerDetectionSuccessful)
2629
        {
2630
          DAC960_Controllers[ControllerNumber] = NULL;
2631
          kfree(Controller);
2632
        }
2633
    }
2634
}
2635
 
2636
 
2637
/*
2638
  DAC960_InitializeController initializes Controller.
2639
*/
2640
 
2641
static void DAC960_InitializeController(DAC960_Controller_T *Controller)
2642
{
2643
  if (DAC960_ReadControllerConfiguration(Controller) &&
2644
      DAC960_ReportControllerConfiguration(Controller) &&
2645
      DAC960_CreateAuxiliaryStructures(Controller) &&
2646
      DAC960_ReadDeviceConfiguration(Controller) &&
2647
      DAC960_ReportDeviceConfiguration(Controller) &&
2648
      DAC960_RegisterBlockDevice(Controller))
2649
    {
2650
      /*
2651
        Initialize the Monitoring Timer.
2652
      */
2653
      init_timer(&Controller->MonitoringTimer);
2654
      Controller->MonitoringTimer.expires =
2655
        jiffies + DAC960_MonitoringTimerInterval;
2656
      Controller->MonitoringTimer.data = (unsigned long) Controller;
2657
      Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
2658
      add_timer(&Controller->MonitoringTimer);
2659
      Controller->ControllerInitialized = true;
2660
    }
2661
  else DAC960_FinalizeController(Controller);
2662
}
2663
 
2664
 
2665
/*
2666
  DAC960_FinalizeController finalizes Controller.
2667
*/
2668
 
2669
static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
2670
{
2671
  if (Controller->ControllerInitialized)
2672
    {
2673
      del_timer(&Controller->MonitoringTimer);
2674
      if (Controller->FirmwareType == DAC960_V1_Controller)
2675
        {
2676
          DAC960_Notice("Flushing Cache...", Controller);
2677
          DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
2678
          DAC960_Notice("done\n", Controller);
2679
          switch (Controller->HardwareType)
2680
            {
2681
            case DAC960_LA_Controller:
2682
              if (Controller->V1.DualModeMemoryMailboxInterface)
2683
                free_pages(Controller->MemoryMailboxPagesAddress,
2684
                           Controller->MemoryMailboxPagesOrder);
2685
              else DAC960_LA_SaveMemoryMailboxInfo(Controller);
2686
              break;
2687
            case DAC960_PG_Controller:
2688
              if (Controller->V1.DualModeMemoryMailboxInterface)
2689
                free_pages(Controller->MemoryMailboxPagesAddress,
2690
                           Controller->MemoryMailboxPagesOrder);
2691
              else DAC960_PG_SaveMemoryMailboxInfo(Controller);
2692
              break;
2693
            case DAC960_PD_Controller:
2694
              release_region(Controller->IO_Address, 0x80);
2695
              break;
2696
            default:
2697
              break;
2698
            }
2699
        }
2700
      else
2701
        {
2702
          DAC960_Notice("Flushing Cache...", Controller);
2703
          DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
2704
                                    DAC960_V2_RAID_Controller);
2705
          DAC960_Notice("done\n", Controller);
2706
          free_pages(Controller->MemoryMailboxPagesAddress,
2707
                     Controller->MemoryMailboxPagesOrder);
2708
        }
2709
    }
2710
  free_irq(Controller->IRQ_Channel, Controller);
2711
  iounmap(Controller->MemoryMappedAddress);
2712
  DAC960_UnregisterBlockDevice(Controller);
2713
  DAC960_DestroyAuxiliaryStructures(Controller);
2714
  DAC960_Controllers[Controller->ControllerNumber] = NULL;
2715
  kfree(Controller);
2716
}
2717
 
2718
 
2719
/*
2720
  DAC960_Initialize initializes the DAC960 Driver.
2721
*/
2722
 
2723
static int DAC960_Initialize(void)
2724
{
2725
  int ControllerNumber;
2726
  DAC960_DetectControllers(DAC960_BA_Controller);
2727
  DAC960_DetectControllers(DAC960_LP_Controller);
2728
  DAC960_DetectControllers(DAC960_LA_Controller);
2729
  DAC960_DetectControllers(DAC960_PG_Controller);
2730
  DAC960_DetectControllers(DAC960_PD_Controller);
2731
  DAC960_DetectControllers(DAC960_P_Controller);
2732
  DAC960_SortControllers();
2733
  if (DAC960_ActiveControllerCount == 0) return -ENODEV;
2734
  for (ControllerNumber = 0;
2735
       ControllerNumber < DAC960_ControllerCount;
2736
       ControllerNumber++)
2737
    {
2738
      DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
2739
      int LogicalDriveNumber;
2740
      if (Controller == NULL) continue;
2741
      DAC960_InitializeController(Controller);
2742
      DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
2743
      for (LogicalDriveNumber = 0;
2744
           LogicalDriveNumber < DAC960_MaxLogicalDrives;
2745
           LogicalDriveNumber++)
2746
        DAC960_RegisterDisk(Controller, LogicalDriveNumber);
2747
    }
2748
  DAC960_CreateProcEntries();
2749
  register_reboot_notifier(&DAC960_NotifierBlock);
2750
  return 0;
2751
}
2752
 
2753
 
2754
/*
2755
  DAC960_Finalize finalizes the DAC960 Driver.
2756
*/
2757
 
2758
static void DAC960_Finalize(void)
2759
{
2760
  int ControllerNumber;
2761
  if (DAC960_ActiveControllerCount == 0) return;
2762
  for (ControllerNumber = 0;
2763
       ControllerNumber < DAC960_ControllerCount;
2764
       ControllerNumber++)
2765
    if (DAC960_Controllers[ControllerNumber] != NULL)
2766
      DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
2767
  DAC960_DestroyProcEntries();
2768
  unregister_reboot_notifier(&DAC960_NotifierBlock);
2769
}
2770
 
2771
 
2772
/*
2773
  DAC960_Notifier is the notifier for the DAC960 Driver.
2774
*/
2775
 
2776
static int DAC960_Notifier(NotifierBlock_T *NotifierBlock,
2777
                           unsigned long Event,
2778
                           void *Buffer)
2779
{
2780
  if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
2781
    return NOTIFY_DONE;
2782
  DAC960_Finalize();
2783
  return NOTIFY_OK;
2784
}
2785
 
2786
 
2787
/*
2788
  DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for
2789
  DAC960 V1 Firmware Controllers.
2790
*/
2791
 
2792
static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
2793
{
2794
  DAC960_Controller_T *Controller = Command->Controller;
2795
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
2796
  DAC960_V1_ClearCommand(Command);
2797
  if (Command->SegmentCount == 1)
2798
    {
2799
      if (Command->CommandType == DAC960_ReadCommand)
2800
        CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
2801
      else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
2802
      CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2803
      CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
2804
      CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
2805
      CommandMailbox->Type5.BusAddress =
2806
        Virtual_to_Bus32(Command->RequestBuffer);
2807
    }
2808
  else
2809
    {
2810
      DAC960_V1_ScatterGatherSegment_T
2811
        *ScatterGatherList = Command->V1.ScatterGatherList;
2812
      BufferHeader_T *BufferHeader = Command->BufferHeader;
2813
      char *LastDataEndPointer = NULL;
2814
      int SegmentNumber = 0;
2815
      if (Command->CommandType == DAC960_ReadCommand)
2816
        CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather;
2817
      else
2818
        CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather;
2819
      CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
2820
      CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
2821
      CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
2822
      CommandMailbox->Type5.BusAddress = Virtual_to_Bus32(ScatterGatherList);
2823
      CommandMailbox->Type5.ScatterGatherCount = Command->SegmentCount;
2824
      while (BufferHeader != NULL)
2825
        {
2826
          if (BufferHeader->b_data == LastDataEndPointer)
2827
            {
2828
              ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
2829
                BufferHeader->b_size;
2830
              LastDataEndPointer += BufferHeader->b_size;
2831
            }
2832
          else
2833
            {
2834
              ScatterGatherList[SegmentNumber].SegmentDataPointer =
2835
                Virtual_to_Bus32(BufferHeader->b_data);
2836
              ScatterGatherList[SegmentNumber].SegmentByteCount =
2837
                BufferHeader->b_size;
2838
              LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
2839
              if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
2840
                panic("DAC960: Scatter/Gather Segment Overflow\n");
2841
            }
2842
          BufferHeader = BufferHeader->b_reqnext;
2843
        }
2844
      if (SegmentNumber != Command->SegmentCount)
2845
        panic("DAC960: SegmentNumber != SegmentCount\n");
2846
    }
2847
  DAC960_QueueCommand(Command);
2848
}
2849
 
2850
 
2851
/*
2852
  DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for
2853
  DAC960 V2 Firmware Controllers.
2854
*/
2855
 
2856
static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
2857
{
2858
  DAC960_Controller_T *Controller = Command->Controller;
2859
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
2860
  DAC960_V2_ClearCommand(Command);
2861
  CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
2862
  CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
2863
    (Command->CommandType == DAC960_ReadCommand);
2864
  CommandMailbox->SCSI_10.DataTransferSize =
2865
    Command->BlockCount << DAC960_BlockSizeBits;
2866
  CommandMailbox->SCSI_10.RequestSenseBusAddress =
2867
    Virtual_to_Bus64(&Command->V2.RequestSense);
2868
  CommandMailbox->SCSI_10.PhysicalDevice =
2869
    Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
2870
  CommandMailbox->SCSI_10.RequestSenseSize =
2871
    sizeof(DAC960_SCSI_RequestSense_T);
2872
  CommandMailbox->SCSI_10.CDBLength = 10;
2873
  CommandMailbox->SCSI_10.SCSI_CDB[0] =
2874
    (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
2875
  CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
2876
  CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
2877
  CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
2878
  CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
2879
  CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
2880
  CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
2881
  if (Command->SegmentCount == 1)
2882
    {
2883
      CommandMailbox->SCSI_10.DataTransferMemoryAddress
2884
                             .ScatterGatherSegments[0]
2885
                             .SegmentDataPointer =
2886
        Virtual_to_Bus64(Command->RequestBuffer);
2887
      CommandMailbox->SCSI_10.DataTransferMemoryAddress
2888
                             .ScatterGatherSegments[0]
2889
                             .SegmentByteCount =
2890
        CommandMailbox->SCSI_10.DataTransferSize;
2891
    }
2892
  else
2893
    {
2894
      DAC960_V2_ScatterGatherSegment_T
2895
        *ScatterGatherList = Command->V2.ScatterGatherList;
2896
      BufferHeader_T *BufferHeader = Command->BufferHeader;
2897
      char *LastDataEndPointer = NULL;
2898
      int SegmentNumber = 0;
2899
      if (Command->SegmentCount > 2)
2900
        {
2901
          CommandMailbox->SCSI_10.CommandControlBits
2902
                         .AdditionalScatterGatherListMemory = true;
2903
          CommandMailbox->SCSI_10.DataTransferMemoryAddress
2904
                         .ExtendedScatterGather.ScatterGatherList0Length =
2905
            Command->SegmentCount;
2906
          CommandMailbox->SCSI_10.DataTransferMemoryAddress
2907
                         .ExtendedScatterGather.ScatterGatherList0Address =
2908
            Virtual_to_Bus64(ScatterGatherList);
2909
        }
2910
      else
2911
        ScatterGatherList =
2912
          CommandMailbox->SCSI_10.DataTransferMemoryAddress
2913
                                 .ScatterGatherSegments;
2914
      while (BufferHeader != NULL)
2915
        {
2916
          if (BufferHeader->b_data == LastDataEndPointer)
2917
            {
2918
              ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
2919
                BufferHeader->b_size;
2920
              LastDataEndPointer += BufferHeader->b_size;
2921
            }
2922
          else
2923
            {
2924
              ScatterGatherList[SegmentNumber].SegmentDataPointer =
2925
                Virtual_to_Bus64(BufferHeader->b_data);
2926
              ScatterGatherList[SegmentNumber].SegmentByteCount =
2927
                BufferHeader->b_size;
2928
              LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
2929
              if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
2930
                panic("DAC960: Scatter/Gather Segment Overflow\n");
2931
            }
2932
          BufferHeader = BufferHeader->b_reqnext;
2933
        }
2934
      if (SegmentNumber != Command->SegmentCount)
2935
        panic("DAC960: SegmentNumber != SegmentCount\n");
2936
    }
2937
  DAC960_QueueCommand(Command);
2938
}
2939
 
2940
 
2941
/*
2942
  DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
2943
  I/O Request Queue and queues it to the Controller.  WaitForCommand is true if
2944
  this function should wait for a Command to become available if necessary.
2945
  This function returns true if an I/O Request was queued and false otherwise.
2946
*/
2947
 
2948
static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
2949
                                     boolean WaitForCommand)
2950
{
2951
  RequestQueue_T *RequestQueue = Controller->RequestQueue;
2952
  ListHead_T *RequestQueueHead;
2953
  IO_Request_T *Request;
2954
  DAC960_Command_T *Command;
2955
  if (RequestQueue == NULL) return false;
2956
  RequestQueueHead = &RequestQueue->queue_head;
2957
  while (true)
2958
    {
2959
      if (list_empty(RequestQueueHead)) return false;
2960
      Request = blkdev_entry_next_request(RequestQueueHead);
2961
      Command = DAC960_AllocateCommand(Controller);
2962
      if (Command != NULL) break;
2963
      if (!WaitForCommand) return false;
2964
      DAC960_WaitForCommand(Controller);
2965
    }
2966
  if (Request->cmd == READ)
2967
    Command->CommandType = DAC960_ReadCommand;
2968
  else Command->CommandType = DAC960_WriteCommand;
2969
  Command->Completion = Request->waiting;
2970
  Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
2971
  Command->BlockNumber =
2972
    Request->sector
2973
    + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
2974
  Command->BlockCount = Request->nr_sectors;
2975
  Command->SegmentCount = Request->nr_segments;
2976
  Command->BufferHeader = Request->bh;
2977
  Command->RequestBuffer = Request->buffer;
2978
  blkdev_dequeue_request(Request);
2979
  blkdev_release_request(Request);
2980
  DAC960_QueueReadWriteCommand(Command);
2981
  return true;
2982
}
2983
 
2984
 
2985
/*
2986
  DAC960_ProcessRequests attempts to remove as many I/O Requests as possible
2987
  from Controller's I/O Request Queue and queue them to the Controller.
2988
*/
2989
 
2990
static inline void DAC960_ProcessRequests(DAC960_Controller_T *Controller)
2991
{
2992
  int Counter = 0;
2993
  while (DAC960_ProcessRequest(Controller, Counter++ == 0)) ;
2994
}
2995
 
2996
 
2997
/*
2998
  DAC960_RequestFunction is the I/O Request Function for DAC960 Controllers.
2999
*/
3000
 
3001
static void DAC960_RequestFunction(RequestQueue_T *RequestQueue)
3002
{
3003
  DAC960_Controller_T *Controller =
3004
    (DAC960_Controller_T *) RequestQueue->queuedata;
3005
  ProcessorFlags_T ProcessorFlags;
3006
  /*
3007
    Acquire exclusive access to Controller.
3008
  */
3009
  DAC960_AcquireControllerLockRF(Controller, &ProcessorFlags);
3010
  /*
3011
    Process I/O Requests for Controller.
3012
  */
3013
  DAC960_ProcessRequests(Controller);
3014
  /*
3015
    Release exclusive access to Controller.
3016
  */
3017
  DAC960_ReleaseControllerLockRF(Controller, &ProcessorFlags);
3018
}
3019
 
3020
 
3021
/*
3022
  DAC960_ProcessCompletedBuffer performs completion processing for an
3023
  individual Buffer.
3024
*/
3025
 
3026
static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
3027
                                                 boolean SuccessfulIO)
3028
{
3029
  blk_finished_io(BufferHeader->b_size >> 9);
3030
  BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
3031
}
3032
 
3033
 
3034
/*
3035
  DAC960_V1_ReadWriteError prints an appropriate error message for Command
3036
  when an error occurs on a Read or Write operation.
3037
*/
3038
 
3039
static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
3040
{
3041
  DAC960_Controller_T *Controller = Command->Controller;
3042
  unsigned char *CommandName = "UNKNOWN";
3043
  switch (Command->CommandType)
3044
    {
3045
    case DAC960_ReadCommand:
3046
    case DAC960_ReadRetryCommand:
3047
      CommandName = "READ";
3048
      break;
3049
    case DAC960_WriteCommand:
3050
    case DAC960_WriteRetryCommand:
3051
      CommandName = "WRITE";
3052
      break;
3053
    case DAC960_MonitoringCommand:
3054
    case DAC960_ImmediateCommand:
3055
    case DAC960_QueuedCommand:
3056
      break;
3057
    }
3058
  switch (Command->V1.CommandStatus)
3059
    {
3060
    case DAC960_V1_IrrecoverableDataError:
3061
      DAC960_Error("Irrecoverable Data Error on %s:\n",
3062
                   Controller, CommandName);
3063
      break;
3064
    case DAC960_V1_LogicalDriveNonexistentOrOffline:
3065
      DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
3066
                   Controller, CommandName);
3067
      break;
3068
    case DAC960_V1_AccessBeyondEndOfLogicalDrive:
3069
      DAC960_Error("Attempt to Access Beyond End of Logical Drive "
3070
                   "on %s:\n", Controller, CommandName);
3071
      break;
3072
    case DAC960_V1_BadDataEncountered:
3073
      DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName);
3074
      break;
3075
    default:
3076
      DAC960_Error("Unexpected Error Status %04X on %s:\n",
3077
                   Controller, Command->V1.CommandStatus, CommandName);
3078
      break;
3079
    }
3080
  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%u\n",
3081
               Controller, Controller->ControllerNumber,
3082
               Command->LogicalDriveNumber, Command->BlockNumber,
3083
               Command->BlockNumber + Command->BlockCount - 1);
3084
  if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
3085
    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
3086
                 Controller, Controller->ControllerNumber,
3087
                 Command->LogicalDriveNumber,
3088
                 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
3089
                 Command->BufferHeader->b_rsector,
3090
                 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
3091
}
3092
 
3093
 
3094
/*
3095
  DAC960_V1_ProcessCompletedCommand performs completion processing for Command
3096
  for DAC960 V1 Firmware Controllers.
3097
*/
3098
 
3099
static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
3100
{
3101
  DAC960_Controller_T *Controller = Command->Controller;
3102
  DAC960_CommandType_T CommandType = Command->CommandType;
3103
  DAC960_V1_CommandOpcode_T CommandOpcode =
3104
    Command->V1.CommandMailbox.Common.CommandOpcode;
3105
  DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
3106
  BufferHeader_T *BufferHeader = Command->BufferHeader;
3107
  if (CommandType == DAC960_ReadCommand ||
3108
      CommandType == DAC960_WriteCommand)
3109
    {
3110
      if (CommandStatus == DAC960_V1_NormalCompletion)
3111
        {
3112
          /*
3113
            Perform completion processing for all buffers in this I/O Request.
3114
          */
3115
          while (BufferHeader != NULL)
3116
            {
3117
              BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3118
              BufferHeader->b_reqnext = NULL;
3119
              DAC960_ProcessCompletedBuffer(BufferHeader, true);
3120
              BufferHeader = NextBufferHeader;
3121
            }
3122
          if (Command->Completion != NULL)
3123
            {
3124
              complete(Command->Completion);
3125
              Command->Completion = NULL;
3126
            }
3127
          add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
3128
        }
3129
      else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
3130
                CommandStatus == DAC960_V1_BadDataEncountered) &&
3131
               BufferHeader != NULL &&
3132
               BufferHeader->b_reqnext != NULL)
3133
        {
3134
          DAC960_V1_CommandMailbox_T *CommandMailbox =
3135
            &Command->V1.CommandMailbox;
3136
          if (CommandType == DAC960_ReadCommand)
3137
            {
3138
              Command->CommandType = DAC960_ReadRetryCommand;
3139
              CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
3140
            }
3141
          else
3142
            {
3143
              Command->CommandType = DAC960_WriteRetryCommand;
3144
              CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
3145
            }
3146
          Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
3147
          CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
3148
          CommandMailbox->Type5.BusAddress =
3149
            Virtual_to_Bus32(BufferHeader->b_data);
3150
          DAC960_QueueCommand(Command);
3151
          return;
3152
        }
3153
      else
3154
        {
3155
          if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
3156
            DAC960_V1_ReadWriteError(Command);
3157
          /*
3158
            Perform completion processing for all buffers in this I/O Request.
3159
          */
3160
          while (BufferHeader != NULL)
3161
            {
3162
              BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3163
              BufferHeader->b_reqnext = NULL;
3164
              DAC960_ProcessCompletedBuffer(BufferHeader, false);
3165
              BufferHeader = NextBufferHeader;
3166
            }
3167
          if (Command->Completion != NULL)
3168
            {
3169
              complete(Command->Completion);
3170
              Command->Completion = NULL;
3171
            }
3172
        }
3173
    }
3174
  else if (CommandType == DAC960_ReadRetryCommand ||
3175
           CommandType == DAC960_WriteRetryCommand)
3176
    {
3177
      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
3178
      BufferHeader->b_reqnext = NULL;
3179
      /*
3180
        Perform completion processing for this single buffer.
3181
      */
3182
      if (CommandStatus == DAC960_V1_NormalCompletion)
3183
        DAC960_ProcessCompletedBuffer(BufferHeader, true);
3184
      else
3185
        {
3186
          if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
3187
            DAC960_V1_ReadWriteError(Command);
3188
          DAC960_ProcessCompletedBuffer(BufferHeader, false);
3189
        }
3190
      if (NextBufferHeader != NULL)
3191
        {
3192
          DAC960_V1_CommandMailbox_T *CommandMailbox =
3193
            &Command->V1.CommandMailbox;
3194
          Command->BlockNumber +=
3195
            BufferHeader->b_size >> DAC960_BlockSizeBits;
3196
          Command->BlockCount =
3197
            NextBufferHeader->b_size >> DAC960_BlockSizeBits;
3198
          Command->BufferHeader = NextBufferHeader;
3199
          CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
3200
          CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
3201
          CommandMailbox->Type5.BusAddress =
3202
            Virtual_to_Bus32(NextBufferHeader->b_data);
3203
          DAC960_QueueCommand(Command);
3204
          return;
3205
        }
3206
    }
3207
  else if (CommandType == DAC960_MonitoringCommand ||
3208
           CommandOpcode == DAC960_V1_Enquiry ||
3209
           CommandOpcode == DAC960_V1_GetRebuildProgress)
3210
    {
3211
      if (CommandType != DAC960_MonitoringCommand)
3212
        {
3213
          if (CommandOpcode == DAC960_V1_Enquiry)
3214
            memcpy(&Controller->V1.NewEnquiry,
3215
                   Bus32_to_Virtual(Command->V1.CommandMailbox
3216
                                               .Type3.BusAddress),
3217
                   sizeof(DAC960_V1_Enquiry_T));
3218
          else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
3219
            memcpy(&Controller->V1.RebuildProgress,
3220
                   Bus32_to_Virtual(Command->V1.CommandMailbox
3221
                                               .Type3.BusAddress),
3222
                   sizeof(DAC960_V1_RebuildProgress_T));
3223
        }
3224
      if (CommandOpcode == DAC960_V1_Enquiry &&
3225
          Controller->ControllerInitialized)
3226
        {
3227
          DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
3228
          DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
3229
          unsigned int OldCriticalLogicalDriveCount =
3230
            OldEnquiry->CriticalLogicalDriveCount;
3231
          unsigned int NewCriticalLogicalDriveCount =
3232
            NewEnquiry->CriticalLogicalDriveCount;
3233
          if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount)
3234
            {
3235
              int LogicalDriveNumber = Controller->LogicalDriveCount - 1;
3236
              while (++LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives)
3237
                DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3238
                                "Now Exists\n", Controller,
3239
                                LogicalDriveNumber,
3240
                                Controller->ControllerNumber,
3241
                                LogicalDriveNumber);
3242
              Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
3243
              DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
3244
            }
3245
          if (NewEnquiry->NumberOfLogicalDrives < Controller->LogicalDriveCount)
3246
            {
3247
              int LogicalDriveNumber = NewEnquiry->NumberOfLogicalDrives - 1;
3248
              while (++LogicalDriveNumber < Controller->LogicalDriveCount)
3249
                DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3250
                                "No Longer Exists\n", Controller,
3251
                                LogicalDriveNumber,
3252
                                Controller->ControllerNumber,
3253
                                LogicalDriveNumber);
3254
              Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
3255
              DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
3256
            }
3257
          if (NewEnquiry->StatusFlags.DeferredWriteError !=
3258
              OldEnquiry->StatusFlags.DeferredWriteError)
3259
            DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
3260
                            (NewEnquiry->StatusFlags.DeferredWriteError
3261
                             ? "TRUE" : "FALSE"));
3262
          if ((NewCriticalLogicalDriveCount > 0 ||
3263
               NewCriticalLogicalDriveCount != OldCriticalLogicalDriveCount) ||
3264
              (NewEnquiry->OfflineLogicalDriveCount > 0 ||
3265
               NewEnquiry->OfflineLogicalDriveCount !=
3266
               OldEnquiry->OfflineLogicalDriveCount) ||
3267
              (NewEnquiry->DeadDriveCount > 0 ||
3268
               NewEnquiry->DeadDriveCount !=
3269
               OldEnquiry->DeadDriveCount) ||
3270
              (NewEnquiry->EventLogSequenceNumber !=
3271
               OldEnquiry->EventLogSequenceNumber) ||
3272
              Controller->MonitoringTimerCount == 0 ||
3273
              (jiffies - Controller->SecondaryMonitoringTime
3274
               >= DAC960_SecondaryMonitoringInterval))
3275
            {
3276
              Controller->V1.NeedLogicalDriveInformation = true;
3277
              Controller->V1.NewEventLogSequenceNumber =
3278
                NewEnquiry->EventLogSequenceNumber;
3279
              Controller->V1.NeedErrorTableInformation = true;
3280
              Controller->V1.NeedDeviceStateInformation = true;
3281
              Controller->V1.StartDeviceStateScan = true;
3282
              Controller->V1.NeedBackgroundInitializationStatus =
3283
                Controller->V1.BackgroundInitializationStatusSupported;
3284
              Controller->SecondaryMonitoringTime = jiffies;
3285
            }
3286
          if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
3287
              NewEnquiry->RebuildFlag
3288
              == DAC960_V1_BackgroundRebuildInProgress ||
3289
              OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
3290
              OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress)
3291
            {
3292
              Controller->V1.NeedRebuildProgress = true;
3293
              Controller->V1.RebuildProgressFirst =
3294
                (NewEnquiry->CriticalLogicalDriveCount <
3295
                 OldEnquiry->CriticalLogicalDriveCount);
3296
            }
3297
          if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress)
3298
            switch (NewEnquiry->RebuildFlag)
3299
              {
3300
              case DAC960_V1_NoStandbyRebuildOrCheckInProgress:
3301
                DAC960_Progress("Consistency Check Completed Successfully\n",
3302
                                Controller);
3303
                break;
3304
              case DAC960_V1_StandbyRebuildInProgress:
3305
              case DAC960_V1_BackgroundRebuildInProgress:
3306
                break;
3307
              case DAC960_V1_BackgroundCheckInProgress:
3308
                Controller->V1.NeedConsistencyCheckProgress = true;
3309
                break;
3310
              case DAC960_V1_StandbyRebuildCompletedWithError:
3311
                DAC960_Progress("Consistency Check Completed with Error\n",
3312
                                Controller);
3313
                break;
3314
              case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed:
3315
                DAC960_Progress("Consistency Check Failed - "
3316
                                "Physical Device Failed\n", Controller);
3317
                break;
3318
              case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
3319
                DAC960_Progress("Consistency Check Failed - "
3320
                                "Logical Drive Failed\n", Controller);
3321
                break;
3322
              case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses:
3323
                DAC960_Progress("Consistency Check Failed - Other Causes\n",
3324
                                Controller);
3325
                break;
3326
              case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated:
3327
                DAC960_Progress("Consistency Check Successfully Terminated\n",
3328
                                Controller);
3329
                break;
3330
              }
3331
          else if (NewEnquiry->RebuildFlag
3332
                   == DAC960_V1_BackgroundCheckInProgress)
3333
            Controller->V1.NeedConsistencyCheckProgress = true;
3334
          Controller->MonitoringAlertMode =
3335
            (NewEnquiry->CriticalLogicalDriveCount > 0 ||
3336
             NewEnquiry->OfflineLogicalDriveCount > 0 ||
3337
             NewEnquiry->DeadDriveCount > 0);
3338
          if (CommandType != DAC960_MonitoringCommand &&
3339
              Controller->V1.RebuildFlagPending)
3340
            {
3341
              DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
3342
                Bus32_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
3343
              Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
3344
              Controller->V1.RebuildFlagPending = false;
3345
            }
3346
          else if (CommandType == DAC960_MonitoringCommand &&
3347
                   NewEnquiry->RebuildFlag >
3348
                   DAC960_V1_BackgroundCheckInProgress)
3349
            {
3350
              Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
3351
              Controller->V1.RebuildFlagPending = true;
3352
            }
3353
          memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry,
3354
                 sizeof(DAC960_V1_Enquiry_T));
3355
        }
3356
      else if (CommandOpcode == DAC960_V1_PerformEventLogOperation)
3357
        {
3358
          static char
3359
            *DAC960_EventMessages[] =
3360
               { "killed because write recovery failed",
3361
                 "killed because of SCSI bus reset failure",
3362
                 "killed because of double check condition",
3363
                 "killed because it was removed",
3364
                 "killed because of gross error on SCSI chip",
3365
                 "killed because of bad tag returned from drive",
3366
                 "killed because of timeout on SCSI command",
3367
                 "killed because of reset SCSI command issued from system",
3368
                 "killed because busy or parity error count exceeded limit",
3369
                 "killed because of 'kill drive' command from system",
3370
                 "killed because of selection timeout",
3371
                 "killed due to SCSI phase sequence error",
3372
                 "killed due to unknown status" };
3373
          DAC960_V1_EventLogEntry_T *EventLogEntry =
3374
            &Controller->V1.EventLogEntry;
3375
          if (EventLogEntry->SequenceNumber ==
3376
              Controller->V1.OldEventLogSequenceNumber)
3377
            {
3378
              unsigned char SenseKey = EventLogEntry->SenseKey;
3379
              unsigned char AdditionalSenseCode =
3380
                EventLogEntry->AdditionalSenseCode;
3381
              unsigned char AdditionalSenseCodeQualifier =
3382
                EventLogEntry->AdditionalSenseCodeQualifier;
3383
              if (SenseKey == DAC960_SenseKey_VendorSpecific &&
3384
                  AdditionalSenseCode == 0x80 &&
3385
                  AdditionalSenseCodeQualifier <
3386
                  sizeof(DAC960_EventMessages) / sizeof(char *))
3387
                DAC960_Critical("Physical Device %d:%d %s\n", Controller,
3388
                                EventLogEntry->Channel,
3389
                                EventLogEntry->TargetID,
3390
                                DAC960_EventMessages[
3391
                                  AdditionalSenseCodeQualifier]);
3392
              else if (SenseKey == DAC960_SenseKey_UnitAttention &&
3393
                       AdditionalSenseCode == 0x29)
3394
                {
3395
                  if (Controller->MonitoringTimerCount > 0)
3396
                    Controller->V1.DeviceResetCount[EventLogEntry->Channel]
3397
                                                   [EventLogEntry->TargetID]++;
3398
                }
3399
              else if (!(SenseKey == DAC960_SenseKey_NoSense ||
3400
                         (SenseKey == DAC960_SenseKey_NotReady &&
3401
                          AdditionalSenseCode == 0x04 &&
3402
                          (AdditionalSenseCodeQualifier == 0x01 ||
3403
                           AdditionalSenseCodeQualifier == 0x02))))
3404
                {
3405
                  DAC960_Critical("Physical Device %d:%d Error Log: "
3406
                                  "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
3407
                                  Controller,
3408
                                  EventLogEntry->Channel,
3409
                                  EventLogEntry->TargetID,
3410
                                  SenseKey,
3411
                                  AdditionalSenseCode,
3412
                                  AdditionalSenseCodeQualifier);
3413
                  DAC960_Critical("Physical Device %d:%d Error Log: "
3414
                                  "Information = %02X%02X%02X%02X "
3415
                                  "%02X%02X%02X%02X\n",
3416
                                  Controller,
3417
                                  EventLogEntry->Channel,
3418
                                  EventLogEntry->TargetID,
3419
                                  EventLogEntry->Information[0],
3420
                                  EventLogEntry->Information[1],
3421
                                  EventLogEntry->Information[2],
3422
                                  EventLogEntry->Information[3],
3423
                                  EventLogEntry->CommandSpecificInformation[0],
3424
                                  EventLogEntry->CommandSpecificInformation[1],
3425
                                  EventLogEntry->CommandSpecificInformation[2],
3426
                                  EventLogEntry->CommandSpecificInformation[3]);
3427
                }
3428
            }
3429
          Controller->V1.OldEventLogSequenceNumber++;
3430
        }
3431
      else if (CommandOpcode == DAC960_V1_GetErrorTable)
3432
        {
3433
          DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
3434
          DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
3435
          int Channel, TargetID;
3436
          for (Channel = 0; Channel < Controller->Channels; Channel++)
3437
            for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
3438
              {
3439
                DAC960_V1_ErrorTableEntry_T *NewErrorEntry =
3440
                  &NewErrorTable->ErrorTableEntries[Channel][TargetID];
3441
                DAC960_V1_ErrorTableEntry_T *OldErrorEntry =
3442
                  &OldErrorTable->ErrorTableEntries[Channel][TargetID];
3443
                if ((NewErrorEntry->ParityErrorCount !=
3444
                     OldErrorEntry->ParityErrorCount) ||
3445
                    (NewErrorEntry->SoftErrorCount !=
3446
                     OldErrorEntry->SoftErrorCount) ||
3447
                    (NewErrorEntry->HardErrorCount !=
3448
                     OldErrorEntry->HardErrorCount) ||
3449
                    (NewErrorEntry->MiscErrorCount !=
3450
                     OldErrorEntry->MiscErrorCount))
3451
                  DAC960_Critical("Physical Device %d:%d Errors: "
3452
                                  "Parity = %d, Soft = %d, "
3453
                                  "Hard = %d, Misc = %d\n",
3454
                                  Controller, Channel, TargetID,
3455
                                  NewErrorEntry->ParityErrorCount,
3456
                                  NewErrorEntry->SoftErrorCount,
3457
                                  NewErrorEntry->HardErrorCount,
3458
                                  NewErrorEntry->MiscErrorCount);
3459
              }
3460
          memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
3461
                 sizeof(DAC960_V1_ErrorTable_T));
3462
        }
3463
      else if (CommandOpcode == DAC960_V1_GetDeviceState)
3464
        {
3465
          DAC960_V1_DeviceState_T *OldDeviceState =
3466
            &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
3467
                                       [Controller->V1.DeviceStateTargetID];
3468
          DAC960_V1_DeviceState_T *NewDeviceState =
3469
            &Controller->V1.NewDeviceState;
3470
          if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
3471
            DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
3472
                            Controller->V1.DeviceStateChannel,
3473
                            Controller->V1.DeviceStateTargetID,
3474
                            (NewDeviceState->DeviceState
3475
                             == DAC960_V1_Device_Dead
3476
                             ? "DEAD"
3477
                             : NewDeviceState->DeviceState
3478
                               == DAC960_V1_Device_WriteOnly
3479
                               ? "WRITE-ONLY"
3480
                               : NewDeviceState->DeviceState
3481
                                 == DAC960_V1_Device_Online
3482
                                 ? "ONLINE" : "STANDBY"));
3483
          if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead &&
3484
              NewDeviceState->DeviceState != DAC960_V1_Device_Dead)
3485
            {
3486
              Controller->V1.NeedDeviceInquiryInformation = true;
3487
              Controller->V1.NeedDeviceSerialNumberInformation = true;
3488
              Controller->V1.DeviceResetCount
3489
                             [Controller->V1.DeviceStateChannel]
3490
                             [Controller->V1.DeviceStateTargetID] = 0;
3491
            }
3492
          memcpy(OldDeviceState, NewDeviceState,
3493
                 sizeof(DAC960_V1_DeviceState_T));
3494
        }
3495
      else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation)
3496
        {
3497
          int LogicalDriveNumber;
3498
          for (LogicalDriveNumber = 0;
3499
               LogicalDriveNumber < Controller->LogicalDriveCount;
3500
               LogicalDriveNumber++)
3501
            {
3502
              DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
3503
                &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
3504
              DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
3505
                &Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
3506
              if (NewLogicalDriveInformation->LogicalDriveState !=
3507
                  OldLogicalDriveInformation->LogicalDriveState)
3508
                DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3509
                                "is now %s\n", Controller,
3510
                                LogicalDriveNumber,
3511
                                Controller->ControllerNumber,
3512
                                LogicalDriveNumber,
3513
                                (NewLogicalDriveInformation->LogicalDriveState
3514
                                 == DAC960_V1_LogicalDrive_Online
3515
                                 ? "ONLINE"
3516
                                 : NewLogicalDriveInformation->LogicalDriveState
3517
                                   == DAC960_V1_LogicalDrive_Critical
3518
                                   ? "CRITICAL" : "OFFLINE"));
3519
              if (NewLogicalDriveInformation->WriteBack !=
3520
                  OldLogicalDriveInformation->WriteBack)
3521
                DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
3522
                                "is now %s\n", Controller,
3523
                                LogicalDriveNumber,
3524
                                Controller->ControllerNumber,
3525
                                LogicalDriveNumber,
3526
                                (NewLogicalDriveInformation->WriteBack
3527
                                 ? "WRITE BACK" : "WRITE THRU"));
3528
            }
3529
          memcpy(&Controller->V1.LogicalDriveInformation,
3530
                 &Controller->V1.NewLogicalDriveInformation,
3531
                 sizeof(DAC960_V1_LogicalDriveInformationArray_T));
3532
        }
3533
      else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
3534
        {
3535
          unsigned int LogicalDriveNumber =
3536
            Controller->V1.RebuildProgress.LogicalDriveNumber;
3537
          unsigned int LogicalDriveSize =
3538
            Controller->V1.RebuildProgress.LogicalDriveSize;
3539
          unsigned int BlocksCompleted =
3540
            LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
3541
          if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
3542
              Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
3543
            CommandStatus = DAC960_V1_RebuildSuccessful;
3544
          switch (CommandStatus)
3545
            {
3546
            case DAC960_V1_NormalCompletion:
3547
              Controller->EphemeralProgressMessage = true;
3548
              DAC960_Progress("Rebuild in Progress: "
3549
                              "Logical Drive %d (/dev/rd/c%dd%d) "
3550
                              "%d%% completed\n",
3551
                              Controller, LogicalDriveNumber,
3552
                              Controller->ControllerNumber,
3553
                              LogicalDriveNumber,
3554
                              (100 * (BlocksCompleted >> 7))
3555
                              / (LogicalDriveSize >> 7));
3556
              Controller->EphemeralProgressMessage = false;
3557
              break;
3558
            case DAC960_V1_RebuildFailed_LogicalDriveFailure:
3559
              DAC960_Progress("Rebuild Failed due to "
3560
                              "Logical Drive Failure\n", Controller);
3561
              break;
3562
            case DAC960_V1_RebuildFailed_BadBlocksOnOther:
3563
              DAC960_Progress("Rebuild Failed due to "
3564
                              "Bad Blocks on Other Drives\n", Controller);
3565
              break;
3566
            case DAC960_V1_RebuildFailed_NewDriveFailed:
3567
              DAC960_Progress("Rebuild Failed due to "
3568
                              "Failure of Drive Being Rebuilt\n", Controller);
3569
              break;
3570
            case DAC960_V1_NoRebuildOrCheckInProgress:
3571
              break;
3572
            case DAC960_V1_RebuildSuccessful:
3573
              DAC960_Progress("Rebuild Completed Successfully\n", Controller);
3574
              break;
3575
            case DAC960_V1_RebuildSuccessfullyTerminated:
3576
              DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
3577
              break;
3578
            }
3579
          Controller->V1.LastRebuildStatus = CommandStatus;
3580
          if (CommandType != DAC960_MonitoringCommand &&
3581
              Controller->V1.RebuildStatusPending)
3582
            {
3583
              Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus;
3584
              Controller->V1.RebuildStatusPending = false;
3585
            }
3586
          else if (CommandType == DAC960_MonitoringCommand &&
3587
                   CommandStatus != DAC960_V1_NormalCompletion &&
3588
                   CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress)
3589
            {
3590
              Controller->V1.PendingRebuildStatus = CommandStatus;
3591
              Controller->V1.RebuildStatusPending = true;
3592
            }
3593
        }
3594
      else if (CommandOpcode == DAC960_V1_RebuildStat)
3595
        {
3596
          unsigned int LogicalDriveNumber =
3597
            Controller->V1.RebuildProgress.LogicalDriveNumber;
3598
          unsigned int LogicalDriveSize =
3599
            Controller->V1.RebuildProgress.LogicalDriveSize;
3600
          unsigned int BlocksCompleted =
3601
            LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
3602
          if (CommandStatus == DAC960_V1_NormalCompletion)
3603
            {
3604
              Controller->EphemeralProgressMessage = true;
3605
              DAC960_Progress("Consistency Check in Progress: "
3606
                              "Logical Drive %d (/dev/rd/c%dd%d) "
3607
                              "%d%% completed\n",
3608
                              Controller, LogicalDriveNumber,
3609
                              Controller->ControllerNumber,
3610
                              LogicalDriveNumber,
3611
                              (100 * (BlocksCompleted >> 7))
3612
                              / (LogicalDriveSize >> 7));
3613
              Controller->EphemeralProgressMessage = false;
3614
            }
3615
        }
3616
      else if (CommandOpcode == DAC960_V1_BackgroundInitializationControl)
3617
        {
3618
          unsigned int LogicalDriveNumber =
3619
            Controller->V1.BackgroundInitializationStatus.LogicalDriveNumber;
3620
          unsigned int LogicalDriveSize =
3621
            Controller->V1.BackgroundInitializationStatus.LogicalDriveSize;
3622
          unsigned int BlocksCompleted =
3623
            Controller->V1.BackgroundInitializationStatus.BlocksCompleted;
3624
          switch (CommandStatus)
3625
            {
3626
            case DAC960_V1_NormalCompletion:
3627
              switch (Controller->V1.BackgroundInitializationStatus.Status)
3628
                {
3629
                case DAC960_V1_BackgroundInitializationInvalid:
3630
                  break;
3631
                case DAC960_V1_BackgroundInitializationStarted:
3632
                  DAC960_Progress("Background Initialization Started\n",
3633
                                  Controller);
3634
                  break;
3635
                case DAC960_V1_BackgroundInitializationInProgress:
3636
                  if (BlocksCompleted ==
3637
                      Controller->V1.LastBackgroundInitializationStatus
3638
                                    .BlocksCompleted &&
3639
                      LogicalDriveNumber ==
3640
                      Controller->V1.LastBackgroundInitializationStatus
3641
                                    .LogicalDriveNumber)
3642
                    break;
3643
                  Controller->EphemeralProgressMessage = true;
3644
                  DAC960_Progress("Background Initialization in Progress: "
3645
                                  "Logical Drive %d (/dev/rd/c%dd%d) "
3646
                                  "%d%% completed\n",
3647
                                  Controller, LogicalDriveNumber,
3648
                                  Controller->ControllerNumber,
3649
                                  LogicalDriveNumber,
3650
                                  (100 * (BlocksCompleted >> 7))
3651
                                  / (LogicalDriveSize >> 7));
3652
                  Controller->EphemeralProgressMessage = false;
3653
                  break;
3654
                case DAC960_V1_BackgroundInitializationSuspended:
3655
                  DAC960_Progress("Background Initialization Suspended\n",
3656
                                  Controller);
3657
                  break;
3658
                case DAC960_V1_BackgroundInitializationCancelled:
3659
                  DAC960_Progress("Background Initialization Cancelled\n",
3660
                                  Controller);
3661
                  break;
3662
                }
3663
              memcpy(&Controller->V1.LastBackgroundInitializationStatus,
3664
                     &Controller->V1.BackgroundInitializationStatus,
3665
                     sizeof(DAC960_V1_BackgroundInitializationStatus_T));
3666
              break;
3667
            case DAC960_V1_BackgroundInitSuccessful:
3668
              if (Controller->V1.BackgroundInitializationStatus.Status ==
3669
                  DAC960_V1_BackgroundInitializationInProgress)
3670
                DAC960_Progress("Background Initialization "
3671
                                "Completed Successfully\n", Controller);
3672
              Controller->V1.BackgroundInitializationStatus.Status =
3673
                DAC960_V1_BackgroundInitializationInvalid;
3674
              break;
3675
            case DAC960_V1_BackgroundInitAborted:
3676
              if (Controller->V1.BackgroundInitializationStatus.Status ==
3677
                  DAC960_V1_BackgroundInitializationInProgress)
3678
                DAC960_Progress("Background Initialization Aborted\n",
3679
                                Controller);
3680
              Controller->V1.BackgroundInitializationStatus.Status =
3681
                DAC960_V1_BackgroundInitializationInvalid;
3682
              break;
3683
            case DAC960_V1_NoBackgroundInitInProgress:
3684
              break;
3685
            }
3686
        }
3687
    }
3688
  if (CommandType == DAC960_MonitoringCommand)
3689
    {
3690
      if (Controller->V1.NewEventLogSequenceNumber
3691
          - Controller->V1.OldEventLogSequenceNumber > 0)
3692
        {
3693
          Command->V1.CommandMailbox.Type3E.CommandOpcode =
3694
            DAC960_V1_PerformEventLogOperation;
3695
          Command->V1.CommandMailbox.Type3E.OperationType =
3696
            DAC960_V1_GetEventLogEntry;
3697
          Command->V1.CommandMailbox.Type3E.OperationQualifier = 1;
3698
          Command->V1.CommandMailbox.Type3E.SequenceNumber =
3699
            Controller->V1.OldEventLogSequenceNumber;
3700
          Command->V1.CommandMailbox.Type3E.BusAddress =
3701
            Virtual_to_Bus32(&Controller->V1.EventLogEntry);
3702
          DAC960_QueueCommand(Command);
3703
          return;
3704
        }
3705
      if (Controller->V1.NeedErrorTableInformation)
3706
        {
3707
          Controller->V1.NeedErrorTableInformation = false;
3708
          Command->V1.CommandMailbox.Type3.CommandOpcode =
3709
            DAC960_V1_GetErrorTable;
3710
          Command->V1.CommandMailbox.Type3.BusAddress =
3711
            Virtual_to_Bus32(&Controller->V1.NewErrorTable);
3712
          DAC960_QueueCommand(Command);
3713
          return;
3714
        }
3715
      if (Controller->V1.NeedRebuildProgress &&
3716
          Controller->V1.RebuildProgressFirst)
3717
        {
3718
          Controller->V1.NeedRebuildProgress = false;
3719
          Command->V1.CommandMailbox.Type3.CommandOpcode =
3720
            DAC960_V1_GetRebuildProgress;
3721
          Command->V1.CommandMailbox.Type3.BusAddress =
3722
            Virtual_to_Bus32(&Controller->V1.RebuildProgress);
3723
          DAC960_QueueCommand(Command);
3724
          return;
3725
        }
3726
      if (Controller->V1.NeedDeviceStateInformation)
3727
        {
3728
          if (Controller->V1.NeedDeviceInquiryInformation)
3729
            {
3730
              DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
3731
              DAC960_SCSI_Inquiry_T *InquiryStandardData =
3732
                &Controller->V1.InquiryStandardData
3733
                                [Controller->V1.DeviceStateChannel]
3734
                                [Controller->V1.DeviceStateTargetID];
3735
              InquiryStandardData->PeripheralDeviceType = 0x1F;
3736
              Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
3737
              Command->V1.CommandMailbox.Type3.BusAddress =
3738
                Virtual_to_Bus32(DCDB);
3739
              DCDB->Channel = Controller->V1.DeviceStateChannel;
3740
              DCDB->TargetID = Controller->V1.DeviceStateTargetID;
3741
              DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
3742
              DCDB->EarlyStatus = false;
3743
              DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
3744
              DCDB->NoAutomaticRequestSense = false;
3745
              DCDB->DisconnectPermitted = true;
3746
              DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
3747
              DCDB->BusAddress = Virtual_to_Bus32(InquiryStandardData);
3748
              DCDB->CDBLength = 6;
3749
              DCDB->TransferLengthHigh4 = 0;
3750
              DCDB->SenseLength = sizeof(DCDB->SenseData);
3751
              DCDB->CDB[0] = 0x12; /* INQUIRY */
3752
              DCDB->CDB[1] = 0; /* EVPD = 0 */
3753
              DCDB->CDB[2] = 0; /* Page Code */
3754
              DCDB->CDB[3] = 0; /* Reserved */
3755
              DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
3756
              DCDB->CDB[5] = 0; /* Control */
3757
              DAC960_QueueCommand(Command);
3758
              Controller->V1.NeedDeviceInquiryInformation = false;
3759
              return;
3760
            }
3761
          if (Controller->V1.NeedDeviceSerialNumberInformation)
3762
            {
3763
              DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
3764
              DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
3765
                &Controller->V1.InquiryUnitSerialNumber
3766
                                [Controller->V1.DeviceStateChannel]
3767
                                [Controller->V1.DeviceStateTargetID];
3768
              InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
3769
              Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
3770
              Command->V1.CommandMailbox.Type3.BusAddress =
3771
                Virtual_to_Bus32(DCDB);
3772
              DCDB->Channel = Controller->V1.DeviceStateChannel;
3773
              DCDB->TargetID = Controller->V1.DeviceStateTargetID;
3774
              DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
3775
              DCDB->EarlyStatus = false;
3776
              DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
3777
              DCDB->NoAutomaticRequestSense = false;
3778
              DCDB->DisconnectPermitted = true;
3779
              DCDB->TransferLength =
3780
                sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
3781
              DCDB->BusAddress = Virtual_to_Bus32(InquiryUnitSerialNumber);
3782
              DCDB->CDBLength = 6;
3783
              DCDB->TransferLengthHigh4 = 0;
3784
              DCDB->SenseLength = sizeof(DCDB->SenseData);
3785
              DCDB->CDB[0] = 0x12; /* INQUIRY */
3786
              DCDB->CDB[1] = 1; /* EVPD = 1 */
3787
              DCDB->CDB[2] = 0x80; /* Page Code */
3788
              DCDB->CDB[3] = 0; /* Reserved */
3789
              DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
3790
              DCDB->CDB[5] = 0; /* Control */
3791
              DAC960_QueueCommand(Command);
3792
              Controller->V1.NeedDeviceSerialNumberInformation = false;
3793
              return;
3794
            }
3795
          if (Controller->V1.StartDeviceStateScan)
3796
            {
3797
              Controller->V1.DeviceStateChannel = 0;
3798
              Controller->V1.DeviceStateTargetID = 0;
3799
              Controller->V1.StartDeviceStateScan = false;
3800
            }
3801
          else if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
3802
            {
3803
              Controller->V1.DeviceStateChannel++;
3804
              Controller->V1.DeviceStateTargetID = 0;
3805
            }
3806
          if (Controller->V1.DeviceStateChannel < Controller->Channels)
3807
            {
3808
              Controller->V1.NewDeviceState.DeviceState =
3809
                DAC960_V1_Device_Dead;
3810
              Command->V1.CommandMailbox.Type3D.CommandOpcode =
3811
                DAC960_V1_GetDeviceState;
3812
              Command->V1.CommandMailbox.Type3D.Channel =
3813
                Controller->V1.DeviceStateChannel;
3814
              Command->V1.CommandMailbox.Type3D.TargetID =
3815
                Controller->V1.DeviceStateTargetID;
3816
              Command->V1.CommandMailbox.Type3D.BusAddress =
3817
                Virtual_to_Bus32(&Controller->V1.NewDeviceState);
3818
              DAC960_QueueCommand(Command);
3819
              return;
3820
            }
3821
          Controller->V1.NeedDeviceStateInformation = false;
3822
        }
3823
      if (Controller->V1.NeedLogicalDriveInformation)
3824
        {
3825
          Controller->V1.NeedLogicalDriveInformation = false;
3826
          Command->V1.CommandMailbox.Type3.CommandOpcode =
3827
            DAC960_V1_GetLogicalDriveInformation;
3828
          Command->V1.CommandMailbox.Type3.BusAddress =
3829
            Virtual_to_Bus32(&Controller->V1.NewLogicalDriveInformation);
3830
          DAC960_QueueCommand(Command);
3831
          return;
3832
        }
3833
      if (Controller->V1.NeedRebuildProgress)
3834
        {
3835
          Controller->V1.NeedRebuildProgress = false;
3836
          Command->V1.CommandMailbox.Type3.CommandOpcode =
3837
            DAC960_V1_GetRebuildProgress;
3838
          Command->V1.CommandMailbox.Type3.BusAddress =
3839
            Virtual_to_Bus32(&Controller->V1.RebuildProgress);
3840
          DAC960_QueueCommand(Command);
3841
          return;
3842
        }
3843
      if (Controller->V1.NeedConsistencyCheckProgress)
3844
        {
3845
          Controller->V1.NeedConsistencyCheckProgress = false;
3846
          Command->V1.CommandMailbox.Type3.CommandOpcode =
3847
            DAC960_V1_RebuildStat;
3848
          Command->V1.CommandMailbox.Type3.BusAddress =
3849
            Virtual_to_Bus32(&Controller->V1.RebuildProgress);
3850
          DAC960_QueueCommand(Command);
3851
          return;
3852
        }
3853
      if (Controller->V1.NeedBackgroundInitializationStatus)
3854
        {
3855
          Controller->V1.NeedBackgroundInitializationStatus = false;
3856
          Command->V1.CommandMailbox.Type3B.CommandOpcode =
3857
            DAC960_V1_BackgroundInitializationControl;
3858
          Command->V1.CommandMailbox.Type3B.CommandOpcode2 = 0x20;
3859
          Command->V1.CommandMailbox.Type3B.BusAddress =
3860
            Virtual_to_Bus32(&Controller->V1.BackgroundInitializationStatus);
3861
          DAC960_QueueCommand(Command);
3862
          return;
3863
        }
3864
      Controller->MonitoringTimerCount++;
3865
      Controller->MonitoringTimer.expires =
3866
        jiffies + DAC960_MonitoringTimerInterval;
3867
      add_timer(&Controller->MonitoringTimer);
3868
    }
3869
  if (CommandType == DAC960_ImmediateCommand)
3870
    {
3871
      complete(Command->Completion);
3872
      Command->Completion = NULL;
3873
      return;
3874
    }
3875
  if (CommandType == DAC960_QueuedCommand)
3876
    {
3877
      DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand;
3878
      KernelCommand->CommandStatus = Command->V1.CommandStatus;
3879
      Command->V1.KernelCommand = NULL;
3880
      if (CommandOpcode == DAC960_V1_DCDB)
3881
        Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel]
3882
                                          [KernelCommand->DCDB->TargetID] =
3883
          false;
3884
      DAC960_DeallocateCommand(Command);
3885
      KernelCommand->CompletionFunction(KernelCommand);
3886
      return;
3887
    }
3888
  /*
3889
    Queue a Status Monitoring Command to the Controller using the just
3890
    completed Command if one was deferred previously due to lack of a
3891
    free Command when the Monitoring Timer Function was called.
3892
  */
3893
  if (Controller->MonitoringCommandDeferred)
3894
    {
3895
      Controller->MonitoringCommandDeferred = false;
3896
      DAC960_V1_QueueMonitoringCommand(Command);
3897
      return;
3898
    }
3899
  /*
3900
    Deallocate the Command.
3901
  */
3902
  DAC960_DeallocateCommand(Command);
3903
  /*
3904
    Wake up any processes waiting on a free Command.
3905
  */
3906
  wake_up(&Controller->CommandWaitQueue);
3907
}
3908
 
3909
 
3910
/*
3911
  DAC960_V2_ReadWriteError prints an appropriate error message for Command
3912
  when an error occurs on a Read or Write operation.
3913
*/
3914
 
3915
static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
3916
{
3917
  DAC960_Controller_T *Controller = Command->Controller;
3918
  unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
3919
                                   "NOT READY", "MEDIUM ERROR",
3920
                                   "HARDWARE ERROR", "ILLEGAL REQUEST",
3921
                                   "UNIT ATTENTION", "DATA PROTECT",
3922
                                   "BLANK CHECK", "VENDOR-SPECIFIC",
3923
                                   "COPY ABORTED", "ABORTED COMMAND",
3924
                                   "EQUAL", "VOLUME OVERFLOW",
3925
                                   "MISCOMPARE", "RESERVED" };
3926
  unsigned char *CommandName = "UNKNOWN";
3927
  switch (Command->CommandType)
3928
    {
3929
    case DAC960_ReadCommand:
3930
    case DAC960_ReadRetryCommand:
3931
      CommandName = "READ";
3932
      break;
3933
    case DAC960_WriteCommand:
3934
    case DAC960_WriteRetryCommand:
3935
      CommandName = "WRITE";
3936
      break;
3937
    case DAC960_MonitoringCommand:
3938
    case DAC960_ImmediateCommand:
3939
    case DAC960_QueuedCommand:
3940
      break;
3941
    }
3942
  DAC960_Error("Error Condition %s on %s:\n", Controller,
3943
               SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
3944
  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%u\n",
3945
               Controller, Controller->ControllerNumber,
3946
               Command->LogicalDriveNumber, Command->BlockNumber,
3947
               Command->BlockNumber + Command->BlockCount - 1);
3948
  if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
3949
    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
3950
                 Controller, Controller->ControllerNumber,
3951
                 Command->LogicalDriveNumber,
3952
                 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
3953
                 Command->BufferHeader->b_rsector,
3954
                 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
3955
}
3956
 
3957
 
3958
/*
3959
  DAC960_V2_ReportEvent prints an appropriate message when a Controller Event
3960
  occurs.
3961
*/
3962
 
3963
static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
3964
                                  DAC960_V2_Event_T *Event)
3965
{
3966
  DAC960_SCSI_RequestSense_T *RequestSense =
3967
    (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData;
3968
  unsigned char MessageBuffer[DAC960_LineBufferSize];
3969
  static struct { int EventCode; unsigned char *EventMessage; } EventList[] =
3970
    { /* Physical Device Events (0x0000 - 0x007F) */
3971
      { 0x0001, "P Online" },
3972
      { 0x0002, "P Standby" },
3973
      { 0x0005, "P Automatic Rebuild Started" },
3974
      { 0x0006, "P Manual Rebuild Started" },
3975
      { 0x0007, "P Rebuild Completed" },
3976
      { 0x0008, "P Rebuild Cancelled" },
3977
      { 0x0009, "P Rebuild Failed for Unknown Reasons" },
3978
      { 0x000A, "P Rebuild Failed due to New Physical Device" },
3979
      { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
3980
      { 0x000C, "S Offline" },
3981
      { 0x000D, "P Found" },
3982
      { 0x000E, "P Removed" },
3983
      { 0x000F, "P Unconfigured" },
3984
      { 0x0010, "P Expand Capacity Started" },
3985
      { 0x0011, "P Expand Capacity Completed" },
3986
      { 0x0012, "P Expand Capacity Failed" },
3987
      { 0x0013, "P Command Timed Out" },
3988
      { 0x0014, "P Command Aborted" },
3989
      { 0x0015, "P Command Retried" },
3990
      { 0x0016, "P Parity Error" },
3991
      { 0x0017, "P Soft Error" },
3992
      { 0x0018, "P Miscellaneous Error" },
3993
      { 0x0019, "P Reset" },
3994
      { 0x001A, "P Active Spare Found" },
3995
      { 0x001B, "P Warm Spare Found" },
3996
      { 0x001C, "S Sense Data Received" },
3997
      { 0x001D, "P Initialization Started" },
3998
      { 0x001E, "P Initialization Completed" },
3999
      { 0x001F, "P Initialization Failed" },
4000
      { 0x0020, "P Initialization Cancelled" },
4001
      { 0x0021, "P Failed because Write Recovery Failed" },
4002
      { 0x0022, "P Failed because SCSI Bus Reset Failed" },
4003
      { 0x0023, "P Failed because of Double Check Condition" },
4004
      { 0x0024, "P Failed because Device Cannot Be Accessed" },
4005
      { 0x0025, "P Failed because of Gross Error on SCSI Processor" },
4006
      { 0x0026, "P Failed because of Bad Tag from Device" },
4007
      { 0x0027, "P Failed because of Command Timeout" },
4008
      { 0x0028, "P Failed because of System Reset" },
4009
      { 0x0029, "P Failed because of Busy Status or Parity Error" },
4010
      { 0x002A, "P Failed because Host Set Device to Failed State" },
4011
      { 0x002B, "P Failed because of Selection Timeout" },
4012
      { 0x002C, "P Failed because of SCSI Bus Phase Error" },
4013
      { 0x002D, "P Failed because Device Returned Unknown Status" },
4014
      { 0x002E, "P Failed because Device Not Ready" },
4015
      { 0x002F, "P Failed because Device Not Found at Startup" },
4016
      { 0x0030, "P Failed because COD Write Operation Failed" },
4017
      { 0x0031, "P Failed because BDT Write Operation Failed" },
4018
      { 0x0039, "P Missing at Startup" },
4019
      { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
4020
      { 0x003C, "P Temporarily Offline Device Automatically Made Online" },
4021
      { 0x003D, "P Standby Rebuild Started" },
4022
      /* Logical Device Events (0x0080 - 0x00FF) */
4023
      { 0x0080, "M Consistency Check Started" },
4024
      { 0x0081, "M Consistency Check Completed" },
4025
      { 0x0082, "M Consistency Check Cancelled" },
4026
      { 0x0083, "M Consistency Check Completed With Errors" },
4027
      { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
4028
      { 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
4029
      { 0x0086, "L Offline" },
4030
      { 0x0087, "L Critical" },
4031
      { 0x0088, "L Online" },
4032
      { 0x0089, "M Automatic Rebuild Started" },
4033
      { 0x008A, "M Manual Rebuild Started" },
4034
      { 0x008B, "M Rebuild Completed" },
4035
      { 0x008C, "M Rebuild Cancelled" },
4036
      { 0x008D, "M Rebuild Failed for Unknown Reasons" },
4037
      { 0x008E, "M Rebuild Failed due to New Physical Device" },
4038
      { 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
4039
      { 0x0090, "M Initialization Started" },
4040
      { 0x0091, "M Initialization Completed" },
4041
      { 0x0092, "M Initialization Cancelled" },
4042
      { 0x0093, "M Initialization Failed" },
4043
      { 0x0094, "L Found" },
4044
      { 0x0095, "L Deleted" },
4045
      { 0x0096, "M Expand Capacity Started" },
4046
      { 0x0097, "M Expand Capacity Completed" },
4047
      { 0x0098, "M Expand Capacity Failed" },
4048
      { 0x0099, "L Bad Block Found" },
4049
      { 0x009A, "L Size Changed" },
4050
      { 0x009B, "L Type Changed" },
4051
      { 0x009C, "L Bad Data Block Found" },
4052
      { 0x009E, "L Read of Data Block in BDT" },
4053
      { 0x009F, "L Write Back Data for Disk Block Lost" },
4054
      { 0x00A0, "L Temporarily Offline RAID-5/3 Drive Made Online" },
4055
      { 0x00A1, "L Temporarily Offline RAID-6/1/0/7 Drive Made Online" },
4056
      { 0x00A2, "L Standby Rebuild Started" },
4057
      /* Fault Management Events (0x0100 - 0x017F) */
4058
      { 0x0140, "E Fan %d Failed" },
4059
      { 0x0141, "E Fan %d OK" },
4060
      { 0x0142, "E Fan %d Not Present" },
4061
      { 0x0143, "E Power Supply %d Failed" },
4062
      { 0x0144, "E Power Supply %d OK" },
4063
      { 0x0145, "E Power Supply %d Not Present" },
4064
      { 0x0146, "E Temperature Sensor %d Temperature Exceeds Safe Limit" },
4065
      { 0x0147, "E Temperature Sensor %d Temperature Exceeds Working Limit" },
4066
      { 0x0148, "E Temperature Sensor %d Temperature Normal" },
4067
      { 0x0149, "E Temperature Sensor %d Not Present" },
4068
      { 0x014A, "E Enclosure Management Unit %d Access Critical" },
4069
      { 0x014B, "E Enclosure Management Unit %d Access OK" },
4070
      { 0x014C, "E Enclosure Management Unit %d Access Offline" },
4071
      /* Controller Events (0x0180 - 0x01FF) */
4072
      { 0x0181, "C Cache Write Back Error" },
4073
      { 0x0188, "C Battery Backup Unit Found" },
4074
      { 0x0189, "C Battery Backup Unit Charge Level Low" },
4075
      { 0x018A, "C Battery Backup Unit Charge Level OK" },
4076
      { 0x0193, "C Installation Aborted" },
4077
      { 0x0195, "C Battery Backup Unit Physically Removed" },
4078
      { 0x0196, "C Memory Error During Warm Boot" },
4079
      { 0x019E, "C Memory Soft ECC Error Corrected" },
4080
      { 0x019F, "C Memory Hard ECC Error Corrected" },
4081
      { 0x01A2, "C Battery Backup Unit Failed" },
4082
      { 0x01AB, "C Mirror Race Recovery Failed" },
4083
      { 0x01AC, "C Mirror Race on Critical Drive" },
4084
      /* Controller Internal Processor Events */
4085
      { 0x0380, "C Internal Controller Hung" },
4086
      { 0x0381, "C Internal Controller Firmware Breakpoint" },
4087
      { 0x0390, "C Internal Controller i960 Processor Specific Error" },
4088
      { 0x03A0, "C Internal Controller StrongARM Processor Specific Error" },
4089
      { 0, "" } };
4090
  int EventListIndex = 0, EventCode;
4091
  unsigned char EventType, *EventMessage;
4092
  if (Event->EventCode == 0x1C &&
4093
      RequestSense->SenseKey == DAC960_SenseKey_VendorSpecific &&
4094
      (RequestSense->AdditionalSenseCode == 0x80 ||
4095
       RequestSense->AdditionalSenseCode == 0x81))
4096
    Event->EventCode = ((RequestSense->AdditionalSenseCode - 0x80) << 8) |
4097
                       RequestSense->AdditionalSenseCodeQualifier;
4098
  while (true)
4099
    {
4100
      EventCode = EventList[EventListIndex].EventCode;
4101
      if (EventCode == Event->EventCode || EventCode == 0) break;
4102
      EventListIndex++;
4103
    }
4104
  EventType = EventList[EventListIndex].EventMessage[0];
4105
  EventMessage = &EventList[EventListIndex].EventMessage[2];
4106
  if (EventCode == 0)
4107
    {
4108
      DAC960_Critical("Unknown Controller Event Code %04X\n",
4109
                      Controller, Event->EventCode);
4110
      return;
4111
    }
4112
  switch (EventType)
4113
    {
4114
    case 'P':
4115
      DAC960_Critical("Physical Device %d:%d %s\n", Controller,
4116
                      Event->Channel, Event->TargetID, EventMessage);
4117
      break;
4118
    case 'L':
4119
      DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
4120
                      Event->LogicalUnit, Controller->ControllerNumber,
4121
                      Event->LogicalUnit, EventMessage);
4122
      break;
4123
    case 'M':
4124
      DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
4125
                      Event->LogicalUnit, Controller->ControllerNumber,
4126
                      Event->LogicalUnit, EventMessage);
4127
      break;
4128
    case 'S':
4129
      if (RequestSense->SenseKey == DAC960_SenseKey_NoSense ||
4130
          (RequestSense->SenseKey == DAC960_SenseKey_NotReady &&
4131
           RequestSense->AdditionalSenseCode == 0x04 &&
4132
           (RequestSense->AdditionalSenseCodeQualifier == 0x01 ||
4133
            RequestSense->AdditionalSenseCodeQualifier == 0x02)))
4134
        break;
4135
      DAC960_Critical("Physical Device %d:%d %s\n", Controller,
4136
                      Event->Channel, Event->TargetID, EventMessage);
4137
      DAC960_Critical("Physical Device %d:%d Request Sense: "
4138
                      "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
4139
                      Controller,
4140
                      Event->Channel,
4141
                      Event->TargetID,
4142
                      RequestSense->SenseKey,
4143
                      RequestSense->AdditionalSenseCode,
4144
                      RequestSense->AdditionalSenseCodeQualifier);
4145
      DAC960_Critical("Physical Device %d:%d Request Sense: "
4146
                      "Information = %02X%02X%02X%02X "
4147
                      "%02X%02X%02X%02X\n",
4148
                      Controller,
4149
                      Event->Channel,
4150
                      Event->TargetID,
4151
                      RequestSense->Information[0],
4152
                      RequestSense->Information[1],
4153
                      RequestSense->Information[2],
4154
                      RequestSense->Information[3],
4155
                      RequestSense->CommandSpecificInformation[0],
4156
                      RequestSense->CommandSpecificInformation[1],
4157
                      RequestSense->CommandSpecificInformation[2],
4158
                      RequestSense->CommandSpecificInformation[3]);
4159
      break;
4160
    case 'E':
4161
      if (Controller->SuppressEnclosureMessages) break;
4162
      sprintf(MessageBuffer, EventMessage, Event->LogicalUnit);
4163
      DAC960_Critical("Enclosure %d %s\n", Controller,
4164
                      Event->TargetID, MessageBuffer);
4165
      break;
4166
    case 'C':
4167
      DAC960_Critical("Controller %s\n", Controller, EventMessage);
4168
      break;
4169
    default:
4170
      DAC960_Critical("Unknown Controller Event Code %04X\n",
4171
                      Controller, Event->EventCode);
4172
      break;
4173
    }
4174
}
4175
 
4176
 
4177
/*
4178
  DAC960_V2_ReportProgress prints an appropriate progress message for
4179
  Logical Device Long Operations.
4180
*/
4181
 
4182
static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller,
4183
                                     unsigned char *MessageString,
4184
                                     unsigned int LogicalDeviceNumber,
4185
                                     unsigned long BlocksCompleted,
4186
                                     unsigned long LogicalDeviceSize)
4187
{
4188
  Controller->EphemeralProgressMessage = true;
4189
  DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) "
4190
                  "%d%% completed\n", Controller,
4191
                  MessageString,
4192
                  LogicalDeviceNumber,
4193
                  Controller->ControllerNumber,
4194
                  LogicalDeviceNumber,
4195
                  (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7));
4196
  Controller->EphemeralProgressMessage = false;
4197
}
4198
 
4199
 
4200
/*
4201
  DAC960_V2_ProcessCompletedCommand performs completion processing for Command
4202
  for DAC960 V2 Firmware Controllers.
4203
*/
4204
 
4205
static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
4206
{
4207
  DAC960_Controller_T *Controller = Command->Controller;
4208
  DAC960_CommandType_T CommandType = Command->CommandType;
4209
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
4210
  DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
4211
  DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
4212
  BufferHeader_T *BufferHeader = Command->BufferHeader;
4213
  if (CommandType == DAC960_ReadCommand ||
4214
      CommandType == DAC960_WriteCommand)
4215
    {
4216
      if (CommandStatus == DAC960_V2_NormalCompletion)
4217
        {
4218
          /*
4219
            Perform completion processing for all buffers in this I/O Request.
4220
          */
4221
          while (BufferHeader != NULL)
4222
            {
4223
              BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
4224
              BufferHeader->b_reqnext = NULL;
4225
              DAC960_ProcessCompletedBuffer(BufferHeader, true);
4226
              BufferHeader = NextBufferHeader;
4227
            }
4228
          if (Command->Completion != NULL)
4229
            {
4230
              complete(Command->Completion);
4231
              Command->Completion = NULL;
4232
            }
4233
          add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
4234
        }
4235
      else if (Command->V2.RequestSense.SenseKey
4236
               == DAC960_SenseKey_MediumError &&
4237
               BufferHeader != NULL &&
4238
               BufferHeader->b_reqnext != NULL)
4239
        {
4240
          if (CommandType == DAC960_ReadCommand)
4241
            Command->CommandType = DAC960_ReadRetryCommand;
4242
          else Command->CommandType = DAC960_WriteRetryCommand;
4243
          Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
4244
          CommandMailbox->SCSI_10.CommandControlBits
4245
                                 .AdditionalScatterGatherListMemory = false;
4246
          CommandMailbox->SCSI_10.DataTransferSize =
4247
            Command->BlockCount << DAC960_BlockSizeBits;
4248
          CommandMailbox->SCSI_10.DataTransferMemoryAddress
4249
                                 .ScatterGatherSegments[0].SegmentDataPointer =
4250
            Virtual_to_Bus64(BufferHeader->b_data);
4251
          CommandMailbox->SCSI_10.DataTransferMemoryAddress
4252
                                 .ScatterGatherSegments[0].SegmentByteCount =
4253
            CommandMailbox->SCSI_10.DataTransferSize;
4254
          CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
4255
          CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
4256
          DAC960_QueueCommand(Command);
4257
          return;
4258
        }
4259
      else
4260
        {
4261
          if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
4262
            DAC960_V2_ReadWriteError(Command);
4263
          /*
4264
            Perform completion processing for all buffers in this I/O Request.
4265
          */
4266
          while (BufferHeader != NULL)
4267
            {
4268
              BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
4269
              BufferHeader->b_reqnext = NULL;
4270
              DAC960_ProcessCompletedBuffer(BufferHeader, false);
4271
              BufferHeader = NextBufferHeader;
4272
            }
4273
          if (Command->Completion != NULL)
4274
            {
4275
              complete(Command->Completion);
4276
              Command->Completion = NULL;
4277
            }
4278
        }
4279
    }
4280
  else if (CommandType == DAC960_ReadRetryCommand ||
4281
           CommandType == DAC960_WriteRetryCommand)
4282
    {
4283
      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
4284
      BufferHeader->b_reqnext = NULL;
4285
      /*
4286
        Perform completion processing for this single buffer.
4287
      */
4288
      if (CommandStatus == DAC960_V2_NormalCompletion)
4289
        DAC960_ProcessCompletedBuffer(BufferHeader, true);
4290
      else
4291
        {
4292
          if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
4293
            DAC960_V2_ReadWriteError(Command);
4294
          DAC960_ProcessCompletedBuffer(BufferHeader, false);
4295
        }
4296
      if (NextBufferHeader != NULL)
4297
        {
4298
          Command->BlockNumber +=
4299
            BufferHeader->b_size >> DAC960_BlockSizeBits;
4300
          Command->BlockCount =
4301
            NextBufferHeader->b_size >> DAC960_BlockSizeBits;
4302
          Command->BufferHeader = NextBufferHeader;
4303
          CommandMailbox->SCSI_10.DataTransferSize =
4304
            Command->BlockCount << DAC960_BlockSizeBits;
4305
          CommandMailbox->SCSI_10.DataTransferMemoryAddress
4306
                                 .ScatterGatherSegments[0]
4307
                                 .SegmentDataPointer =
4308
            Virtual_to_Bus64(NextBufferHeader->b_data);
4309
          CommandMailbox->SCSI_10.DataTransferMemoryAddress
4310
                                 .ScatterGatherSegments[0]
4311
                                 .SegmentByteCount =
4312
            CommandMailbox->SCSI_10.DataTransferSize;
4313
          CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
4314
          CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
4315
          CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
4316
          CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
4317
          CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
4318
          CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
4319
          DAC960_QueueCommand(Command);
4320
          return;
4321
        }
4322
    }
4323
  else if (CommandType == DAC960_MonitoringCommand)
4324
    {
4325
      if (CommandOpcode == DAC960_V2_GetControllerInfo)
4326
        {
4327
          DAC960_V2_ControllerInfo_T *NewControllerInfo =
4328
            &Controller->V2.NewControllerInformation;
4329
          DAC960_V2_ControllerInfo_T *ControllerInfo =
4330
            &Controller->V2.ControllerInformation;
4331
          Controller->LogicalDriveCount =
4332
            NewControllerInfo->LogicalDevicesPresent;
4333
          Controller->V2.NeedLogicalDeviceInformation = true;
4334
          Controller->V2.NeedPhysicalDeviceInformation = true;
4335
          Controller->V2.StartLogicalDeviceInformationScan = true;
4336
          Controller->V2.StartPhysicalDeviceInformationScan = true;
4337
          Controller->MonitoringAlertMode =
4338
            (NewControllerInfo->LogicalDevicesCritical > 0 ||
4339
             NewControllerInfo->LogicalDevicesOffline > 0 ||
4340
             NewControllerInfo->PhysicalDisksCritical > 0 ||
4341
             NewControllerInfo->PhysicalDisksOffline > 0);
4342
          memcpy(ControllerInfo, NewControllerInfo,
4343
                 sizeof(DAC960_V2_ControllerInfo_T));
4344
        }
4345
      else if (CommandOpcode == DAC960_V2_GetEvent)
4346
        {
4347
          if (CommandStatus == DAC960_V2_NormalCompletion)
4348
            DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
4349
          Controller->V2.NextEventSequenceNumber++;
4350
        }
4351
      else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
4352
               CommandStatus == DAC960_V2_NormalCompletion)
4353
        {
4354
          DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
4355
            &Controller->V2.NewPhysicalDeviceInformation;
4356
          unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
4357
          DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
4358
            Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
4359
          DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
4360
            Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
4361
          unsigned int DeviceIndex;
4362
          while (PhysicalDeviceInfo != NULL &&
4363
                 (NewPhysicalDeviceInfo->Channel >
4364
                  PhysicalDeviceInfo->Channel ||
4365
                  (NewPhysicalDeviceInfo->Channel ==
4366
                   PhysicalDeviceInfo->Channel &&
4367
                   (NewPhysicalDeviceInfo->TargetID >
4368
                    PhysicalDeviceInfo->TargetID ||
4369
                   (NewPhysicalDeviceInfo->TargetID ==
4370
                    PhysicalDeviceInfo->TargetID &&
4371
                    NewPhysicalDeviceInfo->LogicalUnit >
4372
                    PhysicalDeviceInfo->LogicalUnit)))))
4373
            {
4374
              DAC960_Critical("Physical Device %d:%d No Longer Exists\n",
4375
                              Controller,
4376
                              PhysicalDeviceInfo->Channel,
4377
                              PhysicalDeviceInfo->TargetID);
4378
              Controller->V2.PhysicalDeviceInformation
4379
                             [PhysicalDeviceIndex] = NULL;
4380
              Controller->V2.InquiryUnitSerialNumber
4381
                             [PhysicalDeviceIndex] = NULL;
4382
              kfree(PhysicalDeviceInfo);
4383
              kfree(InquiryUnitSerialNumber);
4384
              for (DeviceIndex = PhysicalDeviceIndex;
4385
                   DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
4386
                   DeviceIndex++)
4387
                {
4388
                  Controller->V2.PhysicalDeviceInformation[DeviceIndex] =
4389
                    Controller->V2.PhysicalDeviceInformation[DeviceIndex+1];
4390
                  Controller->V2.InquiryUnitSerialNumber[DeviceIndex] =
4391
                    Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1];
4392
                }
4393
              Controller->V2.PhysicalDeviceInformation
4394
                             [DAC960_V2_MaxPhysicalDevices-1] = NULL;
4395
              Controller->V2.InquiryUnitSerialNumber
4396
                             [DAC960_V2_MaxPhysicalDevices-1] = NULL;
4397
              PhysicalDeviceInfo =
4398
                Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
4399
              InquiryUnitSerialNumber =
4400
                Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
4401
            }
4402
          if (PhysicalDeviceInfo == NULL ||
4403
              (NewPhysicalDeviceInfo->Channel !=
4404
               PhysicalDeviceInfo->Channel) ||
4405
              (NewPhysicalDeviceInfo->TargetID !=
4406
               PhysicalDeviceInfo->TargetID) ||
4407
              (NewPhysicalDeviceInfo->LogicalUnit !=
4408
               PhysicalDeviceInfo->LogicalUnit))
4409
            {
4410
              PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
4411
                kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
4412
              InquiryUnitSerialNumber =
4413
                (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
4414
                  kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
4415
                          GFP_ATOMIC);
4416
              if (InquiryUnitSerialNumber == NULL &&
4417
                  PhysicalDeviceInfo != NULL)
4418
                {
4419
                  kfree(PhysicalDeviceInfo);
4420
                  PhysicalDeviceInfo = NULL;
4421
                }
4422
              DAC960_Critical("Physical Device %d:%d Now Exists%s\n",
4423
                              Controller,
4424
                              NewPhysicalDeviceInfo->Channel,
4425
                              NewPhysicalDeviceInfo->TargetID,
4426
                              (PhysicalDeviceInfo != NULL
4427
                               ? "" : " - Allocation Failed"));
4428
              if (PhysicalDeviceInfo != NULL)
4429
                {
4430
                  memset(PhysicalDeviceInfo, 0,
4431
                         sizeof(DAC960_V2_PhysicalDeviceInfo_T));
4432
                  PhysicalDeviceInfo->PhysicalDeviceState =
4433
                    DAC960_V2_Device_InvalidState;
4434
                  memset(InquiryUnitSerialNumber, 0,
4435
                         sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
4436
                  InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
4437
                  for (DeviceIndex = DAC960_V2_MaxPhysicalDevices - 1;
4438
                       DeviceIndex > PhysicalDeviceIndex;
4439
                       DeviceIndex--)
4440
                    {
4441
                      Controller->V2.PhysicalDeviceInformation[DeviceIndex] =
4442
                        Controller->V2.PhysicalDeviceInformation[DeviceIndex-1];
4443
                      Controller->V2.InquiryUnitSerialNumber[DeviceIndex] =
4444
                        Controller->V2.InquiryUnitSerialNumber[DeviceIndex-1];
4445
                    }
4446
                  Controller->V2.PhysicalDeviceInformation
4447
                                 [PhysicalDeviceIndex] =
4448
                    PhysicalDeviceInfo;
4449
                  Controller->V2.InquiryUnitSerialNumber
4450
                                 [PhysicalDeviceIndex] =
4451
                    InquiryUnitSerialNumber;
4452
                  Controller->V2.NeedDeviceSerialNumberInformation = true;
4453
                }
4454
            }
4455
          if (PhysicalDeviceInfo != NULL)
4456
            {
4457
              if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
4458
                  PhysicalDeviceInfo->PhysicalDeviceState)
4459
                DAC960_Critical(
4460
                  "Physical Device %d:%d is now %s\n", Controller,
4461
                  NewPhysicalDeviceInfo->Channel,
4462
                  NewPhysicalDeviceInfo->TargetID,
4463
                  (NewPhysicalDeviceInfo->PhysicalDeviceState
4464
                   == DAC960_V2_Device_Online
4465
                   ? "ONLINE"
4466
                   : NewPhysicalDeviceInfo->PhysicalDeviceState
4467
                     == DAC960_V2_Device_Rebuild
4468
                     ? "REBUILD"
4469
                     : NewPhysicalDeviceInfo->PhysicalDeviceState
4470
                       == DAC960_V2_Device_Missing
4471
                       ? "MISSING"
4472
                       : NewPhysicalDeviceInfo->PhysicalDeviceState
4473
                         == DAC960_V2_Device_Critical
4474
                         ? "CRITICAL"
4475
                         : NewPhysicalDeviceInfo->PhysicalDeviceState
4476
                           == DAC960_V2_Device_Dead
4477
                           ? "DEAD"
4478
                           : NewPhysicalDeviceInfo->PhysicalDeviceState
4479
                             == DAC960_V2_Device_SuspectedDead
4480
                             ? "SUSPECTED-DEAD"
4481
                             : NewPhysicalDeviceInfo->PhysicalDeviceState
4482
                               == DAC960_V2_Device_CommandedOffline
4483
                               ? "COMMANDED-OFFLINE"
4484
                               : NewPhysicalDeviceInfo->PhysicalDeviceState
4485
                                 == DAC960_V2_Device_Standby
4486
                                 ? "STANDBY" : "UNKNOWN"));
4487
              if ((NewPhysicalDeviceInfo->ParityErrors !=
4488
                   PhysicalDeviceInfo->ParityErrors) ||
4489
                  (NewPhysicalDeviceInfo->SoftErrors !=
4490
                   PhysicalDeviceInfo->SoftErrors) ||
4491
                  (NewPhysicalDeviceInfo->HardErrors !=
4492
                   PhysicalDeviceInfo->HardErrors) ||
4493
                  (NewPhysicalDeviceInfo->MiscellaneousErrors !=
4494
                   PhysicalDeviceInfo->MiscellaneousErrors) ||
4495
                  (NewPhysicalDeviceInfo->CommandTimeouts !=
4496
                   PhysicalDeviceInfo->CommandTimeouts) ||
4497
                  (NewPhysicalDeviceInfo->Retries !=
4498
                   PhysicalDeviceInfo->Retries) ||
4499
                  (NewPhysicalDeviceInfo->Aborts !=
4500
                   PhysicalDeviceInfo->Aborts) ||
4501
                  (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
4502
                   PhysicalDeviceInfo->PredictedFailuresDetected))
4503
                {
4504
                  DAC960_Critical("Physical Device %d:%d Errors: "
4505
                                  "Parity = %d, Soft = %d, "
4506
                                  "Hard = %d, Misc = %d\n",
4507
                                  Controller,
4508
                                  NewPhysicalDeviceInfo->Channel,
4509
                                  NewPhysicalDeviceInfo->TargetID,
4510
                                  NewPhysicalDeviceInfo->ParityErrors,
4511
                                  NewPhysicalDeviceInfo->SoftErrors,
4512
                                  NewPhysicalDeviceInfo->HardErrors,
4513
                                  NewPhysicalDeviceInfo->MiscellaneousErrors);
4514
                  DAC960_Critical("Physical Device %d:%d Errors: "
4515
                                  "Timeouts = %d, Retries = %d, "
4516
                                  "Aborts = %d, Predicted = %d\n",
4517
                                  Controller,
4518
                                  NewPhysicalDeviceInfo->Channel,
4519
                                  NewPhysicalDeviceInfo->TargetID,
4520
                                  NewPhysicalDeviceInfo->CommandTimeouts,
4521
                                  NewPhysicalDeviceInfo->Retries,
4522
                                  NewPhysicalDeviceInfo->Aborts,
4523
                                  NewPhysicalDeviceInfo
4524
                                  ->PredictedFailuresDetected);
4525
                }
4526
              if ((PhysicalDeviceInfo->PhysicalDeviceState
4527
                   == DAC960_V2_Device_Dead ||
4528
                   PhysicalDeviceInfo->PhysicalDeviceState
4529
                   == DAC960_V2_Device_InvalidState) &&
4530
                  NewPhysicalDeviceInfo->PhysicalDeviceState
4531
                  != DAC960_V2_Device_Dead)
4532
                Controller->V2.NeedDeviceSerialNumberInformation = true;
4533
              memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
4534
                     sizeof(DAC960_V2_PhysicalDeviceInfo_T));
4535
            }
4536
          NewPhysicalDeviceInfo->LogicalUnit++;
4537
          Controller->V2.PhysicalDeviceIndex++;
4538
        }
4539
      else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
4540
        {
4541
          unsigned int DeviceIndex;
4542
          for (DeviceIndex = Controller->V2.PhysicalDeviceIndex;
4543
               DeviceIndex < DAC960_V2_MaxPhysicalDevices;
4544
               DeviceIndex++)
4545
            {
4546
              DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
4547
                Controller->V2.PhysicalDeviceInformation[DeviceIndex];
4548
              DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
4549
                Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
4550
              if (PhysicalDeviceInfo == NULL) break;
4551
              DAC960_Critical("Physical Device %d:%d No Longer Exists\n",
4552
                              Controller,
4553
                              PhysicalDeviceInfo->Channel,
4554
                              PhysicalDeviceInfo->TargetID);
4555
              Controller->V2.PhysicalDeviceInformation[DeviceIndex] = NULL;
4556
              Controller->V2.InquiryUnitSerialNumber[DeviceIndex] = NULL;
4557
              kfree(PhysicalDeviceInfo);
4558
              kfree(InquiryUnitSerialNumber);
4559
            }
4560
          Controller->V2.NeedPhysicalDeviceInformation = false;
4561
        }
4562
      else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
4563
               CommandStatus == DAC960_V2_NormalCompletion)
4564
        {
4565
          DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
4566
            &Controller->V2.NewLogicalDeviceInformation;
4567
          unsigned short LogicalDeviceNumber =
4568
            NewLogicalDeviceInfo->LogicalDeviceNumber;
4569
          DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4570
            Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
4571
          if (LogicalDeviceInfo == NULL)
4572
            {
4573
              DAC960_V2_PhysicalDevice_T PhysicalDevice;
4574
              PhysicalDevice.Controller = 0;
4575
              PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
4576
              PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
4577
              PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
4578
              Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
4579
                PhysicalDevice;
4580
              LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
4581
                kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
4582
              Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
4583
                LogicalDeviceInfo;
4584
              DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
4585
                              "Now Exists%s\n", Controller,
4586
                              LogicalDeviceNumber,
4587
                              Controller->ControllerNumber,
4588
                              LogicalDeviceNumber,
4589
                              (LogicalDeviceInfo != NULL
4590
                               ? "" : " - Allocation Failed"));
4591
              if (LogicalDeviceInfo != NULL)
4592
                {
4593
                  memset(LogicalDeviceInfo, 0,
4594
                         sizeof(DAC960_V2_LogicalDeviceInfo_T));
4595
                  DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
4596
                }
4597
            }
4598
          if (LogicalDeviceInfo != NULL)
4599
            {
4600
              unsigned long LogicalDeviceSize =
4601
                NewLogicalDeviceInfo->ConfigurableDeviceSize;
4602
              if (NewLogicalDeviceInfo->LogicalDeviceState !=
4603
                  LogicalDeviceInfo->LogicalDeviceState)
4604
                DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
4605
                                "is now %s\n", Controller,
4606
                                LogicalDeviceNumber,
4607
                                Controller->ControllerNumber,
4608
                                LogicalDeviceNumber,
4609
                                (NewLogicalDeviceInfo->LogicalDeviceState
4610
                                 == DAC960_V2_LogicalDevice_Online
4611
                                 ? "ONLINE"
4612
                                 : NewLogicalDeviceInfo->LogicalDeviceState
4613
                                   == DAC960_V2_LogicalDevice_Critical
4614
                                   ? "CRITICAL" : "OFFLINE"));
4615
              if ((NewLogicalDeviceInfo->SoftErrors !=
4616
                   LogicalDeviceInfo->SoftErrors) ||
4617
                  (NewLogicalDeviceInfo->CommandsFailed !=
4618
                   LogicalDeviceInfo->CommandsFailed) ||
4619
                  (NewLogicalDeviceInfo->DeferredWriteErrors !=
4620
                   LogicalDeviceInfo->DeferredWriteErrors))
4621
                DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
4622
                                "Soft = %d, Failed = %d, Deferred Write = %d\n",
4623
                                Controller, LogicalDeviceNumber,
4624
                                Controller->ControllerNumber,
4625
                                LogicalDeviceNumber,
4626
                                NewLogicalDeviceInfo->SoftErrors,
4627
                                NewLogicalDeviceInfo->CommandsFailed,
4628
                                NewLogicalDeviceInfo->DeferredWriteErrors);
4629
              if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
4630
                DAC960_V2_ReportProgress(Controller,
4631
                                         "Consistency Check",
4632
                                         LogicalDeviceNumber,
4633
                                         NewLogicalDeviceInfo
4634
                                         ->ConsistencyCheckBlockNumber,
4635
                                         LogicalDeviceSize);
4636
              else if (NewLogicalDeviceInfo->RebuildInProgress)
4637
                DAC960_V2_ReportProgress(Controller,
4638
                                         "Rebuild",
4639
                                         LogicalDeviceNumber,
4640
                                         NewLogicalDeviceInfo
4641
                                         ->RebuildBlockNumber,
4642
                                         LogicalDeviceSize);
4643
              else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
4644
                DAC960_V2_ReportProgress(Controller,
4645
                                         "Background Initialization",
4646
                                         LogicalDeviceNumber,
4647
                                         NewLogicalDeviceInfo
4648
                                         ->BackgroundInitializationBlockNumber,
4649
                                         LogicalDeviceSize);
4650
              else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
4651
                DAC960_V2_ReportProgress(Controller,
4652
                                         "Foreground Initialization",
4653
                                         LogicalDeviceNumber,
4654
                                         NewLogicalDeviceInfo
4655
                                         ->ForegroundInitializationBlockNumber,
4656
                                         LogicalDeviceSize);
4657
              else if (NewLogicalDeviceInfo->DataMigrationInProgress)
4658
                DAC960_V2_ReportProgress(Controller,
4659
                                         "Data Migration",
4660
                                         LogicalDeviceNumber,
4661
                                         NewLogicalDeviceInfo
4662
                                         ->DataMigrationBlockNumber,
4663
                                         LogicalDeviceSize);
4664
              else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
4665
                DAC960_V2_ReportProgress(Controller,
4666
                                         "Patrol Operation",
4667
                                         LogicalDeviceNumber,
4668
                                         NewLogicalDeviceInfo
4669
                                         ->PatrolOperationBlockNumber,
4670
                                         LogicalDeviceSize);
4671
              if (LogicalDeviceInfo->BackgroundInitializationInProgress &&
4672
                  !NewLogicalDeviceInfo->BackgroundInitializationInProgress)
4673
                DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) "
4674
                                "Background Initialization %s\n",
4675
                                Controller,
4676
                                LogicalDeviceNumber,
4677
                                Controller->ControllerNumber,
4678
                                LogicalDeviceNumber,
4679
                                (NewLogicalDeviceInfo->LogicalDeviceControl
4680
                                                      .LogicalDeviceInitialized
4681
                                 ? "Completed" : "Failed"));
4682
              memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
4683
                     sizeof(DAC960_V2_LogicalDeviceInfo_T));
4684
            }
4685
          Controller->V2.LogicalDriveFoundDuringScan
4686
                         [LogicalDeviceNumber] = true;
4687
          NewLogicalDeviceInfo->LogicalDeviceNumber++;
4688
        }
4689
      else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
4690
        {
4691
          int LogicalDriveNumber;
4692
          for (LogicalDriveNumber = 0;
4693
               LogicalDriveNumber < DAC960_MaxLogicalDrives;
4694
               LogicalDriveNumber++)
4695
            {
4696
              DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
4697
                Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
4698
              if (LogicalDeviceInfo == NULL ||
4699
                  Controller->V2.LogicalDriveFoundDuringScan
4700
                                 [LogicalDriveNumber])
4701
                continue;
4702
              DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
4703
                              "No Longer Exists\n", Controller,
4704
                              LogicalDriveNumber,
4705
                              Controller->ControllerNumber,
4706
                              LogicalDriveNumber);
4707
              Controller->V2.LogicalDeviceInformation
4708
                             [LogicalDriveNumber] = NULL;
4709
              kfree(LogicalDeviceInfo);
4710
              Controller->LogicalDriveInitiallyAccessible
4711
                          [LogicalDriveNumber] = false;
4712
              DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
4713
            }
4714
          Controller->V2.NeedLogicalDeviceInformation = false;
4715
        }
4716
      if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
4717
          - Controller->V2.NextEventSequenceNumber > 0)
4718
        {
4719
          CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
4720
          CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
4721
          CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
4722
            Controller->V2.NextEventSequenceNumber >> 16;
4723
          CommandMailbox->GetEvent.ControllerNumber = 0;
4724
          CommandMailbox->GetEvent.IOCTL_Opcode =
4725
            DAC960_V2_GetEvent;
4726
          CommandMailbox->GetEvent.EventSequenceNumberLow16 =
4727
            Controller->V2.NextEventSequenceNumber & 0xFFFF;
4728
          CommandMailbox->GetEvent.DataTransferMemoryAddress
4729
                                  .ScatterGatherSegments[0]
4730
                                  .SegmentDataPointer =
4731
            Virtual_to_Bus64(&Controller->V2.Event);
4732
          CommandMailbox->GetEvent.DataTransferMemoryAddress
4733
                                  .ScatterGatherSegments[0]
4734
                                  .SegmentByteCount =
4735
            CommandMailbox->GetEvent.DataTransferSize;
4736
          DAC960_QueueCommand(Command);
4737
          return;
4738
        }
4739
      if (Controller->V2.NeedPhysicalDeviceInformation)
4740
        {
4741
          if (Controller->V2.NeedDeviceSerialNumberInformation)
4742
            {
4743
              DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
4744
                Controller->V2.InquiryUnitSerialNumber
4745
                               [Controller->V2.PhysicalDeviceIndex - 1];
4746
              InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
4747
              CommandMailbox->SCSI_10.CommandOpcode =
4748
                DAC960_V2_SCSI_10_Passthru;
4749
              CommandMailbox->SCSI_10.DataTransferSize =
4750
                sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
4751
              CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
4752
                Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
4753
              CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
4754
                Controller->V2.NewPhysicalDeviceInformation.TargetID;
4755
              CommandMailbox->SCSI_10.PhysicalDevice.Channel =
4756
                Controller->V2.NewPhysicalDeviceInformation.Channel;
4757
              CommandMailbox->SCSI_10.CDBLength = 6;
4758
              CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
4759
              CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
4760
              CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
4761
              CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
4762
              CommandMailbox->SCSI_10.SCSI_CDB[4] =
4763
                sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
4764
              CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
4765
              CommandMailbox->SCSI_10.DataTransferMemoryAddress
4766
                                     .ScatterGatherSegments[0]
4767
                                     .SegmentDataPointer =
4768
                Virtual_to_Bus64(InquiryUnitSerialNumber);
4769
              CommandMailbox->SCSI_10.DataTransferMemoryAddress
4770
                                     .ScatterGatherSegments[0]
4771
                                     .SegmentByteCount =
4772
                CommandMailbox->SCSI_10.DataTransferSize;
4773
              DAC960_QueueCommand(Command);
4774
              Controller->V2.NeedDeviceSerialNumberInformation = false;
4775
              return;
4776
            }
4777
          if (Controller->V2.StartPhysicalDeviceInformationScan)
4778
            {
4779
              Controller->V2.PhysicalDeviceIndex = 0;
4780
              Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
4781
              Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
4782
              Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
4783
              Controller->V2.StartPhysicalDeviceInformationScan = false;
4784
            }
4785
          CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
4786
          CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
4787
            sizeof(DAC960_V2_PhysicalDeviceInfo_T);
4788
          CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
4789
            Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
4790
          CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
4791
            Controller->V2.NewPhysicalDeviceInformation.TargetID;
4792
          CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
4793
            Controller->V2.NewPhysicalDeviceInformation.Channel;
4794
          CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
4795
            DAC960_V2_GetPhysicalDeviceInfoValid;
4796
          CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
4797
                                            .ScatterGatherSegments[0]
4798
                                            .SegmentDataPointer =
4799
            Virtual_to_Bus64(&Controller->V2.NewPhysicalDeviceInformation);
4800
          CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
4801
                                            .ScatterGatherSegments[0]
4802
                                            .SegmentByteCount =
4803
            CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
4804
          DAC960_QueueCommand(Command);
4805
          return;
4806
        }
4807
      if (Controller->V2.NeedLogicalDeviceInformation)
4808
        {
4809
          if (Controller->V2.StartLogicalDeviceInformationScan)
4810
            {
4811
              int LogicalDriveNumber;
4812
              for (LogicalDriveNumber = 0;
4813
                   LogicalDriveNumber < DAC960_MaxLogicalDrives;
4814
                   LogicalDriveNumber++)
4815
                Controller->V2.LogicalDriveFoundDuringScan
4816
                               [LogicalDriveNumber] = false;
4817
              Controller->V2.NewLogicalDeviceInformation
4818
                            .LogicalDeviceNumber = 0;
4819
              Controller->V2.StartLogicalDeviceInformationScan = false;
4820
            }
4821
          CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
4822
          CommandMailbox->LogicalDeviceInfo.DataTransferSize =
4823
            sizeof(DAC960_V2_LogicalDeviceInfo_T);
4824
          CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
4825
            Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
4826
          CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
4827
            DAC960_V2_GetLogicalDeviceInfoValid;
4828
          CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
4829
                                           .ScatterGatherSegments[0]
4830
                                           .SegmentDataPointer =
4831
            Virtual_to_Bus64(&Controller->V2.NewLogicalDeviceInformation);
4832
          CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
4833
                                           .ScatterGatherSegments[0]
4834
                                           .SegmentByteCount =
4835
            CommandMailbox->LogicalDeviceInfo.DataTransferSize;
4836
          DAC960_QueueCommand(Command);
4837
          return;
4838
        }
4839
      Controller->MonitoringTimerCount++;
4840
      Controller->MonitoringTimer.expires =
4841
        jiffies + DAC960_HealthStatusMonitoringInterval;
4842
      add_timer(&Controller->MonitoringTimer);
4843
    }
4844
  if (CommandType == DAC960_ImmediateCommand)
4845
    {
4846
      complete(Command->Completion);
4847
      Command->Completion = NULL;
4848
      return;
4849
    }
4850
  if (CommandType == DAC960_QueuedCommand)
4851
    {
4852
      DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
4853
      KernelCommand->CommandStatus = CommandStatus;
4854
      KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
4855
      KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
4856
      Command->V2.KernelCommand = NULL;
4857
      DAC960_DeallocateCommand(Command);
4858
      KernelCommand->CompletionFunction(KernelCommand);
4859
      return;
4860
    }
4861
  /*
4862
    Queue a Status Monitoring Command to the Controller using the just
4863
    completed Command if one was deferred previously due to lack of a
4864
    free Command when the Monitoring Timer Function was called.
4865
  */
4866
  if (Controller->MonitoringCommandDeferred)
4867
    {
4868
      Controller->MonitoringCommandDeferred = false;
4869
      DAC960_V2_QueueMonitoringCommand(Command);
4870
      return;
4871
    }
4872
  /*
4873
    Deallocate the Command.
4874
  */
4875
  DAC960_DeallocateCommand(Command);
4876
  /*
4877
    Wake up any processes waiting on a free Command.
4878
  */
4879
  wake_up(&Controller->CommandWaitQueue);
4880
}
4881
 
4882
 
4883
/*
4884
  DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
4885
  Controllers.
4886
*/
4887
 
4888
static void DAC960_BA_InterruptHandler(int IRQ_Channel,
4889
                                       void *DeviceIdentifier,
4890
                                       Registers_T *InterruptRegisters)
4891
{
4892
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4893
  void *ControllerBaseAddress = Controller->BaseAddress;
4894
  DAC960_V2_StatusMailbox_T *NextStatusMailbox;
4895
  ProcessorFlags_T ProcessorFlags;
4896
  /*
4897
    Acquire exclusive access to Controller.
4898
  */
4899
  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4900
  /*
4901
    Process Hardware Interrupts for Controller.
4902
  */
4903
  DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
4904
  NextStatusMailbox = Controller->V2.NextStatusMailbox;
4905
  while (NextStatusMailbox->Fields.CommandIdentifier > 0)
4906
    {
4907
      DAC960_V2_CommandIdentifier_T CommandIdentifier =
4908
        NextStatusMailbox->Fields.CommandIdentifier;
4909
      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4910
      Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4911
      Command->V2.RequestSenseLength =
4912
        NextStatusMailbox->Fields.RequestSenseLength;
4913
      Command->V2.DataTransferResidue =
4914
        NextStatusMailbox->Fields.DataTransferResidue;
4915
      NextStatusMailbox->Words[0] = 0;
4916
      if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
4917
        NextStatusMailbox = Controller->V2.FirstStatusMailbox;
4918
      DAC960_V2_ProcessCompletedCommand(Command);
4919
    }
4920
  Controller->V2.NextStatusMailbox = NextStatusMailbox;
4921
  /*
4922
    Attempt to remove additional I/O Requests from the Controller's
4923
    I/O Request Queue and queue them to the Controller.
4924
  */
4925
  while (DAC960_ProcessRequest(Controller, false)) ;
4926
  /*
4927
    Release exclusive access to Controller.
4928
  */
4929
  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4930
}
4931
 
4932
 
4933
/*
4934
  DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
4935
  Controllers.
4936
*/
4937
 
4938
static void DAC960_LP_InterruptHandler(int IRQ_Channel,
4939
                                       void *DeviceIdentifier,
4940
                                       Registers_T *InterruptRegisters)
4941
{
4942
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4943
  void *ControllerBaseAddress = Controller->BaseAddress;
4944
  DAC960_V2_StatusMailbox_T *NextStatusMailbox;
4945
  ProcessorFlags_T ProcessorFlags;
4946
  /*
4947
    Acquire exclusive access to Controller.
4948
  */
4949
  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
4950
  /*
4951
    Process Hardware Interrupts for Controller.
4952
  */
4953
  DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
4954
  NextStatusMailbox = Controller->V2.NextStatusMailbox;
4955
  while (NextStatusMailbox->Fields.CommandIdentifier > 0)
4956
    {
4957
      DAC960_V2_CommandIdentifier_T CommandIdentifier =
4958
        NextStatusMailbox->Fields.CommandIdentifier;
4959
      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
4960
      Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
4961
      Command->V2.RequestSenseLength =
4962
        NextStatusMailbox->Fields.RequestSenseLength;
4963
      Command->V2.DataTransferResidue =
4964
        NextStatusMailbox->Fields.DataTransferResidue;
4965
      NextStatusMailbox->Words[0] = 0;
4966
      if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
4967
        NextStatusMailbox = Controller->V2.FirstStatusMailbox;
4968
      DAC960_V2_ProcessCompletedCommand(Command);
4969
    }
4970
  Controller->V2.NextStatusMailbox = NextStatusMailbox;
4971
  /*
4972
    Attempt to remove additional I/O Requests from the Controller's
4973
    I/O Request Queue and queue them to the Controller.
4974
  */
4975
  while (DAC960_ProcessRequest(Controller, false)) ;
4976
  /*
4977
    Release exclusive access to Controller.
4978
  */
4979
  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
4980
}
4981
 
4982
 
4983
/*
4984
  DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
4985
  Controllers.
4986
*/
4987
 
4988
static void DAC960_LA_InterruptHandler(int IRQ_Channel,
4989
                                       void *DeviceIdentifier,
4990
                                       Registers_T *InterruptRegisters)
4991
{
4992
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
4993
  void *ControllerBaseAddress = Controller->BaseAddress;
4994
  DAC960_V1_StatusMailbox_T *NextStatusMailbox;
4995
  ProcessorFlags_T ProcessorFlags;
4996
  /*
4997
    Acquire exclusive access to Controller.
4998
  */
4999
  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
5000
  /*
5001
    Process Hardware Interrupts for Controller.
5002
  */
5003
  DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
5004
  NextStatusMailbox = Controller->V1.NextStatusMailbox;
5005
  while (NextStatusMailbox->Fields.Valid)
5006
    {
5007
      DAC960_V1_CommandIdentifier_T CommandIdentifier =
5008
        NextStatusMailbox->Fields.CommandIdentifier;
5009
      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
5010
      Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
5011
      NextStatusMailbox->Word = 0;
5012
      if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
5013
        NextStatusMailbox = Controller->V1.FirstStatusMailbox;
5014
      DAC960_V1_ProcessCompletedCommand(Command);
5015
    }
5016
  Controller->V1.NextStatusMailbox = NextStatusMailbox;
5017
  /*
5018
    Attempt to remove additional I/O Requests from the Controller's
5019
    I/O Request Queue and queue them to the Controller.
5020
  */
5021
  while (DAC960_ProcessRequest(Controller, false)) ;
5022
  /*
5023
    Release exclusive access to Controller.
5024
  */
5025
  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
5026
}
5027
 
5028
 
5029
/*
5030
  DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
5031
  Controllers.
5032
*/
5033
 
5034
static void DAC960_PG_InterruptHandler(int IRQ_Channel,
5035
                                       void *DeviceIdentifier,
5036
                                       Registers_T *InterruptRegisters)
5037
{
5038
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
5039
  void *ControllerBaseAddress = Controller->BaseAddress;
5040
  DAC960_V1_StatusMailbox_T *NextStatusMailbox;
5041
  ProcessorFlags_T ProcessorFlags;
5042
  /*
5043
    Acquire exclusive access to Controller.
5044
  */
5045
  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
5046
  /*
5047
    Process Hardware Interrupts for Controller.
5048
  */
5049
  DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
5050
  NextStatusMailbox = Controller->V1.NextStatusMailbox;
5051
  while (NextStatusMailbox->Fields.Valid)
5052
    {
5053
      DAC960_V1_CommandIdentifier_T CommandIdentifier =
5054
        NextStatusMailbox->Fields.CommandIdentifier;
5055
      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
5056
      Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
5057
      NextStatusMailbox->Word = 0;
5058
      if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
5059
        NextStatusMailbox = Controller->V1.FirstStatusMailbox;
5060
      DAC960_V1_ProcessCompletedCommand(Command);
5061
    }
5062
  Controller->V1.NextStatusMailbox = NextStatusMailbox;
5063
  /*
5064
    Attempt to remove additional I/O Requests from the Controller's
5065
    I/O Request Queue and queue them to the Controller.
5066
  */
5067
  while (DAC960_ProcessRequest(Controller, false)) ;
5068
  /*
5069
    Release exclusive access to Controller.
5070
  */
5071
  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
5072
}
5073
 
5074
 
5075
/*
5076
  DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
5077
  Controllers.
5078
*/
5079
 
5080
static void DAC960_PD_InterruptHandler(int IRQ_Channel,
5081
                                       void *DeviceIdentifier,
5082
                                       Registers_T *InterruptRegisters)
5083
{
5084
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
5085
  void *ControllerBaseAddress = Controller->BaseAddress;
5086
  ProcessorFlags_T ProcessorFlags;
5087
  /*
5088
    Acquire exclusive access to Controller.
5089
  */
5090
  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
5091
  /*
5092
    Process Hardware Interrupts for Controller.
5093
  */
5094
  while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
5095
    {
5096
      DAC960_V1_CommandIdentifier_T CommandIdentifier =
5097
        DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
5098
      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
5099
      Command->V1.CommandStatus =
5100
        DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
5101
      DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
5102
      DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
5103
      DAC960_V1_ProcessCompletedCommand(Command);
5104
    }
5105
  /*
5106
    Attempt to remove additional I/O Requests from the Controller's
5107
    I/O Request Queue and queue them to the Controller.
5108
  */
5109
  while (DAC960_ProcessRequest(Controller, false)) ;
5110
  /*
5111
    Release exclusive access to Controller.
5112
  */
5113
  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
5114
}
5115
 
5116
 
5117
/*
5118
  DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series
5119
  Controllers.
5120
*/
5121
 
5122
static void DAC960_P_InterruptHandler(int IRQ_Channel,
5123
                                      void *DeviceIdentifier,
5124
                                      Registers_T *InterruptRegisters)
5125
{
5126
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
5127
  void *ControllerBaseAddress = Controller->BaseAddress;
5128
  ProcessorFlags_T ProcessorFlags;
5129
  /*
5130
    Acquire exclusive access to Controller.
5131
  */
5132
  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
5133
  /*
5134
    Process Hardware Interrupts for Controller.
5135
  */
5136
  while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
5137
    {
5138
      DAC960_V1_CommandIdentifier_T CommandIdentifier =
5139
        DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
5140
      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
5141
      DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
5142
      DAC960_V1_CommandOpcode_T CommandOpcode =
5143
        CommandMailbox->Common.CommandOpcode;
5144
      Command->V1.CommandStatus =
5145
        DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
5146
      DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
5147
      DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
5148
      switch (CommandOpcode)
5149
        {
5150
        case DAC960_V1_Enquiry_Old:
5151
          Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry;
5152
          DAC960_P_To_PD_TranslateEnquiry(
5153
            Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
5154
          break;
5155
        case DAC960_V1_GetDeviceState_Old:
5156
          Command->V1.CommandMailbox.Common.CommandOpcode =
5157
            DAC960_V1_GetDeviceState;
5158
          DAC960_P_To_PD_TranslateDeviceState(
5159
            Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
5160
          break;
5161
        case DAC960_V1_Read_Old:
5162
          Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read;
5163
          DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
5164
          break;
5165
        case DAC960_V1_Write_Old:
5166
          Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Write;
5167
          DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
5168
          break;
5169
        case DAC960_V1_ReadWithScatterGather_Old:
5170
          Command->V1.CommandMailbox.Common.CommandOpcode =
5171
            DAC960_V1_ReadWithScatterGather;
5172
          DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
5173
          break;
5174
        case DAC960_V1_WriteWithScatterGather_Old:
5175
          Command->V1.CommandMailbox.Common.CommandOpcode =
5176
            DAC960_V1_WriteWithScatterGather;
5177
          DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
5178
          break;
5179
        default:
5180
          break;
5181
        }
5182
      DAC960_V1_ProcessCompletedCommand(Command);
5183
    }
5184
  /*
5185
    Attempt to remove additional I/O Requests from the Controller's
5186
    I/O Request Queue and queue them to the Controller.
5187
  */
5188
  while (DAC960_ProcessRequest(Controller, false)) ;
5189
  /*
5190
    Release exclusive access to Controller.
5191
  */
5192
  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
5193
}
5194
 
5195
 
5196
/*
5197
  DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
5198
  Firmware Controllers.
5199
*/
5200
 
5201
static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
5202
{
5203
  DAC960_Controller_T *Controller = Command->Controller;
5204
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
5205
  DAC960_V1_ClearCommand(Command);
5206
  Command->CommandType = DAC960_MonitoringCommand;
5207
  CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
5208
  CommandMailbox->Type3.BusAddress =
5209
    Virtual_to_Bus32(&Controller->V1.NewEnquiry);
5210
  DAC960_QueueCommand(Command);
5211
}
5212
 
5213
 
5214
/*
5215
  DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
5216
  Firmware Controllers.
5217
*/
5218
 
5219
static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
5220
{
5221
  DAC960_Controller_T *Controller = Command->Controller;
5222
  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
5223
  DAC960_V2_ClearCommand(Command);
5224
  Command->CommandType = DAC960_MonitoringCommand;
5225
  CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
5226
  CommandMailbox->ControllerInfo.CommandControlBits
5227
                                .DataTransferControllerToHost = true;
5228
  CommandMailbox->ControllerInfo.CommandControlBits
5229
                                .NoAutoRequestSense = true;
5230
  CommandMailbox->ControllerInfo.DataTransferSize =
5231
    sizeof(DAC960_V2_ControllerInfo_T);
5232
  CommandMailbox->ControllerInfo.ControllerNumber = 0;
5233
  CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
5234
  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
5235
                                .ScatterGatherSegments[0]
5236
                                .SegmentDataPointer =
5237
    Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
5238
  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
5239
                                .ScatterGatherSegments[0]
5240
                                .SegmentByteCount =
5241
    CommandMailbox->ControllerInfo.DataTransferSize;
5242
  DAC960_QueueCommand(Command);
5243
}
5244
 
5245
 
5246
/*
5247
  DAC960_MonitoringTimerFunction is the timer function for monitoring
5248
  the status of DAC960 Controllers.
5249
*/
5250
 
5251
static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
5252
{
5253
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
5254
  DAC960_Command_T *Command;
5255
  ProcessorFlags_T ProcessorFlags;
5256
  if (Controller->FirmwareType == DAC960_V1_Controller)
5257
    {
5258
      /*
5259
        Acquire exclusive access to Controller.
5260
      */
5261
      DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5262
      /*
5263
        Queue a Status Monitoring Command to Controller.
5264
      */
5265
      Command = DAC960_AllocateCommand(Controller);
5266
      if (Command != NULL)
5267
        DAC960_V1_QueueMonitoringCommand(Command);
5268
      else Controller->MonitoringCommandDeferred = true;
5269
      /*
5270
        Release exclusive access to Controller.
5271
      */
5272
      DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5273
    }
5274
  else
5275
    {
5276
      DAC960_V2_ControllerInfo_T *ControllerInfo =
5277
        &Controller->V2.ControllerInformation;
5278
      unsigned int StatusChangeCounter =
5279
        Controller->V2.HealthStatusBuffer->StatusChangeCounter;
5280
      boolean ForceMonitoringCommand = false;
5281
      if (jiffies - Controller->SecondaryMonitoringTime
5282
          > DAC960_SecondaryMonitoringInterval)
5283
        {
5284
          int LogicalDriveNumber;
5285
          for (LogicalDriveNumber = 0;
5286
               LogicalDriveNumber < DAC960_MaxLogicalDrives;
5287
               LogicalDriveNumber++)
5288
            {
5289
              DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
5290
                Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
5291
              if (LogicalDeviceInfo == NULL) continue;
5292
              if (!LogicalDeviceInfo->LogicalDeviceControl
5293
                                     .LogicalDeviceInitialized)
5294
                {
5295
                  ForceMonitoringCommand = true;
5296
                  break;
5297
                }
5298
            }
5299
          Controller->SecondaryMonitoringTime = jiffies;
5300
        }
5301
      if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
5302
          Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
5303
          == Controller->V2.NextEventSequenceNumber &&
5304
          (ControllerInfo->BackgroundInitializationsActive +
5305
           ControllerInfo->LogicalDeviceInitializationsActive +
5306
           ControllerInfo->PhysicalDeviceInitializationsActive +
5307
           ControllerInfo->ConsistencyChecksActive +
5308
           ControllerInfo->RebuildsActive +
5309
           ControllerInfo->OnlineExpansionsActive == 0 ||
5310
           jiffies - Controller->PrimaryMonitoringTime
5311
           < DAC960_MonitoringTimerInterval) &&
5312
          !ForceMonitoringCommand)
5313
        {
5314
          Controller->MonitoringTimer.expires =
5315
            jiffies + DAC960_HealthStatusMonitoringInterval;
5316
          add_timer(&Controller->MonitoringTimer);
5317
          return;
5318
        }
5319
      Controller->V2.StatusChangeCounter = StatusChangeCounter;
5320
      Controller->PrimaryMonitoringTime = jiffies;
5321
      /*
5322
        Acquire exclusive access to Controller.
5323
      */
5324
      DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5325
      /*
5326
        Queue a Status Monitoring Command to Controller.
5327
      */
5328
      Command = DAC960_AllocateCommand(Controller);
5329
      if (Command != NULL)
5330
        DAC960_V2_QueueMonitoringCommand(Command);
5331
      else Controller->MonitoringCommandDeferred = true;
5332
      /*
5333
        Release exclusive access to Controller.
5334
      */
5335
      DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5336
      /*
5337
        Wake up any processes waiting on a Health Status Buffer change.
5338
      */
5339
      wake_up(&Controller->HealthStatusWaitQueue);
5340
    }
5341
}
5342
 
5343
 
5344
/*
5345
  DAC960_Open is the Device Open Function for the DAC960 Driver.
5346
*/
5347
 
5348
static int DAC960_Open(Inode_T *Inode, File_T *File)
5349
{
5350
  int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
5351
  int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
5352
  DAC960_Controller_T *Controller;
5353
  if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
5354
      (File->f_flags & O_NONBLOCK))
5355
    goto ModuleOnly;
5356
  if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
5357
    return -ENXIO;
5358
  Controller = DAC960_Controllers[ControllerNumber];
5359
  if (Controller == NULL) return -ENXIO;
5360
  if (Controller->FirmwareType == DAC960_V1_Controller)
5361
    {
5362
      if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
5363
        return -ENXIO;
5364
      if (Controller->V1.LogicalDriveInformation
5365
                         [LogicalDriveNumber].LogicalDriveState
5366
          == DAC960_V1_LogicalDrive_Offline)
5367
        return -ENXIO;
5368
    }
5369
  else
5370
    {
5371
      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
5372
        Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
5373
      if (LogicalDeviceInfo == NULL ||
5374
          LogicalDeviceInfo->LogicalDeviceState
5375
          == DAC960_V2_LogicalDevice_Offline)
5376
        return -ENXIO;
5377
    }
5378
  if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
5379
    {
5380
      Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
5381
      DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
5382
      DAC960_RegisterDisk(Controller, LogicalDriveNumber);
5383
    }
5384
  if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
5385
    return -ENXIO;
5386
  /*
5387
    Increment Controller and Logical Drive Usage Counts.
5388
  */
5389
  Controller->ControllerUsageCount++;
5390
  Controller->LogicalDriveUsageCount[LogicalDriveNumber]++;
5391
 ModuleOnly:
5392
  return 0;
5393
}
5394
 
5395
 
5396
/*
5397
  DAC960_Release is the Device Release Function for the DAC960 Driver.
5398
*/
5399
 
5400
static int DAC960_Release(Inode_T *Inode, File_T *File)
5401
{
5402
  int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
5403
  int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
5404
  DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
5405
  if (ControllerNumber == 0 && LogicalDriveNumber == 0 &&
5406
      File != NULL && (File->f_flags & O_NONBLOCK))
5407
    goto ModuleOnly;
5408
  /*
5409
    Decrement the Logical Drive and Controller Usage Counts.
5410
  */
5411
  Controller->LogicalDriveUsageCount[LogicalDriveNumber]--;
5412
  Controller->ControllerUsageCount--;
5413
 ModuleOnly:
5414
  return 0;
5415
}
5416
 
5417
 
5418
/*
5419
  DAC960_IOCTL is the Device IOCTL Function for the DAC960 Driver.
5420
*/
5421
 
5422
static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
5423
                        unsigned int Request, unsigned long Argument)
5424
{
5425
  int ControllerNumber = DAC960_ControllerNumber(Inode->i_rdev);
5426
  int LogicalDriveNumber = DAC960_LogicalDriveNumber(Inode->i_rdev);
5427
  DiskGeometry_T Geometry, *UserGeometry;
5428
  DAC960_Controller_T *Controller;
5429
  int PartitionNumber;
5430
  if (File != NULL && (File->f_flags & O_NONBLOCK))
5431
    return DAC960_UserIOCTL(Inode, File, Request, Argument);
5432
  if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
5433
    return -ENXIO;
5434
  Controller = DAC960_Controllers[ControllerNumber];
5435
  if (Controller == NULL) return -ENXIO;
5436
  switch (Request)
5437
    {
5438
    case HDIO_GETGEO:
5439
      /* Get BIOS Disk Geometry. */
5440
      UserGeometry = (DiskGeometry_T *) Argument;
5441
      if (UserGeometry == NULL) return -EINVAL;
5442
      if (Controller->FirmwareType == DAC960_V1_Controller)
5443
        {
5444
          if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
5445
            return -ENXIO;
5446
          Geometry.heads = Controller->V1.GeometryTranslationHeads;
5447
          Geometry.sectors = Controller->V1.GeometryTranslationSectors;
5448
          Geometry.cylinders =
5449
            Controller->V1.LogicalDriveInformation[LogicalDriveNumber]
5450
                                                  .LogicalDriveSize
5451
            / (Geometry.heads * Geometry.sectors);
5452
        }
5453
      else
5454
        {
5455
          DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
5456
            Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
5457
          if (LogicalDeviceInfo == NULL)
5458
            return -EINVAL;
5459
          switch (LogicalDeviceInfo->DriveGeometry)
5460
            {
5461
            case DAC960_V2_Geometry_128_32:
5462
              Geometry.heads = 128;
5463
              Geometry.sectors = 32;
5464
              break;
5465
            case DAC960_V2_Geometry_255_63:
5466
              Geometry.heads = 255;
5467
              Geometry.sectors = 63;
5468
              break;
5469
            default:
5470
              DAC960_Error("Illegal Logical Device Geometry %d\n",
5471
                           Controller, LogicalDeviceInfo->DriveGeometry);
5472
              return -EINVAL;
5473
            }
5474
          Geometry.cylinders =
5475
            LogicalDeviceInfo->ConfigurableDeviceSize
5476
            / (Geometry.heads * Geometry.sectors);
5477
        }
5478
      Geometry.start =
5479
        Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
5480
      return (copy_to_user(UserGeometry, &Geometry,
5481
                           sizeof(DiskGeometry_T)) ? -EFAULT : 0);
5482
    case BLKGETSIZE:
5483
      /* Get Device Size. */
5484
      if ((unsigned long *) Argument == NULL) return -EINVAL;
5485
      return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
5486
                                                 .nr_sects,
5487
                      (unsigned long *) Argument);
5488
    case BLKGETSIZE64:
5489
      if ((u64 *) Argument == NULL) return -EINVAL;
5490
      return put_user((u64) Controller->GenericDiskInfo
5491
                                       .part[MINOR(Inode->i_rdev)]
5492
                                       .nr_sects << 9,
5493
                      (u64 *) Argument);
5494
    case BLKRAGET:
5495
    case BLKRASET:
5496
    case BLKFLSBUF:
5497
    case BLKBSZGET:
5498
    case BLKBSZSET:
5499
      return blk_ioctl(Inode->i_rdev, Request, Argument);
5500
    case BLKRRPART:
5501
      /* Re-Read Partition Table. */
5502
      if (!capable(CAP_SYS_ADMIN)) return -EACCES;
5503
      if (Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 1)
5504
        return -EBUSY;
5505
      for (PartitionNumber = 0;
5506
           PartitionNumber < DAC960_MaxPartitions;
5507
           PartitionNumber++)
5508
        {
5509
          KernelDevice_T Device = DAC960_KernelDevice(ControllerNumber,
5510
                                                      LogicalDriveNumber,
5511
                                                      PartitionNumber);
5512
          int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber,
5513
                                               PartitionNumber);
5514
          if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0)
5515
            continue;
5516
          /*
5517
            Flush all changes and invalidate buffered state.
5518
          */
5519
          invalidate_device(Device, 1);
5520
          /*
5521
            Clear existing partition sizes.
5522
          */
5523
          if (PartitionNumber > 0)
5524
            {
5525
              Controller->GenericDiskInfo.part[MinorNumber].start_sect = 0;
5526
              Controller->GenericDiskInfo.part[MinorNumber].nr_sects = 0;
5527
            }
5528
          /*
5529
            Reset the Block Size so that the partition table can be read.
5530
          */
5531
          set_blocksize(Device, BLOCK_SIZE);
5532
        }
5533
      DAC960_RegisterDisk(Controller, LogicalDriveNumber);
5534
      return 0;
5535
    }
5536
  return -EINVAL;
5537
}
5538
 
5539
 
5540
/*
5541
  DAC960_UserIOCTL is the User IOCTL Function for the DAC960 Driver.
5542
*/
5543
 
5544
static int DAC960_UserIOCTL(Inode_T *Inode, File_T *File,
5545
                            unsigned int Request, unsigned long Argument)
5546
{
5547
  int ErrorCode = 0 ;
5548
  if (!capable(CAP_SYS_ADMIN)) return -EACCES;
5549
  switch (Request)
5550
    {
5551
    case DAC960_IOCTL_GET_CONTROLLER_COUNT:
5552
      return DAC960_ControllerCount;
5553
    case DAC960_IOCTL_GET_CONTROLLER_INFO:
5554
      {
5555
        DAC960_ControllerInfo_T *UserSpaceControllerInfo =
5556
          (DAC960_ControllerInfo_T *) Argument;
5557
        DAC960_ControllerInfo_T ControllerInfo;
5558
        DAC960_Controller_T *Controller;
5559
        int ControllerNumber;
5560
        if (UserSpaceControllerInfo == NULL) return -EINVAL;
5561
        ErrorCode = get_user(ControllerNumber,
5562
                             &UserSpaceControllerInfo->ControllerNumber);
5563
        if (ErrorCode != 0) return ErrorCode;
5564
        if (ControllerNumber < 0 ||
5565
            ControllerNumber > DAC960_ControllerCount - 1)
5566
          return -ENXIO;
5567
        Controller = DAC960_Controllers[ControllerNumber];
5568
        if (Controller == NULL) return -ENXIO;
5569
        memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
5570
        ControllerInfo.ControllerNumber = ControllerNumber;
5571
        ControllerInfo.FirmwareType = Controller->FirmwareType;
5572
        ControllerInfo.Channels = Controller->Channels;
5573
        ControllerInfo.Targets = Controller->Targets;
5574
        ControllerInfo.PCI_Bus = Controller->Bus;
5575
        ControllerInfo.PCI_Device = Controller->Device;
5576
        ControllerInfo.PCI_Function = Controller->Function;
5577
        ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
5578
        ControllerInfo.PCI_Address = Controller->PCI_Address;
5579
        strcpy(ControllerInfo.ModelName, Controller->ModelName);
5580
        strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
5581
        return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
5582
                             sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
5583
      }
5584
    case DAC960_IOCTL_V1_EXECUTE_COMMAND:
5585
      {
5586
        DAC960_V1_UserCommand_T *UserSpaceUserCommand =
5587
          (DAC960_V1_UserCommand_T *) Argument;
5588
        DAC960_V1_UserCommand_T UserCommand;
5589
        DAC960_Controller_T *Controller;
5590
        DAC960_Command_T *Command = NULL;
5591
        DAC960_V1_CommandOpcode_T CommandOpcode;
5592
        DAC960_V1_CommandStatus_T CommandStatus;
5593
        DAC960_V1_DCDB_T DCDB;
5594
        ProcessorFlags_T ProcessorFlags;
5595
        int ControllerNumber, DataTransferLength;
5596
        unsigned char *DataTransferBuffer = NULL;
5597
        if (UserSpaceUserCommand == NULL) return -EINVAL;
5598
        if (copy_from_user(&UserCommand, UserSpaceUserCommand,
5599
                                   sizeof(DAC960_V1_UserCommand_T))) {
5600
                ErrorCode = -EFAULT;
5601
                goto Failure1;
5602
        }
5603
        ControllerNumber = UserCommand.ControllerNumber;
5604
        if (ControllerNumber < 0 ||
5605
            ControllerNumber > DAC960_ControllerCount - 1)
5606
          return -ENXIO;
5607
        Controller = DAC960_Controllers[ControllerNumber];
5608
        if (Controller == NULL) return -ENXIO;
5609
        if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
5610
        CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
5611
        DataTransferLength = UserCommand.DataTransferLength;
5612
        if (CommandOpcode & 0x80) return -EINVAL;
5613
        if (CommandOpcode == DAC960_V1_DCDB)
5614
          {
5615
            if (copy_from_user(&DCDB, UserCommand.DCDB,
5616
                               sizeof(DAC960_V1_DCDB_T))) {
5617
                ErrorCode = -EFAULT;
5618
                goto Failure1;
5619
            }
5620
            if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL;
5621
            if (!((DataTransferLength == 0 &&
5622
                   DCDB.Direction
5623
                   == DAC960_V1_DCDB_NoDataTransfer) ||
5624
                  (DataTransferLength > 0 &&
5625
                   DCDB.Direction
5626
                   == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
5627
                  (DataTransferLength < 0 &&
5628
                   DCDB.Direction
5629
                   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
5630
              return -EINVAL;
5631
            if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
5632
                != abs(DataTransferLength))
5633
              return -EINVAL;
5634
          }
5635
        if (DataTransferLength > 0)
5636
          {
5637
            DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
5638
            if (DataTransferBuffer == NULL) return -ENOMEM;
5639
            memset(DataTransferBuffer, 0, DataTransferLength);
5640
          }
5641
        else if (DataTransferLength < 0)
5642
          {
5643
            DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
5644
            if (DataTransferBuffer == NULL) return -ENOMEM;
5645
            if (copy_from_user(DataTransferBuffer,
5646
                               UserCommand.DataTransferBuffer,
5647
                               -DataTransferLength)) {
5648
                ErrorCode = -EFAULT;
5649
                goto Failure1;
5650
            }
5651
          }
5652
        if (CommandOpcode == DAC960_V1_DCDB)
5653
          {
5654
            DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5655
            while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5656
              DAC960_WaitForCommand(Controller);
5657
            while (Controller->V1.DirectCommandActive[DCDB.Channel]
5658
                                                     [DCDB.TargetID])
5659
              {
5660
                spin_unlock_irq(&io_request_lock);
5661
                __wait_event(Controller->CommandWaitQueue,
5662
                             !Controller->V1.DirectCommandActive
5663
                                             [DCDB.Channel][DCDB.TargetID]);
5664
                spin_lock_irq(&io_request_lock);
5665
              }
5666
            Controller->V1.DirectCommandActive[DCDB.Channel]
5667
                                              [DCDB.TargetID] = true;
5668
            DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5669
            DAC960_V1_ClearCommand(Command);
5670
            Command->CommandType = DAC960_ImmediateCommand;
5671
            memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
5672
                   sizeof(DAC960_V1_CommandMailbox_T));
5673
            Command->V1.CommandMailbox.Type3.BusAddress =
5674
              Virtual_to_Bus32(&DCDB);
5675
            DCDB.BusAddress = Virtual_to_Bus32(DataTransferBuffer);
5676
          }
5677
        else
5678
          {
5679
            DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5680
            while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5681
              DAC960_WaitForCommand(Controller);
5682
            DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5683
            DAC960_V1_ClearCommand(Command);
5684
            Command->CommandType = DAC960_ImmediateCommand;
5685
            memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
5686
                   sizeof(DAC960_V1_CommandMailbox_T));
5687
            if (DataTransferBuffer != NULL)
5688
              Command->V1.CommandMailbox.Type3.BusAddress =
5689
                Virtual_to_Bus32(DataTransferBuffer);
5690
          }
5691
        DAC960_ExecuteCommand(Command);
5692
        CommandStatus = Command->V1.CommandStatus;
5693
        DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5694
        DAC960_DeallocateCommand(Command);
5695
        DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5696
        if (DataTransferLength > 0)
5697
          {
5698
            if (copy_to_user(UserCommand.DataTransferBuffer,
5699
                             DataTransferBuffer, DataTransferLength))
5700
                ErrorCode = -EFAULT;
5701
                goto Failure1;
5702
          }
5703
        if (CommandOpcode == DAC960_V1_DCDB)
5704
          {
5705
            Controller->V1.DirectCommandActive[DCDB.Channel]
5706
                                              [DCDB.TargetID] = false;
5707
            if (copy_to_user(UserCommand.DCDB, &DCDB,
5708
                             sizeof(DAC960_V1_DCDB_T))) {
5709
                ErrorCode = -EFAULT;
5710
                goto Failure1;
5711
            }
5712
          }
5713
        ErrorCode = CommandStatus;
5714
      Failure1:
5715
        if (DataTransferBuffer != NULL)
5716
          kfree(DataTransferBuffer);
5717
        return ErrorCode;
5718
      }
5719
    case DAC960_IOCTL_V2_EXECUTE_COMMAND:
5720
      {
5721
        DAC960_V2_UserCommand_T *UserSpaceUserCommand =
5722
          (DAC960_V2_UserCommand_T *) Argument;
5723
        DAC960_V2_UserCommand_T UserCommand;
5724
        DAC960_Controller_T *Controller;
5725
        DAC960_Command_T *Command = NULL;
5726
        DAC960_V2_CommandMailbox_T *CommandMailbox;
5727
        DAC960_V2_CommandStatus_T CommandStatus;
5728
        ProcessorFlags_T ProcessorFlags;
5729
        int ControllerNumber, DataTransferLength;
5730
        int DataTransferResidue, RequestSenseLength;
5731
        unsigned char *DataTransferBuffer = NULL;
5732
        unsigned char *RequestSenseBuffer = NULL;
5733
        if (UserSpaceUserCommand == NULL) return -EINVAL;
5734
        if (copy_from_user(&UserCommand, UserSpaceUserCommand,
5735
                           sizeof(DAC960_V2_UserCommand_T))) {
5736
                ErrorCode = -EFAULT;
5737
                goto Failure2;
5738
        }
5739
        ControllerNumber = UserCommand.ControllerNumber;
5740
        if (ControllerNumber < 0 ||
5741
            ControllerNumber > DAC960_ControllerCount - 1)
5742
          return -ENXIO;
5743
        Controller = DAC960_Controllers[ControllerNumber];
5744
        if (Controller == NULL) return -ENXIO;
5745
        if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5746
        DataTransferLength = UserCommand.DataTransferLength;
5747
        if (DataTransferLength > 0)
5748
          {
5749
            DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
5750
            if (DataTransferBuffer == NULL) return -ENOMEM;
5751
            memset(DataTransferBuffer, 0, DataTransferLength);
5752
          }
5753
        else if (DataTransferLength < 0)
5754
          {
5755
            DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
5756
            if (DataTransferBuffer == NULL) return -ENOMEM;
5757
            if (copy_from_user(DataTransferBuffer,
5758
                               UserCommand.DataTransferBuffer,
5759
                               -DataTransferLength)) {
5760
                ErrorCode = -EFAULT;
5761
                goto Failure2;
5762
            }
5763
          }
5764
        RequestSenseLength = UserCommand.RequestSenseLength;
5765
        if (RequestSenseLength > 0)
5766
          {
5767
            RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
5768
            if (RequestSenseBuffer == NULL)
5769
              {
5770
                ErrorCode = -ENOMEM;
5771
                goto Failure2;
5772
              }
5773
            memset(RequestSenseBuffer, 0, RequestSenseLength);
5774
          }
5775
        DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5776
        while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
5777
          DAC960_WaitForCommand(Controller);
5778
        DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5779
        DAC960_V2_ClearCommand(Command);
5780
        Command->CommandType = DAC960_ImmediateCommand;
5781
        CommandMailbox = &Command->V2.CommandMailbox;
5782
        memcpy(CommandMailbox, &UserCommand.CommandMailbox,
5783
               sizeof(DAC960_V2_CommandMailbox_T));
5784
        CommandMailbox->Common.CommandControlBits
5785
                              .AdditionalScatterGatherListMemory = false;
5786
        CommandMailbox->Common.CommandControlBits
5787
                              .NoAutoRequestSense = true;
5788
        CommandMailbox->Common.DataTransferSize = 0;
5789
        CommandMailbox->Common.DataTransferPageNumber = 0;
5790
        memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
5791
               sizeof(DAC960_V2_DataTransferMemoryAddress_T));
5792
        if (DataTransferLength != 0)
5793
          {
5794
            if (DataTransferLength > 0)
5795
              {
5796
                CommandMailbox->Common.CommandControlBits
5797
                                      .DataTransferControllerToHost = true;
5798
                CommandMailbox->Common.DataTransferSize = DataTransferLength;
5799
              }
5800
            else
5801
              {
5802
                CommandMailbox->Common.CommandControlBits
5803
                                      .DataTransferControllerToHost = false;
5804
                CommandMailbox->Common.DataTransferSize = -DataTransferLength;
5805
              }
5806
            CommandMailbox->Common.DataTransferMemoryAddress
5807
                                  .ScatterGatherSegments[0]
5808
                                  .SegmentDataPointer =
5809
              Virtual_to_Bus64(DataTransferBuffer);
5810
            CommandMailbox->Common.DataTransferMemoryAddress
5811
                                  .ScatterGatherSegments[0]
5812
                                  .SegmentByteCount =
5813
              CommandMailbox->Common.DataTransferSize;
5814
          }
5815
        if (RequestSenseLength > 0)
5816
          {
5817
            CommandMailbox->Common.CommandControlBits
5818
                                  .NoAutoRequestSense = false;
5819
            CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
5820
            CommandMailbox->Common.RequestSenseBusAddress =
5821
              Virtual_to_Bus64(RequestSenseBuffer);
5822
          }
5823
        DAC960_ExecuteCommand(Command);
5824
        CommandStatus = Command->V2.CommandStatus;
5825
        RequestSenseLength = Command->V2.RequestSenseLength;
5826
        DataTransferResidue = Command->V2.DataTransferResidue;
5827
        DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5828
        DAC960_DeallocateCommand(Command);
5829
        DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
5830
        if (RequestSenseLength > UserCommand.RequestSenseLength)
5831
          RequestSenseLength = UserCommand.RequestSenseLength;
5832
        if (copy_to_user(&UserSpaceUserCommand->DataTransferLength,
5833
                                 &DataTransferResidue,
5834
                                 sizeof(DataTransferResidue))) {
5835
                ErrorCode = -EFAULT;
5836
                goto Failure2;
5837
        }
5838
        if (copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
5839
                         &RequestSenseLength, sizeof(RequestSenseLength))) {
5840
                ErrorCode = -EFAULT;
5841
                goto Failure2;
5842
        }
5843
        if (DataTransferLength > 0)
5844
          {
5845
            if (copy_to_user(UserCommand.DataTransferBuffer,
5846
                             DataTransferBuffer, DataTransferLength)) {
5847
                ErrorCode = -EFAULT;
5848
                goto Failure2;
5849
            }
5850
          }
5851
        if (RequestSenseLength > 0)
5852
          {
5853
            if (copy_to_user(UserCommand.RequestSenseBuffer,
5854
                             RequestSenseBuffer, RequestSenseLength)) {
5855
                ErrorCode = -EFAULT;
5856
                goto Failure2;
5857
            }
5858
          }
5859
        ErrorCode = CommandStatus;
5860
      Failure2:
5861
        if (DataTransferBuffer != NULL)
5862
          kfree(DataTransferBuffer);
5863
        if (RequestSenseBuffer != NULL)
5864
          kfree(RequestSenseBuffer);
5865
        return ErrorCode;
5866
      }
5867
    case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
5868
      {
5869
        DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
5870
          (DAC960_V2_GetHealthStatus_T *) Argument;
5871
        DAC960_V2_GetHealthStatus_T GetHealthStatus;
5872
        DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
5873
        DAC960_Controller_T *Controller;
5874
        int ControllerNumber;
5875
        if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
5876
        if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
5877
                           sizeof(DAC960_V2_GetHealthStatus_T)))
5878
                return -EFAULT;
5879
        ControllerNumber = GetHealthStatus.ControllerNumber;
5880
        if (ControllerNumber < 0 ||
5881
            ControllerNumber > DAC960_ControllerCount - 1)
5882
          return -ENXIO;
5883
        Controller = DAC960_Controllers[ControllerNumber];
5884
        if (Controller == NULL) return -ENXIO;
5885
        if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
5886
        if (copy_from_user(&HealthStatusBuffer,
5887
                           GetHealthStatus.HealthStatusBuffer,
5888
                           sizeof(DAC960_V2_HealthStatusBuffer_T)))
5889
                return -EFAULT;
5890
        while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
5891
               == HealthStatusBuffer.StatusChangeCounter &&
5892
               Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
5893
               == HealthStatusBuffer.NextEventSequenceNumber)
5894
          {
5895
            interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
5896
                                           DAC960_MonitoringTimerInterval);
5897
            if (signal_pending(current)) return -EINTR;
5898
          }
5899
        if (copy_to_user(GetHealthStatus.HealthStatusBuffer,
5900
                         Controller->V2.HealthStatusBuffer,
5901
                         sizeof(DAC960_V2_HealthStatusBuffer_T)))
5902
                return -EFAULT;
5903
        return 0;
5904
      }
5905
    }
5906
  return -EINVAL;
5907
}
5908
 
5909
 
5910
/*
5911
  DAC960_KernelIOCTL is the Kernel IOCTL Function for the DAC960 Driver.
5912
*/
5913
 
5914
int DAC960_KernelIOCTL(unsigned int Request, void *Argument)
5915
{
5916
  switch (Request)
5917
    {
5918
    case DAC960_IOCTL_GET_CONTROLLER_COUNT:
5919
      return DAC960_ControllerCount;
5920
    case DAC960_IOCTL_GET_CONTROLLER_INFO:
5921
      {
5922
        DAC960_ControllerInfo_T *ControllerInfo =
5923
          (DAC960_ControllerInfo_T *) Argument;
5924
        DAC960_Controller_T *Controller;
5925
        int ControllerNumber;
5926
        if (ControllerInfo == NULL) return -EINVAL;
5927
        ControllerNumber = ControllerInfo->ControllerNumber;
5928
        if (ControllerNumber < 0 ||
5929
            ControllerNumber > DAC960_ControllerCount - 1)
5930
          return -ENXIO;
5931
        Controller = DAC960_Controllers[ControllerNumber];
5932
        if (Controller == NULL) return -ENXIO;
5933
        memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
5934
        ControllerInfo->ControllerNumber = ControllerNumber;
5935
        ControllerInfo->FirmwareType = Controller->FirmwareType;
5936
        ControllerInfo->Channels = Controller->Channels;
5937
        ControllerInfo->Targets = Controller->Targets;
5938
        ControllerInfo->PCI_Bus = Controller->Bus;
5939
        ControllerInfo->PCI_Device = Controller->Device;
5940
        ControllerInfo->PCI_Function = Controller->Function;
5941
        ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
5942
        ControllerInfo->PCI_Address = Controller->PCI_Address;
5943
        strcpy(ControllerInfo->ModelName, Controller->ModelName);
5944
        strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
5945
        return 0;
5946
      }
5947
    case DAC960_IOCTL_V1_EXECUTE_COMMAND:
5948
      {
5949
        DAC960_V1_KernelCommand_T *KernelCommand =
5950
          (DAC960_V1_KernelCommand_T *) Argument;
5951
        DAC960_Controller_T *Controller;
5952
        DAC960_Command_T *Command = NULL;
5953
        DAC960_V1_CommandOpcode_T CommandOpcode;
5954
        DAC960_V1_DCDB_T *DCDB = NULL;
5955
        ProcessorFlags_T ProcessorFlags;
5956
        int ControllerNumber, DataTransferLength;
5957
        unsigned char *DataTransferBuffer = NULL;
5958
        if (KernelCommand == NULL) return -EINVAL;
5959
        ControllerNumber = KernelCommand->ControllerNumber;
5960
        if (ControllerNumber < 0 ||
5961
            ControllerNumber > DAC960_ControllerCount - 1)
5962
          return -ENXIO;
5963
        Controller = DAC960_Controllers[ControllerNumber];
5964
        if (Controller == NULL) return -ENXIO;
5965
        if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
5966
        CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
5967
        DataTransferLength = KernelCommand->DataTransferLength;
5968
        DataTransferBuffer = KernelCommand->DataTransferBuffer;
5969
        if (CommandOpcode & 0x80) return -EINVAL;
5970
        if (CommandOpcode == DAC960_V1_DCDB)
5971
          {
5972
            DCDB = KernelCommand->DCDB;
5973
            if (DCDB->Channel >= DAC960_V1_MaxChannels) return -EINVAL;
5974
            if (!((DataTransferLength == 0 &&
5975
                   DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
5976
                  (DataTransferLength > 0 &&
5977
                   DCDB->Direction
5978
                   == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
5979
                  (DataTransferLength < 0 &&
5980
                   DCDB->Direction
5981
                   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
5982
              return -EINVAL;
5983
            if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
5984
                != abs(DataTransferLength))
5985
              return -EINVAL;
5986
          }
5987
        if (DataTransferLength != 0 && DataTransferBuffer == NULL)
5988
          return -EINVAL;
5989
        if (DataTransferLength > 0)
5990
          memset(DataTransferBuffer, 0, DataTransferLength);
5991
        if (CommandOpcode == DAC960_V1_DCDB)
5992
          {
5993
            DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
5994
            if (!Controller->V1.DirectCommandActive[DCDB->Channel]
5995
                                                   [DCDB->TargetID])
5996
              Command = DAC960_AllocateCommand(Controller);
5997
            if (Command == NULL)
5998
              {
5999
                DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6000
                return -EBUSY;
6001
              }
6002
            else Controller->V1.DirectCommandActive[DCDB->Channel]
6003
                                                   [DCDB->TargetID] = true;
6004
            DAC960_V1_ClearCommand(Command);
6005
            Command->CommandType = DAC960_QueuedCommand;
6006
            memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
6007
                   sizeof(DAC960_V1_CommandMailbox_T));
6008
            Command->V1.CommandMailbox.Type3.BusAddress =
6009
              Virtual_to_Bus32(DCDB);
6010
            Command->V1.KernelCommand = KernelCommand;
6011
            DCDB->BusAddress = Virtual_to_Bus32(DataTransferBuffer);
6012
            DAC960_QueueCommand(Command);
6013
            DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6014
          }
6015
        else
6016
          {
6017
            DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6018
            Command = DAC960_AllocateCommand(Controller);
6019
            if (Command == NULL)
6020
              {
6021
                DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6022
                return -EBUSY;
6023
              }
6024
            DAC960_V1_ClearCommand(Command);
6025
            Command->CommandType = DAC960_QueuedCommand;
6026
            memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
6027
                   sizeof(DAC960_V1_CommandMailbox_T));
6028
            if (DataTransferBuffer != NULL)
6029
              Command->V1.CommandMailbox.Type3.BusAddress =
6030
                Virtual_to_Bus32(DataTransferBuffer);
6031
            Command->V1.KernelCommand = KernelCommand;
6032
            DAC960_QueueCommand(Command);
6033
            DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6034
          }
6035
        return 0;
6036
      }
6037
    case DAC960_IOCTL_V2_EXECUTE_COMMAND:
6038
      {
6039
        DAC960_V2_KernelCommand_T *KernelCommand =
6040
          (DAC960_V2_KernelCommand_T *) Argument;
6041
        DAC960_Controller_T *Controller;
6042
        DAC960_Command_T *Command = NULL;
6043
        DAC960_V2_CommandMailbox_T *CommandMailbox;
6044
        ProcessorFlags_T ProcessorFlags;
6045
        int ControllerNumber, DataTransferLength, RequestSenseLength;
6046
        unsigned char *DataTransferBuffer = NULL;
6047
        unsigned char *RequestSenseBuffer = NULL;
6048
        if (KernelCommand == NULL) return -EINVAL;
6049
        ControllerNumber = KernelCommand->ControllerNumber;
6050
        if (ControllerNumber < 0 ||
6051
            ControllerNumber > DAC960_ControllerCount - 1)
6052
          return -ENXIO;
6053
        Controller = DAC960_Controllers[ControllerNumber];
6054
        if (Controller == NULL) return -ENXIO;
6055
        if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
6056
        DataTransferLength = KernelCommand->DataTransferLength;
6057
        RequestSenseLength = KernelCommand->RequestSenseLength;
6058
        DataTransferBuffer = KernelCommand->DataTransferBuffer;
6059
        RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
6060
        if (DataTransferLength != 0 && DataTransferBuffer == NULL)
6061
          return -EINVAL;
6062
        if (RequestSenseLength < 0)
6063
          return -EINVAL;
6064
        if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
6065
          return -EINVAL;
6066
        if (DataTransferLength > 0)
6067
          memset(DataTransferBuffer, 0, DataTransferLength);
6068
        if (RequestSenseLength > 0)
6069
          memset(RequestSenseBuffer, 0, RequestSenseLength);
6070
        DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6071
        Command = DAC960_AllocateCommand(Controller);
6072
        if (Command == NULL)
6073
          {
6074
            DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6075
            return -EBUSY;
6076
          }
6077
        DAC960_V2_ClearCommand(Command);
6078
        Command->CommandType = DAC960_QueuedCommand;
6079
        CommandMailbox = &Command->V2.CommandMailbox;
6080
        memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
6081
               sizeof(DAC960_V2_CommandMailbox_T));
6082
        CommandMailbox->Common.CommandControlBits
6083
                              .AdditionalScatterGatherListMemory = false;
6084
        CommandMailbox->Common.CommandControlBits
6085
                              .NoAutoRequestSense = true;
6086
        CommandMailbox->Common.DataTransferSize = 0;
6087
        CommandMailbox->Common.DataTransferPageNumber = 0;
6088
        memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
6089
               sizeof(DAC960_V2_DataTransferMemoryAddress_T));
6090
        if (DataTransferLength != 0)
6091
          {
6092
            if (DataTransferLength > 0)
6093
              {
6094
                CommandMailbox->Common.CommandControlBits
6095
                                      .DataTransferControllerToHost = true;
6096
                CommandMailbox->Common.DataTransferSize = DataTransferLength;
6097
              }
6098
            else
6099
              {
6100
                CommandMailbox->Common.CommandControlBits
6101
                                      .DataTransferControllerToHost = false;
6102
                CommandMailbox->Common.DataTransferSize = -DataTransferLength;
6103
              }
6104
            CommandMailbox->Common.DataTransferMemoryAddress
6105
                                  .ScatterGatherSegments[0]
6106
                                  .SegmentDataPointer =
6107
              Virtual_to_Bus64(DataTransferBuffer);
6108
            CommandMailbox->Common.DataTransferMemoryAddress
6109
                                  .ScatterGatherSegments[0]
6110
                                  .SegmentByteCount =
6111
              CommandMailbox->Common.DataTransferSize;
6112
          }
6113
        if (RequestSenseLength > 0)
6114
          {
6115
            CommandMailbox->Common.CommandControlBits
6116
                                  .NoAutoRequestSense = false;
6117
            CommandMailbox->Common.RequestSenseBusAddress =
6118
              Virtual_to_Bus64(RequestSenseBuffer);
6119
          }
6120
        Command->V2.KernelCommand = KernelCommand;
6121
        DAC960_QueueCommand(Command);
6122
        DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6123
        return 0;
6124
      }
6125
    }
6126
  return -EINVAL;
6127
}
6128
 
6129
 
6130
/*
6131
  DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
6132
  additional bytes in the Combined Status Buffer and grows the buffer if
6133
  necessary.  It returns true if there is enough room and false otherwise.
6134
*/
6135
 
6136
static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
6137
                                        unsigned int ByteCount)
6138
{
6139
  unsigned char *NewStatusBuffer;
6140
  if (Controller->InitialStatusLength + 1 +
6141
      Controller->CurrentStatusLength + ByteCount + 1 <=
6142
      Controller->CombinedStatusBufferLength)
6143
    return true;
6144
  if (Controller->CombinedStatusBufferLength == 0)
6145
    {
6146
      unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
6147
      while (NewStatusBufferLength < ByteCount)
6148
        NewStatusBufferLength *= 2;
6149
      Controller->CombinedStatusBuffer =
6150
        (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
6151
      if (Controller->CombinedStatusBuffer == NULL) return false;
6152
      Controller->CombinedStatusBufferLength = NewStatusBufferLength;
6153
      return true;
6154
    }
6155
  NewStatusBuffer = (unsigned char *)
6156
    kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
6157
  if (NewStatusBuffer == NULL)
6158
    {
6159
      DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
6160
                     Controller);
6161
      return false;
6162
    }
6163
  memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
6164
         Controller->CombinedStatusBufferLength);
6165
  kfree(Controller->CombinedStatusBuffer);
6166
  Controller->CombinedStatusBuffer = NewStatusBuffer;
6167
  Controller->CombinedStatusBufferLength *= 2;
6168
  Controller->CurrentStatusBuffer =
6169
    &NewStatusBuffer[Controller->InitialStatusLength + 1];
6170
  return true;
6171
}
6172
 
6173
 
6174
/*
6175
  DAC960_Message prints Driver Messages.
6176
*/
6177
 
6178
static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
6179
                           unsigned char *Format,
6180
                           DAC960_Controller_T *Controller,
6181
                           ...)
6182
{
6183
  static unsigned char Buffer[DAC960_LineBufferSize];
6184
  static boolean BeginningOfLine = true;
6185
  va_list Arguments;
6186
  int Length = 0;
6187
  va_start(Arguments, Controller);
6188
  Length = vsprintf(Buffer, Format, Arguments);
6189
  va_end(Arguments);
6190
  if (Controller == NULL)
6191
    printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
6192
           DAC960_ControllerCount, Buffer);
6193
  else if (MessageLevel == DAC960_AnnounceLevel ||
6194
           MessageLevel == DAC960_InfoLevel)
6195
    {
6196
      if (!Controller->ControllerInitialized)
6197
        {
6198
          if (DAC960_CheckStatusBuffer(Controller, Length))
6199
            {
6200
              strcpy(&Controller->CombinedStatusBuffer
6201
                                  [Controller->InitialStatusLength],
6202
                     Buffer);
6203
              Controller->InitialStatusLength += Length;
6204
              Controller->CurrentStatusBuffer =
6205
                &Controller->CombinedStatusBuffer
6206
                             [Controller->InitialStatusLength + 1];
6207
            }
6208
          if (MessageLevel == DAC960_AnnounceLevel)
6209
            {
6210
              static int AnnouncementLines = 0;
6211
              if (++AnnouncementLines <= 2)
6212
                printk("%sDAC960: %s", DAC960_MessageLevelMap[MessageLevel],
6213
                       Buffer);
6214
            }
6215
          else
6216
            {
6217
              if (BeginningOfLine)
6218
                {
6219
                  if (Buffer[0] != '\n' || Length > 1)
6220
                    printk("%sDAC960#%d: %s",
6221
                           DAC960_MessageLevelMap[MessageLevel],
6222
                           Controller->ControllerNumber, Buffer);
6223
                }
6224
              else printk("%s", Buffer);
6225
            }
6226
        }
6227
      else if (DAC960_CheckStatusBuffer(Controller, Length))
6228
        {
6229
          strcpy(&Controller->CurrentStatusBuffer[
6230
                    Controller->CurrentStatusLength], Buffer);
6231
          Controller->CurrentStatusLength += Length;
6232
        }
6233
    }
6234
  else if (MessageLevel == DAC960_ProgressLevel)
6235
    {
6236
      strcpy(Controller->ProgressBuffer, Buffer);
6237
      Controller->ProgressBufferLength = Length;
6238
      if (Controller->EphemeralProgressMessage)
6239
        {
6240
          if (jiffies - Controller->LastProgressReportTime
6241
              >= DAC960_ProgressReportingInterval)
6242
            {
6243
              printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
6244
                     Controller->ControllerNumber, Buffer);
6245
              Controller->LastProgressReportTime = jiffies;
6246
            }
6247
        }
6248
      else printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
6249
                  Controller->ControllerNumber, Buffer);
6250
    }
6251
  else if (MessageLevel == DAC960_UserCriticalLevel)
6252
    {
6253
      strcpy(&Controller->UserStatusBuffer[Controller->UserStatusLength],
6254
             Buffer);
6255
      Controller->UserStatusLength += Length;
6256
      if (Buffer[0] != '\n' || Length > 1)
6257
        printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
6258
               Controller->ControllerNumber, Buffer);
6259
    }
6260
  else
6261
    {
6262
      if (BeginningOfLine)
6263
        printk("%sDAC960#%d: %s", DAC960_MessageLevelMap[MessageLevel],
6264
               Controller->ControllerNumber, Buffer);
6265
      else printk("%s", Buffer);
6266
    }
6267
  BeginningOfLine = (Buffer[Length-1] == '\n');
6268
}
6269
 
6270
 
6271
/*
6272
  DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
6273
  Channel:TargetID specification from a User Command string.  It updates
6274
  Channel and TargetID and returns true on success and false on failure.
6275
*/
6276
 
6277
static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
6278
                                          char *UserCommandString,
6279
                                          unsigned char *Channel,
6280
                                          unsigned char *TargetID)
6281
{
6282
  char *NewUserCommandString = UserCommandString;
6283
  unsigned long XChannel, XTargetID;
6284
  while (*UserCommandString == ' ') UserCommandString++;
6285
  if (UserCommandString == NewUserCommandString)
6286
    return false;
6287
  XChannel = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
6288
  if (NewUserCommandString == UserCommandString ||
6289
      *NewUserCommandString != ':' ||
6290
      XChannel >= Controller->Channels)
6291
    return false;
6292
  UserCommandString = ++NewUserCommandString;
6293
  XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
6294
  if (NewUserCommandString == UserCommandString ||
6295
      *NewUserCommandString != '\0' ||
6296
      XTargetID >= Controller->Targets)
6297
    return false;
6298
  *Channel = XChannel;
6299
  *TargetID = XTargetID;
6300
  return true;
6301
}
6302
 
6303
 
6304
/*
6305
  DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
6306
  specification from a User Command string.  It updates LogicalDriveNumber and
6307
  returns true on success and false on failure.
6308
*/
6309
 
6310
static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
6311
                                        char *UserCommandString,
6312
                                        unsigned char *LogicalDriveNumber)
6313
{
6314
  char *NewUserCommandString = UserCommandString;
6315
  unsigned long XLogicalDriveNumber;
6316
  while (*UserCommandString == ' ') UserCommandString++;
6317
  if (UserCommandString == NewUserCommandString)
6318
    return false;
6319
  XLogicalDriveNumber =
6320
    simple_strtoul(UserCommandString, &NewUserCommandString, 10);
6321
  if (NewUserCommandString == UserCommandString ||
6322
      *NewUserCommandString != '\0' ||
6323
      XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
6324
    return false;
6325
  *LogicalDriveNumber = XLogicalDriveNumber;
6326
  return true;
6327
}
6328
 
6329
 
6330
/*
6331
  DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
6332
  DAC960 V1 Firmware Controllers.
6333
*/
6334
 
6335
static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
6336
                                     DAC960_Command_T *Command,
6337
                                     unsigned char Channel,
6338
                                     unsigned char TargetID,
6339
                                     DAC960_V1_PhysicalDeviceState_T
6340
                                       DeviceState,
6341
                                     const unsigned char *DeviceStateString)
6342
{
6343
  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
6344
  CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
6345
  CommandMailbox->Type3D.Channel = Channel;
6346
  CommandMailbox->Type3D.TargetID = TargetID;
6347
  CommandMailbox->Type3D.DeviceState = DeviceState;
6348
  CommandMailbox->Type3D.Modifier = 0;
6349
  DAC960_ExecuteCommand(Command);
6350
  switch (Command->V1.CommandStatus)
6351
    {
6352
    case DAC960_V1_NormalCompletion:
6353
      DAC960_UserCritical("%s of Physical Device %d:%d Succeeded\n", Controller,
6354
                          DeviceStateString, Channel, TargetID);
6355
      break;
6356
    case DAC960_V1_UnableToStartDevice:
6357
      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
6358
                          "Unable to Start Device\n", Controller,
6359
                          DeviceStateString, Channel, TargetID);
6360
      break;
6361
    case DAC960_V1_NoDeviceAtAddress:
6362
      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
6363
                          "No Device at Address\n", Controller,
6364
                          DeviceStateString, Channel, TargetID);
6365
      break;
6366
    case DAC960_V1_InvalidChannelOrTargetOrModifier:
6367
      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
6368
                          "Invalid Channel or Target or Modifier\n",
6369
                          Controller, DeviceStateString, Channel, TargetID);
6370
      break;
6371
    case DAC960_V1_ChannelBusy:
6372
      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
6373
                          "Channel Busy\n", Controller,
6374
                          DeviceStateString, Channel, TargetID);
6375
      break;
6376
    default:
6377
      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
6378
                          "Unexpected Status %04X\n", Controller,
6379
                          DeviceStateString, Channel, TargetID,
6380
                          Command->V1.CommandStatus);
6381
      break;
6382
    }
6383
}
6384
 
6385
 
6386
/*
6387
  DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
6388
  Controllers.
6389
*/
6390
 
6391
static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
6392
                                            unsigned char *UserCommand)
6393
{
6394
  DAC960_Command_T *Command;
6395
  DAC960_V1_CommandMailbox_T *CommandMailbox;
6396
  ProcessorFlags_T ProcessorFlags;
6397
  unsigned char Channel, TargetID, LogicalDriveNumber;
6398
  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6399
  while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
6400
    DAC960_WaitForCommand(Controller);
6401
  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6402
  Controller->UserStatusLength = 0;
6403
  DAC960_V1_ClearCommand(Command);
6404
  Command->CommandType = DAC960_ImmediateCommand;
6405
  CommandMailbox = &Command->V1.CommandMailbox;
6406
  if (strcmp(UserCommand, "flush-cache") == 0)
6407
    {
6408
      CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
6409
      DAC960_ExecuteCommand(Command);
6410
      DAC960_UserCritical("Cache Flush Completed\n", Controller);
6411
    }
6412
  else if (strncmp(UserCommand, "kill", 4) == 0 &&
6413
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
6414
                                      &Channel, &TargetID))
6415
    {
6416
      DAC960_V1_DeviceState_T *DeviceState =
6417
        &Controller->V1.DeviceState[Channel][TargetID];
6418
      if (DeviceState->Present &&
6419
          DeviceState->DeviceType == DAC960_V1_DiskType &&
6420
          DeviceState->DeviceState != DAC960_V1_Device_Dead)
6421
        DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
6422
                                 DAC960_V1_Device_Dead, "Kill");
6423
      else DAC960_UserCritical("Kill of Physical Device %d:%d Illegal\n",
6424
                               Controller, Channel, TargetID);
6425
    }
6426
  else if (strncmp(UserCommand, "make-online", 11) == 0 &&
6427
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
6428
                                      &Channel, &TargetID))
6429
    {
6430
      DAC960_V1_DeviceState_T *DeviceState =
6431
        &Controller->V1.DeviceState[Channel][TargetID];
6432
      if (DeviceState->Present &&
6433
          DeviceState->DeviceType == DAC960_V1_DiskType &&
6434
          DeviceState->DeviceState == DAC960_V1_Device_Dead)
6435
        DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
6436
                                 DAC960_V1_Device_Online, "Make Online");
6437
      else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegal\n",
6438
                               Controller, Channel, TargetID);
6439
 
6440
    }
6441
  else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
6442
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
6443
                                      &Channel, &TargetID))
6444
    {
6445
      DAC960_V1_DeviceState_T *DeviceState =
6446
        &Controller->V1.DeviceState[Channel][TargetID];
6447
      if (DeviceState->Present &&
6448
          DeviceState->DeviceType == DAC960_V1_DiskType &&
6449
          DeviceState->DeviceState == DAC960_V1_Device_Dead)
6450
        DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
6451
                                 DAC960_V1_Device_Standby, "Make Standby");
6452
      else DAC960_UserCritical("Make Standby of Physical "
6453
                               "Device %d:%d Illegal\n",
6454
                               Controller, Channel, TargetID);
6455
    }
6456
  else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
6457
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
6458
                                      &Channel, &TargetID))
6459
    {
6460
      CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
6461
      CommandMailbox->Type3D.Channel = Channel;
6462
      CommandMailbox->Type3D.TargetID = TargetID;
6463
      DAC960_ExecuteCommand(Command);
6464
      switch (Command->V1.CommandStatus)
6465
        {
6466
        case DAC960_V1_NormalCompletion:
6467
          DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiated\n",
6468
                              Controller, Channel, TargetID);
6469
          break;
6470
        case DAC960_V1_AttemptToRebuildOnlineDrive:
6471
          DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
6472
                              "Attempt to Rebuild Online or "
6473
                              "Unresponsive Drive\n",
6474
                              Controller, Channel, TargetID);
6475
          break;
6476
        case DAC960_V1_NewDiskFailedDuringRebuild:
6477
          DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
6478
                              "New Disk Failed During Rebuild\n",
6479
                              Controller, Channel, TargetID);
6480
          break;
6481
        case DAC960_V1_InvalidDeviceAddress:
6482
          DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
6483
                              "Invalid Device Address\n",
6484
                              Controller, Channel, TargetID);
6485
          break;
6486
        case DAC960_V1_RebuildOrCheckAlreadyInProgress:
6487
          DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
6488
                              "Rebuild or Consistency Check Already "
6489
                              "in Progress\n", Controller, Channel, TargetID);
6490
          break;
6491
        default:
6492
          DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
6493
                              "Unexpected Status %04X\n", Controller,
6494
                              Channel, TargetID, Command->V1.CommandStatus);
6495
          break;
6496
        }
6497
    }
6498
  else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
6499
           DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
6500
                                    &LogicalDriveNumber))
6501
    {
6502
      CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
6503
      CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
6504
      CommandMailbox->Type3C.AutoRestore = true;
6505
      DAC960_ExecuteCommand(Command);
6506
      switch (Command->V1.CommandStatus)
6507
        {
6508
        case DAC960_V1_NormalCompletion:
6509
          DAC960_UserCritical("Consistency Check of Logical Drive %d "
6510
                              "(/dev/rd/c%dd%d) Initiated\n",
6511
                              Controller, LogicalDriveNumber,
6512
                              Controller->ControllerNumber,
6513
                              LogicalDriveNumber);
6514
          break;
6515
        case DAC960_V1_DependentDiskIsDead:
6516
          DAC960_UserCritical("Consistency Check of Logical Drive %d "
6517
                              "(/dev/rd/c%dd%d) Failed - "
6518
                              "Dependent Physical Device is DEAD\n",
6519
                              Controller, LogicalDriveNumber,
6520
                              Controller->ControllerNumber,
6521
                              LogicalDriveNumber);
6522
          break;
6523
        case DAC960_V1_InvalidOrNonredundantLogicalDrive:
6524
          DAC960_UserCritical("Consistency Check of Logical Drive %d "
6525
                              "(/dev/rd/c%dd%d) Failed - "
6526
                              "Invalid or Nonredundant Logical Drive\n",
6527
                              Controller, LogicalDriveNumber,
6528
                              Controller->ControllerNumber,
6529
                              LogicalDriveNumber);
6530
          break;
6531
        case DAC960_V1_RebuildOrCheckAlreadyInProgress:
6532
          DAC960_UserCritical("Consistency Check of Logical Drive %d "
6533
                              "(/dev/rd/c%dd%d) Failed - Rebuild or "
6534
                              "Consistency Check Already in Progress\n",
6535
                              Controller, LogicalDriveNumber,
6536
                              Controller->ControllerNumber,
6537
                              LogicalDriveNumber);
6538
          break;
6539
        default:
6540
          DAC960_UserCritical("Consistency Check of Logical Drive %d "
6541
                              "(/dev/rd/c%dd%d) Failed - "
6542
                              "Unexpected Status %04X\n",
6543
                              Controller, LogicalDriveNumber,
6544
                              Controller->ControllerNumber,
6545
                              LogicalDriveNumber, Command->V1.CommandStatus);
6546
          break;
6547
        }
6548
    }
6549
  else if (strcmp(UserCommand, "cancel-rebuild") == 0 ||
6550
           strcmp(UserCommand, "cancel-consistency-check") == 0)
6551
    {
6552
      unsigned char OldRebuildRateConstant;
6553
      CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
6554
      CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
6555
      CommandMailbox->Type3R.BusAddress =
6556
        Virtual_to_Bus32(&OldRebuildRateConstant);
6557
      DAC960_ExecuteCommand(Command);
6558
      switch (Command->V1.CommandStatus)
6559
        {
6560
        case DAC960_V1_NormalCompletion:
6561
          DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
6562
                              Controller);
6563
          break;
6564
        default:
6565
          DAC960_UserCritical("Cancellation of Rebuild or "
6566
                              "Consistency Check Failed - "
6567
                              "Unexpected Status %04X\n",
6568
                              Controller, Command->V1.CommandStatus);
6569
          break;
6570
        }
6571
    }
6572
  else DAC960_UserCritical("Illegal User Command: '%s'\n",
6573
                           Controller, UserCommand);
6574
  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6575
  DAC960_DeallocateCommand(Command);
6576
  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6577
  return true;
6578
}
6579
 
6580
 
6581
/*
6582
  DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
6583
  TargetID into a Logical Device.  It returns true on success and false
6584
  on failure.
6585
*/
6586
 
6587
static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
6588
                                                 unsigned char Channel,
6589
                                                 unsigned char TargetID,
6590
                                                 unsigned short
6591
                                                   *LogicalDeviceNumber)
6592
{
6593
  DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
6594
  DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
6595
  CommandMailbox = &Command->V2.CommandMailbox;
6596
  memcpy(&SavedCommandMailbox, CommandMailbox,
6597
         sizeof(DAC960_V2_CommandMailbox_T));
6598
  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
6599
  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
6600
                                    .DataTransferControllerToHost = true;
6601
  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
6602
                                    .NoAutoRequestSense = true;
6603
  CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
6604
    sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
6605
  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
6606
  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
6607
  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
6608
    DAC960_V2_TranslatePhysicalToLogicalDevice;
6609
  CommandMailbox->Common.DataTransferMemoryAddress
6610
                        .ScatterGatherSegments[0]
6611
                        .SegmentDataPointer =
6612
    Virtual_to_Bus64(&PhysicalToLogicalDevice);
6613
  CommandMailbox->Common.DataTransferMemoryAddress
6614
                        .ScatterGatherSegments[0]
6615
                        .SegmentByteCount =
6616
    CommandMailbox->Common.DataTransferSize;
6617
  DAC960_ExecuteCommand(Command);
6618
  memcpy(CommandMailbox, &SavedCommandMailbox,
6619
         sizeof(DAC960_V2_CommandMailbox_T));
6620
  *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
6621
  return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
6622
}
6623
 
6624
 
6625
/*
6626
  DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
6627
  Controllers.
6628
*/
6629
 
6630
static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
6631
                                            unsigned char *UserCommand)
6632
{
6633
  DAC960_Command_T *Command;
6634
  DAC960_V2_CommandMailbox_T *CommandMailbox;
6635
  ProcessorFlags_T ProcessorFlags;
6636
  unsigned char Channel, TargetID, LogicalDriveNumber;
6637
  unsigned short LogicalDeviceNumber;
6638
  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6639
  while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
6640
    DAC960_WaitForCommand(Controller);
6641
  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6642
  Controller->UserStatusLength = 0;
6643
  DAC960_V2_ClearCommand(Command);
6644
  Command->CommandType = DAC960_ImmediateCommand;
6645
  CommandMailbox = &Command->V2.CommandMailbox;
6646
  CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
6647
  CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
6648
  CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
6649
  if (strcmp(UserCommand, "flush-cache") == 0)
6650
    {
6651
      CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
6652
      CommandMailbox->DeviceOperation.OperationDevice =
6653
        DAC960_V2_RAID_Controller;
6654
      DAC960_ExecuteCommand(Command);
6655
      DAC960_UserCritical("Cache Flush Completed\n", Controller);
6656
    }
6657
  else if (strncmp(UserCommand, "kill", 4) == 0 &&
6658
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
6659
                                      &Channel, &TargetID) &&
6660
           DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6661
                                             &LogicalDeviceNumber))
6662
    {
6663
      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6664
        LogicalDeviceNumber;
6665
      CommandMailbox->SetDeviceState.IOCTL_Opcode =
6666
        DAC960_V2_SetDeviceState;
6667
      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6668
        DAC960_V2_Device_Dead;
6669
      DAC960_ExecuteCommand(Command);
6670
      DAC960_UserCritical("Kill of Physical Device %d:%d %s\n",
6671
                          Controller, Channel, TargetID,
6672
                          (Command->V2.CommandStatus
6673
                           == DAC960_V2_NormalCompletion
6674
                           ? "Succeeded" : "Failed"));
6675
    }
6676
  else if (strncmp(UserCommand, "make-online", 11) == 0 &&
6677
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
6678
                                      &Channel, &TargetID) &&
6679
           DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6680
                                             &LogicalDeviceNumber))
6681
    {
6682
      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6683
        LogicalDeviceNumber;
6684
      CommandMailbox->SetDeviceState.IOCTL_Opcode =
6685
        DAC960_V2_SetDeviceState;
6686
      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6687
        DAC960_V2_Device_Online;
6688
      DAC960_ExecuteCommand(Command);
6689
      DAC960_UserCritical("Make Online of Physical Device %d:%d %s\n",
6690
                          Controller, Channel, TargetID,
6691
                          (Command->V2.CommandStatus
6692
                           == DAC960_V2_NormalCompletion
6693
                           ? "Succeeded" : "Failed"));
6694
    }
6695
  else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
6696
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
6697
                                      &Channel, &TargetID) &&
6698
           DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6699
                                             &LogicalDeviceNumber))
6700
    {
6701
      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
6702
        LogicalDeviceNumber;
6703
      CommandMailbox->SetDeviceState.IOCTL_Opcode =
6704
        DAC960_V2_SetDeviceState;
6705
      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
6706
        DAC960_V2_Device_Standby;
6707
      DAC960_ExecuteCommand(Command);
6708
      DAC960_UserCritical("Make Standby of Physical Device %d:%d %s\n",
6709
                          Controller, Channel, TargetID,
6710
                          (Command->V2.CommandStatus
6711
                           == DAC960_V2_NormalCompletion
6712
                           ? "Succeeded" : "Failed"));
6713
    }
6714
  else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
6715
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
6716
                                      &Channel, &TargetID) &&
6717
           DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6718
                                             &LogicalDeviceNumber))
6719
    {
6720
      CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
6721
        LogicalDeviceNumber;
6722
      CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
6723
        DAC960_V2_RebuildDeviceStart;
6724
      DAC960_ExecuteCommand(Command);
6725
      DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
6726
                          Controller, Channel, TargetID,
6727
                          (Command->V2.CommandStatus
6728
                           == DAC960_V2_NormalCompletion
6729
                           ? "Initiated" : "Not Initiated"));
6730
    }
6731
  else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
6732
           DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
6733
                                      &Channel, &TargetID) &&
6734
           DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
6735
                                             &LogicalDeviceNumber))
6736
    {
6737
      CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
6738
        LogicalDeviceNumber;
6739
      CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
6740
        DAC960_V2_RebuildDeviceStop;
6741
      DAC960_ExecuteCommand(Command);
6742
      DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
6743
                          Controller, Channel, TargetID,
6744
                          (Command->V2.CommandStatus
6745
                           == DAC960_V2_NormalCompletion
6746
                           ? "Cancelled" : "Not Cancelled"));
6747
    }
6748
  else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
6749
           DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
6750
                                    &LogicalDriveNumber))
6751
    {
6752
      CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
6753
        LogicalDriveNumber;
6754
      CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
6755
        DAC960_V2_ConsistencyCheckStart;
6756
      CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
6757
      CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
6758
      DAC960_ExecuteCommand(Command);
6759
      DAC960_UserCritical("Consistency Check of Logical Drive %d "
6760
                          "(/dev/rd/c%dd%d) %s\n",
6761
                          Controller, LogicalDriveNumber,
6762
                          Controller->ControllerNumber,
6763
                          LogicalDriveNumber,
6764
                          (Command->V2.CommandStatus
6765
                           == DAC960_V2_NormalCompletion
6766
                           ? "Initiated" : "Not Initiated"));
6767
    }
6768
  else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
6769
           DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
6770
                                    &LogicalDriveNumber))
6771
    {
6772
      CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
6773
        LogicalDriveNumber;
6774
      CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
6775
        DAC960_V2_ConsistencyCheckStop;
6776
      DAC960_ExecuteCommand(Command);
6777
      DAC960_UserCritical("Consistency Check of Logical Drive %d "
6778
                          "(/dev/rd/c%dd%d) %s\n",
6779
                          Controller, LogicalDriveNumber,
6780
                          Controller->ControllerNumber,
6781
                          LogicalDriveNumber,
6782
                          (Command->V2.CommandStatus
6783
                           == DAC960_V2_NormalCompletion
6784
                           ? "Cancelled" : "Not Cancelled"));
6785
    }
6786
  else if (strcmp(UserCommand, "perform-discovery") == 0)
6787
    {
6788
      CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_StartDiscovery;
6789
      DAC960_ExecuteCommand(Command);
6790
      DAC960_UserCritical("Discovery %s\n", Controller,
6791
                          (Command->V2.CommandStatus
6792
                           == DAC960_V2_NormalCompletion
6793
                           ? "Initiated" : "Not Initiated"));
6794
      if (Command->V2.CommandStatus == DAC960_V2_NormalCompletion)
6795
        {
6796
          CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
6797
          CommandMailbox->ControllerInfo.CommandControlBits
6798
                                        .DataTransferControllerToHost = true;
6799
          CommandMailbox->ControllerInfo.CommandControlBits
6800
                                        .NoAutoRequestSense = true;
6801
          CommandMailbox->ControllerInfo.DataTransferSize =
6802
            sizeof(DAC960_V2_ControllerInfo_T);
6803
          CommandMailbox->ControllerInfo.ControllerNumber = 0;
6804
          CommandMailbox->ControllerInfo.IOCTL_Opcode =
6805
            DAC960_V2_GetControllerInfo;
6806
          CommandMailbox->ControllerInfo.DataTransferMemoryAddress
6807
                                        .ScatterGatherSegments[0]
6808
                                        .SegmentDataPointer =
6809
            Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
6810
          CommandMailbox->ControllerInfo.DataTransferMemoryAddress
6811
                                        .ScatterGatherSegments[0]
6812
                                        .SegmentByteCount =
6813
            CommandMailbox->ControllerInfo.DataTransferSize;
6814
          DAC960_ExecuteCommand(Command);
6815
          while (Controller->V2.NewControllerInformation.PhysicalScanActive)
6816
            {
6817
              DAC960_ExecuteCommand(Command);
6818
              sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
6819
            }
6820
          DAC960_UserCritical("Discovery Completed\n", Controller);
6821
        }
6822
    }
6823
  else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0)
6824
    Controller->SuppressEnclosureMessages = true;
6825
  else DAC960_UserCritical("Illegal User Command: '%s'\n",
6826
                           Controller, UserCommand);
6827
  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
6828
  DAC960_DeallocateCommand(Command);
6829
  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
6830
  return true;
6831
}
6832
 
6833
 
6834
/*
6835
  DAC960_ProcReadStatus implements reading /proc/rd/status.
6836
*/
6837
 
6838
static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
6839
                                 int Count, int *EOF, void *Data)
6840
{
6841
  unsigned char *StatusMessage = "OK\n";
6842
  int ControllerNumber, BytesAvailable;
6843
  for (ControllerNumber = 0;
6844
       ControllerNumber < DAC960_ControllerCount;
6845
       ControllerNumber++)
6846
    {
6847
      DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
6848
      if (Controller == NULL) continue;
6849
      if (Controller->MonitoringAlertMode)
6850
        {
6851
          StatusMessage = "ALERT\n";
6852
          break;
6853
        }
6854
    }
6855
  BytesAvailable = strlen(StatusMessage) - Offset;
6856
  if (Count >= BytesAvailable)
6857
    {
6858
      Count = BytesAvailable;
6859
      *EOF = true;
6860
    }
6861
  if (Count <= 0) return 0;
6862
  *Start = Page;
6863
  memcpy(Page, &StatusMessage[Offset], Count);
6864
  return Count;
6865
}
6866
 
6867
 
6868
/*
6869
  DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status.
6870
*/
6871
 
6872
static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset,
6873
                                        int Count, int *EOF, void *Data)
6874
{
6875
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6876
  int BytesAvailable = Controller->InitialStatusLength - Offset;
6877
  if (Count >= BytesAvailable)
6878
    {
6879
      Count = BytesAvailable;
6880
      *EOF = true;
6881
    }
6882
  if (Count <= 0) return 0;
6883
  *Start = Page;
6884
  memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
6885
  return Count;
6886
}
6887
 
6888
 
6889
/*
6890
  DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status.
6891
*/
6892
 
6893
static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
6894
                                        int Count, int *EOF, void *Data)
6895
{
6896
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6897
  unsigned char *StatusMessage =
6898
    "No Rebuild or Consistency Check in Progress\n";
6899
  int ProgressMessageLength = strlen(StatusMessage);
6900
  int BytesAvailable;
6901
  if (jiffies != Controller->LastCurrentStatusTime)
6902
    {
6903
      Controller->CurrentStatusLength = 0;
6904
      DAC960_AnnounceDriver(Controller);
6905
      DAC960_ReportControllerConfiguration(Controller);
6906
      DAC960_ReportDeviceConfiguration(Controller);
6907
      if (Controller->ProgressBufferLength > 0)
6908
        ProgressMessageLength = Controller->ProgressBufferLength;
6909
      if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
6910
        {
6911
          unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
6912
          CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
6913
          CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
6914
          if (Controller->ProgressBufferLength > 0)
6915
            strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
6916
                   Controller->ProgressBuffer);
6917
          else
6918
            strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
6919
                   StatusMessage);
6920
          Controller->CurrentStatusLength += ProgressMessageLength;
6921
        }
6922
      Controller->LastCurrentStatusTime = jiffies;
6923
    }
6924
  BytesAvailable = Controller->CurrentStatusLength - Offset;
6925
  if (Count >= BytesAvailable)
6926
    {
6927
      Count = BytesAvailable;
6928
      *EOF = true;
6929
    }
6930
  if (Count <= 0) return 0;
6931
  *Start = Page;
6932
  memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
6933
  return Count;
6934
}
6935
 
6936
 
6937
/*
6938
  DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command.
6939
*/
6940
 
6941
static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset,
6942
                                      int Count, int *EOF, void *Data)
6943
{
6944
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6945
  int BytesAvailable = Controller->UserStatusLength - Offset;
6946
  if (Count >= BytesAvailable)
6947
    {
6948
      Count = BytesAvailable;
6949
      *EOF = true;
6950
    }
6951
  if (Count <= 0) return 0;
6952
  *Start = Page;
6953
  memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
6954
  return Count;
6955
}
6956
 
6957
 
6958
/*
6959
  DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command.
6960
*/
6961
 
6962
static int DAC960_ProcWriteUserCommand(File_T *File, const char *Buffer,
6963
                                       unsigned long Count, void *Data)
6964
{
6965
  DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
6966
  unsigned char CommandBuffer[80];
6967
  int Length;
6968
  if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
6969
  if (copy_from_user(CommandBuffer, Buffer, Count)) return -EFAULT;
6970
  CommandBuffer[Count] = '\0';
6971
  Length = strlen(CommandBuffer);
6972
  if (CommandBuffer[Length-1] == '\n')
6973
    CommandBuffer[--Length] = '\0';
6974
  if (Controller->FirmwareType == DAC960_V1_Controller)
6975
    return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
6976
            ? Count : -EBUSY);
6977
  else
6978
    return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
6979
            ? Count : -EBUSY);
6980
}
6981
 
6982
 
6983
/*
6984
  DAC960_CreateProcEntries creates the /proc/rd/... entries for the
6985
  DAC960 Driver.
6986
*/
6987
 
6988
static void DAC960_CreateProcEntries(void)
6989
{
6990
  PROC_DirectoryEntry_T *StatusProcEntry;
6991
  int ControllerNumber;
6992
  DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
6993
  StatusProcEntry = create_proc_read_entry("status", 0,
6994
                                           DAC960_ProcDirectoryEntry,
6995
                                           DAC960_ProcReadStatus, NULL);
6996
  for (ControllerNumber = 0;
6997
       ControllerNumber < DAC960_ControllerCount;
6998
       ControllerNumber++)
6999
    {
7000
      DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
7001
      PROC_DirectoryEntry_T *ControllerProcEntry;
7002
      PROC_DirectoryEntry_T *UserCommandProcEntry;
7003
      if (Controller == NULL) continue;
7004
      sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
7005
      ControllerProcEntry = proc_mkdir(Controller->ControllerName,
7006
                                       DAC960_ProcDirectoryEntry);
7007
      create_proc_read_entry("initial_status", 0, ControllerProcEntry,
7008
                             DAC960_ProcReadInitialStatus, Controller);
7009
      create_proc_read_entry("current_status", 0, ControllerProcEntry,
7010
                             DAC960_ProcReadCurrentStatus, Controller);
7011
      UserCommandProcEntry =
7012
        create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
7013
                               ControllerProcEntry, DAC960_ProcReadUserCommand,
7014
                               Controller);
7015
      UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
7016
      Controller->ControllerProcEntry = ControllerProcEntry;
7017
    }
7018
}
7019
 
7020
 
7021
/*
7022
  DAC960_DestroyProcEntries destroys the /proc/rd/... entries for the
7023
  DAC960 Driver.
7024
*/
7025
 
7026
static void DAC960_DestroyProcEntries(void)
7027
{
7028
  int ControllerNumber;
7029
  for (ControllerNumber = 0;
7030
       ControllerNumber < DAC960_ControllerCount;
7031
       ControllerNumber++)
7032
    {
7033
      DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
7034
      if (Controller == NULL) continue;
7035
      remove_proc_entry("initial_status", Controller->ControllerProcEntry);
7036
      remove_proc_entry("current_status", Controller->ControllerProcEntry);
7037
      remove_proc_entry("user_command", Controller->ControllerProcEntry);
7038
      remove_proc_entry(Controller->ControllerName, DAC960_ProcDirectoryEntry);
7039
    }
7040
  remove_proc_entry("rd/status", NULL);
7041
  remove_proc_entry("rd", NULL);
7042
}
7043
 
7044
 
7045
module_init(DAC960_Initialize);
7046
module_exit(DAC960_Finalize);
7047
 
7048
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.