X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fide%2Fide.c;h=16890769dca686dff62ec62bc0c2f741b7ef190c;hb=9b3a89f8b052f2a6193a9691e053f986144a65a0;hp=defd4b4bd37488ab38198e8ab86f963c438e2809;hpb=00dd7b7d26a3bf3780cfcebfdde2b86126b3a082;p=pandora-kernel.git diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index defd4b4bd374..16890769dca6 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -450,7 +450,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif) * @hwif: hwif to update * @tmp_hwif: template * - * Restore hwif to a previous state by copying most settngs + * Restore hwif to a previous state by copying most settings * from the template. */ @@ -539,9 +539,10 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->dma_vendor3 = tmp_hwif->dma_vendor3; hwif->dma_prdtable = tmp_hwif->dma_prdtable; - hwif->dma_extra = tmp_hwif->dma_extra; hwif->config_data = tmp_hwif->config_data; hwif->select_data = tmp_hwif->select_data; + hwif->extra_base = tmp_hwif->extra_base; + hwif->extra_ports = tmp_hwif->extra_ports; hwif->autodma = tmp_hwif->autodma; hwif->udma_four = tmp_hwif->udma_four; hwif->no_dsc = tmp_hwif->no_dsc; @@ -550,7 +551,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) } /** - * ide_unregister - free an ide interface + * ide_unregister - free an IDE interface * @index: index of interface (will change soon to a pointer) * * Perform the final unregister of an IDE interface. At the moment @@ -563,8 +564,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) * deadlocking the IDE layer. The shutdown callback is called * before we take the lock and free resources. It is up to the * caller to be sure there is no pending I/O here, and that - * the interfce will not be reopened (present/vanishing locking - * isnt yet done btw). After we commit to the final kill we + * the interface will not be reopened (present/vanishing locking + * isn't yet done BTW). After we commit to the final kill we * call the cleanup callback with the ide locks held. * * Unregister restores the hwif structures to the default state. @@ -674,6 +675,9 @@ void ide_unregister(unsigned int index) hwif->dma_status = 0; hwif->dma_vendor3 = 0; hwif->dma_prdtable = 0; + + hwif->extra_base = 0; + hwif->extra_ports = 0; } /* copy original settings */ @@ -969,8 +973,8 @@ ide_settings_t *ide_find_setting_by_name (ide_drive_t *drive, char *name) * @drive: drive * * Automatically remove all the driver specific settings for this - * drive. This function may sleep and must not be called from IRQ - * context. The caller must hold ide_setting_sem. + * drive. This function may not be called from IRQ context. The + * caller must hold ide_setting_sem. */ static void auto_remove_settings (ide_drive_t *drive) @@ -1207,7 +1211,7 @@ int system_bus_clock (void) EXPORT_SYMBOL(system_bus_clock); -static int generic_ide_suspend(struct device *dev, pm_message_t state) +static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = dev->driver_data; struct request rq; @@ -1217,11 +1221,13 @@ static int generic_ide_suspend(struct device *dev, pm_message_t state) memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); - rq.flags = REQ_PM_SUSPEND; + rq.cmd_type = REQ_TYPE_PM_SUSPEND; rq.special = &args; - rq.end_io_data = &rqpm; + rq.data = &rqpm; rqpm.pm_step = ide_pm_state_start_suspend; - rqpm.pm_state = state.event; + if (mesg.event == PM_EVENT_PRETHAW) + mesg.event = PM_EVENT_FREEZE; + rqpm.pm_state = mesg.event; return ide_do_drive_cmd(drive, &rq, ide_wait); } @@ -1236,9 +1242,9 @@ static int generic_ide_resume(struct device *dev) memset(&rq, 0, sizeof(rq)); memset(&rqpm, 0, sizeof(rqpm)); memset(&args, 0, sizeof(args)); - rq.flags = REQ_PM_RESUME; + rq.cmd_type = REQ_TYPE_PM_RESUME; rq.special = &args; - rq.end_io_data = &rqpm; + rq.data = &rqpm; rqpm.pm_step = ide_pm_state_start_resume; rqpm.pm_state = PM_EVENT_ON; @@ -1358,6 +1364,11 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device spin_lock_irqsave(&ide_lock, flags); + if (HWGROUP(drive)->resetting) { + spin_unlock_irqrestore(&ide_lock, flags); + return -EBUSY; + } + ide_abort(drive, "drive reset"); BUG_ON(HWGROUP(drive)->handler); @@ -1863,11 +1874,22 @@ void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) { unsigned long flags; - down(&ide_setting_sem); - spin_lock_irqsave(&ide_lock, flags); #ifdef CONFIG_PROC_FS ide_remove_proc_entries(drive->proc, driver->proc); #endif + down(&ide_setting_sem); + spin_lock_irqsave(&ide_lock, flags); + /* + * ide_setting_sem protects the settings list + * ide_lock protects the use of settings + * + * so we need to hold both, ide_settings_sem because we want to + * modify the settings list, and ide_lock because we cannot take + * a setting out that is being used. + * + * OTOH both ide_{read,write}_setting are only ever used under + * ide_setting_sem. + */ auto_remove_settings(drive); spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); @@ -1991,10 +2013,16 @@ EXPORT_SYMBOL_GPL(ide_bus_type); */ static int __init ide_init(void) { + int ret; + printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); system_bus_speed = ide_system_bus_speed(); - bus_register(&ide_bus_type); + ret = bus_register(&ide_bus_type); + if (ret < 0) { + printk(KERN_WARNING "IDE: bus_register error: %d\n", ret); + return ret; + } init_ide_data();