mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-06 00:04:42 +00:00
qla2x00t-32gbit: Upgrade initiator code to the code from kernel v5.1-rc2
This patch is the output of git diff v4.18.20..v5.1-rc2 drivers/scsi/qla2xxx. Only one manual change has been applied, namely the removal of "cmd->se_cmd.map_cpu = cpu;" from qlt_alloc_qfull_cmd(). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8094 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
+704
-19
@@ -158,9 +158,17 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj,
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ha->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (IS_NOCACHE_VPD_TYPE(ha))
|
||||
ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
|
||||
ha->nvram_size);
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
|
||||
return memory_read_from_buffer(buf, count, &off, ha->nvram,
|
||||
ha->nvram_size);
|
||||
}
|
||||
@@ -208,10 +216,17 @@ qla2x00_sysfs_write_nvram(struct file *filp, struct kobject *kobj,
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
mutex_lock(&ha->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Write NVRAM. */
|
||||
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
|
||||
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
|
||||
count);
|
||||
count);
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
|
||||
ql_dbg(ql_dbg_user, vha, 0x7060,
|
||||
"Setting ISP_ABORT_NEEDED\n");
|
||||
@@ -322,6 +337,10 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
|
||||
size = ha->optrom_size - start;
|
||||
|
||||
mutex_lock(&ha->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
switch (val) {
|
||||
case 0:
|
||||
if (ha->optrom_state != QLA_SREADING &&
|
||||
@@ -499,8 +518,14 @@ qla2x00_sysfs_read_vpd(struct file *filp, struct kobject *kobj,
|
||||
qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE)
|
||||
faddr = ha->flt_region_vpd_sec << 2;
|
||||
|
||||
mutex_lock(&ha->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
ha->isp_ops->read_optrom(vha, ha->vpd, faddr,
|
||||
ha->vpd_size);
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
}
|
||||
return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
|
||||
}
|
||||
@@ -518,6 +543,9 @@ qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj,
|
||||
if (unlikely(pci_channel_offline(ha->pdev)))
|
||||
return 0;
|
||||
|
||||
if (qla2x00_chip_is_down(vha))
|
||||
return 0;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size ||
|
||||
!ha->isp_ops->write_nvram)
|
||||
return 0;
|
||||
@@ -528,16 +556,25 @@ qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj,
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
mutex_lock(&ha->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Write NVRAM. */
|
||||
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
|
||||
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
|
||||
|
||||
/* Update flash version information for 4Gb & above. */
|
||||
if (!IS_FWI2_CAPABLE(ha))
|
||||
if (!IS_FWI2_CAPABLE(ha)) {
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp_data = vmalloc(256);
|
||||
if (!tmp_data) {
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
ql_log(ql_log_warn, vha, 0x706b,
|
||||
"Unable to allocate memory for VPD information update.\n");
|
||||
return -ENOMEM;
|
||||
@@ -545,6 +582,8 @@ qla2x00_sysfs_write_vpd(struct file *filp, struct kobject *kobj,
|
||||
ha->isp_ops->get_flash_version(vha, tmp_data);
|
||||
vfree(tmp_data);
|
||||
|
||||
mutex_unlock(&ha->optrom_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -570,10 +609,15 @@ qla2x00_sysfs_read_sfp(struct file *filp, struct kobject *kobj,
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count < SFP_DEV_SIZE)
|
||||
return 0;
|
||||
|
||||
if (qla2x00_reset_active(vha))
|
||||
mutex_lock(&vha->hw->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rval = qla2x00_read_sfp_dev(vha, buf, count);
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
|
||||
if (rval)
|
||||
return -EIO;
|
||||
|
||||
@@ -733,6 +777,15 @@ qla2x00_issue_logo(struct file *filp, struct kobject *kobj,
|
||||
int type;
|
||||
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);
|
||||
|
||||
did.b.domain = (type & 0x00ff0000) >> 16;
|
||||
@@ -771,12 +824,21 @@ qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj,
|
||||
if (!capable(CAP_SYS_ADMIN) || off != 0 || count > XGMAC_DATA_SIZE)
|
||||
return 0;
|
||||
|
||||
if (unlikely(pci_channel_offline(ha->pdev)))
|
||||
return 0;
|
||||
mutex_lock(&vha->hw->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ha->xgmac_data)
|
||||
goto do_read;
|
||||
|
||||
ha->xgmac_data = dma_alloc_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE,
|
||||
&ha->xgmac_data_dma, GFP_KERNEL);
|
||||
if (!ha->xgmac_data) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
ql_log(ql_log_warn, vha, 0x7076,
|
||||
"Unable to allocate memory for XGMAC read-data.\n");
|
||||
return 0;
|
||||
@@ -788,6 +850,8 @@ do_read:
|
||||
|
||||
rval = qla2x00_get_xgmac_stats(vha, ha->xgmac_data_dma,
|
||||
XGMAC_DATA_SIZE, &actual_size);
|
||||
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x7077,
|
||||
"Unable to read XGMAC data (%x).\n", rval);
|
||||
@@ -824,10 +888,16 @@ qla2x00_sysfs_read_dcbx_tlv(struct file *filp, struct kobject *kobj,
|
||||
|
||||
if (ha->dcbx_tlv)
|
||||
goto do_read;
|
||||
mutex_lock(&vha->hw->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ha->dcbx_tlv = dma_alloc_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE,
|
||||
&ha->dcbx_tlv_dma, GFP_KERNEL);
|
||||
if (!ha->dcbx_tlv) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
ql_log(ql_log_warn, vha, 0x7078,
|
||||
"Unable to allocate memory for DCBX TLV read-data.\n");
|
||||
return -ENOMEM;
|
||||
@@ -838,6 +908,9 @@ do_read:
|
||||
|
||||
rval = qla2x00_get_dcbx_params(vha, ha->dcbx_tlv_dma,
|
||||
DCBX_TLV_DATA_SIZE);
|
||||
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x7079,
|
||||
"Unable to read DCBX TLV (%x).\n", rval);
|
||||
@@ -932,7 +1005,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha, bool stop_beacon)
|
||||
/* Scsi_Host attributes. */
|
||||
|
||||
static ssize_t
|
||||
qla2x00_drvr_version_show(struct device *dev,
|
||||
qla2x00_driver_version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
|
||||
@@ -1036,7 +1109,7 @@ qla2x00_link_state_show(struct device *dev, struct device_attribute *attr,
|
||||
vha->device_flags & DFLG_NO_CABLE)
|
||||
len = scnprintf(buf, PAGE_SIZE, "Link Down\n");
|
||||
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");
|
||||
else {
|
||||
len = scnprintf(buf, PAGE_SIZE, "Link Up - ");
|
||||
@@ -1137,6 +1210,34 @@ qla2x00_zio_timer_store(struct device *dev, struct device_attribute *attr,
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla_zio_threshold_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d exchanges\n",
|
||||
vha->hw->last_zio_threshold);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla_zio_threshold_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int val = 0;
|
||||
|
||||
if (vha->hw->zio_mode != QLA_ZIO_MODE_6)
|
||||
return -EINVAL;
|
||||
if (sscanf(buf, "%d", &val) != 1)
|
||||
return -EINVAL;
|
||||
if (val < 0 || val > 256)
|
||||
return -ERANGE;
|
||||
|
||||
atomic_set(&vha->hw->zio_threshold, val);
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_beacon_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
@@ -1163,15 +1264,17 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
|
||||
if (IS_QLA2100(ha) || IS_QLA2200(ha))
|
||||
return -EPERM;
|
||||
|
||||
if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
|
||||
if (sscanf(buf, "%d", &val) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&vha->hw->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
ql_log(ql_log_warn, vha, 0x707a,
|
||||
"Abort ISP active -- ignoring beacon request.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (sscanf(buf, "%d", &val) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
rval = ha->isp_ops->beacon_on(vha);
|
||||
else
|
||||
@@ -1180,6 +1283,8 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
|
||||
if (rval != QLA_SUCCESS)
|
||||
count = 0;
|
||||
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -1349,18 +1454,24 @@ qla2x00_thermal_temp_show(struct device *dev,
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
uint16_t temp = 0;
|
||||
int rc;
|
||||
|
||||
if (qla2x00_reset_active(vha)) {
|
||||
mutex_lock(&vha->hw->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
ql_log(ql_log_warn, vha, 0x70dc, "ISP reset active.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (vha->hw->flags.eeh_busy) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
ql_log(ql_log_warn, vha, 0x70dd, "PCI EEH busy.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (qla2x00_get_thermal_temp(vha, &temp) == QLA_SUCCESS)
|
||||
rc = qla2x00_get_thermal_temp(vha, &temp);
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
if (rc == QLA_SUCCESS)
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", temp);
|
||||
|
||||
done:
|
||||
@@ -1381,13 +1492,24 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
|
||||
return scnprintf(buf, PAGE_SIZE, "0x%x\n", pstate);
|
||||
}
|
||||
|
||||
if (qla2x00_reset_active(vha))
|
||||
mutex_lock(&vha->hw->optrom_mutex);
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
ql_log(ql_log_warn, vha, 0x707c,
|
||||
"ISP reset active.\n");
|
||||
else if (!vha->hw->flags.eeh_busy)
|
||||
rval = qla2x00_get_firmware_state(vha, state);
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto out;
|
||||
} else if (vha->hw->flags.eeh_busy) {
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rval = qla2x00_get_firmware_state(vha, state);
|
||||
mutex_unlock(&vha->hw->optrom_mutex);
|
||||
out:
|
||||
if (rval != QLA_SUCCESS) {
|
||||
memset(state, -1, sizeof(state));
|
||||
rval = qla2x00_get_firmware_state(vha, state);
|
||||
}
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
||||
state[0], state[1], state[2], state[3], state[4], state[5]);
|
||||
@@ -1513,7 +1635,536 @@ qla2x00_max_speed_sup_show(struct device *dev, struct device_attribute *attr,
|
||||
ha->max_speed_sup ? "32Gps" : "16Gps");
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
|
||||
static ssize_t
|
||||
qla2x00_port_speed_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev));
|
||||
ulong type, speed;
|
||||
int oldspeed, rval;
|
||||
int mode = QLA_SET_DATA_RATE_LR;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (!IS_QLA27XX(vha->hw)) {
|
||||
ql_log(ql_log_warn, vha, 0x70d8,
|
||||
"Speed setting not supported \n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rval = kstrtol(buf, 10, &type);
|
||||
if (rval)
|
||||
return rval;
|
||||
speed = type;
|
||||
if (type == 40 || type == 80 || type == 160 ||
|
||||
type == 320) {
|
||||
ql_dbg(ql_dbg_user, vha, 0x70d9,
|
||||
"Setting will be affected after a loss of sync\n");
|
||||
type = type/10;
|
||||
mode = QLA_SET_DATA_RATE_NOLR;
|
||||
}
|
||||
|
||||
oldspeed = ha->set_data_rate;
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
ha->set_data_rate = PORT_SPEED_AUTO;
|
||||
break;
|
||||
case 4:
|
||||
ha->set_data_rate = PORT_SPEED_4GB;
|
||||
break;
|
||||
case 8:
|
||||
ha->set_data_rate = PORT_SPEED_8GB;
|
||||
break;
|
||||
case 16:
|
||||
ha->set_data_rate = PORT_SPEED_16GB;
|
||||
break;
|
||||
case 32:
|
||||
ha->set_data_rate = PORT_SPEED_32GB;
|
||||
break;
|
||||
default:
|
||||
ql_log(ql_log_warn, vha, 0x1199,
|
||||
"Unrecognized speed setting:%lx. Setting Autoneg\n",
|
||||
speed);
|
||||
ha->set_data_rate = PORT_SPEED_AUTO;
|
||||
}
|
||||
|
||||
if (qla2x00_chip_is_down(vha) || (oldspeed == ha->set_data_rate))
|
||||
return -EINVAL;
|
||||
|
||||
ql_log(ql_log_info, vha, 0x70da,
|
||||
"Setting speed to %lx Gbps \n", type);
|
||||
|
||||
rval = qla2x00_set_data_rate(vha, mode);
|
||||
if (rval != QLA_SUCCESS)
|
||||
return -EIO;
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
ssize_t rval;
|
||||
char *spd[7] = {"0", "0", "0", "4", "8", "16", "32"};
|
||||
|
||||
rval = qla2x00_get_data_rate(vha);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x70db,
|
||||
"Unable to get port speed rval:%zd\n", rval);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ql_log(ql_log_info, vha, 0x70d6,
|
||||
"port speed:%d\n", ha->link_data_rate);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]);
|
||||
}
|
||||
|
||||
/* ----- */
|
||||
|
||||
static ssize_t
|
||||
qlini_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int len = 0;
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
"Supported options: enabled | disabled | dual | exclusive\n");
|
||||
|
||||
/* --- */
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len, "Current selection: ");
|
||||
|
||||
switch (vha->qlini_mode) {
|
||||
case QLA2XXX_INI_MODE_EXCLUSIVE:
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
QLA2XXX_INI_MODE_STR_EXCLUSIVE);
|
||||
break;
|
||||
case QLA2XXX_INI_MODE_DISABLED:
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
QLA2XXX_INI_MODE_STR_DISABLED);
|
||||
break;
|
||||
case QLA2XXX_INI_MODE_ENABLED:
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
QLA2XXX_INI_MODE_STR_ENABLED);
|
||||
break;
|
||||
case QLA2XXX_INI_MODE_DUAL:
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
QLA2XXX_INI_MODE_STR_DUAL);
|
||||
break;
|
||||
}
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len, "\n");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static char *mode_to_str[] = {
|
||||
"exclusive",
|
||||
"disabled",
|
||||
"enabled",
|
||||
"dual",
|
||||
};
|
||||
|
||||
#define NEED_EXCH_OFFLOAD(_exchg) ((_exchg) > FW_DEF_EXCHANGES_CNT)
|
||||
static int qla_set_ini_mode(scsi_qla_host_t *vha, int op)
|
||||
{
|
||||
int rc = 0;
|
||||
enum {
|
||||
NO_ACTION,
|
||||
MODE_CHANGE_ACCEPT,
|
||||
MODE_CHANGE_NO_ACTION,
|
||||
TARGET_STILL_ACTIVE,
|
||||
};
|
||||
int action = NO_ACTION;
|
||||
int set_mode = 0;
|
||||
u8 eo_toggle = 0; /* exchange offload flipped */
|
||||
|
||||
switch (vha->qlini_mode) {
|
||||
case QLA2XXX_INI_MODE_DISABLED:
|
||||
switch (op) {
|
||||
case QLA2XXX_INI_MODE_DISABLED:
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
|
||||
vha->hw->flags.exchoffld_enabled)
|
||||
eo_toggle = 1;
|
||||
if (((vha->ql2xexchoffld !=
|
||||
vha->u_ql2xexchoffld) &&
|
||||
NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
|
||||
eo_toggle) {
|
||||
/*
|
||||
* The number of exchange to be offload
|
||||
* was tweaked or offload option was
|
||||
* flipped
|
||||
*/
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
} else {
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
}
|
||||
} else {
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
}
|
||||
break;
|
||||
case QLA2XXX_INI_MODE_EXCLUSIVE:
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
|
||||
vha->hw->flags.exchoffld_enabled)
|
||||
eo_toggle = 1;
|
||||
if (((vha->ql2xexchoffld !=
|
||||
vha->u_ql2xexchoffld) &&
|
||||
NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
|
||||
eo_toggle) {
|
||||
/*
|
||||
* The number of exchange to be offload
|
||||
* was tweaked or offload option was
|
||||
* flipped
|
||||
*/
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
} else {
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
}
|
||||
} else {
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
}
|
||||
break;
|
||||
case QLA2XXX_INI_MODE_DUAL:
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
/* active_mode is target only, reset it to dual */
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
set_mode = 1;
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
} else {
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
}
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_ENABLED:
|
||||
if (qla_tgt_mode_enabled(vha))
|
||||
action = TARGET_STILL_ACTIVE;
|
||||
else {
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
set_mode = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_EXCLUSIVE:
|
||||
switch (op) {
|
||||
case QLA2XXX_INI_MODE_EXCLUSIVE:
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
|
||||
vha->hw->flags.exchoffld_enabled)
|
||||
eo_toggle = 1;
|
||||
if (((vha->ql2xexchoffld !=
|
||||
vha->u_ql2xexchoffld) &&
|
||||
NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
|
||||
eo_toggle)
|
||||
/*
|
||||
* The number of exchange to be offload
|
||||
* was tweaked or offload option was
|
||||
* flipped
|
||||
*/
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
else
|
||||
action = NO_ACTION;
|
||||
} else
|
||||
action = NO_ACTION;
|
||||
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_DISABLED:
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
|
||||
vha->hw->flags.exchoffld_enabled)
|
||||
eo_toggle = 1;
|
||||
if (((vha->ql2xexchoffld !=
|
||||
vha->u_ql2xexchoffld) &&
|
||||
NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
|
||||
eo_toggle)
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
else
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
} else
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_DUAL: /* exclusive -> dual */
|
||||
if (qla_tgt_mode_enabled(vha)) {
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
set_mode = 1;
|
||||
} else
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_ENABLED:
|
||||
if (qla_tgt_mode_enabled(vha))
|
||||
action = TARGET_STILL_ACTIVE;
|
||||
else {
|
||||
if (vha->hw->flags.fw_started)
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
else
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_ENABLED:
|
||||
switch (op) {
|
||||
case QLA2XXX_INI_MODE_ENABLED:
|
||||
if (NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg) !=
|
||||
vha->hw->flags.exchoffld_enabled)
|
||||
eo_toggle = 1;
|
||||
if (((vha->ql2xiniexchg != vha->u_ql2xiniexchg) &&
|
||||
NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg)) ||
|
||||
eo_toggle)
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
else
|
||||
action = NO_ACTION;
|
||||
break;
|
||||
case QLA2XXX_INI_MODE_DUAL:
|
||||
case QLA2XXX_INI_MODE_DISABLED:
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
break;
|
||||
default:
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_DUAL:
|
||||
switch (op) {
|
||||
case QLA2XXX_INI_MODE_DUAL:
|
||||
if (qla_tgt_mode_enabled(vha) ||
|
||||
qla_dual_mode_enabled(vha)) {
|
||||
if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld +
|
||||
vha->u_ql2xiniexchg) !=
|
||||
vha->hw->flags.exchoffld_enabled)
|
||||
eo_toggle = 1;
|
||||
|
||||
if ((((vha->ql2xexchoffld +
|
||||
vha->ql2xiniexchg) !=
|
||||
(vha->u_ql2xiniexchg +
|
||||
vha->u_ql2xexchoffld)) &&
|
||||
NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg +
|
||||
vha->u_ql2xexchoffld)) || eo_toggle)
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
else
|
||||
action = NO_ACTION;
|
||||
} else {
|
||||
if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld +
|
||||
vha->u_ql2xiniexchg) !=
|
||||
vha->hw->flags.exchoffld_enabled)
|
||||
eo_toggle = 1;
|
||||
|
||||
if ((((vha->ql2xexchoffld + vha->ql2xiniexchg)
|
||||
!= (vha->u_ql2xiniexchg +
|
||||
vha->u_ql2xexchoffld)) &&
|
||||
NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg +
|
||||
vha->u_ql2xexchoffld)) || eo_toggle)
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
else
|
||||
action = NO_ACTION;
|
||||
}
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_DISABLED:
|
||||
if (qla_tgt_mode_enabled(vha) ||
|
||||
qla_dual_mode_enabled(vha)) {
|
||||
/* turning off initiator mode */
|
||||
set_mode = 1;
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
} else {
|
||||
action = MODE_CHANGE_NO_ACTION;
|
||||
}
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_EXCLUSIVE:
|
||||
if (qla_tgt_mode_enabled(vha) ||
|
||||
qla_dual_mode_enabled(vha)) {
|
||||
set_mode = 1;
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
} else {
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
}
|
||||
break;
|
||||
|
||||
case QLA2XXX_INI_MODE_ENABLED:
|
||||
if (qla_tgt_mode_enabled(vha) ||
|
||||
qla_dual_mode_enabled(vha)) {
|
||||
action = TARGET_STILL_ACTIVE;
|
||||
} else {
|
||||
action = MODE_CHANGE_ACCEPT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case MODE_CHANGE_ACCEPT:
|
||||
ql_log(ql_log_warn, vha, 0xffff,
|
||||
"Mode change accepted. From %s to %s, Tgt exchg %d|%d. ini exchg %d|%d\n",
|
||||
mode_to_str[vha->qlini_mode], mode_to_str[op],
|
||||
vha->ql2xexchoffld, vha->u_ql2xexchoffld,
|
||||
vha->ql2xiniexchg, vha->u_ql2xiniexchg);
|
||||
|
||||
vha->qlini_mode = op;
|
||||
vha->ql2xexchoffld = vha->u_ql2xexchoffld;
|
||||
vha->ql2xiniexchg = vha->u_ql2xiniexchg;
|
||||
if (set_mode)
|
||||
qlt_set_mode(vha);
|
||||
vha->flags.online = 1;
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
break;
|
||||
|
||||
case MODE_CHANGE_NO_ACTION:
|
||||
ql_log(ql_log_warn, vha, 0xffff,
|
||||
"Mode is set. No action taken. From %s to %s, Tgt exchg %d|%d. ini exchg %d|%d\n",
|
||||
mode_to_str[vha->qlini_mode], mode_to_str[op],
|
||||
vha->ql2xexchoffld, vha->u_ql2xexchoffld,
|
||||
vha->ql2xiniexchg, vha->u_ql2xiniexchg);
|
||||
vha->qlini_mode = op;
|
||||
vha->ql2xexchoffld = vha->u_ql2xexchoffld;
|
||||
vha->ql2xiniexchg = vha->u_ql2xiniexchg;
|
||||
break;
|
||||
|
||||
case TARGET_STILL_ACTIVE:
|
||||
ql_log(ql_log_warn, vha, 0xffff,
|
||||
"Target Mode is active. Unable to change Mode.\n");
|
||||
break;
|
||||
|
||||
case NO_ACTION:
|
||||
default:
|
||||
ql_log(ql_log_warn, vha, 0xffff,
|
||||
"Mode unchange. No action taken. %d|%d pct %d|%d.\n",
|
||||
vha->qlini_mode, op,
|
||||
vha->ql2xexchoffld, vha->u_ql2xexchoffld);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qlini_mode_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int ini;
|
||||
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
|
||||
if (strncasecmp(QLA2XXX_INI_MODE_STR_EXCLUSIVE, buf,
|
||||
strlen(QLA2XXX_INI_MODE_STR_EXCLUSIVE)) == 0)
|
||||
ini = QLA2XXX_INI_MODE_EXCLUSIVE;
|
||||
else if (strncasecmp(QLA2XXX_INI_MODE_STR_DISABLED, buf,
|
||||
strlen(QLA2XXX_INI_MODE_STR_DISABLED)) == 0)
|
||||
ini = QLA2XXX_INI_MODE_DISABLED;
|
||||
else if (strncasecmp(QLA2XXX_INI_MODE_STR_ENABLED, buf,
|
||||
strlen(QLA2XXX_INI_MODE_STR_ENABLED)) == 0)
|
||||
ini = QLA2XXX_INI_MODE_ENABLED;
|
||||
else if (strncasecmp(QLA2XXX_INI_MODE_STR_DUAL, buf,
|
||||
strlen(QLA2XXX_INI_MODE_STR_DUAL)) == 0)
|
||||
ini = QLA2XXX_INI_MODE_DUAL;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
qla_set_ini_mode(vha, ini);
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ql2xexchoffld_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int len = 0;
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
"target exchange: new %d : current: %d\n\n",
|
||||
vha->u_ql2xexchoffld, vha->ql2xexchoffld);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
"Please (re)set operating mode via \"/sys/class/scsi_host/host%ld/qlini_mode\" to load new setting.\n",
|
||||
vha->host_no);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ql2xexchoffld_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int val = 0;
|
||||
|
||||
if (sscanf(buf, "%d", &val) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (val > FW_MAX_EXCHANGES_CNT)
|
||||
val = FW_MAX_EXCHANGES_CNT;
|
||||
else if (val < 0)
|
||||
val = 0;
|
||||
|
||||
vha->u_ql2xexchoffld = val;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ql2xiniexchg_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int len = 0;
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
"target exchange: new %d : current: %d\n\n",
|
||||
vha->u_ql2xiniexchg, vha->ql2xiniexchg);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE-len,
|
||||
"Please (re)set operating mode via \"/sys/class/scsi_host/host%ld/qlini_mode\" to load new setting.\n",
|
||||
vha->host_no);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ql2xiniexchg_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
int val = 0;
|
||||
|
||||
if (sscanf(buf, "%d", &val) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (val > FW_MAX_EXCHANGES_CNT)
|
||||
val = FW_MAX_EXCHANGES_CNT;
|
||||
else if (val < 0)
|
||||
val = 0;
|
||||
|
||||
vha->u_ql2xiniexchg = val;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_dif_bundle_statistics_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE,
|
||||
"cross=%llu read=%llu write=%llu kalloc=%llu dma_alloc=%llu unusable=%u\n",
|
||||
ha->dif_bundle_crossed_pages, ha->dif_bundle_reads,
|
||||
ha->dif_bundle_writes, ha->dif_bundle_kallocs,
|
||||
ha->dif_bundle_dma_allocs, ha->pool.unusable.count);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL);
|
||||
static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
|
||||
static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
|
||||
static DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);
|
||||
@@ -1560,6 +2211,17 @@ static DEVICE_ATTR(allow_cna_fw_dump, S_IRUGO | S_IWUSR,
|
||||
static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL);
|
||||
static DEVICE_ATTR(min_link_speed, S_IRUGO, qla2x00_min_link_speed_show, NULL);
|
||||
static DEVICE_ATTR(max_speed_sup, S_IRUGO, qla2x00_max_speed_sup_show, NULL);
|
||||
static DEVICE_ATTR(zio_threshold, 0644,
|
||||
qla_zio_threshold_show,
|
||||
qla_zio_threshold_store);
|
||||
static DEVICE_ATTR_RW(qlini_mode);
|
||||
static DEVICE_ATTR_RW(ql2xexchoffld);
|
||||
static DEVICE_ATTR_RW(ql2xiniexchg);
|
||||
static DEVICE_ATTR(dif_bundle_statistics, 0444,
|
||||
qla2x00_dif_bundle_statistics_show, NULL);
|
||||
static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show,
|
||||
qla2x00_port_speed_store);
|
||||
|
||||
|
||||
struct device_attribute *qla2x00_host_attrs[] = {
|
||||
&dev_attr_driver_version,
|
||||
@@ -1596,9 +2258,30 @@ struct device_attribute *qla2x00_host_attrs[] = {
|
||||
&dev_attr_pep_version,
|
||||
&dev_attr_min_link_speed,
|
||||
&dev_attr_max_speed_sup,
|
||||
&dev_attr_zio_threshold,
|
||||
&dev_attr_dif_bundle_statistics,
|
||||
&dev_attr_port_speed,
|
||||
NULL, /* reserve for qlini_mode */
|
||||
NULL, /* reserve for ql2xiniexchg */
|
||||
NULL, /* reserve for ql2xexchoffld */
|
||||
NULL,
|
||||
};
|
||||
|
||||
void qla_insert_tgt_attrs(void)
|
||||
{
|
||||
struct device_attribute **attr;
|
||||
|
||||
/* advance to empty slot */
|
||||
for (attr = &qla2x00_host_attrs[0]; *attr; ++attr)
|
||||
continue;
|
||||
|
||||
*attr = &dev_attr_qlini_mode;
|
||||
attr++;
|
||||
*attr = &dev_attr_ql2xiniexchg;
|
||||
attr++;
|
||||
*attr = &dev_attr_ql2xexchoffld;
|
||||
}
|
||||
|
||||
/* Host attributes. */
|
||||
|
||||
static void
|
||||
@@ -1840,11 +2523,11 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
|
||||
if (unlikely(pci_channel_offline(ha->pdev)))
|
||||
goto done;
|
||||
|
||||
if (qla2x00_reset_active(vha))
|
||||
if (qla2x00_chip_is_down(vha))
|
||||
goto done;
|
||||
|
||||
stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats),
|
||||
&stats_dma, GFP_KERNEL);
|
||||
stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma,
|
||||
GFP_KERNEL);
|
||||
if (!stats) {
|
||||
ql_log(ql_log_warn, vha, 0x707d,
|
||||
"Failed to allocate memory for stats.\n");
|
||||
@@ -2140,6 +2823,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
|
||||
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
|
||||
msleep(1000);
|
||||
|
||||
qla_nvme_delete(vha);
|
||||
|
||||
qla24xx_disable_vp(vha);
|
||||
qla2x00_wait_for_sess_deletion(vha);
|
||||
|
||||
|
||||
@@ -2312,8 +2312,8 @@ qla2x00_get_priv_stats(struct bsg_job *bsg_job)
|
||||
if (!IS_FWI2_CAPABLE(ha))
|
||||
return -EPERM;
|
||||
|
||||
stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats),
|
||||
&stats_dma, GFP_KERNEL);
|
||||
stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma,
|
||||
GFP_KERNEL);
|
||||
if (!stats) {
|
||||
ql_log(ql_log_warn, vha, 0x70e2,
|
||||
"Failed to allocate memory for stats.\n");
|
||||
@@ -2487,7 +2487,7 @@ qla24xx_bsg_request(struct bsg_job *bsg_job)
|
||||
vha = shost_priv(host);
|
||||
}
|
||||
|
||||
if (qla2x00_reset_active(vha)) {
|
||||
if (qla2x00_chip_is_down(vha)) {
|
||||
ql_dbg(ql_dbg_user, vha, 0x709f,
|
||||
"BSG: ISP abort active/needed -- cmd=%d.\n",
|
||||
bsg_request->msgcode);
|
||||
|
||||
@@ -1130,6 +1130,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||
ha->fw_dump);
|
||||
goto qla24xx_fw_dump_failed;
|
||||
}
|
||||
QLA_FW_STOPPED(ha);
|
||||
fw = &ha->fw_dump->isp.isp24;
|
||||
qla2xxx_prep_dump(ha, ha->fw_dump);
|
||||
|
||||
@@ -1384,6 +1385,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||
ha->fw_dump);
|
||||
goto qla25xx_fw_dump_failed;
|
||||
}
|
||||
QLA_FW_STOPPED(ha);
|
||||
fw = &ha->fw_dump->isp.isp25;
|
||||
qla2xxx_prep_dump(ha, ha->fw_dump);
|
||||
ha->fw_dump->version = htonl(2);
|
||||
@@ -2036,6 +2038,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
|
||||
"request...\n", ha->fw_dump);
|
||||
goto qla83xx_fw_dump_failed;
|
||||
}
|
||||
QLA_FW_STOPPED(ha);
|
||||
fw = &ha->fw_dump->isp.isp83;
|
||||
qla2xxx_prep_dump(ha, ha->fw_dump);
|
||||
|
||||
|
||||
+86
-11
@@ -262,8 +262,8 @@ struct name_list_extended {
|
||||
struct get_name_list_extended *l;
|
||||
dma_addr_t ldma;
|
||||
struct list_head fcports;
|
||||
spinlock_t fcports_lock;
|
||||
u32 size;
|
||||
u8 sent;
|
||||
};
|
||||
/*
|
||||
* Timeout timer counts in seconds
|
||||
@@ -313,6 +313,8 @@ struct srb_cmd {
|
||||
#define SRB_CRC_CTX_DMA_VALID BIT_2 /* DIF: context DMA valid */
|
||||
#define SRB_CRC_PROT_DMA_VALID BIT_4 /* DIF: prot DMA valid */
|
||||
#define SRB_CRC_CTX_DSD_VALID BIT_5 /* DIF: dsd_list valid */
|
||||
#define SRB_WAKEUP_ON_COMP BIT_6
|
||||
#define SRB_DIF_BUNDL_DMA_VALID BIT_7 /* DIF: DMA list valid */
|
||||
|
||||
/* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
|
||||
#define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID)
|
||||
@@ -379,6 +381,7 @@ struct srb_iocb {
|
||||
#define SRB_LOGIN_COND_PLOGI BIT_1
|
||||
#define SRB_LOGIN_SKIP_PRLI BIT_2
|
||||
#define SRB_LOGIN_NVME_PRLI BIT_3
|
||||
#define SRB_LOGIN_PRLI_ONLY BIT_4
|
||||
uint16_t data[2];
|
||||
u32 iop[2];
|
||||
} logio;
|
||||
@@ -398,6 +401,8 @@ struct srb_iocb {
|
||||
struct completion comp;
|
||||
struct els_plogi_payload *els_plogi_pyld;
|
||||
struct els_plogi_payload *els_resp_pyld;
|
||||
u32 tx_size;
|
||||
u32 rx_size;
|
||||
dma_addr_t els_plogi_pyld_dma;
|
||||
dma_addr_t els_resp_pyld_dma;
|
||||
uint32_t fw_status[3];
|
||||
@@ -515,6 +520,7 @@ struct srb_iocb {
|
||||
enum {
|
||||
TYPE_SRB,
|
||||
TYPE_TGT_CMD,
|
||||
TYPE_TGT_TMCMD, /* task management */
|
||||
};
|
||||
|
||||
typedef struct srb {
|
||||
@@ -1887,6 +1893,13 @@ struct crc_context {
|
||||
/* List of DMA context transfers */
|
||||
struct list_head dsd_list;
|
||||
|
||||
/* List of DIF Bundling context DMA address */
|
||||
struct list_head ldif_dsd_list;
|
||||
u8 no_ldif_dsd;
|
||||
|
||||
struct list_head ldif_dma_hndl_list;
|
||||
u32 dif_bundl_len;
|
||||
u8 no_dif_bundl;
|
||||
/* This structure should not exceed 512 bytes */
|
||||
};
|
||||
|
||||
@@ -2276,7 +2289,6 @@ struct ct_sns_desc {
|
||||
enum discovery_state {
|
||||
DSC_DELETED,
|
||||
DSC_GNN_ID,
|
||||
DSC_GID_PN,
|
||||
DSC_GNL,
|
||||
DSC_LOGIN_PEND,
|
||||
DSC_LOGIN_FAILED,
|
||||
@@ -2301,7 +2313,6 @@ enum login_state { /* FW control Target side */
|
||||
enum fcport_mgt_event {
|
||||
FCME_RELOGIN = 1,
|
||||
FCME_RSCN,
|
||||
FCME_GIDPN_DONE,
|
||||
FCME_PLOGI_DONE, /* Initiator side sent LLIOCB */
|
||||
FCME_PRLI_DONE,
|
||||
FCME_GNL_DONE,
|
||||
@@ -2312,6 +2323,7 @@ enum fcport_mgt_event {
|
||||
FCME_ADISC_DONE,
|
||||
FCME_GNNID_DONE,
|
||||
FCME_GFPNID_DONE,
|
||||
FCME_ELS_PLOGI_DONE,
|
||||
};
|
||||
|
||||
enum rscn_addr_format {
|
||||
@@ -2346,7 +2358,7 @@ typedef struct fc_port {
|
||||
unsigned int login_succ:1;
|
||||
unsigned int query:1;
|
||||
unsigned int id_changed:1;
|
||||
unsigned int rscn_rcvd:1;
|
||||
unsigned int scan_needed:1;
|
||||
|
||||
struct work_struct nvme_del_work;
|
||||
struct completion nvme_del_done;
|
||||
@@ -2355,7 +2367,9 @@ typedef struct fc_port {
|
||||
#define NVME_PRLI_SP_INITIATOR BIT_5
|
||||
#define NVME_PRLI_SP_TARGET BIT_4
|
||||
#define NVME_PRLI_SP_DISCOVERY BIT_3
|
||||
#define NVME_PRLI_SP_FIRST_BURST BIT_0
|
||||
uint8_t nvme_flag;
|
||||
uint32_t nvme_first_burst_size;
|
||||
#define NVME_FLAG_REGISTERED 4
|
||||
#define NVME_FLAG_DELETING 2
|
||||
#define NVME_FLAG_RESETTING 1
|
||||
@@ -2370,11 +2384,13 @@ typedef struct fc_port {
|
||||
unsigned long expires;
|
||||
struct list_head del_list_entry;
|
||||
struct work_struct free_work;
|
||||
|
||||
struct work_struct reg_work;
|
||||
uint64_t jiffies_at_registration;
|
||||
struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
|
||||
|
||||
uint16_t tgt_id;
|
||||
uint16_t old_tgt_id;
|
||||
uint16_t sec_since_registration;
|
||||
|
||||
uint8_t fcp_prio;
|
||||
|
||||
@@ -2407,7 +2423,9 @@ typedef struct fc_port {
|
||||
struct qla_tgt_sess *tgt_session;
|
||||
struct ct_sns_desc ct_desc;
|
||||
enum discovery_state disc_state;
|
||||
enum discovery_state next_disc_state;
|
||||
enum login_state fw_login_state;
|
||||
unsigned long dm_login_expire;
|
||||
unsigned long plogi_nack_done_deadline;
|
||||
|
||||
u32 login_gen, last_login_gen;
|
||||
@@ -2418,7 +2436,8 @@ typedef struct fc_port {
|
||||
u8 iocb[IOCB_SIZE];
|
||||
u8 current_login_state;
|
||||
u8 last_login_state;
|
||||
struct completion n2n_done;
|
||||
u16 n2n_link_reset_cnt;
|
||||
u16 n2n_chip_reset;
|
||||
} fc_port_t;
|
||||
|
||||
#define QLA_FCPORT_SCAN 1
|
||||
@@ -3205,17 +3224,14 @@ enum qla_work_type {
|
||||
QLA_EVT_ASYNC_LOGOUT,
|
||||
QLA_EVT_ASYNC_LOGOUT_DONE,
|
||||
QLA_EVT_ASYNC_ADISC,
|
||||
QLA_EVT_ASYNC_ADISC_DONE,
|
||||
QLA_EVT_UEVENT,
|
||||
QLA_EVT_AENFX,
|
||||
QLA_EVT_GIDPN,
|
||||
QLA_EVT_GPNID,
|
||||
QLA_EVT_UNMAP,
|
||||
QLA_EVT_NEW_SESS,
|
||||
QLA_EVT_GPDB,
|
||||
QLA_EVT_PRLI,
|
||||
QLA_EVT_GPSC,
|
||||
QLA_EVT_UPD_FCPORT,
|
||||
QLA_EVT_GNL,
|
||||
QLA_EVT_NACK,
|
||||
QLA_EVT_RELOGIN,
|
||||
@@ -3228,6 +3244,7 @@ enum qla_work_type {
|
||||
QLA_EVT_GFPNID,
|
||||
QLA_EVT_SP_RETRY,
|
||||
QLA_EVT_IIDMA,
|
||||
QLA_EVT_ELS_PLOGI,
|
||||
};
|
||||
|
||||
|
||||
@@ -3475,6 +3492,9 @@ struct qla_qpair {
|
||||
struct list_head qp_list_elem; /* vha->qp_list */
|
||||
struct list_head hints_list;
|
||||
uint16_t cpuid;
|
||||
uint16_t retry_term_cnt;
|
||||
uint32_t retry_term_exchg_addr;
|
||||
uint64_t retry_term_jiff;
|
||||
struct qla_tgt_counters tgt_counters;
|
||||
};
|
||||
|
||||
@@ -3599,6 +3619,8 @@ struct qla_hw_data {
|
||||
uint32_t detected_lr_sfp:1;
|
||||
uint32_t using_lr_setting:1;
|
||||
uint32_t rida_fmt2:1;
|
||||
uint32_t purge_mbox:1;
|
||||
uint32_t n2n_bigger:1;
|
||||
} flags;
|
||||
|
||||
uint16_t max_exchg;
|
||||
@@ -3676,12 +3698,14 @@ struct qla_hw_data {
|
||||
#define PORT_SPEED_UNKNOWN 0xFFFF
|
||||
#define PORT_SPEED_1GB 0x00
|
||||
#define PORT_SPEED_2GB 0x01
|
||||
#define PORT_SPEED_AUTO 0x02
|
||||
#define PORT_SPEED_4GB 0x03
|
||||
#define PORT_SPEED_8GB 0x04
|
||||
#define PORT_SPEED_16GB 0x05
|
||||
#define PORT_SPEED_32GB 0x06
|
||||
#define PORT_SPEED_10GB 0x13
|
||||
uint16_t link_data_rate; /* F/W operating speed */
|
||||
uint16_t set_data_rate; /* Set by user */
|
||||
|
||||
uint8_t current_topology;
|
||||
uint8_t prev_topology;
|
||||
@@ -3844,6 +3868,10 @@ struct qla_hw_data {
|
||||
int port_down_retry_count;
|
||||
uint8_t mbx_count;
|
||||
uint8_t aen_mbx_count;
|
||||
atomic_t num_pend_mbx_stage1;
|
||||
atomic_t num_pend_mbx_stage2;
|
||||
atomic_t num_pend_mbx_stage3;
|
||||
uint16_t frame_payload_size;
|
||||
|
||||
uint32_t login_retry_count;
|
||||
/* SNS command interfaces. */
|
||||
@@ -3903,6 +3931,9 @@ struct qla_hw_data {
|
||||
int exchoffld_size;
|
||||
int exchoffld_count;
|
||||
|
||||
/* n2n */
|
||||
struct els_plogi_payload plogi_els_payld;
|
||||
|
||||
void *swl;
|
||||
|
||||
/* These are used by mailbox operations. */
|
||||
@@ -3939,6 +3970,10 @@ struct qla_hw_data {
|
||||
uint16_t fw_subminor_version;
|
||||
uint16_t fw_attributes;
|
||||
uint16_t fw_attributes_h;
|
||||
#define FW_ATTR_H_NVME_FBURST BIT_1
|
||||
#define FW_ATTR_H_NVME BIT_10
|
||||
#define FW_ATTR_H_NVME_UPDATED BIT_14
|
||||
|
||||
uint16_t fw_attributes_ext[2];
|
||||
uint32_t fw_memory_size;
|
||||
uint32_t fw_transfer_size;
|
||||
@@ -4157,6 +4192,7 @@ struct qla_hw_data {
|
||||
struct work_struct board_disable;
|
||||
|
||||
struct mr_data_fx00 mr;
|
||||
uint32_t chip_reset;
|
||||
|
||||
struct qlt_hw_data tgt;
|
||||
int allow_cna_fw_dump;
|
||||
@@ -4164,8 +4200,32 @@ struct qla_hw_data {
|
||||
uint16_t min_link_speed;
|
||||
uint16_t max_speed_sup;
|
||||
|
||||
/* DMA pool for the DIF bundling buffers */
|
||||
struct dma_pool *dif_bundl_pool;
|
||||
#define DIF_BUNDLING_DMA_POOL_SIZE 1024
|
||||
struct {
|
||||
struct {
|
||||
struct list_head head;
|
||||
uint count;
|
||||
} good;
|
||||
struct {
|
||||
struct list_head head;
|
||||
uint count;
|
||||
} unusable;
|
||||
} pool;
|
||||
|
||||
unsigned long long dif_bundle_crossed_pages;
|
||||
unsigned long long dif_bundle_reads;
|
||||
unsigned long long dif_bundle_writes;
|
||||
unsigned long long dif_bundle_kallocs;
|
||||
unsigned long long dif_bundle_dma_allocs;
|
||||
|
||||
atomic_t nvme_active_aen_cnt;
|
||||
uint16_t nvme_last_rptd_aen; /* Last recorded aen count */
|
||||
|
||||
atomic_t zio_threshold;
|
||||
uint16_t last_zio_threshold;
|
||||
#define DEFAULT_ZIO_THRESHOLD 5
|
||||
};
|
||||
|
||||
#define FW_ABILITY_MAX_SPEED_MASK 0xFUL
|
||||
@@ -4174,6 +4234,10 @@ struct qla_hw_data {
|
||||
#define FW_ABILITY_MAX_SPEED(ha) \
|
||||
(ha->fw_ability_mask & FW_ABILITY_MAX_SPEED_MASK)
|
||||
|
||||
#define QLA_GET_DATA_RATE 0
|
||||
#define QLA_SET_DATA_RATE_NOLR 1
|
||||
#define QLA_SET_DATA_RATE_LR 2 /* Set speed and initiate LR */
|
||||
|
||||
/*
|
||||
* Qlogic scsi host structure
|
||||
*/
|
||||
@@ -4205,6 +4269,7 @@ typedef struct scsi_qla_host {
|
||||
uint32_t qpairs_req_created:1;
|
||||
uint32_t qpairs_rsp_created:1;
|
||||
uint32_t nvme_enabled:1;
|
||||
uint32_t nvme_first_burst:1;
|
||||
} flags;
|
||||
|
||||
atomic_t loop_state;
|
||||
@@ -4238,17 +4303,18 @@ typedef struct scsi_qla_host {
|
||||
#define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */
|
||||
#define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */
|
||||
#define ISP_QUIESCE_NEEDED 20 /* Driver need some quiescence */
|
||||
#define FREE_BIT 21
|
||||
#define N2N_LINK_RESET 21
|
||||
#define PORT_UPDATE_NEEDED 22
|
||||
#define FX00_RESET_RECOVERY 23
|
||||
#define FX00_TARGET_SCAN 24
|
||||
#define FX00_CRITEMP_RECOVERY 25
|
||||
#define FX00_HOST_INFO_RESEND 26
|
||||
#define QPAIR_ONLINE_CHECK_NEEDED 27
|
||||
#define SET_ZIO_THRESHOLD_NEEDED 28
|
||||
#define SET_NVME_ZIO_THRESHOLD_NEEDED 28
|
||||
#define DETECT_SFP_CHANGE 29
|
||||
#define N2N_LOGIN_NEEDED 30
|
||||
#define IOCB_WORK_ACTIVE 31
|
||||
#define SET_ZIO_THRESHOLD_NEEDED 32
|
||||
|
||||
unsigned long pci_flags;
|
||||
#define PFLG_DISCONNECTED 0 /* PCI device removed */
|
||||
@@ -4351,6 +4417,13 @@ typedef struct scsi_qla_host {
|
||||
atomic_t vref_count;
|
||||
struct qla8044_reset_template reset_tmplt;
|
||||
uint16_t bbcr;
|
||||
|
||||
uint16_t u_ql2xexchoffld;
|
||||
uint16_t u_ql2xiniexchg;
|
||||
uint16_t qlini_mode;
|
||||
uint16_t ql2xexchoffld;
|
||||
uint16_t ql2xiniexchg;
|
||||
|
||||
struct name_list_extended gnl;
|
||||
/* Count of active session/fcport */
|
||||
int fcport_count;
|
||||
@@ -4362,6 +4435,8 @@ typedef struct scsi_qla_host {
|
||||
uint16_t n2n_id;
|
||||
struct list_head gpnid_list;
|
||||
struct fab_scan scan;
|
||||
|
||||
unsigned int irq_offset;
|
||||
} scsi_qla_host_t;
|
||||
|
||||
struct qla27xx_image_status {
|
||||
|
||||
@@ -193,6 +193,8 @@ qla_dfs_tgt_counters_show(struct seq_file *s, void *unused)
|
||||
|
||||
for (i = 0; i < vha->hw->max_qpairs; i++) {
|
||||
qpair = vha->hw->queue_pair_map[i];
|
||||
if (!qpair)
|
||||
continue;
|
||||
qla_core_sbt_cmd += qpair->tgt_counters.qla_core_sbt_cmd;
|
||||
core_qla_que_buf += qpair->tgt_counters.core_qla_que_buf;
|
||||
qla_core_ret_ctio += qpair->tgt_counters.qla_core_ret_ctio;
|
||||
@@ -446,11 +448,6 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
|
||||
|
||||
atomic_set(&qla2x00_dfs_root_count, 0);
|
||||
qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL);
|
||||
if (!qla2x00_dfs_root) {
|
||||
ql_log(ql_log_warn, vha, 0x00f7,
|
||||
"Unable to create debugfs root directory.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
create_dir:
|
||||
if (ha->dfs_dir)
|
||||
@@ -458,64 +455,28 @@ create_dir:
|
||||
|
||||
mutex_init(&ha->fce_mutex);
|
||||
ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root);
|
||||
if (!ha->dfs_dir) {
|
||||
ql_log(ql_log_warn, vha, 0x00f8,
|
||||
"Unable to create debugfs ha directory.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
atomic_inc(&qla2x00_dfs_root_count);
|
||||
|
||||
create_nodes:
|
||||
ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count",
|
||||
S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops);
|
||||
if (!ha->dfs_fw_resource_cnt) {
|
||||
ql_log(ql_log_warn, vha, 0x00fd,
|
||||
"Unable to create debugFS fw_resource_count node.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR,
|
||||
ha->dfs_dir, vha, &dfs_tgt_counters_ops);
|
||||
if (!ha->dfs_tgt_counters) {
|
||||
ql_log(ql_log_warn, vha, 0xd301,
|
||||
"Unable to create debugFS tgt_counters node.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database",
|
||||
S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_port_database_ops);
|
||||
if (!ha->tgt.dfs_tgt_port_database) {
|
||||
ql_log(ql_log_warn, vha, 0xd03f,
|
||||
"Unable to create debugFS tgt_port_database node.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
|
||||
&dfs_fce_ops);
|
||||
if (!ha->dfs_fce) {
|
||||
ql_log(ql_log_warn, vha, 0x00f9,
|
||||
"Unable to create debugfs fce node.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess",
|
||||
S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops);
|
||||
if (!ha->tgt.dfs_tgt_sess) {
|
||||
ql_log(ql_log_warn, vha, 0xd040,
|
||||
"Unable to create debugFS tgt_sess node.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) {
|
||||
if (IS_QLA27XX(ha) || IS_QLA83XX(ha))
|
||||
ha->tgt.dfs_naqp = debugfs_create_file("naqp",
|
||||
0400, ha->dfs_dir, vha, &dfs_naqp_ops);
|
||||
if (!ha->tgt.dfs_naqp) {
|
||||
ql_log(ql_log_warn, vha, 0xd011,
|
||||
"Unable to create debugFS naqp node.\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1366,6 +1366,11 @@ struct vp_rpt_id_entry_24xx {
|
||||
/* format 1 fabric */
|
||||
uint8_t vpstat1_subcode; /* vp_status=1 subcode */
|
||||
uint8_t flags;
|
||||
#define TOPO_MASK 0xE
|
||||
#define TOPO_FL 0x2
|
||||
#define TOPO_N2N 0x4
|
||||
#define TOPO_F 0x6
|
||||
|
||||
uint16_t fip_flags;
|
||||
uint8_t rsv2[12];
|
||||
|
||||
|
||||
+17
-14
@@ -45,8 +45,7 @@ extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
|
||||
extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t);
|
||||
extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *,
|
||||
port_id_t);
|
||||
extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *, bool);
|
||||
|
||||
extern void qla2x00_update_fcports(scsi_qla_host_t *);
|
||||
|
||||
@@ -55,7 +54,7 @@ extern void qla2x00_abort_isp_cleanup(scsi_qla_host_t *);
|
||||
extern void qla2x00_quiesce_io(scsi_qla_host_t *);
|
||||
|
||||
extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
|
||||
|
||||
void qla_register_fcport_fn(struct work_struct *);
|
||||
extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
|
||||
extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
|
||||
|
||||
@@ -74,8 +73,6 @@ extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *,
|
||||
enum qla_work_type);
|
||||
extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
|
||||
@@ -110,6 +107,7 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, u8 *, u8*,
|
||||
int qla24xx_fcport_handle_login(struct scsi_qla_host *, fc_port_t *);
|
||||
int qla24xx_detect_sfp(scsi_qla_host_t *vha);
|
||||
int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8);
|
||||
|
||||
void qla2x00_async_prlo_done(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_post_async_prlo_work(struct scsi_qla_host *, fc_port_t *,
|
||||
@@ -118,6 +116,9 @@ extern int qla2x00_post_async_prlo_done_work(struct scsi_qla_host *,
|
||||
fc_port_t *, uint16_t *);
|
||||
int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
|
||||
void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport);
|
||||
int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *);
|
||||
void qla_rscn_replay(fc_port_t *fcport);
|
||||
|
||||
/*
|
||||
* Global Data in qla_os.c source file.
|
||||
*/
|
||||
@@ -158,6 +159,8 @@ extern int ql2xnvmeenable;
|
||||
extern int ql2xautodetectsfp;
|
||||
extern int ql2xenablemsix;
|
||||
extern int qla2xuseresexchforels;
|
||||
extern int ql2xexlogins;
|
||||
extern int ql2xdifbundlinginternalbuffers;
|
||||
|
||||
extern int qla2x00_loop_reset(scsi_qla_host_t *);
|
||||
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
|
||||
@@ -208,11 +211,11 @@ extern void qla2x00_disable_board_on_pci_error(struct work_struct *);
|
||||
extern void qla2x00_sp_compl(void *, int);
|
||||
extern void qla2xxx_qpair_sp_free_dma(void *);
|
||||
extern void qla2xxx_qpair_sp_compl(void *, int);
|
||||
extern int qla24xx_post_upd_fcport_work(struct scsi_qla_host *, fc_port_t *);
|
||||
extern void qla24xx_sched_upd_fcport(fc_port_t *);
|
||||
void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
|
||||
int qla24xx_async_abort_cmd(srb_t *);
|
||||
int qla24xx_async_abort_cmd(srb_t *, bool);
|
||||
int qla24xx_post_relogin_work(struct scsi_qla_host *vha);
|
||||
void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *);
|
||||
|
||||
@@ -267,8 +270,8 @@ extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *,
|
||||
uint16_t, struct req_que *);
|
||||
extern int qla2x00_start_scsi(srb_t *sp);
|
||||
extern int qla24xx_start_scsi(srb_t *sp);
|
||||
int qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
|
||||
uint16_t, uint64_t, uint8_t);
|
||||
int qla2x00_marker(struct scsi_qla_host *, struct qla_qpair *,
|
||||
uint16_t, uint64_t, uint8_t);
|
||||
extern int qla2x00_start_sp(srb_t *);
|
||||
extern int qla24xx_dif_start_scsi(srb_t *);
|
||||
extern int qla2x00_start_bidir(srb_t *, struct scsi_qla_host *, uint32_t);
|
||||
@@ -283,7 +286,7 @@ extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *,
|
||||
extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *,
|
||||
uint32_t *, uint16_t, struct qla_tc_param *);
|
||||
extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *,
|
||||
uint32_t *, uint16_t, struct qla_tc_param *);
|
||||
uint32_t *, uint16_t, struct qla_tgt_cmd *);
|
||||
extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *);
|
||||
extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);
|
||||
extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *,
|
||||
@@ -644,9 +647,6 @@ extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *, size_t);
|
||||
extern int qla2x00_chk_ms_status(scsi_qla_host_t *, ms_iocb_entry_t *,
|
||||
struct ct_sns_rsp *, const char *);
|
||||
extern void qla2x00_async_iocb_timeout(void *data);
|
||||
extern int qla24xx_async_gidpn(scsi_qla_host_t *, fc_port_t *);
|
||||
int qla24xx_post_gidpn_work(struct scsi_qla_host *, fc_port_t *);
|
||||
void qla24xx_handle_gidpn_event(scsi_qla_host_t *, struct event_arg *);
|
||||
|
||||
extern void qla2x00_free_fcport(fc_port_t *);
|
||||
|
||||
@@ -677,6 +677,7 @@ void qla_scan_work_fn(struct work_struct *);
|
||||
*/
|
||||
struct device_attribute;
|
||||
extern struct device_attribute *qla2x00_host_attrs[];
|
||||
extern struct device_attribute *qla2x00_host_attrs_dm[];
|
||||
struct fc_function_template;
|
||||
extern struct fc_function_template qla2xxx_transport_functions;
|
||||
extern struct fc_function_template qla2xxx_transport_vport_functions;
|
||||
@@ -690,7 +691,7 @@ extern int qla2x00_echo_test(scsi_qla_host_t *,
|
||||
extern int qla24xx_update_all_fcp_prio(scsi_qla_host_t *);
|
||||
extern int qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *,
|
||||
struct qla_fcp_prio_cfg *, uint8_t);
|
||||
|
||||
void qla_insert_tgt_attrs(void);
|
||||
/*
|
||||
* Global Function Prototypes in qla_dfs.c source file.
|
||||
*/
|
||||
@@ -897,5 +898,7 @@ void qlt_unknown_atio_work_fn(struct work_struct *);
|
||||
void qlt_update_host_map(struct scsi_qla_host *, port_id_t);
|
||||
void qlt_remove_target_resources(struct qla_hw_data *);
|
||||
void qlt_clr_qp_table(struct scsi_qla_host *vha);
|
||||
void qlt_set_mode(struct scsi_qla_host *);
|
||||
int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode);
|
||||
|
||||
#endif /* _QLA_GBL_H */
|
||||
|
||||
+245
-444
File diff suppressed because it is too large
Load Diff
+720
-504
File diff suppressed because it is too large
Load Diff
@@ -58,14 +58,12 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr)
|
||||
static inline void
|
||||
qla2x00_poll(struct rsp_que *rsp)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct qla_hw_data *ha = rsp->hw;
|
||||
local_irq_save(flags);
|
||||
|
||||
if (IS_P3P_TYPE(ha))
|
||||
qla82xx_poll(0, rsp);
|
||||
else
|
||||
ha->isp_ops->intr_handler(0, rsp);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
static inline uint8_t *
|
||||
@@ -204,8 +202,15 @@ qla2x00_reset_active(scsi_qla_host_t *vha)
|
||||
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 *
|
||||
qla2xxx_get_qpair_sp(struct qla_qpair *qpair, fc_port_t *fcport, gfp_t flag)
|
||||
qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
|
||||
fc_port_t *fcport, gfp_t flag)
|
||||
{
|
||||
srb_t *sp = NULL;
|
||||
uint8_t bail;
|
||||
@@ -221,7 +226,9 @@ qla2xxx_get_qpair_sp(struct qla_qpair *qpair, fc_port_t *fcport, gfp_t flag)
|
||||
memset(sp, 0, sizeof(*sp));
|
||||
sp->fcport = fcport;
|
||||
sp->iocbs = 1;
|
||||
sp->vha = qpair->vha;
|
||||
sp->vha = vha;
|
||||
sp->qpair = qpair;
|
||||
sp->cmd_type = TYPE_SRB;
|
||||
INIT_LIST_HEAD(&sp->elem);
|
||||
|
||||
done:
|
||||
@@ -242,19 +249,17 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
|
||||
{
|
||||
srb_t *sp = NULL;
|
||||
uint8_t bail;
|
||||
struct qla_qpair *qpair;
|
||||
|
||||
QLA_VHA_MARK_BUSY(vha, bail);
|
||||
if (unlikely(bail))
|
||||
return NULL;
|
||||
|
||||
sp = mempool_alloc(vha->hw->srb_mempool, flag);
|
||||
qpair = vha->hw->base_qpair;
|
||||
sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, flag);
|
||||
if (!sp)
|
||||
goto done;
|
||||
|
||||
memset(sp, 0, sizeof(*sp));
|
||||
sp->fcport = fcport;
|
||||
sp->cmd_type = TYPE_SRB;
|
||||
sp->iocbs = 1;
|
||||
sp->vha = vha;
|
||||
done:
|
||||
if (!sp)
|
||||
@@ -266,7 +271,7 @@ static inline void
|
||||
qla2x00_rel_sp(srb_t *sp)
|
||||
{
|
||||
QLA_VHA_MARK_NOT_BUSY(sp->vha);
|
||||
mempool_free(sp, sp->vha->hw->srb_mempool);
|
||||
qla2xxx_rel_qpair_sp(sp->qpair, sp);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -278,8 +283,6 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
|
||||
init_completion(&sp->comp);
|
||||
if (IS_QLAFX00(sp->vha->hw) && (sp->type == SRB_FXIOCB_DCMD))
|
||||
init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
|
||||
if (sp->type == SRB_ELS_DCMD)
|
||||
init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
|
||||
add_timer(&sp->u.iocb_cmd.timer);
|
||||
}
|
||||
|
||||
@@ -315,13 +318,13 @@ static inline bool
|
||||
qla_is_exch_offld_enabled(struct scsi_qla_host *vha)
|
||||
{
|
||||
if (qla_ini_mode_enabled(vha) &&
|
||||
(ql2xiniexchg > FW_DEF_EXCHANGES_CNT))
|
||||
(vha->ql2xiniexchg > FW_DEF_EXCHANGES_CNT))
|
||||
return true;
|
||||
else if (qla_tgt_mode_enabled(vha) &&
|
||||
(ql2xexchoffld > FW_DEF_EXCHANGES_CNT))
|
||||
(vha->ql2xexchoffld > FW_DEF_EXCHANGES_CNT))
|
||||
return true;
|
||||
else if (qla_dual_mode_enabled(vha) &&
|
||||
((ql2xiniexchg + ql2xexchoffld) > FW_DEF_EXCHANGES_CNT))
|
||||
((vha->ql2xiniexchg + vha->ql2xexchoffld) > FW_DEF_EXCHANGES_CNT))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
+410
-166
@@ -336,7 +336,7 @@ qla2x00_start_scsi(srb_t *sp)
|
||||
|
||||
/* Send marker if required */
|
||||
if (vha->marker_needed != 0) {
|
||||
if (qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
|
||||
if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
|
||||
QLA_SUCCESS) {
|
||||
return (QLA_FUNCTION_FAILED);
|
||||
}
|
||||
@@ -490,8 +490,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
|
||||
/**
|
||||
* qla2x00_marker() - Send a marker IOCB to the firmware.
|
||||
* @vha: HA context
|
||||
* @req: request queue
|
||||
* @rsp: response queue
|
||||
* @qpair: queue pair pointer
|
||||
* @loop_id: loop ID
|
||||
* @lun: LUN
|
||||
* @type: marker modifier
|
||||
@@ -501,18 +500,16 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
|
||||
* Returns non-zero if a failure occurred, else zero.
|
||||
*/
|
||||
static int
|
||||
__qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
|
||||
struct rsp_que *rsp, uint16_t loop_id,
|
||||
uint64_t lun, uint8_t type)
|
||||
__qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
|
||||
uint16_t loop_id, uint64_t lun, uint8_t type)
|
||||
{
|
||||
mrk_entry_t *mrk;
|
||||
struct mrk_entry_24xx *mrk24 = NULL;
|
||||
|
||||
struct req_que *req = qpair->req;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||
|
||||
req = ha->req_q_map[0];
|
||||
mrk = (mrk_entry_t *)qla2x00_alloc_iocbs(vha, NULL);
|
||||
mrk = (mrk_entry_t *)__qla2x00_alloc_iocbs(qpair, NULL);
|
||||
if (mrk == NULL) {
|
||||
ql_log(ql_log_warn, base_vha, 0x3026,
|
||||
"Failed to allocate Marker IOCB.\n");
|
||||
@@ -543,16 +540,15 @@ __qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
|
||||
struct rsp_que *rsp, uint16_t loop_id, uint64_t lun,
|
||||
uint8_t type)
|
||||
qla2x00_marker(struct scsi_qla_host *vha, struct qla_qpair *qpair,
|
||||
uint16_t loop_id, uint64_t lun, uint8_t type)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags = 0;
|
||||
|
||||
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
|
||||
ret = __qla2x00_marker(vha, req, rsp, loop_id, lun, type);
|
||||
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
||||
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
||||
ret = __qla2x00_marker(vha, qpair, loop_id, lun, type);
|
||||
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -567,11 +563,11 @@ qla2x00_marker(struct scsi_qla_host *vha, struct req_que *req,
|
||||
int qla2x00_issue_marker(scsi_qla_host_t *vha, int ha_locked)
|
||||
{
|
||||
if (ha_locked) {
|
||||
if (__qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0,
|
||||
if (__qla2x00_marker(vha, vha->hw->base_qpair, 0, 0,
|
||||
MK_SYNC_ALL) != QLA_SUCCESS)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
} else {
|
||||
if (qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0,
|
||||
if (qla2x00_marker(vha, vha->hw->base_qpair, 0, 0,
|
||||
MK_SYNC_ALL) != QLA_SUCCESS)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
@@ -1098,88 +1094,300 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
|
||||
|
||||
int
|
||||
qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
|
||||
uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc)
|
||||
uint32_t *cur_dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc)
|
||||
{
|
||||
void *next_dsd;
|
||||
uint8_t avail_dsds = 0;
|
||||
uint32_t dsd_list_len;
|
||||
struct dsd_dma *dsd_ptr;
|
||||
struct dsd_dma *dsd_ptr = NULL, *dif_dsd, *nxt_dsd;
|
||||
struct scatterlist *sg, *sgl;
|
||||
int i;
|
||||
struct scsi_cmnd *cmd;
|
||||
uint32_t *cur_dsd = dsd;
|
||||
uint16_t used_dsds = tot_dsds;
|
||||
struct crc_context *difctx = NULL;
|
||||
struct scsi_qla_host *vha;
|
||||
uint dsd_list_len;
|
||||
uint avail_dsds = 0;
|
||||
uint used_dsds = tot_dsds;
|
||||
bool dif_local_dma_alloc = false;
|
||||
bool direction_to_device = false;
|
||||
int i;
|
||||
|
||||
if (sp) {
|
||||
cmd = GET_CMD_SP(sp);
|
||||
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
||||
sgl = scsi_prot_sglist(cmd);
|
||||
vha = sp->vha;
|
||||
difctx = sp->u.scmd.ctx;
|
||||
direction_to_device = cmd->sc_data_direction == DMA_TO_DEVICE;
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe021,
|
||||
"%s: scsi_cmnd: %p, crc_ctx: %p, sp: %p\n",
|
||||
__func__, cmd, difctx, sp);
|
||||
} else if (tc) {
|
||||
vha = tc->vha;
|
||||
sgl = tc->prot_sg;
|
||||
difctx = tc->ctx;
|
||||
direction_to_device = tc->dma_data_direction == DMA_TO_DEVICE;
|
||||
} else {
|
||||
BUG();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe021,
|
||||
"%s: enter\n", __func__);
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe021,
|
||||
"%s: enter (write=%u)\n", __func__, direction_to_device);
|
||||
|
||||
for_each_sg(sgl, sg, tot_dsds, i) {
|
||||
dma_addr_t sle_dma;
|
||||
/* if initiator doing write or target doing read */
|
||||
if (direction_to_device) {
|
||||
for_each_sg(sgl, sg, tot_dsds, i) {
|
||||
u64 sle_phys = sg_phys(sg);
|
||||
|
||||
/* Allocate additional continuation packets? */
|
||||
if (avail_dsds == 0) {
|
||||
avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
|
||||
QLA_DSDS_PER_IOCB : used_dsds;
|
||||
dsd_list_len = (avail_dsds + 1) * 12;
|
||||
used_dsds -= avail_dsds;
|
||||
/* If SGE addr + len flips bits in upper 32-bits */
|
||||
if (MSD(sle_phys + sg->length) ^ MSD(sle_phys)) {
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe022,
|
||||
"%s: page boundary crossing (phys=%llx len=%x)\n",
|
||||
__func__, sle_phys, sg->length);
|
||||
|
||||
/* allocate tracking DS */
|
||||
dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC);
|
||||
if (!dsd_ptr)
|
||||
return 1;
|
||||
|
||||
/* allocate new list */
|
||||
dsd_ptr->dsd_addr = next_dsd =
|
||||
dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
|
||||
&dsd_ptr->dsd_list_dma);
|
||||
|
||||
if (!next_dsd) {
|
||||
/*
|
||||
* Need to cleanup only this dsd_ptr, rest
|
||||
* will be done by sp_free_dma()
|
||||
*/
|
||||
kfree(dsd_ptr);
|
||||
return 1;
|
||||
if (difctx) {
|
||||
ha->dif_bundle_crossed_pages++;
|
||||
dif_local_dma_alloc = true;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose,
|
||||
vha, 0xe022,
|
||||
"%s: difctx pointer is NULL\n",
|
||||
__func__);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sp) {
|
||||
list_add_tail(&dsd_ptr->list,
|
||||
&((struct crc_context *)
|
||||
sp->u.scmd.ctx)->dsd_list);
|
||||
|
||||
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
||||
} else {
|
||||
list_add_tail(&dsd_ptr->list,
|
||||
&(tc->ctx->dsd_list));
|
||||
*tc->ctx_dsd_alloced = 1;
|
||||
}
|
||||
|
||||
/* add new list to cmd iocb or last list */
|
||||
*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
||||
*cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
|
||||
*cur_dsd++ = dsd_list_len;
|
||||
cur_dsd = (uint32_t *)next_dsd;
|
||||
}
|
||||
sle_dma = sg_dma_address(sg);
|
||||
ha->dif_bundle_writes++;
|
||||
} else {
|
||||
ha->dif_bundle_reads++;
|
||||
}
|
||||
|
||||
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
|
||||
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
|
||||
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
|
||||
if (ql2xdifbundlinginternalbuffers)
|
||||
dif_local_dma_alloc = direction_to_device;
|
||||
|
||||
avail_dsds--;
|
||||
if (dif_local_dma_alloc) {
|
||||
u32 track_difbundl_buf = 0;
|
||||
u32 ldma_sg_len = 0;
|
||||
u8 ldma_needed = 1;
|
||||
|
||||
difctx->no_dif_bundl = 0;
|
||||
difctx->dif_bundl_len = 0;
|
||||
|
||||
/* Track DSD buffers */
|
||||
INIT_LIST_HEAD(&difctx->ldif_dsd_list);
|
||||
/* Track local DMA buffers */
|
||||
INIT_LIST_HEAD(&difctx->ldif_dma_hndl_list);
|
||||
|
||||
for_each_sg(sgl, sg, tot_dsds, i) {
|
||||
u32 sglen = sg_dma_len(sg);
|
||||
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe023,
|
||||
"%s: sg[%x] (phys=%llx sglen=%x) ldma_sg_len: %x dif_bundl_len: %x ldma_needed: %x\n",
|
||||
__func__, i, (u64)sg_phys(sg), sglen, ldma_sg_len,
|
||||
difctx->dif_bundl_len, ldma_needed);
|
||||
|
||||
while (sglen) {
|
||||
u32 xfrlen = 0;
|
||||
|
||||
if (ldma_needed) {
|
||||
/*
|
||||
* Allocate list item to store
|
||||
* the DMA buffers
|
||||
*/
|
||||
dsd_ptr = kzalloc(sizeof(*dsd_ptr),
|
||||
GFP_ATOMIC);
|
||||
if (!dsd_ptr) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe024,
|
||||
"%s: failed alloc dsd_ptr\n",
|
||||
__func__);
|
||||
return 1;
|
||||
}
|
||||
ha->dif_bundle_kallocs++;
|
||||
|
||||
/* allocate dma buffer */
|
||||
dsd_ptr->dsd_addr = dma_pool_alloc
|
||||
(ha->dif_bundl_pool, GFP_ATOMIC,
|
||||
&dsd_ptr->dsd_list_dma);
|
||||
if (!dsd_ptr->dsd_addr) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe024,
|
||||
"%s: failed alloc ->dsd_ptr\n",
|
||||
__func__);
|
||||
/*
|
||||
* need to cleanup only this
|
||||
* dsd_ptr rest will be done
|
||||
* by sp_free_dma()
|
||||
*/
|
||||
kfree(dsd_ptr);
|
||||
ha->dif_bundle_kallocs--;
|
||||
return 1;
|
||||
}
|
||||
ha->dif_bundle_dma_allocs++;
|
||||
ldma_needed = 0;
|
||||
difctx->no_dif_bundl++;
|
||||
list_add_tail(&dsd_ptr->list,
|
||||
&difctx->ldif_dma_hndl_list);
|
||||
}
|
||||
|
||||
/* xfrlen is min of dma pool size and sglen */
|
||||
xfrlen = (sglen >
|
||||
(DIF_BUNDLING_DMA_POOL_SIZE - ldma_sg_len)) ?
|
||||
DIF_BUNDLING_DMA_POOL_SIZE - ldma_sg_len :
|
||||
sglen;
|
||||
|
||||
/* replace with local allocated dma buffer */
|
||||
sg_pcopy_to_buffer(sgl, sg_nents(sgl),
|
||||
dsd_ptr->dsd_addr + ldma_sg_len, xfrlen,
|
||||
difctx->dif_bundl_len);
|
||||
difctx->dif_bundl_len += xfrlen;
|
||||
sglen -= xfrlen;
|
||||
ldma_sg_len += xfrlen;
|
||||
if (ldma_sg_len == DIF_BUNDLING_DMA_POOL_SIZE ||
|
||||
sg_is_last(sg)) {
|
||||
ldma_needed = 1;
|
||||
ldma_sg_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
track_difbundl_buf = used_dsds = difctx->no_dif_bundl;
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe025,
|
||||
"dif_bundl_len=%x, no_dif_bundl=%x track_difbundl_buf: %x\n",
|
||||
difctx->dif_bundl_len, difctx->no_dif_bundl,
|
||||
track_difbundl_buf);
|
||||
|
||||
if (sp)
|
||||
sp->flags |= SRB_DIF_BUNDL_DMA_VALID;
|
||||
else
|
||||
tc->prot_flags = DIF_BUNDL_DMA_VALID;
|
||||
|
||||
list_for_each_entry_safe(dif_dsd, nxt_dsd,
|
||||
&difctx->ldif_dma_hndl_list, list) {
|
||||
u32 sglen = (difctx->dif_bundl_len >
|
||||
DIF_BUNDLING_DMA_POOL_SIZE) ?
|
||||
DIF_BUNDLING_DMA_POOL_SIZE : difctx->dif_bundl_len;
|
||||
|
||||
BUG_ON(track_difbundl_buf == 0);
|
||||
|
||||
/* Allocate additional continuation packets? */
|
||||
if (avail_dsds == 0) {
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha,
|
||||
0xe024,
|
||||
"%s: adding continuation iocb's\n",
|
||||
__func__);
|
||||
avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
|
||||
QLA_DSDS_PER_IOCB : used_dsds;
|
||||
dsd_list_len = (avail_dsds + 1) * 12;
|
||||
used_dsds -= avail_dsds;
|
||||
|
||||
/* allocate tracking DS */
|
||||
dsd_ptr = kzalloc(sizeof(*dsd_ptr), GFP_ATOMIC);
|
||||
if (!dsd_ptr) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe026,
|
||||
"%s: failed alloc dsd_ptr\n",
|
||||
__func__);
|
||||
return 1;
|
||||
}
|
||||
ha->dif_bundle_kallocs++;
|
||||
|
||||
difctx->no_ldif_dsd++;
|
||||
/* allocate new list */
|
||||
dsd_ptr->dsd_addr =
|
||||
dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
|
||||
&dsd_ptr->dsd_list_dma);
|
||||
if (!dsd_ptr->dsd_addr) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe026,
|
||||
"%s: failed alloc ->dsd_addr\n",
|
||||
__func__);
|
||||
/*
|
||||
* need to cleanup only this dsd_ptr
|
||||
* rest will be done by sp_free_dma()
|
||||
*/
|
||||
kfree(dsd_ptr);
|
||||
ha->dif_bundle_kallocs--;
|
||||
return 1;
|
||||
}
|
||||
ha->dif_bundle_dma_allocs++;
|
||||
|
||||
if (sp) {
|
||||
list_add_tail(&dsd_ptr->list,
|
||||
&difctx->ldif_dsd_list);
|
||||
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
||||
} else {
|
||||
list_add_tail(&dsd_ptr->list,
|
||||
&difctx->ldif_dsd_list);
|
||||
tc->ctx_dsd_alloced = 1;
|
||||
}
|
||||
|
||||
/* add new list to cmd iocb or last list */
|
||||
*cur_dsd++ =
|
||||
cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
||||
*cur_dsd++ =
|
||||
cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
|
||||
*cur_dsd++ = dsd_list_len;
|
||||
cur_dsd = dsd_ptr->dsd_addr;
|
||||
}
|
||||
*cur_dsd++ = cpu_to_le32(LSD(dif_dsd->dsd_list_dma));
|
||||
*cur_dsd++ = cpu_to_le32(MSD(dif_dsd->dsd_list_dma));
|
||||
*cur_dsd++ = cpu_to_le32(sglen);
|
||||
avail_dsds--;
|
||||
difctx->dif_bundl_len -= sglen;
|
||||
track_difbundl_buf--;
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe026,
|
||||
"%s: no_ldif_dsd:%x, no_dif_bundl:%x\n", __func__,
|
||||
difctx->no_ldif_dsd, difctx->no_dif_bundl);
|
||||
} else {
|
||||
for_each_sg(sgl, sg, tot_dsds, i) {
|
||||
dma_addr_t sle_dma;
|
||||
|
||||
/* Allocate additional continuation packets? */
|
||||
if (avail_dsds == 0) {
|
||||
avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ?
|
||||
QLA_DSDS_PER_IOCB : used_dsds;
|
||||
dsd_list_len = (avail_dsds + 1) * 12;
|
||||
used_dsds -= avail_dsds;
|
||||
|
||||
/* allocate tracking DS */
|
||||
dsd_ptr = kzalloc(sizeof(*dsd_ptr), GFP_ATOMIC);
|
||||
if (!dsd_ptr) {
|
||||
ql_dbg(ql_dbg_tgt + ql_dbg_verbose,
|
||||
vha, 0xe027,
|
||||
"%s: failed alloc dsd_dma...\n",
|
||||
__func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* allocate new list */
|
||||
dsd_ptr->dsd_addr =
|
||||
dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC,
|
||||
&dsd_ptr->dsd_list_dma);
|
||||
if (!dsd_ptr->dsd_addr) {
|
||||
/* need to cleanup only this dsd_ptr */
|
||||
/* rest will be done by sp_free_dma() */
|
||||
kfree(dsd_ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sp) {
|
||||
list_add_tail(&dsd_ptr->list,
|
||||
&difctx->dsd_list);
|
||||
sp->flags |= SRB_CRC_CTX_DSD_VALID;
|
||||
} else {
|
||||
list_add_tail(&dsd_ptr->list,
|
||||
&difctx->dsd_list);
|
||||
tc->ctx_dsd_alloced = 1;
|
||||
}
|
||||
|
||||
/* add new list to cmd iocb or last list */
|
||||
*cur_dsd++ =
|
||||
cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
|
||||
*cur_dsd++ =
|
||||
cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
|
||||
*cur_dsd++ = dsd_list_len;
|
||||
cur_dsd = dsd_ptr->dsd_addr;
|
||||
}
|
||||
sle_dma = sg_dma_address(sg);
|
||||
*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
|
||||
*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
|
||||
*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
|
||||
avail_dsds--;
|
||||
}
|
||||
}
|
||||
/* Null termination */
|
||||
*cur_dsd++ = 0;
|
||||
@@ -1187,7 +1395,6 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
|
||||
*cur_dsd++ = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla24xx_build_scsi_crc_2_iocbs() - Build IOCB command utilizing Command
|
||||
* Type 6 IOCB types.
|
||||
@@ -1195,8 +1402,8 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
|
||||
* @sp: SRB command to process
|
||||
* @cmd_pkt: Command type 3 IOCB
|
||||
* @tot_dsds: Total number of segments to transfer
|
||||
* @tot_prot_dsds:
|
||||
* @fw_prot_opts:
|
||||
* @tot_prot_dsds: Total number of segments with protection information
|
||||
* @fw_prot_opts: Protection options to be passed to firmware
|
||||
*/
|
||||
inline int
|
||||
qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
|
||||
@@ -1416,21 +1623,19 @@ qla24xx_start_scsi(srb_t *sp)
|
||||
uint16_t req_cnt;
|
||||
uint16_t tot_dsds;
|
||||
struct req_que *req = NULL;
|
||||
struct rsp_que *rsp = NULL;
|
||||
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
||||
struct scsi_qla_host *vha = sp->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
/* Setup device pointers. */
|
||||
req = vha->req;
|
||||
rsp = req->rsp;
|
||||
|
||||
/* So we know we haven't pci_map'ed anything yet */
|
||||
tot_dsds = 0;
|
||||
|
||||
/* Send marker if required */
|
||||
if (vha->marker_needed != 0) {
|
||||
if (qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
|
||||
if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
|
||||
QLA_SUCCESS)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
vha->marker_needed = 0;
|
||||
@@ -1583,7 +1788,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
|
||||
|
||||
/* Send marker if required */
|
||||
if (vha->marker_needed != 0) {
|
||||
if (qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
|
||||
if (qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL) !=
|
||||
QLA_SUCCESS)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
vha->marker_needed = 0;
|
||||
@@ -1754,7 +1959,6 @@ qla2xxx_start_scsi_mq(srb_t *sp)
|
||||
uint16_t req_cnt;
|
||||
uint16_t tot_dsds;
|
||||
struct req_que *req = NULL;
|
||||
struct rsp_que *rsp = NULL;
|
||||
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
|
||||
struct scsi_qla_host *vha = sp->fcport->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
@@ -1764,7 +1968,6 @@ qla2xxx_start_scsi_mq(srb_t *sp)
|
||||
spin_lock_irqsave(&qpair->qp_lock, flags);
|
||||
|
||||
/* Setup qpair pointers */
|
||||
rsp = qpair->rsp;
|
||||
req = qpair->req;
|
||||
|
||||
/* So we know we haven't pci_map'ed anything yet */
|
||||
@@ -1772,7 +1975,7 @@ qla2xxx_start_scsi_mq(srb_t *sp)
|
||||
|
||||
/* Send marker if required */
|
||||
if (vha->marker_needed != 0) {
|
||||
if (__qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
|
||||
if (__qla2x00_marker(vha, qpair, 0, 0, MK_SYNC_ALL) !=
|
||||
QLA_SUCCESS) {
|
||||
spin_unlock_irqrestore(&qpair->qp_lock, flags);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
@@ -1940,7 +2143,7 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
|
||||
|
||||
/* Send marker if required */
|
||||
if (vha->marker_needed != 0) {
|
||||
if (__qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL) !=
|
||||
if (__qla2x00_marker(vha, qpair, 0, 0, MK_SYNC_ALL) !=
|
||||
QLA_SUCCESS) {
|
||||
spin_unlock_irqrestore(&qpair->qp_lock, flags);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
@@ -2208,8 +2411,11 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio)
|
||||
|
||||
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
|
||||
logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
|
||||
if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI)
|
||||
if (lio->u.logio.flags & SRB_LOGIN_NVME_PRLI) {
|
||||
logio->control_flags |= LCF_NVME_PRLI;
|
||||
if (sp->vha->flags.nvme_first_burst)
|
||||
logio->io_parameter[0] = NVME_PRLI_SP_FIRST_BURST;
|
||||
}
|
||||
|
||||
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
logio->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
@@ -2224,12 +2430,15 @@ qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
|
||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
||||
|
||||
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
|
||||
logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
|
||||
|
||||
if (lio->u.logio.flags & SRB_LOGIN_COND_PLOGI)
|
||||
logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
|
||||
if (lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI)
|
||||
logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
|
||||
if (lio->u.logio.flags & SRB_LOGIN_PRLI_ONLY) {
|
||||
logio->control_flags = cpu_to_le16(LCF_COMMAND_PRLI);
|
||||
} else {
|
||||
logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
|
||||
if (lio->u.logio.flags & SRB_LOGIN_COND_PLOGI)
|
||||
logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
|
||||
if (lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI)
|
||||
logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
|
||||
}
|
||||
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
logio->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
logio->port_id[1] = sp->fcport->d_id.b.area;
|
||||
@@ -2267,8 +2476,7 @@ qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
|
||||
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
|
||||
logio->control_flags =
|
||||
cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
|
||||
if (!sp->fcport->se_sess ||
|
||||
!sp->fcport->keep_nport_handle)
|
||||
if (!sp->fcport->keep_nport_handle)
|
||||
logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT);
|
||||
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
logio->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
@@ -2446,6 +2654,7 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
sp->fcport = fcport;
|
||||
elsio->timeout = qla2x00_els_dcmd_iocb_timeout;
|
||||
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
|
||||
init_completion(&sp->u.iocb_cmd.u.els_logo.comp);
|
||||
sp->done = qla2x00_els_dcmd_sp_done;
|
||||
sp->free = qla2x00_els_dcmd_sp_free;
|
||||
|
||||
@@ -2493,7 +2702,6 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
{
|
||||
scsi_qla_host_t *vha = sp->vha;
|
||||
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
||||
uint32_t dsd_len = 24;
|
||||
|
||||
els_iocb->entry_type = ELS_IOCB_TYPE;
|
||||
els_iocb->entry_count = 1;
|
||||
@@ -2516,20 +2724,21 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
els_iocb->control_flags = 0;
|
||||
|
||||
if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) {
|
||||
els_iocb->tx_byte_count = sizeof(struct els_plogi_payload);
|
||||
els_iocb->tx_byte_count = els_iocb->tx_len =
|
||||
sizeof(struct els_plogi_payload);
|
||||
els_iocb->tx_address[0] =
|
||||
cpu_to_le32(LSD(elsio->u.els_plogi.els_plogi_pyld_dma));
|
||||
els_iocb->tx_address[1] =
|
||||
cpu_to_le32(MSD(elsio->u.els_plogi.els_plogi_pyld_dma));
|
||||
els_iocb->tx_len = dsd_len;
|
||||
|
||||
els_iocb->rx_dsd_count = 1;
|
||||
els_iocb->rx_byte_count = sizeof(struct els_plogi_payload);
|
||||
els_iocb->rx_byte_count = els_iocb->rx_len =
|
||||
sizeof(struct els_plogi_payload);
|
||||
els_iocb->rx_address[0] =
|
||||
cpu_to_le32(LSD(elsio->u.els_plogi.els_resp_pyld_dma));
|
||||
els_iocb->rx_address[1] =
|
||||
cpu_to_le32(MSD(elsio->u.els_plogi.els_resp_pyld_dma));
|
||||
els_iocb->rx_len = dsd_len;
|
||||
|
||||
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073,
|
||||
"PLOGI ELS IOCB:\n");
|
||||
ql_dump_buffer(ql_log_info, vha, 0x0109,
|
||||
@@ -2551,26 +2760,6 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
|
||||
sp->vha->qla_stats.control_requests++;
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_els_dcmd2_sp_free(void *data)
|
||||
{
|
||||
srb_t *sp = data;
|
||||
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
||||
|
||||
if (elsio->u.els_plogi.els_plogi_pyld)
|
||||
dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE,
|
||||
elsio->u.els_plogi.els_plogi_pyld,
|
||||
elsio->u.els_plogi.els_plogi_pyld_dma);
|
||||
|
||||
if (elsio->u.els_plogi.els_resp_pyld)
|
||||
dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE,
|
||||
elsio->u.els_plogi.els_resp_pyld,
|
||||
elsio->u.els_plogi.els_resp_pyld_dma);
|
||||
|
||||
del_timer(&elsio->timer);
|
||||
qla2x00_rel_sp(sp);
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_els_dcmd2_iocb_timeout(void *data)
|
||||
{
|
||||
@@ -2578,7 +2767,6 @@ qla2x00_els_dcmd2_iocb_timeout(void *data)
|
||||
fc_port_t *fcport = sp->fcport;
|
||||
struct scsi_qla_host *vha = sp->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
||||
unsigned long flags = 0;
|
||||
int res;
|
||||
|
||||
@@ -2594,7 +2782,7 @@ qla2x00_els_dcmd2_iocb_timeout(void *data)
|
||||
(res == QLA_SUCCESS) ? "successful" : "failed");
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
complete(&lio->u.els_plogi.comp);
|
||||
sp->done(sp, QLA_FUNCTION_TIMEOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2604,24 +2792,61 @@ qla2x00_els_dcmd2_sp_done(void *ptr, int res)
|
||||
fc_port_t *fcport = sp->fcport;
|
||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
||||
struct scsi_qla_host *vha = sp->vha;
|
||||
struct event_arg ea;
|
||||
struct qla_work_evt *e;
|
||||
|
||||
ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3072,
|
||||
"%s ELS hdl=%x, portid=%06x done %8phC\n",
|
||||
sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
|
||||
ql_dbg(ql_dbg_disc, vha, 0x3072,
|
||||
"%s ELS done rc %d hdl=%x, portid=%06x %8phC\n",
|
||||
sp->name, res, sp->handle, fcport->d_id.b24, fcport->port_name);
|
||||
|
||||
complete(&lio->u.els_plogi.comp);
|
||||
fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
|
||||
del_timer(&sp->u.iocb_cmd.timer);
|
||||
|
||||
if (sp->flags & SRB_WAKEUP_ON_COMP)
|
||||
complete(&lio->u.els_plogi.comp);
|
||||
else {
|
||||
if (res) {
|
||||
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
|
||||
} else {
|
||||
memset(&ea, 0, sizeof(ea));
|
||||
ea.fcport = fcport;
|
||||
ea.rc = res;
|
||||
ea.event = FCME_ELS_PLOGI_DONE;
|
||||
qla2x00_fcport_event_handler(vha, &ea);
|
||||
}
|
||||
|
||||
e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
|
||||
if (!e) {
|
||||
struct srb_iocb *elsio = &sp->u.iocb_cmd;
|
||||
|
||||
if (elsio->u.els_plogi.els_plogi_pyld)
|
||||
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||
elsio->u.els_plogi.tx_size,
|
||||
elsio->u.els_plogi.els_plogi_pyld,
|
||||
elsio->u.els_plogi.els_plogi_pyld_dma);
|
||||
|
||||
if (elsio->u.els_plogi.els_resp_pyld)
|
||||
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||
elsio->u.els_plogi.rx_size,
|
||||
elsio->u.els_plogi.els_resp_pyld,
|
||||
elsio->u.els_plogi.els_resp_pyld_dma);
|
||||
sp->free(sp);
|
||||
return;
|
||||
}
|
||||
e->u.iosb.sp = sp;
|
||||
qla2x00_post_work(vha, e);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
fc_port_t *fcport, port_id_t remote_did)
|
||||
fc_port_t *fcport, bool wait)
|
||||
{
|
||||
srb_t *sp;
|
||||
struct srb_iocb *elsio = NULL;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
int rval = QLA_SUCCESS;
|
||||
void *ptr, *resp_ptr;
|
||||
dma_addr_t ptr_dma;
|
||||
|
||||
/* Alloc SRB structure */
|
||||
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
|
||||
@@ -2632,10 +2857,6 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
}
|
||||
|
||||
elsio = &sp->u.iocb_cmd;
|
||||
fcport->d_id.b.domain = remote_did.b.domain;
|
||||
fcport->d_id.b.area = remote_did.b.area;
|
||||
fcport->d_id.b.al_pa = remote_did.b.al_pa;
|
||||
|
||||
ql_dbg(ql_dbg_io, vha, 0x3073,
|
||||
"Enter: PLOGI portid=%06x\n", fcport->d_id.b24);
|
||||
|
||||
@@ -2646,15 +2867,17 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
|
||||
elsio->timeout = qla2x00_els_dcmd2_iocb_timeout;
|
||||
init_completion(&elsio->u.els_plogi.comp);
|
||||
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT);
|
||||
if (wait)
|
||||
sp->flags = SRB_WAKEUP_ON_COMP;
|
||||
|
||||
qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT + 2);
|
||||
|
||||
sp->done = qla2x00_els_dcmd2_sp_done;
|
||||
sp->free = qla2x00_els_dcmd2_sp_free;
|
||||
elsio->u.els_plogi.tx_size = elsio->u.els_plogi.rx_size = DMA_POOL_SIZE;
|
||||
|
||||
ptr = elsio->u.els_plogi.els_plogi_pyld =
|
||||
dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE,
|
||||
&elsio->u.els_plogi.els_plogi_pyld_dma, GFP_KERNEL);
|
||||
ptr_dma = elsio->u.els_plogi.els_plogi_pyld_dma;
|
||||
|
||||
if (!elsio->u.els_plogi.els_plogi_pyld) {
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
@@ -2674,33 +2897,52 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode,
|
||||
|
||||
memset(ptr, 0, sizeof(struct els_plogi_payload));
|
||||
memset(resp_ptr, 0, sizeof(struct els_plogi_payload));
|
||||
memcpy(elsio->u.els_plogi.els_plogi_pyld->data,
|
||||
&ha->plogi_els_payld.data,
|
||||
sizeof(elsio->u.els_plogi.els_plogi_pyld->data));
|
||||
|
||||
elsio->u.els_plogi.els_cmd = els_opcode;
|
||||
elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode;
|
||||
qla24xx_get_port_login_templ(vha, ptr_dma + 4,
|
||||
&elsio->u.els_plogi.els_plogi_pyld->data[0],
|
||||
sizeof(struct els_plogi_payload));
|
||||
|
||||
ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
|
||||
ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x0109,
|
||||
ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n");
|
||||
ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109,
|
||||
(uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70);
|
||||
|
||||
rval = qla2x00_start_sp(sp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
goto out;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_disc, vha, 0x3074,
|
||||
"%s PLOGI sent, hdl=%x, loopid=%x, to port_id %06x from port_id %06x\n",
|
||||
sp->name, sp->handle, fcport->loop_id,
|
||||
fcport->d_id.b24, vha->d_id.b24);
|
||||
}
|
||||
|
||||
ql_dbg(ql_dbg_io, vha, 0x3074,
|
||||
"%s PLOGI sent, hdl=%x, loopid=%x, portid=%06x\n",
|
||||
sp->name, sp->handle, fcport->loop_id, fcport->d_id.b24);
|
||||
if (wait) {
|
||||
wait_for_completion(&elsio->u.els_plogi.comp);
|
||||
|
||||
wait_for_completion(&elsio->u.els_plogi.comp);
|
||||
|
||||
if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
if (elsio->u.els_plogi.comp_status != CS_COMPLETE)
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
} else {
|
||||
goto done;
|
||||
}
|
||||
|
||||
out:
|
||||
fcport->flags &= ~(FCF_ASYNC_SENT);
|
||||
if (elsio->u.els_plogi.els_plogi_pyld)
|
||||
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||
elsio->u.els_plogi.tx_size,
|
||||
elsio->u.els_plogi.els_plogi_pyld,
|
||||
elsio->u.els_plogi.els_plogi_pyld_dma);
|
||||
|
||||
if (elsio->u.els_plogi.els_resp_pyld)
|
||||
dma_free_coherent(&sp->vha->hw->pdev->dev,
|
||||
elsio->u.els_plogi.rx_size,
|
||||
elsio->u.els_plogi.els_resp_pyld,
|
||||
elsio->u.els_plogi.els_resp_pyld_dma);
|
||||
|
||||
sp->free(sp);
|
||||
done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
@@ -2955,8 +3197,8 @@ qla82xx_start_scsi(srb_t *sp)
|
||||
|
||||
/* Send marker if required */
|
||||
if (vha->marker_needed != 0) {
|
||||
if (qla2x00_marker(vha, req,
|
||||
rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS) {
|
||||
if (qla2x00_marker(vha, ha->base_qpair,
|
||||
0, 0, MK_SYNC_ALL) != QLA_SUCCESS) {
|
||||
ql_log(ql_log_warn, vha, 0x300c,
|
||||
"qla2x00_marker failed for cmd=%p.\n", cmd);
|
||||
return QLA_FUNCTION_FAILED;
|
||||
@@ -3258,19 +3500,21 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb)
|
||||
{
|
||||
struct srb_iocb *aio = &sp->u.iocb_cmd;
|
||||
scsi_qla_host_t *vha = sp->vha;
|
||||
struct req_que *req = vha->req;
|
||||
struct req_que *req = sp->qpair->req;
|
||||
|
||||
memset(abt_iocb, 0, sizeof(struct abort_entry_24xx));
|
||||
abt_iocb->entry_type = ABORT_IOCB_TYPE;
|
||||
abt_iocb->entry_count = 1;
|
||||
abt_iocb->handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle));
|
||||
abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
if (sp->fcport) {
|
||||
abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
abt_iocb->port_id[1] = sp->fcport->d_id.b.area;
|
||||
abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
|
||||
}
|
||||
abt_iocb->handle_to_abort =
|
||||
cpu_to_le32(MAKE_HANDLE(aio->u.abt.req_que_no,
|
||||
aio->u.abt.cmd_hndl));
|
||||
abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
abt_iocb->port_id[1] = sp->fcport->d_id.b.area;
|
||||
abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
|
||||
abt_iocb->vp_index = vha->vp_idx;
|
||||
abt_iocb->req_que_no = cpu_to_le16(aio->u.abt.req_que_no);
|
||||
/* Send the command to the firmware */
|
||||
@@ -3396,22 +3640,22 @@ qla24xx_prlo_iocb(srb_t *sp, struct logio_entry_24xx *logio)
|
||||
int
|
||||
qla2x00_start_sp(srb_t *sp)
|
||||
{
|
||||
int rval;
|
||||
int rval = QLA_SUCCESS;
|
||||
scsi_qla_host_t *vha = sp->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct qla_qpair *qp = sp->qpair;
|
||||
void *pkt;
|
||||
unsigned long flags;
|
||||
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
pkt = qla2x00_alloc_iocbs(vha, sp);
|
||||
spin_lock_irqsave(qp->qp_lock_ptr, flags);
|
||||
pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
|
||||
if (!pkt) {
|
||||
rval = EAGAIN;
|
||||
ql_log(ql_log_warn, vha, 0x700c,
|
||||
"qla2x00_alloc_iocbs failed.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
rval = QLA_SUCCESS;
|
||||
switch (sp->type) {
|
||||
case SRB_LOGIN_CMD:
|
||||
IS_FWI2_CAPABLE(ha) ?
|
||||
@@ -3482,9 +3726,9 @@ qla2x00_start_sp(srb_t *sp)
|
||||
}
|
||||
|
||||
wmb();
|
||||
qla2x00_start_iocbs(vha, ha->req_q_map[0]);
|
||||
qla2x00_start_iocbs(vha, qp->req);
|
||||
done:
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
|
||||
return rval;
|
||||
}
|
||||
|
||||
@@ -3607,8 +3851,8 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
|
||||
|
||||
/* Send marker if required */
|
||||
if (vha->marker_needed != 0) {
|
||||
if (qla2x00_marker(vha, req,
|
||||
rsp, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS)
|
||||
if (qla2x00_marker(vha, ha->base_qpair,
|
||||
0, 0, MK_SYNC_ALL) != QLA_SUCCESS)
|
||||
return EXT_STATUS_MAILBOX;
|
||||
vha->marker_needed = 0;
|
||||
}
|
||||
|
||||
+73
-46
@@ -25,7 +25,7 @@ static int qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
|
||||
|
||||
/**
|
||||
* qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
|
||||
* @irq:
|
||||
* @irq: interrupt number
|
||||
* @dev_id: SCSI driver HA context
|
||||
*
|
||||
* Called by system whenever the host adapter generates an interrupt.
|
||||
@@ -144,7 +144,7 @@ qla2x00_check_reg16_for_disconnect(scsi_qla_host_t *vha, uint16_t reg)
|
||||
|
||||
/**
|
||||
* qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
|
||||
* @irq:
|
||||
* @irq: interrupt number
|
||||
* @dev_id: SCSI driver HA context
|
||||
*
|
||||
* Called by system whenever the host adapter generates an interrupt.
|
||||
@@ -834,7 +834,8 @@ skip_rio:
|
||||
* Restore for Physical Port only
|
||||
*/
|
||||
if (!vha->vp_idx) {
|
||||
if (ha->flags.fawwpn_enabled) {
|
||||
if (ha->flags.fawwpn_enabled &&
|
||||
(ha->current_topology == ISP_CFG_F)) {
|
||||
void *wwpn = ha->init_cb->port_name;
|
||||
memcpy(vha->port_name, wwpn, WWN_SIZE);
|
||||
fc_host_port_name(vha->host) =
|
||||
@@ -911,7 +912,8 @@ skip_rio:
|
||||
if (!atomic_read(&vha->loop_down_timer))
|
||||
atomic_set(&vha->loop_down_timer,
|
||||
LOOP_DOWN_TIME);
|
||||
qla2x00_mark_all_devices_lost(vha, 1);
|
||||
if (!N2N_TOPO(ha))
|
||||
qla2x00_mark_all_devices_lost(vha, 1);
|
||||
}
|
||||
|
||||
if (vha->vp_idx) {
|
||||
@@ -1713,6 +1715,15 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
|
||||
vha->hw->exch_starvation = 0;
|
||||
data[0] = MBS_COMMAND_COMPLETE;
|
||||
|
||||
if (sp->type == SRB_PRLI_CMD) {
|
||||
lio->u.logio.iop[0] =
|
||||
le32_to_cpu(logio->io_parameter[0]);
|
||||
lio->u.logio.iop[1] =
|
||||
le32_to_cpu(logio->io_parameter[1]);
|
||||
goto logio_done;
|
||||
}
|
||||
|
||||
if (sp->type != SRB_LOGIN_CMD)
|
||||
goto logio_done;
|
||||
|
||||
@@ -1849,11 +1860,12 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
|
||||
uint16_t state_flags;
|
||||
struct nvmefc_fcp_req *fd;
|
||||
uint16_t ret = 0;
|
||||
uint16_t ret = QLA_SUCCESS;
|
||||
uint16_t comp_status = le16_to_cpu(sts->comp_status);
|
||||
|
||||
iocb = &sp->u.iocb_cmd;
|
||||
fcport = sp->fcport;
|
||||
iocb->u.nvme.comp_status = le16_to_cpu(sts->comp_status);
|
||||
iocb->u.nvme.comp_status = comp_status;
|
||||
state_flags = le16_to_cpu(sts->state_flags);
|
||||
fd = iocb->u.nvme.desc;
|
||||
|
||||
@@ -1891,28 +1903,35 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
fd->transferred_length = fd->payload_length -
|
||||
le32_to_cpu(sts->residual_len);
|
||||
|
||||
switch (le16_to_cpu(sts->comp_status)) {
|
||||
if (unlikely(comp_status != CS_COMPLETE))
|
||||
ql_log(ql_log_warn, fcport->vha, 0x5060,
|
||||
"NVME-%s ERR Handling - hdl=%x status(%x) tr_len:%x resid=%x ox_id=%x\n",
|
||||
sp->name, sp->handle, comp_status,
|
||||
fd->transferred_length, le32_to_cpu(sts->residual_len),
|
||||
sts->ox_id);
|
||||
|
||||
/*
|
||||
* If transport error then Failure (HBA rejects request)
|
||||
* otherwise transport will handle.
|
||||
*/
|
||||
switch (comp_status) {
|
||||
case CS_COMPLETE:
|
||||
ret = QLA_SUCCESS;
|
||||
break;
|
||||
case CS_ABORTED:
|
||||
|
||||
case CS_RESET:
|
||||
case CS_PORT_UNAVAILABLE:
|
||||
case CS_PORT_LOGGED_OUT:
|
||||
fcport->nvme_flag |= NVME_FLAG_RESETTING;
|
||||
/* fall through */
|
||||
case CS_ABORTED:
|
||||
case CS_PORT_BUSY:
|
||||
ql_log(ql_log_warn, fcport->vha, 0x5060,
|
||||
"NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x ox_id=%x\n",
|
||||
sp->name, sp->handle, sts->comp_status,
|
||||
le32_to_cpu(sts->residual_len), sts->ox_id);
|
||||
fd->transferred_length = 0;
|
||||
iocb->u.nvme.rsp_pyld_len = 0;
|
||||
ret = QLA_ABORTED;
|
||||
break;
|
||||
case CS_DATA_UNDERRUN:
|
||||
break;
|
||||
default:
|
||||
ql_log(ql_log_warn, fcport->vha, 0x5060,
|
||||
"NVME-%s error - hdl=%x completion status(%x) resid=%x ox_id=%x\n",
|
||||
sp->name, sp->handle, sts->comp_status,
|
||||
le32_to_cpu(sts->residual_len), sts->ox_id);
|
||||
ret = QLA_FUNCTION_FAILED;
|
||||
break;
|
||||
}
|
||||
@@ -2716,6 +2735,17 @@ check_scsi_status:
|
||||
cp->device->vendor);
|
||||
break;
|
||||
|
||||
case CS_DMA:
|
||||
ql_log(ql_log_info, fcport->vha, 0x3022,
|
||||
"CS_DMA error: 0x%x-0x%x (0x%x) nexus=%ld:%d:%llu portid=%06x oxid=0x%x cdb=%10phN len=0x%x rsp_info=0x%x resid=0x%x fw_resid=0x%x sp=%p cp=%p.\n",
|
||||
comp_status, scsi_status, res, vha->host_no,
|
||||
cp->device->id, cp->device->lun, fcport->d_id.b24,
|
||||
ox_id, cp->cmnd, scsi_bufflen(cp), rsp_info_len,
|
||||
resid_len, fw_resid_len, sp, cp);
|
||||
ql_dump_buffer(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe0ee,
|
||||
pkt, sizeof(*sts24));
|
||||
res = DID_ERROR << 16;
|
||||
break;
|
||||
default:
|
||||
res = DID_ERROR << 16;
|
||||
break;
|
||||
@@ -2836,6 +2866,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
|
||||
case ELS_IOCB_TYPE:
|
||||
case ABORT_IOCB_TYPE:
|
||||
case MBX_IOCB_TYPE:
|
||||
default:
|
||||
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
|
||||
if (sp) {
|
||||
sp->done(sp, res);
|
||||
@@ -2846,7 +2877,6 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
|
||||
case ABTS_RESP_24XX:
|
||||
case CTIO_TYPE7:
|
||||
case CTIO_CRC2:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
fatal:
|
||||
@@ -3100,7 +3130,7 @@ done:
|
||||
|
||||
/**
|
||||
* qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP24xx.
|
||||
* @irq:
|
||||
* @irq: interrupt number
|
||||
* @dev_id: SCSI driver HA context
|
||||
*
|
||||
* Called by system whenever the host adapter generates an interrupt.
|
||||
@@ -3120,6 +3150,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
||||
uint16_t mb[8];
|
||||
struct rsp_que *rsp;
|
||||
unsigned long flags;
|
||||
bool process_atio = false;
|
||||
|
||||
rsp = (struct rsp_que *) dev_id;
|
||||
if (!rsp) {
|
||||
@@ -3180,22 +3211,13 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
case INTR_ATIO_QUE_UPDATE_27XX:
|
||||
case INTR_ATIO_QUE_UPDATE:{
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
case INTR_ATIO_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
break;
|
||||
}
|
||||
case INTR_ATIO_RSP_QUE_UPDATE: {
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
|
||||
case INTR_ATIO_RSP_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ql_dbg(ql_dbg_async, vha, 0x504f,
|
||||
"Unrecognized interrupt type (%d).\n", stat * 0xff);
|
||||
@@ -3209,6 +3231,12 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
||||
qla2x00_handle_mbx_completion(ha, status);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
if (process_atio) {
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags);
|
||||
qlt_24xx_process_atio_queue(vha, 0);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -3255,6 +3283,7 @@ qla24xx_msix_default(int irq, void *dev_id)
|
||||
uint32_t hccr;
|
||||
uint16_t mb[8];
|
||||
unsigned long flags;
|
||||
bool process_atio = false;
|
||||
|
||||
rsp = (struct rsp_que *) dev_id;
|
||||
if (!rsp) {
|
||||
@@ -3311,22 +3340,13 @@ qla24xx_msix_default(int irq, void *dev_id)
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
case INTR_ATIO_QUE_UPDATE_27XX:
|
||||
case INTR_ATIO_QUE_UPDATE:{
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
case INTR_ATIO_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
break;
|
||||
}
|
||||
case INTR_ATIO_RSP_QUE_UPDATE: {
|
||||
unsigned long flags2;
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags2);
|
||||
qlt_24xx_process_atio_queue(vha, 1);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags2);
|
||||
|
||||
case INTR_ATIO_RSP_QUE_UPDATE:
|
||||
process_atio = true;
|
||||
qla24xx_process_response_queue(vha, rsp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ql_dbg(ql_dbg_async, vha, 0x5051,
|
||||
"Unrecognized interrupt type (%d).\n", stat & 0xff);
|
||||
@@ -3337,6 +3357,12 @@ qla24xx_msix_default(int irq, void *dev_id)
|
||||
qla2x00_handle_mbx_completion(ha, status);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
if (process_atio) {
|
||||
spin_lock_irqsave(&ha->tgt.atio_lock, flags);
|
||||
qlt_24xx_process_atio_queue(vha, 0);
|
||||
spin_unlock_irqrestore(&ha->tgt.atio_lock, flags);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -3405,7 +3431,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
|
||||
min_vecs++;
|
||||
}
|
||||
|
||||
if (USER_CTRL_IRQ(ha)) {
|
||||
if (USER_CTRL_IRQ(ha) || !ha->mqiobase) {
|
||||
/* user wants to control IRQ setting for target mode */
|
||||
ret = pci_alloc_irq_vectors(ha->pdev, min_vecs,
|
||||
ha->msix_count, PCI_IRQ_MSIX);
|
||||
@@ -3441,6 +3467,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
|
||||
"Adjusted Max no of queues pairs: %d.\n", ha->max_qpairs);
|
||||
}
|
||||
}
|
||||
vha->irq_offset = desc.pre_vectors;
|
||||
ha->msix_entries = kcalloc(ha->msix_count,
|
||||
sizeof(struct qla_msix_entry),
|
||||
GFP_KERNEL);
|
||||
|
||||
+215
-77
@@ -59,6 +59,8 @@ static struct rom_cmd {
|
||||
{ MBC_IOCB_COMMAND_A64 },
|
||||
{ MBC_GET_ADAPTER_LOOP_ID },
|
||||
{ MBC_READ_SFP },
|
||||
{ MBC_GET_RNID_PARAMS },
|
||||
{ MBC_GET_SET_ZIO_THRESHOLD },
|
||||
};
|
||||
|
||||
static int is_rom_cmd(uint16_t cmd)
|
||||
@@ -110,6 +112,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
unsigned long wait_time;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
|
||||
u32 chip_reset;
|
||||
|
||||
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
|
||||
@@ -140,7 +143,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
|
||||
rval = QLA_SUCCESS;
|
||||
abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
|
||||
|
||||
chip_reset = ha->chip_reset;
|
||||
|
||||
if (ha->flags.pci_channel_io_perm_failure) {
|
||||
ql_log(ql_log_warn, vha, 0x1003,
|
||||
@@ -167,6 +170,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
return QLA_FUNCTION_TIMEOUT;
|
||||
}
|
||||
|
||||
atomic_inc(&ha->num_pend_mbx_stage1);
|
||||
/*
|
||||
* Wait for active mailbox commands to finish by waiting at most tov
|
||||
* seconds. This is to serialize actual issuing of mailbox cmds during
|
||||
@@ -177,10 +181,16 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
ql_log(ql_log_warn, vha, 0xd035,
|
||||
"Cmd access timeout, cmd=0x%x, Exiting.\n",
|
||||
mcp->mb[0]);
|
||||
atomic_dec(&ha->num_pend_mbx_stage1);
|
||||
return QLA_FUNCTION_TIMEOUT;
|
||||
}
|
||||
atomic_dec(&ha->num_pend_mbx_stage1);
|
||||
if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) {
|
||||
rval = QLA_ABORTED;
|
||||
goto premature_exit;
|
||||
}
|
||||
|
||||
|
||||
ha->flags.mbox_busy = 1;
|
||||
/* Save mailbox command for debug */
|
||||
ha->mcp = mcp;
|
||||
|
||||
@@ -189,6 +199,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
if (ha->flags.purge_mbox || chip_reset != ha->chip_reset ||
|
||||
ha->flags.mbox_busy) {
|
||||
rval = QLA_ABORTED;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
goto premature_exit;
|
||||
}
|
||||
ha->flags.mbox_busy = 1;
|
||||
|
||||
/* Load mailbox registers. */
|
||||
if (IS_P3P_TYPE(ha))
|
||||
optr = (uint16_t __iomem *)®->isp82.mailbox_in[0];
|
||||
@@ -231,16 +249,18 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
"jiffies=%lx.\n", jiffies);
|
||||
|
||||
/* Wait for mbx cmd completion until timeout */
|
||||
|
||||
atomic_inc(&ha->num_pend_mbx_stage2);
|
||||
if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
|
||||
set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
|
||||
|
||||
if (IS_P3P_TYPE(ha)) {
|
||||
if (RD_REG_DWORD(®->isp82.hint) &
|
||||
HINT_MBX_INT_PENDING) {
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock,
|
||||
flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
|
||||
atomic_dec(&ha->num_pend_mbx_stage2);
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1010,
|
||||
"Pending mailbox timeout, exiting.\n");
|
||||
rval = QLA_FUNCTION_TIMEOUT;
|
||||
@@ -254,14 +274,37 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
wait_time = jiffies;
|
||||
atomic_inc(&ha->num_pend_mbx_stage3);
|
||||
if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
|
||||
mcp->tov * HZ)) {
|
||||
if (chip_reset != ha->chip_reset) {
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock,
|
||||
flags);
|
||||
atomic_dec(&ha->num_pend_mbx_stage2);
|
||||
atomic_dec(&ha->num_pend_mbx_stage3);
|
||||
rval = QLA_ABORTED;
|
||||
goto premature_exit;
|
||||
}
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x117a,
|
||||
"cmd=%x Timeout.\n", command);
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
} else if (ha->flags.purge_mbox ||
|
||||
chip_reset != ha->chip_reset) {
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
atomic_dec(&ha->num_pend_mbx_stage2);
|
||||
atomic_dec(&ha->num_pend_mbx_stage3);
|
||||
rval = QLA_ABORTED;
|
||||
goto premature_exit;
|
||||
}
|
||||
atomic_dec(&ha->num_pend_mbx_stage3);
|
||||
|
||||
if (time_after(jiffies, wait_time + 5 * HZ))
|
||||
ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
|
||||
command, jiffies_to_msecs(jiffies - wait_time));
|
||||
@@ -272,9 +315,10 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
if (IS_P3P_TYPE(ha)) {
|
||||
if (RD_REG_DWORD(®->isp82.hint) &
|
||||
HINT_MBX_INT_PENDING) {
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock,
|
||||
flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
atomic_dec(&ha->num_pend_mbx_stage2);
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1012,
|
||||
"Pending mailbox timeout, exiting.\n");
|
||||
rval = QLA_FUNCTION_TIMEOUT;
|
||||
@@ -289,6 +333,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
|
||||
wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
|
||||
while (!ha->flags.mbox_int) {
|
||||
if (ha->flags.purge_mbox ||
|
||||
chip_reset != ha->chip_reset) {
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock,
|
||||
flags);
|
||||
atomic_dec(&ha->num_pend_mbx_stage2);
|
||||
rval = QLA_ABORTED;
|
||||
goto premature_exit;
|
||||
}
|
||||
|
||||
if (time_after(jiffies, wait_time))
|
||||
break;
|
||||
|
||||
@@ -312,6 +367,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
"Waited %d sec.\n",
|
||||
(uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
|
||||
}
|
||||
atomic_dec(&ha->num_pend_mbx_stage2);
|
||||
|
||||
/* Check whether we timed out */
|
||||
if (ha->flags.mbox_int) {
|
||||
@@ -325,7 +381,10 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
|
||||
|
||||
if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
/* Setting Link-Down error */
|
||||
mcp->mb[0] = MBS_LINK_DOWN_ERROR;
|
||||
ha->mcp = NULL;
|
||||
@@ -390,14 +449,18 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
/* Capture FW dump only, if PCI device active */
|
||||
if (!pci_channel_offline(vha->hw->pdev)) {
|
||||
pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
|
||||
if (w == 0xffff || ictrl == 0xffffffff) {
|
||||
if (w == 0xffff || ictrl == 0xffffffff ||
|
||||
(chip_reset != ha->chip_reset)) {
|
||||
/* This is special case if there is unload
|
||||
* of driver happening and if PCI device go
|
||||
* into bad state due to PCI error condition
|
||||
* then only PCI ERR flag would be set.
|
||||
* we will do premature exit for above case.
|
||||
*/
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock,
|
||||
flags);
|
||||
rval = QLA_FUNCTION_TIMEOUT;
|
||||
goto premature_exit;
|
||||
}
|
||||
@@ -412,8 +475,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
rval = QLA_FUNCTION_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
ha->flags.mbox_busy = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
/* Clean up */
|
||||
ha->mcp = NULL;
|
||||
@@ -454,7 +518,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
qla2xxx_wake_dpc(vha);
|
||||
}
|
||||
} else if (!abort_active) {
|
||||
} else if (current == ha->dpc_thread) {
|
||||
/* call abort directly since we are in the DPC thread */
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x101d,
|
||||
"Timeout, calling abort_isp.\n");
|
||||
@@ -497,7 +561,11 @@ premature_exit:
|
||||
complete(&ha->mbx_cmd_comp);
|
||||
|
||||
mbx_done:
|
||||
if (rval) {
|
||||
if (rval == QLA_ABORTED) {
|
||||
ql_log(ql_log_info, vha, 0xd035,
|
||||
"Chip Reset in progress. Purging Mbox cmd=0x%x.\n",
|
||||
mcp->mb[0]);
|
||||
} else if (rval) {
|
||||
if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) {
|
||||
pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR,
|
||||
dev_name(&ha->pdev->dev), 0x1020+0x800,
|
||||
@@ -1041,7 +1109,12 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
|
||||
* FW supports nvme and driver load parameter requested nvme.
|
||||
* BIT 26 of fw_attributes indicates NVMe support.
|
||||
*/
|
||||
if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) {
|
||||
if ((ha->fw_attributes_h &
|
||||
(FW_ATTR_H_NVME | FW_ATTR_H_NVME_UPDATED)) &&
|
||||
ql2xnvmeenable) {
|
||||
if (ha->fw_attributes_h & FW_ATTR_H_NVME_FBURST)
|
||||
vha->flags.nvme_first_burst = 1;
|
||||
|
||||
vha->flags.nvme_enabled = 1;
|
||||
ql_log(ql_log_info, vha, 0xd302,
|
||||
"%s: FC-NVMe is Enabled (0x%x)\n",
|
||||
@@ -1440,17 +1513,12 @@ qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
scsi_qla_host_t *vha;
|
||||
struct req_que *req;
|
||||
struct rsp_que *rsp;
|
||||
|
||||
l = l;
|
||||
vha = fcport->vha;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
|
||||
"Entered %s.\n", __func__);
|
||||
|
||||
req = vha->hw->req_q_map[0];
|
||||
rsp = req->rsp;
|
||||
mcp->mb[0] = MBC_ABORT_TARGET;
|
||||
mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
|
||||
if (HAS_EXTENDED_IDS(vha->hw)) {
|
||||
@@ -1473,7 +1541,7 @@ qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
|
||||
}
|
||||
|
||||
/* Issue marker IOCB. */
|
||||
rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
|
||||
rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, 0,
|
||||
MK_SYNC_ID);
|
||||
if (rval2 != QLA_SUCCESS) {
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1040,
|
||||
@@ -1493,16 +1561,12 @@ qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
scsi_qla_host_t *vha;
|
||||
struct req_que *req;
|
||||
struct rsp_que *rsp;
|
||||
|
||||
vha = fcport->vha;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
|
||||
"Entered %s.\n", __func__);
|
||||
|
||||
req = vha->hw->req_q_map[0];
|
||||
rsp = req->rsp;
|
||||
mcp->mb[0] = MBC_LUN_RESET;
|
||||
mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
if (HAS_EXTENDED_IDS(vha->hw))
|
||||
@@ -1522,7 +1586,7 @@ qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
|
||||
}
|
||||
|
||||
/* Issue marker IOCB. */
|
||||
rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
|
||||
rval2 = qla2x00_marker(vha, vha->hw->base_qpair, fcport->loop_id, l,
|
||||
MK_SYNC_ID_LUN);
|
||||
if (rval2 != QLA_SUCCESS) {
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1044,
|
||||
@@ -2177,7 +2241,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha)
|
||||
mcp->out_mb = MBX_2|MBX_1|MBX_0;
|
||||
} else if (IS_FWI2_CAPABLE(vha->hw)) {
|
||||
mcp->mb[0] = MBC_LIP_FULL_LOGIN;
|
||||
mcp->mb[1] = BIT_6;
|
||||
mcp->mb[1] = BIT_4;
|
||||
mcp->mb[2] = 0;
|
||||
mcp->mb[3] = vha->hw->loop_reset_delay;
|
||||
mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
@@ -2687,7 +2751,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *vha)
|
||||
"Entered %s.\n", __func__);
|
||||
|
||||
mcp->mb[0] = MBC_LIP_FULL_LOGIN;
|
||||
mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
|
||||
mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_4 : 0;
|
||||
mcp->mb[2] = 0;
|
||||
mcp->mb[3] = 0;
|
||||
mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
|
||||
@@ -3026,22 +3090,25 @@ qla24xx_abort_command(srb_t *sp)
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
struct req_que *req = vha->req;
|
||||
struct qla_qpair *qpair = sp->qpair;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
|
||||
"Entered %s.\n", __func__);
|
||||
|
||||
if (vha->flags.qpairs_available && sp->qpair)
|
||||
req = sp->qpair->req;
|
||||
else
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
if (ql2xasynctmfenable)
|
||||
return qla24xx_async_abort_command(sp);
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
||||
for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
|
||||
if (req->outstanding_cmds[handle] == sp)
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
|
||||
if (handle == req->num_outstanding_cmds) {
|
||||
/* Command not found. */
|
||||
return QLA_FUNCTION_FAILED;
|
||||
@@ -3111,7 +3178,6 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
|
||||
scsi_qla_host_t *vha;
|
||||
struct qla_hw_data *ha;
|
||||
struct req_que *req;
|
||||
struct rsp_que *rsp;
|
||||
struct qla_qpair *qpair;
|
||||
|
||||
vha = fcport->vha;
|
||||
@@ -3124,10 +3190,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
|
||||
if (vha->vp_idx && vha->qpair) {
|
||||
/* NPIV port */
|
||||
qpair = vha->qpair;
|
||||
rsp = qpair->rsp;
|
||||
req = qpair->req;
|
||||
} else {
|
||||
rsp = req->rsp;
|
||||
}
|
||||
|
||||
tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
|
||||
@@ -3184,7 +3247,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
|
||||
}
|
||||
|
||||
/* Issue marker IOCB. */
|
||||
rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
|
||||
rval2 = qla2x00_marker(vha, ha->base_qpair, fcport->loop_id, l,
|
||||
type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
|
||||
if (rval2 != QLA_SUCCESS) {
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1099,
|
||||
@@ -3405,9 +3468,9 @@ qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
|
||||
/**
|
||||
* qla2x00_set_serdes_params() -
|
||||
* @vha: HA context
|
||||
* @sw_em_1g:
|
||||
* @sw_em_2g:
|
||||
* @sw_em_4g:
|
||||
* @sw_em_1g: serial link options
|
||||
* @sw_em_2g: serial link options
|
||||
* @sw_em_4g: serial link options
|
||||
*
|
||||
* Returns
|
||||
*/
|
||||
@@ -3794,30 +3857,68 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
|
||||
"Format 1: WWPN %8phC.\n",
|
||||
vha->port_name);
|
||||
|
||||
/* N2N. direct connect */
|
||||
if (IS_QLA27XX(ha) &&
|
||||
((rptid_entry->u.f1.flags>>1) & 0x7) == 2) {
|
||||
/* if our portname is higher then initiate N2N login */
|
||||
if (wwn_to_u64(vha->port_name) >
|
||||
wwn_to_u64(rptid_entry->u.f1.port_name)) {
|
||||
// ??? qlt_update_host_map(vha, id);
|
||||
vha->n2n_id = 0x1;
|
||||
ql_dbg(ql_dbg_async, vha, 0x5075,
|
||||
"Format 1: Setting n2n_update_needed for id %d\n",
|
||||
vha->n2n_id);
|
||||
switch (rptid_entry->u.f1.flags & TOPO_MASK) {
|
||||
case TOPO_N2N:
|
||||
ha->current_topology = ISP_CFG_N;
|
||||
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
|
||||
fcport = qla2x00_find_fcport_by_wwpn(vha,
|
||||
rptid_entry->u.f1.port_name, 1);
|
||||
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
|
||||
|
||||
if (fcport) {
|
||||
fcport->plogi_nack_done_deadline = jiffies + HZ;
|
||||
fcport->dm_login_expire = jiffies + 3*HZ;
|
||||
fcport->scan_state = QLA_FCPORT_FOUND;
|
||||
switch (fcport->disc_state) {
|
||||
case DSC_DELETED:
|
||||
set_bit(RELOGIN_NEEDED,
|
||||
&vha->dpc_flags);
|
||||
break;
|
||||
case DSC_DELETE_PEND:
|
||||
break;
|
||||
default:
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ql_dbg(ql_dbg_async, vha, 0x5075,
|
||||
"Format 1: Remote login - Waiting for WWPN %8phC.\n",
|
||||
rptid_entry->u.f1.port_name);
|
||||
id.b24 = 0;
|
||||
if (wwn_to_u64(vha->port_name) >
|
||||
wwn_to_u64(rptid_entry->u.f1.port_name)) {
|
||||
vha->d_id.b24 = 0;
|
||||
vha->d_id.b.al_pa = 1;
|
||||
ha->flags.n2n_bigger = 1;
|
||||
|
||||
id.b.al_pa = 2;
|
||||
ql_dbg(ql_dbg_async, vha, 0x5075,
|
||||
"Format 1: assign local id %x remote id %x\n",
|
||||
vha->d_id.b24, id.b24);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_async, vha, 0x5075,
|
||||
"Format 1: Remote login - Waiting for WWPN %8phC.\n",
|
||||
rptid_entry->u.f1.port_name);
|
||||
ha->flags.n2n_bigger = 0;
|
||||
}
|
||||
qla24xx_post_newsess_work(vha, &id,
|
||||
rptid_entry->u.f1.port_name,
|
||||
rptid_entry->u.f1.node_name,
|
||||
NULL,
|
||||
FC4_TYPE_UNKNOWN);
|
||||
}
|
||||
|
||||
memcpy(vha->n2n_port_name, rptid_entry->u.f1.port_name,
|
||||
WWN_SIZE);
|
||||
/* if our portname is higher then initiate N2N login */
|
||||
|
||||
set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
|
||||
set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
|
||||
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
|
||||
ha->flags.n2n_ae = 1;
|
||||
return;
|
||||
break;
|
||||
case TOPO_FL:
|
||||
ha->current_topology = ISP_CFG_FL;
|
||||
break;
|
||||
case TOPO_F:
|
||||
ha->current_topology = ISP_CFG_F;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ha->flags.gpsc_supported = 1;
|
||||
@@ -3906,30 +4007,9 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
|
||||
rptid_entry->u.f2.port_name, 1);
|
||||
|
||||
if (fcport) {
|
||||
fcport->login_retry = vha->hw->login_retry_count;
|
||||
fcport->plogi_nack_done_deadline = jiffies + HZ;
|
||||
fcport->scan_state = QLA_FCPORT_FOUND;
|
||||
switch (fcport->disc_state) {
|
||||
case DSC_DELETED:
|
||||
ql_dbg(ql_dbg_disc, vha, 0x210d,
|
||||
"%s %d %8phC login\n",
|
||||
__func__, __LINE__, fcport->port_name);
|
||||
qla24xx_fcport_handle_login(vha, fcport);
|
||||
break;
|
||||
case DSC_DELETE_PEND:
|
||||
break;
|
||||
default:
|
||||
qlt_schedule_sess_for_deletion(fcport);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
id.b.al_pa = rptid_entry->u.f2.remote_nport_id[0];
|
||||
id.b.area = rptid_entry->u.f2.remote_nport_id[1];
|
||||
id.b.domain = rptid_entry->u.f2.remote_nport_id[2];
|
||||
qla24xx_post_newsess_work(vha, &id,
|
||||
rptid_entry->u.f2.port_name,
|
||||
rptid_entry->u.f2.node_name,
|
||||
NULL,
|
||||
FC4_TYPE_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4660,7 +4740,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
|
||||
"Done %s.\n", __func__);
|
||||
bp = (uint32_t *) buf;
|
||||
for (i = 0; i < (bufsiz-4)/4; i++, bp++)
|
||||
*bp = cpu_to_be32(*bp);
|
||||
*bp = le32_to_cpu(*bp);
|
||||
}
|
||||
|
||||
return rval;
|
||||
@@ -5158,6 +5238,66 @@ qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Set the specified data rate */
|
||||
int
|
||||
qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode)
|
||||
{
|
||||
int rval;
|
||||
mbx_cmd_t mc;
|
||||
mbx_cmd_t *mcp = &mc;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint16_t val;
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
|
||||
"Entered %s speed:0x%x mode:0x%x.\n", __func__, ha->set_data_rate,
|
||||
mode);
|
||||
|
||||
if (!IS_FWI2_CAPABLE(ha))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
memset(mcp, 0, sizeof(*mcp));
|
||||
switch (ha->set_data_rate) {
|
||||
case PORT_SPEED_AUTO:
|
||||
case PORT_SPEED_4GB:
|
||||
case PORT_SPEED_8GB:
|
||||
case PORT_SPEED_16GB:
|
||||
case PORT_SPEED_32GB:
|
||||
val = ha->set_data_rate;
|
||||
break;
|
||||
default:
|
||||
ql_log(ql_log_warn, vha, 0x1199,
|
||||
"Unrecognized speed setting:%d. Setting Autoneg\n",
|
||||
ha->set_data_rate);
|
||||
val = ha->set_data_rate = PORT_SPEED_AUTO;
|
||||
break;
|
||||
}
|
||||
|
||||
mcp->mb[0] = MBC_DATA_RATE;
|
||||
mcp->mb[1] = mode;
|
||||
mcp->mb[2] = val;
|
||||
|
||||
mcp->out_mb = MBX_2|MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_2|MBX_1|MBX_0;
|
||||
if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
|
||||
mcp->in_mb |= MBX_4|MBX_3;
|
||||
mcp->tov = MBX_TOV_SECONDS;
|
||||
mcp->flags = 0;
|
||||
rval = qla2x00_mailbox_command(vha, mcp);
|
||||
if (rval != QLA_SUCCESS) {
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1107,
|
||||
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
|
||||
} else {
|
||||
if (mcp->mb[1] != 0x7)
|
||||
ql_dbg(ql_dbg_mbx, vha, 0x1179,
|
||||
"Speed set:0x%x\n", mcp->mb[1]);
|
||||
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
|
||||
"Done %s.\n", __func__);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_get_data_rate(scsi_qla_host_t *vha)
|
||||
{
|
||||
@@ -5173,7 +5313,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha)
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
mcp->mb[0] = MBC_DATA_RATE;
|
||||
mcp->mb[1] = 0;
|
||||
mcp->mb[1] = QLA_GET_DATA_RATE;
|
||||
mcp->out_mb = MBX_1|MBX_0;
|
||||
mcp->in_mb = MBX_2|MBX_1|MBX_0;
|
||||
if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
|
||||
@@ -6178,8 +6318,6 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
|
||||
fcport->d_id.b.rsvd_1 = 0;
|
||||
|
||||
if (fcport->fc4f_nvme) {
|
||||
fcport->nvme_prli_service_param =
|
||||
pd->prli_nvme_svc_param_word_3;
|
||||
fcport->port_type = FCT_NVME;
|
||||
} else {
|
||||
/* If not target must be initiator or unknown type. */
|
||||
|
||||
@@ -492,7 +492,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
|
||||
"Couldn't allocate vp_id.\n");
|
||||
goto create_vhost_failed;
|
||||
}
|
||||
vha->mgmt_svr_loop_id = NPH_MGMT_SERVER;
|
||||
vha->mgmt_svr_loop_id = qla2x00_reserve_mgmt_server_loop_id(vha);
|
||||
|
||||
vha->dpc_flags = 0L;
|
||||
|
||||
@@ -507,6 +507,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
|
||||
qla2x00_start_timer(vha, WATCH_INTERVAL);
|
||||
|
||||
vha->req = base_vha->req;
|
||||
vha->flags.nvme_enabled = base_vha->flags.nvme_enabled;
|
||||
host->can_queue = base_vha->req->length + 128;
|
||||
host->cmd_per_lun = 3;
|
||||
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif)
|
||||
|
||||
@@ -2212,7 +2212,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req,
|
||||
struct bsg_job *bsg_job;
|
||||
struct fc_bsg_reply *bsg_reply;
|
||||
struct srb_iocb *iocb_job;
|
||||
int res;
|
||||
int res = 0;
|
||||
struct qla_mt_iocb_rsp_fx00 fstatus;
|
||||
uint8_t *fw_sts_ptr;
|
||||
|
||||
@@ -2624,7 +2624,7 @@ qlafx00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
|
||||
* qlafx00_multistatus_entry() - Process Multi response queue entries.
|
||||
* @vha: SCSI driver HA context
|
||||
* @rsp: response queue
|
||||
* @pkt:
|
||||
* @pkt: received packet
|
||||
*/
|
||||
static void
|
||||
qlafx00_multistatus_entry(struct scsi_qla_host *vha,
|
||||
@@ -2681,12 +2681,10 @@ qlafx00_multistatus_entry(struct scsi_qla_host *vha,
|
||||
* @vha: SCSI driver HA context
|
||||
* @rsp: response queue
|
||||
* @pkt: Entry pointer
|
||||
* @estatus:
|
||||
* @etype:
|
||||
*/
|
||||
static void
|
||||
qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp,
|
||||
struct sts_entry_fx00 *pkt, uint8_t estatus, uint8_t etype)
|
||||
struct sts_entry_fx00 *pkt)
|
||||
{
|
||||
srb_t *sp;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
@@ -2695,9 +2693,6 @@ qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp,
|
||||
struct req_que *req = NULL;
|
||||
int res = DID_ERROR << 16;
|
||||
|
||||
ql_dbg(ql_dbg_async, vha, 0x507f,
|
||||
"type of error status in response: 0x%x\n", estatus);
|
||||
|
||||
req = ha->req_q_map[que];
|
||||
|
||||
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
|
||||
@@ -2745,9 +2740,11 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha,
|
||||
|
||||
if (pkt->entry_status != 0 &&
|
||||
pkt->entry_type != IOCTL_IOSB_TYPE_FX00) {
|
||||
ql_dbg(ql_dbg_async, vha, 0x507f,
|
||||
"type of error status in response: 0x%x\n",
|
||||
pkt->entry_status);
|
||||
qlafx00_error_entry(vha, rsp,
|
||||
(struct sts_entry_fx00 *)pkt, pkt->entry_status,
|
||||
pkt->entry_type);
|
||||
(struct sts_entry_fx00 *)pkt);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2867,7 +2864,7 @@ qlafx00_async_event(scsi_qla_host_t *vha)
|
||||
/**
|
||||
* qlafx00x_mbx_completion() - Process mailbox command completions.
|
||||
* @vha: SCSI driver HA context
|
||||
* @mb0:
|
||||
* @mb0: value to be written into mailbox register 0
|
||||
*/
|
||||
static void
|
||||
qlafx00_mbx_completion(scsi_qla_host_t *vha, uint32_t mb0)
|
||||
@@ -2893,7 +2890,7 @@ qlafx00_mbx_completion(scsi_qla_host_t *vha, uint32_t mb0)
|
||||
|
||||
/**
|
||||
* qlafx00_intr_handler() - Process interrupts for the ISPFX00.
|
||||
* @irq:
|
||||
* @irq: interrupt number
|
||||
* @dev_id: SCSI driver HA context
|
||||
*
|
||||
* Called by system whenever the host adapter generates an interrupt.
|
||||
|
||||
+44
-48
@@ -30,6 +30,9 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!vha->nvme_local_port && qla_nvme_register_hba(vha))
|
||||
return 0;
|
||||
|
||||
if (!(fcport->nvme_prli_service_param &
|
||||
(NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
|
||||
(fcport->nvme_flag & NVME_FLAG_REGISTERED))
|
||||
@@ -182,6 +185,14 @@ static void qla_nvme_abort_work(struct work_struct *work)
|
||||
struct qla_hw_data *ha = fcport->vha->hw;
|
||||
int rval;
|
||||
|
||||
if (fcport)
|
||||
ql_dbg(ql_dbg_io, fcport->vha, 0xffff,
|
||||
"%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n",
|
||||
__func__, sp, sp->handle, fcport, fcport->deleted);
|
||||
|
||||
if (!ha->flags.fw_started && (fcport && fcport->deleted))
|
||||
return;
|
||||
|
||||
rval = ha->isp_ops->abort_command(sp);
|
||||
|
||||
ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
|
||||
@@ -269,17 +280,6 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
|
||||
schedule_work(&priv->abort_work);
|
||||
}
|
||||
|
||||
static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle)
|
||||
{
|
||||
struct qla_qpair *qpair = hw_queue_handle;
|
||||
unsigned long flags;
|
||||
struct scsi_qla_host *vha = lport->private;
|
||||
|
||||
spin_lock_irqsave(&qpair->qp_lock, flags);
|
||||
qla24xx_process_response_queue(vha, qpair->rsp);
|
||||
spin_unlock_irqrestore(&qpair->qp_lock, flags);
|
||||
}
|
||||
|
||||
static inline int qla2x00_start_nvme_mq(srb_t *sp)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -366,17 +366,24 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
|
||||
|
||||
/* No data transfer how do we check buffer len == 0?? */
|
||||
if (fd->io_dir == NVMEFC_FCP_READ) {
|
||||
cmd_pkt->control_flags =
|
||||
cpu_to_le16(CF_READ_DATA | CF_NVME_ENABLE);
|
||||
cmd_pkt->control_flags = CF_READ_DATA;
|
||||
vha->qla_stats.input_bytes += fd->payload_length;
|
||||
vha->qla_stats.input_requests++;
|
||||
} else if (fd->io_dir == NVMEFC_FCP_WRITE) {
|
||||
cmd_pkt->control_flags =
|
||||
cpu_to_le16(CF_WRITE_DATA | CF_NVME_ENABLE);
|
||||
cmd_pkt->control_flags = CF_WRITE_DATA;
|
||||
if ((vha->flags.nvme_first_burst) &&
|
||||
(sp->fcport->nvme_prli_service_param &
|
||||
NVME_PRLI_SP_FIRST_BURST)) {
|
||||
if ((fd->payload_length <=
|
||||
sp->fcport->nvme_first_burst_size) ||
|
||||
(sp->fcport->nvme_first_burst_size == 0))
|
||||
cmd_pkt->control_flags |=
|
||||
CF_NVME_FIRST_BURST_ENABLE;
|
||||
}
|
||||
vha->qla_stats.output_bytes += fd->payload_length;
|
||||
vha->qla_stats.output_requests++;
|
||||
} else if (fd->io_dir == 0) {
|
||||
cmd_pkt->control_flags = cpu_to_le16(CF_NVME_ENABLE);
|
||||
cmd_pkt->control_flags = 0;
|
||||
}
|
||||
|
||||
/* Set NPORT-ID */
|
||||
@@ -471,21 +478,10 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
|
||||
int rval = -ENODEV;
|
||||
srb_t *sp;
|
||||
struct qla_qpair *qpair = hw_queue_handle;
|
||||
struct nvme_private *priv;
|
||||
struct nvme_private *priv = fd->private;
|
||||
struct qla_nvme_rport *qla_rport = rport->private;
|
||||
|
||||
if (!fd || !qpair) {
|
||||
ql_log(ql_log_warn, NULL, 0x2134,
|
||||
"NO NVMe request or Queue Handle\n");
|
||||
return rval;
|
||||
}
|
||||
|
||||
priv = fd->private;
|
||||
fcport = qla_rport->fcport;
|
||||
if (!fcport) {
|
||||
ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n");
|
||||
return rval;
|
||||
}
|
||||
|
||||
vha = fcport->vha;
|
||||
|
||||
@@ -503,7 +499,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
|
||||
return -EBUSY;
|
||||
|
||||
/* Alloc SRB structure */
|
||||
sp = qla2xxx_get_qpair_sp(qpair, fcport, GFP_ATOMIC);
|
||||
sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
|
||||
if (!sp)
|
||||
return -EBUSY;
|
||||
|
||||
@@ -514,6 +510,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
|
||||
sp->name = "nvme_cmd";
|
||||
sp->done = qla_nvme_sp_done;
|
||||
sp->qpair = qpair;
|
||||
sp->vha = vha;
|
||||
nvme = &sp->u.iocb_cmd;
|
||||
nvme->u.nvme.desc = fd;
|
||||
|
||||
@@ -561,7 +558,7 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
|
||||
schedule_work(&fcport->free_work);
|
||||
}
|
||||
|
||||
fcport->nvme_flag &= ~(NVME_FLAG_REGISTERED | NVME_FLAG_DELETING);
|
||||
fcport->nvme_flag &= ~NVME_FLAG_DELETING;
|
||||
ql_log(ql_log_info, fcport->vha, 0x2110,
|
||||
"remoteport_delete of %p completed.\n", fcport);
|
||||
}
|
||||
@@ -575,7 +572,6 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = {
|
||||
.ls_abort = qla_nvme_ls_abort,
|
||||
.fcp_io = qla_nvme_post_cmd,
|
||||
.fcp_abort = qla_nvme_fcp_abort,
|
||||
.poll_queue = qla_nvme_poll,
|
||||
.max_hw_queues = 8,
|
||||
.max_sgl_segments = 128,
|
||||
.max_dif_sgl_segments = 64,
|
||||
@@ -619,6 +615,7 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work)
|
||||
struct fc_port *fcport = container_of(work, struct fc_port,
|
||||
nvme_del_work);
|
||||
struct qla_nvme_rport *qla_rport, *trport;
|
||||
scsi_qla_host_t *base_vha;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return;
|
||||
@@ -626,6 +623,15 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work)
|
||||
ql_log(ql_log_warn, NULL, 0x2112,
|
||||
"%s: unregister remoteport on %p\n",__func__, fcport);
|
||||
|
||||
base_vha = pci_get_drvdata(fcport->vha->hw->pdev);
|
||||
if (test_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags)) {
|
||||
ql_dbg(ql_dbg_disc, fcport->vha, 0x2114,
|
||||
"%s: Notify FC-NVMe transport, set devloss=0\n",
|
||||
__func__);
|
||||
|
||||
nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(qla_rport, trport,
|
||||
&fcport->vha->nvme_rport_list, list) {
|
||||
if (qla_rport->fcport == fcport) {
|
||||
@@ -642,23 +648,11 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work)
|
||||
|
||||
void qla_nvme_delete(struct scsi_qla_host *vha)
|
||||
{
|
||||
struct qla_nvme_rport *qla_rport, *trport;
|
||||
fc_port_t *fcport;
|
||||
int nv_ret;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(qla_rport, trport,
|
||||
&vha->nvme_rport_list, list) {
|
||||
fcport = qla_rport->fcport;
|
||||
|
||||
ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n",
|
||||
__func__, fcport);
|
||||
|
||||
nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0);
|
||||
}
|
||||
|
||||
if (vha->nvme_local_port) {
|
||||
init_completion(&vha->nvme_del_done);
|
||||
ql_log(ql_log_info, vha, 0x2116,
|
||||
@@ -673,15 +667,15 @@ void qla_nvme_delete(struct scsi_qla_host *vha)
|
||||
}
|
||||
}
|
||||
|
||||
void qla_nvme_register_hba(struct scsi_qla_host *vha)
|
||||
int qla_nvme_register_hba(struct scsi_qla_host *vha)
|
||||
{
|
||||
struct nvme_fc_port_template *tmpl;
|
||||
struct qla_hw_data *ha;
|
||||
struct nvme_fc_port_info pinfo;
|
||||
int ret;
|
||||
int ret = EINVAL;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_NVME_FC))
|
||||
return;
|
||||
return ret;
|
||||
|
||||
ha = vha->hw;
|
||||
tmpl = &qla_nvme_fc_transport;
|
||||
@@ -708,7 +702,9 @@ void qla_nvme_register_hba(struct scsi_qla_host *vha)
|
||||
if (ret) {
|
||||
ql_log(ql_log_warn, vha, 0xffff,
|
||||
"register_localport failed: ret=%x\n", ret);
|
||||
return;
|
||||
} else {
|
||||
vha->nvme_local_port->private = vha;
|
||||
}
|
||||
vha->nvme_local_port->private = vha;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ struct cmd_nvme {
|
||||
uint64_t rsvd;
|
||||
|
||||
uint16_t control_flags; /* Control Flags */
|
||||
#define CF_NVME_ENABLE BIT_9
|
||||
#define CF_NVME_FIRST_BURST_ENABLE BIT_11
|
||||
#define CF_DIF_SEG_DESCR_ENABLE BIT_3
|
||||
#define CF_DATA_SEG_DESCR_ENABLE BIT_2
|
||||
#define CF_READ_DATA BIT_1
|
||||
@@ -142,7 +142,7 @@ struct pt_ls4_rx_unsol {
|
||||
/*
|
||||
* Global functions prototype in qla_nvme.c source file.
|
||||
*/
|
||||
void qla_nvme_register_hba(struct scsi_qla_host *);
|
||||
int qla_nvme_register_hba(struct scsi_qla_host *);
|
||||
int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *);
|
||||
void qla_nvme_delete(struct scsi_qla_host *);
|
||||
void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res);
|
||||
|
||||
@@ -2010,7 +2010,7 @@ qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
|
||||
|
||||
/**
|
||||
* qla82xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
|
||||
* @irq:
|
||||
* @irq: interrupt number
|
||||
* @dev_id: SCSI driver HA context
|
||||
*
|
||||
* Called by system whenever the host adapter generates an interrupt.
|
||||
@@ -3699,8 +3699,8 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
/* Wait for pending cmds (physical and virtual) to complete */
|
||||
if (!qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
|
||||
WAIT_HOST) == QLA_SUCCESS) {
|
||||
if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0,
|
||||
WAIT_HOST)) {
|
||||
ql_dbg(ql_dbg_init, vha, 0x00b3,
|
||||
"Done wait for "
|
||||
"pending commands.\n");
|
||||
|
||||
@@ -3878,7 +3878,7 @@ out:
|
||||
#define PF_BITS_MASK (0xF << 16)
|
||||
/**
|
||||
* qla8044_intr_handler() - Process interrupts for the ISP8044
|
||||
* @irq:
|
||||
* @irq: interrupt number
|
||||
* @dev_id: SCSI driver HA context
|
||||
*
|
||||
* Called by system whenever the host adapter generates an interrupt.
|
||||
|
||||
+592
-233
File diff suppressed because it is too large
Load Diff
@@ -2229,7 +2229,7 @@ qla2x00_erase_flash_sector(struct qla_hw_data *ha, uint32_t addr,
|
||||
|
||||
/**
|
||||
* qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip.
|
||||
* @ha:
|
||||
* @ha: host adapter
|
||||
* @man_id: Flash manufacturer ID
|
||||
* @flash_id: Flash ID
|
||||
*/
|
||||
|
||||
+409
-200
File diff suppressed because it is too large
Load Diff
@@ -772,14 +772,6 @@ int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
|
||||
#define FC_TM_REJECT 4
|
||||
#define FC_TM_FAILED 5
|
||||
|
||||
#if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G)
|
||||
#define pci_dma_lo32(a) (a & 0xffffffff)
|
||||
#define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff)
|
||||
#else
|
||||
#define pci_dma_lo32(a) (a & 0xffffffff)
|
||||
#define pci_dma_hi32(a) 0
|
||||
#endif
|
||||
|
||||
#define QLA_TGT_SENSE_VALID(sense) ((sense != NULL) && \
|
||||
(((const uint8_t *)(sense))[0] & 0x70) == 0x70)
|
||||
|
||||
@@ -901,6 +893,7 @@ struct qla_tgt_cmd {
|
||||
unsigned int aborted:1;
|
||||
unsigned int data_work:1;
|
||||
unsigned int data_work_free:1;
|
||||
unsigned int released:1;
|
||||
|
||||
struct scatterlist *sg; /* cmd data buffer SG vector */
|
||||
int sg_cnt; /* SG segments count */
|
||||
@@ -909,6 +902,7 @@ struct qla_tgt_cmd {
|
||||
u64 unpacked_lun;
|
||||
enum dma_data_direction dma_data_direction;
|
||||
|
||||
uint16_t ctio_flags;
|
||||
uint16_t vp_idx;
|
||||
uint16_t loop_id; /* to save extra sess dereferences */
|
||||
struct qla_tgt *tgt; /* to save extra sess dereferences */
|
||||
@@ -935,6 +929,8 @@ struct qla_tgt_cmd {
|
||||
uint64_t lba;
|
||||
uint16_t a_guard, e_guard, a_app_tag, e_app_tag;
|
||||
uint32_t a_ref_tag, e_ref_tag;
|
||||
#define DIF_BUNDL_DMA_VALID 1
|
||||
uint16_t prot_flags;
|
||||
|
||||
uint64_t jiffies_at_alloc;
|
||||
uint64_t jiffies_at_free;
|
||||
@@ -957,16 +953,20 @@ struct qla_tgt_sess_work_param {
|
||||
};
|
||||
|
||||
struct qla_tgt_mgmt_cmd {
|
||||
uint8_t cmd_type;
|
||||
uint8_t pad[3];
|
||||
uint16_t tmr_func;
|
||||
uint8_t fc_tm_rsp;
|
||||
uint8_t abort_io_attr;
|
||||
struct fc_port *sess;
|
||||
struct qla_qpair *qpair;
|
||||
struct scsi_qla_host *vha;
|
||||
struct se_cmd se_cmd;
|
||||
struct work_struct free_work;
|
||||
unsigned int flags;
|
||||
#define QLA24XX_MGMT_SEND_NACK BIT_0
|
||||
#define QLA24XX_MGMT_ABORT_IO_ATTR_VALID BIT_1
|
||||
uint32_t reset_count;
|
||||
#define QLA24XX_MGMT_SEND_NACK 1
|
||||
struct work_struct work;
|
||||
uint64_t unpacked_lun;
|
||||
union {
|
||||
|
||||
+144
-97
@@ -221,7 +221,13 @@ qla27xx_skip_entry(struct qla27xx_fwdt_entry *ent, void *buf)
|
||||
ent->hdr.driver_flags |= DRIVER_FLAG_SKIP_ENTRY;
|
||||
}
|
||||
|
||||
static int
|
||||
static inline struct qla27xx_fwdt_entry *
|
||||
qla27xx_next_entry(struct qla27xx_fwdt_entry *ent)
|
||||
{
|
||||
return (void *)ent + ent->hdr.size;
|
||||
}
|
||||
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -229,10 +235,10 @@ qla27xx_fwdt_entry_t0(struct scsi_qla_host *vha,
|
||||
"%s: nop [%lx]\n", __func__, *len);
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -241,10 +247,10 @@ qla27xx_fwdt_entry_t255(struct scsi_qla_host *vha,
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
|
||||
/* terminate */
|
||||
return true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -255,10 +261,10 @@ qla27xx_fwdt_entry_t256(struct scsi_qla_host *vha,
|
||||
qla27xx_read_window(reg, ent->t256.base_addr, ent->t256.pci_offset,
|
||||
ent->t256.reg_count, ent->t256.reg_width, buf, len);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -269,10 +275,10 @@ qla27xx_fwdt_entry_t257(struct scsi_qla_host *vha,
|
||||
qla27xx_write_reg(reg, IOBASE_ADDR, ent->t257.base_addr, buf);
|
||||
qla27xx_write_reg(reg, ent->t257.pci_offset, ent->t257.write_data, buf);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -284,10 +290,10 @@ qla27xx_fwdt_entry_t258(struct scsi_qla_host *vha,
|
||||
qla27xx_read_window(reg, ent->t258.base_addr, ent->t258.pci_offset,
|
||||
ent->t258.reg_count, ent->t258.reg_width, buf, len);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -299,10 +305,10 @@ qla27xx_fwdt_entry_t259(struct scsi_qla_host *vha,
|
||||
qla27xx_write_reg(reg, ent->t259.banksel_offset, ent->t259.bank, buf);
|
||||
qla27xx_write_reg(reg, ent->t259.pci_offset, ent->t259.write_data, buf);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -313,10 +319,10 @@ qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha,
|
||||
qla27xx_insert32(ent->t260.pci_offset, buf, len);
|
||||
qla27xx_read_reg(reg, ent->t260.pci_offset, buf, len);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -326,10 +332,10 @@ qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha,
|
||||
"%s: wrpci [%lx]\n", __func__, *len);
|
||||
qla27xx_write_reg(reg, ent->t261.pci_offset, ent->t261.write_data, buf);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -362,6 +368,11 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
|
||||
ent->t262.start_addr = start;
|
||||
ent->t262.end_addr = end;
|
||||
}
|
||||
} else if (ent->t262.ram_area == T262_RAM_AREA_MISC) {
|
||||
if (buf) {
|
||||
ent->t262.start_addr = start;
|
||||
ent->t262.end_addr = end;
|
||||
}
|
||||
} else {
|
||||
ql_dbg(ql_dbg_misc, vha, 0xd022,
|
||||
"%s: unknown area %x\n", __func__, ent->t262.ram_area);
|
||||
@@ -384,10 +395,10 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha,
|
||||
}
|
||||
*len += dwords * sizeof(uint32_t);
|
||||
done:
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -450,10 +461,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
}
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -478,10 +489,10 @@ qla27xx_fwdt_entry_t264(struct scsi_qla_host *vha,
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
}
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -492,10 +503,10 @@ qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha,
|
||||
if (buf)
|
||||
qla24xx_pause_risc(reg, vha->hw);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -504,10 +515,10 @@ qla27xx_fwdt_entry_t266(struct scsi_qla_host *vha,
|
||||
if (buf)
|
||||
qla24xx_soft_reset(vha->hw);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -517,10 +528,10 @@ qla27xx_fwdt_entry_t267(struct scsi_qla_host *vha,
|
||||
"%s: dis intr [%lx]\n", __func__, *len);
|
||||
qla27xx_write_reg(reg, ent->t267.pci_offset, ent->t267.data, buf);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -587,10 +598,10 @@ qla27xx_fwdt_entry_t268(struct scsi_qla_host *vha,
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -604,10 +615,10 @@ qla27xx_fwdt_entry_t269(struct scsi_qla_host *vha,
|
||||
if (buf)
|
||||
ent->t269.scratch_size = 5 * sizeof(uint32_t);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -625,10 +636,10 @@ qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha,
|
||||
addr += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -642,10 +653,10 @@ qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha,
|
||||
qla27xx_write_reg(reg, 0xc4, data, buf);
|
||||
qla27xx_write_reg(reg, 0xc0, addr, buf);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -662,10 +673,10 @@ qla27xx_fwdt_entry_t272(struct scsi_qla_host *vha,
|
||||
}
|
||||
*len += dwords * sizeof(uint32_t);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -685,10 +696,10 @@ qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha,
|
||||
addr += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -746,10 +757,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
}
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
@@ -763,7 +774,7 @@ qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
goto done;
|
||||
}
|
||||
if (offset + ent->t275.length > ent->hdr.entry_size) {
|
||||
if (offset + ent->t275.length > ent->hdr.size) {
|
||||
ql_dbg(ql_dbg_misc, vha, 0xd030,
|
||||
"%s: buffer overflow\n", __func__);
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
@@ -772,59 +783,103 @@ qla27xx_fwdt_entry_t275(struct scsi_qla_host *vha,
|
||||
|
||||
qla27xx_insertbuf(ent->t275.buffer, ent->t275.length, buf, len);
|
||||
done:
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static int
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t276(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
uint type = vha->hw->pdev->device >> 4 & 0xf;
|
||||
uint func = vha->hw->port_no & 0x3;
|
||||
|
||||
ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd214,
|
||||
"%s: cond [%lx]\n", __func__, *len);
|
||||
|
||||
if (type != ent->t276.cond1 || func != ent->t276.cond2) {
|
||||
ent = qla27xx_next_entry(ent);
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
}
|
||||
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t277(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
|
||||
|
||||
ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd215,
|
||||
"%s: rdpep [%lx]\n", __func__, *len);
|
||||
qla27xx_insert32(ent->t277.wr_cmd_data, buf, len);
|
||||
qla27xx_write_reg(reg, ent->t277.cmd_addr, ent->t277.wr_cmd_data, buf);
|
||||
qla27xx_read_reg(reg, ent->t277.data_addr, buf, len);
|
||||
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_t278(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha);
|
||||
|
||||
ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd216,
|
||||
"%s: wrpep [%lx]\n", __func__, *len);
|
||||
qla27xx_write_reg(reg, ent->t278.data_addr, ent->t278.wr_data, buf);
|
||||
qla27xx_write_reg(reg, ent->t278.cmd_addr, ent->t278.wr_cmd_data, buf);
|
||||
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
static struct qla27xx_fwdt_entry *
|
||||
qla27xx_fwdt_entry_other(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_entry *ent, void *buf, ulong *len)
|
||||
{
|
||||
ql_dbg(ql_dbg_misc, vha, 0xd2ff,
|
||||
"%s: type %x [%lx]\n", __func__, ent->hdr.entry_type, *len);
|
||||
"%s: type %x [%lx]\n", __func__, ent->hdr.type, *len);
|
||||
qla27xx_skip_entry(ent, buf);
|
||||
|
||||
return false;
|
||||
return qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
struct qla27xx_fwdt_entry_call {
|
||||
static struct {
|
||||
uint type;
|
||||
int (*call)(
|
||||
struct scsi_qla_host *,
|
||||
struct qla27xx_fwdt_entry *,
|
||||
void *,
|
||||
ulong *);
|
||||
typeof(qla27xx_fwdt_entry_other)(*call);
|
||||
} qla27xx_fwdt_entry_call[] = {
|
||||
{ ENTRY_TYPE_NOP, qla27xx_fwdt_entry_t0 },
|
||||
{ ENTRY_TYPE_TMP_END, qla27xx_fwdt_entry_t255 },
|
||||
{ ENTRY_TYPE_RD_IOB_T1, qla27xx_fwdt_entry_t256 },
|
||||
{ ENTRY_TYPE_WR_IOB_T1, qla27xx_fwdt_entry_t257 },
|
||||
{ ENTRY_TYPE_RD_IOB_T2, qla27xx_fwdt_entry_t258 },
|
||||
{ ENTRY_TYPE_WR_IOB_T2, qla27xx_fwdt_entry_t259 },
|
||||
{ ENTRY_TYPE_RD_PCI, qla27xx_fwdt_entry_t260 },
|
||||
{ ENTRY_TYPE_WR_PCI, qla27xx_fwdt_entry_t261 },
|
||||
{ ENTRY_TYPE_RD_RAM, qla27xx_fwdt_entry_t262 },
|
||||
{ ENTRY_TYPE_GET_QUEUE, qla27xx_fwdt_entry_t263 },
|
||||
{ ENTRY_TYPE_GET_FCE, qla27xx_fwdt_entry_t264 },
|
||||
{ ENTRY_TYPE_PSE_RISC, qla27xx_fwdt_entry_t265 },
|
||||
{ ENTRY_TYPE_RST_RISC, qla27xx_fwdt_entry_t266 },
|
||||
{ ENTRY_TYPE_DIS_INTR, qla27xx_fwdt_entry_t267 },
|
||||
{ ENTRY_TYPE_GET_HBUF, qla27xx_fwdt_entry_t268 },
|
||||
{ ENTRY_TYPE_SCRATCH, qla27xx_fwdt_entry_t269 },
|
||||
{ ENTRY_TYPE_RDREMREG, qla27xx_fwdt_entry_t270 },
|
||||
{ ENTRY_TYPE_WRREMREG, qla27xx_fwdt_entry_t271 },
|
||||
{ ENTRY_TYPE_RDREMRAM, qla27xx_fwdt_entry_t272 },
|
||||
{ ENTRY_TYPE_PCICFG, qla27xx_fwdt_entry_t273 },
|
||||
{ ENTRY_TYPE_GET_SHADOW, qla27xx_fwdt_entry_t274 },
|
||||
{ ENTRY_TYPE_WRITE_BUF, qla27xx_fwdt_entry_t275 },
|
||||
{ ENTRY_TYPE_CONDITIONAL, qla27xx_fwdt_entry_t276 },
|
||||
{ ENTRY_TYPE_RDPEPREG, qla27xx_fwdt_entry_t277 },
|
||||
{ ENTRY_TYPE_WRPEPREG, qla27xx_fwdt_entry_t278 },
|
||||
{ -1, qla27xx_fwdt_entry_other }
|
||||
};
|
||||
|
||||
static struct qla27xx_fwdt_entry_call ql27xx_fwdt_entry_call_list[] = {
|
||||
{ ENTRY_TYPE_NOP , qla27xx_fwdt_entry_t0 } ,
|
||||
{ ENTRY_TYPE_TMP_END , qla27xx_fwdt_entry_t255 } ,
|
||||
{ ENTRY_TYPE_RD_IOB_T1 , qla27xx_fwdt_entry_t256 } ,
|
||||
{ ENTRY_TYPE_WR_IOB_T1 , qla27xx_fwdt_entry_t257 } ,
|
||||
{ ENTRY_TYPE_RD_IOB_T2 , qla27xx_fwdt_entry_t258 } ,
|
||||
{ ENTRY_TYPE_WR_IOB_T2 , qla27xx_fwdt_entry_t259 } ,
|
||||
{ ENTRY_TYPE_RD_PCI , qla27xx_fwdt_entry_t260 } ,
|
||||
{ ENTRY_TYPE_WR_PCI , qla27xx_fwdt_entry_t261 } ,
|
||||
{ ENTRY_TYPE_RD_RAM , qla27xx_fwdt_entry_t262 } ,
|
||||
{ ENTRY_TYPE_GET_QUEUE , qla27xx_fwdt_entry_t263 } ,
|
||||
{ ENTRY_TYPE_GET_FCE , qla27xx_fwdt_entry_t264 } ,
|
||||
{ ENTRY_TYPE_PSE_RISC , qla27xx_fwdt_entry_t265 } ,
|
||||
{ ENTRY_TYPE_RST_RISC , qla27xx_fwdt_entry_t266 } ,
|
||||
{ ENTRY_TYPE_DIS_INTR , qla27xx_fwdt_entry_t267 } ,
|
||||
{ ENTRY_TYPE_GET_HBUF , qla27xx_fwdt_entry_t268 } ,
|
||||
{ ENTRY_TYPE_SCRATCH , qla27xx_fwdt_entry_t269 } ,
|
||||
{ ENTRY_TYPE_RDREMREG , qla27xx_fwdt_entry_t270 } ,
|
||||
{ ENTRY_TYPE_WRREMREG , qla27xx_fwdt_entry_t271 } ,
|
||||
{ ENTRY_TYPE_RDREMRAM , qla27xx_fwdt_entry_t272 } ,
|
||||
{ ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } ,
|
||||
{ ENTRY_TYPE_GET_SHADOW , qla27xx_fwdt_entry_t274 } ,
|
||||
{ ENTRY_TYPE_WRITE_BUF , qla27xx_fwdt_entry_t275 } ,
|
||||
{ -1 , qla27xx_fwdt_entry_other }
|
||||
};
|
||||
|
||||
static inline int (*qla27xx_find_entry(uint type))
|
||||
(struct scsi_qla_host *, struct qla27xx_fwdt_entry *, void *, ulong *)
|
||||
static inline
|
||||
typeof(qla27xx_fwdt_entry_call->call)(qla27xx_find_entry(uint type))
|
||||
{
|
||||
struct qla27xx_fwdt_entry_call *list = ql27xx_fwdt_entry_call_list;
|
||||
typeof(*qla27xx_fwdt_entry_call) *list = qla27xx_fwdt_entry_call;
|
||||
|
||||
while (list->type < type)
|
||||
list++;
|
||||
@@ -834,14 +889,6 @@ static inline int (*qla27xx_find_entry(uint type))
|
||||
return qla27xx_fwdt_entry_other;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
qla27xx_next_entry(void *p)
|
||||
{
|
||||
struct qla27xx_fwdt_entry *ent = p;
|
||||
|
||||
return p + ent->hdr.entry_size;
|
||||
}
|
||||
|
||||
static void
|
||||
qla27xx_walk_template(struct scsi_qla_host *vha,
|
||||
struct qla27xx_fwdt_template *tmp, void *buf, ulong *len)
|
||||
@@ -852,18 +899,16 @@ qla27xx_walk_template(struct scsi_qla_host *vha,
|
||||
ql_dbg(ql_dbg_misc, vha, 0xd01a,
|
||||
"%s: entry count %lx\n", __func__, count);
|
||||
while (count--) {
|
||||
if (buf && *len >= vha->hw->fw_dump_len)
|
||||
ent = qla27xx_find_entry(ent->hdr.type)(vha, ent, buf, len);
|
||||
if (!ent)
|
||||
break;
|
||||
if (qla27xx_find_entry(ent->hdr.entry_type)(vha, ent, buf, len))
|
||||
break;
|
||||
ent = qla27xx_next_entry(ent);
|
||||
}
|
||||
|
||||
if (count)
|
||||
ql_dbg(ql_dbg_misc, vha, 0xd018,
|
||||
"%s: entry residual count (%lx)\n", __func__, count);
|
||||
|
||||
if (ent->hdr.entry_type != ENTRY_TYPE_TMP_END)
|
||||
if (ent)
|
||||
ql_dbg(ql_dbg_misc, vha, 0xd019,
|
||||
"%s: missing end entry (%lx)\n", __func__, count);
|
||||
|
||||
@@ -1037,8 +1082,10 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
|
||||
ql_log(ql_log_warn, vha, 0xd300,
|
||||
"Firmware has been previously dumped (%p),"
|
||||
" -- ignoring request\n", vha->hw->fw_dump);
|
||||
else
|
||||
else {
|
||||
QLA_FW_STOPPED(vha->hw);
|
||||
qla27xx_execute_fwdt_template(vha);
|
||||
}
|
||||
|
||||
#ifndef __CHECKER__
|
||||
if (!hardware_locked)
|
||||
|
||||
@@ -54,6 +54,9 @@ struct __packed qla27xx_fwdt_template {
|
||||
#define ENTRY_TYPE_PCICFG 273
|
||||
#define ENTRY_TYPE_GET_SHADOW 274
|
||||
#define ENTRY_TYPE_WRITE_BUF 275
|
||||
#define ENTRY_TYPE_CONDITIONAL 276
|
||||
#define ENTRY_TYPE_RDPEPREG 277
|
||||
#define ENTRY_TYPE_WRPEPREG 278
|
||||
|
||||
#define CAPTURE_FLAG_PHYS_ONLY BIT_0
|
||||
#define CAPTURE_FLAG_PHYS_VIRT BIT_1
|
||||
@@ -62,8 +65,8 @@ struct __packed qla27xx_fwdt_template {
|
||||
|
||||
struct __packed qla27xx_fwdt_entry {
|
||||
struct __packed {
|
||||
uint32_t entry_type;
|
||||
uint32_t entry_size;
|
||||
uint32_t type;
|
||||
uint32_t size;
|
||||
uint32_t reserved_1;
|
||||
|
||||
uint8_t capture_flags;
|
||||
@@ -199,6 +202,24 @@ struct __packed qla27xx_fwdt_entry {
|
||||
uint32_t length;
|
||||
uint8_t buffer[];
|
||||
} t275;
|
||||
|
||||
struct __packed {
|
||||
uint32_t cond1;
|
||||
uint32_t cond2;
|
||||
} t276;
|
||||
|
||||
struct __packed {
|
||||
uint32_t cmd_addr;
|
||||
uint32_t wr_cmd_data;
|
||||
uint32_t data_addr;
|
||||
} t277;
|
||||
|
||||
struct __packed {
|
||||
uint32_t cmd_addr;
|
||||
uint32_t wr_cmd_data;
|
||||
uint32_t data_addr;
|
||||
uint32_t wr_data;
|
||||
} t278;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -206,6 +227,7 @@ struct __packed qla27xx_fwdt_entry {
|
||||
#define T262_RAM_AREA_EXTERNAL_RAM 2
|
||||
#define T262_RAM_AREA_SHARED_RAM 3
|
||||
#define T262_RAM_AREA_DDR_RAM 4
|
||||
#define T262_RAM_AREA_MISC 5
|
||||
|
||||
#define T263_QUEUE_TYPE_REQ 1
|
||||
#define T263_QUEUE_TYPE_RSP 2
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/*
|
||||
* Driver version
|
||||
*/
|
||||
#define QLA2XXX_VERSION "10.00.00.07-k"
|
||||
#define QLA2XXX_VERSION "10.00.00.14-k"
|
||||
|
||||
#define QLA_DRIVER_MAJOR_VER 10
|
||||
#define QLA_DRIVER_MINOR_VER 0
|
||||
|
||||
Reference in New Issue
Block a user