drivers/scsi/sun_esp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/scsi/sun_esp.c
Extension
.c
Size
13529 bytes
Lines
614
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 (can_do_sbus64) {
			esp->prev_hme_dmacsr |= DMA_SCSI_SBUS64;
			sbus_set_sbus64(&op->dev, esp->bursts);
		}

		lim = 1000;
		while (dma_read32(DMA_CSR) & DMA_PEND_READ) {
			if (--lim == 0) {
				printk(KERN_ALERT PFX "esp%d: DMA_PEND_READ "
				       "will not clear!\n",
				       esp->host->unique_id);
				break;
			}
			udelay(1);
		}

		dma_write32(0, DMA_CSR);
		dma_write32(esp->prev_hme_dmacsr, DMA_CSR);

		dma_write32(0, DMA_ADDR);
		break;

	case dvmarev2:
		if (esp->rev != ESP100) {
			val = dma_read32(DMA_CSR);
			dma_write32(val | DMA_3CLKS, DMA_CSR);
		}
		break;

	case dvmarev3:
		val = dma_read32(DMA_CSR);
		val &= ~DMA_3CLKS;
		val |= DMA_2CLKS;
		if (can_do_burst32) {
			val &= ~DMA_BRST_SZ;
			val |= DMA_BRST32;
		}
		dma_write32(val, DMA_CSR);
		break;

	case dvmaesc1:
		val = dma_read32(DMA_CSR);
		val |= DMA_ADD_ENABLE;
		val &= ~DMA_BCNT_ENAB;
		if (!can_do_burst32 && can_do_burst16) {
			val |= DMA_ESC_BURST;
		} else {
			val &= ~(DMA_ESC_BURST);
		}
		dma_write32(val, DMA_CSR);
		break;

	default:
		break;
	}

	/* Enable interrupts.  */
	val = dma_read32(DMA_CSR);
	dma_write32(val | DMA_INT_ENAB, DMA_CSR);
}

static void sbus_esp_dma_drain(struct esp *esp)
{
	u32 csr;
	int lim;

	if (esp->dmarev == dvmahme)
		return;

	csr = dma_read32(DMA_CSR);
	if (!(csr & DMA_FIFO_ISDRAIN))
		return;

	if (esp->dmarev != dvmarev3 && esp->dmarev != dvmaesc1)
		dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR);

	lim = 1000;
	while (dma_read32(DMA_CSR) & DMA_FIFO_ISDRAIN) {
		if (--lim == 0) {
			printk(KERN_ALERT PFX "esp%d: DMA will not drain!\n",
			       esp->host->unique_id);
			break;
		}
		udelay(1);
	}
}

static void sbus_esp_dma_invalidate(struct esp *esp)
{
	if (esp->dmarev == dvmahme) {

Annotation

Implementation Notes