X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Fide%2Fide.c;h=2b1a1389c31880b16d492f8145ddfe5ac96acd90;hb=c1607e1af238b823a2158a18ff6c89144ce38c6c;hp=9c8468de1a7521aa62c179cd6bf952fa461a2a4c;hpb=ebdea46fecae40c4d7effcd33f40918a37a1df4b;p=powerpc.git diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 9c8468de1a..15b13831ee 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -187,6 +187,12 @@ int noautodma = 1; EXPORT_SYMBOL(noautodma); +#ifdef CONFIG_BLK_DEV_IDEACPI +int ide_noacpi = 0; +int ide_noacpitfs = 1; +int ide_noacpionboot = 1; +#endif + /* * This is declared extern in ide.h, for access by other IDE modules: */ @@ -450,7 +456,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. */ @@ -503,6 +509,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->ide_dma_on = tmp_hwif->ide_dma_on; hwif->ide_dma_off_quietly = tmp_hwif->ide_dma_off_quietly; hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; + hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on; hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off; hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq; @@ -539,18 +546,18 @@ 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; hwif->hwif_data = tmp_hwif->hwif_data; } /** - * 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 +570,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 +681,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 +979,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) @@ -1210,16 +1220,21 @@ EXPORT_SYMBOL(system_bus_clock); static int generic_ide_suspend(struct device *dev, pm_message_t mesg) { ide_drive_t *drive = dev->driver_data; + ide_hwif_t *hwif = HWIF(drive); struct request rq; struct request_pm_state rqpm; ide_task_t args; + /* Call ACPI _GTM only once */ + if (!(drive->dn % 2)) + ide_acpi_get_timing(hwif); + 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; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; @@ -1231,16 +1246,23 @@ static int generic_ide_suspend(struct device *dev, pm_message_t mesg) static int generic_ide_resume(struct device *dev) { ide_drive_t *drive = dev->driver_data; + ide_hwif_t *hwif = HWIF(drive); struct request rq; struct request_pm_state rqpm; ide_task_t args; + /* Call ACPI _STM only once */ + if (!(drive->dn % 2)) + ide_acpi_push_timing(hwif); + + ide_acpi_exec_tfs(drive); + 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; @@ -1360,6 +1382,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); @@ -1534,6 +1561,24 @@ static int __init ide_setup(char *s) } #endif /* CONFIG_BLK_DEV_IDEPCI */ +#ifdef CONFIG_BLK_DEV_IDEACPI + if (!strcmp(s, "ide=noacpi")) { + //printk(" : Disable IDE ACPI support.\n"); + ide_noacpi = 1; + return 1; + } + if (!strcmp(s, "ide=acpigtf")) { + //printk(" : Enable IDE ACPI _GTF support.\n"); + ide_noacpitfs = 0; + return 1; + } + if (!strcmp(s, "ide=acpionboot")) { + //printk(" : Call IDE ACPI methods on boot.\n"); + ide_noacpionboot = 0; + return 1; + } +#endif /* CONFIG_BLK_DEV_IDEACPI */ + /* * Look for drive options: "hdx=" */ @@ -1772,8 +1817,9 @@ done: return 1; } -extern void pnpide_init(void); -extern void h8300_ide_init(void); +extern void __init pnpide_init(void); +extern void __exit pnpide_exit(void); +extern void __init h8300_ide_init(void); /* * probe_for_hwifs() finds/initializes "known" IDE interfaces @@ -1865,11 +1911,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); @@ -1993,10 +2050,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(); @@ -2061,13 +2124,17 @@ int __init init_module (void) return ide_init(); } -void cleanup_module (void) +void __exit cleanup_module (void) { int index; for (index = 0; index < MAX_HWIFS; ++index) ide_unregister(index); +#ifdef CONFIG_BLK_DEV_IDEPNP + pnpide_exit(); +#endif + #ifdef CONFIG_PROC_FS proc_ide_destroy(); #endif