From 9f0f6509f5278b5d46a282acf40e7b69790892a6 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 12 Apr 2007 18:30:36 -0700 Subject: Move driver load call to after AGP init, in case the load routine needs AGP stuff. --- linux-core/drm_stub.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index f4da7dac..13652ebd 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -113,10 +113,6 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, dev->driver = driver; - if (dev->driver->load) - if ((retcode = dev->driver->load(dev, ent->driver_data))) - goto error_out_unreg; - if (drm_core_has_AGP(dev)) { if (drm_device_is_agp(dev)) dev->agp = drm_agp_init(dev); @@ -136,6 +132,11 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, } } + + if (dev->driver->load) + if ((retcode = dev->driver->load(dev, ent->driver_data))) + goto error_out_unreg; + retcode = drm_ctxbitmap_init(dev); if (retcode) { DRM_ERROR("Cannot allocate memory for context bitmap.\n"); -- cgit v1.2.3 From cc471a361fc7058df4fb8d15d9c9a8b5cdd3dd77 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Fri, 13 Apr 2007 14:33:52 +1000 Subject: i915/drm: clean up a lot of the i915/drm startup/teardown sequences When the kernel driver is loaded it sets up a lot of stuff.. it tears down the same stuff on unload. This add a new map type called DRM_DRIVER which means the driver will clean the mapping up and fix up the map cleaner --- linux-core/drm_stub.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 13652ebd..417e5095 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -132,7 +132,6 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, } } - if (dev->driver->load) if ((retcode = dev->driver->load(dev, ent->driver_data))) goto error_out_unreg; -- cgit v1.2.3 From 79aa1d54746f33c33ffbf98fb96ccbf88c3cb390 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 17 Apr 2007 18:16:38 +1000 Subject: another large overhaul of interactions with userspace... We need to keep a list of user created fbs to nuke on master exit. We also need to use the bo properly. --- linux-core/drm_stub.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 417e5095..01ffe679 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -79,27 +79,28 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, #endif dev->irq = pdev->irq; - if (drm_ht_create(&dev->map_hash, DRM_MAP_HASH_ORDER)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); + if (drm_ht_create(&dev->map_hash, DRM_MAP_HASH_ORDER)) return -ENOMEM; - } + if (drm_mm_init(&dev->offset_manager, DRM_FILE_PAGE_OFFSET_START, DRM_FILE_PAGE_OFFSET_SIZE)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); drm_ht_remove(&dev->map_hash); return -ENOMEM; } if (drm_ht_create(&dev->object_hash, DRM_OBJECT_HASH_ORDER)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); drm_ht_remove(&dev->map_hash); drm_mm_takedown(&dev->offset_manager); return -ENOMEM; } dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS); - if (dev->maplist == NULL) + if (dev->maplist == NULL) { + drm_ht_remove(&dev->object_hash); + drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); return -ENOMEM; + } INIT_LIST_HEAD(&dev->maplist->head); /* the DRM has 6 counters */ -- cgit v1.2.3 From 8fd8bf599b42b6caa062afabdfce7385d59a7695 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 18 Nov 2007 19:16:40 +0100 Subject: drm: don't reset to 0 irq_enabled when client open file descriptor --- linux-core/drm_stub.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 4aaf0a9c..eb4ba8e9 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -84,6 +84,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, dev->hose = pdev->sysdata; #endif dev->irq = pdev->irq; + dev->irq_enabled = 0; if (drm_ht_create(&dev->map_hash, DRM_MAP_HASH_ORDER)) return -ENOMEM; -- cgit v1.2.3 From 10937cf20b6814e4cf68114fab4619fad94eafcb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Jan 2008 16:12:24 +1100 Subject: drm: move drm_head to drm_minor and fix up users --- linux-core/drm_stub.c | 53 ++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index cc759d5c..433869e6 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -37,20 +37,20 @@ #include "drmP.h" #include "drm_core.h" -unsigned int drm_cards_limit = 16; /* Enough for one machine */ +unsigned int drm_minors_limit = 16; /* Enough for one machine */ unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); -MODULE_PARM_DESC(cards_limit, "Maximum number of graphics cards"); +MODULE_PARM_DESC(minors_limit, "Maximum number of graphics cards"); MODULE_PARM_DESC(debug, "Enable debug output"); -module_param_named(cards_limit, drm_cards_limit, int, 0444); +module_param_named(minors_limit, drm_minors_limit, int, 0444); module_param_named(debug, drm_debug, int, 0600); -struct drm_head **drm_heads; +struct drm_minor **drm_minors; struct class *drm_class; struct proc_dir_entry *drm_proc_root; @@ -160,48 +160,48 @@ error_out_unreg: * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_head(struct drm_device * dev, struct drm_head * head) +static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) { - struct drm_head **heads = drm_heads; + struct drm_minor **minors = drm_minors; int ret; - int minor; + int index; DRM_DEBUG("\n"); - for (minor = 0; minor < drm_cards_limit; minor++, heads++) { - if (!*heads) { + for (index = 0; index < drm_minors_limit; index++, minors++) { + if (!*minors) { - *head = (struct drm_head) { + *minor = (struct drm_minor) { .dev = dev, - .device = MKDEV(DRM_MAJOR, minor), - .minor = minor, + .device = MKDEV(DRM_MAJOR, index), + .minor = index, }; if ((ret = - drm_proc_init(dev, minor, drm_proc_root, - &head->dev_root))) { + drm_proc_init(dev, index, drm_proc_root, + &minor->dev_root))) { printk(KERN_ERR "DRM: Failed to initialize /proc/dri.\n"); goto err_g1; } - ret = drm_sysfs_device_add(dev, head); + ret = drm_sysfs_device_add(dev, minor); if (ret) { printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); goto err_g2; } - *heads = head; + *minors = minor; - DRM_DEBUG("new minor assigned %d\n", minor); + DRM_DEBUG("new minor assigned %d\n", index); return 0; } } DRM_ERROR("out of minors\n"); return -ENOMEM; err_g2: - drm_proc_cleanup(minor, drm_proc_root, head->dev_root); + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); err_g1: - *head = (struct drm_head) { + *minor = (struct drm_minor) { .dev = NULL}; return ret; } @@ -309,17 +309,18 @@ int drm_put_dev(struct drm_device * dev) * last minor released. * */ -int drm_put_head(struct drm_head * head) +int drm_put_minor(struct drm_minor *minor) { - int minor = head->minor; + int index = minor->minor; - DRM_DEBUG("release secondary minor %d\n", minor); + DRM_DEBUG("release secondary minor %d\n", index); - drm_proc_cleanup(minor, drm_proc_root, head->dev_root); - drm_sysfs_device_remove(head->dev); + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); + drm_sysfs_device_remove(minor->dev); - *head = (struct drm_head) {.dev = NULL}; + *minor = (struct drm_minor) {.type = DRM_MINOR_UNASSIGNED, + .dev = NULL}; - drm_heads[minor] = NULL; + drm_minors[index] = NULL; return 0; } -- cgit v1.2.3 From d3da253adbf471c9af9c68b2ff67cbf516856352 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Jan 2008 17:49:40 +1100 Subject: drm: add initial support for a drm control device node --- linux-core/drm_stub.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 433869e6..cee00c5e 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -160,7 +160,7 @@ error_out_unreg: * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) +static int drm_get_minor(struct drm_device *dev, struct drm_minor *minor, int type) { struct drm_minor **minors = drm_minors; int ret; @@ -172,19 +172,23 @@ static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) if (!*minors) { *minor = (struct drm_minor) { + .type = type, .dev = dev, .device = MKDEV(DRM_MAJOR, index), .minor = index, }; - if ((ret = - drm_proc_init(dev, index, drm_proc_root, - &minor->dev_root))) { - printk(KERN_ERR - "DRM: Failed to initialize /proc/dri.\n"); - goto err_g1; - } - ret = drm_sysfs_device_add(dev, minor); + if (type == DRM_MINOR_RENDER) { + ret = drm_proc_init(dev, index, drm_proc_root, + &minor->dev_root); + if (ret) { + DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); + goto err_g1; + } + } else + minor->dev_root = NULL; + + ret = drm_sysfs_device_add(minor); if (ret) { printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); @@ -199,7 +203,8 @@ static int drm_get_head(struct drm_device * dev, struct drm_minor *minor) DRM_ERROR("out of minors\n"); return -ENOMEM; err_g2: - drm_proc_cleanup(index, drm_proc_root, minor->dev_root); + if (minor->type == DRM_MINOR_RENDER) + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); err_g1: *minor = (struct drm_minor) { .dev = NULL}; @@ -245,22 +250,28 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, printk(KERN_ERR "DRM: fill_in_dev failed\n"); goto err_g3; } - if ((ret = drm_get_head(dev, &dev->primary))) + + if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL))) goto err_g3; + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_RENDER))) + goto err_g4; + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->primary.minor); return 0; - err_g3: +err_g4: + drm_put_minor(&dev->control); +err_g3: if (!drm_fb_loaded) pci_disable_device(pdev); - err_g2: +err_g2: if (!drm_fb_loaded) pci_release_regions(pdev); - err_g1: +err_g1: if (!drm_fb_loaded) pci_set_drvdata(pdev, NULL); @@ -315,8 +326,9 @@ int drm_put_minor(struct drm_minor *minor) DRM_DEBUG("release secondary minor %d\n", index); - drm_proc_cleanup(index, drm_proc_root, minor->dev_root); - drm_sysfs_device_remove(minor->dev); + if (minor->type == DRM_MINOR_RENDER) + drm_proc_cleanup(index, drm_proc_root, minor->dev_root); + drm_sysfs_device_remove(minor); *minor = (struct drm_minor) {.type = DRM_MINOR_UNASSIGNED, .dev = NULL}; -- cgit v1.2.3 From f276c845bde4c712aa383540a2dd2055ecc00031 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 13 Feb 2008 12:12:52 +1000 Subject: drm: re-write minor number allocation to use an idr. Fixup the minor number allocation scheme to use an idr and move the control nodes up higher. --- linux-core/drm_stub.c | 143 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 93 insertions(+), 50 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index cee00c5e..5a39afb3 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -50,10 +50,47 @@ MODULE_PARM_DESC(debug, "Enable debug output"); module_param_named(minors_limit, drm_minors_limit, int, 0444); module_param_named(debug, drm_debug, int, 0600); -struct drm_minor **drm_minors; +struct idr drm_minors_idr; + struct class *drm_class; struct proc_dir_entry *drm_proc_root; +static int drm_minor_get_id(struct drm_device *dev, int type) +{ + int new_id; + int ret; + int base = 0, limit = 127; + + if (type == DRM_MINOR_CONTROL) { + base += 128; + limit = base + 64; + } else if (type == DRM_MINOR_GPGPU) { + base += 192; + limit = base + 64; + } + +again: + if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) { + DRM_ERROR("Out of memory expanding drawable idr\n"); + return -ENOMEM; + } + mutex_lock(&dev->struct_mutex); + ret = idr_get_new_above(&drm_minors_idr, NULL, + base, &new_id); + mutex_unlock(&dev->struct_mutex); + if (ret == -EAGAIN) { + goto again; + } else if (ret) { + return ret; + } + + if (new_id >= limit) { + idr_remove(&drm_minors_idr, new_id); + return -EINVAL; + } + return new_id; +} + static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) @@ -160,54 +197,61 @@ error_out_unreg: * create the proc init entry via proc_init(). This routines assigns * minor numbers to secondary heads of multi-headed cards */ -static int drm_get_minor(struct drm_device *dev, struct drm_minor *minor, int type) +static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) { - struct drm_minor **minors = drm_minors; + struct drm_minor *new_minor; int ret; - int index; + int minor_id; DRM_DEBUG("\n"); - for (index = 0; index < drm_minors_limit; index++, minors++) { - if (!*minors) { - - *minor = (struct drm_minor) { - .type = type, - .dev = dev, - .device = MKDEV(DRM_MAJOR, index), - .minor = index, - }; - - if (type == DRM_MINOR_RENDER) { - ret = drm_proc_init(dev, index, drm_proc_root, - &minor->dev_root); - if (ret) { - DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); - goto err_g1; - } - } else - minor->dev_root = NULL; - - ret = drm_sysfs_device_add(minor); - if (ret) { - printk(KERN_ERR - "DRM: Error sysfs_device_add.\n"); - goto err_g2; - } - *minors = minor; - - DRM_DEBUG("new minor assigned %d\n", index); - return 0; + minor_id = drm_minor_get_id(dev, type); + if (minor_id < 0) + return minor_id; + + new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL); + if (!new_minor) { + ret = -ENOMEM; + goto err_idr; + } + + new_minor->type = type; + new_minor->device = MKDEV(DRM_MAJOR, minor_id); + new_minor->dev = dev; + new_minor->index = minor_id; + + idr_replace(&drm_minors_idr, new_minor, minor_id); + + if (type == DRM_MINOR_RENDER) { + ret = drm_proc_init(dev, minor_id, drm_proc_root, + &new_minor->dev_root); + if (ret) { + DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); + goto err_mem; } + } else + new_minor->dev_root = NULL; + + ret = drm_sysfs_device_add(new_minor); + if (ret) { + printk(KERN_ERR + "DRM: Error sysfs_device_add.\n"); + goto err_g2; } - DRM_ERROR("out of minors\n"); - return -ENOMEM; + *minor = new_minor; + + DRM_DEBUG("new minor assigned %d\n", minor_id); + return 0; + + err_g2: - if (minor->type == DRM_MINOR_RENDER) - drm_proc_cleanup(index, drm_proc_root, minor->dev_root); -err_g1: - *minor = (struct drm_minor) { - .dev = NULL}; + if (new_minor->type == DRM_MINOR_RENDER) + drm_proc_cleanup(minor_id, drm_proc_root, new_minor->dev_root); +err_mem: + kfree(new_minor); +err_idr: + idr_remove(&drm_minors_idr, minor_id); + *minor = NULL; return ret; } @@ -259,7 +303,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary.minor); + driver->date, dev->primary->index); return 0; @@ -320,19 +364,18 @@ int drm_put_dev(struct drm_device * dev) * last minor released. * */ -int drm_put_minor(struct drm_minor *minor) +int drm_put_minor(struct drm_minor **minor_p) { - int index = minor->minor; - - DRM_DEBUG("release secondary minor %d\n", index); + struct drm_minor *minor = *minor_p; + DRM_DEBUG("release secondary minor %d\n", minor->index); if (minor->type == DRM_MINOR_RENDER) - drm_proc_cleanup(index, drm_proc_root, minor->dev_root); + drm_proc_cleanup(minor->index, drm_proc_root, minor->dev_root); drm_sysfs_device_remove(minor); - *minor = (struct drm_minor) {.type = DRM_MINOR_UNASSIGNED, - .dev = NULL}; + idr_remove(&drm_minors_idr, minor->index); - drm_minors[index] = NULL; + kfree(minor); + *minor_p = NULL; return 0; } -- cgit v1.2.3 From 0fbee62ec14d08714dbc558dd20cc00b9a79c042 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 13 Feb 2008 15:19:42 +1000 Subject: major port of multi-master ideas into modesetting --- linux-core/drm_stub.c | 70 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 12 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 5a39afb3..66a7b8b5 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -91,13 +91,63 @@ again: return new_id; } +struct drm_master *drm_get_master(struct drm_device *dev) +{ + struct drm_master *master; + + master = drm_calloc(1, sizeof(*master), DRM_MEM_DRIVER); + if (!master) + return NULL; + +// INIT_LIST_HEAD(&master->filelist); + spin_lock_init(&master->lock.spinlock); + init_waitqueue_head(&master->lock.lock_queue); + drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER); + INIT_LIST_HEAD(&master->magicfree); + master->dev = dev; + + return master; +} + +void drm_put_master(struct drm_master *master) +{ + struct drm_magic_entry *pt, *next; + struct drm_device *dev = master->dev; + + if (dev->driver->master_destroy) + dev->driver->master_destroy(dev, master); + + if (master->unique) { + drm_free(master->unique, strlen(master->unique) + 1, DRM_MEM_DRIVER); + master->unique = NULL; + master->unique_len = 0; + } + + list_for_each_entry_safe(pt, next, &master->magicfree, head) { + list_del(&pt->head); + drm_ht_remove_item(&master->magiclist, &pt->hash_item); + drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); + } + + drm_ht_remove(&master->magiclist); + + if (master->lock.hw_lock) { + if (dev->sigdata.lock == master->lock.hw_lock) + dev->sigdata.lock = NULL; + master->lock.hw_lock = NULL; /* SHM removed */ + master->lock.file_priv = NULL; + wake_up_interruptible(&master->lock.lock_queue); + } + + drm_free(master, sizeof(*master), DRM_MEM_DRIVER); +} + static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) { int retcode; - INIT_LIST_HEAD(&dev->filelist); INIT_LIST_HEAD(&dev->ctxlist); INIT_LIST_HEAD(&dev->vmalist); INIT_LIST_HEAD(&dev->maplist); @@ -105,7 +155,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, spin_lock_init(&dev->count_lock); spin_lock_init(&dev->drw_lock); spin_lock_init(&dev->tasklet_lock); - spin_lock_init(&dev->lock.spinlock); +// spin_lock_init(&dev->lock.spinlock); init_timer(&dev->timer); mutex_init(&dev->struct_mutex); mutex_init(&dev->ctxlist_mutex); @@ -168,10 +218,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, } } - if (dev->driver->load) - if ((retcode = dev->driver->load(dev, ent->driver_data))) - goto error_out_unreg; - retcode = drm_ctxbitmap_init(dev); if (retcode) { DRM_ERROR("Cannot allocate memory for context bitmap.\n"); @@ -301,12 +347,17 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_RENDER))) goto err_g4; + if (dev->driver->load) + if ((ret = dev->driver->load(dev, ent->driver_data))) + goto err_g5; + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->primary->index); return 0; - +err_g5: + drm_put_minor(&dev->primary); err_g4: drm_put_minor(&dev->control); err_g3: @@ -340,11 +391,6 @@ int drm_put_dev(struct drm_device * dev) { DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name); - if (dev->unique) { - drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER); - dev->unique = NULL; - dev->unique_len = 0; - } if (dev->devname) { drm_free(dev->devname, strlen(dev->devname) + 1, DRM_MEM_DRIVER); -- cgit v1.2.3 From a4fc1d7ac6be8d2648acda463723d56c68e4122e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 13 Feb 2008 16:30:15 +1000 Subject: start moving over to proper hierarchy wrt master accesses --- linux-core/drm_stub.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 66a7b8b5..ebb8fb97 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -91,7 +91,7 @@ again: return new_id; } -struct drm_master *drm_get_master(struct drm_device *dev) +struct drm_master *drm_get_master(struct drm_minor *minor) { struct drm_master *master; @@ -104,7 +104,9 @@ struct drm_master *drm_get_master(struct drm_device *dev) init_waitqueue_head(&master->lock.lock_queue); drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER); INIT_LIST_HEAD(&master->magicfree); - master->dev = dev; + master->minor = minor; + + list_add_tail(&master->head, &minor->master_list); return master; } @@ -112,7 +114,9 @@ struct drm_master *drm_get_master(struct drm_device *dev) void drm_put_master(struct drm_master *master) { struct drm_magic_entry *pt, *next; - struct drm_device *dev = master->dev; + struct drm_device *dev = master->minor->dev; + + list_del(&master->head); if (dev->driver->master_destroy) dev->driver->master_destroy(dev, master); @@ -265,12 +269,12 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t new_minor->device = MKDEV(DRM_MAJOR, minor_id); new_minor->dev = dev; new_minor->index = minor_id; + INIT_LIST_HEAD(&new_minor->master_list); idr_replace(&drm_minors_idr, new_minor, minor_id); if (type == DRM_MINOR_RENDER) { - ret = drm_proc_init(dev, minor_id, drm_proc_root, - &new_minor->dev_root); + ret = drm_proc_init(new_minor, minor_id, drm_proc_root); if (ret) { DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); goto err_mem; @@ -292,7 +296,7 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t err_g2: if (new_minor->type == DRM_MINOR_RENDER) - drm_proc_cleanup(minor_id, drm_proc_root, new_minor->dev_root); + drm_proc_cleanup(new_minor, drm_proc_root); err_mem: kfree(new_minor); err_idr: @@ -416,7 +420,7 @@ int drm_put_minor(struct drm_minor **minor_p) DRM_DEBUG("release secondary minor %d\n", minor->index); if (minor->type == DRM_MINOR_RENDER) - drm_proc_cleanup(minor->index, drm_proc_root, minor->dev_root); + drm_proc_cleanup(minor, drm_proc_root); drm_sysfs_device_remove(minor); idr_remove(&drm_minors_idr, minor->index); -- cgit v1.2.3 From f2f8ace3e1342d83096bf392922130d39cd86ec2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 15 Feb 2008 09:57:30 +1000 Subject: remove drm_minors_limit --- linux-core/drm_stub.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index ebb8fb97..d3992584 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -37,17 +37,14 @@ #include "drmP.h" #include "drm_core.h" -unsigned int drm_minors_limit = 16; /* Enough for one machine */ unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); -MODULE_PARM_DESC(minors_limit, "Maximum number of graphics cards"); MODULE_PARM_DESC(debug, "Enable debug output"); -module_param_named(minors_limit, drm_minors_limit, int, 0444); module_param_named(debug, drm_debug, int, 0600); struct idr drm_minors_idr; -- cgit v1.2.3 From 75b01cf996f2efdd72c5280238460443d5d1fbc7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 15 Feb 2008 10:04:28 +1000 Subject: switch naming to new proposed scheme --- linux-core/drm_stub.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index d3992584..801dab09 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -56,14 +56,14 @@ static int drm_minor_get_id(struct drm_device *dev, int type) { int new_id; int ret; - int base = 0, limit = 127; + int base = 0, limit = 63; if (type == DRM_MINOR_CONTROL) { + base += 64; + limit = base + 127; + } else if (type == DRM_MINOR_RENDER) { base += 128; - limit = base + 64; - } else if (type == DRM_MINOR_GPGPU) { - base += 192; - limit = base + 64; + limit = base + 255; } again: @@ -270,7 +270,7 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t idr_replace(&drm_minors_idr, new_minor, minor_id); - if (type == DRM_MINOR_RENDER) { + if (type == DRM_MINOR_LEGACY) { ret = drm_proc_init(new_minor, minor_id, drm_proc_root); if (ret) { DRM_ERROR("DRM: Failed to initialize /proc/dri.\n"); @@ -292,7 +292,7 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t err_g2: - if (new_minor->type == DRM_MINOR_RENDER) + if (new_minor->type == DRM_MINOR_LEGACY) drm_proc_cleanup(new_minor, drm_proc_root); err_mem: kfree(new_minor); @@ -345,7 +345,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL))) goto err_g3; - if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_RENDER))) + if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) goto err_g4; if (dev->driver->load) @@ -416,7 +416,7 @@ int drm_put_minor(struct drm_minor **minor_p) struct drm_minor *minor = *minor_p; DRM_DEBUG("release secondary minor %d\n", minor->index); - if (minor->type == DRM_MINOR_RENDER) + if (minor->type == DRM_MINOR_LEGACY) drm_proc_cleanup(minor, drm_proc_root); drm_sysfs_device_remove(minor); -- cgit v1.2.3 From 222092a1a810b67b014ad6881f0c028ec6563329 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 15 Feb 2008 16:15:04 +1000 Subject: various fixes from trying to get userspace started --- linux-core/drm_stub.c | 1 + 1 file changed, 1 insertion(+) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 801dab09..334c8f03 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -152,6 +152,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, INIT_LIST_HEAD(&dev->ctxlist); INIT_LIST_HEAD(&dev->vmalist); INIT_LIST_HEAD(&dev->maplist); + INIT_LIST_HEAD(&dev->filelist); spin_lock_init(&dev->count_lock); spin_lock_init(&dev->drw_lock); -- cgit v1.2.3 From 01dcc47d895997f77c9457558e974d41c23ed4e1 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Feb 2008 16:24:17 +1000 Subject: drm: add modesetting as a driver feature. This change adds a driver feature that for i915 is controlled by a module parameter. You now need to do insmod i915.ko modeset=1 to enable it the modesetting paths. It also fixes up lots of X paths. I can run my new DDX driver on this code with and without modesetting enabled --- linux-core/drm_stub.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 334c8f03..6856075b 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -343,8 +343,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, goto err_g3; } - if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL))) - goto err_g3; + /* only add the control node on a modesetting platform */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + if ((ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL))) + goto err_g3; if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) goto err_g4; @@ -361,7 +363,8 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, err_g5: drm_put_minor(&dev->primary); err_g4: - drm_put_minor(&dev->control); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); err_g3: if (!drm_fb_loaded) pci_disable_device(pdev); -- cgit v1.2.3 From 348d95e00be73b650dabcf121e6b18d669bf4192 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 7 Mar 2008 12:25:26 +1100 Subject: worst merge effort ever --- linux-core/drm_stub.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index ba13e5e5..6856075b 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -355,10 +355,6 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if ((ret = dev->driver->load(dev, ent->driver_data))) goto err_g5; - if (dev->driver->load) - if ((ret = dev->driver->load(dev, ent->driver_data))) - goto err_g4; - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->primary->index); -- cgit v1.2.3 From 607964ed9e5f6d86a0960bef2341e7f5de9c71da Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 17 Mar 2008 16:37:46 +1000 Subject: drm: add master set/drop protocol this may not survive long - just need something for testing --- linux-core/drm_stub.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 6856075b..f66dec07 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -88,6 +88,29 @@ again: return new_id; } +int drm_setmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + if (file_priv->minor->master && file_priv->minor->master != file_priv->master) + return -EINVAL; + + if (!file_priv->master) + return -EINVAL; + + if (!file_priv->minor->master && file_priv->minor->master != file_priv->master) + file_priv->minor->master = file_priv->master; + return 0; +} + +int drm_dropmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + if (!file_priv->master) + return -EINVAL; + file_priv->minor->master = NULL; + return 0; +} + struct drm_master *drm_get_master(struct drm_minor *minor) { struct drm_master *master; -- cgit v1.2.3 From 149b17311ad5f117e8f53a7a8cc032e369b95ed2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Jun 2008 16:45:44 +1000 Subject: drm: initial mode object groups. This creates a default group attached to the legacy drm minor nodes. It covers all the objects in the set. make set resources only return objects for this set. Need to fix up other functions to only work on objects in their allowed set. --- linux-core/drm_stub.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index f66dec07..45b8f386 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -378,6 +378,11 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, if ((ret = dev->driver->load(dev, ent->driver_data))) goto err_g5; + /* setup the grouping for the legacy output */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group)) + goto err_g5; + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->primary->index); -- cgit v1.2.3 From 296073dc5f0bf3f8b74a7d6db48b05c09a1b9242 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 31 Jul 2008 14:39:25 +1000 Subject: drm: remove object hash --- linux-core/drm_stub.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index c62b901d..97533d72 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -207,12 +207,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, return -ENOMEM; } - if (drm_ht_create(&dev->object_hash, DRM_OBJECT_HASH_ORDER)) { - drm_ht_remove(&dev->map_hash); - drm_memrange_takedown(&dev->offset_manager); - return -ENOMEM; - } - /* the DRM has 6 counters */ dev->counters = 6; dev->types[0] = _DRM_STAT_LOCK; -- cgit v1.2.3 From 717dd804d0d1d9984345a998b28ee47079c70639 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 4 Aug 2008 14:54:32 +1000 Subject: drm: fixup master code to use krefs --- linux-core/drm_stub.c | 85 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 33 deletions(-) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 97533d72..4654dca1 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -88,30 +88,7 @@ again: return new_id; } -int drm_setmaster_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - if (file_priv->minor->master && file_priv->minor->master != file_priv->master) - return -EINVAL; - - if (!file_priv->master) - return -EINVAL; - - if (!file_priv->minor->master && file_priv->minor->master != file_priv->master) - file_priv->minor->master = file_priv->master; - return 0; -} - -int drm_dropmaster_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - if (!file_priv->master) - return -EINVAL; - file_priv->minor->master = NULL; - return 0; -} - -struct drm_master *drm_get_master(struct drm_minor *minor) +struct drm_master *drm_master_create(struct drm_minor *minor) { struct drm_master *master; @@ -119,7 +96,7 @@ struct drm_master *drm_get_master(struct drm_minor *minor) if (!master) return NULL; -// INIT_LIST_HEAD(&master->filelist); + kref_init(&master->refcount); spin_lock_init(&master->lock.spinlock); init_waitqueue_head(&master->lock.lock_queue); drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER); @@ -131,8 +108,15 @@ struct drm_master *drm_get_master(struct drm_minor *minor) return master; } -void drm_put_master(struct drm_master *master) +struct drm_master *drm_master_get(struct drm_master *master) +{ + kref_get(&master->refcount); + return master; +} + +static void drm_master_destroy(struct kref *kref) { + struct drm_master *master = container_of(kref, struct drm_master, refcount); struct drm_magic_entry *pt, *next; struct drm_device *dev = master->minor->dev; @@ -166,21 +150,56 @@ void drm_put_master(struct drm_master *master) drm_free(master, sizeof(*master), DRM_MEM_DRIVER); } +void drm_master_put(struct drm_master **master) +{ + kref_put(&(*master)->refcount, drm_master_destroy); + *master = NULL; +} + +int drm_setmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + if (file_priv->minor->master && file_priv->minor->master != file_priv->master) + return -EINVAL; + + if (!file_priv->master) + return -EINVAL; + + if (!file_priv->minor->master && file_priv->minor->master != file_priv->master) { + mutex_lock(&dev->struct_mutex); + file_priv->minor->master = drm_master_get(file_priv->master); + mutex_unlock(&dev->struct_mutex); + } + + return 0; +} + +int drm_dropmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + if (!file_priv->master) + return -EINVAL; + mutex_lock(&dev->struct_mutex); + drm_master_put(&file_priv->minor->master); + mutex_unlock(&dev->struct_mutex); + return 0; +} + static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) { int retcode; + INIT_LIST_HEAD(&dev->filelist); INIT_LIST_HEAD(&dev->ctxlist); INIT_LIST_HEAD(&dev->vmalist); INIT_LIST_HEAD(&dev->maplist); - INIT_LIST_HEAD(&dev->filelist); spin_lock_init(&dev->count_lock); spin_lock_init(&dev->drw_lock); spin_lock_init(&dev->tasklet_lock); -// spin_lock_init(&dev->lock.spinlock); + init_timer(&dev->timer); mutex_init(&dev->struct_mutex); mutex_init(&dev->ctxlist_mutex); @@ -402,10 +421,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, return 0; err_g5: - drm_put_minor(dev, &dev->primary); + drm_put_minor(&dev->primary); err_g4: if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(dev, &dev->control); + drm_put_minor(&dev->control); err_g3: if (!drm_fb_loaded) pci_disable_device(pdev); @@ -456,14 +475,14 @@ int drm_put_dev(struct drm_device * dev) * last minor released. * */ -int drm_put_minor(struct drm_device *dev, struct drm_minor **minor_p) +int drm_put_minor(struct drm_minor **minor_p) { struct drm_minor *minor = *minor_p; DRM_DEBUG("release secondary minor %d\n", minor->index); if (minor->type == DRM_MINOR_LEGACY) { - if (dev->driver->proc_cleanup) - dev->driver->proc_cleanup(minor); + if (minor->dev->driver->proc_cleanup) + minor->dev->driver->proc_cleanup(minor); drm_proc_cleanup(minor, drm_proc_root); } drm_sysfs_device_remove(minor); -- cgit v1.2.3 From 6d0de5a899ea883693737333b4b0511c28f32d92 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Sep 2008 14:30:05 -0400 Subject: Export drm_put_minor --- linux-core/drm_stub.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'linux-core/drm_stub.c') diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 1257b0d4..cd6cd4b5 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -492,3 +492,5 @@ int drm_put_minor(struct drm_minor **minor_p) *minor_p = NULL; return 0; } + +EXPORT_SYMBOL(drm_put_minor); -- cgit v1.2.3