aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r--drivers/ide/ide-probe.c51
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
1280EXPORT_SYMBOL_GPL(ide_init_disk); 1281EXPORT_SYMBOL_GPL(ide_init_disk);
1281 1282
1283static 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
1282static void drive_release_dev (struct device *dev) 1306static 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;