int i; 
static int cciss_ioctl(struct inode *inode, struct file *filep, 		unsigned int cmd, unsigned long arg){	struct block_device *bdev = inode->i_bdev;	struct gendisk *disk = bdev->bd_disk;	ctlr_info_t *host = get_host(disk);	drive_info_struct *drv = get_drv(disk);	int ctlr = host->ctlr;	void __user *argp = (void __user *)arg;#ifdef CCISS_DEBUG	printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);#endif /* CCISS_DEBUG */ 		switch(cmd) {	case HDIO_GETGEO:	{                struct hd_geometry driver_geo;                if (drv->cylinders) {                        driver_geo.heads = drv->heads;                        driver_geo.sectors = drv->sectors;                        driver_geo.cylinders = drv->cylinders;                } else			return -ENXIO;                driver_geo.start= get_start_sect(inode->i_bdev);                if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry)))                        return  -EFAULT;                return(0);	}	case CCISS_GETPCIINFO:	{		cciss_pci_info_struct pciinfo;		if (!arg) return -EINVAL;		pciinfo.domain = pci_domain_nr(host->pdev->bus);		pciinfo.bus = host->pdev->bus->number;		pciinfo.dev_fn = host->pdev->devfn;		pciinfo.board_id = host->board_id;		if (copy_to_user(argp, &pciinfo,  sizeof( cciss_pci_info_struct )))			return  -EFAULT;		return(0);	}		case CCISS_GETINTINFO:	{		cciss_coalint_struct intinfo;		if (!arg) return -EINVAL;		intinfo.delay = readl(&host->cfgtable->HostWrite.CoalIntDelay);		intinfo.count = readl(&host->cfgtable->HostWrite.CoalIntCount);		if (copy_to_user(argp, &intinfo, sizeof( cciss_coalint_struct )))			return -EFAULT;                return(0);        }	case CCISS_SETINTINFO:        {                cciss_coalint_struct intinfo;		unsigned long flags;		int i;		if (!arg) return -EINVAL;			if (!capable(CAP_SYS_ADMIN)) return -EPERM;		if (copy_from_user(&intinfo, argp, sizeof( cciss_coalint_struct)))			return -EFAULT;		if ( (intinfo.delay == 0 ) && (intinfo.count == 0))		{//			printk("cciss_ioctl: delay and count cannot be 0\n");			return( -EINVAL);		}		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);		/* Update the field, and then ring the doorbell */ 		writel( intinfo.delay, 			&(host->cfgtable->HostWrite.CoalIntDelay));		writel( intinfo.count,                         &(host->cfgtable->HostWrite.CoalIntCount));		writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {			if (!(readl(host->vaddr + SA5_DOORBELL) 					& CFGTBL_ChangeReq))				break;			/* delay and try again */			udelay(1000);		}			spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);		if (i >= MAX_IOCTL_CONFIG_WAIT)			return -EAGAIN;                return(0);        }	case CCISS_GETNODENAME:        {                NodeName_type NodeName;		int i; 		if (!arg) return -EINVAL;		for(i=0;i<16;i++)			NodeName[i] = readb(&host->cfgtable->ServerName[i]);                if (copy_to_user(argp, NodeName, sizeof( NodeName_type)))                	return  -EFAULT;                return(0);        }	case CCISS_SETNODENAME:	{		NodeName_type NodeName;		unsigned long flags;		int i;		if (!arg) return -EINVAL;		if (!capable(CAP_SYS_ADMIN)) return -EPERM;				if (copy_from_user(NodeName, argp, sizeof( NodeName_type)))			return -EFAULT;		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);			/* Update the field, and then ring the doorbell */ 		for(i=0;i<16;i++)			writeb( NodeName[i], &host->cfgtable->ServerName[i]);					writel( CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL);		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {			if (!(readl(host->vaddr + SA5_DOORBELL) 					& CFGTBL_ChangeReq))				break;			/* delay and try again */			udelay(1000);		}			spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);		if (i >= MAX_IOCTL_CONFIG_WAIT)			return -EAGAIN;                return(0);        }	case CCISS_GETHEARTBEAT:        {                Heartbeat_type heartbeat;		if (!arg) return -EINVAL;                heartbeat = readl(&host->cfgtable->HeartBeat);                if (copy_to_user(argp, &heartbeat, sizeof( Heartbeat_type)))                	return -EFAULT;                return(0);        }	case CCISS_GETBUSTYPES:        {                BusTypes_type BusTypes;		if (!arg) return -EINVAL;                BusTypes = readl(&host->cfgtable->BusTypes);                if (copy_to_user(argp, &BusTypes, sizeof( BusTypes_type) ))                	return  -EFAULT;                return(0);        }	case CCISS_GETFIRMVER:        {		FirmwareVer_type firmware;		if (!arg) return -EINVAL;		memcpy(firmware, host->firm_ver, 4);                if (copy_to_user(argp, firmware, sizeof( FirmwareVer_type)))                	return -EFAULT;                return(0);        }        case CCISS_GETDRIVVER:        {		DriverVer_type DriverVer = DRIVER_VERSION;                if (!arg) return -EINVAL;                if (copy_to_user(argp, &DriverVer, sizeof( DriverVer_type) ))                	return -EFAULT;                return(0);        }	case CCISS_REVALIDVOLS:		if (bdev != bdev->bd_contains || drv != host->drv)			return -ENXIO;                return revalidate_allvol(host); 	case CCISS_GETLUNINFO: { 		LogvolInfo_struct luninfo; 		int i; 		 		luninfo.LunID = drv->LunID; 		luninfo.num_opens = drv->usage_count; 		luninfo.num_parts = 0; 		if (copy_to_user(argp, &luninfo, 				sizeof(LogvolInfo_struct))) 			return -EFAULT; 		return(0); 	}	case CCISS_DEREGDISK:		return deregister_disk(disk);	case CCISS_REGNEWD:		return register_new_disk(host);	case CCISS_PASSTHRU:	{		IOCTL_Command_struct iocommand;		CommandList_struct *c;		char 	*buff = NULL;		u64bit	temp64;		unsigned long flags;		DECLARE_COMPLETION(wait);		if (!arg) return -EINVAL;			if (!capable(CAP_SYS_RAWIO)) return -EPERM;		if (copy_from_user(&iocommand, argp, sizeof( IOCTL_Command_struct) ))			return -EFAULT;		if((iocommand.buf_size < 1) && 				(iocommand.Request.Type.Direction != XFER_NONE))		{				return -EINVAL;		} #if 0 /* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */		/* Check kmalloc limits */		if(iocommand.buf_size > 128000)			return -EINVAL;#endif		if(iocommand.buf_size > 0)		{			buff =  kmalloc(iocommand.buf_size, GFP_KERNEL);			if( buff == NULL) 				return -EFAULT;		}		if (iocommand.Request.Type.Direction == XFER_WRITE)		{			/* Copy the data into the buffer we created */ 			if (copy_from_user(buff, iocommand.buf, iocommand.buf_size))			{				kfree(buff);				return -EFAULT;			}		} else {			memset(buff, 0, iocommand.buf_size);		}		if ((c = cmd_alloc(host , 0)) == NULL)		{			kfree(buff);			return -ENOMEM;		}			// Fill in the command type 		c->cmd_type = CMD_IOCTL_PEND;			// Fill in Command Header 		c->Header.ReplyQueue = 0;  // unused in simple mode		if( iocommand.buf_size > 0) 	// buffer to fill 		{			c->Header.SGList = 1;			c->Header.SGTotal= 1;		} else	// no buffers to fill  		{			c->Header.SGList = 0;                	c->Header.SGTotal= 0;		}		c->Header.LUN = iocommand.LUN_info;		c->Header.Tag.lower = c->busaddr;  // use the kernel address the cmd block for tag				// Fill in Request block 		c->Request = iocommand.Request; 			// Fill in the scatter gather information		if (iocommand.buf_size > 0 ) 		{			temp64.val = pci_map_single( host->pdev, buff,                                        iocommand.buf_size,                                 PCI_DMA_BIDIRECTIONAL);				c->SG[0].Addr.lower = temp64.val32.lower;			c->SG[0].Addr.upper = temp64.val32.upper;			c->SG[0].Len = iocommand.buf_size;			c->SG[0].Ext = 0;  // we are not chaining		}		c->waiting = &wait;		/* Put the request on the tail of the request queue */		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);		addQ(&host->reqQ, c);		host->Qdepth++;		start_io(host);		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);		wait_for_completion(&wait);		/* unlock the buffers from DMA */		temp64.val32.lower = c->SG[0].Addr.lower;                temp64.val32.upper = c->SG[0].Addr.upper;                pci_unmap_single( host->pdev, (dma_addr_t) temp64.val,                	iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);		/* Copy the error information out */ 		iocommand.error_info = *(c->err_info);		if ( copy_to_user(argp, &iocommand, sizeof( IOCTL_Command_struct) ) )		{			kfree(buff);			cmd_free(host, c, 0);			return( -EFAULT);			} 			if (iocommand.Request.Type.Direction == XFER_READ)                {                        /* Copy the data out of the buffer we created */                        if (copy_to_user(iocommand.buf, buff, iocommand.buf_size))			{                        	kfree(buff);				cmd_free(host, c, 0);				return -EFAULT;			}                }                kfree(buff);		cmd_free(host, c, 0);                return(0);	} 	case CCISS_BIG_PASSTHRU: {		BIG_IOCTL_Command_struct *ioc;		CommandList_struct *c;		unsigned char **buff = NULL;		int	*buff_size = NULL;		u64bit	temp64;		unsigned long flags;		BYTE sg_used = 0;		int status = 0;		int i;		DECLARE_COMPLETION(wait);		__u32   left;		__u32	sz;		BYTE    __user *data_ptr;		if (!arg)			return -EINVAL;		if (!capable(CAP_SYS_RAWIO))			return -EPERM;		ioc = (BIG_IOCTL_Command_struct *) 			kmalloc(sizeof(*ioc), GFP_KERNEL);		if (!ioc) {			status = -ENOMEM;			goto cleanup1;		}		if (copy_from_user(ioc, argp, sizeof(*ioc))) {			status = -EFAULT;			goto cleanup1;		}		if ((ioc->buf_size < 1) &&			(ioc->Request.Type.Direction != XFER_NONE)) {				status = -EINVAL;				goto cleanup1;		}		/* Check kmalloc limits  using all SGs */		if (ioc->malloc_size > MAX_KMALLOC_SIZE) {			status = -EINVAL;			goto cleanup1;		}		if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {			status = -EINVAL;			goto cleanup1;		}		buff = (unsigned char **) kmalloc(MAXSGENTRIES * 				sizeof(char *), GFP_KERNEL);		if (!buff) {			status = -ENOMEM;			goto cleanup1;		}		memset(buff, 0, MAXSGENTRIES);		buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int), 					GFP_KERNEL);		if (!buff_size) {			status = -ENOMEM;			goto cleanup1;		}		left = ioc->buf_size;		data_ptr = ioc->buf;		while (left) {			sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;			buff_size[sg_used] = sz;			buff[sg_used] = kmalloc(sz, GFP_KERNEL);			if (buff[sg_used] == NULL) {				status = -ENOMEM;				goto cleanup1;			}			if (ioc->Request.Type.Direction == XFER_WRITE &&				copy_from_user(buff[sg_used], data_ptr, sz)) {					status = -ENOMEM;					goto cleanup1;						} else {				memset(buff[sg_used], 0, sz);			}			left -= sz;			data_ptr += sz;			sg_used++;		}		if ((c = cmd_alloc(host , 0)) == NULL) {			status = -ENOMEM;			goto cleanup1;			}		c->cmd_type = CMD_IOCTL_PEND;		c->Header.ReplyQueue = 0;				if( ioc->buf_size > 0) {			c->Header.SGList = sg_used;			c->Header.SGTotal= sg_used;		} else { 			c->Header.SGList = 0;			c->Header.SGTotal= 0;		}		c->Header.LUN = ioc->LUN_info;		c->Header.Tag.lower = c->busaddr;				c->Request = ioc->Request;		if (ioc->buf_size > 0 ) {			int i;			for(i=0; i<sg_used; i++) {				temp64.val = pci_map_single( host->pdev, buff[i],					buff_size[i],					PCI_DMA_BIDIRECTIONAL);				c->SG[i].Addr.lower = temp64.val32.lower;				c->SG[i].Addr.upper = temp64.val32.upper;				c->SG[i].Len = buff_size[i];				c->SG[i].Ext = 0;  /* we are not chaining */			}		}		c->waiting = &wait;		/* Put the request on the tail of the request queue */		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);		addQ(&host->reqQ, c);		host->Qdepth++;		start_io(host);		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);		wait_for_completion(&wait);		/* unlock the buffers from DMA */		for(i=0; i<sg_used; i++) {			temp64.val32.lower = c->SG[i].Addr.lower;			temp64.val32.upper = c->SG[i].Addr.upper;			pci_unmap_single( host->pdev, (dma_addr_t) temp64.val,				buff_size[i], PCI_DMA_BIDIRECTIONAL);		}		/* Copy the error information out */		ioc->error_info = *(c->err_info);		if (copy_to_user(argp, ioc, sizeof(*ioc))) {			cmd_free(host, c, 0);			status = -EFAULT;			goto cleanup1;		}		if (ioc->Request.Type.Direction == XFER_READ) {			/* Copy the data out of the buffer we created */			BYTE __user *ptr = ioc->buf;	        	for(i=0; i< sg_used; i++) {				if (copy_to_user(ptr, buff[i], buff_size[i])) {					cmd_free(host, c, 0);					status = -EFAULT;					goto cleanup1;				}				ptr += buff_size[i];			}		}		cmd_free(host, c, 0);		status = 0;cleanup1:		if (buff) {			for(i=0; i<sg_used; i++)				if(buff[i] != NULL)					kfree(buff[i]);			kfree(buff);		}		if (buff_size)			kfree(buff_size);		if (ioc)			kfree(ioc);		return(status);	}	default:		return -ENOTTY;	}	}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/97afa0a25afb43a82954662773a9d48d61b2996a/cciss.c/clean/drivers/block/cciss.c