Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.4.30 /drivers/scsi/sata_nv.c

Filename:/drivers/scsi/sata_nv.c
Lines Added:45
Lines Deleted:14
Also changed in: (Previous) 2.4.30-rc4  2.4.30-rc3  2.4.30-rc2  2.4.30-rc1  2.4.30-pre3  2.4.30-pre2-bk3 
(Following) 2.4.32-pre3  2.4.32-rc1  2.4.32-rc2  2.4.32-rc3  2.4.32  2.4.33-pre1 

Location
[  2.4.30
  [  drivers
    [  scsi
       o  sata_nv.c

Patch

diff -urN linux-2.4.29/drivers/scsi/sata_nv.c linux-2.4.30/drivers/scsi/sata_nv.c
--- linux-2.4.29/drivers/scsi/sata_nv.c   2005-01-19 06:10:03.000000000 -0800
+++ linux-2.4.30/drivers/scsi/sata_nv.c   2005-04-03 18:42:19.951155154 -0700
@@ -20,6 +20,10 @@
  *  If you do not delete the provisions above, a recipient may use your
  *  version of this file under either the OSL or the GPL.
  *
+ *  0.06
+ *     - Added generic SATA support by using a pci_device_id that filters on
+ *       the IDE storage class code.
+ *
  *  0.03
  *     - Fixed a bug where the hotplug handlers for non-CK804/MCP04 were using
  *       mmio_base, which is only set for the CK804/MCP04 case.
@@ -44,7 +48,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME         "sata_nv"
-#define DRV_VERSION         "0.5"
+#define DRV_VERSION         "0.6"
 
 #define NV_PORTS         2
 #define NV_PIO_MASK         0x1f
@@ -95,7 +99,8 @@
 #define NV_MCP_SATA_CFG_20_SATA_SPACE_EN   0x04
 
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t nv_interrupt (int irq, void *dev_instance,
+             struct pt_regs *regs);
 static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void nv_host_stop (struct ata_host_set *host_set);
@@ -108,6 +113,7 @@
 
 enum nv_host_type
 {
+   GENERIC,
    NFORCE2,
    NFORCE3,
    CK804
@@ -128,6 +134,9 @@
       PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
    { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
       PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
+   { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+      PCI_ANY_ID, PCI_ANY_ID,
+      PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
    { 0, } /* terminate list */
 };
 
@@ -136,7 +145,6 @@
 struct nv_host_desc
 {
    enum nv_host_type   host_type;
-   unsigned long      host_flags;
    void         (*enable_hotplug)(struct ata_probe_ent *probe_ent);
    void         (*disable_hotplug)(struct ata_host_set *host_set);
    void         (*check_hotplug)(struct ata_host_set *host_set);
@@ -144,21 +152,24 @@
 };
 static struct nv_host_desc nv_device_tbl[] = {
    {
+      .host_type   = GENERIC,
+      .enable_hotplug   = NULL,
+      .disable_hotplug= NULL,
+      .check_hotplug   = NULL,
+   },
+   {
       .host_type   = NFORCE2,
-      .host_flags   = 0x00000000,
       .enable_hotplug   = nv_enable_hotplug,
       .disable_hotplug= nv_disable_hotplug,
       .check_hotplug   = nv_check_hotplug,
    },
    {
       .host_type   = NFORCE3,
-      .host_flags   = 0x00000000,
       .enable_hotplug   = nv_enable_hotplug,
       .disable_hotplug= nv_disable_hotplug,
       .check_hotplug   = nv_check_hotplug,
    },
    {   .host_type   = CK804,
-      .host_flags   = NV_HOST_FLAGS_SCR_MMIO,
       .enable_hotplug   = nv_enable_hotplug_ck804,
       .disable_hotplug= nv_disable_hotplug_ck804,
       .check_hotplug   = nv_check_hotplug_ck804,
@@ -168,6 +179,7 @@
 struct nv_host
 {
    struct nv_host_desc   *host_desc;
+   unsigned long      host_flags;
 };
 
 static struct pci_driver nv_pci_driver = {
@@ -207,6 +219,8 @@
    .phy_reset      = sata_phy_reset,
    .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,
@@ -245,7 +259,8 @@
 MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
-irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t nv_interrupt (int irq, void *dev_instance,
+             struct pt_regs *regs)
 {
    struct ata_host_set *host_set = dev_instance;
    struct nv_host *host = host_set->private_data;
@@ -285,8 +300,8 @@
    if (sc_reg > SCR_CONTROL)
       return 0xffffffffU;
 
-   if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-      return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
+   if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+      return readl((void*)ap->ioaddr.scr_addr + (sc_reg * 4));
    else
       return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
 }
@@ -299,8 +314,8 @@
    if (sc_reg > SCR_CONTROL)
       return;
 
-   if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-      writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+   if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+      writel(val, (void*)ap->ioaddr.scr_addr + (sc_reg * 4));
    else
       outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
 }
@@ -322,7 +337,16 @@
    struct nv_host *host;
    struct ata_port_info *ppi;
    struct ata_probe_ent *probe_ent;
+   int pci_dev_busy = 0;
    int rc;
+   u32 bar;
+
+        // Make sure this is a SATA controller by counting the number of bars
+        // (NVIDIA SATA controllers will always have six bars).  Otherwise,
+        // it's an IDE controller and we ignore it.
+   for (bar=0; bar<6; bar++)
+      if (pci_resource_start(pdev, bar) == 0)
+         return -ENODEV;
 
    if (!printed_version++)
       printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
@@ -332,8 +356,10 @@
       goto err_out;
 
    rc = pci_request_regions(pdev, DRV_NAME);
-   if (rc)
+   if (rc) {
+      pci_dev_busy = 1;
       goto err_out_disable;
+   }
 
    rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
    if (rc)
@@ -350,11 +376,15 @@
    if (!host)
       goto err_out_free_ent;
 
+   memset(host, 0, sizeof(struct nv_host));
    host->host_desc = &nv_device_tbl[ent->driver_data];
 
    probe_ent->private_data = host;
 
-   if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
+   if (pci_resource_flags(pdev, 5) & IORESOURCE_MEM)
+      host->host_flags |= NV_HOST_FLAGS_SCR_MMIO;
+
+   if (host->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
       unsigned long base;
 
       probe_ent->mmio_base = ioremap(pci_resource_start(pdev, 5),
@@ -395,7 +425,8 @@
 err_out_regions:
    pci_release_regions(pdev);
 err_out_disable:
-   pci_disable_device(pdev);
+   if (!pci_dev_busy)
+      pci_disable_device(pdev);
 err_out:
    return rc;
 }


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.