diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 8f952af48322..37fb44b0074b 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 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). @@ -64,7 +62,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #ifdef CONFIG_SCSI_PROC_FS #include -static char *sg_version_date = "20061027"; +static char *sg_version_date = "20140603"; static int sg_proc_init(void); static void sg_proc_cleanup(void); @@ -74,6 +72,12 @@ static void sg_proc_cleanup(void); #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) * Then when using 32 bit integers x * m may overflow during the calculation. @@ -161,7 +165,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */ char low_dma; /* as in parent but possibly overridden to 1 */ char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */ 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; @@ -566,7 +570,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) 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 ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) return -ENXIO; @@ -598,12 +602,6 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) 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 { @@ -675,7 +673,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, 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; @@ -1654,15 +1652,27 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd) 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; @@ -1747,6 +1757,8 @@ static int sg_finish_rem_req(Sg_request * srp) 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 a9f3c6fc3f57..d8c0c4307fca 100644 --- a/include/scsi/sg.h +++ b/include/scsi/sg.h @@ -4,77 +4,34 @@ #include /* - 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: /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: /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 @@ typedef struct sg_io_hdr { 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 */