Commit 4015c949 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] update ide core

- New style ide-default driver
- Don't attach non existant drives
- DRIVER()==NULL checks can go
- Ioctl checks that were missing are now in
parent 54f8af28
/* /*
* linux/drivers/ide/ide.c Version 7.00alpha1 August 19 2002 * linux/drivers/ide/ide.c Version 7.00beta2 Mar 05 2003
* *
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below) * Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/ */
...@@ -177,6 +177,7 @@ static int idebus_parameter; /* holds the "idebus=" parameter */ ...@@ -177,6 +177,7 @@ static int idebus_parameter; /* holds the "idebus=" parameter */
static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
static int initializing; /* set while initializing built-in drivers */ static int initializing; /* set while initializing built-in drivers */
DECLARE_MUTEX(ide_cfg_sem);
spinlock_t ide_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; spinlock_t ide_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
...@@ -214,6 +215,8 @@ EXPORT_SYMBOL(idefloppy); ...@@ -214,6 +215,8 @@ EXPORT_SYMBOL(idefloppy);
EXPORT_SYMBOL(idetape); EXPORT_SYMBOL(idetape);
EXPORT_SYMBOL(idescsi); EXPORT_SYMBOL(idescsi);
extern ide_driver_t idedefault_driver;
static void setup_driver_defaults (ide_drive_t *drive);
/* /*
* Do not even *think* about calling this! * Do not even *think* about calling this!
...@@ -271,6 +274,8 @@ static void init_hwif_data (unsigned int index) ...@@ -271,6 +274,8 @@ static void init_hwif_data (unsigned int index)
drive->max_failures = IDE_DEFAULT_MAX_FAILURES; drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
drive->using_dma = 0; drive->using_dma = 0;
drive->is_flash = 0; drive->is_flash = 0;
drive->driver = &idedefault_driver;
setup_driver_defaults(drive);
drive->vdma = 0; drive->vdma = 0;
INIT_LIST_HEAD(&drive->list); INIT_LIST_HEAD(&drive->list);
} }
...@@ -349,9 +354,7 @@ unsigned long current_capacity (ide_drive_t *drive) ...@@ -349,9 +354,7 @@ unsigned long current_capacity (ide_drive_t *drive)
{ {
if (!drive->present) if (!drive->present)
return 0; return 0;
if (drive->driver != NULL) return DRIVER(drive)->capacity(drive);
return DRIVER(drive)->capacity(drive);
return 0;
} }
EXPORT_SYMBOL(current_capacity); EXPORT_SYMBOL(current_capacity);
...@@ -580,17 +583,19 @@ extern void init_hwif_data(unsigned int index); ...@@ -580,17 +583,19 @@ extern void init_hwif_data(unsigned int index);
void ide_unregister (unsigned int index) void ide_unregister (unsigned int index)
{ {
ide_drive_t *drive, *d; ide_drive_t *drive;
ide_hwif_t *hwif, *g; ide_hwif_t *hwif, *g;
ide_hwgroup_t *hwgroup; ide_hwgroup_t *hwgroup;
int irq_count = 0, unit, i; int irq_count = 0, unit, i;
unsigned long flags;
ide_hwif_t old_hwif; ide_hwif_t old_hwif;
if (index >= MAX_HWIFS) if (index >= MAX_HWIFS)
BUG(); BUG();
spin_lock_irqsave(&ide_lock, flags); BUG_ON(in_interrupt());
BUG_ON(irqs_disabled());
down(&ide_cfg_sem);
spin_lock_irq(&ide_lock);
hwif = &ide_hwifs[index]; hwif = &ide_hwifs[index];
if (!hwif->present) if (!hwif->present)
goto abort; goto abort;
...@@ -600,25 +605,23 @@ void ide_unregister (unsigned int index) ...@@ -600,25 +605,23 @@ void ide_unregister (unsigned int index)
continue; continue;
if (drive->usage) if (drive->usage)
goto abort; goto abort;
if (drive->driver != NULL && DRIVER(drive)->shutdown(drive)) if (DRIVER(drive)->shutdown(drive))
goto abort; goto abort;
} }
hwif->present = 0; hwif->present = 0;
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irq(&ide_lock);
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
drive = &hwif->drives[unit]; drive = &hwif->drives[unit];
if (!drive->present) if (!drive->present)
continue; continue;
if (drive->driver != NULL) DRIVER(drive)->cleanup(drive);
DRIVER(drive)->cleanup(drive);
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
destroy_proc_ide_drives(hwif); destroy_proc_ide_drives(hwif);
#endif #endif
spin_lock_irqsave(&ide_lock, flags);
hwgroup = hwif->hwgroup; hwgroup = hwif->hwgroup;
/* /*
...@@ -633,6 +636,7 @@ void ide_unregister (unsigned int index) ...@@ -633,6 +636,7 @@ void ide_unregister (unsigned int index)
if (irq_count == 1) if (irq_count == 1)
free_irq(hwif->irq, hwgroup); free_irq(hwif->irq, hwgroup);
spin_lock_irq(&ide_lock);
/* /*
* Note that we only release the standard ports, * Note that we only release the standard ports,
* and do not even try to handle any extra ports * and do not even try to handle any extra ports
...@@ -644,7 +648,6 @@ void ide_unregister (unsigned int index) ...@@ -644,7 +648,6 @@ void ide_unregister (unsigned int index)
* Remove us from the hwgroup, and free * Remove us from the hwgroup, and free
* the hwgroup if we were the only member * the hwgroup if we were the only member
*/ */
d = hwgroup->drive;
for (i = 0; i < MAX_DRIVES; ++i) { for (i = 0; i < MAX_DRIVES; ++i) {
drive = &hwif->drives[i]; drive = &hwif->drives[i];
if (drive->de) { if (drive->de) {
...@@ -653,11 +656,23 @@ void ide_unregister (unsigned int index) ...@@ -653,11 +656,23 @@ void ide_unregister (unsigned int index)
} }
if (!drive->present) if (!drive->present)
continue; continue;
while (hwgroup->drive->next != drive) if (drive == drive->next) {
hwgroup->drive = hwgroup->drive->next; /* special case: last drive from hwgroup. */
hwgroup->drive->next = drive->next; BUG_ON(hwgroup->drive != drive);
if (hwgroup->drive == drive)
hwgroup->drive = NULL; hwgroup->drive = NULL;
} else {
ide_drive_t *walk;
walk = hwgroup->drive;
while (walk->next != drive)
walk = walk->next;
walk->next = drive->next;
if (hwgroup->drive == drive) {
hwgroup->drive = drive->next;
hwgroup->hwif = HWIF(hwgroup->drive);
}
}
BUG_ON(hwgroup->drive == drive);
if (drive->id != NULL) { if (drive->id != NULL) {
kfree(drive->id); kfree(drive->id);
drive->id = NULL; drive->id = NULL;
...@@ -665,15 +680,28 @@ void ide_unregister (unsigned int index) ...@@ -665,15 +680,28 @@ void ide_unregister (unsigned int index)
drive->present = 0; drive->present = 0;
blk_cleanup_queue(&drive->queue); blk_cleanup_queue(&drive->queue);
} }
if (d->present) if (hwif->next == hwif) {
hwgroup->drive = d;
while (hwgroup->hwif->next != hwif)
hwgroup->hwif = hwgroup->hwif->next;
hwgroup->hwif->next = hwif->next;
if (hwgroup->hwif == hwif)
kfree(hwgroup); kfree(hwgroup);
else BUG_ON(hwgroup->hwif != hwif);
hwgroup->hwif = HWIF(hwgroup->drive); } else {
/* There is another interface in hwgroup.
* Unlink us, and set hwgroup->drive and ->hwif to
* something sane.
*/
g = hwgroup->hwif;
while (g->next != hwif)
g = g->next;
g->next = hwif->next;
if (hwgroup->hwif == hwif) {
/* Chose a random hwif for hwgroup->hwif.
* It's guaranteed that there are no drives
* left in the hwgroup.
*/
BUG_ON(hwgroup->drive != NULL);
hwgroup->hwif = g;
}
BUG_ON(hwgroup->hwif == hwif);
}
#if !defined(CONFIG_DMA_NONPCI) #if !defined(CONFIG_DMA_NONPCI)
if (hwif->dma_base) { if (hwif->dma_base) {
...@@ -813,7 +841,8 @@ void ide_unregister (unsigned int index) ...@@ -813,7 +841,8 @@ void ide_unregister (unsigned int index)
hwif->hwif_data = old_hwif.hwif_data; hwif->hwif_data = old_hwif.hwif_data;
abort: abort:
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irq(&ide_lock);
up(&ide_cfg_sem);
} }
EXPORT_SYMBOL(ide_unregister); EXPORT_SYMBOL(ide_unregister);
...@@ -998,7 +1027,7 @@ int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioct ...@@ -998,7 +1027,7 @@ int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioct
setting->set = set; setting->set = set;
setting->next = *p; setting->next = *p;
if (drive->driver) if (drive->driver != &idedefault_driver)
setting->auto_remove = 1; setting->auto_remove = 1;
*p = setting; *p = setting;
up(&ide_setting_sem); up(&ide_setting_sem);
...@@ -1305,15 +1334,9 @@ int ide_atapi_to_scsi (ide_drive_t *drive, int arg) ...@@ -1305,15 +1334,9 @@ int ide_atapi_to_scsi (ide_drive_t *drive, int arg)
return 0; return 0;
} }
if (drive->driver != NULL) { if (DRIVER(drive)->cleanup(drive)) {
#if 0 drive->scsi = 0;
ide_unregister_subdriver(drive); return 0;
#else
if (DRIVER(drive)->cleanup(drive)) {
drive->scsi = 0;
return 0;
}
#endif
} }
drive->scsi = (u8) arg; drive->scsi = (u8) arg;
...@@ -1354,7 +1377,7 @@ void ide_delay_50ms (void) ...@@ -1354,7 +1377,7 @@ void ide_delay_50ms (void)
mdelay(50); mdelay(50);
#else #else
__set_current_state(TASK_UNINTERRUPTIBLE); __set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/20); schedule_timeout(1+HZ/20);
#endif /* CONFIG_BLK_DEV_IDECS */ #endif /* CONFIG_BLK_DEV_IDECS */
} }
...@@ -1376,7 +1399,7 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver) ...@@ -1376,7 +1399,7 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver)
{ {
if (!drive->present || drive->usage || drive->dead) if (!drive->present || drive->usage || drive->dead)
goto abort; goto abort;
if (drive->driver != NULL && DRIVER(drive)->cleanup(drive)) if (DRIVER(drive)->cleanup(drive))
goto abort; goto abort;
strncpy(drive->driver_req, driver, 9); strncpy(drive->driver_req, driver, 9);
if (ata_attach(drive)) { if (ata_attach(drive)) {
...@@ -1388,7 +1411,7 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver) ...@@ -1388,7 +1411,7 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver)
} else { } else {
drive->driver_req[0] = 0; drive->driver_req[0] = 0;
} }
if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver)) if (DRIVER(drive)!= &idedefault_driver && !strcmp(DRIVER(drive)->name, driver))
return 0; return 0;
abort: abort:
return 1; return 1;
...@@ -1413,10 +1436,12 @@ int ata_attach(ide_drive_t *drive) ...@@ -1413,10 +1436,12 @@ int ata_attach(ide_drive_t *drive)
spin_lock(&drivers_lock); spin_lock(&drivers_lock);
module_put(driver->owner); module_put(driver->owner);
} }
drive->gendev.driver = &idedefault_driver.gen_driver;
spin_unlock(&drivers_lock); spin_unlock(&drivers_lock);
if(idedefault_driver.attach(drive) != 0)
panic("ide: default attach failed");
spin_lock(&drives_lock); spin_lock(&drives_lock);
list_add_tail(&drive->list, &ata_unused); list_add_tail(&drive->list, &ata_unused);
drive->gendev.driver = NULL;
spin_unlock(&drives_lock); spin_unlock(&drives_lock);
return 1; return 1;
} }
...@@ -1477,7 +1502,7 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd, ...@@ -1477,7 +1502,7 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
case HDIO_GET_IDENTITY: case HDIO_GET_IDENTITY:
if (bdev != bdev->bd_contains) if (bdev != bdev->bd_contains)
return -EINVAL; return -EINVAL;
if (drive->id == NULL) if (drive->id_read == 0)
return -ENOMSG; return -ENOMSG;
if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142)) if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))
return -EFAULT; return -EFAULT;
...@@ -1522,7 +1547,7 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd, ...@@ -1522,7 +1547,7 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
case HDIO_SCAN_HWIF: case HDIO_SCAN_HWIF:
{ {
int args[3]; int args[3];
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_RAWIO)) return -EACCES;
if (copy_from_user(args, (void *)arg, 3 * sizeof(int))) if (copy_from_user(args, (void *)arg, 3 * sizeof(int)))
return -EFAULT; return -EFAULT;
if (ide_register(args[0], args[1], args[2]) == -1) if (ide_register(args[0], args[1], args[2]) == -1)
...@@ -1530,14 +1555,12 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd, ...@@ -1530,14 +1555,12 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
return 0; return 0;
} }
case HDIO_UNREGISTER_HWIF: case HDIO_UNREGISTER_HWIF:
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_RAWIO)) return -EACCES;
/* (arg > MAX_HWIFS) checked in function */ /* (arg > MAX_HWIFS) checked in function */
ide_unregister(arg); ide_unregister(arg);
return 0; return 0;
case HDIO_SET_NICE: case HDIO_SET_NICE:
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (drive->driver == NULL)
return -EPERM;
if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
return -EPERM; return -EPERM;
drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;
...@@ -1551,18 +1574,26 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd, ...@@ -1551,18 +1574,26 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
{ {
unsigned long flags; unsigned long flags;
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_ADMIN)) return -EACCES;
#if 1
/*
* Abort the current command on the
* group if there is one, taking
* care not to allow anything else
* to be queued and to die on the
* spot if we miss one somehow
*/
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if ( HWGROUP(drive)->handler != NULL) {
printk(KERN_ERR "%s: ide_set_handler: handler not null; %p\n", drive->name, HWGROUP(drive)->handler); DRIVER(drive)->abort(drive, "drive reset");
(void) HWGROUP(drive)->handler(drive); if(HWGROUP(drive)->handler)
// HWGROUP(drive)->handler = NULL; BUG();
HWGROUP(drive)->expiry = NULL;
del_timer(&HWGROUP(drive)->timer); /* Ensure nothing gets queued after we
} drop the lock. Reset will clear the busy */
HWGROUP(drive)->busy = 1;
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
#endif
(void) ide_do_reset(drive); (void) ide_do_reset(drive);
if (drive->suspend_reset) { if (drive->suspend_reset) {
/* /*
...@@ -1594,9 +1625,8 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd, ...@@ -1594,9 +1625,8 @@ int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EACCES; return -EACCES;
if (HWIF(drive)->busproc) if (HWIF(drive)->busproc)
HWIF(drive)->busproc(drive, (int)arg); return HWIF(drive)->busproc(drive, (int)arg);
return 0; return -EOPNOTSUPP;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -2194,7 +2224,7 @@ static int default_cleanup (ide_drive_t *drive) ...@@ -2194,7 +2224,7 @@ static int default_cleanup (ide_drive_t *drive)
static int default_shutdown(ide_drive_t *drive) static int default_shutdown(ide_drive_t *drive)
{ {
if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) { if (drive->usage || DRIVER(drive)->busy) {
return 1; return 1;
} }
drive->dead = 1; drive->dead = 1;
...@@ -2262,6 +2292,11 @@ static int default_attach (ide_drive_t *drive) ...@@ -2262,6 +2292,11 @@ static int default_attach (ide_drive_t *drive)
return 0; return 0;
} }
static ide_startstop_t default_abort (ide_drive_t *drive, const char *msg)
{
return ide_abort(drive, msg);
}
static void setup_driver_defaults (ide_drive_t *drive) static void setup_driver_defaults (ide_drive_t *drive)
{ {
ide_driver_t *d = drive->driver; ide_driver_t *d = drive->driver;
...@@ -2273,6 +2308,7 @@ static void setup_driver_defaults (ide_drive_t *drive) ...@@ -2273,6 +2308,7 @@ static void setup_driver_defaults (ide_drive_t *drive)
if (d->end_request == NULL) d->end_request = default_end_request; if (d->end_request == NULL) d->end_request = default_end_request;
if (d->sense == NULL) d->sense = default_sense; if (d->sense == NULL) d->sense = default_sense;
if (d->error == NULL) d->error = default_error; if (d->error == NULL) d->error = default_error;
if (d->abort == NULL) d->abort = default_abort;
if (d->pre_reset == NULL) d->pre_reset = default_pre_reset; if (d->pre_reset == NULL) d->pre_reset = default_pre_reset;
if (d->capacity == NULL) d->capacity = default_capacity; if (d->capacity == NULL) d->capacity = default_capacity;
if (d->special == NULL) d->special = default_special; if (d->special == NULL) d->special = default_special;
...@@ -2283,9 +2319,11 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio ...@@ -2283,9 +2319,11 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
{ {
unsigned long flags; unsigned long flags;
BUG_ON(drive->driver == NULL);
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if (version != IDE_SUBDRIVER_VERSION || !drive->present || if (version != IDE_SUBDRIVER_VERSION || !drive->present ||
drive->driver != NULL || drive->usage || drive->dead) { drive->driver != &idedefault_driver || drive->usage || drive->dead) {
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
return 1; return 1;
} }
...@@ -2295,6 +2333,7 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio ...@@ -2295,6 +2333,7 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
spin_lock(&drives_lock); spin_lock(&drives_lock);
list_add(&drive->list, &driver->drives); list_add(&drive->list, &driver->drives);
spin_unlock(&drives_lock); spin_unlock(&drives_lock);
// printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name);
if ((drive->autotune == IDE_TUNE_DEFAULT) || if ((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO)) { (drive->autotune == IDE_TUNE_AUTO)) {
/* DMA timings and setup moved to ide-probe.c */ /* DMA timings and setup moved to ide-probe.c */
...@@ -2319,7 +2358,7 @@ int ide_unregister_subdriver (ide_drive_t *drive) ...@@ -2319,7 +2358,7 @@ int ide_unregister_subdriver (ide_drive_t *drive)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ide_lock, flags); spin_lock_irqsave(&ide_lock, flags);
if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) { if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) {
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
return 1; return 1;
} }
...@@ -2331,10 +2370,12 @@ int ide_unregister_subdriver (ide_drive_t *drive) ...@@ -2331,10 +2370,12 @@ int ide_unregister_subdriver (ide_drive_t *drive)
ide_remove_proc_entries(drive->proc, generic_subdriver_entries); ide_remove_proc_entries(drive->proc, generic_subdriver_entries);
#endif #endif
auto_remove_settings(drive); auto_remove_settings(drive);
drive->driver = NULL; drive->driver = &idedefault_driver;
setup_driver_defaults(drive);
spin_unlock_irqrestore(&ide_lock, flags); spin_unlock_irqrestore(&ide_lock, flags);
spin_lock(&drives_lock); spin_lock(&drives_lock);
list_del_init(&drive->list); list_del_init(&drive->list);
list_add(&drive->list, &drive->driver->drives);
spin_unlock(&drives_lock); spin_unlock(&drives_lock);
return 0; return 0;
} }
...@@ -2344,10 +2385,7 @@ EXPORT_SYMBOL(ide_unregister_subdriver); ...@@ -2344,10 +2385,7 @@ EXPORT_SYMBOL(ide_unregister_subdriver);
static int ide_drive_remove(struct device * dev) static int ide_drive_remove(struct device * dev)
{ {
ide_drive_t * drive = container_of(dev,ide_drive_t,gendev); ide_drive_t * drive = container_of(dev,ide_drive_t,gendev);
ide_driver_t * driver = drive->driver; DRIVER(drive)->cleanup(drive);
if (driver && driver->cleanup)
driver->cleanup(drive);
return 0; return 0;
} }
...@@ -2367,7 +2405,8 @@ int ide_register_driver(ide_driver_t *driver) ...@@ -2367,7 +2405,8 @@ int ide_register_driver(ide_driver_t *driver)
while (!list_empty(&list)) { while (!list_empty(&list)) {
ide_drive_t *drive = list_entry(list.next, ide_drive_t, list); ide_drive_t *drive = list_entry(list.next, ide_drive_t, list);
list_del_init(&drive->list); list_del_init(&drive->list);
ata_attach(drive); if (drive->present)
ata_attach(drive);
} }
driver->gen_driver.name = (char *) driver->name; driver->gen_driver.name = (char *) driver->name;
driver->gen_driver.bus = &ide_bus_type; driver->gen_driver.bus = &ide_bus_type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment