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

📄 gdth.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
static 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;}#elsestatic void *gdth_mmap(ulong paddr, ulong size) {     return ioremap(paddr, size); }static void gdth_munmap(void *addr) {    return iounmap(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 char *gdth_ioctl_tab[4][MAXHA];                  /* ioctl buffer */static gdth_evt_str ebuffer[MAX_EVENTS];                /* event buffer */static int elastidx;static int eoldidx;static struct {    Scsi_Cmnd   *cmnd;                          /* pending request */    ushort      service;                        /* service */} gdth_cmd_tab[GDTH_MAXCMDS][MAXHA];            /* table of pend. requests */#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,DIN,DUN,DUN,DIN,DIN,DIN,    DIN,DIN,DIN,DNO,DIN,DNO,DNO,DIN,DIN,DIN,DIN,DIN,DIN,DIN,DIN,DIN,    DIN,DIN,DIN,DIN,DIN,DNO,DUN,DNO,DNO,DNO,DUN,DNO,DIN,DIN,DUN,DUN,    DUN,DUN,DUN,DUN,DUN,DIN,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,DIN,DUN,DNO,DUN,DIN,DIN,    DIN,DIN,DIN,DNO,DUN,DIN,DIN,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 */#if LINUX_VERSION_CODE >= 0x020126#include <linux/init.h>#else#define __initfunc(A) A#define __initdata#define __init#endif/* /proc support */#if LINUX_VERSION_CODE >= 0x010300#include <linux/stat.h> struct proc_dir_entry proc_scsi_gdth = {    PROC_SCSI_GDTH, 4, "gdth",    S_IFDIR | S_IRUGO | S_IXUGO, 2};#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);    } else {#if LINUX_VERSION_CODE >= 0x020168        mdelay(milliseconds);#else        int i;        for (i = 0; i < milliseconds; ++i)             udelay(1000);#endif    }}/* controller search and initialization functions */__initfunc (static int gdth_search_eisa(ushort eisa_adr)){    ulong 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;                                   }__initfunc (static int gdth_search_isa(ulong bios_adr)){    void *addr;    ulong id;    TRACE(("gdth_search_isa() bios adr. %lx\n",bios_adr));    if ((addr = gdth_mmap(bios_adr+BIOS_ID_OFFS, sizeof(ulong))) != NULL) {	id = readl(addr);	gdth_munmap(addr);	if (id == GDT2_ID)                          /* GDT2000 */	    return 1;    }    return 0;}__initfunc (static int gdth_search_pci(ushort device_id,ushort index,gdth_pci_str *pcistr)){    int error;    ulong base0,base1,base2;    TRACE(("gdth_search_pci() device_id %d, index %d\n",                 device_id,index));#if LINUX_VERSION_CODE >= 0x20155    if (!pci_present())        return 0;#else    if (!pcibios_present())        return 0;#endif    if (pcibios_find_device(PCI_VENDOR_ID_VORTEX,device_id,index,                             &pcistr->bus,&pcistr->device_fn))        return 0;    /* GDT PCI controller found, now read resources from config space */#if LINUX_VERSION_CODE >= 0x20155    {	struct pci_dev *pdev = pci_find_slot(pcistr->bus, pcistr->device_fn);	base0 = pdev->base_address[0];	base1 = pdev->base_address[1];	base2 = pdev->base_address[2];	if ((error = pcibios_read_config_dword(pcistr->bus,pcistr->device_fn,					       PCI_ROM_ADDRESS,					       (int *) &pcistr->bios))) {	    printk("GDT-PCI: error %d reading configuration space", error);	    return -1;	}	pcistr->irq = pdev->irq;    }#else#if LINUX_VERSION_CODE >= 0x010300#define GDTH_BASEP      (int *)#else#define GDTH_BASEP#endif    if ((error = pcibios_read_config_dword(pcistr->bus,pcistr->device_fn,                                           PCI_BASE_ADDRESS_0,                                           GDTH_BASEP&base0)) ||        (error = pcibios_read_config_dword(pcistr->bus,pcistr->device_fn,                                           PCI_BASE_ADDRESS_1,                                           GDTH_BASEP&base1)) ||        (error = pcibios_read_config_dword(pcistr->bus,pcistr->device_fn,                                           PCI_BASE_ADDRESS_2,                                           GDTH_BASEP&base2)) ||        (error = pcibios_read_config_dword(pcistr->bus,pcistr->device_fn,                                           PCI_ROM_ADDRESS,                                           GDTH_BASEP&pcistr->bios)) ||        (error = pcibios_read_config_byte(pcistr->bus,pcistr->device_fn,                                          PCI_INTERRUPT_LINE,&pcistr->irq))) {        printk("GDT-PCI: error %d reading configuration space", error);        return -1;    }#endif    pcistr->device_id = device_id;    if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000 or GDT6000B */        device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */        if ((base0 & PCI_BASE_ADDRESS_SPACE)!=PCI_BASE_ADDRESS_SPACE_MEMORY)            return -1;        pcistr->dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;    } 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)            return -1;        pcistr->dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;        pcistr->io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;        pcistr->io    = base1 & PCI_BASE_ADDRESS_IO_MASK;    }    return 1;}__initfunc (static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha)){    ulong 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=%ld\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 = (ulong)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, check IRQ table from cmd line !\n"));	    for (i=0,irq_found=FALSE; i<MAXHA && irqs[i]!=0xff; ++i) {		if (irqs[i]!=0) {		    irq_found=TRUE;		    break;		}	    }	    if (irq_found) {		ha->irq = irqs[i];		irqs[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;}       __initfunc (static int gdth_init_isa(ulong bios_adr,gdth_ha_str *ha)){    register gdt2_dpram_str *dp2_ptr;    int i;    unchar irq_drq,prot_ver;    ulong retries;    TRACE(("gdth_init_isa() bios adr. %lx\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;    }    dp2_ptr = (gdt2_dpram_str *)ha->brd;    writeb(1, &dp2_ptr->io.memlock);			/* switch off write protection */    /* reset interface area */    memset_io((char *)&dp2_ptr->u,0,sizeof(dp2_ptr->u));    if (readl(&dp2_ptr->u) != 0) {	printk("GDT-PCI: Initialization error (DPMEM write error)\n");	gdth_munmap(ha->brd);	return 0;    }    /* disable board interrupts, read DRQ and IRQ */    writeb(0xff, &dp2_ptr->io.irqdel);    writeb(0x00, &dp2_ptr->io.irqen);    writeb(0x00, &dp2_ptr->u.ic.S_Status);    writeb(0x00, &dp2_ptr->u.ic.Cmd_Index);    irq_drq = readb(&dp2_ptr->io.rq);    for (i=0; i<3; ++i) {        if ((irq_drq & 1)==0)            break;        irq_drq >>= 1;    }    ha->drq = gdth_drq_tab[i];    irq_drq = readb(&dp2_ptr->io.rq) >> 3;    for (i=1; i<5; ++i) {        if ((irq_drq & 1)==0)            break;        irq_drq >>= 1;    }    ha->irq = gdth_irq_tab[i];    /* deinitialize services */    writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]);    writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx);    writeb(0, &dp2_ptr->io.event);    retries = INIT_RETRIES;    gdth_delay(20);    while (readb(&dp2_ptr->u.ic.S_Status) != 0xff) {        if (--retries == 0) {            printk("GDT-ISA: Initialization error (DEINIT failed)\n");	    gdth_munmap(ha->brd);            return 0;        }        gdth_delay(1);    }    prot_ver = (unchar)readl(&dp2_ptr->u.ic.S_Info[0]);    writeb(0, &dp2_ptr->u.ic.Status);    writeb(0xff, &dp2_ptr->io.irqdel);    if (prot_ver != PROTOCOL_VERSION) {        printk("GDT-ISA: Illegal protocol version\n");	gdth_munmap(ha->brd);        return 0;    }    ha->type = GDT_ISA;

⌨️ 快捷键说明

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