Print this page
1023 nv_sata support for NVIDIA MCP61

@@ -19,16 +19,17 @@
  * CDDL HEADER END
  */
 
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*
  *
- * nv_sata is a combo SATA HBA driver for ck804/mcp5x (mcp5x = mcp55/mcp51)
- * based chipsets.
+ * nv_sata is a combo SATA HBA driver for CK804/MCP04 (ck804) and
+ * MCP55/MCP51/MCP61 (mcp5x) based chipsets.
  *
  * NCQ
  * ---
  *
  * A portion of the NCQ is in place, but is incomplete.  NCQ is disabled

@@ -310,11 +311,11 @@
 
 extern struct mod_ops mod_driverops;
 
 static  struct modldrv modldrv = {
         &mod_driverops, /* driverops */
-        "Nvidia ck804/mcp51/mcp55 HBA",
+        "NVIDIA CK804/MCP04/MCP51/MCP55/MCP61 HBA",
         &nv_dev_ops,    /* driver ops */
 };
 
 static  struct modlinkage modlinkage = {
         MODREV_1,

@@ -597,15 +598,18 @@
                 NVLOG(NVDBG_INIT, nvc, NULL, "nv_attach(): DDI_ATTACH", NULL);
 
                 attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
 
                 if (pci_config_setup(dip, &pci_conf_handle) == DDI_SUCCESS) {
+                        nvc->nvc_devid = pci_config_get16(pci_conf_handle,
+                            PCI_CONF_DEVID);
                         nvc->nvc_revid = pci_config_get8(pci_conf_handle,
                             PCI_CONF_REVID);
                         NVLOG(NVDBG_INIT, nvc, NULL,
-                            "inst %d: silicon revid is %x nv_debug_flags=%x",
-                            inst, nvc->nvc_revid, nv_debug_flags);
+                            "inst %d: devid is %x silicon revid is %x"
+                            " nv_debug_flags=%x", inst, nvc->nvc_devid,
+                            nvc->nvc_revid, nv_debug_flags);
                 } else {
                         break;
                 }
 
                 attach_state |= ATTACH_PROGRESS_CONF_HANDLE;

@@ -2492,11 +2496,11 @@
         nv_setup_timeout(nvp, nvp->nvp_wait_sig);
 }
 
 
 /*
- * Initialize register handling specific to mcp51/mcp55
+ * Initialize register handling specific to mcp51/mcp55/mcp61
  */
 /* ARGSUSED */
 static void
 mcp5x_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
 {

@@ -2547,16 +2551,18 @@
         /*
          * mcp55 rev A03 and above supports 40-bit physical addressing.
          * Enable DMA to take advantage of that.
          *
          */
-        if (nvc->nvc_revid >= 0xa3) {
+        if ((nvc->nvc_devid > 0x37f) ||
+            ((nvc->nvc_devid == 0x37f) && (nvc->nvc_revid >= 0xa3))) {
                 if (nv_sata_40bit_dma == B_TRUE) {
                         uint32_t reg32;
                         NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
-                            "rev id is %X.  40-bit DMA addressing"
-                            " enabled", nvc->nvc_revid);
+                            "devid is %X revid is %X. 40-bit DMA"
+                            " addressing enabled", nvc->nvc_devid,
+                            nvc->nvc_revid);
                         nvc->dma_40bit = B_TRUE;
 
                         reg32 = pci_config_get32(pci_conf_handle,
                             NV_SATA_CFG_20);
                         pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,

@@ -2577,12 +2583,13 @@
                 } else {
                         NVLOG(NVDBG_INIT, nvp->nvp_ctlp, nvp,
                             "40-bit DMA disabled by nv_sata_40bit_dma", NULL);
                 }
         } else {
-                nv_cmn_err(CE_NOTE, nvp->nvp_ctlp, nvp, "rev id is %X and is "
-                    "not capable of 40-bit DMA addressing", nvc->nvc_revid);
+                nv_cmn_err(CE_NOTE, nvp->nvp_ctlp, nvp, "devid is %X revid is"
+                    " %X. Not capable of 40-bit DMA addressing",
+                    nvc->nvc_devid, nvc->nvc_revid);
         }
 }
 
 
 /*

@@ -2640,23 +2647,20 @@
 static int
 nv_init_ctl(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
 {
         struct sata_hba_tran stran;
         nv_port_t *nvp;
-        int j, ck804;
+        int j;
         uchar_t *cmd_addr, *ctl_addr, *bm_addr;
         ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
         uchar_t *bar5  = nvc->nvc_bar_addr[5];
         uint32_t reg32;
         uint8_t reg8, reg8_save;
 
         NVLOG(NVDBG_INIT, nvc, NULL, "nv_init_ctl entered", NULL);
 
-        ck804 = B_TRUE;
-#ifdef SGPIO_SUPPORT
         nvc->nvc_mcp5x_flag = B_FALSE;
-#endif
 
         /*
          * Need to set bit 2 to 1 at config offset 0x50
          * to enable access to the bar5 registers.
          */

@@ -2683,25 +2687,26 @@
                 nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), j);
                 reg8 = nv_get8(bar5_hdl,
                     (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
 
                 if (reg8 != j) {
-                        ck804 = B_FALSE;
                         nvc->nvc_mcp5x_flag = B_TRUE;
                         break;
                 }
         }
 
         nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), reg8_save);
 
-        if (ck804 == B_TRUE) {
-                NVLOG(NVDBG_INIT, nvc, NULL, "controller is CK804", NULL);
+        if (nvc->nvc_mcp5x_flag == B_FALSE) {
+                NVLOG(NVDBG_INIT, nvc, NULL, "controller is CK804/MCP04",
+                    NULL);
                 nvc->nvc_interrupt = ck804_intr;
                 nvc->nvc_reg_init = ck804_reg_init;
                 nvc->nvc_set_intr = ck804_set_intr;
         } else {
-                NVLOG(NVDBG_INIT, nvc, NULL, "controller is MCP51/MCP55", NULL);
+                NVLOG(NVDBG_INIT, nvc, NULL, "controller is MCP51/MCP55/MCP61",
+                    NULL);
                 nvc->nvc_interrupt = mcp5x_intr;
                 nvc->nvc_reg_init = mcp5x_reg_init;
                 nvc->nvc_set_intr = mcp5x_set_intr;
         }