]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 May 2015 12:32:40 +0000 (14:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 May 2015 12:32:40 +0000 (14:32 +0200)
added patches:
3w-9xxx-fix-command-completion-race.patch
3w-sas-fix-command-completion-race.patch
3w-xxxx-fix-command-completion-race.patch
usb-host-oxu210hp-use-new-usb_resume_timeout.patch

queue-3.10/3w-9xxx-fix-command-completion-race.patch [new file with mode: 0644]
queue-3.10/3w-sas-fix-command-completion-race.patch [new file with mode: 0644]
queue-3.10/3w-xxxx-fix-command-completion-race.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/usb-host-oxu210hp-use-new-usb_resume_timeout.patch [new file with mode: 0644]

diff --git a/queue-3.10/3w-9xxx-fix-command-completion-race.patch b/queue-3.10/3w-9xxx-fix-command-completion-race.patch
new file mode 100644 (file)
index 0000000..82dabd9
--- /dev/null
@@ -0,0 +1,157 @@
+From 118c855b5623f3e2e6204f02623d88c09e0c34de Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 23 Apr 2015 09:48:51 +0200
+Subject: 3w-9xxx: fix command completion race
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 118c855b5623f3e2e6204f02623d88c09e0c34de upstream.
+
+The 3w-9xxx driver needs to tear down the dma mappings before returning
+the command to the midlayer, as there is no guarantee the sglist and
+count are valid after that point.  Also remove the dma mapping helpers
+which have another inherent race due to the request_id index.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Adam Radford <aradford@gmail.com>
+Signed-off-by: James Bottomley <JBottomley@Odin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/3w-9xxx.c |   57 +++++++++++--------------------------------------
+ drivers/scsi/3w-9xxx.h |    5 ----
+ 2 files changed, 13 insertions(+), 49 deletions(-)
+
+--- a/drivers/scsi/3w-9xxx.c
++++ b/drivers/scsi/3w-9xxx.c
+@@ -149,7 +149,6 @@ static int twa_reset_sequence(TW_Device_
+ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg);
+ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
+ static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code);
+-static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id);
+ /* Functions */
+@@ -1352,11 +1351,11 @@ static irqreturn_t twa_interrupt(int irq
+                               }
+                               /* Now complete the io */
++                              scsi_dma_unmap(cmd);
++                              cmd->scsi_done(cmd);
+                               tw_dev->state[request_id] = TW_S_COMPLETED;
+                               twa_free_request_id(tw_dev, request_id);
+                               tw_dev->posted_request_count--;
+-                              tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+-                              twa_unmap_scsi_data(tw_dev, request_id);
+                       }
+                       /* Check for valid status after each drain */
+@@ -1414,26 +1413,6 @@ static void twa_load_sgl(TW_Device_Exten
+       }
+ } /* End twa_load_sgl() */
+-/* This function will perform a pci-dma mapping for a scatter gather list */
+-static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
+-{
+-      int use_sg;
+-      struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+-
+-      use_sg = scsi_dma_map(cmd);
+-      if (!use_sg)
+-              return 0;
+-      else if (use_sg < 0) {
+-              TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
+-              return 0;
+-      }
+-
+-      cmd->SCp.phase = TW_PHASE_SGLIST;
+-      cmd->SCp.have_data_in = use_sg;
+-
+-      return use_sg;
+-} /* End twa_map_scsi_sg_data() */
+-
+ /* This function will poll for a response interrupt of a request */
+ static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
+ {
+@@ -1612,9 +1591,11 @@ static int twa_reset_device_extension(TW
+                   (tw_dev->state[i] != TW_S_INITIAL) &&
+                   (tw_dev->state[i] != TW_S_COMPLETED)) {
+                       if (tw_dev->srb[i]) {
+-                              tw_dev->srb[i]->result = (DID_RESET << 16);
+-                              tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+-                              twa_unmap_scsi_data(tw_dev, i);
++                              struct scsi_cmnd *cmd = tw_dev->srb[i];
++
++                              cmd->result = (DID_RESET << 16);
++                              scsi_dma_unmap(cmd);
++                              cmd->scsi_done(cmd);
+                       }
+               }
+       }
+@@ -1793,21 +1774,18 @@ static int twa_scsi_queue_lck(struct scs
+       /* Save the scsi command for use by the ISR */
+       tw_dev->srb[request_id] = SCpnt;
+-      /* Initialize phase to zero */
+-      SCpnt->SCp.phase = TW_PHASE_INITIAL;
+-
+       retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
+       switch (retval) {
+       case SCSI_MLQUEUE_HOST_BUSY:
++              scsi_dma_unmap(SCpnt);
+               twa_free_request_id(tw_dev, request_id);
+-              twa_unmap_scsi_data(tw_dev, request_id);
+               break;
+       case 1:
+-              tw_dev->state[request_id] = TW_S_COMPLETED;
+-              twa_free_request_id(tw_dev, request_id);
+-              twa_unmap_scsi_data(tw_dev, request_id);
+               SCpnt->result = (DID_ERROR << 16);
++              scsi_dma_unmap(SCpnt);
+               done(SCpnt);
++              tw_dev->state[request_id] = TW_S_COMPLETED;
++              twa_free_request_id(tw_dev, request_id);
+               retval = 0;
+       }
+ out:
+@@ -1875,8 +1853,8 @@ static int twa_scsiop_execute_scsi(TW_De
+                               command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
+                               command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
+                       } else {
+-                              sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
+-                              if (sg_count == 0)
++                              sg_count = scsi_dma_map(srb);
++                              if (sg_count < 0)
+                                       goto out;
+                               scsi_for_each_sg(srb, sg, sg_count, i) {
+@@ -1991,15 +1969,6 @@ static char *twa_string_lookup(twa_messa
+       return(table[index].text);
+ } /* End twa_string_lookup() */
+-/* This function will perform a pci-dma unmap */
+-static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
+-{
+-      struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+-
+-      if (cmd->SCp.phase == TW_PHASE_SGLIST)
+-              scsi_dma_unmap(cmd);
+-} /* End twa_unmap_scsi_data() */
+-
+ /* This function gets called when a disk is coming on-line */
+ static int twa_slave_configure(struct scsi_device *sdev)
+ {
+--- a/drivers/scsi/3w-9xxx.h
++++ b/drivers/scsi/3w-9xxx.h
+@@ -324,11 +324,6 @@ static twa_message_type twa_error_table[
+ #define TW_CURRENT_DRIVER_BUILD 0
+ #define TW_CURRENT_DRIVER_BRANCH 0
+-/* Phase defines */
+-#define TW_PHASE_INITIAL 0
+-#define TW_PHASE_SINGLE  1
+-#define TW_PHASE_SGLIST  2
+-
+ /* Misc defines */
+ #define TW_9550SX_DRAIN_COMPLETED           0xFFFF
+ #define TW_SECTOR_SIZE                        512
diff --git a/queue-3.10/3w-sas-fix-command-completion-race.patch b/queue-3.10/3w-sas-fix-command-completion-race.patch
new file mode 100644 (file)
index 0000000..eb92dc3
--- /dev/null
@@ -0,0 +1,136 @@
+From 579d69bc1fd56d5af5761969aa529d1d1c188300 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 23 Apr 2015 09:48:49 +0200
+Subject: 3w-sas: fix command completion race
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 579d69bc1fd56d5af5761969aa529d1d1c188300 upstream.
+
+The 3w-sas driver needs to tear down the dma mappings before returning
+the command to the midlayer, as there is no guarantee the sglist and
+count are valid after that point.  Also remove the dma mapping helpers
+which have another inherent race due to the request_id index.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reported-by: Torsten Luettgert <ml-lkml@enda.eu>
+Tested-by: Bernd Kardatzki <Bernd.Kardatzki@med.uni-tuebingen.de>
+Acked-by: Adam Radford <aradford@gmail.com>
+Signed-off-by: James Bottomley <JBottomley@Odin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/3w-sas.c |   50 ++++++++++----------------------------------------
+ drivers/scsi/3w-sas.h |    4 ----
+ 2 files changed, 10 insertions(+), 44 deletions(-)
+
+--- a/drivers/scsi/3w-sas.c
++++ b/drivers/scsi/3w-sas.c
+@@ -303,26 +303,6 @@ static int twl_post_command_packet(TW_De
+       return 0;
+ } /* End twl_post_command_packet() */
+-/* This function will perform a pci-dma mapping for a scatter gather list */
+-static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
+-{
+-      int use_sg;
+-      struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+-
+-      use_sg = scsi_dma_map(cmd);
+-      if (!use_sg)
+-              return 0;
+-      else if (use_sg < 0) {
+-              TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list");
+-              return 0;
+-      }
+-
+-      cmd->SCp.phase = TW_PHASE_SGLIST;
+-      cmd->SCp.have_data_in = use_sg;
+-
+-      return use_sg;
+-} /* End twl_map_scsi_sg_data() */
+-
+ /* This function hands scsi cdb's to the firmware */
+ static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
+ {
+@@ -370,8 +350,8 @@ static int twl_scsiop_execute_scsi(TW_De
+       if (!sglistarg) {
+               /* Map sglist from scsi layer to cmd packet */
+               if (scsi_sg_count(srb)) {
+-                      sg_count = twl_map_scsi_sg_data(tw_dev, request_id);
+-                      if (sg_count == 0)
++                      sg_count = scsi_dma_map(srb);
++                      if (sg_count <= 0)
+                               goto out;
+                       scsi_for_each_sg(srb, sg, sg_count, i) {
+@@ -1116,15 +1096,6 @@ out:
+       return retval;
+ } /* End twl_initialize_device_extension() */
+-/* This function will perform a pci-dma unmap */
+-static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
+-{
+-      struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+-
+-      if (cmd->SCp.phase == TW_PHASE_SGLIST)
+-              scsi_dma_unmap(cmd);
+-} /* End twl_unmap_scsi_data() */
+-
+ /* This function will handle attention interrupts */
+ static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
+ {
+@@ -1265,11 +1236,11 @@ static irqreturn_t twl_interrupt(int irq
+                       }
+                       /* Now complete the io */
++                      scsi_dma_unmap(cmd);
++                      cmd->scsi_done(cmd);
+                       tw_dev->state[request_id] = TW_S_COMPLETED;
+                       twl_free_request_id(tw_dev, request_id);
+                       tw_dev->posted_request_count--;
+-                      tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+-                      twl_unmap_scsi_data(tw_dev, request_id);
+               }
+               /* Check for another response interrupt */
+@@ -1414,10 +1385,12 @@ static int twl_reset_device_extension(TW
+               if ((tw_dev->state[i] != TW_S_FINISHED) &&
+                   (tw_dev->state[i] != TW_S_INITIAL) &&
+                   (tw_dev->state[i] != TW_S_COMPLETED)) {
+-                      if (tw_dev->srb[i]) {
+-                              tw_dev->srb[i]->result = (DID_RESET << 16);
+-                              tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+-                              twl_unmap_scsi_data(tw_dev, i);
++                      struct scsi_cmnd *cmd = tw_dev->srb[i];
++
++                      if (cmd) {
++                              cmd->result = (DID_RESET << 16);
++                              scsi_dma_unmap(cmd);
++                              cmd->scsi_done(cmd);
+                       }
+               }
+       }
+@@ -1521,9 +1494,6 @@ static int twl_scsi_queue_lck(struct scs
+       /* Save the scsi command for use by the ISR */
+       tw_dev->srb[request_id] = SCpnt;
+-      /* Initialize phase to zero */
+-      SCpnt->SCp.phase = TW_PHASE_INITIAL;
+-
+       retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
+       if (retval) {
+               tw_dev->state[request_id] = TW_S_COMPLETED;
+--- a/drivers/scsi/3w-sas.h
++++ b/drivers/scsi/3w-sas.h
+@@ -103,10 +103,6 @@ static char *twl_aen_severity_table[] =
+ #define TW_CURRENT_DRIVER_BUILD 0
+ #define TW_CURRENT_DRIVER_BRANCH 0
+-/* Phase defines */
+-#define TW_PHASE_INITIAL 0
+-#define TW_PHASE_SGLIST  2
+-
+ /* Misc defines */
+ #define TW_SECTOR_SIZE                        512
+ #define TW_MAX_UNITS                        32
diff --git a/queue-3.10/3w-xxxx-fix-command-completion-race.patch b/queue-3.10/3w-xxxx-fix-command-completion-race.patch
new file mode 100644 (file)
index 0000000..48999e2
--- /dev/null
@@ -0,0 +1,120 @@
+From 9cd9554615cba14f0877cc9972a6537ad2bdde61 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 23 Apr 2015 09:48:50 +0200
+Subject: 3w-xxxx: fix command completion race
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 9cd9554615cba14f0877cc9972a6537ad2bdde61 upstream.
+
+The 3w-xxxx driver needs to tear down the dma mappings before returning
+the command to the midlayer, as there is no guarantee the sglist and
+count are valid after that point.  Also remove the dma mapping helpers
+which have another inherent race due to the request_id index.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Adam Radford <aradford@gmail.com>
+Signed-off-by: James Bottomley <JBottomley@Odin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/3w-xxxx.c |   42 ++++++------------------------------------
+ drivers/scsi/3w-xxxx.h |    5 -----
+ 2 files changed, 6 insertions(+), 41 deletions(-)
+
+--- a/drivers/scsi/3w-xxxx.c
++++ b/drivers/scsi/3w-xxxx.c
+@@ -1283,32 +1283,6 @@ static int tw_initialize_device_extensio
+       return 0;
+ } /* End tw_initialize_device_extension() */
+-static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
+-{
+-      int use_sg;
+-
+-      dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
+-
+-      use_sg = scsi_dma_map(cmd);
+-      if (use_sg < 0) {
+-              printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
+-              return 0;
+-      }
+-
+-      cmd->SCp.phase = TW_PHASE_SGLIST;
+-      cmd->SCp.have_data_in = use_sg;
+-
+-      return use_sg;
+-} /* End tw_map_scsi_sg_data() */
+-
+-static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
+-{
+-      dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
+-
+-      if (cmd->SCp.phase == TW_PHASE_SGLIST)
+-              scsi_dma_unmap(cmd);
+-} /* End tw_unmap_scsi_data() */
+-
+ /* This function will reset a device extension */
+ static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
+ {
+@@ -1331,8 +1305,8 @@ static int tw_reset_device_extension(TW_
+                       srb = tw_dev->srb[i];
+                       if (srb != NULL) {
+                               srb->result = (DID_RESET << 16);
+-                              tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
+-                              tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
++                              scsi_dma_unmap(srb);
++                              srb->scsi_done(srb);
+                       }
+               }
+       }
+@@ -1779,8 +1753,8 @@ static int tw_scsiop_read_write(TW_Devic
+       command_packet->byte8.io.lba = lba;
+       command_packet->byte6.block_count = num_sectors;
+-      use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
+-      if (!use_sg)
++      use_sg = scsi_dma_map(srb);
++      if (use_sg <= 0)
+               return 1;
+       scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
+@@ -1967,9 +1941,6 @@ static int tw_scsi_queue_lck(struct scsi
+       /* Save the scsi command for use by the ISR */
+       tw_dev->srb[request_id] = SCpnt;
+-      /* Initialize phase to zero */
+-      SCpnt->SCp.phase = TW_PHASE_INITIAL;
+-
+       switch (*command) {
+               case READ_10:
+               case READ_6:
+@@ -2196,12 +2167,11 @@ static irqreturn_t tw_interrupt(int irq,
+                               /* Now complete the io */
+                               if ((error != TW_ISR_DONT_COMPLETE)) {
++                                      scsi_dma_unmap(tw_dev->srb[request_id]);
++                                      tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+                                       tw_dev->state[request_id] = TW_S_COMPLETED;
+                                       tw_state_request_finish(tw_dev, request_id);
+                                       tw_dev->posted_request_count--;
+-                                      tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
+-                                      
+-                                      tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
+                               }
+                       }
+                               
+--- a/drivers/scsi/3w-xxxx.h
++++ b/drivers/scsi/3w-xxxx.h
+@@ -195,11 +195,6 @@ static unsigned char tw_sense_table[][4]
+ #define TW_AEN_SMART_FAIL        0x000F
+ #define TW_AEN_SBUF_FAIL         0x0024
+-/* Phase defines */
+-#define TW_PHASE_INITIAL 0
+-#define TW_PHASE_SINGLE 1
+-#define TW_PHASE_SGLIST 2
+-
+ /* Misc defines */
+ #define TW_ALIGNMENT_6000                   64 /* 64 bytes */
+ #define TW_ALIGNMENT_7000                     4  /* 4 bytes */
index 4d625152f2ebd36680724b8a6f1bb59f82bd6f90..04ca88ae3955719a3dd09be480248c0f068de675 100644 (file)
@@ -7,3 +7,7 @@ alsa-hda-fix-mute-led-fixed-mode.patch
 serial-of-serial-remove-device_type-serial-registration.patch
 rbd-end-i-o-the-entire-obj_request-on-error.patch
 ext4-fix-data-corruption-caused-by-unwritten-and-delayed-extents.patch
+3w-xxxx-fix-command-completion-race.patch
+3w-9xxx-fix-command-completion-race.patch
+3w-sas-fix-command-completion-race.patch
+usb-host-oxu210hp-use-new-usb_resume_timeout.patch
diff --git a/queue-3.10/usb-host-oxu210hp-use-new-usb_resume_timeout.patch b/queue-3.10/usb-host-oxu210hp-use-new-usb_resume_timeout.patch
new file mode 100644 (file)
index 0000000..5b471d9
--- /dev/null
@@ -0,0 +1,37 @@
+From 84c0d178eb9f3a3ae4d63dc97a440266cf17f7f5 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <balbi@ti.com>
+Date: Fri, 13 Feb 2015 14:57:54 -0600
+Subject: usb: host: oxu210hp: use new USB_RESUME_TIMEOUT
+
+From: Felipe Balbi <balbi@ti.com>
+
+commit 84c0d178eb9f3a3ae4d63dc97a440266cf17f7f5 upstream.
+
+Make sure we're using the new macro, so our
+resume signaling will always pass certification.
+
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/oxu210hp-hcd.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/oxu210hp-hcd.c
++++ b/drivers/usb/host/oxu210hp-hcd.c
+@@ -2497,11 +2497,12 @@ static irqreturn_t oxu210_hcd_irq(struct
+                                       || oxu->reset_done[i] != 0)
+                               continue;
+-                      /* start 20 msec resume signaling from this port,
+-                       * and make khubd collect PORT_STAT_C_SUSPEND to
++                      /* start USB_RESUME_TIMEOUT resume signaling from this
++                       * port, and make hub_wq collect PORT_STAT_C_SUSPEND to
+                        * stop that signaling.
+                        */
+-                      oxu->reset_done[i] = jiffies + msecs_to_jiffies(20);
++                      oxu->reset_done[i] = jiffies +
++                              msecs_to_jiffies(USB_RESUME_TIMEOUT);
+                       oxu_dbg(oxu, "port %d remote wakeup\n", i + 1);
+                       mod_timer(&hcd->rh_timer, oxu->reset_done[i]);
+               }