[Linux1394-cvslog] rev 759 - trunk
Brought to you by:
aeb,
bencollins
From: SVN U. <ben...@li...> - 2003-02-01 13:57:29
|
Author: bencollins Date: 2003-01-30 21:14:45 -0500 (Thu, 30 Jan 2003) New Revision: 759 Modified: trunk/dv1394-private.h trunk/dv1394.c Log: Merge devfs changes from 2.5.59 Modified: trunk/dv1394-private.h ============================================================================== --- trunk/dv1394-private.h (original) +++ trunk/dv1394-private.h 2003-02-01 08:56:56.000000000 -0500 @@ -583,8 +583,5 @@ #define CIP_N_PAL 1 #define CIP_D_PAL 16 -/* Base for our DevFS entries */ -#define DV1394_DEV_BASE "ieee1394/dv" - #endif /* _DV_1394_PRIVATE_H */ Modified: trunk/dv1394.c ============================================================================== --- trunk/dv1394.c (original) +++ trunk/dv1394.c 2003-02-01 08:56:57.000000000 -0500 @@ -175,6 +175,15 @@ static struct hpsb_highlevel *hl_handle; /* = NULL; */ +static LIST_HEAD(dv1394_devfs); +struct dv1394_devfs_entry { + struct list_head list; + devfs_handle_t devfs; + char name[32]; + struct dv1394_devfs_entry *parent; +}; +static spinlock_t dv1394_devfs_lock = SPIN_LOCK_UNLOCKED; + /* translate from a struct file* to the corresponding struct video_card* */ static inline struct video_card* file_to_video_card(struct file *file) @@ -2447,40 +2456,135 @@ /*** DEVFS HELPERS *********************************************************/ +struct dv1394_devfs_entry * +dv1394_devfs_find( char *name) +{ + struct list_head *lh; + struct dv1394_devfs_entry *p; + + spin_lock( &dv1394_devfs_lock); + if(!list_empty(&dv1394_devfs)) { + list_for_each(lh, &dv1394_devfs) { + p = list_entry(lh, struct dv1394_devfs_entry, list); + if(!strncmp(p->name, name, sizeof(p->name))) { + goto found; + } + } + } + p = NULL; + +found: + spin_unlock( &dv1394_devfs_lock); + return p; +} + #ifdef CONFIG_DEVFS_FS static int dv1394_devfs_add_entry(struct video_card *video) { - char buf[64]; - snprintf(buf, sizeof(buf), DV1394_DEV_BASE "/host%d/%s/%s", - (video->id>>2), - (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"), - (video->mode == MODE_RECEIVE ? "in" : "out")); + char buf[32]; + struct dv1394_devfs_entry *p; + struct dv1394_devfs_entry *parent; - video->devfs_handle = devfs_register(NULL, buf, DEVFS_FL_NONE, + p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL); + if(!p) { + printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n"); + goto err; + } + memset(p, 0, sizeof(struct dv1394_devfs_entry)); + + snprintf(buf, sizeof(buf), "dv/host%d/%s", (video->id>>2), + (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL")); + + parent = dv1394_devfs_find(buf); + if (parent == NULL) { + printk(KERN_ERR "dv1394: unable to locate parent devfs of %s\n", buf); + goto err_free; + } + + video->devfs_handle = devfs_register( + parent->devfs, + (video->mode == MODE_RECEIVE ? "in" : "out"), + DEVFS_FL_NONE, IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394*16 + video->id, S_IFCHR | S_IRUGO | S_IWUGO, &dv1394_fops, (void*) video); + p->devfs = video->devfs_handle; + if (p->devfs == NULL) { + printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/%s/%s\n", + parent->name, + (video->mode == MODE_RECEIVE ? "in" : "out")); + goto err_free; + } + + spin_lock( &dv1394_devfs_lock); + INIT_LIST_HEAD(&p->list); + list_add_tail(&p->list, &dv1394_devfs); + spin_unlock( &dv1394_devfs_lock); + return 0; + + err_free: + kfree(p); + err: + return -ENOMEM; } -static int dv1394_devfs_add_dir(char *name) +static int +dv1394_devfs_add_dir( char *name, + struct dv1394_devfs_entry *parent, + struct dv1394_devfs_entry **out) { - if (!devfs_mk_dir(NULL, name, NULL)) - printk(KERN_ERR "dv1394: unable to create /dev/%s\n", name); - return -ENOMEM; + struct dv1394_devfs_entry *p; + + p = kmalloc(sizeof(struct dv1394_devfs_entry), GFP_KERNEL); + if(!p) { + printk(KERN_ERR "dv1394: cannot allocate dv1394_devfs_entry\n"); + goto err; + } + memset(p, 0, sizeof(struct dv1394_devfs_entry)); + + if (parent == NULL) { + snprintf(p->name, sizeof(p->name), "%s", name); + p->devfs = devfs_mk_dir(ieee1394_devfs_handle, name, NULL); + } else { + snprintf(p->name, sizeof(p->name), "%s/%s", parent->name, name); + p->devfs = devfs_mk_dir(parent->devfs, name, NULL); + } + if (p->devfs == NULL) { + printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/%s\n", p->name); + goto err_free; } + p->parent = parent; + if (out != NULL) *out = p; + + spin_lock( &dv1394_devfs_lock); + INIT_LIST_HEAD(&p->list); + list_add_tail(&p->list, &dv1394_devfs); + spin_unlock( &dv1394_devfs_lock); + return 0; + + err_free: + kfree(p); + err: + return -ENOMEM; } void dv1394_devfs_del( char *name) { - char s[64]; - sprintf(s, "ieee1394/%s", name); - devfs_find_and_unregister(NULL, s, 0, 0, 0, 0); + struct dv1394_devfs_entry *p = dv1394_devfs_find(name); + if (p != NULL) { + devfs_unregister(p->devfs); + + spin_lock( &dv1394_devfs_lock); + list_del(&p->list); + spin_unlock( &dv1394_devfs_lock); + kfree(p); + } } #endif /* CONFIG_DEVFS_FS */ @@ -2664,12 +2768,15 @@ #endif #ifdef CONFIG_DEVFS_FS - snprintf(buf, sizeof(buf), DV1394_DEV_BASE "/host%d", ohci->id); - dv1394_devfs_add_dir(buf); - snprintf(buf, sizeof(buf), DV1394_DEV_BASE "/host%d/NTSC", ohci->id); - dv1394_devfs_add_dir(buf); - snprintf(buf, sizeof(buf), DV1394_DEV_BASE "/host%d/PAL", ohci->id); - dv1394_devfs_add_dir(buf); +{ + struct dv1394_devfs_entry *devfs_entry = dv1394_devfs_find("dv"); + if (devfs_entry != NULL) { + snprintf(buf, sizeof(buf), "host%d", ohci->id); + dv1394_devfs_add_dir(buf, devfs_entry, &devfs_entry); + dv1394_devfs_add_dir("NTSC", devfs_entry, NULL); + dv1394_devfs_add_dir("PAL", devfs_entry, NULL); + } +} #endif dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); @@ -2829,8 +2936,8 @@ } #ifdef CONFIG_DEVFS_FS - if (dv1394_devfs_add_dir(DV1394_DEV_BASE) < 0) { - printk(KERN_ERR "dv1394: unable to create /dev/%s\n", DV1394_DEV_BASE); + if (dv1394_devfs_add_dir("dv", NULL, NULL) < 0) { + printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/dv\n"); ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394); return -ENOMEM; } @@ -2838,7 +2945,7 @@ #ifdef CONFIG_PROC_FS if (dv1394_procfs_add_dir("dv",NULL,NULL) < 0) { - printk(KERN_ERR "dv1394: unable to create /proc/bus/%s\n", DV1394_DEV_BASE); + printk(KERN_ERR "dv1394: unable to create /proc/bus/ieee1394/dv\n"); ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394); #ifdef CONFIG_DEVFS_FS dv1394_devfs_del("dv"); |