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

📄 aachba.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 3 页
字号:
 * * Arguments: [1] pointer to void [1] int * * Purpose: Sets SCSI inquiry data strings for vendor, product * and revision level. Allows strings to be set in platform dependant * files instead of in OS dependant driver source. */static void setinqstr(int devtype, void *data, int tindex){	struct scsi_inq *str;	char *findit;	struct aac_driver_ident *mp;	extern struct aac_driver_ident aac_drivers[];	/* HACK FIXME */	mp = &aac_drivers[devtype];   	str = (struct scsi_inq *)(data); /* cast data to scsi inq block */	inqstrcpy (mp->vname, str->vid); 	inqstrcpy (mp->model, str->pid); /* last six chars reserved for vol type */	findit = str->pid;	for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */		findit++;		if (tindex < (sizeof(container_types)/sizeof(char *))){		inqstrcpy (container_types[tindex], findit);	}	inqstrcpy ("0001", str->prl);}void set_sense(char *sense_buf, u8 sense_key, u8 sense_code,		    u8 a_sense_code, u8 incorrect_length,		    u8 bit_pointer, unsigned field_pointer,		    unsigned long residue){	sense_buf[0] = 0xF0;	/* Sense data valid, err code 70h (current error) */	sense_buf[1] = 0;	/* Segment number, always zero */	if (incorrect_length) {		sense_buf[2] = sense_key | 0x20;	/* Set the ILI bit | sense key */		sense_buf[3] = BYTE3(residue);		sense_buf[4] = BYTE2(residue);		sense_buf[5] = BYTE1(residue);		sense_buf[6] = BYTE0(residue);	} else		sense_buf[2] = sense_key;	/* Sense key */	if (sense_key == SENKEY_ILLEGAL)		sense_buf[7] = 10;	/* Additional sense length */	else		sense_buf[7] = 6;	/* Additional sense length */	sense_buf[12] = sense_code;	/* Additional sense code */	sense_buf[13] = a_sense_code;	/* Additional sense code qualifier */	if (sense_key == SENKEY_ILLEGAL) {		sense_buf[15] = 0;		if (sense_code == SENCODE_INVALID_PARAM_FIELD)			sense_buf[15] = 0x80;	/* Std sense key specific field */		/* Illegal parameter is in the parameter block */		if (sense_code == SENCODE_INVALID_CDB_FIELD)			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(Scsi_Cmnd * scsicmd){	unsigned long cpu_flags;	spin_lock_irqsave(&io_request_lock, cpu_flags);	scsicmd->scsi_done(scsicmd);	spin_unlock_irqrestore(&io_request_lock, cpu_flags);}static void __aac_io_done(Scsi_Cmnd * scsicmd){	scsicmd->scsi_done(scsicmd);}static void read_callback(void *context, struct fib * fibptr){	struct aac_dev *dev;	struct aac_read_reply *readreply;	Scsi_Cmnd *scsicmd;	unsigned long lba;	int cid;	scsicmd = (Scsi_Cmnd *) context;	dev = (struct aac_dev *)scsicmd->host->hostdata;	cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];	dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %ld, 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,			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));	else if(scsicmd->request_bufflen)		pci_unmap_single(dev->pdev, (u32)scsicmd->SCp.ptr, scsicmd->request_bufflen,				scsi_to_pci_dma_dir(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 | GOOD;	else {		printk(KERN_WARNING "read_callback: read failed, status = %d\n", readreply->status);		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;		set_sense((char *) &sense_data[cid],				    SENKEY_HW_ERR,				    SENCODE_INTERNAL_TARGET_FAILURE,				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,				    0, 0);	}	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;	Scsi_Cmnd *scsicmd;	unsigned long lba;	int cid;	scsicmd = (Scsi_Cmnd *) context;	dev = (struct aac_dev *)scsicmd->host->hostdata;	cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun);	lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3];	dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %ld, 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,			scsi_to_pci_dma_dir(scsicmd->sc_data_direction));	else if(scsicmd->request_bufflen)		pci_unmap_single(dev->pdev, (u32)scsicmd->SCp.ptr, scsicmd->request_bufflen,			scsi_to_pci_dma_dir(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 | GOOD;	else {		printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status);		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;		set_sense((char *) &sense_data[cid],				    SENKEY_HW_ERR,				    SENCODE_INTERNAL_TARGET_FAILURE,				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,				    0, 0);	}	fib_complete(fibptr);	fib_free(fibptr);	aac_io_done(scsicmd);}int aac_read(Scsi_Cmnd * scsicmd, int cid){	unsigned long lba;	unsigned long count;	unsigned long byte_count = 0;	int status;	struct aac_read *readcmd;	u16 fibsize;	struct aac_dev *dev;	struct fib * cmd_fibcontext;	dev = (struct aac_dev *)scsicmd->host->hostdata;	/*	 *	Get block address and transfer length	 */	if (scsicmd->cmnd[0] == SS_READ)	/* 6 byte command */	{		dprintk((KERN_DEBUG "aachba: received a read(6) command on target %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 target %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 = %lu, t = %ld.\n", smp_processor_id(), lba, jiffies));	/*	 *	Alocate and initialize a Fib	 */	if (!(cmd_fibcontext = fib_alloc(dev))) {		scsicmd->result = DID_ERROR << 16;		aac_io_done(scsicmd);		return (-1);	}	fib_init(cmd_fibcontext);	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);	readcmd->sg.count = cpu_to_le32(1);	if (count * 512 > (64 * 1024))		BUG();	/*	 *	Build Scatter/Gather list	 */	if (scsicmd->use_sg)	/* use scatter/gather list */	{		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));					byte_count = 0;		for (i = 0; i < sg_count; i++) {			readcmd->sg.sg[i].addr = cpu_to_le32(sg_dma_address(sg));			readcmd->sg.sg[i].count = cpu_to_le32(sg_dma_len(sg));			byte_count += sg->length;			if (sg->length > (64 * 1024))				BUG();			sg++;		}		readcmd->sg.count = cpu_to_le32(sg_count);		if (sg_count > MAX_DRIVER_SG_SEGMENT_COUNT)			BUG();	}	else if(scsicmd->request_bufflen)	{		u32 addr;		addr = pci_map_single(dev->pdev, scsicmd->request_buffer,				scsicmd->request_bufflen, scsi_to_pci_dma_dir(scsicmd->sc_data_direction));		scsicmd->SCp.ptr = (void *)addr;		readcmd->sg.sg[0].addr = cpu_to_le32(addr);		readcmd->sg.sg[0].count = cpu_to_le32(scsicmd->request_bufflen);		byte_count = scsicmd->request_bufflen;		if (byte_count > (64 * 1024))			BUG();	}	if (byte_count != readcmd->count)		BUG();	/*	 *	Now send the Fib to the adapter	 */	fibsize = sizeof(struct aac_read) + ((readcmd->sg.count - 1) * sizeof (struct sgentry));	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) 		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 | QUEUE_FULL;	aac_io_done(scsicmd);	fib_complete(cmd_fibcontext);	fib_free(cmd_fibcontext);	return -1;}static int aac_write(Scsi_Cmnd * scsicmd, int cid){	unsigned long lba;	unsigned long count;	unsigned long byte_count = 0;	int status;	struct aac_write *writecmd;	u16 fibsize;	struct aac_dev *dev;	struct fib * cmd_fibcontext;	dev = (struct aac_dev *)scsicmd->host->hostdata;	/*	 *	Get block address and transfer length	 */	if (scsicmd->cmnd[0] == SS_WRITE)	/* 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 target %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 = %lu, 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);	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);	/* FIXME: why isnt ->stable setup */	if (count * 512 > (64 * 1024)) {		BUG();	}	/*	 *	Build Scatter/Gather list	 */	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));		byte_count = 0;		for (i = 0; i < scsicmd->use_sg; i++) {			writecmd->sg.sg[i].addr = cpu_to_le32(sg_dma_address(sg));			writecmd->sg.sg[i].count = cpu_to_le32(sg_dma_len(sg));			byte_count += sg->length;			if (sg->length > (64 * 1024))				BUG();			sg++;		}		writecmd->sg.count = cpu_to_le32(sg_count);		if (sg_count > MAX_DRIVER_SG_SEGMENT_COUNT)			BUG();	}	else if(scsicmd->request_bufflen)	{		u32 addr; 		addr = pci_map_single(dev->pdev,				scsicmd->request_buffer,				scsicmd->request_bufflen,				scsi_to_pci_dma_dir(scsicmd->sc_data_direction));

⌨️ 快捷键说明

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