📄 gdth.c
字号:
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 + -