Commit 18277e88 authored by Patrick Mochel's avatar Patrick Mochel Committed by Linus Torvalds

[PATCH] Adding driver model support in IDE

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.
parent f3533a9f
...@@ -563,6 +563,11 @@ static void hwif_register (ide_hwif_t *hwif) ...@@ -563,6 +563,11 @@ static void hwif_register (ide_hwif_t *hwif)
{ {
u32 i = 0; 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) if (hwif->mmio == 2)
return; return;
if (hwif->io_ports[IDE_CONTROL_OFFSET]) if (hwif->io_ports[IDE_CONTROL_OFFSET])
...@@ -715,8 +720,9 @@ int probe_hwif_init (ide_hwif_t *hwif) ...@@ -715,8 +720,9 @@ int probe_hwif_init (ide_hwif_t *hwif)
u16 unit = 0; u16 unit = 0;
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
if (drive->present) if (drive->present) {
ata_attach(drive); ata_attach(drive);
}
} }
} }
#endif #endif
...@@ -973,6 +979,15 @@ static void init_gendisk (ide_hwif_t *hwif) ...@@ -973,6 +979,15 @@ static void init_gendisk (ide_hwif_t *hwif)
gd[unit].major_name = names + 4*unit; gd[unit].major_name = names + 4*unit;
gd[unit].minor_shift = PARTN_BITS; gd[unit].minor_shift = PARTN_BITS;
gd[unit].fops = ide_fops; 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; hwif->drives[unit].disk = gd + unit;
} }
......
...@@ -152,6 +152,7 @@ ...@@ -152,6 +152,7 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/device.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -3524,6 +3525,10 @@ static struct notifier_block ide_notifier = { ...@@ -3524,6 +3525,10 @@ static struct notifier_block ide_notifier = {
5 5
}; };
struct bus_type ide_bus_type = {
.name = "ide",
};
/* /*
* This is gets invoked once during initialization, to set *everything* up * This is gets invoked once during initialization, to set *everything* up
*/ */
...@@ -3537,6 +3542,8 @@ int __init ide_init (void) ...@@ -3537,6 +3542,8 @@ int __init ide_init (void)
banner_printed = 1; banner_printed = 1;
} }
bus_register(&ide_bus_type);
init_ide_data(); init_ide_data();
initializing = 1; initializing = 1;
...@@ -3591,6 +3598,8 @@ void cleanup_module (void) ...@@ -3591,6 +3598,8 @@ void cleanup_module (void)
proc_ide_destroy(); proc_ide_destroy();
#endif #endif
devfs_unregister (ide_devfs_handle); devfs_unregister (ide_devfs_handle);
bus_unregister(&ide_bus_type);
} }
#else /* !MODULE */ #else /* !MODULE */
......
...@@ -666,6 +666,9 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_ ...@@ -666,6 +666,9 @@ static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_
if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL) if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
continue; continue;
/* setup proper ancestral information */
hwif->gendev.parent = &dev->dev;
if (hwif->channel) { if (hwif->channel) {
index.b.high = hwif->index; index.b.high = hwif->index;
} else { } else {
......
...@@ -1072,6 +1072,8 @@ typedef struct hwif_s { ...@@ -1072,6 +1072,8 @@ typedef struct hwif_s {
unsigned highmem : 1; /* can do full 32-bit dma */ unsigned highmem : 1; /* can do full 32-bit dma */
unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */ unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */
struct device gendev;
void *hwif_data; /* extra hwif data */ void *hwif_data; /* extra hwif data */
} ide_hwif_t; } ide_hwif_t;
...@@ -1759,4 +1761,6 @@ extern spinlock_t ide_lock; ...@@ -1759,4 +1761,6 @@ extern spinlock_t ide_lock;
#define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable(); } while (0) #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 */ #endif /* _IDE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment