]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-probe.c
Driver core: convert block from raw kobjects to core devices
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-probe.c
index 3c945d64d8458c01dbdc6e2e35a7cc69a9203494..0cb3d2bb3ab924c8a87c5322ca7dafc3e89f3a08 100644 (file)
  *
  * This is the IDE probe module, as evolved from hd.c and ide.c.
  *
- * Version 1.00                move drive probing code from ide.c to ide-probe.c
- * Version 1.01                fix compilation problem for m68k
- * Version 1.02                increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot
- *                      by Andrea Arcangeli
- * Version 1.03                fix for (hwif->chipset == ide_4drives)
- * Version 1.04                fixed buggy treatments of known flash memory cards
- *
- * Version 1.05                fix for (hwif->chipset == ide_pdc4030)
- *                     added ide6/7/8/9
- *                     allowed for secondary flash card to be detectable
- *                      with new flag : drive->ata_flash : 1;
- * Version 1.06                stream line request queue and prep for cascade project.
- * Version 1.07                max_sect <= 255; slower disks would get behind and
- *                     then fall over when they get to 256.    Paul G.
- * Version 1.10                Update set for new IDE. drive->id is now always
- *                     valid after probe time even with noprobe
+ * -- increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot
+ *      by Andrea Arcangeli
  */
 
 #include <linux/module.h>
@@ -47,6 +33,7 @@
 #include <linux/spinlock.h>
 #include <linux/kmod.h>
 #include <linux/pci.h>
+#include <linux/scatterlist.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -171,11 +158,12 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
        ide_fixstring(id->fw_rev,    sizeof(id->fw_rev),    bswap);
        ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);
 
+       /* we depend on this a lot! */
+       id->model[sizeof(id->model)-1] = '\0';
+
        if (strstr(id->model, "E X A B Y T E N E S T"))
                goto err_misc;
 
-       /* we depend on this a lot! */
-       id->model[sizeof(id->model)-1] = '\0';
        printk("%s: %s, ", drive->name, id->model);
        drive->present = 1;
        drive->dead = 0;
@@ -642,7 +630,7 @@ static void hwif_register (ide_hwif_t *hwif)
 
 static int wait_hwif_ready(ide_hwif_t *hwif)
 {
-       int rc;
+       int unit, rc;
 
        printk(KERN_DEBUG "Probing IDE interface %s...\n", hwif->name);
 
@@ -659,20 +647,27 @@ static int wait_hwif_ready(ide_hwif_t *hwif)
                return rc;
 
        /* Now make sure both master & slave are ready */
-       SELECT_DRIVE(&hwif->drives[0]);
-       hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
-       mdelay(2);
-       rc = ide_wait_not_busy(hwif, 35000);
-       if (rc)
-               return rc;
-       SELECT_DRIVE(&hwif->drives[1]);
-       hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
-       mdelay(2);
-       rc = ide_wait_not_busy(hwif, 35000);
+       for (unit = 0; unit < MAX_DRIVES; unit++) {
+               ide_drive_t *drive = &hwif->drives[unit];
 
+               /* Ignore disks that we will not probe for later. */
+               if (!drive->noprobe || drive->present) {
+                       SELECT_DRIVE(drive);
+                       if (IDE_CONTROL_REG)
+                               hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
+                       mdelay(2);
+                       rc = ide_wait_not_busy(hwif, 35000);
+                       if (rc)
+                               goto out;
+               } else
+                       printk(KERN_DEBUG "%s: ide_wait_not_busy() skipped\n",
+                                         drive->name);
+       }
+out:
        /* Exit function with master reselected (let's be sane) */
-       SELECT_DRIVE(&hwif->drives[0]);
-       
+       if (unit)
+               SELECT_DRIVE(&hwif->drives[0]);
+
        return rc;
 }
 
@@ -717,7 +712,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
  * This routine only knows how to look for drive units 0 and 1
  * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static void probe_hwif(ide_hwif_t *hwif)
 {
        unsigned long flags;
        unsigned int irqd;
@@ -819,8 +814,8 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
                return;
        }
 
-       if (fixup)
-               fixup(hwif);
+       if (hwif->fixup)
+               hwif->fixup(hwif);
 
        for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
@@ -859,10 +854,11 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
 }
 
 static int hwif_init(ide_hwif_t *hwif);
+static void hwif_register_devices(ide_hwif_t *hwif);
 
-int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static int probe_hwif_init(ide_hwif_t *hwif)
 {
-       probe_hwif(hwif, fixup);
+       probe_hwif(hwif);
 
        if (!hwif_init(hwif)) {
                printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -870,34 +866,12 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)
                return -1;
        }
 
-       if (hwif->present) {
-               u16 unit = 0;
-               int ret;
+       if (hwif->present)
+               hwif_register_devices(hwif);
 
-               for (unit = 0; unit < MAX_DRIVES; ++unit) {
-                       ide_drive_t *drive = &hwif->drives[unit];
-                       /* For now don't attach absent drives, we may
-                          want them on default or a new "empty" class
-                          for hotplug reprobing ? */
-                       if (drive->present) {
-                               ret = device_register(&drive->gendev);
-                               if (ret < 0)
-                                       printk(KERN_WARNING "IDE: %s: "
-                                               "device_register error: %d\n",
-                                               __FUNCTION__, ret);
-                       }
-               }
-       }
        return 0;
 }
 
-int probe_hwif_init(ide_hwif_t *hwif)
-{
-       return probe_hwif_init_with_fixup(hwif, NULL);
-}
-
-EXPORT_SYMBOL(probe_hwif_init);
-
 #if MAX_HWIFS > 1
 /*
  * save_match() is used to simplify logic in init_irq() below.
@@ -951,7 +925,8 @@ static int ide_init_queue(ide_drive_t *drive)
        blk_queue_segment_boundary(q, 0xffff);
 
        if (!hwif->rqsize) {
-               if (hwif->no_lba48 || hwif->no_lba48_dma)
+               if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+                   (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
                        hwif->rqsize = 256;
                else
                        hwif->rqsize = 65536;
@@ -1198,7 +1173,7 @@ static struct kobject *exact_match(dev_t dev, int *part, void *data)
 {
        struct gendisk *p = data;
        *part &= (1 << PARTN_BITS) - 1;
-       return &p->kobj;
+       return &p->dev.kobj;
 }
 
 static int exact_lock(dev_t dev, void *data)
@@ -1337,12 +1312,14 @@ static int hwif_init(ide_hwif_t *hwif)
        if (!hwif->sg_max_nents)
                hwif->sg_max_nents = PRD_ENTRIES;
 
-       hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+       hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
                                 GFP_KERNEL);
        if (!hwif->sg_table) {
                printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
                goto out;
        }
+
+       sg_init_table(hwif->sg_table, hwif->sg_max_nents);
        
        if (init_irq(hwif) == 0)
                goto done;
@@ -1378,6 +1355,24 @@ out:
        return 0;
 }
 
+static void hwif_register_devices(ide_hwif_t *hwif)
+{
+       unsigned int i;
+
+       for (i = 0; i < MAX_DRIVES; i++) {
+               ide_drive_t *drive = &hwif->drives[i];
+
+               if (drive->present) {
+                       int ret = device_register(&drive->gendev);
+
+                       if (ret < 0)
+                               printk(KERN_WARNING "IDE: %s: "
+                                       "device_register error: %d\n",
+                                       __FUNCTION__, ret);
+               }
+       }
+}
+
 int ideprobe_init (void)
 {
        unsigned int index;
@@ -1389,27 +1384,18 @@ int ideprobe_init (void)
 
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
-                       probe_hwif(&ide_hwifs[index], NULL);
+                       probe_hwif(&ide_hwifs[index]);
        for (index = 0; index < MAX_HWIFS; ++index)
                if (probe[index])
                        hwif_init(&ide_hwifs[index]);
        for (index = 0; index < MAX_HWIFS; ++index) {
                if (probe[index]) {
                        ide_hwif_t *hwif = &ide_hwifs[index];
-                       int unit;
                        if (!hwif->present)
                                continue;
                        if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
                                hwif->chipset = ide_generic;
-                       for (unit = 0; unit < MAX_DRIVES; ++unit)
-                               if (hwif->drives[unit].present) {
-                                       int ret = device_register(
-                                               &hwif->drives[unit].gendev);
-                                       if (ret < 0)
-                                               printk(KERN_WARNING "IDE: %s: "
-                                                       "device_register error: %d\n",
-                                                       __FUNCTION__, ret);
-                               }
+                       hwif_register_devices(hwif);
                }
        }
        for (index = 0; index < MAX_HWIFS; ++index)
@@ -1419,3 +1405,22 @@ int ideprobe_init (void)
 }
 
 EXPORT_SYMBOL_GPL(ideprobe_init);
+
+int ide_device_add(u8 idx[4])
+{
+       int i, rc = 0;
+
+       for (i = 0; i < 4; i++) {
+               if (idx[i] != 0xff)
+                       rc |= probe_hwif_init(&ide_hwifs[idx[i]]);
+       }
+
+       for (i = 0; i < 4; i++) {
+               if (idx[i] != 0xff)
+                       ide_proc_register_port(&ide_hwifs[idx[i]]);
+       }
+
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(ide_device_add);