]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
nvme-apple: Prevent shared tags across queues on Apple A11
authorNick Chan <towinchenmi@gmail.com>
Sun, 7 Jun 2026 06:10:58 +0000 (14:10 +0800)
committerKeith Busch <kbusch@kernel.org>
Mon, 8 Jun 2026 19:44:23 +0000 (12:44 -0700)
On Apple A11, tags of pending commands must be unique across the admin
and IO queues, else the firmware crashes with
"duplicate tag error for tag N", with N being the tag.

Apply the existing workaround for M1 of reserving two tags for the admin
queue to A11.

Cc: stable@vger.kernel.org
Fixes: 04d8ecf37b5e ("nvme: apple: Add Apple A11 support")
Reviewed-by: Sven Peter <sven@kernel.org>
Signed-off-by: Nick Chan <towinchenmi@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
drivers/nvme/host/apple.c

index de0d5126458f9b73b949ef5f16b1b46608bf606d..79e1fe2a23f9c62fca06cdfb350b86bd14d4d93a 100644 (file)
@@ -225,7 +225,7 @@ static unsigned int apple_nvme_queue_depth(struct apple_nvme_queue *q)
 {
        struct apple_nvme *anv = queue_to_apple_nvme(q);
 
-       if (q->is_adminq && anv->hw->has_lsq_nvmmu)
+       if (q->is_adminq)
                return APPLE_NVME_AQ_DEPTH;
 
        return anv->hw->max_queue_depth;
@@ -303,7 +303,7 @@ static void apple_nvme_submit_cmd_t8015(struct apple_nvme_queue *q,
                memcpy((void *)q->sqes + (q->sq_tail << APPLE_NVME_IOSQES),
                        cmd, sizeof(*cmd));
 
-       if (++q->sq_tail == anv->hw->max_queue_depth)
+       if (++q->sq_tail == apple_nvme_queue_depth(q))
                q->sq_tail = 0;
 
        writel(q->sq_tail, q->sq_db);
@@ -1138,10 +1138,7 @@ static void apple_nvme_reset_work(struct work_struct *work)
        }
 
        /* Setup the admin queue */
-       if (anv->hw->has_lsq_nvmmu)
-               aqa = APPLE_NVME_AQ_DEPTH - 1;
-       else
-               aqa = anv->hw->max_queue_depth - 1;
+       aqa = APPLE_NVME_AQ_DEPTH - 1;
        aqa |= aqa << 16;
        writel(aqa, anv->mmio_nvme + NVME_REG_AQA);
        writeq(anv->adminq.sq_dma_addr, anv->mmio_nvme + NVME_REG_ASQ);
@@ -1324,8 +1321,7 @@ static int apple_nvme_alloc_tagsets(struct apple_nvme *anv)
         * both queues. The admin queue gets the first APPLE_NVME_AQ_DEPTH which
         * must be marked as reserved in the IO queue.
         */
-       if (anv->hw->has_lsq_nvmmu)
-               anv->tagset.reserved_tags = APPLE_NVME_AQ_DEPTH;
+       anv->tagset.reserved_tags = APPLE_NVME_AQ_DEPTH;
        anv->tagset.queue_depth = anv->hw->max_queue_depth - 1;
        anv->tagset.timeout = NVME_IO_TIMEOUT;
        anv->tagset.numa_node = NUMA_NO_NODE;