Commit 48e7ce94 authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Richard Henderson

[PATCH] alpha ISA dma and MAX_DMA_ADDRESS

Thanks David Miller, Jay Estabrook and Richard Henderson for
reviewing the patch and for corrections.

Description:

The ISA dma falls into 2 classes.
1. True busmastering (aka DMA_MODE_CASCADE) when the ISA device
   generate bus addresses by itself. Obviously, such devices are
   limited to lower 16 Mb as there are only 24 address lines on
   the ISA bus. Drivers for these devices pass NULL pdev
   argument to pci mapping functions, and we must always use
   dma_mask = 0x00ffffff in this case.
2. ISA devices using i8237 DMA controller functionality:
   floppy, all soundcards (AFAIK) and a lot of other cheap ISA cards.
   In this case actual device doing DMA is a PCI-to-ISA bridge.
   Quite a few of ISA bridges can do 32-bit DMA (using "high page"
   extensions), and alpha traditionally uses this.

I propose the following:
introduce 'struct pci_dev *isa_bridge' global variable; this
will be pointer to either real bridge device found by pci
probing code, or a fake device in special cases (like jensen running
generic kernel). isa_bridge->dma_mask will be set depending on DMA
capabilities of particular bridge (either using generic quirk list or
in an arch specific manner).
This would allow devices like floppy and audio utilize 32-bit DMA
just by replacing 'NULL' with 'isa_bridge' in the pci mapping calls.

Also, this helps to resolve ISA dma vs. MAX_DMA_ADDRESS mess on alpha.
Setting MAX_DMA_ADDRESS depending on the number of address lines
on the ISA bridge became bogus since early 2.4 when we started to
use the SG windows. Basically, if we have a working iommu, we don't
have any dma limitations. All we need is a correct dma_mask to choose
proper dma window.
OTOH, there are 'iommuless' alphas (rx164, nautilus, possibly early
miata) which need to have 16 Mb GFP_DMA zone (just like i386) even
if their ISA bridge is 32-bit.

Proposed changes:
- rename all XXX_MAX_DMA_ADDRESS to XXX_MAX_ISA_DMA_ADDRESS;
  alpha_mv.max_dma_address - ditto (it's about 90% of the patch);
- ISA bridge on nautilus does support 32-bit dma;
- MAX_DMA_ADDRESS is 16 Mb if there is no iommu, ~0UL (unlimited)
  otherwise;
- if needed, fall back to GFP_DMA allocations in
  pci_alloc_consistent();
- pci_dma_supported() also returns success if GFP_DMA is helpful;
- isa_bridge stuff. Used only by floppy as yet.

Ivan.
parent 71660e15
......@@ -117,6 +117,18 @@ quirk_cypress(struct pci_dev *dev)
}
}
/* Called for each device after PCI setup is done. */
static void __init
pcibios_fixup_final(struct pci_dev *dev)
{
unsigned int class = dev->class >> 8;
if (class == PCI_CLASS_BRIDGE_ISA || class == PCI_CLASS_BRIDGE_ISA) {
dev->dma_mask = MAX_ISA_DMA_ADDRESS - 1;
isa_bridge = dev;
}
}
struct pci_fixup pcibios_fixups[] __initdata = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
quirk_eisa_bridge },
......@@ -126,6 +138,8 @@ struct pci_fixup pcibios_fixups[] __initdata = {
quirk_ali_ide_ports },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693,
quirk_cypress },
{ PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID,
pcibios_fixup_final },
{ 0 }
};
......
......@@ -30,9 +30,7 @@
#define DEBUG_NODIRECT 0
#define DEBUG_FORCEDAC 0
/* Most Alphas support 32-bit ISA DMA. Exceptions are XL, Ruffian,
Nautilus, Sable, and Alcor (see asm-alpha/dma.h for details). */
#define ISA_DMA_MASK (MAX_DMA_ADDRESS - IDENT_ADDR - 1)
#define ISA_DMA_MASK 0x00ffffff
static inline unsigned long
mk_iommu_pte(unsigned long paddr)
......@@ -189,6 +187,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
long npages, dma_ofs, i;
unsigned long paddr;
dma_addr_t ret;
unsigned int align = 0;
paddr = __pa(cpu_addr);
......@@ -216,17 +215,14 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
}
/* If the machine doesn't define a pci_tbi routine, we have to
assume it doesn't support sg mapping. */
assume it doesn't support sg mapping, and, since we tried to
use direct_map above, it now must be considered an error. */
if (! alpha_mv.mv_pci_tbi) {
static int been_here = 0;
static int been_here = 0; /* Only print the message once. */
if (!been_here) {
printk(KERN_WARNING "pci_map_single: no hw sg, using "
"direct map when possible\n");
printk(KERN_WARNING "pci_map_single: no HW sg\n");
been_here = 1;
}
if (paddr + size <= __direct_map_size)
return (paddr + __direct_map_base);
else
return 0;
}
......@@ -235,8 +231,11 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
arena = hose->sg_isa;
npages = calc_npages((paddr & ~PAGE_MASK) + size);
/* Force allocation to 64KB boundary for all ISA devices. */
dma_ofs = iommu_arena_alloc(arena, npages, pdev ? 8 : 0);
/* Force allocation to 64KB boundary for ISA bridges. */
if (pdev && pdev == isa_bridge)
align = 8;
dma_ofs = iommu_arena_alloc(arena, npages, align);
if (dma_ofs < 0) {
printk(KERN_WARNING "pci_map_single failed: "
"could not allocate dma page tables\n");
......@@ -364,8 +363,10 @@ pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
{
void *cpu_addr;
long order = get_order(size);
int gfp = GFP_ATOMIC;
cpu_addr = (void *)__get_free_pages(GFP_ATOMIC, order);
try_again:
cpu_addr = (void *)__get_free_pages(gfp, order);
if (! cpu_addr) {
printk(KERN_INFO "pci_alloc_consistent: "
"get_free_pages failed from %p\n",
......@@ -379,7 +380,12 @@ pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
*dma_addrp = pci_map_single_1(pdev, cpu_addr, size, 0);
if (*dma_addrp == 0) {
free_pages((unsigned long)cpu_addr, order);
if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA))
return NULL;
/* The address doesn't fit required mask and we
do not have iommu. Try again with GFP_DMA. */
gfp |= GFP_DMA;
goto try_again;
}
DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n",
......@@ -727,8 +733,8 @@ pci_dma_supported(struct pci_dev *pdev, u64 mask)
the entire direct mapped space or the total system memory as
shifted by the map base */
if (__direct_map_size != 0
&& (__direct_map_base + __direct_map_size - 1 <= mask
|| __direct_map_base + (max_low_pfn<<PAGE_SHIFT)-1 <= mask))
&& (__direct_map_base + __direct_map_size - 1 <= mask ||
__direct_map_base + (max_low_pfn << PAGE_SHIFT) - 1 <= mask))
return 1;
/* Check that we have a scatter-gather arena that fits. */
......@@ -740,6 +746,10 @@ pci_dma_supported(struct pci_dev *pdev, u64 mask)
if (arena && arena->dma_base + arena->size - 1 <= mask)
return 1;
/* As last resort try ZONE_DMA. */
if (!__direct_map_base && MAX_DMA_ADDRESS - IDENT_ADDR - 1 <= mask)
return 1;
return 0;
}
......
......@@ -251,7 +251,7 @@ struct alpha_machine_vector alcor_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_ALCOR_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
......@@ -281,7 +281,7 @@ struct alpha_machine_vector xlt_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
......
......@@ -327,7 +327,7 @@ struct alpha_machine_vector cabriolet_mv __initmv = {
DO_APECS_IO,
DO_APECS_BUS,
machine_check: apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -355,7 +355,7 @@ struct alpha_machine_vector eb164_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
......@@ -380,7 +380,7 @@ struct alpha_machine_vector eb66p_mv __initmv = {
DO_LCA_IO,
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -405,7 +405,7 @@ struct alpha_machine_vector lx164_mv __initmv = {
DO_PYXIS_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: PYXIS_DAC_OFFSET,
......@@ -431,7 +431,7 @@ struct alpha_machine_vector pc164_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
......
......@@ -572,7 +572,7 @@ struct alpha_machine_vector dp264_mv __initmv = {
DO_TSUNAMI_IO,
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: TSUNAMI_DAC_OFFSET,
......@@ -597,7 +597,7 @@ struct alpha_machine_vector monet_mv __initmv = {
DO_TSUNAMI_IO,
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: TSUNAMI_DAC_OFFSET,
......@@ -621,7 +621,7 @@ struct alpha_machine_vector webbrick_mv __initmv = {
DO_TSUNAMI_IO,
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: TSUNAMI_DAC_OFFSET,
......@@ -645,7 +645,7 @@ struct alpha_machine_vector clipper_mv __initmv = {
DO_TSUNAMI_IO,
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: TSUNAMI_DAC_OFFSET,
......@@ -674,7 +674,7 @@ struct alpha_machine_vector shark_mv __initmv = {
DO_TSUNAMI_IO,
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: TSUNAMI_DAC_OFFSET,
......
......@@ -214,7 +214,7 @@ struct alpha_machine_vector eb64p_mv __initmv = {
DO_APECS_IO,
DO_APECS_BUS,
machine_check: apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -240,7 +240,7 @@ struct alpha_machine_vector eb66_mv __initmv = {
DO_LCA_IO,
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......
......@@ -231,7 +231,7 @@ struct alpha_machine_vector eiger_mv __initmv = {
DO_TSUNAMI_IO,
DO_TSUNAMI_BUS,
machine_check: tsunami_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: TSUNAMI_DAC_OFFSET,
......
......@@ -219,6 +219,11 @@ static void __init
jensen_init_arch(void)
{
struct pci_controller *hose;
#ifdef CONFIG_PCI
static struct pci_dev fake_isa_bridge = { dma_mask: 0xffffffffUL, };
isa_bridge = &fake_isa_bridge;
#endif
/* Create a hose so that we can report i/o base addresses to
userland. */
......@@ -257,7 +262,7 @@ struct alpha_machine_vector jensen_mv __initmv = {
IO_LITE(JENSEN,jensen),
BUS(jensen),
machine_check: jensen_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
rtc_port: 0x170,
nr_irqs: 16,
......
......@@ -267,7 +267,7 @@ struct alpha_machine_vector miata_mv __initmv = {
DO_PYXIS_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: PYXIS_DAC_OFFSET,
......
......@@ -223,7 +223,7 @@ struct alpha_machine_vector mikasa_mv __initmv = {
DO_APECS_IO,
DO_APECS_BUS,
machine_check: mikasa_apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -249,7 +249,7 @@ struct alpha_machine_vector mikasa_primo_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
......
......@@ -516,7 +516,7 @@ struct alpha_machine_vector nautilus_mv __initmv = {
DO_IRONGATE_IO,
DO_IRONGATE_BUS,
machine_check: nautilus_machine_check,
max_dma_address: ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: IRONGATE_DEFAULT_MEM_BASE,
......
......@@ -305,7 +305,7 @@ struct alpha_machine_vector noritake_mv __initmv = {
DO_APECS_IO,
DO_APECS_BUS,
machine_check: noritake_apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -331,7 +331,7 @@ struct alpha_machine_vector noritake_primo_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
......
......@@ -252,7 +252,7 @@ struct alpha_machine_vector rawhide_mv __initmv = {
DO_MCPCIA_IO,
DO_MCPCIA_BUS,
machine_check: mcpcia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: MCPCIA_DEFAULT_MEM_BASE,
pci_dac_offset: MCPCIA_DAC_OFFSET,
......
......@@ -218,7 +218,7 @@ struct alpha_machine_vector ruffian_mv __initmv = {
DO_PYXIS_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_RUFFIAN_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: PYXIS_DAC_OFFSET,
......
......@@ -203,7 +203,7 @@ struct alpha_machine_vector rx164_mv __initmv = {
DO_POLARIS_IO,
DO_POLARIS_BUS,
machine_check: polaris_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
......
......@@ -290,7 +290,7 @@ struct alpha_machine_vector sable_mv __initmv = {
DO_T2_IO,
DO_T2_BUS,
machine_check: t2_machine_check,
max_dma_address: ALPHA_SABLE_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
min_mem_address: T2_DEFAULT_MEM_BASE,
......@@ -322,7 +322,7 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
DO_T2_IO,
DO_T2_BUS,
machine_check: t2_machine_check,
max_dma_address: ALPHA_SABLE_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
min_io_address: EISA_DEFAULT_IO_BASE,
min_mem_address: T2_DEFAULT_MEM_BASE,
......
......@@ -258,7 +258,7 @@ struct alpha_machine_vector alphabook1_mv __initmv = {
DO_LCA_IO,
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -289,7 +289,7 @@ struct alpha_machine_vector avanti_mv __initmv = {
DO_APECS_IO,
DO_APECS_BUS,
machine_check: apecs_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -318,7 +318,7 @@ struct alpha_machine_vector noname_mv __initmv = {
DO_LCA_IO,
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -356,7 +356,7 @@ struct alpha_machine_vector p2k_mv __initmv = {
DO_LCA_IO,
DO_LCA_BUS,
machine_check: lca_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: APECS_AND_LCA_DEFAULT_MEM_BASE,
......@@ -385,7 +385,7 @@ struct alpha_machine_vector xl_mv __initmv = {
DO_APECS_IO,
BUS(apecs),
machine_check: apecs_machine_check,
max_dma_address: ALPHA_XL_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_XL_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: XL_DEFAULT_MEM_BASE,
......
......@@ -160,7 +160,7 @@ struct alpha_machine_vector sx164_mv __initmv = {
DO_PYXIS_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: PYXIS_DAC_OFFSET,
......
......@@ -275,7 +275,7 @@ struct alpha_machine_vector takara_mv __initmv = {
DO_CIA_IO,
DO_CIA_BUS,
machine_check: cia_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
......
......@@ -373,7 +373,7 @@ struct alpha_machine_vector privateer_mv __initmv = {
DO_TITAN_IO,
DO_TITAN_BUS,
machine_check: privateer_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
pci_dac_offset: TITAN_DAC_OFFSET,
......
......@@ -339,7 +339,7 @@ struct alpha_machine_vector wildfire_mv __initmv = {
DO_WILDFIRE_IO,
DO_WILDFIRE_BUS,
machine_check: wildfire_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
max_isa_dma_address: ALPHA_MAX_ISA_DMA_ADDRESS,
min_io_address: DEFAULT_IO_BASE,
min_mem_address: DEFAULT_MEM_BASE,
......
......@@ -642,6 +642,11 @@ device_initcall(pci_init);
__setup("pci=", pci_setup);
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
struct pci_dev *isa_bridge;
EXPORT_SYMBOL(isa_bridge);
#endif
EXPORT_SYMBOL(pci_enable_device);
EXPORT_SYMBOL(pci_disable_device);
EXPORT_SYMBOL(pci_find_capability);
......
......@@ -85,44 +85,47 @@
/* The maximum address for ISA DMA transfer on Alpha XL, due to an
hardware SIO limitation, is 64MB.
*/
#define ALPHA_XL_MAX_DMA_ADDRESS (IDENT_ADDR+0x04000000UL)
#define ALPHA_XL_MAX_ISA_DMA_ADDRESS 0x04000000UL
/* The maximum address for ISA DMA transfer on RUFFIAN and NAUTILUS,
/* The maximum address for ISA DMA transfer on RUFFIAN,
due to an hardware SIO limitation, is 16MB.
*/
#define ALPHA_RUFFIAN_MAX_DMA_ADDRESS (IDENT_ADDR+0x01000000UL)
#define ALPHA_NAUTILUS_MAX_DMA_ADDRESS (IDENT_ADDR+0x01000000UL)
#define ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS 0x01000000UL
/* The maximum address for ISA DMA transfer on SABLE, and some ALCORs,
due to an hardware SIO chip limitation, is 2GB.
*/
#define ALPHA_SABLE_MAX_DMA_ADDRESS (IDENT_ADDR+0x80000000UL)
#define ALPHA_ALCOR_MAX_DMA_ADDRESS (IDENT_ADDR+0x80000000UL)
#define ALPHA_SABLE_MAX_ISA_DMA_ADDRESS 0x80000000UL
#define ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS 0x80000000UL
/*
Maximum address for all the others is the complete 32-bit bus
address space.
*/
#define ALPHA_MAX_DMA_ADDRESS (IDENT_ADDR+0x100000000UL)
#define ALPHA_MAX_ISA_DMA_ADDRESS 0x100000000UL
#ifdef CONFIG_ALPHA_GENERIC
# define MAX_DMA_ADDRESS (alpha_mv.max_dma_address)
# define MAX_ISA_DMA_ADDRESS (alpha_mv.max_isa_dma_address)
#else
# if defined(CONFIG_ALPHA_XL)
# define MAX_DMA_ADDRESS ALPHA_XL_MAX_DMA_ADDRESS
# define MAX_ISA_DMA_ADDRESS ALPHA_XL_MAX_ISA_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_RUFFIAN)
# define MAX_DMA_ADDRESS ALPHA_RUFFIAN_MAX_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_NAUTILUS)
# define MAX_DMA_ADDRESS ALPHA_NAUTILUS_MAX_DMA_ADDRESS
# define MAX_ISA_DMA_ADDRESS ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS
# elif defined(CONFIG_ALPHA_SABLE)
# define MAX_DMA_ADDRESS ALPHA_SABLE_MAX_DMA_ADDRESS
# define MAX_ISA_DMA_ADDRESS ALPHA_SABLE_MAX_DMA_ISA_ADDRESS
# elif defined(CONFIG_ALPHA_ALCOR)
# define MAX_DMA_ADDRESS ALPHA_ALCOR_MAX_DMA_ADDRESS
# define MAX_ISA_DMA_ADDRESS ALPHA_ALCOR_MAX_DMA_ISA_ADDRESS
# else
# define MAX_DMA_ADDRESS ALPHA_MAX_DMA_ADDRESS
# define MAX_ISA_DMA_ADDRESS ALPHA_MAX_ISA_DMA_ADDRESS
# endif
#endif
/* If we have the iommu, we don't have any address limitations on DMA.
Otherwise (Nautilus, RX164), we have to have 0-16 Mb DMA zone
like i386. */
#define MAX_DMA_ADDRESS (alpha_mv.mv_pci_tbi ? \
~0UL : IDENT_ADDR + 0x01000000)
/* 8237 DMA controllers */
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
......
......@@ -51,12 +51,12 @@ alpha_fd_dma_setup(char *addr, unsigned long size, int mode, int io)
if (bus_addr
&& (addr != prev_addr || size != prev_size || dir != prev_dir)) {
/* different from last time -- unmap prev */
pci_unmap_single(NULL, bus_addr, prev_size, prev_dir);
pci_unmap_single(isa_bridge, bus_addr, prev_size, prev_dir);
bus_addr = 0;
}
if (!bus_addr) /* need to map it */
bus_addr = pci_map_single(NULL, addr, size, dir);
bus_addr = pci_map_single(isa_bridge, addr, size, dir);
/* remember this one as prev */
prev_addr = addr;
......
......@@ -34,7 +34,7 @@ struct alpha_machine_vector
int nr_irqs;
int rtc_port;
int max_asn;
unsigned long max_dma_address;
unsigned long max_isa_dma_address;
unsigned long irq_probe_mask;
unsigned long iack_sc;
unsigned long min_io_address;
......
......@@ -643,6 +643,10 @@ void pci_pool_destroy (struct pci_pool *pool);
void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
extern struct pci_dev *isa_bridge;
#endif
#endif /* CONFIG_PCI */
/* Include architecture-dependent settings and functions */
......@@ -703,6 +707,8 @@ static inline int pci_enable_wake(struct pci_dev *dev, u32 state, int enable) {
#define pci_for_each_dev(dev) \
for(dev = NULL; 0; )
#define isa_bridge ((struct pci_dev *)NULL)
#else
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment