#include "char.h" #include #include #include #include "doomdev.h" #include "util.h" #include "pci.h" #include "surface.h" #define DOOMDEV_COUNT 256 #define DOOMDEV_NAME "doom" dev_t first; int major; int next_minor = 0; long doom_create_surface(struct file *filp, unsigned long arg) { struct doomdev_ioctl_create_surface *params; params = (struct doomdev_ioctl_create_surface *)arg; return new_surface(params); } long doom_create_texture(struct file *filp, unsigned long arg) { return -1; } long doom_create_flat(struct file *filp, unsigned long arg) { return -1; } long doom_create_colormaps(struct file *filp, unsigned long arg) { return -1; } long doom_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { case DOOMDEV_IOCTL_CREATE_SURFACE: return doom_create_surface(filp, arg); case DOOMDEV_IOCTL_CREATE_TEXTURE: return doom_create_texture(filp, arg); case DOOMDEV_IOCTL_CREATE_FLAT: return doom_create_flat(filp, arg); case DOOMDEV_IOCTL_CREATE_COLORMAPS: return doom_create_colormaps(filp, arg); default: return -EINVAL; } } int doom_open(struct inode *inode, struct file *filp) { return 0; } struct file_operations doomdev_fops = { .owner = THIS_MODULE, .unlocked_ioctl = doom_ioctl, .compat_ioctl = doom_ioctl, .open = doom_open }; struct class *doom_class; int new_doomdev(struct pci_dev *dev) { int err = 0; int minor; struct doom_data *doom_data; dev_t devt; if (next_minor >= DOOMDEV_COUNT) { return -ENOMEM; } doom_data = pci_get_drvdata(dev); doom_data->cdev = cdev_alloc(); if (doom_data->cdev == NULL) { err = -ENOMEM; goto error_cdev; } cdev_init(doom_data->cdev, &doomdev_fops); ORFAIL(cdev_add(doom_data->cdev, first, 1), error_add); minor = next_minor++; devt = MKDEV(major, minor); doom_data->device = device_create(doom_class, &dev->dev, devt, NULL, "doom%d", minor), ORFAIL_PTR(doom_data->device, error_create); return 0; error_create: cdev_del(doom_data->cdev); error_add: error_cdev: return err; } void destroy_doomdev(struct doom_data *doom_data) { device_destroy(doom_class, doom_data->device->devt); cdev_del(doom_data->cdev); } int char_init(void) { int err = 0; ORFAIL(alloc_chrdev_region(&first, 0, DOOMDEV_COUNT, DOOMDEV_NAME), error_region); major = MAJOR(first); doom_class = class_create(THIS_MODULE, "doom"); ORFAIL_PTR(doom_class, error_create); return 0; error_create: unregister_chrdev_region(first, DOOMDEV_COUNT); error_region: return err; } void char_cleanup(void) { unregister_chrdev_region(first, DOOMDEV_COUNT); class_unregister(doom_class); class_destroy(doom_class); }