Hi,

I have discovered a few (easily fixed) faults with the USB backport:

1. Nothing in /proc/bus/usb even when usbdevfs mounted
======================================================

Symptoms: Even when usbdevfs is mounted on /proc/bus/usb, 'ls' shows
no files or directories. A simple test program that reads the directory
entries using system calls reports error ENOTDIR from call to sys_getdents.

The problem is caused by usbdevfs_root_inode_operations and
usbdevfs_bus_inode_operations not having an initialised
default_file_ops member.

2. Can't read /proc/bus/usb/drivers or /proc/bus/usb/devices
============================================================

Symptoms: (After fixing #1 above) Attempts to 'cat' the above mentioned
files fails.

The problem is caused by missing code in function usbdevfs_read_inode. This
function should set the inode->i_ops field but does not do so - it looks
like
this code was deleted when the backport was done, due to differences in the
way inode structs were set up in the later kernels.

Under 2.2.14, inode structs contain an i_ops field that points to an i_ops
struct; this struct in turn points to the fops struct that describes file
operations that can be performed on the file.

Under 2.3.xx kernels the inode struct directly contains a pointer to the
fops
struct, rather than indirectly via an i_ops struct.


3. Kernel OOPS when mass storage device is connected
====================================================

Symptoms: A kernel oops 'Unable to handle kernel NULL pointer dereference
at virtual address 00000014' when a mass storage device is connected. I saw
it when connecting an Iomega ZIPCD USB CD Rewriter. The oops message (when
decoded) points out build_proc_dir_entries in scsi.c as the offending
function.

This problem is caused in the us_detect function, where the proc_dir field
in the
SCSI Host Template structure is set to NULL. This is OK in 2.3.xx kernels
because in the build_proc_dir_entries function, the proc_dir field is filled
in.
However, in 2.2.14 this function assumes proc_dir already contains a valid
proc_dir_entry pointer.

Patches to fix these problems are below.

BTW, I have managed to get the ZIPCD drive working quite well for reading
CD's.
I haven't worked up the courage to try burning a CD yet! I did try reading
an
audio CD with cdparanoia - this failed miserably, I kept getting

'kernel: usb_control/bulk_msg: timeout'

Any ideas??

Regards,
Mike


=================================Patch
Follows=================================
--- /usr/src/linux/drivers/usb/inode.c.orig Wed Mar 29 18:50:15 2000
+++ /usr/src/linux/drivers/usb/inode.c Thu Apr  6 21:40:49 2000
@@ -48,15 +48,30 @@

 static LIST_HEAD(superlist);

+/* M. Harris 6/4/00:
+ *    These modifications required because under 2.2.14 inode's have
+ *    "i_op" fields which indirectly point to a fops struct.
+ *    The original 2.3.xx code assumes that the inode will directly
+ *    contain a fops struct
+ */
+
 struct special {
  const char *name;
- struct file_operations *fops;
+ struct inode_operations *iops;  /* Changed for backport */
  struct list_head inodes;
 };

+static struct inode_operations usbdevfs_devices_inode_operations = {
+        default_file_ops: &usbdevfs_devices_fops,
+};
+
+static struct inode_operations usbdevfs_drivers_inode_operations = {
+        default_file_ops: &usbdevfs_drivers_fops,
+};
+
 static struct special special[] =

- { "devices", &usbdevfs_devices_fops,  },
- { "drivers", &usbdevfs_drivers_fops,  }
+ { "devices", &usbdevfs_devices_inode_operations,  },
+ { "drivers", &usbdevfs_drivers_inode_operations,  }
 };

 #define NRSPECIAL (sizeof(special)/sizeof(special[0]))
@@ -397,6 +412,7 @@
 };

 static struct inode_operations usbdevfs_root_inode_operations = {
+        default_file_ops: &usbdevfs_root_file_operations,
  lookup: usbdevfs_root_lookup,
 };

@@ -405,6 +421,7 @@
 };

 static struct inode_operations usbdevfs_bus_inode_operations = {
+        default_file_ops: &usbdevfs_bus_file_operations,
  lookup: usbdevfs_bus_lookup,
 };

@@ -429,6 +446,11 @@
   if (inode->i_ino <= IROOT || inode->i_ino > IROOT+NRSPECIAL)
    return;
   spec = &special[inode->i_ino-(IROOT+1)];
+
+  /* MHs 6/4/00: This bit changed for the backport */
+
+  inode->i_op=spec->iops;
+
   return;

  case IDEVICE:
--- /usr/src/linux/drivers/usb/usb-storage.c.orig Thu Mar  9 22:44:34 2000
+++ /usr/src/linux/drivers/usb/usb-storage.c Mon Apr  3 07:54:45 2000
@@ -30,6 +30,7 @@
 #include <linux/malloc.h>
 #include <linux/spinlock.h>
 #include <linux/smp_lock.h>
+#include <linux/proc_fs.h>

 #include <linux/blk.h>
 #include "../scsi/scsi.h"
@@ -116,6 +117,15 @@
  { NULL, NULL }
 };

+/* MH 3/4/00:
+*      Need this for 2.2.x SCSI code - you can not send a NULL proc_dir
+*      entry otherwise you will get a kernel oops
+*/
+
+struct proc_dir_entry proc_scsi_usb_scsi =
+{PROC_SCSI_USB_SCSI, 3, "usb", S_IFDIR | S_IRUGO | S_IXUGO, 2};
+
+
 /***********************************************************************
  * Data transfer routines
  ***********************************************************************/
@@ -1123,8 +1133,10 @@
   return 0;
  strcpy(sht->name, name);

- /* we start with no /proc directory entry */
- sht->proc_dir = NULL;
+        /* MH 3/4/00: Cannot leave proc_dir=NULL as this causes problems
+         *            with SCSI code, which assume it is valid.
+         */
+ sht->proc_dir = &proc_scsi_usb_scsi;

  /* register the host */
  us->host = scsi_register(sht, sizeof(us));



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to