1 From: Penchala Narsimha Reddy Chilakala <ServeRAIDDriver@hcl.in>
2 Subject: Problems with aacraid
5 The attached patch aac24701 was generated for the following issues only:
9 Behavior of the ternary operation in function aac_send_raw_srb () was
10 observed incorrect in 64-bit version. This issue was because of missing
11 parenthesis in the condition to check the sg count.
15 Fixed by adding parentheses.
19 Driver IOCTLs is signaled with EINTR while waiting on response from the
20 lower layers. Returning “EINTR” will never initiate internal retry.
24 Fixed by replacing “EINTR” with “ERESTARTSYS” for mid-layer retries.
28 The driver tends to not free the memory (FIB) when the management
29 request exits prematurely. The accumulation of such un-freed memory causes the
30 driver to fail to allocate anymore memory (FIB) and hence return 0x70000 value
31 to the upper layer, which puts the file system into read only mode.
35 The fix makes sure to free the memory(FIB) even if the request exits
36 prematurely hence ensuring the driver wouldn’t run out of memory(FIBs)
40 The driver exhibits performance problems as the execution of
41 SYNCHRONIZE CACHE is quite time-consuming.
45 The issue is fixed by setting WCE=0 in the INQUIRY data, thus
46 causing the SCSI midlayer not to issue any SYNCHRONIZE CACHE commands.
48 Signed-off-by: Hannes Reinecke <hare@suse.de>
50 diff -ru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
51 --- a/drivers/scsi/aacraid/aachba.c 2009-09-16 16:40:05.000000000 +0530
52 +++ b/drivers/scsi/aacraid/aachba.c 2009-09-16 17:41:00.000000000 +0530
56 static int nondasd = -1;
57 -static int aac_cache;
58 +static int aac_cache = 2; /* WCE=0 to avoid performance problems */
59 static int dacmode = -1;
63 MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n"
64 "\tbit 0 - Disable FUA in WRITE SCSI commands\n"
65 "\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n"
66 - "\tbit 2 - Disable only if Battery not protecting Cache");
67 + "\tbit 2 - Disable only if Battery is protecting Cache");
68 module_param(dacmode, int, S_IRUGO|S_IWUSR);
69 MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC."
72 module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
73 MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
76 +module_param_named(wwn, aac_wwn, int, S_IRUGO|S_IWUSR);
77 +MODULE_PARM_DESC(wwn, "Select a WWN type for the arrays:\n"
79 + "\t1 - Array Meta Data Signature (default)\n"
80 + "\t2 - Adapter Serial Number");
83 static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
85 struct scsi_device *device;
90 - aac_fib_complete(fibptr);
91 + /* Do not set XferState to zero unless receives a response from F/W */
93 + aac_fib_complete(fibptr);
95 /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
97 if ((aac_commit == 1) || commit_flag) {
102 - aac_fib_complete(fibptr);
103 + /* Do not set XferState to zero unless
104 + * receives a response from F/W */
106 + aac_fib_complete(fibptr);
107 } else if (aac_commit == 0) {
109 "aac_get_config_status: Foreign device configurations are being ignored\n");
112 - aac_fib_free(fibptr);
113 + /* FIB should be freed only after getting the response from the F/W */
114 + if (status != -ERESTARTSYS)
115 + aac_fib_free(fibptr);
120 maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
121 aac_fib_complete(fibptr);
123 - aac_fib_free(fibptr);
124 + /* FIB should be freed only after getting the response from the F/W */
125 + if (status != -ERESTARTSYS)
126 + aac_fib_free(fibptr);
128 if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
129 maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
130 @@ -1206,9 +1224,8 @@
132 static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
134 - if ((sizeof(dma_addr_t) > 4) &&
135 - (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
136 - (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
137 + if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
138 + (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
140 return aac_scsi_32(fib, cmd);
142 @@ -1238,8 +1255,12 @@
146 - aac_fib_complete(fibptr);
147 - aac_fib_free(fibptr);
148 + /* FIB should be freed only after
149 + * getting the response from the F/W */
150 + if (rcode != -ERESTARTSYS) {
151 + aac_fib_complete(fibptr);
152 + aac_fib_free(fibptr);
156 memcpy(&dev->adapter_info, info, sizeof(*info));
157 @@ -1263,6 +1284,12 @@
160 memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));
161 + if (rcode == -ERESTARTSYS) {
162 + fibptr = aac_fib_alloc(dev);
170 @@ -1371,8 +1398,11 @@
171 if (dev->nondasd_support && !dev->in_reset)
172 printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
174 + if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK)
175 + dev->needs_dac = 1;
176 dev->dac_support = 0;
177 - if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
178 + if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&
179 + (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
181 printk(KERN_INFO "%s%d: 64bit support enabled.\n",
183 @@ -1382,6 +1412,15 @@
185 dev->dac_support = (dacmode!=0);
188 + /* avoid problems with AAC_QUIRK_SCSI_32 controllers */
189 + if (dev->dac_support && (aac_get_driver_ident(dev->cardtype)->quirks
190 + & AAC_QUIRK_SCSI_32)) {
191 + dev->nondasd_support = 0;
193 + expose_physicals = 0;
196 if(dev->dac_support != 0) {
197 if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
198 !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
199 @@ -1451,9 +1490,11 @@
200 (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
204 - aac_fib_complete(fibptr);
205 - aac_fib_free(fibptr);
206 + /* FIB should be freed only after getting the response from the F/W */
207 + if (rcode != -ERESTARTSYS) {
208 + aac_fib_complete(fibptr);
209 + aac_fib_free(fibptr);
214 @@ -1614,6 +1655,7 @@
215 * Alocate and initialize a Fib
217 if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
218 + printk(KERN_WARNING "aac_read: fib allocation failed\n");
222 @@ -1693,9 +1735,14 @@
223 * Allocate and initialize a Fib then setup a BlockWrite command
225 if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
226 - scsicmd->result = DID_ERROR << 16;
227 - scsicmd->scsi_done(scsicmd);
229 + /* FIB temporarily unavailable,not catastrophic failure */
231 + /* scsicmd->result = DID_ERROR << 16;
232 + * scsicmd->scsi_done(scsicmd);
235 + printk(KERN_WARNING "aac_write: fib allocation failed\n");
239 status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
240 @@ -2058,7 +2105,7 @@
241 dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
242 memset(&inq_data, 0, sizeof (struct inquiry_data));
244 - if (scsicmd->cmnd[1] & 0x1) {
245 + if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {
246 char *arr = (char *)&inq_data;
249 @@ -2081,7 +2128,12 @@
250 arr[1] = scsicmd->cmnd[2];
251 scsi_sg_copy_from_buffer(scsicmd, &inq_data,
253 - return aac_get_container_serial(scsicmd);
255 + return aac_get_container_serial(
257 + /* SLES 10 SP1 special */
258 + scsicmd->result = DID_OK << 16 |
259 + COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
261 /* vpd page not implemented */
262 scsicmd->result = DID_OK << 16 |
263 diff -ru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
264 --- a/drivers/scsi/aacraid/aacraid.h 2009-09-16 16:40:05.000000000 +0530
265 +++ b/drivers/scsi/aacraid/aacraid.h 2009-09-16 17:46:20.000000000 +0530
267 *----------------------------------------------------------------------------*/
269 #ifndef AAC_DRIVER_BUILD
270 -# define AAC_DRIVER_BUILD 2456
271 +# define AAC_DRIVER_BUILD 24701
272 # define AAC_DRIVER_BRANCH "-ms"
274 #define MAXIMUM_NUM_CONTAINERS 32
276 u8 MfgPcbaSerialNo[12];
278 __le32 SupportedOptions2;
279 - __le32 ReservedGrowth[1];
280 + __le32 StructExpansion;
281 + /* StructExpansion == 1 */
282 + __le32 FeatureBits3;
283 + __le32 SupportedPerformanceModes;
284 + __le32 ReservedForFutureGrowth[80];
286 #define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
287 #define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
288 @@ -1020,6 +1024,7 @@
295 # define AAC_COMM_PRODUCER 0
296 @@ -1031,6 +1036,9 @@
300 + int management_fib_count;
301 + spinlock_t manage_lock;
305 #define aac_adapter_interrupt(dev) \
306 diff -ru a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
307 --- a/drivers/scsi/aacraid/commctrl.c 2009-09-16 16:40:05.000000000 +0530
308 +++ b/drivers/scsi/aacraid/commctrl.c 2009-09-16 17:41:00.000000000 +0530
310 fibptr->hw_fib_pa = hw_fib_pa;
311 fibptr->hw_fib_va = hw_fib;
313 - if (retval != -EINTR)
314 + if (retval != -ERESTARTSYS)
315 aac_fib_free(fibptr);
321 if(down_interruptible(&fibctx->wait_sem) < 0) {
323 + status = -ERESTARTSYS;
325 /* Lock again and retry */
326 spin_lock_irqsave(&dev->fib_lock, flags);
327 @@ -583,10 +583,10 @@
330 if (upsg->sg[i].count >
331 - (dev->adapter_info.options &
332 + ((dev->adapter_info.options &
334 (dev->scsi_host_ptr->max_sectors << 9) :
340 @@ -635,10 +635,10 @@
343 if (usg->sg[i].count >
344 - (dev->adapter_info.options &
345 + ((dev->adapter_info.options &
347 (dev->scsi_host_ptr->max_sectors << 9) :
353 @@ -685,10 +685,10 @@
356 if (usg->sg[i].count >
357 - (dev->adapter_info.options &
358 + ((dev->adapter_info.options &
360 (dev->scsi_host_ptr->max_sectors << 9) :
366 @@ -724,10 +724,10 @@
369 if (upsg->sg[i].count >
370 - (dev->adapter_info.options &
371 + ((dev->adapter_info.options &
373 (dev->scsi_host_ptr->max_sectors << 9) :
380 psg->count = cpu_to_le32(sg_indx+1);
381 status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
383 - if (status == -EINTR) {
385 + if (status == -ERESTARTSYS) {
386 + rcode = -ERESTARTSYS;
391 for(i=0; i <= sg_indx; i++){
394 - if (rcode != -EINTR) {
395 + if (rcode != -ERESTARTSYS) {
396 aac_fib_complete(srbfib);
397 aac_fib_free(srbfib);
399 @@ -832,13 +832,22 @@
400 int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
404 + unsigned long mflags;
407 * HBA gets first crack
410 + spin_lock_irqsave(&dev->manage_lock, mflags);
411 + if (dev->management_fib_count > AAC_NUM_MGT_FIB) {
412 + printk(KERN_INFO "No management Fibs Available:%d\n",
413 + dev->management_fib_count);
414 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
417 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
418 status = aac_dev_ioctl(dev, cmd, arg);
419 - if(status != -ENOTTY)
420 + if (status != -ENOTTY)
424 diff -ru a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
425 --- a/drivers/scsi/aacraid/comminit.c 2009-09-16 16:40:05.000000000 +0530
426 +++ b/drivers/scsi/aacraid/comminit.c 2009-09-16 17:41:00.000000000 +0530
428 const unsigned long printfbufsiz = 256;
429 struct aac_init *init;
431 + unsigned long aac_max_hostphysmempages;
433 size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
436 init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
437 init->AdapterFibsSize = cpu_to_le32(fibsize);
438 init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
439 - init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
441 + * number of 4k pages of host physical memory. The aacraid fw needs
442 + * this number to be less than 4gb worth of pages. New firmware doesn't
443 + * have any issues with the mapping system, but older Firmware did, and
444 + * had *troubles* dealing with the math overloading past 32 bits, thus
445 + * we must limit this field.
447 + aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
448 + if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
449 + init->HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
451 + init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
454 if (dev->comm_interface == AAC_COMM_MESSAGE) {
458 aac_fib_complete(fibctx);
459 - aac_fib_free(fibctx);
460 + /* FIB should be freed only after getting the response from the F/W */
461 + if (status != -ERESTARTSYS)
462 + aac_fib_free(fibctx);
468 * Check the preferred comm settings, defaults from template.
470 + dev->management_fib_count = 0;
471 + spin_lock_init(&dev->manage_lock);
472 dev->max_fib_size = sizeof(struct hw_fib);
473 dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
474 - sizeof(struct aac_fibhdr)
475 diff -ru a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
476 --- a/drivers/scsi/aacraid/commsup.c 2009-09-16 16:40:05.000000000 +0530
477 +++ b/drivers/scsi/aacraid/commsup.c 2009-09-16 17:41:00.000000000 +0530
480 void aac_fib_free(struct fib *fibptr)
482 - unsigned long flags;
483 + unsigned long flags, flagsv;
485 + spin_lock_irqsave(&fibptr->event_lock, flagsv);
486 + if (fibptr->done == 2) {
487 + spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
490 + spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
492 spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
493 if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
494 @@ -473,14 +480,27 @@
497 spin_lock_irqsave(&fibptr->event_lock, flags);
498 - aac_adapter_deliver(fibptr);
500 + if (aac_adapter_deliver(fibptr) != 0) {
501 + printk(KERN_ERR "aac_fib_send: returned -EBUSY\n");
503 + spin_unlock_irqrestore(&fibptr->event_lock, flags);
509 * If the caller wanted us to wait for response wait now.
513 + unsigned long mflags;
514 spin_unlock_irqrestore(&fibptr->event_lock, flags);
516 + spin_lock_irqsave(&dev->manage_lock, mflags);
517 + dev->management_fib_count++;
518 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
520 /* Only set for first known interruptable command */
523 @@ -515,15 +535,14 @@
527 - } else if (down_interruptible(&fibptr->event_wait)) {
529 - up(&fibptr->event_wait);
532 + down_interruptible(&fibptr->event_wait);
534 spin_lock_irqsave(&fibptr->event_lock, flags);
535 - if ((fibptr->done == 0) || (fibptr->done == 2)) {
536 + if (fibptr->done == 0) {
537 fibptr->done = 2; /* Tell interrupt we aborted */
538 spin_unlock_irqrestore(&fibptr->event_lock, flags);
540 + return -ERESTARTSYS;
542 spin_unlock_irqrestore(&fibptr->event_lock, flags);
543 BUG_ON(fibptr->done == 0);
546 int aac_fib_complete(struct fib *fibptr)
548 + unsigned long flags;
549 struct hw_fib * hw_fib = fibptr->hw_fib_va;
553 * command is complete that we had sent to the adapter and this
554 * cdb could be reused.
556 + spin_lock_irqsave(&fibptr->event_lock, flags);
557 + if (fibptr->done == 2) {
558 + spin_unlock_irqrestore(&fibptr->event_lock, flags);
561 + spin_unlock_irqrestore(&fibptr->event_lock, flags);
563 if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
564 (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
566 @@ -1355,7 +1382,10 @@
569 aac_fib_complete(fibctx);
570 - aac_fib_free(fibctx);
571 + /* FIB should be freed only after getting
572 + * the response from the F/W */
573 + if (status != -ERESTARTSYS)
574 + aac_fib_free(fibctx);
578 @@ -1759,6 +1789,7 @@
581 if ((fibptr = aac_fib_alloc(dev))) {
585 aac_fib_init(fibptr);
586 @@ -1769,15 +1800,21 @@
588 *info = cpu_to_le32(now.tv_sec);
590 - (void)aac_fib_send(SendHostTime,
591 + status = aac_fib_send(SendHostTime,
598 - aac_fib_complete(fibptr);
599 - aac_fib_free(fibptr);
600 + /* Do not set XferState to zero unless
601 + * receives a response from F/W */
603 + aac_fib_complete(fibptr);
604 + /* FIB should be freed only after
605 + * getting the response from the F/W */
606 + if (status != -ERESTARTSYS)
607 + aac_fib_free(fibptr);
609 difference = (long)(unsigned)update_interval*HZ;
611 diff -ru a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
612 --- a/drivers/scsi/aacraid/dpcsup.c 2009-09-16 16:40:05.000000000 +0530
613 +++ b/drivers/scsi/aacraid/dpcsup.c 2009-09-16 17:41:00.000000000 +0530
615 struct hw_fib * hwfib;
618 - unsigned long flags;
619 + unsigned long flags, mflags;
621 spin_lock_irqsave(q->lock, flags);
623 @@ -125,12 +125,21 @@
626 spin_lock_irqsave(&fib->event_lock, flagv);
630 - up(&fib->event_wait);
631 + up(&fib->event_wait);
633 spin_unlock_irqrestore(&fib->event_lock, flagv);
635 + spin_lock_irqsave(&dev->manage_lock, mflags);
636 + dev->management_fib_count--;
637 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
639 FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
640 if (fib->done == 2) {
641 + spin_lock_irqsave(&fib->event_lock, flagv);
643 + spin_unlock_irqrestore(&fib->event_lock, flagv);
644 aac_fib_complete(fib);
649 unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
651 + unsigned long mflags;
652 dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
653 if ((index & 0x00000002L)) {
654 struct hw_fib * hw_fib;
655 @@ -320,11 +330,25 @@
657 dprintk((KERN_INFO "event_wait up\n"));
658 spin_lock_irqsave(&fib->event_lock, flagv);
662 - up(&fib->event_wait);
663 + up(&fib->event_wait);
665 spin_unlock_irqrestore(&fib->event_lock, flagv);
667 + spin_lock_irqsave(&dev->manage_lock, mflags);
668 + dev->management_fib_count--;
669 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
671 FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
672 + if (fib->done == 2) {
673 + spin_lock_irqsave(&fib->event_lock, flagv);
675 + spin_unlock_irqrestore(&fib->event_lock, flagv);
676 + aac_fib_complete(fib);
683 diff -ru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
684 --- a/drivers/scsi/aacraid/linit.c 2009-09-16 16:40:05.000000000 +0530
685 +++ b/drivers/scsi/aacraid/linit.c 2009-09-16 17:41:00.000000000 +0530
688 * Note: The last field is used to index into aac_drivers below.
690 -static struct pci_device_id aac_pci_tbl[] = {
691 +#ifdef DECLARE_PCI_DEVICE_TABLE
692 +static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
693 +#elif defined(__devinitconst)
694 +static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
696 +static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
698 { 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
699 { 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
700 { 0x1028, 0x0003, 0x1028, 0x0003, 0, 0, 2 }, /* PERC 3/Si (SlimFast/PERC3Si */