drivers/pci/controller/pci-thunder-ecam.c

Source file repositories/reference/linux-study-clean/drivers/pci/controller/pci-thunder-ecam.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/pci-thunder-ecam.c
Extension
.c
Size
9468 bytes
Lines
366
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!has_msix && where_a == 0x70) {
			v |= 0xbc00; /* next capability is EA at 0xbc */
			set_val(v, where, size, val);
			return PCIBIOS_SUCCESSFUL;
		}
		if (where_a == 0xb0) {
			addr = bus->ops->map_bus(bus, devfn, where_a);
			if (!addr)
				return PCIBIOS_DEVICE_NOT_FOUND;

			v = readl(addr);
			if (v & 0xff00)
				pr_err("Bad MSI-X cap header: %08x\n", v);
			v |= 0xbc00; /* next capability is EA at 0xbc */
			set_val(v, where, size, val);
			return PCIBIOS_SUCCESSFUL;
		}
		if (where_a == 0xbc) {
			if (is_nic)
				v = 0x40014; /* EA last in chain, 4 entries */
			else if (is_tns)
				v = 0x30014; /* EA last in chain, 3 entries */
			else if (has_msix)
				v = 0x20014; /* EA last in chain, 2 entries */
			else
				v = 0x10014; /* EA last in chain, 1 entry */
			set_val(v, where, size, val);
			return PCIBIOS_SUCCESSFUL;
		}
		if (where_a >= 0xc0 && where_a < 0xd0)
			/* EA entry-0. PP=0, BAR0 Size:3 */
			return handle_ea_bar(0x80ff0003,
					     0x10, bus, devfn, where,
					     size, val);
		if (where_a >= 0xd0 && where_a < 0xe0 && has_msix)
			 /* EA entry-1. PP=0, BAR4 Size:3 */
			return handle_ea_bar(0x80ff0043,
					     0x20, bus, devfn, where,
					     size, val);
		if (where_a >= 0xe0 && where_a < 0xf0 && is_tns)
			/* EA entry-2. PP=0, BAR2, Size:3 */
			return handle_ea_bar(0x80ff0023,
					     0x18, bus, devfn, where,
					     size, val);
		if (where_a >= 0xe0 && where_a < 0xf0 && is_nic)
			/* EA entry-2. PP=4, VF_BAR0 (9), Size:3 */
			return handle_ea_bar(0x80ff0493,
					     0x1a4, bus, devfn, where,
					     size, val);
		if (where_a >= 0xf0 && where_a < 0x100 && is_nic)
			/* EA entry-3. PP=4, VF_BAR4 (d), Size:3 */
			return handle_ea_bar(0x80ff04d3,
					     0x1b4, bus, devfn, where,
					     size, val);
	} else if (cfg_type == 1) {
		bool is_rsl_bridge = devfn == 0x08;
		bool is_rad_bridge = devfn == 0xa0;
		bool is_zip_bridge = devfn == 0xa8;
		bool is_dfa_bridge = devfn == 0xb0;
		bool is_nic_bridge = devfn == 0x10;

		if (where_a == 0x70) {
			addr = bus->ops->map_bus(bus, devfn, where_a);
			if (!addr)
				return PCIBIOS_DEVICE_NOT_FOUND;

			v = readl(addr);
			if (v & 0xff00)
				pr_err("Bad PCIe cap header: %08x\n", v);
			v |= 0xbc00; /* next capability is EA at 0xbc */
			set_val(v, where, size, val);
			return PCIBIOS_SUCCESSFUL;
		}
		if (where_a == 0xbc) {
			if (is_nic_bridge)
				v = 0x10014; /* EA last in chain, 1 entry */
			else
				v = 0x00014; /* EA last in chain, no entries */
			set_val(v, where, size, val);
			return PCIBIOS_SUCCESSFUL;
		}
		if (where_a == 0xc0) {
			if (is_rsl_bridge || is_nic_bridge)
				v = 0x0101; /* subordinate:secondary = 1:1 */
			else if (is_rad_bridge)
				v = 0x0202; /* subordinate:secondary = 2:2 */
			else if (is_zip_bridge)
				v = 0x0303; /* subordinate:secondary = 3:3 */
			else if (is_dfa_bridge)
				v = 0x0404; /* subordinate:secondary = 4:4 */

Annotation

Implementation Notes