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

📄 aachba.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data));	status = fib_send(ContainerCommand, 		  cmd_fibcontext, 		  sizeof (struct aac_get_name),		  FsaNormal, 		  0, 1, 		  (fib_callback) get_container_name_callback, 		  (void *) scsicmd);		/*	 *	Check that the command queued to the controller	 */	if (status == -EINPROGRESS) 		return 0;			printk(KERN_WARNING "aac_get_container_name: fib_send failed with status: %d.\n", status);	fib_complete(cmd_fibcontext);	fib_free(cmd_fibcontext);	return -1;}/** *	probe_container		-	query a logical volume *	@dev: device to query *	@cid: container identifier * *	Queries the controller about the given volume. The volume information *	is updated in the struct fsa_dev_info structure rather than returned. */ int probe_container(struct aac_dev *dev, int cid){	struct fsa_dev_info *fsa_dev_ptr;	int status;	struct aac_query_mount *dinfo;	struct aac_mount *dresp;	struct fib * fibptr;	unsigned instance;	fsa_dev_ptr = dev->fsa_dev;	instance = dev->scsi_host_ptr->unique_id;	if (!(fibptr = fib_alloc(dev)))		return -ENOMEM;	fib_init(fibptr);	dinfo = (struct aac_query_mount *)fib_data(fibptr);	dinfo->command = cpu_to_le32(VM_NameServe);	dinfo->count = cpu_to_le32(cid);	dinfo->type = cpu_to_le32(FT_FILESYS);	status = fib_send(ContainerCommand,			    fibptr,			    sizeof(struct aac_query_mount),			    FsaNormal,			    1, 1,			    NULL, NULL);	if (status < 0) {		printk(KERN_WARNING "aacraid: probe_container query failed.\n");		goto error;	}	dresp = (struct aac_mount *) fib_data(fibptr);	if ((le32_to_cpu(dresp->status) == ST_OK) &&	    (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) {		dinfo->command = cpu_to_le32(VM_NameServe64);		dinfo->count = cpu_to_le32(cid);		dinfo->type = cpu_to_le32(FT_FILESYS);		if (fib_send(ContainerCommand,			    fibptr,			    sizeof(struct aac_query_mount),			    FsaNormal,			    1, 1,			    NULL, NULL) < 0)			goto error;	} else		dresp->mnt[0].capacityhigh = 0;	if ((le32_to_cpu(dresp->status) == ST_OK) &&	    (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) &&	    (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) {		fsa_dev_ptr[cid].valid = 1;		fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol);		fsa_dev_ptr[cid].size		  = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) +		    (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32);		if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY)			fsa_dev_ptr[cid].ro = 1;	}error:	fib_complete(fibptr);	fib_free(fibptr);	return status;}/* Local Structure to set SCSI inquiry data strings */struct scsi_inq {	char vid[8];         /* Vendor ID */	char pid[16];        /* Product ID */	char prl[4];         /* Product Revision Level */};/** *	InqStrCopy	-	string merge *	@a:	string to copy from *	@b:	string to copy to * * 	Copy a String from one location to another *	without copying \0 */static void inqstrcpy(char *a, char *b){	while(*a != (char)0) 		*b++ = *a++;}static char *container_types[] = {        "None",        "Volume",        "Mirror",        "Stripe",        "RAID5",        "SSRW",        "SSRO",        "Morph",        "Legacy",        "RAID4",        "RAID10",                     "RAID00",                     "V-MIRRORS",                  "PSEUDO R4",          	"RAID50",	"RAID5D",	"RAID5D0",	"RAID1E",	"RAID6",	"RAID60",        "Unknown"};/* Function: setinqstr * * 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(struct aac_dev *dev, void *data, int tindex){	struct scsi_inq *str;	str = (struct scsi_inq *)(data); /* cast data to scsi inq block */	memset(str, ' ', sizeof(*str));	if (dev->supplement_adapter_info.AdapterTypeText[0]) {		char * cp = dev->supplement_adapter_info.AdapterTypeText;		int c = sizeof(str->vid);		while (*cp && *cp != ' ' && --c)			++cp;		c = *cp;		*cp = '\0';		inqstrcpy (dev->supplement_adapter_info.AdapterTypeText,		  str->vid); 		*cp = c;		while (*cp && *cp != ' ')			++cp;		while (*cp == ' ')			++cp;		/* last six chars reserved for vol type */		c = 0;		if (strlen(cp) > sizeof(str->pid)) {			c = cp[sizeof(str->pid)];			cp[sizeof(str->pid)] = '\0';		}		inqstrcpy (cp, str->pid);		if (c)			cp[sizeof(str->pid)] = c;	} else {		struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);   		inqstrcpy (mp->vname, str->vid); 		/* last six chars reserved for vol type */		inqstrcpy (mp->model, str->pid);	}	if (tindex < (sizeof(container_types)/sizeof(char *))){		char *findit = str->pid;		for ( ; *findit != ' '; findit++); /* walk till we find a space */		/* RAID is superfluous in the context of a RAID device */		if (memcmp(findit-4, "RAID", 4) == 0)			*(findit -= 4) = ' ';		if (((findit - str->pid) + strlen(container_types[tindex]))		 < (sizeof(str->pid) + sizeof(str->prl)))			inqstrcpy (container_types[tindex], findit + 1);	}	inqstrcpy ("V1.0", str->prl);}static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,		      u8 a_sense_code, u8 incorrect_length,		      u8 bit_pointer, u16 field_pointer,		      u32 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 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 == ILLEGAL_REQUEST)		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 == ILLEGAL_REQUEST) {		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 */	}}int aac_get_adapter_info(struct aac_dev* dev){	struct fib* fibptr;	int rcode;	u32 tmp;	struct aac_adapter_info *info;	struct aac_bus_info *command;	struct aac_bus_info_response *bus_info;	if (!(fibptr = fib_alloc(dev)))		return -ENOMEM;	fib_init(fibptr);	info = (struct aac_adapter_info *) fib_data(fibptr);	memset(info,0,sizeof(*info));	rcode = fib_send(RequestAdapterInfo,			 fibptr, 			 sizeof(*info),			 FsaNormal, 			 -1, 1, /* First `interrupt' command uses special wait */			 NULL, 			 NULL);	if (rcode < 0) {		fib_complete(fibptr);		fib_free(fibptr);		return rcode;	}	memcpy(&dev->adapter_info, info, sizeof(*info));	if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {		struct aac_supplement_adapter_info * info;		fib_init(fibptr);		info = (struct aac_supplement_adapter_info *) fib_data(fibptr);		memset(info,0,sizeof(*info));		rcode = fib_send(RequestSupplementAdapterInfo,				 fibptr,				 sizeof(*info),				 FsaNormal,				 1, 1,				 NULL,				 NULL);		if (rcode >= 0)			memcpy(&dev->supplement_adapter_info, info, sizeof(*info));	}	/* 	 * GetBusInfo 	 */	fib_init(fibptr);	bus_info = (struct aac_bus_info_response *) fib_data(fibptr);	memset(bus_info, 0, sizeof(*bus_info));	command = (struct aac_bus_info *)bus_info;	command->Command = cpu_to_le32(VM_Ioctl);	command->ObjType = cpu_to_le32(FT_DRIVE);	command->MethodId = cpu_to_le32(1);	command->CtlCmd = cpu_to_le32(GetBusInfo);	rcode = fib_send(ContainerCommand,			 fibptr,			 sizeof (*bus_info),			 FsaNormal,			 1, 1,			 NULL, NULL);	if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) {		dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus);		dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);	}	tmp = le32_to_cpu(dev->adapter_info.kernelrev);	printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", 			dev->name, 			dev->id,			tmp>>24,			(tmp>>16)&0xff,			tmp&0xff,			le32_to_cpu(dev->adapter_info.kernelbuild),			(int)sizeof(dev->supplement_adapter_info.BuildDate),			dev->supplement_adapter_info.BuildDate);	tmp = le32_to_cpu(dev->adapter_info.monitorrev);	printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", 			dev->name, dev->id,			tmp>>24,(tmp>>16)&0xff,tmp&0xff,			le32_to_cpu(dev->adapter_info.monitorbuild));	tmp = le32_to_cpu(dev->adapter_info.biosrev);	printk(KERN_INFO "%s%d: bios %d.%d-%d[%d]\n", 			dev->name, dev->id,			tmp>>24,(tmp>>16)&0xff,tmp&0xff,			le32_to_cpu(dev->adapter_info.biosbuild));	if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)		printk(KERN_INFO "%s%d: serial %x\n",			dev->name, dev->id,			le32_to_cpu(dev->adapter_info.serial[0]));	dev->nondasd_support = 0;	dev->raid_scsi_mode = 0;	if(dev->adapter_info.options & AAC_OPT_NONDASD){		dev->nondasd_support = 1;	}	/*	 * 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;		}	}	/* 	 * 57 scatter gather elements 	 */	if (!(dev->raw_io_interface)) {		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) {			/* 			 * 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);		}		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.

⌨️ 快捷键说明

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