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