drivers/scsi/aic94xx/aic94xx_seq.c

Source file repositories/reference/linux-study-clean/drivers/scsi/aic94xx/aic94xx_seq.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/aic94xx/aic94xx_seq.c
Extension
.c
Size
46802 bytes
Lines
1402
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

if (le32_to_cpu(*prog) != val) {
			asd_printk("%s: cseq verify failed at %u "
				   "read:0x%x, wanted:0x%x\n",
				   pci_name(asd_ha->pcidev),
				   i, val, le32_to_cpu(*prog));
			return -1;
		}
	}
	ASD_DPRINTK("verified %d bytes, passed\n", size);
	return 0;
}

/**
 * asd_verify_lseq - verify the microcode of a link sequencer
 * @asd_ha: pointer to host adapter structure
 * @_prog: pointer to the microcode
 * @size: size of the microcode in bytes
 * @lseq: link sequencer of interest
 *
 * The link sequencer code is accessed in 4 KB pages, which are selected
 * by setting LmRAMPAGE (bits 8 and 9) of the LmBISTCTL1 register.
 * The 10 KB LSEQm instruction code is mapped, page at a time, at
 * LmSEQRAM address.
 */
static int asd_verify_lseq(struct asd_ha_struct *asd_ha, const u8 *_prog,
			   u32 size, int lseq)
{
#define LSEQ_CODEPAGE_SIZE 4096
	int pages =  (size + LSEQ_CODEPAGE_SIZE - 1) / LSEQ_CODEPAGE_SIZE;
	u32 page;
	const u32 *prog = (u32 *) _prog;

	for (page = 0; page < pages; page++) {
		u32 i;

		asd_write_reg_dword(asd_ha, LmBISTCTL1(lseq),
				    page << LmRAMPAGE_LSHIFT);
		for (i = 0; size > 0 && i < LSEQ_CODEPAGE_SIZE;
		     i += 4, prog++, size-=4) {

			u32 val = asd_read_reg_dword(asd_ha, LmSEQRAM(lseq)+i);

			if (le32_to_cpu(*prog) != val) {
				asd_printk("%s: LSEQ%d verify failed "
					   "page:%d, offs:%d\n",
					   pci_name(asd_ha->pcidev),
					   lseq, page, i);
				return -1;
			}
		}
	}
	ASD_DPRINTK("LSEQ%d verified %d bytes, passed\n", lseq,
		    (int)((u8 *)prog-_prog));
	return 0;
}

/**
 * asd_verify_seq -- verify CSEQ/LSEQ microcode
 * @asd_ha: pointer to host adapter structure
 * @prog: pointer to microcode
 * @size: size of the microcode
 * @lseq_mask: if 0, verify CSEQ microcode, else mask of LSEQs of interest
 *
 * Return 0 if microcode is correct, negative on mismatch.
 */
static int asd_verify_seq(struct asd_ha_struct *asd_ha, const u8 *prog,
			      u32 size, u8 lseq_mask)
{
	if (lseq_mask == 0)
		return asd_verify_cseq(asd_ha, prog, size);
	else {
		int lseq, err;

		for_each_sequencer(lseq_mask, lseq_mask, lseq) {
			err = asd_verify_lseq(asd_ha, prog, size, lseq);
			if (err)
				return err;
		}
	}

	return 0;
}
#define ASD_DMA_MODE_DOWNLOAD
#ifdef ASD_DMA_MODE_DOWNLOAD
/* This is the size of the CSEQ Mapped instruction page */
#define MAX_DMA_OVLY_COUNT ((1U << 14)-1)
static int asd_download_seq(struct asd_ha_struct *asd_ha,
			    const u8 * const prog, u32 size, u8 lseq_mask)
{
	u32 comstaten;

Annotation

Implementation Notes