gdth_proc.c

来自「linux 内核源代码」· C语言 代码 · 共 819 行 · 第 1/2 页

C
819
字号
                    k++; j--;                } else {                    strcpy(hrec, "ok");                }                                    if (drv_no == i) {                    size = sprintf(buffer+len,                                   "\n Number:       \t%-2d        \tStatus:        \t%s\n",                                   drv_no, hrec);                    len += size;  pos = begin + len;                    flag = TRUE;                    no_mdrv = pcdi->cd_ldcnt;                    if (no_mdrv > 1 || pcdi->ld_slave != -1) {                        is_mirr = TRUE;                        strcpy(hrec, "RAID-1");                    } else if (pcdi->ld_dtype == 0) {                        strcpy(hrec, "Disk");                    } else if (pcdi->ld_dtype == 1) {                        strcpy(hrec, "RAID-0");                    } else if (pcdi->ld_dtype == 2) {                        strcpy(hrec, "Chain");                    } else {                        strcpy(hrec, "???");                    }                    size = sprintf(buffer+len,                                   " Capacity [MB]:\t%-6d    \tType:          \t%s\n",                                   pcdi->ld_blkcnt/(1024*1024/pcdi->ld_blksize),                                   hrec);                    len += size;  pos = begin + len;                } else {                    size = sprintf(buffer+len,                                   " Slave Number: \t%-2d        \tStatus:        \t%s\n",                                   drv_no & 0x7fff, hrec);                    len += size;  pos = begin + len;                }                drv_no = pcdi->ld_slave;                if (pos < offset) {                    len = 0;                    begin = pos;                }                if (pos > offset + length)                    goto stop_output;            } while (drv_no != -1);                         if (is_mirr) {                size = sprintf(buffer+len,                               " Missing Drv.: \t%-2d        \tInvalid Drv.:  \t%d\n",                               no_mdrv - j - k, k);                len += size;  pos = begin + len;            }                          if (!ha->hdr[i].is_arraydrv)                strcpy(hrec, "--");            else                sprintf(hrec, "%d", ha->hdr[i].master_no);            size = sprintf(buffer+len,                           " To Array Drv.:\t%s\n", hrec);            len += size;  pos = begin + len;            if (pos < offset) {                len = 0;                begin = pos;            }            if (pos > offset + length)                goto stop_output;        }               gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);                if (!flag) {            size = sprintf(buffer+len, "\n --\n");            len += size;  pos = begin + len;        }           /* 4. about array drives */        size = sprintf(buffer+len,"\nArray Drives:");        len += size;  pos = begin + len;        flag = FALSE;        buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);        if (!buf)             goto stop_output;        for (i = 0; i < MAX_LDRIVES; ++i) {            if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))                continue;            /* 4.a array drive info */            TRACE2(("array_info() drive no %d\n",i));            pai = (gdth_arrayinf_str *)buf;            gdtcmd->Service = CACHESERVICE;            gdtcmd->OpCode = GDT_IOCTL;            gdtcmd->u.ioctl.p_param = paddr;            gdtcmd->u.ioctl.param_size = sizeof(gdth_arrayinf_str);            gdtcmd->u.ioctl.subfunc = ARRAY_INFO | LA_CTRL_PATTERN;            gdtcmd->u.ioctl.channel = i;            if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {                if (pai->ai_state == 0)                    strcpy(hrec, "idle");                else if (pai->ai_state == 2)                    strcpy(hrec, "build");                else if (pai->ai_state == 4)                    strcpy(hrec, "ready");                else if (pai->ai_state == 6)                    strcpy(hrec, "fail");                else if (pai->ai_state == 8 || pai->ai_state == 10)                    strcpy(hrec, "rebuild");                else                    strcpy(hrec, "error");                if (pai->ai_ext_state & 0x10)                    strcat(hrec, "/expand");                else if (pai->ai_ext_state & 0x1)                    strcat(hrec, "/patch");                size = sprintf(buffer+len,                               "\n Number:       \t%-2d        \tStatus:        \t%s\n",                               i,hrec);                len += size;  pos = begin + len;                flag = TRUE;                if (pai->ai_type == 0)                    strcpy(hrec, "RAID-0");                else if (pai->ai_type == 4)                    strcpy(hrec, "RAID-4");                else if (pai->ai_type == 5)                    strcpy(hrec, "RAID-5");                else                     strcpy(hrec, "RAID-10");                size = sprintf(buffer+len,                               " Capacity [MB]:\t%-6d    \tType:          \t%s\n",                               pai->ai_size/(1024*1024/pai->ai_secsize),                               hrec);                len += size;  pos = begin + len;                if (pos < offset) {                    len = 0;                    begin = pos;                }                if (pos > offset + length)                    goto stop_output;            }        }        gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);                if (!flag) {            size = sprintf(buffer+len, "\n --\n");            len += size;  pos = begin + len;        }        /* 5. about host drives */        size = sprintf(buffer+len,"\nHost Drives:");        len += size;  pos = begin + len;        flag = FALSE;        buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr);        if (!buf)             goto stop_output;        for (i = 0; i < MAX_LDRIVES; ++i) {            if (!ha->hdr[i].is_logdrv ||                 (ha->hdr[i].is_arraydrv && !ha->hdr[i].is_master))                continue;            /* 5.a get host drive list */            TRACE2(("host_get() drv_no %d\n",i));                       phg = (gdth_hget_str *)buf;            gdtcmd->Service = CACHESERVICE;            gdtcmd->OpCode = GDT_IOCTL;            gdtcmd->u.ioctl.p_param = paddr;            gdtcmd->u.ioctl.param_size = sizeof(gdth_hget_str);            gdtcmd->u.ioctl.subfunc = HOST_GET | LA_CTRL_PATTERN;            gdtcmd->u.ioctl.channel = i;            phg->entries = MAX_HDRIVES;            phg->offset = GDTOFFSOF(gdth_hget_str, entry[0]);             if (gdth_execute(host, gdtcmd, cmnd, 30, NULL) == S_OK) {                ha->hdr[i].ldr_no = i;                ha->hdr[i].rw_attribs = 0;                ha->hdr[i].start_sec = 0;            } else {                for (j = 0; j < phg->entries; ++j) {                    k = phg->entry[j].host_drive;                    if (k >= MAX_LDRIVES)                        continue;                    ha->hdr[k].ldr_no = phg->entry[j].log_drive;                    ha->hdr[k].rw_attribs = phg->entry[j].rw_attribs;                    ha->hdr[k].start_sec = phg->entry[j].start_sec;                }            }        }        gdth_ioctl_free(ha, sizeof(gdth_hget_str), buf, paddr);        for (i = 0; i < MAX_HDRIVES; ++i) {            if (!(ha->hdr[i].present))                continue;                          size = sprintf(buffer+len,                           "\n Number:       \t%-2d        \tArr/Log. Drive:\t%d\n",                           i, ha->hdr[i].ldr_no);            len += size;  pos = begin + len;            flag = TRUE;            size = sprintf(buffer+len,                           " Capacity [MB]:\t%-6d    \tStart Sector:  \t%d\n",                           (ulong32)(ha->hdr[i].size/2048), ha->hdr[i].start_sec);            len += size;  pos = begin + len;            if (pos < offset) {                len = 0;                begin = pos;            }            if (pos > offset + length)                goto stop_output;        }                if (!flag) {            size = sprintf(buffer+len, "\n --\n");            len += size;  pos = begin + len;        }    }    /* controller events */    size = sprintf(buffer+len,"\nController Events:\n");    len += size;  pos = begin + len;    for (id = -1;;) {        id = gdth_read_event(ha, id, estr);        if (estr->event_source == 0)            break;        if (estr->event_data.eu.driver.ionode == ha->hanum &&            estr->event_source == ES_ASYNC) {             gdth_log_event(&estr->event_data, hrec);            do_gettimeofday(&tv);            sec = (int)(tv.tv_sec - estr->first_stamp);            if (sec < 0) sec = 0;            size = sprintf(buffer+len," date- %02d:%02d:%02d\t%s\n",                           sec/3600, sec%3600/60, sec%60, hrec);            len += size;  pos = begin + len;            if (pos < offset) {                len = 0;                begin = pos;            }            if (pos > offset + length)                goto stop_output;        }        if (id == -1)            break;    }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));    rc = len;free_fail:    kfree(gdtcmd);    kfree(estr);    return rc;}static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,                              ulong64 *paddr){    ulong flags;    char *ret_val;    if (size == 0)        return NULL;    spin_lock_irqsave(&ha->smp_lock, flags);    if (!ha->scratch_busy && size <= GDTH_SCRATCH) {        ha->scratch_busy = TRUE;        ret_val = ha->pscratch;        *paddr = ha->scratch_phys;    } else if (scratch) {        ret_val = NULL;    } else {        dma_addr_t dma_addr;        ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr);        *paddr = dma_addr;    }    spin_unlock_irqrestore(&ha->smp_lock, flags);    return ret_val;}static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr){    ulong flags;    spin_lock_irqsave(&ha->smp_lock, flags);    if (buf == ha->pscratch) {        ha->scratch_busy = FALSE;    } else {        pci_free_consistent(ha->pdev, size, buf, paddr);    }    spin_unlock_irqrestore(&ha->smp_lock, flags);}#ifdef GDTH_IOCTL_PROCstatic int gdth_ioctl_check_bin(gdth_ha_str *ha, ushort size){    ulong flags;    int ret_val;    spin_lock_irqsave(&ha->smp_lock, flags);    ret_val = FALSE;    if (ha->scratch_busy) {        if (((gdth_iord_str *)ha->pscratch)->size == (ulong32)size)            ret_val = TRUE;    }    spin_unlock_irqrestore(&ha->smp_lock, flags);    return ret_val;}#endifstatic void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id){    ulong flags;    int i;    Scsi_Cmnd *scp;    struct gdth_cmndinfo *cmndinfo;    unchar b, t;    spin_lock_irqsave(&ha->smp_lock, flags);    for (i = 0; i < GDTH_MAXCMDS; ++i) {        scp = ha->cmd_tab[i].cmnd;        cmndinfo = gdth_cmnd_priv(scp);        b = scp->device->channel;        t = scp->device->id;        if (!SPECIAL_SCP(scp) && t == (unchar)id &&             b == (unchar)busnum) {            cmndinfo->wait_for_completion = 0;            spin_unlock_irqrestore(&ha->smp_lock, flags);            while (!cmndinfo->wait_for_completion)                barrier();            spin_lock_irqsave(&ha->smp_lock, flags);        }    }    spin_unlock_irqrestore(&ha->smp_lock, flags);}static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id){    ulong flags;    Scsi_Cmnd *scp;    unchar b, t;    spin_lock_irqsave(&ha->smp_lock, flags);    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {        struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);        if (!cmndinfo->internal_command) {            b = scp->device->channel;            t = scp->device->id;            if (t == (unchar)id && b == (unchar)busnum) {                TRACE2(("gdth_stop_timeout(): update_timeout()\n"));                cmndinfo->timeout = gdth_update_timeout(scp, 0);            }        }    }    spin_unlock_irqrestore(&ha->smp_lock, flags);}static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id){    ulong flags;    Scsi_Cmnd *scp;    unchar b, t;    spin_lock_irqsave(&ha->smp_lock, flags);    for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {        struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);        if (!cmndinfo->internal_command) {            b = scp->device->channel;            t = scp->device->id;            if (t == (unchar)id && b == (unchar)busnum) {                TRACE2(("gdth_start_timeout(): update_timeout()\n"));                gdth_update_timeout(scp, cmndinfo->timeout);            }        }    }    spin_unlock_irqrestore(&ha->smp_lock, flags);}static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout){    int oldto;    oldto = scp->timeout_per_command;    scp->timeout_per_command = timeout;    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);    }    return oldto;}

⌨️ 快捷键说明

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