Re: [CMT 12/16] qla4xxx: driver review ql4_nvram.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Only a few missing printk levels.

++doug
--
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.c b/drivers/scsi/qla4xxx/ql4_nvram.c
new file mode 100644
index 0000000..e28678d
--- /dev/null
+++ b/drivers/scsi/qla4xxx/ql4_nvram.c
@@ -0,0 +1,220 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2006 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+
+#define EEPROM_SIZE(ha) \
+    (IS_QLA4022(ha) ? FM93C86A_SIZE_16 : FM93C66A_SIZE_16)
+#define EEPROM_NO_ADDR_BITS(ha) \
+    (IS_QLA4022(ha) ? FM93C86A_NO_ADDR_BITS_16 : FM93C56A_NO_ADDR_BITS_16)
+#define EEPROM_NO_DATA_BITS(ha) FM93C56A_DATA_BITS_16
+
+static int
+FM93C56A_Select(scsi_qla_host_t * ha)
+{
+	DEBUG5(printk(KERN_ERR "FM93C56A_Select:\n"));
+
+	ha->eeprom_cmd_data = AUBURN_EEPROM_CS_1 | 0x000f0000;
+	WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data);
+	PCI_POSTING(ISP_NVRAM(ha));
+	return 1;
+}
+
+static int
+FM93C56A_Cmd(scsi_qla_host_t * ha, int cmd, int addr)
+{
+	int i;
+	int mask;
+	int dataBit;
+	int previousBit;
+
+	/* Clock in a zero, then do the start bit. */
+	WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1);
+	WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
+	    AUBURN_EEPROM_CLK_RISE);
+	WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 |
+	    AUBURN_EEPROM_CLK_FALL);
+	PCI_POSTING(ISP_NVRAM(ha));
+	mask = 1 << (FM93C56A_CMD_BITS - 1);
+
+	/* Force the previous data bit to be different. */
+	previousBit = 0xffff;
+	for (i = 0; i < FM93C56A_CMD_BITS; i++) {
+		dataBit =
+		    (cmd & mask) ? AUBURN_EEPROM_DO_1 : AUBURN_EEPROM_DO_0;
+		if (previousBit != dataBit) {
+
+			/*
+			 * If the bit changed, then change the DO state to
+			 * match.
+			 */
+			WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | dataBit);
+			previousBit = dataBit;
+		}
+		WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | dataBit |
+		    AUBURN_EEPROM_CLK_RISE);
+		WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | dataBit |
+		    AUBURN_EEPROM_CLK_FALL);
+		PCI_POSTING(ISP_NVRAM(ha));
+		cmd = cmd << 1;
+	}
+	mask = 1 << (EEPROM_NO_ADDR_BITS(ha) - 1);
+
+	/* Force the previous data bit to be different. */
+	previousBit = 0xffff;
+	for (i = 0; i < EEPROM_NO_ADDR_BITS(ha); i++) {
+		dataBit = addr & mask ? AUBURN_EEPROM_DO_1 : AUBURN_EEPROM_DO_0;
+		if (previousBit != dataBit) {
+			/*
+			 * If the bit changed, then change the DO state to
+			 * match.
+			 */
+			WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | dataBit);
+			previousBit = dataBit;
+		}
+		WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | dataBit |
+		    AUBURN_EEPROM_CLK_RISE);
+		WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data | dataBit |
+		    AUBURN_EEPROM_CLK_FALL);
+		PCI_POSTING(ISP_NVRAM(ha));
+		addr = addr << 1;
+	}
+	return 1;
+}
+
+static int
+FM93C56A_Deselect(scsi_qla_host_t * ha)
+{
+	ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000;
+	WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data);
+	PCI_POSTING(ISP_NVRAM(ha));
+	return 1;
+}
+
+static int
+FM93C56A_DataIn(scsi_qla_host_t * ha, unsigned short *value)
+{
+	int i;
+	int data = 0;
+	int dataBit;
+
+	/* Read the data bits
+	 * The first bit is a dummy.  Clock right over it. */
+	for (i = 0; i < EEPROM_NO_DATA_BITS(ha); i++) {
+		WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data |
+		    AUBURN_EEPROM_CLK_RISE);
+		WRT_REG_DWORD(ISP_NVRAM(ha), ha->eeprom_cmd_data |
+		    AUBURN_EEPROM_CLK_FALL);
+		dataBit =
+		    (RD_REG_DWORD(ISP_NVRAM(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0;
+		data = (data << 1) | dataBit;
+	}
+
+	*value = data;
+	return 1;
+}
+
+static int
+EEPROM_ReadWord(int eepromAddr, u16 * value, scsi_qla_host_t * ha)
+{
+	FM93C56A_Select(ha);
+	FM93C56A_Cmd(ha, FM93C56A_READ, eepromAddr);
+	FM93C56A_DataIn(ha, value);
+	FM93C56A_Deselect(ha);
+	return 1;
+}
+
+/* Hardware_lock must be set before calling */
+u16
+RD_NVRAM_WORD(scsi_qla_host_t * ha, int offset)
+{
+	u16 val;
+
+	/* NOTE: NVRAM uses half-word addresses */
+	EEPROM_ReadWord(offset, &val, ha);
+	return val;
+}
+
+int
+qla4xxx_is_nvram_configuration_valid(scsi_qla_host_t * ha)
+{
+	int status = QLA_ERROR;
+	uint16_t checksum = 0;
+	uint32_t index;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	for (index = 0; index < EEPROM_SIZE(ha); index++)
+		checksum += RD_NVRAM_WORD(ha, index);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	if (checksum == 0)
+		status = QLA_SUCCESS;
+
+	return status;
+}
+
+/*************************************************************************
+ *
+ *			Hardware Semaphore routines
+ *
+ *************************************************************************/
+int
+ql4xxx_sem_spinlock(scsi_qla_host_t * ha, u32 sem_mask, u32 sem_bits)
+{
+	uint32_t value;
+	unsigned long flags;
+
+	DEBUG2(printk("scsi%ld : Trying to get SEM lock - mask= 0x%x, code = "
+	    "0x%x\n", ha->host_no, sem_mask, sem_bits));

-EPRINTKMISSINGLEVEL

+	while (1) {
+		spin_lock_irqsave(&ha->hardware_lock, flags);
+		WRT_REG_DWORD(ISP_SEMAPHORE(ha), (sem_mask | sem_bits));
+		value = RD_REG_DWORD(ISP_SEMAPHORE(ha));
+		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		if ((value & (sem_mask >> 16)) == sem_bits) {
+			DEBUG2(printk("scsi%ld : Got SEM LOCK - mask= 0x%x, "
+			    "code = 0x%x\n", ha->host_no, sem_mask, sem_bits));

-EPRINTKMISSINGLEVEL

+			break;
+		}
+		msleep(100);
+	}
+	return 1;
+}
+
+void
+ql4xxx_sem_unlock(scsi_qla_host_t * ha, u32 sem_mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	WRT_REG_DWORD(ISP_SEMAPHORE(ha), sem_mask);
+	PCI_POSTING(ISP_SEMAPHORE(ha));
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	DEBUG2(printk("scsi%ld : UNLOCK SEM - mask= 0x%x\n", ha->host_no,
+	    sem_mask));

-EPRINTKMISSINGLEVEL

+}
+
+int
+ql4xxx_sem_lock(scsi_qla_host_t * ha, u32 sem_mask, u32 sem_bits)
+{
+	uint32_t value;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	WRT_REG_DWORD(ISP_SEMAPHORE(ha), (sem_mask | sem_bits));
+	value = RD_REG_DWORD(ISP_SEMAPHORE(ha));
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	if ((value & (sem_mask >> 16)) == sem_bits) {
+		DEBUG2(printk("scsi%ld : Got SEM LOCK - mask= 0x%x, code = "
+		    "0x%x, sema code=0x%x\n", ha->host_no, sem_mask, sem_bits,
+		    value));

-EPRINTKMISSINGLEVEL

+		return 1;
+	}
+	return 0;
+}
-
: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux