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.
- 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/gfp.hlinux/pci.hlinux/blkdev.hlinux/delay.hlinux/interrupt.hlinux/device.hscsi/scsi.hscsi/scsi_host.hscsi/scsi_cmnd.hlinux/libata.hsata_promise.h
Detected Declarations
struct pdc_port_privstruct pdc_host_privfunction pdc_common_port_startfunction pdc_sata_port_startfunction pdc_fpdma_clear_interrupt_flagfunction pdc_fpdma_resetfunction pdc_not_at_command_packet_phasefunction pdc_clear_internal_debug_record_error_registerfunction pdc_reset_portfunction pdc_pata_cable_detectfunction pdc_sata_scr_readfunction pdc_sata_scr_writefunction pdc_atapi_pktfunction idfunction PRDfunction pdc_qc_prepfunction pdc_is_sataii_tx4function pdc_port_no_to_ata_nofunction pdc_sata_nr_portsfunction pdc_sata_ata_port_to_ata_nofunction pdc_freezefunction pdc_sata_freezefunction pdc_thawfunction pdc_sata_thawfunction pdc_pata_softresetfunction pdc_ata_port_to_ata_nofunction pdc_hard_reset_portfunction pdc_sata_hardresetfunction pdc_error_handlerfunction pdc_post_internal_cmdfunction pdc_error_intrfunction pdc_host_intrfunction pdc_irq_clearfunction pdc_interruptfunction pdc_packet_startfunction pdc_qc_issuefunction pdc_tf_load_mmiofunction pdc_exec_command_mmiofunction pdc_check_atapi_dmafunction pdc_old_sata_check_atapi_dmafunction pdc_ata_setup_portfunction pdc_host_initfunction pdc_ata_init_one
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
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/gfp.h`, `linux/pci.h`, `linux/blkdev.h`, `linux/delay.h`, `linux/interrupt.h`, `linux/device.h`.
- Detected declarations: `struct pdc_port_priv`, `struct pdc_host_priv`, `function pdc_common_port_start`, `function pdc_sata_port_start`, `function pdc_fpdma_clear_interrupt_flag`, `function pdc_fpdma_reset`, `function pdc_not_at_command_packet_phase`, `function pdc_clear_internal_debug_record_error_register`, `function pdc_reset_port`, `function pdc_pata_cable_detect`.
- Atlas domain: Driver Families / drivers/ata.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.