diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 20:54:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 20:54:40 -0400 |
commit | c55d267de274d308927b60c3e740c1a826832317 (patch) | |
tree | 21b53a8c725d9f9650f60d94b349459d5b8dae10 /drivers/scsi/megaraid | |
parent | 61ef46fd45c3c62dc7c880a45dd2aa841b9af8fb (diff) | |
parent | bc898c97f7ba24def788d9f80786cf028a197122 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (170 commits)
[SCSI] scsi_dh_rdac: Add MD36xxf into device list
[SCSI] scsi_debug: add consecutive medium errors
[SCSI] libsas: fix ata list corruption issue
[SCSI] hpsa: export resettable host attribute
[SCSI] hpsa: move device attributes to avoid forward declarations
[SCSI] scsi_debug: Logical Block Provisioning (SBC3r26)
[SCSI] sd: Logical Block Provisioning update
[SCSI] Include protection operation in SCSI command trace
[SCSI] hpsa: fix incorrect PCI IDs and add two new ones (2nd try)
[SCSI] target: Fix volume size misreporting for volumes > 2TB
[SCSI] bnx2fc: Broadcom FCoE offload driver
[SCSI] fcoe: fix broken fcoe interface reset
[SCSI] fcoe: precedence bug in fcoe_filter_frames()
[SCSI] libfcoe: Remove stale fcoe-netdev entries
[SCSI] libfcoe: Move FCOE_MTU definition from fcoe.h to libfcoe.h
[SCSI] libfc: introduce __fc_fill_fc_hdr that accepts fc_hdr as an argument
[SCSI] fcoe, libfc: initialize EM anchors list and then update npiv EMs
[SCSI] Revert "[SCSI] libfc: fix exchange being deleted when the abort itself is timed out"
[SCSI] libfc: Fixing a memory leak when destroying an interface
[SCSI] megaraid_sas: Version and Changelog update
...
Fix up trivial conflicts due to whitespace differences in
drivers/scsi/libsas/{sas_ata.c,sas_scsi_host.c}
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.h | 10 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_base.c | 147 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fusion.c | 19 |
3 files changed, 112 insertions, 64 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 1b5e375732c0..635b228c3ead 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -33,9 +33,9 @@ | |||
33 | /* | 33 | /* |
34 | * MegaRAID SAS Driver meta data | 34 | * MegaRAID SAS Driver meta data |
35 | */ | 35 | */ |
36 | #define MEGASAS_VERSION "00.00.05.29-rc1" | 36 | #define MEGASAS_VERSION "00.00.05.34-rc1" |
37 | #define MEGASAS_RELDATE "Dec. 7, 2010" | 37 | #define MEGASAS_RELDATE "Feb. 24, 2011" |
38 | #define MEGASAS_EXT_VERSION "Tue. Dec. 7 17:00:00 PDT 2010" | 38 | #define MEGASAS_EXT_VERSION "Thu. Feb. 24 17:00:00 PDT 2011" |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Device IDs | 41 | * Device IDs |
@@ -723,6 +723,7 @@ struct megasas_ctrl_info { | |||
723 | MEGASAS_MAX_DEV_PER_CHANNEL) | 723 | MEGASAS_MAX_DEV_PER_CHANNEL) |
724 | 724 | ||
725 | #define MEGASAS_MAX_SECTORS (2*1024) | 725 | #define MEGASAS_MAX_SECTORS (2*1024) |
726 | #define MEGASAS_MAX_SECTORS_IEEE (2*128) | ||
726 | #define MEGASAS_DBG_LVL 1 | 727 | #define MEGASAS_DBG_LVL 1 |
727 | 728 | ||
728 | #define MEGASAS_FW_BUSY 1 | 729 | #define MEGASAS_FW_BUSY 1 |
@@ -1477,4 +1478,7 @@ struct megasas_mgmt_info { | |||
1477 | int max_index; | 1478 | int max_index; |
1478 | }; | 1479 | }; |
1479 | 1480 | ||
1481 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | ||
1482 | #define PCI_MSIX_FLAGS_ENABLE (1 << 15) | ||
1483 | |||
1480 | #endif /*LSI_MEGARAID_SAS_H */ | 1484 | #endif /*LSI_MEGARAID_SAS_H */ |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5d6d07bd1cd0..f875e818905f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -18,12 +18,13 @@ | |||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | * | 19 | * |
20 | * FILE: megaraid_sas_base.c | 20 | * FILE: megaraid_sas_base.c |
21 | * Version : v00.00.05.29-rc1 | 21 | * Version : v00.00.05.34-rc1 |
22 | * | 22 | * |
23 | * Authors: LSI Corporation | 23 | * Authors: LSI Corporation |
24 | * Sreenivas Bagalkote | 24 | * Sreenivas Bagalkote |
25 | * Sumant Patro | 25 | * Sumant Patro |
26 | * Bo Yang | 26 | * Bo Yang |
27 | * Adam Radford <linuxraid@lsi.com> | ||
27 | * | 28 | * |
28 | * Send feedback to: <megaraidlinux@lsi.com> | 29 | * Send feedback to: <megaraidlinux@lsi.com> |
29 | * | 30 | * |
@@ -134,7 +135,11 @@ spinlock_t poll_aen_lock; | |||
134 | void | 135 | void |
135 | megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, | 136 | megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, |
136 | u8 alt_status); | 137 | u8 alt_status); |
137 | 138 | static u32 | |
139 | megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs); | ||
140 | static int | ||
141 | megasas_adp_reset_gen2(struct megasas_instance *instance, | ||
142 | struct megasas_register_set __iomem *reg_set); | ||
138 | static irqreturn_t megasas_isr(int irq, void *devp); | 143 | static irqreturn_t megasas_isr(int irq, void *devp); |
139 | static u32 | 144 | static u32 |
140 | megasas_init_adapter_mfi(struct megasas_instance *instance); | 145 | megasas_init_adapter_mfi(struct megasas_instance *instance); |
@@ -554,6 +559,8 @@ static int | |||
554 | megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) | 559 | megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) |
555 | { | 560 | { |
556 | u32 status; | 561 | u32 status; |
562 | u32 mfiStatus = 0; | ||
563 | |||
557 | /* | 564 | /* |
558 | * Check if it is our interrupt | 565 | * Check if it is our interrupt |
559 | */ | 566 | */ |
@@ -564,6 +571,15 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) | |||
564 | } | 571 | } |
565 | 572 | ||
566 | /* | 573 | /* |
574 | * Check if it is our interrupt | ||
575 | */ | ||
576 | if ((megasas_read_fw_status_reg_gen2(regs) & MFI_STATE_MASK) == | ||
577 | MFI_STATE_FAULT) { | ||
578 | mfiStatus = MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE; | ||
579 | } else | ||
580 | mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE; | ||
581 | |||
582 | /* | ||
567 | * Clear the interrupt by writing back the same value | 583 | * Clear the interrupt by writing back the same value |
568 | */ | 584 | */ |
569 | writel(status, ®s->outbound_intr_status); | 585 | writel(status, ®s->outbound_intr_status); |
@@ -573,7 +589,7 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs) | |||
573 | */ | 589 | */ |
574 | readl(®s->outbound_intr_status); | 590 | readl(®s->outbound_intr_status); |
575 | 591 | ||
576 | return 1; | 592 | return mfiStatus; |
577 | } | 593 | } |
578 | 594 | ||
579 | /** | 595 | /** |
@@ -597,17 +613,6 @@ megasas_fire_cmd_skinny(struct megasas_instance *instance, | |||
597 | } | 613 | } |
598 | 614 | ||
599 | /** | 615 | /** |
600 | * megasas_adp_reset_skinny - For controller reset | ||
601 | * @regs: MFI register set | ||
602 | */ | ||
603 | static int | ||
604 | megasas_adp_reset_skinny(struct megasas_instance *instance, | ||
605 | struct megasas_register_set __iomem *regs) | ||
606 | { | ||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | /** | ||
611 | * megasas_check_reset_skinny - For controller reset check | 616 | * megasas_check_reset_skinny - For controller reset check |
612 | * @regs: MFI register set | 617 | * @regs: MFI register set |
613 | */ | 618 | */ |
@@ -625,7 +630,7 @@ static struct megasas_instance_template megasas_instance_template_skinny = { | |||
625 | .disable_intr = megasas_disable_intr_skinny, | 630 | .disable_intr = megasas_disable_intr_skinny, |
626 | .clear_intr = megasas_clear_intr_skinny, | 631 | .clear_intr = megasas_clear_intr_skinny, |
627 | .read_fw_status_reg = megasas_read_fw_status_reg_skinny, | 632 | .read_fw_status_reg = megasas_read_fw_status_reg_skinny, |
628 | .adp_reset = megasas_adp_reset_skinny, | 633 | .adp_reset = megasas_adp_reset_gen2, |
629 | .check_reset = megasas_check_reset_skinny, | 634 | .check_reset = megasas_check_reset_skinny, |
630 | .service_isr = megasas_isr, | 635 | .service_isr = megasas_isr, |
631 | .tasklet = megasas_complete_cmd_dpc, | 636 | .tasklet = megasas_complete_cmd_dpc, |
@@ -740,20 +745,28 @@ megasas_adp_reset_gen2(struct megasas_instance *instance, | |||
740 | { | 745 | { |
741 | u32 retry = 0 ; | 746 | u32 retry = 0 ; |
742 | u32 HostDiag; | 747 | u32 HostDiag; |
748 | u32 *seq_offset = ®_set->seq_offset; | ||
749 | u32 *hostdiag_offset = ®_set->host_diag; | ||
750 | |||
751 | if (instance->instancet == &megasas_instance_template_skinny) { | ||
752 | seq_offset = ®_set->fusion_seq_offset; | ||
753 | hostdiag_offset = ®_set->fusion_host_diag; | ||
754 | } | ||
755 | |||
756 | writel(0, seq_offset); | ||
757 | writel(4, seq_offset); | ||
758 | writel(0xb, seq_offset); | ||
759 | writel(2, seq_offset); | ||
760 | writel(7, seq_offset); | ||
761 | writel(0xd, seq_offset); | ||
743 | 762 | ||
744 | writel(0, ®_set->seq_offset); | ||
745 | writel(4, ®_set->seq_offset); | ||
746 | writel(0xb, ®_set->seq_offset); | ||
747 | writel(2, ®_set->seq_offset); | ||
748 | writel(7, ®_set->seq_offset); | ||
749 | writel(0xd, ®_set->seq_offset); | ||
750 | msleep(1000); | 763 | msleep(1000); |
751 | 764 | ||
752 | HostDiag = (u32)readl(®_set->host_diag); | 765 | HostDiag = (u32)readl(hostdiag_offset); |
753 | 766 | ||
754 | while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { | 767 | while ( !( HostDiag & DIAG_WRITE_ENABLE) ) { |
755 | msleep(100); | 768 | msleep(100); |
756 | HostDiag = (u32)readl(®_set->host_diag); | 769 | HostDiag = (u32)readl(hostdiag_offset); |
757 | printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", | 770 | printk(KERN_NOTICE "RESETGEN2: retry=%x, hostdiag=%x\n", |
758 | retry, HostDiag); | 771 | retry, HostDiag); |
759 | 772 | ||
@@ -764,14 +777,14 @@ megasas_adp_reset_gen2(struct megasas_instance *instance, | |||
764 | 777 | ||
765 | printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); | 778 | printk(KERN_NOTICE "ADP_RESET_GEN2: HostDiag=%x\n", HostDiag); |
766 | 779 | ||
767 | writel((HostDiag | DIAG_RESET_ADAPTER), ®_set->host_diag); | 780 | writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset); |
768 | 781 | ||
769 | ssleep(10); | 782 | ssleep(10); |
770 | 783 | ||
771 | HostDiag = (u32)readl(®_set->host_diag); | 784 | HostDiag = (u32)readl(hostdiag_offset); |
772 | while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { | 785 | while ( ( HostDiag & DIAG_RESET_ADAPTER) ) { |
773 | msleep(100); | 786 | msleep(100); |
774 | HostDiag = (u32)readl(®_set->host_diag); | 787 | HostDiag = (u32)readl(hostdiag_offset); |
775 | printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", | 788 | printk(KERN_NOTICE "RESET_GEN2: retry=%x, hostdiag=%x\n", |
776 | retry, HostDiag); | 789 | retry, HostDiag); |
777 | 790 | ||
@@ -2503,7 +2516,9 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, | |||
2503 | if ((mfiStatus = instance->instancet->clear_intr( | 2516 | if ((mfiStatus = instance->instancet->clear_intr( |
2504 | instance->reg_set) | 2517 | instance->reg_set) |
2505 | ) == 0) { | 2518 | ) == 0) { |
2506 | return IRQ_NONE; | 2519 | /* Hardware may not set outbound_intr_status in MSI-X mode */ |
2520 | if (!instance->msi_flag) | ||
2521 | return IRQ_NONE; | ||
2507 | } | 2522 | } |
2508 | 2523 | ||
2509 | instance->mfiStatus = mfiStatus; | 2524 | instance->mfiStatus = mfiStatus; |
@@ -2611,7 +2626,9 @@ megasas_transition_to_ready(struct megasas_instance* instance) | |||
2611 | case MFI_STATE_FAULT: | 2626 | case MFI_STATE_FAULT: |
2612 | 2627 | ||
2613 | printk(KERN_DEBUG "megasas: FW in FAULT state!!\n"); | 2628 | printk(KERN_DEBUG "megasas: FW in FAULT state!!\n"); |
2614 | return -ENODEV; | 2629 | max_wait = MEGASAS_RESET_WAIT_TIME; |
2630 | cur_state = MFI_STATE_FAULT; | ||
2631 | break; | ||
2615 | 2632 | ||
2616 | case MFI_STATE_WAIT_HANDSHAKE: | 2633 | case MFI_STATE_WAIT_HANDSHAKE: |
2617 | /* | 2634 | /* |
@@ -3424,7 +3441,6 @@ fail_reply_queue: | |||
3424 | megasas_free_cmds(instance); | 3441 | megasas_free_cmds(instance); |
3425 | 3442 | ||
3426 | fail_alloc_cmds: | 3443 | fail_alloc_cmds: |
3427 | iounmap(instance->reg_set); | ||
3428 | return 1; | 3444 | return 1; |
3429 | } | 3445 | } |
3430 | 3446 | ||
@@ -3494,7 +3510,7 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
3494 | 3510 | ||
3495 | /* Get operational params, sge flags, send init cmd to controller */ | 3511 | /* Get operational params, sge flags, send init cmd to controller */ |
3496 | if (instance->instancet->init_adapter(instance)) | 3512 | if (instance->instancet->init_adapter(instance)) |
3497 | return -ENODEV; | 3513 | goto fail_init_adapter; |
3498 | 3514 | ||
3499 | printk(KERN_ERR "megasas: INIT adapter done\n"); | 3515 | printk(KERN_ERR "megasas: INIT adapter done\n"); |
3500 | 3516 | ||
@@ -3543,7 +3559,7 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
3543 | * Setup tasklet for cmd completion | 3559 | * Setup tasklet for cmd completion |
3544 | */ | 3560 | */ |
3545 | 3561 | ||
3546 | tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc, | 3562 | tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, |
3547 | (unsigned long)instance); | 3563 | (unsigned long)instance); |
3548 | 3564 | ||
3549 | /* Initialize the cmd completion timer */ | 3565 | /* Initialize the cmd completion timer */ |
@@ -3553,6 +3569,7 @@ static int megasas_init_fw(struct megasas_instance *instance) | |||
3553 | MEGASAS_COMPLETION_TIMER_INTERVAL); | 3569 | MEGASAS_COMPLETION_TIMER_INTERVAL); |
3554 | return 0; | 3570 | return 0; |
3555 | 3571 | ||
3572 | fail_init_adapter: | ||
3556 | fail_ready_state: | 3573 | fail_ready_state: |
3557 | iounmap(instance->reg_set); | 3574 | iounmap(instance->reg_set); |
3558 | 3575 | ||
@@ -3820,6 +3837,10 @@ static int megasas_io_attach(struct megasas_instance *instance) | |||
3820 | instance->max_fw_cmds - MEGASAS_INT_CMDS; | 3837 | instance->max_fw_cmds - MEGASAS_INT_CMDS; |
3821 | host->this_id = instance->init_id; | 3838 | host->this_id = instance->init_id; |
3822 | host->sg_tablesize = instance->max_num_sge; | 3839 | host->sg_tablesize = instance->max_num_sge; |
3840 | |||
3841 | if (instance->fw_support_ieee) | ||
3842 | instance->max_sectors_per_req = MEGASAS_MAX_SECTORS_IEEE; | ||
3843 | |||
3823 | /* | 3844 | /* |
3824 | * Check if the module parameter value for max_sectors can be used | 3845 | * Check if the module parameter value for max_sectors can be used |
3825 | */ | 3846 | */ |
@@ -3899,9 +3920,26 @@ fail_set_dma_mask: | |||
3899 | static int __devinit | 3920 | static int __devinit |
3900 | megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | 3921 | megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) |
3901 | { | 3922 | { |
3902 | int rval; | 3923 | int rval, pos; |
3903 | struct Scsi_Host *host; | 3924 | struct Scsi_Host *host; |
3904 | struct megasas_instance *instance; | 3925 | struct megasas_instance *instance; |
3926 | u16 control = 0; | ||
3927 | |||
3928 | /* Reset MSI-X in the kdump kernel */ | ||
3929 | if (reset_devices) { | ||
3930 | pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX); | ||
3931 | if (pos) { | ||
3932 | pci_read_config_word(pdev, msi_control_reg(pos), | ||
3933 | &control); | ||
3934 | if (control & PCI_MSIX_FLAGS_ENABLE) { | ||
3935 | dev_info(&pdev->dev, "resetting MSI-X\n"); | ||
3936 | pci_write_config_word(pdev, | ||
3937 | msi_control_reg(pos), | ||
3938 | control & | ||
3939 | ~PCI_MSIX_FLAGS_ENABLE); | ||
3940 | } | ||
3941 | } | ||
3942 | } | ||
3905 | 3943 | ||
3906 | /* | 3944 | /* |
3907 | * Announce PCI information | 3945 | * Announce PCI information |
@@ -4039,12 +4077,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4039 | else | 4077 | else |
4040 | INIT_WORK(&instance->work_init, process_fw_state_change_wq); | 4078 | INIT_WORK(&instance->work_init, process_fw_state_change_wq); |
4041 | 4079 | ||
4042 | /* | ||
4043 | * Initialize MFI Firmware | ||
4044 | */ | ||
4045 | if (megasas_init_fw(instance)) | ||
4046 | goto fail_init_mfi; | ||
4047 | |||
4048 | /* Try to enable MSI-X */ | 4080 | /* Try to enable MSI-X */ |
4049 | if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) && | 4081 | if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) && |
4050 | (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) && | 4082 | (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) && |
@@ -4054,6 +4086,12 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4054 | instance->msi_flag = 1; | 4086 | instance->msi_flag = 1; |
4055 | 4087 | ||
4056 | /* | 4088 | /* |
4089 | * Initialize MFI Firmware | ||
4090 | */ | ||
4091 | if (megasas_init_fw(instance)) | ||
4092 | goto fail_init_mfi; | ||
4093 | |||
4094 | /* | ||
4057 | * Register IRQ | 4095 | * Register IRQ |
4058 | */ | 4096 | */ |
4059 | if (request_irq(instance->msi_flag ? instance->msixentry.vector : | 4097 | if (request_irq(instance->msi_flag ? instance->msixentry.vector : |
@@ -4105,24 +4143,23 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4105 | instance->instancet->disable_intr(instance->reg_set); | 4143 | instance->instancet->disable_intr(instance->reg_set); |
4106 | free_irq(instance->msi_flag ? instance->msixentry.vector : | 4144 | free_irq(instance->msi_flag ? instance->msixentry.vector : |
4107 | instance->pdev->irq, instance); | 4145 | instance->pdev->irq, instance); |
4146 | fail_irq: | ||
4147 | if (instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) | ||
4148 | megasas_release_fusion(instance); | ||
4149 | else | ||
4150 | megasas_release_mfi(instance); | ||
4151 | fail_init_mfi: | ||
4108 | if (instance->msi_flag) | 4152 | if (instance->msi_flag) |
4109 | pci_disable_msix(instance->pdev); | 4153 | pci_disable_msix(instance->pdev); |
4110 | |||
4111 | fail_irq: | ||
4112 | fail_init_mfi: | ||
4113 | fail_alloc_dma_buf: | 4154 | fail_alloc_dma_buf: |
4114 | if (instance->evt_detail) | 4155 | if (instance->evt_detail) |
4115 | pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), | 4156 | pci_free_consistent(pdev, sizeof(struct megasas_evt_detail), |
4116 | instance->evt_detail, | 4157 | instance->evt_detail, |
4117 | instance->evt_detail_h); | 4158 | instance->evt_detail_h); |
4118 | 4159 | ||
4119 | if (instance->producer) { | 4160 | if (instance->producer) |
4120 | pci_free_consistent(pdev, sizeof(u32), instance->producer, | 4161 | pci_free_consistent(pdev, sizeof(u32), instance->producer, |
4121 | instance->producer_h); | 4162 | instance->producer_h); |
4122 | megasas_release_mfi(instance); | ||
4123 | } else { | ||
4124 | megasas_release_fusion(instance); | ||
4125 | } | ||
4126 | if (instance->consumer) | 4163 | if (instance->consumer) |
4127 | pci_free_consistent(pdev, sizeof(u32), instance->consumer, | 4164 | pci_free_consistent(pdev, sizeof(u32), instance->consumer, |
4128 | instance->consumer_h); | 4165 | instance->consumer_h); |
@@ -4242,9 +4279,8 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4242 | /* cancel the delayed work if this work still in queue */ | 4279 | /* cancel the delayed work if this work still in queue */ |
4243 | if (instance->ev != NULL) { | 4280 | if (instance->ev != NULL) { |
4244 | struct megasas_aen_event *ev = instance->ev; | 4281 | struct megasas_aen_event *ev = instance->ev; |
4245 | cancel_delayed_work( | 4282 | cancel_delayed_work_sync( |
4246 | (struct delayed_work *)&ev->hotplug_work); | 4283 | (struct delayed_work *)&ev->hotplug_work); |
4247 | flush_scheduled_work(); | ||
4248 | instance->ev = NULL; | 4284 | instance->ev = NULL; |
4249 | } | 4285 | } |
4250 | 4286 | ||
@@ -4297,6 +4333,10 @@ megasas_resume(struct pci_dev *pdev) | |||
4297 | if (megasas_set_dma_mask(pdev)) | 4333 | if (megasas_set_dma_mask(pdev)) |
4298 | goto fail_set_dma_mask; | 4334 | goto fail_set_dma_mask; |
4299 | 4335 | ||
4336 | /* Now re-enable MSI-X */ | ||
4337 | if (instance->msi_flag) | ||
4338 | pci_enable_msix(instance->pdev, &instance->msixentry, 1); | ||
4339 | |||
4300 | /* | 4340 | /* |
4301 | * Initialize MFI Firmware | 4341 | * Initialize MFI Firmware |
4302 | */ | 4342 | */ |
@@ -4333,10 +4373,6 @@ megasas_resume(struct pci_dev *pdev) | |||
4333 | tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, | 4373 | tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, |
4334 | (unsigned long)instance); | 4374 | (unsigned long)instance); |
4335 | 4375 | ||
4336 | /* Now re-enable MSI-X */ | ||
4337 | if (instance->msi_flag) | ||
4338 | pci_enable_msix(instance->pdev, &instance->msixentry, 1); | ||
4339 | |||
4340 | /* | 4376 | /* |
4341 | * Register IRQ | 4377 | * Register IRQ |
4342 | */ | 4378 | */ |
@@ -4417,9 +4453,8 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev) | |||
4417 | /* cancel the delayed work if this work still in queue*/ | 4453 | /* cancel the delayed work if this work still in queue*/ |
4418 | if (instance->ev != NULL) { | 4454 | if (instance->ev != NULL) { |
4419 | struct megasas_aen_event *ev = instance->ev; | 4455 | struct megasas_aen_event *ev = instance->ev; |
4420 | cancel_delayed_work( | 4456 | cancel_delayed_work_sync( |
4421 | (struct delayed_work *)&ev->hotplug_work); | 4457 | (struct delayed_work *)&ev->hotplug_work); |
4422 | flush_scheduled_work(); | ||
4423 | instance->ev = NULL; | 4458 | instance->ev = NULL; |
4424 | } | 4459 | } |
4425 | 4460 | ||
@@ -4611,6 +4646,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, | |||
4611 | * For each user buffer, create a mirror buffer and copy in | 4646 | * For each user buffer, create a mirror buffer and copy in |
4612 | */ | 4647 | */ |
4613 | for (i = 0; i < ioc->sge_count; i++) { | 4648 | for (i = 0; i < ioc->sge_count; i++) { |
4649 | if (!ioc->sgl[i].iov_len) | ||
4650 | continue; | ||
4651 | |||
4614 | kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev, | 4652 | kbuff_arr[i] = dma_alloc_coherent(&instance->pdev->dev, |
4615 | ioc->sgl[i].iov_len, | 4653 | ioc->sgl[i].iov_len, |
4616 | &buf_handle, GFP_KERNEL); | 4654 | &buf_handle, GFP_KERNEL); |
@@ -5177,6 +5215,7 @@ megasas_aen_polling(struct work_struct *work) | |||
5177 | break; | 5215 | break; |
5178 | 5216 | ||
5179 | case MR_EVT_LD_OFFLINE: | 5217 | case MR_EVT_LD_OFFLINE: |
5218 | case MR_EVT_CFG_CLEARED: | ||
5180 | case MR_EVT_LD_DELETED: | 5219 | case MR_EVT_LD_DELETED: |
5181 | megasas_get_ld_list(instance); | 5220 | megasas_get_ld_list(instance); |
5182 | for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { | 5221 | for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) { |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index d6e2a663b165..145a8cffb1fa 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
@@ -81,6 +81,10 @@ u16 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map); | |||
81 | struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map); | 81 | struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map); |
82 | 82 | ||
83 | u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map); | 83 | u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map); |
84 | |||
85 | void | ||
86 | megasas_check_and_restore_queue_depth(struct megasas_instance *instance); | ||
87 | |||
84 | u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, | 88 | u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map, |
85 | struct LD_LOAD_BALANCE_INFO *lbInfo); | 89 | struct LD_LOAD_BALANCE_INFO *lbInfo); |
86 | u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo, | 90 | u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo, |
@@ -983,13 +987,15 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) | |||
983 | 987 | ||
984 | return 0; | 988 | return 0; |
985 | 989 | ||
986 | fail_alloc_cmds: | ||
987 | fail_alloc_mfi_cmds: | ||
988 | fail_map_info: | 990 | fail_map_info: |
989 | if (i == 1) | 991 | if (i == 1) |
990 | dma_free_coherent(&instance->pdev->dev, fusion->map_sz, | 992 | dma_free_coherent(&instance->pdev->dev, fusion->map_sz, |
991 | fusion->ld_map[0], fusion->ld_map_phys[0]); | 993 | fusion->ld_map[0], fusion->ld_map_phys[0]); |
992 | fail_ioc_init: | 994 | fail_ioc_init: |
995 | megasas_free_cmds_fusion(instance); | ||
996 | fail_alloc_cmds: | ||
997 | megasas_free_cmds(instance); | ||
998 | fail_alloc_mfi_cmds: | ||
993 | return 1; | 999 | return 1; |
994 | } | 1000 | } |
995 | 1001 | ||
@@ -1431,8 +1437,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, | |||
1431 | local_map_ptr = fusion->ld_map[(instance->map_id & 1)]; | 1437 | local_map_ptr = fusion->ld_map[(instance->map_id & 1)]; |
1432 | 1438 | ||
1433 | /* Check if this is a system PD I/O */ | 1439 | /* Check if this is a system PD I/O */ |
1434 | if ((instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) && | 1440 | if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) { |
1435 | (instance->pd_list[pd_index].driveType == TYPE_DISK)) { | ||
1436 | io_request->Function = 0; | 1441 | io_request->Function = 0; |
1437 | io_request->DevHandle = | 1442 | io_request->DevHandle = |
1438 | local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; | 1443 | local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; |
@@ -1455,7 +1460,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, | |||
1455 | MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); | 1460 | MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); |
1456 | } | 1461 | } |
1457 | io_request->RaidContext.VirtualDiskTgtId = device_id; | 1462 | io_request->RaidContext.VirtualDiskTgtId = device_id; |
1458 | io_request->LUN[0] = scmd->device->lun; | 1463 | io_request->LUN[1] = scmd->device->lun; |
1459 | io_request->DataLength = scsi_bufflen(scmd); | 1464 | io_request->DataLength = scsi_bufflen(scmd); |
1460 | } | 1465 | } |
1461 | 1466 | ||
@@ -1479,7 +1484,7 @@ megasas_build_io_fusion(struct megasas_instance *instance, | |||
1479 | device_id = MEGASAS_DEV_INDEX(instance, scp); | 1484 | device_id = MEGASAS_DEV_INDEX(instance, scp); |
1480 | 1485 | ||
1481 | /* Zero out some fields so they don't get reused */ | 1486 | /* Zero out some fields so they don't get reused */ |
1482 | io_request->LUN[0] = 0; | 1487 | io_request->LUN[1] = 0; |
1483 | io_request->CDB.EEDP32.PrimaryReferenceTag = 0; | 1488 | io_request->CDB.EEDP32.PrimaryReferenceTag = 0; |
1484 | io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0; | 1489 | io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0; |
1485 | io_request->EEDPFlags = 0; | 1490 | io_request->EEDPFlags = 0; |
@@ -1743,7 +1748,7 @@ complete_cmd_fusion(struct megasas_instance *instance) | |||
1743 | wmb(); | 1748 | wmb(); |
1744 | writel(fusion->last_reply_idx, | 1749 | writel(fusion->last_reply_idx, |
1745 | &instance->reg_set->reply_post_host_index); | 1750 | &instance->reg_set->reply_post_host_index); |
1746 | 1751 | megasas_check_and_restore_queue_depth(instance); | |
1747 | return IRQ_HANDLED; | 1752 | return IRQ_HANDLED; |
1748 | } | 1753 | } |
1749 | 1754 | ||