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

Commit d915058f authored by David C Somayajulu's avatar David C Somayajulu Committed by James Bottomley
Browse files

[SCSI] qla4xxx: add support for qla4032



This patch provides the following:

1. adds support for the next version of Qlogic's iSCSI HBA, qla4032
   (PCI Device ID 4032).

2. removes dead code related to topcat chip and renames
   qla4010_soft_reset to qla4xxx_soft_reset (minor changes).

Signed-off-by: default avatarDavid Somayajulu <david.somayajulu@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 0bd2af46
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ void __dump_registers(struct scsi_qla_host *ha)
		       readw(&ha->reg->u1.isp4010.nvram));
	}

	else if (is_qla4022(ha)) {
	else if (is_qla4022(ha) | is_qla4032(ha)) {
		printk(KERN_INFO "0x%02X intr_mask	 = 0x%08X\n",
		       (uint8_t) offsetof(struct isp_reg,
					  u1.isp4022.intr_mask),
@@ -119,7 +119,7 @@ void __dump_registers(struct scsi_qla_host *ha)
		       readw(&ha->reg->u2.isp4010.port_err_status));
	}

	else if (is_qla4022(ha)) {
	else if (is_qla4022(ha) | is_qla4032(ha)) {
		printk(KERN_INFO "Page 0 Registers:\n");
		printk(KERN_INFO "0x%02X ext_hw_conf	 = 0x%08X\n",
		       (uint8_t) offsetof(struct isp_reg,
+57 −48
Original line number Diff line number Diff line
@@ -40,7 +40,11 @@

#ifndef PCI_DEVICE_ID_QLOGIC_ISP4022
#define PCI_DEVICE_ID_QLOGIC_ISP4022	0x4022
#endif				/*  */
#endif

#ifndef PCI_DEVICE_ID_QLOGIC_ISP4032
#define PCI_DEVICE_ID_QLOGIC_ISP4032	0x4032
#endif

#define QLA_SUCCESS			0
#define QLA_ERROR			1
@@ -277,7 +281,6 @@ struct scsi_qla_host {
#define AF_INTERRUPTS_ON	      6 /* 0x00000040 Not Used */
#define AF_GET_CRASH_RECORD	      7 /* 0x00000080 */
#define AF_LINK_UP		      8 /* 0x00000100 */
#define AF_TOPCAT_CHIP_PRESENT	      9 /* 0x00000200 */
#define AF_IRQ_ATTACHED		     10 /* 0x00000400 */
#define AF_ISNS_CMD_IN_PROCESS	     12 /* 0x00001000 */
#define AF_ISNS_CMD_DONE	     13 /* 0x00002000 */
@@ -317,16 +320,17 @@ struct scsi_qla_host {
	/* NVRAM registers */
	struct eeprom_data *nvram;
	spinlock_t hardware_lock ____cacheline_aligned;
	spinlock_t list_lock;
	uint32_t   eeprom_cmd_data;

	/* Counters for general statistics */
	uint64_t isr_count;
	uint64_t adapter_error_count;
	uint64_t device_error_count;
	uint64_t total_io_count;
	uint64_t total_mbytes_xferred;
	uint64_t link_failure_count;
	uint64_t invalid_crc_count;
	uint32_t bytes_xfered;
	uint32_t spurious_int_count;
	uint32_t aborted_io_count;
	uint32_t io_timeout_count;
@@ -438,6 +442,11 @@ static inline int is_qla4022(struct scsi_qla_host *ha)
	return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022;
}

static inline int is_qla4032(struct scsi_qla_host *ha)
{
	return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4032;
}

static inline int adapter_up(struct scsi_qla_host *ha)
{
	return (test_bit(AF_ONLINE, &ha->flags) != 0) &&
@@ -451,58 +460,58 @@ static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost)

static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		&ha->reg->u1.isp4022.semaphore :
		&ha->reg->u1.isp4010.nvram);
	return (is_qla4010(ha) ?
		&ha->reg->u1.isp4010.nvram :
		&ha->reg->u1.isp4022.semaphore);
}

static inline void __iomem* isp_nvram(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		&ha->reg->u1.isp4022.nvram :
		&ha->reg->u1.isp4010.nvram);
	return (is_qla4010(ha) ?
		&ha->reg->u1.isp4010.nvram :
		&ha->reg->u1.isp4022.nvram);
}

static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		&ha->reg->u2.isp4022.p0.ext_hw_conf :
		&ha->reg->u2.isp4010.ext_hw_conf);
	return (is_qla4010(ha) ?
		&ha->reg->u2.isp4010.ext_hw_conf :
		&ha->reg->u2.isp4022.p0.ext_hw_conf);
}

static inline void __iomem* isp_port_status(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		&ha->reg->u2.isp4022.p0.port_status :
		&ha->reg->u2.isp4010.port_status);
	return (is_qla4010(ha) ?
		&ha->reg->u2.isp4010.port_status :
		&ha->reg->u2.isp4022.p0.port_status);
}

static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		&ha->reg->u2.isp4022.p0.port_ctrl :
		&ha->reg->u2.isp4010.port_ctrl);
	return (is_qla4010(ha) ?
		&ha->reg->u2.isp4010.port_ctrl :
		&ha->reg->u2.isp4022.p0.port_ctrl);
}

static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		&ha->reg->u2.isp4022.p0.port_err_status :
		&ha->reg->u2.isp4010.port_err_status);
	return (is_qla4010(ha) ?
		&ha->reg->u2.isp4010.port_err_status :
		&ha->reg->u2.isp4022.p0.port_err_status);
}

static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		&ha->reg->u2.isp4022.p0.gp_out :
		&ha->reg->u2.isp4010.gp_out);
	return (is_qla4010(ha) ?
		&ha->reg->u2.isp4010.gp_out :
		&ha->reg->u2.isp4022.p0.gp_out);
}

static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha)
{
	return (is_qla4022(ha) ?
		offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2 :
		offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2);
	return (is_qla4010(ha) ?
		offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2 :
		offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2);
}

int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);
@@ -511,59 +520,59 @@ int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits);

static inline int ql4xxx_lock_flash(struct scsi_qla_host *a)
{
	if (is_qla4022(a))
	if (is_qla4010(a))
		return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK,
					   QL4010_FLASH_SEM_BITS);
	else
		return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK,
					   (QL4022_RESOURCE_BITS_BASE_CODE |
					    (a->mac_index)) << 13);
	else
		return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK,
					   QL4010_FLASH_SEM_BITS);
}

static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a)
{
	if (is_qla4022(a))
		ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK);
	else
	if (is_qla4010(a))
		ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK);
	else
		ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK);
}

static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a)
{
	if (is_qla4022(a))
	if (is_qla4010(a))
		return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK,
					   QL4010_NVRAM_SEM_BITS);
	else
		return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK,
					   (QL4022_RESOURCE_BITS_BASE_CODE |
					    (a->mac_index)) << 10);
	else
		return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK,
					   QL4010_NVRAM_SEM_BITS);
}

static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a)
{
	if (is_qla4022(a))
		ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK);
	else
	if (is_qla4010(a))
		ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK);
	else
		ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK);
}

static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a)
{
	if (is_qla4022(a))
	if (is_qla4010(a))
		return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK,
				       QL4010_DRVR_SEM_BITS);
	else
		return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK,
				       (QL4022_RESOURCE_BITS_BASE_CODE |
					(a->mac_index)) << 1);
	else
		return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK,
				       QL4010_DRVR_SEM_BITS);
}

static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a)
{
	if (is_qla4022(a))
		ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK);
	else
	if (is_qla4010(a))
		ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK);
	else
		ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK);
}

/*---------------------------------------------------------------------------*/
+6 −1
Original line number Diff line number Diff line
@@ -296,7 +296,6 @@ static inline uint32_t clr_rmask(uint32_t val)
/*  ISP Semaphore definitions */

/*  ISP General Purpose Output definitions */
#define GPOR_TOPCAT_RESET			0x00000004

/*  shadow registers (DMA'd from HA to system memory.  read only) */
struct shadow_regs {
@@ -339,10 +338,13 @@ union external_hw_config_reg {
/*  Mailbox command definitions */
#define MBOX_CMD_ABOUT_FW			0x0009
#define MBOX_CMD_LUN_RESET			0x0016
#define MBOX_CMD_GET_MANAGEMENT_DATA		0x001E
#define MBOX_CMD_GET_FW_STATUS			0x001F
#define MBOX_CMD_SET_ISNS_SERVICE		0x0021
#define ISNS_DISABLE				0
#define ISNS_ENABLE				1
#define MBOX_CMD_COPY_FLASH			0x0024
#define MBOX_CMD_WRITE_FLASH			0x0025
#define MBOX_CMD_READ_FLASH			0x0026
#define MBOX_CMD_CLEAR_DATABASE_ENTRY		0x0031
#define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT		0x0056
@@ -360,10 +362,13 @@ union external_hw_config_reg {
#define DDB_DS_SESSION_FAILED			0x06
#define DDB_DS_LOGIN_IN_PROCESS			0x07
#define MBOX_CMD_GET_FW_STATE			0x0069
#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK_DEFAULTS 0x006A
#define MBOX_CMD_RESTORE_FACTORY_DEFAULTS	0x0087

/* Mailbox 1 */
#define FW_STATE_READY				0x0000
#define FW_STATE_CONFIG_WAIT			0x0001
#define FW_STATE_WAIT_LOGIN			0x0002
#define FW_STATE_ERROR				0x0004
#define FW_STATE_DHCP_IN_PROGRESS		0x0008

+10 −35
Original line number Diff line number Diff line
@@ -259,10 +259,16 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha)
			      "seconds expired= %d\n", ha->host_no, __func__,
			      ha->firmware_state, ha->addl_fw_state,
			      timeout_count));
		if (is_qla4032(ha) &&
			!(ha->addl_fw_state & FW_ADDSTATE_LINK_UP) &&
			(timeout_count < ADAPTER_INIT_TOV - 5)) {
			break;
		}

		msleep(1000);
	}			/* end of for */

	if (timeout_count <= 0)
	if (timeout_count == 0)
		DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n",
			      ha->host_no, __func__));

@@ -806,32 +812,6 @@ int qla4xxx_relogin_device(struct scsi_qla_host *ha,
	return QLA_SUCCESS;
}

/**
 * qla4010_get_topcat_presence - check if it is QLA4040 TopCat Chip
 * @ha: Pointer to host adapter structure.
 *
 **/
static int qla4010_get_topcat_presence(struct scsi_qla_host *ha)
{
	unsigned long flags;
	uint16_t topcat;

	if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS)
		return QLA_ERROR;
	spin_lock_irqsave(&ha->hardware_lock, flags);
	topcat = rd_nvram_word(ha, offsetof(struct eeprom_data,
					    isp4010.topcat));
	spin_unlock_irqrestore(&ha->hardware_lock, flags);

	if ((topcat & TOPCAT_MASK) == TOPCAT_PRESENT)
		set_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags);
	else
		clear_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags);
	ql4xxx_unlock_nvram(ha);
	return QLA_SUCCESS;
}


static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
{
	unsigned long flags;
@@ -866,7 +846,7 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
		/* set defaults */
		if (is_qla4010(ha))
			extHwConfig.Asuint32_t = 0x1912;
		else if (is_qla4022(ha))
		else if (is_qla4022(ha) | is_qla4032(ha))
			extHwConfig.Asuint32_t = 0x0023;
	}
	DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n",
@@ -927,7 +907,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha)

	spin_lock_irqsave(&ha->hardware_lock, flags);
	writel(jiffies, &ha->reg->mailbox[7]);
	if (is_qla4022(ha))
	if (is_qla4022(ha) | is_qla4032(ha))
		writel(set_rmask(NVR_WRITE_ENABLE),
		       &ha->reg->u1.isp4022.nvram);

@@ -1018,12 +998,7 @@ static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
	int soft_reset = 1;
	int config_chip = 0;

	if (is_qla4010(ha)){
		if (qla4010_get_topcat_presence(ha) != QLA_SUCCESS)
			return QLA_ERROR;
	}

	if (is_qla4022(ha))
	if (is_qla4022(ha) | is_qla4032(ha))
		ql4xxx_set_mac_number(ha);

	if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS)
+2 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ qla4xxx_lookup_ddb_by_fw_index(struct scsi_qla_host *ha, uint32_t fw_ddb_index)
static inline void
__qla4xxx_enable_intrs(struct scsi_qla_host *ha)
{
	if (is_qla4022(ha)) {
	if (is_qla4022(ha) | is_qla4032(ha)) {
		writel(set_rmask(IMR_SCSI_INTR_ENABLE),
		       &ha->reg->u1.isp4022.intr_mask);
		readl(&ha->reg->u1.isp4022.intr_mask);
@@ -52,7 +52,7 @@ __qla4xxx_enable_intrs(struct scsi_qla_host *ha)
static inline void
__qla4xxx_disable_intrs(struct scsi_qla_host *ha)
{
	if (is_qla4022(ha)) {
	if (is_qla4022(ha) | is_qla4032(ha)) {
		writel(clr_rmask(IMR_SCSI_INTR_ENABLE),
		       &ha->reg->u1.isp4022.intr_mask);
		readl(&ha->reg->u1.isp4022.intr_mask);
Loading