aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-07-23 20:39:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-07-23 20:39:28 -0400
commitea9339e564605286bd04c32c460f8cedc979458c (patch)
tree39dae203b2a6fba41ea84cafee57a3124df82a80
parentb292d6b5c4220d527c92316c0d11d16e9895f07e (diff)
parent1a112d10f03e83fb3a2fdc4c9165865dec8a3ca6 (diff)
Merge branch 'for-3.16-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata regression fix from Tejun Heo: "The last libata/for-3.16-fixes pull contained a regression introduced by 1871ee134b73 ("libata: support the ata host which implements a queue depth less than 32") which in turn was a fix for a regression introduced earlier while changing queue tag order to accomodate hard drives which perform poorly if tags are not allocated in circular order (ugh...). The regression happens only for SAS controllers making use of libata to serve ATA devices. They don't fill an ata_host field which is used by the new tag allocation function leading to NULL dereference. This patch adds a new intermediate field ata_host->n_tags which is initialized for both SAS and !SAS cases to fix the issue" * 'for-3.16-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: libata: introduce ata_host->n_tags to avoid oops on SAS controllers
-rw-r--r--drivers/ata/libata-core.c16
-rw-r--r--include/linux/libata.h1
2 files changed, 5 insertions, 12 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index d19c37a7abc9..677c0c1b03bd 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4798,9 +4798,8 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
4798static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) 4798static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
4799{ 4799{
4800 struct ata_queued_cmd *qc = NULL; 4800 struct ata_queued_cmd *qc = NULL;
4801 unsigned int i, tag, max_queue; 4801 unsigned int max_queue = ap->host->n_tags;
4802 4802 unsigned int i, tag;
4803 max_queue = ap->scsi_host->can_queue;
4804 4803
4805 /* no command while frozen */ 4804 /* no command while frozen */
4806 if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) 4805 if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
@@ -6094,6 +6093,7 @@ void ata_host_init(struct ata_host *host, struct device *dev,
6094{ 6093{
6095 spin_lock_init(&host->lock); 6094 spin_lock_init(&host->lock);
6096 mutex_init(&host->eh_mutex); 6095 mutex_init(&host->eh_mutex);
6096 host->n_tags = ATA_MAX_QUEUE - 1;
6097 host->dev = dev; 6097 host->dev = dev;
6098 host->ops = ops; 6098 host->ops = ops;
6099} 6099}
@@ -6175,15 +6175,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
6175{ 6175{
6176 int i, rc; 6176 int i, rc;
6177 6177
6178 /* 6178 host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1);
6179 * The max queue supported by hardware must not be greater than
6180 * ATA_MAX_QUEUE.
6181 */
6182 if (sht->can_queue > ATA_MAX_QUEUE) {
6183 dev_err(host->dev, "BUG: the hardware max queue is too large\n");
6184 WARN_ON(1);
6185 return -EINVAL;
6186 }
6187 6179
6188 /* host must have been started */ 6180 /* host must have been started */
6189 if (!(host->flags & ATA_HOST_STARTED)) { 6181 if (!(host->flags & ATA_HOST_STARTED)) {
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 5ab4e3a76721..92abb497ab14 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -593,6 +593,7 @@ struct ata_host {
593 struct device *dev; 593 struct device *dev;
594 void __iomem * const *iomap; 594 void __iomem * const *iomap;
595 unsigned int n_ports; 595 unsigned int n_ports;
596 unsigned int n_tags; /* nr of NCQ tags */
596 void *private_data; 597 void *private_data;
597 struct ata_port_operations *ops; 598 struct ata_port_operations *ops;
598 unsigned long flags; 599 unsigned long flags;