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

📄 aachba.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 4 页
字号:
	/*	 * First check the fib status	 */	if (le32_to_cpu(srbreply->status) != ST_OK){		int len;		printk(KERN_WARNING "aac_srb_callback: srb failed, status = %d\n", le32_to_cpu(srbreply->status));		len = (srbreply->sense_data_size > sizeof(scsicmd->sense_buffer))?				sizeof(scsicmd->sense_buffer):srbreply->sense_data_size;		scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;		memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);	}	/*	 * Next check the srb status	 */	switch(le32_to_cpu(srbreply->srb_status)){	case SRB_STATUS_ERROR_RECOVERY:	case SRB_STATUS_PENDING:	case SRB_STATUS_SUCCESS:		if(scsicmd->cmnd[0] == INQUIRY ){			u8 b;			/* We can't expose disk devices because we can't tell whether they			 * are the raw container drives or stand alone drives			 */			b = *(u8*)scsicmd->buffer;			if( (b & 0x0f) == TYPE_DISK ){				scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;			}		} else {			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;		}		break;	case SRB_STATUS_DATA_OVERRUN:		switch(scsicmd->cmnd[0]){		case  READ_6:		case  WRITE_6:		case  READ_10:		case  WRITE_10:		case  READ_12:		case  WRITE_12:			if(le32_to_cpu(srbreply->data_xfer_length) < scsicmd->underflow ) {				printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");			} else {				printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n");			}			scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;			break;		default:			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;			break;		}		break;	case SRB_STATUS_ABORTED:		scsicmd->result = DID_ABORT << 16 | ABORT << 8;		break;	case SRB_STATUS_ABORT_FAILED:		// Not sure about this one - but assuming the hba was trying to abort for some reason		scsicmd->result = DID_ERROR << 16 | ABORT << 8;		break;	case SRB_STATUS_PARITY_ERROR:		scsicmd->result = DID_PARITY << 16 | MSG_PARITY_ERROR << 8;		break;	case SRB_STATUS_NO_DEVICE:	case SRB_STATUS_INVALID_PATH_ID:	case SRB_STATUS_INVALID_TARGET_ID:	case SRB_STATUS_INVALID_LUN:	case SRB_STATUS_SELECTION_TIMEOUT:		scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;		break;	case SRB_STATUS_COMMAND_TIMEOUT:	case SRB_STATUS_TIMEOUT:		scsicmd->result = DID_TIME_OUT << 16 | COMMAND_COMPLETE << 8;		break;	case SRB_STATUS_BUSY:		scsicmd->result = DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;		break;	case SRB_STATUS_BUS_RESET:		scsicmd->result = DID_RESET << 16 | COMMAND_COMPLETE << 8;		break;	case SRB_STATUS_MESSAGE_REJECTED:		scsicmd->result = DID_ERROR << 16 | MESSAGE_REJECT << 8;		break;	case SRB_STATUS_REQUEST_FLUSHED:	case SRB_STATUS_ERROR:	case SRB_STATUS_INVALID_REQUEST:	case SRB_STATUS_REQUEST_SENSE_FAILED:	case SRB_STATUS_NO_HBA:	case SRB_STATUS_UNEXPECTED_BUS_FREE:	case SRB_STATUS_PHASE_SEQUENCE_FAILURE:	case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:	case SRB_STATUS_DELAYED_RETRY:	case SRB_STATUS_BAD_FUNCTION:	case SRB_STATUS_NOT_STARTED:	case SRB_STATUS_NOT_IN_USE:	case SRB_STATUS_FORCE_ABORT:	case SRB_STATUS_DOMAIN_VALIDATION_FAIL:	default:#ifdef AAC_DETAILED_STATUS_INFO		printk("aacraid: SRB ERROR (%s)\n",aac_get_status_string(le32_to_cpu(srbreply->srb_status)));#endif		scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8;		break;	}	if (le32_to_cpu(srbreply->scsi_status) == 0x02 ){  // Check Condition		int len;		len = (srbreply->sense_data_size > sizeof(scsicmd->sense_buffer))?				sizeof(scsicmd->sense_buffer):srbreply->sense_data_size;		printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n", le32_to_cpu(srbreply->status), len);		memcpy(scsicmd->sense_buffer, srbreply->sense_data, len);	}	/*	 * OR in the scsi status (already shifted up a bit)	 */	scsicmd->result |= le32_to_cpu(srbreply->scsi_status);	fib_complete(fibptr);	fib_free(fibptr);	aac_io_done(scsicmd);}/** * * aac_send_scb_fib * @scsicmd: the scsi command block * * This routine will form a FIB and fill in the aac_srb from the  * scsicmd passed in. */static int aac_send_srb_fib(Scsi_Cmnd* scsicmd){	struct fib* cmd_fibcontext;	struct aac_dev* dev;	int status;	struct aac_srb *srbcmd;	u16 fibsize;	u32 flag;	if( scsicmd->target > 15 || scsicmd->lun > 7) {		scsicmd->result = DID_NO_CONNECT << 16;		__aac_io_done(scsicmd);		return 0;	}	dev = (struct aac_dev *)scsicmd->host->hostdata;	switch(scsicmd->sc_data_direction){	case SCSI_DATA_WRITE:		flag = SRB_DataOut;		break;	case SCSI_DATA_UNKNOWN:  		flag = SRB_DataIn | SRB_DataOut;		break;	case SCSI_DATA_READ:		flag = SRB_DataIn;		break;	case SCSI_DATA_NONE: 	default:		flag = SRB_NoDataXfer;		break;	}	/*	 *	Allocate and initialize a Fib then setup a BlockWrite command	 */	if (!(cmd_fibcontext = fib_alloc(dev))) {		scsicmd->result = DID_ERROR << 16;		__aac_io_done(scsicmd);		return -1;	}	fib_init(cmd_fibcontext);	srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);	srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);	srbcmd->channel  = cpu_to_le32(aac_logical_to_phys(scsicmd->channel));	srbcmd->target   = cpu_to_le32(scsicmd->target);	srbcmd->lun      = cpu_to_le32(scsicmd->lun);	srbcmd->flags    = cpu_to_le32(flag);	srbcmd->timeout  = cpu_to_le32(0);  // timeout not used	srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter	srbcmd->cdb_size = cpu_to_le32(scsicmd->cmd_len);		if( dev->pae_support ==1 ) {		aac_build_sg64(scsicmd, (struct sgmap64*) &srbcmd->sg);		srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);		memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));		memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);		/*		 *	Build Scatter/Gather list		 */		fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64));		/*		 *	Now send the Fib to the adapter		 */		status = fib_send(ScsiPortCommand64, cmd_fibcontext, fibsize, FsaNormal, 0, 1,				  (fib_callback) aac_srb_callback, (void *) scsicmd);	} else {		aac_build_sg(scsicmd, (struct sgmap*)&srbcmd->sg);		srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);		memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));		memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);		/*		 *	Build Scatter/Gather list		 */		fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));		/*		 *	Now send the Fib to the adapter		 */		status = fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1,				  (fib_callback) aac_srb_callback, (void *) scsicmd);	}	/*	 *	Check that the command queued to the controller	 */	if (status == -EINPROGRESS){		return 0;	}	printk(KERN_WARNING "aac_srb: fib_send failed with status: %d\n", status);	/*	 *	For some reason, the Fib didn't queue, return QUEUE_FULL	 */	scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL;	__aac_io_done(scsicmd);	fib_complete(cmd_fibcontext);	fib_free(cmd_fibcontext);	return -1;}static unsigned long aac_build_sg(Scsi_Cmnd* scsicmd, struct sgmap* psg){	struct aac_dev *dev;	unsigned long byte_count = 0;	dev = (struct aac_dev *)scsicmd->host->hostdata;	// Get rid of old data	psg->count = cpu_to_le32(0);	psg->sg[0].addr = cpu_to_le32(NULL);	psg->sg[0].count = cpu_to_le32(0);  	if (scsicmd->use_sg) {		struct scatterlist *sg;		int i;		int sg_count;		sg = (struct scatterlist *) scsicmd->request_buffer;		sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));		psg->count = cpu_to_le32(sg_count);		byte_count = 0;		for (i = 0; i < sg_count; i++) {			psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));			psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));			byte_count += sg_dma_len(sg);			sg++;		}		/* hba wants the size to be exact */		if(byte_count > scsicmd->request_bufflen){			psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);			byte_count = scsicmd->request_bufflen;		}		/* Check for command underflow */		if(scsicmd->underflow && (byte_count < scsicmd->underflow)){			printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",					byte_count, scsicmd->underflow);		}	}	else if(scsicmd->request_bufflen) {		dma_addr_t addr; 		addr = pci_map_single(dev->pdev,				scsicmd->request_buffer,				scsicmd->request_bufflen,				scsi_to_pci_dma_dir(scsicmd->sc_data_direction));		psg->count = cpu_to_le32(1);		psg->sg[0].addr = cpu_to_le32(addr);		psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  		scsicmd->SCp.ptr = (void *)addr;		byte_count = scsicmd->request_bufflen;	}	return byte_count;}static unsigned long aac_build_sg64(Scsi_Cmnd* scsicmd, struct sgmap64* psg){	struct aac_dev *dev;	unsigned long byte_count = 0;	u64 le_addr;	dev = (struct aac_dev *)scsicmd->host->hostdata;	// Get rid of old data	psg->count = cpu_to_le32(0);	psg->sg[0].addr[0] = cpu_to_le32(NULL);	psg->sg[0].addr[1] = cpu_to_le32(NULL);	psg->sg[0].count = cpu_to_le32(0);  	if (scsicmd->use_sg) {		struct scatterlist *sg;		int i;		int sg_count;		sg = (struct scatterlist *) scsicmd->request_buffer;		sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));		psg->count = cpu_to_le32(sg_count);		byte_count = 0;		for (i = 0; i < sg_count; i++) {			le_addr = cpu_to_le64(sg_dma_address(sg));			psg->sg[i].addr[1] = (u32)(le_addr>>32);			psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff);			psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));			byte_count += sg_dma_len(sg);			sg++;		}		/* hba wants the size to be exact */		if(byte_count > scsicmd->request_bufflen){			psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);			byte_count = scsicmd->request_bufflen;		}		/* Check for command underflow */		if(scsicmd->underflow && (byte_count < scsicmd->underflow)){			printk(KERN_WARNING"aacraid: cmd len %08lX cmd underflow %08X\n",					byte_count, scsicmd->underflow);		}	}	else if(scsicmd->request_bufflen) {		dma_addr_t addr; 		addr = pci_map_single(dev->pdev,				scsicmd->request_buffer,				scsicmd->request_bufflen,				scsi_to_pci_dma_dir(scsicmd->sc_data_direction));		psg->count = cpu_to_le32(1);		le_addr = cpu_to_le64(addr);		psg->sg[0].addr[1] = (u32)(le_addr>>32);		psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff);		psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  		scsicmd->SCp.ptr = (void *)addr;		byte_count = scsicmd->request_bufflen;	}	return byte_count;}#ifdef AAC_DETAILED_STATUS_INFOstruct aac_srb_status_info {	u32	status;	char	*str;};static struct aac_srb_status_info srb_status_info[] = {	{ SRB_STATUS_PENDING,		"Pending Status"},	{ SRB_STATUS_SUCCESS,		"Success"},	{ SRB_STATUS_ABORTED,		"Aborted Command"},	{ SRB_STATUS_ABORT_FAILED,	"Abort Failed"},	{ SRB_STATUS_ERROR,		"Error Event"}, 	{ SRB_STATUS_BUSY,		"Device Busy"},	{ SRB_STATUS_INVALID_REQUEST,	"Invalid Request"},	{ SRB_STATUS_INVALID_PATH_ID,	"Invalid Path ID"},	{ SRB_STATUS_NO_DEVICE,		"No Device"},	{ SRB_STATUS_TIMEOUT,		"Timeout"},	{ SRB_STATUS_SELECTION_TIMEOUT,	"Selection Timeout"},	{ SRB_STATUS_COMMAND_TIMEOUT,	"Command Timeout"},	{ SRB_STATUS_MESSAGE_REJECTED,	"Message Rejected"},	{ SRB_STATUS_BUS_RESET,		"Bus Reset"},	{ SRB_STATUS_PARITY_ERROR,	"Parity Error"},	{ SRB_STATUS_REQUEST_SENSE_FAILED,"Request Sense Failed"},	{ SRB_STATUS_NO_HBA,		"No HBA"},	{ SRB_STATUS_DATA_OVERRUN,	"Data Overrun/Data Underrun"},	{ SRB_STATUS_UNEXPECTED_BUS_FREE,"Unexpected Bus Free"},	{ SRB_STATUS_PHASE_SEQUENCE_FAILURE,"Phase Error"},	{ SRB_STATUS_BAD_SRB_BLOCK_LENGTH,"Bad Srb Block Length"},	{ SRB_STATUS_REQUEST_FLUSHED,	"Request Flushed"},	{ SRB_STATUS_DELAYED_RETRY,	"Delayed Retry"},	{ SRB_STATUS_INVALID_LUN,	"Invalid LUN"}, 	{ SRB_STATUS_INVALID_TARGET_ID,	"Invalid TARGET ID"},	{ SRB_STATUS_BAD_FUNCTION,	"Bad Function"},	{ SRB_STATUS_ERROR_RECOVERY,	"Error Recovery"},	{ SRB_STATUS_NOT_STARTED,	"Not Started"},	{ SRB_STATUS_NOT_IN_USE,	"Not In Use"},    	{ SRB_STATUS_FORCE_ABORT,	"Force Abort"},	{ SRB_STATUS_DOMAIN_VALIDATION_FAIL,"Domain Validation Failure"},	{ 0xff,				"Unknown Error"}};char *aac_get_status_string(u32 status){	int i;	for(i=0; i < (sizeof(srb_status_info)/sizeof(struct aac_srb_status_info)); i++ ){		if(srb_status_info[i].status == status){			return srb_status_info[i].str;		}	}	return "Bad Status Code";}#endif

⌨️ 快捷键说明

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