diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl> | 2005-05-26 08:55:34 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl> | 2005-05-26 08:55:34 -0400 |
commit | 8604affde9d4f52f04342d6a37c77d95fa167e7a (patch) | |
tree | 12143c1be244c69c7c2b488a34856f60d0625e03 /drivers/ide | |
parent | bef9c558841604116704e10b3d9ff3dbf4939423 (diff) |
[PATCH] convert IDE device drivers to driver-model
* add ide_bus_match() and export ide_bus_type
* split ide_remove_driver_from_hwgroup() out of ide_unregister()
* move device cleanup from ide_unregister() to drive_release_dev()
* convert ide_driver_t->name to driver->name
* convert ide_driver_t->{attach,cleanup} to driver->{probe,remove}
* remove ide_driver_t->busy as ide_bus_type->subsys.rwsem
protects against concurrent ->{probe,remove} calls
* make ide_{un}register_driver() void as it cannot fail now
* use driver_{un}register() directly, remove ide_{un}register_driver()
* use device_register() instead of ata_attach(), remove ata_attach()
* add proc_print_driver() and ide_drivers_show(), remove ide_drivers_op
* fix ide_replace_subdriver() and move it to ide-proc.c
* remove ide_driver_t->drives, ide_drives and drives_lock
* remove ide_driver_t->drivers, drivers and drivers_lock
* remove ide_drive_t->driver and DRIVER() macro
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@elka.pw.edu.pl>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-cd.c | 47 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 41 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 42 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 47 | ||||
-rw-r--r-- | drivers/ide/ide-proc.c | 52 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 51 | ||||
-rw-r--r-- | drivers/ide/ide.c | 307 |
7 files changed, 186 insertions, 401 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4f7ce7056228..f0bd242e030f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -3255,16 +3255,12 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive) | |||
3255 | return capacity * sectors_per_frame; | 3255 | return capacity * sectors_per_frame; |
3256 | } | 3256 | } |
3257 | 3257 | ||
3258 | static | 3258 | static int ide_cd_remove(struct device *dev) |
3259 | int ide_cdrom_cleanup(ide_drive_t *drive) | ||
3260 | { | 3259 | { |
3260 | ide_drive_t *drive = to_ide_device(dev); | ||
3261 | struct cdrom_info *info = drive->driver_data; | 3261 | struct cdrom_info *info = drive->driver_data; |
3262 | 3262 | ||
3263 | if (ide_unregister_subdriver(drive)) { | 3263 | ide_unregister_subdriver(drive, info->driver); |
3264 | printk(KERN_ERR "%s: %s: failed to ide_unregister_subdriver\n", | ||
3265 | __FUNCTION__, drive->name); | ||
3266 | return 1; | ||
3267 | } | ||
3268 | 3264 | ||
3269 | del_gendisk(info->disk); | 3265 | del_gendisk(info->disk); |
3270 | 3266 | ||
@@ -3297,7 +3293,7 @@ static void ide_cd_release(struct kref *kref) | |||
3297 | kfree(info); | 3293 | kfree(info); |
3298 | } | 3294 | } |
3299 | 3295 | ||
3300 | static int ide_cdrom_attach (ide_drive_t *drive); | 3296 | static int ide_cd_probe(struct device *); |
3301 | 3297 | ||
3302 | #ifdef CONFIG_PROC_FS | 3298 | #ifdef CONFIG_PROC_FS |
3303 | static int proc_idecd_read_capacity | 3299 | static int proc_idecd_read_capacity |
@@ -3320,19 +3316,20 @@ static ide_proc_entry_t idecd_proc[] = { | |||
3320 | 3316 | ||
3321 | static ide_driver_t ide_cdrom_driver = { | 3317 | static ide_driver_t ide_cdrom_driver = { |
3322 | .owner = THIS_MODULE, | 3318 | .owner = THIS_MODULE, |
3323 | .name = "ide-cdrom", | 3319 | .gen_driver = { |
3320 | .name = "ide-cdrom", | ||
3321 | .bus = &ide_bus_type, | ||
3322 | .probe = ide_cd_probe, | ||
3323 | .remove = ide_cd_remove, | ||
3324 | }, | ||
3324 | .version = IDECD_VERSION, | 3325 | .version = IDECD_VERSION, |
3325 | .media = ide_cdrom, | 3326 | .media = ide_cdrom, |
3326 | .busy = 0, | ||
3327 | .supports_dsc_overlap = 1, | 3327 | .supports_dsc_overlap = 1, |
3328 | .cleanup = ide_cdrom_cleanup, | ||
3329 | .do_request = ide_do_rw_cdrom, | 3328 | .do_request = ide_do_rw_cdrom, |
3330 | .end_request = ide_end_request, | 3329 | .end_request = ide_end_request, |
3331 | .error = __ide_error, | 3330 | .error = __ide_error, |
3332 | .abort = __ide_abort, | 3331 | .abort = __ide_abort, |
3333 | .proc = idecd_proc, | 3332 | .proc = idecd_proc, |
3334 | .attach = ide_cdrom_attach, | ||
3335 | .drives = LIST_HEAD_INIT(ide_cdrom_driver.drives), | ||
3336 | }; | 3333 | }; |
3337 | 3334 | ||
3338 | static int idecd_open(struct inode * inode, struct file * file) | 3335 | static int idecd_open(struct inode * inode, struct file * file) |
@@ -3418,8 +3415,9 @@ static char *ignore = NULL; | |||
3418 | module_param(ignore, charp, 0400); | 3415 | module_param(ignore, charp, 0400); |
3419 | MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); | 3416 | MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); |
3420 | 3417 | ||
3421 | static int ide_cdrom_attach (ide_drive_t *drive) | 3418 | static int ide_cd_probe(struct device *dev) |
3422 | { | 3419 | { |
3420 | ide_drive_t *drive = to_ide_device(dev); | ||
3423 | struct cdrom_info *info; | 3421 | struct cdrom_info *info; |
3424 | struct gendisk *g; | 3422 | struct gendisk *g; |
3425 | struct request_sense sense; | 3423 | struct request_sense sense; |
@@ -3453,11 +3451,8 @@ static int ide_cdrom_attach (ide_drive_t *drive) | |||
3453 | 3451 | ||
3454 | ide_init_disk(g, drive); | 3452 | ide_init_disk(g, drive); |
3455 | 3453 | ||
3456 | if (ide_register_subdriver(drive, &ide_cdrom_driver)) { | 3454 | ide_register_subdriver(drive, &ide_cdrom_driver); |
3457 | printk(KERN_ERR "%s: Failed to register the driver with ide.c\n", | 3455 | |
3458 | drive->name); | ||
3459 | goto out_put_disk; | ||
3460 | } | ||
3461 | memset(info, 0, sizeof (struct cdrom_info)); | 3456 | memset(info, 0, sizeof (struct cdrom_info)); |
3462 | 3457 | ||
3463 | kref_init(&info->kref); | 3458 | kref_init(&info->kref); |
@@ -3470,7 +3465,6 @@ static int ide_cdrom_attach (ide_drive_t *drive) | |||
3470 | 3465 | ||
3471 | drive->driver_data = info; | 3466 | drive->driver_data = info; |
3472 | 3467 | ||
3473 | DRIVER(drive)->busy++; | ||
3474 | g->minors = 1; | 3468 | g->minors = 1; |
3475 | snprintf(g->devfs_name, sizeof(g->devfs_name), | 3469 | snprintf(g->devfs_name, sizeof(g->devfs_name), |
3476 | "%s/cd", drive->devfs_name); | 3470 | "%s/cd", drive->devfs_name); |
@@ -3478,8 +3472,7 @@ static int ide_cdrom_attach (ide_drive_t *drive) | |||
3478 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; | 3472 | g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; |
3479 | if (ide_cdrom_setup(drive)) { | 3473 | if (ide_cdrom_setup(drive)) { |
3480 | struct cdrom_device_info *devinfo = &info->devinfo; | 3474 | struct cdrom_device_info *devinfo = &info->devinfo; |
3481 | DRIVER(drive)->busy--; | 3475 | ide_unregister_subdriver(drive, &ide_cdrom_driver); |
3482 | ide_unregister_subdriver(drive); | ||
3483 | if (info->buffer != NULL) | 3476 | if (info->buffer != NULL) |
3484 | kfree(info->buffer); | 3477 | kfree(info->buffer); |
3485 | if (info->toc != NULL) | 3478 | if (info->toc != NULL) |
@@ -3492,7 +3485,6 @@ static int ide_cdrom_attach (ide_drive_t *drive) | |||
3492 | drive->driver_data = NULL; | 3485 | drive->driver_data = NULL; |
3493 | goto failed; | 3486 | goto failed; |
3494 | } | 3487 | } |
3495 | DRIVER(drive)->busy--; | ||
3496 | 3488 | ||
3497 | cdrom_read_toc(drive, &sense); | 3489 | cdrom_read_toc(drive, &sense); |
3498 | g->fops = &idecd_ops; | 3490 | g->fops = &idecd_ops; |
@@ -3500,23 +3492,20 @@ static int ide_cdrom_attach (ide_drive_t *drive) | |||
3500 | add_disk(g); | 3492 | add_disk(g); |
3501 | return 0; | 3493 | return 0; |
3502 | 3494 | ||
3503 | out_put_disk: | ||
3504 | put_disk(g); | ||
3505 | out_free_cd: | 3495 | out_free_cd: |
3506 | kfree(info); | 3496 | kfree(info); |
3507 | failed: | 3497 | failed: |
3508 | return 1; | 3498 | return -ENODEV; |
3509 | } | 3499 | } |
3510 | 3500 | ||
3511 | static void __exit ide_cdrom_exit(void) | 3501 | static void __exit ide_cdrom_exit(void) |
3512 | { | 3502 | { |
3513 | ide_unregister_driver(&ide_cdrom_driver); | 3503 | driver_unregister(&ide_cdrom_driver.gen_driver); |
3514 | } | 3504 | } |
3515 | 3505 | ||
3516 | static int ide_cdrom_init(void) | 3506 | static int ide_cdrom_init(void) |
3517 | { | 3507 | { |
3518 | ide_register_driver(&ide_cdrom_driver); | 3508 | return driver_register(&ide_cdrom_driver.gen_driver); |
3519 | return 0; | ||
3520 | } | 3509 | } |
3521 | 3510 | ||
3522 | module_init(ide_cdrom_init); | 3511 | module_init(ide_cdrom_init); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5d54f7756100..3302cd8eab4c 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -1024,14 +1024,16 @@ static void ide_cacheflush_p(ide_drive_t *drive) | |||
1024 | printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); | 1024 | printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | static int idedisk_cleanup (ide_drive_t *drive) | 1027 | static int ide_disk_remove(struct device *dev) |
1028 | { | 1028 | { |
1029 | ide_drive_t *drive = to_ide_device(dev); | ||
1029 | struct ide_disk_obj *idkp = drive->driver_data; | 1030 | struct ide_disk_obj *idkp = drive->driver_data; |
1030 | struct gendisk *g = idkp->disk; | 1031 | struct gendisk *g = idkp->disk; |
1031 | 1032 | ||
1032 | ide_cacheflush_p(drive); | 1033 | ide_cacheflush_p(drive); |
1033 | if (ide_unregister_subdriver(drive)) | 1034 | |
1034 | return 1; | 1035 | ide_unregister_subdriver(drive, idkp->driver); |
1036 | |||
1035 | del_gendisk(g); | 1037 | del_gendisk(g); |
1036 | 1038 | ||
1037 | ide_disk_put(idkp); | 1039 | ide_disk_put(idkp); |
@@ -1052,7 +1054,7 @@ static void ide_disk_release(struct kref *kref) | |||
1052 | kfree(idkp); | 1054 | kfree(idkp); |
1053 | } | 1055 | } |
1054 | 1056 | ||
1055 | static int idedisk_attach(ide_drive_t *drive); | 1057 | static int ide_disk_probe(struct device *dev); |
1056 | 1058 | ||
1057 | static void ide_device_shutdown(struct device *dev) | 1059 | static void ide_device_shutdown(struct device *dev) |
1058 | { | 1060 | { |
@@ -1082,27 +1084,23 @@ static void ide_device_shutdown(struct device *dev) | |||
1082 | dev->bus->suspend(dev, PMSG_SUSPEND); | 1084 | dev->bus->suspend(dev, PMSG_SUSPEND); |
1083 | } | 1085 | } |
1084 | 1086 | ||
1085 | /* | ||
1086 | * IDE subdriver functions, registered with ide.c | ||
1087 | */ | ||
1088 | static ide_driver_t idedisk_driver = { | 1087 | static ide_driver_t idedisk_driver = { |
1089 | .owner = THIS_MODULE, | 1088 | .owner = THIS_MODULE, |
1090 | .gen_driver = { | 1089 | .gen_driver = { |
1090 | .name = "ide-disk", | ||
1091 | .bus = &ide_bus_type, | ||
1092 | .probe = ide_disk_probe, | ||
1093 | .remove = ide_disk_remove, | ||
1091 | .shutdown = ide_device_shutdown, | 1094 | .shutdown = ide_device_shutdown, |
1092 | }, | 1095 | }, |
1093 | .name = "ide-disk", | ||
1094 | .version = IDEDISK_VERSION, | 1096 | .version = IDEDISK_VERSION, |
1095 | .media = ide_disk, | 1097 | .media = ide_disk, |
1096 | .busy = 0, | ||
1097 | .supports_dsc_overlap = 0, | 1098 | .supports_dsc_overlap = 0, |
1098 | .cleanup = idedisk_cleanup, | ||
1099 | .do_request = ide_do_rw_disk, | 1099 | .do_request = ide_do_rw_disk, |
1100 | .end_request = ide_end_request, | 1100 | .end_request = ide_end_request, |
1101 | .error = __ide_error, | 1101 | .error = __ide_error, |
1102 | .abort = __ide_abort, | 1102 | .abort = __ide_abort, |
1103 | .proc = idedisk_proc, | 1103 | .proc = idedisk_proc, |
1104 | .attach = idedisk_attach, | ||
1105 | .drives = LIST_HEAD_INIT(idedisk_driver.drives), | ||
1106 | }; | 1104 | }; |
1107 | 1105 | ||
1108 | static int idedisk_open(struct inode *inode, struct file *filp) | 1106 | static int idedisk_open(struct inode *inode, struct file *filp) |
@@ -1199,8 +1197,9 @@ static struct block_device_operations idedisk_ops = { | |||
1199 | 1197 | ||
1200 | MODULE_DESCRIPTION("ATA DISK Driver"); | 1198 | MODULE_DESCRIPTION("ATA DISK Driver"); |
1201 | 1199 | ||
1202 | static int idedisk_attach(ide_drive_t *drive) | 1200 | static int ide_disk_probe(struct device *dev) |
1203 | { | 1201 | { |
1202 | ide_drive_t *drive = to_ide_device(dev); | ||
1204 | struct ide_disk_obj *idkp; | 1203 | struct ide_disk_obj *idkp; |
1205 | struct gendisk *g; | 1204 | struct gendisk *g; |
1206 | 1205 | ||
@@ -1222,10 +1221,7 @@ static int idedisk_attach(ide_drive_t *drive) | |||
1222 | 1221 | ||
1223 | ide_init_disk(g, drive); | 1222 | ide_init_disk(g, drive); |
1224 | 1223 | ||
1225 | if (ide_register_subdriver(drive, &idedisk_driver)) { | 1224 | ide_register_subdriver(drive, &idedisk_driver); |
1226 | printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name); | ||
1227 | goto out_put_disk; | ||
1228 | } | ||
1229 | 1225 | ||
1230 | memset(idkp, 0, sizeof(*idkp)); | 1226 | memset(idkp, 0, sizeof(*idkp)); |
1231 | 1227 | ||
@@ -1239,7 +1235,6 @@ static int idedisk_attach(ide_drive_t *drive) | |||
1239 | 1235 | ||
1240 | drive->driver_data = idkp; | 1236 | drive->driver_data = idkp; |
1241 | 1237 | ||
1242 | DRIVER(drive)->busy++; | ||
1243 | idedisk_setup(drive); | 1238 | idedisk_setup(drive); |
1244 | if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { | 1239 | if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { |
1245 | printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", | 1240 | printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", |
@@ -1247,7 +1242,7 @@ static int idedisk_attach(ide_drive_t *drive) | |||
1247 | drive->attach = 0; | 1242 | drive->attach = 0; |
1248 | } else | 1243 | } else |
1249 | drive->attach = 1; | 1244 | drive->attach = 1; |
1250 | DRIVER(drive)->busy--; | 1245 | |
1251 | g->minors = 1 << PARTN_BITS; | 1246 | g->minors = 1 << PARTN_BITS; |
1252 | strcpy(g->devfs_name, drive->devfs_name); | 1247 | strcpy(g->devfs_name, drive->devfs_name); |
1253 | g->driverfs_dev = &drive->gendev; | 1248 | g->driverfs_dev = &drive->gendev; |
@@ -1257,22 +1252,20 @@ static int idedisk_attach(ide_drive_t *drive) | |||
1257 | add_disk(g); | 1252 | add_disk(g); |
1258 | return 0; | 1253 | return 0; |
1259 | 1254 | ||
1260 | out_put_disk: | ||
1261 | put_disk(g); | ||
1262 | out_free_idkp: | 1255 | out_free_idkp: |
1263 | kfree(idkp); | 1256 | kfree(idkp); |
1264 | failed: | 1257 | failed: |
1265 | return 1; | 1258 | return -ENODEV; |
1266 | } | 1259 | } |
1267 | 1260 | ||
1268 | static void __exit idedisk_exit (void) | 1261 | static void __exit idedisk_exit (void) |
1269 | { | 1262 | { |
1270 | ide_unregister_driver(&idedisk_driver); | 1263 | driver_unregister(&idedisk_driver.gen_driver); |
1271 | } | 1264 | } |
1272 | 1265 | ||
1273 | static int idedisk_init (void) | 1266 | static int idedisk_init (void) |
1274 | { | 1267 | { |
1275 | return ide_register_driver(&idedisk_driver); | 1268 | return driver_register(&idedisk_driver.gen_driver); |
1276 | } | 1269 | } |
1277 | 1270 | ||
1278 | module_init(idedisk_init); | 1271 | module_init(idedisk_init); |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 36c0b74a4e45..c949e98df4b6 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -1865,13 +1865,13 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) | |||
1865 | idefloppy_add_settings(drive); | 1865 | idefloppy_add_settings(drive); |
1866 | } | 1866 | } |
1867 | 1867 | ||
1868 | static int idefloppy_cleanup (ide_drive_t *drive) | 1868 | static int ide_floppy_remove(struct device *dev) |
1869 | { | 1869 | { |
1870 | ide_drive_t *drive = to_ide_device(dev); | ||
1870 | idefloppy_floppy_t *floppy = drive->driver_data; | 1871 | idefloppy_floppy_t *floppy = drive->driver_data; |
1871 | struct gendisk *g = floppy->disk; | 1872 | struct gendisk *g = floppy->disk; |
1872 | 1873 | ||
1873 | if (ide_unregister_subdriver(drive)) | 1874 | ide_unregister_subdriver(drive, floppy->driver); |
1874 | return 1; | ||
1875 | 1875 | ||
1876 | del_gendisk(g); | 1876 | del_gendisk(g); |
1877 | 1877 | ||
@@ -1916,26 +1916,24 @@ static ide_proc_entry_t idefloppy_proc[] = { | |||
1916 | 1916 | ||
1917 | #endif /* CONFIG_PROC_FS */ | 1917 | #endif /* CONFIG_PROC_FS */ |
1918 | 1918 | ||
1919 | static int idefloppy_attach(ide_drive_t *drive); | 1919 | static int ide_floppy_probe(struct device *); |
1920 | 1920 | ||
1921 | /* | ||
1922 | * IDE subdriver functions, registered with ide.c | ||
1923 | */ | ||
1924 | static ide_driver_t idefloppy_driver = { | 1921 | static ide_driver_t idefloppy_driver = { |
1925 | .owner = THIS_MODULE, | 1922 | .owner = THIS_MODULE, |
1926 | .name = "ide-floppy", | 1923 | .gen_driver = { |
1924 | .name = "ide-floppy", | ||
1925 | .bus = &ide_bus_type, | ||
1926 | .probe = ide_floppy_probe, | ||
1927 | .remove = ide_floppy_remove, | ||
1928 | }, | ||
1927 | .version = IDEFLOPPY_VERSION, | 1929 | .version = IDEFLOPPY_VERSION, |
1928 | .media = ide_floppy, | 1930 | .media = ide_floppy, |
1929 | .busy = 0, | ||
1930 | .supports_dsc_overlap = 0, | 1931 | .supports_dsc_overlap = 0, |
1931 | .cleanup = idefloppy_cleanup, | ||
1932 | .do_request = idefloppy_do_request, | 1932 | .do_request = idefloppy_do_request, |
1933 | .end_request = idefloppy_do_end_request, | 1933 | .end_request = idefloppy_do_end_request, |
1934 | .error = __ide_error, | 1934 | .error = __ide_error, |
1935 | .abort = __ide_abort, | 1935 | .abort = __ide_abort, |
1936 | .proc = idefloppy_proc, | 1936 | .proc = idefloppy_proc, |
1937 | .attach = idefloppy_attach, | ||
1938 | .drives = LIST_HEAD_INIT(idefloppy_driver.drives), | ||
1939 | }; | 1937 | }; |
1940 | 1938 | ||
1941 | static int idefloppy_open(struct inode *inode, struct file *filp) | 1939 | static int idefloppy_open(struct inode *inode, struct file *filp) |
@@ -2122,8 +2120,9 @@ static struct block_device_operations idefloppy_ops = { | |||
2122 | .revalidate_disk= idefloppy_revalidate_disk | 2120 | .revalidate_disk= idefloppy_revalidate_disk |
2123 | }; | 2121 | }; |
2124 | 2122 | ||
2125 | static int idefloppy_attach (ide_drive_t *drive) | 2123 | static int ide_floppy_probe(struct device *dev) |
2126 | { | 2124 | { |
2125 | ide_drive_t *drive = to_ide_device(dev); | ||
2127 | idefloppy_floppy_t *floppy; | 2126 | idefloppy_floppy_t *floppy; |
2128 | struct gendisk *g; | 2127 | struct gendisk *g; |
2129 | 2128 | ||
@@ -2152,10 +2151,7 @@ static int idefloppy_attach (ide_drive_t *drive) | |||
2152 | 2151 | ||
2153 | ide_init_disk(g, drive); | 2152 | ide_init_disk(g, drive); |
2154 | 2153 | ||
2155 | if (ide_register_subdriver(drive, &idefloppy_driver)) { | 2154 | ide_register_subdriver(drive, &idefloppy_driver); |
2156 | printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name); | ||
2157 | goto out_put_disk; | ||
2158 | } | ||
2159 | 2155 | ||
2160 | memset(floppy, 0, sizeof(*floppy)); | 2156 | memset(floppy, 0, sizeof(*floppy)); |
2161 | 2157 | ||
@@ -2169,9 +2165,8 @@ static int idefloppy_attach (ide_drive_t *drive) | |||
2169 | 2165 | ||
2170 | drive->driver_data = floppy; | 2166 | drive->driver_data = floppy; |
2171 | 2167 | ||
2172 | DRIVER(drive)->busy++; | ||
2173 | idefloppy_setup (drive, floppy); | 2168 | idefloppy_setup (drive, floppy); |
2174 | DRIVER(drive)->busy--; | 2169 | |
2175 | g->minors = 1 << PARTN_BITS; | 2170 | g->minors = 1 << PARTN_BITS; |
2176 | g->driverfs_dev = &drive->gendev; | 2171 | g->driverfs_dev = &drive->gendev; |
2177 | strcpy(g->devfs_name, drive->devfs_name); | 2172 | strcpy(g->devfs_name, drive->devfs_name); |
@@ -2181,19 +2176,17 @@ static int idefloppy_attach (ide_drive_t *drive) | |||
2181 | add_disk(g); | 2176 | add_disk(g); |
2182 | return 0; | 2177 | return 0; |
2183 | 2178 | ||
2184 | out_put_disk: | ||
2185 | put_disk(g); | ||
2186 | out_free_floppy: | 2179 | out_free_floppy: |
2187 | kfree(floppy); | 2180 | kfree(floppy); |
2188 | failed: | 2181 | failed: |
2189 | return 1; | 2182 | return -ENODEV; |
2190 | } | 2183 | } |
2191 | 2184 | ||
2192 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); | 2185 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); |
2193 | 2186 | ||
2194 | static void __exit idefloppy_exit (void) | 2187 | static void __exit idefloppy_exit (void) |
2195 | { | 2188 | { |
2196 | ide_unregister_driver(&idefloppy_driver); | 2189 | driver_unregister(&idefloppy_driver.gen_driver); |
2197 | } | 2190 | } |
2198 | 2191 | ||
2199 | /* | 2192 | /* |
@@ -2202,8 +2195,7 @@ static void __exit idefloppy_exit (void) | |||
2202 | static int idefloppy_init (void) | 2195 | static int idefloppy_init (void) |
2203 | { | 2196 | { |
2204 | printk("ide-floppy driver " IDEFLOPPY_VERSION "\n"); | 2197 | printk("ide-floppy driver " IDEFLOPPY_VERSION "\n"); |
2205 | ide_register_driver(&idefloppy_driver); | 2198 | return driver_register(&idefloppy_driver.gen_driver); |
2206 | return 0; | ||
2207 | } | 2199 | } |
2208 | 2200 | ||
2209 | module_init(idefloppy_init); | 2201 | module_init(idefloppy_init); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 554473a95cf7..53b84a84f6cb 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/slab.h> | 47 | #include <linux/slab.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/ide.h> | 49 | #include <linux/ide.h> |
50 | #include <linux/devfs_fs_kernel.h> | ||
50 | #include <linux/spinlock.h> | 51 | #include <linux/spinlock.h> |
51 | #include <linux/kmod.h> | 52 | #include <linux/kmod.h> |
52 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
@@ -918,7 +919,7 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif) | |||
918 | want them on default or a new "empty" class | 919 | want them on default or a new "empty" class |
919 | for hotplug reprobing ? */ | 920 | for hotplug reprobing ? */ |
920 | if (drive->present) { | 921 | if (drive->present) { |
921 | ata_attach(drive); | 922 | device_register(&drive->gendev); |
922 | } | 923 | } |
923 | } | 924 | } |
924 | } | 925 | } |
@@ -1279,10 +1280,51 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) | |||
1279 | 1280 | ||
1280 | EXPORT_SYMBOL_GPL(ide_init_disk); | 1281 | EXPORT_SYMBOL_GPL(ide_init_disk); |
1281 | 1282 | ||
1283 | static void ide_remove_drive_from_hwgroup(ide_drive_t *drive) | ||
1284 | { | ||
1285 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | ||
1286 | |||
1287 | if (drive == drive->next) { | ||
1288 | /* special case: last drive from hwgroup. */ | ||
1289 | BUG_ON(hwgroup->drive != drive); | ||
1290 | hwgroup->drive = NULL; | ||
1291 | } else { | ||
1292 | ide_drive_t *walk; | ||
1293 | |||
1294 | walk = hwgroup->drive; | ||
1295 | while (walk->next != drive) | ||
1296 | walk = walk->next; | ||
1297 | walk->next = drive->next; | ||
1298 | if (hwgroup->drive == drive) { | ||
1299 | hwgroup->drive = drive->next; | ||
1300 | hwgroup->hwif = hwgroup->drive->hwif; | ||
1301 | } | ||
1302 | } | ||
1303 | BUG_ON(hwgroup->drive == drive); | ||
1304 | } | ||
1305 | |||
1282 | static void drive_release_dev (struct device *dev) | 1306 | static void drive_release_dev (struct device *dev) |
1283 | { | 1307 | { |
1284 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); | 1308 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); |
1285 | 1309 | ||
1310 | spin_lock_irq(&ide_lock); | ||
1311 | if (drive->devfs_name[0] != '\0') { | ||
1312 | devfs_remove(drive->devfs_name); | ||
1313 | drive->devfs_name[0] = '\0'; | ||
1314 | } | ||
1315 | ide_remove_drive_from_hwgroup(drive); | ||
1316 | if (drive->id != NULL) { | ||
1317 | kfree(drive->id); | ||
1318 | drive->id = NULL; | ||
1319 | } | ||
1320 | drive->present = 0; | ||
1321 | /* Messed up locking ... */ | ||
1322 | spin_unlock_irq(&ide_lock); | ||
1323 | blk_cleanup_queue(drive->queue); | ||
1324 | spin_lock_irq(&ide_lock); | ||
1325 | drive->queue = NULL; | ||
1326 | spin_unlock_irq(&ide_lock); | ||
1327 | |||
1286 | up(&drive->gendev_rel_sem); | 1328 | up(&drive->gendev_rel_sem); |
1287 | } | 1329 | } |
1288 | 1330 | ||
@@ -1306,7 +1348,6 @@ static void init_gendisk (ide_hwif_t *hwif) | |||
1306 | drive->gendev.driver_data = drive; | 1348 | drive->gendev.driver_data = drive; |
1307 | drive->gendev.release = drive_release_dev; | 1349 | drive->gendev.release = drive_release_dev; |
1308 | if (drive->present) { | 1350 | if (drive->present) { |
1309 | device_register(&drive->gendev); | ||
1310 | sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d", | 1351 | sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d", |
1311 | (hwif->channel && hwif->mate) ? | 1352 | (hwif->channel && hwif->mate) ? |
1312 | hwif->mate->index : hwif->index, | 1353 | hwif->mate->index : hwif->index, |
@@ -1412,7 +1453,7 @@ int ideprobe_init (void) | |||
1412 | hwif->chipset = ide_generic; | 1453 | hwif->chipset = ide_generic; |
1413 | for (unit = 0; unit < MAX_DRIVES; ++unit) | 1454 | for (unit = 0; unit < MAX_DRIVES; ++unit) |
1414 | if (hwif->drives[unit].present) | 1455 | if (hwif->drives[unit].present) |
1415 | ata_attach(&hwif->drives[unit]); | 1456 | device_register(&hwif->drives[unit].gendev); |
1416 | } | 1457 | } |
1417 | } | 1458 | } |
1418 | return 0; | 1459 | return 0; |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 4b1e43b4118b..4063d2c34e3d 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -307,17 +307,41 @@ static int proc_ide_read_driver | |||
307 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 307 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
308 | { | 308 | { |
309 | ide_drive_t *drive = (ide_drive_t *) data; | 309 | ide_drive_t *drive = (ide_drive_t *) data; |
310 | ide_driver_t *driver = drive->driver; | 310 | struct device *dev = &drive->gendev; |
311 | ide_driver_t *ide_drv; | ||
311 | int len; | 312 | int len; |
312 | 313 | ||
313 | if (driver) { | 314 | down_read(&dev->bus->subsys.rwsem); |
315 | if (dev->driver) { | ||
316 | ide_drv = container_of(dev->driver, ide_driver_t, gen_driver); | ||
314 | len = sprintf(page, "%s version %s\n", | 317 | len = sprintf(page, "%s version %s\n", |
315 | driver->name, driver->version); | 318 | dev->driver->name, ide_drv->version); |
316 | } else | 319 | } else |
317 | len = sprintf(page, "ide-default version 0.9.newide\n"); | 320 | len = sprintf(page, "ide-default version 0.9.newide\n"); |
321 | up_read(&dev->bus->subsys.rwsem); | ||
318 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); | 322 | PROC_IDE_READ_RETURN(page,start,off,count,eof,len); |
319 | } | 323 | } |
320 | 324 | ||
325 | static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) | ||
326 | { | ||
327 | struct device *dev = &drive->gendev; | ||
328 | int ret = 1; | ||
329 | |||
330 | down_write(&dev->bus->subsys.rwsem); | ||
331 | device_release_driver(dev); | ||
332 | /* FIXME: device can still be in use by previous driver */ | ||
333 | strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); | ||
334 | device_attach(dev); | ||
335 | drive->driver_req[0] = 0; | ||
336 | if (dev->driver == NULL) | ||
337 | device_attach(dev); | ||
338 | if (dev->driver && !strcmp(dev->driver->name, driver)) | ||
339 | ret = 0; | ||
340 | up_write(&dev->bus->subsys.rwsem); | ||
341 | |||
342 | return ret; | ||
343 | } | ||
344 | |||
321 | static int proc_ide_write_driver | 345 | static int proc_ide_write_driver |
322 | (struct file *file, const char __user *buffer, unsigned long count, void *data) | 346 | (struct file *file, const char __user *buffer, unsigned long count, void *data) |
323 | { | 347 | { |
@@ -488,16 +512,32 @@ void destroy_proc_ide_interface(ide_hwif_t *hwif) | |||
488 | } | 512 | } |
489 | } | 513 | } |
490 | 514 | ||
491 | extern struct seq_operations ide_drivers_op; | 515 | static int proc_print_driver(struct device_driver *drv, void *data) |
516 | { | ||
517 | ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver); | ||
518 | struct seq_file *s = data; | ||
519 | |||
520 | seq_printf(s, "%s version %s\n", drv->name, ide_drv->version); | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static int ide_drivers_show(struct seq_file *s, void *p) | ||
526 | { | ||
527 | bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver); | ||
528 | return 0; | ||
529 | } | ||
530 | |||
492 | static int ide_drivers_open(struct inode *inode, struct file *file) | 531 | static int ide_drivers_open(struct inode *inode, struct file *file) |
493 | { | 532 | { |
494 | return seq_open(file, &ide_drivers_op); | 533 | return single_open(file, &ide_drivers_show, NULL); |
495 | } | 534 | } |
535 | |||
496 | static struct file_operations ide_drivers_operations = { | 536 | static struct file_operations ide_drivers_operations = { |
497 | .open = ide_drivers_open, | 537 | .open = ide_drivers_open, |
498 | .read = seq_read, | 538 | .read = seq_read, |
499 | .llseek = seq_lseek, | 539 | .llseek = seq_lseek, |
500 | .release = seq_release, | 540 | .release = single_release, |
501 | }; | 541 | }; |
502 | 542 | ||
503 | void proc_ide_create(void) | 543 | void proc_ide_create(void) |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 482544854985..5a3dc46008e6 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -4681,21 +4681,12 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) | |||
4681 | idetape_add_settings(drive); | 4681 | idetape_add_settings(drive); |
4682 | } | 4682 | } |
4683 | 4683 | ||
4684 | static int idetape_cleanup (ide_drive_t *drive) | 4684 | static int ide_tape_remove(struct device *dev) |
4685 | { | 4685 | { |
4686 | ide_drive_t *drive = to_ide_device(dev); | ||
4686 | idetape_tape_t *tape = drive->driver_data; | 4687 | idetape_tape_t *tape = drive->driver_data; |
4687 | unsigned long flags; | ||
4688 | |||
4689 | spin_lock_irqsave(&ide_lock, flags); | ||
4690 | if (test_bit(IDETAPE_BUSY, &tape->flags) || drive->usage || | ||
4691 | tape->first_stage != NULL || tape->merge_stage_size) { | ||
4692 | spin_unlock_irqrestore(&ide_lock, flags); | ||
4693 | return 1; | ||
4694 | } | ||
4695 | 4688 | ||
4696 | spin_unlock_irqrestore(&ide_lock, flags); | 4689 | ide_unregister_subdriver(drive, tape->driver); |
4697 | DRIVER(drive)->busy = 0; | ||
4698 | (void) ide_unregister_subdriver(drive); | ||
4699 | 4690 | ||
4700 | ide_unregister_region(tape->disk); | 4691 | ide_unregister_region(tape->disk); |
4701 | 4692 | ||
@@ -4710,6 +4701,8 @@ static void ide_tape_release(struct kref *kref) | |||
4710 | ide_drive_t *drive = tape->drive; | 4701 | ide_drive_t *drive = tape->drive; |
4711 | struct gendisk *g = tape->disk; | 4702 | struct gendisk *g = tape->disk; |
4712 | 4703 | ||
4704 | BUG_ON(tape->first_stage != NULL || tape->merge_stage_size); | ||
4705 | |||
4713 | drive->dsc_overlap = 0; | 4706 | drive->dsc_overlap = 0; |
4714 | drive->driver_data = NULL; | 4707 | drive->driver_data = NULL; |
4715 | devfs_remove("%s/mt", drive->devfs_name); | 4708 | devfs_remove("%s/mt", drive->devfs_name); |
@@ -4747,26 +4740,24 @@ static ide_proc_entry_t idetape_proc[] = { | |||
4747 | 4740 | ||
4748 | #endif | 4741 | #endif |
4749 | 4742 | ||
4750 | static int idetape_attach(ide_drive_t *drive); | 4743 | static int ide_tape_probe(struct device *); |
4751 | 4744 | ||
4752 | /* | ||
4753 | * IDE subdriver functions, registered with ide.c | ||
4754 | */ | ||
4755 | static ide_driver_t idetape_driver = { | 4745 | static ide_driver_t idetape_driver = { |
4756 | .owner = THIS_MODULE, | 4746 | .owner = THIS_MODULE, |
4757 | .name = "ide-tape", | 4747 | .gen_driver = { |
4748 | .name = "ide-tape", | ||
4749 | .bus = &ide_bus_type, | ||
4750 | .probe = ide_tape_probe, | ||
4751 | .remove = ide_tape_remove, | ||
4752 | }, | ||
4758 | .version = IDETAPE_VERSION, | 4753 | .version = IDETAPE_VERSION, |
4759 | .media = ide_tape, | 4754 | .media = ide_tape, |
4760 | .busy = 1, | ||
4761 | .supports_dsc_overlap = 1, | 4755 | .supports_dsc_overlap = 1, |
4762 | .cleanup = idetape_cleanup, | ||
4763 | .do_request = idetape_do_request, | 4756 | .do_request = idetape_do_request, |
4764 | .end_request = idetape_end_request, | 4757 | .end_request = idetape_end_request, |
4765 | .error = __ide_error, | 4758 | .error = __ide_error, |
4766 | .abort = __ide_abort, | 4759 | .abort = __ide_abort, |
4767 | .proc = idetape_proc, | 4760 | .proc = idetape_proc, |
4768 | .attach = idetape_attach, | ||
4769 | .drives = LIST_HEAD_INIT(idetape_driver.drives), | ||
4770 | }; | 4761 | }; |
4771 | 4762 | ||
4772 | /* | 4763 | /* |
@@ -4829,8 +4820,9 @@ static struct block_device_operations idetape_block_ops = { | |||
4829 | .ioctl = idetape_ioctl, | 4820 | .ioctl = idetape_ioctl, |
4830 | }; | 4821 | }; |
4831 | 4822 | ||
4832 | static int idetape_attach (ide_drive_t *drive) | 4823 | static int ide_tape_probe(struct device *dev) |
4833 | { | 4824 | { |
4825 | ide_drive_t *drive = to_ide_device(dev); | ||
4834 | idetape_tape_t *tape; | 4826 | idetape_tape_t *tape; |
4835 | struct gendisk *g; | 4827 | struct gendisk *g; |
4836 | int minor; | 4828 | int minor; |
@@ -4865,10 +4857,7 @@ static int idetape_attach (ide_drive_t *drive) | |||
4865 | 4857 | ||
4866 | ide_init_disk(g, drive); | 4858 | ide_init_disk(g, drive); |
4867 | 4859 | ||
4868 | if (ide_register_subdriver(drive, &idetape_driver)) { | 4860 | ide_register_subdriver(drive, &idetape_driver); |
4869 | printk(KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name); | ||
4870 | goto out_put_disk; | ||
4871 | } | ||
4872 | 4861 | ||
4873 | memset(tape, 0, sizeof(*tape)); | 4862 | memset(tape, 0, sizeof(*tape)); |
4874 | 4863 | ||
@@ -4902,12 +4891,11 @@ static int idetape_attach (ide_drive_t *drive) | |||
4902 | ide_register_region(g); | 4891 | ide_register_region(g); |
4903 | 4892 | ||
4904 | return 0; | 4893 | return 0; |
4905 | out_put_disk: | 4894 | |
4906 | put_disk(g); | ||
4907 | out_free_tape: | 4895 | out_free_tape: |
4908 | kfree(tape); | 4896 | kfree(tape); |
4909 | failed: | 4897 | failed: |
4910 | return 1; | 4898 | return -ENODEV; |
4911 | } | 4899 | } |
4912 | 4900 | ||
4913 | MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); | 4901 | MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); |
@@ -4915,7 +4903,7 @@ MODULE_LICENSE("GPL"); | |||
4915 | 4903 | ||
4916 | static void __exit idetape_exit (void) | 4904 | static void __exit idetape_exit (void) |
4917 | { | 4905 | { |
4918 | ide_unregister_driver(&idetape_driver); | 4906 | driver_unregister(&idetape_driver.gen_driver); |
4919 | unregister_chrdev(IDETAPE_MAJOR, "ht"); | 4907 | unregister_chrdev(IDETAPE_MAJOR, "ht"); |
4920 | } | 4908 | } |
4921 | 4909 | ||
@@ -4928,8 +4916,7 @@ static int idetape_init (void) | |||
4928 | printk(KERN_ERR "ide-tape: Failed to register character device interface\n"); | 4916 | printk(KERN_ERR "ide-tape: Failed to register character device interface\n"); |
4929 | return -EBUSY; | 4917 | return -EBUSY; |
4930 | } | 4918 | } |
4931 | ide_register_driver(&idetape_driver); | 4919 | return driver_register(&idetape_driver.gen_driver); |
4932 | return 0; | ||
4933 | } | 4920 | } |
4934 | 4921 | ||
4935 | module_init(idetape_init); | 4922 | module_init(idetape_init); |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 973dec799b5c..dae1bd5b8c3e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -196,8 +196,6 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ | |||
196 | 196 | ||
197 | EXPORT_SYMBOL(ide_hwifs); | 197 | EXPORT_SYMBOL(ide_hwifs); |
198 | 198 | ||
199 | static struct list_head ide_drives = LIST_HEAD_INIT(ide_drives); | ||
200 | |||
201 | /* | 199 | /* |
202 | * Do not even *think* about calling this! | 200 | * Do not even *think* about calling this! |
203 | */ | 201 | */ |
@@ -358,54 +356,6 @@ static int ide_system_bus_speed(void) | |||
358 | return system_bus_speed; | 356 | return system_bus_speed; |
359 | } | 357 | } |
360 | 358 | ||
361 | /* | ||
362 | * drives_lock protects the list of drives, drivers_lock the | ||
363 | * list of drivers. Currently nobody takes both at once. | ||
364 | */ | ||
365 | |||
366 | static DEFINE_SPINLOCK(drives_lock); | ||
367 | static DEFINE_SPINLOCK(drivers_lock); | ||
368 | static LIST_HEAD(drivers); | ||
369 | |||
370 | /* Iterator for the driver list. */ | ||
371 | |||
372 | static void *m_start(struct seq_file *m, loff_t *pos) | ||
373 | { | ||
374 | struct list_head *p; | ||
375 | loff_t l = *pos; | ||
376 | spin_lock(&drivers_lock); | ||
377 | list_for_each(p, &drivers) | ||
378 | if (!l--) | ||
379 | return list_entry(p, ide_driver_t, drivers); | ||
380 | return NULL; | ||
381 | } | ||
382 | |||
383 | static void *m_next(struct seq_file *m, void *v, loff_t *pos) | ||
384 | { | ||
385 | struct list_head *p = ((ide_driver_t *)v)->drivers.next; | ||
386 | (*pos)++; | ||
387 | return p==&drivers ? NULL : list_entry(p, ide_driver_t, drivers); | ||
388 | } | ||
389 | |||
390 | static void m_stop(struct seq_file *m, void *v) | ||
391 | { | ||
392 | spin_unlock(&drivers_lock); | ||
393 | } | ||
394 | |||
395 | static int show_driver(struct seq_file *m, void *v) | ||
396 | { | ||
397 | ide_driver_t *driver = v; | ||
398 | seq_printf(m, "%s version %s\n", driver->name, driver->version); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | struct seq_operations ide_drivers_op = { | ||
403 | .start = m_start, | ||
404 | .next = m_next, | ||
405 | .stop = m_stop, | ||
406 | .show = show_driver | ||
407 | }; | ||
408 | |||
409 | #ifdef CONFIG_PROC_FS | 359 | #ifdef CONFIG_PROC_FS |
410 | struct proc_dir_entry *proc_ide_root; | 360 | struct proc_dir_entry *proc_ide_root; |
411 | #endif | 361 | #endif |
@@ -630,7 +580,7 @@ void ide_unregister(unsigned int index) | |||
630 | ide_hwif_t *hwif, *g; | 580 | ide_hwif_t *hwif, *g; |
631 | static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ | 581 | static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ |
632 | ide_hwgroup_t *hwgroup; | 582 | ide_hwgroup_t *hwgroup; |
633 | int irq_count = 0, unit, i; | 583 | int irq_count = 0, unit; |
634 | 584 | ||
635 | BUG_ON(index >= MAX_HWIFS); | 585 | BUG_ON(index >= MAX_HWIFS); |
636 | 586 | ||
@@ -643,23 +593,22 @@ void ide_unregister(unsigned int index) | |||
643 | goto abort; | 593 | goto abort; |
644 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 594 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
645 | drive = &hwif->drives[unit]; | 595 | drive = &hwif->drives[unit]; |
646 | if (!drive->present) | 596 | if (!drive->present) { |
597 | if (drive->devfs_name[0] != '\0') { | ||
598 | devfs_remove(drive->devfs_name); | ||
599 | drive->devfs_name[0] = '\0'; | ||
600 | } | ||
647 | continue; | 601 | continue; |
648 | if (drive->usage || DRIVER(drive)->busy) | 602 | } |
649 | goto abort; | 603 | spin_unlock_irq(&ide_lock); |
650 | drive->dead = 1; | 604 | device_unregister(&drive->gendev); |
605 | down(&drive->gendev_rel_sem); | ||
606 | spin_lock_irq(&ide_lock); | ||
651 | } | 607 | } |
652 | hwif->present = 0; | 608 | hwif->present = 0; |
653 | 609 | ||
654 | spin_unlock_irq(&ide_lock); | 610 | spin_unlock_irq(&ide_lock); |
655 | 611 | ||
656 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | ||
657 | drive = &hwif->drives[unit]; | ||
658 | if (!drive->present) | ||
659 | continue; | ||
660 | DRIVER(drive)->cleanup(drive); | ||
661 | } | ||
662 | |||
663 | destroy_proc_ide_interface(hwif); | 612 | destroy_proc_ide_interface(hwif); |
664 | 613 | ||
665 | hwgroup = hwif->hwgroup; | 614 | hwgroup = hwif->hwgroup; |
@@ -687,44 +636,6 @@ void ide_unregister(unsigned int index) | |||
687 | * Remove us from the hwgroup, and free | 636 | * Remove us from the hwgroup, and free |
688 | * the hwgroup if we were the only member | 637 | * the hwgroup if we were the only member |
689 | */ | 638 | */ |
690 | for (i = 0; i < MAX_DRIVES; ++i) { | ||
691 | drive = &hwif->drives[i]; | ||
692 | if (drive->devfs_name[0] != '\0') { | ||
693 | devfs_remove(drive->devfs_name); | ||
694 | drive->devfs_name[0] = '\0'; | ||
695 | } | ||
696 | if (!drive->present) | ||
697 | continue; | ||
698 | if (drive == drive->next) { | ||
699 | /* special case: last drive from hwgroup. */ | ||
700 | BUG_ON(hwgroup->drive != drive); | ||
701 | hwgroup->drive = NULL; | ||
702 | } else { | ||
703 | ide_drive_t *walk; | ||
704 | |||
705 | walk = hwgroup->drive; | ||
706 | while (walk->next != drive) | ||
707 | walk = walk->next; | ||
708 | walk->next = drive->next; | ||
709 | if (hwgroup->drive == drive) { | ||
710 | hwgroup->drive = drive->next; | ||
711 | hwgroup->hwif = HWIF(hwgroup->drive); | ||
712 | } | ||
713 | } | ||
714 | BUG_ON(hwgroup->drive == drive); | ||
715 | if (drive->id != NULL) { | ||
716 | kfree(drive->id); | ||
717 | drive->id = NULL; | ||
718 | } | ||
719 | drive->present = 0; | ||
720 | /* Messed up locking ... */ | ||
721 | spin_unlock_irq(&ide_lock); | ||
722 | blk_cleanup_queue(drive->queue); | ||
723 | device_unregister(&drive->gendev); | ||
724 | down(&drive->gendev_rel_sem); | ||
725 | spin_lock_irq(&ide_lock); | ||
726 | drive->queue = NULL; | ||
727 | } | ||
728 | if (hwif->next == hwif) { | 639 | if (hwif->next == hwif) { |
729 | BUG_ON(hwgroup->hwif != hwif); | 640 | BUG_ON(hwgroup->hwif != hwif); |
730 | kfree(hwgroup); | 641 | kfree(hwgroup); |
@@ -1304,73 +1215,6 @@ int system_bus_clock (void) | |||
1304 | 1215 | ||
1305 | EXPORT_SYMBOL(system_bus_clock); | 1216 | EXPORT_SYMBOL(system_bus_clock); |
1306 | 1217 | ||
1307 | /* | ||
1308 | * Locking is badly broken here - since way back. That sucker is | ||
1309 | * root-only, but that's not an excuse... The real question is what | ||
1310 | * exclusion rules do we want here. | ||
1311 | */ | ||
1312 | int ide_replace_subdriver (ide_drive_t *drive, const char *driver) | ||
1313 | { | ||
1314 | if (!drive->present || drive->usage || drive->dead) | ||
1315 | goto abort; | ||
1316 | if (DRIVER(drive)->cleanup(drive)) | ||
1317 | goto abort; | ||
1318 | strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); | ||
1319 | if (ata_attach(drive)) { | ||
1320 | spin_lock(&drives_lock); | ||
1321 | list_del_init(&drive->list); | ||
1322 | spin_unlock(&drives_lock); | ||
1323 | drive->driver_req[0] = 0; | ||
1324 | ata_attach(drive); | ||
1325 | } else { | ||
1326 | drive->driver_req[0] = 0; | ||
1327 | } | ||
1328 | if (drive->driver && !strcmp(drive->driver->name, driver)) | ||
1329 | return 0; | ||
1330 | abort: | ||
1331 | return 1; | ||
1332 | } | ||
1333 | |||
1334 | /** | ||
1335 | * ata_attach - attach an ATA/ATAPI device | ||
1336 | * @drive: drive to attach | ||
1337 | * | ||
1338 | * Takes a drive that is as yet not assigned to any midlayer IDE | ||
1339 | * driver (or is assigned to the default driver) and figures out | ||
1340 | * which driver would like to own it. If nobody claims the drive | ||
1341 | * then it is automatically attached to the default driver used for | ||
1342 | * unclaimed objects. | ||
1343 | * | ||
1344 | * A return of zero indicates attachment to a driver, of one | ||
1345 | * attachment to the default driver. | ||
1346 | * | ||
1347 | * Takes drivers_lock. | ||
1348 | */ | ||
1349 | |||
1350 | int ata_attach(ide_drive_t *drive) | ||
1351 | { | ||
1352 | struct list_head *p; | ||
1353 | spin_lock(&drivers_lock); | ||
1354 | list_for_each(p, &drivers) { | ||
1355 | ide_driver_t *driver = list_entry(p, ide_driver_t, drivers); | ||
1356 | if (!try_module_get(driver->owner)) | ||
1357 | continue; | ||
1358 | spin_unlock(&drivers_lock); | ||
1359 | if (driver->attach(drive) == 0) { | ||
1360 | module_put(driver->owner); | ||
1361 | drive->gendev.driver = &driver->gen_driver; | ||
1362 | return 0; | ||
1363 | } | ||
1364 | spin_lock(&drivers_lock); | ||
1365 | module_put(driver->owner); | ||
1366 | } | ||
1367 | drive->gendev.driver = NULL; | ||
1368 | spin_unlock(&drivers_lock); | ||
1369 | if (ide_register_subdriver(drive, NULL)) | ||
1370 | panic("ide: default attach failed"); | ||
1371 | return 1; | ||
1372 | } | ||
1373 | |||
1374 | static int generic_ide_suspend(struct device *dev, pm_message_t state) | 1218 | static int generic_ide_suspend(struct device *dev, pm_message_t state) |
1375 | { | 1219 | { |
1376 | ide_drive_t *drive = dev->driver_data; | 1220 | ide_drive_t *drive = dev->driver_data; |
@@ -2013,27 +1857,11 @@ static void __init probe_for_hwifs (void) | |||
2013 | #endif | 1857 | #endif |
2014 | } | 1858 | } |
2015 | 1859 | ||
2016 | int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) | 1860 | void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) |
2017 | { | 1861 | { |
2018 | unsigned long flags; | ||
2019 | |||
2020 | spin_lock_irqsave(&ide_lock, flags); | ||
2021 | if (!drive->present || drive->driver != NULL || | ||
2022 | drive->usage || drive->dead) { | ||
2023 | spin_unlock_irqrestore(&ide_lock, flags); | ||
2024 | return 1; | ||
2025 | } | ||
2026 | drive->driver = driver; | ||
2027 | spin_unlock_irqrestore(&ide_lock, flags); | ||
2028 | spin_lock(&drives_lock); | ||
2029 | list_add_tail(&drive->list, driver ? &driver->drives : &ide_drives); | ||
2030 | spin_unlock(&drives_lock); | ||
2031 | // printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name); | ||
2032 | #ifdef CONFIG_PROC_FS | 1862 | #ifdef CONFIG_PROC_FS |
2033 | if (driver) | 1863 | ide_add_proc_entries(drive->proc, driver->proc, drive); |
2034 | ide_add_proc_entries(drive->proc, driver->proc, drive); | ||
2035 | #endif | 1864 | #endif |
2036 | return 0; | ||
2037 | } | 1865 | } |
2038 | 1866 | ||
2039 | EXPORT_SYMBOL(ide_register_subdriver); | 1867 | EXPORT_SYMBOL(ide_register_subdriver); |
@@ -2041,136 +1869,51 @@ EXPORT_SYMBOL(ide_register_subdriver); | |||
2041 | /** | 1869 | /** |
2042 | * ide_unregister_subdriver - disconnect drive from driver | 1870 | * ide_unregister_subdriver - disconnect drive from driver |
2043 | * @drive: drive to unplug | 1871 | * @drive: drive to unplug |
1872 | * @driver: driver | ||
2044 | * | 1873 | * |
2045 | * Disconnect a drive from the driver it was attached to and then | 1874 | * Disconnect a drive from the driver it was attached to and then |
2046 | * clean up the various proc files and other objects attached to it. | 1875 | * clean up the various proc files and other objects attached to it. |
2047 | * | 1876 | * |
2048 | * Takes ide_setting_sem, ide_lock and drives_lock. | 1877 | * Takes ide_setting_sem and ide_lock. |
2049 | * Caller must hold none of the locks. | 1878 | * Caller must hold none of the locks. |
2050 | * | ||
2051 | * No locking versus subdriver unload because we are moving to the | ||
2052 | * default driver anyway. Wants double checking. | ||
2053 | */ | 1879 | */ |
2054 | 1880 | ||
2055 | int ide_unregister_subdriver (ide_drive_t *drive) | 1881 | void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) |
2056 | { | 1882 | { |
2057 | unsigned long flags; | 1883 | unsigned long flags; |
2058 | 1884 | ||
2059 | down(&ide_setting_sem); | 1885 | down(&ide_setting_sem); |
2060 | spin_lock_irqsave(&ide_lock, flags); | 1886 | spin_lock_irqsave(&ide_lock, flags); |
2061 | if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) { | ||
2062 | spin_unlock_irqrestore(&ide_lock, flags); | ||
2063 | up(&ide_setting_sem); | ||
2064 | return 1; | ||
2065 | } | ||
2066 | #ifdef CONFIG_PROC_FS | 1887 | #ifdef CONFIG_PROC_FS |
2067 | ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); | 1888 | ide_remove_proc_entries(drive->proc, driver->proc); |
2068 | #endif | 1889 | #endif |
2069 | auto_remove_settings(drive); | 1890 | auto_remove_settings(drive); |
2070 | drive->driver = NULL; | ||
2071 | spin_unlock_irqrestore(&ide_lock, flags); | 1891 | spin_unlock_irqrestore(&ide_lock, flags); |
2072 | up(&ide_setting_sem); | 1892 | up(&ide_setting_sem); |
2073 | spin_lock(&drives_lock); | ||
2074 | list_del_init(&drive->list); | ||
2075 | spin_unlock(&drives_lock); | ||
2076 | /* drive will be added to &ide_drives in ata_attach() */ | ||
2077 | return 0; | ||
2078 | } | 1893 | } |
2079 | 1894 | ||
2080 | EXPORT_SYMBOL(ide_unregister_subdriver); | 1895 | EXPORT_SYMBOL(ide_unregister_subdriver); |
2081 | 1896 | ||
2082 | static int ide_drive_remove(struct device * dev) | ||
2083 | { | ||
2084 | ide_drive_t * drive = container_of(dev,ide_drive_t,gendev); | ||
2085 | DRIVER(drive)->cleanup(drive); | ||
2086 | return 0; | ||
2087 | } | ||
2088 | |||
2089 | /** | ||
2090 | * ide_register_driver - register IDE device driver | ||
2091 | * @driver: the IDE device driver | ||
2092 | * | ||
2093 | * Register a new device driver and then scan the devices | ||
2094 | * on the IDE bus in case any should be attached to the | ||
2095 | * driver we have just registered. If so attach them. | ||
2096 | * | ||
2097 | * Takes drivers_lock and drives_lock. | ||
2098 | */ | ||
2099 | |||
2100 | int ide_register_driver(ide_driver_t *driver) | ||
2101 | { | ||
2102 | struct list_head list; | ||
2103 | struct list_head *list_loop; | ||
2104 | struct list_head *tmp_storage; | ||
2105 | |||
2106 | spin_lock(&drivers_lock); | ||
2107 | list_add(&driver->drivers, &drivers); | ||
2108 | spin_unlock(&drivers_lock); | ||
2109 | |||
2110 | INIT_LIST_HEAD(&list); | ||
2111 | spin_lock(&drives_lock); | ||
2112 | list_splice_init(&ide_drives, &list); | ||
2113 | spin_unlock(&drives_lock); | ||
2114 | |||
2115 | list_for_each_safe(list_loop, tmp_storage, &list) { | ||
2116 | ide_drive_t *drive = container_of(list_loop, ide_drive_t, list); | ||
2117 | list_del_init(&drive->list); | ||
2118 | if (drive->present) | ||
2119 | ata_attach(drive); | ||
2120 | } | ||
2121 | driver->gen_driver.name = (char *) driver->name; | ||
2122 | driver->gen_driver.bus = &ide_bus_type; | ||
2123 | driver->gen_driver.remove = ide_drive_remove; | ||
2124 | return driver_register(&driver->gen_driver); | ||
2125 | } | ||
2126 | |||
2127 | EXPORT_SYMBOL(ide_register_driver); | ||
2128 | |||
2129 | /** | ||
2130 | * ide_unregister_driver - unregister IDE device driver | ||
2131 | * @driver: the IDE device driver | ||
2132 | * | ||
2133 | * Called when a driver module is being unloaded. We reattach any | ||
2134 | * devices to whatever driver claims them next (typically the default | ||
2135 | * driver). | ||
2136 | * | ||
2137 | * Takes drivers_lock and called functions will take ide_setting_sem. | ||
2138 | */ | ||
2139 | |||
2140 | void ide_unregister_driver(ide_driver_t *driver) | ||
2141 | { | ||
2142 | ide_drive_t *drive; | ||
2143 | |||
2144 | spin_lock(&drivers_lock); | ||
2145 | list_del(&driver->drivers); | ||
2146 | spin_unlock(&drivers_lock); | ||
2147 | |||
2148 | driver_unregister(&driver->gen_driver); | ||
2149 | |||
2150 | while(!list_empty(&driver->drives)) { | ||
2151 | drive = list_entry(driver->drives.next, ide_drive_t, list); | ||
2152 | if (driver->cleanup(drive)) { | ||
2153 | printk(KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name); | ||
2154 | BUG(); | ||
2155 | } | ||
2156 | ata_attach(drive); | ||
2157 | } | ||
2158 | } | ||
2159 | |||
2160 | EXPORT_SYMBOL(ide_unregister_driver); | ||
2161 | |||
2162 | /* | 1897 | /* |
2163 | * Probe module | 1898 | * Probe module |
2164 | */ | 1899 | */ |
2165 | 1900 | ||
2166 | EXPORT_SYMBOL(ide_lock); | 1901 | EXPORT_SYMBOL(ide_lock); |
2167 | 1902 | ||
1903 | static int ide_bus_match(struct device *dev, struct device_driver *drv) | ||
1904 | { | ||
1905 | return 1; | ||
1906 | } | ||
1907 | |||
2168 | struct bus_type ide_bus_type = { | 1908 | struct bus_type ide_bus_type = { |
2169 | .name = "ide", | 1909 | .name = "ide", |
1910 | .match = ide_bus_match, | ||
2170 | .suspend = generic_ide_suspend, | 1911 | .suspend = generic_ide_suspend, |
2171 | .resume = generic_ide_resume, | 1912 | .resume = generic_ide_resume, |
2172 | }; | 1913 | }; |
2173 | 1914 | ||
1915 | EXPORT_SYMBOL_GPL(ide_bus_type); | ||
1916 | |||
2174 | /* | 1917 | /* |
2175 | * This is gets invoked once during initialization, to set *everything* up | 1918 | * This is gets invoked once during initialization, to set *everything* up |
2176 | */ | 1919 | */ |