diff options
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 554473a95cf7..5d876f53c697 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> |
@@ -696,13 +697,13 @@ static int wait_hwif_ready(ide_hwif_t *hwif) | |||
696 | SELECT_DRIVE(&hwif->drives[0]); | 697 | SELECT_DRIVE(&hwif->drives[0]); |
697 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); | 698 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); |
698 | mdelay(2); | 699 | mdelay(2); |
699 | rc = ide_wait_not_busy(hwif, 10000); | 700 | rc = ide_wait_not_busy(hwif, 35000); |
700 | if (rc) | 701 | if (rc) |
701 | return rc; | 702 | return rc; |
702 | SELECT_DRIVE(&hwif->drives[1]); | 703 | SELECT_DRIVE(&hwif->drives[1]); |
703 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); | 704 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); |
704 | mdelay(2); | 705 | mdelay(2); |
705 | rc = ide_wait_not_busy(hwif, 10000); | 706 | rc = ide_wait_not_busy(hwif, 35000); |
706 | 707 | ||
707 | /* Exit function with master reselected (let's be sane) */ | 708 | /* Exit function with master reselected (let's be sane) */ |
708 | SELECT_DRIVE(&hwif->drives[0]); | 709 | SELECT_DRIVE(&hwif->drives[0]); |
@@ -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; |