summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-11-13 22:53:49 +0000
committermav <mav@FreeBSD.org>2009-11-13 22:53:49 +0000
commit5fe8543b993cea03f49828ffd109a114bb422252 (patch)
tree6a814ae1f0956ab0c85767feee8a6e82d078ca3b /sys/dev
parent54fc6843452906e37c5d1a6e731763bc2f5d8a9d (diff)
downloadFreeBSD-src-5fe8543b993cea03f49828ffd109a114bb422252.zip
FreeBSD-src-5fe8543b993cea03f49828ffd109a114bb422252.tar.gz
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
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ata/ata-pci.h3
-rw-r--r--sys/dev/ata/chipsets/ata-marvell.c94
2 files changed, 72 insertions, 25 deletions
diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 66a25c4..00c5962 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -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
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index 346fed5..f08a288 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -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
OpenPOWER on IntegriCloud