aachba.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 1,659 行 · 第 1/4 页

C
1,659
字号
			sense_buf[15] = 0xc0;/* Std sense key specific field */		/* Illegal parameter is in the CDB block */		sense_buf[15] |= bit_pointer;		sense_buf[16] = field_pointer >> 8;	/* MSB */		sense_buf[17] = field_pointer;		/* LSB */	}}static void aac_io_done(struct scsi_cmnd * scsicmd){	unsigned long cpu_flags;	struct Scsi_Host *host = scsicmd->device->host;	spin_lock_irqsave(host->host_lock, cpu_flags);	scsicmd->scsi_done(scsicmd);	spin_unlock_irqrestore(host->host_lock, cpu_flags);}static void __aac_io_done(struct scsi_cmnd * scsicmd){	scsicmd->scsi_done(scsicmd);}int aac_get_adapter_info(struct aac_dev* dev){	struct fib* fibptr;	struct aac_adapter_info* info;	int rcode;	u32 tmp;	if (!(fibptr = fib_alloc(dev)))		return -ENOMEM;	fib_init(fibptr);	info = (struct aac_adapter_info*) fib_data(fibptr);	memset(info,0,sizeof(struct aac_adapter_info));	rcode = fib_send(RequestAdapterInfo,			fibptr, 			sizeof(struct aac_adapter_info),			FsaNormal, 			1, 1, 			NULL, 			NULL);	memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info));	tmp = dev->adapter_info.kernelrev;	printk(KERN_INFO"%s%d: kernel %d.%d.%d build %d\n", 			dev->name, dev->id,			tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff,			dev->adapter_info.kernelbuild);	tmp = dev->adapter_info.monitorrev;	printk(KERN_INFO"%s%d: monitor %d.%d.%d build %d\n", 			dev->name, dev->id,			tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff,			dev->adapter_info.monitorbuild);	tmp = dev->adapter_info.biosrev;	printk(KERN_INFO"%s%d: bios %d.%d.%d build %d\n", 			dev->name, dev->id,			tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff,			dev->adapter_info.biosbuild);	printk(KERN_INFO"%s%d: serial %x%x\n",			dev->name, dev->id,			dev->adapter_info.serial[0],			dev->adapter_info.serial[1]);	dev->nondasd_support = 0;	if(dev->adapter_info.options & AAC_OPT_NONDASD){//		dev->nondasd_support = 1;// dmb - temporarily disable nondasd	}	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->pae_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->pae_support = 1;	}	if(paemode != -1){		dev->pae_support = (paemode!=0);	}	if(dev->pae_support != 0) {		printk(KERN_INFO"%s%d: 64 Bit PAE enabled\n", dev->name, dev->id);		pci_set_dma_mask(dev->pdev, (dma_addr_t)0xFFFFFFFFFFFFFFFFULL);	}	fib_complete(fibptr);	fib_free(fibptr);	return rcode;}static void read_callback(void *context, struct fib * fibptr){	struct aac_dev *dev;	struct aac_read_reply *readreply;	struct scsi_cmnd *scsicmd;	u32 lba;	u32 cid;	scsicmd = (struct scsi_cmnd *) context;	dev = (struct aac_dev *)scsicmd->device->host->hostdata;	cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];	dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));	if (fibptr == NULL)		BUG();			if(scsicmd->use_sg)		pci_unmap_sg(dev->pdev, 			(struct scatterlist *)scsicmd->buffer,			scsicmd->use_sg,			scsicmd->sc_data_direction);	else if(scsicmd->request_bufflen)		pci_unmap_single(dev->pdev, (dma_addr_t)(ulong)scsicmd->SCp.ptr,				 scsicmd->request_bufflen,				 scsicmd->sc_data_direction);	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 {		printk(KERN_WARNING "read_callback: read failed, status = %d\n", readreply->status);		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;		set_sense((u8 *) &sense_data[cid],				    HARDWARE_ERROR,				    SENCODE_INTERNAL_TARGET_FAILURE,				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,				    0, 0);		memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof(struct sense_data));	}	fib_complete(fibptr);	fib_free(fibptr);	aac_io_done(scsicmd);}static void write_callback(void *context, struct fib * fibptr){	struct aac_dev *dev;	struct aac_write_reply *writereply;	struct scsi_cmnd *scsicmd;	u32 lba;	u32 cid;	scsicmd = (struct scsi_cmnd *) context;	dev = (struct aac_dev *)scsicmd->device->host->hostdata;	cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];	dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));	if (fibptr == NULL)		BUG();	if(scsicmd->use_sg)		pci_unmap_sg(dev->pdev, 			(struct scatterlist *)scsicmd->buffer,			scsicmd->use_sg,			scsicmd->sc_data_direction);	else if(scsicmd->request_bufflen)		pci_unmap_single(dev->pdev, (dma_addr_t)(ulong)scsicmd->SCp.ptr,				 scsicmd->request_bufflen,				 scsicmd->sc_data_direction);	writereply = (struct aac_write_reply *) fib_data(fibptr);	if (le32_to_cpu(writereply->status) == ST_OK)		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;	else {		printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status);		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;		set_sense((u8 *) &sense_data[cid],				    HARDWARE_ERROR,				    SENCODE_INTERNAL_TARGET_FAILURE,				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,				    0, 0);		memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof(struct sense_data));	}	fib_complete(fibptr);	fib_free(fibptr);	aac_io_done(scsicmd);}int aac_read(struct scsi_cmnd * scsicmd, int cid){	u32 lba;	u32 count;	int status;	u16 fibsize;	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] == READ_6)	/* 6 byte command */	{		dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid));		lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];		count = scsicmd->cmnd[4];		if (count == 0)			count = 256;	} else {		dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid));		lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];	}	dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));	/*	 *	Alocate and initialize a Fib	 */	if (!(cmd_fibcontext = fib_alloc(dev))) {		return -1;	}	fib_init(cmd_fibcontext);	if(dev->pae_support == 1){		struct aac_read64 *readcmd;		readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);		readcmd->command = cpu_to_le32(VM_CtHostRead64);		readcmd->cid = cpu_to_le16(cid);		readcmd->sector_count = cpu_to_le16(count);		readcmd->block = cpu_to_le32(lba);		readcmd->pad   = cpu_to_le16(0);		readcmd->flags = cpu_to_le16(0); 		aac_build_sg64(scsicmd, &readcmd->sg);		if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)			BUG();		fibsize = sizeof(struct aac_read64) + ((readcmd->sg.count - 1) * sizeof (struct sgentry64));		/*		 *	Now send the Fib to the adapter		 */		status = fib_send(ContainerCommand64, 			  cmd_fibcontext, 			  fibsize, 			  FsaNormal, 			  0, 1, 			  (fib_callback) read_callback, 			  (void *) scsicmd);	} else {		struct aac_read *readcmd;		readcmd = (struct aac_read *) fib_data(cmd_fibcontext);		readcmd->command = cpu_to_le32(VM_CtBlockRead);		readcmd->cid = cpu_to_le32(cid);		readcmd->block = cpu_to_le32(lba);		readcmd->count = cpu_to_le32(count * 512);		if (count * 512 > (64 * 1024))			BUG();		aac_build_sg(scsicmd, &readcmd->sg);		if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)			BUG();		fibsize = sizeof(struct aac_read) + ((readcmd->sg.count - 1) * sizeof (struct sgentry));		/*		 *	Now send the Fib to the adapter		 */		status = fib_send(ContainerCommand, 			  cmd_fibcontext, 			  fibsize, 			  FsaNormal, 			  0, 1, 			  (fib_callback) read_callback, 			  (void *) scsicmd);	}		/*	 *	Check that the command queued to the controller	 */	if (status == -EINPROGRESS) 	{		dprintk("read queued.\n");		return 0;	}			printk(KERN_WARNING "aac_read: 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;	aac_io_done(scsicmd);	fib_complete(cmd_fibcontext);	fib_free(cmd_fibcontext);	return -1;}static int aac_write(struct scsi_cmnd * scsicmd, int cid){	u32 lba;	u32 count;	int status;	u16 fibsize;	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;	} else {		dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid));		lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];	}	dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));	/*	 *	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);	if(dev->pae_support == 1){		struct aac_write64 *writecmd;		writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext);		writecmd->command = cpu_to_le32(VM_CtHostWrite64);		writecmd->cid = cpu_to_le16(cid);		writecmd->sector_count = cpu_to_le16(count); 		writecmd->block = cpu_to_le32(lba);		writecmd->pad	= cpu_to_le16(0);		writecmd->flags	= cpu_to_le16(0);		aac_build_sg64(scsicmd, &writecmd->sg);		if(writecmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)			BUG();		fibsize = sizeof(struct aac_write64) + ((writecmd->sg.count - 1) * sizeof (struct sgentry64));		/*		 *	Now send the Fib to the adapter		 */		status = fib_send(ContainerCommand64, 			  cmd_fibcontext, 			  fibsize, 			  FsaNormal, 			  0, 1, 			  (fib_callback) write_callback, 			  (void *) scsicmd);	} else {		struct aac_write *writecmd;		writecmd = (struct aac_write *) fib_data(cmd_fibcontext);		writecmd->command = cpu_to_le32(VM_CtBlockWrite);		writecmd->cid = cpu_to_le32(cid);		writecmd->block = cpu_to_le32(lba);		writecmd->count = cpu_to_le32(count * 512);		writecmd->sg.count = cpu_to_le32(1);		/* ->stable is not used - it did mean which type of write */		if (count * 512 > (64 * 1024)) {			BUG();		}		aac_build_sg(scsicmd, &writecmd->sg);		if(writecmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT)			BUG();		fibsize = sizeof(struct aac_write) + ((writecmd->sg.count - 1) * sizeof (struct sgentry));		/*		 *	Now send the Fib to the adapter		 */		status = fib_send(ContainerCommand, 			  cmd_fibcontext, 			  fibsize, 			  FsaNormal, 			  0, 1, 			  (fib_callback) write_callback, 			  (void *) scsicmd);	}	/*	 *	Check that the command queued to the controller	 */	if (status == -EINPROGRESS)	{		dprintk("write queued.\n");		return 0;	}	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;	aac_io_done(scsicmd);	fib_complete(cmd_fibcontext);	fib_free(cmd_fibcontext);	return -1;}

⌨️ 快捷键说明

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