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 + -
显示快捷键?