if (copy_from_user(&mv, (void*)arg, sizeof (mv))) 
if (copy_from_user(&mv, argp, sizeof (mv))) 
static int ch_ioctl(struct inode * inode, struct file * file,		    unsigned int cmd, unsigned long arg){	scsi_changer *ch = file->private_data;	int retval;		switch (cmd) {	case CHIOGPARAMS:	{		struct changer_params params;				params.cp_curpicker = 0;		params.cp_npickers  = ch->counts[CHET_MT];		params.cp_nslots    = ch->counts[CHET_ST];		params.cp_nportals  = ch->counts[CHET_IE];		params.cp_ndrives   = ch->counts[CHET_DT];				if (copy_to_user((void *) arg, &params, sizeof(params)))			return -EFAULT;		return 0;	}	case CHIOGVPARAMS:	{		struct changer_vendor_params vparams;		memset(&vparams,0,sizeof(vparams));		if (ch->counts[CHET_V1]) {			vparams.cvp_n1  = ch->counts[CHET_V1];			strncpy(vparams.cvp_label1,vendor_labels[0],16);		}		if (ch->counts[CHET_V2]) {			vparams.cvp_n2  = ch->counts[CHET_V2];			strncpy(vparams.cvp_label2,vendor_labels[1],16);		}		if (ch->counts[CHET_V3]) {			vparams.cvp_n3  = ch->counts[CHET_V3];			strncpy(vparams.cvp_label3,vendor_labels[2],16);		}		if (ch->counts[CHET_V4]) {			vparams.cvp_n4  = ch->counts[CHET_V4];			strncpy(vparams.cvp_label4,vendor_labels[3],16);		}		if (copy_to_user((void *) arg, &vparams, sizeof(vparams)))			return -EFAULT;		return 0;	}		case CHIOPOSITION:	{		struct changer_position pos;				if (copy_from_user(&pos, (void*)arg, sizeof (pos)))			return -EFAULT;		if (0 != ch_checkrange(ch, pos.cp_type, pos.cp_unit)) {			dprintk("CHIOPOSITION: invalid parameter\n");			return -EBADSLT;		}		down(&ch->lock);		retval = ch_position(ch,0,				     ch->firsts[pos.cp_type] + pos.cp_unit,				     pos.cp_flags & CP_INVERT);		up(&ch->lock);		return retval;	}		case CHIOMOVE:	{		struct changer_move mv;		if (copy_from_user(&mv, (void*)arg, sizeof (mv)))			return -EFAULT;		if (0 != ch_checkrange(ch, mv.cm_fromtype, mv.cm_fromunit) ||		    0 != ch_checkrange(ch, mv.cm_totype,   mv.cm_tounit  )) {			dprintk("CHIOMOVE: invalid parameter\n");			return -EBADSLT;		}				down(&ch->lock);		retval = ch_move(ch,0,				 ch->firsts[mv.cm_fromtype] + mv.cm_fromunit,				 ch->firsts[mv.cm_totype]   + mv.cm_tounit,				 mv.cm_flags & CM_INVERT);		up(&ch->lock);		return retval;	}	case CHIOEXCHANGE:	{		struct changer_exchange mv;				if (copy_from_user(&mv, (void*)arg, sizeof (mv)))			return -EFAULT;		if (0 != ch_checkrange(ch, mv.ce_srctype,  mv.ce_srcunit ) ||		    0 != ch_checkrange(ch, mv.ce_fdsttype, mv.ce_fdstunit) ||		    0 != ch_checkrange(ch, mv.ce_sdsttype, mv.ce_sdstunit)) {			dprintk("CHIOEXCHANGE: invalid parameter\n");			return -EBADSLT;		}				down(&ch->lock);		retval = ch_exchange			(ch,0,			 ch->firsts[mv.ce_srctype]  + mv.ce_srcunit,			 ch->firsts[mv.ce_fdsttype] + mv.ce_fdstunit,			 ch->firsts[mv.ce_sdsttype] + mv.ce_sdstunit,			 mv.ce_flags & CE_INVERT1, mv.ce_flags & CE_INVERT2);		up(&ch->lock);		return retval;	}	case CHIOGSTATUS:	{		struct changer_element_status ces;				if (copy_from_user(&ces, (void*)arg, sizeof (ces)))			return -EFAULT;		if (ces.ces_type < 0 || ces.ces_type >= CH_TYPES)			return -EINVAL;		return ch_gstatus(ch, ces.ces_type, ces.ces_data);	}	case CHIOGELEM:	{		struct changer_get_element cge;		u_char  cmd[12];		u_char  *buffer;		unsigned int elem;		int     result,i;				if (copy_from_user(&cge, (void*)arg, sizeof (cge)))			return -EFAULT;		if (0 != ch_checkrange(ch, cge.cge_type, cge.cge_unit))			return -EINVAL;		elem = ch->firsts[cge.cge_type] + cge.cge_unit;				buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);		if (!buffer)			return -ENOMEM;		down(&ch->lock);			voltag_retry:		memset(cmd,0,sizeof(cmd));		cmd[0] = READ_ELEMENT_STATUS;		cmd[1] = (ch->device->lun << 5) |			(ch->voltags ? 0x10 : 0) |			ch_elem_to_typecode(ch,elem);		cmd[2] = (elem >> 8) & 0xff;		cmd[3] = elem        & 0xff;		cmd[5] = 1;		cmd[9] = 255;				if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) {			cge.cge_status = buffer[18];			cge.cge_flags = 0;			if (buffer[18] & CESTATUS_EXCEPT) {				cge.cge_errno = EIO;			}			if (buffer[25] & 0x80) {				cge.cge_flags |= CGE_SRC;				if (buffer[25] & 0x40)					cge.cge_flags |= CGE_INVERT;				elem = (buffer[26]<<8) | buffer[27];				for (i = 0; i < 4; i++) {					if (elem >= ch->firsts[i] &&					    elem <  ch->firsts[i] + ch->counts[i]) {						cge.cge_srctype = i;						cge.cge_srcunit = elem-ch->firsts[i];					}				}			}			if ((buffer[22] & 0x30) == 0x30) {				cge.cge_flags |= CGE_IDLUN;				cge.cge_id  = buffer[23];				cge.cge_lun = buffer[22] & 7;			}			if (buffer[9] & 0x80) {				cge.cge_flags |= CGE_PVOLTAG;				memcpy(cge.cge_pvoltag,buffer+28,36);			}			if (buffer[9] & 0x40) {				cge.cge_flags |= CGE_AVOLTAG;				memcpy(cge.cge_avoltag,buffer+64,36);			}		} else if (ch->voltags) {			ch->voltags = 0;			vprintk("device has no volume tag support\n");			goto voltag_retry;		}		kfree(buffer);		up(&ch->lock);				if (copy_to_user((void*)arg, &cge, sizeof (cge)))			return -EFAULT;		return result;	}	case CHIOINITELEM:	{		down(&ch->lock);		retval = ch_init_elem(ch);		up(&ch->lock);		return retval;	}			case CHIOSVOLTAG:	{		struct changer_set_voltag csv;		int elem;		if (copy_from_user(&csv, (void*)arg, sizeof(csv)))			return -EFAULT;		if (0 != ch_checkrange(ch, csv.csv_type, csv.csv_unit)) {			dprintk("CHIOSVOLTAG: invalid parameter\n");			return -EBADSLT;		}		elem = ch->firsts[csv.csv_type] + csv.csv_unit;		down(&ch->lock);		retval = ch_set_voltag(ch, elem,				       csv.csv_flags & CSV_AVOLTAG,				       csv.csv_flags & CSV_CLEARTAG,				       csv.csv_voltag);		up(&ch->lock);		return retval;	}	default:		return scsi_ioctl(ch->device, cmd, (void*)arg);	}}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/fe08ac3178243fbed61f24878ffcf5cfb53fceb1/ch.c/clean/drivers/scsi/ch.c