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; |
