*
* 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 neccessary
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
-#include "siimage.h"
-
-#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS)
-#include <linux/proc_fs.h>
-
-static u8 siimage_proc = 0;
-#define SIIMAGE_MAX_DEVS 16
-static struct pci_dev *siimage_devs[SIIMAGE_MAX_DEVS];
-static int n_siimage_devs;
-#endif /* defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) */
-
/**
* pdev_is_sata - check if device is SATA
* @pdev: PCI device to check
return base;
}
-#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS)
-/**
- * print_siimage_get_info - print minimal proc information
- * @buf: buffer to write into (kernel space)
- * @dev: PCI device we are describing
- * @index: Controller number
- *
- * Print the basic information for the state of the CMD680/SI3112
- * channel. We don't actually dump a lot of information out for
- * this controller although we could expand it if we needed.
- */
-
-static char *print_siimage_get_info (char *buf, struct pci_dev *dev, int index)
-{
- char *p = buf;
- u8 mmio = (pci_get_drvdata(dev) != NULL) ? 1 : 0;
- unsigned long bmdma = pci_resource_start(dev, 4);
-
- if(mmio)
- bmdma = pci_resource_start(dev, 5);
-
- p += sprintf(p, "\nController: %d\n", index);
- p += sprintf(p, "SiI%x Chipset.\n", dev->device);
- if (mmio)
- p += sprintf(p, "MMIO Base 0x%lx\n", bmdma);
- p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma);
- p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma+8);
- return (char *)p;
-}
-
-/**
- * siimage_get_info - proc callback
- * @buffer: kernel buffer to complete
- * @addr: written with base of data to return
- * offset: seek offset
- * count: bytes to fill in
- *
- * Called when the user reads data from the virtual file for this
- * controller from /proc
- */
-
-static int siimage_get_info (char *buffer, char **addr, off_t offset, int count)
-{
- char *p = buffer;
- int len;
- u16 i;
-
- p += sprintf(p, "\n");
- for (i = 0; i < n_siimage_devs; i++) {
- struct pci_dev *dev = siimage_devs[i];
- p = print_siimage_get_info(p, dev, i);
- }
- /* p - buffer must be less than 4k! */
- len = (p - buffer) - offset;
- *addr = buffer + offset;
-
- return len > count ? count : len;
-}
-
-#endif /* defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS) */
-
/**
* siimage_ratemask - Compute available modes
* @drive: IDE drive
struct hd_driveid *id = drive->id;
if ((id->capability & 1) != 0 && drive->autodma) {
- /* Consult the list of known "bad" drives */
- if (__ide_dma_bad_drive(drive))
- goto fast_ata_pio;
-
- if ((id->field_valid & 4) && siimage_ratemask(drive)) {
- if (id->dma_ultra & hwif->ultra_mask) {
- /* Force if Capable UltraDMA */
- int dma = config_chipset_for_dma(drive);
- if ((id->field_valid & 2) && !dma)
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-try_dma_modes:
- if ((id->dma_mword & hwif->mwdma_mask) ||
- (id->dma_1word & hwif->swdma_mask)) {
- /* Force if Capable regular DMA modes */
- if (!config_chipset_for_dma(drive))
- goto no_dma_set;
- }
- } else if (__ide_dma_good_drive(drive) &&
- (id->eide_dma_time < 150)) {
- /* Consult the list of known "good" drives */
- if (!config_chipset_for_dma(drive))
- goto no_dma_set;
- } else {
- goto fast_ata_pio;
+
+ if (ide_use_dma(drive)) {
+ if (config_chipset_for_dma(drive))
+ return hwif->ide_dma_on(drive);
}
- return hwif->ide_dma_on(drive);
+
+ goto fast_ata_pio;
+
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
-no_dma_set:
config_chipset_for_pio(drive, 1);
return hwif->ide_dma_off_quietly(drive);
}
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
u32 sata_error = hwif->INL(SATA_ERROR_REG);
hwif->OUTL(sata_error, 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 0;
}
-static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive)
-{
- int temp = __ide_dma_verbose(drive);
- return temp;
-}
-
/**
* siimage_busproc - bus isolation ioctl
* @drive: drive to isolate/restore
if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {
printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
hwif->name, hwif->INL(SATA_STATUS_REG));
- HWGROUP(drive)->poll_timeout = 0;
+ HWGROUP(drive)->polling = 0;
return ide_started;
}
return 0;
case 0x00: printk("== 100\n"); break;
}
}
-
-#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS)
- siimage_devs[n_siimage_devs++] = dev;
-
- if (!siimage_proc) {
- siimage_proc = 1;
- ide_pci_create_host_proc("siimage", siimage_get_info);
- }
-#endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */
}
/**
unsigned long bar5 = pci_resource_start(dev, 5);
unsigned long barsize = pci_resource_len(dev, 5);
u8 tmpbyte = 0;
- unsigned long addr;
- void *ioaddr;
+ void __iomem *ioaddr;
+ u32 tmp, irq_mask;
/*
* Drop back to PIO if we can't map the mmio. Some
}
pci_set_master(dev);
- pci_set_drvdata(dev, ioaddr);
- addr = (unsigned long) ioaddr;
+ pci_set_drvdata(dev, (void *) ioaddr);
if (pdev_is_sata(dev)) {
- writel(0, addr + 0x148);
- writel(0, addr + 0x1C8);
+ /* make sure IDE0/1 interrupts are not masked */
+ irq_mask = (1 << 22) | (1 << 23);
+ tmp = readl(ioaddr + 0x48);
+ if (tmp & irq_mask) {
+ tmp &= ~irq_mask;
+ writel(tmp, ioaddr + 0x48);
+ readl(ioaddr + 0x48); /* flush */
+ }
+ writel(0, ioaddr + 0x148);
+ writel(0, ioaddr + 0x1C8);
}
- writeb(0, addr + 0xB4);
- writeb(0, addr + 0xF4);
- tmpbyte = readb(addr + 0x4A);
+ writeb(0, ioaddr + 0xB4);
+ writeb(0, ioaddr + 0xF4);
+ tmpbyte = readb(ioaddr + 0x4A);
switch(tmpbyte & 0x30) {
case 0x00:
/* In 100 MHz clocking, try and switch to 133 */
- writeb(tmpbyte|0x10, addr + 0x4A);
+ writeb(tmpbyte|0x10, ioaddr + 0x4A);
break;
case 0x10:
/* On 133Mhz clocking */
case 0x30:
/* Clocking is disabled */
/* 133 clock attempt to force it on */
- writeb(tmpbyte & ~0x20, addr + 0x4A);
+ writeb(tmpbyte & ~0x20, ioaddr + 0x4A);
break;
}
- writeb( 0x72, addr + 0xA1);
- writew( 0x328A, addr + 0xA2);
- writel(0x62DD62DD, addr + 0xA4);
- writel(0x43924392, addr + 0xA8);
- writel(0x40094009, addr + 0xAC);
- writeb( 0x72, addr + 0xE1);
- writew( 0x328A, addr + 0xE2);
- writel(0x62DD62DD, addr + 0xE4);
- writel(0x43924392, addr + 0xE8);
- writel(0x40094009, addr + 0xEC);
+ writeb( 0x72, ioaddr + 0xA1);
+ writew( 0x328A, ioaddr + 0xA2);
+ writel(0x62DD62DD, ioaddr + 0xA4);
+ writel(0x43924392, ioaddr + 0xA8);
+ writel(0x40094009, ioaddr + 0xAC);
+ writeb( 0x72, ioaddr + 0xE1);
+ writew( 0x328A, ioaddr + 0xE2);
+ writel(0x62DD62DD, ioaddr + 0xE4);
+ writel(0x43924392, ioaddr + 0xE8);
+ writel(0x40094009, ioaddr + 0xEC);
if (pdev_is_sata(dev)) {
- writel(0xFFFF0000, addr + 0x108);
- writel(0xFFFF0000, addr + 0x188);
- writel(0x00680000, addr + 0x148);
- writel(0x00680000, addr + 0x1C8);
+ writel(0xFFFF0000, ioaddr + 0x108);
+ writel(0xFFFF0000, ioaddr + 0x188);
+ writel(0x00680000, ioaddr + 0x148);
+ writel(0x00680000, ioaddr + 0x1C8);
}
- tmpbyte = readb(addr + 0x4A);
+ tmpbyte = readb(ioaddr + 0x4A);
proc_reports_siimage(dev, (tmpbyte>>4), name);
return 1;
* to 133MHz clocking if the system isn't already set up to do it.
*/
-static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name)
{
u32 class_rev = 0;
u8 tmpbyte = 0;
* 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 __init init_mmio_iops_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
void *addr = pci_get_drvdata(dev);
* the MMIO layout isnt the same as the the standard port
* based I/O
*/
-
+
memset(&hw, 0, sizeof(hw_regs_t));
- hw.priv = addr;
- base = (unsigned long)addr;
- if(ch)
+ base = (unsigned long)addr;
+ if (ch)
base += 0xC0;
else
base += 0x80;
* 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;
hw.io_ports[IDE_IRQ_OFFSET] = 0;
- if (pdev_is_sata(dev)) {
- base = (unsigned long) addr;
- if(ch)
- base += 0x80;
- hw.sata_scr[SATA_STATUS_OFFSET] = base + 0x104;
- hw.sata_scr[SATA_ERROR_OFFSET] = base + 0x108;
- hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100;
- hw.sata_misc[SATA_MISC_OFFSET] = base + 0x140;
- hw.sata_misc[SATA_PHY_OFFSET] = base + 0x144;
- hw.sata_misc[SATA_IEN_OFFSET] = base + 0x148;
+ if (pdev_is_sata(dev)) {
+ base = (unsigned long)addr;
+ if (ch)
+ base += 0x80;
+ hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104;
+ hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108;
+ hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100;
+ hwif->sata_misc[SATA_MISC_OFFSET] = base + 0x140;
+ hwif->sata_misc[SATA_PHY_OFFSET] = base + 0x144;
+ hwif->sata_misc[SATA_IEN_OFFSET] = base + 0x148;
}
hw.irq = hwif->pci_dev->irq;
memcpy(&hwif->hw, &hw, sizeof(hw));
memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
- if (is_sata(hwif)) {
- memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr));
- memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc));
- }
-
hwif->irq = hw.irq;
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;
}
return 0;
}
+/**
+ * siimage_fixup - post probe fixups
+ * @hwif: interface to fix up
+ *
+ * Called after drive probe we use this to decide whether the
+ * Seagate fixup must be applied. This used to be in init_iops but
+ * that can occur before we know what drives are present.
+ */
+
+static void __devinit siimage_fixup(ide_hwif_t *hwif)
+{
+ /* Try and raise the rqsize */
+ if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0]))
+ hwif->rqsize = 128;
+}
+
/**
* init_iops_siimage - set up iops
* @hwif: interface to set up
* look in we get for setting up the hwif so that we
* can get the iops right before using them.
*/
-
-static void __init init_iops_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_iops_siimage(ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
u32 class_rev = 0;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
- hwif->hwif_data = 0;
+ hwif->hwif_data = NULL;
- hwif->rqsize = 128;
- if (is_sata(hwif) && is_dev_seagate_sata(&hwif->drives[0]))
- hwif->rqsize = 15;
+ /* Pessimal until we finish probing */
+ hwif->rqsize = 15;
if (pci_get_drvdata(dev) == NULL)
return;
* Check for the presence of an ATA66 capable cable on the
* interface.
*/
-
-static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
+
+static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif)
{
unsigned long addr = siimage_selreg(hwif, 0);
if (pci_get_drvdata(hwif->pci_dev) == NULL) {
* requires several custom handlers so we override the default
* ide DMA handlers appropriately
*/
-
-static void __init init_hwif_siimage (ide_hwif_t *hwif)
+
+static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
{
hwif->autodma = 0;
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;
if (hwif->mmio) {
hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;
- hwif->ide_dma_verbose = &siimage_mmio_ide_dma_verbose;
} else {
hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;
}
hwif->drives[1].autodma = hwif->autodma;
}
+#define DECLARE_SII_DEV(name_str) \
+ { \
+ .name = name_str, \
+ .init_chipset = init_chipset_siimage, \
+ .init_iops = init_iops_siimage, \
+ .init_hwif = init_hwif_siimage, \
+ .fixup = siimage_fixup, \
+ .channels = 2, \
+ .autodma = AUTODMA, \
+ .bootable = ON_BOARD, \
+ }
+
+static ide_pci_device_t siimage_chipsets[] __devinitdata = {
+ /* 0 */ DECLARE_SII_DEV("SiI680"),
+ /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
+ /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
+};
+
/**
* siimage_init_one - pci layer discovery entry
* @dev: PCI device
static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d = &siimage_chipsets[id->driver_data];
- if (dev->device != d->device)
- BUG();
- ide_setup_pci_device(dev, d);
- return 0;
+ return ide_setup_pci_device(dev, &siimage_chipsets[id->driver_data]);
}
static struct pci_device_id siimage_pci_tbl[] = {
{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#ifdef CONFIG_BLK_DEV_IDE_SATA
{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+#endif
{ 0, },
};
MODULE_DEVICE_TABLE(pci, siimage_pci_tbl);
static struct pci_driver driver = {
- .name = "SiI IDE",
+ .name = "SiI_IDE",
.id_table = siimage_pci_tbl,
.probe = siimage_init_one,
};
-static int siimage_ide_init(void)
+static int __init siimage_ide_init(void)
{
return ide_pci_register_driver(&driver);
}