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

📄 gdth.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
            ha->pccb->CommandIndex = (ulong)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)        writeb(1, &((gdt2_dpram_str *)ha->brd)->u.ic.Sema0);    else if (ha->type == GDT_PCI)        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)        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;        writew(dp_offset + DPMEM_COMMAND_OFFSET, 	       &dp2_ptr->u.ic.comm_queue[cmd_no].offset);        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;        writew(dp_offset + DPMEM_COMMAND_OFFSET, 	       &dp6_ptr->u.ic.comm_queue[cmd_no].offset);        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;        writew(dp_offset + DPMEM_COMMAND_OFFSET, 	       &dp6c_ptr->u.ic.comm_queue[cmd_no].offset);	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;        writew(dp_offset + DPMEM_COMMAND_OFFSET, 	       &dp6m_ptr->u.ic.comm_queue[cmd_no].offset);        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;#ifdef GDTH_STATISTICS    ulong i,j;    for (i=0,j=0; j<GDTH_MAXCMDS; ++j) {        if (gdth_cmd_tab[j][hanum].cmnd != UNUSED_CMND)            ++i;    }    if (max_index < i) {        max_index = i;        TRACE3(("GDT: max_index = %d\n",(ushort)i));    }#endif    TRACE(("gdth_release_event() hanum %d\n",hanum));    ha = HADATA(gdth_ctr_tab[hanum]);    if (ha->pccb->OpCode == GDT_INIT)        ha->pccb->Service |= 0x80;    if (ha->type == GDT_EISA) {        outb(ha->pccb->Service, ha->bmic + LDOORREG);        if (ha->pccb->OpCode == GDT_INIT)               /* store DMA buffer */            outl((ulong)ha->pccb, ha->bmic + MAILBOXREG);    } else if (ha->type == GDT_ISA)        writeb(0, &((gdt2_dpram_str *)ha->brd)->io.event);    else if (ha->type == GDT_PCI)        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)        writeb(1, &((gdt6m_dpram_str *)ha->brd)->i960r.ldoor_reg);}    static int gdth_wait(int hanum,int index,ulong time){    gdth_ha_str *ha;    int answer_found = FALSE;    TRACE(("gdth_wait() hanum %d index %d time %ld\n",hanum,index,time));    ha = HADATA(gdth_ctr_tab[hanum]);    if (index == 0)        return 1;                               /* no wait required */    gdth_from_wait = TRUE;    do {#if LINUX_VERSION_CODE >= 0x010346        gdth_interrupt((int)ha->irq,NULL,NULL);#else        gdth_interrupt((int)ha->irq,NULL);#endif        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,ulong p1,                             ulong p2,ulong 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        = 0;        }        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 */__initfunc (static int gdth_search_drives(int hanum)){    register gdth_ha_str *ha;    ushort cdev_cnt,i;    unchar b,t,pos_found;    ulong drv_cyls, drv_hds, drv_secs;    ulong bus_no;    gdth_getch_str *chn;    gdth_iochan_str *ioc;        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);	return 0;    }    TRACE2(("gdth_search_drives() CACHES. init. after mountall\n"));    cdev_cnt = (ushort)ha->info;    /* detect number of SCSI buses - try new IOCTL */    ioc = (gdth_iochan_str *)DMADATA(gdth_ctr_tab[hanum]);    ioc->version 	= -1UL;    ioc->list_entries	= MAXBUS;    ioc->first_chan	= 0;    ioc->last_chan	= MAXBUS-1;    ioc->list_offset	= GDTOFFSOF(gdth_iochan_str, list[0]);    if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,GET_IOCHAN_DESC,			  INVALID_CHANNEL,sizeof(gdth_iochan_str))) {	TRACE2(("GET_IOCHAN_DESC supported!\n"));	ha->bus_cnt = ioc->chan_count;	for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no)	    if (ioc->list[bus_no].proc_id < MAXID)		ha->id[bus_no][ioc->list[bus_no].proc_id].type = SIOP_DTYP;    } else {	/* old method */	chn = (gdth_getch_str *)DMADATA(gdth_ctr_tab[hanum]);	for (bus_no = 0; bus_no < MAXBUS; ++bus_no) {	    chn->channel_no = bus_no;	    if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,				   SCSI_CHAN_CNT | L_CTRL_PATTERN,				   IO_CHANNEL | INVALID_CHANNEL,				   sizeof(gdth_getch_str))) {		if (bus_no == 0) {		    printk("GDT: Error detecting SCSI channel count (0x%x)\n",			   ha->status);		    return 0;		}		break;	    }	    if (chn->siop_id < MAXID)		ha->id[bus_no][chn->siop_id].type = SIOP_DTYP;	}       	ha->bus_cnt = (unchar)bus_no;    }    TRACE2(("gdth_search_drives() %d SCSI channels\n",ha->bus_cnt));    /* read cache configuration */    if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_INFO,			   INVALID_CHANNEL,sizeof(gdth_cinfo_str))) {	printk("GDT: Initialization error cache service (code %d)\n",	       ha->status);	return 0;    }    ha->cpar = ((gdth_cinfo_str *)DMADATA(gdth_ctr_tab[hanum]))->cpar;    TRACE2(("gdth_search_drives() cinfo: vs %lx sta %d str %d dw %d b %d\n",	    ha->cpar.version,ha->cpar.state,ha->cpar.strategy,	    ha->cpar.write_back,ha->cpar.block_size));    /* read board info, fill ctr_name[] */    if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_INFO,			  INVALID_CHANNEL,sizeof(gdth_binfo_str))) {	TRACE2(("BOARD_INFO supported!\n"));	strcpy(ha->ctr_name, ((gdth_binfo_str *)DMADATA(gdth_ctr_tab[hanum]))->type_string);    } else {	strcpy(ha->ctr_name, gdth_ctr_name(hanum));    }    TRACE2(("Controller name: %s\n",ha->ctr_name));    /* initialize raw service */    if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_INIT,0,0,0)) {        printk("GDT: Initialization error raw service (code %d)\n",               ha->status);        return 0;    }    TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n"));    /* set/get features raw service (scatter/gather) */    ha->raw_feat = 0;    if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_SET_FEAT,SCATTER_GATHER,                          0,0)) {        TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n"));        if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_GET_FEAT,0,0,0)) {            TRACE2(("gdth_search_dr(): get feat RAWSERVICE %ld\n",                          ha->info));            ha->raw_feat = (ushort)ha->info;        }    }     /* set/get features cache service (equal to raw service) */    if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_SET_FEAT,0,                          SCATTER_GATHER,0)) {        TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n"));        if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_GET_FEAT,0,0,0)) {            TRACE2(("gdth_search_dr(): get feat CACHESERV. %ld\n",                          ha->info));            ha->cache_feat = (ushort)ha->info;        }    }    /* reserve drives for raw service */    for (i = 0; reserve_list[i].hanum != 0xff; ++i) {	if (reserve_list[i].hanum < MAXHA && reserve_list[i].hanum == hanum &&	    reserve_list[i].bus < MAXBUS && reserve_list[i].id < MAXID) {	    TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d\n",		    reserve_list[i].hanum, reserve_list[i].bus,		    reserve_list[i].id));	    if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE,0,				   reserve_list[i].bus, reserve_list[i].id)) {		printk("GDT: Error raw service (RESERVE, code %d)\n",		       ha->status);	    }	}    }    /* scanning for raw devices */    for (b=0; b<ha->bus_cnt; ++b) {        for (t=0; t<MAXID; ++t) {            TRACE(("gdth_search_drives() rawd. bus %d id %d\n",b,t));            if (ha->id[b][t].type != SIOP_DTYP &&                 gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_INFO,0,b,t)) {                ha->id[b][t].type = RAW_DTYP;            }        }    }    /* scanning for cache devices */    for (i=0; i<cdev_cnt && i<MAX_HDRIVES; ++i) {        TRACE(("gdth_search_drives() cachedev. %d\n",i));        if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_INFO,i,0,0)) {            /* dynamic relation between host drive number and Bus/ID */            /* search free position */            pos_found = FALSE;

⌨️ 快捷键说明

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