⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 megaraid.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <linux/delay.h>#include <linux/pci.h>#include <linux/proc_fs.h>#include <linux/blk.h>#include <linux/wait.h>#include <linux/tqueue.h>#include <linux/interrupt.h>#include <linux/mm.h>#include <asm/pgtable.h>#include <linux/sched.h>#include <linux/stat.h>#include <linux/slab.h>	/* for kmalloc() */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)	/* 0x20100 */#include <linux/bios32.h>#else#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)	/* 0x20300 */#include <asm/spinlock.h>#else#include <linux/spinlock.h>#endif#endif#include <asm/io.h>#include <asm/irq.h>#if LINUX_VERSION_CODE > KERNEL_VERSION(2,0,24)	/* 0x020024 */#include <asm/uaccess.h>#endif/* * These header files are required for Shutdown Notification routines */#include <linux/notifier.h>#include <linux/reboot.h>#include <linux/init.h>#include "sd.h"#include "scsi.h"#include "hosts.h"#include "megaraid.h"/* *================================================================ *  #Defines *================================================================ */#define MAX_SERBUF 160#define COM_BASE 0x2f8static ulong RDINDOOR (mega_host_config * megaCfg){	return readl (megaCfg->base + 0x20);}static void WRINDOOR (mega_host_config * megaCfg, ulong value){	writel (value, megaCfg->base + 0x20);}static ulong RDOUTDOOR (mega_host_config * megaCfg){	return readl (megaCfg->base + 0x2C);}static void WROUTDOOR (mega_host_config * megaCfg, ulong value){	writel (value, megaCfg->base + 0x2C);}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)	/* 0x020200 */#include <linux/smp.h>#define cpuid smp_processor_id()#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)#define scsi_set_pci_device(x,y)#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 *//* *	Linux 2.4 and higher * *	No driver private lock *	Use the io_request_lock not cli/sti *	queue task is a simple api without irq forms */MODULE_AUTHOR ("LSI Logic Corporation");MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");MODULE_LICENSE ("GPL");#define DRIVER_LOCK_T#define DRIVER_LOCK_INIT(p)#define DRIVER_LOCK(p)#define DRIVER_UNLOCK(p)#define IO_LOCK_T unsigned long io_flags = 0#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);#define queue_task_irq(a,b)     queue_task(a,b)#define queue_task_irq_off(a,b) queue_task(a,b)#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)	/* 0x020200 *//* *	Linux 2.2 and higher * *	No driver private lock *	Use the io_request_lock not cli/sti *	No pci region api *	queue_task is now a single simple API */static char kernel_version[] = UTS_RELEASE;MODULE_AUTHOR ("LSI Logic Corporation");MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");#define DRIVER_LOCK_T#define DRIVER_LOCK_INIT(p)#define DRIVER_LOCK(p)#define DRIVER_UNLOCK(p)#define IO_LOCK_T unsigned long io_flags = 0#define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);#define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);#define pci_free_consistent(a,b,c,d)#define pci_unmap_single(a,b,c,d)#define pci_enable_device(x) (0)#define queue_task_irq(a,b)     queue_task(a,b)#define queue_task_irq_off(a,b) queue_task(a,b)#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,19)	/* 0x020219 */#define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)#define init_MUTEX(x)           (*(x)=MUTEX)#define DECLARE_WAIT_QUEUE_HEAD(x)	struct wait_queue *x = NULL#endif#else/* *	Linux 2.0 macros. Here we have to provide some of our own *	functionality. We also only work little endian 32bit. *	Again no pci_alloc/free api *	IO_LOCK/IO_LOCK_T were never used in 2.0 so now are empty  */ #define cpuid 0#define DRIVER_LOCK_T long cpu_flags;#define DRIVER_LOCK_INIT(p)#define DRIVER_LOCK(p) \       		save_flags(cpu_flags); \       		cli();#define DRIVER_UNLOCK(p) \       		restore_flags(cpu_flags);#define IO_LOCK_T#define IO_LOCK(p)#define IO_UNLOCK(p)#define le32_to_cpu(x) (x)#define cpu_to_le32(x) (x)#define pci_free_consistent(a,b,c,d)#define pci_unmap_single(a,b,c,d)#define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)#define init_MUTEX(x)           (*(x)=MUTEX)#define pci_enable_device(x) (0)/* *	2.0 lacks spinlocks, iounmap/ioremap */#define ioremap vremap#define iounmap vfree /* simulate spin locks */typedef struct {	volatile char lock;} spinlock_t;#define spin_lock_init(x) { (x)->lock = 0;}#define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\                                        (x)->lock=1; save_flags(flags);\                                        cli();}#define spin_unlock_irqrestore(x,flags) { (x)->lock=0; restore_flags(flags);}#define DECLARE_WAIT_QUEUE_HEAD(x)	struct wait_queue *x = NULL#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 */#define dma_alloc_consistent pci_alloc_consistent#define dma_free_consistent pci_free_consistent#else#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,19)	/* 0x020219 */typedef unsigned long dma_addr_t;#endifvoid *dma_alloc_consistent(void *, size_t, dma_addr_t *);void dma_free_consistent(void *, size_t, void *, dma_addr_t);int mega_get_order(int);int pow_2(int);#endif/* set SERDEBUG to 1 to enable serial debugging */#define SERDEBUG 0#if SERDEBUGstatic void ser_init (void);static void ser_puts (char *str);static void ser_putc (char c);static int ser_printk (const char *fmt, ...);#endif#ifdef CONFIG_PROC_FS#define COPY_BACK if (offset > megaCfg->procidx) { \		*eof = TRUE; \        megaCfg->procidx = 0; \        megaCfg->procbuf[0] = 0; \        return 0;} \ if ((count + offset) > megaCfg->procidx) { \      count = megaCfg->procidx - offset; \      *eof = TRUE; } \      memcpy(page, &megaCfg->procbuf[offset], count); \      megaCfg->procidx = 0; \      megaCfg->procbuf[0] = 0;#endif/* * ================================================================ *                    Global variables *================================================================ *//*  Use "megaraid=skipXX" as LILO option to prohibit driver from scanning    XX scsi id on each channel.  Used for Madrona motherboard, where SAF_TE    processor id cannot be scanned */static char *megaraid;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)	/* 0x20100 */#ifdef MODULEMODULE_PARM (megaraid, "s");#endif#endifstatic int skip_id = -1;static int numCtlrs = 0;static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = { 0 };static struct proc_dir_entry *mega_proc_dir_entry;#if DEBUGstatic u32 maxCmdTime = 0;#endifstatic mega_scb *pLastScb = NULL;static struct notifier_block mega_notifier = {	megaraid_reboot_notify,	NULL,	0};/* For controller re-ordering */struct mega_hbas mega_hbas[MAX_CONTROLLERS];/* * The File Operations structure for the serial/ioctl interface of the driver *//* For controller re-ordering */ static struct file_operations megadev_fops = {	ioctl:megadev_ioctl_entry,	open:megadev_open,	release:megadev_close,};/* * Array to structures for storing the information about the controllers. This * information is sent to the user level applications, when they do an ioctl * for this information. */static struct mcontroller mcontroller[MAX_CONTROLLERS];/* The current driver version */static u32 driver_ver = 114;/* major number used by the device for character interface */static int major;static struct semaphore mimd_ioctl_sem;static struct semaphore mimd_entry_mtx;#if SERDEBUGvolatile static spinlock_t serial_lock;#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)	/* 0x20300 */static struct proc_dir_entry proc_scsi_megaraid = {	PROC_SCSI_MEGARAID, 8, "megaraid",	S_IFDIR | S_IRUGO | S_IXUGO, 2};#endif#ifdef CONFIG_PROC_FSextern struct proc_dir_entry proc_root;#endifstatic char mega_ch_class;	/* channels are raid or scsi */#define	IS_RAID_CH(ch)	( (mega_ch_class >> (ch)) & 0x01 )#if SERDEBUGstatic char strbuf[MAX_SERBUF + 1];static void ser_init (void){	unsigned port = COM_BASE;	outb (0x80, port + 3);	outb (0, port + 1);	/* 9600 Baud, if 19200: outb(6,port) */	outb (12, port);	outb (3, port + 3);	outb (0, port + 1);}static void ser_puts (char *str){	char *ptr;	ser_init ();	for (ptr = str; *ptr; ++ptr)		ser_putc (*ptr);}static void ser_putc (char c){	unsigned port = COM_BASE;	while ((inb (port + 5) & 0x20) == 0) ;	outb (c, port);	if (c == 0x0a) {		while ((inb (port + 5) & 0x20) == 0) ;		outb (0x0d, port);	}}static int ser_printk (const char *fmt, ...){	va_list args;	int i;	long flags;	spin_lock_irqsave (&serial_lock, flags);	va_start (args, fmt);	i = vsprintf (strbuf, fmt, args);	ser_puts (strbuf);	va_end (args);	spin_unlock_irqrestore (&serial_lock, flags);	return i;}#define TRACE(a)    { ser_printk a;}#else#define TRACE(A)#endif#define TRACE1(a)static void callDone (Scsi_Cmnd * SCpnt){	if (SCpnt->result) {		TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n",			SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,			SCpnt->target, SCpnt->lun, SCpnt->result));	}	SCpnt->scsi_done (SCpnt);}/*------------------------------------------------------------------------- * *                      Local functions * *-------------------------------------------------------------------------*//*======================= * Free a SCB structure *======================= */static void mega_freeSCB (mega_host_config * megaCfg, mega_scb * pScb){	mega_scb *pScbtmp;	if ((pScb == NULL) || (pScb->idx >= 0xFE)) {		return;	}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	switch (pScb->dma_type) {	case M_RD_DMA_TYPE_NONE:		break;	case M_RD_PTHRU_WITH_BULK_DATA:		pci_unmap_single (megaCfg->dev, pScb->dma_h_bulkdata,				  pScb->pthru->dataxferlen,				  pScb->dma_direction);		break;	case M_RD_EPTHRU_WITH_BULK_DATA:		pci_unmap_single (megaCfg->dev, pScb->dma_h_bulkdata,				  pScb->epthru->dataxferlen,				  pScb->dma_direction);		break;	case M_RD_PTHRU_WITH_SGLIST:	{		int count;		for (count = 0; count < pScb->sglist_count; count++) {			pci_unmap_single (megaCfg->dev,					  pScb->dma_h_sglist[count],					  pScb->sgList[count].length,					  pScb->dma_direction);		}		break;	}	case M_RD_BULK_DATA_ONLY:		pci_unmap_single (megaCfg->dev,				  pScb->dma_h_bulkdata,				  pScb->iDataSize, pScb->dma_direction);		break;	case M_RD_SGLIST_ONLY:		pci_unmap_sg (megaCfg->dev,			      pScb->SCpnt->request_buffer,			      pScb->SCpnt->use_sg, pScb->dma_direction);		break;	default:		break;	}#endif	/* Unlink from pending queue */	if (pScb == megaCfg->qPendingH) {		if (megaCfg->qPendingH == megaCfg->qPendingT)			megaCfg->qPendingH = megaCfg->qPendingT = NULL;		else			megaCfg->qPendingH = megaCfg->qPendingH->next;		megaCfg->qPcnt--;	} else {		for (pScbtmp = megaCfg->qPendingH; pScbtmp;		     pScbtmp = pScbtmp->next) {			if (pScbtmp->next == pScb) {				pScbtmp->next = pScb->next;				if (pScb == megaCfg->qPendingT) {					megaCfg->qPendingT = pScbtmp;				}				megaCfg->qPcnt--;				break;			}		}	}	/* Link back into free list */	pScb->state = SCB_FREE;	pScb->SCpnt = NULL;	if (megaCfg->qFreeH == (mega_scb *) NULL) {		megaCfg->qFreeH = megaCfg->qFreeT = pScb;	} else {		megaCfg->qFreeT->next = pScb;		megaCfg->qFreeT = pScb;	}	megaCfg->qFreeT->next = NULL;	megaCfg->qFcnt++;}/*=========================== * Allocate a SCB structure

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -