ide: remove write-only ide_hwif_t.no_dsc flag
[powerpc.git] / drivers / ide / ide.c
index 287a662..15b1383 100644 (file)
@@ -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:
  */
@@ -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;
@@ -545,7 +552,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        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;
 }
@@ -973,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)
@@ -1214,10 +1220,15 @@ 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));
@@ -1235,10 +1246,17 @@ 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));
@@ -1543,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="
         */
@@ -1781,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
@@ -1874,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);
@@ -2076,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