/*
 * SCSI Media Changer device driver for Linux 2.6
 *
 *     (c) 1996-2003 Gerd Knorr <kraxel@bytesex.org>
 *
 */

#define VERSION "0.25"

#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/completion.h>
#include <linux/ioctl32.h>
#include <linux/compat.h>
#include <linux/chio.h>			/* here are all the ioctls */

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_request.h>
#include <scsi/scsi_dbg.h>

#define CH_DT_MAX       16
#define CH_TYPES        8

MODULE_DESCRIPTION("device driver for scsi media changer devices");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org>");
MODULE_LICENSE("GPL");

static int init = 1;
module_param(init, int, 0444);
MODULE_PARM_DESC(init, \
    "initialize element status on driver load (default: on)");

static int timeout_move = 300;
module_param(timeout_move, int, 0644);
MODULE_PARM_DESC(timeout_move,"timeout for move commands "
		 "(default: 300 seconds)");

static int timeout_init = 3600;
module_param(timeout_init, int, 0644);
MODULE_PARM_DESC(timeout_init,"timeout for INITIALIZE ELEMENT STATUS "
		 "(default: 3600 seconds)");

static int verbose = 1;
module_param(verbose, int, 0644);
MODULE_PARM_DESC(verbose,"be verbose (default: on)");

static int debug = 0;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,"enable/disable debug messages, also prints more "
		 "detailed sense codes on scsi errors (default: off)");

static int dt_id[CH_DT_MAX] = { [ 0 ... (CH_DT_MAX-1) ] = -1 };
static int dt_lun[CH_DT_MAX];
module_param_array(dt_id,  int, NULL, 0444);
module_param_array(dt_lun, int, NULL, 0444);

/* tell the driver about vendor-specific slots */
static int vendor_firsts[CH_TYPES-4];
static int vendor_counts[CH_TYPES-4];
module_param_array(vendor_firsts, int, NULL, 0444);
module_param_array(vendor_counts, int, NULL, 0444);

static char *vendor_labels[CH_TYPES-4] = {
	"v0", "v1", "v2", "v3"
};
// module_param_string_array(vendor_labels, NULL, 0444);

#define dprintk(fmt, arg...)    if (debug) \
        printk(KERN_DEBUG "%s: " fmt, ch->name , ## arg)
#define vprintk(fmt, arg...)    if (verbose) \
        printk(KERN_INFO "%s: " fmt, ch->name , ## arg)

/* ------------------------------------------------------------------- */

#define MAX_RETRIES   1

static int  ch_probe(struct device *);
static int  ch_remove(struct device *);
static int  ch_open(struct inode * inode, struct file * filp);
static int  ch_release(struct inode * inode, struct file * filp);
static int  ch_ioctl(struct inode * inode, struct file * filp,
		     unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
static long ch_ioctl_compat(struct file * filp,
			    unsigned int cmd, unsigned long arg);
#endif

static struct class * ch_sysfs_class;

typedef struct {
	struct list_head    list;
	int                 minor;
	char                name[8];
	struct scsi_device  *device;
	struct scsi_device  **dt;        /* ptrs to data transfer elements */
	u_int               firsts[CH_TYPES];
	u_int               counts[CH_TYPES];
	u_int               unit_attention;
	u_int		    voltags;
	struct semaphore    lock;
} scsi_changer;

static LIST_HEAD(ch_devlist);
static spinlock_t ch_devlist_lock = SPIN_LOCK_UNLOCKED;
static int ch_devcount;

static struct scsi_driver ch_template =
{
	.owner     	= THIS_MODULE,
	.gendrv     	= {
		.name	= "ch",
		.probe  = ch_probe,
		.remove = ch_remove,
	},
};

static struct file_operations changer_fops =
{
	.owner        = THIS_MODULE,
	.open         = ch_open,
	.release      = ch_release,
	.ioctl        = ch_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = ch_ioctl_compat,
#endif
};

static struct {
	unsigned char  sense;
	unsigned char  asc;
	unsigned char  ascq;
	int	       errno;
} err[] = {
/* Just filled in what looks right. Hav'nt checked any standard paper for
   these errno assignments, so they may be wrong... */
	{
		.sense  = ILLEGAL_REQUEST,
		.asc    = 0x21,
		.ascq   = 0x01,
		.errno  = EBADSLT, /* Invalid element address */
	},{
		.sense  = ILLEGAL_REQUEST,
		.asc    = 0x28,
		.ascq   = 0x01,
		.errno  = EBADE,   /* Import or export element accessed */
	},{
		.sense  = ILLEGAL_REQUEST,
		.asc    = 0x3B,
		.ascq   = 0x0D,
		.errno  = EXFULL,  /* Medium destination element full */
	},{
		.sense  = ILLEGAL_REQUEST,
		.asc    = 0x3B,
		.ascq   = 0x0E,
		.errno  = EBADE,   /* Medium source element empty */
	},{
		.sense  = ILLEGAL_REQUEST,
		.asc    = 0x20,
		.ascq   = 0x00,
		.errno  = EBADRQC, /* Invalid command operation code */
	},{
	        /* end of list */
	}
};

/* ------------------------------------------------------------------- */

static int ch_find_errno(unsigned char *sense_buffer)
{
	int i,errno = 0;

	/* Check to see if additional sense information is available */
	if (sense_buffer[7]  > 5 &&
	    sense_buffer[12] != 0) {
		for (i = 0; err[i].errno != 0; i++) {
			if (err[i].sense == sense_buffer[ 2] &&
			    err[i].asc   == sense_buffer[12] &&
			    err[i].ascq  == sense_buffer[13]) {
				errno = -err[i].errno;
				break;
			}
		}
	}
	if (errno == 0)
		errno = -EIO;
	return errno;
}

static int
ch_do_scsi(scsi_changer *ch, unsigned char *cmd,
	   void *buffer, unsigned buflength,
	   enum dma_data_direction direction)
{
	int errno, retries = 0, timeout;
	struct scsi_request *sr;
	
	sr = scsi_allocate_request(ch->device, GFP_KERNEL);
	if (NULL == sr)
		return -ENOMEM;

	timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS)
		? timeout_init : timeout_move;

 retry:
	errno = 0;
	if (debug) {
		dprintk("command: ");
		__scsi_print_command(cmd);
	}

        scsi_wait_req(sr, cmd, buffer, buflength,
		      timeout * HZ, MAX_RETRIES);

	dprintk("result: 0x%x\n",sr->sr_result);
	if (driver_byte(sr->sr_result) & DRIVER_SENSE) {
		if (debug)
			scsi_print_req_sense(ch->name, sr);
		errno = ch_find_errno(sr->sr_sense_buffer);

		switch(sr->sr_sense_buffer[2] & 0xf) {
		case UNIT_ATTENTION:
			ch->unit_attention = 1;
			if (retries++ < 3)
				goto retry;
			break;
		}
	}
	scsi_release_request(sr);
	return errno;
}

/* ------------------------------------------------------------------------ */

static int
ch_elem_to_typecode(scsi_changer *ch, u_int elem)
{
	int i;
	
	for (i = 0; i < CH_TYPES; i++) {
		if (elem >= ch->firsts[i]  &&
		    elem <  ch->firsts[i] +
	            ch->counts[i])
			return i+1;
	}
	return 0;
}

static int
ch_read_element_status(scsi_changer *ch, u_int elem, char *data)
{
	u_char  cmd[12];
	u_char  *buffer;
	int     result;
	
	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
	if(!buffer)
		return -ENOMEM;
	
 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))) {
		if (((buffer[16] << 8) | buffer[17]) != elem) {
			dprintk("asked for element 0x%02x, got 0x%02x\n",
				elem,(buffer[16] << 8) | buffer[17]);
			kfree(buffer);
			return -EIO;
		}
		memcpy(data,buffer+16,16);
	} else {
		if (ch->voltags) {
			ch->voltags = 0;
			vprintk("device has no volume tag support\n");
			goto retry;
		}
		dprintk("READ ELEMENT STATUS for element 0x%x failed\n",elem);
	}
	kfree(buffer);
	return result;
}

static int 
ch_init_elem(scsi_changer *ch)
{
	int err;
	u_char cmd[6];

	vprintk("INITIALIZE ELEMENT STATUS, may take some time ...\n");
	memset(cmd,0,sizeof(cmd));
	cmd[0] = INITIALIZE_ELEMENT_STATUS;
	cmd[1] = ch->device->lun << 5;
	err = ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE);
	vprintk("... finished\n");
	return err;
}

static int
ch_readconfig(scsi_changer *ch)
{
	u_char  cmd[10], data[16];
	u_char  *buffer;
	int     result,id,lun,i;
	u_int   elem;

	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
	if (!buffer)
		return -ENOMEM;
	memset(buffer,0,512);
	
	memset(cmd,0,sizeof(cmd));
	cmd[0] = MODE_SENSE;
	cmd[1] = ch->device->lun << 5;
	cmd[2] = 0x1d;
	cmd[4] = 255;
	result = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE);
	if (0 != result) {
		cmd[1] |= (1<<3);
		result  = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE);
	}
	if (0 == result) {
		ch->firsts[CHET_MT] =
			(buffer[buffer[3]+ 6] << 8) | buffer[buffer[3]+ 7];
		ch->counts[CHET_MT] =
			(buffer[buffer[3]+ 8] << 8) | buffer[buffer[3]+ 9];
		ch->firsts[CHET_ST] =
			(buffer[buffer[3]+10] << 8) | buffer[buffer[3]+11];
		ch->counts[CHET_ST] =
			(buffer[buffer[3]+12] << 8) | buffer[buffer[3]+13];
		ch->firsts[CHET_IE] =
			(buffer[buffer[3]+14] << 8) | buffer[buffer[3]+15];
		ch->counts[CHET_IE] =
			(buffer[buffer[3]+16] << 8) | buffer[buffer[3]+17];
		ch->firsts[CHET_DT] =
			(buffer[buffer[3]+18] << 8) | buffer[buffer[3]+19];
		ch->counts[CHET_DT] =
			(buffer[buffer[3]+20] << 8) | buffer[buffer[3]+21];
		vprintk("type #1 (mt): 0x%x+%d [medium transport]\n",
			ch->firsts[CHET_MT],
			ch->counts[CHET_MT]);
		vprintk("type #2 (st): 0x%x+%d [storage]\n",
			ch->firsts[CHET_ST],
			ch->counts[CHET_ST]);
		vprintk("type #3 (ie): 0x%x+%d [import/export]\n",
			ch->firsts[CHET_IE],
			ch->counts[CHET_IE]);
		vprintk("type #4 (dt): 0x%x+%d [data transfer]\n",
			ch->firsts[CHET_DT],
			ch->counts[CHET_DT]);
	} else {
		vprintk("reading element address assigment page failed!\n");
	}
	
	/* vendor specific element types */
	for (i = 0; i < 4; i++) {
		if (0 == vendor_counts[i])
			continue;
		if (NULL == vendor_labels[i])
			continue;
		ch->firsts[CHET_V1+i] = vendor_firsts[i];
		ch->counts[CHET_V1+i] = vendor_counts[i];
		vprintk("type #%d (v%d): 0x%x+%d [%s, vendor specific]\n",
			i+5,i+1,vendor_firsts[i],vendor_counts[i],
			vendor_labels[i]);
	}

	/* look up the devices of the data transfer elements */
	ch->dt = kmalloc(ch->counts[CHET_DT]*sizeof(struct scsi_device),
			 GFP_KERNEL);
	for (elem = 0; elem < ch->counts[CHET_DT]; elem++) {
		id  = -1;
		lun = 0;
		if (elem < CH_DT_MAX  &&  -1 != dt_id[elem]) {
			id  = dt_id[elem];
			lun = dt_lun[elem];
			vprintk("dt 0x%x: [insmod option] ",
				elem+ch->firsts[CHET_DT]);
		} else if (0 != ch_read_element_status
			   (ch,elem+ch->firsts[CHET_DT],data)) {
			vprintk("dt 0x%x: READ ELEMENT STATUS failed\n",
				elem+ch->firsts[CHET_DT]);
		} else {
			vprintk("dt 0x%x: ",elem+ch->firsts[CHET_DT]);
			if (data[6] & 0x80) {
				if (verbose)
					printk("not this SCSI bus\n");
				ch->dt[elem] = NULL;
			} else if (0 == (data[6] & 0x30)) {
				if (verbose)
					printk("ID/LUN unknown\n");
				ch->dt[elem] = NULL;
			} else {
				id  = ch->device->id;
				lun = 0;
				if (data[6] & 0x20) id  = data[7];
				if (data[6] & 0x10) lun = data[6] & 7;
			}
		}
		if (-1 != id) {
			if (verbose)
				printk("ID %i, LUN %i, ",id,lun);
			ch->dt[elem] =
				scsi_device_lookup(ch->device->host,
						   ch->device->channel,
						   id,lun);
			if (!ch->dt[elem]) {
				/* should not happen */
				if (verbose)
					printk("Huh? device not found!\n");
			} else {
				if (verbose)
					printk("name: %8.8s %16.16s %4.4s\n",
					       ch->dt[elem]->vendor,
					       ch->dt[elem]->model,
					       ch->dt[elem]->rev);
			}
		}
	}
	ch->voltags = 1;
	kfree(buffer);

	return 0;
}

/* ------------------------------------------------------------------------ */

static int
ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate)
{
	u_char  cmd[10];
	
	dprintk("position: 0x%x\n",elem);
	if (0 == trans)
		trans = ch->firsts[CHET_MT];
	memset(cmd,0,sizeof(cmd));
	cmd[0]  = POSITION_TO_ELEMENT;
	cmd[1]  = ch->device->lun << 5;
	cmd[2]  = (trans >> 8) & 0xff;
	cmd[3]  =  trans       & 0xff;
	cmd[4]  = (elem  >> 8) & 0xff;
	cmd[5]  =  elem        & 0xff;
	cmd[8]  = rotate ? 1 : 0;
	return ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE);
}

static int
ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate)
{
	u_char  cmd[12];
	
	dprintk("move: 0x%x => 0x%x\n",src,dest);
	if (0 == trans)
		trans = ch->firsts[CHET_MT];
	memset(cmd,0,sizeof(cmd));
	cmd[0]  = MOVE_MEDIUM;
	cmd[1]  = ch->device->lun << 5;
	cmd[2]  = (trans >> 8) & 0xff;
	cmd[3]  =  trans       & 0xff;
	cmd[4]  = (src   >> 8) & 0xff;
	cmd[5]  =  src         & 0xff;
	cmd[6]  = (dest  >> 8) & 0xff;
	cmd[7]  =  dest        & 0xff;
	cmd[10] = rotate ? 1 : 0;
	return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE);
}

static int
ch_exchange(scsi_changer *ch, u_int trans, u_int src,
	    u_int dest1, u_int dest2, int rotate1, int rotate2)
{
	u_char  cmd[12];
	
	dprintk("exchange: 0x%x => 0x%x => 0x%x\n",
		src,dest1,dest2);
	if (0 == trans)
		trans = ch->firsts[CHET_MT];
	memset(cmd,0,sizeof(cmd));
	cmd[0]  = EXCHANGE_MEDIUM;
	cmd[1]  = ch->device->lun << 5;
	cmd[2]  = (trans >> 8) & 0xff;
	cmd[3]  =  trans       & 0xff;
	cmd[4]  = (src   >> 8) & 0xff;
	cmd[5]  =  src         & 0xff;
	cmd[6]  = (dest1 >> 8) & 0xff;
	cmd[7]  =  dest1       & 0xff;
	cmd[8]  = (dest2 >> 8) & 0xff;
	cmd[9]  =  dest2       & 0xff;
	cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0);
	
	return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE);
}

static void
ch_check_voltag(char *tag)
{
	int i;

	for (i = 0; i < 32; i++) {
		/* restrict to ascii */
		if (tag[i] >= 0x7f || tag[i] < 0x20)
			tag[i] = ' ';
		/* don't allow search wildcards */
		if (tag[i] == '?' ||
		    tag[i] == '*')
			tag[i] = ' ';
	}
}

static int
ch_set_voltag(scsi_changer *ch, u_int elem,
	      int alternate, int clear, u_char *tag)
{
	u_char  cmd[12];
	u_char  *buffer;
	int result;

	buffer = kmalloc(512, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;
	memset(buffer,0,512);

	dprintk("%s %s voltag: 0x%x => \"%s\"\n",
		clear     ? "clear"     : "set",
		alternate ? "alternate" : "primary",
		elem, tag);
	memset(cmd,0,sizeof(cmd));
	cmd[0]  = SEND_VOLUME_TAG;
	cmd[1] = (ch->device->lun << 5) | 
		ch_elem_to_typecode(ch,elem);
	cmd[2] = (elem >> 8) & 0xff;
	cmd[3] = elem        & 0xff;
	cmd[5] = clear
		? (alternate ? 0x0d : 0x0c)
		: (alternate ? 0x0b : 0x0a);
	
	cmd[9] = 255;

	memcpy(buffer,tag,32);
	ch_check_voltag(buffer);

	result = ch_do_scsi(ch, cmd, buffer, 256, DMA_TO_DEVICE);
	kfree(buffer);
	return result;
}

static int ch_gstatus(scsi_changer *ch, int type, unsigned char *dest)
{
	int retval = 0;
	u_char data[16];
	unsigned int i;
	
	down(&ch->lock);
	for (i = 0; i < ch->counts[type]; i++) {
		if (0 != ch_read_element_status
		    (ch, ch->firsts[type]+i,data)) {
			retval = -EIO;
			break;
		}
		put_user(data[2], dest+i);
		if (data[2] & CESTATUS_EXCEPT)
			vprintk("element 0x%x: asc=0x%x, ascq=0x%x\n",
				ch->firsts[type]+i,
				(int)data[4],(int)data[5]);
		retval = ch_read_element_status
			(ch, ch->firsts[type]+i,data);
		if (0 != retval)
			break;
	}
	up(&ch->lock);
	return retval;
}

/* ------------------------------------------------------------------------ */

static int
ch_release(struct inode *inode, struct file *file)
{
	scsi_changer *ch = file->private_data;

	scsi_device_put(ch->device);
	file->private_data = NULL;
	return 0;
}

static int
ch_open(struct inode *inode, struct file *file)
{
	scsi_changer *tmp, *ch;
	int minor = iminor(inode);

	spin_lock(&ch_devlist_lock);
	ch = NULL;
	list_for_each_entry(tmp,&ch_devlist,list) {
		if (tmp->minor == minor)
			ch = tmp;
	}
	if (NULL == ch || scsi_device_get(ch->device)) {
		spin_unlock(&ch_devlist_lock);
		return -ENXIO;
	}
	spin_unlock(&ch_devlist_lock);

	file->private_data = ch;
	return 0;
}

static int
ch_checkrange(scsi_changer *ch, unsigned int type, unsigned int unit)
{
	if (type >= CH_TYPES  ||  unit >= ch->counts[type])
		return -1;
	return 0;
}

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);

	}
}

#ifdef CONFIG_COMPAT

struct changer_element_status32 {
	int		ces_type;
	compat_uptr_t	ces_data;
};
#define CHIOGSTATUS32  _IOW('c', 8,struct changer_element_status32)

static long ch_ioctl_compat(struct file * file,
			    unsigned int cmd, unsigned long arg)
{
	scsi_changer *ch = file->private_data;
	
	switch (cmd) {
	case CHIOGPARAMS:
	case CHIOGVPARAMS:
	case CHIOPOSITION:
	case CHIOMOVE:
	case CHIOEXCHANGE:
	case CHIOGELEM:
	case CHIOINITELEM:
	case CHIOSVOLTAG:
		/* compatible */
		return ch_ioctl(NULL /* inode, unused */,
				file, cmd, arg);
	case CHIOGSTATUS32:
	{
		struct changer_element_status32 ces32;
		unsigned char *data;
		
		if (copy_from_user(&ces32, (void*)arg, sizeof (ces32)))
			return -EFAULT;
		if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES)
			return -EINVAL;

		data = compat_ptr(ces32.ces_data);
		return ch_gstatus(ch, ces32.ces_type, data);
	}
	default:
		// return scsi_ioctl_compat(ch->device, cmd, (void*)arg);
		return -ENOIOCTLCMD;

	}
}
#endif

/* ------------------------------------------------------------------------ */

static int ch_probe(struct device *dev)
{
	struct scsi_device *sd = to_scsi_device(dev);
	scsi_changer *ch;
	
	if (sd->type != TYPE_MEDIUM_CHANGER)
		return -ENODEV;
    
	ch = kmalloc(sizeof(*ch), GFP_KERNEL);
	if (NULL == ch)
		return -ENOMEM;

	memset(ch,0,sizeof(*ch));
	ch->minor = ch_devcount;
	sprintf(ch->name,"ch%d",ch->minor);
	init_MUTEX(&ch->lock);
	ch->device = sd;
	ch_readconfig(ch);
	if (init)
		ch_init_elem(ch);

	class_device_create(ch_sysfs_class,
			    MKDEV(SCSI_CHANGER_MAJOR,ch->minor),
			    dev, "s%s", ch->name);

	printk(KERN_INFO "Attached scsi changer %s "
	       "at scsi%d, channel %d, id %d, lun %d\n", 
	       ch->name, sd->host->host_no, sd->channel, sd->id, sd->lun);
	
	spin_lock(&ch_devlist_lock);
	list_add_tail(&ch->list,&ch_devlist);
	ch_devcount++;
	spin_unlock(&ch_devlist_lock);
	return 0;
}

static int ch_remove(struct device *dev)
{
	struct scsi_device *sd = to_scsi_device(dev);
	scsi_changer *tmp, *ch;

	spin_lock(&ch_devlist_lock);
	ch = NULL;
	list_for_each_entry(tmp,&ch_devlist,list) {
		if (tmp->device == sd)
			ch = tmp;
	}
	BUG_ON(NULL == ch);
	list_del(&ch->list);
	spin_unlock(&ch_devlist_lock);

	class_device_destroy(ch_sysfs_class,
			     MKDEV(SCSI_CHANGER_MAJOR,ch->minor));
	kfree(ch->dt);
	kfree(ch);
	ch_devcount--;
	return 0;
}

static int __init init_ch_module(void)
{
	int rc;
	
	printk(KERN_INFO "SCSI Media Changer driver v" VERSION " \n");
        ch_sysfs_class = class_create(THIS_MODULE, "scsi_changer");
        if (IS_ERR(ch_sysfs_class)) {
		rc = PTR_ERR(ch_sysfs_class);
		return rc;
        }
	rc = register_chrdev(SCSI_CHANGER_MAJOR,"ch",&changer_fops);
	if (rc < 0) {
		printk("Unable to get major %d for SCSI-Changer\n",
		       SCSI_CHANGER_MAJOR);
		goto fail1;
	}
	rc = scsi_register_driver(&ch_template.gendrv);
	if (rc < 0)
		goto fail2;
	return 0;

 fail2:
	unregister_chrdev(SCSI_CHANGER_MAJOR, "ch");
 fail1:
	class_destroy(ch_sysfs_class);
	return rc;
}

static void __exit exit_ch_module(void) 
{
	scsi_unregister_driver(&ch_template.gendrv);
	unregister_chrdev(SCSI_CHANGER_MAJOR, "ch");
	class_destroy(ch_sysfs_class);
}

module_init(init_ch_module);
module_exit(exit_ch_module);

/*
 * Local variables:
 * c-basic-offset: 8
 * End:
 */
