This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / scsi / sata_sil.c
index 219dcef..0512a57 100644 (file)
@@ -1,8 +1,12 @@
 /*
- *  ata_sil.c - Silicon Image SATA
+ *  sata_sil.c - Silicon Image SATA
+ *
+ *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
+ *                 Please ALWAYS copy linux-ide@vger.kernel.org
+ *                 on emails.
  *
  *  Copyright 2003 Red Hat, Inc.
- *  Copyright 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *  Copyright 2003 Benjamin Herrenschmidt
  *
  *  The contents of this file are subject to the Open
  *  Software License version 1.1 that can be found at
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include "scsi.h"
-#include "hosts.h"
+#include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_sil"
-#define DRV_VERSION    "0.54"
+#define DRV_VERSION    "0.8"
 
 enum {
        sil_3112                = 0,
@@ -67,6 +71,8 @@ static struct pci_device_id sil_pci_tbl[] = {
        { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 },
        { 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 },
        { }     /* terminate list */
 };
 
@@ -80,8 +86,12 @@ struct sil_drivelist {
        { "ST330013AS",         SIL_QUIRK_MOD15WRITE },
        { "ST340017AS",         SIL_QUIRK_MOD15WRITE },
        { "ST360015AS",         SIL_QUIRK_MOD15WRITE },
+       { "ST380013AS",         SIL_QUIRK_MOD15WRITE },
        { "ST380023AS",         SIL_QUIRK_MOD15WRITE },
        { "ST3120023AS",        SIL_QUIRK_MOD15WRITE },
+       { "ST3160023AS",        SIL_QUIRK_MOD15WRITE },
+       { "ST3120026AS",        SIL_QUIRK_MOD15WRITE },
+       { "ST3200822AS",        SIL_QUIRK_MOD15WRITE },
        { "ST340014ASL",        SIL_QUIRK_MOD15WRITE },
        { "ST360014ASL",        SIL_QUIRK_MOD15WRITE },
        { "ST380011ASL",        SIL_QUIRK_MOD15WRITE },
@@ -101,6 +111,7 @@ static struct pci_driver sil_pci_driver = {
 static Scsi_Host_Template sil_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
+       .ioctl                  = ata_scsi_ioctl,
        .queuecommand           = ata_scsi_queuecmd,
        .eh_strategy_handler    = ata_scsi_error,
        .can_queue              = ATA_DEF_QUEUE,
@@ -119,16 +130,22 @@ static Scsi_Host_Template sil_sht = {
 static struct ata_port_operations sil_ops = {
        .port_disable           = ata_port_disable,
        .dev_config             = sil_dev_config,
-       .tf_load                = ata_tf_load_mmio,
-       .tf_read                = ata_tf_read_mmio,
-       .check_status           = ata_check_status_mmio,
-       .exec_command           = ata_exec_command_mmio,
+       .tf_load                = ata_tf_load,
+       .tf_read                = ata_tf_read,
+       .check_status           = ata_check_status,
+       .exec_command           = ata_exec_command,
+       .dev_select             = ata_std_dev_select,
        .phy_reset              = sata_phy_reset,
        .post_set_mode          = sil_post_set_mode,
-       .bmdma_start            = ata_bmdma_start_mmio,
-       .fill_sg                = ata_fill_sg,
+       .bmdma_setup            = ata_bmdma_setup,
+       .bmdma_start            = ata_bmdma_start,
+       .bmdma_stop             = ata_bmdma_stop,
+       .bmdma_status           = ata_bmdma_status,
+       .qc_prep                = ata_qc_prep,
+       .qc_issue               = ata_qc_issue_prot,
        .eng_timeout            = ata_eng_timeout,
        .irq_handler            = ata_interrupt,
+       .irq_clear              = ata_bmdma_irq_clear,
        .scr_read               = sil_scr_read,
        .scr_write              = sil_scr_write,
        .port_start             = ata_port_start,
@@ -141,7 +158,8 @@ static struct ata_port_info sil_port_info[] = {
                .sht            = &sil_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_SRST | ATA_FLAG_MMIO,
-               .pio_mask       = 0x03,                 /* pio3-4 */
+               .pio_mask       = 0x1f,                 /* pio0-4 */
+               .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
                .port_ops       = &sil_ops,
        }, /* sil_3114 */
@@ -149,7 +167,8 @@ static struct ata_port_info sil_port_info[] = {
                .sht            = &sil_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_SRST | ATA_FLAG_MMIO,
-               .pio_mask       = 0x03,                 /* pio3-4 */
+               .pio_mask       = 0x1f,                 /* pio0-4 */
+               .mwdma_mask     = 0x07,                 /* mwdma0-2 */
                .udma_mask      = 0x3f,                 /* udma0-5 */
                .port_ops       = &sil_ops,
        },
@@ -177,6 +196,7 @@ MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 static void sil_post_set_mode (struct ata_port *ap)
 {
@@ -262,7 +282,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
  *
  *     20040111 - Seagate drives affected by the Mod15Write bug are blacklisted
  *     The Maxtor quirk is in the blacklist, but I'm keeping the original
- *     pessimistic fix for the following reasons:
+ *     pessimistic fix for the following reasons...
  *     - There seems to be less info on it, only one device gleaned off the
  *     Windows driver, maybe only one is affected.  More info would be greatly
  *     appreciated.
@@ -271,8 +291,14 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
 {
        unsigned int n, quirks = 0;
-       const char *s = &dev->product[0];
-       unsigned int len = strnlen(s, sizeof(dev->product));
+       unsigned char model_num[40];
+       const char *s;
+       unsigned int len;
+
+       ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
+                         sizeof(model_num));
+       s = &model_num[0];
+       len = strnlen(s, sizeof(model_num));
 
        /* ATAPI specifies that empty space is blank-filled; remove blanks */
        while ((len > 0) && (s[len - 1] == ' '))
@@ -291,6 +317,7 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
                       ap->id, dev->devno);
                ap->host->max_sectors = 15;
                ap->host->hostt->max_sectors = 15;
+               dev->flags |= ATA_DFLAG_LOCK_SECTORS;
                return;
        }
 
@@ -311,6 +338,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        void *mmio_base;
        int rc;
        unsigned int i;
+       int pci_dev_busy = 0;
        u32 tmp, irq_mask;
 
        if (!printed_version++)
@@ -325,8 +353,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                return rc;
 
        rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc)
+       if (rc) {
+               pci_dev_busy = 1;
                goto err_out;
+       }
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
@@ -343,11 +373,12 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 
        memset(probe_ent, 0, sizeof(*probe_ent));
        INIT_LIST_HEAD(&probe_ent->node);
-       probe_ent->pdev = pdev;
+       probe_ent->dev = pci_dev_to_dev(pdev);
        probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
        probe_ent->sht = sil_port_info[ent->driver_data].sht;
        probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
        probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask;
+       probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask;
        probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask;
                probe_ent->irq = pdev->irq;
                probe_ent->irq_flags = SA_SHIRQ;
@@ -412,7 +443,8 @@ err_out_free_ent:
 err_out_regions:
        pci_release_regions(pdev);
 err_out:
-       pci_disable_device(pdev);
+       if (!pci_dev_busy)
+               pci_disable_device(pdev);
        return rc;
 }