📄 megaraid.c
字号:
int len; int i; i = 0; /* avoid compilation warnings */ len = 0; adapter = (adapter_t *)data; len = sprintf(page, "Statistical Information for this controller\n"); len += sprintf(page+len, "pend_cmds = %d\n", atomic_read(&adapter->pend_cmds));#if MEGA_HAVE_STATS for(i = 0; i < adapter->numldrv; i++) { len += sprintf(page+len, "Logical Drive %d:\n", i); len += sprintf(page+len, "\tReads Issued = %lu, Writes Issued = %lu\n", adapter->nreads[i], adapter->nwrites[i]); len += sprintf(page+len, "\tSectors Read = %lu, Sectors Written = %lu\n", adapter->nreadblocks[i], adapter->nwriteblocks[i]); len += sprintf(page+len, "\tRead errors = %lu, Write errors = %lu\n\n", adapter->rd_errors[i], adapter->wr_errors[i]); }#else len += sprintf(page+len, "IO and error counters not compiled in driver.\n");#endif *eof = 1; return len;}/** * proc_read_mbox() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display mailbox information for the last command issued. This information * is good for debugging. */static intproc_read_mbox(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; volatile mbox_t *mbox = adapter->mbox; int len = 0; len = sprintf(page, "Contents of Mail Box Structure\n"); len += sprintf(page+len, " Fw Command = 0x%02x\n", mbox->m_out.cmd); len += sprintf(page+len, " Cmd Sequence = 0x%02x\n", mbox->m_out.cmdid); len += sprintf(page+len, " No of Sectors= %04d\n", mbox->m_out.numsectors); len += sprintf(page+len, " LBA = 0x%02x\n", mbox->m_out.lba); len += sprintf(page+len, " DTA = 0x%08x\n", mbox->m_out.xferaddr); len += sprintf(page+len, " Logical Drive= 0x%02x\n", mbox->m_out.logdrv); len += sprintf(page+len, " No of SG Elmt= 0x%02x\n", mbox->m_out.numsgelements); len += sprintf(page+len, " Busy = %01x\n", mbox->m_in.busy); len += sprintf(page+len, " Status = 0x%02x\n", mbox->m_in.status); *eof = 1; return len;}/** * proc_rebuild_rate() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display current rebuild rate */static intproc_rebuild_rate(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; dma_addr_t dma_handle; caddr_t inquiry; struct pci_dev *pdev; int len = 0; if( make_local_pdev(adapter, &pdev) != 0 ) { *eof = 1; return len; } if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { free_local_pdev(pdev); *eof = 1; return len; } if( mega_adapinq(adapter, dma_handle) != 0 ) { len = sprintf(page, "Adapter inquiry failed.\n"); printk(KERN_WARNING "megaraid: inquiry failed.\n"); mega_free_inquiry(inquiry, dma_handle, pdev); free_local_pdev(pdev); *eof = 1; return len; } if( adapter->flag & BOARD_40LD ) { len = sprintf(page, "Rebuild Rate: [%d%%]\n", ((mega_inquiry3 *)inquiry)->rebuild_rate); } else { len = sprintf(page, "Rebuild Rate: [%d%%]\n", ((mraid_ext_inquiry *) inquiry)->raid_inq.adapter_info.rebuild_rate); } mega_free_inquiry(inquiry, dma_handle, pdev); free_local_pdev(pdev); *eof = 1; return len;}/** * proc_battery() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display information about the battery module on the controller. */static intproc_battery(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; dma_addr_t dma_handle; caddr_t inquiry; struct pci_dev *pdev; u8 battery_status = 0; char str[256]; int len = 0; if( make_local_pdev(adapter, &pdev) != 0 ) { *eof = 1; return len; } if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { free_local_pdev(pdev); *eof = 1; return len; } if( mega_adapinq(adapter, dma_handle) != 0 ) { len = sprintf(page, "Adapter inquiry failed.\n"); printk(KERN_WARNING "megaraid: inquiry failed.\n"); mega_free_inquiry(inquiry, dma_handle, pdev); free_local_pdev(pdev); *eof = 1; return len; } if( adapter->flag & BOARD_40LD ) { battery_status = ((mega_inquiry3 *)inquiry)->battery_status; } else { battery_status = ((mraid_ext_inquiry *)inquiry)-> raid_inq.adapter_info.battery_status; } /* * Decode the battery status */ sprintf(str, "Battery Status:[%d]", battery_status); if(battery_status == MEGA_BATT_CHARGE_DONE) strcat(str, " Charge Done"); if(battery_status & MEGA_BATT_MODULE_MISSING) strcat(str, " Module Missing"); if(battery_status & MEGA_BATT_LOW_VOLTAGE) strcat(str, " Low Voltage"); if(battery_status & MEGA_BATT_TEMP_HIGH) strcat(str, " Temperature High"); if(battery_status & MEGA_BATT_PACK_MISSING) strcat(str, " Pack Missing"); if(battery_status & MEGA_BATT_CHARGE_INPROG) strcat(str, " Charge In-progress"); if(battery_status & MEGA_BATT_CHARGE_FAIL) strcat(str, " Charge Fail"); if(battery_status & MEGA_BATT_CYCLES_EXCEEDED) strcat(str, " Cycles Exceeded"); len = sprintf(page, "%s\n", str); mega_free_inquiry(inquiry, dma_handle, pdev); free_local_pdev(pdev); *eof = 1; return len;}/** * proc_pdrv_ch0() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display information about the physical drives on physical channel 0. */static intproc_pdrv_ch0(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; *eof = 1; return (proc_pdrv(adapter, page, 0));}/** * proc_pdrv_ch1() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display information about the physical drives on physical channel 1. */static intproc_pdrv_ch1(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; *eof = 1; return (proc_pdrv(adapter, page, 1));}/** * proc_pdrv_ch2() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display information about the physical drives on physical channel 2. */static intproc_pdrv_ch2(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; *eof = 1; return (proc_pdrv(adapter, page, 2));}/** * proc_pdrv_ch3() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display information about the physical drives on physical channel 3. */static intproc_pdrv_ch3(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; *eof = 1; return (proc_pdrv(adapter, page, 3));}/** * proc_pdrv() * @page - buffer to write the data in * @adapter - pointer to our soft state * * Display information about the physical drives. */static intproc_pdrv(adapter_t *adapter, char *page, int channel){ dma_addr_t dma_handle; char *scsi_inq; dma_addr_t scsi_inq_dma_handle; caddr_t inquiry; struct pci_dev *pdev; u8 *pdrv_state; u8 state; int tgt; int max_channels; int len = 0; char str[80]; int i; if( make_local_pdev(adapter, &pdev) != 0 ) { return len; } if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) { goto free_pdev; } if( mega_adapinq(adapter, dma_handle) != 0 ) { len = sprintf(page, "Adapter inquiry failed.\n"); printk(KERN_WARNING "megaraid: inquiry failed.\n"); goto free_inquiry; } scsi_inq = pci_alloc_consistent(pdev, 256, &scsi_inq_dma_handle); if( scsi_inq == NULL ) { len = sprintf(page, "memory not available for scsi inq.\n"); goto free_inquiry; } if( adapter->flag & BOARD_40LD ) { pdrv_state = ((mega_inquiry3 *)inquiry)->pdrv_state; } else { pdrv_state = ((mraid_ext_inquiry *)inquiry)-> raid_inq.pdrv_info.pdrv_state; } max_channels = adapter->product_info.nchannels; if( channel >= max_channels ) { goto free_pci; } for( tgt = 0; tgt <= MAX_TARGET; tgt++ ) { i = channel*16 + tgt; state = *(pdrv_state + i); switch( state & 0x0F ) { case PDRV_ONLINE: sprintf(str, "Channel:%2d Id:%2d State: Online", channel, tgt); break; case PDRV_FAILED: sprintf(str, "Channel:%2d Id:%2d State: Failed", channel, tgt); break; case PDRV_RBLD: sprintf(str, "Channel:%2d Id:%2d State: Rebuild", channel, tgt); break; case PDRV_HOTSPARE: sprintf(str, "Channel:%2d Id:%2d State: Hot spare", channel, tgt); break; default: sprintf(str, "Channel:%2d Id:%2d State: Un-configured", channel, tgt); break; } /* * This interface displays inquiries for disk drives * only. Inquries for logical drives and non-disk * devices are available through /proc/scsi/scsi */ memset(scsi_inq, 0, 256); if( mega_internal_dev_inquiry(adapter, channel, tgt, scsi_inq_dma_handle) || (scsi_inq[0] & 0x1F) != TYPE_DISK ) { continue; } /* * Check for overflow. We print less than 240 * characters for inquiry */ if( (len + 240) >= PAGE_SIZE ) break; len += sprintf(page+len, "%s.\n", str); len += mega_print_inquiry(page+len, scsi_inq); }free_pci: pci_free_consistent(pdev, 256, scsi_inq, scsi_inq_dma_handle);free_inquiry: mega_free_inquiry(inquiry, dma_handle, pdev);free_pdev: free_local_pdev(pdev); return len;}/* * Display scsi inquiry */static intmega_print_inquiry(char *page, char *scsi_inq){ int len = 0; int i; len = sprintf(page, " Vendor: "); for( i = 8; i < 16; i++ ) { len += sprintf(page+len, "%c", scsi_inq[i]); } len += sprintf(page+len, " Model: "); for( i = 16; i < 32; i++ ) { len += sprintf(page+len, "%c", scsi_inq[i]); } len += sprintf(page+len, " Rev: "); for( i = 32; i < 36; i++ ) { len += sprintf(page+len, "%c", scsi_inq[i]); } len += sprintf(page+len, "\n"); i = scsi_inq[0] & 0x1f; len += sprintf(page+len, " Type: %s ", scsi_device_type(i)); len += sprintf(page+len, " ANSI SCSI revision: %02x", scsi_inq[2] & 0x07); if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 ) len += sprintf(page+len, " CCS\n"); else len += sprintf(page+len, "\n"); return len;}/** * proc_rdrv_10() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display real time information about the logical drives 0 through 9. */static intproc_rdrv_10(char *page, char **start, off_t offset, int count, int *eof, void *data){ adapter_t *adapter = (adapter_t *)data; *eof = 1; return (proc_rdrv(adapter, page, 0, 9));}/** * proc_rdrv_20() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state * * Display real time information about the logical drives 0 through
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -