This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / scsi / sata_vsc.c
index d63a339..c5e09dc 100644 (file)
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_vsc"
-#define DRV_VERSION    "0.01"
+#define DRV_VERSION    "1.0"
 
 /* Interrupt register offsets (from chip base address) */
 #define VSC_SATA_INT_STAT_OFFSET       0x00
@@ -155,7 +156,8 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
  *
  * Read the interrupt register and process for the devices that have them pending.
  */
-irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
+                                      struct pt_regs *regs)
 {
        struct ata_host_set *host_set = dev_instance;
        unsigned int i;
@@ -190,6 +192,7 @@ irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct pt_regs *reg
 static Scsi_Host_Template vsc_sata_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,
@@ -203,6 +206,7 @@ static Scsi_Host_Template vsc_sata_sht = {
        .dma_boundary           = ATA_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
        .bios_param             = ata_std_bios_param,
+       .ordered_flush          = 1,
 };
 
 
@@ -210,11 +214,14 @@ static struct ata_port_operations vsc_sata_ops = {
        .port_disable           = ata_port_disable,
        .tf_load                = vsc_sata_tf_load,
        .tf_read                = vsc_sata_tf_read,
-       .exec_command           = ata_exec_command_mmio,
-       .check_status           = ata_check_status_mmio,
+       .exec_command           = ata_exec_command,
+       .check_status           = ata_check_status,
+       .dev_select             = ata_std_dev_select,
        .phy_reset              = sata_phy_reset,
-       .bmdma_setup            = ata_bmdma_setup_mmio,
-       .bmdma_start            = ata_bmdma_start_mmio,
+       .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,
@@ -224,6 +231,7 @@ static struct ata_port_operations vsc_sata_ops = {
        .scr_write              = vsc_sata_scr_write,
        .port_start             = ata_port_start,
        .port_stop              = ata_port_stop,
+       .host_stop              = ata_host_stop,
 };
 
 static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base)
@@ -253,6 +261,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
        static int printed_version;
        struct ata_probe_ent *probe_ent = NULL;
        unsigned long base;
+       int pci_dev_busy = 0;
        void *mmio_base;
        int rc;
 
@@ -272,16 +281,18 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
        }
 
        rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc)
+       if (rc) {
+               pci_dev_busy = 1;
                goto err_out;
+       }
 
        /*
         * Use 32 bit DMA mask, because 64 bit address support is poor.
         */
-       rc = pci_set_dma_mask(pdev, 0xFFFFFFFFULL);
+       rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc)
                goto err_out_regions;
-       rc = pci_set_consistent_dma_mask(pdev, 0xFFFFFFFFULL);
+       rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
        if (rc)
                goto err_out_regions;
 
@@ -291,7 +302,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
                goto err_out_regions;
        }
        memset(probe_ent, 0, sizeof(*probe_ent));
-       probe_ent->pdev = pdev;
+       probe_ent->dev = pci_dev_to_dev(pdev);
        INIT_LIST_HEAD(&probe_ent->node);
 
        mmio_base = ioremap(pci_resource_start(pdev, 0),
@@ -320,6 +331,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
         * if we don't fill these
         */
        probe_ent->pio_mask = 0x1f;
+       probe_ent->mwdma_mask = 0x07;
        probe_ent->udma_mask = 0x7f;
 
        /* We have 4 ports per PCI function */
@@ -330,6 +342,14 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
 
        pci_set_master(pdev);
 
+       /* 
+        * Config offset 0x98 is "Extended Control and Status Register 0"
+        * Default value is (1 << 28).  All bits except bit 28 are reserved in
+        * DPA mode.  If bit 28 is set, LED 0 reflects all ports' activity.
+        * If bit 28 is clear, each port has its own LED.
+        */
+       pci_write_config_dword(pdev, 0x98, 0);
+
        /* FIXME: check ata_device_add return value */
        ata_device_add(probe_ent);
        kfree(probe_ent);
@@ -341,7 +361,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;
 }
 
@@ -382,6 +403,7 @@ MODULE_AUTHOR("Jeremy Higdon");
 MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 module_init(vsc_sata_init);
 module_exit(vsc_sata_exit);