]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Adding driver model support in IDE
authorPatrick Mochel <mochel@osdl.org>
Fri, 20 Sep 2002 03:49:33 +0000 (20:49 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 20 Sep 2002 03:49:33 +0000 (20:49 -0700)
This adds the basic driver model support for the IDE subsystem.

Basically, it registers the controllers and devices with the driver
model core, which puts them in the device tree and gets them a directory
in driverfs.  The driverfs layout looks like this (on my workstation):

[mochel@cherise mochel]$ tree -d /sys/root/pci0/
/sys/root/pci0/
|-- 00:00.0
|-- 00:01.0
|   `-- 01:00.0
|-- 00:02.0
|   `-- 02:1f.0
|       `-- 03:00.0
|-- 00:1e.0
|   `-- 04:04.0
|-- 00:1f.0
|-- 00:1f.1
|   |-- ide0
|   |   |-- 0.0
|   |   `-- 0.1
|   `-- ide1
|       |-- 1.0
|       `-- 1.1

The drive bus IDs (the directory names)  are created using this:

sprintf(bus_id,"%u.%u",hwif->index,unit);

which should give each drive a unique name for the entire system, right?

I've also created a struct bus_type for IDE, which gives ide a directory
in the driverfs bus/ directory. The layout of that is:

[mochel@cherise mochel]$ tree -d /sys/bus/ide/
/sys/bus/ide/
|-- devices
|   |-- 0.0 -> ../../../root/pci0/00:1f.1/ide0/0.0
|   |-- 0.1 -> ../../../root/pci0/00:1f.1/ide0/0.1
|   |-- 1.0 -> ../../../root/pci0/00:1f.1/ide1/1.0
|   `-- 1.1 -> ../../../root/pci0/00:1f.1/ide1/1.1
`-- drivers

Those are symlinks under devices/ (which is why the drive names must be
unique..). When drivers are registered with the IDE core, they should also
be passed through the core, which will give them a directory in the
drivers/ directory just above.

In general, there is a bit of code that can be cleaned up, and some
explicit calls removed, because of the way the driver model core works.
Most of these are pretty simple, and barring any objections, I will
implement and send them to you.

drivers/ide/ide-probe.c
drivers/ide/ide.c
drivers/ide/setup-pci.c
include/linux/ide.h

index 652c7875b7efd0a636e097cd525a1c1286b4c347..fd375a5ac974eecf04afb73a95e66388e7d1c298 100644 (file)
@@ -563,6 +563,11 @@ static void hwif_register (ide_hwif_t *hwif)
 {
        u32 i = 0;
 
+       /* register with global device tree */
+       strncpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE);
+       snprintf(hwif->gendev.name,DEVICE_NAME_SIZE,"IDE Controller");
+       device_register(&hwif->gendev);
+
        if (hwif->mmio == 2)
                return;
        if (hwif->io_ports[IDE_CONTROL_OFFSET])
@@ -715,8 +720,9 @@ int probe_hwif_init (ide_hwif_t *hwif)
                u16 unit = 0;
                for (unit = 0; unit < MAX_DRIVES; ++unit) {
                        ide_drive_t *drive = &hwif->drives[unit];
-                       if (drive->present)
+                       if (drive->present) {
                                ata_attach(drive);
+                       }
                }
        }
 #endif
@@ -973,6 +979,15 @@ static void init_gendisk (ide_hwif_t *hwif)
                gd[unit].major_name = names + 4*unit;
                gd[unit].minor_shift = PARTN_BITS; 
                gd[unit].fops = ide_fops;
+
+               snprintf(gd[unit].disk_dev.bus_id,BUS_ID_SIZE,"%u.%u",
+                        hwif->index,unit);
+               snprintf(gd[unit].disk_dev.name,DEVICE_NAME_SIZE,
+                        "%s","IDE Drive");
+               gd[unit].disk_dev.parent = &hwif->gendev;
+               gd[unit].disk_dev.bus = &ide_bus_type;
+               device_register(&gd[unit].disk_dev);
+
                hwif->drives[unit].disk = gd + unit;
        }
 
index dd43f6487ce3479ef97d3b9273157df581efd012..73d4eb67dcd43ff9370591960cd07ba26b71c152 100644 (file)
 #include <linux/reboot.h>
 #include <linux/cdrom.h>
 #include <linux/seq_file.h>
+#include <linux/device.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -3524,6 +3525,10 @@ static struct notifier_block ide_notifier = {
        5
 };
 
+struct bus_type ide_bus_type = {
+       .name           = "ide",
+};
+
 /*
  * This is gets invoked once during initialization, to set *everything* up
  */
@@ -3537,6 +3542,8 @@ int __init ide_init (void)
                banner_printed = 1;
        }
 
+       bus_register(&ide_bus_type);
+
        init_ide_data();
 
        initializing = 1;
@@ -3591,6 +3598,8 @@ void cleanup_module (void)
        proc_ide_destroy();
 #endif
        devfs_unregister (ide_devfs_handle);
+
+       bus_unregister(&ide_bus_type);
 }
 
 #else /* !MODULE */
index 61f384ebf281cda7b834eca6d64ca731541b8815..80e52d12f4bdc29debbe1dd4e1cc3b04cebf46d3 100644 (file)
@@ -666,6 +666,9 @@ controller_ok:
                if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
                        continue;
 
+               /* setup proper ancestral information */
+               hwif->gendev.parent = &dev->dev;
+
                if (hwif->channel) {
                        index.b.high = hwif->index;
                } else {
index 45b772a5d9227bbd91272a7bbf132925b677c2ce..ca112e24acdb91a69d71099d2f0ac40240fbedf6 100644 (file)
@@ -1072,6 +1072,8 @@ typedef struct hwif_s {
        unsigned        highmem    : 1; /* can do full 32-bit dma */
        unsigned        no_dsc     : 1; /* 0 default, 1 dsc_overlap disabled */
 
+       struct device   gendev;
+
        void            *hwif_data;     /* extra hwif data */
 } ide_hwif_t;
 
@@ -1759,4 +1761,6 @@ extern spinlock_t ide_lock;
 
 #define local_irq_set(flags)   do { local_save_flags((flags)); local_irq_enable(); } while (0)
 
+extern struct bus_type ide_bus_type;
+
 #endif /* _IDE_H */