drivers/scsi/qla2xxx/qla_sup.c

Source file repositories/reference/linux-study-clean/drivers/scsi/qla2xxx/qla_sup.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/qla2xxx/qla_sup.c
Extension
.c
Size
97691 bytes
Lines
3712
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

while (data & NVR_BUSY) {
			udelay(100);
			data = rd_reg_word(&reg->nvram);
		}

		/* Lock resource */
		wrt_reg_word(&reg->u.isp2300.host_semaphore, 0x1);
		rd_reg_word(&reg->u.isp2300.host_semaphore);
		udelay(5);
		data = rd_reg_word(&reg->u.isp2300.host_semaphore);
		while ((data & BIT_0) == 0) {
			/* Lock failed */
			udelay(100);
			wrt_reg_word(&reg->u.isp2300.host_semaphore, 0x1);
			rd_reg_word(&reg->u.isp2300.host_semaphore);
			udelay(5);
			data = rd_reg_word(&reg->u.isp2300.host_semaphore);
		}
	}
}

/**
 * qla2x00_unlock_nvram_access() -
 * @ha: HA context
 */
static void
qla2x00_unlock_nvram_access(struct qla_hw_data *ha)
{
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;

	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
		wrt_reg_word(&reg->u.isp2300.host_semaphore, 0);
		rd_reg_word(&reg->u.isp2300.host_semaphore);
	}
}

/**
 * qla2x00_nv_write() - Prepare for NVRAM read/write operation.
 * @ha: HA context
 * @data: Serial interface selector
 */
static void
qla2x00_nv_write(struct qla_hw_data *ha, uint16_t data)
{
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;

	wrt_reg_word(&reg->nvram, data | NVR_SELECT | NVR_WRT_ENABLE);
	rd_reg_word(&reg->nvram);		/* PCI Posting. */
	NVRAM_DELAY();
	wrt_reg_word(&reg->nvram, data | NVR_SELECT | NVR_CLOCK |
	    NVR_WRT_ENABLE);
	rd_reg_word(&reg->nvram);		/* PCI Posting. */
	NVRAM_DELAY();
	wrt_reg_word(&reg->nvram, data | NVR_SELECT | NVR_WRT_ENABLE);
	rd_reg_word(&reg->nvram);		/* PCI Posting. */
	NVRAM_DELAY();
}

/**
 * qla2x00_nvram_request() - Sends read command to NVRAM and gets data from
 *	NVRAM.
 * @ha: HA context
 * @nv_cmd: NVRAM command
 *
 * Bit definitions for NVRAM command:
 *
 *	Bit 26     = start bit
 *	Bit 25, 24 = opcode
 *	Bit 23-16  = address
 *	Bit 15-0   = write data
 *
 * Returns the word read from nvram @addr.
 */
static uint16_t
qla2x00_nvram_request(struct qla_hw_data *ha, uint32_t nv_cmd)
{
	uint8_t		cnt;
	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
	uint16_t	data = 0;
	uint16_t	reg_data;

	/* Send command to NVRAM. */
	nv_cmd <<= 5;
	for (cnt = 0; cnt < 11; cnt++) {
		if (nv_cmd & BIT_31)
			qla2x00_nv_write(ha, NVR_DATA_OUT);
		else
			qla2x00_nv_write(ha, 0);
		nv_cmd <<= 1;
	}

Annotation

Implementation Notes