Skip to content

Commit 1871ee1

Browse files
haokexinhtejun
authored andcommitted
libata: support the ata host which implements a queue depth less than 32
The sata on fsl mpc8315e is broken after the commit 8a4aeec ("libata/ahci: accommodate tag ordered controllers"). The reason is that the ata controller on this SoC only implement a queue depth of 16. When issuing the commands in tag order, all the commands in tag 16 ~ 31 are mapped to tag 0 unconditionally and then causes the sata malfunction. It makes no senses to use a 32 queue in software while the hardware has less queue depth. So consider the queue depth implemented by the hardware when requesting a command tag. Fixes: 8a4aeec ("libata/ahci: accommodate tag ordered controllers") Cc: [email protected] Signed-off-by: Kevin Hao <[email protected]> Acked-by: Dan Williams <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 7188b06 commit 1871ee1

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

drivers/ata/libata-core.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4787,21 +4787,27 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
47874787
* ata_qc_new - Request an available ATA command, for queueing
47884788
* @ap: target port
47894789
*
4790+
* Some ATA host controllers may implement a queue depth which is less
4791+
* than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond
4792+
* the hardware limitation.
4793+
*
47904794
* LOCKING:
47914795
* None.
47924796
*/
47934797

47944798
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
47954799
{
47964800
struct ata_queued_cmd *qc = NULL;
4797-
unsigned int i, tag;
4801+
unsigned int i, tag, max_queue;
4802+
4803+
max_queue = ap->scsi_host->can_queue;
47984804

47994805
/* no command while frozen */
48004806
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
48014807
return NULL;
48024808

4803-
for (i = 0; i < ATA_MAX_QUEUE; i++) {
4804-
tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
4809+
for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
4810+
tag = tag < max_queue ? tag : 0;
48054811

48064812
/* the last tag is reserved for internal command. */
48074813
if (tag == ATA_TAG_INTERNAL)
@@ -6169,6 +6175,16 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
61696175
{
61706176
int i, rc;
61716177

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+
}
6187+
61726188
/* host must have been started */
61736189
if (!(host->flags & ATA_HOST_STARTED)) {
61746190
dev_err(host->dev, "BUG: trying to register unstarted host\n");

0 commit comments

Comments
 (0)