Skip to content

Commit

Permalink
drm: reorganise minor number handling using backported modesetting code.
Browse files Browse the repository at this point in the history
rips out the head crap and replaces it with an idr and drm_minor structure

Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Dave Airlie authored and Dave Airlie committed Apr 26, 2008
1 parent 7b832b5 commit 2c14f28
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 184 deletions.
42 changes: 20 additions & 22 deletions drivers/char/drm/drmP.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,12 @@ struct drm_buf_entry {
struct drm_file {
int authenticated;
int master;
int minor;
pid_t pid;
uid_t uid;
drm_magic_t magic;
unsigned long ioctl_count;
struct list_head lhead;
struct drm_head *head;
struct drm_minor *minor;
int remove_auth_on_close;
unsigned long lock_count;
struct file *filp;
Expand Down Expand Up @@ -630,24 +629,26 @@ struct drm_driver {
struct pci_driver pci_driver;
};

#define DRM_MINOR_UNASSIGNED 0
#define DRM_MINOR_LEGACY 1

/**
* DRM head structure. This structure represent a video head on a card
* that may contain multiple heads. Embed one per head of these in the
* private drm_device structure.
* DRM minor structure. This structure represents a drm minor number.
*/
struct drm_head {
int minor; /**< Minor device number */
struct drm_minor {
int index; /**< Minor device number */
int type; /**< Control or render */
dev_t device; /**< Device number for mknod */
struct device kdev; /**< Linux device */
struct drm_device *dev;
struct proc_dir_entry *dev_root; /**< proc directory entry */
dev_t device; /**< Device number for mknod */
};

/**
* DRM device structure. This structure represent a complete card that
* may contain multiple heads.
*/
struct drm_device {
struct device dev; /**< Linux device */
char *unique; /**< Unique identifier: e.g., busid */
int unique_len; /**< Length of unique field */
char *devname; /**< For /proc/interrupts */
Expand Down Expand Up @@ -763,7 +764,7 @@ struct drm_device {
struct drm_driver *driver;
drm_local_map_t *agp_buffer_map;
unsigned int agp_buffer_token;
struct drm_head primary; /**< primary screen head */
struct drm_minor *primary; /**< render type primary screen head */

/** \name Drawable information */
/*@{ */
Expand Down Expand Up @@ -1030,23 +1031,20 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
struct drm_driver *driver);
extern int drm_put_dev(struct drm_device *dev);
extern int drm_put_head(struct drm_head *head);
extern int drm_put_minor(struct drm_minor **minor);
extern unsigned int drm_debug;
extern unsigned int drm_cards_limit;
extern struct drm_head **drm_heads;

extern struct class *drm_class;
extern struct proc_dir_entry *drm_proc_root;

extern struct idr drm_minors_idr;

extern drm_local_map_t *drm_getsarea(struct drm_device *dev);

/* Proc support (drm_proc.h) */
extern int drm_proc_init(struct drm_device *dev,
int minor,
struct proc_dir_entry *root,
struct proc_dir_entry **dev_root);
extern int drm_proc_cleanup(int minor,
struct proc_dir_entry *root,
struct proc_dir_entry *dev_root);
extern int drm_proc_init(struct drm_minor *minor, int minor_id,
struct proc_dir_entry *root);
extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root);

/* Scatter Gather Support (drm_scatter.h) */
extern void drm_sg_cleanup(struct drm_sg_mem * entry);
Expand All @@ -1071,8 +1069,8 @@ extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);
struct drm_sysfs_class;
extern struct class *drm_sysfs_create(struct module *owner, char *name);
extern void drm_sysfs_destroy(void);
extern int drm_sysfs_device_add(struct drm_device *dev, struct drm_head *head);
extern void drm_sysfs_device_remove(struct drm_device *dev);
extern int drm_sysfs_device_add(struct drm_minor *minor);
extern void drm_sysfs_device_remove(struct drm_minor *minor);

/*
* Basic memory manager support (drm_mm.c)
Expand Down
2 changes: 1 addition & 1 deletion drivers/char/drm/drm_agpsupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ EXPORT_SYMBOL(drm_agp_acquire);
int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
return drm_agp_acquire((struct drm_device *) file_priv->head->dev);
return drm_agp_acquire((struct drm_device *) file_priv->minor->dev);
}

/**
Expand Down
60 changes: 28 additions & 32 deletions drivers/char/drm/drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,35 +313,36 @@ static void drm_cleanup(struct drm_device * dev)
drm_ht_remove(&dev->map_hash);
drm_ctxbitmap_cleanup(dev);

drm_put_head(&dev->primary);
drm_put_minor(&dev->primary);
if (drm_put_dev(dev))
DRM_ERROR("Cannot unload module\n");
}

void drm_exit(struct drm_driver *driver)
int drm_minors_cleanup(int id, void *ptr, void *data)
{
int i;
struct drm_device *dev = NULL;
struct drm_head *head;
struct drm_minor *minor = ptr;
struct drm_device *dev;
struct drm_driver *driver = data;

dev = minor->dev;
if (minor->dev->driver != driver)
return 0;

if (minor->type != DRM_MINOR_LEGACY)
return 0;

if (dev)
pci_dev_put(dev->pdev);
drm_cleanup(dev);
return 1;
}

void drm_exit(struct drm_driver *driver)
{
DRM_DEBUG("\n");

for (i = 0; i < drm_cards_limit; i++) {
head = drm_heads[i];
if (!head)
continue;
if (!head->dev)
continue;
if (head->dev->driver != driver)
continue;
dev = head->dev;
if (dev) {
/* release the pci driver */
if (dev->pdev)
pci_dev_put(dev->pdev);
drm_cleanup(dev);
}
}
idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver);

DRM_INFO("Module unloaded\n");
}

Expand All @@ -357,13 +358,7 @@ static int __init drm_core_init(void)
{
int ret = -ENOMEM;

drm_cards_limit =
(drm_cards_limit <
DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
drm_heads =
drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
if (!drm_heads)
goto err_p1;
idr_init(&drm_minors_idr);

if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
goto err_p1;
Expand Down Expand Up @@ -391,7 +386,8 @@ static int __init drm_core_init(void)
drm_sysfs_destroy();
err_p2:
unregister_chrdev(DRM_MAJOR, "drm");
drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);

idr_destroy(&drm_minors_idr);
err_p1:
return ret;
}
Expand All @@ -403,7 +399,7 @@ static void __exit drm_core_exit(void)

unregister_chrdev(DRM_MAJOR, "drm");

drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
idr_destroy(&drm_minors_idr);
}

module_init(drm_core_init);
Expand Down Expand Up @@ -452,7 +448,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
struct drm_file *file_priv = filp->private_data;
struct drm_device *dev = file_priv->head->dev;
struct drm_device *dev = file_priv->minor->dev;
struct drm_ioctl_desc *ioctl;
drm_ioctl_t *func;
unsigned int nr = DRM_IOCTL_NR(cmd);
Expand All @@ -465,7 +461,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,

DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
task_pid_nr(current), cmd, nr,
(long)old_encode_dev(file_priv->head->device),
(long)old_encode_dev(file_priv->minor->device),
file_priv->authenticated);

if ((nr >= DRM_CORE_IOCTL_COUNT) &&
Expand Down
37 changes: 17 additions & 20 deletions drivers/char/drm/drm_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,15 @@ static int drm_setup(struct drm_device * dev)
int drm_open(struct inode *inode, struct file *filp)
{
struct drm_device *dev = NULL;
int minor = iminor(inode);
int minor_id = iminor(inode);
struct drm_minor *minor;
int retcode = 0;

if (!((minor >= 0) && (minor < drm_cards_limit)))
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
return -ENODEV;

if (!drm_heads[minor])
return -ENODEV;

if (!(dev = drm_heads[minor]->dev))
if (!(dev = minor->dev))
return -ENODEV;

retcode = drm_open_helper(inode, filp, dev);
Expand Down Expand Up @@ -168,19 +167,18 @@ EXPORT_SYMBOL(drm_open);
int drm_stub_open(struct inode *inode, struct file *filp)
{
struct drm_device *dev = NULL;
int minor = iminor(inode);
struct drm_minor *minor;
int minor_id = iminor(inode);
int err = -ENODEV;
const struct file_operations *old_fops;

DRM_DEBUG("\n");

if (!((minor >= 0) && (minor < drm_cards_limit)))
return -ENODEV;

if (!drm_heads[minor])
minor = idr_find(&drm_minors_idr, minor_id);
if (!minor)
return -ENODEV;

if (!(dev = drm_heads[minor]->dev))
if (!(dev = minor->dev))
return -ENODEV;

old_fops = filp->f_op;
Expand Down Expand Up @@ -225,7 +223,7 @@ static int drm_cpu_valid(void)
static int drm_open_helper(struct inode *inode, struct file *filp,
struct drm_device * dev)
{
int minor = iminor(inode);
int minor_id = iminor(inode);
struct drm_file *priv;
int ret;

Expand All @@ -234,7 +232,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
if (!drm_cpu_valid())
return -EINVAL;

DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor);
DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id);

priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
if (!priv)
Expand All @@ -245,8 +243,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
priv->filp = filp;
priv->uid = current->euid;
priv->pid = task_pid_nr(current);
priv->minor = minor;
priv->head = drm_heads[minor];
priv->minor = idr_find(&drm_minors_idr, minor_id);
priv->ioctl_count = 0;
/* for compatibility root is always authenticated */
priv->authenticated = capable(CAP_SYS_ADMIN);
Expand Down Expand Up @@ -297,11 +294,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
int drm_fasync(int fd, struct file *filp, int on)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->head->dev;
struct drm_device *dev = priv->minor->dev;
int retcode;

DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
(long)old_encode_dev(priv->head->device));
(long)old_encode_dev(priv->minor->device));
retcode = fasync_helper(fd, filp, on, &dev->buf_async);
if (retcode < 0)
return retcode;
Expand All @@ -324,7 +321,7 @@ EXPORT_SYMBOL(drm_fasync);
int drm_release(struct inode *inode, struct file *filp)
{
struct drm_file *file_priv = filp->private_data;
struct drm_device *dev = file_priv->head->dev;
struct drm_device *dev = file_priv->minor->dev;
int retcode = 0;
unsigned long irqflags;

Expand All @@ -341,7 +338,7 @@ int drm_release(struct inode *inode, struct file *filp)

DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
task_pid_nr(current),
(long)old_encode_dev(file_priv->head->device),
(long)old_encode_dev(file_priv->minor->device),
dev->open_count);

if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
Expand Down
Loading

0 comments on commit 2c14f28

Please sign in to comment.