ChangeSet 1.868, 2002/12/10 17:02:12-08:00, [EMAIL PROTECTED]

[PATCH] USB: Added usb-serial driver core bus support.

This means that all individual usb-serial ports show up as their
own devices in the driver model tree.


diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c   Fri Dec 13 17:19:16 2002
+++ b/drivers/usb/serial/usb-serial.c   Fri Dec 13 17:19:16 2002
@@ -14,6 +14,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (12/10/2002) gkh
+ *     Split the ports off into their own struct device, and added a
+ *     usb-serial bus driver.
+ *
  * (11/19/2002) gkh
  *     removed a few #ifdefs for the generic code and cleaned up the failure
  *     logic in initialization.
@@ -345,7 +349,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.8"
+#define DRIVER_VERSION "v2.0"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, [EMAIL PROTECTED], 
http://www.kroah.com/linux/";
 #define DRIVER_DESC "USB Serial Driver core"
 
@@ -385,6 +389,32 @@
 static struct usb_serial       *serial_table[SERIAL_TTY_MINORS];       /* initially 
all NULL */
 static LIST_HEAD(usb_serial_driver_list);
 
+static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
+{
+       struct usb_serial_device_type *driver;
+       const struct usb_serial_port *port;
+
+       /* 
+        * drivers are already assigned to ports in serial_probe so it's
+        * a simple check here.
+        */
+       port = to_usb_serial_port(dev);
+       if (!port)
+               return 0;
+
+       driver = to_usb_serial_driver(drv);
+
+       if (driver == port->serial->type)
+               return 1;
+
+       return 0;
+}
+
+static struct bus_type usb_serial_bus_type = {
+       .name =         "usb-serial",
+       .match =        usb_serial_device_match,
+};
+
 struct usb_serial *usb_serial_get_by_minor (unsigned int minor)
 {
        return serial_table[minor];
@@ -1132,11 +1162,17 @@
                }
        }
 
-       /* initialize the devfs nodes for this device and let the user know what ports 
we are bound to */
-       for (i = 0; i < serial->num_ports; ++i) {
-               tty_register_devfs (&serial_tty_driver, 0, serial->port[i].number);
-               info("%s converter now attached to ttyUSB%d (or usb/tts/%d for 
devfs)", 
-                    type->name, serial->port[i].number, serial->port[i].number);
+       /* register all of the individual ports with the driver core */
+       for (i = 0; i < num_ports; ++i) {
+               port = &serial->port[i];
+               port->dev.parent = &serial->dev->dev;
+               port->dev.driver = NULL;
+               port->dev.bus = &usb_serial_bus_type;
+
+               snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", 
+port->number);
+               snprintf (&port->dev.name[0], sizeof(port->dev.name), "usb serial port 
+%d", port->number);
+               dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id);
+               device_register (&port->dev);
        }
 
        usb_serial_console_init (debug, minor);
@@ -1204,6 +1240,9 @@
                serial_shutdown (serial);
 
                for (i = 0; i < serial->num_ports; ++i)
+                       device_unregister(&serial->port[i].dev);
+
+               for (i = 0; i < serial->num_ports; ++i)
                        serial->port[i].open_count = 0;
 
                for (i = 0; i < serial->num_bulk_in; ++i) {
@@ -1233,12 +1272,6 @@
                        if (port->interrupt_in_buffer)
                                kfree (port->interrupt_in_buffer);
                }
-
-               for (i = 0; i < serial->num_ports; ++i) {
-                       tty_unregister_devfs (&serial_tty_driver, 
serial->port[i].number);
-                       info("%s converter now disconnected from ttyUSB%d", 
serial->type->name, serial->port[i].number);
-               }
-
                /* return the minor range that this device had */
                return_serial (serial);
 
@@ -1294,6 +1327,8 @@
                serial_table[i] = NULL;
        }
 
+       bus_register(&usb_serial_bus_type);
+
        /* register the generic driver, if we should */
        result = usb_serial_generic_register(debug);
        if (result < 0) {
@@ -1341,21 +1376,103 @@
 
        usb_deregister(&usb_serial_driver);
        tty_unregister_driver(&serial_tty_driver);
+       bus_unregister(&usb_serial_bus_type);
 }
 
 
 module_init(usb_serial_init);
 module_exit(usb_serial_exit);
 
+static int usb_serial_device_probe (struct device *dev)
+{
+       struct usb_serial_device_type *driver;
+       struct usb_serial_port *port;
+       int retval = 0;
+       int minor;
+
+       port = to_usb_serial_port(dev);
+       if (!port) {
+               retval = -ENODEV;
+               goto exit;
+       }
+
+       driver = port->serial->type;
+       if (driver->port_probe) {
+               if (!try_module_get(driver->owner)) {
+                       err ("module get failed, exiting");
+                       retval = -EIO;
+                       goto exit;
+               }
+               retval = driver->port_probe (port);
+               module_put(driver->owner);
+               if (retval)
+                       goto exit;
+       }
+
+       minor = port->number;
+
+       tty_register_devfs (&serial_tty_driver, 0, minor);
+       info("%s converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
+            driver->name, minor, minor);
+
+exit:
+       return retval;
+}
+
+static int usb_serial_device_remove (struct device *dev)
+{
+       struct usb_serial_device_type *driver;
+       struct usb_serial_port *port;
+       int retval = 0;
+       int minor;
+
+       port = to_usb_serial_port(dev);
+       if (!port) {
+               return -ENODEV;
+       }
+
+       driver = port->serial->type;
+       if (driver->port_remove) {
+               if (!try_module_get(driver->owner)) {
+                       err ("module get failed, exiting");
+                       retval = -EIO;
+                       goto exit;
+               }
+               retval = driver->port_remove (port);
+               module_put(driver->owner);
+       }
+exit:
+       minor = port->number;
+       tty_unregister_devfs (&serial_tty_driver, minor);
+       info("%s converter now disconnected from ttyUSB%d",
+            driver->name, minor);
+
+       return retval;
+}
 
 int usb_serial_register(struct usb_serial_device_type *new_device)
 {
+       int retval;
+
        /* Add this device to our list of devices */
        list_add(&new_device->driver_list, &usb_serial_driver_list);
 
-       info ("USB Serial support registered for %s", new_device->name);
+       new_device->driver.name = (char *)new_device->name;
+       new_device->driver.bus = &usb_serial_bus_type;
+       new_device->driver.probe = usb_serial_device_probe;
+       new_device->driver.remove = usb_serial_device_remove;
+
+       retval = driver_register(&new_device->driver);
+
+       if (!retval) {
+               info("USB Serial support registered for %s",
+                       new_device->name);
+       } else {
+               err("problem %d when registering driver %s",
+                       retval, new_device->name);
+       }
 
-       return 0;
+       return retval;
 }
 
 
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h   Fri Dec 13 17:19:16 2002
+++ b/drivers/usb/serial/usb-serial.h   Fri Dec 13 17:19:16 2002
@@ -121,7 +121,9 @@
        int                     open_count;
        struct semaphore        sem;
        void *                  private;
+       struct device           dev;
 };
+#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
 
 /**
  * usb_serial - structure used by the usb-serial core for a device
@@ -206,13 +208,17 @@
        char    num_ports;
 
        struct list_head        driver_list;
-       
+       struct device_driver    driver;
+
        int (*probe) (struct usb_serial *serial);
        int (*attach) (struct usb_serial *serial);
        int (*calc_num_ports) (struct usb_serial *serial);
 
        void (*shutdown) (struct usb_serial *serial);
 
+       int (*port_probe) (struct usb_serial_port *port);
+       int (*port_remove) (struct usb_serial_port *port);
+
        /* serial function calls */
        int  (*open)            (struct usb_serial_port *port, struct file * filp);
        void (*close)           (struct usb_serial_port *port, struct file * filp);
@@ -229,6 +235,7 @@
        void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
        void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
 };
+#define to_usb_serial_driver(d) container_of(d, struct usb_serial_device_type, driver)
 
 extern int  usb_serial_register(struct usb_serial_device_type *new_device);
 extern void usb_serial_deregister(struct usb_serial_device_type *device);


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to