⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 megaraid.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
 *=========================== */static mega_scb *mega_allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt){	mega_scb *pScb;	/* Unlink command from Free List */	if ((pScb = megaCfg->qFreeH) != NULL) {		megaCfg->qFreeH = pScb->next;		megaCfg->qFcnt--;		pScb->isrcount = jiffies;		pScb->next = NULL;		pScb->state = SCB_ACTIVE;		pScb->SCpnt = SCpnt;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)		pScb->dma_type = M_RD_DMA_TYPE_NONE;#endif		return pScb;	}	printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");	return NULL;}/* Run through the list of completed requests  and finish it */static void mega_rundoneq (mega_host_config * megaCfg){	Scsi_Cmnd *SCpnt;	while ((SCpnt = megaCfg->qCompletedH) != NULL) {		megaCfg->qCompletedH = (Scsi_Cmnd *) SCpnt->host_scribble;		megaCfg->qCcnt--;		SCpnt->host_scribble = (unsigned char *) NULL;	/* XC : sep 14 */		/* Callback */		callDone (SCpnt);	}	megaCfg->qCompletedH = megaCfg->qCompletedT = NULL;}/* * Runs through the list of pending requests * Assumes that mega_lock spin_lock has been acquired. */static int mega_runpendq (mega_host_config * megaCfg){	mega_scb *pScb;	int rc;	/* Issue any pending commands to the card */	for (pScb = megaCfg->qPendingH; pScb; pScb = pScb->next) {		if (pScb->state == SCB_ACTIVE) {			if ((rc =			     megaIssueCmd (megaCfg, pScb->mboxData, pScb, 1)) == -1)				return rc;		}	}	return 0;}/* Add command to the list of completed requests */static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, int status){	int islogical;	Scsi_Cmnd *SCpnt;	mega_passthru *pthru;	mega_ext_passthru *epthru;	mega_mailbox *mbox;	struct scatterlist *sgList;	u8	c;	if (pScb == NULL) {		TRACE (("NULL pScb in mega_cmd_done!"));		printk(KERN_CRIT "NULL pScb in mega_cmd_done!");	}	SCpnt = pScb->SCpnt;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	pthru = pScb->pthru;	epthru = pScb->epthru;#else	pthru = &pScb->pthru;	epthru = &pScb->epthru;#endif	mbox = (mega_mailbox *) & pScb->mboxData;	if (SCpnt == NULL) {		TRACE (("NULL SCpnt in mega_cmd_done!"));		TRACE (("pScb->idx = ", pScb->idx));		TRACE (("pScb->state = ", pScb->state));		TRACE (("pScb->state = ", pScb->state));		panic(KERN_ERR "megaraid:Problem...!\n");	}	islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&					(SCpnt->channel <= megaCfg->host->max_channel) );#if 0	islogical = (SCpnt->channel == megaCfg->host->max_channel);#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* Special Case to handle PassThrough->XferAddrress > 4GB */	switch (SCpnt->cmnd[0]) {	case INQUIRY:	case READ_CAPACITY:		memcpy (SCpnt->request_buffer,			pScb->bounce_buffer, SCpnt->request_bufflen);		break;	}#endif	mega_freeSCB (megaCfg, pScb);	/*	 * Do not return the presence of hard disk on the channel so, inquiry	 * sent, and returned data==hard disk or removable hard disk and not	 * logical, request should return failure! - PJ	 */#if 0	if (SCpnt->cmnd[0] == INQUIRY && ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) && !islogical) {		status = 0xF0;	}#endif	if (SCpnt->cmnd[0] == INQUIRY && !islogical) {		if ( SCpnt->use_sg ) {			sgList = (struct scatterlist *)SCpnt->request_buffer;			memcpy(&c, sgList[0].address, 0x1);		} else {			memcpy(&c, SCpnt->request_buffer, 0x1);		}#if 0		if( (c & 0x1F ) == TYPE_DISK ) {			status = 0xF0;		}#endif		if( IS_RAID_CH(SCpnt->channel) && ((c & 0x1F ) == TYPE_DISK) ) {			status = 0xF0;		}	}	/* clear result; otherwise, success returns corrupt value */	SCpnt->result = 0;	if ((SCpnt->cmnd[0] & M_RD_IOCTL_CMD)) {	/* i.e. ioctl cmd such as M_RD_IOCTL_CMD, M_RD_IOCTL_CMD_NEW of megamgr */		switch (status) {		case 2:		case 0xF0:		case 0xF4:			SCpnt->result = (DID_BAD_TARGET << 16) | status;			break;		default:			SCpnt->result |= status;		}		/*end of switch */	} else {		/* Convert MegaRAID status to Linux error code */		switch (status) {		case 0x00:	/* SUCCESS , i.e. SCSI_STATUS_GOOD */			SCpnt->result |= (DID_OK << 16);			break;		case 0x02:	/* ERROR_ABORTED, i.e. SCSI_STATUS_CHECK_CONDITION */			/*set sense_buffer and result fields */			if (mbox->cmd == MEGA_MBOXCMD_PASSTHRU) {				memcpy (SCpnt->sense_buffer, pthru->reqsensearea, 14);			} else if (mbox->cmd == MEGA_MBOXCMD_EXTPASSTHRU) {				SCpnt->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | (CHECK_CONDITION << 1);				memcpy(					SCpnt->sense_buffer,					epthru->reqsensearea, 14				);				SCpnt->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | (CHECK_CONDITION << 1);				/*SCpnt->result =					(DRIVER_SENSE << 24) |					(DID_ERROR << 16) | status;*/			} else {				SCpnt->sense_buffer[0] = 0x70;				SCpnt->sense_buffer[2] = ABORTED_COMMAND;				SCpnt->result |= (CHECK_CONDITION << 1);			}			break;		case 0x08:	/* ERR_DEST_DRIVE_FAILED, i.e. SCSI_STATUS_BUSY */			SCpnt->result |= (DID_BUS_BUSY << 16) | status;			break;		default:			SCpnt->result |= (DID_BAD_TARGET << 16) | status;			break;		}	}	/* Add Scsi_Command to end of completed queue */	if (megaCfg->qCompletedH == NULL) {		megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;	} else {		megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;		megaCfg->qCompletedT = SCpnt;	}	megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;	megaCfg->qCcnt++;}/*------------------------------------------------------------------- * *                 Build a SCB from a Scsi_Cmnd * * Returns a SCB pointer, or NULL * If NULL is returned, the scsi_done function MUST have been called * *-------------------------------------------------------------------*/static mega_scb *mega_build_cmd (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt){	mega_scb *pScb;	mega_mailbox *mbox;	mega_passthru *pthru;	mega_ext_passthru *epthru;	long seg;	char islogical;	int lun = SCpnt->lun;	int		max_lun;	if ((SCpnt->cmnd[0] == MEGADEVIOC))		return megadev_doioctl (megaCfg, SCpnt);	if ((SCpnt->cmnd[0] == M_RD_IOCTL_CMD)		    || (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW))#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  		return mega_ioctl (megaCfg, SCpnt);	/* Handle IOCTL command */#else	{		printk(KERN_WARNING "megaraid ioctl: older interface - "				"not supported.\n");		return NULL;	}#endif	islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&					(SCpnt->channel <= megaCfg->host->max_channel) );#if 0	islogical = (IS_RAID_CH(SCpnt->channel) && /* virtual ch is raid - AM */						(SCpnt->channel == megaCfg->host->max_channel));#endif	if ( ! megaCfg->support_ext_cdb ) {		if (!islogical && lun != 0) {			SCpnt->result = (DID_BAD_TARGET << 16);			callDone (SCpnt);			return NULL;		}	}	if (!islogical && SCpnt->target == skip_id) {		SCpnt->result = (DID_BAD_TARGET << 16);		callDone (SCpnt);		return NULL;	}	if (islogical) {		/* have just LUN 0 for each target on virtual channels */		if( SCpnt->lun != 0 ) {			SCpnt->result = (DID_BAD_TARGET << 16);			callDone (SCpnt);			return NULL;		}		lun = mega_get_lun(megaCfg, SCpnt);	    max_lun = (megaCfg->flag & BOARD_40LD) ?						FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;		 /*		  * max_lun increases by 0x80 if some logical drive was deleted.		  */		if(megaCfg->read_ldidmap) {			max_lun += 0x80;		}		if( lun > max_lun ) {			SCpnt->result = (DID_BAD_TARGET << 16);			callDone (SCpnt);			return NULL;		}		/*		 * If we have a logical drive with boot enabled, project it first		 */		if( megaCfg->boot_ldrv_enabled ) {			if( lun == 0 ) {				lun = megaCfg->boot_ldrv;			}			else {				if( lun <= megaCfg->boot_ldrv ) {					lun--;				}			}		}	} else {		if ( lun > 7) {				/* Do not support lun >7 for physically accessed devices */			SCpnt->result = (DID_BAD_TARGET << 16);			callDone (SCpnt);			return NULL;		}	}	/*-----------------------------------------------------	 *	 *               Logical drive commands	 *	 *-----------------------------------------------------*/	if (islogical) {		switch (SCpnt->cmnd[0]) {		case TEST_UNIT_READY:			memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen);			SCpnt->result = (DID_OK << 16);			callDone (SCpnt);			return NULL;		case MODE_SENSE:			memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]);			SCpnt->result = (DID_OK << 16);			callDone (SCpnt);			return NULL;		case READ_CAPACITY:		case INQUIRY:			/* Allocate a SCB and initialize passthru */			if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {				SCpnt->result = (DID_ERROR << 16);				callDone (SCpnt);				return NULL;			}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)			pthru = pScb->pthru;#else			pthru = &pScb->pthru;#endif			mbox = (mega_mailbox *) & pScb->mboxData;			memset (mbox, 0, sizeof (pScb->mboxData));			memset (pthru, 0, sizeof (mega_passthru));			pthru->timeout = 0;			pthru->ars = 1;			pthru->reqsenselen = 14;			pthru->islogical = 1;			pthru->logdrv = lun;			pthru->cdblen = SCpnt->cmd_len;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)			/*Not sure about the direction */			pScb->dma_direction = PCI_DMA_BIDIRECTIONAL;			pScb->dma_type = M_RD_PTHRU_WITH_BULK_DATA;#if 0/* Normal Code w/o the need for bounce buffer */			pScb->dma_h_bulkdata			    = pci_map_single (megaCfg->dev,					      SCpnt->request_buffer,					      SCpnt->request_bufflen,					      pScb->dma_direction);			pthru->dataxferaddr = pScb->dma_h_bulkdata;#else/* Special Code to use bounce buffer for READ_CAPA/INQ */			pthru->dataxferaddr = pScb->dma_bounce_buffer;			pScb->dma_type = M_RD_DMA_TYPE_NONE;#endif#else			pthru->dataxferaddr =			    virt_to_bus (SCpnt->request_buffer);#endif			pthru->dataxferlen = SCpnt->request_bufflen;			memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);			/* Initialize mailbox area */			mbox->cmd = MEGA_MBOXCMD_PASSTHRU;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)			mbox->xferaddr = pScb->dma_passthruhandle64;			TRACE1 (("M_RD_PTHRU_WITH_BULK_DATA Enabled \n"));#else			mbox->xferaddr = virt_to_bus (pthru);#endif			return pScb;		case READ_6:		case WRITE_6:		case READ_10:		case WRITE_10:			/* Allocate a SCB and initialize mailbox */			if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {				SCpnt->result = (DID_ERROR << 16);				callDone (SCpnt);				return NULL;			}			mbox = (mega_mailbox *) & pScb->mboxData;			memset (mbox, 0, sizeof (pScb->mboxData));			mbox->logdrv = lun;			if (megaCfg->flag & BOARD_64BIT) {				mbox->cmd = (*SCpnt->cmnd == READ_6					     || *SCpnt->cmnd ==					     READ_10) ? MEGA_MBOXCMD_LREAD64 :				    MEGA_MBOXCMD_LWRITE64;			} else {				mbox->cmd = (*SCpnt->cmnd == READ_6					     || *SCpnt->cmnd ==					     READ_10) ? MEGA_MBOXCMD_LREAD :				    MEGA_MBOXCMD_LWRITE;			}			/* 6-byte */			if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {				mbox->numsectors = (u32) SCpnt->cmnd[4];				mbox->lba =				    ((u32) SCpnt->cmnd[1] << 16) |				    ((u32) SCpnt->cmnd[2] << 8) |				    (u32) SCpnt->cmnd[3];				mbox->lba &= 0x1FFFFF;				if (*SCpnt->cmnd == READ_6) {					megaCfg->nReads[(int) lun]++;					megaCfg->nReadBlocks[(int) lun] +=					    mbox->numsectors;				} else {					megaCfg->nWrites[(int) lun]++;					megaCfg->nWriteBlocks[(int) lun] +=					    mbox->numsectors;				}			}			/* 10-byte */			if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {				mbox->numsectors =				    (u32) SCpnt->cmnd[8] |				    ((u32) SCpnt->cmnd[7] << 8);				mbox->lba =				    ((u32) SCpnt->cmnd[2] << 24) |				    ((u32) SCpnt->cmnd[3] << 16) |				    ((u32) SCpnt->cmnd[4] << 8) |				    (u32) SCpnt->cmnd[5];				if (*SCpnt->cmnd == READ_10) {					megaCfg->nReads[(int) lun]++;					megaCfg->nReadBlocks[(int) lun] +=					    mbox->numsectors;				} else {					megaCfg->nWrites[(int) lun]++;					megaCfg->nWriteBlocks[(int) lun] +=					    mbox->numsectors;				}			}			/* 12-byte */			if (*SCpnt->cmnd == READ_12 || *SCpnt->cmnd == WRITE_12) {				mbox->lba =				    ((u32) SCpnt->cmnd[2] << 24) |				    ((u32) SCpnt->cmnd[3] << 16) |				    ((u32) SCpnt->cmnd[4] << 8) |				    (u32) SCpnt->cmnd[5];				mbox->numsectors =				    ((u32) SCpnt->cmnd[6] << 24) |				    ((u32) SCpnt->cmnd[7] << 16) |				    ((u32) SCpnt->cmnd[8] << 8) |				    (u32) SCpnt->cmnd[9];				if (*SCpnt->cmnd == READ_12) {					megaCfg->nReads[(int) lun]++;					megaCfg->nReadBlocks[(int) lun] +=					    mbox->numsectors;				} else {					megaCfg->nWrites[(int) lun]++;

⌨️ 快捷键说明

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