Commit 22ebde16 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

scsi: qla2xxx: Prevent sysfs access when chip is down

Prevent user from sending commands through sysfs while firmware is not
running or reset is in progress.
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 7e84766c
...@@ -518,6 +518,9 @@ qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj, ...@@ -518,6 +518,9 @@ qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj,
if (unlikely(pci_channel_offline(ha->pdev))) if (unlikely(pci_channel_offline(ha->pdev)))
return 0; return 0;
if (qla2x00_chip_is_down(vha))
return 0;
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size || if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size ||
!ha->isp_ops->write_nvram) !ha->isp_ops->write_nvram)
return 0; return 0;
...@@ -570,7 +573,7 @@ qla2x00_sysfs_read_sfp(struct file *filp, struct kobject *kobj, ...@@ -570,7 +573,7 @@ qla2x00_sysfs_read_sfp(struct file *filp, struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN) || off != 0 || count < SFP_DEV_SIZE) if (!capable(CAP_SYS_ADMIN) || off != 0 || count < SFP_DEV_SIZE)
return 0; return 0;
if (qla2x00_reset_active(vha)) if (qla2x00_chip_is_down(vha))
return 0; return 0;
rval = qla2x00_read_sfp_dev(vha, buf, count); rval = qla2x00_read_sfp_dev(vha, buf, count);
...@@ -733,6 +736,15 @@ qla2x00_issue_logo(struct file *filp, struct kobject *kobj, ...@@ -733,6 +736,15 @@ qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
int type; int type;
port_id_t did; port_id_t did;
if (!capable(CAP_SYS_ADMIN))
return 0;
if (unlikely(pci_channel_offline(vha->hw->pdev)))
return 0;
if (qla2x00_chip_is_down(vha))
return 0;
type = simple_strtol(buf, NULL, 10); type = simple_strtol(buf, NULL, 10);
did.b.domain = (type & 0x00ff0000) >> 16; did.b.domain = (type & 0x00ff0000) >> 16;
...@@ -771,6 +783,12 @@ qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj, ...@@ -771,6 +783,12 @@ qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN) || off != 0 || count > XGMAC_DATA_SIZE) if (!capable(CAP_SYS_ADMIN) || off != 0 || count > XGMAC_DATA_SIZE)
return 0; return 0;
if (unlikely(pci_channel_offline(ha->pdev)))
return 0;
if (qla2x00_chip_is_down(vha))
return 0;
if (ha->xgmac_data) if (ha->xgmac_data)
goto do_read; goto do_read;
...@@ -825,6 +843,9 @@ qla2x00_sysfs_read_dcbx_tlv(struct file *filp, struct kobject *kobj, ...@@ -825,6 +843,9 @@ qla2x00_sysfs_read_dcbx_tlv(struct file *filp, struct kobject *kobj,
if (ha->dcbx_tlv) if (ha->dcbx_tlv)
goto do_read; goto do_read;
if (qla2x00_chip_is_down(vha))
return 0;
ha->dcbx_tlv = dma_alloc_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE, ha->dcbx_tlv = dma_alloc_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE,
&ha->dcbx_tlv_dma, GFP_KERNEL); &ha->dcbx_tlv_dma, GFP_KERNEL);
if (!ha->dcbx_tlv) { if (!ha->dcbx_tlv) {
...@@ -1036,7 +1057,7 @@ qla2x00_link_state_show(struct device *dev, struct device_attribute *attr, ...@@ -1036,7 +1057,7 @@ qla2x00_link_state_show(struct device *dev, struct device_attribute *attr,
vha->device_flags & DFLG_NO_CABLE) vha->device_flags & DFLG_NO_CABLE)
len = scnprintf(buf, PAGE_SIZE, "Link Down\n"); len = scnprintf(buf, PAGE_SIZE, "Link Down\n");
else if (atomic_read(&vha->loop_state) != LOOP_READY || else if (atomic_read(&vha->loop_state) != LOOP_READY ||
qla2x00_reset_active(vha)) qla2x00_chip_is_down(vha))
len = scnprintf(buf, PAGE_SIZE, "Unknown Link State\n"); len = scnprintf(buf, PAGE_SIZE, "Unknown Link State\n");
else { else {
len = scnprintf(buf, PAGE_SIZE, "Link Up - "); len = scnprintf(buf, PAGE_SIZE, "Link Up - ");
...@@ -1163,7 +1184,7 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr, ...@@ -1163,7 +1184,7 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
if (IS_QLA2100(ha) || IS_QLA2200(ha)) if (IS_QLA2100(ha) || IS_QLA2200(ha))
return -EPERM; return -EPERM;
if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) { if (qla2x00_chip_is_down(vha)) {
ql_log(ql_log_warn, vha, 0x707a, ql_log(ql_log_warn, vha, 0x707a,
"Abort ISP active -- ignoring beacon request.\n"); "Abort ISP active -- ignoring beacon request.\n");
return -EBUSY; return -EBUSY;
...@@ -1350,7 +1371,7 @@ qla2x00_thermal_temp_show(struct device *dev, ...@@ -1350,7 +1371,7 @@ qla2x00_thermal_temp_show(struct device *dev,
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
uint16_t temp = 0; uint16_t temp = 0;
if (qla2x00_reset_active(vha)) { if (qla2x00_chip_is_down(vha)) {
ql_log(ql_log_warn, vha, 0x70dc, "ISP reset active.\n"); ql_log(ql_log_warn, vha, 0x70dc, "ISP reset active.\n");
goto done; goto done;
} }
...@@ -1381,7 +1402,7 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr, ...@@ -1381,7 +1402,7 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "0x%x\n", pstate); return scnprintf(buf, PAGE_SIZE, "0x%x\n", pstate);
} }
if (qla2x00_reset_active(vha)) if (qla2x00_chip_is_down(vha))
ql_log(ql_log_warn, vha, 0x707c, ql_log(ql_log_warn, vha, 0x707c,
"ISP reset active.\n"); "ISP reset active.\n");
else if (!vha->hw->flags.eeh_busy) else if (!vha->hw->flags.eeh_busy)
...@@ -1840,7 +1861,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) ...@@ -1840,7 +1861,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
if (unlikely(pci_channel_offline(ha->pdev))) if (unlikely(pci_channel_offline(ha->pdev)))
goto done; goto done;
if (qla2x00_reset_active(vha)) if (qla2x00_chip_is_down(vha))
goto done; goto done;
stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats), stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats),
......
...@@ -7017,7 +7017,7 @@ uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha) ...@@ -7017,7 +7017,7 @@ uint8_t qla27xx_find_valid_image(struct scsi_qla_host *vha)
ha->active_image = QLA27XX_SECONDARY_IMAGE; ha->active_image = QLA27XX_SECONDARY_IMAGE;
} }
ql_dbg(ql_dbg_init, vha, 0x018f, "%s image\n", ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x018f, "%s image\n",
ha->active_image == 0 ? "default bootld and fw" : ha->active_image == 0 ? "default bootld and fw" :
ha->active_image == 1 ? "primary" : ha->active_image == 1 ? "primary" :
ha->active_image == 2 ? "secondary" : ha->active_image == 2 ? "secondary" :
......
...@@ -202,6 +202,12 @@ qla2x00_reset_active(scsi_qla_host_t *vha) ...@@ -202,6 +202,12 @@ qla2x00_reset_active(scsi_qla_host_t *vha)
test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
} }
static inline int
qla2x00_chip_is_down(scsi_qla_host_t *vha)
{
return (qla2x00_reset_active(vha) || !vha->hw->flags.fw_started);
}
static inline srb_t * static inline srb_t *
qla2xxx_get_qpair_sp(struct qla_qpair *qpair, fc_port_t *fcport, gfp_t flag) qla2xxx_get_qpair_sp(struct qla_qpair *qpair, fc_port_t *fcport, gfp_t flag)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment