/*
- * linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003
+ * linux/drivers/ide/pci/siimage.c Version 1.11 Jan 27, 2007
*
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat <alan@redhat.com>
+ * Copyright (C) 2007 MontaVista Software, Inc.
*
* May be copied or modified under the terms of the GNU General Public License
*
- * Documentation available under NDA only
+ * Documentation for CMD680:
+ * http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
+ *
+ * Documentation for SiI 3112:
+ * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
+ *
+ * Errata and other documentation only available under NDA.
*
*
* FAQ Items:
* If you have strange problems with nVidia chipset systems please
* see the SI support documentation and update your system BIOS
* if neccessary
+ *
+ * The Dell DRAC4 has some interesting features including effectively hot
+ * unplugging/replugging the virtual CD interface when the DRAC is reset.
+ * This often causes drivers/ide/siimage to panic but is ok with the rather
+ * smarter code in libata.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
-#undef SIIMAGE_VIRTUAL_DMAPIO
-#undef SIIMAGE_LARGE_DMA
-
/**
* pdev_is_sata - check if device is SATA
* @pdev: PCI device to check
unsigned long tfaddr = siimage_selreg(hwif, 0x02);
/* cheat for now and use the docs */
- switch(mode_wanted) {
- case 4:
- speedp = 0x10c1;
- speedt = 0x10c1;
- break;
- case 3:
- speedp = 0x10C3;
- speedt = 0x10C3;
- break;
- case 2:
- speedp = 0x1104;
- speedt = 0x1281;
- break;
- case 1:
- speedp = 0x2283;
- speedt = 0x1281;
- break;
- case 0:
- default:
- speedp = 0x328A;
- speedt = 0x328A;
- break;
+ switch (mode_wanted) {
+ case 4:
+ speedp = 0x10c1;
+ speedt = 0x10c1;
+ break;
+ case 3:
+ speedp = 0x10c3;
+ speedt = 0x10c3;
+ break;
+ case 2:
+ speedp = 0x1104;
+ speedt = 0x1281;
+ break;
+ case 1:
+ speedp = 0x2283;
+ speedt = 0x2283;
+ break;
+ case 0:
+ default:
+ speedp = 0x328a;
+ speedt = 0x328a;
+ break;
}
- if (hwif->mmio)
- {
- hwif->OUTW(speedt, addr);
- hwif->OUTW(speedp, tfaddr);
+
+ if (hwif->mmio) {
+ hwif->OUTW(speedp, addr);
+ hwif->OUTW(speedt, tfaddr);
/* Now set up IORDY */
if(mode_wanted == 3 || mode_wanted == 4)
hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
else
hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
- }
- else
- {
+ } else {
pci_write_config_word(hwif->pci_dev, addr, speedp);
pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
if (!speed)
return 0;
- if (ide_set_xfer_rate(drive, speed))
+ if (siimage_tune_chipset(drive, speed))
return 0;
- if (!drive->init_speed)
- drive->init_speed = speed;
-
return ide_dma_enable(drive);
}
static int siimage_config_drive_for_dma (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- struct hd_driveid *id = drive->id;
-
- if ((id->capability & 1) != 0 && drive->autodma) {
-
- if (ide_use_dma(drive)) {
- if (config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
- }
-
- goto fast_ata_pio;
+ if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+ return 0;
- } else if ((id->capability & 8) || (id->field_valid & 2)) {
-fast_ata_pio:
+ if (ide_use_fast_pio(drive))
config_chipset_for_pio(drive, 1);
- return hwif->ide_dma_off_quietly(drive);
- }
- /* IORDY not supported */
- return 0;
+
+ return -1;
}
/* returns 1 if dma irq issued, 0 otherwise */
return 0;
}
-#if 0
-/**
- * siimage_mmio_ide_dma_count - DMA bytes done
- * @drive
- *
- * If we are doing VDMA the CMD680 requires a little bit
- * of more careful handling and we have to read the counts
- * off ourselves. For non VDMA life is normal.
- */
-
-static int siimage_mmio_ide_dma_count (ide_drive_t *drive)
-{
-#ifdef SIIMAGE_VIRTUAL_DMAPIO
- struct request *rq = HWGROUP(drive)->rq;
- ide_hwif_t *hwif = HWIF(drive);
- u32 count = (rq->nr_sectors * SECTOR_SIZE);
- u32 rcount = 0;
- unsigned long addr = siimage_selreg(hwif, 0x1C);
-
- hwif->OUTL(count, addr);
- rcount = hwif->INL(addr);
-
- printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n",
- drive->name, count, rcount, rq->nr_sectors);
-
-#endif /* SIIMAGE_VIRTUAL_DMAPIO */
- return __ide_dma_count(drive);
-}
-#endif
-
/**
* siimage_mmio_ide_dma_test_irq - check we caused an IRQ
* @drive: drive we are testing
unsigned long addr = siimage_selreg(hwif, 0x1);
if (SATA_ERROR_REG) {
- u32 ext_stat = hwif->INL(base + 0x10);
+ u32 ext_stat = readl((void __iomem *)(base + 0x10));
u8 watchdog = 0;
if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
- u32 sata_error = hwif->INL(SATA_ERROR_REG);
- hwif->OUTL(sata_error, SATA_ERROR_REG);
+ u32 sata_error = readl((void __iomem *)SATA_ERROR_REG);
+ writel(sata_error, (void __iomem *)SATA_ERROR_REG);
watchdog = (sata_error & 0x00680000) ? 1 : 0;
-#if 1
printk(KERN_WARNING "%s: sata_error = 0x%08x, "
"watchdog = %d, %s\n",
drive->name, sata_error, watchdog,
__FUNCTION__);
-#endif
} else {
watchdog = (ext_stat & 0x8000) ? 1 : 0;
}
/* return 1 if INTR asserted */
- if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04)
+ if ((readb((void __iomem *)hwif->dma_status) & 0x04) == 0x04)
return 1;
/* return 1 if Device INTR asserted */
- if ((hwif->INB(addr) & 8) == 8)
+ if ((readb((void __iomem *)addr) & 8) == 8)
return 0; //return 1;
return 0;
u32 stat_config = 0;
unsigned long addr = siimage_selreg(hwif, 0);
- if (hwif->mmio) {
- stat_config = hwif->INL(addr);
- } else
+ if (hwif->mmio)
+ stat_config = readl((void __iomem *)addr);
+ else
pci_read_config_dword(hwif->pci_dev, addr, &stat_config);
switch (state) {
if (SATA_STATUS_REG) {
ide_hwif_t *hwif = HWIF(drive);
- if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {
+ /* SATA_STATUS_REG is valid only when in MMIO mode */
+ if ((readl((void __iomem *)SATA_STATUS_REG) & 0x03) != 0x03) {
printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
- hwif->name, hwif->INL(SATA_STATUS_REG));
+ hwif->name, readl((void __iomem *)SATA_STATUS_REG));
HWGROUP(drive)->polling = 0;
return ide_started;
}
}
if (SATA_STATUS_REG) {
- u32 sata_stat = hwif->INL(SATA_STATUS_REG);
+ /* SATA_STATUS_REG is valid only when in MMIO mode */
+ u32 sata_stat = readl((void __iomem *)SATA_STATUS_REG);
printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n",
hwif->name, sata_stat, __FUNCTION__);
if (!(sata_stat)) {
* time.
*
* The hardware supports buffered taskfiles and also some rather nice
- * extended PRD tables. Unfortunately right now we don't.
+ * extended PRD tables. For better SI3112 support use the libata driver
*/
static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
* so we can't currently use it sanely since we want to
* use LBA48 mode.
*/
-// base += 0x10;
-// hwif->no_lba48 = 1;
-
hw.io_ports[IDE_DATA_OFFSET] = base;
hw.io_ports[IDE_ERROR_OFFSET] = base + 1;
hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2;
base = (unsigned long) addr;
-#ifdef SIIMAGE_LARGE_DMA
-/* Watch the brackets - even Ken and Dennis get some language design wrong */
- hwif->dma_base = base + (ch ? 0x18 : 0x10);
- hwif->dma_base2 = base + (ch ? 0x08 : 0x00);
- hwif->dma_prdtable = hwif->dma_base2 + 4;
-#else /* ! SIIMAGE_LARGE_DMA */
hwif->dma_base = base + (ch ? 0x08 : 0x00);
- hwif->dma_base2 = base + (ch ? 0x18 : 0x10);
-#endif /* SIIMAGE_LARGE_DMA */
- hwif->mmio = 2;
+
+ hwif->mmio = 1;
}
static int is_dev_seagate_sata(ide_drive_t *drive)
hwif->reset_poll = &siimage_reset_poll;
hwif->pre_reset = &siimage_pre_reset;
- if(is_sata(hwif))
+ if(is_sata(hwif)) {
+ static int first = 1;
+
hwif->busproc = &siimage_busproc;
+ if (first) {
+ printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n");
+ first = 0;
+ }
+ }
if (!hwif->dma_base) {
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
.probe = siimage_init_one,
};
-static int siimage_ide_init(void)
+static int __init siimage_ide_init(void)
{
return ide_pci_register_driver(&driver);
}