Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b867cf7 authored by Anirban Chakraborty's avatar Anirban Chakraborty Committed by James Bottomley
Browse files

[SCSI] qla2xxx: Refactor qla data structures



Following changes have been made to the qla2xxx FC driver in
preparation for the multi- queue and future SR IOV hardware.

1. scsi_qla_host structure has been changed to contain scsi host
   specific data only.

2. A new structure, qla_hw_data is created to contain HBA specific
   hardware data.

3. Request and response IO specific data strucures are created.

4. The global list of fcports for the hba is not maintained anymore,
   instead a fcport list is construted on per scsi_qla_host.

Signed-of-by: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent a9b589d9
Loading
Loading
Loading
Loading
+162 −136
Original line number Original line Diff line number Diff line
@@ -19,8 +19,9 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj,
			   struct bin_attribute *bin_attr,
			   struct bin_attribute *bin_attr,
			   char *buf, loff_t off, size_t count)
			   char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;


	if (ha->fw_dump_reading == 0)
	if (ha->fw_dump_reading == 0)
		return 0;
		return 0;
@@ -34,8 +35,9 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj,
			    struct bin_attribute *bin_attr,
			    struct bin_attribute *bin_attr,
			    char *buf, loff_t off, size_t count)
			    char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;
	int reading;
	int reading;


	if (off != 0)
	if (off != 0)
@@ -48,7 +50,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj,
			break;
			break;


		qla_printk(KERN_INFO, ha,
		qla_printk(KERN_INFO, ha,
		    "Firmware dump cleared on (%ld).\n", ha->host_no);
		    "Firmware dump cleared on (%ld).\n", vha->host_no);


		ha->fw_dump_reading = 0;
		ha->fw_dump_reading = 0;
		ha->fw_dumped = 0;
		ha->fw_dumped = 0;
@@ -59,14 +61,14 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj,


			qla_printk(KERN_INFO, ha,
			qla_printk(KERN_INFO, ha,
			    "Raw firmware dump ready for read on (%ld).\n",
			    "Raw firmware dump ready for read on (%ld).\n",
			    ha->host_no);
			    vha->host_no);
		}
		}
		break;
		break;
	case 2:
	case 2:
		qla2x00_alloc_fw_dump(ha);
		qla2x00_alloc_fw_dump(vha);
		break;
		break;
	case 3:
	case 3:
		qla2x00_system_error(ha);
		qla2x00_system_error(vha);
		break;
		break;
	}
	}
	return (count);
	return (count);
@@ -87,8 +89,9 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
			 struct bin_attribute *bin_attr,
			 struct bin_attribute *bin_attr,
			 char *buf, loff_t off, size_t count)
			 char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;


	if (!capable(CAP_SYS_ADMIN))
	if (!capable(CAP_SYS_ADMIN))
		return 0;
		return 0;
@@ -103,8 +106,9 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
			  struct bin_attribute *bin_attr,
			  struct bin_attribute *bin_attr,
			  char *buf, loff_t off, size_t count)
			  char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;
	uint16_t	cnt;
	uint16_t	cnt;


	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
@@ -134,11 +138,11 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
	}
	}


	/* Write NVRAM. */
	/* Write NVRAM. */
	ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
	ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
	ha->isp_ops->read_nvram(ha, (uint8_t *)ha->nvram, ha->nvram_base,
	ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
	    count);
	    count);


	set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
	set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);


	return (count);
	return (count);
}
}
@@ -158,8 +162,9 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj,
			  struct bin_attribute *bin_attr,
			  struct bin_attribute *bin_attr,
			  char *buf, loff_t off, size_t count)
			  char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;


	if (ha->optrom_state != QLA_SREADING)
	if (ha->optrom_state != QLA_SREADING)
		return 0;
		return 0;
@@ -173,8 +178,9 @@ qla2x00_sysfs_write_optrom(struct kobject *kobj,
			   struct bin_attribute *bin_attr,
			   struct bin_attribute *bin_attr,
			   char *buf, loff_t off, size_t count)
			   char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;


	if (ha->optrom_state != QLA_SWRITING)
	if (ha->optrom_state != QLA_SWRITING)
		return -EINVAL;
		return -EINVAL;
@@ -203,8 +209,10 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
			       struct bin_attribute *bin_attr,
			       struct bin_attribute *bin_attr,
			       char *buf, loff_t off, size_t count)
			       char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;

	uint32_t start = 0;
	uint32_t start = 0;
	uint32_t size = ha->optrom_size;
	uint32_t size = ha->optrom_size;
	int val, valid;
	int val, valid;
@@ -262,7 +270,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
		    ha->optrom_region_start, ha->optrom_region_size));
		    ha->optrom_region_start, ha->optrom_region_size));


		memset(ha->optrom_buffer, 0, ha->optrom_region_size);
		memset(ha->optrom_buffer, 0, ha->optrom_region_size);
		ha->isp_ops->read_optrom(ha, ha->optrom_buffer,
		ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
		    ha->optrom_region_start, ha->optrom_region_size);
		    ha->optrom_region_start, ha->optrom_region_size);
		break;
		break;
	case 2:
	case 2:
@@ -333,7 +341,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
		    "Writing flash region -- 0x%x/0x%x.\n",
		    "Writing flash region -- 0x%x/0x%x.\n",
		    ha->optrom_region_start, ha->optrom_region_size));
		    ha->optrom_region_start, ha->optrom_region_size));


		ha->isp_ops->write_optrom(ha, ha->optrom_buffer,
		ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
		    ha->optrom_region_start, ha->optrom_region_size);
		    ha->optrom_region_start, ha->optrom_region_size);
		break;
		break;
	default:
	default:
@@ -356,8 +364,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
		       struct bin_attribute *bin_attr,
		       struct bin_attribute *bin_attr,
		       char *buf, loff_t off, size_t count)
		       char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;


	if (!capable(CAP_SYS_ADMIN))
	if (!capable(CAP_SYS_ADMIN))
		return 0;
		return 0;
@@ -371,15 +380,16 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
			struct bin_attribute *bin_attr,
			struct bin_attribute *bin_attr,
			char *buf, loff_t off, size_t count)
			char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;


	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
		return 0;
		return 0;


	/* Write NVRAM. */
	/* Write NVRAM. */
	ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
	ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
	ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count);
	ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);


	return count;
	return count;
}
}
@@ -399,8 +409,9 @@ qla2x00_sysfs_read_sfp(struct kobject *kobj,
		       struct bin_attribute *bin_attr,
		       struct bin_attribute *bin_attr,
		       char *buf, loff_t off, size_t count)
		       char *buf, loff_t off, size_t count)
{
{
	struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	    struct device, kobj)));
	struct qla_hw_data *ha = vha->hw;
	uint16_t iter, addr, offset;
	uint16_t iter, addr, offset;
	int rval;
	int rval;


@@ -429,7 +440,7 @@ qla2x00_sysfs_read_sfp(struct kobject *kobj,
			offset = 0;
			offset = 0;
		}
		}


		rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset,
		rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, addr, offset,
		    SFP_BLOCK_SIZE);
		    SFP_BLOCK_SIZE);
		if (rval != QLA_SUCCESS) {
		if (rval != QLA_SUCCESS) {
			qla_printk(KERN_WARNING, ha,
			qla_printk(KERN_WARNING, ha,
@@ -469,30 +480,31 @@ static struct sysfs_entry {
};
};


void
void
qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
{
{
	struct Scsi_Host *host = ha->host;
	struct Scsi_Host *host = vha->host;
	struct sysfs_entry *iter;
	struct sysfs_entry *iter;
	int ret;
	int ret;


	for (iter = bin_file_entries; iter->name; iter++) {
	for (iter = bin_file_entries; iter->name; iter++) {
		if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
		if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw))
			continue;
			continue;


		ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
		ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
		    iter->attr);
		    iter->attr);
		if (ret)
		if (ret)
			qla_printk(KERN_INFO, ha,
			qla_printk(KERN_INFO, vha->hw,
			    "Unable to create sysfs %s binary attribute "
			    "Unable to create sysfs %s binary attribute "
			    "(%d).\n", iter->name, ret);
			    "(%d).\n", iter->name, ret);
	}
	}
}
}


void
void
qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
{
{
	struct Scsi_Host *host = ha->host;
	struct Scsi_Host *host = vha->host;
	struct sysfs_entry *iter;
	struct sysfs_entry *iter;
	struct qla_hw_data *ha = vha->hw;


	for (iter = bin_file_entries; iter->name; iter++) {
	for (iter = bin_file_entries; iter->name; iter++) {
		if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
		if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
@@ -503,7 +515,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
	}
	}


	if (ha->beacon_blink_led == 1)
	if (ha->beacon_blink_led == 1)
		ha->isp_ops->beacon_off(ha);
		ha->isp_ops->beacon_off(vha);
}
}


/* Scsi_Host attributes. */
/* Scsi_Host attributes. */
@@ -519,22 +531,24 @@ static ssize_t
qla2x00_fw_version_show(struct device *dev,
qla2x00_fw_version_show(struct device *dev,
			struct device_attribute *attr, char *buf)
			struct device_attribute *attr, char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	char fw_str[30];
	struct qla_hw_data *ha = vha->hw;
	char fw_str[128];


	return snprintf(buf, PAGE_SIZE, "%s\n",
	return snprintf(buf, PAGE_SIZE, "%s\n",
	    ha->isp_ops->fw_version_str(ha, fw_str));
	    ha->isp_ops->fw_version_str(vha, fw_str));
}
}


static ssize_t
static ssize_t
qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr,
qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr,
			char *buf)
			char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	struct qla_hw_data *ha = vha->hw;
	uint32_t sn;
	uint32_t sn;


	if (IS_FWI2_CAPABLE(ha)) {
	if (IS_FWI2_CAPABLE(ha)) {
		qla2xxx_get_vpd_field(ha, "SN", buf, PAGE_SIZE);
		qla2xxx_get_vpd_field(vha, "SN", buf, PAGE_SIZE);
		return snprintf(buf, PAGE_SIZE, "%s\n", buf);
		return snprintf(buf, PAGE_SIZE, "%s\n", buf);
	}
	}


@@ -547,15 +561,16 @@ static ssize_t
qla2x00_isp_name_show(struct device *dev, struct device_attribute *attr,
qla2x00_isp_name_show(struct device *dev, struct device_attribute *attr,
		      char *buf)
		      char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device);
	return snprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device);
}
}


static ssize_t
static ssize_t
qla2x00_isp_id_show(struct device *dev, struct device_attribute *attr,
qla2x00_isp_id_show(struct device *dev, struct device_attribute *attr,
		    char *buf)
		    char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	struct qla_hw_data *ha = vha->hw;
	return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
	return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
	    ha->product_id[0], ha->product_id[1], ha->product_id[2],
	    ha->product_id[0], ha->product_id[1], ha->product_id[2],
	    ha->product_id[3]);
	    ha->product_id[3]);
@@ -565,43 +580,44 @@ static ssize_t
qla2x00_model_name_show(struct device *dev, struct device_attribute *attr,
qla2x00_model_name_show(struct device *dev, struct device_attribute *attr,
			char *buf)
			char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number);
	return snprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_number);
}
}


static ssize_t
static ssize_t
qla2x00_model_desc_show(struct device *dev, struct device_attribute *attr,
qla2x00_model_desc_show(struct device *dev, struct device_attribute *attr,
			char *buf)
			char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	return snprintf(buf, PAGE_SIZE, "%s\n",
	return snprintf(buf, PAGE_SIZE, "%s\n",
	    ha->model_desc ? ha->model_desc: "");
	    vha->hw->model_desc ? vha->hw->model_desc : "");
}
}


static ssize_t
static ssize_t
qla2x00_pci_info_show(struct device *dev, struct device_attribute *attr,
qla2x00_pci_info_show(struct device *dev, struct device_attribute *attr,
		      char *buf)
		      char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	char pci_info[30];
	char pci_info[30];


	return snprintf(buf, PAGE_SIZE, "%s\n",
	return snprintf(buf, PAGE_SIZE, "%s\n",
	    ha->isp_ops->pci_info_str(ha, pci_info));
	    vha->hw->isp_ops->pci_info_str(vha, pci_info));
}
}


static ssize_t
static ssize_t
qla2x00_link_state_show(struct device *dev, struct device_attribute *attr,
qla2x00_link_state_show(struct device *dev, struct device_attribute *attr,
			char *buf)
			char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	struct qla_hw_data *ha = vha->hw;
	int len = 0;
	int len = 0;


	if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
	if (atomic_read(&vha->loop_state) == LOOP_DOWN ||
	    atomic_read(&ha->loop_state) == LOOP_DEAD)
	    atomic_read(&vha->loop_state) == LOOP_DEAD)
		len = snprintf(buf, PAGE_SIZE, "Link Down\n");
		len = snprintf(buf, PAGE_SIZE, "Link Down\n");
	else if (atomic_read(&ha->loop_state) != LOOP_READY ||
	else if (atomic_read(&vha->loop_state) != LOOP_READY ||
	    test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
	    test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags))
	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
		len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
		len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
	else {
	else {
		len = snprintf(buf, PAGE_SIZE, "Link Up - ");
		len = snprintf(buf, PAGE_SIZE, "Link Up - ");
@@ -632,10 +648,10 @@ static ssize_t
qla2x00_zio_show(struct device *dev, struct device_attribute *attr,
qla2x00_zio_show(struct device *dev, struct device_attribute *attr,
		 char *buf)
		 char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	int len = 0;
	int len = 0;


	switch (ha->zio_mode) {
	switch (vha->hw->zio_mode) {
	case QLA_ZIO_MODE_6:
	case QLA_ZIO_MODE_6:
		len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
		len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n");
		break;
		break;
@@ -650,7 +666,8 @@ static ssize_t
qla2x00_zio_store(struct device *dev, struct device_attribute *attr,
qla2x00_zio_store(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
		  const char *buf, size_t count)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	struct qla_hw_data *ha = vha->hw;
	int val = 0;
	int val = 0;
	uint16_t zio_mode;
	uint16_t zio_mode;


@@ -668,7 +685,7 @@ qla2x00_zio_store(struct device *dev, struct device_attribute *attr,
	/* Update per-hba values and queue a reset. */
	/* Update per-hba values and queue a reset. */
	if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) {
	if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) {
		ha->zio_mode = zio_mode;
		ha->zio_mode = zio_mode;
		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
	}
	}
	return strlen(buf);
	return strlen(buf);
}
}
@@ -677,16 +694,16 @@ static ssize_t
qla2x00_zio_timer_show(struct device *dev, struct device_attribute *attr,
qla2x00_zio_timer_show(struct device *dev, struct device_attribute *attr,
		       char *buf)
		       char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));


	return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100);
	return snprintf(buf, PAGE_SIZE, "%d us\n", vha->hw->zio_timer * 100);
}
}


static ssize_t
static ssize_t
qla2x00_zio_timer_store(struct device *dev, struct device_attribute *attr,
qla2x00_zio_timer_store(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
			const char *buf, size_t count)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	int val = 0;
	int val = 0;
	uint16_t zio_timer;
	uint16_t zio_timer;


@@ -696,7 +713,7 @@ qla2x00_zio_timer_store(struct device *dev, struct device_attribute *attr,
		return -ERANGE;
		return -ERANGE;


	zio_timer = (uint16_t)(val / 100);
	zio_timer = (uint16_t)(val / 100);
	ha->zio_timer = zio_timer;
	vha->hw->zio_timer = zio_timer;


	return strlen(buf);
	return strlen(buf);
}
}
@@ -705,10 +722,10 @@ static ssize_t
qla2x00_beacon_show(struct device *dev, struct device_attribute *attr,
qla2x00_beacon_show(struct device *dev, struct device_attribute *attr,
		    char *buf)
		    char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	int len = 0;
	int len = 0;


	if (ha->beacon_blink_led)
	if (vha->hw->beacon_blink_led)
		len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n");
		len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n");
	else
	else
		len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
		len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n");
@@ -719,14 +736,15 @@ static ssize_t
qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
		     const char *buf, size_t count)
		     const char *buf, size_t count)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
	struct qla_hw_data *ha = vha->hw;
	int val = 0;
	int val = 0;
	int rval;
	int rval;


	if (IS_QLA2100(ha) || IS_QLA2200(ha))
	if (IS_QLA2100(ha) || IS_QLA2200(ha))
		return -EPERM;
		return -EPERM;


	if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) {
	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {
		qla_printk(KERN_WARNING, ha,
		qla_printk(KERN_WARNING, ha,
		    "Abort ISP active -- ignoring beacon request.\n");
		    "Abort ISP active -- ignoring beacon request.\n");
		return -EBUSY;
		return -EBUSY;
@@ -736,9 +754,9 @@ qla2x00_beacon_store(struct device *dev, struct device_attribute *attr,
		return -EINVAL;
		return -EINVAL;


	if (val)
	if (val)
		rval = ha->isp_ops->beacon_on(ha);
		rval = ha->isp_ops->beacon_on(vha);
	else
	else
		rval = ha->isp_ops->beacon_off(ha);
		rval = ha->isp_ops->beacon_off(vha);


	if (rval != QLA_SUCCESS)
	if (rval != QLA_SUCCESS)
		count = 0;
		count = 0;
@@ -750,8 +768,8 @@ static ssize_t
qla2x00_optrom_bios_version_show(struct device *dev,
qla2x00_optrom_bios_version_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
				 struct device_attribute *attr, char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

	struct qla_hw_data *ha = vha->hw;
	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],
	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],
	    ha->bios_revision[0]);
	    ha->bios_revision[0]);
}
}
@@ -760,8 +778,8 @@ static ssize_t
qla2x00_optrom_efi_version_show(struct device *dev,
qla2x00_optrom_efi_version_show(struct device *dev,
				struct device_attribute *attr, char *buf)
				struct device_attribute *attr, char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

	struct qla_hw_data *ha = vha->hw;
	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],
	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],
	    ha->efi_revision[0]);
	    ha->efi_revision[0]);
}
}
@@ -770,8 +788,8 @@ static ssize_t
qla2x00_optrom_fcode_version_show(struct device *dev,
qla2x00_optrom_fcode_version_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
				  struct device_attribute *attr, char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

	struct qla_hw_data *ha = vha->hw;
	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],
	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],
	    ha->fcode_revision[0]);
	    ha->fcode_revision[0]);
}
}
@@ -780,8 +798,8 @@ static ssize_t
qla2x00_optrom_fw_version_show(struct device *dev,
qla2x00_optrom_fw_version_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
			       struct device_attribute *attr, char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

	struct qla_hw_data *ha = vha->hw;
	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",
	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",
	    ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2],
	    ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2],
	    ha->fw_revision[3]);
	    ha->fw_revision[3]);
@@ -791,8 +809,8 @@ static ssize_t
qla2x00_total_isp_aborts_show(struct device *dev,
qla2x00_total_isp_aborts_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
			      struct device_attribute *attr, char *buf)
{
{
	scsi_qla_host_t *ha = shost_priv(class_to_shost(dev));
	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));

	struct qla_hw_data *ha = vha->hw;
	return snprintf(buf, PAGE_SIZE, "%d\n",
	return snprintf(buf, PAGE_SIZE, "%d\n",
	    ha->qla_stats.total_isp_aborts);
	    ha->qla_stats.total_isp_aborts);
}
}
@@ -848,16 +866,17 @@ struct device_attribute *qla2x00_host_attrs[] = {
static void
static void
qla2x00_get_host_port_id(struct Scsi_Host *shost)
qla2x00_get_host_port_id(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = shost_priv(shost);
	scsi_qla_host_t *vha = shost_priv(shost);


	fc_host_port_id(shost) = ha->d_id.b.domain << 16 |
	fc_host_port_id(shost) = vha->d_id.b.domain << 16 |
	    ha->d_id.b.area << 8 | ha->d_id.b.al_pa;
	    vha->d_id.b.area << 8 | vha->d_id.b.al_pa;
}
}


static void
static void
qla2x00_get_host_speed(struct Scsi_Host *shost)
qla2x00_get_host_speed(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
	struct qla_hw_data *ha = ((struct scsi_qla_host *)
					(shost_priv(shost)))->hw;
	u32 speed = FC_PORTSPEED_UNKNOWN;
	u32 speed = FC_PORTSPEED_UNKNOWN;


	switch (ha->link_data_rate) {
	switch (ha->link_data_rate) {
@@ -880,14 +899,14 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
static void
static void
qla2x00_get_host_port_type(struct Scsi_Host *shost)
qla2x00_get_host_port_type(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = shost_priv(shost);
	scsi_qla_host_t *vha = shost_priv(shost);
	uint32_t port_type = FC_PORTTYPE_UNKNOWN;
	uint32_t port_type = FC_PORTTYPE_UNKNOWN;


	if (ha->parent) {
	if (vha->vp_idx) {
		fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
		fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
		return;
		return;
	}
	}
	switch (ha->current_topology) {
	switch (vha->hw->current_topology) {
	case ISP_CFG_NL:
	case ISP_CFG_NL:
		port_type = FC_PORTTYPE_LPORT;
		port_type = FC_PORTTYPE_LPORT;
		break;
		break;
@@ -908,11 +927,11 @@ static void
qla2x00_get_starget_node_name(struct scsi_target *starget)
qla2x00_get_starget_node_name(struct scsi_target *starget)
{
{
	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
	scsi_qla_host_t *ha = shost_priv(host);
	scsi_qla_host_t *vha = shost_priv(host);
	fc_port_t *fcport;
	fc_port_t *fcport;
	u64 node_name = 0;
	u64 node_name = 0;


	list_for_each_entry(fcport, &ha->fcports, list) {
	list_for_each_entry(fcport, &vha->vp_fcports, list) {
		if (fcport->rport &&
		if (fcport->rport &&
		    starget->id == fcport->rport->scsi_target_id) {
		    starget->id == fcport->rport->scsi_target_id) {
			node_name = wwn_to_u64(fcport->node_name);
			node_name = wwn_to_u64(fcport->node_name);
@@ -927,11 +946,11 @@ static void
qla2x00_get_starget_port_name(struct scsi_target *starget)
qla2x00_get_starget_port_name(struct scsi_target *starget)
{
{
	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
	scsi_qla_host_t *ha = shost_priv(host);
	scsi_qla_host_t *vha = shost_priv(host);
	fc_port_t *fcport;
	fc_port_t *fcport;
	u64 port_name = 0;
	u64 port_name = 0;


	list_for_each_entry(fcport, &ha->fcports, list) {
	list_for_each_entry(fcport, &vha->vp_fcports, list) {
		if (fcport->rport &&
		if (fcport->rport &&
		    starget->id == fcport->rport->scsi_target_id) {
		    starget->id == fcport->rport->scsi_target_id) {
			port_name = wwn_to_u64(fcport->port_name);
			port_name = wwn_to_u64(fcport->port_name);
@@ -946,11 +965,11 @@ static void
qla2x00_get_starget_port_id(struct scsi_target *starget)
qla2x00_get_starget_port_id(struct scsi_target *starget)
{
{
	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
	struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
	scsi_qla_host_t *ha = shost_priv(host);
	scsi_qla_host_t *vha = shost_priv(host);
	fc_port_t *fcport;
	fc_port_t *fcport;
	uint32_t port_id = ~0U;
	uint32_t port_id = ~0U;


	list_for_each_entry(fcport, &ha->fcports, list) {
	list_for_each_entry(fcport, &vha->vp_fcports, list) {
		if (fcport->rport &&
		if (fcport->rport &&
		    starget->id == fcport->rport->scsi_target_id) {
		    starget->id == fcport->rport->scsi_target_id) {
			port_id = fcport->d_id.b.domain << 16 |
			port_id = fcport->d_id.b.domain << 16 |
@@ -999,9 +1018,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
	 * final cleanup of firmware resources (PCBs and XCBs).
	 * final cleanup of firmware resources (PCBs and XCBs).
	 */
	 */
	if (fcport->loop_id != FC_NO_LOOP_ID) {
	if (fcport->loop_id != FC_NO_LOOP_ID) {
		fcport->ha->isp_ops->fabric_logout(fcport->ha, fcport->loop_id,
		fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
		    fcport->d_id.b.domain, fcport->d_id.b.area,
			fcport->loop_id, fcport->d_id.b.domain,
		    fcport->d_id.b.al_pa);
			fcport->d_id.b.area, fcport->d_id.b.al_pa);
		fcport->loop_id = FC_NO_LOOP_ID;
		fcport->loop_id = FC_NO_LOOP_ID;
	}
	}


@@ -1011,16 +1030,18 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
static int
static int
qla2x00_issue_lip(struct Scsi_Host *shost)
qla2x00_issue_lip(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = shost_priv(shost);
	scsi_qla_host_t *vha = shost_priv(shost);


	qla2x00_loop_reset(ha);
	qla2x00_loop_reset(vha);
	return 0;
	return 0;
}
}


static struct fc_host_statistics *
static struct fc_host_statistics *
qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
	scsi_qla_host_t *vha = shost_priv(shost);
	struct qla_hw_data *ha = vha->hw;
	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
	int rval;
	int rval;
	struct link_statistics *stats;
	struct link_statistics *stats;
	dma_addr_t stats_dma;
	dma_addr_t stats_dma;
@@ -1032,21 +1053,21 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
	stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma);
	stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma);
	if (stats == NULL) {
	if (stats == NULL) {
		DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
		DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
		    __func__, ha->host_no));
		    __func__, base_vha->host_no));
		goto done;
		goto done;
	}
	}
	memset(stats, 0, DMA_POOL_SIZE);
	memset(stats, 0, DMA_POOL_SIZE);


	rval = QLA_FUNCTION_FAILED;
	rval = QLA_FUNCTION_FAILED;
	if (IS_FWI2_CAPABLE(ha)) {
	if (IS_FWI2_CAPABLE(ha)) {
		rval = qla24xx_get_isp_stats(ha, stats, stats_dma);
		rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma);
	} else if (atomic_read(&ha->loop_state) == LOOP_READY &&
	} else if (atomic_read(&base_vha->loop_state) == LOOP_READY &&
		    !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) &&
		    !test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) &&
		    !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) &&
		    !test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
		    !ha->dpc_active) {
		    !ha->dpc_active) {
		/* Must be in a 'READY' state for statistics retrieval. */
		/* Must be in a 'READY' state for statistics retrieval. */
		rval = qla2x00_get_link_status(ha, ha->loop_id, stats,
		rval = qla2x00_get_link_status(base_vha, base_vha->loop_id,
		    stats_dma);
						stats, stats_dma);
	}
	}


	if (rval != QLA_SUCCESS)
	if (rval != QLA_SUCCESS)
@@ -1077,29 +1098,29 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
static void
static void
qla2x00_get_host_symbolic_name(struct Scsi_Host *shost)
qla2x00_get_host_symbolic_name(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = shost_priv(shost);
	scsi_qla_host_t *vha = shost_priv(shost);


	qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost));
	qla2x00_get_sym_node_name(vha, fc_host_symbolic_name(shost));
}
}


static void
static void
qla2x00_set_host_system_hostname(struct Scsi_Host *shost)
qla2x00_set_host_system_hostname(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = shost_priv(shost);
	scsi_qla_host_t *vha = shost_priv(shost);


	set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
	set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
}
}


static void
static void
qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = shost_priv(shost);
	scsi_qla_host_t *vha = shost_priv(shost);
	u64 node_name;
	u64 node_name;


	if (ha->device_flags & SWITCH_FOUND)
	if (vha->device_flags & SWITCH_FOUND)
		node_name = wwn_to_u64(ha->fabric_node_name);
		node_name = wwn_to_u64(vha->fabric_node_name);
	else
	else
		node_name = wwn_to_u64(ha->node_name);
		node_name = wwn_to_u64(vha->node_name);


	fc_host_fabric_name(shost) = node_name;
	fc_host_fabric_name(shost) = node_name;
}
}
@@ -1107,11 +1128,12 @@ qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
static void
static void
qla2x00_get_host_port_state(struct Scsi_Host *shost)
qla2x00_get_host_port_state(struct Scsi_Host *shost)
{
{
	scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
	scsi_qla_host_t *vha = shost_priv(shost);
	struct scsi_qla_host *base_vha = pci_get_drvdata(vha->hw->pdev);


	if (!ha->flags.online)
	if (!base_vha->flags.online)
		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
	else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT)
	else if (atomic_read(&base_vha->loop_state) == LOOP_TIMEOUT)
		fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
		fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
	else
	else
		fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
		fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
@@ -1121,8 +1143,8 @@ static int
qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
{
{
	int	ret = 0;
	int	ret = 0;
	scsi_qla_host_t *ha = shost_priv(fc_vport->shost);
	scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
	scsi_qla_host_t *vha;
	scsi_qla_host_t *vha = NULL;


	ret = qla24xx_vport_create_req_sanity_check(fc_vport);
	ret = qla24xx_vport_create_req_sanity_check(fc_vport);
	if (ret) {
	if (ret) {
@@ -1144,18 +1166,19 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
		atomic_set(&vha->vp_state, VP_FAILED);
		atomic_set(&vha->vp_state, VP_FAILED);


	/* ready to create vport */
	/* ready to create vport */
	qla_printk(KERN_INFO, vha, "VP entry id %d assigned.\n", vha->vp_idx);
	qla_printk(KERN_INFO, vha->hw, "VP entry id %d assigned.\n",
							vha->vp_idx);


	/* initialized vport states */
	/* initialized vport states */
	atomic_set(&vha->loop_state, LOOP_DOWN);
	atomic_set(&vha->loop_state, LOOP_DOWN);
	vha->vp_err_state=  VP_ERR_PORTDWN;
	vha->vp_err_state=  VP_ERR_PORTDWN;
	vha->vp_prev_err_state=  VP_ERR_UNKWN;
	vha->vp_prev_err_state=  VP_ERR_UNKWN;
	/* Check if physical ha port is Up */
	/* Check if physical ha port is Up */
	if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
	if (atomic_read(&base_vha->loop_state) == LOOP_DOWN ||
	    atomic_read(&ha->loop_state) == LOOP_DEAD) {
	    atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
		/* Don't retry or attempt login of this virtual port */
		/* Don't retry or attempt login of this virtual port */
		DEBUG15(printk ("scsi(%ld): pport loop_state is not UP.\n",
		DEBUG15(printk ("scsi(%ld): pport loop_state is not UP.\n",
		    vha->host_no));
		    base_vha->host_no));
		atomic_set(&vha->loop_state, LOOP_DEAD);
		atomic_set(&vha->loop_state, LOOP_DEAD);
		if (!disable)
		if (!disable)
			fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
			fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN);
@@ -1171,9 +1194,9 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
	fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
	fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
	fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name);
	fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name);
	fc_host_supported_classes(vha->host) =
	fc_host_supported_classes(vha->host) =
		fc_host_supported_classes(ha->host);
		fc_host_supported_classes(base_vha->host);
	fc_host_supported_speeds(vha->host) =
	fc_host_supported_speeds(vha->host) =
		fc_host_supported_speeds(ha->host);
		fc_host_supported_speeds(base_vha->host);


	qla24xx_vport_disable(fc_vport, disable);
	qla24xx_vport_disable(fc_vport, disable);


@@ -1181,8 +1204,6 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
vport_create_failed_2:
vport_create_failed_2:
	qla24xx_disable_vp(vha);
	qla24xx_disable_vp(vha);
	qla24xx_deallocate_vp_id(vha);
	qla24xx_deallocate_vp_id(vha);
	kfree(vha->port_name);
	kfree(vha->node_name);
	scsi_host_put(vha->host);
	scsi_host_put(vha->host);
	return FC_VPORT_FAILED;
	return FC_VPORT_FAILED;
}
}
@@ -1191,17 +1212,25 @@ static int
qla24xx_vport_delete(struct fc_vport *fc_vport)
qla24xx_vport_delete(struct fc_vport *fc_vport)
{
{
	scsi_qla_host_t *vha = fc_vport->dd_data;
	scsi_qla_host_t *vha = fc_vport->dd_data;
	scsi_qla_host_t *pha = to_qla_parent(vha);
	fc_port_t *fcport, *tfcport;


	while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
	while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
	    test_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags))
	    test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
		msleep(1000);
		msleep(1000);


	qla24xx_disable_vp(vha);
	qla24xx_disable_vp(vha);
	qla24xx_deallocate_vp_id(vha);


	kfree(vha->node_name);
	fc_remove_host(vha->host);
	kfree(vha->port_name);

	scsi_remove_host(vha->host);

	list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) {
		list_del(&fcport->list);
		kfree(fcport);
		fcport = NULL;
	}

	qla24xx_deallocate_vp_id(vha);


	if (vha->timer_active) {
	if (vha->timer_active) {
		qla2x00_vp_stop_timer(vha);
		qla2x00_vp_stop_timer(vha);
@@ -1210,10 +1239,6 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
		    vha->host_no, vha->vp_idx, vha));
		    vha->host_no, vha->vp_idx, vha));
        }
        }


	fc_remove_host(vha->host);

	scsi_remove_host(vha->host);

	scsi_host_put(vha->host);
	scsi_host_put(vha->host);


	return 0;
	return 0;
@@ -1318,15 +1343,16 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
};
};


void
void
qla2x00_init_host_attr(scsi_qla_host_t *ha)
qla2x00_init_host_attr(scsi_qla_host_t *vha)
{
{
	struct qla_hw_data *ha = vha->hw;
	u32 speed = FC_PORTSPEED_UNKNOWN;
	u32 speed = FC_PORTSPEED_UNKNOWN;


	fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
	fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
	fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
	fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name);
	fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
	fc_host_supported_classes(vha->host) = FC_COS_CLASS3;
	fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;;
	fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
	fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count;
	fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;


	if (IS_QLA25XX(ha))
	if (IS_QLA25XX(ha))
		speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
		speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
@@ -1338,5 +1364,5 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha)
		speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
		speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
	else
	else
		speed = FC_PORTSPEED_1GBIT;
		speed = FC_PORTSPEED_1GBIT;
	fc_host_supported_speeds(ha->host) = speed;
	fc_host_supported_speeds(vha->host) = speed;
}
}
+33 −28

File changed.

Preview size limit exceeded, changes collapsed.

+278 −247

File changed.

Preview size limit exceeded, changes collapsed.

+13 −8
Original line number Original line Diff line number Diff line
@@ -15,10 +15,11 @@ static atomic_t qla2x00_dfs_root_count;
static int
static int
qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
{
{
	scsi_qla_host_t *ha = s->private;
	scsi_qla_host_t *vha = s->private;
	uint32_t cnt;
	uint32_t cnt;
	uint32_t *fce;
	uint32_t *fce;
	uint64_t fce_start;
	uint64_t fce_start;
	struct qla_hw_data *ha = vha->hw;


	mutex_lock(&ha->fce_mutex);
	mutex_lock(&ha->fce_mutex);


@@ -51,7 +52,8 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
static int
static int
qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
{
{
	scsi_qla_host_t *ha = inode->i_private;
	scsi_qla_host_t *vha = inode->i_private;
	struct qla_hw_data *ha = vha->hw;
	int rval;
	int rval;


	if (!ha->flags.fce_enabled)
	if (!ha->flags.fce_enabled)
@@ -60,7 +62,7 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
	mutex_lock(&ha->fce_mutex);
	mutex_lock(&ha->fce_mutex);


	/* Pause tracing to flush FCE buffers. */
	/* Pause tracing to flush FCE buffers. */
	rval = qla2x00_disable_fce_trace(ha, &ha->fce_wr, &ha->fce_rd);
	rval = qla2x00_disable_fce_trace(vha, &ha->fce_wr, &ha->fce_rd);
	if (rval)
	if (rval)
		qla_printk(KERN_WARNING, ha,
		qla_printk(KERN_WARNING, ha,
		    "DebugFS: Unable to disable FCE (%d).\n", rval);
		    "DebugFS: Unable to disable FCE (%d).\n", rval);
@@ -75,7 +77,8 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
static int
static int
qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
{
{
	scsi_qla_host_t *ha = inode->i_private;
	scsi_qla_host_t *vha = inode->i_private;
	struct qla_hw_data *ha = vha->hw;
	int rval;
	int rval;


	if (ha->flags.fce_enabled)
	if (ha->flags.fce_enabled)
@@ -86,7 +89,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
	/* Re-enable FCE tracing. */
	/* Re-enable FCE tracing. */
	ha->flags.fce_enabled = 1;
	ha->flags.fce_enabled = 1;
	memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
	memset(ha->fce, 0, fce_calc_size(ha->fce_bufs));
	rval = qla2x00_enable_fce_trace(ha, ha->fce_dma, ha->fce_bufs,
	rval = qla2x00_enable_fce_trace(vha, ha->fce_dma, ha->fce_bufs,
	    ha->fce_mb, &ha->fce_bufs);
	    ha->fce_mb, &ha->fce_bufs);
	if (rval) {
	if (rval) {
		qla_printk(KERN_WARNING, ha,
		qla_printk(KERN_WARNING, ha,
@@ -107,8 +110,9 @@ static const struct file_operations dfs_fce_ops = {
};
};


int
int
qla2x00_dfs_setup(scsi_qla_host_t *ha)
qla2x00_dfs_setup(scsi_qla_host_t *vha)
{
{
	struct qla_hw_data *ha = vha->hw;
	if (!IS_QLA25XX(ha))
	if (!IS_QLA25XX(ha))
		goto out;
		goto out;
	if (!ha->fce)
	if (!ha->fce)
@@ -130,7 +134,7 @@ qla2x00_dfs_setup(scsi_qla_host_t *ha)
		goto create_nodes;
		goto create_nodes;


	mutex_init(&ha->fce_mutex);
	mutex_init(&ha->fce_mutex);
	ha->dfs_dir = debugfs_create_dir(ha->host_str, qla2x00_dfs_root);
	ha->dfs_dir = debugfs_create_dir(vha->host_str, qla2x00_dfs_root);
	if (!ha->dfs_dir) {
	if (!ha->dfs_dir) {
		qla_printk(KERN_NOTICE, ha,
		qla_printk(KERN_NOTICE, ha,
		    "DebugFS: Unable to create ha directory.\n");
		    "DebugFS: Unable to create ha directory.\n");
@@ -152,8 +156,9 @@ qla2x00_dfs_setup(scsi_qla_host_t *ha)
}
}


int
int
qla2x00_dfs_remove(scsi_qla_host_t *ha)
qla2x00_dfs_remove(scsi_qla_host_t *vha)
{
{
	struct qla_hw_data *ha = vha->hw;
	if (ha->dfs_fce) {
	if (ha->dfs_fce) {
		debugfs_remove(ha->dfs_fce);
		debugfs_remove(ha->dfs_fce);
		ha->dfs_fce = NULL;
		ha->dfs_fce = NULL;
+8 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading