mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
264 lines
9.6 KiB
Diff
264 lines
9.6 KiB
Diff
From 8093bf02878aa659cfcf8cbfc272b2ad45eef24f Mon Sep 17 00:00:00 2001
|
|
From: Douglas Gilbert <dgilbert@interlog.com>
|
|
Date: Tue, 03 Jun 2014 13:18:18 -0400
|
|
Subject: [PATCH] BACKPORT: sg: relax 16 byte cdb restriction
|
|
|
|
- remove the 16 byte CDB (SCSI command) length limit from the sg driver
|
|
by handling longer CDBs the same way as the bsg driver. Remove comment
|
|
from sg.h public interface about the cmd_len field being limited to 16
|
|
bytes.
|
|
- remove some dead code caused by this change
|
|
- cleanup comment block at the top of sg.h, fix urls
|
|
|
|
Change-Id: Ie8150e5375b3316d5d5206f079c4a50f1c50b755
|
|
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
|
|
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
|
|
Reviewed-by: Hannes Reinecke <hare@suse.de>
|
|
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
|
---
|
|
|
|
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
|
|
index 216d31f..56178bc 100644
|
|
--- a/drivers/scsi/sg.c
|
|
+++ b/drivers/scsi/sg.c
|
|
@@ -7,9 +7,7 @@
|
|
* 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
|
|
+ * Copyright (C) 1998 - 2014 Douglas Gilbert
|
|
*
|
|
* 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
|
|
@@ -18,11 +16,11 @@
|
|
*
|
|
*/
|
|
|
|
-static int sg_version_num = 30534; /* 2 digits for each component */
|
|
-#define SG_VERSION_STR "3.5.34"
|
|
+static int sg_version_num = 30536; /* 2 digits for each component */
|
|
+#define SG_VERSION_STR "3.5.36"
|
|
|
|
/*
|
|
- * D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
|
|
+ * D. P. Gilbert (dgilbert@interlog.com), 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).
|
|
@@ -63,7 +61,7 @@
|
|
|
|
#ifdef CONFIG_SCSI_PROC_FS
|
|
#include <linux/proc_fs.h>
|
|
-static char *sg_version_date = "20061027";
|
|
+static char *sg_version_date = "20140603";
|
|
|
|
static int sg_proc_init(void);
|
|
static void sg_proc_cleanup(void);
|
|
@@ -72,6 +70,12 @@
|
|
#define SG_ALLOW_DIO_DEF 0
|
|
|
|
#define SG_MAX_DEVS 32768
|
|
+
|
|
+/* SG_MAX_CDB_SIZE should be 260 (spc4r37 section 3.1.30) however the type
|
|
+ * of sg_io_hdr::cmd_len can only represent 255. All SCSI commands greater
|
|
+ * than 16 bytes are "variable length" whose length is a multiple of 4
|
|
+ */
|
|
+#define SG_MAX_CDB_SIZE 252
|
|
|
|
/*
|
|
* Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
|
|
@@ -159,7 +163,7 @@
|
|
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() */
|
|
+ unsigned char next_cmd_len; /* 0: automatic, >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 */
|
|
struct kref f_ref;
|
|
@@ -542,7 +546,7 @@
|
|
Sg_request *srp;
|
|
struct sg_header old_hdr;
|
|
sg_io_hdr_t *hp;
|
|
- unsigned char cmnd[MAX_COMMAND_SIZE];
|
|
+ unsigned char cmnd[SG_MAX_CDB_SIZE];
|
|
|
|
if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
|
|
return -EINVAL;
|
|
@@ -577,12 +581,6 @@
|
|
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 {
|
|
@@ -654,7 +652,7 @@
|
|
int k;
|
|
Sg_request *srp;
|
|
sg_io_hdr_t *hp;
|
|
- unsigned char cmnd[MAX_COMMAND_SIZE];
|
|
+ unsigned char cmnd[SG_MAX_CDB_SIZE];
|
|
int timeout;
|
|
unsigned long ul_timeout;
|
|
|
|
@@ -1647,15 +1645,27 @@
|
|
struct request_queue *q = sfp->parentdp->device->request_queue;
|
|
struct rq_map_data *md, map_data;
|
|
int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ;
|
|
+ unsigned char *long_cmdp = NULL;
|
|
|
|
SCSI_LOG_TIMEOUT(4, printk(KERN_INFO "sg_start_req: dxfer_len=%d\n",
|
|
dxfer_len));
|
|
|
|
+ if (hp->cmd_len > BLK_MAX_CDB) {
|
|
+ long_cmdp = kzalloc(hp->cmd_len, GFP_KERNEL);
|
|
+ if (!long_cmdp)
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
rq = blk_get_request(q, rw, GFP_ATOMIC);
|
|
- if (!rq)
|
|
+ if (!rq) {
|
|
+ kfree(long_cmdp);
|
|
return -ENOMEM;
|
|
+ }
|
|
|
|
blk_rq_set_block_pc(rq);
|
|
+
|
|
+ if (hp->cmd_len > BLK_MAX_CDB)
|
|
+ rq->cmd = long_cmdp;
|
|
memcpy(rq->cmd, cmd, hp->cmd_len);
|
|
rq->cmd_len = hp->cmd_len;
|
|
|
|
@@ -1740,6 +1750,8 @@
|
|
if (srp->bio)
|
|
ret = blk_rq_unmap_user(srp->bio);
|
|
|
|
+ if (srp->rq->cmd != srp->rq->__cmd)
|
|
+ kfree(srp->rq->cmd);
|
|
blk_put_request(srp->rq);
|
|
}
|
|
|
|
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
|
|
index a9f3c6f..d8c0c43 100644
|
|
--- a/include/scsi/sg.h
|
|
+++ b/include/scsi/sg.h
|
|
@@ -4,77 +4,34 @@
|
|
#include <linux/compiler.h>
|
|
|
|
/*
|
|
- 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.h):
|
|
-* Copyright (C) 1992 Lawrence Foard
|
|
-Version 2 and 3 extensions to driver:
|
|
-* Copyright (C) 1998 - 2006 Douglas Gilbert
|
|
-
|
|
- Version: 3.5.34 (20060920)
|
|
- This version is for 2.6 series kernels.
|
|
-
|
|
- For a full changelog see http://www.torque.net/sg
|
|
-
|
|
-Map of SG verions to the Linux kernels in which they appear:
|
|
- ---------- ----------------------------------
|
|
- original all kernels < 2.2.6
|
|
- 2.1.40 2.2.20
|
|
- 3.0.x optional version 3 sg driver for 2.2 series
|
|
- 3.1.17++ 2.4.0++
|
|
- 3.5.30++ 2.6.0++
|
|
-
|
|
-Major new features in SG 3.x driver (cf SG 2.x drivers)
|
|
- - SG_IO ioctl() combines function if write() and read()
|
|
- - new interface (sg_io_hdr_t) but still supports old interface
|
|
- - scatter/gather in user space, direct IO, and mmap supported
|
|
-
|
|
- The normal action of this driver is to use the adapter (HBA) driver to DMA
|
|
- data into kernel buffers and then use the CPU to copy the data into the
|
|
- user space (vice versa for writes). That is called "indirect" IO due to
|
|
- the double handling of data. There are two methods offered to remove the
|
|
- redundant copy: 1) direct IO and 2) using the mmap() system call to map
|
|
- the reserve buffer (this driver has one reserve buffer per fd) into the
|
|
- user space. Both have their advantages.
|
|
- In terms of absolute speed mmap() is faster. If speed is not a concern,
|
|
- indirect IO should be fine. Read the documentation for more information.
|
|
-
|
|
- ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or
|
|
- 'echo 1 > /sys/module/sg/parameters/allow_dio' is needed.
|
|
- That attribute is 0 by default. **
|
|
-
|
|
- Historical note: this SCSI pass-through driver has been known as "sg" for
|
|
- a decade. In broader kernel discussions "sg" is used to refer to scatter
|
|
- gather techniques. The context should clarify which "sg" is referred to.
|
|
-
|
|
- Documentation
|
|
- =============
|
|
- A web site for the SG device driver can be found at:
|
|
- http://www.torque.net/sg [alternatively check the MAINTAINERS file]
|
|
- The documentation for the sg version 3 driver can be found at:
|
|
- http://www.torque.net/sg/p/sg_v3_ho.html
|
|
- This is a rendering from DocBook source [change the extension to "sgml"
|
|
- or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
|
|
- The SG_IO ioctl is now found in other parts kernel (e.g. the block layer).
|
|
- For more information see http://www.torque.net/sg/sg_io.html
|
|
-
|
|
- The older, version 2 documents discuss the original sg interface in detail:
|
|
- http://www.torque.net/sg/p/scsi-generic.txt
|
|
- http://www.torque.net/sg/p/scsi-generic_long.txt
|
|
- Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt
|
|
-
|
|
- Utility and test programs are available at the sg web site. They are
|
|
- packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils
|
|
- (for the lk 2.2 series).
|
|
-*/
|
|
+ * 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.h):
|
|
+ * Copyright (C) 1992 Lawrence Foard
|
|
+ * Version 2 and 3 extensions to driver:
|
|
+ * Copyright (C) 1998 - 2014 Douglas Gilbert
|
|
+ *
|
|
+ * Version: 3.5.36 (20140603)
|
|
+ * This version is for 2.6 and 3 series kernels.
|
|
+ *
|
|
+ * Documentation
|
|
+ * =============
|
|
+ * A web site for the SG device driver can be found at:
|
|
+ * http://sg.danny.cz/sg [alternatively check the MAINTAINERS file]
|
|
+ * The documentation for the sg version 3 driver can be found at:
|
|
+ * http://sg.danny.cz/sg/p/sg_v3_ho.html
|
|
+ * Also see: <kernel_source>/Documentation/scsi/scsi-generic.txt
|
|
+ *
|
|
+ * For utility and test programs see: http://sg.danny.cz/sg/sg3_utils.html
|
|
+ */
|
|
|
|
#ifdef __KERNEL__
|
|
extern int sg_big_buff; /* for sysctl */
|
|
#endif
|
|
|
|
-/* New interface introduced in the 3.x SG drivers follows */
|
|
|
|
typedef struct sg_iovec /* same structure as used by readv() Linux system */
|
|
{ /* call. It defines one scatter-gather element. */
|
|
@@ -87,7 +44,7 @@
|
|
{
|
|
int interface_id; /* [i] 'S' for SCSI generic (required) */
|
|
int dxfer_direction; /* [i] data transfer direction */
|
|
- unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
|
|
+ unsigned char cmd_len; /* [i] SCSI command length */
|
|
unsigned char mx_sb_len; /* [i] max length to write to sbp */
|
|
unsigned short iovec_count; /* [i] 0 implies no scatter gather */
|
|
unsigned int dxfer_len; /* [i] byte count of data transfer */
|