Date: Sat, 1 Sep 2007 10:41:47 +0200 (CEST) From: Dwight Berendse <dwight@berendse.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/116010: [patch] Added Marvell 6101/6145 PATA support for 6.2-STABLE Message-ID: <20070901084147.48FB3CFC1FA@mx0.lagnetworks.nl> Resent-Message-ID: <200709021040.l82Ae8gn085909@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070901084147.48FB3CFC1FA>