kern/116010: [patch] Added Marvell 6101/6145 PATA support for 6.2-STABLE

Dwight Berendse dwight at berendse.org
Sun Sep 2 03:40:08 PDT 2007


>Number:         116010
>Category:       kern
>Synopsis:       [patch] Added Marvell 6101/6145 PATA support for 6.2-STABLE
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Sep 02 10:40:07 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Dwight Berendse
>Release:        FreeBSD 6.2-STABLE i386
>Organization:
not applicable
>Environment:
System: FreeBSD duocore.lan 6.2-STABLE FreeBSD 6.2-STABLE #1: Wed Aug 29 17:36:5
6 CEST 2007     spyro at duocore.lan:/usr/src/sys/i386/compile/SMP  i386

>Description:
	Since I have one of those new Intel boards with the Marvell
	6101/6145 PATA chipset I have taken the liberty to merge the
	relevant sourcecode from FreeBSD-7-CURRENT and merged it with
	FreeBSD-6.2-STABLE (MFC). I've tested it for 3 days now and it
	seems to work perfect. It would be nice if this support was
	added into the source of STABLE; patch included.
>How-To-Repeat:
	Not applicable; simply not supported at the moment.
>Fix:
	MFC into FreeBSD6.2-STABLE, see patch below.

--- ata-chipset.c.diff begins here ---
--- sys/dev/ata/ata-chipset.c	2007-07-04 14:29:15.000000000 +0200
+++ /sys/dev/ata/marvell_patch/ata-chipset.c	2007-08-30 17:04:02.000000000 +0200
@@ -105,14 +105,17 @@
 static void ata_jmicron_reset(device_t dev);
 static void ata_jmicron_dmainit(device_t dev);
 static void ata_jmicron_setmode(device_t dev, int mode);
-static int ata_marvell_chipinit(device_t dev);
-static int ata_marvell_allocate(device_t dev);
-static int ata_marvell_status(device_t dev);
-static int ata_marvell_begin_transaction(struct ata_request *request);
-static int ata_marvell_end_transaction(struct ata_request *request);
-static void ata_marvell_reset(device_t dev);
-static void ata_marvell_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
-static void ata_marvell_dmainit(device_t dev);
+static int ata_marvell_pata_chipinit(device_t dev);
+static int ata_marvell_pata_allocate(device_t dev);
+static void ata_marvell_pata_setmode(device_t dev, int mode);
+static int ata_marvell_edma_chipinit(device_t dev);
+static int ata_marvell_edma_allocate(device_t dev);
+static int ata_marvell_edma_status(device_t dev);
+static int ata_marvell_edma_begin_transaction(struct ata_request *request);
+static int ata_marvell_edma_end_transaction(struct ata_request *request);
+static void ata_marvell_edma_reset(device_t dev);
+static void ata_marvell_edma_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
+static void ata_marvell_edma_dmainit(device_t dev);
 static int ata_national_chipinit(device_t dev);
 static void ata_national_setmode(device_t dev, int mode);
 static int ata_netcell_chipinit(device_t dev);
@@ -2318,12 +2321,14 @@
     struct ata_pci_controller *ctlr = device_get_softc(dev);
     struct ata_chip_id *idx;
     static struct ata_chip_id ids[] =
-    {{ ATA_M88SX5040, 0, 4, MV5XXX, ATA_SA150, "88SX5040" },
-     { ATA_M88SX5041, 0, 4, MV5XXX, ATA_SA150, "88SX5041" },
-     { ATA_M88SX5080, 0, 8, MV5XXX, ATA_SA150, "88SX5080" },
-     { ATA_M88SX5081, 0, 8, MV5XXX, ATA_SA150, "88SX5081" },
-     { ATA_M88SX6041, 0, 4, MV6XXX, ATA_SA300, "88SX6041" },
-     { ATA_M88SX6081, 0, 8, MV6XXX, ATA_SA300, "88SX6081" },
+    {{ ATA_M88SX5040, 0, 4, MV50XX, ATA_SA150, "88SX5040" },
+     { ATA_M88SX5041, 0, 4, MV50XX, ATA_SA150, "88SX5041" },
+     { ATA_M88SX5080, 0, 8, MV50XX, ATA_SA150, "88SX5080" },
+     { ATA_M88SX5081, 0, 8, MV50XX, ATA_SA150, "88SX5081" },
+     { ATA_M88SX6041, 0, 4, MV60XX, ATA_SA300, "88SX6041" },
+     { ATA_M88SX6081, 0, 8, MV60XX, ATA_SA300, "88SX6081" },
+     { ATA_M88SX6101, 0, 1, MV61XX, ATA_UDMA6, "88SX6101" },
+     { ATA_M88SX6145, 0, 2, MV61XX, ATA_UDMA6, "88SX6145" },
      { 0, 0, 0, 0, 0, 0}};
     char buffer[64];
 
@@ -2334,12 +2339,62 @@
 	    idx->text, ata_mode2str(idx->max_dma));
     device_set_desc_copy(dev, buffer);
     ctlr->chip = idx;
-    ctlr->chipinit = ata_marvell_chipinit;
+    switch (ctlr->chip->cfg2) {
+    case MV50XX:
+    case MV60XX:
+	ctlr->chipinit = ata_marvell_edma_chipinit;
+	break;
+    case MV61XX:
+	ctlr->chipinit = ata_marvell_pata_chipinit;
+	break;
+    }
     return 0;
 }
 
 static int
-ata_marvell_chipinit(device_t dev)
+ata_marvell_pata_chipinit(device_t dev)
+{
+    struct ata_pci_controller *ctlr = device_get_softc(dev);
+
+    if (ata_setup_interrupt(dev))
+	return ENXIO;
+
+    ctlr->allocate = ata_marvell_pata_allocate;
+    ctlr->setmode = ata_marvell_pata_setmode;
+    ctlr->channels = ctlr->chip->cfg1;
+    return 0;
+}
+
+static int
+ata_marvell_pata_allocate(device_t dev)
+{
+    struct ata_channel *ch = device_get_softc(dev);
+ 
+    /* setup the usual register normal pci style */
+    if (ata_pci_allocate(dev))
+	return ENXIO;
+ 
+    /* dont use 32 bit PIO transfers */
+	ch->flags |= ATA_USE_16BIT;
+
+    return 0;
+}
+
+static void
+ata_marvell_pata_setmode(device_t dev, int mode)
+{
+    device_t gparent = GRANDPARENT(dev);
+    struct ata_pci_controller *ctlr = device_get_softc(gparent);
+    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;
+}
+
+static int
+ata_marvell_edma_chipinit(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
 
@@ -2358,9 +2413,9 @@
     /* mask all PCI interrupts */
     ATA_OUTL(ctlr->r_res1, 0x01d5c, 0x00000000);
 
-    ctlr->allocate = ata_marvell_allocate;
-    ctlr->reset = ata_marvell_reset;
-    ctlr->dmainit = ata_marvell_dmainit;
+    ctlr->allocate = ata_marvell_edma_allocate;
+    ctlr->reset = ata_marvell_edma_reset;
+    ctlr->dmainit = ata_marvell_edma_dmainit;
     ctlr->setmode = ata_sata_setmode;
     ctlr->channels = ctlr->chip->cfg1;
 
@@ -2386,11 +2441,11 @@
 }
 
 static int
-ata_marvell_allocate(device_t dev)
+ata_marvell_edma_allocate(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
-    u_int64_t work = ch->dma->work_bus;
+    bus_addr_t work = ch->dma->work_bus;
     int i;
 
     /* clear work area */
@@ -2408,7 +2463,7 @@
 
     /* set SATA resources */
     switch (ctlr->chip->cfg2) {
-    case MV5XXX:
+    case MV50XX:
 	ch->r_io[ATA_SSTATUS].res = ctlr->r_res1;
 	ch->r_io[ATA_SSTATUS].offset =  0x00100 + ATA_MV_HOST_BASE(ch);
 	ch->r_io[ATA_SERROR].res = ctlr->r_res1;
@@ -2416,7 +2471,7 @@
 	ch->r_io[ATA_SCONTROL].res = ctlr->r_res1;
 	ch->r_io[ATA_SCONTROL].offset = 0x00108 + ATA_MV_HOST_BASE(ch);
 	break;
-    case MV6XXX:
+    case MV60XX:
 	ch->r_io[ATA_SSTATUS].res = ctlr->r_res1;
 	ch->r_io[ATA_SSTATUS].offset =  0x02300 + ATA_MV_EDMA_BASE(ch);
 	ch->r_io[ATA_SERROR].res = ctlr->r_res1;
@@ -2431,9 +2486,9 @@
     ch->flags |= ATA_NO_SLAVE;
     ch->flags |= ATA_USE_16BIT; /* XXX SOS needed ? */
     ata_generic_hw(dev);
-    ch->hw.begin_transaction = ata_marvell_begin_transaction;
-    ch->hw.end_transaction = ata_marvell_end_transaction;
-    ch->hw.status = ata_marvell_status;
+    ch->hw.begin_transaction = ata_marvell_edma_begin_transaction;
+    ch->hw.end_transaction = ata_marvell_edma_end_transaction;
+    ch->hw.status = ata_marvell_edma_status;
 
     /* disable the EDMA machinery */
     ATA_OUTL(ctlr->r_res1, 0x02028 + ATA_MV_EDMA_BASE(ch), 0x00000002);
@@ -2443,7 +2498,7 @@
     ATA_OUTL(ctlr->r_res1, 0x02000 + ATA_MV_EDMA_BASE(ch), (1<<11) | (1<<13));
 
     /* request queue base high */
-    ATA_OUTL(ctlr->r_res1, 0x02010 + ATA_MV_EDMA_BASE(ch), work >> 32);
+    ATA_OUTL(ctlr->r_res1, 0x02010 + ATA_MV_EDMA_BASE(ch), (work >> 16) >> 16);
 
     /* request queue in ptr */
     ATA_OUTL(ctlr->r_res1, 0x02014 + ATA_MV_EDMA_BASE(ch), work & 0xffffffff);
@@ -2453,7 +2508,7 @@
 
     /* response queue base high */
     work += 1024;
-    ATA_OUTL(ctlr->r_res1, 0x0201c + ATA_MV_EDMA_BASE(ch), work >> 32);
+    ATA_OUTL(ctlr->r_res1, 0x0201c + ATA_MV_EDMA_BASE(ch), (work >> 16) >> 16);
 
     /* response queue in ptr */
     ATA_OUTL(ctlr->r_res1, 0x02020 + ATA_MV_EDMA_BASE(ch), 0x0);
@@ -2476,7 +2531,7 @@
 }
 
 static int
-ata_marvell_status(device_t dev)
+ata_marvell_edma_status(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
@@ -2530,7 +2585,7 @@
 
 /* must be called with ATA channel locked and state_mtx held */
 static int
-ata_marvell_begin_transaction(struct ata_request *request)
+ata_marvell_edma_begin_transaction(struct ata_request *request)
 {
     struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
     struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
@@ -2573,7 +2628,7 @@
 
     /* fill in this request */
     quadp[0] = (long)ch->dma->sg_bus & 0xffffffff;
-    quadp[1] = (u_int64_t)ch->dma->sg_bus >> 32;
+    quadp[1] = (ch->dma->sg_bus & 0xffffffff00000000ull) >> 32;
     wordp[4] = (request->flags & ATA_R_READ ? 0x01 : 0x00) | (tag<<1);
 
     i = 10;
@@ -2622,7 +2677,7 @@
 
 /* must be called with ATA channel locked and state_mtx held */
 static int
-ata_marvell_end_transaction(struct ata_request *request)
+ata_marvell_edma_end_transaction(struct ata_request *request)
 {
     struct ata_pci_controller *ctlr=device_get_softc(GRANDPARENT(request->dev));
     struct ata_channel *ch = device_get_softc(device_get_parent(request->dev));
@@ -2676,7 +2731,7 @@
 }
 
 static void
-ata_marvell_reset(device_t dev)
+ata_marvell_edma_reset(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
@@ -2703,7 +2758,8 @@
 }
 
 static void
-ata_marvell_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
+ata_marvell_edma_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs,
+			   int error)
 {
     struct ata_dmasetprd_args *args = xsc;
     struct ata_marvell_dma_prdentry *prd = args->dmatab;
@@ -2714,25 +2770,21 @@
 
     for (i = 0; i < nsegs; i++) {
 	prd[i].addrlo = htole32(segs[i].ds_addr);
+	prd[i].addrhi = 0;
 	prd[i].count = htole32(segs[i].ds_len);
-	prd[i].addrhi = htole32((u_int64_t)segs[i].ds_addr >> 32);
     }
     prd[i - 1].count |= htole32(ATA_DMA_EOT);
 }
 
 static void
-ata_marvell_dmainit(device_t dev)
+ata_marvell_edma_dmainit(device_t dev)
 {
-    struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
 
     ata_dmainit(dev);
     if (ch->dma) {
 	/* note start and stop are not used here */
-	ch->dma->setprd = ata_marvell_dmasetprd;
-	
-	if (ATA_INL(ctlr->r_res1, 0x00d00) & 0x00000004)
-	    ch->dma->max_address = BUS_SPACE_MAXADDR;
+	ch->dma->setprd = ata_marvell_edma_dmasetprd;
     }
 }
 
--- ata-chipset.c.diff ends here ---

--- ata-pci.h.diff begins here ---
--- sys/dev/ata/ata-pci.h	2007-02-12 00:46:45.000000000 +0100
+++ /sys/dev/ata/marvell_patch/ata-pci.h	2007-08-30 23:08:22.000000000 +0200
@@ -187,6 +187,8 @@
 #define ATA_M88SX5081           0x508111ab
 #define ATA_M88SX6041           0x604111ab
 #define ATA_M88SX6081           0x608111ab
+#define ATA_M88SX6101           0x610111ab
+#define ATA_M88SX6145           0x614511ab
 
 #define ATA_MICRON_ID           0x1042
 #define ATA_MICRON_RZ1000       0x10001042
@@ -367,8 +369,9 @@
 #define HPT374          3
 #define HPTOLD          0x01
 
-#define MV5XXX          5
-#define MV6XXX          6
+#define MV50XX          50
+#define MV60XX          60
+#define MV61XX          61
 
 #define PROLD           0
 #define PRNEW           1
--- ata-pci.h.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list