Hello All Can anybody tell me what steps i follow to write usb driver for ADC card. I have seen Mouse driver, and it is a bit difficult for me to design ADC driver based on this. Can any one will suggest me some solution. Thanks Pankaj. On Tue, 11 Dec 2001 [EMAIL PROTECTED] wrote : > Send linux-usb-devel mailing list submissions to > [EMAIL PROTECTED] > > To subscribe or unsubscribe via the World Wide Web, > visit > https://lists.sourceforge.net/lists/listinfo/linux-usb-- > devel > or, via email, send a message with subject or body > 'help' to > [EMAIL PROTECTED] > > You can reach the person managing the list at > [EMAIL PROTECTED] > > When replying, please edit your Subject line so it is > more specific > than "Re: Contents of linux-usb-devel digest..." > > > Today's Topics: > > 1. Re: Re: Q: device(file) permissions for USB > (Johannes Erdfelt) > 2. Newbie developer issues (Steven Toth) > 3. Re: Newbie developer issues (Georg Acher) > 4. Re: Newbie developer issues (Steven Toth) > 5. Re: EZUSB firmware uploader, clone or share? > (Oliver Neukum) > 6. [RFC] usbfs patch to use the vfs better (Greg KH) > 7. Re: [RFC] usbfs patch to use the vfs better > (David Brownell) > > --__--__-- > > Message: 1 > Date: Mon, 10 Dec 2001 15:03:13 -0500 > From: Johannes Erdfelt <[EMAIL PROTECTED]> > To: David Brownell <[EMAIL PROTECTED]> > Cc: Dan Streetman <[EMAIL PROTECTED]>, > [EMAIL PROTECTED] > Subject: Re: [linux-usb-devel] Re: Q: device(file) > permissions for USB > > On Mon, Dec 10, 2001, David Brownell > <[EMAIL PROTECTED]> wrote: > > > I also never advocated removing topology > information. We already have it > > > via an ioctl call. I just don't want topology > exposed in the directory > > > structure for usbdevfs. > > > > > > In that case, we're forcing the information on > everyone if they care or > > > not, and most programs don't care. > > > > Hmm ... today we force "addressing information" on > everyone regardless > > of whether they care, and unlike topology info it's > quite useless. > > Not really. We use addressing information to provide > unique filenames. > > I don't parse the filename, nor should anyone else. > > It could be completely random for all I care, as long > as it's unique. > > > For backwards compatibility, I think "usbdevfs" > should likely not change > > very much. I can imagine replacing "bus number" with > a stable ID (like > > PCI slot/function), and "bus address" with a > different one (encoding > > topology without new directory names). Adding more > directory structure > > would seem trouble-prone to me. > > I'm against a new directory structure. > > We could encode the topology in the filename, but I > don't see why we > should go through that trouble. > > > But I could imagine something else working a lot > better than "usbdevfs". > > It's just "preliminary" after all, and now folk have > had a chance to learn > > a lot more about how to expose USB to user mode > drivers. There's > > no reason not to leverage that knowledge to create a > better model. > > I agree that we can make it better, but I don't think > exposing the > topology in the directory or filename is better. > > I just think we're focusing on the wrong thing here. > > JE > > > > --__--__-- > > Message: 2 > Reply-To: [EMAIL PROTECTED] > From: "Steven Toth" <[EMAIL PROTECTED]> > To: [EMAIL PROTECTED] > Date: Mon, 10 Dec 2001 20:27:30 +0000 > Subject: [linux-usb-devel] Newbie developer issues > > Hi, > > I'm stuck on a project and I wondered if any of you > kind chaps might be able > to help? (platform = kernel 2.4.16 using usb-uhci) > > I'm writing a device driver (GPL) for the PrimaScan > icam320 webcam (based on > the existing driver for dabusb). I'm using sniffusb > 0.13 to intercept the > windows<->webcam. I've got the device registered, > probed and initialised by > sending the same control messages logged by sniff usb. > > Now problems or errors until now. > > > Question 1. I'm submitting the ISO tranfer URBs which > are all coming back > (via completion handler) with the correct number of > packets - but they are > all empty. No errors, status is fine, frame count is > increasing as expected > ... just no data. What's the best way to prove 100% > that they're coming from > the webcam? I'll happily patch the kernel to output > extra diagnostics if > necessary... Any suggestions? > > Example hexdump from received packet data: > 000000 00ff 0000 0000 0000 0000 0000 0000 0000 > 000010 0000 0000 0000 0000 0000 0000 0000 0000 > * > 000380 00ff 0000 0000 0000 0000 0000 0000 0000 > 000390 0000 0000 0000 0000 0000 0000 0000 0000 > * > 000700 00ff 0000 0000 0000 0000 0000 0000 0000 > 000710 0000 0000 0000 0000 0000 0000 0000 0000 > * > 000a80 00ff 0000 0000 0000 0000 0000 0000 0000 > 000a90 0000 0000 0000 0000 0000 0000 0000 0000 > * > 000e00 00ff 0000 0000 0000 0000 0000 0000 0000 > 000e10 0000 0000 0000 0000 0000 0000 0000 0000 > * > 001180 00ff 0000 0000 0000 0000 0000 0000 0000 > 001190 0000 0000 0000 0000 0000 0000 0000 0000 > > Question 2. Before the URB is passed to the completion > handler, the urb->dev > field is being nullified. What's the rational behind > this? It causes > dabusb.c to oops when calling "unsigned int pipe = > usb_rcvisocpipe > (purb->dev, _DABUSB_ISOPIPE);" Anyone else noticed > this? Look like the > driver in 2.4.16 is broke an no one noticed. > > Question 3. SniffUSB starts the logfile with the output > below, am I correct > in assuming that this is the same as... > > usb_set_configuration (usbdev, usbdev->config[0] > .bConfigurationValue) > and > usb_set_interface (s->usbdev, 0, 6); > > > UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, > IOCTL_INTERNAL_USB_SUBMIT_URB > > >>>>>>>URB 782 going down... > -- URB_FUNCTION_SELECT_INTERFACE: > !!! Hdr.Length is wrong! (is: 32, should be at least: > 56) > ConfigurationHandle = 0xc2a122c0 > Interface: Length = 0x00000024 > Interface: InterfaceNumber = 0x00 > Interface: AlternateSetting = 0x06 > Interface: Class = 0xff > Interface: SubClass = 0x00 > Interface: Protocol = 0x00 > Interface: InterfaceHandle = 0xcc5ed5f0 > Interface: NumberOfPipes = 0x00000001 > > <<<<<<< URB 782 coming back... > -- URB_FUNCTION_SELECT_INTERFACE: > !!! Hdr.Length is wrong! (is: 32, should be at least: > 56) > ConfigurationHandle = 0xc2a122c0 > Interface: Length = 0x00000024 > Interface: InterfaceNumber = 0x00 > Interface: AlternateSetting = 0x06 > Interface: Class = 0xff > Interface: SubClass = 0x00 > Interface: Protocol = 0x00 > Interface: InterfaceHandle = 0xcc5e9d80 > Interface: NumberOfPipes = 0x00000001 > Interface: Pipes[0] : MaximumPacketSize = 0x0380 > Interface: Pipes[0] : EndpointAddress = 0x81 > Interface: Pipes[0] : Interval = 0x01 > Interface: Pipes[0] : PipeType = 0x01 > (UsbdPipeTypeIsochronous) > Interface: Pipes[0] : PipeHandle = 0xcc5e9d98 > Interface: Pipes[0] : MaxTransferSize = 0x00008000 > Interface: Pipes[0] : PipeFlags = 0x00 > UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, > IOCTL_INTERNAL_USB_SUBMIT_URB > > I know you're all busy but any advise/comments would be > very welcome. > > Thanks again, > > Steve > > > ________________________________________________________- > _________ > Get your FREE download of MSN Explorer at > http://explorer.msn.com/intl.asp > > > > --__--__-- > > Message: 3 > Date: Mon, 10 Dec 2001 22:07:48 +0100 > From: Georg Acher <[EMAIL PROTECTED]> > To: [EMAIL PROTECTED] > Subject: Re: [linux-usb-devel] Newbie developer issues > > On Mon, Dec 10, 2001 at 08:27:30PM +0000, Steven Toth > wrote: > > > Question 1. I'm submitting the ISO tranfer URBs which > are all coming back > > (via completion handler) with the correct number of > packets - but they are > > all empty. No errors, status is fine, frame count is > increasing as expected > > ... just no data. What's the best way to prove 100% > that they're coming from > > the webcam? I'll happily patch the kernel to output > extra diagnostics if > > necessary... Any suggestions? > > Fill the memory with another pattern (eg. 0xaa or such) > . If it is changed, > it definitely came from the device. Another hint would > be the length of each > frame. > > > Question 2. Before the URB is passed to the > completion handler, the urb->dev > > field is being nullified. What's the rational behind > this? It causes > > There's a potential race how to distinguish when an URB > is definitely > finished by the HCD. The nulled ->dev prohibits > immediate resubmission for > example. > > > dabusb.c to oops when calling "unsigned int pipe = > usb_rcvisocpipe > > (purb->dev, _DABUSB_ISOPIPE);" Anyone else noticed > this? Look like the > > driver in 2.4.16 is broke an no one noticed. > > The dabusb-driver wasn't updated for a long time, since > the device also > wasn't (commercially) available (at that time...). > Since Terratec now starts > to sell the DR-Box-1 (their name of the receiver), it > will get an update soon. > The current dabusb.c can be found in our CVS at > http://usb.cs.tum.edu/ > > > Question 3. SniffUSB starts the logfile with the > output below, am I correct > > in assuming that this is the same as... > > > > usb_set_configuration (usbdev, usbdev->config[0] > .bConfigurationValue) > > and > > usb_set_interface (s->usbdev, 0, 6); > > I'm not familiar with SniffUSB... > -- > Georg Acher, [EMAIL PROTECTED] > http://www.in.tum.de/~acher/ > "Oh no, not again !" The bowl of petunias > > > > --__--__-- > > Message: 4 > Reply-To: [EMAIL PROTECTED] > From: "Steven Toth" <[EMAIL PROTECTED]> > To: [EMAIL PROTECTED] > Subject: Re: [linux-usb-devel] Newbie developer issues > Date: Mon, 10 Dec 2001 21:44:35 +0000 > > > Georg, thanks for the feedback.... > > >Fill the memory with another pattern (eg. 0xaa or such) > . If it > >is changed, it definitely came from the device. > Another hint > >would be the length of each frame. > > Sorry, my fault, I should I said, I already tried that > but I'm still getting > zero's (indicating that the device is indeed sending > them). The length is > also good. To be honest, I think the frames are OK, > probably me being > anal... I wanted to double/triple check the results. > > > > > > Question 2. Before the URB is passed to the > completion handler, the > >urb->dev > > > field is being nullified. What's the rational > behind this? It causes > > > >There's a potential race how to distinguish when an > URB is definitely > >finished by the HCD. The nulled ->dev prohibits > immediate resubmission for > >example. > > Ok, that makes sense. I went though 20 oops's before I > installed kmsgdump > and found out why. :-) > > > > > > dabusb.c to oops when calling "unsigned int pipe = > usb_rcvisocpipe > > > (purb->dev, _DABUSB_ISOPIPE);" Anyone else noticed > this? Look like the > > > driver in 2.4.16 is broke an no one noticed. > > > >The dabusb-driver wasn't updated for a long time, > since the device also > >wasn't (commercially) available (at that time...). > Since Terratec now > >starts > >to sell the DR-Box-1 (their name of the receiver), it > will get an update > >soon. > >The current dabusb.c can be found in our CVS at > http://usb.cs.tum.edu/ > > > > > Question 3. SniffUSB starts the logfile with the > output below, am I > >correct > > > in assuming that this is the same as... > > > > > > usb_set_configuration (usbdev, usbdev->config[0] > .bConfigurationValue) > > > and > > > usb_set_interface (s->usbdev, 0, 6); > > > >I'm not familiar with SniffUSB... > > Thanks anyway, > > Steve > > ________________________________________________________- > _________ > Get your FREE download of MSN Explorer at > http://explorer.msn.com/intl.asp > > > > --__--__-- > > Message: 5 > From: [EMAIL PROTECTED] (Oliver Neukum) > Reply-To: [EMAIL PROTECTED] > To: David Brownell <[EMAIL PROTECTED]> > Subject: Re: [linux-usb-devel] EZUSB firmware uploader, > clone or share? > Date: Tue, 11 Dec 2001 00:00:25 +0100 > Cc: [EMAIL PROTECTED] > > Am Montag, 10. Dezember 2001 18:41 schrieb David > Brownell: > > When "struct usb_device" gets suspend/resume methods, > > wouldn't such a device just turn its suspend() into a > disconnect > > so it gets fully re-enumerated on a resume()? > > > > - Dave > > Firstly, with current device names you must not do so > or you could > find your devices rearranged on resume. > Secondly, even if you did so, it wouldn't matter, as > the device still > exists as far as the block layer is concerned. > To reload firmware on a rw block device you simply must > allocate > memory only with GFP_NOIO. Thus if you want to do it in > user space > you must have a demon running which mlocks everything > relevant. > You cannot simply run a shell script on resume. > > Regards > Oliver > > > --__--__-- > > Message: 6 > Date: Mon, 10 Dec 2001 15:37:16 -0800 > From: Greg KH <[EMAIL PROTECTED]> > To: [EMAIL PROTECTED] > Subject: [linux-usb-devel] [RFC] usbfs patch to use the > vfs better > > Hi all, > > Here's a patch that converts the usbfs code to use the > vfs layer much > better. The code is based on pcihpfs, driverfs, and > ramfs which all are > very simple filesystems. It ends up reducing much of > the code, and > finally the "special" files are easier to understand > how they are > created :) It also removes lots of BKL accesses, and > removes the > usbdevice_fs entries from the inode and super_block > kernel structures. > > I've tested this out with usbview and lsusb, which are > the only programs > that I have that use the filesystem. Could people with > devices that > access the filesystem (like gphoto2 and other libusb > based programs) > please test this out and let me know if I've broken > anything? > > I know I don't have the mount permissions correct right > now, but I will > fix that before submitting the patch to Linus. > > thanks, > > greg k-h > > > diff -Nru a/drivers/usb/devio.c b/drivers/usb/devio.c > --- a/drivers/usb/devio.c Mon Dec 10 15:24:23 2001 > +++ b/drivers/usb/devio.c Mon Dec 10 15:24:23 2001 > @@ -471,9 +471,7 @@ > */ > lock_kernel(); > ret = -ENOENT; > - if (ITYPE(inode->i_ino) != IDEVICE) > - goto out; > - dev = inode->u.usbdev_i.p.dev; > + dev = inode->u.generic_ip; > if (!dev) > goto out; > ret = -ENOMEM; > diff -Nru a/drivers/usb/inode.c b/drivers/usb/inode.c > --- a/drivers/usb/inode.c Mon Dec 10 15:24:24 2001 > +++ b/drivers/usb/inode.c Mon Dec 10 15:24:24 2001 > @@ -41,128 +41,19 @@ > #include <linux/usbdevice_fs.h> > #include <asm/uaccess.h> > > -/* ----------------------------------------------------- > ----------------- */ > - > -/* > - * This list of superblocks is still used, > - * but since usbdevfs became FS_SINGLE > - * there is only one super_block. > - */ > -static LIST_HEAD(superlist); > - > -struct special { > - const char *name; > - struct file_operations *fops; > - struct inode *inode; > - struct list_head inodes; > -}; > - > -static struct special special[] = { > - { "devices", &usbdevfs_devices_fops, }, > - { "drivers", &usbdevfs_drivers_fops, } > -}; > - > -#define NRSPECIAL (sizeof(special)/sizeof(special[0])) > - > -/* ----------------------------------------------------- > ----------------- */ > - > -static int dnumber(struct dentry *dentry) > -{ > - const char *name; > - unsigned int s; > - > - if (dentry->d_name.len != 3) > - return -1; > - name = dentry->d_name.name; > - if (name[0] < '0' || name[0] > '9' || > - name[1] < '0' || name[1] > '9' || > - name[2] < '0' || name[2] > '9') > - return -1; > - s = name[0] - '0'; > - s = s * 10 + name[1] - '0'; > - s = s * 10 + name[2] - '0'; > - return s; > -} > - > -/* > - * utility functions; should be called with the kernel > lock held > - * to protect against busses/devices > appearing/disappearing > - */ > - > -static void new_dev_inode(struct usb_device *dev, > struct super_block *sb) > -{ > - struct inode *inode; > - unsigned int devnum = dev->devnum; > - unsigned int busnum = dev->bus->busnum; > - > - if (devnum < 1 || devnum > 127 || busnum > 255) > - return; > - inode = iget(sb, IDEVICE | (busnum << 8) | devnum); > - if (!inode) { > - printk(KERN_ERR "usbdevfs: cannot create inode for > bus %u device %u\n", busnum, devnum); > - return; > - } > - inode->i_atime = inode->i_mtime = inode->i_ctime = > CURRENT_TIME; > - inode->i_uid = sb->u.usbdevfs_sb.devuid; > - inode->i_gid = sb->u.usbdevfs_sb.devgid; > - inode->i_mode = sb->u.usbdevfs_sb.devmode | S_IFREG; > - inode->i_fop = &usbdevfs_device_file_operations; > - inode->i_size = sizeof(struct usb_device_descriptor); > - inode->u.usbdev_i.p.dev = dev; > - list_add_tail(&inode->u.usbdev_i.slist, > &sb->u.usbdevfs_sb.ilist); > - list_add_tail(&inode->u.usbdev_i.dlist, &dev->inodes); > -} > - > -static void recurse_new_dev_inode(struct usb_device > *dev, struct super_block *sb) > -{ > - unsigned int i; > - > - if (!dev) > - return; > - new_dev_inode(dev, sb); > - for (i = 0; i < dev->maxchild; i++) { > - if (!dev->children[i]) > - continue; > - recurse_new_dev_inode(dev->children[i], sb); > - } > -} > > -static void new_bus_inode(struct usb_bus *bus, struct > super_block *sb) > -{ > - struct inode *inode; > - unsigned int busnum = bus->busnum; > - > - if (busnum > 255) > - return; > - inode = iget(sb, IBUS | (busnum << 8)); > - if (!inode) { > - printk(KERN_ERR "usbdevfs: cannot create inode for > bus %u\n", busnum); > - return; > - } > - inode->i_atime = inode->i_mtime = inode->i_ctime = > CURRENT_TIME; > - inode->i_uid = sb->u.usbdevfs_sb.busuid; > - inode->i_gid = sb->u.usbdevfs_sb.busgid; > - inode->i_mode = sb->u.usbdevfs_sb.busmode | S_IFDIR; > - inode->i_op = &usbdevfs_bus_inode_operations; > - inode->i_fop = &usbdevfs_bus_file_operations; > - inode->u.usbdev_i.p.bus = bus; > - list_add_tail(&inode->u.usbdev_i.slist, > &sb->u.usbdevfs_sb.ilist); > - list_add_tail(&inode->u.usbdev_i.dlist, &bus->inodes); > -} > - > -static void free_inode(struct inode *inode) > -{ > - inode->u.usbdev_i.p.bus = NULL; > - inode->u.usbdev_i.p.dev = NULL; > - inode->i_mode &= ~S_IRWXUGO; > - inode->i_uid = inode->i_gid = 0; > - inode->i_size = 0; > - list_del(&inode->u.usbdev_i.slist); > - INIT_LIST_HEAD(&inode->u.usbdev_i.slist); > - list_del(&inode->u.usbdev_i.dlist); > - INIT_LIST_HEAD(&inode->u.usbdev_i.dlist); > - iput(inode); > -} > +static struct super_operations usbfs_ops; > +static struct address_space_operations usbfs_aops; > +static struct file_operations usbfs_dir_operations; > +static struct file_operations default_file_operations; > +static struct inode_operations > usbfs_dir_inode_operations; > +static struct vfsmount *usbfs_mount; > +static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED; > +static int mount_count = 0; > + > +static struct dentry *devices_dentry; > +static struct dentry *drivers_dentry; > +static int num_buses; > > static int parse_options(struct super_block *s, char > *data) > { > @@ -242,6 +133,7 @@ > } > } > > +/* > s->u.usbdevfs_sb.devuid = devuid; > s->u.usbdevfs_sb.devgid = devgid; > s->u.usbdevfs_sb.devmode = devmode; > @@ -251,461 +143,541 @@ > s->u.usbdevfs_sb.listuid = listuid; > s->u.usbdevfs_sb.listgid = listgid; > s->u.usbdevfs_sb.listmode = listmode; > - > +*/ > return 0; > } > > -static struct usb_bus *usbdevfs_findbus(int busnr) > + > +/* ----------------------------------------------------- > ----------------- */ > + > +static struct dentry *usbfs_lookup (struct inode *dir, > struct dentry *dentry) > { > - struct list_head *list; > - struct usb_bus *bus; > + d_add(dentry, NULL); > + return NULL; > +} > > - down (&usb_bus_list_lock); > - for (list = usb_bus_list.next; list != > &usb_bus_list; list = list->next) { > - bus = list_entry(list, struct usb_bus, > bus_list); > - if (bus->busnum == busnr) { > - up (&usb_bus_list_lock); > - return bus; > +static int usbfs_statfs(struct super_block *sb, struct > statfs *buf) > +{ > + buf->f_type = USBDEVICE_SUPER_MAGIC; > + buf->f_bsize = PAGE_CACHE_SIZE; > + buf->f_namelen = NAME_MAX; > + return 0; > +} > + > +static struct inode *usbfs_get_inode (struct > super_block *sb, int mode, int dev) > +{ > + struct inode *inode = new_inode(sb); > + > + if (inode) { > + inode->i_mode = mode; > + inode->i_uid = current->fsuid; > + inode->i_gid = current->fsgid; > + inode->i_blksize = PAGE_CACHE_SIZE; > + inode->i_blocks = 0; > + inode->i_rdev = NODEV; > + inode->i_mapping->a_ops = &usbfs_aops; > + inode->i_atime = inode->i_mtime = inode->i_ctime = > CURRENT_TIME; > + switch (mode & S_IFMT) { > + default: > + init_special_inode(inode, mode, dev); > + break; > + case S_IFREG: > + inode->i_fop = &default_file_operations; > + break; > + case S_IFDIR: > + inode->i_op = &usbfs_dir_inode_operations; > + inode->i_fop = &usbfs_dir_operations; > + break; > } > - } > - up (&usb_bus_list_lock); > - return NULL; > + } > + return inode; > } > > -#if 0 > -static struct usb_device *finddev(struct usb_device > *dev, int devnr) > +static int usbfs_mknod (struct inode *dir, struct > dentry *dentry, int mode, int dev) > { > - unsigned int i; > - struct usb_device *d2; > + struct inode *inode = usbfs_get_inode(dir->i_sb, mode, > dev); > + int error = -ENOSPC; > > - if (!dev) > - return NULL; > - if (dev->devnum == devnr) > - return dev; > - for (i = 0; i < dev->maxchild; i++) { > - if (!dev->children[i]) > - continue; > - if ((d2 = finddev(dev->children[i], > devnr))) > - return d2; > - } > - return NULL; > + if (inode) { > + d_instantiate(dentry, inode); > + dget(dentry); > + error = 0; > + } > + return error; > } > > -static struct usb_device *usbdevfs_finddevice(struct > usb_bus *bus, int devnr) > +static int usbfs_mkdir (struct inode *dir, struct > dentry *dentry, int mode) > { > - return finddev(bus->root_hub, devnr); > + return usbfs_mknod (dir, dentry, mode | S_IFDIR, 0); > } > -#endif > > -/* ----------------------------------------------------- > ----------------- */ > +static int usbfs_create (struct inode *dir, struct > dentry *dentry, int mode) > +{ > + return usbfs_mknod (dir, dentry, mode | S_IFREG, 0); > +} > > -static int usbdevfs_revalidate(struct dentry *dentry, > int flags) > +static int usbfs_link (struct dentry *old_dentry, > struct inode *dir, > + struct dentry *dentry) > { > - struct inode *inode = dentry->d_inode; > + struct inode *inode = old_dentry->d_inode; > > - if (!inode) > - return 0; > - if (ITYPE(inode->i_ino) == IBUS && > !inode->u.usbdev_i.p.bus) > - return 0; > - if (ITYPE(inode->i_ino) == IDEVICE && > !inode->u.usbdev_i.p.dev) > - return 0; > - return 1; > + if(S_ISDIR(inode->i_mode)) > + return -EPERM; > + > + inode->i_nlink++; > + atomic_inc(&inode->i_count); > + dget(dentry); > + d_instantiate(dentry, inode); > + return 0; > } > > -static struct dentry_operations > usbdevfs_dentry_operations = { > - d_revalidate: usbdevfs_revalidate, > -}; > +static inline int usbfs_positive (struct dentry > *dentry) > +{ > + return dentry->d_inode && !d_unhashed(dentry); > +} > > -static struct dentry *usbdevfs_root_lookup(struct > inode *dir, struct dentry *dentry) > +static int usbfs_empty (struct dentry *dentry) > { > - int busnr; > - unsigned long ino = 0; > - unsigned int i; > - struct inode *inode; > + struct list_head *list; > > - /* sanity check */ > - if (dir->i_ino != IROOT) > - return ERR_PTR(-EINVAL); > - dentry->d_op = &usbdevfs_dentry_operations; > - busnr = dnumber(dentry); > - if (busnr >= 0 && busnr <= 255) > - ino = IBUS | (busnr << 8); > - if (!ino) { > - for (i = 0; i < NRSPECIAL; i++) { > - if (strlen(special[i].name) == dentry->d_name.len > && > - !strncmp(special[i].name, dentry->d_name.name, > dentry->d_name.len)) { > - ino = ISPECIAL | (i + IROOT + 1); > - break; > - } > - } > - } > - if (!ino) > - return ERR_PTR(-ENOENT); > - inode = iget(dir->i_sb, ino); > - if (!inode) > - return ERR_PTR(-EINVAL); > - if (inode && ITYPE(ino) == IBUS && > inode->u.usbdev_i.p.bus == NULL) { > - iput(inode); > - inode = NULL; > + spin_lock(&dcache_lock); > + > + list_for_each(list, &dentry->d_subdirs) { > + struct dentry *de = list_entry(list, struct dentry, > d_child); > + if (usbfs_positive(de)) { > + spin_unlock(&dcache_lock); > + return 0; > + } > } > - d_add(dentry, inode); > - return NULL; > + > + spin_unlock(&dcache_lock); > + return 1; > } > > -static struct dentry *usbdevfs_bus_lookup(struct inode > *dir, struct dentry *dentry) > +static int usbfs_unlink (struct inode *dir, struct > dentry *dentry) > { > - struct inode *inode; > - int devnr; > + int error = -ENOTEMPTY; > > - /* sanity check */ > - if (ITYPE(dir->i_ino) != IBUS) > - return ERR_PTR(-EINVAL); > - dentry->d_op = &usbdevfs_dentry_operations; > - devnr = dnumber(dentry); > - if (devnr < 1 || devnr > 127) > - return ERR_PTR(-ENOENT); > - inode = iget(dir->i_sb, IDEVICE | (dir->i_ino & (0xff > << 8)) | devnr); > - if (!inode) > - return ERR_PTR(-EINVAL); > - if (inode && inode->u.usbdev_i.p.dev == NULL) { > - iput(inode); > - inode = NULL; > + if (usbfs_empty(dentry)) { > + struct inode *inode = dentry->d_inode; > + > + inode->i_nlink--; > + dput(dentry); > + error = 0; > } > - d_add(dentry, inode); > - return NULL; > + return error; > } > > -static int usbdevfs_root_readdir(struct file *filp, > void *dirent, filldir_t filldir) > +static int usbfs_rename (struct inode *old_dir, struct > dentry *old_dentry, > + struct inode *new_dir, struct dentry *new_dentry) > { > - struct inode *inode = filp->f_dentry->d_inode; > - unsigned long ino = inode->i_ino; > - struct special *spec; > - struct list_head *list; > - struct usb_bus *bus; > - char numbuf[8]; > - unsigned int i; > - > - /* sanity check */ > - if (ino != IROOT) > - return -EINVAL; > - i = filp->f_pos; > - switch (i) { > - case 0: > - if (filldir(dirent, ".", 1, i, IROOT, DT_DIR) < 0) > - return 0; > - filp->f_pos++; > - i++; > - /* fall through */ > + int error = -ENOTEMPTY; > > - case 1: > - if (filldir(dirent, "..", 2, i, IROOT, DT_DIR) < 0) > - return 0; > - filp->f_pos++; > - i++; > - /* fall through */ > - > - default: > - > - while (i >= 2 && i < 2+NRSPECIAL) { > - spec = &special[filp->f_pos-2]; > - if (filldir(dirent, spec->name, strlen(spec->name), > i, ISPECIAL | (filp->f_pos-2+IROOT), DT_UNKNOWN) < 0) > - return 0; > - filp->f_pos++; > - i++; > + if (usbfs_empty(new_dentry)) { > + struct inode *inode = new_dentry->d_inode; > + if (inode) { > + inode->i_nlink--; > + dput(new_dentry); > } > - if (i < 2+NRSPECIAL) > - return 0; > - i -= 2+NRSPECIAL; > - down (&usb_bus_list_lock); > - for (list = usb_bus_list.next; list != &usb_bus_list; > list = list->next) { > - if (i > 0) { > - i--; > - continue; > - } > - bus = list_entry(list, struct usb_bus, bus_list); > - sprintf(numbuf, "%03d", bus->busnum); > - if (filldir(dirent, numbuf, 3, filp->f_pos, IBUS | > ((bus->busnum & 0xff) << 8), DT_UNKNOWN) < 0) > - break; > - filp->f_pos++; > - } > - up (&usb_bus_list_lock); > - return 0; > + error = 0; > } > + return error; > } > > -static int bus_readdir(struct usb_device *dev, > unsigned long ino, int pos, struct file *filp, void > *dirent, filldir_t filldir) > -{ > - char numbuf[8]; > - unsigned int i; > - > - if (!dev) > - return pos; > - sprintf(numbuf, "%03d", dev->devnum); > - if (pos > 0) > - pos--; > - else { > - if (filldir(dirent, numbuf, 3, filp->f_pos, ino | > (dev->devnum & 0xff), DT_UNKNOWN) < 0) > - return -1; > - filp->f_pos++; > - } > - for (i = 0; i < dev->maxchild; i++) { > - if (!dev->children[i]) > - continue; > - pos = bus_readdir(dev->children[i], ino, pos, filp, > dirent, filldir); > - if (pos < 0) > - return -1; > - } > - return pos; > -} > - > -static int usbdevfs_bus_readdir(struct file *filp, > void *dirent, filldir_t filldir) > -{ > - struct inode *inode = filp->f_dentry->d_inode; > - unsigned long ino = inode->i_ino; > - struct usb_bus *bus; > - > - /* sanity check */ > - if (ITYPE(ino) != IBUS) > - return -EINVAL; > - switch ((unsigned int)filp->f_pos) { > - case 0: > - if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) > < 0) > - return 0; > - filp->f_pos++; > - /* fall through */ > +#define usbfs_rmdir usbfs_unlink > > - case 1: > - if (filldir(dirent, "..", 2, filp->f_pos, IROOT, > DT_DIR) < 0) > - return 0; > - filp->f_pos++; > - /* fall through */ > +/* default file operations */ > +static ssize_t default_read_file (struct file *file, > char *buf, size_t count, loff_t *ppos) > +{ > + return 0; > +} > + > +static ssize_t default_write_file (struct file *file, > const char *buf, size_t count, loff_t *ppos) > +{ > + return count; > +} > + > +static loff_t default_file_lseek (struct file *file, > loff_t offset, int orig) > +{ > + loff_t retval = -EINVAL; > > + switch(orig) { > + case 0: > + if (offset > 0) { > + file->f_pos = offset; > + retval = file->f_pos; > + } > + break; > + case 1: > + if ((offset + file->f_pos) > 0) { > + file->f_pos += offset; > + retval = file->f_pos; > + } > + break; > default: > - lock_kernel(); > - bus = usbdevfs_findbus(IBUSNR(ino)); > - bus_readdir(bus->root_hub, IDEVICE | ((bus->busnum & > 0xff) << 8), filp->f_pos-2, filp, dirent, filldir); > - unlock_kernel(); > - return 0; > + break; > } > + return retval; > } > > -static struct file_operations > usbdevfs_root_file_operations = { > - readdir: usbdevfs_root_readdir, > +static int default_open (struct inode *inode, struct > file *filp) > +{ > + if (inode->u.generic_ip) > + filp->private_data = inode->u.generic_ip; > + > + return 0; > +} > + > +static int default_sync_file (struct file *file, > struct dentry *dentry, int datasync) > +{ > + return 0; > +} > + > +static struct address_space_operations usbfs_aops = { > }; > > -static struct inode_operations > usbdevfs_root_inode_operations = { > - lookup: usbdevfs_root_lookup, > +static struct file_operations usbfs_dir_operations = { > + read: generic_read_dir, > + readdir: dcache_readdir, > + fsync: default_sync_file, > }; > > -static struct file_operations > usbdevfs_bus_file_operations = { > - readdir: usbdevfs_bus_readdir, > +static struct file_operations default_file_operations > = { > + read: default_read_file, > + write: default_write_file, > + open: default_open, > + llseek: default_file_lseek, > + fsync: default_sync_file, > + mmap: generic_file_mmap, > }; > > -static struct inode_operations > usbdevfs_bus_inode_operations = { > - lookup: usbdevfs_bus_lookup, > +static struct inode_operations > usbfs_dir_inode_operations = { > + create: usbfs_create, > + lookup: usbfs_lookup, > + link: usbfs_link, > + unlink: usbfs_unlink, > + mkdir: usbfs_mkdir, > + rmdir: usbfs_rmdir, > + mknod: usbfs_mknod, > + rename: usbfs_rename, > }; > > -static void usbdevfs_read_inode(struct inode *inode) > -{ > - struct special *spec; > +static struct super_operations usbfs_ops = { > + statfs: usbfs_statfs, > + put_inode: force_delete, > +}; > > - inode->i_ctime = inode->i_mtime = inode->i_atime = > CURRENT_TIME; > - inode->i_mode = S_IFREG; > - inode->i_gid = inode->i_uid = 0; > - INIT_LIST_HEAD(&inode->u.usbdev_i.dlist); > - INIT_LIST_HEAD(&inode->u.usbdev_i.slist); > - inode->u.usbdev_i.p.dev = NULL; > - inode->u.usbdev_i.p.bus = NULL; > - switch (ITYPE(inode->i_ino)) { > - case ISPECIAL: > - if (inode->i_ino == IROOT) { > - inode->i_op = &usbdevfs_root_inode_operations; > - inode->i_fop = &usbdevfs_root_file_operations; > - inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; > - return; > - } > - if (inode->i_ino <= IROOT || inode->i_ino > > IROOT+NRSPECIAL) > - return; > - spec = &special[inode->i_ino-(IROOT+1)]; > - inode->i_fop = spec->fops; > - return; > +static struct super_block *usbfs_read_super (struct > super_block *sb, void *data, > + int silent) > +{ > + struct inode *inode; > + struct dentry *root; > > - case IDEVICE: > - return; > + if (parse_options(sb, data)) { > + warn("usbfs: mount parameter error:"); > + return NULL; > + } > > - case IBUS: > - return; > + sb->s_blocksize = PAGE_CACHE_SIZE; > + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; > + sb->s_magic = USBDEVICE_SUPER_MAGIC; > + sb->s_op = &usbfs_ops; > + inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0); > > - default: > - return; > - } > -} > + if (!inode) { > + dbg("%s: could not get inode!\n",__FUNCTION__); > + return NULL; > + } > > -static void usbdevfs_put_super(struct super_block *sb) > -{ > - list_del(&sb->u.usbdevfs_sb.slist); > - INIT_LIST_HEAD(&sb->u.usbdevfs_sb.slist); > - while (!list_empty(&sb->u.usbdevfs_sb.ilist)) > - free_inode(list_entry(sb->u.usbdevfs_sb.ilist.next, > struct inode, u.usbdev_i.slist)); > + root = d_alloc_root(inode); > + if (!root) { > + dbg("%s: could not get root dentry!\n",__FUNCTION__); > + iput(inode); > + return NULL; > + } > + sb->s_root = root; > + return sb; > } > > -static int usbdevfs_statfs(struct super_block *sb, > struct statfs *buf) > +/** > + * fs_create_by_name - create a file, given a name > + * @name: name of file > + * @mode: type of file > + * @parent: dentry of directory to create it in > + * @dentry: resulting dentry of file > + * > + * There is a bit of overhead in creating a file - > basically, we > + * have to hash the name of the file, then look it up. > This will > + * prevent files of the same name. > + * We then call the proper vfs_ function to take care > of all the > + * file creation details. > + * This function handles both regular files and > directories. > + */ > +static int fs_create_by_name (const char *name, mode_t > mode, > + struct dentry *parent, struct dentry **dentry) > { > - buf->f_type = USBDEVICE_SUPER_MAGIC; > - buf->f_bsize = PAGE_SIZE/sizeof(long); /* > ??? */ > - buf->f_bfree = 0; > - buf->f_bavail = 0; > - buf->f_ffree = 0; > - buf->f_namelen = NAME_MAX; > - return 0; > -} > + struct dentry *d = NULL; > + struct qstr qstr; > + int error; > > -static int usbdevfs_remount(struct super_block *s, int > *flags, char *data) > -{ > - struct list_head *ilist = s->u.usbdevfs_sb.ilist.next; > - struct inode *inode; > - int ret; > + /* If the parent is not specified, we create it in > the root. > + * We need the root dentry to do this, which is in > the super > + * block. A pointer to that is in the struct vfsmount > that we > + * have around. > + */ > + if (!parent ) { > + if (usbfs_mount && usbfs_mount->mnt_sb) { > + parent = usbfs_mount->mnt_sb->s_root; > + } > + } > > - if ((ret = parse_options(s, data))) { > - printk(KERN_WARNING "usbdevfs: remount parameter > error\n"); > - return ret; > + if (!parent) { > + dbg("Ah! can not find a parent!\n"); > + return -EFAULT; > } > > - for (; ilist != &s->u.usbdevfs_sb.ilist; ilist = > ilist->next) { > - inode = list_entry(ilist, struct inode, > u.usbdev_i.slist); > + *dentry = NULL; > + qstr.name = name; > + qstr.len = strlen(name); > + qstr.hash = full_name_hash(name,qstr.len); > + > + parent = dget(parent); > + > + down(&parent->d_inode->i_sem); > > - switch (ITYPE(inode->i_ino)) { > - case ISPECIAL : > - inode->i_uid = s->u.usbdevfs_sb.listuid; > - inode->i_gid = s->u.usbdevfs_sb.listgid; > - inode->i_mode = s->u.usbdevfs_sb.listmode | > S_IFREG; > - break; > - case IBUS : > - inode->i_uid = s->u.usbdevfs_sb.busuid; > - inode->i_gid = s->u.usbdevfs_sb.busgid; > - inode->i_mode = s->u.usbdevfs_sb.busmode | S_IFDIR; > - break; > - case IDEVICE : > - inode->i_uid = s->u.usbdevfs_sb.devuid; > - inode->i_gid = s->u.usbdevfs_sb.devgid; > - inode->i_mode = s->u.usbdevfs_sb.devmode | S_IFREG; > - break; > + d = lookup_hash(&qstr,parent); > + > + error = PTR_ERR(d); > + if (!IS_ERR(d)) { > + switch(mode & S_IFMT) { > + case 0: > + case S_IFREG: > + error = vfs_create(parent->d_inode,d,mode); > + break; > + case S_IFDIR: > + error = vfs_mkdir(parent->d_inode,d,mode); > + break; > + default: > + err("cannot create special files\n"); > } > + *dentry = d; > } > + up(&parent->d_inode->i_sem); > > - return 0; > + dput(parent); > + return error; > } > > -static struct super_operations usbdevfs_sops = { > - read_inode: usbdevfs_read_inode, > - put_super: usbdevfs_put_super, > - statfs: usbdevfs_statfs, > - remount_fs: usbdevfs_remount, > -}; > - > -struct super_block *usbdevfs_read_super(struct > super_block *s, void *data, int silent) > +static struct dentry *fs_create_file (const char *name, > mode_t mode, > + struct dentry *parent, void *data, > + struct file_operations *fops) > { > - struct inode *root_inode, *inode; > - struct list_head *blist; > - struct usb_bus *bus; > - unsigned int i; > + struct dentry *dentry; > + int error; > > - if (parse_options(s, data)) { > - printk(KERN_WARNING "usbdevfs: mount parameter > error\n"); > - return NULL; > + dbg("creating file '%s'\n",name); > + > + error = fs_create_by_name(name,mode,parent,&dentry); > + if (error) { > + dentry = NULL; > + } else { > + if (dentry->d_inode) { > + if (data) > + dentry->d_inode->u.generic_ip = data; > + if (fops) > + dentry->d_inode->i_fop = fops; > + } > } > > - /* fill superblock */ > - s->s_blocksize = 1024; > - s->s_blocksize_bits = 10; > - s->s_magic = USBDEVICE_SUPER_MAGIC; > - s->s_op = &usbdevfs_sops; > - INIT_LIST_HEAD(&s->u.usbdevfs_sb.slist); > - INIT_LIST_HEAD(&s->u.usbdevfs_sb.ilist); > - root_inode = iget(s, IROOT); > - if (!root_inode) > - goto out_no_root; > - s->s_root = d_alloc_root(root_inode); > - if (!s->s_root) > - goto out_no_root; > - list_add_tail(&s->u.usbdevfs_sb.slist, &superlist); > - for (i = 0; i < NRSPECIAL; i++) { > - if (!(inode = iget(s, IROOT+1+i))) > - continue; > - inode->i_uid = s->u.usbdevfs_sb.listuid; > - inode->i_gid = s->u.usbdevfs_sb.listgid; > - inode->i_mode = s->u.usbdevfs_sb.listmode | S_IFREG; > - special[i].inode = inode; > - list_add_tail(&inode->u.usbdev_i.slist, > &s->u.usbdevfs_sb.ilist); > - list_add_tail(&inode->u.usbdev_i.dlist, &special[i] > .inodes); > - } > - down (&usb_bus_list_lock); > - for (blist = usb_bus_list.next; blist != > &usb_bus_list; blist = blist->next) { > - bus = list_entry(blist, struct usb_bus, bus_list); > - new_bus_inode(bus, s); > - recurse_new_dev_inode(bus->root_hub, s); > - } > - up (&usb_bus_list_lock); > - return s; > - > - out_no_root: > - printk("usbdevfs_read_super: get root inode > failed\n"); > - iput(root_inode); > - return NULL; > + return dentry; > +} > + > +static void fs_remove_file (struct dentry *dentry) > +{ > + struct dentry *parent = dentry->d_parent; > + > + if (!parent || !parent->d_inode) > + return; > + > + down(&parent->d_inode->i_sem); > + if (usbfs_positive(dentry)) { > + if (dentry->d_inode) { > + if (S_ISDIR(dentry->d_inode->i_mode)) > + vfs_rmdir(parent->d_inode,dentry); > + else > + vfs_unlink(parent->d_inode,dentry); > + } > + > + dput(dentry); > + } > + up(&parent->d_inode->i_sem); > } > > +/* ----------------------------------------------------- > ----------------- */ > + > + > + > /* > - * The usbdevfs name is now depreciated (as of 2.5.1). > + * The usbdevfs name is now deprecated (as of 2.5.1). > * It will be removed when the 2.7.x development cycle > is started. > * You have been warned :) > */ > -static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", > usbdevfs_read_super, FS_SINGLE); > -static DECLARE_FSTYPE(usb_fs_type, "usbfs", > usbdevfs_read_super, FS_SINGLE); > +static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", > usbfs_read_super, FS_SINGLE); > +static DECLARE_FSTYPE(usb_fs_type, "usbfs", > usbfs_read_super, FS_SINGLE); > > /* ----------------------------------------------------- > ----------------- */ > +static int get_mount (void) > +{ > + struct vfsmount *mnt; > + > + spin_lock (&mount_lock); > + if (usbfs_mount) { > + mntget(usbfs_mount); > + ++mount_count; > + spin_unlock (&mount_lock); > + goto go_ahead; > + } > + > + spin_unlock (&mount_lock); > + mnt = kern_mount (&usb_fs_type); > + if (IS_ERR(mnt)) { > + err ("could not mount the fs...erroring out!\n"); > + return -ENODEV; > + } > + spin_lock (&mount_lock); > + if (!usbfs_mount) { > + usbfs_mount = mnt; > + ++mount_count; > + spin_unlock (&mount_lock); > + goto go_ahead; > + } > + mntget(usbfs_mount); > + ++mount_count; > + spin_unlock (&mount_lock); > + mntput(mnt); > + > +go_ahead: > + dbg("mount_count = %d\n", mount_count); > + return 0; > +} > + > +static void remove_mount (void) > +{ > + struct vfsmount *mnt; > + > + spin_lock (&mount_lock); > + mnt = usbfs_mount; > + --mount_count; > + if (!mount_count) > + usbfs_mount = NULL; > + > + spin_unlock (&mount_lock); > + mntput(mnt); > + dbg("mount_count = %d\n", mount_count); > +} > + > +static int create_special_files (void) > +{ > + int retval; > + > + /* create the devices and drivers special files */ > + retval = get_mount (); > + if (retval) > + return retval; > + devices_dentry = fs_create_file ("devices", S_IFREG | > S_IRUGO, > + NULL, NULL, &usbdevfs_devices_fops); > + if (devices_dentry == NULL) { > + err ("Unable to create devices usbfs file"); > + return -ENODEV; > + } > + drivers_dentry = fs_create_file ("drivers", S_IFREG | > S_IRUGO, > + NULL, NULL, &usbdevfs_drivers_fops); > + if (drivers_dentry == NULL) { > + err ("Unable to create drivers usbfs file"); > + return -ENODEV; > + } > + > + return 0; > +} > + > +static void remove_special_files (void) > +{ > + if (devices_dentry) > + fs_remove_file (devices_dentry); > + if (drivers_dentry) > + fs_remove_file (drivers_dentry); > + devices_dentry = NULL; > + drivers_dentry = NULL; > + remove_mount(); > +} > > static void update_special_inodes (void) > { > - int i; > - for (i = 0; i < NRSPECIAL; i++) { > - struct inode *inode = special[i].inode; > + struct inode *inode; > + > + if (devices_dentry) { > + inode = devices_dentry->d_inode; > + if (inode) > + inode->i_atime = inode->i_mtime = inode->i_ctime = > CURRENT_TIME; > + } > + if (drivers_dentry) { > + inode = devices_dentry->d_inode; > if (inode) > inode->i_atime = inode->i_mtime = inode->i_ctime = > CURRENT_TIME; > } > } > > - > void usbdevfs_add_bus(struct usb_bus *bus) > { > - struct list_head *slist; > + char name[8]; > + int retval; > + > + /* create the special files if this is the first bus > added */ > + if (num_buses == 0) { > + retval = create_special_files(); > + if (retval) > + return; > + } > + ++num_buses; > + > + sprintf (name, "%03d", bus->busnum); > + bus->dentry = fs_create_file (name, > + S_IFDIR | S_IXUGO | S_IRUGO, > + NULL, bus, NULL); > + if (bus->dentry == NULL) > + return; > > - lock_kernel(); > - for (slist = superlist.next; slist != &superlist; > slist = slist->next) > - new_bus_inode(bus, list_entry(slist, struct > super_block, u.usbdevfs_sb.slist)); > - update_special_inodes(); > - unlock_kernel(); > usbdevfs_conn_disc_event(); > } > > + > void usbdevfs_remove_bus(struct usb_bus *bus) > { > - lock_kernel(); > - while (!list_empty(&bus->inodes)) > - free_inode(list_entry(bus->inodes.next, struct inode, > u.usbdev_i.dlist)); > - update_special_inodes(); > - unlock_kernel(); > + if (bus->dentry) { > + fs_remove_file (bus->dentry); > + bus->dentry = NULL; > + } > + > + --num_buses; > + if (num_buses <= 0) { > + remove_special_files(); > + num_buses = 0; > + } > + > usbdevfs_conn_disc_event(); > } > > void usbdevfs_add_device(struct usb_device *dev) > { > - struct list_head *slist; > + char name[8]; > + > + sprintf (name, "%03d", dev->devnum); > + dev->dentry = fs_create_file (name, > + S_IFREG | S_IRUGO | S_IWUSR, > + dev->bus->dentry, dev, > + &usbdevfs_device_file_operations); > > - lock_kernel(); > - for (slist = superlist.next; slist != &superlist; > slist = slist->next) > - new_dev_inode(dev, list_entry(slist, struct > super_block, u.usbdevfs_sb.slist)); > update_special_inodes(); > - unlock_kernel(); > usbdevfs_conn_disc_event(); > } > > @@ -715,8 +687,10 @@ > struct siginfo sinfo; > > lock_kernel(); > - while (!list_empty(&dev->inodes)) > - free_inode(list_entry(dev->inodes.next, struct inode, > u.usbdev_i.dlist)); > + if (dev->dentry) { > + fs_remove_file (dev->dentry); > + dev->dentry = NULL; > + } > while (!list_empty(&dev->filelist)) { > ds = list_entry(dev->filelist.next, struct dev_state, > list); > list_del(&ds->list); > @@ -732,9 +706,8 @@ > send_sig_info(ds->discsignr, &sinfo, ds->disctask); > } > } > - > - update_special_inodes(); > unlock_kernel(); > + update_special_inodes(); > usbdevfs_conn_disc_event(); > } > > @@ -748,9 +721,6 @@ > { > int ret; > > - for (ret = 0; ret < NRSPECIAL; ret++) { > - INIT_LIST_HEAD(&special[ret].inodes); > - } > if ((ret = usb_register(&usbdevfs_driver))) > return ret; > if ((ret = register_filesystem(&usb_fs_type))) { > @@ -766,6 +736,10 @@ > /* create mount point for usbdevfs */ > usbdir = proc_mkdir("usb", proc_bus); > #endif > + > + num_buses = 0; > + > + > return ret; > } > > diff -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c > --- a/drivers/usb/usb.c Mon Dec 10 15:24:24 2001 > +++ b/drivers/usb/usb.c Mon Dec 10 15:24:24 2001 > @@ -421,7 +421,6 @@ > bus->bandwidth_isoc_reqs = 0; > > INIT_LIST_HEAD(&bus->bus_list); > - INIT_LIST_HEAD(&bus->inodes); > > atomic_set(&bus->refcnt, 1); > > @@ -1016,7 +1015,6 @@ > dev->bus = bus; > dev->parent = parent; > atomic_set(&dev->refcnt, 1); > - INIT_LIST_HEAD(&dev->inodes); > INIT_LIST_HEAD(&dev->filelist); > > init_MUTEX(&dev->serialize); > diff -Nru a/include/linux/fs.h b/include/linux/fs.h > --- a/include/linux/fs.h Mon Dec 10 15:24:24 2001 > +++ b/include/linux/fs.h Mon Dec 10 15:24:24 2001 > @@ -312,7 +312,6 @@ > #include <linux/udf_fs_i.h> > #include <linux/ncp_fs_i.h> > #include <linux/proc_fs_i.h> > -#include <linux/usbdev_fs_i.h> > #include <linux/jffs2_fs_i.h> > #include <linux/cramfs_fs_sb.h> > > @@ -503,7 +502,6 @@ > struct ncp_inode_info ncpfs_i; > struct proc_inode_info proc_i; > struct socket socket_i; > - struct usbdev_inode_info usbdev_i; > struct jffs2_inode_info jffs2_i; > void *generic_ip; > } u; > @@ -687,7 +685,6 @@ > #include <linux/bfs_fs_sb.h> > #include <linux/udf_fs_sb.h> > #include <linux/ncp_fs_sb.h> > -#include <linux/usbdev_fs_sb.h> > #include <linux/cramfs_fs_sb.h> > #include <linux/jffs2_fs_sb.h> > > @@ -745,7 +742,6 @@ > struct bfs_sb_info bfs_sb; > struct udf_sb_info udf_sb; > struct ncp_sb_info ncpfs_sb; > - struct usbdev_sb_info usbdevfs_sb; > struct jffs2_sb_info jffs2_sb; > struct cramfs_sb_info cramfs_sb; > void *generic_sbp; > diff -Nru a/include/linux/usb.h b/include/linux/usb.h > --- a/include/linux/usb.h Mon Dec 10 15:24:24 2001 > +++ b/include/linux/usb.h Mon Dec 10 15:24:24 2001 > @@ -989,8 +989,7 @@ > int bandwidth_int_reqs; /* number of Interrupt > requesters */ > int bandwidth_isoc_reqs; /* number of Isoc. > requesters */ > > - /* usbdevfs inode list */ > - struct list_head inodes; > + struct dentry *dentry; /* usbfs dentry entry for the > bus */ > > atomic_t refcnt; > }; > @@ -1090,9 +1089,8 @@ > > void *hcpriv; /* Host Controller private data */ > > - /* usbdevfs inode list */ > - struct list_head inodes; > struct list_head filelist; > + struct dentry *dentry; /* usbfs dentry entry for the > device */ > > /* > * Child devices - these can be either new devices > diff -Nru a/include/linux/usbdevice_fs.h > b/include/linux/usbdevice_fs.h > --- a/include/linux/usbdevice_fs.h Mon Dec 10 15:24:24 > 2001 > +++ b/include/linux/usbdevice_fs.h Mon Dec 10 15:24:24 > 2001 > @@ -150,17 +150,6 @@ > #include <linux/list.h> > #include <asm/semaphore.h> > > -/* > - * inode number macros > - */ > -#define ITYPE(x) ((x)&(0xf<<28)) > -#define ISPECIAL (0<<28) > -#define IBUS (1<<28) > -#define IDEVICE (2<<28) > -#define IBUSNR(x) (((x)>>8)&0xff) > -#define IDEVNR(x) ((x)&0xff) > - > -#define IROOT 1 > > struct dev_state { > struct list_head list; /* state list */ > > > --__--__-- > > Message: 7 > Date: Mon, 10 Dec 2001 15:54:43 -0800 > From: David Brownell <[EMAIL PROTECTED]> > Subject: Re: [linux-usb-devel] [RFC] usbfs patch to use > the vfs better > To: Greg KH <[EMAIL PROTECTED]>, > [EMAIL PROTECTED] > > > I've tested this out with usbview and lsusb, which > are the only programs > > that I have that use the filesystem. Could people > with devices that > > access the filesystem (like gphoto2 and other libusb > based programs) > > please test this out and let me know if I've broken > anything? > > I'll see how this works with jUSB, jPhoto, and such ... > but it'll likely > take a while to do that. > > To my understanding, jUSB bangs on that filesystem code > much > more than libusb ... :) > > - Dave > > > > > > --__--__-- > > _______________________________________________ > [EMAIL PROTECTED] > To unsubscribe, use the last form field at: > https://lists.sourceforge.net/lists/listinfo/linux-usb-d- > evel > > > End of linux-usb-devel Digest
_______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel