Skip to content

Commit ea9339e

Browse files
committed
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 1871ee1 ("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
2 parents b292d6b + 1a112d1 commit ea9339e

File tree

2 files changed

+5
-12
lines changed

2 files changed

+5
-12
lines changed

drivers/ata/libata-core.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4798,9 +4798,8 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
47984798
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
47994799
{
48004800
struct ata_queued_cmd *qc = NULL;
4801-
unsigned int i, tag, max_queue;
4802-
4803-
max_queue = ap->scsi_host->can_queue;
4801+
unsigned int max_queue = ap->host->n_tags;
4802+
unsigned int i, tag;
48044803

48054804
/* no command while frozen */
48064805
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
@@ -6094,6 +6093,7 @@ void ata_host_init(struct ata_host *host, struct device *dev,
60946093
{
60956094
spin_lock_init(&host->lock);
60966095
mutex_init(&host->eh_mutex);
6096+
host->n_tags = ATA_MAX_QUEUE - 1;
60976097
host->dev = dev;
60986098
host->ops = ops;
60996099
}
@@ -6175,15 +6175,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
61756175
{
61766176
int i, rc;
61776177

6178-
/*
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-
}
6178+
host->n_tags = clamp(sht->can_queue, 1, ATA_MAX_QUEUE - 1);
61876179

61886180
/* host must have been started */
61896181
if (!(host->flags & ATA_HOST_STARTED)) {

include/linux/libata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ struct ata_host {
593593
struct device *dev;
594594
void __iomem * const *iomap;
595595
unsigned int n_ports;
596+
unsigned int n_tags; /* nr of NCQ tags */
596597
void *private_data;
597598
struct ata_port_operations *ops;
598599
unsigned long flags;

0 commit comments

Comments
 (0)