On Tuesday 05 February 2008 16:46:38 Iain Barker wrote: > FYI, we've been looking at this recently, and the DMA-related PXA patch > from this email thread: > http://lists.infradead.org/pipermail/linux-pcmcia/2007-April/004473.html > > On Wed Apr 4 06:36:35 EDT 2007, Steve Newbury wrote: > > The only way of getting CF devices to run in (U)DMA mode is to physically > > attach them to an IDE controller. CF devices can electrically operate as > > either PCMCIA-like or IDE devices. If operating as a PCMCIA device it > > can only be accessed with IO or MMIO. If you want more performance than > > the 300ns cycle IO access time you need to use MMIO **and set the access > > speed to the correct value for that CF device**, you'll then get much > > higher performace (upto 20MB/s). Using a variation on Thomas Kleffel's > > patch I've tried before, not completely managed to get it working, see > > this lists archives. I couldn't get the interrupt working for some > > reason. > > > > Steve > > The compact flash spec has a feature that allows DMA host controllers to > move data to and from the CF data buffer WHEN USING PIO MODE, more > efficiently and quicker than simply doing individual reads and writes to > and from the single 16-bit ata data register. > > i.e. for architectures which have a DMA controller (for example, PCI > bridges) when used with PCMCIA controllers which DO NOT support DMA (for > example, TI PCI1510), this can reduce CPU overhead for PIO transfers > considerably. > > This feature is simply a pseudo buffer, that resides at ata offset > 0x0400-0x0800, that allows incrementing dmas sequential access to the same > ata data register, which in reality is just a fifo, but the feature is only > available when the cf is configured for MEMORY mode. > > There was an earlier attempt to support MMIO by Thomas Kleffel, but his > patch was reverted in 2.6.19 by Andrew Morton due to various problems. > > Although it's not in the mainline Linux code, I know readers on this list > who use Thomas' patch, so this is an attempt at summarising the problems > and possible fixes. > > 1/ It has a problem with still using the default PCI IO access functions to > communicate with the cf's ATA registers during probe, rather than using > MMIO for all operations. > > Fix: Adding specific code to ide_register_hw_with_fixup function to load > the PCI MEM functions into the hwif struct when that struct is being > initialized and the is_mmio flag is set. > > In drivers/ide/legacy/ide-cs.c > > Within the CIS parser, set the memory mode per Thomas' is_mmio patch: > > link->conf.IntType = INT_MEMORY; > > Then pass is_mmio from Thomas' patch as the last parameter when calling the fixup function: > > int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp, > > void(*fixup)(ide_hwif_t *hwif), int is_mmio) > > 807a808,821 > > > if (is_mmio) > > { > > default_hwif_mmiops(hwif); > > hwif->io_ports[IDE_DATA_OFFSET] += 0x0400; > > hwif->mmio = 2; > > } > > 2/ Once the ide driver was able to communicate successfully with the cf ATA > registers in MEM mode we could see that the interrupts didn't work. > > Fix: Changing the desired interrupt mode from INT_MEMORY_AND_IO to > INT_MEMORY when configuring the pcmcia socket controller. The lowest-level > yenta socket code could handle this functionality but the higher-level > pcmcia code could not handle it. > > i.e. fix this by adding 2 lines of of INT_MEMORY support code to the > pcmcia_request_configuration function. > > In drivers/pcmcia/pcmcia_resource.c > 628a629,633 > > > if (req->IntType & INT_MEMORY) > > { > > s->socket.flags &= ~SS_IOCARD; // this is not an IO card > > s->socket.csc_mask |= SS_READY; // enable the READY > > interrupt } > > 3/ Extend the base register so that it looks at the MMIO buffer at +400 > instead of the base data register. > > In drivers/ide/legacy/ide-cs.c > > > int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp, > > void(*fixup)(ide_hwif_t *hwif), int is_mmio) > > 807a808,821 > > > /* if the mmio flag is set we populate the hwif structure with > > * the functions used to access PCI memory space (as opposed to > > * the default functions which access PCI io space). we also > > * change the 'data' offset to the address of the data buffer > > * that exists at offset 0x0400 so that we can use pci dmas > > * to move data faster. > > */ > > if (is_mmio) > > { > > default_hwif_mmiops(hwif); > > hwif->io_ports[IDE_DATA_OFFSET] += 0x0400; > > hwif->mmio = 2; > > } > > Note: This isn't a complete solution, as with the ide driver now working in > MEMORY mode it still needs architecture-specific code to implement the DMA > transfer to the MMIO FIFO buffer. That's relatively trivial using the arch > native PCI driver functions to move 16-bit data to and from the PCI bus > using block transfers instead of single-access transfers, for example the > PXA driver from Steven.
Hi Iain, good job! Do you have a patch? I'm busy with other things at the moment but I'll find some time to try this out. You managed to get further than I did, I was quit stuck on the lack of IRQ from the drive, the datasheet I was using for reference didn't mention that the interrupt for memory accesses is only generated in memory only mode! _______________________________________________ Linux PCMCIA reimplementation list http://lists.infradead.org/mailman/listinfo/linux-pcmcia
