Messages in this thread | | | Date | Tue, 23 Sep 2008 17:53:06 +0800 | From | "殺人熊" <> | Subject | IDE DMA sglist handle probelem |
| |
Hi,
I want to test a private cache for IDE R/W in 2.6.26. Before develop the private cache, I need to do something with the IDE read/write buffer. If service a read command, I replace the DMA buffer address of sglist by my buffer before transfer, and memcpy the received data(in my buffer) to original DMA buffer of sglist. If service a write command, I replace the DMA buffer address by my buffer, and memcpy the write data from sglist to my buffer, then transfer it. I implement it on linux-2.6.26/drivers/ata/libata-core.c.
I replace each DMA address of sglist as follow: ----------------------------------------------------------------------------- for_each_sg(qc->sg, sg, qc->n_elem, si) { u32 addr, len; addr = sg_dma_address(sg); len = sg_dma_len(sg);
//if write command, copy data from DMA address to my buf if (qc->tf.command == ATA_CMD_WRITE || qc->tf.command == ATA_CMD_WRITE_EXT) { memcpy(myBuf[si], bus_to_virt(addr), len); }
//save orignal DAM address savedAddr[si] = (unsigned char *)addr;
//replace DMA address by my buf sg_dma_address(sg) = myBuf[si]; } ----------------------------------------------------------------------------- The book Linux Device Driver say that driver can not access DMA sg between dma_map_sg and dma_unmap_sg, so I implement them before dma_map_sg and after dma_unmap_sg. I use a burn-in tool to test the fixed functions, and found the data verify success for 80 hours, buf if I try to extract three big packages in the disk at the same time, the kernel panic:
BUG: unable to handle kernel paging request a ff450fd7 IP:[<c05f5ba4>] iret_exc+0x68c/0x8d2 *pde = 00008067 *pte = 00000000 Oop : 0002 [#1] SMP
I do not know what is wrong. How to access the sglist DMA buffer correctly?
| |