}
 #endif
 
-static int ide_cd_remove(struct device *dev)
+static void ide_cd_remove(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        struct cdrom_info *info = drive->driver_data;
 
        ide_unregister_subdriver(drive, info->driver);
        del_gendisk(info->disk);
 
        ide_cd_put(info);
-
-       return 0;
 }
 
 static void ide_cd_release(struct kref *kref)
        kfree(info);
 }
 
-static int ide_cd_probe(struct device *);
+static int ide_cd_probe(ide_drive_t *);
 
 #ifdef CONFIG_PROC_FS
 static int proc_idecd_read_capacity
                .owner          = THIS_MODULE,
                .name           = "ide-cdrom",
                .bus            = &ide_bus_type,
-               .probe          = ide_cd_probe,
-               .remove         = ide_cd_remove,
        },
+       .probe                  = ide_cd_probe,
+       .remove                 = ide_cd_remove,
        .version                = IDECD_VERSION,
        .media                  = ide_cdrom,
        .supports_dsc_overlap   = 1,
 module_param(ignore, charp, 0400);
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
 
-static int ide_cd_probe(struct device *dev)
+static int ide_cd_probe(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        struct cdrom_info *info;
        struct gendisk *g;
        struct request_sense sense;
 
                printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
 }
 
-static int ide_disk_remove(struct device *dev)
+static void ide_disk_remove(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        struct ide_disk_obj *idkp = drive->driver_data;
        struct gendisk *g = idkp->disk;
 
        ide_cacheflush_p(drive);
 
        ide_disk_put(idkp);
-
-       return 0;
 }
 
 static void ide_disk_release(struct kref *kref)
        kfree(idkp);
 }
 
-static int ide_disk_probe(struct device *dev);
+static int ide_disk_probe(ide_drive_t *drive);
 
-static void ide_device_shutdown(struct device *dev)
+static void ide_device_shutdown(ide_drive_t *drive)
 {
-       ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
-
 #ifdef CONFIG_ALPHA
        /* On Alpha, halt(8) doesn't actually turn the machine off,
           it puts you into the sort of firmware monitor. Typically,
        }
 
        printk("Shutdown: %s\n", drive->name);
-       dev->bus->suspend(dev, PMSG_SUSPEND);
+       drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
 }
 
 static ide_driver_t idedisk_driver = {
                .owner          = THIS_MODULE,
                .name           = "ide-disk",
                .bus            = &ide_bus_type,
-               .probe          = ide_disk_probe,
-               .remove         = ide_disk_remove,
-               .shutdown       = ide_device_shutdown,
        },
+       .probe                  = ide_disk_probe,
+       .remove                 = ide_disk_remove,
+       .shutdown               = ide_device_shutdown,
        .version                = IDEDISK_VERSION,
        .media                  = ide_disk,
        .supports_dsc_overlap   = 0,
 
 MODULE_DESCRIPTION("ATA DISK Driver");
 
-static int ide_disk_probe(struct device *dev)
+static int ide_disk_probe(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        struct ide_disk_obj *idkp;
        struct gendisk *g;
 
 
        idefloppy_add_settings(drive);
 }
 
-static int ide_floppy_remove(struct device *dev)
+static void ide_floppy_remove(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        idefloppy_floppy_t *floppy = drive->driver_data;
        struct gendisk *g = floppy->disk;
 
        del_gendisk(g);
 
        ide_floppy_put(floppy);
-
-       return 0;
 }
 
 static void ide_floppy_release(struct kref *kref)
 
 #endif /* CONFIG_PROC_FS */
 
-static int ide_floppy_probe(struct device *);
+static int ide_floppy_probe(ide_drive_t *);
 
 static ide_driver_t idefloppy_driver = {
        .gen_driver = {
                .owner          = THIS_MODULE,
                .name           = "ide-floppy",
                .bus            = &ide_bus_type,
-               .probe          = ide_floppy_probe,
-               .remove         = ide_floppy_remove,
        },
+       .probe                  = ide_floppy_probe,
+       .remove                 = ide_floppy_remove,
        .version                = IDEFLOPPY_VERSION,
        .media                  = ide_floppy,
        .supports_dsc_overlap   = 0,
        .revalidate_disk= idefloppy_revalidate_disk
 };
 
-static int ide_floppy_probe(struct device *dev)
+static int ide_floppy_probe(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        idefloppy_floppy_t *floppy;
        struct gendisk *g;
 
 
        idetape_add_settings(drive);
 }
 
-static int ide_tape_remove(struct device *dev)
+static void ide_tape_remove(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        idetape_tape_t *tape = drive->driver_data;
 
        ide_unregister_subdriver(drive, tape->driver);
        ide_unregister_region(tape->disk);
 
        ide_tape_put(tape);
-
-       return 0;
 }
 
 static void ide_tape_release(struct kref *kref)
 
 #endif
 
-static int ide_tape_probe(struct device *);
+static int ide_tape_probe(ide_drive_t *);
 
 static ide_driver_t idetape_driver = {
        .gen_driver = {
                .owner          = THIS_MODULE,
                .name           = "ide-tape",
                .bus            = &ide_bus_type,
-               .probe          = ide_tape_probe,
-               .remove         = ide_tape_remove,
        },
+       .probe                  = ide_tape_probe,
+       .remove                 = ide_tape_remove,
        .version                = IDETAPE_VERSION,
        .media                  = ide_tape,
        .supports_dsc_overlap   = 1,
        .ioctl          = idetape_ioctl,
 };
 
-static int ide_tape_probe(struct device *dev)
+static int ide_tape_probe(ide_drive_t *drive)
 {
-       ide_drive_t *drive = to_ide_device(dev);
        idetape_tape_t *tape;
        struct gendisk *g;
        int minor;
        idetape_setup(drive, tape, minor);
 
        class_device_create(idetape_sysfs_class, NULL,
-                       MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name);
+                       MKDEV(IDETAPE_MAJOR, minor), &drive->gendev, "%s", tape->name);
        class_device_create(idetape_sysfs_class, NULL,
-                       MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name);
+                       MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name);
 
        devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
                        S_IFCHR | S_IRUGO | S_IWUGO,
 
        return 0;
 }
 
+static int generic_ide_probe(struct device *dev)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       ide_driver_t *drv = to_ide_driver(dev->driver);
+
+       return drv->probe ? drv->probe(drive) : -ENODEV;
+}
+
+static int generic_ide_remove(struct device *dev)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       ide_driver_t *drv = to_ide_driver(dev->driver);
+
+       if (drv->remove)
+               drv->remove(drive);
+
+       return 0;
+}
+
+static void generic_ide_shutdown(struct device *dev)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       ide_driver_t *drv = to_ide_driver(dev->driver);
+
+       if (dev->driver && drv->shutdown)
+               drv->shutdown(drive);
+}
+
 struct bus_type ide_bus_type = {
        .name           = "ide",
        .match          = ide_bus_match,
        .uevent         = ide_uevent,
+       .probe          = generic_ide_probe,
+       .remove         = generic_ide_remove,
+       .shutdown       = generic_ide_shutdown,
        .dev_attrs      = ide_dev_attrs,
        .suspend        = generic_ide_suspend,
        .resume         = generic_ide_resume,
 
        ide_startstop_t (*abort)(ide_drive_t *, struct request *rq);
        ide_proc_entry_t        *proc;
        struct device_driver    gen_driver;
+       int             (*probe)(ide_drive_t *);
+       void            (*remove)(ide_drive_t *);
+       void            (*shutdown)(ide_drive_t *);
 } ide_driver_t;
 
+#define to_ide_driver(drv) container_of(drv, ide_driver_t, gen_driver)
+
 int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long);
 
 /*