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

📄 gdth.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (ha->type == GDT_EISA) {        outb(0xff, ha->bmic + EDOORREG);        outb(0xff, ha->bmic + EDENABREG);        outb(0x01, ha->bmic + EINTENABREG);    } else if (ha->type == GDT_ISA) {        dp2_ptr = (gdt2_dpram_str *)ha->brd;        gdth_writeb(1, &dp2_ptr->io.irqdel);        gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index);        gdth_writeb(1, &dp2_ptr->io.irqen);    } else if (ha->type == GDT_PCI) {        dp6_ptr = (gdt6_dpram_str *)ha->brd;        gdth_writeb(1, &dp6_ptr->io.irqdel);        gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index);        gdth_writeb(1, &dp6_ptr->io.irqen);    } else if (ha->type == GDT_PCINEW) {        outb(0xff, PTR2USHORT(&ha->plx->edoor_reg));        outb(0x03, PTR2USHORT(&ha->plx->control1));    } else if (ha->type == GDT_PCIMPR) {        dp6m_ptr = (gdt6m_dpram_str *)ha->brd;        gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg);        gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4,                    &dp6m_ptr->i960r.edoor_en_reg);    }    GDTH_UNLOCK_HA(ha, flags);}static int gdth_get_status(unchar *pIStatus,int irq){    register gdth_ha_str *ha;    int i;    TRACE(("gdth_get_status() irq %d ctr_count %d\n",           irq,gdth_ctr_count));        *pIStatus = 0;    for (i=0; i<gdth_ctr_count; ++i) {        ha = HADATA(gdth_ctr_tab[i]);        if (ha->irq != (unchar)irq)             /* check IRQ */            continue;        if (ha->type == GDT_EISA)            *pIStatus = inb((ushort)ha->bmic + EDOORREG);        else if (ha->type == GDT_ISA)            *pIStatus =                gdth_readb(&((gdt2_dpram_str *)ha->brd)->u.ic.Cmd_Index);        else if (ha->type == GDT_PCI)            *pIStatus =                gdth_readb(&((gdt6_dpram_str *)ha->brd)->u.ic.Cmd_Index);        else if (ha->type == GDT_PCINEW)             *pIStatus = inb(PTR2USHORT(&ha->plx->edoor_reg));        else if (ha->type == GDT_PCIMPR)            *pIStatus =                gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.edoor_reg);           if (*pIStatus)                                              return i;                           /* board found */    }    return -1;}                     static int gdth_test_busy(int hanum){    register gdth_ha_str *ha;    register int gdtsema0 = 0;    TRACE(("gdth_test_busy() hanum %d\n",hanum));        ha = HADATA(gdth_ctr_tab[hanum]);    if (ha->type == GDT_EISA)        gdtsema0 = (int)inb(ha->bmic + SEMA0REG);    else if (ha->type == GDT_ISA)        gdtsema0 = (int)gdth_readb(&((gdt2_dpram_str *)ha->brd)->u.ic.Sema0);    else if (ha->type == GDT_PCI)        gdtsema0 = (int)gdth_readb(&((gdt6_dpram_str *)ha->brd)->u.ic.Sema0);    else if (ha->type == GDT_PCINEW)         gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg));    else if (ha->type == GDT_PCIMPR)        gdtsema0 =             (int)gdth_readb(&((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg);    return (gdtsema0 & 1);}static int gdth_get_cmd_index(int hanum){    register gdth_ha_str *ha;    int i;    TRACE(("gdth_get_cmd_index() hanum %d\n",hanum));    ha = HADATA(gdth_ctr_tab[hanum]);    for (i=0; i<GDTH_MAXCMDS; ++i) {        if (ha->cmd_tab[i].cmnd == UNUSED_CMND) {            ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer;            ha->cmd_tab[i].service = ha->pccb->Service;            ha->pccb->CommandIndex = (ulong32)i+2;            return (i+2);        }    }    return 0;}static void gdth_set_sema0(int hanum){    register gdth_ha_str *ha;    TRACE(("gdth_set_sema0() hanum %d\n",hanum));    ha = HADATA(gdth_ctr_tab[hanum]);    if (ha->type == GDT_EISA) {        outb(1, ha->bmic + SEMA0REG);    } else if (ha->type == GDT_ISA) {        gdth_writeb(1, &((gdt2_dpram_str *)ha->brd)->u.ic.Sema0);    } else if (ha->type == GDT_PCI) {        gdth_writeb(1, &((gdt6_dpram_str *)ha->brd)->u.ic.Sema0);    } else if (ha->type == GDT_PCINEW) {         outb(1, PTR2USHORT(&ha->plx->sema0_reg));    } else if (ha->type == GDT_PCIMPR) {        gdth_writeb(1, &((gdt6m_dpram_str *)ha->brd)->i960r.sema0_reg);    }}static void gdth_copy_command(int hanum){    register gdth_ha_str *ha;    register gdth_cmd_str *cmd_ptr;    register gdt6m_dpram_str *dp6m_ptr;    register gdt6c_dpram_str *dp6c_ptr;    gdt6_dpram_str *dp6_ptr;    gdt2_dpram_str *dp2_ptr;    ushort cp_count,dp_offset,cmd_no;        TRACE(("gdth_copy_command() hanum %d\n",hanum));    ha = HADATA(gdth_ctr_tab[hanum]);    cp_count = ha->cmd_len;    dp_offset= ha->cmd_offs_dpmem;    cmd_no   = ha->cmd_cnt;    cmd_ptr  = ha->pccb;    ++ha->cmd_cnt;                                                          if (ha->type == GDT_EISA)        return;                                 /* no DPMEM, no copy */    /* set cpcount dword aligned */    if (cp_count & 3)        cp_count += (4 - (cp_count & 3));    ha->cmd_offs_dpmem += cp_count;        /* set offset and service, copy command to DPMEM */    if (ha->type == GDT_ISA) {        dp2_ptr = (gdt2_dpram_str *)ha->brd;        gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET,                     &dp2_ptr->u.ic.comm_queue[cmd_no].offset);        gdth_writew((ushort)cmd_ptr->Service,                     &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id);        memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);    } else if (ha->type == GDT_PCI) {        dp6_ptr = (gdt6_dpram_str *)ha->brd;        gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET,                     &dp6_ptr->u.ic.comm_queue[cmd_no].offset);        gdth_writew((ushort)cmd_ptr->Service,                     &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id);        memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);    } else if (ha->type == GDT_PCINEW) {        dp6c_ptr = (gdt6c_dpram_str *)ha->brd;        gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET,                     &dp6c_ptr->u.ic.comm_queue[cmd_no].offset);        gdth_writew((ushort)cmd_ptr->Service,                     &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id);        memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);    } else if (ha->type == GDT_PCIMPR) {        dp6m_ptr = (gdt6m_dpram_str *)ha->brd;        gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET,                     &dp6m_ptr->u.ic.comm_queue[cmd_no].offset);        gdth_writew((ushort)cmd_ptr->Service,                     &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id);        memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);    }}static void gdth_release_event(int hanum){    register gdth_ha_str *ha;    TRACE(("gdth_release_event() hanum %d\n",hanum));    ha = HADATA(gdth_ctr_tab[hanum]);#ifdef GDTH_STATISTICS    {        ulong32 i,j;        for (i=0,j=0; j<GDTH_MAXCMDS; ++j) {            if (ha->cmd_tab[j].cmnd != UNUSED_CMND)                ++i;        }        if (max_index < i) {            max_index = i;            TRACE3(("GDT: max_index = %d\n",(ushort)i));        }    }#endif    if (ha->pccb->OpCode == GDT_INIT)        ha->pccb->Service |= 0x80;    if (ha->type == GDT_EISA) {        if (ha->pccb->OpCode == GDT_INIT)               /* store DMA buffer */            outl(virt_to_bus(ha->pccb), ha->bmic + MAILBOXREG);        outb(ha->pccb->Service, ha->bmic + LDOORREG);    } else if (ha->type == GDT_ISA) {        gdth_writeb(0, &((gdt2_dpram_str *)ha->brd)->io.event);    } else if (ha->type == GDT_PCI) {        gdth_writeb(0, &((gdt6_dpram_str *)ha->brd)->io.event);    } else if (ha->type == GDT_PCINEW) {         outb(1, PTR2USHORT(&ha->plx->ldoor_reg));    } else if (ha->type == GDT_PCIMPR) {        gdth_writeb(1, &((gdt6m_dpram_str *)ha->brd)->i960r.ldoor_reg);    }}    static int gdth_wait(int hanum,int index,ulong32 time){    gdth_ha_str *ha;    int answer_found = FALSE;    TRACE(("gdth_wait() hanum %d index %d time %d\n",hanum,index,time));    ha = HADATA(gdth_ctr_tab[hanum]);    if (index == 0)        return 1;                               /* no wait required */    gdth_from_wait = TRUE;    do {        gdth_interrupt((int)ha->irq,ha,NULL);        if (wait_hanum==hanum && wait_index==index) {            answer_found = TRUE;            break;        }        gdth_delay(1);    } while (--time);    gdth_from_wait = FALSE;        while (gdth_test_busy(hanum))        gdth_delay(0);    return (answer_found);}static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1,                             ulong32 p2,ulong32 p3){    register gdth_ha_str *ha;    register gdth_cmd_str *cmd_ptr;    int retries,index;    TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode));    ha = HADATA(gdth_ctr_tab[hanum]);    cmd_ptr = ha->pccb;    memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str));    /* make command  */    for (retries = INIT_RETRIES;;) {        cmd_ptr->Service          = service;        cmd_ptr->RequestBuffer    = INTERNAL_CMND;        if (!(index=gdth_get_cmd_index(hanum))) {            TRACE(("GDT: No free command index found\n"));            return 0;        }        gdth_set_sema0(hanum);        cmd_ptr->OpCode           = opcode;        cmd_ptr->BoardNode        = LOCALBOARD;        if (service == CACHESERVICE) {            if (opcode == GDT_IOCTL) {                cmd_ptr->u.ioctl.subfunc = p1;                cmd_ptr->u.ioctl.channel = p2;                cmd_ptr->u.ioctl.param_size = (ushort)p3;                cmd_ptr->u.ioctl.p_param = virt_to_bus(ha->pscratch);            } else {                cmd_ptr->u.cache.DeviceNo = (ushort)p1;                cmd_ptr->u.cache.BlockNo  = p2;            }        } else if (service == SCSIRAWSERVICE) {            cmd_ptr->u.raw.direction  = p1;            cmd_ptr->u.raw.bus        = (unchar)p2;            cmd_ptr->u.raw.target     = (unchar)p3;            cmd_ptr->u.raw.lun        = (unchar)(p3 >> 8);        }        ha->cmd_len          = sizeof(gdth_cmd_str);        ha->cmd_offs_dpmem   = 0;        ha->cmd_cnt          = 0;        gdth_copy_command(hanum);        gdth_release_event(hanum);        gdth_delay(20);        if (!gdth_wait(hanum,index,INIT_TIMEOUT)) {            printk("GDT: Initialization error (timeout service %d)\n",service);            return 0;        }        if (ha->status != S_BSY || --retries == 0)            break;        gdth_delay(1);       }           return (ha->status != S_OK ? 0:1);}    /* search for devices */static int __init gdth_search_drives(int hanum){    register gdth_ha_str *ha;    ushort cdev_cnt, i;    int drv_cyls, drv_hds, drv_secs;    ulong32 bus_no;    ulong32 drv_cnt, drv_no, j;    gdth_getch_str *chn;    gdth_drlist_str *drl;    gdth_iochan_str *ioc;    gdth_raw_iochan_str *iocr;    gdth_arraylist_str *alst;            TRACE(("gdth_search_drives() hanum %d\n",hanum));    ha = HADATA(gdth_ctr_tab[hanum]);    /* initialize controller services, at first: screen service */    if (!gdth_internal_cmd(hanum,SCREENSERVICE,GDT_INIT,0,0,0)) {        printk("GDT: Initialization error screen service (code %d)\n",               ha->status);        return 0;    }    TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n"));        /* initialize cache service */    if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0)) {        printk("GDT: Initialization error cache service (code %d)\n",               ha->status);        return 0;    }    TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n"));    cdev_cnt = (ushort)ha->info;    /* mount all cache devices */    gdth_internal_cmd(hanum,CACHESERVICE,GDT_MOUNT,0xffff,1,0);    TRACE2(("gdth_search_drives(): mountall CACHESERVICE OK\n"));    /* initialize cache service after mountall */    if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0)) {        printk("GDT: Initialization error cache service (code %d)\n",               ha->status);

⌨️ 快捷键说明

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