📄 1025.ddma.patch
字号:
+ */+ 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;+ }+ } else {+ /*+ * 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.+ */+ /* physical addr was carried by bi_private*/ + if (em86xx_mbus_setup_dma(g_mbus_reg, (unsigned int)rq->bio->bi_private, + rq->bio->bi_size, NULL, drive)) {+ printk(KERN_ERR PFX "fail to setup dma, fallback to pio\n");+ em86xx_mbus_free_dma(g_mbus_reg, SBOX_IDEDVD);+ goto fallback_pio;+ } } drive->waiting_for_dma = 1; return 0; fallback_pio:- ide_map_sg(drive, rq);+ if (!phys_mapped) + ide_map_sg(drive, rq); return 1; } @@ -429,6 +449,11 @@ u8 dma_stat; int mbus_stat; struct scatterlist *sg = hwif->sg_table;+ struct request *rq;+ int phys_mapped;++ rq = HWGROUP(drive)->rq;+ phys_mapped = (bio_flagged(rq->bio, BIO_PHYSICAL) ? 1 : 0); dma_stat = hwif->INB(hwif->dma_status); @@ -456,8 +481,10 @@ /* stop bus mastering */ hwif->OUTB(0x4, hwif->dma_command); - dma_unmap_sg(&hwif->gendev, sg, hwif->sg_nents,- hwif->sg_dma_direction);+ if (!phys_mapped) + dma_unmap_sg(&hwif->gendev, sg, hwif->sg_nents,+ hwif->sg_dma_direction);+ drive->waiting_for_dma = 0; /* fake dma error in case of mbus timeout, else returndiff -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-pbide.c linux-2.6.15/drivers/ide/tangox/tangox-pbide.c--- linux-2.6.15.ref/drivers/ide/tangox/tangox-pbide.c 2007-07-06 10:25:03.000000000 -0700+++ linux-2.6.15/drivers/ide/tangox/tangox-pbide.c 2007-07-06 10:37:24.000000000 -0700@@ -13,6 +13,8 @@ extern int tangox_isaide_enabled(void); extern int tangox_isaide_cs_select(void); extern int tangox_isaide_timing_slot(void);+extern void mbus_setup_dma_double(unsigned int regbase, unsigned int addr, + unsigned int count, unsigned int addr2, unsigned int count2); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SMP86xx PB IDE driver");@@ -272,13 +274,18 @@ ide_hwif_t *hwif = HWIF(drive); struct scatterlist *sg = hwif->sg_table;+ int phys_mapped; - dma_map_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction);+ phys_mapped = (bio_flagged(rq->bio, BIO_PHYSICAL) ? 1 : 0); - if (hwif->sg_nents > 2) { /* this shouldn't happen since we limited rqsize=16 for now*/- printk("cannot handle multiple transfer yet. sg_nents=0x%x\n", hwif->sg_nents);- dma_unmap_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction);- return 1;+ if (!phys_mapped) {+ dma_map_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction);++ if (hwif->sg_nents > 2) { /* this shouldn't happen since we limited rqsize=16 for now*/+ printk("cannot handle multiple transfer yet. sg_nents=0x%x\n", hwif->sg_nents);+ dma_unmap_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction);+ return 1;+ } } // setup switchbox and wait for its readiness@@ -298,51 +305,67 @@ if (drive->media == ide_disk) ide_set_handler(drive, &tangox_pbide_dma_intr, 2 * WAIT_CMD, NULL); - addr = sg_dma_address(sg);- size = sg_dma_len(sg);+ if (!phys_mapped) {+ addr = sg_dma_address(sg); + size = sg_dma_len(sg);+ } else {+ addr = (unsigned int)rq->bio->bi_private;+ size = rq->bio->bi_size;+ } - if (hwif->sg_nents == 1) {+ if (!phys_mapped) {+ if (hwif->sg_nents == 1) { - /* perform a single (linear/rectangle) transfer */+ /* perform a single (linear/rectangle) transfer */ - // setup PB automode registers- gbus_writel(REG_BASE_host_interface + PB_automode_start_address, 0);- gbus_writel(REG_BASE_host_interface + PB_automode_control,- 0x00140000 | ((read ? 1 : 0) << 16) | (size >> 1));+ // setup PB automode registers+ gbus_writel(REG_BASE_host_interface + PB_automode_start_address, 0);+ gbus_writel(REG_BASE_host_interface + PB_automode_control,+ 0x00140000 | ((read ? 1 : 0) << 16) | (size >> 1));++ if (read)+ dma_cache_inv((unsigned int)phys_to_virt(addr), size);+ else+ dma_cache_wback_inv((unsigned int)phys_to_virt(addr), size);++ em86xx_mbus_setup_dma(read ? g_regbase_read : g_regbase_write,+ addr, size, NULL, NULL);+ } else { + /* perform a double transfer */+ unsigned int addr1 = 0;+ unsigned int size1 = 0;++ sg = &hwif->sg_table[1];++ addr1 = sg_dma_address(sg);+ size1 = sg_dma_len(sg);++ // setup PB automode registers+ gbus_writel(REG_BASE_host_interface + PB_automode_start_address, 0);+ gbus_writel(REG_BASE_host_interface + PB_automode_control,+ 0x00140000 | ((read ? 1 : 0) << 16) | ((size+size1) >> 1));++ if (read) {+ dma_cache_inv((unsigned int)phys_to_virt(addr), size);+ dma_cache_inv((unsigned int)phys_to_virt(addr1), size1);+ } else {+ dma_cache_wback_inv((unsigned int)phys_to_virt(addr), size);+ dma_cache_wback_inv((unsigned int)phys_to_virt(addr1), size1);+ } - if (read)- dma_cache_inv((unsigned int)phys_to_virt(addr), size);- else- dma_cache_wback_inv((unsigned int)phys_to_virt(addr), size);-- em86xx_mbus_setup_dma(read ? g_regbase_read : g_regbase_write,- addr, size, NULL, NULL);- }- else { - /* perform a double transfer */- unsigned int addr1 = 0;- unsigned int size1 = 0;-- sg = &hwif->sg_table[1];-- addr1 = sg_dma_address(sg);- size1 = sg_dma_len(sg);-- // setup PB automode registers- gbus_writel(REG_BASE_host_interface + PB_automode_start_address, 0);- gbus_writel(REG_BASE_host_interface + PB_automode_control,- 0x00140000 | ((read ? 1 : 0) << 16) | ((size+size1) >> 1));-- if (read) {- dma_cache_inv((unsigned int)phys_to_virt(addr), size);- dma_cache_inv((unsigned int)phys_to_virt(addr1), size1);- } else {- dma_cache_wback_inv((unsigned int)phys_to_virt(addr), size);- dma_cache_wback_inv((unsigned int)phys_to_virt(addr1), size1);+ mbus_setup_dma_double(read ? g_regbase_read : g_regbase_write, + addr, size, addr1, size1); }+ } else {+ /* perform a single (linear/rectangle) transfer */ - mbus_setup_dma_double(read ? g_regbase_read : g_regbase_write, - addr, size, addr1, size1);+ // setup PB automode registers+ gbus_writel(REG_BASE_host_interface + PB_automode_start_address, 0);+ gbus_writel(REG_BASE_host_interface + PB_automode_control,+ 0x00140000 | ((read ? 1 : 0) << 16) | (size >> 1));++ em86xx_mbus_setup_dma(read ? g_regbase_read : g_regbase_write, + addr, size, NULL, NULL); } if (drive->media == ide_disk) {@@ -359,14 +382,18 @@ ide_hwif_t *hwif = HWIF(drive); struct request *rq; int iswrite;+ int phys_mapped; drive->waiting_for_dma = 1; rq = HWGROUP(drive)->rq; iswrite = (rq_data_dir(rq) == WRITE); hwif->sg_dma_direction = iswrite ? DMA_TO_DEVICE : DMA_FROM_DEVICE;+ phys_mapped = (bio_flagged(rq->bio, BIO_PHYSICAL) ? 1 : 0); - // this will do the merge- ide_map_sg(drive, rq);+ if (!phys_mapped) {+ // this will do the merge+ ide_map_sg(drive, rq);+ } return tangox_pbide_rwdma(drive, !iswrite, rq); }@@ -440,13 +467,16 @@ static int tangox_pbide_dma_end_io(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive);- struct scatterlist *sg = hwif->sg_table; struct request *rq = HWGROUP(drive)->rq;-+ struct scatterlist *sg = hwif->sg_table;+ int phys_mapped; int stat = em86xx_mbus_wait(rq->cmd == READ ? g_regbase_read : g_regbase_write, SBOX_IDEFLASH); - dma_unmap_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction);+ phys_mapped = (bio_flagged(rq->bio, BIO_PHYSICAL) ? 1 : 0);++ if (!phys_mapped)+ dma_unmap_sg(&hwif->gendev, sg, hwif->sg_nents, hwif->sg_dma_direction); /* Free up MBUS channel */ em86xx_mbus_free_dma(g_regbase_read, SBOX_IDEFLASH);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/include/linux/bio.h linux-2.6.15/include/linux/bio.h--- linux-2.6.15.ref/include/linux/bio.h 2006-01-25 20:52:00.000000000 -0800+++ linux-2.6.15/include/linux/bio.h 2007-07-06 10:37:24.000000000 -0700@@ -124,6 +124,7 @@ #define BIO_BOUNCED 5 /* bio is a bounce bio */ #define BIO_USER_MAPPED 6 /* contains user pages */ #define BIO_EOPNOTSUPP 7 /* not supported */+#define BIO_PHYSICAL 8 /* this bio is pointing to physically contiguous space */ #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) /*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/include/linux/slab.h linux-2.6.15/include/linux/slab.h--- linux-2.6.15.ref/include/linux/slab.h 2007-07-06 10:31:10.000000000 -0700+++ linux-2.6.15/include/linux/slab.h 2007-07-06 10:37:24.000000000 -0700@@ -76,7 +76,7 @@ extern struct cache_sizes malloc_sizes[]; extern void *__kmalloc(size_t, gfp_t); -#define MAX_KMALLOC_ORDER 8 /* 2^8 pages max */+#define MAX_KMALLOC_ORDER 10 /* 2^10 pages max */ static inline void *kmalloc(size_t size, gfp_t flags) {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/mm/highmem.c linux-2.6.15/mm/highmem.c--- linux-2.6.15.ref/mm/highmem.c 2006-01-25 20:52:04.000000000 -0800+++ linux-2.6.15/mm/highmem.c 2007-07-06 10:37:24.000000000 -0700@@ -469,6 +469,9 @@ { mempool_t *pool; + if (bio_flagged(*bio_orig, BIO_PHYSICAL)) + return;+ /* * for non-isa bounce case, just check if the bounce pfn is equal * to or bigger than the highest pfn in the system -- in that case,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/README.1025.ddma.patch linux-2.6.15/README.1025.ddma.patch--- linux-2.6.15.ref/README.1025.ddma.patch 1969-12-31 16:00:00.000000000 -0800+++ linux-2.6.15/README.1025.ddma.patch 2007-07-06 10:38:05.000000000 -0700@@ -0,0 +1,21 @@+Feature:+--------+Enabling more direct DDMA (adding RUA memory as well) operations.++Prerequisite patch numbers:+---------------------------+0000+1000+1003+1004++Primary author:+---------------+Craig Qu/YH Lin++Related to which chip version SMP86xx xx=?+-----------------------------------------+Tango2 ES6/RevA or above, or Tango3 ES1 or above++(linux patches) which CONFIG_... are provided:+----------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -