aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c42
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c3
2 files changed, 28 insertions, 17 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 2542f1f8bf8..13215cd396a 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,
768static int 775static int
769lpfc_sli4_pdev_status_reg_wait(struct lpfc_hba *phba) 776lpfc_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 b9ff38fa7c2..d8ac7694854 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;