diff options
Diffstat (limited to 'drivers/scsi')
40 files changed, 583 insertions, 197 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 | } |
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 4d419c155ce9..78971db5b60e 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3171 | tinfo->curr.transport_version = 2; | 3171 | tinfo->curr.transport_version = 2; |
3172 | tinfo->goal.transport_version = 2; | 3172 | tinfo->goal.transport_version = 2; |
3173 | tinfo->goal.ppr_options = 0; | 3173 | tinfo->goal.ppr_options = 0; |
3174 | /* | 3174 | if (scb != NULL) { |
3175 | * Remove any SCBs in the waiting for selection | 3175 | /* |
3176 | * queue that may also be for this target so | 3176 | * Remove any SCBs in the waiting |
3177 | * that command ordering is preserved. | 3177 | * for selection queue that may |
3178 | */ | 3178 | * also be for this target so that |
3179 | ahd_freeze_devq(ahd, scb); | 3179 | * command ordering is preserved. |
3180 | ahd_qinfifo_requeue_tail(ahd, scb); | 3180 | */ |
3181 | ahd_freeze_devq(ahd, scb); | ||
3182 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3183 | } | ||
3181 | printerror = 0; | 3184 | printerror = 0; |
3182 | } | 3185 | } |
3183 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) | 3186 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) |
@@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3194 | MSG_EXT_WDTR_BUS_8_BIT, | 3197 | MSG_EXT_WDTR_BUS_8_BIT, |
3195 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | 3198 | AHD_TRANS_CUR|AHD_TRANS_GOAL, |
3196 | /*paused*/TRUE); | 3199 | /*paused*/TRUE); |
3197 | /* | 3200 | if (scb != NULL) { |
3198 | * Remove any SCBs in the waiting for selection | 3201 | /* |
3199 | * queue that may also be for this target so that | 3202 | * Remove any SCBs in the waiting for |
3200 | * command ordering is preserved. | 3203 | * selection queue that may also be for |
3201 | */ | 3204 | * this target so that command ordering |
3202 | ahd_freeze_devq(ahd, scb); | 3205 | * is preserved. |
3203 | ahd_qinfifo_requeue_tail(ahd, scb); | 3206 | */ |
3207 | ahd_freeze_devq(ahd, scb); | ||
3208 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3209 | } | ||
3204 | printerror = 0; | 3210 | printerror = 0; |
3205 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) | 3211 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) |
3206 | && ppr_busfree == 0) { | 3212 | && ppr_busfree == 0) { |
@@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3217 | /*ppr_options*/0, | 3223 | /*ppr_options*/0, |
3218 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | 3224 | AHD_TRANS_CUR|AHD_TRANS_GOAL, |
3219 | /*paused*/TRUE); | 3225 | /*paused*/TRUE); |
3220 | /* | 3226 | if (scb != NULL) { |
3221 | * Remove any SCBs in the waiting for selection | 3227 | /* |
3222 | * queue that may also be for this target so that | 3228 | * Remove any SCBs in the waiting for |
3223 | * command ordering is preserved. | 3229 | * selection queue that may also be for |
3224 | */ | 3230 | * this target so that command ordering |
3225 | ahd_freeze_devq(ahd, scb); | 3231 | * is preserved. |
3226 | ahd_qinfifo_requeue_tail(ahd, scb); | 3232 | */ |
3233 | ahd_freeze_devq(ahd, scb); | ||
3234 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3235 | } | ||
3227 | printerror = 0; | 3236 | printerror = 0; |
3228 | } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 | 3237 | } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 |
3229 | && ahd_sent_msg(ahd, AHDMSG_1B, | 3238 | && ahd_sent_msg(ahd, AHDMSG_1B, |
@@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3251 | * the message phases. We check it last in case we | 3260 | * the message phases. We check it last in case we |
3252 | * had to send some other message that caused a busfree. | 3261 | * had to send some other message that caused a busfree. |
3253 | */ | 3262 | */ |
3254 | if (printerror != 0 | 3263 | if (scb != NULL && printerror != 0 |
3255 | && (lastphase == P_MESGIN || lastphase == P_MESGOUT) | 3264 | && (lastphase == P_MESGIN || lastphase == P_MESGOUT) |
3256 | && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { | 3265 | && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { |
3257 | 3266 | ||
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 477542602284..9e71ac611146 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c | |||
@@ -2516,7 +2516,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt) | |||
2516 | if (info->scsi.phase == PHASE_IDLE) | 2516 | if (info->scsi.phase == PHASE_IDLE) |
2517 | fas216_kick(info); | 2517 | fas216_kick(info); |
2518 | 2518 | ||
2519 | mod_timer(&info->eh_timer, 30 * HZ); | 2519 | mod_timer(&info->eh_timer, jiffies + 30 * HZ); |
2520 | spin_unlock_irqrestore(&info->host_lock, flags); | 2520 | spin_unlock_irqrestore(&info->host_lock, flags); |
2521 | 2521 | ||
2522 | /* | 2522 | /* |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index 26ffdcd5a437..15a00e8b7122 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c | |||
@@ -1440,6 +1440,10 @@ void cxgb3i_c3cn_release(struct s3_conn *c3cn) | |||
1440 | static int is_cxgb3_dev(struct net_device *dev) | 1440 | static int is_cxgb3_dev(struct net_device *dev) |
1441 | { | 1441 | { |
1442 | struct cxgb3i_sdev_data *cdata; | 1442 | struct cxgb3i_sdev_data *cdata; |
1443 | struct net_device *ndev = dev; | ||
1444 | |||
1445 | if (dev->priv_flags & IFF_802_1Q_VLAN) | ||
1446 | ndev = vlan_dev_real_dev(dev); | ||
1443 | 1447 | ||
1444 | write_lock(&cdata_rwlock); | 1448 | write_lock(&cdata_rwlock); |
1445 | list_for_each_entry(cdata, &cdata_list, list) { | 1449 | list_for_each_entry(cdata, &cdata_list, list) { |
@@ -1447,7 +1451,7 @@ static int is_cxgb3_dev(struct net_device *dev) | |||
1447 | int i; | 1451 | int i; |
1448 | 1452 | ||
1449 | for (i = 0; i < ports->nports; i++) | 1453 | for (i = 0; i < ports->nports; i++) |
1450 | if (dev == ports->lldevs[i]) { | 1454 | if (ndev == ports->lldevs[i]) { |
1451 | write_unlock(&cdata_rwlock); | 1455 | write_unlock(&cdata_rwlock); |
1452 | return 1; | 1456 | return 1; |
1453 | } | 1457 | } |
@@ -1566,6 +1570,26 @@ out_err: | |||
1566 | return -EINVAL; | 1570 | return -EINVAL; |
1567 | } | 1571 | } |
1568 | 1572 | ||
1573 | /** | ||
1574 | * cxgb3i_find_dev - find the interface associated with the given address | ||
1575 | * @ipaddr: ip address | ||
1576 | */ | ||
1577 | static struct net_device * | ||
1578 | cxgb3i_find_dev(struct net_device *dev, __be32 ipaddr) | ||
1579 | { | ||
1580 | struct flowi fl; | ||
1581 | int err; | ||
1582 | struct rtable *rt; | ||
1583 | |||
1584 | memset(&fl, 0, sizeof(fl)); | ||
1585 | fl.nl_u.ip4_u.daddr = ipaddr; | ||
1586 | |||
1587 | err = ip_route_output_key(dev ? dev_net(dev) : &init_net, &rt, &fl); | ||
1588 | if (!err) | ||
1589 | return (&rt->u.dst)->dev; | ||
1590 | |||
1591 | return NULL; | ||
1592 | } | ||
1569 | 1593 | ||
1570 | /** | 1594 | /** |
1571 | * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address | 1595 | * cxgb3i_c3cn_connect - initiates an iscsi tcp connection to a given address |
@@ -1581,6 +1605,7 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, | |||
1581 | struct cxgb3i_sdev_data *cdata; | 1605 | struct cxgb3i_sdev_data *cdata; |
1582 | struct t3cdev *cdev; | 1606 | struct t3cdev *cdev; |
1583 | __be32 sipv4; | 1607 | __be32 sipv4; |
1608 | struct net_device *dstdev; | ||
1584 | int err; | 1609 | int err; |
1585 | 1610 | ||
1586 | c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); | 1611 | c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); |
@@ -1591,6 +1616,13 @@ int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, | |||
1591 | c3cn->daddr.sin_port = usin->sin_port; | 1616 | c3cn->daddr.sin_port = usin->sin_port; |
1592 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; | 1617 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; |
1593 | 1618 | ||
1619 | dstdev = cxgb3i_find_dev(dev, usin->sin_addr.s_addr); | ||
1620 | if (!dstdev || !is_cxgb3_dev(dstdev)) | ||
1621 | return -ENETUNREACH; | ||
1622 | |||
1623 | if (dstdev->priv_flags & IFF_802_1Q_VLAN) | ||
1624 | dev = dstdev; | ||
1625 | |||
1594 | rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, | 1626 | rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, |
1595 | c3cn->daddr.sin_addr.s_addr, | 1627 | c3cn->daddr.sin_addr.s_addr, |
1596 | c3cn->saddr.sin_port, | 1628 | c3cn->saddr.sin_port, |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 10be9f36a4cc..2f47ae7cce91 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -2009,6 +2009,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
2009 | fcoe_interface_cleanup(fcoe); | 2009 | fcoe_interface_cleanup(fcoe); |
2010 | rtnl_unlock(); | 2010 | rtnl_unlock(); |
2011 | fcoe_if_destroy(fcoe->ctlr.lp); | 2011 | fcoe_if_destroy(fcoe->ctlr.lp); |
2012 | module_put(THIS_MODULE); | ||
2013 | |||
2012 | out_putdev: | 2014 | out_putdev: |
2013 | dev_put(netdev); | 2015 | dev_put(netdev); |
2014 | out_nodev: | 2016 | out_nodev: |
@@ -2059,6 +2061,11 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2059 | } | 2061 | } |
2060 | #endif | 2062 | #endif |
2061 | 2063 | ||
2064 | if (!try_module_get(THIS_MODULE)) { | ||
2065 | rc = -EINVAL; | ||
2066 | goto out_nomod; | ||
2067 | } | ||
2068 | |||
2062 | rtnl_lock(); | 2069 | rtnl_lock(); |
2063 | netdev = fcoe_if_to_netdev(buffer); | 2070 | netdev = fcoe_if_to_netdev(buffer); |
2064 | if (!netdev) { | 2071 | if (!netdev) { |
@@ -2099,17 +2106,24 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2099 | if (!fcoe_link_ok(lport)) | 2106 | if (!fcoe_link_ok(lport)) |
2100 | fcoe_ctlr_link_up(&fcoe->ctlr); | 2107 | fcoe_ctlr_link_up(&fcoe->ctlr); |
2101 | 2108 | ||
2102 | rc = 0; | ||
2103 | out_free: | ||
2104 | /* | 2109 | /* |
2105 | * Release from init in fcoe_interface_create(), on success lport | 2110 | * Release from init in fcoe_interface_create(), on success lport |
2106 | * should be holding a reference taken in fcoe_if_create(). | 2111 | * should be holding a reference taken in fcoe_if_create(). |
2107 | */ | 2112 | */ |
2108 | fcoe_interface_put(fcoe); | 2113 | fcoe_interface_put(fcoe); |
2114 | dev_put(netdev); | ||
2115 | rtnl_unlock(); | ||
2116 | mutex_unlock(&fcoe_config_mutex); | ||
2117 | |||
2118 | return 0; | ||
2119 | out_free: | ||
2120 | fcoe_interface_put(fcoe); | ||
2109 | out_putdev: | 2121 | out_putdev: |
2110 | dev_put(netdev); | 2122 | dev_put(netdev); |
2111 | out_nodev: | 2123 | out_nodev: |
2112 | rtnl_unlock(); | 2124 | rtnl_unlock(); |
2125 | module_put(THIS_MODULE); | ||
2126 | out_nomod: | ||
2113 | mutex_unlock(&fcoe_config_mutex); | 2127 | mutex_unlock(&fcoe_config_mutex); |
2114 | return rc; | 2128 | return rc; |
2115 | } | 2129 | } |
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 9823291395ad..511cb6b371ee 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -1187,7 +1187,7 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1187 | next_timer = fip->ctlr_ka_time; | 1187 | next_timer = fip->ctlr_ka_time; |
1188 | 1188 | ||
1189 | if (time_after_eq(jiffies, fip->port_ka_time)) { | 1189 | if (time_after_eq(jiffies, fip->port_ka_time)) { |
1190 | fip->port_ka_time += jiffies + | 1190 | fip->port_ka_time = jiffies + |
1191 | msecs_to_jiffies(FIP_VN_KA_PERIOD); | 1191 | msecs_to_jiffies(FIP_VN_KA_PERIOD); |
1192 | fip->send_port_ka = 1; | 1192 | fip->send_port_ka = 1; |
1193 | } | 1193 | } |
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 19d711cb938c..7f4364770e4a 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -1890,7 +1890,7 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, | |||
1890 | fc_exch_setup_hdr(ep, fp, ep->f_ctl); | 1890 | fc_exch_setup_hdr(ep, fp, ep->f_ctl); |
1891 | sp->cnt++; | 1891 | sp->cnt++; |
1892 | 1892 | ||
1893 | if (ep->xid <= lport->lro_xid) | 1893 | if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) |
1894 | fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); | 1894 | fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); |
1895 | 1895 | ||
1896 | if (unlikely(lport->tt.frame_send(lport, fp))) | 1896 | if (unlikely(lport->tt.frame_send(lport, fp))) |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 881d5dfe8c74..6fde2fabfd9b 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -298,9 +298,6 @@ void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid) | |||
298 | { | 298 | { |
299 | struct fc_lport *lport; | 299 | struct fc_lport *lport; |
300 | 300 | ||
301 | if (!fsp) | ||
302 | return; | ||
303 | |||
304 | lport = fsp->lp; | 301 | lport = fsp->lp; |
305 | if ((fsp->req_flags & FC_SRB_READ) && | 302 | if ((fsp->req_flags & FC_SRB_READ) && |
306 | (lport->lro_enabled) && (lport->tt.ddp_setup)) { | 303 | (lport->lro_enabled) && (lport->tt.ddp_setup)) { |
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 0b165024a219..7ec8ce75007c 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -1800,7 +1800,8 @@ int fc_lport_bsg_request(struct fc_bsg_job *job) | |||
1800 | u32 did; | 1800 | u32 did; |
1801 | 1801 | ||
1802 | job->reply->reply_payload_rcv_len = 0; | 1802 | job->reply->reply_payload_rcv_len = 0; |
1803 | rsp->resid_len = job->reply_payload.payload_len; | 1803 | if (rsp) |
1804 | rsp->resid_len = job->reply_payload.payload_len; | ||
1804 | 1805 | ||
1805 | mutex_lock(&lport->lp_mutex); | 1806 | mutex_lock(&lport->lp_mutex); |
1806 | 1807 | ||
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 02300523b234..97923bb07765 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
@@ -623,7 +623,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
623 | 623 | ||
624 | tov = ntohl(plp->fl_csp.sp_e_d_tov); | 624 | tov = ntohl(plp->fl_csp.sp_e_d_tov); |
625 | if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) | 625 | if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) |
626 | tov /= 1000; | 626 | tov /= 1000000; |
627 | if (tov > rdata->e_d_tov) | 627 | if (tov > rdata->e_d_tov) |
628 | rdata->e_d_tov = tov; | 628 | rdata->e_d_tov = tov; |
629 | csp_seq = ntohs(plp->fl_csp.sp_tot_seq); | 629 | csp_seq = ntohs(plp->fl_csp.sp_tot_seq); |
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index db6856c138fc..4ad87fd74ddd 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c | |||
@@ -992,12 +992,10 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) | |||
992 | if (r2t == NULL) { | 992 | if (r2t == NULL) { |
993 | if (kfifo_out(&tcp_task->r2tqueue, | 993 | if (kfifo_out(&tcp_task->r2tqueue, |
994 | (void *)&tcp_task->r2t, sizeof(void *)) != | 994 | (void *)&tcp_task->r2t, sizeof(void *)) != |
995 | sizeof(void *)) { | 995 | sizeof(void *)) |
996 | WARN_ONCE(1, "unexpected fifo state"); | ||
997 | r2t = NULL; | 996 | r2t = NULL; |
998 | } | 997 | else |
999 | 998 | r2t = tcp_task->r2t; | |
1000 | r2t = tcp_task->r2t; | ||
1001 | } | 999 | } |
1002 | spin_unlock_bh(&session->lock); | 1000 | spin_unlock_bh(&session->lock); |
1003 | } | 1001 | } |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ce522702a6c1..2cc39684ce97 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -4142,8 +4142,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
4142 | spin_lock_irq(shost->host_lock); | 4142 | spin_lock_irq(shost->host_lock); |
4143 | if (vport->fc_rscn_flush) { | 4143 | if (vport->fc_rscn_flush) { |
4144 | /* Another thread is walking fc_rscn_id_list on this vport */ | 4144 | /* Another thread is walking fc_rscn_id_list on this vport */ |
4145 | spin_unlock_irq(shost->host_lock); | ||
4146 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 4145 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
4146 | spin_unlock_irq(shost->host_lock); | ||
4147 | /* Send back ACC */ | 4147 | /* Send back ACC */ |
4148 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | 4148 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
4149 | return 0; | 4149 | return 0; |
@@ -5948,8 +5948,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5948 | lpfc_initial_fdisc(vport); | 5948 | lpfc_initial_fdisc(vport); |
5949 | break; | 5949 | break; |
5950 | } | 5950 | } |
5951 | |||
5952 | } else { | 5951 | } else { |
5952 | vport->vpi_state |= LPFC_VPI_REGISTERED; | ||
5953 | if (vport == phba->pport) | 5953 | if (vport == phba->pport) |
5954 | if (phba->sli_rev < LPFC_SLI_REV4) | 5954 | if (phba->sli_rev < LPFC_SLI_REV4) |
5955 | lpfc_issue_fabric_reglogin(vport); | 5955 | lpfc_issue_fabric_reglogin(vport); |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 3b9424427652..2445e399fd60 100755..100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -747,6 +747,10 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
747 | 747 | ||
748 | if (phba->link_state == LPFC_LINK_DOWN) | 748 | if (phba->link_state == LPFC_LINK_DOWN) |
749 | return 0; | 749 | return 0; |
750 | |||
751 | /* Block all SCSI stack I/Os */ | ||
752 | lpfc_scsi_dev_block(phba); | ||
753 | |||
750 | spin_lock_irq(&phba->hbalock); | 754 | spin_lock_irq(&phba->hbalock); |
751 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | 755 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); |
752 | if (phba->link_state > LPFC_LINK_DOWN) { | 756 | if (phba->link_state > LPFC_LINK_DOWN) { |
@@ -1555,10 +1559,16 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1555 | * to book keeping the FCFIs can be used. | 1559 | * to book keeping the FCFIs can be used. |
1556 | */ | 1560 | */ |
1557 | if (shdr_status || shdr_add_status) { | 1561 | if (shdr_status || shdr_add_status) { |
1558 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 1562 | if (shdr_status == STATUS_FCF_TABLE_EMPTY) { |
1559 | "2521 READ_FCF_RECORD mailbox failed " | 1563 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
1560 | "with status x%x add_status x%x, mbx\n", | 1564 | "2726 READ_FCF_RECORD Indicates empty " |
1561 | shdr_status, shdr_add_status); | 1565 | "FCF table.\n"); |
1566 | } else { | ||
1567 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1568 | "2521 READ_FCF_RECORD mailbox failed " | ||
1569 | "with status x%x add_status x%x, mbx\n", | ||
1570 | shdr_status, shdr_add_status); | ||
1571 | } | ||
1562 | goto out; | 1572 | goto out; |
1563 | } | 1573 | } |
1564 | /* Interpreting the returned information of FCF records */ | 1574 | /* Interpreting the returned information of FCF records */ |
@@ -1698,7 +1708,9 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1698 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1708 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1699 | return; | 1709 | return; |
1700 | } | 1710 | } |
1711 | spin_lock_irq(&phba->hbalock); | ||
1701 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; | 1712 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; |
1713 | spin_unlock_irq(&phba->hbalock); | ||
1702 | 1714 | ||
1703 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1715 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
1704 | lpfc_initial_fdisc(vport); | 1716 | lpfc_initial_fdisc(vport); |
@@ -2259,7 +2271,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2259 | mb->mbxStatus); | 2271 | mb->mbxStatus); |
2260 | break; | 2272 | break; |
2261 | } | 2273 | } |
2274 | spin_lock_irq(&phba->hbalock); | ||
2262 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; | 2275 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; |
2276 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
2277 | spin_unlock_irq(&phba->hbalock); | ||
2263 | vport->unreg_vpi_cmpl = VPORT_OK; | 2278 | vport->unreg_vpi_cmpl = VPORT_OK; |
2264 | mempool_free(pmb, phba->mbox_mem_pool); | 2279 | mempool_free(pmb, phba->mbox_mem_pool); |
2265 | /* | 2280 | /* |
@@ -4475,8 +4490,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
4475 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | 4490 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) |
4476 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 4491 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
4477 | lpfc_mbx_unreg_vpi(vports[i]); | 4492 | lpfc_mbx_unreg_vpi(vports[i]); |
4493 | spin_lock_irq(&phba->hbalock); | ||
4478 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 4494 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; |
4479 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; | 4495 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; |
4496 | spin_unlock_irq(&phba->hbalock); | ||
4480 | } | 4497 | } |
4481 | lpfc_destroy_vport_work_array(phba, vports); | 4498 | lpfc_destroy_vport_work_array(phba, vports); |
4482 | 4499 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 1585148a17e5..8a2a1c5935c6 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
@@ -1013,7 +1013,7 @@ struct lpfc_mbx_wq_destroy { | |||
1013 | }; | 1013 | }; |
1014 | 1014 | ||
1015 | #define LPFC_HDR_BUF_SIZE 128 | 1015 | #define LPFC_HDR_BUF_SIZE 128 |
1016 | #define LPFC_DATA_BUF_SIZE 4096 | 1016 | #define LPFC_DATA_BUF_SIZE 2048 |
1017 | struct rq_context { | 1017 | struct rq_context { |
1018 | uint32_t word0; | 1018 | uint32_t word0; |
1019 | #define lpfc_rq_context_rq_size_SHIFT 16 | 1019 | #define lpfc_rq_context_rq_size_SHIFT 16 |
@@ -1371,6 +1371,7 @@ struct lpfc_mbx_query_fw_cfg { | |||
1371 | #define STATUS_ERROR_ACITMAIN 0x2a | 1371 | #define STATUS_ERROR_ACITMAIN 0x2a |
1372 | #define STATUS_REBOOT_REQUIRED 0x2c | 1372 | #define STATUS_REBOOT_REQUIRED 0x2c |
1373 | #define STATUS_FCF_IN_USE 0x3a | 1373 | #define STATUS_FCF_IN_USE 0x3a |
1374 | #define STATUS_FCF_TABLE_EMPTY 0x43 | ||
1374 | 1375 | ||
1375 | struct lpfc_mbx_sli4_config { | 1376 | struct lpfc_mbx_sli4_config { |
1376 | struct mbox_header header; | 1377 | struct mbox_header header; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d4da6bdd0e73..b8eb1b6e5e77 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -3006,6 +3006,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3006 | struct lpfc_vport *vport; | 3006 | struct lpfc_vport *vport; |
3007 | struct lpfc_nodelist *ndlp; | 3007 | struct lpfc_nodelist *ndlp; |
3008 | struct Scsi_Host *shost; | 3008 | struct Scsi_Host *shost; |
3009 | uint32_t link_state; | ||
3009 | 3010 | ||
3010 | phba->fc_eventTag = acqe_fcoe->event_tag; | 3011 | phba->fc_eventTag = acqe_fcoe->event_tag; |
3011 | phba->fcoe_eventtag = acqe_fcoe->event_tag; | 3012 | phba->fcoe_eventtag = acqe_fcoe->event_tag; |
@@ -3052,9 +3053,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, | |||
3052 | break; | 3053 | break; |
3053 | /* | 3054 | /* |
3054 | * Currently, driver support only one FCF - so treat this as | 3055 | * Currently, driver support only one FCF - so treat this as |
3055 | * a link down. | 3056 | * a link down, but save the link state because we don't want |
3057 | * it to be changed to Link Down unless it is already down. | ||
3056 | */ | 3058 | */ |
3059 | link_state = phba->link_state; | ||
3057 | lpfc_linkdown(phba); | 3060 | lpfc_linkdown(phba); |
3061 | phba->link_state = link_state; | ||
3058 | /* Unregister FCF if no devices connected to it */ | 3062 | /* Unregister FCF if no devices connected to it */ |
3059 | lpfc_unregister_unused_fcf(phba); | 3063 | lpfc_unregister_unused_fcf(phba); |
3060 | break; | 3064 | break; |
@@ -7226,8 +7230,6 @@ lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) | |||
7226 | { | 7230 | { |
7227 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7231 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
7228 | "2711 PCI channel permanent disable for failure\n"); | 7232 | "2711 PCI channel permanent disable for failure\n"); |
7229 | /* Block all SCSI devices' I/Os on the host */ | ||
7230 | lpfc_scsi_dev_block(phba); | ||
7231 | /* Clean up all driver's outstanding SCSI I/Os */ | 7233 | /* Clean up all driver's outstanding SCSI I/Os */ |
7232 | lpfc_sli_flush_fcp_rings(phba); | 7234 | lpfc_sli_flush_fcp_rings(phba); |
7233 | } | 7235 | } |
@@ -7256,6 +7258,9 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) | |||
7256 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 7258 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
7257 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 7259 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
7258 | 7260 | ||
7261 | /* Block all SCSI devices' I/Os on the host */ | ||
7262 | lpfc_scsi_dev_block(phba); | ||
7263 | |||
7259 | switch (state) { | 7264 | switch (state) { |
7260 | case pci_channel_io_normal: | 7265 | case pci_channel_io_normal: |
7261 | /* Non-fatal error, prepare for recovery */ | 7266 | /* Non-fatal error, prepare for recovery */ |
@@ -7507,6 +7512,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
7507 | error = -ENODEV; | 7512 | error = -ENODEV; |
7508 | goto out_free_sysfs_attr; | 7513 | goto out_free_sysfs_attr; |
7509 | } | 7514 | } |
7515 | /* Default to single FCP EQ for non-MSI-X */ | ||
7516 | if (phba->intr_type != MSIX) | ||
7517 | phba->cfg_fcp_eq_count = 1; | ||
7510 | /* Set up SLI-4 HBA */ | 7518 | /* Set up SLI-4 HBA */ |
7511 | if (lpfc_sli4_hba_setup(phba)) { | 7519 | if (lpfc_sli4_hba_setup(phba)) { |
7512 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 7520 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 7935667b81a5..589549b2bf0e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1383,7 +1383,7 @@ lpfc_sli_hbq_to_firmware_s4(struct lpfc_hba *phba, uint32_t hbqno, | |||
1383 | /* HBQ for ELS and CT traffic. */ | 1383 | /* HBQ for ELS and CT traffic. */ |
1384 | static struct lpfc_hbq_init lpfc_els_hbq = { | 1384 | static struct lpfc_hbq_init lpfc_els_hbq = { |
1385 | .rn = 1, | 1385 | .rn = 1, |
1386 | .entry_count = 200, | 1386 | .entry_count = 256, |
1387 | .mask_count = 0, | 1387 | .mask_count = 0, |
1388 | .profile = 0, | 1388 | .profile = 0, |
1389 | .ring_mask = (1 << LPFC_ELS_RING), | 1389 | .ring_mask = (1 << LPFC_ELS_RING), |
@@ -1482,8 +1482,11 @@ err: | |||
1482 | int | 1482 | int |
1483 | lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | 1483 | lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) |
1484 | { | 1484 | { |
1485 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 1485 | if (phba->sli_rev == LPFC_SLI_REV4) |
1486 | lpfc_hbq_defs[qno]->add_count)); | 1486 | return 0; |
1487 | else | ||
1488 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | ||
1489 | lpfc_hbq_defs[qno]->add_count); | ||
1487 | } | 1490 | } |
1488 | 1491 | ||
1489 | /** | 1492 | /** |
@@ -1498,8 +1501,12 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno) | |||
1498 | static int | 1501 | static int |
1499 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) | 1502 | lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno) |
1500 | { | 1503 | { |
1501 | return(lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | 1504 | if (phba->sli_rev == LPFC_SLI_REV4) |
1502 | lpfc_hbq_defs[qno]->init_count)); | 1505 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, |
1506 | lpfc_hbq_defs[qno]->entry_count); | ||
1507 | else | ||
1508 | return lpfc_sli_hbqbuf_fill_hbqs(phba, qno, | ||
1509 | lpfc_hbq_defs[qno]->init_count); | ||
1503 | } | 1510 | } |
1504 | 1511 | ||
1505 | /** | 1512 | /** |
@@ -4110,6 +4117,7 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
4110 | if (rc) { | 4117 | if (rc) { |
4111 | dma_free_coherent(&phba->pcidev->dev, dma_size, | 4118 | dma_free_coherent(&phba->pcidev->dev, dma_size, |
4112 | dmabuf->virt, dmabuf->phys); | 4119 | dmabuf->virt, dmabuf->phys); |
4120 | kfree(dmabuf); | ||
4113 | return -EIO; | 4121 | return -EIO; |
4114 | } | 4122 | } |
4115 | 4123 | ||
@@ -5848,7 +5856,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
5848 | iocbq->iocb.un.ulpWord[3]); | 5856 | iocbq->iocb.un.ulpWord[3]); |
5849 | wqe->generic.word3 = 0; | 5857 | wqe->generic.word3 = 0; |
5850 | bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); | 5858 | bf_set(wqe_rcvoxid, &wqe->generic, iocbq->iocb.ulpContext); |
5851 | bf_set(wqe_xc, &wqe->generic, 1); | ||
5852 | /* The entire sequence is transmitted for this IOCB */ | 5859 | /* The entire sequence is transmitted for this IOCB */ |
5853 | xmit_len = total_len; | 5860 | xmit_len = total_len; |
5854 | cmnd = CMD_XMIT_SEQUENCE64_CR; | 5861 | cmnd = CMD_XMIT_SEQUENCE64_CR; |
@@ -10944,7 +10951,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
10944 | return dmabuf; | 10951 | return dmabuf; |
10945 | } | 10952 | } |
10946 | temp_hdr = seq_dmabuf->hbuf.virt; | 10953 | temp_hdr = seq_dmabuf->hbuf.virt; |
10947 | if (new_hdr->fh_seq_cnt < temp_hdr->fh_seq_cnt) { | 10954 | if (be16_to_cpu(new_hdr->fh_seq_cnt) < |
10955 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { | ||
10948 | list_del_init(&seq_dmabuf->hbuf.list); | 10956 | list_del_init(&seq_dmabuf->hbuf.list); |
10949 | list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list); | 10957 | list_add_tail(&dmabuf->hbuf.list, &vport->rcv_buffer_list); |
10950 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); | 10958 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); |
@@ -10955,6 +10963,11 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
10955 | list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list); | 10963 | list_move_tail(&seq_dmabuf->hbuf.list, &vport->rcv_buffer_list); |
10956 | seq_dmabuf->time_stamp = jiffies; | 10964 | seq_dmabuf->time_stamp = jiffies; |
10957 | lpfc_update_rcv_time_stamp(vport); | 10965 | lpfc_update_rcv_time_stamp(vport); |
10966 | if (list_empty(&seq_dmabuf->dbuf.list)) { | ||
10967 | temp_hdr = dmabuf->hbuf.virt; | ||
10968 | list_add_tail(&dmabuf->dbuf.list, &seq_dmabuf->dbuf.list); | ||
10969 | return seq_dmabuf; | ||
10970 | } | ||
10958 | /* find the correct place in the sequence to insert this frame */ | 10971 | /* find the correct place in the sequence to insert this frame */ |
10959 | list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { | 10972 | list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { |
10960 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 10973 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
@@ -10963,7 +10976,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
10963 | * If the frame's sequence count is greater than the frame on | 10976 | * If the frame's sequence count is greater than the frame on |
10964 | * the list then insert the frame right after this frame | 10977 | * the list then insert the frame right after this frame |
10965 | */ | 10978 | */ |
10966 | if (new_hdr->fh_seq_cnt > temp_hdr->fh_seq_cnt) { | 10979 | if (be16_to_cpu(new_hdr->fh_seq_cnt) > |
10980 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { | ||
10967 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); | 10981 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); |
10968 | return seq_dmabuf; | 10982 | return seq_dmabuf; |
10969 | } | 10983 | } |
@@ -11210,7 +11224,7 @@ lpfc_seq_complete(struct hbq_dmabuf *dmabuf) | |||
11210 | seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 11224 | seq_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
11211 | hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | 11225 | hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; |
11212 | /* If there is a hole in the sequence count then fail. */ | 11226 | /* If there is a hole in the sequence count then fail. */ |
11213 | if (++seq_count != hdr->fh_seq_cnt) | 11227 | if (++seq_count != be16_to_cpu(hdr->fh_seq_cnt)) |
11214 | return 0; | 11228 | return 0; |
11215 | fctl = (hdr->fh_f_ctl[0] << 16 | | 11229 | fctl = (hdr->fh_f_ctl[0] << 16 | |
11216 | hdr->fh_f_ctl[1] << 8 | | 11230 | hdr->fh_f_ctl[1] << 8 | |
@@ -11242,6 +11256,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
11242 | struct lpfc_iocbq *first_iocbq, *iocbq; | 11256 | struct lpfc_iocbq *first_iocbq, *iocbq; |
11243 | struct fc_frame_header *fc_hdr; | 11257 | struct fc_frame_header *fc_hdr; |
11244 | uint32_t sid; | 11258 | uint32_t sid; |
11259 | struct ulp_bde64 *pbde; | ||
11245 | 11260 | ||
11246 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; | 11261 | fc_hdr = (struct fc_frame_header *)seq_dmabuf->hbuf.virt; |
11247 | /* remove from receive buffer list */ | 11262 | /* remove from receive buffer list */ |
@@ -11283,8 +11298,9 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf) | |||
11283 | if (!iocbq->context3) { | 11298 | if (!iocbq->context3) { |
11284 | iocbq->context3 = d_buf; | 11299 | iocbq->context3 = d_buf; |
11285 | iocbq->iocb.ulpBdeCount++; | 11300 | iocbq->iocb.ulpBdeCount++; |
11286 | iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize = | 11301 | pbde = (struct ulp_bde64 *) |
11287 | LPFC_DATA_BUF_SIZE; | 11302 | &iocbq->iocb.unsli3.sli3Words[4]; |
11303 | pbde->tus.f.bdeSize = LPFC_DATA_BUF_SIZE; | ||
11288 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += | 11304 | first_iocbq->iocb.unsli3.rcvsli3.acc_len += |
11289 | bf_get(lpfc_rcqe_length, | 11305 | bf_get(lpfc_rcqe_length, |
11290 | &seq_dmabuf->cq_event.cqe.rcqe_cmpl); | 11306 | &seq_dmabuf->cq_event.cqe.rcqe_cmpl); |
@@ -11401,15 +11417,9 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba, | |||
11401 | return; | 11417 | return; |
11402 | } | 11418 | } |
11403 | /* If not last frame in sequence continue processing frames. */ | 11419 | /* If not last frame in sequence continue processing frames. */ |
11404 | if (!lpfc_seq_complete(seq_dmabuf)) { | 11420 | if (!lpfc_seq_complete(seq_dmabuf)) |
11405 | /* | ||
11406 | * When saving off frames post a new one and mark this | ||
11407 | * frame to be freed when it is finished. | ||
11408 | **/ | ||
11409 | lpfc_sli_hbqbuf_fill_hbqs(phba, LPFC_ELS_HBQ, 1); | ||
11410 | dmabuf->tag = -1; | ||
11411 | return; | 11421 | return; |
11412 | } | 11422 | |
11413 | /* Send the complete sequence to the upper layer protocol */ | 11423 | /* Send the complete sequence to the upper layer protocol */ |
11414 | lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); | 11424 | lpfc_sli4_send_seq_to_ulp(vport, seq_dmabuf); |
11415 | } | 11425 | } |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 25d66d070cf8..44e5f574236b 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -28,7 +28,7 @@ | |||
28 | /* Multi-queue arrangement for fast-path FCP work queues */ | 28 | /* Multi-queue arrangement for fast-path FCP work queues */ |
29 | #define LPFC_FN_EQN_MAX 8 | 29 | #define LPFC_FN_EQN_MAX 8 |
30 | #define LPFC_SP_EQN_DEF 1 | 30 | #define LPFC_SP_EQN_DEF 1 |
31 | #define LPFC_FP_EQN_DEF 1 | 31 | #define LPFC_FP_EQN_DEF 4 |
32 | #define LPFC_FP_EQN_MIN 1 | 32 | #define LPFC_FP_EQN_MIN 1 |
33 | #define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF) | 33 | #define LPFC_FP_EQN_MAX (LPFC_FN_EQN_MAX - LPFC_SP_EQN_DEF) |
34 | 34 | ||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index c7f3aed2aab8..792f72263f1a 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.3.6" | 21 | #define LPFC_DRIVER_VERSION "8.3.7" |
22 | #define LPFC_DRIVER_NAME "lpfc" | 22 | #define LPFC_DRIVER_NAME "lpfc" |
23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" | 23 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" |
24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" | 24 | #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" |
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 7d6dd83d3592..e3c7fa642306 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -512,8 +512,10 @@ enable_vport(struct fc_vport *fc_vport) | |||
512 | return VPORT_OK; | 512 | return VPORT_OK; |
513 | } | 513 | } |
514 | 514 | ||
515 | spin_lock_irq(&phba->hbalock); | ||
515 | vport->load_flag |= FC_LOADING; | 516 | vport->load_flag |= FC_LOADING; |
516 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 517 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
518 | spin_unlock_irq(&phba->hbalock); | ||
517 | 519 | ||
518 | /* Use the Physical nodes Fabric NDLP to determine if the link is | 520 | /* Use the Physical nodes Fabric NDLP to determine if the link is |
519 | * up and ready to FDISC. | 521 | * up and ready to FDISC. |
@@ -700,7 +702,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
700 | } | 702 | } |
701 | spin_unlock_irq(&phba->ndlp_lock); | 703 | spin_unlock_irq(&phba->ndlp_lock); |
702 | } | 704 | } |
703 | if (vport->vpi_state != LPFC_VPI_REGISTERED) | 705 | if (!(vport->vpi_state & LPFC_VPI_REGISTERED)) |
704 | goto skip_logo; | 706 | goto skip_logo; |
705 | vport->unreg_vpi_cmpl = VPORT_INVAL; | 707 | vport->unreg_vpi_cmpl = VPORT_INVAL; |
706 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 708 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 99ff99e45bee..d9b8ca5116bc 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -3781,6 +3781,7 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) | |||
3781 | compat_alloc_user_space(sizeof(struct megasas_iocpacket)); | 3781 | compat_alloc_user_space(sizeof(struct megasas_iocpacket)); |
3782 | int i; | 3782 | int i; |
3783 | int error = 0; | 3783 | int error = 0; |
3784 | compat_uptr_t ptr; | ||
3784 | 3785 | ||
3785 | if (clear_user(ioc, sizeof(*ioc))) | 3786 | if (clear_user(ioc, sizeof(*ioc))) |
3786 | return -EFAULT; | 3787 | return -EFAULT; |
@@ -3793,9 +3794,22 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) | |||
3793 | copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) | 3794 | copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) |
3794 | return -EFAULT; | 3795 | return -EFAULT; |
3795 | 3796 | ||
3796 | for (i = 0; i < MAX_IOCTL_SGE; i++) { | 3797 | /* |
3797 | compat_uptr_t ptr; | 3798 | * The sense_ptr is used in megasas_mgmt_fw_ioctl only when |
3799 | * sense_len is not null, so prepare the 64bit value under | ||
3800 | * the same condition. | ||
3801 | */ | ||
3802 | if (ioc->sense_len) { | ||
3803 | void __user **sense_ioc_ptr = | ||
3804 | (void __user **)(ioc->frame.raw + ioc->sense_off); | ||
3805 | compat_uptr_t *sense_cioc_ptr = | ||
3806 | (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off); | ||
3807 | if (get_user(ptr, sense_cioc_ptr) || | ||
3808 | put_user(compat_ptr(ptr), sense_ioc_ptr)) | ||
3809 | return -EFAULT; | ||
3810 | } | ||
3798 | 3811 | ||
3812 | for (i = 0; i < MAX_IOCTL_SGE; i++) { | ||
3799 | if (get_user(ptr, &cioc->sgl[i].iov_base) || | 3813 | if (get_user(ptr, &cioc->sgl[i].iov_base) || |
3800 | put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || | 3814 | put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || |
3801 | copy_in_user(&ioc->sgl[i].iov_len, | 3815 | copy_in_user(&ioc->sgl[i].iov_len, |
@@ -4046,7 +4060,7 @@ megasas_aen_polling(struct work_struct *work) | |||
4046 | } | 4060 | } |
4047 | 4061 | ||
4048 | 4062 | ||
4049 | static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO, | 4063 | static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUSR, |
4050 | megasas_sysfs_show_poll_mode_io, | 4064 | megasas_sysfs_show_poll_mode_io, |
4051 | megasas_sysfs_set_poll_mode_io); | 4065 | megasas_sysfs_set_poll_mode_io); |
4052 | 4066 | ||
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index e7d2688fbeba..b6f1ef954af1 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
@@ -2483,14 +2483,12 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) | |||
2483 | sense_copied = 1; | 2483 | sense_copied = 1; |
2484 | } | 2484 | } |
2485 | 2485 | ||
2486 | if (RES_IS_GSCSI(res->cfg_entry)) { | 2486 | if (RES_IS_GSCSI(res->cfg_entry)) |
2487 | pmcraid_cancel_all(cmd, sense_copied); | 2487 | pmcraid_cancel_all(cmd, sense_copied); |
2488 | } else if (sense_copied) { | 2488 | else if (sense_copied) |
2489 | pmcraid_erp_done(cmd); | 2489 | pmcraid_erp_done(cmd); |
2490 | return 0; | 2490 | else |
2491 | } else { | ||
2492 | pmcraid_request_sense(cmd); | 2491 | pmcraid_request_sense(cmd); |
2493 | } | ||
2494 | 2492 | ||
2495 | return 1; | 2493 | return 1; |
2496 | 2494 | ||
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 21e2bc4d7401..3a9f5b288aee 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -232,6 +232,9 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
232 | if (off) | 232 | if (off) |
233 | return 0; | 233 | return 0; |
234 | 234 | ||
235 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
236 | return 0; | ||
237 | |||
235 | if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) | 238 | if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) |
236 | return -EINVAL; | 239 | return -EINVAL; |
237 | if (start > ha->optrom_size) | 240 | if (start > ha->optrom_size) |
@@ -379,6 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
379 | struct device, kobj))); | 382 | struct device, kobj))); |
380 | struct qla_hw_data *ha = vha->hw; | 383 | struct qla_hw_data *ha = vha->hw; |
381 | 384 | ||
385 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
386 | return 0; | ||
387 | |||
382 | if (!capable(CAP_SYS_ADMIN)) | 388 | if (!capable(CAP_SYS_ADMIN)) |
383 | return 0; | 389 | return 0; |
384 | 390 | ||
@@ -398,6 +404,9 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, | |||
398 | struct qla_hw_data *ha = vha->hw; | 404 | struct qla_hw_data *ha = vha->hw; |
399 | uint8_t *tmp_data; | 405 | uint8_t *tmp_data; |
400 | 406 | ||
407 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
408 | return 0; | ||
409 | |||
401 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || | 410 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || |
402 | !ha->isp_ops->write_nvram) | 411 | !ha->isp_ops->write_nvram) |
403 | return 0; | 412 | return 0; |
@@ -1238,10 +1247,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr, | |||
1238 | char *buf) | 1247 | char *buf) |
1239 | { | 1248 | { |
1240 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1249 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1241 | int rval; | 1250 | int rval = QLA_FUNCTION_FAILED; |
1242 | uint16_t state[5]; | 1251 | uint16_t state[5]; |
1243 | 1252 | ||
1244 | rval = qla2x00_get_firmware_state(vha, state); | 1253 | if (!vha->hw->flags.eeh_busy) |
1254 | rval = qla2x00_get_firmware_state(vha, state); | ||
1245 | if (rval != QLA_SUCCESS) | 1255 | if (rval != QLA_SUCCESS) |
1246 | memset(state, -1, sizeof(state)); | 1256 | memset(state, -1, sizeof(state)); |
1247 | 1257 | ||
@@ -1452,10 +1462,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
1452 | if (!fcport) | 1462 | if (!fcport) |
1453 | return; | 1463 | return; |
1454 | 1464 | ||
1455 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) | 1465 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) |
1466 | return; | ||
1467 | |||
1468 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | ||
1456 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | 1469 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); |
1457 | else | 1470 | return; |
1458 | qla2x00_abort_fcport_cmds(fcport); | 1471 | } |
1459 | 1472 | ||
1460 | /* | 1473 | /* |
1461 | * Transport has effectively 'deleted' the rport, clear | 1474 | * Transport has effectively 'deleted' the rport, clear |
@@ -1475,6 +1488,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) | |||
1475 | if (!fcport) | 1488 | if (!fcport) |
1476 | return; | 1489 | return; |
1477 | 1490 | ||
1491 | if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) | ||
1492 | return; | ||
1493 | |||
1478 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { | 1494 | if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { |
1479 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); | 1495 | qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); |
1480 | return; | 1496 | return; |
@@ -1515,6 +1531,12 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
1515 | pfc_host_stat = &ha->fc_host_stat; | 1531 | pfc_host_stat = &ha->fc_host_stat; |
1516 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); | 1532 | memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); |
1517 | 1533 | ||
1534 | if (test_bit(UNLOADING, &vha->dpc_flags)) | ||
1535 | goto done; | ||
1536 | |||
1537 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
1538 | goto done; | ||
1539 | |||
1518 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); | 1540 | stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); |
1519 | if (stats == NULL) { | 1541 | if (stats == NULL) { |
1520 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", | 1542 | DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index f660dd70b72e..d6d9c86cb058 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -26,7 +26,7 @@ | |||
26 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ | 26 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ |
27 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ | 27 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ |
28 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ | 28 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ |
29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output MULTI-Q trace messages */ | 29 | /* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */ |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Macros use for debugging the driver. | 32 | * Macros use for debugging the driver. |
@@ -132,6 +132,13 @@ | |||
132 | #else | 132 | #else |
133 | #define DEBUG16(x) do {} while (0) | 133 | #define DEBUG16(x) do {} while (0) |
134 | #endif | 134 | #endif |
135 | |||
136 | #if defined(QL_DEBUG_LEVEL_17) | ||
137 | #define DEBUG17(x) do {x;} while (0) | ||
138 | #else | ||
139 | #define DEBUG17(x) do {} while (0) | ||
140 | #endif | ||
141 | |||
135 | /* | 142 | /* |
136 | * Firmware Dump structure definition | 143 | * Firmware Dump structure definition |
137 | */ | 144 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 384afda7dbe9..1263d9796e89 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1586,8 +1586,7 @@ typedef struct fc_port { | |||
1586 | */ | 1586 | */ |
1587 | #define FCF_FABRIC_DEVICE BIT_0 | 1587 | #define FCF_FABRIC_DEVICE BIT_0 |
1588 | #define FCF_LOGIN_NEEDED BIT_1 | 1588 | #define FCF_LOGIN_NEEDED BIT_1 |
1589 | #define FCF_TAPE_PRESENT BIT_2 | 1589 | #define FCF_FCP2_DEVICE BIT_2 |
1590 | #define FCF_FCP2_DEVICE BIT_3 | ||
1591 | 1590 | ||
1592 | /* No loop ID flag. */ | 1591 | /* No loop ID flag. */ |
1593 | #define FC_NO_LOOP_ID 0x1000 | 1592 | #define FC_NO_LOOP_ID 0x1000 |
@@ -2256,11 +2255,13 @@ struct qla_hw_data { | |||
2256 | uint32_t disable_serdes :1; | 2255 | uint32_t disable_serdes :1; |
2257 | uint32_t gpsc_supported :1; | 2256 | uint32_t gpsc_supported :1; |
2258 | uint32_t npiv_supported :1; | 2257 | uint32_t npiv_supported :1; |
2258 | uint32_t pci_channel_io_perm_failure :1; | ||
2259 | uint32_t fce_enabled :1; | 2259 | uint32_t fce_enabled :1; |
2260 | uint32_t fac_supported :1; | 2260 | uint32_t fac_supported :1; |
2261 | uint32_t chip_reset_done :1; | 2261 | uint32_t chip_reset_done :1; |
2262 | uint32_t port0 :1; | 2262 | uint32_t port0 :1; |
2263 | uint32_t running_gold_fw :1; | 2263 | uint32_t running_gold_fw :1; |
2264 | uint32_t eeh_busy :1; | ||
2264 | uint32_t cpu_affinity_enabled :1; | 2265 | uint32_t cpu_affinity_enabled :1; |
2265 | uint32_t disable_msix_handshake :1; | 2266 | uint32_t disable_msix_handshake :1; |
2266 | } flags; | 2267 | } flags; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0b6801fc6389..8bc6f53691e9 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -324,6 +324,7 @@ qla2x00_read_ram_word(scsi_qla_host_t *, uint32_t, uint32_t *); | |||
324 | extern int | 324 | extern int |
325 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); | 325 | qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t); |
326 | 326 | ||
327 | extern int qla2x00_get_data_rate(scsi_qla_host_t *); | ||
327 | /* | 328 | /* |
328 | * Global Function Prototypes in qla_isr.c source file. | 329 | * Global Function Prototypes in qla_isr.c source file. |
329 | */ | 330 | */ |
@@ -452,6 +453,5 @@ extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | |||
452 | extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | 453 | extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); |
453 | extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | 454 | extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); |
454 | extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | 455 | extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); |
455 | extern struct scsi_qla_host * qla25xx_get_host(struct rsp_que *); | ||
456 | 456 | ||
457 | #endif /* _QLA_GBL_H */ | 457 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 73a793539d45..3f8e8495b743 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -205,7 +205,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
205 | 205 | ||
206 | switch (data[0]) { | 206 | switch (data[0]) { |
207 | case MBS_COMMAND_COMPLETE: | 207 | case MBS_COMMAND_COMPLETE: |
208 | if (fcport->flags & FCF_TAPE_PRESENT) | 208 | if (fcport->flags & FCF_FCP2_DEVICE) |
209 | opts |= BIT_1; | 209 | opts |= BIT_1; |
210 | rval = qla2x00_get_port_database(vha, fcport, opts); | 210 | rval = qla2x00_get_port_database(vha, fcport, opts); |
211 | if (rval != QLA_SUCCESS) | 211 | if (rval != QLA_SUCCESS) |
@@ -269,6 +269,8 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
269 | vha->flags.online = 0; | 269 | vha->flags.online = 0; |
270 | ha->flags.chip_reset_done = 0; | 270 | ha->flags.chip_reset_done = 0; |
271 | vha->flags.reset_active = 0; | 271 | vha->flags.reset_active = 0; |
272 | ha->flags.pci_channel_io_perm_failure = 0; | ||
273 | ha->flags.eeh_busy = 0; | ||
272 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); | 274 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
273 | atomic_set(&vha->loop_state, LOOP_DOWN); | 275 | atomic_set(&vha->loop_state, LOOP_DOWN); |
274 | vha->device_flags = DFLG_NO_CABLE; | 276 | vha->device_flags = DFLG_NO_CABLE; |
@@ -581,6 +583,9 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) | |||
581 | uint32_t cnt; | 583 | uint32_t cnt; |
582 | uint16_t cmd; | 584 | uint16_t cmd; |
583 | 585 | ||
586 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
587 | return; | ||
588 | |||
584 | ha->isp_ops->disable_intrs(ha); | 589 | ha->isp_ops->disable_intrs(ha); |
585 | 590 | ||
586 | spin_lock_irqsave(&ha->hardware_lock, flags); | 591 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -786,6 +791,12 @@ void | |||
786 | qla24xx_reset_chip(scsi_qla_host_t *vha) | 791 | qla24xx_reset_chip(scsi_qla_host_t *vha) |
787 | { | 792 | { |
788 | struct qla_hw_data *ha = vha->hw; | 793 | struct qla_hw_data *ha = vha->hw; |
794 | |||
795 | if (pci_channel_offline(ha->pdev) && | ||
796 | ha->flags.pci_channel_io_perm_failure) { | ||
797 | return; | ||
798 | } | ||
799 | |||
789 | ha->isp_ops->disable_intrs(ha); | 800 | ha->isp_ops->disable_intrs(ha); |
790 | 801 | ||
791 | /* Perform RISC reset. */ | 802 | /* Perform RISC reset. */ |
@@ -2266,6 +2277,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) | |||
2266 | clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | 2277 | clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
2267 | clear_bit(RSCN_UPDATE, &vha->dpc_flags); | 2278 | clear_bit(RSCN_UPDATE, &vha->dpc_flags); |
2268 | 2279 | ||
2280 | qla2x00_get_data_rate(vha); | ||
2281 | |||
2269 | /* Determine what we need to do */ | 2282 | /* Determine what we need to do */ |
2270 | if (ha->current_topology == ISP_CFG_FL && | 2283 | if (ha->current_topology == ISP_CFG_FL && |
2271 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { | 2284 | (test_bit(LOCAL_LOOP_UPDATE, &flags))) { |
@@ -2713,7 +2726,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2713 | 2726 | ||
2714 | /* | 2727 | /* |
2715 | * Logout all previous fabric devices marked lost, except | 2728 | * Logout all previous fabric devices marked lost, except |
2716 | * tape devices. | 2729 | * FCP2 devices. |
2717 | */ | 2730 | */ |
2718 | list_for_each_entry(fcport, &vha->vp_fcports, list) { | 2731 | list_for_each_entry(fcport, &vha->vp_fcports, list) { |
2719 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) | 2732 | if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) |
@@ -2726,7 +2739,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
2726 | qla2x00_mark_device_lost(vha, fcport, | 2739 | qla2x00_mark_device_lost(vha, fcport, |
2727 | ql2xplogiabsentdevice, 0); | 2740 | ql2xplogiabsentdevice, 0); |
2728 | if (fcport->loop_id != FC_NO_LOOP_ID && | 2741 | if (fcport->loop_id != FC_NO_LOOP_ID && |
2729 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 2742 | (fcport->flags & FCF_FCP2_DEVICE) == 0 && |
2730 | fcport->port_type != FCT_INITIATOR && | 2743 | fcport->port_type != FCT_INITIATOR && |
2731 | fcport->port_type != FCT_BROADCAST) { | 2744 | fcport->port_type != FCT_BROADCAST) { |
2732 | ha->isp_ops->fabric_logout(vha, | 2745 | ha->isp_ops->fabric_logout(vha, |
@@ -3005,7 +3018,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, | |||
3005 | fcport->d_id.b24 = new_fcport->d_id.b24; | 3018 | fcport->d_id.b24 = new_fcport->d_id.b24; |
3006 | fcport->flags |= FCF_LOGIN_NEEDED; | 3019 | fcport->flags |= FCF_LOGIN_NEEDED; |
3007 | if (fcport->loop_id != FC_NO_LOOP_ID && | 3020 | if (fcport->loop_id != FC_NO_LOOP_ID && |
3008 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 3021 | (fcport->flags & FCF_FCP2_DEVICE) == 0 && |
3009 | fcport->port_type != FCT_INITIATOR && | 3022 | fcport->port_type != FCT_INITIATOR && |
3010 | fcport->port_type != FCT_BROADCAST) { | 3023 | fcport->port_type != FCT_BROADCAST) { |
3011 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, | 3024 | ha->isp_ops->fabric_logout(vha, fcport->loop_id, |
@@ -3259,9 +3272,9 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport, | |||
3259 | 3272 | ||
3260 | rval = qla2x00_fabric_login(vha, fcport, next_loopid); | 3273 | rval = qla2x00_fabric_login(vha, fcport, next_loopid); |
3261 | if (rval == QLA_SUCCESS) { | 3274 | if (rval == QLA_SUCCESS) { |
3262 | /* Send an ADISC to tape devices.*/ | 3275 | /* Send an ADISC to FCP2 devices.*/ |
3263 | opts = 0; | 3276 | opts = 0; |
3264 | if (fcport->flags & FCF_TAPE_PRESENT) | 3277 | if (fcport->flags & FCF_FCP2_DEVICE) |
3265 | opts |= BIT_1; | 3278 | opts |= BIT_1; |
3266 | rval = qla2x00_get_port_database(vha, fcport, opts); | 3279 | rval = qla2x00_get_port_database(vha, fcport, opts); |
3267 | if (rval != QLA_SUCCESS) { | 3280 | if (rval != QLA_SUCCESS) { |
@@ -3560,6 +3573,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) | |||
3560 | /* Requeue all commands in outstanding command list. */ | 3573 | /* Requeue all commands in outstanding command list. */ |
3561 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); | 3574 | qla2x00_abort_all_cmds(vha, DID_RESET << 16); |
3562 | 3575 | ||
3576 | if (unlikely(pci_channel_offline(ha->pdev) && | ||
3577 | ha->flags.pci_channel_io_perm_failure)) { | ||
3578 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); | ||
3579 | status = 0; | ||
3580 | return status; | ||
3581 | } | ||
3582 | |||
3563 | ha->isp_ops->get_flash_version(vha, req->ring); | 3583 | ha->isp_ops->get_flash_version(vha, req->ring); |
3564 | 3584 | ||
3565 | ha->isp_ops->nvram_config(vha); | 3585 | ha->isp_ops->nvram_config(vha); |
@@ -4458,6 +4478,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha) | |||
4458 | int ret, retries; | 4478 | int ret, retries; |
4459 | struct qla_hw_data *ha = vha->hw; | 4479 | struct qla_hw_data *ha = vha->hw; |
4460 | 4480 | ||
4481 | if (ha->flags.pci_channel_io_perm_failure) | ||
4482 | return; | ||
4461 | if (!IS_FWI2_CAPABLE(ha)) | 4483 | if (!IS_FWI2_CAPABLE(ha)) |
4462 | return; | 4484 | return; |
4463 | if (!ha->fw_major_version) | 4485 | if (!ha->fw_major_version) |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1692a883f4de..6fc63b98818c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -152,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
152 | for (iter = 50; iter--; ) { | 152 | for (iter = 50; iter--; ) { |
153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 153 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
154 | if (stat & HSR_RISC_PAUSED) { | 154 | if (stat & HSR_RISC_PAUSED) { |
155 | if (pci_channel_offline(ha->pdev)) | 155 | if (unlikely(pci_channel_offline(ha->pdev))) |
156 | break; | 156 | break; |
157 | 157 | ||
158 | hccr = RD_REG_WORD(®->hccr); | 158 | hccr = RD_REG_WORD(®->hccr); |
@@ -1846,12 +1846,15 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1846 | reg = &ha->iobase->isp24; | 1846 | reg = &ha->iobase->isp24; |
1847 | status = 0; | 1847 | status = 0; |
1848 | 1848 | ||
1849 | if (unlikely(pci_channel_offline(ha->pdev))) | ||
1850 | return IRQ_HANDLED; | ||
1851 | |||
1849 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1852 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1850 | vha = pci_get_drvdata(ha->pdev); | 1853 | vha = pci_get_drvdata(ha->pdev); |
1851 | for (iter = 50; iter--; ) { | 1854 | for (iter = 50; iter--; ) { |
1852 | stat = RD_REG_DWORD(®->host_status); | 1855 | stat = RD_REG_DWORD(®->host_status); |
1853 | if (stat & HSRX_RISC_PAUSED) { | 1856 | if (stat & HSRX_RISC_PAUSED) { |
1854 | if (pci_channel_offline(ha->pdev)) | 1857 | if (unlikely(pci_channel_offline(ha->pdev))) |
1855 | break; | 1858 | break; |
1856 | 1859 | ||
1857 | hccr = RD_REG_DWORD(®->hccr); | 1860 | hccr = RD_REG_DWORD(®->hccr); |
@@ -1914,6 +1917,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1914 | struct rsp_que *rsp; | 1917 | struct rsp_que *rsp; |
1915 | struct device_reg_24xx __iomem *reg; | 1918 | struct device_reg_24xx __iomem *reg; |
1916 | struct scsi_qla_host *vha; | 1919 | struct scsi_qla_host *vha; |
1920 | unsigned long flags; | ||
1917 | 1921 | ||
1918 | rsp = (struct rsp_que *) dev_id; | 1922 | rsp = (struct rsp_que *) dev_id; |
1919 | if (!rsp) { | 1923 | if (!rsp) { |
@@ -1924,15 +1928,15 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1924 | ha = rsp->hw; | 1928 | ha = rsp->hw; |
1925 | reg = &ha->iobase->isp24; | 1929 | reg = &ha->iobase->isp24; |
1926 | 1930 | ||
1927 | spin_lock_irq(&ha->hardware_lock); | 1931 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1928 | 1932 | ||
1929 | vha = qla25xx_get_host(rsp); | 1933 | vha = pci_get_drvdata(ha->pdev); |
1930 | qla24xx_process_response_queue(vha, rsp); | 1934 | qla24xx_process_response_queue(vha, rsp); |
1931 | if (!ha->flags.disable_msix_handshake) { | 1935 | if (!ha->flags.disable_msix_handshake) { |
1932 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1936 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1933 | RD_REG_DWORD_RELAXED(®->hccr); | 1937 | RD_REG_DWORD_RELAXED(®->hccr); |
1934 | } | 1938 | } |
1935 | spin_unlock_irq(&ha->hardware_lock); | 1939 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1936 | 1940 | ||
1937 | return IRQ_HANDLED; | 1941 | return IRQ_HANDLED; |
1938 | } | 1942 | } |
@@ -1943,6 +1947,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1943 | struct qla_hw_data *ha; | 1947 | struct qla_hw_data *ha; |
1944 | struct rsp_que *rsp; | 1948 | struct rsp_que *rsp; |
1945 | struct device_reg_24xx __iomem *reg; | 1949 | struct device_reg_24xx __iomem *reg; |
1950 | unsigned long flags; | ||
1946 | 1951 | ||
1947 | rsp = (struct rsp_que *) dev_id; | 1952 | rsp = (struct rsp_que *) dev_id; |
1948 | if (!rsp) { | 1953 | if (!rsp) { |
@@ -1955,10 +1960,10 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1955 | /* Clear the interrupt, if enabled, for this response queue */ | 1960 | /* Clear the interrupt, if enabled, for this response queue */ |
1956 | if (rsp->options & ~BIT_6) { | 1961 | if (rsp->options & ~BIT_6) { |
1957 | reg = &ha->iobase->isp24; | 1962 | reg = &ha->iobase->isp24; |
1958 | spin_lock_irq(&ha->hardware_lock); | 1963 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1959 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1964 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1960 | RD_REG_DWORD_RELAXED(®->hccr); | 1965 | RD_REG_DWORD_RELAXED(®->hccr); |
1961 | spin_unlock_irq(&ha->hardware_lock); | 1966 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1962 | } | 1967 | } |
1963 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); | 1968 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); |
1964 | 1969 | ||
@@ -1976,6 +1981,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1976 | uint32_t stat; | 1981 | uint32_t stat; |
1977 | uint32_t hccr; | 1982 | uint32_t hccr; |
1978 | uint16_t mb[4]; | 1983 | uint16_t mb[4]; |
1984 | unsigned long flags; | ||
1979 | 1985 | ||
1980 | rsp = (struct rsp_que *) dev_id; | 1986 | rsp = (struct rsp_que *) dev_id; |
1981 | if (!rsp) { | 1987 | if (!rsp) { |
@@ -1987,12 +1993,12 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1987 | reg = &ha->iobase->isp24; | 1993 | reg = &ha->iobase->isp24; |
1988 | status = 0; | 1994 | status = 0; |
1989 | 1995 | ||
1990 | spin_lock_irq(&ha->hardware_lock); | 1996 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1991 | vha = pci_get_drvdata(ha->pdev); | 1997 | vha = pci_get_drvdata(ha->pdev); |
1992 | do { | 1998 | do { |
1993 | stat = RD_REG_DWORD(®->host_status); | 1999 | stat = RD_REG_DWORD(®->host_status); |
1994 | if (stat & HSRX_RISC_PAUSED) { | 2000 | if (stat & HSRX_RISC_PAUSED) { |
1995 | if (pci_channel_offline(ha->pdev)) | 2001 | if (unlikely(pci_channel_offline(ha->pdev))) |
1996 | break; | 2002 | break; |
1997 | 2003 | ||
1998 | hccr = RD_REG_DWORD(®->hccr); | 2004 | hccr = RD_REG_DWORD(®->hccr); |
@@ -2036,7 +2042,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
2036 | } | 2042 | } |
2037 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 2043 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
2038 | } while (0); | 2044 | } while (0); |
2039 | spin_unlock_irq(&ha->hardware_lock); | 2045 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
2040 | 2046 | ||
2041 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 2047 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
2042 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 2048 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -2274,30 +2280,3 @@ int qla25xx_request_irq(struct rsp_que *rsp) | |||
2274 | msix->rsp = rsp; | 2280 | msix->rsp = rsp; |
2275 | return ret; | 2281 | return ret; |
2276 | } | 2282 | } |
2277 | |||
2278 | struct scsi_qla_host * | ||
2279 | qla25xx_get_host(struct rsp_que *rsp) | ||
2280 | { | ||
2281 | srb_t *sp; | ||
2282 | struct qla_hw_data *ha = rsp->hw; | ||
2283 | struct scsi_qla_host *vha = NULL; | ||
2284 | struct sts_entry_24xx *pkt; | ||
2285 | struct req_que *req; | ||
2286 | uint16_t que; | ||
2287 | uint32_t handle; | ||
2288 | |||
2289 | pkt = (struct sts_entry_24xx *) rsp->ring_ptr; | ||
2290 | que = MSW(pkt->handle); | ||
2291 | handle = (uint32_t) LSW(pkt->handle); | ||
2292 | req = ha->req_q_map[que]; | ||
2293 | if (handle < MAX_OUTSTANDING_COMMANDS) { | ||
2294 | sp = req->outstanding_cmds[handle]; | ||
2295 | if (sp) | ||
2296 | return sp->fcport->vha; | ||
2297 | else | ||
2298 | goto base_que; | ||
2299 | } | ||
2300 | base_que: | ||
2301 | vha = pci_get_drvdata(ha->pdev); | ||
2302 | return vha; | ||
2303 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 05d595d9a7ef..056e4d4505f3 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -56,6 +56,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
56 | 56 | ||
57 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); | 57 | DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no)); |
58 | 58 | ||
59 | if (ha->flags.pci_channel_io_perm_failure) { | ||
60 | DEBUG(printk("%s(%ld): Perm failure on EEH, timeout MBX " | ||
61 | "Exiting.\n", __func__, vha->host_no)); | ||
62 | return QLA_FUNCTION_TIMEOUT; | ||
63 | } | ||
64 | |||
59 | /* | 65 | /* |
60 | * Wait for active mailbox commands to finish by waiting at most tov | 66 | * Wait for active mailbox commands to finish by waiting at most tov |
61 | * seconds. This is to serialize actual issuing of mailbox cmds during | 67 | * seconds. This is to serialize actual issuing of mailbox cmds during |
@@ -154,10 +160,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
154 | /* Check for pending interrupts. */ | 160 | /* Check for pending interrupts. */ |
155 | qla2x00_poll(ha->rsp_q_map[0]); | 161 | qla2x00_poll(ha->rsp_q_map[0]); |
156 | 162 | ||
157 | if (command != MBC_LOAD_RISC_RAM_EXTENDED && | 163 | if (!ha->flags.mbox_int && |
158 | !ha->flags.mbox_int) | 164 | !(IS_QLA2200(ha) && |
165 | command == MBC_LOAD_RISC_RAM_EXTENDED)) | ||
159 | msleep(10); | 166 | msleep(10); |
160 | } /* while */ | 167 | } /* while */ |
168 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
169 | "Waited %d sec\n", | ||
170 | (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ))); | ||
161 | } | 171 | } |
162 | 172 | ||
163 | /* Check whether we timed out */ | 173 | /* Check whether we timed out */ |
@@ -227,7 +237,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
227 | 237 | ||
228 | if (rval == QLA_FUNCTION_TIMEOUT && | 238 | if (rval == QLA_FUNCTION_TIMEOUT && |
229 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { | 239 | mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { |
230 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { | 240 | if (!io_lock_on || (mcp->flags & IOCTL_CMD) || |
241 | ha->flags.eeh_busy) { | ||
231 | /* not in dpc. schedule it for dpc to take over. */ | 242 | /* not in dpc. schedule it for dpc to take over. */ |
232 | DEBUG(printk("%s(%ld): timeout schedule " | 243 | DEBUG(printk("%s(%ld): timeout schedule " |
233 | "isp_abort_needed.\n", __func__, | 244 | "isp_abort_needed.\n", __func__, |
@@ -237,7 +248,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
237 | base_vha->host_no)); | 248 | base_vha->host_no)); |
238 | qla_printk(KERN_WARNING, ha, | 249 | qla_printk(KERN_WARNING, ha, |
239 | "Mailbox command timeout occurred. Scheduling ISP " | 250 | "Mailbox command timeout occurred. Scheduling ISP " |
240 | "abort.\n"); | 251 | "abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy); |
241 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | 252 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); |
242 | qla2xxx_wake_dpc(vha); | 253 | qla2xxx_wake_dpc(vha); |
243 | } else if (!abort_active) { | 254 | } else if (!abort_active) { |
@@ -2530,6 +2541,9 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma, | |||
2530 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2541 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2531 | return QLA_FUNCTION_FAILED; | 2542 | return QLA_FUNCTION_FAILED; |
2532 | 2543 | ||
2544 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2545 | return QLA_FUNCTION_FAILED; | ||
2546 | |||
2533 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2547 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2534 | 2548 | ||
2535 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2549 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2565,6 +2579,9 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha) | |||
2565 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2579 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2566 | return QLA_FUNCTION_FAILED; | 2580 | return QLA_FUNCTION_FAILED; |
2567 | 2581 | ||
2582 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2583 | return QLA_FUNCTION_FAILED; | ||
2584 | |||
2568 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2585 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2569 | 2586 | ||
2570 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2587 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2595,6 +2612,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma, | |||
2595 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) | 2612 | if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw)) |
2596 | return QLA_FUNCTION_FAILED; | 2613 | return QLA_FUNCTION_FAILED; |
2597 | 2614 | ||
2615 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2616 | return QLA_FUNCTION_FAILED; | ||
2617 | |||
2598 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2618 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2599 | 2619 | ||
2600 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2620 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -2639,6 +2659,9 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd) | |||
2639 | if (!IS_FWI2_CAPABLE(vha->hw)) | 2659 | if (!IS_FWI2_CAPABLE(vha->hw)) |
2640 | return QLA_FUNCTION_FAILED; | 2660 | return QLA_FUNCTION_FAILED; |
2641 | 2661 | ||
2662 | if (unlikely(pci_channel_offline(vha->hw->pdev))) | ||
2663 | return QLA_FUNCTION_FAILED; | ||
2664 | |||
2642 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); | 2665 | DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); |
2643 | 2666 | ||
2644 | mcp->mb[0] = MBC_TRACE_CONTROL; | 2667 | mcp->mb[0] = MBC_TRACE_CONTROL; |
@@ -3643,3 +3666,36 @@ qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data) | |||
3643 | 3666 | ||
3644 | return rval; | 3667 | return rval; |
3645 | } | 3668 | } |
3669 | |||
3670 | int | ||
3671 | qla2x00_get_data_rate(scsi_qla_host_t *vha) | ||
3672 | { | ||
3673 | int rval; | ||
3674 | mbx_cmd_t mc; | ||
3675 | mbx_cmd_t *mcp = &mc; | ||
3676 | struct qla_hw_data *ha = vha->hw; | ||
3677 | |||
3678 | if (!IS_FWI2_CAPABLE(ha)) | ||
3679 | return QLA_FUNCTION_FAILED; | ||
3680 | |||
3681 | DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, vha->host_no)); | ||
3682 | |||
3683 | mcp->mb[0] = MBC_DATA_RATE; | ||
3684 | mcp->mb[1] = 0; | ||
3685 | mcp->out_mb = MBX_1|MBX_0; | ||
3686 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
3687 | mcp->tov = MBX_TOV_SECONDS; | ||
3688 | mcp->flags = 0; | ||
3689 | rval = qla2x00_mailbox_command(vha, mcp); | ||
3690 | if (rval != QLA_SUCCESS) { | ||
3691 | DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n", | ||
3692 | __func__, vha->host_no, rval, mcp->mb[0])); | ||
3693 | } else { | ||
3694 | DEBUG11(printk(KERN_INFO | ||
3695 | "%s(%ld): done.\n", __func__, vha->host_no)); | ||
3696 | if (mcp->mb[1] != 0x7) | ||
3697 | ha->link_data_rate = mcp->mb[1]; | ||
3698 | } | ||
3699 | |||
3700 | return rval; | ||
3701 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 2a4c7f4e7b69..ff17dee28613 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -636,11 +636,15 @@ failed: | |||
636 | 636 | ||
637 | static void qla_do_work(struct work_struct *work) | 637 | static void qla_do_work(struct work_struct *work) |
638 | { | 638 | { |
639 | unsigned long flags; | ||
639 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); | 640 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); |
640 | struct scsi_qla_host *vha; | 641 | struct scsi_qla_host *vha; |
642 | struct qla_hw_data *ha = rsp->hw; | ||
641 | 643 | ||
642 | vha = qla25xx_get_host(rsp); | 644 | spin_lock_irqsave(&rsp->hw->hardware_lock, flags); |
645 | vha = pci_get_drvdata(ha->pdev); | ||
643 | qla24xx_process_response_queue(vha, rsp); | 646 | qla24xx_process_response_queue(vha, rsp); |
647 | spin_unlock_irqrestore(&rsp->hw->hardware_lock, flags); | ||
644 | } | 648 | } |
645 | 649 | ||
646 | /* create response queue */ | 650 | /* create response queue */ |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 2f873d237325..8529eb1f3cd4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -475,11 +475,11 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
475 | srb_t *sp; | 475 | srb_t *sp; |
476 | int rval; | 476 | int rval; |
477 | 477 | ||
478 | if (unlikely(pci_channel_offline(ha->pdev))) { | 478 | if (ha->flags.eeh_busy) { |
479 | if (ha->pdev->error_state == pci_channel_io_frozen) | 479 | if (ha->flags.pci_channel_io_perm_failure) |
480 | cmd->result = DID_REQUEUE << 16; | ||
481 | else | ||
482 | cmd->result = DID_NO_CONNECT << 16; | 480 | cmd->result = DID_NO_CONNECT << 16; |
481 | else | ||
482 | cmd->result = DID_REQUEUE << 16; | ||
483 | goto qc24_fail_command; | 483 | goto qc24_fail_command; |
484 | } | 484 | } |
485 | 485 | ||
@@ -552,8 +552,15 @@ qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) | |||
552 | #define ABORT_POLLING_PERIOD 1000 | 552 | #define ABORT_POLLING_PERIOD 1000 |
553 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) | 553 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) |
554 | unsigned long wait_iter = ABORT_WAIT_ITER; | 554 | unsigned long wait_iter = ABORT_WAIT_ITER; |
555 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | ||
556 | struct qla_hw_data *ha = vha->hw; | ||
555 | int ret = QLA_SUCCESS; | 557 | int ret = QLA_SUCCESS; |
556 | 558 | ||
559 | if (unlikely(pci_channel_offline(ha->pdev)) || ha->flags.eeh_busy) { | ||
560 | DEBUG17(qla_printk(KERN_WARNING, ha, "return:eh_wait\n")); | ||
561 | return ret; | ||
562 | } | ||
563 | |||
557 | while (CMD_SP(cmd) && wait_iter--) { | 564 | while (CMD_SP(cmd) && wait_iter--) { |
558 | msleep(ABORT_POLLING_PERIOD); | 565 | msleep(ABORT_POLLING_PERIOD); |
559 | } | 566 | } |
@@ -1181,7 +1188,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev) | |||
1181 | scsi_qla_host_t *vha = shost_priv(sdev->host); | 1188 | scsi_qla_host_t *vha = shost_priv(sdev->host); |
1182 | struct qla_hw_data *ha = vha->hw; | 1189 | struct qla_hw_data *ha = vha->hw; |
1183 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | 1190 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); |
1184 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; | ||
1185 | struct req_que *req = vha->req; | 1191 | struct req_que *req = vha->req; |
1186 | 1192 | ||
1187 | if (sdev->tagged_supported) | 1193 | if (sdev->tagged_supported) |
@@ -1190,8 +1196,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev) | |||
1190 | scsi_deactivate_tcq(sdev, req->max_q_depth); | 1196 | scsi_deactivate_tcq(sdev, req->max_q_depth); |
1191 | 1197 | ||
1192 | rport->dev_loss_tmo = ha->port_down_retry_count; | 1198 | rport->dev_loss_tmo = ha->port_down_retry_count; |
1193 | if (sdev->type == TYPE_TAPE) | ||
1194 | fcport->flags |= FCF_TAPE_PRESENT; | ||
1195 | 1199 | ||
1196 | return 0; | 1200 | return 0; |
1197 | } | 1201 | } |
@@ -1810,6 +1814,13 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1810 | 1814 | ||
1811 | /* Set ISP-type information. */ | 1815 | /* Set ISP-type information. */ |
1812 | qla2x00_set_isp_flags(ha); | 1816 | qla2x00_set_isp_flags(ha); |
1817 | |||
1818 | /* Set EEH reset type to fundamental if required by hba */ | ||
1819 | if ( IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) { | ||
1820 | pdev->needs_freset = 1; | ||
1821 | pci_save_state(pdev); | ||
1822 | } | ||
1823 | |||
1813 | /* Configure PCI I/O space */ | 1824 | /* Configure PCI I/O space */ |
1814 | ret = qla2x00_iospace_config(ha); | 1825 | ret = qla2x00_iospace_config(ha); |
1815 | if (ret) | 1826 | if (ret) |
@@ -2174,6 +2185,24 @@ qla2x00_free_device(scsi_qla_host_t *vha) | |||
2174 | { | 2185 | { |
2175 | struct qla_hw_data *ha = vha->hw; | 2186 | struct qla_hw_data *ha = vha->hw; |
2176 | 2187 | ||
2188 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
2189 | |||
2190 | /* Disable timer */ | ||
2191 | if (vha->timer_active) | ||
2192 | qla2x00_stop_timer(vha); | ||
2193 | |||
2194 | /* Kill the kernel thread for this host */ | ||
2195 | if (ha->dpc_thread) { | ||
2196 | struct task_struct *t = ha->dpc_thread; | ||
2197 | |||
2198 | /* | ||
2199 | * qla2xxx_wake_dpc checks for ->dpc_thread | ||
2200 | * so we need to zero it out. | ||
2201 | */ | ||
2202 | ha->dpc_thread = NULL; | ||
2203 | kthread_stop(t); | ||
2204 | } | ||
2205 | |||
2177 | qla25xx_delete_queues(vha); | 2206 | qla25xx_delete_queues(vha); |
2178 | 2207 | ||
2179 | if (ha->flags.fce_enabled) | 2208 | if (ha->flags.fce_enabled) |
@@ -2185,6 +2214,8 @@ qla2x00_free_device(scsi_qla_host_t *vha) | |||
2185 | /* Stop currently executing firmware. */ | 2214 | /* Stop currently executing firmware. */ |
2186 | qla2x00_try_to_stop_firmware(vha); | 2215 | qla2x00_try_to_stop_firmware(vha); |
2187 | 2216 | ||
2217 | vha->flags.online = 0; | ||
2218 | |||
2188 | /* turn-off interrupts on the card */ | 2219 | /* turn-off interrupts on the card */ |
2189 | if (ha->interrupts_on) | 2220 | if (ha->interrupts_on) |
2190 | ha->isp_ops->disable_intrs(ha); | 2221 | ha->isp_ops->disable_intrs(ha); |
@@ -2771,7 +2802,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) | |||
2771 | 2802 | ||
2772 | fcport->login_retry--; | 2803 | fcport->login_retry--; |
2773 | if (fcport->flags & FCF_FABRIC_DEVICE) { | 2804 | if (fcport->flags & FCF_FABRIC_DEVICE) { |
2774 | if (fcport->flags & FCF_TAPE_PRESENT) | 2805 | if (fcport->flags & FCF_FCP2_DEVICE) |
2775 | ha->isp_ops->fabric_logout(vha, | 2806 | ha->isp_ops->fabric_logout(vha, |
2776 | fcport->loop_id, | 2807 | fcport->loop_id, |
2777 | fcport->d_id.b.domain, | 2808 | fcport->d_id.b.domain, |
@@ -2859,6 +2890,13 @@ qla2x00_do_dpc(void *data) | |||
2859 | if (!base_vha->flags.init_done) | 2890 | if (!base_vha->flags.init_done) |
2860 | continue; | 2891 | continue; |
2861 | 2892 | ||
2893 | if (ha->flags.eeh_busy) { | ||
2894 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
2895 | "qla2x00_do_dpc: dpc_flags: %lx\n", | ||
2896 | base_vha->dpc_flags)); | ||
2897 | continue; | ||
2898 | } | ||
2899 | |||
2862 | DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); | 2900 | DEBUG3(printk("scsi(%ld): DPC handler\n", base_vha->host_no)); |
2863 | 2901 | ||
2864 | ha->dpc_active = 1; | 2902 | ha->dpc_active = 1; |
@@ -3049,8 +3087,13 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3049 | int index; | 3087 | int index; |
3050 | srb_t *sp; | 3088 | srb_t *sp; |
3051 | int t; | 3089 | int t; |
3090 | uint16_t w; | ||
3052 | struct qla_hw_data *ha = vha->hw; | 3091 | struct qla_hw_data *ha = vha->hw; |
3053 | struct req_que *req; | 3092 | struct req_que *req; |
3093 | |||
3094 | /* Hardware read to raise pending EEH errors during mailbox waits. */ | ||
3095 | if (!pci_channel_offline(ha->pdev)) | ||
3096 | pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); | ||
3054 | /* | 3097 | /* |
3055 | * Ports - Port down timer. | 3098 | * Ports - Port down timer. |
3056 | * | 3099 | * |
@@ -3095,7 +3138,10 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3095 | if (!IS_QLA2100(ha) && vha->link_down_timeout) | 3138 | if (!IS_QLA2100(ha) && vha->link_down_timeout) |
3096 | atomic_set(&vha->loop_state, LOOP_DEAD); | 3139 | atomic_set(&vha->loop_state, LOOP_DEAD); |
3097 | 3140 | ||
3098 | /* Schedule an ISP abort to return any tape commands. */ | 3141 | /* |
3142 | * Schedule an ISP abort to return any FCP2-device | ||
3143 | * commands. | ||
3144 | */ | ||
3099 | /* NPIV - scan physical port only */ | 3145 | /* NPIV - scan physical port only */ |
3100 | if (!vha->vp_idx) { | 3146 | if (!vha->vp_idx) { |
3101 | spin_lock_irqsave(&ha->hardware_lock, | 3147 | spin_lock_irqsave(&ha->hardware_lock, |
@@ -3112,7 +3158,7 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
3112 | if (sp->ctx) | 3158 | if (sp->ctx) |
3113 | continue; | 3159 | continue; |
3114 | sfcp = sp->fcport; | 3160 | sfcp = sp->fcport; |
3115 | if (!(sfcp->flags & FCF_TAPE_PRESENT)) | 3161 | if (!(sfcp->flags & FCF_FCP2_DEVICE)) |
3116 | continue; | 3162 | continue; |
3117 | 3163 | ||
3118 | set_bit(ISP_ABORT_NEEDED, | 3164 | set_bit(ISP_ABORT_NEEDED, |
@@ -3252,16 +3298,23 @@ qla2x00_release_firmware(void) | |||
3252 | static pci_ers_result_t | 3298 | static pci_ers_result_t |
3253 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | 3299 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
3254 | { | 3300 | { |
3255 | scsi_qla_host_t *base_vha = pci_get_drvdata(pdev); | 3301 | scsi_qla_host_t *vha = pci_get_drvdata(pdev); |
3302 | struct qla_hw_data *ha = vha->hw; | ||
3303 | |||
3304 | DEBUG2(qla_printk(KERN_WARNING, ha, "error_detected:state %x\n", | ||
3305 | state)); | ||
3256 | 3306 | ||
3257 | switch (state) { | 3307 | switch (state) { |
3258 | case pci_channel_io_normal: | 3308 | case pci_channel_io_normal: |
3309 | ha->flags.eeh_busy = 0; | ||
3259 | return PCI_ERS_RESULT_CAN_RECOVER; | 3310 | return PCI_ERS_RESULT_CAN_RECOVER; |
3260 | case pci_channel_io_frozen: | 3311 | case pci_channel_io_frozen: |
3312 | ha->flags.eeh_busy = 1; | ||
3261 | pci_disable_device(pdev); | 3313 | pci_disable_device(pdev); |
3262 | return PCI_ERS_RESULT_NEED_RESET; | 3314 | return PCI_ERS_RESULT_NEED_RESET; |
3263 | case pci_channel_io_perm_failure: | 3315 | case pci_channel_io_perm_failure: |
3264 | qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); | 3316 | ha->flags.pci_channel_io_perm_failure = 1; |
3317 | qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); | ||
3265 | return PCI_ERS_RESULT_DISCONNECT; | 3318 | return PCI_ERS_RESULT_DISCONNECT; |
3266 | } | 3319 | } |
3267 | return PCI_ERS_RESULT_NEED_RESET; | 3320 | return PCI_ERS_RESULT_NEED_RESET; |
@@ -3312,6 +3365,8 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
3312 | struct qla_hw_data *ha = base_vha->hw; | 3365 | struct qla_hw_data *ha = base_vha->hw; |
3313 | int rc; | 3366 | int rc; |
3314 | 3367 | ||
3368 | DEBUG17(qla_printk(KERN_WARNING, ha, "slot_reset\n")); | ||
3369 | |||
3315 | if (ha->mem_only) | 3370 | if (ha->mem_only) |
3316 | rc = pci_enable_device_mem(pdev); | 3371 | rc = pci_enable_device_mem(pdev); |
3317 | else | 3372 | else |
@@ -3320,19 +3375,33 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) | |||
3320 | if (rc) { | 3375 | if (rc) { |
3321 | qla_printk(KERN_WARNING, ha, | 3376 | qla_printk(KERN_WARNING, ha, |
3322 | "Can't re-enable PCI device after reset.\n"); | 3377 | "Can't re-enable PCI device after reset.\n"); |
3323 | |||
3324 | return ret; | 3378 | return ret; |
3325 | } | 3379 | } |
3326 | pci_set_master(pdev); | ||
3327 | 3380 | ||
3328 | if (ha->isp_ops->pci_config(base_vha)) | 3381 | if (ha->isp_ops->pci_config(base_vha)) |
3329 | return ret; | 3382 | return ret; |
3330 | 3383 | ||
3384 | #ifdef QL_DEBUG_LEVEL_17 | ||
3385 | { | ||
3386 | uint8_t b; | ||
3387 | uint32_t i; | ||
3388 | |||
3389 | printk("slot_reset_1: "); | ||
3390 | for (i = 0; i < 256; i++) { | ||
3391 | pci_read_config_byte(ha->pdev, i, &b); | ||
3392 | printk("%s%02x", (i%16) ? " " : "\n", b); | ||
3393 | } | ||
3394 | printk("\n"); | ||
3395 | } | ||
3396 | #endif | ||
3331 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 3397 | set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
3332 | if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) | 3398 | if (qla2x00_abort_isp(base_vha) == QLA_SUCCESS) |
3333 | ret = PCI_ERS_RESULT_RECOVERED; | 3399 | ret = PCI_ERS_RESULT_RECOVERED; |
3334 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); | 3400 | clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); |
3335 | 3401 | ||
3402 | DEBUG17(qla_printk(KERN_WARNING, ha, | ||
3403 | "slot_reset-return:ret=%x\n", ret)); | ||
3404 | |||
3336 | return ret; | 3405 | return ret; |
3337 | } | 3406 | } |
3338 | 3407 | ||
@@ -3343,12 +3412,17 @@ qla2xxx_pci_resume(struct pci_dev *pdev) | |||
3343 | struct qla_hw_data *ha = base_vha->hw; | 3412 | struct qla_hw_data *ha = base_vha->hw; |
3344 | int ret; | 3413 | int ret; |
3345 | 3414 | ||
3415 | DEBUG17(qla_printk(KERN_WARNING, ha, "pci_resume\n")); | ||
3416 | |||
3346 | ret = qla2x00_wait_for_hba_online(base_vha); | 3417 | ret = qla2x00_wait_for_hba_online(base_vha); |
3347 | if (ret != QLA_SUCCESS) { | 3418 | if (ret != QLA_SUCCESS) { |
3348 | qla_printk(KERN_ERR, ha, | 3419 | qla_printk(KERN_ERR, ha, |
3349 | "the device failed to resume I/O " | 3420 | "the device failed to resume I/O " |
3350 | "from slot/link_reset"); | 3421 | "from slot/link_reset"); |
3351 | } | 3422 | } |
3423 | |||
3424 | ha->flags.eeh_busy = 0; | ||
3425 | |||
3352 | pci_cleanup_aer_uncorrect_error_status(pdev); | 3426 | pci_cleanup_aer_uncorrect_error_status(pdev); |
3353 | } | 3427 | } |
3354 | 3428 | ||
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 010e69b29afe..371dc895972a 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -2292,11 +2292,14 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, | |||
2292 | uint32_t faddr, left, burst; | 2292 | uint32_t faddr, left, burst; |
2293 | struct qla_hw_data *ha = vha->hw; | 2293 | struct qla_hw_data *ha = vha->hw; |
2294 | 2294 | ||
2295 | if (IS_QLA25XX(ha) || IS_QLA81XX(ha)) | ||
2296 | goto try_fast; | ||
2295 | if (offset & 0xfff) | 2297 | if (offset & 0xfff) |
2296 | goto slow_read; | 2298 | goto slow_read; |
2297 | if (length < OPTROM_BURST_SIZE) | 2299 | if (length < OPTROM_BURST_SIZE) |
2298 | goto slow_read; | 2300 | goto slow_read; |
2299 | 2301 | ||
2302 | try_fast: | ||
2300 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | 2303 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, |
2301 | &optrom_dma, GFP_KERNEL); | 2304 | &optrom_dma, GFP_KERNEL); |
2302 | if (!optrom) { | 2305 | if (!optrom) { |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index c482220f7eed..ed36279a33c1 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.01-k8" | 10 | #define QLA2XXX_VERSION "8.03.01-k10" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d8927681ec88..c6642423cc67 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -749,9 +749,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
749 | */ | 749 | */ |
750 | req->next_rq->resid_len = scsi_in(cmd)->resid; | 750 | req->next_rq->resid_len = scsi_in(cmd)->resid; |
751 | 751 | ||
752 | scsi_release_buffers(cmd); | ||
752 | blk_end_request_all(req, 0); | 753 | blk_end_request_all(req, 0); |
753 | 754 | ||
754 | scsi_release_buffers(cmd); | ||
755 | scsi_next_command(cmd); | 755 | scsi_next_command(cmd); |
756 | return; | 756 | return; |
757 | } | 757 | } |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index ddfcecd5099f..653f22a8deb9 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -3527,7 +3527,10 @@ fc_bsg_job_timeout(struct request *req) | |||
3527 | if (!done && i->f->bsg_timeout) { | 3527 | if (!done && i->f->bsg_timeout) { |
3528 | /* call LLDD to abort the i/o as it has timed out */ | 3528 | /* call LLDD to abort the i/o as it has timed out */ |
3529 | err = i->f->bsg_timeout(job); | 3529 | err = i->f->bsg_timeout(job); |
3530 | if (err) | 3530 | if (err == -EAGAIN) { |
3531 | job->ref_cnt--; | ||
3532 | return BLK_EH_RESET_TIMER; | ||
3533 | } else if (err) | ||
3531 | printk(KERN_ERR "ERROR: FC BSG request timeout - LLD " | 3534 | printk(KERN_ERR "ERROR: FC BSG request timeout - LLD " |
3532 | "abort failed with status %d\n", err); | 3535 | "abort failed with status %d\n", err); |
3533 | } | 3536 | } |
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 3058bb1aff95..fd7b15be7640 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -623,6 +623,11 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
623 | } | 623 | } |
624 | break; | 624 | break; |
625 | case INQUIRY: | 625 | case INQUIRY: |
626 | if (lun >= host->max_lun) { | ||
627 | cmd->result = DID_NO_CONNECT << 16; | ||
628 | done(cmd); | ||
629 | return 0; | ||
630 | } | ||
626 | if (id != host->max_id - 1) | 631 | if (id != host->max_id - 1) |
627 | break; | 632 | break; |
628 | if (!lun && !cmd->device->channel && | 633 | if (!lun && !cmd->device->channel && |