📄 gdth.c
字号:
static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr);static void gdth_readapp_event(gdth_ha_str *ha, unchar application, gdth_evt_str *estr);static void gdth_clear_events(void);static void gdth_copy_internal_data(Scsi_Cmnd *scp,char *buffer,ushort count);static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp);static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive);static int gdth_search_eisa(ushort eisa_adr);static int gdth_search_isa(ulong32 bios_adr);static int gdth_search_pci(gdth_pci_str *pcistr);static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, ushort vendor, ushort dev);static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt);static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha);static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha);static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha);static void gdth_enable_int(int hanum);static int gdth_get_status(unchar *pIStatus,int irq);static int gdth_test_busy(int hanum);static int gdth_get_cmd_index(int hanum);static void gdth_release_event(int hanum);static int gdth_wait(int hanum,int index,ulong32 time);static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, ulong32 p2,ulong32 p3);static int gdth_search_drives(int hanum);static int gdth_analyse_hdrive(int hanum, ushort hdrive);static void *gdth_mmap(ulong paddr, ulong size);static void gdth_munmap(void *addr);static const char *gdth_ctr_name(int hanum);#if LINUX_VERSION_CODE >= 0x010300static void gdth_flush(int hanum);#if LINUX_VERSION_CODE >= 0x020100static int gdth_halt(struct notifier_block *nb, ulong event, void *buf);#elsestatic int halt_called = FALSE;void gdth_halt(void);#endif#endif#ifdef DEBUG_GDTHstatic unchar DebugState = DEBUG_GDTH;#ifdef __SERIAL__#define MAX_SERBUF 160static void ser_init(void);static void ser_puts(char *str);static void ser_putc(char c);static int ser_printk(const char *fmt, ...);static char strbuf[MAX_SERBUF+1];#ifdef __COM2__#define COM_BASE 0x2f8#else#define COM_BASE 0x3f8#endifstatic void ser_init(){ unsigned port=COM_BASE; outb(0x80,port+3); outb(0,port+1); /* 19200 Baud, if 9600: outb(12,port) */ outb(6, port); outb(3,port+3); outb(0,port+1); /* ser_putc('I'); ser_putc(' '); */}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; va_start(args,fmt); i = vsprintf(strbuf,fmt,args); ser_puts(strbuf); va_end(args); return i;}#define TRACE(a) {if (DebugState==1) {ser_printk a;}}#define TRACE2(a) {if (DebugState==1 || DebugState==2) {ser_printk a;}}#define TRACE3(a) {if (DebugState!=0) {ser_printk a;}}#else /* !__SERIAL__ */#define TRACE(a) {if (DebugState==1) {printk a;}}#define TRACE2(a) {if (DebugState==1 || DebugState==2) {printk a;}}#define TRACE3(a) {if (DebugState!=0) {printk a;}}#endif#else /* !DEBUG */#define TRACE(a)#define TRACE2(a)#define TRACE3(a)#endif#ifdef GDTH_STATISTICSstatic ulong32 max_rq=0, max_index=0, max_sg=0;static ulong32 act_ints=0, act_ios=0, act_stats=0, act_rq=0;static struct timer_list gdth_timer;#endif#define PTR2USHORT(a) (ushort)(ulong)(a)#define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) #define INDEX_OK(i,t) ((i)<sizeof(t)/sizeof((t)[0]))#define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata))#define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext)#define CMDDATA(a) (&((gdth_ext_str *)((a)->hostdata))->cmdext)#define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b))#if LINUX_VERSION_CODE < 0x010300static void *gdth_mmap(ulong paddr, ulong size) { if (paddr >= high_memory) return NULL; else return (void *)paddr;}static void gdth_munmap(void *addr) {}inline ulong32 virt_to_phys(volatile void *addr){ return (ulong32)addr;}inline void *phys_to_virt(ulong32 addr){ return (void *)addr;}#define virt_to_bus virt_to_phys#define bus_to_virt phys_to_virt#define gdth_readb(addr) (*(volatile unchar *)(addr))#define gdth_readw(addr) (*(volatile ushort *)(addr))#define gdth_readl(addr) (*(volatile ulong32 *)(addr))#define gdth_writeb(b,addr) (*(volatile unchar *)(addr) = (b))#define gdth_writew(b,addr) (*(volatile ushort *)(addr) = (b))#define gdth_writel(b,addr) (*(volatile ulong32 *)(addr) = (b))#define memset_io(a,b,c) memset((void *)(a),(b),(c))#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))#define PCI_SLOT(devfn) ((devfn >> 3) & 0x1f)#elif LINUX_VERSION_CODE < 0x020100static int remapped = FALSE;static void *gdth_mmap(ulong paddr, ulong size) { if ( paddr >= high_memory) { remapped = TRUE; return vremap(paddr, size); } else { return (void *)paddr; }}static void gdth_munmap(void *addr) { if (remapped) vfree(addr); remapped = FALSE;}#define gdth_readb(addr) readb((ulong)(addr))#define gdth_readw(addr) readw((ulong)(addr))#define gdth_readl(addr) (ulong32)readl((ulong)(addr))#define gdth_writeb(b,addr) writeb((b),(ulong)(addr))#define gdth_writew(b,addr) writew((b),(ulong)(addr))#define gdth_writel(b,addr) writel((ulong32)(b),(ulong)(addr))#elsestatic void *gdth_mmap(ulong paddr, ulong size) { return ioremap(paddr, size); }static void gdth_munmap(void *addr) { return iounmap(addr);}#define gdth_readb(addr) readb((ulong)(addr))#define gdth_readw(addr) readw((ulong)(addr))#define gdth_readl(addr) (ulong32)readl((ulong)(addr))#define gdth_writeb(b,addr) writeb((b),(ulong)(addr))#define gdth_writew(b,addr) writew((b),(ulong)(addr))#define gdth_writel(b,addr) writel((ulong32)(b),(ulong)(addr))#endifstatic unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */static unchar gdth_polling; /* polling if TRUE */static unchar gdth_from_wait = FALSE; /* gdth_wait() */static int wait_index,wait_hanum; /* gdth_wait() */static int gdth_ctr_count = 0; /* controller count */static int gdth_ctr_vcount = 0; /* virt. ctr. count */static int gdth_ctr_released = 0; /* gdth_release() */static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */static struct Scsi_Host *gdth_ctr_vtab[MAXHA*MAXBUS]; /* virt. ctr. table */static unchar gdth_write_through = FALSE; /* write through */static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */static int elastidx;static int eoldidx;#define DIN 1 /* IN data direction */#define DOU 2 /* OUT data direction */#define DNO DIN /* no data transfer */#define DUN DIN /* unknown data direction */static unchar gdth_direction_tab[0x100] = { DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN, DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN, DIN,DUN,DIN,DUN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU, DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU, DOU,DOU,DIN,DIN,DIN,DNO,DUN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DIN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DNO,DNO,DUN,DIN,DNO,DOU,DUN,DNO,DUN,DOU,DOU, DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN};/* __initfunc, __initdata macros */#if LINUX_VERSION_CODE >= 0x020322#define GDTH_INITFUNC(type, func) type __init func #include <linux/init.h>#elif LINUX_VERSION_CODE >= 0x020126#define GDTH_INITFUNC(type, func) __initfunc(type func)#include <linux/init.h>#else#define GDTH_INITFUNC(type, func) type func#define __initdata#define __init#endif#if LINUX_VERSION_CODE >= 0x02015F#define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock)#define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags)#define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags)#define GDTH_LOCK_SCSI_DONE(flags) spin_lock_irqsave(&io_request_lock,flags)#define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(&io_request_lock,flags)#define GDTH_LOCK_SCSI_DOCMD() spin_lock_irq(&io_request_lock)#define GDTH_UNLOCK_SCSI_DOCMD() spin_unlock_irq(&io_request_lock)#else#define GDTH_INIT_LOCK_HA(ha) do {} while (0)#define GDTH_LOCK_HA(ha,flags) do {save_flags(flags); cli();} while (0)#define GDTH_UNLOCK_HA(ha,flags) do {restore_flags(flags);} while (0)#define GDTH_LOCK_SCSI_DONE(flags) do {} while (0)#define GDTH_UNLOCK_SCSI_DONE(flags) do {} while (0)#define GDTH_LOCK_SCSI_DOCMD() do {} while (0)#define GDTH_UNLOCK_SCSI_DOCMD() do {} while (0)#endif/* LILO and modprobe/insmod parameters *//* IRQ list for GDT3000/3020 EISA controllers */static int irq[MAXHA] __initdata = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* disable driver flag */static int disable __initdata = 0;/* reserve flag */static int reserve_mode = 1; /* reserve list */static int reserve_list[MAX_RES_ARGS] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};/* scan order for PCI controllers */static int reverse_scan = 0;/* virtual channel for the host drives */static int hdr_channel = 0;/* max. IDs per channel */static int max_ids = MAXID;/* rescan all IDs */static int rescan = 0;/* map channels to virtual controllers */static int virt_ctr = 0;/* shared access */static int shared_access = 0;#ifdef MODULE#if LINUX_VERSION_CODE >= 0x02011A/* parameters for modprobe/insmod */MODULE_PARM(irq, "i");MODULE_PARM(disable, "i");MODULE_PARM(reserve_mode, "i");MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i");MODULE_PARM(reverse_scan, "i");MODULE_PARM(hdr_channel, "i");MODULE_PARM(max_ids, "i");MODULE_PARM(rescan, "i");MODULE_PARM(virt_ctr, "i");MODULE_PARM(shared_access, "i");MODULE_AUTHOR("Achim Leubner");MODULE_LICENSE("GPL");#endif#endif/* /proc support */#if LINUX_VERSION_CODE >= 0x010300#include <linux/stat.h> #if LINUX_VERSION_CODE < 0x020322struct proc_dir_entry proc_scsi_gdth = { PROC_SCSI_GDTH, 4, "gdth", S_IFDIR | S_IRUGO | S_IXUGO, 2};#endif#include "gdth_proc.h"#include "gdth_proc.c"#endif#if LINUX_VERSION_CODE >= 0x020100/* notifier block to get a notify on system shutdown/halt/reboot */static struct notifier_block gdth_notifier = { gdth_halt, NULL, 0};#endifstatic void gdth_delay(int milliseconds){ if (milliseconds == 0) { udelay(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -