drivers/ata/sata_promise.c

Source file repositories/reference/linux-study-clean/drivers/ata/sata_promise.c

File Facts

System
Linux kernel
Corpus path
drivers/ata/sata_promise.c
Extension
.c
Size
34082 bytes
Lines
1232
Domain
Driver Families
Bucket
drivers/ata
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static struct pci_driver pdc_ata_pci_driver = {
	.name			= DRV_NAME,
	.id_table		= pdc_ata_pci_tbl,
	.probe			= pdc_ata_init_one,
	.remove			= ata_pci_remove_one,
};

static int pdc_common_port_start(struct ata_port *ap)
{
	struct device *dev = ap->host->dev;
	struct pdc_port_priv *pp;
	int rc;

	/* we use the same prd table as bmdma, allocate it */
	rc = ata_bmdma_port_start(ap);
	if (rc)
		return rc;

	pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
	if (!pp)
		return -ENOMEM;

	pp->pkt = dmam_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
	if (!pp->pkt)
		return -ENOMEM;

	ap->private_data = pp;

	return 0;
}

static int pdc_sata_port_start(struct ata_port *ap)
{
	int rc;

	rc = pdc_common_port_start(ap);
	if (rc)
		return rc;

	/* fix up PHYMODE4 align timing */
	if (ap->flags & PDC_FLAG_GEN_II) {
		void __iomem *sata_mmio = ap->ioaddr.scr_addr;
		unsigned int tmp;

		tmp = readl(sata_mmio + PDC_PHYMODE4);
		tmp = (tmp & ~3) | 1;	/* set bits 1:0 = 0:1 */
		writel(tmp, sata_mmio + PDC_PHYMODE4);
	}

	return 0;
}

static void pdc_fpdma_clear_interrupt_flag(struct ata_port *ap)
{
	void __iomem *sata_mmio = ap->ioaddr.scr_addr;
	u32 tmp;

	tmp = readl(sata_mmio + PDC_FPDMA_CTLSTAT);
	tmp |= PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG;
	tmp |= PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG;

	/* It's not allowed to write to the entire FPDMA_CTLSTAT register
	   when NCQ is running. So do a byte-sized write to bits 10 and 11. */
	writeb(tmp >> 8, sata_mmio + PDC_FPDMA_CTLSTAT + 1);
	readb(sata_mmio + PDC_FPDMA_CTLSTAT + 1); /* flush */
}

static void pdc_fpdma_reset(struct ata_port *ap)
{
	void __iomem *sata_mmio = ap->ioaddr.scr_addr;
	u8 tmp;

	tmp = (u8)readl(sata_mmio + PDC_FPDMA_CTLSTAT);
	tmp &= 0x7F;
	tmp |= PDC_FPDMA_CTLSTAT_RESET;
	writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
	readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
	udelay(100);
	tmp &= ~PDC_FPDMA_CTLSTAT_RESET;
	writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
	readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */

	pdc_fpdma_clear_interrupt_flag(ap);
}

static void pdc_not_at_command_packet_phase(struct ata_port *ap)
{
	void __iomem *sata_mmio = ap->ioaddr.scr_addr;
	unsigned int i;
	u32 tmp;

Annotation

Implementation Notes