drivers/char/agp/backend.c
Source file repositories/reference/linux-study-clean/drivers/char/agp/backend.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/agp/backend.c- Extension
.c- Size
- 8623 bytes
- Lines
- 342
- Domain
- Driver Families
- Bucket
- drivers/char
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/module.hlinux/pci.hlinux/init.hlinux/slab.hlinux/pagemap.hlinux/miscdevice.hlinux/pm.hlinux/agp_backend.hlinux/agpgart.hlinux/vmalloc.hasm/io.hagp.h
Detected Declarations
function agp_backend_releasefunction agp_find_maxfunction agp_backend_initializefunction agp_backend_cleanupfunction agp_put_bridgefunction agp_add_bridgefunction agp_remove_bridgefunction agp_setupexport agp_bridgeexport agp_bridgesexport agp_find_bridgeexport agp_backend_acquireexport agp_backend_releaseexport agp_alloc_bridgeexport agp_put_bridgeexport agp_add_bridgeexport agp_remove_bridgeexport agp_offexport agp_try_unsupported_boot
Annotated Snippet
if (!page) {
dev_err(&bridge->dev->dev,
"can't get memory for scratch page\n");
return -ENOMEM;
}
bridge->scratch_page_page = page;
bridge->scratch_page_dma = page_to_phys(page);
bridge->scratch_page = bridge->driver->mask_memory(bridge,
bridge->scratch_page_dma, 0);
}
size_value = bridge->driver->fetch_size();
if (size_value == 0) {
dev_err(&bridge->dev->dev, "can't determine aperture size\n");
rc = -EINVAL;
goto err_out;
}
if (bridge->driver->create_gatt_table(bridge)) {
dev_err(&bridge->dev->dev,
"can't get memory for graphics translation table\n");
rc = -ENOMEM;
goto err_out;
}
got_gatt = 1;
bridge->key_list = vzalloc(PAGE_SIZE * 4);
if (bridge->key_list == NULL) {
dev_err(&bridge->dev->dev,
"can't allocate memory for key lists\n");
rc = -ENOMEM;
goto err_out;
}
got_keylist = 1;
/* FIXME vmalloc'd memory not guaranteed contiguous */
if (bridge->driver->configure()) {
dev_err(&bridge->dev->dev, "error configuring host chipset\n");
rc = -EINVAL;
goto err_out;
}
INIT_LIST_HEAD(&bridge->mapped_list);
spin_lock_init(&bridge->mapped_lock);
return 0;
err_out:
if (bridge->driver->needs_scratch_page) {
struct page *page = bridge->scratch_page_page;
bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP);
bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE);
}
if (got_gatt)
bridge->driver->free_gatt_table(bridge);
if (got_keylist) {
vfree(bridge->key_list);
bridge->key_list = NULL;
}
return rc;
}
/* cannot be __exit b/c as it could be called from __init code */
static void agp_backend_cleanup(struct agp_bridge_data *bridge)
{
if (bridge->driver->cleanup)
bridge->driver->cleanup();
if (bridge->driver->free_gatt_table)
bridge->driver->free_gatt_table(bridge);
vfree(bridge->key_list);
bridge->key_list = NULL;
if (bridge->driver->agp_destroy_page &&
bridge->driver->needs_scratch_page) {
struct page *page = bridge->scratch_page_page;
bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP);
bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE);
}
}
/* When we remove the global variable agp_bridge from all drivers
* then agp_alloc_bridge and agp_generic_find_bridge need to be updated
*/
struct agp_bridge_data *agp_alloc_bridge(void)
{
Annotation
- Immediate include surface: `linux/module.h`, `linux/pci.h`, `linux/init.h`, `linux/slab.h`, `linux/pagemap.h`, `linux/miscdevice.h`, `linux/pm.h`, `linux/agp_backend.h`.
- Detected declarations: `function agp_backend_release`, `function agp_find_max`, `function agp_backend_initialize`, `function agp_backend_cleanup`, `function agp_put_bridge`, `function agp_add_bridge`, `function agp_remove_bridge`, `function agp_setup`, `export agp_bridge`, `export agp_bridges`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.