Hi, As some good news and additional information, with the following patch I no more get "UDP bad cheksum" error as I mentioned erlier with Iperf in udp mode. But some times I get the following call trace in dmesg after running Iperf in UDP mode, more than one time (and ofcourse Iperf stops transferring data while it uses 100% of CPU cycles. [ 130.171909] mydriver-aes: mydriver Crypto-Engine enabled. [ 134.767846] NET: Registered protocol family 15 [ 200.031846] iperf: page allocation failure. order:0, mode:0x20 [ 200.031850] Pid: 10935, comm: iperf Tainted: P 2.6.36-zen1 #1 [ 200.031852] Call Trace: [ 200.031860] [<ffffffff8108ab39>] ? __alloc_pages_nodemask+0x6d3/0x722 [ 200.031864] [<ffffffff810b454f>] ? virt_to_head_page+0x9/0x30 [ 200.031867] [<ffffffff810afac2>] ? alloc_pages_current+0xa5/0xce [ 200.031869] [<ffffffff810899ad>] ? __get_free_pages+0x9/0x46 [ 200.031872] [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23 [ 200.031876] [<ffffffff811a10ad>] ? blkcipher_walk_next+0x68/0x2d9 [ 200.031882] [<ffffffffa001dad4>] ? mydriver_cbc_encrypt+0x47/0x9c [mydriver_aes2] [ 200.031886] [<ffffffff81454789>] ? ipt_do_table+0x5d8/0x619 [ 200.031888] [<ffffffff811a0871>] ? async_encrypt+0x35/0x3a [ 200.031891] [<ffffffff811a1e0c>] ? eseqiv_givencrypt+0x341/0x389 [ 200.031894] [<ffffffff813b8bb5>] ? __skb_to_sgvec+0x49/0x1ea [ 200.031897] [<ffffffff813b8d1e>] ? __skb_to_sgvec+0x1b2/0x1ea [ 200.031899] [<ffffffff811a8fc8>] ? crypto_authenc_givencrypt+0x60/0x7c [ 200.031902] [<ffffffff814492dd>] ? esp_output+0x320/0x357 [ 200.031905] [<ffffffff814658cd>] ? xfrm_output_resume+0x38d/0x48f [ 200.031908] [<ffffffff813e1f62>] ? nf_hook_slow+0xc8/0xd9 [ 200.031911] [<ffffffff81416f9f>] ? ip_push_pending_frames+0x2cc/0x328 [ 200.031914] [<ffffffff8143339e>] ? udp_push_pending_frames+0x2c4/0x342 [ 200.031917] [<ffffffff814350ca>] ? udp_sendmsg+0x508/0x600 [ 200.031919] [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23 [ 200.031923] [<ffffffff813b3458>] ? sock_aio_write+0xd5/0xe9 [ 200.031926] [<ffffffff8100340e>] ? apic_timer_interrupt+0xe/0x20 [ 200.031928] [<ffffffff810ba2ea>] ? do_sync_write+0xb0/0xf2 [ 200.031931] [<ffffffff8100864b>] ? sched_clock+0x5/0x8 [ 200.031934] [<ffffffff8119c550>] ? security_file_permission+0x18/0x67 [ 200.031937] [<ffffffff810bac07>] ? vfs_write+0xbc/0x101 [ 200.031939] [<ffffffff810bad08>] ? sys_write+0x45/0x6e [ 200.031941] [<ffffffff81002a42>] ? system_call_fastpath+0x16/0x1b [ 200.031942] Mem-Info: [ 200.031944] Node 0 DMA per-cpu: [ 200.031946] CPU 0: hi: 0, btch: 1 usd: 0 [ 200.031947] CPU 1: hi: 0, btch: 1 usd: 0 [ 200.031949] CPU 2: hi: 0, btch: 1 usd: 0 [ 200.031950] CPU 3: hi: 0, btch: 1 usd: 0 [ 200.031951] Node 0 DMA32 per-cpu: [ 200.031953] CPU 0: hi: 186, btch: 31 usd: 30 [ 200.032016] CPU 1: hi: 186, btch: 31 usd: 23 [ 200.032018] CPU 2: hi: 186, btch: 31 usd: 182 [ 200.032019] CPU 3: hi: 186, btch: 31 usd: 171 [ 200.032023] active_anon:248219 inactive_anon:82742 isolated_anon:7 [ 200.032024] active_file:10553 inactive_file:11106 isolated_file:27 [ 200.032025] unevictable:0 dirty:19 writeback:1881 unstable:0 [ 200.032026] free:2536 slab_reclaimable:2970 slab_unreclaimable:6490 [ 200.032026] mapped:19597 shmem:292 pagetables:12316 bounce:0 [ 200.032028] Node 0 DMA free:8012kB min:40kB low:48kB high:60kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15768kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:16kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes [ 200.032036] lowmem_reserve[]: 0 2002 2002 2002 [ 200.032039] Node 0 DMA32 free:2132kB min:5704kB low:7128kB high:8556kB active_anon:992876kB inactive_anon:330968kB active_file:42212kB inactive_file:44424kB unevictable:0kB isolated(anon):28kB isolated(file):108kB present:2050992kB mlocked:0kB dirty:76kB writeback:7524kB mapped:78388kB shmem:1168kB slab_reclaimable:11880kB slab_unreclaimable:25944kB kernel_stack:2320kB pagetables:49264kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 200.032050] lowmem_reserve[]: 0 0 0 0 [ 200.032059] Node 0 DMA: 1*4kB 1*8kB 0*16kB 0*32kB 1*64kB 0*128kB 1*256kB 1*512kB 1*1024kB 1*2048kB 1*4096kB = 8012kB [ 200.032066] Node 0 DMA32: 1*4kB 0*8kB 1*16kB 0*32kB 1*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 1*2048kB 0*4096kB = 2132kB [ 200.032072] 37527 total pagecache pages [ 200.032074] 15549 pages in swap cache [ 200.032075] Swap cache stats: add 72816, delete 57267, find 8267/8477 [ 200.032076] Free swap = 3832196kB [ 200.032078] Total swap = 4096568kB [ 200.040499] 523951 pages RAM [ 200.040501] 9684 pages reserved [ 200.040502] 231120 pages shared [ 200.040503] 486710 pages non-shared [ 200.040514] BUG: unable to handle kernel NULL pointer dereference at (null) [ 200.040517] IP: [<ffffffffa001d395>] mydriver_transform+0x1a3/0x6a8 [mydriver_aes2] [ 200.040523] PGD 7c3dd067 PUD 41dc067 PMD 0 [ 200.040526] Oops: 0000 [#1] PREEMPT SMP [ 200.040528] last sysfs file: /sys/devices/virtual/misc/fuse/dev [ 200.040530] CPU 0 [ 200.040531] Modules linked in: ctr twofish_generic twofish_x86_64 twofish_common camellia serpent blowfish cast5 xcbc rmd160 sha512_generic sha256_generic crypto_null af_key mydriver_aes2 fuse nvidia(P) r8169 iTCO_wdt iTCO_vendor_support [ 200.040542] [ 200.040544] Pid: 10935, comm: iperf Tainted: P 2.6.36-zen1 #1 EP45-UD3P/EP45-UD3P [ 200.040546] RIP: 0010:[<ffffffffa001d395>] [<ffffffffa001d395>] mydriver_transform+0x1a3/0x6a8 [mydriver_aes2] [ 200.040550] RSP: 0018:ffff880072c5b898 EFLAGS: 00010246 [ 200.040551] RAX: ffff880055a3a030 RBX: 0000000000000680 RCX: 00000000000005f0 [ 200.040553] RDX: 0000000000000680 RSI: 0000000000000000 RDI: ffff880055a3a030 [ 200.040555] RBP: 0000000000000000 R08: 0000000000000680 R09: 0000000000000018 [ 200.040556] R10: 000000007d078004 R11: 0000000000013234 R12: 0000000000000010 [ 200.040558] R13: 0000000000000004 R14: 00000000eaef0000 R15: 00000000000005f0 [ 200.040561] FS: 0000000041767950(0063) GS:ffff880001a00000(0000) knlGS:0000000000000000 [ 200.040562] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 200.040564] CR2: 0000000000000000 CR3: 000000007409d000 CR4: 00000000000406f0 [ 200.040566] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 200.040568] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 200.040570] Process iperf (pid: 10935, threadinfo ffff880072c5a000, task ffff880006d09000) [ 200.040571] Stack: [ 200.040572] ffff880006d09000 0000000000000000 ffffffff817854f0 0000000000000020 [ 200.040574] <0> 0000000000000000 0000efea72c5b9e8 ffff88007d4a7c58 00000001810afac2 [ 200.040577] <0> 0000000000000000 ffff88004d53dc00 ffff880072c5b901 000000000000000f [ 200.040580] Call Trace: [ 200.040585] [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23 [ 200.040588] [<ffffffffa001db0b>] ? mydriver_cbc_encrypt+0x7e/0x9c [mydriver_aes2] [ 200.040592] [<ffffffff811a0871>] ? async_encrypt+0x35/0x3a [ 200.040595] [<ffffffff811a1e0c>] ? eseqiv_givencrypt+0x341/0x389 [ 200.040598] [<ffffffff813b8bb5>] ? __skb_to_sgvec+0x49/0x1ea [ 200.040600] [<ffffffff813b8d1e>] ? __skb_to_sgvec+0x1b2/0x1ea [ 200.040603] [<ffffffff811a8fc8>] ? crypto_authenc_givencrypt+0x60/0x7c [ 200.040607] [<ffffffff814492dd>] ? esp_output+0x320/0x357 [ 200.040610] [<ffffffff814658cd>] ? xfrm_output_resume+0x38d/0x48f [ 200.040613] [<ffffffff813e1f62>] ? nf_hook_slow+0xc8/0xd9 [ 200.040616] [<ffffffff81416f9f>] ? ip_push_pending_frames+0x2cc/0x328 [ 200.040619] [<ffffffff8143339e>] ? udp_push_pending_frames+0x2c4/0x342 [ 200.040621] [<ffffffff814350ca>] ? udp_sendmsg+0x508/0x600 [ 200.040623] [<ffffffff8102bbbf>] ? need_resched+0x1a/0x23 [ 200.040627] [<ffffffff813b3458>] ? sock_aio_write+0xd5/0xe9 [ 200.040630] [<ffffffff8100340e>] ? apic_timer_interrupt+0xe/0x20 [ 200.040633] [<ffffffff810ba2ea>] ? do_sync_write+0xb0/0xf2 [ 200.040636] [<ffffffff8100864b>] ? sched_clock+0x5/0x8 [ 200.040639] [<ffffffff8119c550>] ? security_file_permission+0x18/0x67 [ 200.040641] [<ffffffff810bac07>] ? vfs_write+0xbc/0x101 [ 200.040643] [<ffffffff810bad08>] ? sys_write+0x45/0x6e [ 200.040646] [<ffffffff81002a42>] ? system_call_fastpath+0x16/0x1b [ 200.040647] Code: 83 c0 08 80 7c 24 50 01 75 10 48 89 c7 49 63 cc 48 8b 74 24 48 f3 a4 48 89 f8 48 89 c7 48 8b 74 24 40 41 0f b7 d8 49 63 cf 89 da <f3> a4 4c 8b 2d 62 1d 00 00 48 8b 3d 53 1d 00 00 b1 01 48 8b 74 [ 200.040668] RIP [<ffffffffa001d395>] mydriver_transform+0x1a3/0x6a8 [mydriver_aes2] [ 200.040671] RSP <ffff880072c5b898> [ 200.040672] CR2: 0000000000000000 [ 200.040733] ---[ end trace ae2865df0a025f7d ]--- [ 221.687773] SysRq : Emergency Sync BUT Iperf in TCP mode has its own problems yet ( the system freezes with no response ). Thank in advance, Hamid. --- mydriver1 2010-12-21 15:20:17.000000000 +0330 +++ mydriver2 2010-12-21 15:24:18.000000000 +0330 @@ -1,4 +1,3 @@ - static int mydriver_cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, @@ -14,18 +13,17 @@ mydriver_cbc_decrypt(struct blkcipher_desc err = blkcipher_walk_virt(desc, &walk); op->iv = walk.iv; - while((nbytes = walk.nbytes)) { + op->src = walk.src.virt.addr, op->dst = walk.dst.virt.addr; op->mode = AES_MODE_CBC; - op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE); + op->len = nbytes; op->dir = AES_DIR_DECRYPT; - ret = mydriver_transform(op, 0); nbytes -= ret; err = blkcipher_walk_done(desc, &walk, nbytes); - } + return err; } @@ -45,16 +43,17 @@ mydriver_cbc_encrypt(struct blkcipher_desc err = blkcipher_walk_virt(desc, &walk); op->iv = walk.iv; - while((nbytes = walk.nbytes)) { + op->src = walk.src.virt.addr, op->dst = walk.dst.virt.addr; op->mode = AES_MODE_CBC; - op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE); + op->len = nbytes; op->dir = AES_DIR_ENCRYPT; ret = mydriver_transform(op, 0); nbytes -= ret; err = blkcipher_walk_done(desc, &walk, nbytes); - } + return err; } + ---------- Forwarded message ---------- From: Hamid Nassiby <h.nassiby@xxxxxxxxx> Date: Sun, Dec 19, 2010 at 4:28 PM Subject: crypto accelerator driver problems To: linux-crypto@xxxxxxxxxxxxxxx Hi All, In a research project, we've developed a crypto accelerator based on Xilinx Virtex5 FPGA family whichÂis connected to PC through PCI-Express slot and is used by IPSec to offload crypto processing fromÂCPU. The accelerator only provides AES and DES3_EDE algorithms and I am responsible for providing driver of the stuff. I inspired much of driver work from geode_aes.c which is located in "drivers/crypto" subdir of kernel source directory. Both algorithms are registered as blkcipher providing cbc wrapper "cbc(aes)" just as one that is registered in geode_aes. Now after months of work, the accelerator is ready to work (Correctness of hardware operation is assured by direct crypto test and not by IPSec) and it is time of driver to provide IPSec access to accelerator. In first try I could get Â"ping" through the IPsec tunnel. One end of IPSec tunnel is equipped by our accelerator and the other end is using kernel native IPSec and built in AES and DES3_EDE algorithms. Now I am faced with 2 problems: 1. Ping will stop getting reply with packet sizes greater than 1426 Bytes (ping dest_ip -s Â1427). I guessed that it might be MTU problem, but reducing mtu with "ifconfig eth1 mtu xxx" or "echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc" Âdoes not solve the problem. Also when I ping each of tunnel ends from another end simultaneously with "ping other_node_ip -i 0.001", the kernel hangs out completely. 2. Iperf problem. When I try to measure throughput of the IPSec gateway equipped by our accelerator ( AES-MD5 ), using iperf in tcp mode, the kernel hangs such that sometimes "Magic SysRq key" does not respond too! And so I could not trace the problem anyway. Using iperf in udp mode works but I get "UDP bad cheksum" in 'dmesg' output of other end of tunnel (Native IPSec and built in kernel algorithms). Two gateways are connected by a cross cable and no router/switch is located between them to cause mtu problems. In my test pcrypt is not used by now and booting the kernel with nosmp (so no fear of thread contention) does not change the situation. So I request you to help me solve the problem. I bring some parts of driver that is changed from geode_aes.c and might give useful information. If it is required, I'll post all driver text. ------------------------------ ---------------------------- static struct crypto_alg mydriver_cbc_alg = {    Â.cra_name        =    "cbc(aes)",    Â.cra_driver_name    Â=    "cbc-aes-mydriver",    Â.cra_priority      =    400,    Â.cra_flags           Â=    CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,    Â.cra_init            =    fallback_init_blk,    Â.cra_exit            =    fallback_exit_blk,    Â.cra_blocksize     Â=    AES_MIN_BLOCK_SIZE,    Â.cra_ctxsize      Â=    sizeof(struct mydriver_aes_op),    Â.cra_alignmask     Â=    15,    Â.cra_type            =    &crypto_blkcipher_type,    Â.cra_module           =    THIS_MODULE,    Â.cra_list            = LIST_HEAD_INIT(mydriver_cbc_alg.cra_list),    Â.cra_u             Â=    {        Â.blkcipher   Â=    {            Â.min_keysize  Â=    AES_MIN_KEY_SIZE,            Â.max_keysize  Â=    AES_MIN_KEY_SIZE,            Â.setkey         =    mydriver_setkey_blk,            Â.encrypt        Â=    mydriver_cbc_encrypt,            Â.decrypt        Â=    mydriver_cbc_decrypt,            Â.ivsize         =    AES_IV_LENGTH,        Â}    Â} }; //--------------- static int mydriver_cbc_encrypt(struct blkcipher_desc *desc,         Âstruct scatterlist *dst, struct scatterlist *src,         Âunsigned int nbytes) {    Âstruct mydriver_aes_op *op = crypto_blkcipher_ctx(desc->tfm);    Âstruct blkcipher_walk walk;    Âint err, ret;    Âif (unlikely(op->keylen != AES_KEYSIZE_128))        Âreturn fallback_blk_enc(desc, dst, src, nbytes);    Âblkcipher_walk_init(&walk, dst, src, nbytes);    Âerr = blkcipher_walk_virt(desc, &walk);    Âop->iv = walk.iv;    Âwhile((nbytes = walk.nbytes)) {        Âop->src = walk.src.virt.addr,        Âop->dst = walk.dst.virt.addr;        Âop->mode = AES_MODE_CBC;        Âop->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE);        Âop->dir = AES_DIR_ENCRYPT;            Â//ret = mydriver_aes_crypt(op);        Âret = mydriver_transform(op, 0);        Ânbytes -= ret;        Âerr = blkcipher_walk_done(desc, &walk, nbytes);    Â}    Âreturn err; } /*--------- mydriver_transform which makes a buffer containing key, iv, data with some additional header that is required by our accelerator, writes the buffer to accelerator by DMA and then reads response from hardware.*/ static inline int mydriver_transform(struct mydriver_aes_op *op, int alg) {        Âint Âreq_len, err;        Âu8 *req_buf = NULL, *res_buf = NULL;        Âalg_operation operation;        Âu32 my_req_id;        Âif (op->len == 0)            Âreturn 0;        Âif ((op->dir == AES_DIR_ENCRYPT) ||(op->dir == DES3_DIR_ENCRYPT)){             operation = SH_ENCRYPT;             my_req_id = smp_processor_id();// This ID is put into our packet and is checked by each thread when the hardware response is ready to see if the packet is its?        Â}        Âelse {            Âoperation = SH_DECRYPT;            Âmy_req_id = smp_processor_id() + 64; //uniqueness of ID does not solve problem described in mail :( .        Â}        Âerr = create_request(alg, op->mode, operation, htonl(my_req_id), op->key, op->iv, op->src, op->len, &req_buf, &req_len);        Âif (err){            Âprintk(KERN_EMERG"mydriver_transform : Error CreateReuest : errcode = %d\n", err);            Â//goto error;        Â}        Âerr = write_request(req_buf, req_len);        Âif (err){            Âprintk(KERN_EMERG"mydriver_transform : Error WriteReuest : errcode = %d\n", err);            Â//goto error;        Â}        Âkfree(req_buf);        Âreq_buf = NULL;        Âerr = read_response(&res_buf, /*local_hdr.Length*/my_req_id);        Âmemcpy(op->dst, (res_buf + sizeof(struct response_hdr)), op->len);        Âkfree(res_buf);        Âres_buf = NULL;        Âreturn op->len; } //----------- /* create_request wich builds packet for mydriver_transform */ static inline int create_request(int alg, char mode, char enc_dec, u32 request_id,          char *key, char *iv, char *data, int datalen,          u8 **outbuf, int *outlen) {    Âint req_len, n_padding, keylen, blocklen, algid;    Âstruct request_hdr *p_hdr;    Âchar *ptr;    Âif (alg == 0){ //AES Algorithm        Âkeylen = 16;        Âblocklen = 16;        Âalgid = 4;    Â} else if (alg == 1){ //DES3 Algorithm        Âkeylen = 24;        Âblocklen = 8;        Âalgid = 3;    Â}    Âreq_len = sizeof(struct request_hdr) + keylen;    Âif (keylen != 0 && keylen % 16 == 0)        Âreq_len += 8; //For request packet to be 128bit aligned    Âif (mode == SHAMS_CBC)        Âreq_len += blocklen; // for IV len    Ân_padding = (blocklen - (datalen % blocklen)) % blocklen; //padding data to be multiple of 128 bits.    Âreq_len += (n_padding + datalen);    Â*outbuf = kmalloc(req_len, GFP_ATOMIC);    Âp_hdr = (struct request_hdr *) *outbuf;    Â*outlen = p_hdr->Length = req_len;    Âp_hdr->request_id = request_id;    Âp_hdr->AlgID_Mode_EncDec = (enc_dec << 15) | (mode << 12) | algid;    Â// Filling key    Âptr = *outbuf + sizeof(struct request_hdr);    Âmemcpy(ptr, key, keylen);    Âptr += keylen;    Âif (keylen != 0 && keylen % 16 == 0){        Âmemset(ptr, 0, 8);        Âptr += 8;    Â}    Â// Filling IV    Âif (mode == SHAMS_CBC){        Âmemcpy(ptr, iv, blocklen);        Âptr += blocklen;    Â}    Â// Copy data    Âmemcpy(ptr, data, datalen);    Âptr += datalen;    Â// Zeroing padd bits    Âmemset(ptr, 0, n_padding);    Âreturn 0; } //-------------------------------- /* write_request that writes the provided buffer to device */ static inline int write_request(u8 *buff, unsigned int count) { unsigned long Âiflags; u32 tlp_count, tlp_size; dma_addr_t dma_addr; struct x5pcie_dma_desc *desc_table = (struct x5pcie_dma_desc *)global_bar[0]; /** DMA operations:*/    Âdma_addr = pci_map_single(global_dev, buff, count, PCI_DMA_TODEVICE);    Âif (0 == dma_addr) {        Âprintk(KERN_EMERG"XPCIe_Read: Map error.\n");        Âreturn -1;    Â} // Do DMA transfer here....    Âcount = count /4;//    Âfor (tlp_size = 32; tlp_size > 0; tlp_size--)        Âif ((count % tlp_size) == 0){            Âtlp_count = count / tlp_size;            Âbreak;        Â}    Âtlp_size = tlp_count | (tlp_size << 16);    Âspin_lock_irqsave(&wlock, iflags);    Â//down(&my_sem); //   Âif (down_interruptible(&my_sem)){ //       Âprintk(KERN_EMERG "\nwrite_request: Error Acquire Semaphore!!"); //       Âreturn -ERESTARTSYS; //   Â}    Âwritel(cpu_to_le32(tlp_size),&desc_table->rdmatlpc);       // read DMA TLP count: ÂTLPs to transfer    Âwritel(cpu_to_le32(dma_addr),&desc_table->rdmatlpa); Â// physical bus address of DMA able buffer    Âwmb();    Âwritew(cpu_to_le16(0x0001),(global_bar[0]+6));        Â// read dma start bit[16] to ddmacr    Âwmb();    Âwhile(readw((global_bar[0]+6)) != 0x0101);    Âspin_unlock_irqrestore(&wlock, iflags);    Â//up(&my_sem);   Â // Unmap the DMA buffer so it is safe for normal access again.    Âpci_unmap_single(global_dev, dma_addr, count, PCI_DMA_TODEVICE);    Â/** End of dma section*/    Âreturn 0; } //-------------- /* read_response that reads the en/decrypted buffer from device */ static inline int read_response(u8 **buff, Âu16 my_req_id) {    Âdma_addr_t dma_addr;    Âu16 count, tmp_req_id;    Âunsigned long Âiflags1;//, iflags2;    Âu32 tlp_count, tlp_size;    Âstruct x5pcie_dma_desc *desc_table = (struct x5pcie_dma_desc *)global_bar[0];    Âfor(;;){        Âspin_lock_irqsave(&alock, iflags1);        Âtmp_req_id = readw((global_bar[0] + 82 + (fifo_entry * 4)));        Âspin_unlock_irqrestore(&alock, iflags1);        Âif(my_req_id == tmp_req_id) // Is the provided packet mine?            Âbreak;    Â}            Âcount = readw(global_bar[0] + 80 + (fifo_entry * 4));//What is the size of my packet?            Âprintk(KERN_EMERG "read_response : my_req_id = %d has count = %d\n", my_req_id, count);            Â*buff = kmalloc(count, GFP_ATOMIC);            Âdma_addr = pci_map_single(global_dev, *buff, count, PCI_DMA_FROMDEVICE);            Âif (0 == dma_addr){                Âprintk(KERN_EMERG"XPCIe_Read: Map error.\n");                Âreturn -1;            Â}            Âcount = count /4;//            Âfor (tlp_size = 32; tlp_size > 0; tlp_size--)                Âif ((count % tlp_size) == 0){                    Âtlp_count = count / tlp_size;                    Âbreak;                Â}            Âtlp_size = tlp_count | (tlp_size << 16);    Â//       Âdown(&my_sem); //           Âif (down_interruptible(&my_sem)){ //               Âprintk(KERN_EMERG "\nread_response: Error Acquire Semaphore!!"); //               Âreturn -ERESTARTSYS; //           Â}            Âwritel(cpu_to_le32(tlp_size),&desc_table->wdmatlpc);    Â// read DMA TLP count: ÂTLPs to transfer            Âwritel(cpu_to_le32(dma_addr),&desc_table->wdmatlpa); Â// physical bus address of DMA able buffer            Âwmb();            Âwritew(cpu_to_le16(0x0001),(global_bar[0]+4));   // read dma start bit[16] to ddmacr            Âwmb();            Âwhile(readw(global_bar[0]+4) != 0x0101);            Âfifo_entry = (fifo_entry + 1) % 9; // 9 : Number of registers holding request_id and len of FiFo's elements .            Â//spin_unlock_irqrestore(&rlock, iflags2);            Â//up(&my_sem);            Âpci_unmap_single(global_dev, dma_addr, count, PCI_DMA_FROMDEVICE);            Âreturn count; } Thanks in advance, Hamid. -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html