]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/sata_sil.c
Merge branch 'release' of master.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6
[linux-2.6-omap-h63xx.git] / drivers / scsi / sata_sil.c
index 345e6f2d28a89058183132ec31bd244914710206..ba98a175ee3a8f9e227917689b9678285df586c3 100644 (file)
  *  libata documentation is available via 'make {ps|pdf}docs',
  *  as Documentation/DocBook/libata.*
  *
+ *  Documentation for SiI 3112:
+ *  http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
+ *
+ *  Other errata and documentation available under NDA.
+ *
  */
 
 #include <linux/kernel.h>
 #define DRV_VERSION    "0.9"
 
 enum {
+       SIL_FLAG_MOD15WRITE     = (1 << 30),
+
        sil_3112                = 0,
-       sil_3114                = 1,
+       sil_3112_m15w           = 1,
+       sil_3114                = 2,
 
        SIL_FIFO_R0             = 0x40,
        SIL_FIFO_W0             = 0x41,
@@ -78,14 +86,15 @@ static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void sil_post_set_mode (struct ata_port *ap);
 
+
 static struct pci_device_id sil_pci_tbl[] = {
-       { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-       { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+       { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
+       { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
        { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
        { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 },
-       { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-       { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
-       { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
+       { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
+       { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
+       { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w },
        { }     /* terminate list */
 };
 
@@ -164,7 +173,7 @@ static struct ata_port_operations sil_ops = {
        .scr_write              = sil_scr_write,
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
-       .host_stop              = ata_host_stop,
+       .host_stop              = ata_pci_host_stop,
 };
 
 static struct ata_port_info sil_port_info[] = {
@@ -177,6 +186,16 @@ static struct ata_port_info sil_port_info[] = {
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
                .port_ops       = &sil_ops,
+       }, /* sil_3112_15w - keep it sync'd w/ sil_3112 */
+       {
+               .sht            = &sil_sht,
+               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
+                                 SIL_FLAG_MOD15WRITE,
+               .pio_mask       = 0x1f,                 /* pio0-4 */
+               .mwdma_mask     = 0x07,                 /* mwdma0-2 */
+               .udma_mask      = 0x3f,                 /* udma0-5 */
+               .port_ops       = &sil_ops,
        }, /* sil_3114 */
        {
                .sht            = &sil_sht,
@@ -213,6 +232,7 @@ MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
+
 static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
 {
        u8 cache_line = 0;
@@ -224,7 +244,8 @@ static void sil_post_set_mode (struct ata_port *ap)
 {
        struct ata_host_set *host_set = ap->host_set;
        struct ata_device *dev;
-       void *addr = host_set->mmio_base + sil_port[ap->port_no].xfer_mode;
+       void __iomem *addr =
+               host_set->mmio_base + sil_port[ap->port_no].xfer_mode;
        u32 tmp, dev_mode[2];
        unsigned int i;
 
@@ -326,15 +347,15 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
        while ((len > 0) && (s[len - 1] == ' '))
                len--;
 
-       for (n = 0; sil_blacklist[n].product; n++) 
+       for (n = 0; sil_blacklist[n].product; n++)
                if (!memcmp(sil_blacklist[n].product, s,
                            strlen(sil_blacklist[n].product))) {
                        quirks = sil_blacklist[n].quirk;
                        break;
                }
-       
+
        /* limit requests to 15 sectors */
-       if (quirks & SIL_QUIRK_MOD15WRITE) {
+       if ((ap->flags & SIL_FLAG_MOD15WRITE) && (quirks & SIL_QUIRK_MOD15WRITE)) {
                printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n",
                       ap->id, dev->devno);
                ap->host->max_sectors = 15;
@@ -357,7 +378,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        static int printed_version;
        struct ata_probe_ent *probe_ent = NULL;
        unsigned long base;
-       void *mmio_base;
+       void __iomem *mmio_base;
        int rc;
        unsigned int i;
        int pci_dev_busy = 0;
@@ -407,8 +428,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                probe_ent->irq_flags = SA_SHIRQ;
        probe_ent->host_flags = sil_port_info[ent->driver_data].host_flags;
 
-       mmio_base = ioremap(pci_resource_start(pdev, 5),
-                           pci_resource_len(pdev, 5));
+       mmio_base = pci_iomap(pdev, 5, 0);
        if (mmio_base == NULL) {
                rc = -ENOMEM;
                goto err_out_free_ent;