diff options
| -rw-r--r-- | drivers/scsi/aacraid/aachba.c | 52 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/aacraid.h | 5 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/commctrl.c | 28 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/comminit.c | 6 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/commsup.c | 72 | ||||
| -rw-r--r-- | drivers/scsi/aacraid/dpcsup.c | 36 |
6 files changed, 154 insertions, 45 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 2a889853a106..7e26ebc26661 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
| @@ -293,7 +293,10 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) | |||
| 293 | status = -EINVAL; | 293 | status = -EINVAL; |
| 294 | } | 294 | } |
| 295 | } | 295 | } |
| 296 | aac_fib_complete(fibptr); | 296 | /* Do not set XferState to zero unless receives a response from F/W */ |
| 297 | if (status >= 0) | ||
| 298 | aac_fib_complete(fibptr); | ||
| 299 | |||
| 297 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ | 300 | /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ |
| 298 | if (status >= 0) { | 301 | if (status >= 0) { |
| 299 | if ((aac_commit == 1) || commit_flag) { | 302 | if ((aac_commit == 1) || commit_flag) { |
| @@ -310,13 +313,18 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) | |||
| 310 | FsaNormal, | 313 | FsaNormal, |
| 311 | 1, 1, | 314 | 1, 1, |
| 312 | NULL, NULL); | 315 | NULL, NULL); |
| 313 | aac_fib_complete(fibptr); | 316 | /* Do not set XferState to zero unless |
| 317 | * receives a response from F/W */ | ||
| 318 | if (status >= 0) | ||
| 319 | aac_fib_complete(fibptr); | ||
| 314 | } else if (aac_commit == 0) { | 320 | } else if (aac_commit == 0) { |
| 315 | printk(KERN_WARNING | 321 | printk(KERN_WARNING |
| 316 | "aac_get_config_status: Foreign device configurations are being ignored\n"); | 322 | "aac_get_config_status: Foreign device configurations are being ignored\n"); |
| 317 | } | 323 | } |
| 318 | } | 324 | } |
| 319 | aac_fib_free(fibptr); | 325 | /* FIB should be freed only after getting the response from the F/W */ |
| 326 | if (status != -ERESTARTSYS) | ||
| 327 | aac_fib_free(fibptr); | ||
| 320 | return status; | 328 | return status; |
| 321 | } | 329 | } |
| 322 | 330 | ||
| @@ -355,7 +363,9 @@ int aac_get_containers(struct aac_dev *dev) | |||
| 355 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); | 363 | maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); |
| 356 | aac_fib_complete(fibptr); | 364 | aac_fib_complete(fibptr); |
| 357 | } | 365 | } |
| 358 | aac_fib_free(fibptr); | 366 | /* FIB should be freed only after getting the response from the F/W */ |
| 367 | if (status != -ERESTARTSYS) | ||
| 368 | aac_fib_free(fibptr); | ||
| 359 | 369 | ||
| 360 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) | 370 | if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) |
| 361 | maximum_num_containers = MAXIMUM_NUM_CONTAINERS; | 371 | maximum_num_containers = MAXIMUM_NUM_CONTAINERS; |
| @@ -1245,8 +1255,12 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
| 1245 | NULL); | 1255 | NULL); |
| 1246 | 1256 | ||
| 1247 | if (rcode < 0) { | 1257 | if (rcode < 0) { |
| 1248 | aac_fib_complete(fibptr); | 1258 | /* FIB should be freed only after |
| 1249 | aac_fib_free(fibptr); | 1259 | * getting the response from the F/W */ |
| 1260 | if (rcode != -ERESTARTSYS) { | ||
| 1261 | aac_fib_complete(fibptr); | ||
| 1262 | aac_fib_free(fibptr); | ||
| 1263 | } | ||
| 1250 | return rcode; | 1264 | return rcode; |
| 1251 | } | 1265 | } |
| 1252 | memcpy(&dev->adapter_info, info, sizeof(*info)); | 1266 | memcpy(&dev->adapter_info, info, sizeof(*info)); |
| @@ -1270,6 +1284,12 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
| 1270 | 1284 | ||
| 1271 | if (rcode >= 0) | 1285 | if (rcode >= 0) |
| 1272 | memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo)); | 1286 | memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo)); |
| 1287 | if (rcode == -ERESTARTSYS) { | ||
| 1288 | fibptr = aac_fib_alloc(dev); | ||
| 1289 | if (!fibptr) | ||
| 1290 | return -ENOMEM; | ||
| 1291 | } | ||
| 1292 | |||
| 1273 | } | 1293 | } |
| 1274 | 1294 | ||
| 1275 | 1295 | ||
| @@ -1470,9 +1490,11 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
| 1470 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; | 1490 | (dev->scsi_host_ptr->sg_tablesize * 8) + 112; |
| 1471 | } | 1491 | } |
| 1472 | } | 1492 | } |
| 1473 | 1493 | /* FIB should be freed only after getting the response from the F/W */ | |
| 1474 | aac_fib_complete(fibptr); | 1494 | if (rcode != -ERESTARTSYS) { |
| 1475 | aac_fib_free(fibptr); | 1495 | aac_fib_complete(fibptr); |
| 1496 | aac_fib_free(fibptr); | ||
| 1497 | } | ||
| 1476 | 1498 | ||
| 1477 | return rcode; | 1499 | return rcode; |
| 1478 | } | 1500 | } |
| @@ -1633,6 +1655,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) | |||
| 1633 | * Alocate and initialize a Fib | 1655 | * Alocate and initialize a Fib |
| 1634 | */ | 1656 | */ |
| 1635 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { | 1657 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
| 1658 | printk(KERN_WARNING "aac_read: fib allocation failed\n"); | ||
| 1636 | return -1; | 1659 | return -1; |
| 1637 | } | 1660 | } |
| 1638 | 1661 | ||
| @@ -1712,9 +1735,14 @@ static int aac_write(struct scsi_cmnd * scsicmd) | |||
| 1712 | * Allocate and initialize a Fib then setup a BlockWrite command | 1735 | * Allocate and initialize a Fib then setup a BlockWrite command |
| 1713 | */ | 1736 | */ |
| 1714 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { | 1737 | if (!(cmd_fibcontext = aac_fib_alloc(dev))) { |
| 1715 | scsicmd->result = DID_ERROR << 16; | 1738 | /* FIB temporarily unavailable,not catastrophic failure */ |
| 1716 | scsicmd->scsi_done(scsicmd); | 1739 | |
| 1717 | return 0; | 1740 | /* scsicmd->result = DID_ERROR << 16; |
| 1741 | * scsicmd->scsi_done(scsicmd); | ||
| 1742 | * return 0; | ||
| 1743 | */ | ||
| 1744 | printk(KERN_WARNING "aac_write: fib allocation failed\n"); | ||
| 1745 | return -1; | ||
| 1718 | } | 1746 | } |
| 1719 | 1747 | ||
| 1720 | status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); | 1748 | status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 83986ed86556..619c02d9c862 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | *----------------------------------------------------------------------------*/ | 12 | *----------------------------------------------------------------------------*/ |
| 13 | 13 | ||
| 14 | #ifndef AAC_DRIVER_BUILD | 14 | #ifndef AAC_DRIVER_BUILD |
| 15 | # define AAC_DRIVER_BUILD 2461 | 15 | # define AAC_DRIVER_BUILD 24702 |
| 16 | # define AAC_DRIVER_BRANCH "-ms" | 16 | # define AAC_DRIVER_BRANCH "-ms" |
| 17 | #endif | 17 | #endif |
| 18 | #define MAXIMUM_NUM_CONTAINERS 32 | 18 | #define MAXIMUM_NUM_CONTAINERS 32 |
| @@ -1036,6 +1036,9 @@ struct aac_dev | |||
| 1036 | u8 printf_enabled; | 1036 | u8 printf_enabled; |
| 1037 | u8 in_reset; | 1037 | u8 in_reset; |
| 1038 | u8 msi; | 1038 | u8 msi; |
| 1039 | int management_fib_count; | ||
| 1040 | spinlock_t manage_lock; | ||
| 1041 | |||
| 1039 | }; | 1042 | }; |
| 1040 | 1043 | ||
| 1041 | #define aac_adapter_interrupt(dev) \ | 1044 | #define aac_adapter_interrupt(dev) \ |
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 0391d759dfdb..9c0c91178538 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c | |||
| @@ -153,7 +153,7 @@ cleanup: | |||
| 153 | fibptr->hw_fib_pa = hw_fib_pa; | 153 | fibptr->hw_fib_pa = hw_fib_pa; |
| 154 | fibptr->hw_fib_va = hw_fib; | 154 | fibptr->hw_fib_va = hw_fib; |
| 155 | } | 155 | } |
| 156 | if (retval != -EINTR) | 156 | if (retval != -ERESTARTSYS) |
| 157 | aac_fib_free(fibptr); | 157 | aac_fib_free(fibptr); |
| 158 | return retval; | 158 | return retval; |
| 159 | } | 159 | } |
| @@ -322,7 +322,7 @@ return_fib: | |||
| 322 | } | 322 | } |
| 323 | if (f.wait) { | 323 | if (f.wait) { |
| 324 | if(down_interruptible(&fibctx->wait_sem) < 0) { | 324 | if(down_interruptible(&fibctx->wait_sem) < 0) { |
| 325 | status = -EINTR; | 325 | status = -ERESTARTSYS; |
| 326 | } else { | 326 | } else { |
| 327 | /* Lock again and retry */ | 327 | /* Lock again and retry */ |
| 328 | spin_lock_irqsave(&dev->fib_lock, flags); | 328 | spin_lock_irqsave(&dev->fib_lock, flags); |
| @@ -593,10 +593,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 593 | u64 addr; | 593 | u64 addr; |
| 594 | void* p; | 594 | void* p; |
| 595 | if (upsg->sg[i].count > | 595 | if (upsg->sg[i].count > |
| 596 | (dev->adapter_info.options & | 596 | ((dev->adapter_info.options & |
| 597 | AAC_OPT_NEW_COMM) ? | 597 | AAC_OPT_NEW_COMM) ? |
| 598 | (dev->scsi_host_ptr->max_sectors << 9) : | 598 | (dev->scsi_host_ptr->max_sectors << 9) : |
| 599 | 65536) { | 599 | 65536)) { |
| 600 | rcode = -EINVAL; | 600 | rcode = -EINVAL; |
| 601 | goto cleanup; | 601 | goto cleanup; |
| 602 | } | 602 | } |
| @@ -645,10 +645,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 645 | u64 addr; | 645 | u64 addr; |
| 646 | void* p; | 646 | void* p; |
| 647 | if (usg->sg[i].count > | 647 | if (usg->sg[i].count > |
| 648 | (dev->adapter_info.options & | 648 | ((dev->adapter_info.options & |
| 649 | AAC_OPT_NEW_COMM) ? | 649 | AAC_OPT_NEW_COMM) ? |
| 650 | (dev->scsi_host_ptr->max_sectors << 9) : | 650 | (dev->scsi_host_ptr->max_sectors << 9) : |
| 651 | 65536) { | 651 | 65536)) { |
| 652 | rcode = -EINVAL; | 652 | rcode = -EINVAL; |
| 653 | goto cleanup; | 653 | goto cleanup; |
| 654 | } | 654 | } |
| @@ -695,10 +695,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 695 | uintptr_t addr; | 695 | uintptr_t addr; |
| 696 | void* p; | 696 | void* p; |
| 697 | if (usg->sg[i].count > | 697 | if (usg->sg[i].count > |
| 698 | (dev->adapter_info.options & | 698 | ((dev->adapter_info.options & |
| 699 | AAC_OPT_NEW_COMM) ? | 699 | AAC_OPT_NEW_COMM) ? |
| 700 | (dev->scsi_host_ptr->max_sectors << 9) : | 700 | (dev->scsi_host_ptr->max_sectors << 9) : |
| 701 | 65536) { | 701 | 65536)) { |
| 702 | rcode = -EINVAL; | 702 | rcode = -EINVAL; |
| 703 | goto cleanup; | 703 | goto cleanup; |
| 704 | } | 704 | } |
| @@ -734,10 +734,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 734 | dma_addr_t addr; | 734 | dma_addr_t addr; |
| 735 | void* p; | 735 | void* p; |
| 736 | if (upsg->sg[i].count > | 736 | if (upsg->sg[i].count > |
| 737 | (dev->adapter_info.options & | 737 | ((dev->adapter_info.options & |
| 738 | AAC_OPT_NEW_COMM) ? | 738 | AAC_OPT_NEW_COMM) ? |
| 739 | (dev->scsi_host_ptr->max_sectors << 9) : | 739 | (dev->scsi_host_ptr->max_sectors << 9) : |
| 740 | 65536) { | 740 | 65536)) { |
| 741 | rcode = -EINVAL; | 741 | rcode = -EINVAL; |
| 742 | goto cleanup; | 742 | goto cleanup; |
| 743 | } | 743 | } |
| @@ -772,8 +772,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) | |||
| 772 | psg->count = cpu_to_le32(sg_indx+1); | 772 | psg->count = cpu_to_le32(sg_indx+1); |
| 773 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); | 773 | status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); |
| 774 | } | 774 | } |
| 775 | if (status == -EINTR) { | 775 | if (status == -ERESTARTSYS) { |
| 776 | rcode = -EINTR; | 776 | rcode = -ERESTARTSYS; |
| 777 | goto cleanup; | 777 | goto cleanup; |
| 778 | } | 778 | } |
| 779 | 779 | ||
| @@ -810,7 +810,7 @@ cleanup: | |||
| 810 | for(i=0; i <= sg_indx; i++){ | 810 | for(i=0; i <= sg_indx; i++){ |
| 811 | kfree(sg_list[i]); | 811 | kfree(sg_list[i]); |
| 812 | } | 812 | } |
| 813 | if (rcode != -EINTR) { | 813 | if (rcode != -ERESTARTSYS) { |
| 814 | aac_fib_complete(srbfib); | 814 | aac_fib_complete(srbfib); |
| 815 | aac_fib_free(srbfib); | 815 | aac_fib_free(srbfib); |
| 816 | } | 816 | } |
| @@ -848,7 +848,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) | |||
| 848 | */ | 848 | */ |
| 849 | 849 | ||
| 850 | status = aac_dev_ioctl(dev, cmd, arg); | 850 | status = aac_dev_ioctl(dev, cmd, arg); |
| 851 | if(status != -ENOTTY) | 851 | if (status != -ENOTTY) |
| 852 | return status; | 852 | return status; |
| 853 | 853 | ||
| 854 | switch (cmd) { | 854 | switch (cmd) { |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 666d5151d628..a7261486ccd4 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
| @@ -194,7 +194,9 @@ int aac_send_shutdown(struct aac_dev * dev) | |||
| 194 | 194 | ||
| 195 | if (status >= 0) | 195 | if (status >= 0) |
| 196 | aac_fib_complete(fibctx); | 196 | aac_fib_complete(fibctx); |
| 197 | aac_fib_free(fibctx); | 197 | /* FIB should be freed only after getting the response from the F/W */ |
| 198 | if (status != -ERESTARTSYS) | ||
| 199 | aac_fib_free(fibctx); | ||
| 198 | return status; | 200 | return status; |
| 199 | } | 201 | } |
| 200 | 202 | ||
| @@ -304,6 +306,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) | |||
| 304 | /* | 306 | /* |
| 305 | * Check the preferred comm settings, defaults from template. | 307 | * Check the preferred comm settings, defaults from template. |
| 306 | */ | 308 | */ |
| 309 | dev->management_fib_count = 0; | ||
| 310 | spin_lock_init(&dev->manage_lock); | ||
| 307 | dev->max_fib_size = sizeof(struct hw_fib); | 311 | dev->max_fib_size = sizeof(struct hw_fib); |
| 308 | dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size | 312 | dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size |
| 309 | - sizeof(struct aac_fibhdr) | 313 | - sizeof(struct aac_fibhdr) |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 956261f25181..94d2954d79ae 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
| @@ -189,7 +189,14 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) | |||
| 189 | 189 | ||
| 190 | void aac_fib_free(struct fib *fibptr) | 190 | void aac_fib_free(struct fib *fibptr) |
| 191 | { | 191 | { |
| 192 | unsigned long flags; | 192 | unsigned long flags, flagsv; |
| 193 | |||
| 194 | spin_lock_irqsave(&fibptr->event_lock, flagsv); | ||
| 195 | if (fibptr->done == 2) { | ||
| 196 | spin_unlock_irqrestore(&fibptr->event_lock, flagsv); | ||
| 197 | return; | ||
| 198 | } | ||
| 199 | spin_unlock_irqrestore(&fibptr->event_lock, flagsv); | ||
| 193 | 200 | ||
| 194 | spin_lock_irqsave(&fibptr->dev->fib_lock, flags); | 201 | spin_lock_irqsave(&fibptr->dev->fib_lock, flags); |
| 195 | if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) | 202 | if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) |
| @@ -390,6 +397,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
| 390 | struct hw_fib * hw_fib = fibptr->hw_fib_va; | 397 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
| 391 | unsigned long flags = 0; | 398 | unsigned long flags = 0; |
| 392 | unsigned long qflags; | 399 | unsigned long qflags; |
| 400 | unsigned long mflags = 0; | ||
| 401 | |||
| 393 | 402 | ||
| 394 | if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) | 403 | if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) |
| 395 | return -EBUSY; | 404 | return -EBUSY; |
| @@ -471,9 +480,31 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
| 471 | if (!dev->queues) | 480 | if (!dev->queues) |
| 472 | return -EBUSY; | 481 | return -EBUSY; |
| 473 | 482 | ||
| 474 | if(wait) | 483 | if (wait) { |
| 484 | |||
| 485 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
| 486 | if (dev->management_fib_count >= AAC_NUM_MGT_FIB) { | ||
| 487 | printk(KERN_INFO "No management Fibs Available:%d\n", | ||
| 488 | dev->management_fib_count); | ||
| 489 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
| 490 | return -EBUSY; | ||
| 491 | } | ||
| 492 | dev->management_fib_count++; | ||
| 493 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
| 475 | spin_lock_irqsave(&fibptr->event_lock, flags); | 494 | spin_lock_irqsave(&fibptr->event_lock, flags); |
| 476 | aac_adapter_deliver(fibptr); | 495 | } |
| 496 | |||
| 497 | if (aac_adapter_deliver(fibptr) != 0) { | ||
| 498 | printk(KERN_ERR "aac_fib_send: returned -EBUSY\n"); | ||
| 499 | if (wait) { | ||
| 500 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
| 501 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
| 502 | dev->management_fib_count--; | ||
| 503 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
| 504 | } | ||
| 505 | return -EBUSY; | ||
| 506 | } | ||
| 507 | |||
| 477 | 508 | ||
| 478 | /* | 509 | /* |
| 479 | * If the caller wanted us to wait for response wait now. | 510 | * If the caller wanted us to wait for response wait now. |
| @@ -516,14 +547,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
| 516 | udelay(5); | 547 | udelay(5); |
| 517 | } | 548 | } |
| 518 | } else if (down_interruptible(&fibptr->event_wait)) { | 549 | } else if (down_interruptible(&fibptr->event_wait)) { |
| 519 | fibptr->done = 2; | 550 | /* Do nothing ... satisfy |
| 520 | up(&fibptr->event_wait); | 551 | * down_interruptible must_check */ |
| 521 | } | 552 | } |
| 553 | |||
| 522 | spin_lock_irqsave(&fibptr->event_lock, flags); | 554 | spin_lock_irqsave(&fibptr->event_lock, flags); |
| 523 | if ((fibptr->done == 0) || (fibptr->done == 2)) { | 555 | if (fibptr->done == 0) { |
| 524 | fibptr->done = 2; /* Tell interrupt we aborted */ | 556 | fibptr->done = 2; /* Tell interrupt we aborted */ |
| 525 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 557 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
| 526 | return -EINTR; | 558 | return -ERESTARTSYS; |
| 527 | } | 559 | } |
| 528 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 560 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
| 529 | BUG_ON(fibptr->done == 0); | 561 | BUG_ON(fibptr->done == 0); |
| @@ -689,6 +721,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
| 689 | 721 | ||
| 690 | int aac_fib_complete(struct fib *fibptr) | 722 | int aac_fib_complete(struct fib *fibptr) |
| 691 | { | 723 | { |
| 724 | unsigned long flags; | ||
| 692 | struct hw_fib * hw_fib = fibptr->hw_fib_va; | 725 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
| 693 | 726 | ||
| 694 | /* | 727 | /* |
| @@ -709,6 +742,13 @@ int aac_fib_complete(struct fib *fibptr) | |||
| 709 | * command is complete that we had sent to the adapter and this | 742 | * command is complete that we had sent to the adapter and this |
| 710 | * cdb could be reused. | 743 | * cdb could be reused. |
| 711 | */ | 744 | */ |
| 745 | spin_lock_irqsave(&fibptr->event_lock, flags); | ||
| 746 | if (fibptr->done == 2) { | ||
| 747 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
| 748 | return 0; | ||
| 749 | } | ||
| 750 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | ||
| 751 | |||
| 712 | if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) && | 752 | if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) && |
| 713 | (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) | 753 | (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) |
| 714 | { | 754 | { |
| @@ -1355,7 +1395,10 @@ int aac_reset_adapter(struct aac_dev * aac, int forced) | |||
| 1355 | 1395 | ||
| 1356 | if (status >= 0) | 1396 | if (status >= 0) |
| 1357 | aac_fib_complete(fibctx); | 1397 | aac_fib_complete(fibctx); |
| 1358 | aac_fib_free(fibctx); | 1398 | /* FIB should be freed only after getting |
| 1399 | * the response from the F/W */ | ||
| 1400 | if (status != -ERESTARTSYS) | ||
| 1401 | aac_fib_free(fibctx); | ||
| 1359 | } | 1402 | } |
| 1360 | } | 1403 | } |
| 1361 | 1404 | ||
| @@ -1759,6 +1802,7 @@ int aac_command_thread(void *data) | |||
| 1759 | struct fib *fibptr; | 1802 | struct fib *fibptr; |
| 1760 | 1803 | ||
| 1761 | if ((fibptr = aac_fib_alloc(dev))) { | 1804 | if ((fibptr = aac_fib_alloc(dev))) { |
| 1805 | int status; | ||
| 1762 | __le32 *info; | 1806 | __le32 *info; |
| 1763 | 1807 | ||
| 1764 | aac_fib_init(fibptr); | 1808 | aac_fib_init(fibptr); |
| @@ -1769,15 +1813,21 @@ int aac_command_thread(void *data) | |||
| 1769 | 1813 | ||
| 1770 | *info = cpu_to_le32(now.tv_sec); | 1814 | *info = cpu_to_le32(now.tv_sec); |
| 1771 | 1815 | ||
| 1772 | (void)aac_fib_send(SendHostTime, | 1816 | status = aac_fib_send(SendHostTime, |
| 1773 | fibptr, | 1817 | fibptr, |
| 1774 | sizeof(*info), | 1818 | sizeof(*info), |
| 1775 | FsaNormal, | 1819 | FsaNormal, |
| 1776 | 1, 1, | 1820 | 1, 1, |
| 1777 | NULL, | 1821 | NULL, |
| 1778 | NULL); | 1822 | NULL); |
| 1779 | aac_fib_complete(fibptr); | 1823 | /* Do not set XferState to zero unless |
| 1780 | aac_fib_free(fibptr); | 1824 | * receives a response from F/W */ |
| 1825 | if (status >= 0) | ||
| 1826 | aac_fib_complete(fibptr); | ||
| 1827 | /* FIB should be freed only after | ||
| 1828 | * getting the response from the F/W */ | ||
| 1829 | if (status != -ERESTARTSYS) | ||
| 1830 | aac_fib_free(fibptr); | ||
| 1781 | } | 1831 | } |
| 1782 | difference = (long)(unsigned)update_interval*HZ; | 1832 | difference = (long)(unsigned)update_interval*HZ; |
| 1783 | } else { | 1833 | } else { |
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index abc9ef5d1b10..9c7408fe8c7d 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c | |||
| @@ -57,9 +57,9 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
| 57 | struct hw_fib * hwfib; | 57 | struct hw_fib * hwfib; |
| 58 | struct fib * fib; | 58 | struct fib * fib; |
| 59 | int consumed = 0; | 59 | int consumed = 0; |
| 60 | unsigned long flags; | 60 | unsigned long flags, mflags; |
| 61 | 61 | ||
| 62 | spin_lock_irqsave(q->lock, flags); | 62 | spin_lock_irqsave(q->lock, flags); |
| 63 | /* | 63 | /* |
| 64 | * Keep pulling response QEs off the response queue and waking | 64 | * Keep pulling response QEs off the response queue and waking |
| 65 | * up the waiters until there are no more QEs. We then return | 65 | * up the waiters until there are no more QEs. We then return |
| @@ -125,12 +125,21 @@ unsigned int aac_response_normal(struct aac_queue * q) | |||
| 125 | } else { | 125 | } else { |
| 126 | unsigned long flagv; | 126 | unsigned long flagv; |
| 127 | spin_lock_irqsave(&fib->event_lock, flagv); | 127 | spin_lock_irqsave(&fib->event_lock, flagv); |
| 128 | if (!fib->done) | 128 | if (!fib->done) { |
| 129 | fib->done = 1; | 129 | fib->done = 1; |
| 130 | up(&fib->event_wait); | 130 | up(&fib->event_wait); |
| 131 | } | ||
| 131 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 132 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
| 133 | |||
| 134 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
| 135 | dev->management_fib_count--; | ||
| 136 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
| 137 | |||
| 132 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 138 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
| 133 | if (fib->done == 2) { | 139 | if (fib->done == 2) { |
| 140 | spin_lock_irqsave(&fib->event_lock, flagv); | ||
| 141 | fib->done = 0; | ||
| 142 | spin_unlock_irqrestore(&fib->event_lock, flagv); | ||
| 134 | aac_fib_complete(fib); | 143 | aac_fib_complete(fib); |
| 135 | aac_fib_free(fib); | 144 | aac_fib_free(fib); |
| 136 | } | 145 | } |
| @@ -232,6 +241,7 @@ unsigned int aac_command_normal(struct aac_queue *q) | |||
| 232 | 241 | ||
| 233 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) | 242 | unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) |
| 234 | { | 243 | { |
| 244 | unsigned long mflags; | ||
| 235 | dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); | 245 | dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); |
| 236 | if ((index & 0x00000002L)) { | 246 | if ((index & 0x00000002L)) { |
| 237 | struct hw_fib * hw_fib; | 247 | struct hw_fib * hw_fib; |
| @@ -320,11 +330,25 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) | |||
| 320 | unsigned long flagv; | 330 | unsigned long flagv; |
| 321 | dprintk((KERN_INFO "event_wait up\n")); | 331 | dprintk((KERN_INFO "event_wait up\n")); |
| 322 | spin_lock_irqsave(&fib->event_lock, flagv); | 332 | spin_lock_irqsave(&fib->event_lock, flagv); |
| 323 | if (!fib->done) | 333 | if (!fib->done) { |
| 324 | fib->done = 1; | 334 | fib->done = 1; |
| 325 | up(&fib->event_wait); | 335 | up(&fib->event_wait); |
| 336 | } | ||
| 326 | spin_unlock_irqrestore(&fib->event_lock, flagv); | 337 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
| 338 | |||
| 339 | spin_lock_irqsave(&dev->manage_lock, mflags); | ||
| 340 | dev->management_fib_count--; | ||
| 341 | spin_unlock_irqrestore(&dev->manage_lock, mflags); | ||
| 342 | |||
| 327 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); | 343 | FIB_COUNTER_INCREMENT(aac_config.NormalRecved); |
| 344 | if (fib->done == 2) { | ||
| 345 | spin_lock_irqsave(&fib->event_lock, flagv); | ||
| 346 | fib->done = 0; | ||
| 347 | spin_unlock_irqrestore(&fib->event_lock, flagv); | ||
| 348 | aac_fib_complete(fib); | ||
| 349 | aac_fib_free(fib); | ||
| 350 | } | ||
| 351 | |||
| 328 | } | 352 | } |
| 329 | return 0; | 353 | return 0; |
| 330 | } | 354 | } |
