aachba.c

来自「linux 内核源代码」· C语言 代码 · 共 2,197 行 · 第 1/5 页

C
2,197
字号
	/*	 * If the firmware supports ROMB RAID/SCSI mode and we are currently	 * in RAID/SCSI mode, set the flag. For now if in this mode we will	 * force nondasd support on. If we decide to allow the non-dasd flag	 * additional changes changes will have to be made to support	 * RAID/SCSI.  the function aac_scsi_cmd in this module will have to be	 * changed to support the new dev->raid_scsi_mode flag instead of	 * leaching off of the dev->nondasd_support flag. Also in linit.c the	 * function aac_detect will have to be modified where it sets up the	 * max number of channels based on the aac->nondasd_support flag only.	 */	if ((dev->adapter_info.options & AAC_OPT_SCSI_MANAGED) &&	    (dev->adapter_info.options & AAC_OPT_RAID_SCSI_MODE)) {		dev->nondasd_support = 1;		dev->raid_scsi_mode = 1;	}	if (dev->raid_scsi_mode != 0)		printk(KERN_INFO "%s%d: ROMB RAID/SCSI mode enabled\n",				dev->name, dev->id);			if(nondasd != -1) {  		dev->nondasd_support = (nondasd!=0);	}	if(dev->nondasd_support != 0){		printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);	}	dev->dac_support = 0;	if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){		printk(KERN_INFO "%s%d: 64bit support enabled.\n", dev->name, dev->id);		dev->dac_support = 1;	}	if(dacmode != -1) {		dev->dac_support = (dacmode!=0);	}	if(dev->dac_support != 0) {		if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&			!pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {			printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n",				dev->name, dev->id);		} else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) &&			!pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) {			printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n",				dev->name, dev->id);			dev->dac_support = 0;		} else {			printk(KERN_WARNING"%s%d: No suitable DMA available.\n",				dev->name, dev->id);			rcode = -ENOMEM;		}	}	/* 	 * Deal with configuring for the individualized limits of each packet	 * interface.	 */	dev->a_ops.adapter_scsi = (dev->dac_support)				? aac_scsi_64				: aac_scsi_32;	if (dev->raw_io_interface) {		dev->a_ops.adapter_bounds = (dev->raw_io_64)					? aac_bounds_64					: aac_bounds_32;		dev->a_ops.adapter_read = aac_read_raw_io;		dev->a_ops.adapter_write = aac_write_raw_io;	} else {		dev->a_ops.adapter_bounds = aac_bounds_32;		dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -			sizeof(struct aac_fibhdr) -			sizeof(struct aac_write) + sizeof(struct sgentry)) /				sizeof(struct sgentry);		if (dev->dac_support) {			dev->a_ops.adapter_read = aac_read_block64;			dev->a_ops.adapter_write = aac_write_block64;			/* 			 * 38 scatter gather elements 			 */			dev->scsi_host_ptr->sg_tablesize =				(dev->max_fib_size -				sizeof(struct aac_fibhdr) -				sizeof(struct aac_write64) +				sizeof(struct sgentry64)) /					sizeof(struct sgentry64);		} else {			dev->a_ops.adapter_read = aac_read_block;			dev->a_ops.adapter_write = aac_write_block;		}		dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;		if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {			/*			 * Worst case size that could cause sg overflow when			 * we break up SG elements that are larger than 64KB.			 * Would be nice if we could tell the SCSI layer what			 * the maximum SG element size can be. Worst case is			 * (sg_tablesize-1) 4KB elements with one 64KB			 * element.			 *	32bit -> 468 or 238KB	64bit -> 424 or 212KB			 */			dev->scsi_host_ptr->max_sectors =			  (dev->scsi_host_ptr->sg_tablesize * 8) + 112;		}	}	aac_fib_complete(fibptr);	aac_fib_free(fibptr);	return rcode;}static void io_callback(void *context, struct fib * fibptr){	struct aac_dev *dev;	struct aac_read_reply *readreply;	struct scsi_cmnd *scsicmd;	u32 cid;	scsicmd = (struct scsi_cmnd *) context;	if (!aac_valid_context(scsicmd, fibptr))		return;	dev = fibptr->dev;	cid = scmd_id(scsicmd);	if (nblank(dprintk(x))) {		u64 lba;		switch (scsicmd->cmnd[0]) {		case WRITE_6:		case READ_6:			lba = ((scsicmd->cmnd[1] & 0x1F) << 16) |			    (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];			break;		case WRITE_16:		case READ_16:			lba = ((u64)scsicmd->cmnd[2] << 56) |			      ((u64)scsicmd->cmnd[3] << 48) |			      ((u64)scsicmd->cmnd[4] << 40) |			      ((u64)scsicmd->cmnd[5] << 32) |			      ((u64)scsicmd->cmnd[6] << 24) |			      (scsicmd->cmnd[7] << 16) |			      (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];			break;		case WRITE_12:		case READ_12:			lba = ((u64)scsicmd->cmnd[2] << 24) |			      (scsicmd->cmnd[3] << 16) |			      (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];			break;		default:			lba = ((u64)scsicmd->cmnd[2] << 24) |			       (scsicmd->cmnd[3] << 16) |			       (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];			break;		}		printk(KERN_DEBUG		  "io_callback[cpu %d]: lba = %llu, t = %ld.\n",		  smp_processor_id(), (unsigned long long)lba, jiffies);	}	BUG_ON(fibptr == NULL);	scsi_dma_unmap(scsicmd);	readreply = (struct aac_read_reply *)fib_data(fibptr);	if (le32_to_cpu(readreply->status) == ST_OK)		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;	else {#ifdef AAC_DETAILED_STATUS_INFO		printk(KERN_WARNING "io_callback: io failed, status = %d\n",		  le32_to_cpu(readreply->status));#endif		scsicmd->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(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));	}	aac_fib_complete(fibptr);	aac_fib_free(fibptr);	scsicmd->scsi_done(scsicmd);}static int aac_read(struct scsi_cmnd * scsicmd){	u64 lba;	u32 count;	int status;	struct aac_dev *dev;	struct fib * cmd_fibcontext;	dev = (struct aac_dev *)scsicmd->device->host->hostdata;	/*	 *	Get block address and transfer length	 */	switch (scsicmd->cmnd[0]) {	case READ_6:		dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", scmd_id(scsicmd)));		lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | 			(scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];		count = scsicmd->cmnd[4];		if (count == 0)			count = 256;		break;	case READ_16:		dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", scmd_id(scsicmd)));		lba = 	((u64)scsicmd->cmnd[2] << 56) |		 	((u64)scsicmd->cmnd[3] << 48) |			((u64)scsicmd->cmnd[4] << 40) |			((u64)scsicmd->cmnd[5] << 32) |			((u64)scsicmd->cmnd[6] << 24) | 			(scsicmd->cmnd[7] << 16) |			(scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];		count = (scsicmd->cmnd[10] << 24) | 			(scsicmd->cmnd[11] << 16) |			(scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];		break;	case READ_12:		dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", scmd_id(scsicmd)));		lba = ((u64)scsicmd->cmnd[2] << 24) | 			(scsicmd->cmnd[3] << 16) |		    	(scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];		count = (scsicmd->cmnd[6] << 24) | 			(scsicmd->cmnd[7] << 16) |		      	(scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];		break;	default:		dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", scmd_id(scsicmd)));		lba = ((u64)scsicmd->cmnd[2] << 24) | 			(scsicmd->cmnd[3] << 16) | 			(scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];		break;	}	dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",	  smp_processor_id(), (unsigned long long)lba, jiffies));	if (aac_adapter_bounds(dev,scsicmd,lba))		return 0;	/*	 *	Alocate and initialize a Fib	 */	if (!(cmd_fibcontext = aac_fib_alloc(dev))) {		return -1;	}	status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);	/*	 *	Check that the command queued to the controller	 */	if (status == -EINPROGRESS) {		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;		return 0;	}			printk(KERN_WARNING "aac_read: aac_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);	aac_fib_complete(cmd_fibcontext);	aac_fib_free(cmd_fibcontext);	return 0;}static int aac_write(struct scsi_cmnd * scsicmd){	u64 lba;	u32 count;	int fua;	int status;	struct aac_dev *dev;	struct fib * cmd_fibcontext;	dev = (struct aac_dev *)scsicmd->device->host->hostdata;	/*	 *	Get block address and transfer length	 */	if (scsicmd->cmnd[0] == WRITE_6)	/* 6 byte command */	{		lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];		count = scsicmd->cmnd[4];		if (count == 0)			count = 256;		fua = 0;	} else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */		dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd)));		lba = 	((u64)scsicmd->cmnd[2] << 56) |			((u64)scsicmd->cmnd[3] << 48) |			((u64)scsicmd->cmnd[4] << 40) |			((u64)scsicmd->cmnd[5] << 32) |			((u64)scsicmd->cmnd[6] << 24) | 			(scsicmd->cmnd[7] << 16) |			(scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];		count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |			(scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];		fua = scsicmd->cmnd[1] & 0x8;	} else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */		dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd)));		lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16)		    | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];		count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)		      | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];		fua = scsicmd->cmnd[1] & 0x8;	} else {		dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd)));		lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];		fua = scsicmd->cmnd[1] & 0x8;	}	dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",	  smp_processor_id(), (unsigned long long)lba, jiffies));	if (aac_adapter_bounds(dev,scsicmd,lba))		return 0;	/*	 *	Allocate and initialize a Fib then setup a BlockWrite command	 */	if (!(cmd_fibcontext = aac_fib_alloc(dev))) {		scsicmd->result = DID_ERROR << 16;		scsicmd->scsi_done(scsicmd);		return 0;	}	status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);	/*	 *	Check that the command queued to the controller	 */	if (status == -EINPROGRESS) {		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;		return 0;	}	printk(KERN_WARNING "aac_write: aac_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);	aac_fib_complete(cmd_fibcontext);	aac_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;	if (!aac_valid_context(cmd, fibptr))		return;	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 = fibptr->dev;		u32 cid = sdev_id(sdev);		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)));	}	aac_fib_complete(fibptr);	aac_fib_free(fibptr);	cmd->scsi_done(cmd);}static int aac_synchronize(struct scsi_cmnd *scsicmd){	int status;	struct fib *cmd_fibcontext;	struct aac_synchronize *synchronizecmd;	struct scsi_cmnd *cmd;	struct scsi_device *sdev = scsicmd->device;	int active = 0;	struct aac_dev *aac;	u64 lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) |		(scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];	u32 count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];	unsigned long flags;	/*	 * Wait for all outstanding queued 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->SCp.phase == AAC_OWNER_FIRMWARE) {			u64 cmnd_lba;			u32 cmnd_count;			if (cmd->cmnd[0] == WRITE_6) {				cmnd_lba = ((cmd->cmnd[1] & 0x1F) << 16) |					(cmd->cmnd[2] << 8) |					cmd->cmnd[3];				cmnd_count = cmd->cmnd[4];				if (cmnd_count == 0)					cmnd_count = 256;			} else if (cmd->cmnd[0] == WRITE_16) {				cmnd_lba = ((u64)cmd->cmnd[2] << 56) |					((u64)cmd->cmnd[3] << 48) |					((u64)cmd->cmnd[4] << 40) |					((u64)cmd->cmnd[5] << 32) |					((u64)cmd->cmnd[6] << 24) |

⌨️ 快捷键说明

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