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

📄 gdth.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
static 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,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,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 */#include <linux/init.h>#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)/* 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;#ifdef MODULE/* 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_AUTHOR("Achim Leubner");#endif/* /proc support */#include <linux/stat.h> #include "gdth_proc.h"#include "gdth_proc.c"/* notifier block to get a notify on system shutdown/halt/reboot */static struct notifier_block gdth_notifier = {    gdth_halt, NULL, 0};static void gdth_delay(int milliseconds){    if (milliseconds == 0) {        udelay(1);    } else {        mdelay(milliseconds);    }}static void gdth_eval_mapping(ulong32 size, int *cyls, int *heads, int *secs){    *cyls = size /HEADS/SECS;    if (*cyls <= MAXCYLS) {	*heads = HEADS;	*secs = SECS;    } else {                            		/* too high for 64*32 */	*cyls = size /MEDHEADS/MEDSECS;	if (*cyls <= MAXCYLS) {	    *heads = MEDHEADS;	    *secs = MEDSECS;	} else {                        		/* too high for 127*63 */	    *cyls = size /BIGHEADS/BIGSECS;	    *heads = BIGHEADS;	    *secs = BIGSECS;	}    }}/* controller search and initialization functions */static int __init gdth_search_eisa(ushort eisa_adr){    ulong32 id;        TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr));    id = inl(eisa_adr+ID0REG);    if (id == GDT3A_ID || id == GDT3B_ID) {     /* GDT3000A or GDT3000B */        if ((inb(eisa_adr+EISAREG) & 8) == 0)               return 0;                           /* not EISA configured */        return 1;    }    if (id == GDT3_ID)                          /* GDT3000 */        return 1;    return 0;                                   }static int __init gdth_search_isa(ulong32 bios_adr){    void *addr;    ulong32 id;    TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr));    if ((addr = gdth_mmap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) {        id = gdth_readl(addr);        gdth_munmap(addr);        if (id == GDT2_ID)                          /* GDT2000 */            return 1;    }    return 0;}static int __init gdth_search_pci(gdth_pci_str *pcistr){    ulong32 base0, base1, base2;    ushort device_id, cnt;    struct pci_dev *pdev;        TRACE(("gdth_search_pci()\n"));    cnt = 0;    for (device_id = 0; device_id <= PCI_DEVICE_ID_VORTEX_GDTMAXRP;          ++device_id) {        if (device_id > PCI_DEVICE_ID_VORTEX_GDT6555 &&            device_id < PCI_DEVICE_ID_VORTEX_GDT6x17RP)            continue;        pdev = NULL;        while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev))                != NULL) {	    if (pci_enable_device(pdev))	    	continue;            if (cnt >= MAXHA)                return cnt;            /* GDT PCI controller found, resources are already in pdev */            pcistr[cnt].pdev = pdev;            pcistr[cnt].device_id = device_id;            pcistr[cnt].bus = pdev->bus->number;            pcistr[cnt].device_fn = pdev->devfn;            pcistr[cnt].irq = pdev->irq;            base0 = pdev->resource[0].flags;            base1 = pdev->resource[1].flags;            base2 = pdev->resource[2].flags;            if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */                device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=                     PCI_BASE_ADDRESS_SPACE_MEMORY)                    continue;                pcistr[cnt].dpmem = pdev->resource[0].start;            } else {                                    /* GDT6110, GDT6120, .. */                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=                    PCI_BASE_ADDRESS_SPACE_MEMORY ||                    (base2 & PCI_BASE_ADDRESS_SPACE) !=                    PCI_BASE_ADDRESS_SPACE_MEMORY ||                    (base1 & PCI_BASE_ADDRESS_SPACE) !=                    PCI_BASE_ADDRESS_SPACE_IO)                    continue;                pcistr[cnt].dpmem = pdev->resource[2].start;                pcistr[cnt].io_mm = pdev->resource[0].start;                pcistr[cnt].io    = pdev->resource[1].start;            }            TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%x\n",                    pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn),                     pcistr[cnt].irq, pcistr[cnt].dpmem));            cnt++;        }           }       return cnt;}static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt){        gdth_pci_str temp;    int i, changed;        TRACE(("gdth_sort_pci() cnt %d\n",cnt));    if (cnt == 0)        return;    do {        changed = FALSE;        for (i = 0; i < cnt-1; ++i) {            if (!reverse_scan) {                if ((pcistr[i].bus > pcistr[i+1].bus) ||                    (pcistr[i].bus == pcistr[i+1].bus &&                     PCI_SLOT(pcistr[i].device_fn) >                      PCI_SLOT(pcistr[i+1].device_fn))) {                    temp = pcistr[i];                    pcistr[i] = pcistr[i+1];                    pcistr[i+1] = temp;                    changed = TRUE;                }            } else {                if ((pcistr[i].bus < pcistr[i+1].bus) ||                    (pcistr[i].bus == pcistr[i+1].bus &&                     PCI_SLOT(pcistr[i].device_fn) <                      PCI_SLOT(pcistr[i+1].device_fn))) {                    temp = pcistr[i];                    pcistr[i] = pcistr[i+1];                    pcistr[i+1] = temp;                    changed = TRUE;                }            }        }    } while (changed);}static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha){    ulong32 retries,id;    unchar prot_ver,eisacf,i,irq_found;    TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr));        /* disable board interrupts, deinitialize services */    outb(0xff,eisa_adr+EDOORREG);    outb(0x00,eisa_adr+EDENABREG);    outb(0x00,eisa_adr+EINTENABREG);        outb(0xff,eisa_adr+LDOORREG);    retries = INIT_RETRIES;    gdth_delay(20);    while (inb(eisa_adr+EDOORREG) != 0xff) {        if (--retries == 0) {            printk("GDT-EISA: Initialization error (DEINIT failed)\n");            return 0;        }        gdth_delay(1);        TRACE2(("wait for DEINIT: retries=%d\n",retries));    }    prot_ver = inb(eisa_adr+MAILBOXREG);    outb(0xff,eisa_adr+EDOORREG);    if (prot_ver != PROTOCOL_VERSION) {        printk("GDT-EISA: Illegal protocol version\n");        return 0;    }    ha->bmic = eisa_adr;    ha->brd_phys = (ulong32)eisa_adr >> 12;    outl(0,eisa_adr+MAILBOXREG);    outl(0,eisa_adr+MAILBOXREG+4);    outl(0,eisa_adr+MAILBOXREG+8);    outl(0,eisa_adr+MAILBOXREG+12);    /* detect IRQ */     if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) {        ha->type = GDT_EISA;        ha->stype = id;        outl(1,eisa_adr+MAILBOXREG+8);        outb(0xfe,eisa_adr+LDOORREG);        retries = INIT_RETRIES;        gdth_delay(20);        while (inb(eisa_adr+EDOORREG) != 0xfe) {            if (--retries == 0) {                printk("GDT-EISA: Initialization error (get IRQ failed)\n");                return 0;            }            gdth_delay(1);        }        ha->irq = inb(eisa_adr+MAILBOXREG);        outb(0xff,eisa_adr+EDOORREG);        TRACE2(("GDT3000/3020: IRQ=%d\n",ha->irq));        /* check the result */        if (ha->irq == 0) {                TRACE2(("Unknown IRQ, use IRQ table from cmd line !\n"));                for (i = 0, irq_found = FALSE;                      i < MAXHA && irq[i] != 0xff; ++i) {                if (irq[i]==10 || irq[i]==11 || irq[i]==12 || irq[i]==14) {                    irq_found = TRUE;                    break;                }                }            if (irq_found) {                ha->irq = irq[i];                irq[i] = 0;                printk("GDT-EISA: Can not detect controller IRQ,\n");                printk("Use IRQ setting from command line (IRQ = %d)\n",                       ha->irq);            } else {                printk("GDT-EISA: Initialization error (unknown IRQ), Enable\n");                printk("the controller BIOS or use command line parameters\n");                return 0;            }        }    } else {        eisacf = inb(eisa_adr+EISAREG) & 7;        if (eisacf > 4)                         /* level triggered */            eisacf -= 4;        ha->irq = gdth_irq_tab[eisacf];        ha->type = GDT_EISA;        ha->stype = id;    }    return 1;}       static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha){    register gdt2_dpram_str *dp2_ptr;    int i;    unchar irq_drq,prot_ver;    ulong32 retries;    TRACE(("gdth_init_isa() bios adr. %x\n",bios_adr));    ha->brd = gdth_mmap(bios_adr, sizeof(gdt2_dpram_str));    if (ha->brd == NULL) {        printk("GDT-ISA: Initialization error (DPMEM remap error)\n");        return 0;

⌨️ 快捷键说明

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