Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 12168
b: refs/heads/master
c: 9dc2d0f
h: refs/heads/master
v: v3
  • Loading branch information
Russell King authored and Russell King committed Nov 2, 2005
1 parent 99661ed commit c2ef856
Show file tree
Hide file tree
Showing 22 changed files with 170 additions and 211 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3a7142371efdc95f4c5b5ffc188b18efdc4e64dd
refs/heads/master: 9dc2d0f55fb693ae6d50c8dd3d934fe3133ca183
4 changes: 0 additions & 4 deletions trunk/arch/ia64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ config MMU
bool
default y

config SWIOTLB
bool
default y

config RWSEM_XCHGADD_ALGORITHM
bool
default y
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/ia64/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ lib-y := __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
bitop.o checksum.o clear_page.o csum_partial_copy.o \
clear_user.o strncpy_from_user.o strlen_user.o strnlen_user.o \
flush.o ip_fast_csum.o do_csum.o \
memset.o strlen.o
memset.o strlen.o swiotlb.o

lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
Expand Down
142 changes: 45 additions & 97 deletions trunk/lib/swiotlb.c → trunk/arch/ia64/lib/swiotlb.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Dynamic DMA mapping support.
*
* This implementation is for IA-64 and EM64T platforms that do not support
* This implementation is for IA-64 platforms that do not support
* I/O TLBs (aka DMA address translation hardware).
* Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>
* Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>
Expand All @@ -11,23 +11,21 @@
* 03/05/07 davidm Switch from PCI-DMA to generic device DMA API.
* 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid
* unnecessary i-cache flushing.
* 04/07/.. ak Better overflow handling. Assorted fixes.
* 05/09/10 linville Add support for syncing ranges, support syncing for
* DMA_BIDIRECTIONAL mappings, miscellaneous cleanup.
* 04/07/.. ak Better overflow handling. Assorted fixes.
*/

#include <linux/cache.h>
#include <linux/dma-mapping.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ctype.h>

#include <asm/io.h>
#include <asm/pci.h>
#include <asm/dma.h>
#include <asm/scatterlist.h>

#include <linux/init.h>
#include <linux/bootmem.h>
Expand Down Expand Up @@ -60,14 +58,6 @@
*/
#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)

/*
* Enumeration for sync targets
*/
enum dma_sync_target {
SYNC_FOR_CPU = 0,
SYNC_FOR_DEVICE = 1,
};

int swiotlb_force;

/*
Expand Down Expand Up @@ -127,7 +117,7 @@ __setup("swiotlb=", setup_io_tlb_npages);

/*
* Statically reserve bounce buffer space and initialize bounce buffer data
* structures for the software IO TLB used to implement the DMA API.
* structures for the software IO TLB used to implement the PCI DMA API.
*/
void
swiotlb_init_with_default_size (size_t default_size)
Expand Down Expand Up @@ -407,28 +397,21 @@ unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
}

static void
sync_single(struct device *hwdev, char *dma_addr, size_t size,
int dir, int target)
sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)
{
int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
char *buffer = io_tlb_orig_addr[index];

switch (target) {
case SYNC_FOR_CPU:
if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))
memcpy(buffer, dma_addr, size);
else if (dir != DMA_TO_DEVICE)
BUG();
break;
case SYNC_FOR_DEVICE:
if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
memcpy(dma_addr, buffer, size);
else if (dir != DMA_FROM_DEVICE)
BUG();
break;
default:
/*
* bounce... copy the data back into/from the original buffer
* XXX How do you handle DMA_BIDIRECTIONAL here ?
*/
if (dir == DMA_FROM_DEVICE)
memcpy(buffer, dma_addr, size);
else if (dir == DMA_TO_DEVICE)
memcpy(dma_addr, buffer, size);
else
BUG();
}
}

void *
Expand Down Expand Up @@ -502,24 +485,24 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic)
/*
* Ran out of IOMMU space for this operation. This is very bad.
* Unfortunately the drivers cannot handle this operation properly.
* unless they check for dma_mapping_error (most don't)
* unless they check for pci_dma_mapping_error (most don't)
* When the mapping is small enough return a static buffer to limit
* the damage, or panic when the transfer is too big.
*/
printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at "
printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "
"device %s\n", size, dev ? dev->bus_id : "?");

if (size > io_tlb_overflow && do_panic) {
if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
panic("DMA: Memory would be corrupted\n");
if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
panic("DMA: Random memory would be DMAed\n");
if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
panic("PCI-DMA: Memory would be corrupted\n");
if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
panic("PCI-DMA: Random memory would be DMAed\n");
}
}

/*
* Map a single buffer of the indicated size for DMA in streaming mode. The
* physical address to use is returned.
* PCI address to use is returned.
*
* Once the device is given the dma address, the device owns this memory until
* either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.
Expand Down Expand Up @@ -606,73 +589,39 @@ swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size,
* after a transfer.
*
* If you perform a swiotlb_map_single() but wish to interrogate the buffer
* using the cpu, yet do not wish to teardown the dma mapping, you must
* call this function before doing so. At the next point you give the dma
* using the cpu, yet do not wish to teardown the PCI dma mapping, you must
* call this function before doing so. At the next point you give the PCI dma
* address back to the card, you must first perform a
* swiotlb_dma_sync_for_device, and then the device again owns the buffer
*/
static inline void
swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
size_t size, int dir, int target)
void
swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
size_t size, int dir)
{
char *dma_addr = phys_to_virt(dev_addr);

if (dir == DMA_NONE)
BUG();
if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
sync_single(hwdev, dma_addr, size, dir, target);
sync_single(hwdev, dma_addr, size, dir);
else if (dir == DMA_FROM_DEVICE)
mark_clean(dma_addr, size);
}

void
swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
size_t size, int dir)
{
swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);
}

void
swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
size_t size, int dir)
{
swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);
}

/*
* Same as above, but for a sub-range of the mapping.
*/
static inline void
swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr,
unsigned long offset, size_t size,
int dir, int target)
{
char *dma_addr = phys_to_virt(dev_addr) + offset;
char *dma_addr = phys_to_virt(dev_addr);

if (dir == DMA_NONE)
BUG();
if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)
sync_single(hwdev, dma_addr, size, dir, target);
sync_single(hwdev, dma_addr, size, dir);
else if (dir == DMA_FROM_DEVICE)
mark_clean(dma_addr, size);
}

void
swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
unsigned long offset, size_t size, int dir)
{
swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,
SYNC_FOR_CPU);
}

void
swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,
unsigned long offset, size_t size, int dir)
{
swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,
SYNC_FOR_DEVICE);
}

/*
* Map a set of buffers described by scatterlist in streaming mode for DMA.
* This is the scatter-gather version of the above swiotlb_map_single
Expand Down Expand Up @@ -747,9 +696,9 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
* The same as swiotlb_sync_single_* but for a scatter-gather list, same rules
* and usage.
*/
static inline void
swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg,
int nelems, int dir, int target)
void
swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
int nelems, int dir)
{
int i;

Expand All @@ -759,21 +708,22 @@ swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg,
for (i = 0; i < nelems; i++, sg++)
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
sync_single(hwdev, (void *) sg->dma_address,
sg->dma_length, dir, target);
}

void
swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
int nelems, int dir)
{
swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);
sg->dma_length, dir);
}

void
swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
int nelems, int dir)
{
swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
int i;

if (dir == DMA_NONE)
BUG();

for (i = 0; i < nelems; i++, sg++)
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
sync_single(hwdev, (void *) sg->dma_address,
sg->dma_length, dir);
}

int
Expand All @@ -783,9 +733,9 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr)
}

/*
* Return whether the given device DMA address mask can be supported
* Return whether the given PCI device DMA address mask can be supported
* properly. For example, if your device can only drive the low 24-bits
* during bus mastering, then you would pass 0x00ffffff as the mask to
* during PCI bus mastering, then you would pass 0x00ffffff as the mask to
* this function.
*/
int
Expand All @@ -801,8 +751,6 @@ EXPORT_SYMBOL(swiotlb_map_sg);
EXPORT_SYMBOL(swiotlb_unmap_sg);
EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
EXPORT_SYMBOL(swiotlb_sync_single_for_device);
EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_cpu);
EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device);
EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
EXPORT_SYMBOL(swiotlb_dma_mapping_error);
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/x86_64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o
obj-$(CONFIG_SWIOTLB) += swiotlb.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o

Expand All @@ -40,6 +41,7 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0
bootflag-y += ../../i386/kernel/bootflag.o
cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
topology-y += ../../i386/mach-default/topology.o
swiotlb-$(CONFIG_SWIOTLB) += ../../ia64/lib/swiotlb.o
microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
quirks-y += ../../i386/kernel/quirks.o
Expand Down
13 changes: 9 additions & 4 deletions trunk/drivers/block/aoe/aoecmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,11 +468,16 @@ aoecmd_ata_rsp(struct sk_buff *skb)
unsigned long duration = jiffies - buf->start_time;
unsigned long n_sect = buf->bio->bi_size >> 9;
struct gendisk *disk = d->gd;
const int rw = bio_data_dir(buf->bio);

disk_stat_inc(disk, ios[rw]);
disk_stat_add(disk, ticks[rw], duration);
disk_stat_add(disk, sectors[rw], n_sect);
if (bio_data_dir(buf->bio) == WRITE) {
disk_stat_inc(disk, writes);
disk_stat_add(disk, write_ticks, duration);
disk_stat_add(disk, write_sectors, n_sect);
} else {
disk_stat_inc(disk, reads);
disk_stat_add(disk, read_ticks, duration);
disk_stat_add(disk, read_sectors, n_sect);
}
disk_stat_add(disk, io_ticks, duration);
n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
bio_endio(buf->bio, buf->bio->bi_size, n);
Expand Down
29 changes: 15 additions & 14 deletions trunk/drivers/block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,13 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
"%8u %8u %8llu %8u "
"%8u %8u %8u"
"\n",
disk_stat_read(disk, ios[0]), disk_stat_read(disk, merges[0]),
(unsigned long long)disk_stat_read(disk, sectors[0]),
jiffies_to_msecs(disk_stat_read(disk, ticks[0])),
disk_stat_read(disk, ios[1]), disk_stat_read(disk, merges[1]),
(unsigned long long)disk_stat_read(disk, sectors[1]),
jiffies_to_msecs(disk_stat_read(disk, ticks[1])),
disk_stat_read(disk, reads), disk_stat_read(disk, read_merges),
(unsigned long long)disk_stat_read(disk, read_sectors),
jiffies_to_msecs(disk_stat_read(disk, read_ticks)),
disk_stat_read(disk, writes),
disk_stat_read(disk, write_merges),
(unsigned long long)disk_stat_read(disk, write_sectors),
jiffies_to_msecs(disk_stat_read(disk, write_ticks)),
disk->in_flight,
jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
Expand Down Expand Up @@ -582,12 +583,12 @@ static int diskstats_show(struct seq_file *s, void *v)
preempt_enable();
seq_printf(s, "%4d %4d %s %u %u %llu %u %u %u %llu %u %u %u %u\n",
gp->major, n + gp->first_minor, disk_name(gp, n, buf),
disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]),
(unsigned long long)disk_stat_read(gp, sectors[0]),
jiffies_to_msecs(disk_stat_read(gp, ticks[0])),
disk_stat_read(gp, ios[1]), disk_stat_read(gp, merges[1]),
(unsigned long long)disk_stat_read(gp, sectors[1]),
jiffies_to_msecs(disk_stat_read(gp, ticks[1])),
disk_stat_read(gp, reads), disk_stat_read(gp, read_merges),
(unsigned long long)disk_stat_read(gp, read_sectors),
jiffies_to_msecs(disk_stat_read(gp, read_ticks)),
disk_stat_read(gp, writes), disk_stat_read(gp, write_merges),
(unsigned long long)disk_stat_read(gp, write_sectors),
jiffies_to_msecs(disk_stat_read(gp, write_ticks)),
gp->in_flight,
jiffies_to_msecs(disk_stat_read(gp, io_ticks)),
jiffies_to_msecs(disk_stat_read(gp, time_in_queue)));
Expand All @@ -600,8 +601,8 @@ static int diskstats_show(struct seq_file *s, void *v)
seq_printf(s, "%4d %4d %s %u %u %u %u\n",
gp->major, n + gp->first_minor + 1,
disk_name(gp, n + 1, buf),
hd->ios[0], hd->sectors[0],
hd->ios[1], hd->sectors[1]);
hd->reads, hd->read_sectors,
hd->writes, hd->write_sectors);
}

return 0;
Expand Down
Loading

0 comments on commit c2ef856

Please sign in to comment.