Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Nov 2009 22:53:49 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r199259 - in head/sys/dev/ata: . chipsets
Message-ID:  <200911132253.nADMrnPb080127@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Nov 13 22:53:49 2009
New Revision: 199259
URL: http://svn.freebsd.org/changeset/base/199259

Log:
  Add support for SATA ports on SATA+PATA Marvell controllers.
  These controllers provide combination of AHCI for SATA and legacy
  PCI ATA for PATA. Use same solution as used for JMicron controllers.
  Add IDs of Marvell 88SX6102, 88SX6111. 88SX6141 alike controllers

Modified:
  head/sys/dev/ata/ata-pci.h
  head/sys/dev/ata/chipsets/ata-marvell.c

Modified: head/sys/dev/ata/ata-pci.h
==============================================================================
--- head/sys/dev/ata/ata-pci.h	Fri Nov 13 21:06:33 2009	(r199258)
+++ head/sys/dev/ata/ata-pci.h	Fri Nov 13 22:53:49 2009	(r199259)
@@ -225,7 +225,10 @@ struct ata_pci_controller {
 #define ATA_M88SX6081           0x608111ab
 #define ATA_M88SX7042           0x704211ab
 #define ATA_M88SX6101           0x610111ab
+#define ATA_M88SX6102           0x610211ab
+#define ATA_M88SX6111           0x611111ab
 #define ATA_M88SX6121           0x612111ab
+#define ATA_M88SX6141           0x614111ab
 #define ATA_M88SX6145           0x614511ab
 
 #define ATA_MICRON_ID           0x1042

Modified: head/sys/dev/ata/chipsets/ata-marvell.c
==============================================================================
--- head/sys/dev/ata/chipsets/ata-marvell.c	Fri Nov 13 21:06:33 2009	(r199258)
+++ head/sys/dev/ata/chipsets/ata-marvell.c	Fri Nov 13 22:53:49 2009	(r199259)
@@ -52,9 +52,11 @@ __FBSDID("$FreeBSD$");
 #include <ata_if.h>
 
 /* local prototypes */
-static int ata_marvell_pata_chipinit(device_t dev);
-static int ata_marvell_pata_ch_attach(device_t dev);
-static void ata_marvell_pata_setmode(device_t dev, int mode);
+static int ata_marvell_chipinit(device_t dev);
+static int ata_marvell_ch_attach(device_t dev);
+static int ata_marvell_ch_detach(device_t dev);
+static void ata_marvell_setmode(device_t dev, int mode);
+static void ata_marvell_reset(device_t dev);
 static int ata_marvell_edma_ch_attach(device_t dev);
 static int ata_marvell_edma_ch_detach(device_t dev);
 static int ata_marvell_edma_status(device_t dev);
@@ -107,9 +109,12 @@ ata_marvell_probe(device_t dev)
      { ATA_M88SX6042, 0, 4, MV_6042, ATA_SA300, "88SX6042" },
      { ATA_M88SX6081, 0, 8, MV_60XX, ATA_SA300, "88SX6081" },
      { ATA_M88SX7042, 0, 4, MV_7042, ATA_SA300, "88SX7042" },
-     { ATA_M88SX6101, 0, 1, MV_61XX, ATA_UDMA6, "88SX6101" },
-     { ATA_M88SX6121, 0, 1, MV_61XX, ATA_UDMA6, "88SX6121" },
-     { ATA_M88SX6145, 0, 2, MV_61XX, ATA_UDMA6, "88SX6145" },
+     { ATA_M88SX6101, 0, 0, MV_61XX, ATA_UDMA6, "88SX6101" },
+     { ATA_M88SX6102, 0, 0, MV_61XX, ATA_UDMA6, "88SX6102" },
+     { ATA_M88SX6111, 0, 1, MV_61XX, ATA_SA300, "88SX6111" },
+     { ATA_M88SX6121, 0, 2, MV_61XX, ATA_SA300, "88SX6121" },
+     { ATA_M88SX6141, 0, 4, MV_61XX, ATA_SA300, "88SX6141" },
+     { ATA_M88SX6145, 0, 4, MV_61XX, ATA_SA300, "88SX6145" },
      { 0, 0, 0, 0, 0, 0}};
 
     if (pci_get_vendor(dev) != ATA_MARVELL_ID)
@@ -128,53 +133,92 @@ ata_marvell_probe(device_t dev)
 	ctlr->chipinit = ata_marvell_edma_chipinit;
 	break;
     case MV_61XX:
-	ctlr->chipinit = ata_marvell_pata_chipinit;
+	ctlr->chipinit = ata_marvell_chipinit;
 	break;
     }
     return (BUS_PROBE_DEFAULT);
 }
 
 static int
-ata_marvell_pata_chipinit(device_t dev)
+ata_marvell_chipinit(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
+    int error = 0;
 
     if (ata_setup_interrupt(dev, ata_generic_intr))
 	return ENXIO;
 
-    ctlr->ch_attach = ata_marvell_pata_ch_attach;
-    ctlr->ch_detach = ata_pci_ch_detach;
-    ctlr->setmode = ata_marvell_pata_setmode;
-    ctlr->channels = ctlr->chip->cfg1;
-    return 0;
+    if (ctlr->chip->cfg1 && (error = ata_ahci_chipinit(dev)))
+	return (error);    
+    ctlr->ch_attach = ata_marvell_ch_attach;
+    ctlr->ch_detach = ata_marvell_ch_detach;
+    ctlr->reset = ata_marvell_reset;
+    ctlr->setmode = ata_marvell_setmode;
+    ctlr->channels = ctlr->chip->cfg1 + 1;
+    return (0);
 }
 
 static int
-ata_marvell_pata_ch_attach(device_t dev)
+ata_marvell_ch_attach(device_t dev)
 {
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
+    int error;
  
-    /* setup the usual register normal pci style */
-    if (ata_pci_ch_attach(dev))
-	return ENXIO;
- 
-    /* dont use 32 bit PIO transfers */
+    if (ch->unit >= ctlr->chip->cfg1) {
+	ch->unit -= ctlr->chip->cfg1;
+	error = ata_pci_ch_attach(dev);
+	ch->unit += ctlr->chip->cfg1;
+    	/* dont use 32 bit PIO transfers */
 	ch->flags |= ATA_USE_16BIT;
+    } else
+	error = ata_ahci_ch_attach(dev);
+    return (error);
+}
 
-    return 0;
+static int
+ata_marvell_ch_detach(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+    int error;
+ 
+    if (ch->unit >= ctlr->chip->cfg1) {
+	ch->unit -= ctlr->chip->cfg1;
+	error = ata_pci_ch_detach(dev);
+	ch->unit += ctlr->chip->cfg1;
+    } else
+	error = ata_ahci_ch_detach(dev);
+    return (error);
+}
+
+static void
+ata_marvell_reset(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
+	
+    if (ch->unit >= ctlr->chip->cfg1)
+	ata_generic_reset(dev);
+    else
+	ata_ahci_reset(dev);
 }
 
 static void
-ata_marvell_pata_setmode(device_t dev, int mode)
+ata_marvell_setmode(device_t dev, int mode)
 {
     device_t gparent = GRANDPARENT(dev);
     struct ata_pci_controller *ctlr = device_get_softc(gparent);
+    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
     struct ata_device *atadev = device_get_softc(dev);
 
-    mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-    mode = ata_check_80pin(dev, mode);
-    if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
-	atadev->mode = mode;
+    if (ch->unit >= ctlr->chip->cfg1) {
+	mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
+	mode = ata_check_80pin(dev, mode);
+	if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
+	    atadev->mode = mode;
+    } else
+	ata_sata_setmode(dev, mode);
 }
 
 int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911132253.nADMrnPb080127>