From 4cc3cfca857c2d65d80624d27781aed899b5acfa Mon Sep 17 00:00:00 2001 From: mikeeq Date: Thu, 10 Oct 2019 14:21:46 +0100 Subject: [PATCH] Migrate patches to linux v5.3 --- ...-the-queue-to-SQ_SIZE-CQ_SIZE-macros.patch | 123 -------- ...port-for-variable-IO-SQ-element-size.patch | 98 ------ ...ci-Add-support-for-Apple-2018-models.patch | 89 ------ ...-shared-tags-across-queues-for-Apple.patch | 83 ----- patches/hid-apple-mod.patch | 27 +- patches/nvme.patch | 294 ++++++++++++++++++ 6 files changed, 306 insertions(+), 408 deletions(-) delete mode 100644 patches/2001-nvme-pci-Pass-the-queue-to-SQ_SIZE-CQ_SIZE-macros.patch delete mode 100644 patches/2002-nvme-pci-Add-support-for-variable-IO-SQ-element-size.patch delete mode 100644 patches/2003-nvme-pci-Add-support-for-Apple-2018-models.patch delete mode 100644 patches/2004-nvme-pci-Support-shared-tags-across-queues-for-Apple.patch create mode 100644 patches/nvme.patch diff --git a/patches/2001-nvme-pci-Pass-the-queue-to-SQ_SIZE-CQ_SIZE-macros.patch b/patches/2001-nvme-pci-Pass-the-queue-to-SQ_SIZE-CQ_SIZE-macros.patch deleted file mode 100644 index 8eeeab3..0000000 --- a/patches/2001-nvme-pci-Pass-the-queue-to-SQ_SIZE-CQ_SIZE-macros.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 895a1134e71e999ec7873faf76ec4b1e2492c92b Mon Sep 17 00:00:00 2001 -From: Benjamin Herrenschmidt -Date: Wed, 17 Jul 2019 10:45:25 +1000 -Subject: [PATCH] nvme-pci: Pass the queue to SQ_SIZE/CQ_SIZE macros - -This will make it easier to handle variable queue entry sizes -later. No functional change. - -Signed-off-by: Benjamin Herrenschmidt -Reviewed-by: Christoph Hellwig ---- - drivers/nvme/host/pci.c | 30 +++++++++++++++--------------- - 1 file changed, 15 insertions(+), 15 deletions(-) - -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index 7fbcd72c438f..a73e4d704483 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -27,8 +27,8 @@ - #include "trace.h" - #include "nvme.h" - --#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) --#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) -+#define SQ_SIZE(q) ((q)->q_depth * sizeof(struct nvme_command)) -+#define CQ_SIZE(q) ((q)->q_depth * sizeof(struct nvme_completion)) - - #define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct nvme_sgl_desc)) - -@@ -1361,16 +1361,16 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) - - static void nvme_free_queue(struct nvme_queue *nvmeq) - { -- dma_free_coherent(nvmeq->dev->dev, CQ_SIZE(nvmeq->q_depth), -+ dma_free_coherent(nvmeq->dev->dev, CQ_SIZE(nvmeq), - (void *)nvmeq->cqes, nvmeq->cq_dma_addr); - if (!nvmeq->sq_cmds) - return; - - if (test_and_clear_bit(NVMEQ_SQ_CMB, &nvmeq->flags)) { - pci_free_p2pmem(to_pci_dev(nvmeq->dev->dev), -- nvmeq->sq_cmds, SQ_SIZE(nvmeq->q_depth)); -+ nvmeq->sq_cmds, SQ_SIZE(nvmeq)); - } else { -- dma_free_coherent(nvmeq->dev->dev, SQ_SIZE(nvmeq->q_depth), -+ dma_free_coherent(nvmeq->dev->dev, SQ_SIZE(nvmeq), - nvmeq->sq_cmds, nvmeq->sq_dma_addr); - } - } -@@ -1450,12 +1450,12 @@ static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues, - } - - static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq, -- int qid, int depth) -+ int qid) - { - struct pci_dev *pdev = to_pci_dev(dev->dev); - - if (qid && dev->cmb_use_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { -- nvmeq->sq_cmds = pci_alloc_p2pmem(pdev, SQ_SIZE(depth)); -+ nvmeq->sq_cmds = pci_alloc_p2pmem(pdev, SQ_SIZE(nvmeq)); - if (nvmeq->sq_cmds) { - nvmeq->sq_dma_addr = pci_p2pmem_virt_to_bus(pdev, - nvmeq->sq_cmds); -@@ -1464,11 +1464,11 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq, - return 0; - } - -- pci_free_p2pmem(pdev, nvmeq->sq_cmds, SQ_SIZE(depth)); -+ pci_free_p2pmem(pdev, nvmeq->sq_cmds, SQ_SIZE(nvmeq)); - } - } - -- nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), -+ nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(nvmeq), - &nvmeq->sq_dma_addr, GFP_KERNEL); - if (!nvmeq->sq_cmds) - return -ENOMEM; -@@ -1482,12 +1482,13 @@ static int nvme_alloc_queue(struct nvme_dev *dev, int qid, int depth) - if (dev->ctrl.queue_count > qid) - return 0; - -- nvmeq->cqes = dma_alloc_coherent(dev->dev, CQ_SIZE(depth), -+ nvmeq->q_depth = depth; -+ nvmeq->cqes = dma_alloc_coherent(dev->dev, CQ_SIZE(nvmeq), - &nvmeq->cq_dma_addr, GFP_KERNEL); - if (!nvmeq->cqes) - goto free_nvmeq; - -- if (nvme_alloc_sq_cmds(dev, nvmeq, qid, depth)) -+ if (nvme_alloc_sq_cmds(dev, nvmeq, qid)) - goto free_cqdma; - - nvmeq->dev = dev; -@@ -1496,15 +1497,14 @@ static int nvme_alloc_queue(struct nvme_dev *dev, int qid, int depth) - nvmeq->cq_head = 0; - nvmeq->cq_phase = 1; - nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; -- nvmeq->q_depth = depth; - nvmeq->qid = qid; - dev->ctrl.queue_count++; - - return 0; - - free_cqdma: -- dma_free_coherent(dev->dev, CQ_SIZE(depth), (void *)nvmeq->cqes, -- nvmeq->cq_dma_addr); -+ dma_free_coherent(dev->dev, CQ_SIZE(nvmeq), (void *)nvmeq->cqes, -+ nvmeq->cq_dma_addr); - free_nvmeq: - return -ENOMEM; - } -@@ -1532,7 +1532,7 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) - nvmeq->cq_head = 0; - nvmeq->cq_phase = 1; - nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; -- memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth)); -+ memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq)); - nvme_dbbuf_init(dev, nvmeq, qid); - dev->online_queues++; - wmb(); /* ensure the first interrupt sees the initialization */ --- -2.22.0 diff --git a/patches/2002-nvme-pci-Add-support-for-variable-IO-SQ-element-size.patch b/patches/2002-nvme-pci-Add-support-for-variable-IO-SQ-element-size.patch deleted file mode 100644 index a9e0ade..0000000 --- a/patches/2002-nvme-pci-Add-support-for-variable-IO-SQ-element-size.patch +++ /dev/null @@ -1,98 +0,0 @@ -From d06200ef3a5c0880bef8aab56cb4d6c6cf84477d Mon Sep 17 00:00:00 2001 -From: Benjamin Herrenschmidt -Date: Wed, 17 Jul 2019 10:45:26 +1000 -Subject: [PATCH 2/4] nvme-pci: Add support for variable IO SQ element - -The size of a submission queue element should always be 6 (64 bytes) -by spec. - -However some controllers such as Apple's are not properly implementing -the standard and require a different size. - -This provides the ground work for the subsequent quirks for these -controllers. - -Signed-off-by: Benjamin Herrenschmidt ---- - drivers/nvme/host/pci.c | 11 ++++++++--- - include/linux/nvme.h | 1 + - 2 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index 9bf56e78e9a4..96625de2ae3f 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -27,7 +27,7 @@ - #include "trace.h" - #include "nvme.h" - --#define SQ_SIZE(q) ((q)->q_depth * sizeof(struct nvme_command)) -+#define SQ_SIZE(q) ((q)->q_depth << (q)->sqes) - #define CQ_SIZE(q) ((q)->q_depth * sizeof(struct nvme_completion)) - - #define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct nvme_sgl_desc)) -@@ -105,6 +105,7 @@ struct nvme_dev { - unsigned io_queues[HCTX_MAX_TYPES]; - unsigned int num_vecs; - int q_depth; -+ int io_sqes; - u32 db_stride; - void __iomem *bar; - unsigned long bar_mapped_size; -@@ -179,7 +180,7 @@ static inline struct nvme_dev *to_nvme_dev(struct nvme_ctrl *ctrl) - struct nvme_queue { - struct nvme_dev *dev; - spinlock_t sq_lock; -- struct nvme_command *sq_cmds; -+ void *sq_cmds; - /* only used for poll queues: */ - spinlock_t cq_poll_lock ____cacheline_aligned_in_smp; - volatile struct nvme_completion *cqes; -@@ -195,6 +196,7 @@ struct nvme_queue { - u16 last_cq_head; - u16 qid; - u8 cq_phase; -+ u8 sqes; - unsigned long flags; - #define NVMEQ_ENABLED 0 - #define NVMEQ_SQ_CMB 1 -@@ -505,7 +507,8 @@ static void nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd, - bool write_sq) - { - spin_lock(&nvmeq->sq_lock); -- memcpy(&nvmeq->sq_cmds[nvmeq->sq_tail], cmd, sizeof(*cmd)); -+ memcpy(nvmeq->sq_cmds + (nvmeq->sq_tail << nvmeq->sqes), -+ cmd, sizeof(*cmd)); - if (++nvmeq->sq_tail == nvmeq->q_depth) - nvmeq->sq_tail = 0; - nvme_write_sq_db(nvmeq, write_sq); -@@ -1478,6 +1481,7 @@ static int nvme_alloc_queue(struct nvme_dev *dev, int qid, int depth) - if (dev->ctrl.queue_count > qid) - return 0; - -+ nvmeq->sqes = qid ? dev->io_sqes : NVME_NVM_ADMSQES; - nvmeq->q_depth = depth; - nvmeq->cqes = dma_alloc_coherent(dev->dev, CQ_SIZE(nvmeq), - &nvmeq->cq_dma_addr, GFP_KERNEL); -@@ -2330,6 +2334,7 @@ static int nvme_pci_enable(struct nvme_dev *dev) - io_queue_depth); - dev->db_stride = 1 << NVME_CAP_STRIDE(dev->ctrl.cap); - dev->dbs = dev->bar + 4096; -+ dev->io_sqes = NVME_NVM_IOSQES; - - /* - * Temporary fix for the Apple controller found in the MacBook8,1 and -diff --git a/include/linux/nvme.h b/include/linux/nvme.h -index 8028adacaff3..a557499e1206 100644 ---- a/include/linux/nvme.h -+++ b/include/linux/nvme.h -@@ -140,6 +140,7 @@ enum { - * Submission and Completion Queue Entry Sizes for the NVM command set. - * (In bytes and specified as a power of two (2^n)). - */ -+#define NVME_NVM_ADMSQES 6 - #define NVME_NVM_IOSQES 6 - #define NVME_NVM_IOCQES 4 - --- -2.22.0 diff --git a/patches/2003-nvme-pci-Add-support-for-Apple-2018-models.patch b/patches/2003-nvme-pci-Add-support-for-Apple-2018-models.patch deleted file mode 100644 index d0fbf88..0000000 --- a/patches/2003-nvme-pci-Add-support-for-Apple-2018-models.patch +++ /dev/null @@ -1,89 +0,0 @@ -From a9fa026d1fd4c5d3f81534aa4d225cfe86d6fa12 Mon Sep 17 00:00:00 2001 -From: Benjamin Herrenschmidt -Date: Wed, 17 Jul 2019 10:45:27 +1000 -Subject: [PATCH 3/4] nvme-pci: Add support for Apple 2018+ models - -Based on reverse engineering and original patch by - -Paul Pawlowski - -This adds support for Apple weird implementation of NVME in their -2018 or later machines. It accounts for the twice-as-big SQ entries -for the IO queues, and the fact that only interrupt vector 0 appears -to function properly. - -Signed-off-by: Benjamin Herrenschmidt ---- - drivers/nvme/host/nvme.h | 10 ++++++++++ - drivers/nvme/host/pci.c | 21 ++++++++++++++++++++- - 2 files changed, 30 insertions(+), 1 deletion(-) - -diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h -index 55553d293a98..190664037a89 100644 ---- a/drivers/nvme/host/nvme.h -+++ b/drivers/nvme/host/nvme.h -@@ -92,6 +92,16 @@ enum nvme_quirks { - * Broken Write Zeroes. - */ - NVME_QUIRK_DISABLE_WRITE_ZEROES = (1 << 9), -+ -+ /* -+ * Use only one interrupt vector for all queues -+ */ -+ NVME_QUIRK_SINGLE_VECTOR = (1 << 10), -+ -+ /* -+ * Use non-standard 128 bytes SQEs. -+ */ -+ NVME_QUIRK_128_BYTES_SQES = (1 << 11), - }; - - /* -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index 96625de2ae3f..e778a3d2d08a 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -2094,6 +2094,13 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues) - dev->io_queues[HCTX_TYPE_DEFAULT] = 1; - dev->io_queues[HCTX_TYPE_READ] = 0; - -+ /* -+ * Some Apple controllers require all queues to use the -+ * first vector. -+ */ -+ if (dev->ctrl.quirks & NVME_QUIRK_SINGLE_VECTOR) -+ irq_queues = 1; -+ - return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues, - PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd); - } -@@ -2334,7 +2341,16 @@ static int nvme_pci_enable(struct nvme_dev *dev) - io_queue_depth); - dev->db_stride = 1 << NVME_CAP_STRIDE(dev->ctrl.cap); - dev->dbs = dev->bar + 4096; -- dev->io_sqes = NVME_NVM_IOSQES; -+ -+ /* -+ * Some Apple controllers require a non-standard SQE size. -+ * Interestingly they also seem to ignore the CC:IOSQES register -+ * so we don't bother updating it here. -+ */ -+ if (dev->ctrl.quirks & NVME_QUIRK_128_BYTES_SQES) -+ dev->io_sqes = 7; -+ else -+ dev->io_sqes = NVME_NVM_IOSQES; - - /* - * Temporary fix for the Apple controller found in the MacBook8,1 and -@@ -2962,6 +2978,9 @@ static const struct pci_device_id nvme_id_table[] = { - { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, - { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) }, - { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, -+ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005), -+ .driver_data = NVME_QUIRK_SINGLE_VECTOR | -+ NVME_QUIRK_128_BYTES_SQES }, - { 0, } - }; - MODULE_DEVICE_TABLE(pci, nvme_id_table); --- -2.22.0 diff --git a/patches/2004-nvme-pci-Support-shared-tags-across-queues-for-Apple.patch b/patches/2004-nvme-pci-Support-shared-tags-across-queues-for-Apple.patch deleted file mode 100644 index 1e3a309..0000000 --- a/patches/2004-nvme-pci-Support-shared-tags-across-queues-for-Apple.patch +++ /dev/null @@ -1,83 +0,0 @@ -From eef64237b280663384cf9dd80c8f343c80581725 Mon Sep 17 00:00:00 2001 -From: Benjamin Herrenschmidt -Date: Fri, 19 Jul 2019 15:03:06 +1000 -Subject: [PATCH 4/4] nvme-pci: Support shared tags across queues - -Another issue with the Apple T2 based 2018 controllers seem to be -that they blow up (and shut the machine down) if there's a tag -collision between the IO queue and the Admin queue. - -My suspicion is that they use our tags for their internal tracking -and don't mix them with the queue id. They also seem to not like -when tags go beyond the IO queue depth, ie 128 tags. - -This adds a quirk that marks tags 0..31 of the IO queue reserved - -Signed-off-by: Benjamin Herrenschmidt ---- - drivers/nvme/host/nvme.h | 5 +++++ - drivers/nvme/host/pci.c | 19 ++++++++++++++++++- - 2 files changed, 23 insertions(+), 1 deletion(-) - -diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h -index 190664037a89..a1cbfae65176 100644 ---- a/drivers/nvme/host/nvme.h -+++ b/drivers/nvme/host/nvme.h -@@ -102,6 +102,11 @@ enum nvme_quirks { - * Use non-standard 128 bytes SQEs. - */ - NVME_QUIRK_128_BYTES_SQES = (1 << 11), -+ -+ /* -+ * Prevent tag overlap between queues -+ */ -+ NVME_QUIRK_SHARED_TAGS = (1 << 12), - }; - - /* -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index e778a3d2d08a..fbc1d7d1d966 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -2119,6 +2119,14 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) - unsigned long size; - - nr_io_queues = max_io_queues(); -+ -+ /* -+ * If tags are shared with admin queue (Apple bug), then -+ * make sure we only use one IO queue. -+ */ -+ if (dev->ctrl.quirks & NVME_QUIRK_SHARED_TAGS) -+ nr_io_queues = 1; -+ - result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); - if (result < 0) - return result; -@@ -2289,6 +2297,14 @@ static int nvme_dev_add(struct nvme_dev *dev) - dev->tagset.flags = BLK_MQ_F_SHOULD_MERGE; - dev->tagset.driver_data = dev; - -+ /* -+ * Some Apple controllers requires tags to be unique -+ * across admin and IO queue, so reserve the first 32 -+ * tags of the IO queue. -+ */ -+ if (dev->ctrl.quirks & NVME_QUIRK_SHARED_TAGS) -+ dev->tagset.reserved_tags = NVME_AQ_DEPTH; -+ - ret = blk_mq_alloc_tag_set(&dev->tagset); - if (ret) { - dev_warn(dev->ctrl.device, -@@ -2980,7 +2996,8 @@ static const struct pci_device_id nvme_id_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, - { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005), - .driver_data = NVME_QUIRK_SINGLE_VECTOR | -- NVME_QUIRK_128_BYTES_SQES }, -+ NVME_QUIRK_128_BYTES_SQES | -+ NVME_QUIRK_SHARED_TAGS }, - { 0, } - }; - MODULE_DEVICE_TABLE(pci, nvme_id_table); --- -2.22.0 diff --git a/patches/hid-apple-mod.patch b/patches/hid-apple-mod.patch index 081418e..60aee70 100644 --- a/patches/hid-apple-mod.patch +++ b/patches/hid-apple-mod.patch @@ -5,7 +5,7 @@ diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 1cb4199..3f30d04 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c -@@ -6,6 +6,7 @@ +@@ -7,6 +7,7 @@ * Copyright (c) 2005 Michael Haboustak for Concept2, Inc * Copyright (c) 2006-2007 Jiri Kosina * Copyright (c) 2008 Jiri Slaby @@ -13,7 +13,7 @@ index 1cb4199..3f30d04 100644 */ /* -@@ -33,6 +34,7 @@ +@@ -30,6 +31,7 @@ #define APPLE_INVERT_HWHEEL 0x0040 #define APPLE_IGNORE_HIDINPUT 0x0080 #define APPLE_NUMLOCK_EMULATION 0x0100 @@ -21,7 +21,7 @@ index 1cb4199..3f30d04 100644 #define APPLE_FLAG_FKEY 0x01 -@@ -54,11 +56,31 @@ +@@ -51,10 +53,30 @@ "(For people who want to keep Windows PC keyboard muscle memory. " "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)"); @@ -41,7 +41,6 @@ index 1cb4199..3f30d04 100644 struct apple_sc { unsigned long quirks; unsigned int fn_on; - DECLARE_BITMAP(pressed_fn, KEY_CNT); DECLARE_BITMAP(pressed_numlock, KEY_CNT); + struct apple_sc_backlight *backlight; +}; @@ -53,7 +52,7 @@ index 1cb4199..3f30d04 100644 }; struct apple_key_translation { -@@ -166,6 +188,16 @@ +@@ -162,6 +184,16 @@ { } }; @@ -70,9 +69,9 @@ index 1cb4199..3f30d04 100644 static const struct apple_key_translation *apple_find_translation( const struct apple_key_translation *table, u16 from) { -@@ -185,9 +217,11 @@ - struct apple_sc *asc = hid_get_drvdata(hid); - const struct apple_key_translation *trans, *table; +@@ -183,9 +215,11 @@ + bool do_translate; + u16 code = 0; - if (usage->code == KEY_FN) { + u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN); @@ -84,7 +83,7 @@ index 1cb4199..3f30d04 100644 return 1; } -@@ -266,6 +300,22 @@ +@@ -270,6 +304,22 @@ } } @@ -107,7 +106,7 @@ index 1cb4199..3f30d04 100644 return 0; } -@@ -329,6 +379,17 @@ +@@ -333,6 +383,16 @@ for (trans = apple_iso_keyboard; trans->from; trans++) set_bit(trans->to, input->keybit); @@ -121,11 +120,10 @@ index 1cb4199..3f30d04 100644 + for (trans = rightalt_as_rightctrl_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + } -+ } static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, -@@ -366,6 +427,11 @@ +@@ -370,6 +430,11 @@ return 0; } @@ -137,7 +135,7 @@ index 1cb4199..3f30d04 100644 static int apple_probe(struct hid_device *hdev, const struct hid_device_id *id) { -@@ -401,9 +467,106 @@ +@@ -405,9 +470,106 @@ return ret; } @@ -244,7 +242,7 @@ index 1cb4199..3f30d04 100644 static const struct hid_device_id apple_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, -@@ -557,6 +720,12 @@ +@@ -561,6 +723,12 @@ .driver_data = APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, @@ -257,4 +255,3 @@ index 1cb4199..3f30d04 100644 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), - diff --git a/patches/nvme.patch b/patches/nvme.patch new file mode 100644 index 0000000..05ead3e --- /dev/null +++ b/patches/nvme.patch @@ -0,0 +1,294 @@ +From 66341331ba0d2de4ff421cdc401a1e34de50502a Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Wed, 7 Aug 2019 17:51:21 +1000 +Subject: [PATCH 3/4] nvme-pci: Add support for Apple 2018+ models + +Based on reverse engineering and original patch by + +Paul Pawlowski + +This adds support for Apple weird implementation of NVME in their +2018 or later machines. It accounts for the twice-as-big SQ entries +for the IO queues, and the fact that only interrupt vector 0 appears +to function properly. + +Signed-off-by: Benjamin Herrenschmidt +Reviewed-by: Minwoo Im +Reviewed-by: Christoph Hellwig +Signed-off-by: Sagi Grimberg +--- + drivers/nvme/host/nvme.h | 10 ++++++++++ + drivers/nvme/host/pci.c | 21 ++++++++++++++++++++- + 2 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h +index 9656f863ea40..21eb48d3385d 100644 +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -97,6 +97,21 @@ + * Force simple suspend/resume path. + */ + NVME_QUIRK_SIMPLE_SUSPEND = (1 << 10), ++ ++ /* ++ * Use only one interrupt vector for all queues ++ */ ++ NVME_QUIRK_SINGLE_VECTOR = (1 << 11), ++ ++ /* ++ * Use non-standard 128 bytes SQEs. ++ */ ++ NVME_QUIRK_128_BYTES_SQES = (1 << 12), ++ ++ /* ++ * Prevent tag overlap between queues ++ */ ++ NVME_QUIRK_SHARED_TAGS = (1 << 12), + }; + + /* +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index eee93e138c2c..effb79341909 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -28,8 +28,8 @@ + #include "trace.h" + #include "nvme.h" + +-#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) +-#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) ++#define SQ_SIZE(q) ((q)->q_depth << (q)->sqes) ++#define CQ_SIZE(q) ((q)->q_depth * sizeof(struct nvme_completion)) + + #define SGES_PER_PAGE (PAGE_SIZE / sizeof(struct nvme_sgl_desc)) + +@@ -100,6 +100,7 @@ + unsigned io_queues[HCTX_MAX_TYPES]; + unsigned int num_vecs; + int q_depth; ++ int io_sqes; + u32 db_stride; + void __iomem *bar; + unsigned long bar_mapped_size; +@@ -162,7 +163,7 @@ + struct nvme_queue { + struct nvme_dev *dev; + spinlock_t sq_lock; +- struct nvme_command *sq_cmds; ++ void *sq_cmds; + /* only used for poll queues: */ + spinlock_t cq_poll_lock ____cacheline_aligned_in_smp; + volatile struct nvme_completion *cqes; +@@ -178,6 +179,7 @@ + u16 last_cq_head; + u16 qid; + u8 cq_phase; ++ u8 sqes; + unsigned long flags; + #define NVMEQ_ENABLED 0 + #define NVMEQ_SQ_CMB 1 +@@ -488,7 +490,8 @@ + bool write_sq) + { + spin_lock(&nvmeq->sq_lock); +- memcpy(&nvmeq->sq_cmds[nvmeq->sq_tail], cmd, sizeof(*cmd)); ++ memcpy(nvmeq->sq_cmds + (nvmeq->sq_tail << nvmeq->sqes), ++ cmd, sizeof(*cmd)); + if (++nvmeq->sq_tail == nvmeq->q_depth) + nvmeq->sq_tail = 0; + nvme_write_sq_db(nvmeq, write_sq); +@@ -1344,16 +1347,16 @@ + + static void nvme_free_queue(struct nvme_queue *nvmeq) + { +- dma_free_coherent(nvmeq->dev->dev, CQ_SIZE(nvmeq->q_depth), ++ dma_free_coherent(nvmeq->dev->dev, CQ_SIZE(nvmeq), + (void *)nvmeq->cqes, nvmeq->cq_dma_addr); + if (!nvmeq->sq_cmds) + return; + + if (test_and_clear_bit(NVMEQ_SQ_CMB, &nvmeq->flags)) { + pci_free_p2pmem(to_pci_dev(nvmeq->dev->dev), +- nvmeq->sq_cmds, SQ_SIZE(nvmeq->q_depth)); ++ nvmeq->sq_cmds, SQ_SIZE(nvmeq)); + } else { +- dma_free_coherent(nvmeq->dev->dev, SQ_SIZE(nvmeq->q_depth), ++ dma_free_coherent(nvmeq->dev->dev, SQ_SIZE(nvmeq), + nvmeq->sq_cmds, nvmeq->sq_dma_addr); + } + } +@@ -1433,12 +1436,12 @@ + } + + static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq, +- int qid, int depth) ++ int qid) + { + struct pci_dev *pdev = to_pci_dev(dev->dev); + + if (qid && dev->cmb_use_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { +- nvmeq->sq_cmds = pci_alloc_p2pmem(pdev, SQ_SIZE(depth)); ++ nvmeq->sq_cmds = pci_alloc_p2pmem(pdev, SQ_SIZE(nvmeq)); + if (nvmeq->sq_cmds) { + nvmeq->sq_dma_addr = pci_p2pmem_virt_to_bus(pdev, + nvmeq->sq_cmds); +@@ -1447,11 +1450,11 @@ + return 0; + } + +- pci_free_p2pmem(pdev, nvmeq->sq_cmds, SQ_SIZE(depth)); ++ pci_free_p2pmem(pdev, nvmeq->sq_cmds, SQ_SIZE(nvmeq)); + } + } + +- nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), ++ nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(nvmeq), + &nvmeq->sq_dma_addr, GFP_KERNEL); + if (!nvmeq->sq_cmds) + return -ENOMEM; +@@ -1465,12 +1468,14 @@ + if (dev->ctrl.queue_count > qid) + return 0; + +- nvmeq->cqes = dma_alloc_coherent(dev->dev, CQ_SIZE(depth), ++ nvmeq->sqes = qid ? dev->io_sqes : NVME_ADM_SQES; ++ nvmeq->q_depth = depth; ++ nvmeq->cqes = dma_alloc_coherent(dev->dev, CQ_SIZE(nvmeq), + &nvmeq->cq_dma_addr, GFP_KERNEL); + if (!nvmeq->cqes) + goto free_nvmeq; + +- if (nvme_alloc_sq_cmds(dev, nvmeq, qid, depth)) ++ if (nvme_alloc_sq_cmds(dev, nvmeq, qid)) + goto free_cqdma; + + nvmeq->dev = dev; +@@ -1479,14 +1484,13 @@ + nvmeq->cq_head = 0; + nvmeq->cq_phase = 1; + nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; +- nvmeq->q_depth = depth; + nvmeq->qid = qid; + dev->ctrl.queue_count++; + + return 0; + + free_cqdma: +- dma_free_coherent(dev->dev, CQ_SIZE(depth), (void *)nvmeq->cqes, ++ dma_free_coherent(dev->dev, CQ_SIZE(nvmeq), (void *)nvmeq->cqes, + nvmeq->cq_dma_addr); + free_nvmeq: + return -ENOMEM; +@@ -1515,7 +1519,7 @@ + nvmeq->cq_head = 0; + nvmeq->cq_phase = 1; + nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; +- memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth)); ++ memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq)); + nvme_dbbuf_init(dev, nvmeq, qid); + dev->online_queues++; + wmb(); /* ensure the first interrupt sees the initialization */ +@@ -2077,6 +2081,13 @@ + dev->io_queues[HCTX_TYPE_DEFAULT] = 1; + dev->io_queues[HCTX_TYPE_READ] = 0; + ++ /* ++ * Some Apple controllers require all queues to use the ++ * first vector. ++ */ ++ if (dev->ctrl.quirks & NVME_QUIRK_SINGLE_VECTOR) ++ irq_queues = 1; ++ + return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues, + PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd); + } +@@ -2095,6 +2106,14 @@ + unsigned long size; + + nr_io_queues = max_io_queues(); ++ ++ /* ++ * If tags are shared with admin queue (Apple bug), then ++ * make sure we only use one IO queue. ++ */ ++ if (dev->ctrl.quirks & NVME_QUIRK_SHARED_TAGS) ++ nr_io_queues = 1; ++ + result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); + if (result < 0) + return result; +@@ -2265,6 +2284,14 @@ + dev->tagset.flags = BLK_MQ_F_SHOULD_MERGE; + dev->tagset.driver_data = dev; + ++ /* ++ * Some Apple controllers requires tags to be unique ++ * across admin and IO queue, so reserve the first 32 ++ * tags of the IO queue. ++ */ ++ if (dev->ctrl.quirks & NVME_QUIRK_SHARED_TAGS) ++ dev->tagset.reserved_tags = NVME_AQ_DEPTH; ++ + ret = blk_mq_alloc_tag_set(&dev->tagset); + if (ret) { + dev_warn(dev->ctrl.device, +@@ -2318,6 +2345,16 @@ + dev->dbs = dev->bar + 4096; + + /* ++ * Some Apple controllers require a non-standard SQE size. ++ * Interestingly they also seem to ignore the CC:IOSQES register ++ * so we don't bother updating it here. ++ */ ++ if (dev->ctrl.quirks & NVME_QUIRK_128_BYTES_SQES) ++ dev->io_sqes = 7; ++ else ++ dev->io_sqes = NVME_NVM_IOSQES; ++ ++ /* + * Temporary fix for the Apple controller found in the MacBook8,1 and + * some MacBook7,1 to avoid controller resets and data loss. + */ +@@ -2334,6 +2371,17 @@ + "set queue depth=%u\n", dev->q_depth); + } + ++ /* ++ * Controllers with the shared tags quirk need the IO queue to be ++ * big enough so that we get 32 tags for the admin queue ++ */ ++ if ((dev->ctrl.quirks & NVME_QUIRK_SHARED_TAGS) && ++ (dev->q_depth < (NVME_AQ_DEPTH + 2))) { ++ dev->q_depth = NVME_AQ_DEPTH + 2; ++ dev_warn(dev->ctrl.device, "IO queue depth clamped to %d\n", ++ dev->q_depth); ++ } ++ + nvme_map_cmb(dev); + + pci_enable_pcie_error_reporting(pdev); +@@ -3041,6 +3089,10 @@ + { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) }, + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005), ++ .driver_data = NVME_QUIRK_SINGLE_VECTOR | ++ NVME_QUIRK_128_BYTES_SQES | ++ NVME_QUIRK_SHARED_TAGS }, + { 0, } + }; + MODULE_DEVICE_TABLE(pci, nvme_id_table); +diff --git a/include/linux/nvme.h b/include/linux/nvme.h +index 32c25b46ae63..f61d6906e59d 100644 +--- a/include/linux/nvme.h ++++ b/include/linux/nvme.h +@@ -140,6 +140,7 @@ + * Submission and Completion Queue Entry Sizes for the NVM command set. + * (In bytes and specified as a power of two (2^n)). + */ ++#define NVME_ADM_SQES 6 + #define NVME_NVM_IOSQES 6 + #define NVME_NVM_IOCQES 4 + +-- +2.23.0