diff options
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 42 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 3 |
2 files changed, 28 insertions, 17 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 2542f1f8bf86..13215cd396aa 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -52,6 +52,13 @@ | |||
52 | #define LPFC_MIN_DEVLOSS_TMO 1 | 52 | #define LPFC_MIN_DEVLOSS_TMO 1 |
53 | #define LPFC_MAX_DEVLOSS_TMO 255 | 53 | #define LPFC_MAX_DEVLOSS_TMO 255 |
54 | 54 | ||
55 | /* | ||
56 | * Write key size should be multiple of 4. If write key is changed | ||
57 | * make sure that library write key is also changed. | ||
58 | */ | ||
59 | #define LPFC_REG_WRITE_KEY_SIZE 4 | ||
60 | #define LPFC_REG_WRITE_KEY "EMLX" | ||
61 | |||
55 | /** | 62 | /** |
56 | * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules | 63 | * lpfc_jedec_to_ascii - Hex to ascii convertor according to JEDEC rules |
57 | * @incr: integer to convert. | 64 | * @incr: integer to convert. |
@@ -693,7 +700,7 @@ lpfc_selective_reset(struct lpfc_hba *phba) | |||
693 | int rc; | 700 | int rc; |
694 | 701 | ||
695 | if (!phba->cfg_enable_hba_reset) | 702 | if (!phba->cfg_enable_hba_reset) |
696 | return -EIO; | 703 | return -EACCES; |
697 | 704 | ||
698 | status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); | 705 | status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); |
699 | 706 | ||
@@ -768,13 +775,18 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr, | |||
768 | static int | 775 | static int |
769 | lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) | 776 | lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) |
770 | { | 777 | { |
771 | struct lpfc_register portstat_reg; | 778 | struct lpfc_register portstat_reg = {0}; |
772 | int i; | 779 | int i; |
773 | 780 | ||
774 | 781 | msleep(100); | |
775 | lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, | 782 | lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, |
776 | &portstat_reg.word0); | 783 | &portstat_reg.word0); |
777 | 784 | ||
785 | /* verify if privilaged for the request operation */ | ||
786 | if (!bf_get(lpfc_sliport_status_rn, &portstat_reg) && | ||
787 | !bf_get(lpfc_sliport_status_err, &portstat_reg)) | ||
788 | return -EPERM; | ||
789 | |||
778 | /* wait for the SLI port firmware ready after firmware reset */ | 790 | /* wait for the SLI port firmware ready after firmware reset */ |
779 | for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) { | 791 | for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) { |
780 | msleep(10); | 792 | msleep(10); |
@@ -816,16 +828,13 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) | |||
816 | int rc; | 828 | int rc; |
817 | 829 | ||
818 | if (!phba->cfg_enable_hba_reset) | 830 | if (!phba->cfg_enable_hba_reset) |
819 | return -EIO; | 831 | return -EACCES; |
820 | 832 | ||
821 | if ((phba->sli_rev < LPFC_SLI_REV4) || | 833 | if ((phba->sli_rev < LPFC_SLI_REV4) || |
822 | (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | 834 | (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != |
823 | LPFC_SLI_INTF_IF_TYPE_2)) | 835 | LPFC_SLI_INTF_IF_TYPE_2)) |
824 | return -EPERM; | 836 | return -EPERM; |
825 | 837 | ||
826 | if (!pdev->is_physfn) | ||
827 | return -EPERM; | ||
828 | |||
829 | /* Disable SR-IOV virtual functions if enabled */ | 838 | /* Disable SR-IOV virtual functions if enabled */ |
830 | if (phba->cfg_sriov_nr_virtfn) { | 839 | if (phba->cfg_sriov_nr_virtfn) { |
831 | pci_disable_sriov(pdev); | 840 | pci_disable_sriov(pdev); |
@@ -858,7 +867,7 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) | |||
858 | rc = lpfc_sli4_pdev_status_reg_wait(phba); | 867 | rc = lpfc_sli4_pdev_status_reg_wait(phba); |
859 | 868 | ||
860 | if (rc) | 869 | if (rc) |
861 | return -EIO; | 870 | return rc; |
862 | 871 | ||
863 | init_completion(&online_compl); | 872 | init_completion(&online_compl); |
864 | rc = lpfc_workq_post_event(phba, &status, &online_compl, | 873 | rc = lpfc_workq_post_event(phba, &status, &online_compl, |
@@ -984,7 +993,7 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr, | |||
984 | if (!status) | 993 | if (!status) |
985 | return strlen(buf); | 994 | return strlen(buf); |
986 | else | 995 | else |
987 | return -EIO; | 996 | return status; |
988 | } | 997 | } |
989 | 998 | ||
990 | /** | 999 | /** |
@@ -3885,18 +3894,23 @@ sysfs_ctlreg_write(struct file *filp, struct kobject *kobj, | |||
3885 | if ((off + count) > FF_REG_AREA_SIZE) | 3894 | if ((off + count) > FF_REG_AREA_SIZE) |
3886 | return -ERANGE; | 3895 | return -ERANGE; |
3887 | 3896 | ||
3888 | if (count == 0) return 0; | 3897 | if (count <= LPFC_REG_WRITE_KEY_SIZE) |
3898 | return 0; | ||
3889 | 3899 | ||
3890 | if (off % 4 || count % 4 || (unsigned long)buf % 4) | 3900 | if (off % 4 || count % 4 || (unsigned long)buf % 4) |
3891 | return -EINVAL; | 3901 | return -EINVAL; |
3892 | 3902 | ||
3893 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) { | 3903 | /* This is to protect HBA registers from accidental writes. */ |
3904 | if (memcmp(buf, LPFC_REG_WRITE_KEY, LPFC_REG_WRITE_KEY_SIZE)) | ||
3905 | return -EINVAL; | ||
3906 | |||
3907 | if (!(vport->fc_flag & FC_OFFLINE_MODE)) | ||
3894 | return -EPERM; | 3908 | return -EPERM; |
3895 | } | ||
3896 | 3909 | ||
3897 | spin_lock_irq(&phba->hbalock); | 3910 | spin_lock_irq(&phba->hbalock); |
3898 | for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) | 3911 | for (buf_off = 0; buf_off < count - LPFC_REG_WRITE_KEY_SIZE; |
3899 | writel(*((uint32_t *)(buf + buf_off)), | 3912 | buf_off += sizeof(uint32_t)) |
3913 | writel(*((uint32_t *)(buf + buf_off + LPFC_REG_WRITE_KEY_SIZE)), | ||
3900 | phba->ctrl_regs_memmap_p + off + buf_off); | 3914 | phba->ctrl_regs_memmap_p + off + buf_off); |
3901 | 3915 | ||
3902 | spin_unlock_irq(&phba->hbalock); | 3916 | spin_unlock_irq(&phba->hbalock); |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b9ff38fa7c26..d8ac7694854e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -4056,9 +4056,6 @@ lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *phba) | |||
4056 | uint16_t nr_virtfn; | 4056 | uint16_t nr_virtfn; |
4057 | int pos; | 4057 | int pos; |
4058 | 4058 | ||
4059 | if (!pdev->is_physfn) | ||
4060 | return 0; | ||
4061 | |||
4062 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); | 4059 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); |
4063 | if (pos == 0) | 4060 | if (pos == 0) |
4064 | return 0; | 4061 | return 0; |