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

📄 gdth_proc.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 2 页
字号:
        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );        if (id == -1)            return(-EBUSY);        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];        for (i = k = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {            found = FALSE;            for (j = 0; j < ha->bus_cnt; ++j) {                for (k = 0; k < MAXID; ++k) {                    if (ha->id[j][k].type == CACHE_DTYP &&                        ha->id[j][k].hostdrive == piowr->iu.lockdrv.drives[i]) {                        found = TRUE;                        break;                    }                }                if (found)                    break;            }            if (!found)                continue;            if (piowr->iu.lockdrv.lock) {                save_flags( flags );                cli();                ha->id[j][k].lock = 1;                restore_flags( flags );                gdth_wait_completion( hanum, j, k );                gdth_stop_timeout( hanum, j, k );            } else {                save_flags( flags );                cli();                ha->id[j][k].lock = 0;                restore_flags( flags );                gdth_start_timeout( hanum, j, k );                gdth_next( hanum );            }        }        piord->size = sizeof(gdth_iord_str);        piord->status = S_OK;        break;      case GDTIOCTL_LOCKCHN:        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );        if (id == -1)            return(-EBUSY);        for (k = 0, j = piowr->iu.lockchn.channel; k < MAXID; ++k) {            if (ha->id[j][k].type != RAW_DTYP)                continue;            if (piowr->iu.lockchn.lock) {                save_flags( flags );                cli();                ha->id[j][k].lock = 1;                restore_flags( flags );                gdth_wait_completion( hanum, j, k );                gdth_stop_timeout( hanum, j, k );            } else {                save_flags( flags );                cli();                ha->id[j][k].lock = 0;                restore_flags( flags );                gdth_start_timeout( hanum, j, k );                gdth_next( hanum );            }        }        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];        piord->size = sizeof(gdth_iord_str);        piord->status = S_OK;        break;      case GDTIOCTL_EVENT:        id = gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) );        if (id == -1)            return(-EBUSY);        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];        if (piowr->iu.event.erase == 0) {            piord->iu.event.handle = gdth_read_event( piowr->iu.event.handle,                (gdth_evt_str *)piord->iu.event.evt );        } else {            piord->iu.event.handle = piowr->iu.event.handle;            gdth_readapp_event( (unchar)piowr->iu.event.erase,                (gdth_evt_str *)piord->iu.event.evt );        }        piord->size = sizeof(gdth_iord_str);        piord->status = S_OK;        break;      default:        return(-EINVAL);    }    /* we return a buffer ID to detect the right buffer during READ-IOCTL */    return id;}static int gdth_get_info(char *buffer,char **start,off_t offset,                         int length,int vh,int hanum,int busnum){    int size = 0,len = 0;    off_t begin = 0,pos = 0;    gdth_ha_str *ha;    gdth_iord_str *piord;    int id;    TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum));    ha = HADATA(gdth_ctr_tab[hanum]);    id = length;    /* look for buffer ID in length */    if (id > 4) {#if LINUX_VERSION_CODE >= 0x020000        size = sprintf(buffer+len,                       "%s SCSI Disk Array Controller\n",                       ha->ctr_name);#else        size = sprintf(buffer+len,                       "%s SCSI Disk Array Controller (SCSI Bus %d)\n",                       ha->ctr_name,busnum);#endif        len += size;  pos = begin + len;        size = sprintf(buffer+len,                       "Firmware Version: %d.%2d\tDriver Version: %s\n",                       (unchar)(ha->cpar.version>>8),                       (unchar)(ha->cpar.version),GDTH_VERSION_STR);        len += size;  pos = begin + len;         if (pos < offset) {            len = 0;            begin = pos;        }        if (pos > offset + length)            goto stop_output;    } else {        piord = (gdth_iord_str *)gdth_ioctl_tab[id-1][hanum];        if (piord == NULL)            goto stop_output;        length = piord->size;        memcpy(buffer+len, (char *)piord, length);        gdth_ioctl_free(hanum, id);        len += length; pos = begin + len;        if (pos < offset) {            len = 0;            begin = pos;        }        if (pos > offset + length)            goto stop_output;    }stop_output:    *start = buffer +(offset-begin);    len -= (offset-begin);    if (len > length)        len = length;    TRACE2(("get_info() len %d pos %d begin %d offset %d length %d size %d\n",            len,(int)pos,(int)begin,(int)offset,length,size));    return(len);}void gdth_scsi_done(Scsi_Cmnd *scp){    TRACE2(("gdth_scsi_done()\n"));    scp->request.rq_status = RQ_SCSI_DONE;    if (scp->request.sem != NULL)        up(scp->request.sem);}static int gdth_ioctl_alloc(int hanum, ushort size){    ulong flags;    int i;    if (size == 0)        return -1;    save_flags(flags);    cli();    for (i = 0; i < 4; ++i) {        if (gdth_ioctl_tab[i][hanum] == NULL) {            gdth_ioctl_tab[i][hanum] = kmalloc( size, GFP_ATOMIC | GFP_DMA );            break;        }    }    restore_flags(flags);    if (i == 4 || gdth_ioctl_tab[i][hanum] == NULL)        return -1;    return (i+1);}static void gdth_ioctl_free(int hanum, int idx){    ulong flags;    save_flags(flags);    cli();    kfree( gdth_ioctl_tab[idx-1][hanum] );    gdth_ioctl_tab[idx-1][hanum] = NULL;    restore_flags(flags);}static void gdth_wait_completion(int hanum, int busnum, int id){    ulong flags;    int i;    Scsi_Cmnd *scp;    save_flags(flags);    cli();    for (i = 0; i < GDTH_MAXCMDS; ++i) {        scp = gdth_cmd_tab[i][hanum].cmnd;#if LINUX_VERSION_CODE >= 0x020000        if (!SPECIAL_SCP(scp) && scp->target == (unchar)id &&            scp->channel == (unchar)busnum)#else        if (!SPECIAL_SCP(scp) && scp->target == (unchar)id &&            NUMDATA(scp->host)->busnum == (unchar)busnum)#endif        {	    scp->SCp.have_data_in = 0;            restore_flags(flags);            while (!scp->SCp.have_data_in)                barrier();	    scp->scsi_done(scp);            save_flags(flags);            cli();        }    }    restore_flags(flags);}static void gdth_stop_timeout(int hanum, int busnum, int id){    ulong flags;    Scsi_Cmnd *scp;    gdth_ha_str *ha;    save_flags(flags);    cli();    ha = HADATA(gdth_ctr_tab[hanum]);    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {#if LINUX_VERSION_CODE >= 0x020000        if (scp->target == (unchar)id &&            scp->channel == (unchar)busnum)#else        if (scp->target == (unchar)id &&            NUMDATA(scp->host)->busnum == (unchar)busnum)#endif        {            TRACE2(("gdth_stop_timeout(): update_timeout()\n"));            scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0);        }    }    restore_flags(flags);}static void gdth_start_timeout(int hanum, int busnum, int id){    ulong flags;    Scsi_Cmnd *scp;    gdth_ha_str *ha;    save_flags(flags);    cli();    ha = HADATA(gdth_ctr_tab[hanum]);    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {#if LINUX_VERSION_CODE >= 0x020000        if (scp->target == (unchar)id &&            scp->channel == (unchar)busnum)#else        if (scp->target == (unchar)id &&            NUMDATA(scp->host)->busnum == (unchar)busnum)#endif        {            TRACE2(("gdth_start_timeout(): update_timeout()\n"));            gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual);        }    }    restore_flags(flags);}static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout){    ulong flags;    int oldto;    save_flags(flags);    cli();    oldto = scp->timeout_per_command;    scp->timeout_per_command = timeout;#if LINUX_VERSION_CODE >= 0x02014B    if (timeout == 0) {	del_timer(&scp->eh_timeout);	scp->eh_timeout.data = (unsigned long) NULL;	scp->eh_timeout.expires = 0;    } else {	if (scp->eh_timeout.data != (unsigned long) NULL) 	    del_timer(&scp->eh_timeout);	scp->eh_timeout.data = (unsigned long) scp;	scp->eh_timeout.expires = jiffies + timeout;	add_timer(&scp->eh_timeout);    }#else    if (timeout > 0) {        if (timer_table[SCSI_TIMER].expires == 0) {            timer_table[SCSI_TIMER].expires = jiffies + timeout;            timer_active |= 1 << SCSI_TIMER;        } else {            if (jiffies + timeout < timer_table[SCSI_TIMER].expires)                timer_table[SCSI_TIMER].expires = jiffies + timeout;        }    }#endif    restore_flags(flags);    return oldto;}

⌨️ 快捷键说明

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