/*
- * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
* License along with this program; if not, write the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/NoticeExplan
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
+#include <linux/ioc4.h>
#include <asm/io.h>
#include <linux/ide.h>
static u8
sgiioc4_INB(unsigned long port)
{
- u8 reg = (u8) inb(port);
+ u8 reg = (u8) readb((void __iomem *) port);
if ((port & 0xFFF) == 0x11C) { /* Status register of IOC4 */
if (reg & 0x51) { /* Not busy...check for interrupt */
unsigned long other_ir = port - 0x110;
- unsigned int intr_reg = (u32) inl(other_ir);
+ unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
/* Clear the Interrupt, Error bits on the IOC4 */
if (intr_reg & 0x03) {
- outl(0x03, other_ir);
- intr_reg = (u32) inl(other_ir);
+ writel(0x03, (void __iomem *) other_ir);
+ intr_reg = (u32) readl((void __iomem *) other_ir);
}
}
}
drive->name);
goto use_pio_instead;
} else {
- u32 xcount, bcount =
+ u32 bcount =
0x10000 - (cur_addr & 0xffff);
if (bcount > cur_len)
*table = 0x0;
table++;
- xcount = bcount & 0xffff;
- *table = cpu_to_be32(xcount);
+ *table = cpu_to_be32(bcount);
table++;
cur_addr += bcount;
hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
hwif->ide_dma_timeout = &__ide_dma_timeout;
+
+ /*
+ * The IOC4 uses MMIO rather than Port IO.
+ * It also needs special workarounds for INB.
+ */
+ default_hwif_mmiops(hwif);
hwif->INB = &sgiioc4_INB;
}
ide_hwif_t *hwif;
int h;
+ /*
+ * Find an empty HWIF; if none available, return -ENOMEM.
+ */
for (h = 0; h < MAX_HWIFS; ++h) {
hwif = &ide_hwifs[h];
- /* Find an empty HWIF */
if (hwif->chipset == ide_unknown)
break;
}
+ if (h == MAX_HWIFS) {
+ printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name);
+ return -ENOMEM;
+ }
/* Get the CmdBlk and CtrlBlk Base Registers */
base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET;
return -EIO;
/* Create /proc/ide entries */
- create_proc_ide_interfaces();
+ create_proc_ide_interfaces();
return 0;
}
unsigned int class_rev;
int ret;
- ret = pci_enable_device(dev);
- if (ret < 0) {
- printk(KERN_ERR
- "Failed to enable device %s at slot %s\n",
- d->name, dev->slot_name);
- goto out;
- }
- pci_set_master(dev);
-
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
- d->name, dev->slot_name, class_rev);
+ d->name, pci_name(dev), class_rev);
if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
"firmware is obsolete - please upgrade to revision"
- "46 or higher\n", d->name, dev->slot_name);
+ "46 or higher\n", d->name, pci_name(dev));
ret = -EAGAIN;
goto out;
}
}
};
-static int __devinit
-sgiioc4_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+int
+ioc4_ide_attach_one(struct ioc4_driver_data *idd)
{
- pci_init_sgiioc4(dev, &sgiioc4_chipsets[id->driver_data]);
- return 0;
+ return pci_init_sgiioc4(idd->idd_pdev,
+ &sgiioc4_chipsets[idd->idd_pci_id->driver_data]);
}
-static struct pci_device_id sgiioc4_pci_tbl[] = {
- {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
- PCI_ANY_ID, 0x0b4000, 0xFFFFFF, 0},
- {0}
-};
-MODULE_DEVICE_TABLE(pci, sgiioc4_pci_tbl);
-
-static struct pci_driver __devinitdata driver = {
- .name = "SGI-IOC4_IDE",
- .id_table = sgiioc4_pci_tbl,
- .probe = sgiioc4_init_one,
+static struct ioc4_submodule ioc4_ide_submodule = {
+ .is_name = "IOC4_ide",
+ .is_owner = THIS_MODULE,
+ .is_probe = ioc4_ide_attach_one,
+/* .is_remove = ioc4_ide_remove_one, */
};
static int __devinit
-sgiioc4_ide_init(void)
+ioc4_ide_init(void)
+{
+ return ioc4_register_submodule(&ioc4_ide_submodule);
+}
+
+static void __devexit
+ioc4_ide_exit(void)
{
- return ide_pci_register_driver(&driver);
+ ioc4_unregister_submodule(&ioc4_ide_submodule);
}
-module_init(sgiioc4_ide_init);
+module_init(ioc4_ide_init);
+module_exit(ioc4_ide_exit);
-MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)");
-MODULE_DESCRIPTION("PCI driver module for SGI IOC4 Base-IO Card");
+MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon");
+MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card");
MODULE_LICENSE("GPL");