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

📄 aachba.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	printk(KERN_WARNING "aac_write: 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 | SAM_STAT_TASK_SET_FULL;	scsicmd->scsi_done(scsicmd);	fib_complete(cmd_fibcontext);	fib_free(cmd_fibcontext);	return 0;}static void synchronize_callback(void *context, struct fib *fibptr){	struct aac_synchronize_reply *synchronizereply;	struct scsi_cmnd *cmd;	cmd = context;	dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", 				smp_processor_id(), jiffies));	BUG_ON(fibptr == NULL);	synchronizereply = fib_data(fibptr);	if (le32_to_cpu(synchronizereply->status) == CT_OK)		cmd->result = DID_OK << 16 | 			COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;	else {		struct scsi_device *sdev = cmd->device;		struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;		u32 cid = ID_LUN_TO_CONTAINER(sdev->id, sdev->lun);		printk(KERN_WARNING 		     "synchronize_callback: synchronize failed, status = %d\n",		     le32_to_cpu(synchronizereply->status));		cmd->result = DID_OK << 16 | 			COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;		set_sense((u8 *)&dev->fsa_dev[cid].sense_data,				    HARDWARE_ERROR,				    SENCODE_INTERNAL_TARGET_FAILURE,				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,				    0, 0);		memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,		  min(sizeof(dev->fsa_dev[cid].sense_data), 			  sizeof(cmd->sense_buffer)));	}	fib_complete(fibptr);	fib_free(fibptr);	cmd->scsi_done(cmd);}static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid){	int status;	struct fib *cmd_fibcontext;	struct aac_synchronize *synchronizecmd;	struct scsi_cmnd *cmd;	struct scsi_device *sdev = scsicmd->device;	int active = 0;	unsigned long flags;	/*	 * Wait for all commands to complete to this specific	 * target (block).	 */	spin_lock_irqsave(&sdev->list_lock, flags);	list_for_each_entry(cmd, &sdev->cmd_list, list)		if (cmd != scsicmd && cmd->serial_number != 0) {			++active;			break;		}	spin_unlock_irqrestore(&sdev->list_lock, flags);	/*	 *	Yield the processor (requeue for later)	 */	if (active)		return SCSI_MLQUEUE_DEVICE_BUSY;	/*	 *	Allocate and initialize a Fib	 */	if (!(cmd_fibcontext = 	    fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) 		return SCSI_MLQUEUE_HOST_BUSY;	fib_init(cmd_fibcontext);	synchronizecmd = fib_data(cmd_fibcontext);	synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);	synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);	synchronizecmd->cid = cpu_to_le32(cid);	synchronizecmd->count = 	     cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));	/*	 *	Now send the Fib to the adapter	 */	status = fib_send(ContainerCommand,		  cmd_fibcontext,		  sizeof(struct aac_synchronize),		  FsaNormal,		  0, 1,		  (fib_callback)synchronize_callback,		  (void *)scsicmd);	/*	 *	Check that the command queued to the controller	 */	if (status == -EINPROGRESS)		return 0;	printk(KERN_WARNING 		"aac_synchronize: fib_send failed with status: %d.\n", status);	fib_complete(cmd_fibcontext);	fib_free(cmd_fibcontext);	return SCSI_MLQUEUE_HOST_BUSY;}/** *	aac_scsi_cmd()		-	Process SCSI command *	@scsicmd:		SCSI command block * *	Emulate a SCSI command and queue the required request for the *	aacraid firmware. */ int aac_scsi_cmd(struct scsi_cmnd * scsicmd){	u32 cid = 0;	struct Scsi_Host *host = scsicmd->device->host;	struct aac_dev *dev = (struct aac_dev *)host->hostdata;	struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;	int ret;		/*	 *	If the bus, id or lun is out of range, return fail	 *	Test does not apply to ID 16, the pseudo id for the controller	 *	itself.	 */	if (scmd_id(scsicmd) != host->this_id) {		if ((scsicmd->device->channel == 0) ){			if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ 				scsicmd->result = DID_NO_CONNECT << 16;				scsicmd->scsi_done(scsicmd);				return 0;			}			cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);			/*			 *	If the target container doesn't exist, it may have			 *	been newly created			 */			if ((fsa_dev_ptr[cid].valid & 1) == 0) {				switch (scsicmd->cmnd[0]) {				case SERVICE_ACTION_IN:					if (!(dev->raw_io_interface) ||					    !(dev->raw_io_64) ||					    ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))						break;				case INQUIRY:				case READ_CAPACITY:				case TEST_UNIT_READY:					spin_unlock_irq(host->host_lock);					probe_container(dev, cid);					if ((fsa_dev_ptr[cid].valid & 1) == 0)						fsa_dev_ptr[cid].valid = 0;					spin_lock_irq(host->host_lock);					if (fsa_dev_ptr[cid].valid == 0) {						scsicmd->result = DID_NO_CONNECT << 16;						scsicmd->scsi_done(scsicmd);						return 0;					}				default:					break;				}			}			/*			 *	If the target container still doesn't exist, 			 *	return failure			 */			if (fsa_dev_ptr[cid].valid == 0) {				scsicmd->result = DID_BAD_TARGET << 16;				scsicmd->scsi_done(scsicmd);				return 0;			}		} else {  /* check for physical non-dasd devices */			if(dev->nondasd_support == 1){				return aac_send_srb_fib(scsicmd);			} else {				scsicmd->result = DID_NO_CONNECT << 16;				scsicmd->scsi_done(scsicmd);				return 0;			}		}	}	/*	 * else Command for the controller itself	 */	else if ((scsicmd->cmnd[0] != INQUIRY) &&	/* only INQUIRY & TUR cmnd supported for controller */		(scsicmd->cmnd[0] != TEST_UNIT_READY)) 	{		dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0]));		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;		set_sense((u8 *) &dev->fsa_dev[cid].sense_data,			    ILLEGAL_REQUEST,			    SENCODE_INVALID_COMMAND,			    ASENCODE_INVALID_COMMAND, 0, 0, 0, 0);		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,		  (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))		    ? sizeof(scsicmd->sense_buffer)		    : sizeof(dev->fsa_dev[cid].sense_data));		scsicmd->scsi_done(scsicmd);		return 0;	}	/* Handle commands here that don't really require going out to the adapter */	switch (scsicmd->cmnd[0]) {	case INQUIRY:	{		struct inquiry_data inq_data;		dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id));		memset(&inq_data, 0, sizeof (struct inquiry_data));		inq_data.inqd_ver = 2;	/* claim compliance to SCSI-2 */		inq_data.inqd_rdf = 2;	/* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */		inq_data.inqd_len = 31;		/*Format for "pad2" is  RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */		inq_data.inqd_pad2= 0x32 ;	 /*WBus16|Sync|CmdQue */		/*		 *	Set the Vendor, Product, and Revision Level		 *	see: <vendor>.c i.e. aac.c		 */		if (scmd_id(scsicmd) == host->this_id) {			setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));			inq_data.inqd_pdt = INQD_PDT_PROC;	/* Processor device */			aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;			scsicmd->scsi_done(scsicmd);			return 0;		}		setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);		inq_data.inqd_pdt = INQD_PDT_DA;	/* Direct/random access device */		aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));		return aac_get_container_name(scsicmd, cid);	}	case SERVICE_ACTION_IN:		if (!(dev->raw_io_interface) ||		    !(dev->raw_io_64) ||		    ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))			break;	{		u64 capacity;		char cp[13];		dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));		capacity = fsa_dev_ptr[cid].size - 1;		cp[0] = (capacity >> 56) & 0xff;		cp[1] = (capacity >> 48) & 0xff;		cp[2] = (capacity >> 40) & 0xff;		cp[3] = (capacity >> 32) & 0xff;		cp[4] = (capacity >> 24) & 0xff;		cp[5] = (capacity >> 16) & 0xff;		cp[6] = (capacity >> 8) & 0xff;		cp[7] = (capacity >> 0) & 0xff;		cp[8] = 0;		cp[9] = 0;		cp[10] = 2;		cp[11] = 0;		cp[12] = 0;		aac_internal_transfer(scsicmd, cp, 0,		  min((unsigned int)scsicmd->cmnd[13], sizeof(cp)));		if (sizeof(cp) < scsicmd->cmnd[13]) {			unsigned int len, offset = sizeof(cp);			memset(cp, 0, offset);			do {				len = min(scsicmd->cmnd[13]-offset, sizeof(cp));				aac_internal_transfer(scsicmd, cp, offset, len);			} while ((offset += len) < scsicmd->cmnd[13]);		}		/* Do not cache partition table for arrays */		scsicmd->device->removable = 1;		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;		scsicmd->scsi_done(scsicmd);		return 0;	}	case READ_CAPACITY:	{		u32 capacity;		char cp[8];		dprintk((KERN_DEBUG "READ CAPACITY command.\n"));		if (fsa_dev_ptr[cid].size <= 0x100000000ULL)			capacity = fsa_dev_ptr[cid].size - 1;		else			capacity = (u32)-1;		cp[0] = (capacity >> 24) & 0xff;		cp[1] = (capacity >> 16) & 0xff;		cp[2] = (capacity >> 8) & 0xff;		cp[3] = (capacity >> 0) & 0xff;		cp[4] = 0;		cp[5] = 0;		cp[6] = 2;		cp[7] = 0;		aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));		/* Do not cache partition table for arrays */		scsicmd->device->removable = 1;		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;		scsicmd->scsi_done(scsicmd);		return 0;	}	case MODE_SENSE:	{		char mode_buf[4];		dprintk((KERN_DEBUG "MODE SENSE command.\n"));		mode_buf[0] = 3;	/* Mode data length */		mode_buf[1] = 0;	/* Medium type - default */		mode_buf[2] = 0;	/* Device-specific param, bit 8: 0/1 = write enabled/protected */		mode_buf[3] = 0;	/* Block descriptor length */		aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;		scsicmd->scsi_done(scsicmd);		return 0;	}	case MODE_SENSE_10:	{		char mode_buf[8];		dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));		mode_buf[0] = 0;	/* Mode data length (MSB) */		mode_buf[1] = 6;	/* Mode data length (LSB) */		mode_buf[2] = 0;	/* Medium type - default */		mode_buf[3] = 0;	/* Device-specific param, bit 8: 0/1 = write enabled/protected */		mode_buf[4] = 0;	/* reserved */		mode_buf[5] = 0;	/* reserved */		mode_buf[6] = 0;	/* Block descriptor length (MSB) */		mode_buf[7] = 0;	/* Block descriptor length (LSB) */		aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;		scsicmd->scsi_done(scsicmd);		return 0;	}	case REQUEST_SENSE:		dprintk((KERN_DEBUG "REQUEST SENSE command.\n"));		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, sizeof (struct sense_data));		memset(&dev->fsa_dev[cid].sense_data, 0, sizeof (struct sense_data));		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;		scsicmd->scsi_done(scsicmd);		return 0;	case ALLOW_MEDIUM_REMOVAL:		dprintk((KERN_DEBUG "LOCK command.\n"));		if (scsicmd->cmnd[4])			fsa_dev_ptr[cid].locked = 1;		else			fsa_dev_ptr[cid].locked = 0;		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;		scsicmd->scsi_done(scsicmd);		return 0;	/*	 *	These commands are all No-Ops	 */	case TEST_UNIT_READY:	case RESERVE:	case RELEASE:	case REZERO_UNIT:	case REASSIGN_BLOCKS:	case SEEK_10:	case START_STOP:		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;		scsicmd->scsi_done(scsicmd);		return 0;	}	switch (scsicmd->cmnd[0]) 	{		case READ_6:		case READ_10:		case READ_12:		case READ_16:			/*			 *	Hack to keep track of ordinal number of the device that			 *	corresponds to a container. Needed to convert			 *	containers to /dev/sd device names			 */			 			spin_unlock_irq(host->host_lock);			if (scsicmd->request->rq_disk)				strlcpy(fsa_dev_ptr[cid].devname,				scsicmd->request->rq_disk->disk_name,			  	min(sizeof(fsa_dev_ptr[cid].devname),				sizeof(scsicmd->request->rq_disk->disk_name) + 1));			ret = aac_read(scsicmd, cid);			spin_lock_irq(host->host_lock);			return ret;		case WRITE_6:		case WRITE_10:		case WRITE_12:		case WRITE_16:			spin_unlock_irq(host->host_lock);			ret = aac_write(scsicmd, cid);			spin_lock_irq(host->host_lock);			return ret;		case SYNCHRONIZE_CACHE:			/* Issue FIB to tell Firmware to flush it's cache */			return aac_synchronize(scsicmd, cid);					default:			/*			 *	Unhandled commands			 */			dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]));			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;			set_sense((u8 *) &dev->fsa_dev[cid].sense_data,				ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,				ASENCODE_INVALID_COMMAND, 0, 0, 0, 0);			memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,			  (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))			    ? sizeof(scsicmd->sense_buffer)

⌨️ 快捷键说明

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