ide: remove write-only ide_hwif_t.no_dsc flag
[powerpc.git] / drivers / ide / ide.c
index 2b1a138..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:
  */
@@ -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,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));
@@ -1231,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));
@@ -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