[PATCH] ide: MODALIAS support for autoloading of ide-cd, ide-disk, ...
Kay Sievers [Mon, 12 Dec 2005 17:03:44 +0000 (18:03 +0100)]
IDE: MODALIAS support for autoloading of ide-cd, ide-disk, ...

Add MODULE_ALIAS to IDE midlayer modules: ide-disk, ide-cd, ide-floppy and
ide-tape, to autoload these modules depending on the probed media type of
the IDE device.

It is used by udev and replaces the former agent shell script of the hotplug
package, which was required to lookup the media type in the proc filesystem.
Using proc was racy, cause the media file is created after the hotplug event
is sent out.

The module autoloading does not take any effect, until something like the
following udev rule is configured:
  SUBSYSTEM=="ide",  ACTION=="add", ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}"

The module ide-scsi will not be autoloaded, cause it requires manual
configuration. It can't be, and never was supported for automatic setup in
the hotplug package. Adding a MODULE_ALIAS to ide-scsi for all supported
media types, would just lead to a default blacklist entry anyway.

  $ modinfo ide-disk
  filename:       /lib/modules/2.6.15-rc4-g1b0997f5/kernel/drivers/ide/ide-disk.ko
  description:    ATA DISK Driver
  alias:          ide:*m-disk*
  license:        GPL
  ...

  $ modprobe -vn ide:m-disk
  insmod /lib/modules/2.6.15-rc4-g1b0997f5/kernel/drivers/ide/ide-disk.ko

  $ cat /sys/bus/ide/devices/0.0/modalias
  ide:m-disk

It also adds attributes to the IDE device:
  $ tree /sys/bus/ide/devices/0.0/
  /sys/bus/ide/devices/0.0/
  |-- bus -> ../../../../../../../bus/ide
  |-- drivename
  |-- media
  |-- modalias
  |-- power
  |   |-- state
  |   `-- wakeup
  `-- uevent

  $ cat /sys/bus/ide/devices/0.0/{modalias,drivename,media}
  ide:m-disk
  hda
  disk

Signed-off-by: Kay Sievers <kay.sievers@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-floppy.c
drivers/ide/ide-tape.c
drivers/ide/ide.c

index b4d7a3e..70aeb3a 100644 (file)
@@ -3509,6 +3509,7 @@ static int __init ide_cdrom_init(void)
        return driver_register(&ide_cdrom_driver.gen_driver);
 }
 
+MODULE_ALIAS("ide:*m-cdrom*");
 module_init(ide_cdrom_init);
 module_exit(ide_cdrom_exit);
 MODULE_LICENSE("GPL");
index 449522f..4e57679 100644 (file)
@@ -1271,6 +1271,7 @@ static int __init idedisk_init(void)
        return driver_register(&idedisk_driver.gen_driver);
 }
 
+MODULE_ALIAS("ide:*m-disk*");
 module_init(idedisk_init);
 module_exit(idedisk_exit);
 MODULE_LICENSE("GPL");
index 9e293c8..fba3fff 100644 (file)
@@ -2197,6 +2197,7 @@ static int __init idefloppy_init(void)
        return driver_register(&idefloppy_driver.gen_driver);
 }
 
+MODULE_ALIAS("ide:*m-floppy*");
 module_init(idefloppy_init);
 module_exit(idefloppy_exit);
 MODULE_LICENSE("GPL");
index 7d7944e..fab9b2b 100644 (file)
@@ -4947,6 +4947,7 @@ out:
        return error;
 }
 
+MODULE_ALIAS("ide:*m-tape*");
 module_init(idetape_init);
 module_exit(idetape_exit);
 MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);
index 8af179b..4b524f6 100644 (file)
@@ -1904,9 +1904,69 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
        return 1;
 }
 
+static char *media_string(ide_drive_t *drive)
+{
+       switch (drive->media) {
+       case ide_disk:
+               return "disk";
+       case ide_cdrom:
+               return "cdrom";
+       case ide_tape:
+               return "tape";
+       case ide_floppy:
+               return "floppy";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", media_string(drive));
+}
+
+static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", drive->name);
+}
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "ide:m-%s\n", media_string(drive));
+}
+
+static struct device_attribute ide_dev_attrs[] = {
+       __ATTR_RO(media),
+       __ATTR_RO(drivename),
+       __ATTR_RO(modalias),
+       __ATTR_NULL
+};
+
+static int ide_uevent(struct device *dev, char **envp, int num_envp,
+                     char *buffer, int buffer_size)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       int i = 0;
+       int length = 0;
+
+       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                      "MEDIA=%s", media_string(drive));
+       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                      "DRIVENAME=%s", drive->name);
+       add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+                      "MODALIAS=ide:m-%s", media_string(drive));
+       envp[i] = NULL;
+       return 0;
+}
+
 struct bus_type ide_bus_type = {
        .name           = "ide",
        .match          = ide_bus_match,
+       .uevent         = ide_uevent,
+       .dev_attrs      = ide_dev_attrs,
        .suspend        = generic_ide_suspend,
        .resume         = generic_ide_resume,
 };