linux_iface.c
来自「6440linuxDriver的源代码」· C语言 代码 · 共 641 行 · 第 1/2 页
C
641 行
/* * * linux_iface.c - Kernel/CLI interface * */#include "hba_header.h"#include "hba_mod.h"#include "hba_timer.h"#include "linux_iface.h"#include "linux_main.h"#define MV_DEVFS_NAME "mv"#ifdef RAID_DRIVERstatic int mv_open(struct inode *inode, struct file *file);#ifdef HAVE_UNLOCKED_IOCTLstatic long mv_ioctl(struct file *file, unsigned int cmd, unsigned long arg);#elsestatic int mv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);#endif /* HAVE_UNLOCKED_IOCTL */#define IOCTL_BUF_LEN (1024*1024)static unsigned char ioctl_buf[IOCTL_BUF_LEN];static struct file_operations mv_fops = { .owner = THIS_MODULE, .open = mv_open,#ifdef HAVE_UNLOCKED_IOCTL .unlocked_ioctl = mv_ioctl,#else .ioctl = mv_ioctl,#endif .release = NULL};#endif /* RAID_DRIVER */void ioctlcallback(MV_PVOID This, PMV_Request req){ struct hba_extension *hba = (struct hba_extension *) This; hba->Io_Count--;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) atomic_set(&hba->hba_sync, 0);#else complete(&hba->cmpl);#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) */ res_free_req_to_pool(hba->req_pool, req);}#ifdef RAID_DRIVERstatic MV_U16 API2Driver_ID(MV_U16 API_ID){ MV_U16 returnID = API_ID; returnID &= 0xfff; return returnID;}static LD_Info ldinfo[LDINFO_NUM] = {{0}};static int mv_proc_ld_info(struct Scsi_Host *host){ struct hba_extension *hba; PMV_Request req; MV_U8 Cdb[MAX_CDB_SIZE]; MV_U16 LD_ID = 0XFF; unsigned long flags; Cdb[0] = APICDB0_LD; Cdb[1] = APICDB1_LD_GETINFO; Cdb[2] = LD_ID & 0xff; Cdb[3] = API2Driver_ID(LD_ID)>>8; hba = __mv_get_ext_from_host(host); req = res_get_req_from_pool(hba->req_pool); if (req == NULL) { return -1; /*FAIL.*/ } req->Cmd_Initiator = hba; req->Org_Req = req; req->Device_Id = VIRTUAL_DEVICE_ID; req->Cmd_Flag = 0; req->Req_Type = REQ_TYPE_OS; if (SCSI_IS_READ(Cdb[0])) req->Cmd_Flag |= CMD_FLAG_DATA_IN; if (SCSI_IS_READ(Cdb[0]) || SCSI_IS_WRITE(Cdb[0])) req->Cmd_Flag |= CMD_FLAG_DMA; req->Data_Transfer_Length = LDINFO_NUM*sizeof(LD_Info); memset(ldinfo, 0, LDINFO_NUM*sizeof(LD_Info)); req->Data_Buffer = ldinfo; SGTable_Init(&req->SG_Table, 0); memcpy(req->Cdb, Cdb, MAX_CDB_SIZE); memset(req->Context, 0, sizeof(MV_PVOID)*MAX_POSSIBLE_MODULE_NUMBER); req->LBA.value = 0; req->Sector_Count = 0; req->Completion = ioctlcallback; req->Req_Type = REQ_TYPE_INTERNAL; spin_lock_irqsave(&hba->irq_lock, flags); hba->Io_Count++;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) atomic_set(&hba->hba_sync, 1);#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) */ hba->desc->ops->module_sendrequest(hba->desc->extension, req); spin_unlock_irqrestore(&hba->irq_lock, flags);#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) if ( !__hba_wait_for_atomic_timeout(&hba->hba_sync, HBA_REQ_TIMER_IOCTL*HZ) ) {#else if (wait_for_completion_timeout(&hba->cmpl, HBA_REQ_TIMER_IOCTL*HZ) == 0) {#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) */ MV_DBG(DMSG_HBA, "__MV__ ioctl req timed out.\n"); return -1; /*FAIL.*/ } return 0;/*SUCCESS.*/}static char* mv_ld_status(int status){ switch (status) { case LD_STATUS_FUNCTIONAL: return "online"; case LD_STATUS_DEGRADE: return "degraded"; case LD_STATUS_DELETED: return "deleted"; case LD_STATUS_PARTIALLYOPTIMAL: return "partially optimal"; case LD_STATUS_OFFLINE: return "offline"; default: return "unknown"; }}static char* mv_ld_raid_mode(int status){ switch (status) { case LD_MODE_RAID0: return "RAID0"; case LD_MODE_RAID1: return "RAID1"; case LD_MODE_RAID10: return "RAID10"; case LD_MODE_RAID1E: return "RAID1E"; case LD_MODE_RAID5: return "RAID5"; case LD_MODE_RAID50: return "RAID50"; case LD_MODE_RAID6: return "RAID6"; case LD_MODE_RAID60: return "RAID60"; case LD_MODE_JBOD: return "JBOD"; default: return "unknown"; }}static char* mv_ld_bga_status(int status){ switch (status) { case LD_BGA_STATE_RUNNING: return "running"; case LD_BGA_STATE_ABORTED: return "aborted"; case LD_BGA_STATE_PAUSED: return "paused"; case LD_BGA_STATE_AUTOPAUSED: return "auto paused"; case LD_BGA_STATE_DDF_PENDING: return "DDF pending"; default: return "N/A"; }}static int mv_ld_get_status(struct Scsi_Host *host, MV_U16 ldid, LD_Status *ldstatus){ struct hba_extension *hba; PMV_Request req; MV_U8 Cdb[MAX_CDB_SIZE]; MV_U16 LD_ID = ldid;/*0XFF;*/ unsigned long flags; hba = __mv_get_ext_from_host(host); Cdb[0] = APICDB0_LD; Cdb[1] = APICDB1_LD_GETSTATUS; Cdb[2] = LD_ID & 0xff; Cdb[3] = API2Driver_ID(LD_ID)>>8; req = res_get_req_from_pool(hba->req_pool); if (req == NULL) return -1; req->Cmd_Initiator = hba; req->Org_Req = req; req->Device_Id = VIRTUAL_DEVICE_ID; req->Cmd_Flag = 0; req->Req_Type = REQ_TYPE_OS; if (SCSI_IS_READ(Cdb[0])) req->Cmd_Flag |= CMD_FLAG_DATA_IN; if ( SCSI_IS_READ(Cdb[0]) || SCSI_IS_WRITE(Cdb[0]) ) req->Cmd_Flag |= CMD_FLAG_DMA; /* Data Buffer */ req->Data_Transfer_Length = sizeof(LD_Status); memset(ldstatus, 0, sizeof(LD_Status)); req->Data_Buffer = ldstatus; SGTable_Init(&req->SG_Table, 0); memcpy(req->Cdb, Cdb, MAX_CDB_SIZE); memset(req->Context, 0, sizeof(MV_PVOID)*MAX_POSSIBLE_MODULE_NUMBER); req->LBA.value = 0; req->Sector_Count = 0; req->Completion = ioctlcallback; req->Req_Type = REQ_TYPE_INTERNAL; spin_lock_irqsave(&hba->irq_lock, flags); hba->Io_Count++;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) atomic_set(&hba->hba_sync, 1);#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) */ hba->desc->ops->module_sendrequest(hba->desc->extension, req); spin_unlock_irqrestore(&hba->irq_lock, flags);#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) if (!__hba_wait_for_atomic_timeout(&hba->hba_sync, HBA_REQ_TIMER_IOCTL*HZ)) {#else if (!wait_for_completion_timeout(&hba->cmpl, HBA_REQ_TIMER_IOCTL*HZ)) {#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) */ MV_DBG(DMSG_HBA, "__MV__ ioctl req timed out.\n"); return -1; /*FAIL.*/ } return 0;/*SUCCESS.*/}static int mv_ld_show_status(char *buf, PLD_Status pld_status){ char *str, *str1; int ret = 0; if ( LD_BGA_STATE_RUNNING == pld_status->BgaState) { if (LD_BGA_REBUILD == pld_status->Bga) str = "rebuilding"; else if (LD_BGA_INIT_QUICK == pld_status->Bga || LD_BGA_INIT_BACK == pld_status->Bga) str = "initializing"; else if (LD_BGA_CONSISTENCY_CHECK == pld_status->Bga || LD_BGA_CONSISTENCY_FIX == pld_status->Bga) str = "synchronizing"; else if (LD_BGA_MIGRATION == pld_status->Bga) str = "migration"; else str = "unknown bga action"; ret = sprintf(buf, " %s is %d%% done", str, pld_status->BgaPercentage); } else if ((LD_BGA_STATE_ABORTED == pld_status->BgaState) || (LD_BGA_STATE_PAUSED == pld_status->BgaState) || (LD_BGA_STATE_AUTOPAUSED == pld_status->BgaState)) { if (LD_BGA_REBUILD == pld_status->Bga) str = "rebuilding"; else if (LD_BGA_INIT_QUICK == pld_status->Bga || LD_BGA_INIT_BACK == pld_status->Bga) str = "initializing"; else if (LD_BGA_CONSISTENCY_CHECK == pld_status->Bga || LD_BGA_CONSISTENCY_FIX == pld_status->Bga) str = "synchronizing"; else if (LD_BGA_MIGRATION == pld_status->Bga) str = "migration"; else str = "unknown bga action"; if (LD_BGA_STATE_ABORTED == pld_status->BgaState) str1 = "aborted"; else if (LD_BGA_STATE_PAUSED == pld_status->BgaState) str1 = "paused"; else if (LD_BGA_STATE_AUTOPAUSED == pld_status->BgaState) str1 = "auto paused"; else str1 = "aborted"; ret = sprintf(buf, " %s is %s", str, str1); } return ret;}#endif /*RAID_DRIVER*/int mv_linux_proc_info(struct Scsi_Host *pSHost, char *pBuffer, char **ppStart,off_t offset, int length, int inout){ int len = 0; int datalen = 0;/*use as a temp flag.*/#ifdef RAID_DRIVER int i = 0; int j = 0; int ret = -1; LD_Status ld_status; char *tmp = NULL; int tmplen = 0;#endif if (!pSHost || !pBuffer) return (-ENOSYS);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?