--- /dev/null
+From e6f77540c067b48dee10f1e33678415bfcc89017 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 30 Aug 2017 16:30:35 +0300
+Subject: scsi: qla2xxx: Fix an integer overflow in sysfs code
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit e6f77540c067b48dee10f1e33678415bfcc89017 upstream.
+
+The value of "size" comes from the user. When we add "start + size" it
+could lead to an integer overflow bug.
+
+It means we vmalloc() a lot more memory than we had intended. I believe
+that on 64 bit systems vmalloc() can succeed even if we ask it to
+allocate huge 4GB buffers. So we would get memory corruption and likely
+a crash when we call ha->isp_ops->write_optrom() and ->read_optrom().
+
+Only root can trigger this bug.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=194061
+
+Fixes: b7cc176c9eb3 ("[SCSI] qla2xxx: Allow region-based flash-part accesses.")
+Reported-by: shqking <shqking@gmail.com>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_attr.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -404,6 +404,8 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
+ return -EINVAL;
+ if (start > ha->optrom_size)
+ return -EINVAL;
++ if (size > ha->optrom_size - start)
++ size = ha->optrom_size - start;
+
+ mutex_lock(&ha->optrom_mutex);
+ switch (val) {
+@@ -429,8 +431,7 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
+ }
+
+ ha->optrom_region_start = start;
+- ha->optrom_region_size = start + size > ha->optrom_size ?
+- ha->optrom_size - start : size;
++ ha->optrom_region_size = start + size;
+
+ ha->optrom_state = QLA_SREADING;
+ ha->optrom_buffer = vmalloc(ha->optrom_region_size);
+@@ -503,8 +504,7 @@ qla2x00_sysfs_write_optrom_ctl(struct fi
+ }
+
+ ha->optrom_region_start = start;
+- ha->optrom_region_size = start + size > ha->optrom_size ?
+- ha->optrom_size - start : size;
++ ha->optrom_region_size = start + size;
+
+ ha->optrom_state = QLA_SWRITING;
+ ha->optrom_buffer = vmalloc(ha->optrom_region_size);
--- /dev/null
+From 4759df905a474d245752c9dc94288e779b8734dd Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 15 Sep 2017 14:05:15 +0200
+Subject: scsi: sg: factor out sg_fill_request_table()
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 4759df905a474d245752c9dc94288e779b8734dd upstream.
+
+Factor out sg_fill_request_table() for better readability.
+
+[mkp: typos, applied by hand]
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c | 61 ++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 35 insertions(+), 26 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -854,6 +854,40 @@ static int max_sectors_bytes(struct requ
+ return max_sectors << 9;
+ }
+
++static void
++sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo)
++{
++ Sg_request *srp;
++ int val;
++ unsigned int ms;
++
++ val = 0;
++ list_for_each_entry(srp, &sfp->rq_list, entry) {
++ if (val > SG_MAX_QUEUE)
++ break;
++ memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
++ rinfo[val].req_state = srp->done + 1;
++ rinfo[val].problem =
++ srp->header.masked_status &
++ srp->header.host_status &
++ srp->header.driver_status;
++ if (srp->done)
++ rinfo[val].duration =
++ srp->header.duration;
++ else {
++ ms = jiffies_to_msecs(jiffies);
++ rinfo[val].duration =
++ (ms > srp->header.duration) ?
++ (ms - srp->header.duration) : 0;
++ }
++ 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;
++ val++;
++ }
++}
++
+ static long
+ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
+ {
+@@ -1047,38 +1081,13 @@ sg_ioctl(struct file *filp, unsigned int
+ return -EFAULT;
+ else {
+ sg_req_info_t *rinfo;
+- unsigned int ms;
+
+ rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
+ GFP_KERNEL);
+ if (!rinfo)
+ return -ENOMEM;
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+- val = 0;
+- list_for_each_entry(srp, &sfp->rq_list, entry) {
+- if (val >= SG_MAX_QUEUE)
+- break;
+- memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+- rinfo[val].req_state = srp->done + 1;
+- rinfo[val].problem =
+- srp->header.masked_status &
+- srp->header.host_status &
+- srp->header.driver_status;
+- if (srp->done)
+- rinfo[val].duration =
+- srp->header.duration;
+- else {
+- ms = jiffies_to_msecs(jiffies);
+- rinfo[val].duration =
+- (ms > srp->header.duration) ?
+- (ms - srp->header.duration) : 0;
+- }
+- 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;
+- val++;
+- }
++ sg_fill_request_table(sfp, rinfo);
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+ result = __copy_to_user(p, rinfo,
+ SZ_SG_REQ_INFO * SG_MAX_QUEUE);
--- /dev/null
+From 3e0097499839e0fe3af380410eababe5a47c4cf9 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 15 Sep 2017 14:05:16 +0200
+Subject: scsi: sg: fixup infoleak when using SG_GET_REQUEST_TABLE
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 3e0097499839e0fe3af380410eababe5a47c4cf9 upstream.
+
+When calling SG_GET_REQUEST_TABLE ioctl only a half-filled table is
+returned; the remaining part will then contain stale kernel memory
+information. This patch zeroes out the entire table to avoid this
+issue.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -865,7 +865,6 @@ sg_fill_request_table(Sg_fd *sfp, sg_req
+ list_for_each_entry(srp, &sfp->rq_list, entry) {
+ if (val > SG_MAX_QUEUE)
+ break;
+- memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+ rinfo[val].req_state = srp->done + 1;
+ rinfo[val].problem =
+ srp->header.masked_status &
+@@ -1082,8 +1081,8 @@ sg_ioctl(struct file *filp, unsigned int
+ else {
+ sg_req_info_t *rinfo;
+
+- rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
+- GFP_KERNEL);
++ rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
++ GFP_KERNEL);
+ if (!rinfo)
+ return -ENOMEM;
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
--- /dev/null
+From bd46fc406b30d1db1aff8dabaff8d18bb423fdcf Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 17 Aug 2017 10:09:54 +0300
+Subject: scsi: sg: off by one in sg_ioctl()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+commit bd46fc406b30d1db1aff8dabaff8d18bb423fdcf upstream.
+
+If "val" is SG_MAX_QUEUE then we are one element beyond the end of the
+"rinfo" array so the > should be >=.
+
+Fixes: 109bade9c625 ("scsi: sg: use standard lists for sg_requests")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -1056,7 +1056,7 @@ sg_ioctl(struct file *filp, unsigned int
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ val = 0;
+ list_for_each_entry(srp, &sfp->rq_list, entry) {
+- if (val > SG_MAX_QUEUE)
++ if (val >= SG_MAX_QUEUE)
+ break;
+ memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
+ rinfo[val].req_state = srp->done + 1;
--- /dev/null
+From 136e57bf43dc4babbfb8783abbf707d483cacbe3 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 7 Apr 2017 09:34:13 +0200
+Subject: scsi: sg: remove 'save_scat_len'
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 136e57bf43dc4babbfb8783abbf707d483cacbe3 upstream.
+
+Unused.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Tested-by: Johannes Thumshirn <jthumshirn@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -157,7 +157,6 @@ typedef struct sg_fd { /* holds the sta
+ 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 */
+@@ -2105,7 +2104,6 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_reques
+ req_schp->pages = NULL;
+ req_schp->page_order = 0;
+ req_schp->sglist_len = 0;
+- sfp->save_scat_len = 0;
+ srp->res_used = 0;
+ /* Called without mutex lock to avoid deadlock */
+ sfp->res_in_use = 0;
--- /dev/null
+From 109bade9c625c89bb5ea753aaa1a0a97e6fbb548 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Fri, 7 Apr 2017 09:34:16 +0200
+Subject: scsi: sg: use standard lists for sg_requests
+
+From: Hannes Reinecke <hare@suse.de>
+
+commit 109bade9c625c89bb5ea753aaa1a0a97e6fbb548 upstream.
+
+'Sg_request' is using a private list implementation; convert it to
+standard lists.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Tested-by: Johannes Thumshirn <jthumshirn@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/sg.c | 147 ++++++++++++++++++++++--------------------------------
+ 1 file changed, 61 insertions(+), 86 deletions(-)
+
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -133,7 +133,7 @@ struct sg_device; /* forward declaratio
+ struct sg_fd;
+
+ typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */
+- struct sg_request *nextrp; /* NULL -> tail request (slist) */
++ struct list_head entry; /* list entry */
+ 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> */
+@@ -157,7 +157,7 @@ typedef struct sg_fd { /* holds the sta
+ 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 */
+- Sg_request *headrp; /* head of request slist, NULL->empty */
++ struct list_head rq_list; /* head of request list */
+ 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 */
+@@ -965,7 +965,7 @@ sg_ioctl(struct file *filp, unsigned int
+ 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) {
++ list_for_each_entry(srp, &sfp->rq_list, entry) {
+ if ((1 == srp->done) && (!srp->sg_io_owned)) {
+ read_unlock_irqrestore(&sfp->rq_list_lock,
+ iflags);
+@@ -978,7 +978,8 @@ sg_ioctl(struct file *filp, unsigned int
+ 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) {
++ val = 0;
++ list_for_each_entry(srp, &sfp->rq_list, entry) {
+ if ((1 == srp->done) && (!srp->sg_io_owned))
+ ++val;
+ }
+@@ -1053,35 +1054,33 @@ sg_ioctl(struct file *filp, unsigned int
+ if (!rinfo)
+ return -ENOMEM;
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+- for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
+- ++val, srp = srp ? srp->nextrp : srp) {
++ val = 0;
++ list_for_each_entry(srp, &sfp->rq_list, entry) {
++ if (val > SG_MAX_QUEUE)
++ break;
+ 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;
+- if (srp->done)
+- rinfo[val].duration =
+- srp->header.duration;
+- else {
+- ms = jiffies_to_msecs(jiffies);
+- rinfo[val].duration =
+- (ms > srp->header.duration) ?
+- (ms - srp->header.duration) : 0;
+- }
+- 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;
++ rinfo[val].req_state = srp->done + 1;
++ rinfo[val].problem =
++ srp->header.masked_status &
++ srp->header.host_status &
++ srp->header.driver_status;
++ if (srp->done)
++ rinfo[val].duration =
++ srp->header.duration;
++ else {
++ ms = jiffies_to_msecs(jiffies);
++ rinfo[val].duration =
++ (ms > srp->header.duration) ?
++ (ms - srp->header.duration) : 0;
+ }
++ 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;
++ val++;
+ }
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+- result = __copy_to_user(p, rinfo,
++ result = __copy_to_user(p, rinfo,
+ SZ_SG_REQ_INFO * SG_MAX_QUEUE);
+ result = result ? -EFAULT : 0;
+ kfree(rinfo);
+@@ -1213,7 +1212,7 @@ sg_poll(struct file *filp, poll_table *
+ 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) {
++ list_for_each_entry(srp, &sfp->rq_list, entry) {
+ /* if any read waiting, flag it */
+ if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned))
+ res = POLLIN | POLLRDNORM;
+@@ -2116,7 +2115,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
+ unsigned long iflags;
+
+ write_lock_irqsave(&sfp->rq_list_lock, iflags);
+- for (resp = sfp->headrp; resp; resp = resp->nextrp) {
++ list_for_each_entry(resp, &sfp->rq_list, entry) {
+ /* 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))) {
+@@ -2134,70 +2133,45 @@ 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 (!list_empty(&sfp->rq_list)) {
++ if (!sfp->cmd_q)
++ goto out_unlock;
++
++ for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
++ if (!rp->parentfp)
++ break;
+ }
++ if (k >= SG_MAX_QUEUE)
++ goto out_unlock;
+ }
+- if (resp) {
+- resp->nextrp = NULL;
+- resp->header.duration = jiffies_to_msecs(jiffies);
+- }
++ memset(rp, 0, sizeof (Sg_request));
++ rp->parentfp = sfp;
++ rp->header.duration = jiffies_to_msecs(jiffies);
++ list_add_tail(&rp->entry, &sfp->rq_list);
+ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+- return resp;
++ return rp;
++out_unlock:
++ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
++ return NULL;
+ }
+
+ /* 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))
++ if (!sfp || !srp || list_empty(&sfp->rq_list))
+ 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;
++ if (!list_empty(&srp->entry)) {
++ list_del(&srp->entry);
++ srp->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;
+@@ -2216,7 +2190,7 @@ sg_add_sfp(Sg_device * sdp)
+
+ init_waitqueue_head(&sfp->read_wait);
+ rwlock_init(&sfp->rq_list_lock);
+-
++ INIT_LIST_HEAD(&sfp->rq_list);
+ kref_init(&sfp->f_ref);
+ mutex_init(&sfp->f_mutex);
+ sfp->timeout = SG_DEFAULT_TIMEOUT;
+@@ -2257,10 +2231,13 @@ sg_remove_sfp_usercontext(struct work_st
+ {
+ struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
+ struct sg_device *sdp = sfp->parentdp;
++ Sg_request *srp;
+
+ /* Cleanup any responses which were never read(). */
+- while (sfp->headrp)
+- sg_finish_rem_req(sfp->headrp);
++ while (!list_empty(&sfp->rq_list)) {
++ srp = list_first_entry(&sfp->rq_list, Sg_request, entry);
++ sg_finish_rem_req(srp);
++ }
+
+ if (sfp->reserve.bufflen > 0) {
+ SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp,
+@@ -2663,7 +2640,7 @@ static int sg_proc_seq_show_devstrs(stru
+ /* must be called while holding sg_index_lock */
+ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
+ {
+- int k, m, new_interface, blen, usg;
++ int k, new_interface, blen, usg;
+ Sg_request *srp;
+ Sg_fd *fp;
+ const sg_io_hdr_t *hp;
+@@ -2683,13 +2660,11 @@ static void sg_proc_debug_helper(struct
+ seq_printf(s, " cmd_q=%d f_packid=%d k_orphan=%d closed=0\n",
+ (int) fp->cmd_q, (int) fp->force_packid,
+ (int) fp->keep_orphan);
+- for (m = 0, srp = fp->headrp;
+- srp != NULL;
+- ++m, srp = srp->nextrp) {
++ list_for_each_entry(srp, &fp->rq_list, entry) {
+ hp = &srp->header;
+ new_interface = (hp->interface_id == '\0') ? 0 : 1;
+ if (srp->res_used) {
+- if (new_interface &&
++ if (new_interface &&
+ (SG_FLAG_MMAP_IO & hp->flags))
+ cp = " mmap>> ";
+ else
+@@ -2720,7 +2695,7 @@ static void sg_proc_debug_helper(struct
+ seq_printf(s, "ms sgat=%d op=0x%02x\n", usg,
+ (int) srp->data.cmd_opcode);
+ }
+- if (0 == m)
++ if (list_empty(&fp->rq_list))
+ seq_puts(s, " No requests active\n");
+ read_unlock(&fp->rq_list_lock);
+ }
scsi-zfcp-fix-payload-with-full-fcp_rsp-iu-in-scsi-trace-records.patch
scsi-zfcp-trace-hba-fsf-response-by-default-on-dismiss-or-timedout-late-response.patch
scsi-zfcp-trace-high-part-of-new-64-bit-scsi-lun.patch
+scsi-sg-remove-save_scat_len.patch
+scsi-sg-use-standard-lists-for-sg_requests.patch
+scsi-sg-off-by-one-in-sg_ioctl.patch
+scsi-sg-factor-out-sg_fill_request_table.patch
+scsi-sg-fixup-infoleak-when-using-sg_get_request_table.patch
+scsi-qla2xxx-fix-an-integer-overflow-in-sysfs-code.patch