📄 1025.ddma.patch
字号:
diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linux-2.6.15.ref/arch/mips/tangox/mbus.c linux-2.6.15/arch/mips/tangox/mbus.c--- linux-2.6.15.ref/arch/mips/tangox/mbus.c 2007-07-06 10:20:55.000000000 -0700+++ linux-2.6.15/arch/mips/tangox/mbus.c 2007-07-06 10:37:24.000000000 -0700@@ -203,8 +203,10 @@ unsigned int addr, unsigned int count) {+#ifndef CONFIG_SD_DIRECT_DMA if ((addr < CPHYSADDR(em8xxx_kmem_start)) || (addr >= (CPHYSADDR(em8xxx_kmem_start) + em8xxx_kmem_size))) printk("MBUS Warning (linear): bad transfer address 0x%08x\n", addr);+#endif gbus_writel(regbase + MIF_add_offset, tangox_dma_address(addr)); gbus_writel(regbase + MIF_cnt_offset, count);@@ -223,10 +225,12 @@ unsigned int addr2, unsigned int count2) {+#ifndef CONFIG_SD_DIRECT_DMA if ((addr < CPHYSADDR(em8xxx_kmem_start)) || (addr >= (CPHYSADDR(em8xxx_kmem_start) + em8xxx_kmem_size))) printk("MBUS Warning (double): bad transfer address 0x%08x\n", addr); if ((addr2 < CPHYSADDR(em8xxx_kmem_start)) || (addr2 >= (CPHYSADDR(em8xxx_kmem_start) + em8xxx_kmem_size))) printk("MBUS Warning (double): bad transfer address2 0x%08x\n", addr2);+#endif gbus_writel(regbase + MIF_add_offset, tangox_dma_address(addr)); gbus_writel(regbase + MIF_cnt_offset, (count2 << 16) | count);@@ -245,8 +249,10 @@ unsigned int horiz, unsigned int lines) {+#ifndef CONFIG_SD_DIRECT_DMA if ((addr < CPHYSADDR(em8xxx_kmem_start)) || (addr >= (CPHYSADDR(em8xxx_kmem_start) + em8xxx_kmem_size))) printk("MBUS Warning (rectangle): bad transfer address 0x%08x\n", addr);+#endif gbus_writel(regbase + MIF_add_offset, tangox_dma_address(addr)); gbus_writel(regbase + MIF_cnt_offset, (lines << 16) | horiz);diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linux-2.6.15.ref/arch/mips/tangox/prom.c linux-2.6.15/arch/mips/tangox/prom.c--- linux-2.6.15.ref/arch/mips/tangox/prom.c 2007-07-06 10:25:03.000000000 -0700+++ linux-2.6.15/arch/mips/tangox/prom.c 2007-07-06 10:37:24.000000000 -0700@@ -3,6 +3,7 @@ #include <asm/bootinfo.h> #include <asm/page.h> #include <linux/module.h>+#include <linux/mm.h> #include "setup.h" @@ -650,3 +651,63 @@ EXPORT_SYMBOL(is_tango2_es89); EXPORT_SYMBOL(is_tango3_es1); +#ifdef CONFIG_SD_DIRECT_DMA++int is_contiguous_memory(void __user *userbuf, unsigned int len, unsigned long *physaddr)+{+ pgd_t *pgd;+ pud_t *pud;+ pmd_t *pmd;+ pte_t *pte;+ unsigned long start = (unsigned long)userbuf;+ unsigned long pg, offset, paddr, ppaddr, end;+ struct mm_struct *mm = current->mm;+ int ret = 0;++//printk("%s:%d: start=0x%08lx, len=0x%x\n", __FILE__, __LINE__, start, len);++ *physaddr = 0;+ down_read(&mm->mmap_sem);+ for (ppaddr = 0, end = start + len; start < end; start += PAGE_SIZE) {+ pg = start & PAGE_MASK;+ offset = start & (PAGE_SIZE - 1);+ if (pg > TASK_SIZE)+ pgd = pgd_offset_k(pg);+ else+ pgd = pgd_offset_gate(mm, pg);+ BUG_ON(pgd_none(*pgd));+ pud = pud_offset(pgd, pg);+ BUG_ON(pud_none(*pud));+ pmd = pmd_offset(pud, pg);+ if (pmd_none(*pmd)) + goto error;+ pte = pte_offset_map(pmd, pg);+ if (pte_none(*pte)) {+ pte_unmap(pte);+ goto error;+ }+ paddr = pte_val(*pte) & PAGE_MASK;+//printk("TRANSLATED 0x%08lx, pte=0x%p, paddr=0x%lx\n", pg, pte, paddr);+ pte_unmap(pte);++ if (ppaddr == 0) { /* first page */+ ppaddr = paddr;+ *physaddr = ppaddr | offset;+ } else if ((ppaddr + PAGE_SIZE) != paddr) /* not contiguous */+ goto not_contiguous;+ else+ ppaddr = paddr;+ }+ ret = 1;++not_contiguous:+error:+ up_read(&mm->mmap_sem);+//printk("%s:%d: return %d\n", __FILE__, __LINE__, ret);+ return ret;+}++EXPORT_SYMBOL(is_contiguous_memory);++#endif /* CONFIG_SD_DIRECT_DMA */+diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linux-2.6.15.ref/block/ll_rw_blk.c linux-2.6.15/block/ll_rw_blk.c--- linux-2.6.15.ref/block/ll_rw_blk.c 2007-07-06 10:20:57.000000000 -0700+++ linux-2.6.15/block/ll_rw_blk.c 2007-07-06 10:37:24.000000000 -0700@@ -2144,6 +2144,11 @@ struct bio *bio; int reading; int dma_alignment = 0;+#ifdef CONFIG_SD_DIRECT_DMA+ extern int is_contiguous_memory(void __user *userbuf, unsigned int len, unsigned long *paddr);+ unsigned long paddr;+ struct gendisk *disk = rq->rq_disk;+#endif if (len > (q->max_sectors << 9)) return -EINVAL;@@ -2172,11 +2177,32 @@ else dma_cache_wback_inv(uaddr, len); #endif- bio = bio_map_user(q, NULL, uaddr, len, reading);- if (IS_ERR(bio)) {- /* the map operation failed, use copy instead */- bio = bio_copy_user(q, uaddr, len, reading);- } +#ifdef CONFIG_SD_DIRECT_DMA+ if ((len >= (128 * 1024)) && (is_contiguous_memory(ubuf, len, &paddr) != 0) && + (disk->major == IDE0_MAJOR)) { /* Only with Sigma's IDE interface */++ bio = kmalloc(sizeof(struct bio), GFP_KERNEL);+ if (bio == NULL)+ return -ENOMEM;++ memset(bio, 0, sizeof(struct bio));+ bio->bi_flags |= (1<<BIO_PHYSICAL);+ bio->bi_rw = (reading ? 0 : 1) | BIO_RW_SYNC;+ bio->bi_size = len;+ bio->bi_io_vec = (void *)ubuf;++ /* to carry physical addr to ide driver */+ bio->bi_private = (void *)paddr;+ } else {+#endif+ bio = bio_map_user(q, NULL, uaddr, len, reading);+ if (IS_ERR(bio)) {+ /* the map operation failed, use copy instead */+ bio = bio_copy_user(q, uaddr, len, reading);+ } +#ifdef CONFIG_SD_DIRECT_DMA+ }+#endif } else bio = bio_copy_user(q, uaddr, len, reading); @@ -2254,10 +2280,18 @@ int ret = 0; if (bio) {- if (bio_flagged(bio, BIO_USER_MAPPED))- bio_unmap_user(bio);- else- ret = bio_uncopy_user(bio);+#ifdef CONFIG_SD_DIRECT_DMA+ if (bio_flagged(bio, BIO_PHYSICAL)) {+ kfree(bio);+ } else {+#endif+ if (bio_flagged(bio, BIO_USER_MAPPED))+ bio_unmap_user(bio);+ else+ ret = bio_uncopy_user(bio);+#ifdef CONFIG_SD_DIRECT_DMA+ }+#endif } return 0;@@ -3216,12 +3250,30 @@ /* first three bits are identical in rq->flags and bio->bi_rw */ rq->flags |= (bio->bi_rw & 7); - rq->nr_phys_segments = bio_phys_segments(q, bio);- rq->nr_hw_segments = bio_hw_segments(q, bio);- rq->current_nr_sectors = bio_cur_sectors(bio);- rq->hard_cur_sectors = rq->current_nr_sectors;- rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);- rq->buffer = bio_data(bio);+#ifdef CONFIG_SD_DIRECT_DMA+ if (bio_flagged(bio, BIO_PHYSICAL)) {+ rq->nr_phys_segments = 1;+ rq->nr_hw_segments = 1;+ rq->current_nr_sectors = bio_cur_sectors(bio);+ rq->hard_cur_sectors = rq->current_nr_sectors;+ rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);+ rq->buffer = bio_data(bio);++ /*elevator doesn't know about this request*/+ rq->flags &= ~REQ_SORTED; + } else {+#endif+ rq->nr_phys_segments = bio_phys_segments(q, bio);+ rq->nr_hw_segments = bio_hw_segments(q, bio);+ rq->current_nr_sectors = bio_cur_sectors(bio);+ rq->hard_cur_sectors = rq->current_nr_sectors;+ rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);+ rq->buffer = bio_data(bio);+#ifdef CONFIG_SD_DIRECT_DMA+ }+#endif+//printk("%x %x %x %x %x %x\n", rq->nr_phys_segments,rq->nr_hw_segments,rq->current_nr_sectors,rq->hard_cur_sectors, rq->hard_nr_sectors,rq->buffer);+//printk("bi_io_vec=%x\n",bio->bi_io_vec); rq->bio = rq->biotail = bio; } diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linux-2.6.15.ref/drivers/ide/Kconfig linux-2.6.15/drivers/ide/Kconfig--- linux-2.6.15.ref/drivers/ide/Kconfig 2007-07-06 10:20:57.000000000 -0700+++ linux-2.6.15/drivers/ide/Kconfig 2007-07-06 10:37:24.000000000 -0700@@ -858,6 +858,13 @@ help How many maximum sectors can be tranferred per request. +config SD_DIRECT_DMA+ depends on (((BLK_DEV_BMIDE_TANGOX && BLK_DEV_BMIDE_TANGOX_DMA) || (BLK_DEV_PBIDE_TANGOX && BLK_DEV_PBIDE_TANGOX_DMA))) && EXPERIMENTAL+ bool "Enabling DDMA support for TangoX platform (experimental)"+ default n+ help+ Enable user level direct DMA transfer to speed up IDE I/O for TangoX chips.+ config SD_CDROM_WAIT bool "enable CDROM wait for spin-up" default ydiff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linux-2.6.15.ref/drivers/ide/tangox/tangox-bmide.c linux-2.6.15/drivers/ide/tangox/tangox-bmide.c--- linux-2.6.15.ref/drivers/ide/tangox/tangox-bmide.c 2007-07-06 10:25:03.000000000 -0700+++ linux-2.6.15/drivers/ide/tangox/tangox-bmide.c 2007-07-06 10:37:24.000000000 -0700@@ -373,7 +373,7 @@ { ide_hwif_t *hwif = HWIF(drive); struct request *rq;- int iswrite;+ int iswrite, phys_mapped; struct scatterlist *sg = hwif->sg_table; rq = HWGROUP(drive)->rq;@@ -381,10 +381,14 @@ iswrite = (rq_data_dir(rq) == WRITE); hwif->sg_dma_direction = iswrite ? DMA_TO_DEVICE : DMA_FROM_DEVICE; - /*- * ide_map_sg will merge contiguous memory zone for us- */- ide_map_sg(drive, rq);+ phys_mapped = (bio_flagged(rq->bio, BIO_PHYSICAL) ? 1 : 0);++ if (!phys_mapped) {+ /*+ * ide_map_sg will merge contiguous memory zone for us+ */+ ide_map_sg(drive, rq);+ } /* try to setup dma channel */ if (em86xx_mbus_alloc_dma(SBOX_IDEDVD, iswrite ? 0 : 1, &g_mbus_reg,@@ -393,33 +397,49 @@ goto fallback_pio; } - /*- * map and transfer first segment- */- dma_map_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction);- g_next_sg = 1;+ if (!phys_mapped) {+ /*+ * map and transfer first segment+ */+ dma_map_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction);+ g_next_sg = 1; - /*- * setup mbus dma for this address. we want an mbus interrupt- * only if this is not the last sg element, so we can refeed- * mbus.- */- if (em86xx_mbus_setup_dma(g_mbus_reg, sg_dma_address(sg),- sg_dma_len(sg),- (hwif->sg_nents == 1) ? NULL :- tangox_mbus_intr, drive)) {- printk(KERN_ERR PFX "fail to setup dma, fallback to pio\n");- dma_unmap_sg(&hwif->gendev, sg, hwif->sg_nents,- hwif->sg_dma_direction);- em86xx_mbus_free_dma(g_mbus_reg, SBOX_IDEDVD);- goto fallback_pio;+ /*+ * setup mbus dma for this address. we want an mbus interrupt+ * only if this is not the last sg element, so we can refeed+ * mbus.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -