diff options
author | sos <sos@FreeBSD.org> | 2007-04-06 16:18:59 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2007-04-06 16:18:59 +0000 |
commit | ad1c8d45dd9e00e35ba116b6533afa81d61ba468 (patch) | |
tree | 201e448cb2148165a217198cea1f94fee5c60221 /sys/dev | |
parent | 6bf6173310e7cae2c2f38a95c34f0158596cb441 (diff) | |
download | FreeBSD-src-ad1c8d45dd9e00e35ba116b6533afa81d61ba468.zip FreeBSD-src-ad1c8d45dd9e00e35ba116b6533afa81d61ba468.tar.gz |
Add support for 64bit addressing to AHCI and Marvell controllers.
Munged into ATA shape and Marvell specifics my yours truely.
Submitted by: jhb
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/ata-all.h | 1 | ||||
-rw-r--r-- | sys/dev/ata/ata-chipset.c | 29 | ||||
-rw-r--r-- | sys/dev/ata/ata-dma.c | 10 | ||||
-rw-r--r-- | sys/dev/ata/ata-lowlevel.c | 1 | ||||
-rw-r--r-- | sys/dev/ata/ata_if.m | 2 |
5 files changed, 28 insertions, 15 deletions
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 2b410a0..31da23b 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -445,6 +445,7 @@ struct ata_dma { #define ATA_DMA_READ 0x01 /* transaction is a read */ #define ATA_DMA_LOADED 0x02 /* DMA tables etc loaded */ #define ATA_DMA_ACTIVE 0x04 /* DMA transfer in progress */ +#define ATA_DMA_64BIT 0x10 /* supports 64bit addressing */ void (*alloc)(device_t dev); void (*free)(device_t dev); diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index be7451b..38ba71b 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -503,6 +503,7 @@ ata_ahci_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; int offset = ch->unit << 7; /* set the SATA resources */ @@ -521,13 +522,13 @@ ata_ahci_allocate(device_t dev) ch->hw.command = NULL; /* not used here */ /* setup work areas */ - ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, - ch->dma->work_bus + ATA_AHCI_CL_OFFSET); - ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, 0x00000000); + work = ch->dma->work_bus + ATA_AHCI_CL_OFFSET; + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, work & 0xffffffff); + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, work >> 32); - ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FB + offset, - ch->dma->work_bus + ATA_AHCI_FB_OFFSET); - ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBU + offset, 0x00000000); + work = ch->dma->work_bus + ATA_AHCI_FB_OFFSET; + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FB + offset, work & 0xffffffff); + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBU + offset, work >> 32); /* enable wanted port interrupts */ ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IE + offset, @@ -766,6 +767,7 @@ ata_ahci_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) static void ata_ahci_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); @@ -773,6 +775,8 @@ ata_ahci_dmainit(device_t dev) /* note start and stop are not used here */ ch->dma->setprd = ata_ahci_dmasetprd; ch->dma->max_iosize = 8192 * DEV_BSIZE; + if (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_CAP_64BIT) + ch->dma->flags |= ATA_DMA_64BIT; } } @@ -2417,7 +2421,7 @@ 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); - bus_addr_t work = ch->dma->work_bus; + u_int64_t work = ch->dma->work_bus; int i; /* clear work area */ @@ -2470,7 +2474,7 @@ ata_marvell_edma_allocate(device_t dev) 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 >> 16) >> 16); + ATA_OUTL(ctlr->r_res1, 0x02010 + ATA_MV_EDMA_BASE(ch), work >> 32); /* request queue in ptr */ ATA_OUTL(ctlr->r_res1, 0x02014 + ATA_MV_EDMA_BASE(ch), work & 0xffffffff); @@ -2480,7 +2484,7 @@ ata_marvell_edma_allocate(device_t dev) /* response queue base high */ work += 1024; - ATA_OUTL(ctlr->r_res1, 0x0201c + ATA_MV_EDMA_BASE(ch), (work >> 16) >> 16); + ATA_OUTL(ctlr->r_res1, 0x0201c + ATA_MV_EDMA_BASE(ch), work >> 32); /* response queue in ptr */ ATA_OUTL(ctlr->r_res1, 0x02020 + ATA_MV_EDMA_BASE(ch), 0x0); @@ -2568,7 +2572,7 @@ ata_marvell_edma_begin_transaction(struct ata_request *request) /* fill in this request */ quadp[0] = (long)ch->dma->sg_bus & 0xffffffff; - quadp[1] = (ch->dma->sg_bus & 0xffffffff00000000ull) >> 32; + quadp[1] = (u_int64_t)ch->dma->sg_bus >> 32; wordp[4] = (request->flags & ATA_R_READ ? 0x01 : 0x00) | (tag<<1); i = 10; @@ -2721,12 +2725,17 @@ ata_marvell_edma_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs, static void 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_edma_dmasetprd; + +device_printf(dev, "HW qword=%08x\n", ATA_INL(ctlr->r_res1, 0x00d00)); + if (ATA_INL(ctlr->r_res1, 0x00d00) & 0x00000004) + ch->dma->flags |= ATA_DMA_64BIT; } } diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 0c1ecaf..fbe23f0 100644 --- a/sys/dev/ata/ata-dma.c +++ b/sys/dev/ata/ata-dma.c @@ -95,22 +95,24 @@ ata_dmaalloc(device_t dev) { struct ata_channel *ch = device_get_softc(dev); struct ata_dc_cb_args ccba; + int maxaddr = (ch->dma->flags & ATA_DMA_64BIT ? + BUS_SPACE_MAXADDR : BUS_SPACE_MAXADDR_32BIT); if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma->alignment, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + maxaddr, BUS_SPACE_MAXADDR, NULL, NULL, ch->dma->max_iosize, ATA_DMA_ENTRIES, ch->dma->segsize, 0, NULL, NULL, &ch->dma->dmatag)) goto error; if (bus_dma_tag_create(ch->dma->dmatag, PAGE_SIZE, PAGE_SIZE, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + maxaddr, BUS_SPACE_MAXADDR, NULL, NULL, MAXTABSZ, 1, MAXTABSZ, 0, NULL, NULL, &ch->dma->sg_tag)) goto error; if (bus_dma_tag_create(ch->dma->dmatag,ch->dma->alignment,ch->dma->boundary, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + maxaddr, BUS_SPACE_MAXADDR, NULL, NULL, ch->dma->max_iosize, ATA_DMA_ENTRIES, ch->dma->segsize, 0, NULL, NULL, &ch->dma->data_tag)) @@ -131,7 +133,7 @@ ata_dmaalloc(device_t dev) goto error; if (bus_dma_tag_create(ch->dma->dmatag, PAGE_SIZE, 64 * 1024, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + maxaddr, BUS_SPACE_MAXADDR, NULL, NULL, MAXWSPCSZ, 1, MAXWSPCSZ, 0, NULL, NULL, &ch->dma->work_tag)) goto error; diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 4150865..07e7184 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -102,6 +102,7 @@ ata_begin_transaction(struct ata_request *request) /* device reset doesn't interrupt */ if (request->u.ata.command == ATA_DEVICE_RESET) { + int timeout = 1000000; do { DELAY(10); diff --git a/sys/dev/ata/ata_if.m b/sys/dev/ata/ata_if.m index 19d6987..2621fef 100644 --- a/sys/dev/ata/ata_if.m +++ b/sys/dev/ata/ata_if.m @@ -1,4 +1,4 @@ -# Copyright (c) 2004 - 2006 Søren Schmidt <sos@FreeBSD.org> +# Copyright (c) 2004 - 2007 Søren Schmidt <sos@FreeBSD.org> # All rights reserved. # # Redistribution and use in source and binary forms, with or without |