lkml.org 
[lkml]   [2003]   [Mar]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH 1/3] revert register_chrdev_region change
    Hi,

    On Mon, 24 Mar 2003, Christoph Hellwig wrote:

    > If you look at Roman's patches they don't even hinder your dev_t enlargement
    > but they provide a singificant benefit. Now I'm personally not yet
    > completly happy with his interface either because he still uses the
    > major/minor split, but I'm working on fixing this properly.

    BTW I have an updated patch, which stores the major char_device at
    (0,major), so the remaining space is free for whatever you need.
    Below is a patch which shows how drivers/usb/core/file.c could look
    after this. There are of course further cleanups possible. :)

    bye, Roman

    diff -Nurp -X /home/roman/nodiff linux-2.5.65-bk4-cdev3/drivers/usb/core/file.c linux-2.5.65-bk4-cdev4/drivers/usb/core/file.c
    --- linux-2.5.65-bk4-cdev3/drivers/usb/core/file.c 2003-03-24 10:26:47.000000000 +0100
    +++ linux-2.5.65-bk4-cdev4/drivers/usb/core/file.c 2003-03-24 14:13:37.000000000 +0100
    @@ -32,41 +32,9 @@ devfs_handle_t usb_devfs_handle; /* /dev
    EXPORT_SYMBOL(usb_devfs_handle);

    #define MAX_USB_MINORS 256
    -static struct file_operations *usb_minors[MAX_USB_MINORS];
    -static spinlock_t minor_lock = SPIN_LOCK_UNLOCKED;
    -
    -static int usb_open(struct inode * inode, struct file * file)
    -{
    - int minor = minor(inode->i_rdev);
    - struct file_operations *c;
    - int err = -ENODEV;
    - struct file_operations *old_fops, *new_fops = NULL;
    -
    - spin_lock (&minor_lock);
    - c = usb_minors[minor];
    -
    - if (!c || !(new_fops = fops_get(c))) {
    - spin_unlock(&minor_lock);
    - return err;
    - }
    - spin_unlock(&minor_lock);
    -
    - old_fops = file->f_op;
    - file->f_op = new_fops;
    - /* Curiouser and curiouser... NULL ->open() as "no device" ? */
    - if (file->f_op->open)
    - err = file->f_op->open(inode,file);
    - if (err) {
    - fops_put(file->f_op);
    - file->f_op = fops_get(old_fops);
    - }
    - fops_put(old_fops);
    - return err;
    -}

    static struct file_operations usb_fops = {
    .owner = THIS_MODULE,
    - .open = usb_open,
    };

    int usb_major_init(void)
    @@ -107,12 +75,9 @@ void usb_major_cleanup(void)
    * device, and 0 on success, alone with a value that the driver should
    * use in start_minor.
    */
    -int usb_register_dev (struct file_operations *fops, int minor, int num_minors, int *start_minor)
    +int usb_register_dev (struct file_operations *fops, int minor, int *start_minor)
    {
    int i;
    - int j;
    - int good_spot;
    - int retval = -EINVAL;

    #ifdef CONFIG_USB_DYNAMIC_MINORS
    /*
    @@ -123,37 +88,29 @@ int usb_register_dev (struct file_operat
    minor = 0;
    #endif

    - dbg ("asking for %d minors, starting at %d", num_minors, minor);
    + dbg ("asking for 1 minors, starting at %d", minor);

    if (fops == NULL)
    - goto exit;
    + return -EINVAL;

    *start_minor = 0;
    - spin_lock (&minor_lock);
    for (i = minor; i < MAX_USB_MINORS; ++i) {
    - if (usb_minors[i])
    - continue;
    -
    - good_spot = 1;
    - for (j = 1; j <= num_minors-1; ++j)
    - if (usb_minors[i+j]) {
    - good_spot = 0;
    - break;
    + cdev = cdget(MKDEV(USB_MAJOR, i));
    + if (!cdev->cd_fops) {
    + down(&cdev->cd_sem);
    + if (!cdev->cd_fops) {
    + dbg("found a minor chunk free, starting at %d", i);
    + cdev->cd_fops = fops;
    + up(&cdev->cd_sem);
    + start_minor = i;
    + return 0;
    }
    - if (good_spot == 0)
    - continue;
    -
    - *start_minor = i;
    - dbg("found a minor chunk free, starting at %d", i);
    - for (i = *start_minor; i < (*start_minor + num_minors); ++i)
    - usb_minors[i] = fops;
    -
    - retval = 0;
    - goto exit;
    + up(&cdev->cd_sem);
    + }
    + cdput(cdev);
    }
    -exit:
    - spin_unlock (&minor_lock);
    - return retval;
    +
    + return -EBUSY;
    }
    EXPORT_SYMBOL(usb_register_dev);

    @@ -169,16 +126,21 @@ EXPORT_SYMBOL(usb_register_dev);
    *
    * This should be called by all drivers that use the USB major number.
    */
    -void usb_deregister_dev (int num_minors, int start_minor)
    +void usb_deregister_dev (int minor)
    {
    int i;

    dbg ("removing %d minors starting at %d", num_minors, start_minor);

    - spin_lock (&minor_lock);
    - for (i = start_minor; i < (start_minor + num_minors); ++i)
    - usb_minors[i] = NULL;
    - spin_unlock (&minor_lock);
    + cdev = cdget(MKDEV(USB_MAJOR, minor));
    + down(&cdev->cd_sem);
    + if (cdev->cd_fops) {
    + cdev->cd_fops = NULL;
    + cdput(cdev);
    + } else
    + printk("usb_deregister_dev: releasing invalid dev %d\n", minor);
    + up(&cdev->cd_sem);
    + cdput(cdev);
    }
    EXPORT_SYMBOL(usb_deregister_dev);

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:34    [W:0.025 / U:118.332 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site