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