]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/ide/ide.c
ide: move ide_arm_init() call from init_ide_data() to ide_init()
[mirror_ubuntu-bionic-kernel.git] / drivers / ide / ide.c
index 5c0e4078b5cbf7dbbb398998fff7b08a3310b2c0..77af743425e813cd695dd17f92a209ee5bc5c162 100644 (file)
@@ -100,8 +100,6 @@ static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
 
 int noautodma = 0;
 
-EXPORT_SYMBOL(noautodma);
-
 #ifdef CONFIG_BLK_DEV_IDEACPI
 int ide_noacpi = 0;
 int ide_noacpitfs = 1;
@@ -118,7 +116,7 @@ EXPORT_SYMBOL(ide_hwifs);
 /*
  * Do not even *think* about calling this!
  */
-static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
+void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
 {
        unsigned int unit;
 
@@ -136,8 +134,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
 
        hwif->bus_state = BUSSTATE_ON;
 
-       hwif->atapi_dma = 0;            /* disable all atapi dma */ 
-
        init_completion(&hwif->gendev_rel_comp);
 
        default_hwif_iops(hwif);
@@ -163,6 +159,7 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index)
                init_completion(&drive->gendev_rel_comp);
        }
 }
+EXPORT_SYMBOL_GPL(ide_init_port_data);
 
 static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
 {
@@ -172,7 +169,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
 
        ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
 
-       memcpy(&hwif->hw, &hw, sizeof(hw));
        memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
 
        hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
@@ -215,16 +211,13 @@ static void __init init_ide_data (void)
        /* Initialise all interface structures */
        for (index = 0; index < MAX_HWIFS; ++index) {
                hwif = &ide_hwifs[index];
-               init_hwif_data(hwif, index);
+               ide_init_port_data(hwif, index);
                init_hwif_default(hwif, index);
 #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
-               hwif->irq = hwif->hw.irq =
+               hwif->irq =
                        ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
 #endif
        }
-#ifdef CONFIG_IDE_ARM
-       ide_arm_init();
-#endif
 }
 
 /**
@@ -269,6 +262,30 @@ static int ide_system_bus_speed(void)
        return system_bus_speed;
 }
 
+ide_hwif_t * ide_find_port(unsigned long base)
+{
+       ide_hwif_t *hwif;
+       int i;
+
+       for (i = 0; i < MAX_HWIFS; i++) {
+               hwif = &ide_hwifs[i];
+               if (hwif->io_ports[IDE_DATA_OFFSET] == base)
+                       goto found;
+       }
+
+       for (i = 0; i < MAX_HWIFS; i++) {
+               hwif = &ide_hwifs[i];
+               if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
+                       goto found;
+       }
+
+       hwif = NULL;
+found:
+       return hwif;
+}
+
+EXPORT_SYMBOL_GPL(ide_find_port);
+
 static struct resource* hwif_request_region(ide_hwif_t *hwif,
                                            unsigned long addr, int num)
 {
@@ -381,7 +398,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 
        hwif->pio_mask                  = tmp_hwif->pio_mask;
 
-       hwif->atapi_dma                 = tmp_hwif->atapi_dma;
        hwif->ultra_mask                = tmp_hwif->ultra_mask;
        hwif->mwdma_mask                = tmp_hwif->mwdma_mask;
        hwif->swdma_mask                = tmp_hwif->swdma_mask;
@@ -404,7 +420,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->reset_poll                = tmp_hwif->reset_poll;
        hwif->pre_reset                 = tmp_hwif->pre_reset;
        hwif->resetproc                 = tmp_hwif->resetproc;
-       hwif->intrproc                  = tmp_hwif->intrproc;
        hwif->maskproc                  = tmp_hwif->maskproc;
        hwif->quirkproc                 = tmp_hwif->quirkproc;
        hwif->busproc                   = tmp_hwif->busproc;
@@ -414,17 +429,13 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->atapi_input_bytes         = tmp_hwif->atapi_input_bytes;
        hwif->atapi_output_bytes        = tmp_hwif->atapi_output_bytes;
 
+       hwif->dma_host_set              = tmp_hwif->dma_host_set;
        hwif->dma_setup                 = tmp_hwif->dma_setup;
        hwif->dma_exec_cmd              = tmp_hwif->dma_exec_cmd;
        hwif->dma_start                 = tmp_hwif->dma_start;
        hwif->ide_dma_end               = tmp_hwif->ide_dma_end;
-       hwif->ide_dma_check             = tmp_hwif->ide_dma_check;
-       hwif->ide_dma_on                = tmp_hwif->ide_dma_on;
-       hwif->dma_off_quietly           = tmp_hwif->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->dma_host_on               = tmp_hwif->dma_host_on;
-       hwif->dma_host_off              = tmp_hwif->dma_host_off;
        hwif->dma_lost_irq              = tmp_hwif->dma_lost_irq;
        hwif->dma_timeout               = tmp_hwif->dma_timeout;
 
@@ -443,14 +454,12 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
 
        hwif->mmio                      = tmp_hwif->mmio;
        hwif->rqsize                    = tmp_hwif->rqsize;
-       hwif->no_lba48                  = tmp_hwif->no_lba48;
 
 #ifndef CONFIG_BLK_DEV_IDECS
        hwif->irq                       = tmp_hwif->irq;
 #endif
 
        hwif->dma_base                  = tmp_hwif->dma_base;
-       hwif->dma_master                = tmp_hwif->dma_master;
        hwif->dma_command               = tmp_hwif->dma_command;
        hwif->dma_vendor1               = tmp_hwif->dma_vendor1;
        hwif->dma_status                = tmp_hwif->dma_status;
@@ -461,7 +470,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        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->hwif_data                 = tmp_hwif->hwif_data;
 }
@@ -585,7 +593,6 @@ void ide_unregister(unsigned int index)
                (void) ide_release_dma(hwif);
 
                hwif->dma_base = 0;
-               hwif->dma_master = 0;
                hwif->dma_command = 0;
                hwif->dma_vendor1 = 0;
                hwif->dma_status = 0;
@@ -600,7 +607,7 @@ void ide_unregister(unsigned int index)
        tmp_hwif = *hwif;
 
        /* restore hwif data to pristine status */
-       init_hwif_data(hwif, index);
+       ide_init_port_data(hwif, index);
        init_hwif_default(hwif, index);
 
        ide_hwif_restore(hwif, &tmp_hwif);
@@ -660,45 +667,52 @@ void ide_setup_ports (    hw_regs_t *hw,
                }
        }
        hw->irq = irq;
-       hw->dma = NO_DMA;
        hw->ack_intr = ack_intr;
 /*
  *     hw->iops = iops;
  */
 }
 
+void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
+{
+       memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+       hwif->irq = hw->irq;
+       hwif->noprobe = 0;
+       hwif->chipset = hw->chipset;
+       hwif->gendev.parent = hw->dev;
+       hwif->ack_intr = hw->ack_intr;
+}
+EXPORT_SYMBOL_GPL(ide_init_port_hw);
+
 /**
- *     ide_register_hw_with_fixup      -       register IDE interface
+ *     ide_register_hw         -       register IDE interface
  *     @hw: hardware registers
- *     @initializing: set while initializing built-in drivers
+ *     @quirkproc: quirkproc function
  *     @hwifp: pointer to returned hwif
- *     @fixup: fixup function
  *
  *     Register an IDE interface, specifying exactly the registers etc.
- *     Set init=1 iff calling before probes have taken place.
  *
  *     Returns -1 on error.
  */
 
-int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
-                              ide_hwif_t **hwifp,
-                              void(*fixup)(ide_hwif_t *hwif))
+int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *),
+                   ide_hwif_t **hwifp)
 {
        int index, retry = 1;
        ide_hwif_t *hwif;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
        do {
                for (index = 0; index < MAX_HWIFS; ++index) {
                        hwif = &ide_hwifs[index];
-                       if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
+                       if (hwif->io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
                                goto found;
                }
                for (index = 0; index < MAX_HWIFS; ++index) {
                        hwif = &ide_hwifs[index];
                        if (hwif->hold)
                                continue;
-                       if ((!hwif->present && !hwif->mate && !initializing) ||
-                           (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
+                       if (!hwif->present && hwif->mate == NULL)
                                goto found;
                }
                for (index = 0; index < MAX_HWIFS; index++)
@@ -709,34 +723,23 @@ found:
        if (hwif->present)
                ide_unregister(index);
        else if (!hwif->hold) {
-               init_hwif_data(hwif, index);
+               ide_init_port_data(hwif, index);
                init_hwif_default(hwif, index);
        }
        if (hwif->present)
                return -1;
-       memcpy(&hwif->hw, hw, sizeof(*hw));
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
-       hwif->irq = hw->irq;
-       hwif->noprobe = 0;
-       hwif->chipset = hw->chipset;
-       hwif->gendev.parent = hw->dev;
 
-       if (!initializing) {
-               probe_hwif_init_with_fixup(hwif, fixup);
-               ide_proc_register_port(hwif);
-       }
+       ide_init_port_hw(hwif, hw);
+       hwif->quirkproc = quirkproc;
 
-       if (hwifp)
-               *hwifp = hwif;
+       idx[0] = index;
 
-       return (initializing || hwif->present) ? index : -1;
-}
+       ide_device_add(idx);
 
-EXPORT_SYMBOL(ide_register_hw_with_fixup);
+       if (hwifp)
+               *hwifp = hwif;
 
-int ide_register_hw(hw_regs_t *hw, int initializing, ide_hwif_t **hwifp)
-{
-       return ide_register_hw_with_fixup(hw, initializing, hwifp, NULL);
+       return hwif->present ? index : -1;
 }
 
 EXPORT_SYMBOL(ide_register_hw);
@@ -790,11 +793,17 @@ int set_io_32bit(ide_drive_t *drive, int arg)
        if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
                return -EINVAL;
 
+       if (ide_spin_wait_hwgroup(drive))
+               return -EBUSY;
+
        drive->io_32bit = arg;
 #ifdef CONFIG_BLK_DEV_DTC2278
        if (HWIF(drive)->chipset == ide_dtc2278)
                HWIF(drive)->drives[!drive->select.b.unit].io_32bit = arg;
 #endif /* CONFIG_BLK_DEV_DTC2278 */
+
+       spin_unlock_irq(&ide_lock);
+
        return 0;
 }
 
@@ -823,7 +832,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
        if (!drive->id || !(drive->id->capability & 1))
                goto out;
 
-       if (hwif->ide_dma_check == NULL)
+       if (hwif->dma_host_set == NULL)
                goto out;
 
        err = -EBUSY;
@@ -838,8 +847,7 @@ int set_using_dma(ide_drive_t *drive, int arg)
        err = 0;
 
        if (arg) {
-               hwif->dma_off_quietly(drive);
-               if (ide_set_dma(drive) || hwif->ide_dma_on(drive))
+               if (ide_set_dma(drive))
                        err = -EIO;
        } else
                ide_dma_off(drive);
@@ -1054,7 +1062,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
                        ide_init_hwif_ports(&hw, (unsigned long) args[0],
                                            (unsigned long) args[1], NULL);
                        hw.irq = args[2];
-                       if (ide_register_hw(&hw, 0, NULL) == -1)
+                       if (ide_register_hw(&hw, NULL, NULL) == -1)
                                return -EIO;
                        return 0;
                }
@@ -1276,7 +1284,7 @@ static int __init ide_setup(char *s)
        if (!strcmp(s, "ide=nodma")) {
                printk(" : Prevented DMA\n");
                noautodma = 1;
-               return 1;
+               goto obsolete_option;
        }
 
 #ifdef CONFIG_IDEPCI_PCIBUS_ORDER
@@ -1310,7 +1318,7 @@ static int __init ide_setup(char *s)
         */
        if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
                const char *hd_words[] = {
-                       "none", "noprobe", "nowerr", "cdrom", "minus5",
+                       "none", "noprobe", "nowerr", "cdrom", "nodma",
                        "autotune", "noautotune", "minus8", "swapdata", "bswap",
                        "noflush", "remap", "remap63", "scsi", NULL };
                unit = s[2] - 'a';
@@ -1338,6 +1346,9 @@ static int __init ide_setup(char *s)
                                drive->ready_stat = 0;
                                hwif->noprobe = 0;
                                goto done;
+                       case -5: /* nodma */
+                               drive->nodma = 1;
+                               goto done;
                        case -6: /* "autotune" */
                                drive->autotune = IDE_TUNE_AUTO;
                                goto obsolete_option;
@@ -1399,9 +1410,12 @@ static int __init ide_setup(char *s)
                 */
                static const char *ide_words[] = {
                        "noprobe", "serialize", "minus3", "minus4",
-                       "reset", "dma", "ata66", "minus8", "minus9",
+                       "reset", "minus6", "ata66", "minus8", "minus9",
                        "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
                        "dtc2278", "umc8672", "ali14xx", NULL };
+
+               hw_regs_t hwregs;
+
                hw = s[3] - '0';
                hwif = &ide_hwifs[hw];
                i = match_parm(&s[4], ide_words, vals, 3);
@@ -1478,6 +1492,7 @@ static int __init ide_setup(char *s)
                        case -10: /* minus10 */
                        case -9: /* minus9 */
                        case -8: /* minus8 */
+                       case -6:
                        case -4:
                        case -3:
                                goto bad_option;
@@ -1492,9 +1507,6 @@ static int __init ide_setup(char *s)
 #else
                                goto bad_hwif;
 #endif
-                       case -6: /* dma */
-                               hwif->autodma = 1;
-                               goto obsolete_option;
                        case -5: /* "reset" */
                                hwif->reset = 1;
                                goto obsolete_option;
@@ -1513,9 +1525,9 @@ static int __init ide_setup(char *s)
                        case 2: /* base,ctl */
                                vals[2] = 0;    /* default irq = probe for it */
                        case 3: /* base,ctl,irq */
-                               hwif->hw.irq = vals[2];
-                               ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq);
-                               memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+                               memset(&hwregs, 0, sizeof(hwregs));
+                               ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq);
+                               memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports));
                                hwif->irq      = vals[2];
                                hwif->noprobe  = 0;
                                hwif->chipset  = ide_forced;
@@ -1656,10 +1668,34 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
        return sprintf(buf, "ide:m-%s\n", media_string(drive));
 }
 
+static ssize_t model_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", drive->id->model);
+}
+
+static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", drive->id->fw_rev);
+}
+
+static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       ide_drive_t *drive = to_ide_device(dev);
+       return sprintf(buf, "%s\n", drive->id->serial_no);
+}
+
 static struct device_attribute ide_dev_attrs[] = {
        __ATTR_RO(media),
        __ATTR_RO(drivename),
        __ATTR_RO(modalias),
+       __ATTR_RO(model),
+       __ATTR_RO(firmware),
+       __ATTR(serial, 0400, serial_show, NULL),
        __ATTR_NULL
 };
 
@@ -1735,6 +1771,9 @@ static int __init ide_init(void)
 
        proc_ide_create();
 
+#ifdef CONFIG_IDE_ARM
+       ide_arm_init();
+#endif
 #ifdef CONFIG_BLK_DEV_ALI14XX
        if (probe_ali14xx)
                (void)ali14xx_init();