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