[PATCH] libata: use ata_scsi_timed_out()
[safe/jmp/linux-2.6] / drivers / scsi / sata_sil.c
index a1b81d4..f40f25e 100644 (file)
@@ -5,24 +5,32 @@
  *                 Please ALWAYS copy linux-ide@vger.kernel.org
  *                 on emails.
  *
- *  Copyright 2003 Red Hat, Inc.
+ *  Copyright 2003-2005 Red Hat, Inc.
  *  Copyright 2003 Benjamin Herrenschmidt
  *
- *  The contents of this file are subject to the Open
- *  Software License version 1.1 that can be found at
- *  http://www.opensource.org/licenses/osl-1.1.txt and is included herein
- *  by reference.
  *
- *  Alternatively, the contents of this file may be used under the terms
- *  of the GNU General Public License version 2 (the "GPL") as distributed
- *  in the kernel source COPYING file, in which case the provisions of
- *  the GPL are applicable instead of the above.  If you wish to allow
- *  the use of your version of this file only under the terms of the
- *  GPL and not to allow others to use your version of this file under
- *  the OSL, indicate your decision by deleting the provisions above and
- *  replace them with the notice and other provisions required by the GPL.
- *  If you do not delete the provisions above, a recipient may use your
- *  version of this file under either the OSL or the GPL.
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *  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.
  *
  */
 
@@ -33,7 +41,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include "scsi.h"
+#include <linux/device.h>
 #include <scsi/scsi_host.h>
 #include <linux/libata.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,
@@ -75,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 },
+
+static const struct pci_device_id sil_pci_tbl[] = {
+       { 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 */
 };
 
@@ -118,11 +130,12 @@ static struct pci_driver sil_pci_driver = {
        .remove                 = ata_pci_remove_one,
 };
 
-static Scsi_Host_Template sil_sht = {
+static struct scsi_host_template sil_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
        .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
+       .eh_timed_out           = ata_scsi_timed_out,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
        .this_id                = ATA_SHT_THIS_ID,
@@ -135,10 +148,9 @@ static Scsi_Host_Template sil_sht = {
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
-       .ordered_flush          = 1,
 };
 
-static struct ata_port_operations sil_ops = {
+static const struct ata_port_operations sil_ops = {
        .port_disable           = ata_port_disable,
        .dev_config             = sil_dev_config,
        .tf_load                = ata_tf_load,
@@ -161,10 +173,10 @@ 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[] = {
+static const struct ata_port_info sil_port_info[] = {
        /* sil_3112 */
        {
                .sht            = &sil_sht,
@@ -174,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,
@@ -210,6 +232,11 @@ MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
+static int slow_down = 0;
+module_param(slow_down, int, 0444);
+MODULE_PARM_DESC(slow_down, "Sledgehammer used to work around random problems, by limiting commands to 15 sectors (0=off, 1=on)");
+
+
 static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
 {
        u8 cache_line = 0;
@@ -221,7 +248,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;
 
@@ -265,7 +293,7 @@ static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_re
 
 static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
 {
-       void *mmio = (void *) sil_scr_addr(ap, sc_reg);
+       void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
        if (mmio)
                return readl(mmio);
        return 0xffffffffU;
@@ -273,7 +301,7 @@ 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)
 {
-       void *mmio = (void *) sil_scr_addr(ap, sc_reg);
+       void *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
        if (mmio)
                writel(val, mmio);
 }
@@ -331,8 +359,10 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
                }
 
        /* limit requests to 15 sectors */
-       if (quirks & SIL_QUIRK_MOD15WRITE) {
-               printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n",
+       if (slow_down ||
+           ((ap->flags & SIL_FLAG_MOD15WRITE) &&
+            (quirks & SIL_QUIRK_MOD15WRITE))) {
+               printk(KERN_INFO "ata%u(%u): applying Seagate errata fix (mod15write workaround)\n",
                       ap->id, dev->devno);
                ap->host->max_sectors = 15;
                ap->host->hostt->max_sectors = 15;
@@ -354,7 +384,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;
@@ -362,7 +392,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        u8 cls;
 
        if (!printed_version++)
-               printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+               dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
        /*
         * If this driver happens to only be useful on Apple's K2, then
@@ -404,8 +434,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;
@@ -440,8 +469,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                        writeb(cls, mmio_base + SIL_FIFO_W3);
                }
        } else
-               printk(KERN_WARNING DRV_NAME "(%s): cache line size not set.  Driver may not function\n",
-                       pci_name(pdev));
+               dev_printk(KERN_WARNING, &pdev->dev,
+                        "cache line size not set.  Driver may not function\n");
 
        if (ent->driver_data == sil_3114) {
                irq_mask = SIL_MASK_4PORT;