/*
 *  History:
 *  Started: Aug 9 by Lawrence Foard (entropy@world.std.com),
 *           to allow user process control of SCSI devices.
 *  Development Sponsored by Killy Corp. NY NY
 *
 * Original driver (sg.c):
 *        Copyright (C) 1992 Lawrence Foard
 * Version 2 and 3 extensions to driver:
 *        Copyright (C) 1998 - 2005 Douglas Gilbert
 *
 *  Modified  19-JAN-1998  Richard Gooch <rgooch@atnf.csiro.au>  Devfs support
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 */

static int sg_version_num = 30532;	/* 2 digits for each component */
#define SG_VERSION_STR "3.5.32"

/*
 *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
 *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
 *        the kernel/module needs to be built with CONFIG_SCSI_LOGGING
 *        (otherwise the macros compile to empty statements).
 *
 */
#include <linux/config.h>
#include <linux/module.h>

#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/mtio.h>
#include <linux/ioctl.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/moduleparam.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/cdev.h>
#include <linux/seq_file.h>
#include <linux/blkdev.h>
#include <linux/delay.h>

#include "scsi.h"
#include <scsi/scsi_host.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/sg.h>

#include "scsi_logging.h"

#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
static char *sg_version_date = "20050117";

static int sg_proc_init(void);
static void sg_proc_cleanup(void);
#endif

#ifndef LINUX_VERSION_CODE
#include <linux/version.h>
#endif				/* LINUX_VERSION_CODE */

#define SG_ALLOW_DIO_DEF 0
#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */

#define SG_MAX_DEVS 32768

/*
 * Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
 * Then when using 32 bit integers x * m may overflow during the calculation.
 * Replacing muldiv(x) by muldiv(x)=((x % d) * m) / d + int(x / d) * m
 * calculates the same, but prevents the overflow when both m and d
 * are "small" numbers (like HZ and USER_HZ).
 * Of course an overflow is inavoidable if the result of muldiv doesn't fit
 * in 32 bits.
 */
#define MULDIV(X,MUL,DIV) ((((X % DIV) * MUL) / DIV) + ((X / DIV) * MUL))

#define SG_DEFAULT_TIMEOUT MULDIV(SG_DEFAULT_TIMEOUT_USER, HZ, USER_HZ)

int sg_big_buff = SG_DEF_RESERVED_SIZE;
/* N.B. This variable is readable and writeable via
   /proc/scsi/sg/def_reserved_size . Each time sg_open() is called a buffer
   of this size (or less if there is not enough memory) will be reserved
   for use by this file descriptor. [Deprecated usage: this variable is also
   readable via /proc/sys/kernel/sg-big-buff if the sg driver is built into
   the kernel (i.e. it is not a module).] */
static int def_reserved_size = -1;	/* picks up init parameter */
static int sg_allow_dio = SG_ALLOW_DIO_DEF;

#define SG_SECTOR_SZ 512
#define SG_SECTOR_MSK (SG_SECTOR_SZ - 1)

#define SG_DEV_ARR_LUMP 32	/* amount to over allocate sg_dev_arr by */

static int sg_add(struct class_device *);
static void sg_remove(struct class_device *);

static Scsi_Request *dummy_cmdp;	/* only used for sizeof */

static DEFINE_RWLOCK(sg_dev_arr_lock);	/* Also used to lock
							   file descriptor list for device */

static struct class_interface sg_interface = {
	.add		= sg_add,
	.remove		= sg_remove,
};

typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
	unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
	unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */
	unsigned bufflen;	/* Size of (aggregate) data buffer */
	unsigned b_malloc_len;	/* actual len malloc'ed in buffer */
	void *buffer;		/* Data buffer or scatter list (k_use_sg>0) */
	char dio_in_use;	/* 0->indirect IO (or mmap), 1->dio */
	unsigned char cmd_opcode; /* first byte of command */
} Sg_scatter_hold;

struct sg_device;		/* forward declarations */
struct sg_fd;

typedef struct sg_request {	/* SG_MAX_QUEUE requests outstanding per file */
	Scsi_Request *my_cmdp;	/* != 0  when request with lower levels */
	struct sg_request *nextrp;	/* NULL -> tail request (slist) */
	struct sg_fd *parentfp;	/* NULL -> not in use */
	Sg_scatter_hold data;	/* hold buffer, perhaps scatter list */
	sg_io_hdr_t header;	/* scsi command+info, see <scsi/sg.h> */
	unsigned char sense_b[sizeof (dummy_cmdp->sr_sense_buffer)];
	char res_used;		/* 1 -> using reserve buffer, 0 -> not ... */
	char orphan;		/* 1 -> drop on sight, 0 -> normal */
	char sg_io_owned;	/* 1 -> packet belongs to SG_IO */
	volatile char done;	/* 0->before bh, 1->before read, 2->read */
} Sg_request;

typedef struct sg_fd {		/* holds the state of a file descriptor */
	struct sg_fd *nextfp;	/* NULL when last opened fd on this device */
	struct sg_device *parentdp;	/* owning device */
	wait_queue_head_t read_wait;	/* queue read until command done */
	rwlock_t rq_list_lock;	/* protect access to list in req_arr */
	int timeout;		/* defaults to SG_DEFAULT_TIMEOUT      */
	int timeout_user;	/* defaults to SG_DEFAULT_TIMEOUT_USER */
	Sg_scatter_hold reserve;	/* buffer held for this file descriptor */
	unsigned save_scat_len;	/* original length of trunc. scat. element */
	Sg_request *headrp;	/* head of request slist, NULL->empty */
	struct fasync_struct *async_qp;	/* used by asynchronous notification */
	Sg_request req_arr[SG_MAX_QUEUE];	/* used as singly-linked list */
	char low_dma;		/* as in parent but possibly overridden to 1 */
	char force_packid;	/* 1 -> pack_id input to read(), 0 -> ignored */
	volatile char closed;	/* 1 -> fd closed but request(s) outstanding */
	char cmd_q;		/* 1 -> allow command queuing, 0 -> don't */
	char next_cmd_len;	/* 0 -> automatic (def), >0 -> use on next write() */
	char keep_orphan;	/* 0 -> drop orphan (def), 1 -> keep for read() */
	char mmap_called;	/* 0 -> mmap() never called on this fd */
} Sg_fd;

typedef struct sg_device { /* holds the state of each scsi generic device */
	struct scsi_device *device;
	wait_queue_head_t o_excl_wait;	/* queue open() when O_EXCL in use */
	int sg_tablesize;	/* adapter's max scatter-gather table size */
	Sg_fd *headfp;		/* first open fd belonging to this device */
	volatile char detached;	/* 0->attached, 1->detached pending removal */
	volatile char exclude;	/* opened for exclusive access */
	char sgdebug;		/* 0->off, 1->sense, 9->dump dev, 10-> all devs */
	struct gendisk *disk;
	struct cdev * cdev;	/* char_dev [sysfs: /sys/cdev/major/sg<n>] */
} Sg_device;

static int sg_fasync(int fd, struct file *filp, int mode);
static void sg_cmd_done(Scsi_Cmnd * SCpnt);	/* tasklet or soft irq callback */
static int sg_start_req(Sg_request * srp);
static void sg_finish_rem_req(Sg_request * srp);
static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
static int sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp,
			 int tablesize);
static ssize_t sg_new_read(Sg_fd * sfp, char __user *buf, size_t count,
			   Sg_request * srp);
static ssize_t sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
			    int blocking, int read_only, Sg_request ** o_srp);
static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
			   unsigned char *cmnd, int timeout, int blocking);
static int sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
		      int wr_xf, int *countp, unsigned char __user **up);
static int sg_write_xfer(Sg_request * srp);
static int sg_read_xfer(Sg_request * srp);
static int sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer);
static void sg_remove_scat(Sg_scatter_hold * schp);
static void sg_build_reserve(Sg_fd * sfp, int req_size);
static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
static char *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
static void sg_page_free(char *buff, int size);
static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
static Sg_request *sg_add_request(Sg_fd * sfp);
static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
static int sg_res_in_use(Sg_fd * sfp);
static int sg_allow_access(unsigned char opcode, char dev_type);
static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
static Sg_device *sg_get_dev(int dev);
static inline unsigned char *sg_scatg2virt(const struct scatterlist *sclp);
#ifdef CONFIG_SCSI_PROC_FS
static int sg_last_dev(void);
#endif

static Sg_device **sg_dev_arr = NULL;
static int sg_dev_max;
static int sg_nr_dev;

#define SZ_SG_HEADER sizeof(struct sg_header)
#define SZ_SG_IO_HDR sizeof(sg_io_hdr_t)
#define SZ_SG_IOVEC sizeof(sg_iovec_t)
#define SZ_SG_REQ_INFO sizeof(sg_req_info_t)

static int
sg_open(struct inode *inode, struct file *filp)
{
	int dev = iminor(inode);
	int flags = filp->f_flags;
	Sg_device *sdp;
	Sg_fd *sfp;
	int res;
	int retval;

	nonseekable_open(inode, filp);
	SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
	sdp = sg_get_dev(dev);
	if ((!sdp) || (!sdp->device))
		return -ENXIO;
	if (sdp->detached)
		return -ENODEV;

	/* This driver's module count bumped by fops_get in <linux/fs.h> */
	/* Prevent the device driver from vanishing while we sleep */
	retval = scsi_device_get(sdp->device);
	if (retval)
		return retval;

	if (!((flags & O_NONBLOCK) ||
	      scsi_block_when_processing_errors(sdp->device))) {
		retval = -ENXIO;
		/* we are in error recovery for this device */
		goto error_out;
	}

	if (flags & O_EXCL) {
		if (O_RDONLY == (flags & O_ACCMODE)) {
			retval = -EPERM; /* Can't lock it with read only access */
			goto error_out;
		}
		if (sdp->headfp && (flags & O_NONBLOCK)) {
			retval = -EBUSY;
			goto error_out;
		}
		res = 0;
		__wait_event_interruptible(sdp->o_excl_wait,
			((sdp->headfp || sdp->exclude) ? 0 : (sdp->exclude = 1)), res);
		if (res) {
			retval = res;	/* -ERESTARTSYS because signal hit process */
			goto error_out;
		}
	} else if (sdp->exclude) {	/* some other fd has an exclusive lock on dev */
		if (flags & O_NONBLOCK) {
			retval = -EBUSY;
			goto error_out;
		}
		res = 0;
		__wait_event_interruptible(sdp->o_excl_wait, (!sdp->exclude),
					   res);
		if (res) {
			retval = res;	/* -ERESTARTSYS because signal hit process */
			goto error_out;
		}
	}
	if (sdp->detached) {
		retval = -ENODEV;
		goto error_out;
	}
	if (!sdp->headfp) {	/* no existing opens on this device */
		sdp->sgdebug = 0;
		sdp->sg_tablesize = sdp->device->host->sg_tablesize;
	}
	if ((sfp = sg_add_sfp(sdp, dev)))
		filp->private_data = sfp;
	else {
		if (flags & O_EXCL)
			sdp->exclude = 0;	/* undo if error */
		retval = -ENOMEM;
		goto error_out;
	}
	return 0;

      error_out:
	scsi_device_put(sdp->device);
	return retval;
}

/* Following function was formerly called 'sg_close' */
static int
sg_release(struct inode *inode, struct file *filp)
{
	Sg_device *sdp;
	Sg_fd *sfp;

	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
		return -ENXIO;
	SCSI_LOG_TIMEOUT(3, printk("sg_release: %s\n", sdp->disk->disk_name));
	sg_fasync(-1, filp, 0);	/* remove filp from async notification list */
	if (0 == sg_remove_sfp(sdp, sfp)) {	/* Returns 1 when sdp gone */
		if (!sdp->detached) {
			scsi_device_put(sdp->device);
		}
		sdp->exclude = 0;
		wake_up_interruptible(&sdp->o_excl_wait);
	}
	return 0;
}

static ssize_t
sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
{
	int res;
	Sg_device *sdp;
	Sg_fd *sfp;
	Sg_request *srp;
	int req_pack_id = -1;
	struct sg_header old_hdr;
	sg_io_hdr_t new_hdr;
	sg_io_hdr_t *hp;

	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
		return -ENXIO;
	SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n",
				   sdp->disk->disk_name, (int) count));
	if (!access_ok(VERIFY_WRITE, buf, count))
		return -EFAULT;
	if (sfp->force_packid && (count >= SZ_SG_HEADER)) {
		if (__copy_from_user(&old_hdr, buf, SZ_SG_HEADER))
			return -EFAULT;
		if (old_hdr.reply_len < 0) {
			if (count >= SZ_SG_IO_HDR) {
				if (__copy_from_user
				    (&new_hdr, buf, SZ_SG_IO_HDR))
					return -EFAULT;
				req_pack_id = new_hdr.pack_id;
			}
		} else
			req_pack_id = old_hdr.pack_id;
	}
	srp = sg_get_rq_mark(sfp, req_pack_id);
	if (!srp) {		/* now wait on packet to arrive */
		if (sdp->detached)
			return -ENODEV;
		if (filp->f_flags & O_NONBLOCK)
			return -EAGAIN;
		while (1) {
			res = 0;	/* following is a macro that beats race condition */
			__wait_event_interruptible(sfp->read_wait,
				(sdp->detached || (srp = sg_get_rq_mark(sfp, req_pack_id))), 
						   res);
			if (sdp->detached)
				return -ENODEV;
			if (0 == res)
				break;
			return res;	/* -ERESTARTSYS because signal hit process */
		}
	}
	if (srp->header.interface_id != '\0')
		return sg_new_read(sfp, buf, count, srp);

	hp = &srp->header;
	memset(&old_hdr, 0, SZ_SG_HEADER);
	old_hdr.reply_len = (int) hp->timeout;
	old_hdr.pack_len = old_hdr.reply_len; /* very old, strange behaviour */
	old_hdr.pack_id = hp->pack_id;
	old_hdr.twelve_byte =
	    ((srp->data.cmd_opcode >= 0xc0) && (12 == hp->cmd_len)) ? 1 : 0;
	old_hdr.target_status = hp->masked_status;
	old_hdr.host_status = hp->host_status;
	old_hdr.driver_status = hp->driver_status;
	if ((CHECK_CONDITION & hp->masked_status) ||
	    (DRIVER_SENSE & hp->driver_status))
		memcpy(old_hdr.sense_buffer, srp->sense_b,
		       sizeof (old_hdr.sense_buffer));
	switch (hp->host_status) {
	/* This setup of 'result' is for backward compatibility and is best
	   ignored by the user who should use target, host + driver status */
	case DID_OK:
	case DID_PASSTHROUGH:
	case DID_SOFT_ERROR:
		old_hdr.result = 0;
		break;
	case DID_NO_CONNECT:
	case DID_BUS_BUSY:
	case DID_TIME_OUT:
		old_hdr.result = EBUSY;
		break;
	case DID_BAD_TARGET:
	case DID_ABORT:
	case DID_PARITY:
	case DID_RESET:
	case DID_BAD_INTR:
		old_hdr.result = EIO;
		break;
	case DID_ERROR:
		old_hdr.result = (srp->sense_b[0] == 0 && 
				  hp->masked_status == GOOD) ? 0 : EIO;
		break;
	default:
		old_hdr.result = EIO;
		break;
	}

	/* Now copy the result back to the user buffer.  */
	if (count >= SZ_SG_HEADER) {
		if (__copy_to_user(buf, &old_hdr, SZ_SG_HEADER))
			return -EFAULT;
		buf += SZ_SG_HEADER;
		if (count > old_hdr.reply_len)
			count = old_hdr.reply_len;
		if (count > SZ_SG_HEADER) {
			if ((res =
			     sg_read_oxfer(srp, buf, count - SZ_SG_HEADER)))
				return -EFAULT;
		}
	} else
		count = (old_hdr.result == 0) ? 0 : -EIO;
	sg_finish_rem_req(srp);
	return count;
}

static ssize_t
sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp)
{
	sg_io_hdr_t *hp = &srp->header;
	int err = 0;
	int len;

	if (count < SZ_SG_IO_HDR) {
		err = -EINVAL;
		goto err_out;
	}
	hp->sb_len_wr = 0;
	if ((hp->mx_sb_len > 0) && hp->sbp) {
		if ((CHECK_CONDITION & hp->masked_status) ||
		    (DRIVER_SENSE & hp->driver_status)) {
			int sb_len = sizeof (dummy_cmdp->sr_sense_buffer);
			sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
			len = 8 + (int) srp->sense_b[7];	/* Additional sense length field */
			len = (len > sb_len) ? sb_len : len;
			if (copy_to_user(hp->sbp, srp->sense_b, len)) {
				err = -EFAULT;
				goto err_out;
			}
			hp->sb_len_wr = len;
		}
	}
	if (hp->masked_status || hp->host_status || hp->driver_status)
		hp->info |= SG_INFO_CHECK;
	if (copy_to_user(buf, hp, SZ_SG_IO_HDR)) {
		err = -EFAULT;
		goto err_out;
	}
	err = sg_read_xfer(srp);
      err_out:
	sg_finish_rem_req(srp);
	return (0 == err) ? count : err;
}

static ssize_t
sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
{
	int mxsize, cmd_size, k;
	int input_size, blocking;
	unsigned char opcode;
	Sg_device *sdp;
	Sg_fd *sfp;
	Sg_request *srp;
	struct sg_header old_hdr;
	sg_io_hdr_t *hp;
	unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];

	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
		return -ENXIO;
	SCSI_LOG_TIMEOUT(3, printk("sg_write: %s, count=%d\n",
				   sdp->disk->disk_name, (int) count));
	if (sdp->detached)
		return -ENODEV;
	if (!((filp->f_flags & O_NONBLOCK) ||
	      scsi_block_when_processing_errors(sdp->device)))
		return -ENXIO;

	if (!access_ok(VERIFY_READ, buf, count))
		return -EFAULT;	/* protects following copy_from_user()s + get_user()s */
	if (count < SZ_SG_HEADER)
		return -EIO;
	if (__copy_from_user(&old_hdr, buf, SZ_SG_HEADER))
		return -EFAULT;
	blocking = !(filp->f_flags & O_NONBLOCK);
	if (old_hdr.reply_len < 0)
		return sg_new_write(sfp, buf, count, blocking, 0, NULL);
	if (count < (SZ_SG_HEADER + 6))
		return -EIO;	/* The minimum scsi command length is 6 bytes. */

	if (!(srp = sg_add_request(sfp))) {
		SCSI_LOG_TIMEOUT(1, printk("sg_write: queue full\n"));
		return -EDOM;
	}
	buf += SZ_SG_HEADER;
	__get_user(opcode, buf);
	if (sfp->next_cmd_len > 0) {
		if (sfp->next_cmd_len > MAX_COMMAND_SIZE) {
			SCSI_LOG_TIMEOUT(1, printk("sg_write: command length too long\n"));
			sfp->next_cmd_len = 0;
			sg_remove_request(sfp, srp);
			return -EIO;
		}
		cmd_size = sfp->next_cmd_len;
		sfp->next_cmd_len = 0;	/* reset so only this write() effected */
	} else {
		cmd_size = COMMAND_SIZE(opcode);	/* based on SCSI command group */
		if ((opcode >= 0xc0) && old_hdr.twelve_byte)
			cmd_size = 12;
	}
	SCSI_LOG_TIMEOUT(4, printk(
		"sg_write:   scsi opcode=0x%02x, cmd_size=%d\n", (int) opcode, cmd_size));
/* Determine buffer size.  */
	input_size = count - cmd_size;
	mxsize = (input_size > old_hdr.reply_len) ? input_size : old_hdr.reply_len;
	mxsize -= SZ_SG_HEADER;
	input_size -= SZ_SG_HEADER;
	if (input_size < 0) {
		sg_remove_request(sfp, srp);
		return -EIO;	/* User did not pass enough bytes for this command. */
	}
	hp = &srp->header;
	hp->interface_id = '\0';	/* indicator of old interface tunnelled */
	hp->cmd_len = (unsigned char) cmd_size;
	hp->iovec_count = 0;
	hp->mx_sb_len = 0;
	if (input_size > 0)
		hp->dxfer_direction = (old_hdr.reply_len > SZ_SG_HEADER) ?
		    SG_DXFER_TO_FROM_DEV : SG_DXFER_TO_DEV;
	else
		hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
	hp->dxfer_len = mxsize;
	hp->dxferp = (char __user *)buf + cmd_size;
	hp->sbp = NULL;
	hp->timeout = old_hdr.reply_len;	/* structure abuse ... */
	hp->flags = input_size;	/* structure abuse ... */
	hp->pack_id = old_hdr.pack_id;
	hp->usr_ptr = NULL;
	if (__copy_from_user(cmnd, buf, cmd_size))
		return -EFAULT;
	/*
	 * SG_DXFER_TO_FROM_DEV is functionally equivalent to SG_DXFER_FROM_DEV,
	 * but is is possible that the app intended SG_DXFER_TO_DEV, because there
	 * is a non-zero input_size, so emit a warning.
	 */
	if (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV)
		if (printk_ratelimit())
			printk(KERN_WARNING
			       "sg_write: data in/out %d/%d bytes for SCSI command 0x%x--"
			       "guessing data in;\n" KERN_WARNING "   "
			       "program %s not setting count and/or reply_len properly\n",
			       old_hdr.reply_len - (int)SZ_SG_HEADER,
			       input_size, (unsigned int) cmnd[0],
			       current->comm);
	k = sg_common_write(sfp, srp, cmnd, sfp->timeout, blocking);
	return (k < 0) ? k : count;
}

static ssize_t
sg_new_write(Sg_fd * sfp, const char __user *buf, size_t count,
	     int blocking, int read_only, Sg_request ** o_srp)
{
	int k;
	Sg_request *srp;
	sg_io_hdr_t *hp;
	unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];
	int timeout;
	unsigned long ul_timeout;

	if (count < SZ_SG_IO_HDR)
		return -EINVAL;
	if (!access_ok(VERIFY_READ, buf, count))
		return -EFAULT; /* protects following copy_from_user()s + get_user()s */

	sfp->cmd_q = 1;	/* when sg_io_hdr seen, set command queuing on */
	if (!(srp = sg_add_request(sfp))) {
		SCSI_LOG_TIMEOUT(1, printk("sg_new_write: queue full\n"));
		return -EDOM;
	}
	hp = &srp->header;
	if (__copy_from_user(hp, buf, SZ_SG_IO_HDR)) {
		sg_remove_request(sfp, srp);
		return -EFAULT;
	}
	if (hp->interface_id != 'S') {
		sg_remove_request(sfp, srp);
		return -ENOSYS;
	}
	if (hp->flags & SG_FLAG_MMAP_IO) {
		if (hp->dxfer_len > sfp->reserve.bufflen) {
			sg_remove_request(sfp, srp);
			return -ENOMEM;	/* MMAP_IO size must fit in reserve buffer */
		}
		if (hp->flags & SG_FLAG_DIRECT_IO) {
			sg_remove_request(sfp, srp);
			return -EINVAL;	/* either MMAP_IO or DIRECT_IO (not both) */
		}
		if (sg_res_in_use(sfp)) {
			sg_remove_request(sfp, srp);
			return -EBUSY;	/* reserve buffer already being used */
		}
	}
	ul_timeout = msecs_to_jiffies(srp->header.timeout);
	timeout = (ul_timeout < INT_MAX) ? ul_timeout : INT_MAX;
	if ((!hp->cmdp) || (hp->cmd_len < 6) || (hp->cmd_len > sizeof (cmnd))) {
		sg_remove_request(sfp, srp);
		return -EMSGSIZE;
	}
	if (!access_ok(VERIFY_READ, hp->cmdp, hp->cmd_len)) {
		sg_remove_request(sfp, srp);
		return -EFAULT;	/* protects following copy_from_user()s + get_user()s */
	}
	if (__copy_from_user(cmnd, hp->cmdp, hp->cmd_len)) {
		sg_remove_request(sfp, srp);
		return -EFAULT;
	}
	if (read_only &&
	    (!sg_allow_access(cmnd[0], sfp->parentdp->device->type))) {
		sg_remove_request(sfp, srp);
		return -EPERM;
	}
	k = sg_common_write(sfp, srp, cmnd, timeout, blocking);
	if (k < 0)
		return k;
	if (o_srp)
		*o_srp = srp;
	return count;
}

static int
sg_common_write(Sg_fd * sfp, Sg_request * srp,
		unsigned char *cmnd, int timeout, int blocking)
{
	int k;
	Scsi_Request *SRpnt;
	Sg_device *sdp = sfp->parentdp;
	sg_io_hdr_t *hp = &srp->header;
	request_queue_t *q;

	srp->data.cmd_opcode = cmnd[0];	/* hold opcode of command */
	hp->status = 0;
	hp->masked_status = 0;
	hp->msg_status = 0;
	hp->info = 0;
	hp->host_status = 0;
	hp->driver_status = 0;
	hp->resid = 0;
	SCSI_LOG_TIMEOUT(4, printk("sg_common_write:  scsi opcode=0x%02x, cmd_size=%d\n",
			  (int) cmnd[0], (int) hp->cmd_len));

	if ((k = sg_start_req(srp))) {
		SCSI_LOG_TIMEOUT(1, printk("sg_write: start_req err=%d\n", k));
		sg_finish_rem_req(srp);
		return k;	/* probably out of space --> ENOMEM */
	}
	if ((k = sg_write_xfer(srp))) {
		SCSI_LOG_TIMEOUT(1, printk("sg_write: write_xfer, bad address\n"));
		sg_finish_rem_req(srp);
		return k;
	}
	if (sdp->detached) {
		sg_finish_rem_req(srp);
		return -ENODEV;
	}
	SRpnt = scsi_allocate_request(sdp->device, GFP_ATOMIC);
	if (SRpnt == NULL) {
		SCSI_LOG_TIMEOUT(1, printk("sg_write: no mem\n"));
		sg_finish_rem_req(srp);
		return -ENOMEM;
	}

	srp->my_cmdp = SRpnt;
	q = SRpnt->sr_device->request_queue;
	SRpnt->sr_request->rq_disk = sdp->disk;
	SRpnt->sr_sense_buffer[0] = 0;
	SRpnt->sr_cmd_len = hp->cmd_len;
	SRpnt->sr_use_sg = srp->data.k_use_sg;
	SRpnt->sr_sglist_len = srp->data.sglist_len;
	SRpnt->sr_bufflen = srp->data.bufflen;
	SRpnt->sr_underflow = 0;
	SRpnt->sr_buffer = srp->data.buffer;
	switch (hp->dxfer_direction) {
	case SG_DXFER_TO_FROM_DEV:
	case SG_DXFER_FROM_DEV:
		SRpnt->sr_data_direction = SCSI_DATA_READ;
		break;
	case SG_DXFER_TO_DEV:
		SRpnt->sr_data_direction = SCSI_DATA_WRITE;
		break;
	case SG_DXFER_UNKNOWN:
		SRpnt->sr_data_direction = SCSI_DATA_UNKNOWN;
		break;
	default:
		SRpnt->sr_data_direction = SCSI_DATA_NONE;
		break;
	}
	SRpnt->upper_private_data = srp;
	srp->data.k_use_sg = 0;
	srp->data.sglist_len = 0;
	srp->data.bufflen = 0;
	srp->data.buffer = NULL;
	hp->duration = jiffies;	/* unit jiffies now, millisecs after done */
/* Now send everything of to mid-level. The next time we hear about this
   packet is when sg_cmd_done() is called (i.e. a callback). */
	scsi_do_req(SRpnt, (void *) cmnd,
		    (void *) SRpnt->sr_buffer, hp->dxfer_len,
		    sg_cmd_done, timeout, SG_DEFAULT_RETRIES);
	/* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
	return 0;
}

static int
sg_srp_done(Sg_request *srp, Sg_fd *sfp)
{
	unsigned long iflags;
	int done;

	read_lock_irqsave(&sfp->rq_list_lock, iflags);
	done = srp->done;
	read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
	return done;
}

static int
sg_ioctl(struct inode *inode, struct file *filp,
	 unsigned int cmd_in, unsigned long arg)
{
	void __user *p = (void __user *)arg;
	int __user *ip = p;
	int result, val, read_only;
	Sg_device *sdp;
	Sg_fd *sfp;
	Sg_request *srp;
	unsigned long iflags;

	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
		return -ENXIO;
	SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: %s, cmd=0x%x\n",
				   sdp->disk->disk_name, (int) cmd_in));
	read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));

	switch (cmd_in) {
	case SG_IO:
		{
			int blocking = 1;	/* ignore O_NONBLOCK flag */

			if (sdp->detached)
				return -ENODEV;
			if (!scsi_block_when_processing_errors(sdp->device))
				return -ENXIO;
			if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
				return -EFAULT;
			result =
			    sg_new_write(sfp, p, SZ_SG_IO_HDR,
					 blocking, read_only, &srp);
			if (result < 0)
				return result;
			srp->sg_io_owned = 1;
			while (1) {
				result = 0;	/* following macro to beat race condition */
				__wait_event_interruptible(sfp->read_wait,
					(sdp->detached || sfp->closed || sg_srp_done(srp, sfp)),
							   result);
				if (sdp->detached)
					return -ENODEV;
				if (sfp->closed)
					return 0;	/* request packet dropped already */
				if (0 == result)
					break;
				srp->orphan = 1;
				return result;	/* -ERESTARTSYS because signal hit process */
			}
			write_lock_irqsave(&sfp->rq_list_lock, iflags);
			srp->done = 2;
			write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
			result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp);
			return (result < 0) ? result : 0;
		}
	case SG_SET_TIMEOUT:
		result = get_user(val, ip);
		if (result)
			return result;
		if (val < 0)
			return -EIO;
		if (val >= MULDIV (INT_MAX, USER_HZ, HZ))
		    val = MULDIV (INT_MAX, USER_HZ, HZ);
		sfp->timeout_user = val;
		sfp->timeout = MULDIV (val, HZ, USER_HZ);

		return 0;
	case SG_GET_TIMEOUT:	/* N.B. User receives timeout as return value */
				/* strange ..., for backward compatibility */
		return sfp->timeout_user;
	case SG_SET_FORCE_LOW_DMA:
		result = get_user(val, ip);
		if (result)
			return result;
		if (val) {
			sfp->low_dma = 1;
			if ((0 == sfp->low_dma) && (0 == sg_res_in_use(sfp))) {
				val = (int) sfp->reserve.bufflen;
				sg_remove_scat(&sfp->reserve);
				sg_build_reserve(sfp, val);
			}
		} else {
			if (sdp->detached)
				return -ENODEV;
			sfp->low_dma = sdp->device->host->unchecked_isa_dma;
		}
		return 0;
	case SG_GET_LOW_DMA:
		return put_user((int) sfp->low_dma, ip);
	case SG_GET_SCSI_ID:
		if (!access_ok(VERIFY_WRITE, p, sizeof (sg_scsi_id_t)))
			return -EFAULT;
		else {
			sg_scsi_id_t __user *sg_idp = p;

			if (sdp->detached)
				return -ENODEV;
			__put_user((int) sdp->device->host->host_no,
				   &sg_idp->host_no);
			__put_user((int) sdp->device->channel,
				   &sg_idp->channel);
			__put_user((int) sdp->device->id, &sg_idp->scsi_id);
			__put_user((int) sdp->device->lun, &sg_idp->lun);
			__put_user((int) sdp->device->type, &sg_idp->scsi_type);
			__put_user((short) sdp->device->host->cmd_per_lun,
				   &sg_idp->h_cmd_per_lun);
			__put_user((short) sdp->device->queue_depth,
				   &sg_idp->d_queue_depth);
			__put_user(0, &sg_idp->unused[0]);
			__put_user(0, &sg_idp->unused[1]);
			return 0;
		}
	case SG_SET_FORCE_PACK_ID:
		result = get_user(val, ip);
		if (result)
			return result;
		sfp->force_packid = val ? 1 : 0;
		return 0;
	case SG_GET_PACK_ID:
		if (!access_ok(VERIFY_WRITE, ip, sizeof (int)))
			return -EFAULT;
		read_lock_irqsave(&sfp->rq_list_lock, iflags);
		for (srp = sfp->headrp; srp; srp = srp->nextrp) {
			if ((1 == srp->done) && (!srp->sg_io_owned)) {
				read_unlock_irqrestore(&sfp->rq_list_lock,
						       iflags);
				__put_user(srp->header.pack_id, ip);
				return 0;
			}
		}
		read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
		__put_user(-1, ip);
		return 0;
	case SG_GET_NUM_WAITING:
		read_lock_irqsave(&sfp->rq_list_lock, iflags);
		for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) {
			if ((1 == srp->done) && (!srp->sg_io_owned))
				++val;
		}
		read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
		return put_user(val, ip);
	case SG_GET_SG_TABLESIZE:
		return put_user(sdp->sg_tablesize, ip);
	case SG_SET_RESERVED_SIZE:
		result = get_user(val, ip);
		if (result)
			return result;
                if (val < 0)
                        return -EINVAL;
		if (val != sfp->reserve.bufflen) {
			if (sg_res_in_use(sfp) || sfp->mmap_called)
				return -EBUSY;
			sg_remove_scat(&sfp->reserve);
			sg_build_reserve(sfp, val);
		}
		return 0;
	case SG_GET_RESERVED_SIZE:
		val = (int) sfp->reserve.bufflen;
		return put_user(val, ip);
	case SG_SET_COMMAND_Q:
		result = get_user(val, ip);
		if (result)
			return result;
		sfp->cmd_q = val ? 1 : 0;
		return 0;
	case SG_GET_COMMAND_Q:
		return put_user((int) sfp->cmd_q, ip);
	case SG_SET_KEEP_ORPHAN:
		result = get_user(val, ip);
		if (result)
			return result;
		sfp->keep_orphan = val;
		return 0;
	case SG_GET_KEEP_ORPHAN:
		return put_user((int) sfp->keep_orphan, ip);
	case SG_NEXT_CMD_LEN:
		result = get_user(val, ip);
		if (result)
			return result;
		sfp->next_cmd_len = (val > 0) ? val : 0;
		return 0;
	case SG_GET_VERSION_NUM:
		return put_user(sg_version_num, ip);
	case SG_GET_ACCESS_COUNT:
		/* faked - we don't have a real access count anymore */
		val = (sdp->device ? 1 : 0);
		return put_user(val, ip);
	case SG_GET_REQUEST_TABLE:
		if (!access_ok(VERIFY_WRITE, p, SZ_SG_REQ_INFO * SG_MAX_QUEUE))
			return -EFAULT;
		else {
			sg_req_info_t rinfo[SG_MAX_QUEUE];
			Sg_request *srp;
			read_lock_irqsave(&sfp->rq_list_lock, iflags);
			for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
			     ++val, srp = srp ? srp->nextrp : srp) {
				memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
				if (srp) {
					rinfo[val].req_state = srp->done + 1;
					rinfo[val].problem =
					    srp->header.masked_status & 
					    srp->header.host_status & 
					    srp->header.driver_status;
					rinfo[val].duration =
					    srp->done ? srp->header.duration :
					    jiffies_to_msecs(
						jiffies - srp->header.duration);
					rinfo[val].orphan = srp->orphan;
					rinfo[val].sg_io_owned = srp->sg_io_owned;
					rinfo[val].pack_id = srp->header.pack_id;
					rinfo[val].usr_ptr = srp->header.usr_ptr;
				}
			}
			read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
			return (__copy_to_user(p, rinfo,
			        SZ_SG_REQ_INFO * SG_MAX_QUEUE) ? -EFAULT : 0);
		}
	case SG_EMULATED_HOST:
		if (sdp->detached)
			return -ENODEV;
		return put_user(sdp->device->host->hostt->emulated, ip);
	case SG_SCSI_RESET:
		if (sdp->detached)
			return -ENODEV;
		if (filp->f_flags & O_NONBLOCK) {
			if (test_bit(SHOST_RECOVERY,
				     &sdp->device->host->shost_state))
				return -EBUSY;
		} else if (!scsi_block_when_processing_errors(sdp->device))
			return -EBUSY;
		result = get_user(val, ip);
		if (result)
			return result;
		if (SG_SCSI_RESET_NOTHING == val)
			return 0;
		switch (val) {
		case SG_SCSI_RESET_DEVICE:
			val = SCSI_TRY_RESET_DEVICE;
			break;
		case SG_SCSI_RESET_BUS:
			val = SCSI_TRY_RESET_BUS;
			break;
		case SG_SCSI_RESET_HOST:
			val = SCSI_TRY_RESET_HOST;
			break;
		default:
			return -EINVAL;
		}
		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
			return -EACCES;
		return (scsi_reset_provider(sdp->device, val) ==
			SUCCESS) ? 0 : -EIO;
	case SCSI_IOCTL_SEND_COMMAND:
		if (sdp->detached)
			return -ENODEV;
		if (read_only) {
			unsigned char opcode = WRITE_6;
			Scsi_Ioctl_Command __user *siocp = p;

			if (copy_from_user(&opcode, siocp->data, 1))
				return -EFAULT;
			if (!sg_allow_access(opcode, sdp->device->type))
				return -EPERM;
		}
		return scsi_ioctl_send_command(sdp->device, p);
	case SG_SET_DEBUG:
		result = get_user(val, ip);
		if (result)
			return result;
		sdp->sgdebug = (char) val;
		return 0;
	case SCSI_IOCTL_GET_IDLUN:
	case SCSI_IOCTL_GET_BUS_NUMBER:
	case SCSI_IOCTL_PROBE_HOST:
	case SG_GET_TRANSFORM:
		if (sdp->detached)
			return -ENODEV;
		return scsi_ioctl(sdp->device, cmd_in, p);
	default:
		if (read_only)
			return -EPERM;	/* don't know so take safe approach */
		return scsi_ioctl(sdp->device, cmd_in, p);
	}
}

#ifdef CONFIG_COMPAT
static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
{
	Sg_device *sdp;
	Sg_fd *sfp;
	struct scsi_device *sdev;

	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
		return -ENXIO;

	sdev = sdp->device;
	if (sdev->host->hostt->compat_ioctl) { 
		int ret;

		ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);

		return ret;
	}
	
	return -ENOIOCTLCMD;
}
#endif

static unsigned int
sg_poll(struct file *filp, poll_table * wait)
{
	unsigned int res = 0;
	Sg_device *sdp;
	Sg_fd *sfp;
	Sg_request *srp;
	int count = 0;
	unsigned long iflags;

	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))
	    || sfp->closed)
		return POLLERR;
	poll_wait(filp, &sfp->read_wait, wait);
	read_lock_irqsave(&sfp->rq_list_lock, iflags);
	for (srp = sfp->headrp; srp; srp = srp->nextrp) {
		/* if any read waiting, flag it */
		if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned))
			res = POLLIN | POLLRDNORM;
		++count;
	}
	read_unlock_irqrestore(&sfp->rq_list_lock, iflags);

	if (sdp->detached)
		res |= POLLHUP;
	else if (!sfp->cmd_q) {
		if (0 == count)
			res |= POLLOUT | POLLWRNORM;
	} else if (count < SG_MAX_QUEUE)
		res |= POLLOUT | POLLWRNORM;
	SCSI_LOG_TIMEOUT(3, printk("sg_poll: %s, res=0x%x\n",
				   sdp->disk->disk_name, (int) res));
	return res;
}

static int
sg_fasync(int fd, struct file *filp, int mode)
{
	int retval;
	Sg_device *sdp;
	Sg_fd *sfp;

	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
		return -ENXIO;
	SCSI_LOG_TIMEOUT(3, printk("sg_fasync: %s, mode=%d\n",
				   sdp->disk->disk_name, mode));

	retval = fasync_helper(fd, filp, mode, &sfp->async_qp);
	return (retval < 0) ? retval : 0;
}

static inline unsigned char *
sg_scatg2virt(const struct scatterlist *sclp)
{
	return (sclp && sclp->page) ?
	    (unsigned char *) page_address(sclp->page) + sclp->offset : NULL;
}

/* When startFinish==1 increments page counts for pages other than the 
   first of scatter gather elements obtained from __get_free_pages().
   When startFinish==0 decrements ... */
static void
sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish)
{
	void *page_ptr;
	struct page *page;
	int k, m;

	SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, scatg=%d\n", 
				   startFinish, rsv_schp->k_use_sg));
	/* N.B. correction _not_ applied to base page of each allocation */
	if (rsv_schp->k_use_sg) {	/* reserve buffer is a scatter gather list */
		struct scatterlist *sclp = rsv_schp->buffer;

		for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
			for (m = PAGE_SIZE; m < sclp->length; m += PAGE_SIZE) {
				page_ptr = sg_scatg2virt(sclp) + m;
				page = virt_to_page(page_ptr);
				if (startFinish)
					get_page(page);
				else {
					if (page_count(page) > 0)
						__put_page(page);
				}
			}
		}
	} else {		/* reserve buffer is just a single allocation */
		for (m = PAGE_SIZE; m < rsv_schp->bufflen; m += PAGE_SIZE) {
			page_ptr = (unsigned char *) rsv_schp->buffer + m;
			page = virt_to_page(page_ptr);
			if (startFinish)
				get_page(page);
			else {
				if (page_count(page) > 0)
					__put_page(page);
			}
		}
	}
}

static struct page *
sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
{
	Sg_fd *sfp;
	struct page *page = NOPAGE_SIGBUS;
	void *page_ptr = NULL;
	unsigned long offset;
	Sg_scatter_hold *rsv_schp;

	if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data)))
		return page;
	rsv_schp = &sfp->reserve;
	offset = addr - vma->vm_start;
	if (offset >= rsv_schp->bufflen)
		return page;
	SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n",
				   offset, rsv_schp->k_use_sg));
	if (rsv_schp->k_use_sg) {	/* reserve buffer is a scatter gather list */
		int k;
		unsigned long sa = vma->vm_start;
		unsigned long len;
		struct scatterlist *sclp = rsv_schp->buffer;

		for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
		     ++k, ++sclp) {
			len = vma->vm_end - sa;
			len = (len < sclp->length) ? len : sclp->length;
			if (offset < len) {
				page_ptr = sg_scatg2virt(sclp) + offset;
				page = virt_to_page(page_ptr);
				get_page(page);	/* increment page count */
				break;
			}
			sa += len;
			offset -= len;
		}
	} else {		/* reserve buffer is just a single allocation */
		page_ptr = (unsigned char *) rsv_schp->buffer + offset;
		page = virt_to_page(page_ptr);
		get_page(page);	/* increment page count */
	}
	if (type)
		*type = VM_FAULT_MINOR;
	return page;
}

static struct vm_operations_struct sg_mmap_vm_ops = {
	.nopage = sg_vma_nopage,
};

static int
sg_mmap(struct file *filp, struct vm_area_struct *vma)
{
	Sg_fd *sfp;
	unsigned long req_sz = vma->vm_end - vma->vm_start;
	Sg_scatter_hold *rsv_schp;

	if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
		return -ENXIO;
	SCSI_LOG_TIMEOUT(3, printk("sg_mmap starting, vm_start=%p, len=%d\n",
				   (void *) vma->vm_start, (int) req_sz));
	if (vma->vm_pgoff)
		return -EINVAL;	/* want no offset */
	rsv_schp = &sfp->reserve;
	if (req_sz > rsv_schp->bufflen)
		return -ENOMEM;	/* cannot map more than reserved buffer */

	if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
		int k;
		unsigned long sa = vma->vm_start;
		unsigned long len;
		struct scatterlist *sclp = rsv_schp->buffer;

		for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
		     ++k, ++sclp) {
			if (0 != sclp->offset)
				return -EFAULT;	/* non page aligned memory ?? */
			len = vma->vm_end - sa;
			len = (len < sclp->length) ? len : sclp->length;
			sa += len;
		}
	} else {	/* reserve buffer is just a single allocation */
		if ((unsigned long) rsv_schp->buffer & (PAGE_SIZE - 1))
			return -EFAULT;	/* non page aligned memory ?? */
	}
	if (0 == sfp->mmap_called) {
		sg_rb_correct4mmap(rsv_schp, 1);	/* do only once per fd lifetime */
		sfp->mmap_called = 1;
	}
	vma->vm_flags |= (VM_RESERVED | VM_IO);
	vma->vm_private_data = sfp;
	vma->vm_ops = &sg_mmap_vm_ops;
	return 0;
}

/* This function is a "bottom half" handler that is called by the
 * mid level when a command is completed (or has failed). */
static void
sg_cmd_done(Scsi_Cmnd * SCpnt)
{
	Scsi_Request *SRpnt = NULL;
	Sg_device *sdp = NULL;
	Sg_fd *sfp;
	Sg_request *srp = NULL;
	unsigned long iflags;

	if (SCpnt && (SRpnt = SCpnt->sc_request))
		srp = (Sg_request *) SRpnt->upper_private_data;
	if (NULL == srp) {
		printk(KERN_ERR "sg_cmd_done: NULL request\n");
		if (SRpnt)
			scsi_release_request(SRpnt);
		return;
	}
	sfp = srp->parentfp;
	if (sfp)
		sdp = sfp->parentdp;
	if ((NULL == sdp) || sdp->detached) {
		printk(KERN_INFO "sg_cmd_done: device detached\n");
		scsi_release_request(SRpnt);
		return;
	}

	/* First transfer ownership of data buffers to sg_device object. */
	srp->data.k_use_sg = SRpnt->sr_use_sg;
	srp->data.sglist_len = SRpnt->sr_sglist_len;
	srp->data.bufflen = SRpnt->sr_bufflen;
	srp->data.buffer = SRpnt->sr_buffer;
	/* now clear out request structure */
	SRpnt->sr_use_sg = 0;
	SRpnt->sr_sglist_len = 0;
	SRpnt->sr_bufflen = 0;
	SRpnt->sr_buffer = NULL;
	SRpnt->sr_underflow = 0;
	SRpnt->sr_request->rq_disk = NULL; /* "sg" _disowns_ request blk */

	srp->my_cmdp = NULL;

	SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
		sdp->disk->disk_name, srp->header.pack_id, (int) SRpnt->sr_result));
	srp->header.resid = SCpnt->resid;
	/* N.B. unit of duration changes here from jiffies to millisecs */
	srp->header.duration =
	    jiffies_to_msecs(jiffies - srp->header.duration);
	if (0 != SRpnt->sr_result) {
		struct scsi_sense_hdr sshdr;

		memcpy(srp->sense_b, SRpnt->sr_sense_buffer,
		       sizeof (srp->sense_b));
		srp->header.status = 0xff & SRpnt->sr_result;
		srp->header.masked_status = status_byte(SRpnt->sr_result);
		srp->header.msg_status = msg_byte(SRpnt->sr_result);
		srp->header.host_status = host_byte(SRpnt->sr_result);
		srp->header.driver_status = driver_byte(SRpnt->sr_result);
		if ((sdp->sgdebug > 0) &&
		    ((CHECK_CONDITION == srp->header.masked_status) ||
		     (COMMAND_TERMINATED == srp->header.masked_status)))
			print_req_sense("sg_cmd_done", SRpnt);

		/* Following if statement is a patch supplied by Eric Youngdale */
		if (driver_byte(SRpnt->sr_result) != 0
		    && scsi_command_normalize_sense(SCpnt, &sshdr)
		    && !scsi_sense_is_deferred(&sshdr)
		    && sshdr.sense_key == UNIT_ATTENTION
		    && sdp->device->removable) {
			/* Detected possible disc change. Set the bit - this */
			/* may be used if there are filesystems using this device */
			sdp->device->changed = 1;
		}
	}
	/* Rely on write phase to clean out srp status values, so no "else" */

	scsi_release_request(SRpnt);
	SRpnt = NULL;
	if (sfp->closed) {	/* whoops this fd already released, cleanup */
		SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, freeing ...\n"));
		sg_finish_rem_req(srp);
		srp = NULL;
		if (NULL == sfp->headrp) {
			SCSI_LOG_TIMEOUT(1, printk("sg...bh: already closed, final cleanup\n"));
			if (0 == sg_remove_sfp(sdp, sfp)) {	/* device still present */
				scsi_device_put(sdp->device);
			}
			sfp = NULL;
		}
	} else if (srp && srp->orphan) {
		if (sfp->keep_orphan)
			srp->sg_io_owned = 0;
		else {
			sg_finish_rem_req(srp);
			srp = NULL;
		}
	}
	if (sfp && srp) {
		/* Now wake up any sg_read() that is waiting for this packet. */
		kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
		write_lock_irqsave(&sfp->rq_list_lock, iflags);
		srp->done = 1;
		wake_up_interruptible(&sfp->read_wait);
		write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
	}
}

static struct file_operations sg_fops = {
	.owner = THIS_MODULE,
	.read = sg_read,
	.write = sg_write,
	.poll = sg_poll,
	.ioctl = sg_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = sg_compat_ioctl,
#endif
	.open = sg_open,
	.mmap = sg_mmap,
	.release = sg_release,
	.fasync = sg_fasync,
};

static struct class_simple * sg_sysfs_class;

static int sg_sysfs_valid = 0;

static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
{
	Sg_device *sdp;
	unsigned long iflags;
	void *old_sg_dev_arr = NULL;
	int k, error;

	sdp = kmalloc(sizeof(Sg_device), GFP_KERNEL);
	if (!sdp) {
		printk(KERN_WARNING "kmalloc Sg_device failure\n");
		return -ENOMEM;
	}

	write_lock_irqsave(&sg_dev_arr_lock, iflags);
	if (unlikely(sg_nr_dev >= sg_dev_max)) {	/* try to resize */
		Sg_device **tmp_da;
		int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP;
		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);

		tmp_da = kmalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL);
		if (unlikely(!tmp_da))
			goto expand_failed;

		write_lock_irqsave(&sg_dev_arr_lock, iflags);
		memset(tmp_da, 0, tmp_dev_max * sizeof(Sg_device *));
		memcpy(tmp_da, sg_dev_arr, sg_dev_max * sizeof(Sg_device *));
		old_sg_dev_arr = sg_dev_arr;
		sg_dev_arr = tmp_da;
		sg_dev_max = tmp_dev_max;
	}

	for (k = 0; k < sg_dev_max; k++)
		if (!sg_dev_arr[k])
			break;
	if (unlikely(k >= SG_MAX_DEVS))
		goto overflow;

	memset(sdp, 0, sizeof(*sdp));
	SCSI_LOG_TIMEOUT(3, printk("sg_alloc: dev=%d \n", k));
	sprintf(disk->disk_name, "sg%d", k);
	disk->first_minor = k;
	sdp->disk = disk;
	sdp->device = scsidp;
	init_waitqueue_head(&sdp->o_excl_wait);
	sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;

	sg_nr_dev++;
	sg_dev_arr[k] = sdp;
	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
	error = k;

 out:
	if (error < 0)
		kfree(sdp);
	kfree(old_sg_dev_arr);
	return error;

 expand_failed:
	printk(KERN_WARNING "sg_alloc: device array cannot be resized\n");
	error = -ENOMEM;
	goto out;

 overflow:
	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
	printk(KERN_WARNING
	       "Unable to attach sg device <%d, %d, %d, %d> type=%d, minor "
	       "number exceeds %d\n", scsidp->host->host_no, scsidp->channel,
	       scsidp->id, scsidp->lun, scsidp->type, SG_MAX_DEVS - 1);
	error = -ENODEV;
	goto out;
}

static int
sg_add(struct class_device *cl_dev)
{
	struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
	struct gendisk *disk;
	Sg_device *sdp = NULL;
	struct cdev * cdev = NULL;
	int error, k;

	disk = alloc_disk(1);
	if (!disk) {
		printk(KERN_WARNING "alloc_disk failed\n");
		return -ENOMEM;
	}
	disk->major = SCSI_GENERIC_MAJOR;

	error = -ENOMEM;
	cdev = cdev_alloc();
	if (!cdev) {
		printk(KERN_WARNING "cdev_alloc failed\n");
		goto out;
	}
	cdev->owner = THIS_MODULE;
	cdev->ops = &sg_fops;

	error = sg_alloc(disk, scsidp);
	if (error < 0) {
		printk(KERN_WARNING "sg_alloc failed\n");
		goto out;
	}
	k = error;
	sdp = sg_dev_arr[k];

	devfs_mk_cdev(MKDEV(SCSI_GENERIC_MAJOR, k),
			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
			"%s/generic", scsidp->devfs_name);
	error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1);
	if (error) {
		devfs_remove("%s/generic", scsidp->devfs_name);
		goto out;
	}
	sdp->cdev = cdev;
	if (sg_sysfs_valid) {
		struct class_device * sg_class_member;

		sg_class_member = class_simple_device_add(sg_sysfs_class, 
				MKDEV(SCSI_GENERIC_MAJOR, k), 
				cl_dev->dev, "%s", 
				disk->disk_name);
		if (IS_ERR(sg_class_member))
			printk(KERN_WARNING "sg_add: "
				"class_simple_device_add failed\n");
		class_set_devdata(sg_class_member, sdp);
		error = sysfs_create_link(&scsidp->sdev_gendev.kobj, 
					  &sg_class_member->kobj, "generic");
		if (error)
			printk(KERN_ERR "sg_add: unable to make symlink "
					"'generic' back to sg%d\n", k);
	} else
		printk(KERN_WARNING "sg_add: sg_sys INvalid\n");

	printk(KERN_NOTICE
	       "Attached scsi generic sg%d at scsi%d, channel"
	       " %d, id %d, lun %d,  type %d\n", k,
	       scsidp->host->host_no, scsidp->channel, scsidp->id,
	       scsidp->lun, scsidp->type);

	return 0;

out:
	put_disk(disk);
	if (cdev)
		cdev_del(cdev);
	return error;
}

static void
sg_remove(struct class_device *cl_dev)
{
	struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
	Sg_device *sdp = NULL;
	unsigned long iflags;
	Sg_fd *sfp;
	Sg_fd *tsfp;
	Sg_request *srp;
	Sg_request *tsrp;
	int k, delay;

	if (NULL == sg_dev_arr)
		return;
	delay = 0;
	write_lock_irqsave(&sg_dev_arr_lock, iflags);
	for (k = 0; k < sg_dev_max; k++) {
		sdp = sg_dev_arr[k];
		if ((NULL == sdp) || (sdp->device != scsidp))
			continue;	/* dirty but lowers nesting */
		if (sdp->headfp) {
			sdp->detached = 1;
			for (sfp = sdp->headfp; sfp; sfp = tsfp) {
				tsfp = sfp->nextfp;
				for (srp = sfp->headrp; srp; srp = tsrp) {
					tsrp = srp->nextrp;
					if (sfp->closed || (0 == sg_srp_done(srp, sfp)))
						sg_finish_rem_req(srp);
				}
				if (sfp->closed) {
					scsi_device_put(sdp->device);
					__sg_remove_sfp(sdp, sfp);
				} else {
					delay = 1;
					wake_up_interruptible(&sfp->read_wait);
					kill_fasync(&sfp->async_qp, SIGPOLL,
						    POLL_HUP);
				}
			}
			SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k));
			if (NULL == sdp->headfp) {
				sg_dev_arr[k] = NULL;
			}
		} else {	/* nothing active, simple case */
			SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k));
			sg_dev_arr[k] = NULL;
		}
		sg_nr_dev--;
		break;
	}
	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);

	if (sdp) {
		sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic");
		class_simple_device_remove(MKDEV(SCSI_GENERIC_MAJOR, k));
		cdev_del(sdp->cdev);
		sdp->cdev = NULL;
		devfs_remove("%s/generic", scsidp->devfs_name);
		put_disk(sdp->disk);
		sdp->disk = NULL;
		if (NULL == sdp->headfp)
			kfree((char *) sdp);
	}

	if (delay)
		msleep(10);	/* dirty detach so delay device destruction */
}

/* Set 'perm' (4th argument) to 0 to disable module_param's definition
 * of sysfs parameters (which module_param doesn't yet support).
 * Sysfs parameters defined explicitly below.
 */
module_param_named(def_reserved_size, def_reserved_size, int, S_IRUGO);
module_param_named(allow_dio, sg_allow_dio, int, S_IRUGO | S_IWUSR);

MODULE_AUTHOR("Douglas Gilbert");
MODULE_DESCRIPTION("SCSI generic (sg) driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(SG_VERSION_STR);

MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
MODULE_PARM_DESC(allow_dio, "allow direct I/O (default: 0 (disallow))");

static int __init
init_sg(void)
{
	int rc;

	if (def_reserved_size >= 0)
		sg_big_buff = def_reserved_size;

	rc = register_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), 
				    SG_MAX_DEVS, "sg");
	if (rc)
		return rc;
        sg_sysfs_class = class_simple_create(THIS_MODULE, "scsi_generic");
        if ( IS_ERR(sg_sysfs_class) ) {
		rc = PTR_ERR(sg_sysfs_class);
		goto err_out;
        }
	sg_sysfs_valid = 1;
	rc = scsi_register_interface(&sg_interface);
	if (0 == rc) {
#ifdef CONFIG_SCSI_PROC_FS
		sg_proc_init();
#endif				/* CONFIG_SCSI_PROC_FS */
		return 0;
	}
	class_simple_destroy(sg_sysfs_class);
err_out:
	unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), SG_MAX_DEVS);
	return rc;
}

static void __exit
exit_sg(void)
{
#ifdef CONFIG_SCSI_PROC_FS
	sg_proc_cleanup();
#endif				/* CONFIG_SCSI_PROC_FS */
	scsi_unregister_interface(&sg_interface);
	class_simple_destroy(sg_sysfs_class);
	sg_sysfs_valid = 0;
	unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
				 SG_MAX_DEVS);
	if (sg_dev_arr != NULL) {
		kfree((char *) sg_dev_arr);
		sg_dev_arr = NULL;
	}
	sg_dev_max = 0;
}

static int
sg_start_req(Sg_request * srp)
{
	int res;
	Sg_fd *sfp = srp->parentfp;
	sg_io_hdr_t *hp = &srp->header;
	int dxfer_len = (int) hp->dxfer_len;
	int dxfer_dir = hp->dxfer_direction;
	Sg_scatter_hold *req_schp = &srp->data;
	Sg_scatter_hold *rsv_schp = &sfp->reserve;

	SCSI_LOG_TIMEOUT(4, printk("sg_start_req: dxfer_len=%d\n", dxfer_len));
	if ((dxfer_len <= 0) || (dxfer_dir == SG_DXFER_NONE))
		return 0;
	if (sg_allow_dio && (hp->flags & SG_FLAG_DIRECT_IO) &&
	    (dxfer_dir != SG_DXFER_UNKNOWN) && (0 == hp->iovec_count) &&
	    (!sfp->parentdp->device->host->unchecked_isa_dma)) {
		res = sg_build_direct(srp, sfp, dxfer_len);
		if (res <= 0)	/* -ve -> error, 0 -> done, 1 -> try indirect */
			return res;
	}
	if ((!sg_res_in_use(sfp)) && (dxfer_len <= rsv_schp->bufflen))
		sg_link_reserve(sfp, srp, dxfer_len);
	else {
		res = sg_build_indirect(req_schp, sfp, dxfer_len);
		if (res) {
			sg_remove_scat(req_schp);
			return res;
		}
	}
	return 0;
}

static void
sg_finish_rem_req(Sg_request * srp)
{
	Sg_fd *sfp = srp->parentfp;
	Sg_scatter_hold *req_schp = &srp->data;

	SCSI_LOG_TIMEOUT(4, printk("sg_finish_rem_req: res_used=%d\n", (int) srp->res_used));
	if (srp->res_used)
		sg_unlink_reserve(sfp, srp);
	else
		sg_remove_scat(req_schp);
	sg_remove_request(sfp, srp);
}

static int
sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
{
	int ret_sz;
	int elem_sz = sizeof (struct scatterlist);
	int sg_bufflen = tablesize * elem_sz;
	int mx_sc_elems = tablesize;

	schp->buffer = sg_page_malloc(sg_bufflen, sfp->low_dma, &ret_sz);
	if (!schp->buffer)
		return -ENOMEM;
	else if (ret_sz != sg_bufflen) {
		sg_bufflen = ret_sz;
		mx_sc_elems = sg_bufflen / elem_sz;
	}
	schp->sglist_len = sg_bufflen;
	memset(schp->buffer, 0, sg_bufflen);
	return mx_sc_elems;	/* number of scat_gath elements allocated */
}

#ifdef SG_ALLOW_DIO_CODE
/* vvvvvvvv  following code borrowed from st driver's direct IO vvvvvvvvv */
	/* hopefully this generic code will moved to a library */

/* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
   - mapping of all pages not successful
   - any page is above max_pfn
   (i.e., either completely successful or fails)
*/
static int 
st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
	          unsigned long uaddr, size_t count, int rw,
	          unsigned long max_pfn)
{
	int res, i, j;
	unsigned int nr_pages;
	struct page **pages;

	nr_pages = ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;

	/* User attempted Overflow! */
	if ((uaddr + count) < uaddr)
		return -EINVAL;

	/* Too big */
        if (nr_pages > max_pages)
		return -ENOMEM;

	/* Hmm? */
	if (count == 0)
		return 0;

	if ((pages = kmalloc(max_pages * sizeof(*pages), GFP_ATOMIC)) == NULL)
		return -ENOMEM;

        /* Try to fault in all of the necessary pages */
	down_read(&current->mm->mmap_sem);
        /* rw==READ means read from drive, write into memory area */
	res = get_user_pages(
		current,
		current->mm,
		uaddr,
		nr_pages,
		rw == READ,
		0, /* don't force */
		pages,
		NULL);
	up_read(&current->mm->mmap_sem);

	/* Errors and no page mapped should return here */
	if (res < nr_pages)
		goto out_unmap;

        for (i=0; i < nr_pages; i++) {
                /* FIXME: flush superflous for rw==READ,
                 * probably wrong function for rw==WRITE
                 */
		flush_dcache_page(pages[i]);
		if (page_to_pfn(pages[i]) > max_pfn)
			goto out_unlock;
		/* ?? Is locking needed? I don't think so */
		/* if (TestSetPageLocked(pages[i]))
		   goto out_unlock; */
        }

	/* Populate the scatter/gather list */
	sgl[0].page = pages[0]; 
	sgl[0].offset = uaddr & ~PAGE_MASK;
	if (nr_pages > 1) {
		sgl[0].length = PAGE_SIZE - sgl[0].offset;
		count -= sgl[0].length;
		for (i=1; i < nr_pages ; i++) {
			sgl[i].offset = 0;
			sgl[i].page = pages[i]; 
			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
			count -= PAGE_SIZE;
		}
	}
	else {
		sgl[0].length = count;
	}

	kfree(pages);
	return nr_pages;

 out_unlock:
	/* for (j=0; j < i; j++)
	   unlock_page(pages[j]); */
	res = 0;
 out_unmap:
	if (res > 0)
		for (j=0; j < res; j++)
			page_cache_release(pages[j]);
	kfree(pages);
	return res;
}


/* And unmap them... */
static int 
st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
		    int dirtied)
{
	int i;

	for (i=0; i < nr_pages; i++) {
		if (dirtied && !PageReserved(sgl[i].page))
			SetPageDirty(sgl[i].page);
		/* unlock_page(sgl[i].page); */
		/* FIXME: cache flush missing for rw==READ
		 * FIXME: call the correct reference counting function
		 */
		page_cache_release(sgl[i].page);
	}

	return 0;
}

/* ^^^^^^^^  above code borrowed from st driver's direct IO ^^^^^^^^^ */
#endif


/* Returns: -ve -> error, 0 -> done, 1 -> try indirect */
static int
sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len)
{
#ifdef SG_ALLOW_DIO_CODE
	sg_io_hdr_t *hp = &srp->header;
	Sg_scatter_hold *schp = &srp->data;
	int sg_tablesize = sfp->parentdp->sg_tablesize;
	struct scatterlist *sgl;
	int mx_sc_elems, res;
	struct scsi_device *sdev = sfp->parentdp->device;

	if (((unsigned long)hp->dxferp &
			queue_dma_alignment(sdev->request_queue)) != 0)
		return 1;
	mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
        if (mx_sc_elems <= 0) {
                return 1;
        }
	sgl = (struct scatterlist *)schp->buffer;
	res = st_map_user_pages(sgl, mx_sc_elems, (unsigned long)hp->dxferp, dxfer_len, 
				(SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0, ULONG_MAX);
	if (res <= 0)
		return 1;
	schp->k_use_sg = res;
	schp->dio_in_use = 1;
	hp->info |= SG_INFO_DIRECT_IO;
	return 0;
#else
	return 1;
#endif
}

static int
sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
{
	int ret_sz;
	int blk_size = buff_size;
	unsigned char *p = NULL;

	if ((blk_size < 0) || (!sfp))
		return -EFAULT;
	if (0 == blk_size)
		++blk_size;	/* don't know why */
/* round request up to next highest SG_SECTOR_SZ byte boundary */
	blk_size = (blk_size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
	SCSI_LOG_TIMEOUT(4, printk("sg_build_indirect: buff_size=%d, blk_size=%d\n",
				   buff_size, blk_size));
	if (blk_size <= SG_SCATTER_SZ) {
		p = sg_page_malloc(blk_size, sfp->low_dma, &ret_sz);
		if (!p)
			return -ENOMEM;
		if (blk_size == ret_sz) {	/* got it on the first attempt */
			schp->k_use_sg = 0;
			schp->buffer = p;
			schp->bufflen = blk_size;
			schp->b_malloc_len = blk_size;
			return 0;
		}
	} else {
		p = sg_page_malloc(SG_SCATTER_SZ, sfp->low_dma, &ret_sz);
		if (!p)
			return -ENOMEM;
	}
/* Want some local declarations, so start new block ... */
	{			/* lets try and build a scatter gather list */
		struct scatterlist *sclp;
		int k, rem_sz, num;
		int mx_sc_elems;
		int sg_tablesize = sfp->parentdp->sg_tablesize;
		int first = 1;

		/* N.B. ret_sz carried into this block ... */
		mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
		if (mx_sc_elems < 0)
			return mx_sc_elems;	/* most likely -ENOMEM */

		for (k = 0, sclp = schp->buffer, rem_sz = blk_size;
		     (rem_sz > 0) && (k < mx_sc_elems);
		     ++k, rem_sz -= ret_sz, ++sclp) {
			if (first)
				first = 0;
			else {
				num =
				    (rem_sz >
				     SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
				p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
				if (!p)
					break;
			}
			sclp->page = virt_to_page(p);
			sclp->offset = offset_in_page(p);
			sclp->length = ret_sz;

			SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
					  k, sg_scatg2virt(sclp), ret_sz));
		}		/* end of for loop */
		schp->k_use_sg = k;
		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
		schp->bufflen = blk_size;
		if (rem_sz > 0)	/* must have failed */
			return -ENOMEM;
	}
	return 0;
}

static int
sg_write_xfer(Sg_request * srp)
{
	sg_io_hdr_t *hp = &srp->header;
	Sg_scatter_hold *schp = &srp->data;
	int num_xfer = 0;
	int j, k, onum, usglen, ksglen, res;
	int iovec_count = (int) hp->iovec_count;
	int dxfer_dir = hp->dxfer_direction;
	unsigned char *p;
	unsigned char __user *up;
	int new_interface = ('\0' == hp->interface_id) ? 0 : 1;

	if ((SG_DXFER_UNKNOWN == dxfer_dir) || (SG_DXFER_TO_DEV == dxfer_dir) ||
	    (SG_DXFER_TO_FROM_DEV == dxfer_dir)) {
		num_xfer = (int) (new_interface ? hp->dxfer_len : hp->flags);
		if (schp->bufflen < num_xfer)
			num_xfer = schp->bufflen;
	}
	if ((num_xfer <= 0) || (schp->dio_in_use) ||
	    (new_interface
	     && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
		return 0;

	SCSI_LOG_TIMEOUT(4, printk("sg_write_xfer: num_xfer=%d, iovec_count=%d, k_use_sg=%d\n",
			  num_xfer, iovec_count, schp->k_use_sg));
	if (iovec_count) {
		onum = iovec_count;
		if (!access_ok(VERIFY_READ, hp->dxferp, SZ_SG_IOVEC * onum))
			return -EFAULT;
	} else
		onum = 1;

	if (0 == schp->k_use_sg) {	/* kernel has single buffer */
		for (j = 0, p = schp->buffer; j < onum; ++j) {
			res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
			if (res)
				return res;
			usglen = (num_xfer > usglen) ? usglen : num_xfer;
			if (__copy_from_user(p, up, usglen))
				return -EFAULT;
			p += usglen;
			num_xfer -= usglen;
			if (num_xfer <= 0)
				return 0;
		}
	} else {		/* kernel using scatter gather list */
		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;

		ksglen = (int) sclp->length;
		p = sg_scatg2virt(sclp);
		for (j = 0, k = 0; j < onum; ++j) {
			res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
			if (res)
				return res;

			for (; p; ++sclp, ksglen = (int) sclp->length,
				  p = sg_scatg2virt(sclp)) {
				if (usglen <= 0)
					break;
				if (ksglen > usglen) {
					if (usglen >= num_xfer) {
						if (__copy_from_user
						    (p, up, num_xfer))
							return -EFAULT;
						return 0;
					}
					if (__copy_from_user(p, up, usglen))
						return -EFAULT;
					p += usglen;
					ksglen -= usglen;
					break;
				} else {
					if (ksglen >= num_xfer) {
						if (__copy_from_user
						    (p, up, num_xfer))
							return -EFAULT;
						return 0;
					}
					if (__copy_from_user(p, up, ksglen))
						return -EFAULT;
					up += ksglen;
					usglen -= ksglen;
				}
				++k;
				if (k >= schp->k_use_sg)
					return 0;
			}
		}
	}
	return 0;
}

static int
sg_u_iovec(sg_io_hdr_t * hp, int sg_num, int ind,
	   int wr_xf, int *countp, unsigned char __user **up)
{
	int num_xfer = (int) hp->dxfer_len;
	unsigned char __user *p = hp->dxferp;
	int count;

	if (0 == sg_num) {
		if (wr_xf && ('\0' == hp->interface_id))
			count = (int) hp->flags;	/* holds "old" input_size */
		else
			count = num_xfer;
	} else {
		sg_iovec_t iovec;
		if (__copy_from_user(&iovec, p + ind*SZ_SG_IOVEC, SZ_SG_IOVEC))
			return -EFAULT;
		p = iovec.iov_base;
		count = (int) iovec.iov_len;
	}
	if (!access_ok(wr_xf ? VERIFY_READ : VERIFY_WRITE, p, count))
		return -EFAULT;
	if (up)
		*up = p;
	if (countp)
		*countp = count;
	return 0;
}

static void
sg_remove_scat(Sg_scatter_hold * schp)
{
	SCSI_LOG_TIMEOUT(4, printk("sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg));
	if (schp->buffer && (schp->sglist_len > 0)) {
		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;

		if (schp->dio_in_use) {
#ifdef SG_ALLOW_DIO_CODE
			st_unmap_user_pages(sclp, schp->k_use_sg, TRUE);
#endif
		} else {
			int k;

			for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
			     ++k, ++sclp) {
				SCSI_LOG_TIMEOUT(5, printk(
				    "sg_remove_scat: k=%d, a=0x%p, len=%d\n",
				    k, sg_scatg2virt(sclp), sclp->length));
				sg_page_free(sg_scatg2virt(sclp), sclp->length);
				sclp->page = NULL;
				sclp->offset = 0;
				sclp->length = 0;
			}
		}
		sg_page_free(schp->buffer, schp->sglist_len);
	} else if (schp->buffer)
		sg_page_free(schp->buffer, schp->b_malloc_len);
	memset(schp, 0, sizeof (*schp));
}

static int
sg_read_xfer(Sg_request * srp)
{
	sg_io_hdr_t *hp = &srp->header;
	Sg_scatter_hold *schp = &srp->data;
	int num_xfer = 0;
	int j, k, onum, usglen, ksglen, res;
	int iovec_count = (int) hp->iovec_count;
	int dxfer_dir = hp->dxfer_direction;
	unsigned char *p;
	unsigned char __user *up;
	int new_interface = ('\0' == hp->interface_id) ? 0 : 1;

	if ((SG_DXFER_UNKNOWN == dxfer_dir) || (SG_DXFER_FROM_DEV == dxfer_dir)
	    || (SG_DXFER_TO_FROM_DEV == dxfer_dir)) {
		num_xfer = hp->dxfer_len;
		if (schp->bufflen < num_xfer)
			num_xfer = schp->bufflen;
	}
	if ((num_xfer <= 0) || (schp->dio_in_use) ||
	    (new_interface
	     && ((SG_FLAG_NO_DXFER | SG_FLAG_MMAP_IO) & hp->flags)))
		return 0;

	SCSI_LOG_TIMEOUT(4, printk("sg_read_xfer: num_xfer=%d, iovec_count=%d, k_use_sg=%d\n",
			  num_xfer, iovec_count, schp->k_use_sg));
	if (iovec_count) {
		onum = iovec_count;
		if (!access_ok(VERIFY_READ, hp->dxferp, SZ_SG_IOVEC * onum))
			return -EFAULT;
	} else
		onum = 1;

	if (0 == schp->k_use_sg) {	/* kernel has single buffer */
		for (j = 0, p = schp->buffer; j < onum; ++j) {
			res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
			if (res)
				return res;
			usglen = (num_xfer > usglen) ? usglen : num_xfer;
			if (__copy_to_user(up, p, usglen))
				return -EFAULT;
			p += usglen;
			num_xfer -= usglen;
			if (num_xfer <= 0)
				return 0;
		}
	} else {		/* kernel using scatter gather list */
		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;

		ksglen = (int) sclp->length;
		p = sg_scatg2virt(sclp);
		for (j = 0, k = 0; j < onum; ++j) {
			res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
			if (res)
				return res;

			for (; p; ++sclp, ksglen = (int) sclp->length,
				  p = sg_scatg2virt(sclp)) {
				if (usglen <= 0)
					break;
				if (ksglen > usglen) {
					if (usglen >= num_xfer) {
						if (__copy_to_user
						    (up, p, num_xfer))
							return -EFAULT;
						return 0;
					}
					if (__copy_to_user(up, p, usglen))
						return -EFAULT;
					p += usglen;
					ksglen -= usglen;
					break;
				} else {
					if (ksglen >= num_xfer) {
						if (__copy_to_user
						    (up, p, num_xfer))
							return -EFAULT;
						return 0;
					}
					if (__copy_to_user(up, p, ksglen))
						return -EFAULT;
					up += ksglen;
					usglen -= ksglen;
				}
				++k;
				if (k >= schp->k_use_sg)
					return 0;
			}
		}
	}
	return 0;
}

static int
sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
{
	Sg_scatter_hold *schp = &srp->data;

	SCSI_LOG_TIMEOUT(4, printk("sg_read_oxfer: num_read_xfer=%d\n",
				   num_read_xfer));
	if ((!outp) || (num_read_xfer <= 0))
		return 0;
	if (schp->k_use_sg > 0) {
		int k, num;
		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;

		for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
		     ++k, ++sclp) {
			num = (int) sclp->length;
			if (num > num_read_xfer) {
				if (__copy_to_user
				    (outp, sg_scatg2virt(sclp), num_read_xfer))
					return -EFAULT;
				break;
			} else {
				if (__copy_to_user
				    (outp, sg_scatg2virt(sclp), num))
					return -EFAULT;
				num_read_xfer -= num;
				if (num_read_xfer <= 0)
					break;
				outp += num;
			}
		}
	} else {
		if (__copy_to_user(outp, schp->buffer, num_read_xfer))
			return -EFAULT;
	}
	return 0;
}

static void
sg_build_reserve(Sg_fd * sfp, int req_size)
{
	Sg_scatter_hold *schp = &sfp->reserve;

	SCSI_LOG_TIMEOUT(4, printk("sg_build_reserve: req_size=%d\n", req_size));
	do {
		if (req_size < PAGE_SIZE)
			req_size = PAGE_SIZE;
		if (0 == sg_build_indirect(schp, sfp, req_size))
			return;
		else
			sg_remove_scat(schp);
		req_size >>= 1;	/* divide by 2 */
	} while (req_size > (PAGE_SIZE / 2));
}

static void
sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
{
	Sg_scatter_hold *req_schp = &srp->data;
	Sg_scatter_hold *rsv_schp = &sfp->reserve;

	srp->res_used = 1;
	SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
	size = (size + 1) & (~1);	/* round to even for aha1542 */
	if (rsv_schp->k_use_sg > 0) {
		int k, num;
		int rem = size;
		struct scatterlist *sclp =
		    (struct scatterlist *) rsv_schp->buffer;

		for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
			num = (int) sclp->length;
			if (rem <= num) {
				if (0 == k) {
					req_schp->k_use_sg = 0;
					req_schp->buffer = sg_scatg2virt(sclp);
				} else {
					sfp->save_scat_len = num;
					sclp->length = (unsigned) rem;
					req_schp->k_use_sg = k + 1;
					req_schp->sglist_len =
					    rsv_schp->sglist_len;
					req_schp->buffer = rsv_schp->buffer;
				}
				req_schp->bufflen = size;
				req_schp->b_malloc_len = rsv_schp->b_malloc_len;
				break;
			} else
				rem -= num;
		}
		if (k >= rsv_schp->k_use_sg)
			SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
	} else {
		req_schp->k_use_sg = 0;
		req_schp->bufflen = size;
		req_schp->buffer = rsv_schp->buffer;
		req_schp->b_malloc_len = rsv_schp->b_malloc_len;
	}
}

static void
sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
{
	Sg_scatter_hold *req_schp = &srp->data;
	Sg_scatter_hold *rsv_schp = &sfp->reserve;

	SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->k_use_sg=%d\n",
				   (int) req_schp->k_use_sg));
	if ((rsv_schp->k_use_sg > 0) && (req_schp->k_use_sg > 0)) {
		struct scatterlist *sclp =
		    (struct scatterlist *) rsv_schp->buffer;

		if (sfp->save_scat_len > 0)
			(sclp + (req_schp->k_use_sg - 1))->length =
			    (unsigned) sfp->save_scat_len;
		else
			SCSI_LOG_TIMEOUT(1, printk ("sg_unlink_reserve: BAD save_scat_len\n"));
	}
	req_schp->k_use_sg = 0;
	req_schp->bufflen = 0;
	req_schp->buffer = NULL;
	req_schp->sglist_len = 0;
	sfp->save_scat_len = 0;
	srp->res_used = 0;
}

static Sg_request *
sg_get_rq_mark(Sg_fd * sfp, int pack_id)
{
	Sg_request *resp;
	unsigned long iflags;

	write_lock_irqsave(&sfp->rq_list_lock, iflags);
	for (resp = sfp->headrp; resp; resp = resp->nextrp) {
		/* look for requests that are ready + not SG_IO owned */
		if ((1 == resp->done) && (!resp->sg_io_owned) &&
		    ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
			resp->done = 2;	/* guard against other readers */
			break;
		}
	}
	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
	return resp;
}

#ifdef CONFIG_SCSI_PROC_FS
static Sg_request *
sg_get_nth_request(Sg_fd * sfp, int nth)
{
	Sg_request *resp;
	unsigned long iflags;
	int k;

	read_lock_irqsave(&sfp->rq_list_lock, iflags);
	for (k = 0, resp = sfp->headrp; resp && (k < nth);
	     ++k, resp = resp->nextrp) ;
	read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
	return resp;
}
#endif

/* always adds to end of list */
static Sg_request *
sg_add_request(Sg_fd * sfp)
{
	int k;
	unsigned long iflags;
	Sg_request *resp;
	Sg_request *rp = sfp->req_arr;

	write_lock_irqsave(&sfp->rq_list_lock, iflags);
	resp = sfp->headrp;
	if (!resp) {
		memset(rp, 0, sizeof (Sg_request));
		rp->parentfp = sfp;
		resp = rp;
		sfp->headrp = resp;
	} else {
		if (0 == sfp->cmd_q)
			resp = NULL;	/* command queuing disallowed */
		else {
			for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
				if (!rp->parentfp)
					break;
			}
			if (k < SG_MAX_QUEUE) {
				memset(rp, 0, sizeof (Sg_request));
				rp->parentfp = sfp;
				while (resp->nextrp)
					resp = resp->nextrp;
				resp->nextrp = rp;
				resp = rp;
			} else
				resp = NULL;
		}
	}
	if (resp) {
		resp->nextrp = NULL;
		resp->header.duration = jiffies;
		resp->my_cmdp = NULL;
	}
	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
	return resp;
}

/* Return of 1 for found; 0 for not found */
static int
sg_remove_request(Sg_fd * sfp, Sg_request * srp)
{
	Sg_request *prev_rp;
	Sg_request *rp;
	unsigned long iflags;
	int res = 0;

	if ((!sfp) || (!srp) || (!sfp->headrp))
		return res;
	write_lock_irqsave(&sfp->rq_list_lock, iflags);
	prev_rp = sfp->headrp;
	if (srp == prev_rp) {
		sfp->headrp = prev_rp->nextrp;
		prev_rp->parentfp = NULL;
		res = 1;
	} else {
		while ((rp = prev_rp->nextrp)) {
			if (srp == rp) {
				prev_rp->nextrp = rp->nextrp;
				rp->parentfp = NULL;
				res = 1;
				break;
			}
			prev_rp = rp;
		}
	}
	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
	return res;
}

#ifdef CONFIG_SCSI_PROC_FS
static Sg_fd *
sg_get_nth_sfp(Sg_device * sdp, int nth)
{
	Sg_fd *resp;
	unsigned long iflags;
	int k;

	read_lock_irqsave(&sg_dev_arr_lock, iflags);
	for (k = 0, resp = sdp->headfp; resp && (k < nth);
	     ++k, resp = resp->nextfp) ;
	read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
	return resp;
}
#endif

static Sg_fd *
sg_add_sfp(Sg_device * sdp, int dev)
{
	Sg_fd *sfp;
	unsigned long iflags;

	sfp = (Sg_fd *) sg_page_malloc(sizeof (Sg_fd), 0, NULL);
	if (!sfp)
		return NULL;
	memset(sfp, 0, sizeof (Sg_fd));
	init_waitqueue_head(&sfp->read_wait);
	rwlock_init(&sfp->rq_list_lock);

	sfp->timeout = SG_DEFAULT_TIMEOUT;
	sfp->timeout_user = SG_DEFAULT_TIMEOUT_USER;
	sfp->force_packid = SG_DEF_FORCE_PACK_ID;
	sfp->low_dma = (SG_DEF_FORCE_LOW_DMA == 0) ?
	    sdp->device->host->unchecked_isa_dma : 1;
	sfp->cmd_q = SG_DEF_COMMAND_Q;
	sfp->keep_orphan = SG_DEF_KEEP_ORPHAN;
	sfp->parentdp = sdp;
	write_lock_irqsave(&sg_dev_arr_lock, iflags);
	if (!sdp->headfp)
		sdp->headfp = sfp;
	else {			/* add to tail of existing list */
		Sg_fd *pfp = sdp->headfp;
		while (pfp->nextfp)
			pfp = pfp->nextfp;
		pfp->nextfp = sfp;
	}
	write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
	SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp));
	sg_build_reserve(sfp, sg_big_buff);
	SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp:   bufflen=%d, k_use_sg=%d\n",
			   sfp->reserve.bufflen, sfp->reserve.k_use_sg));
	return sfp;
}

static void
__sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
{
	Sg_fd *fp;
	Sg_fd *prev_fp;

	prev_fp = sdp->headfp;
	if (sfp == prev_fp)
		sdp->headfp = prev_fp->nextfp;
	else {
		while ((fp = prev_fp->nextfp)) {
			if (sfp == fp) {
				prev_fp->nextfp = fp->nextfp;
				break;
			}
			prev_fp = fp;
		}
	}
	if (sfp->reserve.bufflen > 0) {
		SCSI_LOG_TIMEOUT(6, 
			printk("__sg_remove_sfp:    bufflen=%d, k_use_sg=%d\n",
			(int) sfp->reserve.bufflen, (int) sfp->reserve.k_use_sg));
		if (sfp->mmap_called)
			sg_rb_correct4mmap(&sfp->reserve, 0);	/* undo correction */
		sg_remove_scat(&sfp->reserve);
	}
	sfp->parentdp = NULL;
	SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp:    sfp=0x%p\n", sfp));
	sg_page_free((char *) sfp, sizeof (Sg_fd));
}

/* Returns 0 in normal case, 1 when detached and sdp object removed */
static int
sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
{
	Sg_request *srp;
	Sg_request *tsrp;
	int dirty = 0;
	int res = 0;

	for (srp = sfp->headrp; srp; srp = tsrp) {
		tsrp = srp->nextrp;
		if (sg_srp_done(srp, sfp))
			sg_finish_rem_req(srp);
		else
			++dirty;
	}
	if (0 == dirty) {
		unsigned long iflags;

		write_lock_irqsave(&sg_dev_arr_lock, iflags);
		__sg_remove_sfp(sdp, sfp);
		if (sdp->detached && (NULL == sdp->headfp)) {
			int k, maxd;

			maxd = sg_dev_max;
			for (k = 0; k < maxd; ++k) {
				if (sdp == sg_dev_arr[k])
					break;
			}
			if (k < maxd)
				sg_dev_arr[k] = NULL;
			kfree((char *) sdp);
			res = 1;
		}
		write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
	} else {
		/* MOD_INC's to inhibit unloading sg and associated adapter driver */
		/* only bump the access_count if we actually succeeded in
		 * throwing another counter on the host module */
		scsi_device_get(sdp->device);	/* XXX: retval ignored? */	
		sfp->closed = 1;	/* flag dirty state on this fd */
		SCSI_LOG_TIMEOUT(1, printk("sg_remove_sfp: worrisome, %d writes pending\n",
				  dirty));
	}
	return res;
}

static int
sg_res_in_use(Sg_fd * sfp)
{
	const Sg_request *srp;
	unsigned long iflags;

	read_lock_irqsave(&sfp->rq_list_lock, iflags);
	for (srp = sfp->headrp; srp; srp = srp->nextrp)
		if (srp->res_used)
			break;
	read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
	return srp ? 1 : 0;
}

/* If retSzp==NULL want exact size or fail */
static char *
sg_page_malloc(int rqSz, int lowDma, int *retSzp)
{
	char *resp = NULL;
	int page_mask;
	int order, a_size;
	int resSz = rqSz;

	if (rqSz <= 0)
		return resp;

	if (lowDma)
		page_mask = GFP_ATOMIC | GFP_DMA | __GFP_NOWARN;
	else
		page_mask = GFP_ATOMIC | __GFP_NOWARN;

	for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
	     order++, a_size <<= 1) ;
	resp = (char *) __get_free_pages(page_mask, order);
	while ((!resp) && order && retSzp) {
		--order;
		a_size >>= 1;	/* divide by 2, until PAGE_SIZE */
		resp = (char *) __get_free_pages(page_mask, order);	/* try half */
		resSz = a_size;
	}
	if (resp) {
		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
			memset(resp, 0, resSz);
		if (retSzp)
			*retSzp = resSz;
	}
	return resp;
}

static void
sg_page_free(char *buff, int size)
{
	int order, a_size;

	if (!buff)
		return;
	for (order = 0, a_size = PAGE_SIZE; a_size < size;
	     order++, a_size <<= 1) ;
	free_pages((unsigned long) buff, order);
}

#ifndef MAINTENANCE_IN_CMD
#define MAINTENANCE_IN_CMD 0xa3
#endif

static unsigned char allow_ops[] = { TEST_UNIT_READY, REQUEST_SENSE,
	INQUIRY, READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
	READ_16, MODE_SENSE, MODE_SENSE_10, LOG_SENSE, REPORT_LUNS,
	SERVICE_ACTION_IN, RECEIVE_DIAGNOSTIC, READ_LONG, MAINTENANCE_IN_CMD
};

static int
sg_allow_access(unsigned char opcode, char dev_type)
{
	int k;

	if (TYPE_SCANNER == dev_type)	/* TYPE_ROM maybe burner */
		return 1;
	for (k = 0; k < sizeof (allow_ops); ++k) {
		if (opcode == allow_ops[k])
			return 1;
	}
	return 0;
}

#ifdef CONFIG_SCSI_PROC_FS
static int
sg_last_dev(void)
{
	int k;
	unsigned long iflags;

	read_lock_irqsave(&sg_dev_arr_lock, iflags);
	for (k = sg_dev_max - 1; k >= 0; --k)
		if (sg_dev_arr[k] && sg_dev_arr[k]->device)
			break;
	read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
	return k + 1;		/* origin 1 */
}
#endif

static Sg_device *
sg_get_dev(int dev)
{
	Sg_device *sdp = NULL;
	unsigned long iflags;

	if (sg_dev_arr && (dev >= 0)) {
		read_lock_irqsave(&sg_dev_arr_lock, iflags);
		if (dev < sg_dev_max)
			sdp = sg_dev_arr[dev];
		read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
	}
	return sdp;
}

#ifdef CONFIG_SCSI_PROC_FS

static struct proc_dir_entry *sg_proc_sgp = NULL;

static char sg_proc_sg_dirname[] = "scsi/sg";

static int sg_proc_seq_show_int(struct seq_file *s, void *v);

static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
			          size_t count, loff_t *off);
static struct file_operations adio_fops = {
	/* .owner, .read and .llseek added in sg_proc_init() */
	.open = sg_proc_single_open_adio,
	.write = sg_proc_write_adio,
	.release = single_release,
};

static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
static ssize_t sg_proc_write_dressz(struct file *filp, 
		const char __user *buffer, size_t count, loff_t *off);
static struct file_operations dressz_fops = {
	.open = sg_proc_single_open_dressz,
	.write = sg_proc_write_dressz,
	.release = single_release,
};

static int sg_proc_seq_show_version(struct seq_file *s, void *v);
static int sg_proc_single_open_version(struct inode *inode, struct file *file);
static struct file_operations version_fops = {
	.open = sg_proc_single_open_version,
	.release = single_release,
};

static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v);
static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file);
static struct file_operations devhdr_fops = {
	.open = sg_proc_single_open_devhdr,
	.release = single_release,
};

static int sg_proc_seq_show_dev(struct seq_file *s, void *v);
static int sg_proc_open_dev(struct inode *inode, struct file *file);
static void * dev_seq_start(struct seq_file *s, loff_t *pos);
static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos);
static void dev_seq_stop(struct seq_file *s, void *v);
static struct file_operations dev_fops = {
	.open = sg_proc_open_dev,
	.release = seq_release,
};
static struct seq_operations dev_seq_ops = {
	.start = dev_seq_start,
	.next  = dev_seq_next,
	.stop  = dev_seq_stop,
	.show  = sg_proc_seq_show_dev,
};

static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v);
static int sg_proc_open_devstrs(struct inode *inode, struct file *file);
static struct file_operations devstrs_fops = {
	.open = sg_proc_open_devstrs,
	.release = seq_release,
};
static struct seq_operations devstrs_seq_ops = {
	.start = dev_seq_start,
	.next  = dev_seq_next,
	.stop  = dev_seq_stop,
	.show  = sg_proc_seq_show_devstrs,
};

static int sg_proc_seq_show_debug(struct seq_file *s, void *v);
static int sg_proc_open_debug(struct inode *inode, struct file *file);
static struct file_operations debug_fops = {
	.open = sg_proc_open_debug,
	.release = seq_release,
};
static struct seq_operations debug_seq_ops = {
	.start = dev_seq_start,
	.next  = dev_seq_next,
	.stop  = dev_seq_stop,
	.show  = sg_proc_seq_show_debug,
};


struct sg_proc_leaf {
	const char * name;
	struct file_operations * fops;
};

static struct sg_proc_leaf sg_proc_leaf_arr[] = {
	{"allow_dio", &adio_fops},
	{"debug", &debug_fops},
	{"def_reserved_size", &dressz_fops},
	{"device_hdr", &devhdr_fops},
	{"devices", &dev_fops},
	{"device_strs", &devstrs_fops},
	{"version", &version_fops}
};

static int
sg_proc_init(void)
{
	int k, mask;
	int num_leaves =
	    sizeof (sg_proc_leaf_arr) / sizeof (sg_proc_leaf_arr[0]);
	struct proc_dir_entry *pdep;
	struct sg_proc_leaf * leaf;

	sg_proc_sgp = create_proc_entry(sg_proc_sg_dirname,
					S_IFDIR | S_IRUGO | S_IXUGO, NULL);
	if (!sg_proc_sgp)
		return 1;
	for (k = 0; k < num_leaves; ++k) {
		leaf = &sg_proc_leaf_arr[k];
		mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO;
		pdep = create_proc_entry(leaf->name, mask, sg_proc_sgp);
		if (pdep) {
			leaf->fops->owner = THIS_MODULE,
			leaf->fops->read = seq_read,
			leaf->fops->llseek = seq_lseek,
			pdep->proc_fops = leaf->fops;
		}
	}
	return 0;
}

static void
sg_proc_cleanup(void)
{
	int k;
	int num_leaves =
	    sizeof (sg_proc_leaf_arr) / sizeof (sg_proc_leaf_arr[0]);

	if (!sg_proc_sgp)
		return;
	for (k = 0; k < num_leaves; ++k)
		remove_proc_entry(sg_proc_leaf_arr[k].name, sg_proc_sgp);
	remove_proc_entry(sg_proc_sg_dirname, NULL);
}


static int sg_proc_seq_show_int(struct seq_file *s, void *v)
{
	seq_printf(s, "%d\n", *((int *)s->private));
	return 0;
}

static int sg_proc_single_open_adio(struct inode *inode, struct file *file)
{
	return single_open(file, sg_proc_seq_show_int, &sg_allow_dio);
}

static ssize_t 
sg_proc_write_adio(struct file *filp, const char __user *buffer,
		   size_t count, loff_t *off)
{
	int num;
	char buff[11];

	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
		return -EACCES;
	num = (count < 10) ? count : 10;
	if (copy_from_user(buff, buffer, num))
		return -EFAULT;
	buff[num] = '\0';
	sg_allow_dio = simple_strtoul(buff, NULL, 10) ? 1 : 0;
	return count;
}

static int sg_proc_single_open_dressz(struct inode *inode, struct file *file)
{
	return single_open(file, sg_proc_seq_show_int, &sg_big_buff);
}

static ssize_t 
sg_proc_write_dressz(struct file *filp, const char __user *buffer,
		     size_t count, loff_t *off)
{
	int num;
	unsigned long k = ULONG_MAX;
	char buff[11];

	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
		return -EACCES;
	num = (count < 10) ? count : 10;
	if (copy_from_user(buff, buffer, num))
		return -EFAULT;
	buff[num] = '\0';
	k = simple_strtoul(buff, NULL, 10);
	if (k <= 1048576) {	/* limit "big buff" to 1 MB */
		sg_big_buff = k;
		return count;
	}
	return -ERANGE;
}

static int sg_proc_seq_show_version(struct seq_file *s, void *v)
{
	seq_printf(s, "%d\t%s [%s]\n", sg_version_num, SG_VERSION_STR,
		   sg_version_date);
	return 0;
}

static int sg_proc_single_open_version(struct inode *inode, struct file *file)
{
	return single_open(file, sg_proc_seq_show_version, NULL);
}

static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v)
{
	seq_printf(s, "host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\t"
		   "online\n");
	return 0;
}

static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file)
{
	return single_open(file, sg_proc_seq_show_devhdr, NULL);
}

struct sg_proc_deviter {
	loff_t	index;
	size_t	max;
};

static void * dev_seq_start(struct seq_file *s, loff_t *pos)
{
	struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL);

	if (! it)
		return NULL;
	if (NULL == sg_dev_arr)
		goto err1;
	it->index = *pos;
	it->max = sg_last_dev();
	if (it->index >= it->max)
		goto err1;
	return it;
err1:
	kfree(it);
	return NULL;
}

static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
	struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;

	*pos = ++it->index;
	return (it->index < it->max) ? it : NULL;
}

static void dev_seq_stop(struct seq_file *s, void *v)
{
	kfree (v);
}

static int sg_proc_open_dev(struct inode *inode, struct file *file)
{
        return seq_open(file, &dev_seq_ops);
}

static int sg_proc_seq_show_dev(struct seq_file *s, void *v)
{
	struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
	Sg_device *sdp;
	struct scsi_device *scsidp;

	sdp = it ? sg_get_dev(it->index) : NULL;
	if (sdp && (scsidp = sdp->device) && (!sdp->detached))
		seq_printf(s, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
			      scsidp->host->host_no, scsidp->channel,
			      scsidp->id, scsidp->lun, (int) scsidp->type,
			      1,
			      (int) scsidp->queue_depth,
			      (int) scsidp->device_busy,
			      (int) scsi_device_online(scsidp));
	else
		seq_printf(s, "-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n");
	return 0;
}

static int sg_proc_open_devstrs(struct inode *inode, struct file *file)
{
        return seq_open(file, &devstrs_seq_ops);
}

static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v)
{
	struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
	Sg_device *sdp;
	struct scsi_device *scsidp;

	sdp = it ? sg_get_dev(it->index) : NULL;
	if (sdp && (scsidp = sdp->device) && (!sdp->detached))
		seq_printf(s, "%8.8s\t%16.16s\t%4.4s\n",
			   scsidp->vendor, scsidp->model, scsidp->rev);
	else
		seq_printf(s, "<no active device>\n");
	return 0;
}

static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
{
	int k, m, new_interface, blen, usg;
	Sg_request *srp;
	Sg_fd *fp;
	const sg_io_hdr_t *hp;
	const char * cp;

	for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) {
		seq_printf(s, "   FD(%d): timeout=%dms bufflen=%d "
			   "(res)sgat=%d low_dma=%d\n", k + 1,
			   jiffies_to_msecs(fp->timeout),
			   fp->reserve.bufflen,
			   (int) fp->reserve.k_use_sg,
			   (int) fp->low_dma);
		seq_printf(s, "   cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n",
			   (int) fp->cmd_q, (int) fp->force_packid,
			   (int) fp->keep_orphan, (int) fp->closed);
		for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) {
			hp = &srp->header;
			new_interface = (hp->interface_id == '\0') ? 0 : 1;
			if (srp->res_used) {
				if (new_interface && 
				    (SG_FLAG_MMAP_IO & hp->flags))
					cp = "     mmap>> ";
				else
					cp = "     rb>> ";
			} else {
				if (SG_INFO_DIRECT_IO_MASK & hp->info)
					cp = "     dio>> ";
				else
					cp = "     ";
			}
			seq_printf(s, cp);
			blen = srp->my_cmdp ? 
				srp->my_cmdp->sr_bufflen : srp->data.bufflen;
			usg = srp->my_cmdp ? 
				srp->my_cmdp->sr_use_sg : srp->data.k_use_sg;
			seq_printf(s, srp->done ? 
				   ((1 == srp->done) ?  "rcv:" : "fin:")
				   : (srp->my_cmdp ? "act:" : "prior:"));
			seq_printf(s, " id=%d blen=%d",
				   srp->header.pack_id, blen);
			if (srp->done)
				seq_printf(s, " dur=%d", hp->duration);
			else
				seq_printf(s, " t_o/elap=%d/%d",
				  new_interface ? hp->timeout : jiffies_to_msecs(fp->timeout),
				  jiffies_to_msecs(hp->duration ? (jiffies - hp->duration) : 0));
			seq_printf(s, "ms sgat=%d op=0x%02x\n", usg,
				   (int) srp->data.cmd_opcode);
		}
		if (0 == m)
			seq_printf(s, "     No requests active\n");
	}
}

static int sg_proc_open_debug(struct inode *inode, struct file *file)
{
        return seq_open(file, &debug_seq_ops);
}

static int sg_proc_seq_show_debug(struct seq_file *s, void *v)
{
	struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
	Sg_device *sdp;

	if (it && (0 == it->index)) {
		seq_printf(s, "dev_max(currently)=%d max_active_device=%d "
			   "(origin 1)\n", sg_dev_max, (int)it->max);
		seq_printf(s, " def_reserved_size=%d\n", sg_big_buff);
	}
	sdp = it ? sg_get_dev(it->index) : NULL;
	if (sdp) {
		struct scsi_device *scsidp = sdp->device;

		if (NULL == scsidp) {
			seq_printf(s, "device %d detached ??\n", 
				   (int)it->index);
			return 0;
		}

		if (sg_get_nth_sfp(sdp, 0)) {
			seq_printf(s, " >>> device=%s ",
				sdp->disk->disk_name);
			if (sdp->detached)
				seq_printf(s, "detached pending close ");
			else
				seq_printf
				    (s, "scsi%d chan=%d id=%d lun=%d   em=%d",
				     scsidp->host->host_no,
				     scsidp->channel, scsidp->id,
				     scsidp->lun,
				     scsidp->host->hostt->emulated);
			seq_printf(s, " sg_tablesize=%d excl=%d\n",
				   sdp->sg_tablesize, sdp->exclude);
		}
		sg_proc_debug_helper(s, sdp);
	}
	return 0;
}

#endif				/* CONFIG_SCSI_PROC_FS */

module_init(init_sg);
module_exit(exit_sg);
MODULE_ALIAS_CHARDEV_MAJOR(SCSI_GENERIC_MAJOR);
