Commit 733bda87 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[AGPGART] implement module locking that works.

parent 11061ebf
......@@ -32,28 +32,8 @@
extern struct agp_bridge_data agp_bridge;
/* Generic routines. */
void agp_generic_agp_enable(u32 mode);
int agp_generic_agp_3_0_enable(u32 mode);
int agp_generic_create_gatt_table(void);
int agp_generic_free_gatt_table(void);
agp_memory *agp_create_memory(int scratch_pages);
int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
void agp_generic_free_by_type(agp_memory * curr);
void *agp_generic_alloc_page(void);
void agp_generic_destroy_page(void *addr);
int agp_generic_suspend(void);
void agp_generic_resume(void);
void agp_free_key(int key);
int agp_num_entries(void);
#define PFX "agpgart: "
int agp_register_driver (struct pci_dev *dev);
int agp_unregister_driver(void);
#ifdef CONFIG_SMP
static void ipi_handler(void *null)
{
......@@ -385,6 +365,11 @@ struct agp_bridge_info {
struct agp_device_ids *ids;
};
struct agp_driver {
struct module *owner;
struct pci_dev *dev;
};
extern struct agp_bridge_info ali_agp_bridge_info;
extern struct agp_bridge_info amd_k8_agp_bridge_info;
extern struct agp_bridge_info amd_agp_bridge_info;
......@@ -393,4 +378,23 @@ extern struct agp_bridge_info sis_agp_bridge_info;
extern struct agp_bridge_info via_agp_bridge_info;
extern struct agp_bridge_info hp_agp_bridge_info;
/* Generic routines. */
void agp_generic_agp_enable(u32 mode);
int agp_generic_agp_3_0_enable(u32 mode);
int agp_generic_create_gatt_table(void);
int agp_generic_free_gatt_table(void);
agp_memory *agp_create_memory(int scratch_pages);
int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
void agp_generic_free_by_type(agp_memory * curr);
void *agp_generic_alloc_page(void);
void agp_generic_destroy_page(void *addr);
int agp_generic_suspend(void);
void agp_generic_resume(void);
void agp_free_key(int key);
int agp_num_entries(void);
int agp_register_driver (struct agp_driver *drv);
int agp_unregister_driver(struct agp_driver *drv);
#endif /* _AGP_BACKEND_PRIV_H */
......@@ -336,6 +336,9 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
return -ENODEV;
}
static struct agp_driver ali_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_ali_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
......@@ -351,7 +354,8 @@ static int __init agp_ali_probe (struct pci_dev *dev, const struct pci_device_id
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
agp_register_driver(dev);
ali_agp_driver.dev = dev;
agp_register_driver(&ali_agp_driver);
return 0;
}
return -ENODEV;
......@@ -390,7 +394,7 @@ static int __init agp_ali_init(void)
static void __exit agp_ali_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&ali_agp_driver);
pci_unregister_driver(&agp_ali_pci_driver);
}
......
......@@ -440,6 +440,10 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
}
static struct agp_driver amd_k7_agp_driver = {
.owner = THIS_MODULE,
};
/* Supported Device Scanning routine */
static int __init agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_id *ent)
......@@ -455,7 +459,8 @@ static int __init agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
agp_register_driver(dev);
amd_k7_agp_driver.dev = dev;
agp_register_driver(&amd_k7_agp_driver);
return 0;
}
return -ENODEV;
......@@ -494,7 +499,7 @@ static int __init agp_amdk7_init(void)
static void __exit agp_amdk7_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&amd_k7_agp_driver);
pci_unregister_driver(&agp_amdk7_pci_driver);
}
......
......@@ -408,6 +408,9 @@ static int __init amd_8151_setup (struct pci_dev *pdev)
return 0;
}
static struct agp_driver amd_k8_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
......@@ -423,7 +426,8 @@ static int __init agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
amd_8151_setup(dev);
agp_register_driver(dev);
amd_k8_agp_driver.dev = dev;
agp_register_driver(&amd_k8_agp_driver);
return 0;
}
......@@ -463,7 +467,7 @@ int __init agp_amdk8_init(void)
static void __exit agp_amdk8_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&amd_k8_agp_driver);
pci_unregister_driver(&agp_amdk8_pci_driver);
}
......
......@@ -219,36 +219,48 @@ static const drm_agp_t drm_agp = {
static int agp_count=0;
int agp_register_driver (struct pci_dev *dev)
int agp_register_driver (struct agp_driver *drv)
{
int ret_val;
if (drv->dev == NULL) {
printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
return -EINVAL;
}
if (agp_count==1) {
printk (KERN_DEBUG PFX "Only one agpgart device currently supported.\n");
return -ENODEV;
}
ret_val = agp_backend_initialize(dev);
if (ret_val) {
agp_bridge.type = NOT_SUPPORTED;
return ret_val;
}
/* Grab reference on the chipset driver. */
if (!try_module_get(drv->owner))
return -EINVAL;
ret_val = agp_backend_initialize(drv->dev);
if (ret_val)
goto err_out;
ret_val = agp_frontend_initialize();
if (ret_val) {
agp_bridge.type = NOT_SUPPORTED;
agp_backend_cleanup();
return ret_val;
}
if (ret_val)
goto frontend_err;
/* FIXME: What to do with this? */
inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
agp_count++;
return 0;
frontend_err:
agp_backend_cleanup();
err_out:
agp_bridge.type = NOT_SUPPORTED;
module_put(drv->owner);
return ret_val;
}
int agp_unregister_driver(void)
int agp_unregister_driver(struct agp_driver *drv)
{
agp_bridge.type = NOT_SUPPORTED;
pm_unregister_all(agp_power);
......@@ -256,6 +268,7 @@ int agp_unregister_driver(void)
agp_backend_cleanup();
inter_module_unregister("drm_agp");
agp_count--;
module_put(drv->owner);
return 0;
}
......
......@@ -116,7 +116,6 @@ void agp_free_memory(agp_memory * curr)
agp_free_key(curr->key);
vfree(curr->memory);
kfree(curr);
MOD_DEC_USE_COUNT;
}
#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
......@@ -138,17 +137,12 @@ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
return new;
}
/* We always increase the module count, since free auto-decrements it */
MOD_INC_USE_COUNT;
scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
new = agp_create_memory(scratch_pages);
if (new == NULL) {
MOD_DEC_USE_COUNT;
if (new == NULL)
return NULL;
}
for (i = 0; i < page_count; i++) {
void *addr = agp_bridge.agp_alloc_page();
......
......@@ -368,10 +368,15 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
return -ENODEV;
}
static struct agp_driver hp_agp_driver = {
.owner = THIS_MODULE;
};
static int __init agp_hp_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev);
hp_agp_driver.dev = dev;
agp_register_driver(&hp_agp_driver);
return 0;
}
return -ENODEV;
......@@ -410,7 +415,7 @@ static int __init agp_hp_init(void)
static void __exit agp_hp_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&hp_agp_driver);
pci_unregister_driver(&agp_hp_pci_driver);
}
......
......@@ -559,6 +559,10 @@ static int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused))
return 0;
}
static struct agp_driver i460_agp_driver = {
.owner = THIS_MODULE;
};
static int __init agp_intel_i460_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
u8 cap_ptr = 0;
......@@ -570,7 +574,8 @@ static int __init agp_intel_i460_probe (struct pci_dev *dev, const struct pci_de
agp_bridge.dev = dev;
agp_bridge.capndx = cap_ptr;
intel_i460_setup(dev);
agp_register_driver(dev);
i460_agp_driver.dev = dev;
agp_register_driver(&i460_agp_driver);
return 0;
}
......@@ -607,7 +612,7 @@ static int __init agp_intel_i460_init(void)
static void __exit agp_intel_i460_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&i460_agp_driver);
pci_unregister_driver(&agp_intel_i460_pci_driver);
}
......
......@@ -164,6 +164,9 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
return -ENODEV;
}
static struct agp_driver i7x05_agp_driver = {
.owner = THIS_MODULE;
};
static int __init agp_i7x05_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
......@@ -178,7 +181,8 @@ static int __init agp_i7x05_probe (struct pci_dev *dev, const struct pci_device_
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode)
agp_register_driver(dev);
i7x05_agp_driver.dev = dev;
agp_register_driver(&i7x05_agp_driver);
return 0;
}
return -ENODEV;
......@@ -218,7 +222,7 @@ int __init agp_i7x05_init(void)
static void __exit agp_i7x05_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&i7x05_agp_driver);
pci_unregister_driver(&agp_i7x05_pci_driver);
}
......
......@@ -195,7 +195,6 @@ static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
new->page_count = pg_count;
new->num_scratch_pages = 0;
vfree(new->memory);
MOD_INC_USE_COUNT;
return new;
}
if(type == AGP_PHYS_MEMORY) {
......@@ -212,7 +211,6 @@ static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
if (new == NULL)
return NULL;
MOD_INC_USE_COUNT;
addr = agp_bridge.agp_alloc_page();
if (addr == NULL) {
......@@ -238,7 +236,6 @@ static void intel_i810_free_by_type(agp_memory * curr)
vfree(curr->memory);
}
kfree(curr);
MOD_DEC_USE_COUNT;
}
static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
......@@ -507,7 +504,6 @@ static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
if (nw == NULL) return(NULL);
MOD_INC_USE_COUNT;
addr = agp_bridge.agp_alloc_page();
if (addr == NULL) {
/* free this structure */
......@@ -1429,11 +1425,15 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
return agp_lookup_host_bridge(dev);
}
static struct agp_driver intel_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_intel_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev);
intel_agp_driver.dev = dev;
agp_register_driver(&intel_agp_driver);
return 0;
}
return -ENODEV;
......@@ -1479,7 +1479,7 @@ int __init agp_intel_init(void)
static void __exit agp_intel_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&intel_agp_driver);
pci_unregister_driver(&agp_intel_pci_driver);
}
......
......@@ -221,6 +221,9 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
return -ENODEV;
}
static struct agp_driver sis_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_sis_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
......@@ -236,7 +239,8 @@ static int __init agp_sis_probe (struct pci_dev *dev, const struct pci_device_id
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
agp_register_driver(dev);
sis_agp_driver.dev = dev;
agp_register_driver(&sis_agp_driver);
return 0;
}
return -ENODEV;
......@@ -275,7 +279,7 @@ static int __init agp_sis_init(void)
static void __exit agp_sis_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&sis_agp_driver);
pci_unregister_driver(&agp_sis_pci_driver);
}
......
......@@ -526,11 +526,15 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
return -ENODEV;
}
static struct agp_driver serverworks_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_serverworks_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
if (agp_find_supported_device(dev) == 0) {
agp_register_driver(dev);
serverworks_agp_driver.dev = dev;
agp_register_driver(&serverworks_agp_driver);
return 0;
}
return -ENODEV;
......@@ -569,7 +573,7 @@ static int __init agp_serverworks_init(void)
static void __exit agp_serverworks_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&serverworks_agp_driver);
pci_unregister_driver(&agp_serverworks_pci_driver);
}
......
......@@ -244,6 +244,9 @@ static int __init agp_lookup_host_bridge (struct pci_dev *pdev)
return -ENODEV;
}
static struct agp_driver via_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
......@@ -259,7 +262,8 @@ static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id
agp_bridge.capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
agp_register_driver(dev);
via_agp_driver.dev = dev;
agp_register_driver(&via_agp_driver);
return 0;
}
return -ENODEV;
......@@ -298,7 +302,7 @@ static int __init agp_via_init(void)
static void __exit agp_via_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&via_agp_driver);
pci_unregister_driver(&agp_via_pci_driver);
}
......
......@@ -100,6 +100,9 @@ static void __init via_kt400_enable(u32 mode)
printk (KERN_INFO PFX "agp_generic_agp_3_0_enable() failed\n");
}
static struct agp_driver via_kt400_agp_driver = {
.owner = THIS_MODULE,
};
static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
{
......@@ -149,7 +152,8 @@ static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id
/* Fill in the mode register */
pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
agp_register_driver(dev);
via_kt400_agp_driver.dev = dev;
agp_register_driver(&via_kt400_agp_driver);
return 0;
}
......@@ -186,7 +190,7 @@ static int __init agp_via_init(void)
static void __exit agp_via_cleanup(void)
{
agp_unregister_driver();
agp_unregister_driver(&via_kt400_agp_driver);
pci_unregister_driver(&agp_via_pci_driver);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment