]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.drivers/aacraid-24701-update
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / aacraid-24701-update
1 From: Penchala Narsimha Reddy Chilakala <ServeRAIDDriver@hcl.in>
2 Subject: Problems with aacraid
3 References: bnc#524242
4
5 The attached patch aac24701 was generated for the following issues only:
6
7 Issue:1
8 --------
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.
12
13 Fix details:
14 -------------
15 Fixed by adding parentheses.
16
17 Issue:2
18 --------
19 Driver IOCTLs is signaled with EINTR while waiting on response from the
20 lower layers. Returning “EINTR” will never initiate internal retry.
21
22 Fix details:
23 -------------
24 Fixed by replacing “EINTR” with “ERESTARTSYS” for mid-layer retries.
25
26 Issue:3
27 --------
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.
32
33 Fix details:
34 -------------
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)
37
38 Issue:4
39 --------
40 The driver exhibits performance problems as the execution of
41 SYNCHRONIZE CACHE is quite time-consuming.
42
43 Fix details:
44 -------------
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.
47
48 Signed-off-by: Hannes Reinecke <hare@suse.de>
49
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
53 @@ -143,7 +143,7 @@
54 */
55
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;
60 int aac_msi;
61 int aac_commit = -1;
62 @@ -157,7 +157,7 @@
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."
70 " 0=off, 1=on");
71 @@ -217,6 +217,14 @@
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.");
74
75 +int aac_wwn = 1;
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"
78 + "\t0 - Disable\n"
79 + "\t1 - Array Meta Data Signature (default)\n"
80 + "\t2 - Adapter Serial Number");
81 +
82 +
83 static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
84 struct fib *fibptr) {
85 struct scsi_device *device;
86 @@ -285,7 +293,10 @@
87 status = -EINVAL;
88 }
89 }
90 - aac_fib_complete(fibptr);
91 + /* Do not set XferState to zero unless receives a response from F/W */
92 + if (status >= 0)
93 + aac_fib_complete(fibptr);
94 +
95 /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
96 if (status >= 0) {
97 if ((aac_commit == 1) || commit_flag) {
98 @@ -302,13 +313,18 @@
99 FsaNormal,
100 1, 1,
101 NULL, NULL);
102 - aac_fib_complete(fibptr);
103 + /* Do not set XferState to zero unless
104 + * receives a response from F/W */
105 + if (status >= 0)
106 + aac_fib_complete(fibptr);
107 } else if (aac_commit == 0) {
108 printk(KERN_WARNING
109 "aac_get_config_status: Foreign device configurations are being ignored\n");
110 }
111 }
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);
116 return status;
117 }
118
119 @@ -347,7 +363,9 @@
120 maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
121 aac_fib_complete(fibptr);
122 }
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);
127
128 if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
129 maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
130 @@ -1206,9 +1224,8 @@
131
132 static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
133 {
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))
139 return FAILED;
140 return aac_scsi_32(fib, cmd);
141 }
142 @@ -1238,8 +1255,12 @@
143 NULL);
144
145 if (rcode < 0) {
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);
153 + }
154 return rcode;
155 }
156 memcpy(&dev->adapter_info, info, sizeof(*info));
157 @@ -1263,6 +1284,12 @@
158
159 if (rcode >= 0)
160 memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));
161 + if (rcode == -ERESTARTSYS) {
162 + fibptr = aac_fib_alloc(dev);
163 + if (!fibptr)
164 + return -ENOMEM;
165 + }
166 +
167 }
168
169
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);
173
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)) {
180 if (!dev->in_reset)
181 printk(KERN_INFO "%s%d: 64bit support enabled.\n",
182 dev->name, dev->id);
183 @@ -1382,6 +1412,15 @@
184 if(dacmode != -1) {
185 dev->dac_support = (dacmode!=0);
186 }
187 +
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;
192 + dev->jbod = 0;
193 + expose_physicals = 0;
194 + }
195 +
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;
201 }
202 }
203 -
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);
210 + }
211
212 return rcode;
213 }
214 @@ -1614,6 +1655,7 @@
215 * Alocate and initialize a Fib
216 */
217 if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
218 + printk(KERN_WARNING "aac_read: fib allocation failed\n");
219 return -1;
220 }
221
222 @@ -1693,9 +1735,14 @@
223 * Allocate and initialize a Fib then setup a BlockWrite command
224 */
225 if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
226 - scsicmd->result = DID_ERROR << 16;
227 - scsicmd->scsi_done(scsicmd);
228 - return 0;
229 + /* FIB temporarily unavailable,not catastrophic failure */
230 +
231 + /* scsicmd->result = DID_ERROR << 16;
232 + * scsicmd->scsi_done(scsicmd);
233 + * return 0;
234 + */
235 + printk(KERN_WARNING "aac_write: fib allocation failed\n");
236 + return -1;
237 }
238
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));
243
244 - if (scsicmd->cmnd[1] & 0x1) {
245 + if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {
246 char *arr = (char *)&inq_data;
247
248 /* EVPD bit set */
249 @@ -2081,7 +2128,12 @@
250 arr[1] = scsicmd->cmnd[2];
251 scsi_sg_copy_from_buffer(scsicmd, &inq_data,
252 sizeof(inq_data));
253 - return aac_get_container_serial(scsicmd);
254 + if (aac_wwn != 2)
255 + return aac_get_container_serial(
256 + scsicmd);
257 + /* SLES 10 SP1 special */
258 + scsicmd->result = DID_OK << 16 |
259 + COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
260 } else {
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
266 @@ -12,7 +12,7 @@
267 *----------------------------------------------------------------------------*/
268
269 #ifndef AAC_DRIVER_BUILD
270 -# define AAC_DRIVER_BUILD 2456
271 +# define AAC_DRIVER_BUILD 24701
272 # define AAC_DRIVER_BRANCH "-ms"
273 #endif
274 #define MAXIMUM_NUM_CONTAINERS 32
275 @@ -865,7 +865,11 @@
276 u8 MfgPcbaSerialNo[12];
277 u8 MfgWWNName[8];
278 __le32 SupportedOptions2;
279 - __le32 ReservedGrowth[1];
280 + __le32 StructExpansion;
281 + /* StructExpansion == 1 */
282 + __le32 FeatureBits3;
283 + __le32 SupportedPerformanceModes;
284 + __le32 ReservedForFutureGrowth[80];
285 };
286 #define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
287 #define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
288 @@ -1020,6 +1024,7 @@
289 u8 jbod;
290 u8 cache_protected;
291 u8 dac_support;
292 + u8 needs_dac;
293 u8 raid_scsi_mode;
294 u8 comm_interface;
295 # define AAC_COMM_PRODUCER 0
296 @@ -1031,6 +1036,9 @@
297 u8 printf_enabled;
298 u8 in_reset;
299 u8 msi;
300 + int management_fib_count;
301 + spinlock_t manage_lock;
302 +
303 };
304
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
309 @@ -143,7 +143,7 @@
310 fibptr->hw_fib_pa = hw_fib_pa;
311 fibptr->hw_fib_va = hw_fib;
312 }
313 - if (retval != -EINTR)
314 + if (retval != -ERESTARTSYS)
315 aac_fib_free(fibptr);
316 return retval;
317 }
318 @@ -312,7 +312,7 @@
319 }
320 if (f.wait) {
321 if(down_interruptible(&fibctx->wait_sem) < 0) {
322 - status = -EINTR;
323 + status = -ERESTARTSYS;
324 } else {
325 /* Lock again and retry */
326 spin_lock_irqsave(&dev->fib_lock, flags);
327 @@ -583,10 +583,10 @@
328 u64 addr;
329 void* p;
330 if (upsg->sg[i].count >
331 - (dev->adapter_info.options &
332 + ((dev->adapter_info.options &
333 AAC_OPT_NEW_COMM) ?
334 (dev->scsi_host_ptr->max_sectors << 9) :
335 - 65536) {
336 + 65536)) {
337 rcode = -EINVAL;
338 goto cleanup;
339 }
340 @@ -635,10 +635,10 @@
341 u64 addr;
342 void* p;
343 if (usg->sg[i].count >
344 - (dev->adapter_info.options &
345 + ((dev->adapter_info.options &
346 AAC_OPT_NEW_COMM) ?
347 (dev->scsi_host_ptr->max_sectors << 9) :
348 - 65536) {
349 + 65536)) {
350 rcode = -EINVAL;
351 goto cleanup;
352 }
353 @@ -685,10 +685,10 @@
354 uintptr_t addr;
355 void* p;
356 if (usg->sg[i].count >
357 - (dev->adapter_info.options &
358 + ((dev->adapter_info.options &
359 AAC_OPT_NEW_COMM) ?
360 (dev->scsi_host_ptr->max_sectors << 9) :
361 - 65536) {
362 + 65536)) {
363 rcode = -EINVAL;
364 goto cleanup;
365 }
366 @@ -724,10 +724,10 @@
367 dma_addr_t addr;
368 void* p;
369 if (upsg->sg[i].count >
370 - (dev->adapter_info.options &
371 + ((dev->adapter_info.options &
372 AAC_OPT_NEW_COMM) ?
373 (dev->scsi_host_ptr->max_sectors << 9) :
374 - 65536) {
375 + 65536)) {
376 rcode = -EINVAL;
377 goto cleanup;
378 }
379 @@ -762,8 +762,8 @@
380 psg->count = cpu_to_le32(sg_indx+1);
381 status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
382 }
383 - if (status == -EINTR) {
384 - rcode = -EINTR;
385 + if (status == -ERESTARTSYS) {
386 + rcode = -ERESTARTSYS;
387 goto cleanup;
388 }
389
390 @@ -800,7 +800,7 @@
391 for(i=0; i <= sg_indx; i++){
392 kfree(sg_list[i]);
393 }
394 - if (rcode != -EINTR) {
395 + if (rcode != -ERESTARTSYS) {
396 aac_fib_complete(srbfib);
397 aac_fib_free(srbfib);
398 }
399 @@ -832,13 +832,22 @@
400 int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
401 {
402 int status;
403 -
404 + unsigned long mflags;
405 +
406 /*
407 * HBA gets first crack
408 */
409
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);
415 + return -EBUSY;
416 + }
417 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
418 status = aac_dev_ioctl(dev, cmd, arg);
419 - if(status != -ENOTTY)
420 + if (status != -ENOTTY)
421 return status;
422
423 switch (cmd) {
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
427 @@ -54,6 +54,7 @@
428 const unsigned long printfbufsiz = 256;
429 struct aac_init *init;
430 dma_addr_t phys;
431 + unsigned long aac_max_hostphysmempages;
432
433 size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
434
435 @@ -90,7 +91,18 @@
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);
440 + /*
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.
446 + */
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);
450 + else
451 + init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
452
453 init->InitFlags = 0;
454 if (dev->comm_interface == AAC_COMM_MESSAGE) {
455 @@ -182,7 +194,9 @@
456
457 if (status >= 0)
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);
463 return status;
464 }
465
466 @@ -292,6 +306,8 @@
467 /*
468 * Check the preferred comm settings, defaults from template.
469 */
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
478 @@ -189,7 +189,14 @@
479
480 void aac_fib_free(struct fib *fibptr)
481 {
482 - unsigned long flags;
483 + unsigned long flags, flagsv;
484 +
485 + spin_lock_irqsave(&fibptr->event_lock, flagsv);
486 + if (fibptr->done == 2) {
487 + spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
488 + return;
489 + }
490 + spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
491
492 spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
493 if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
494 @@ -473,14 +480,27 @@
495
496 if(wait)
497 spin_lock_irqsave(&fibptr->event_lock, flags);
498 - aac_adapter_deliver(fibptr);
499 +
500 + if (aac_adapter_deliver(fibptr) != 0) {
501 + printk(KERN_ERR "aac_fib_send: returned -EBUSY\n");
502 + if (wait)
503 + spin_unlock_irqrestore(&fibptr->event_lock, flags);
504 + return -EBUSY;
505 + }
506 +
507
508 /*
509 * If the caller wanted us to wait for response wait now.
510 */
511
512 if (wait) {
513 + unsigned long mflags;
514 spin_unlock_irqrestore(&fibptr->event_lock, flags);
515 +
516 + spin_lock_irqsave(&dev->manage_lock, mflags);
517 + dev->management_fib_count++;
518 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
519 +
520 /* Only set for first known interruptable command */
521 if (wait < 0) {
522 /*
523 @@ -515,15 +535,14 @@
524 }
525 udelay(5);
526 }
527 - } else if (down_interruptible(&fibptr->event_wait)) {
528 - fibptr->done = 2;
529 - up(&fibptr->event_wait);
530 - }
531 + } else
532 + down_interruptible(&fibptr->event_wait);
533 +
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);
539 - return -EINTR;
540 + return -ERESTARTSYS;
541 }
542 spin_unlock_irqrestore(&fibptr->event_lock, flags);
543 BUG_ON(fibptr->done == 0);
544 @@ -689,6 +708,7 @@
545
546 int aac_fib_complete(struct fib *fibptr)
547 {
548 + unsigned long flags;
549 struct hw_fib * hw_fib = fibptr->hw_fib_va;
550
551 /*
552 @@ -709,6 +729,13 @@
553 * command is complete that we had sent to the adapter and this
554 * cdb could be reused.
555 */
556 + spin_lock_irqsave(&fibptr->event_lock, flags);
557 + if (fibptr->done == 2) {
558 + spin_unlock_irqrestore(&fibptr->event_lock, flags);
559 + return 0;
560 + }
561 + spin_unlock_irqrestore(&fibptr->event_lock, flags);
562 +
563 if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
564 (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
565 {
566 @@ -1355,7 +1382,10 @@
567
568 if (status >= 0)
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);
575 }
576 }
577
578 @@ -1759,6 +1789,7 @@
579 struct fib *fibptr;
580
581 if ((fibptr = aac_fib_alloc(dev))) {
582 + int status;
583 __le32 *info;
584
585 aac_fib_init(fibptr);
586 @@ -1769,15 +1800,21 @@
587
588 *info = cpu_to_le32(now.tv_sec);
589
590 - (void)aac_fib_send(SendHostTime,
591 + status = aac_fib_send(SendHostTime,
592 fibptr,
593 sizeof(*info),
594 FsaNormal,
595 1, 1,
596 NULL,
597 NULL);
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 */
602 + if (status >= 0)
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);
608 }
609 difference = (long)(unsigned)update_interval*HZ;
610 } else {
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
614 @@ -57,7 +57,7 @@
615 struct hw_fib * hwfib;
616 struct fib * fib;
617 int consumed = 0;
618 - unsigned long flags;
619 + unsigned long flags, mflags;
620
621 spin_lock_irqsave(q->lock, flags);
622 /*
623 @@ -125,12 +125,21 @@
624 } else {
625 unsigned long flagv;
626 spin_lock_irqsave(&fib->event_lock, flagv);
627 - if (!fib->done)
628 + if (!fib->done) {
629 fib->done = 1;
630 - up(&fib->event_wait);
631 + up(&fib->event_wait);
632 + }
633 spin_unlock_irqrestore(&fib->event_lock, flagv);
634 +
635 + spin_lock_irqsave(&dev->manage_lock, mflags);
636 + dev->management_fib_count--;
637 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
638 +
639 FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
640 if (fib->done == 2) {
641 + spin_lock_irqsave(&fib->event_lock, flagv);
642 + fib->done = 0;
643 + spin_unlock_irqrestore(&fib->event_lock, flagv);
644 aac_fib_complete(fib);
645 aac_fib_free(fib);
646 }
647 @@ -232,6 +241,7 @@
648
649 unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
650 {
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 @@
656 unsigned long flagv;
657 dprintk((KERN_INFO "event_wait up\n"));
658 spin_lock_irqsave(&fib->event_lock, flagv);
659 - if (!fib->done)
660 + if (!fib->done) {
661 fib->done = 1;
662 - up(&fib->event_wait);
663 + up(&fib->event_wait);
664 + }
665 spin_unlock_irqrestore(&fib->event_lock, flagv);
666 +
667 + spin_lock_irqsave(&dev->manage_lock, mflags);
668 + dev->management_fib_count--;
669 + spin_unlock_irqrestore(&dev->manage_lock, mflags);
670 +
671 FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
672 + if (fib->done == 2) {
673 + spin_lock_irqsave(&fib->event_lock, flagv);
674 + fib->done = 0;
675 + spin_unlock_irqrestore(&fib->event_lock, flagv);
676 + aac_fib_complete(fib);
677 + aac_fib_free(fib);
678 + }
679 +
680 }
681 return 0;
682 }
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
686 @@ -86,7 +86,13 @@
687 *
688 * Note: The last field is used to index into aac_drivers below.
689 */
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 = {
695 +#else
696 +static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
697 +#endif
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 */