paep.c
来自「这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自」· C语言 代码 · 共 1,171 行 · 第 1/3 页
C
1,171 行
/* * $Revision: 1.1 $ * $Source: /home/master/uaep/driver/linux/paep.c,v $ * $Date: 2002/02/21 17:00:41 $ * * $CN{$ * * Copyright (c) 1999-2001 Accelerated Encryption Processing Ltd. (AEP) * Bray Business Park, Southern Cross Route, Bray, Co. Wicklow, Ireland. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of AEP Ltd. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $}CN$ *//* * AEP driver * For a Uniprocessor: * Compile with "gcc -O -DMODULE -D__KERNEL__ -c paep.c" * For an SMP machine: * Compile with "gcc -O -DMODULE -D__KERNEL__ -D__SMP__ -c paep.c" * Install with "root /sbin/insmod paep.o" * See also "lsmod" and "rmmod" * Get the major number from /var/log/messages * Use via "mknod /dev/aep c <major#> <minor#>" * * * History: * * - implemented proc_entry_owner to open and close /proc/paep entry only once for all AEP devices * - kernel style indent, changed write_dma_msg and make_dma_msg to static inline */#include <linux/version.h>/* * Removed this file for compatiblility across * 2.4.* kernels *//*#include <linux/modversions.h>*/#include <linux/kernel.h>#include <linux/init.h>#include <linux/config.h>#include <linux/pci.h>#include <linux/mm.h>#include <linux/module.h>#include <linux/types.h>#include <linux/fs.h>#include <linux/interrupt.h>#include <linux/errno.h> /* for -EBUSY */#include <linux/proc_fs.h>#include <linux/devfs_fs_kernel.h>#include <linux/poll.h>#include <asm/uaccess.h> /* for copy_to_user */#include <asm/io.h> #include "paep.h"#ifndef DRIVER_VERSION#define DRIVER_VERSION "UNLABELLED"#endifstatic char const _RCSId[] = "$Id: paep.c,v 1.1 2002/02/21 17:00:41 tmaher Exp $" "$Source: /home/master/uaep/driver/linux/paep.c,v $";static char aep_version_str[100] = "AEP Device Driver. Version: ";/* add more vendor/id pairs in the future when aep gets its own id's */static struct pci_device_id aep_pci_tbl[] __initdata = { { AEP_PCI_VENDOR, AEP_PCI_ID, AEP_SUBSYS_VENDOR, AEP_SUBSYS_ID, }, { 0, } ,};static struct file_operations aep_fops = { owner: THIS_MODULE, llseek: NULL, read: read_aep, write: write_aep, readdir: NULL, poll: poll_aep, ioctl: NULL, mmap: NULL, open: open_aep, flush: NULL, release: release_aep, fsync: NULL, fasync: NULL, lock: NULL, readv: NULL, writev: NULL};MODULE_DEVICE_TABLE (pci, aep_pci_tbl);static struct pci_driver aep_driver = { name: AEP_DRIVER_NAME, id_table: aep_pci_tbl, probe: aep_init_one_device, remove: aep_remove_one_device, suspend: NULL, resume: NULL};MODULE_AUTHOR("AEP software development team");MODULE_DESCRIPTION("AEP (tm) 1000 PCI cryptographic accelerator driver");MODULE_LICENSE("Dual BSD/GPL");/* globals for this driver - Not visible to the kernel */static struct pci_dev **dev_list_pp = NULL; /* list of AEP devices */static struct pci_dev *proc_entry_owner_p = NULL; /* /proc/paep entry is common to all devices, only open once */static int nb_cards = 0; /* used to generate the names in /dev/paep0, /dev/paep1, /dev/paep<nb_cards> */static int dma_buff_order = 0; /* order of the buffer used to dma data */static void inline write_dma_msg(const DMA_msg_t *msg_p, paep_unit_info_t *dev_param_p, int target_address){ assert(msg_p && dev_param_p && target_address); DPRINTK("writing message to 0x%08X\n", target_address); DPRINTK_MSG(msg_p); writel(msg_p->command, dev_param_p->mem_space + target_address); writel(msg_p->address, dev_param_p->mem_space + target_address + sizeof(u32)); writel(msg_p->length, dev_param_p->mem_space + target_address + 2*sizeof(u32)); return;}static void inline make_dma_msg(DMA_msg_t *msg_p, int command, int address, int length){ assert(msg_p); msg_p->command = command; msg_p->address = address; msg_p->length = length;}int aep_read_procmem(char *buf_p, char **start_pp, off_t offset, int len, int *unused_p, void* also_unused_p){ int count; struct pci_dev *dev_p; paep_unit_info_t *dev_param_p; assert(buf_p && start_pp); len = 0; for (count = 0; count < AEP_MAXCARDS_NB; count++) { if (dev_list_pp[count]) { dev_p = dev_list_pp[count]; dev_param_p = dev_p->driver_data; len += sprintf(buf_p+len, "\nDevice %i:\n",count); /* flags */ len += sprintf(buf_p+len, " Flags = 0x%08X ", dev_param_p->flags); if (dev_param_p->flags) { len += sprintf(buf_p+len, "( "); if (dev_param_p->flags & DEV_OPEN) len += sprintf(buf_p+len, "DEV_OPEN"); if (dev_param_p->flags & DMA_DEV_BUSY) len += sprintf(buf_p+len, " | DMA_DEV_BUSY"); if (dev_param_p->flags & WAITING_FOR_READ_DATA) len += sprintf(buf_p+len, " | WAITING_FOR_READ_DATA"); if (dev_param_p->flags & READ_DATA_AVAILABLE) len += sprintf(buf_p+len, " | READ_DATA_AVAILABLE"); len += sprintf(buf_p+len, " )\n"); } else { len += sprintf(buf_p+len, "\n"); } if (len > LIMIT) return len; /* read state */ len += sprintf(buf_p+len, " Read State = 0x%08X ", dev_param_p->read_state); if (dev_param_p->read_state == RS_IDLE) { len += sprintf(buf_p+len, "( IDLE )\n"); } else if (dev_param_p->read_state == RS_DMA_ACTIVE) { len += sprintf(buf_p+len, "( DMA_ACTIVE )\n"); } else if (dev_param_p->read_state == RS_DMA_COMPLETE) { len += sprintf(buf_p+len, "( DMA_COMPLETE)\n"); } else if (dev_param_p->read_state == RS_DEAD) { len += sprintf(buf_p+len, "( DEAD)\n"); } else { len += sprintf(buf_p+len, "(***Unknown***)\n"); } if (len > LIMIT) return len; /* write state */ len += sprintf(buf_p+len, " Write State = 0x%08X ", dev_param_p->write_state); if (dev_param_p->write_state == WS_IDLE) { len += sprintf(buf_p+len, "( IDLE )\n"); } else if (dev_param_p->write_state == WS_DMA_ACTIVE) { len += sprintf(buf_p+len, "( DMA_ACTIVE )\n"); } else if (dev_param_p->write_state == WS_DMA_COMPLETE) { len += sprintf(buf_p+len, "( DMA_COMPLETE)\n"); } else if (dev_param_p->write_state == WS_DEAD) { len += sprintf(buf_p+len, "( DEAD)\n"); } else { len += sprintf(buf_p+len, "(***Unknown***)\n"); } if (len > LIMIT) return len;#ifdef INSTRUMENT len += sprintf(buf_p+len, " Open Count = %ld\n", dev_param_p->open_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Busy on Open Count = %ld\n", dev_param_p->open_busy_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Close Count = %ld\n", dev_param_p->close_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Read Count = %ld\n", dev_param_p->read_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Read DMA Count = %ld\n", dev_param_p->read_dma_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Busy on Read Count = %ld\n", dev_param_p->read_busy_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Read Byte Count = %ld\n", dev_param_p->read_byte_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Write Count = %ld\n", dev_param_p->write_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Write DMA Count = %ld\n", dev_param_p->write_dma_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Busy on Write Count = %ld\n", dev_param_p->write_busy_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Busy on Write Count 2 = %ld\n", dev_param_p->write_busy_cnt2); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Write Byte Count = %ld\n", dev_param_p->write_byte_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " Interrupt Count = %ld\n", dev_param_p->interrupt_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " SIGNAL_DRIVER: %ld\n", dev_param_p->SIGNAL_DRIVER_int_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " DMA_WRITE_COMPLETE: %ld\n", dev_param_p->DMA_WRITE_COMPLETE_int_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " DMA_WRITE_NO_SPACE: %ld\n", dev_param_p->DMA_WRITE_NO_SPACE_int_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " DMA_WRITE_ERROR: %ld\n", dev_param_p->DMA_WRITE_ERROR_int_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " DMA_READ_COMPLETE: %ld\n", dev_param_p->DMA_READ_COMPLETE_int_cnt); if (len > LIMIT) return len; len += sprintf(buf_p+len, " DMA_READ_ERROR: %ld\n", dev_param_p->DMA_READ_ERROR_int_cnt); if (len > LIMIT) return len;#endif/*INSTRUMENT*/ #ifndef DONT_PRINT_DEBUG_PROC len += sprintf(buf_p+len, " dev_p = 0x%p\n", dev_p); if (len > LIMIT) return len; len += sprintf(buf_p+len, " config_space = 0x%p\n", dev_param_p->config_space); if (len > LIMIT) return len; len += sprintf(buf_p+len, " mem_space = 0x%p\n", dev_param_p->mem_space); if (len > LIMIT) return len; len += sprintf(buf_p+len, " read_dma_buf_p = 0x%p\n", dev_param_p->read_dma_buf_p); if (len > LIMIT) return len; len += sprintf(buf_p+len, " write_dma_buf_p = 0x%p\n", dev_param_p->write_dma_buf_p); if (len > LIMIT) return len; len += sprintf(buf_p+len, " int_inuse = 0x%08x\n", dev_param_p->int_inuse); if (len > LIMIT) return len;#endif/* DONT_PRINT_DEBUG_PROC */ } } return len;}/* Read function*/static ssize_t read_aep(struct file *file_p, char *buf_p, size_t count, loff_t *ppos_p){ paep_unit_info_t *dev_param_p = file_p->private_data; DMA_msg_t msg; unsigned int targ_msg = 0; wait_queue_t local_wq; assert(file_p && buf_p); BANNER(); if((file_p->f_flags & O_NONBLOCK) && (!(dev_param_p->flags & READ_DATA_AVAILABLE))){ return -EAGAIN; } DPRINTK("file_p = 0x%p, buf_p = 0x%p, count = 0x%08X, ppos_p = 0x%p\n", file_p, buf_p, count, ppos_p); init_waitqueue_entry(&local_wq, current); #ifdef INSTRUMENT ++dev_param_p->read_cnt;#endif /* INSTRUMENT */ /* Wait until there is data available before * we proceed with the read. */ down_interruptible(&dev_param_p->read_sem); down(&dev_param_p->aep_sem); dev_param_p->flags &= ~READ_DATA_AVAILABLE; /* Set up the DMA and initiate it */ make_dma_msg(&msg, DMA_DEVICE_READ, virt_to_bus(dev_param_p->read_dma_buf_p), count); targ_msg = get_msg_ptr(dev_param_p); exit_if_invalid_msg_ptr(targ_msg, dev_param_p); /* * set up device and go! * * Note: we don't need to acquire the MUTEX here for two reasons: * 1) we are the only top half routine that touches this stuff, and * the mutex & conditional variable stuff surrounding DMA_DEV_BUSY * art the start of this routine single threads us, therefore 2) only * the interrupt routine can interrupt this stuff. */ /* Write the message we just made to the device */ write_dma_msg(&msg, dev_param_p, targ_msg); /* * Put this mesage on the InBound Post list. When the inbound post list is not * empty the target gets interrupted and takes the next address from the list and * processes the message */ DPRINTK("writing request\n"); add_wait_queue(&dev_param_p->rq, &local_wq); current->state = TASK_INTERRUPTIBLE; post_msg(targ_msg, dev_param_p); /* Suspend the process with a timeout in case our device goes to lunch */ schedule_timeout(IO_TIMEOUT * HZ); remove_wait_queue(&dev_param_p->rq, &local_wq); up(&dev_param_p->aep_sem); /* * Determine whether we completed, or timed out. Note that * there is a small chance here that we both completed and
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?