X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fdrm%2Fdrm_stub.c;h=9a842a36bb2754cfef213344754e0ff951e4c44c;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=8ccbdef7bb3ec3b9c35096acec942739bb40525e;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 8ccbdef7b..9a842a36b 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c @@ -37,35 +37,37 @@ #include "drm_core.h" unsigned int drm_cards_limit = 16; /* Enough for one machine */ -unsigned int drm_debug = 0; /* 1 to enable debug output */ +unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); -MODULE_AUTHOR( CORE_AUTHOR ); -MODULE_DESCRIPTION( CORE_DESC ); +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(debug, "Enable debug output"); module_param_named(cards_limit, drm_cards_limit, int, 0444); -module_param_named(debug, drm_debug, int, 0666); +module_param_named(debug, drm_debug, int, 0600); drm_head_t **drm_heads; -struct drm_sysfs_class *drm_class; +struct class *drm_class; struct proc_dir_entry *drm_proc_root; -static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver) +static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, + const struct pci_device_id *ent, + struct drm_driver *driver) { int retcode; spin_lock_init(&dev->count_lock); - init_timer( &dev->timer ); - sema_init( &dev->struct_sem, 1 ); - sema_init( &dev->ctxlist_sem, 1 ); + init_timer(&dev->timer); + mutex_init(&dev->struct_mutex); + mutex_init(&dev->ctxlist_mutex); - dev->pdev = pdev; + dev->pdev = pdev; #ifdef __alpha__ - dev->hose = pdev->sysdata; + dev->hose = pdev->sysdata; dev->pci_domain = dev->hose->bus->number; #else dev->pci_domain = 0; @@ -75,88 +77,114 @@ static int drm_fill_in_dev(drm_device_t *dev, struct pci_dev *pdev, const struct dev->pci_func = PCI_FUNC(pdev->devfn); dev->irq = pdev->irq; + dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS); + if (dev->maplist == NULL) + return -ENOMEM; + INIT_LIST_HEAD(&dev->maplist->head); + /* the DRM has 6 basic counters */ dev->counters = 6; - dev->types[0] = _DRM_STAT_LOCK; - dev->types[1] = _DRM_STAT_OPENS; - dev->types[2] = _DRM_STAT_CLOSES; - dev->types[3] = _DRM_STAT_IOCTLS; - dev->types[4] = _DRM_STAT_LOCKS; - dev->types[5] = _DRM_STAT_UNLOCKS; + dev->types[0] = _DRM_STAT_LOCK; + dev->types[1] = _DRM_STAT_OPENS; + dev->types[2] = _DRM_STAT_CLOSES; + dev->types[3] = _DRM_STAT_IOCTLS; + dev->types[4] = _DRM_STAT_LOCKS; + dev->types[5] = _DRM_STAT_UNLOCKS; dev->driver = driver; - - if (dev->driver->preinit) - if ((retcode = dev->driver->preinit(dev, ent->driver_data))) + + if (dev->driver->load) + if ((retcode = dev->driver->load(dev, ent->driver_data))) goto error_out_unreg; if (drm_core_has_AGP(dev)) { - dev->agp = drm_agp_init(dev); - if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) { - DRM_ERROR( "Cannot initialize the agpgart module.\n" ); + if (drm_device_is_agp(dev)) + dev->agp = drm_agp_init(dev); + if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) + && (dev->agp == NULL)) { + DRM_ERROR("Cannot initialize the agpgart module.\n"); retcode = -EINVAL; goto error_out_unreg; } if (drm_core_has_MTRR(dev)) { if (dev->agp) - dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base, - dev->agp->agp_info.aper_size*1024*1024, - MTRR_TYPE_WRCOMB, - 1 ); + dev->agp->agp_mtrr = + mtrr_add(dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size * + 1024 * 1024, MTRR_TYPE_WRCOMB, 1); } } - retcode = drm_ctxbitmap_init( dev ); - if( retcode ) { - DRM_ERROR( "Cannot allocate memory for context bitmap.\n" ); + retcode = drm_ctxbitmap_init(dev); + if (retcode) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); goto error_out_unreg; } return 0; - -error_out_unreg: - drm_takedown(dev); + + error_out_unreg: + drm_lastclose(dev); return retcode; } + /** - * File \c open operation. + * Get a secondary minor number. * - * \param inode device inode. - * \param filp file pointer. + * \param dev device data structure + * \param sec-minor structure to hold the assigned minor + * \return negative number on failure. * - * Puts the dev->fops corresponding to the device minor number into - * \p filp, call the \c open method, and restore the file operations. + * Search an empty entry and initialize it to the given parameters, and + * create the proc init entry via proc_init(). This routines assigns + * minor numbers to secondary heads of multi-headed cards */ -int drm_stub_open(struct inode *inode, struct file *filp) +static int drm_get_head(drm_device_t * dev, drm_head_t * head) { - drm_device_t *dev = NULL; - int minor = iminor(inode); - int err = -ENODEV; - struct file_operations *old_fops; - + drm_head_t **heads = drm_heads; + int ret; + int minor; + DRM_DEBUG("\n"); - if (!((minor >= 0) && (minor < drm_cards_limit))) - return -ENODEV; + for (minor = 0; minor < drm_cards_limit; minor++, heads++) { + if (!*heads) { - if (!drm_heads[minor]) - return -ENODEV; - - if (!(dev = drm_heads[minor]->dev)) - return -ENODEV; - - old_fops = filp->f_op; - filp->f_op = fops_get(&dev->driver->fops); - if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { - fops_put(filp->f_op); - filp->f_op = fops_get(old_fops); - } - fops_put(old_fops); + *head = (drm_head_t) { + .dev = dev,.device = + MKDEV(DRM_MAJOR, minor),.minor = minor,}; + + if ((ret = + drm_proc_init(dev, minor, drm_proc_root, + &head->dev_root))) { + printk(KERN_ERR + "DRM: Failed to initialize /proc/dri.\n"); + goto err_g1; + } - return err; -} + head->dev_class = drm_sysfs_device_add(drm_class, head); + if (IS_ERR(head->dev_class)) { + printk(KERN_ERR + "DRM: Error sysfs_device_add.\n"); + ret = PTR_ERR(head->dev_class); + goto err_g2; + } + *heads = head; + DRM_DEBUG("new minor assigned %d\n", minor); + return 0; + } + } + DRM_ERROR("out of minors\n"); + return -ENOMEM; + err_g2: + drm_proc_cleanup(minor, drm_proc_root, head->dev_root); + err_g1: + *head = (drm_head_t) { + .dev = NULL}; + return ret; +} /** * Register. @@ -170,7 +198,7 @@ int drm_stub_open(struct inode *inode, struct file *filp) * Try and register, if we fail to register, backout previous work. */ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, - struct drm_driver *driver) + struct drm_driver *driver) { drm_device_t *dev; int ret; @@ -189,79 +217,17 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, } if ((ret = drm_get_head(dev, &dev->primary))) goto err_g1; - - /* postinit is a required function to display the signon banner */ - /* drivers add secondary heads here if needed */ - if ((ret = dev->driver->postinit(dev, ent->driver_data))) - goto err_g1; + + 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_g1: + err_g1: drm_free(dev, sizeof(*dev), DRM_MEM_STUB); return ret; } -EXPORT_SYMBOL(drm_get_dev); - -/** - * Get a secondary minor number. - * - * \param dev device data structure - * \param sec-minor structure to hold the assigned minor - * \return negative number on failure. - * - * Search an empty entry and initialize it to the given parameters, and - * create the proc init entry via proc_init(). This routines assigns - * minor numbers to secondary heads of multi-headed cards - */ -int drm_get_head(drm_device_t *dev, drm_head_t *head) -{ - drm_head_t **heads = drm_heads; - int ret; - int minor; - - DRM_DEBUG("\n"); - - for (minor = 0; minor < drm_cards_limit; minor++, heads++) { - if (!*heads) { - - *head = (drm_head_t) { - .dev = dev, - .device = MKDEV(DRM_MAJOR, minor), - .minor = minor, - }; - - if ((ret = drm_proc_init(dev, minor, drm_proc_root, &head->dev_root))) { - printk (KERN_ERR "DRM: Failed to initialize /proc/dri.\n"); - goto err_g1; - } - - - head->dev_class = drm_sysfs_device_add(drm_class, - MKDEV(DRM_MAJOR, - minor), - &dev->pdev->dev, - "card%d", minor); - if (IS_ERR(head->dev_class)) { - printk(KERN_ERR "DRM: Error sysfs_device_add.\n"); - ret = PTR_ERR(head->dev_class); - goto err_g2; - } - *heads = head; - - DRM_DEBUG("new minor assigned %d\n", minor); - return 0; - } - } - DRM_ERROR("out of minors\n"); - return -ENOMEM; -err_g2: - drm_proc_cleanup(minor, drm_proc_root, head->dev_root); -err_g1: - *head = (drm_head_t) {.dev = NULL}; - return ret; -} - /** * Put a device minor number. @@ -301,19 +267,18 @@ int drm_put_dev(drm_device_t * dev) * last minor released. * */ -int drm_put_head(drm_head_t *head) +int drm_put_head(drm_head_t * head) { int minor = head->minor; - + DRM_DEBUG("release secondary minor %d\n", minor); - + drm_proc_cleanup(minor, drm_proc_root, head->dev_root); - drm_sysfs_device_remove(MKDEV(DRM_MAJOR, head->minor)); - - *head = (drm_head_t){.dev = NULL}; + drm_sysfs_device_remove(head->dev_class); + + *head = (drm_head_t) {.dev = NULL}; drm_heads[minor] = NULL; - + return 0; } -