From: Greg Kroah-Hartman Date: Fri, 19 Jun 2015 19:09:27 +0000 (-0700) Subject: 4.0-stable patches X-Git-Tag: v3.10.81~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f03d83afe164fd2858df38ef42fc586a7cf1542;p=thirdparty%2Fkernel%2Fstable-queue.git 4.0-stable patches added patches: block-discard-bdi_unregister-in-favour-of-bdi_destroy.patch block-fix-ext_dev_lock-lockdep-report.patch input-alps-do-not-reduce-trackpoint-speed-by-half.patch input-elantech-add-new-icbody-type.patch input-elantech-fix-detection-of-touchpads-where-the-revision-matches-a-known-rate.patch input-synaptics-add-min-max-quirk-for-lenovo-s540.patch usb-cp210x-add-id-for-hubz-dual-zigbee-and-z-wave-dongle.patch usb-dwc3-gadget-fix-incorrect-depcmd-and-dgcmd-status-macros.patch usb-host-xhci-add-mutex-for-non-thread-safe-data.patch usb-make-module-xhci_hcd-removable.patch usb-serial-ftdi_sio-add-support-for-a-motion-tracker-development-board.patch x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch --- diff --git a/queue-4.0/block-discard-bdi_unregister-in-favour-of-bdi_destroy.patch b/queue-4.0/block-discard-bdi_unregister-in-favour-of-bdi_destroy.patch new file mode 100644 index 00000000000..c2c6eed2f02 --- /dev/null +++ b/queue-4.0/block-discard-bdi_unregister-in-favour-of-bdi_destroy.patch @@ -0,0 +1,115 @@ +From aad653a0bc09dd4ebcb5579f9f835bbae9ef2ba3 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 19 May 2015 15:58:37 +1000 +Subject: block: discard bdi_unregister() in favour of bdi_destroy() + +From: NeilBrown + +commit aad653a0bc09dd4ebcb5579f9f835bbae9ef2ba3 upstream. + +bdi_unregister() now contains very little functionality. + +It contains a "WARN_ON" if bdi->dev is NULL. This warning is of no +real consequence as bdi->dev isn't needed by anything else in the function, +and it triggers if + blk_cleanup_queue() -> bdi_destroy() +is called before bdi_unregister, which happens since + Commit: 6cd18e711dd8 ("block: destroy bdi before blockdev is unregistered.") + +So this isn't wanted. + +It also calls bdi_set_min_ratio(). This needs to be called after +writes through the bdi have all been flushed, and before the bdi is destroyed. +Calling it early is better than calling it late as it frees up a global +resource. + +Calling it immediately after bdi_wb_shutdown() in bdi_destroy() +perfectly fits these requirements. + +So bdi_unregister() can be discarded with the important content moved to +bdi_destroy(), as can the + writeback_bdi_unregister +event which is already not used. + +Reported-by: Mike Snitzer +Fixes: c4db59d31e39 ("fs: don't reassign dirty inodes to default_backing_dev_info") +Fixes: 6cd18e711dd8 ("block: destroy bdi before blockdev is unregistered.") +Acked-by: Peter Zijlstra (Intel) +Acked-by: Dan Williams +Tested-by: Nicholas Moulin +Signed-off-by: NeilBrown +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/genhd.c | 1 - + include/linux/backing-dev.h | 1 - + include/trace/events/writeback.h | 1 - + mm/backing-dev.c | 18 +----------------- + 4 files changed, 1 insertion(+), 20 deletions(-) + +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -653,7 +653,6 @@ void del_gendisk(struct gendisk *disk) + disk->flags &= ~GENHD_FL_UP; + + sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); +- bdi_unregister(&disk->queue->backing_dev_info); + blk_unregister_queue(disk); + blk_unregister_region(disk_devt(disk), disk->minors); + +--- a/include/linux/backing-dev.h ++++ b/include/linux/backing-dev.h +@@ -116,7 +116,6 @@ __printf(3, 4) + int bdi_register(struct backing_dev_info *bdi, struct device *parent, + const char *fmt, ...); + int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); +-void bdi_unregister(struct backing_dev_info *bdi); + int __must_check bdi_setup_and_register(struct backing_dev_info *, char *); + void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, + enum wb_reason reason); +--- a/include/trace/events/writeback.h ++++ b/include/trace/events/writeback.h +@@ -233,7 +233,6 @@ DEFINE_EVENT(writeback_class, name, \ + DEFINE_WRITEBACK_EVENT(writeback_nowork); + DEFINE_WRITEBACK_EVENT(writeback_wake_background); + DEFINE_WRITEBACK_EVENT(writeback_bdi_register); +-DEFINE_WRITEBACK_EVENT(writeback_bdi_unregister); + + DECLARE_EVENT_CLASS(wbc_class, + TP_PROTO(struct writeback_control *wbc, struct backing_dev_info *bdi), +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -359,23 +359,6 @@ static void bdi_wb_shutdown(struct backi + flush_delayed_work(&bdi->wb.dwork); + } + +-/* +- * Called when the device behind @bdi has been removed or ejected. +- * +- * We can't really do much here except for reducing the dirty ratio at +- * the moment. In the future we should be able to set a flag so that +- * the filesystem can handle errors at mark_inode_dirty time instead +- * of only at writeback time. +- */ +-void bdi_unregister(struct backing_dev_info *bdi) +-{ +- if (WARN_ON_ONCE(!bdi->dev)) +- return; +- +- bdi_set_min_ratio(bdi, 0); +-} +-EXPORT_SYMBOL(bdi_unregister); +- + static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi) + { + memset(wb, 0, sizeof(*wb)); +@@ -443,6 +426,7 @@ void bdi_destroy(struct backing_dev_info + int i; + + bdi_wb_shutdown(bdi); ++ bdi_set_min_ratio(bdi, 0); + + WARN_ON(!list_empty(&bdi->work_list)); + WARN_ON(delayed_work_pending(&bdi->wb.dwork)); diff --git a/queue-4.0/block-fix-ext_dev_lock-lockdep-report.patch b/queue-4.0/block-fix-ext_dev_lock-lockdep-report.patch new file mode 100644 index 00000000000..e72624eebae --- /dev/null +++ b/queue-4.0/block-fix-ext_dev_lock-lockdep-report.patch @@ -0,0 +1,99 @@ +From 4d66e5e9b6d720d8463e11d027bd4ad91c8b1318 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Wed, 10 Jun 2015 23:47:14 -0400 +Subject: block: fix ext_dev_lock lockdep report + +From: Dan Williams + +commit 4d66e5e9b6d720d8463e11d027bd4ad91c8b1318 upstream. + + ================================= + [ INFO: inconsistent lock state ] + 4.1.0-rc7+ #217 Tainted: G O + --------------------------------- + inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. + swapper/6/0 [HC0[0]:SC1[1]:HE1:SE0] takes: + (ext_devt_lock){+.?...}, at: [] blk_free_devt+0x3c/0x70 + {SOFTIRQ-ON-W} state was registered at: + [] __lock_acquire+0x461/0x1e70 + [] lock_acquire+0xb7/0x290 + [] _raw_spin_lock+0x38/0x50 + [] blk_alloc_devt+0x6d/0xd0 <-- take the lock in process context +[..] + [] __lock_acquire+0x3fe/0x1e70 + [] ? __lock_acquire+0xe5d/0x1e70 + [] lock_acquire+0xb7/0x290 + [] ? blk_free_devt+0x3c/0x70 + [] _raw_spin_lock+0x38/0x50 + [] ? blk_free_devt+0x3c/0x70 + [] blk_free_devt+0x3c/0x70 <-- take the lock in softirq + [] part_release+0x1c/0x50 + [] device_release+0x36/0xb0 + [] kobject_cleanup+0x7b/0x1a0 + [] kobject_put+0x30/0x70 + [] put_device+0x17/0x20 + [] delete_partition_rcu_cb+0x16c/0x180 + [] ? read_dev_sector+0xa0/0xa0 + [] rcu_process_callbacks+0x2ff/0xa90 + [] ? rcu_process_callbacks+0x2bf/0xa90 + [] __do_softirq+0xde/0x600 + +Neil sees this in his tests and it also triggers on pmem driver unbind +for the libnvdimm tests. This fix is on top of an initial fix by Keith +for incorrect usage of mutex_lock() in this path: 2da78092dda1 "block: +Fix dev_t minor allocation lifetime". Both this and 2da78092dda1 are +candidates for -stable. + +Fixes: 2da78092dda1 ("block: Fix dev_t minor allocation lifetime") +Cc: Keith Busch +Reported-by: NeilBrown +Signed-off-by: Dan Williams +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/genhd.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -422,9 +422,9 @@ int blk_alloc_devt(struct hd_struct *par + /* allocate ext devt */ + idr_preload(GFP_KERNEL); + +- spin_lock(&ext_devt_lock); ++ spin_lock_bh(&ext_devt_lock); + idx = idr_alloc(&ext_devt_idr, part, 0, NR_EXT_DEVT, GFP_NOWAIT); +- spin_unlock(&ext_devt_lock); ++ spin_unlock_bh(&ext_devt_lock); + + idr_preload_end(); + if (idx < 0) +@@ -449,9 +449,9 @@ void blk_free_devt(dev_t devt) + return; + + if (MAJOR(devt) == BLOCK_EXT_MAJOR) { +- spin_lock(&ext_devt_lock); ++ spin_lock_bh(&ext_devt_lock); + idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); +- spin_unlock(&ext_devt_lock); ++ spin_unlock_bh(&ext_devt_lock); + } + } + +@@ -691,13 +691,13 @@ struct gendisk *get_gendisk(dev_t devt, + } else { + struct hd_struct *part; + +- spin_lock(&ext_devt_lock); ++ spin_lock_bh(&ext_devt_lock); + part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); + if (part && get_disk(part_to_disk(part))) { + *partno = part->partno; + disk = part_to_disk(part); + } +- spin_unlock(&ext_devt_lock); ++ spin_unlock_bh(&ext_devt_lock); + } + + return disk; diff --git a/queue-4.0/input-alps-do-not-reduce-trackpoint-speed-by-half.patch b/queue-4.0/input-alps-do-not-reduce-trackpoint-speed-by-half.patch new file mode 100644 index 00000000000..4cb788364bf --- /dev/null +++ b/queue-4.0/input-alps-do-not-reduce-trackpoint-speed-by-half.patch @@ -0,0 +1,43 @@ +From 088df2ccef75754cc16a6ba31829d23bcb2b68ed Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 4 Jun 2015 22:31:43 -0700 +Subject: Input: alps - do not reduce trackpoint speed by half + +From: Hans de Goede + +commit 088df2ccef75754cc16a6ba31829d23bcb2b68ed upstream. + +On some v7 devices (e.g. Lenovo-E550) the deltas reported are typically +only in the 0-1 range dividing this by 2 results in a range of 0-0. + +And even for v7 devices where this does not lead to making the trackstick +entirely unusable, it makes it twice as slow as before we added v7 support +and were using the ps/2 mouse emulation of the dual point setup. + +If some kind of generic slowdown is actually necessary for some devices, +then that belongs in userspace, not in the kernel. + +Reported-and-tested-by: Rico Moorman +Signed-off-by: Hans de Goede +Reviewed-by: Benjamin Tissoires +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/alps.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/input/mouse/alps.c ++++ b/drivers/input/mouse/alps.c +@@ -1042,9 +1042,8 @@ static void alps_process_trackstick_pack + right = (packet[1] & 0x02) >> 1; + middle = (packet[1] & 0x04) >> 2; + +- /* Divide 2 since trackpoint's speed is too fast */ +- input_report_rel(dev2, REL_X, (char)x / 2); +- input_report_rel(dev2, REL_Y, -((char)y / 2)); ++ input_report_rel(dev2, REL_X, (char)x); ++ input_report_rel(dev2, REL_Y, -((char)y)); + + input_report_key(dev2, BTN_LEFT, left); + input_report_key(dev2, BTN_RIGHT, right); diff --git a/queue-4.0/input-elantech-add-new-icbody-type.patch b/queue-4.0/input-elantech-add-new-icbody-type.patch new file mode 100644 index 00000000000..e4a9bd5ac2e --- /dev/null +++ b/queue-4.0/input-elantech-add-new-icbody-type.patch @@ -0,0 +1,29 @@ +From 692dd1916436164e228608803dfb6cb768d6355a Mon Sep 17 00:00:00 2001 +From: Sam Hung +Date: Thu, 4 Jun 2015 22:00:24 -0700 +Subject: Input: elantech - add new icbody type + +From: Sam Hung + +commit 692dd1916436164e228608803dfb6cb768d6355a upstream. + +This adds new icbody type to the list recognized by Elantech PS/2 driver. + +Signed-off-by: Sam Hung +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elantech.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1556,6 +1556,7 @@ static int elantech_set_properties(struc + case 9: + case 10: + case 13: ++ case 14: + etd->hw_version = 4; + break; + default: diff --git a/queue-4.0/input-elantech-fix-detection-of-touchpads-where-the-revision-matches-a-known-rate.patch b/queue-4.0/input-elantech-fix-detection-of-touchpads-where-the-revision-matches-a-known-rate.patch new file mode 100644 index 00000000000..ec66067e89e --- /dev/null +++ b/queue-4.0/input-elantech-fix-detection-of-touchpads-where-the-revision-matches-a-known-rate.patch @@ -0,0 +1,44 @@ +From 5f0ee9d17aae628b22be86966471db65be21f262 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 2 Jun 2015 10:40:50 -0700 +Subject: Input: elantech - fix detection of touchpads where the revision matches a known rate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Hans de Goede + +commit 5f0ee9d17aae628b22be86966471db65be21f262 upstream. + +Make the check to skip the rate check more lax, so that it applies +to all hw_version 4 models. + +This fixes the touchpad not being detected properly on Asus PU551LA +laptops. + +Reported-and-tested-by: David Zafra Gómez +Signed-off-by: Hans de Goede +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/elantech.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1376,10 +1376,11 @@ static bool elantech_is_signature_valid( + return true; + + /* +- * Some models have a revision higher then 20. Meaning param[2] may +- * be 10 or 20, skip the rates check for these. ++ * Some hw_version >= 4 models have a revision higher then 20. Meaning ++ * that param[2] may be 10 or 20, skip the rates check for these. + */ +- if (param[0] == 0x46 && (param[1] & 0xef) == 0x0f && param[2] < 40) ++ if ((param[0] & 0x0f) >= 0x06 && (param[1] & 0xaf) == 0x0f && ++ param[2] < 40) + return true; + + for (i = 0; i < ARRAY_SIZE(rates); i++) diff --git a/queue-4.0/input-synaptics-add-min-max-quirk-for-lenovo-s540.patch b/queue-4.0/input-synaptics-add-min-max-quirk-for-lenovo-s540.patch new file mode 100644 index 00000000000..42ec93f9d1a --- /dev/null +++ b/queue-4.0/input-synaptics-add-min-max-quirk-for-lenovo-s540.patch @@ -0,0 +1,43 @@ +From 7f2ca8b55aeff1fe51ed3570200ef88a96060917 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Mon, 8 Jun 2015 10:17:32 -0700 +Subject: Input: synaptics - add min/max quirk for Lenovo S540 + +From: Peter Hutterer + +commit 7f2ca8b55aeff1fe51ed3570200ef88a96060917 upstream. + +https://bugzilla.redhat.com/show_bug.cgi?id=1223051#c2 + +Tested-by: tommy.gagnes@gmail.com +Signed-off-by: Peter Hutterer +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/synaptics.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -148,6 +148,11 @@ static const struct min_max_quirk min_ma + 1024, 5112, 2024, 4832 + }, + { ++ (const char * const []){"LEN2000", NULL}, ++ {ANY_BOARD_ID, ANY_BOARD_ID}, ++ 1024, 5113, 2021, 4832 ++ }, ++ { + (const char * const []){"LEN2001", NULL}, + {ANY_BOARD_ID, ANY_BOARD_ID}, + 1024, 5022, 2508, 4832 +@@ -188,7 +193,7 @@ static const char * const topbuttonpad_p + "LEN0045", + "LEN0047", + "LEN0049", +- "LEN2000", ++ "LEN2000", /* S540 */ + "LEN2001", /* Edge E431 */ + "LEN2002", /* Edge E531 */ + "LEN2003", diff --git a/queue-4.0/series b/queue-4.0/series index cc052cffe2a..42353700a39 100644 --- a/queue-4.0/series +++ b/queue-4.0/series @@ -49,3 +49,15 @@ dmaengine-at_xdmac-rework-slave-configuration-part.patch dmaengine-at_xdmac-lock-fixes.patch i2c-hix5hd2-fix-modalias-to-make-module-auto-loading-work.patch i2c-s3c2410-fix-oops-in-suspend-callback-for-non-dt.patch +input-alps-do-not-reduce-trackpoint-speed-by-half.patch +input-synaptics-add-min-max-quirk-for-lenovo-s540.patch +input-elantech-fix-detection-of-touchpads-where-the-revision-matches-a-known-rate.patch +input-elantech-add-new-icbody-type.patch +block-fix-ext_dev_lock-lockdep-report.patch +block-discard-bdi_unregister-in-favour-of-bdi_destroy.patch +usb-cp210x-add-id-for-hubz-dual-zigbee-and-z-wave-dongle.patch +usb-serial-ftdi_sio-add-support-for-a-motion-tracker-development-board.patch +usb-dwc3-gadget-fix-incorrect-depcmd-and-dgcmd-status-macros.patch +usb-host-xhci-add-mutex-for-non-thread-safe-data.patch +usb-make-module-xhci_hcd-removable.patch +x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch diff --git a/queue-4.0/usb-cp210x-add-id-for-hubz-dual-zigbee-and-z-wave-dongle.patch b/queue-4.0/usb-cp210x-add-id-for-hubz-dual-zigbee-and-z-wave-dongle.patch new file mode 100644 index 00000000000..d1ed7289b10 --- /dev/null +++ b/queue-4.0/usb-cp210x-add-id-for-hubz-dual-zigbee-and-z-wave-dongle.patch @@ -0,0 +1,30 @@ +From df72d588c54dad57dabb3cc8a87475d8ed66d806 Mon Sep 17 00:00:00 2001 +From: "John D. Blair" +Date: Thu, 4 Jun 2015 13:18:19 -0700 +Subject: USB: cp210x: add ID for HubZ dual ZigBee and Z-Wave dongle + +From: "John D. Blair" + +commit df72d588c54dad57dabb3cc8a87475d8ed66d806 upstream. + +Added the USB serial device ID for the HubZ dual ZigBee +and Z-Wave radio dongle. + +Signed-off-by: John D. Blair +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cp210x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -128,6 +128,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ + { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ + { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ ++ { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ diff --git a/queue-4.0/usb-dwc3-gadget-fix-incorrect-depcmd-and-dgcmd-status-macros.patch b/queue-4.0/usb-dwc3-gadget-fix-incorrect-depcmd-and-dgcmd-status-macros.patch new file mode 100644 index 00000000000..510db54440b --- /dev/null +++ b/queue-4.0/usb-dwc3-gadget-fix-incorrect-depcmd-and-dgcmd-status-macros.patch @@ -0,0 +1,40 @@ +From 459e210c4fd034d20077bcec31fec9472a700fe9 Mon Sep 17 00:00:00 2001 +From: Subbaraya Sundeep Bhatta +Date: Thu, 21 May 2015 15:46:46 +0530 +Subject: usb: dwc3: gadget: Fix incorrect DEPCMD and DGCMD status macros + +From: Subbaraya Sundeep Bhatta + +commit 459e210c4fd034d20077bcec31fec9472a700fe9 upstream. + +Fixed the incorrect macro definitions correctly as per databook. + +Signed-off-by: Subbaraya Sundeep Bhatta +Fixes: b09bb64239c8 (usb: dwc3: gadget: implement Global Command support) +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/core.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/dwc3/core.h ++++ b/drivers/usb/dwc3/core.h +@@ -339,7 +339,7 @@ + #define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c + #define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10 + +-#define DWC3_DGCMD_STATUS(n) (((n) >> 15) & 1) ++#define DWC3_DGCMD_STATUS(n) (((n) >> 12) & 0x0F) + #define DWC3_DGCMD_CMDACT (1 << 10) + #define DWC3_DGCMD_CMDIOC (1 << 8) + +@@ -355,7 +355,7 @@ + #define DWC3_DEPCMD_PARAM_SHIFT 16 + #define DWC3_DEPCMD_PARAM(x) ((x) << DWC3_DEPCMD_PARAM_SHIFT) + #define DWC3_DEPCMD_GET_RSC_IDX(x) (((x) >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f) +-#define DWC3_DEPCMD_STATUS(x) (((x) >> 15) & 1) ++#define DWC3_DEPCMD_STATUS(x) (((x) >> 12) & 0x0F) + #define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11) + #define DWC3_DEPCMD_CMDACT (1 << 10) + #define DWC3_DEPCMD_CMDIOC (1 << 8) diff --git a/queue-4.0/usb-host-xhci-add-mutex-for-non-thread-safe-data.patch b/queue-4.0/usb-host-xhci-add-mutex-for-non-thread-safe-data.patch new file mode 100644 index 00000000000..953188a772b --- /dev/null +++ b/queue-4.0/usb-host-xhci-add-mutex-for-non-thread-safe-data.patch @@ -0,0 +1,234 @@ +From a00918d0521df1c7a2ec9143142a3ea998c8526d Mon Sep 17 00:00:00 2001 +From: Chris Bainbridge +Date: Tue, 19 May 2015 16:30:51 +0300 +Subject: usb: host: xhci: add mutex for non-thread-safe data + +From: Chris Bainbridge + +commit a00918d0521df1c7a2ec9143142a3ea998c8526d upstream. + +Regression in commit 638139eb95d2 ("usb: hub: allow to process more usb +hub events in parallel") + +The regression resulted in intermittent failure to initialise a 10-port +hub (with three internal VL812 4-port hub controllers) on boot, with a +failure rate of around 8%, due to multiple race conditions when +accessing addr_dev and slot_id in struct xhci_hcd. + +This regression also exposed a problem with xhci_setup_device, which +"should be protected by the usb_address0_mutex" but no longer is due to + +commit 6fecd4f2a58c ("USB: separate usb_address0 mutexes for each bus") + +With separate buses (and locks) it is no longer the case that a single +lock will protect xhci_setup_device from accesses by two parallel +threads processing events on the two buses. + +Fix this by adding a mutex to protect addr_dev and slot_id in struct +xhci_hcd, and by making the assignment of slot_id atomic. + +Fixes multiple boot errors: + +[ 0.583008] xhci_hcd 0000:00:14.0: Bad Slot ID 2 +[ 0.583009] xhci_hcd 0000:00:14.0: Could not allocate xHCI USB device data structures +[ 0.583012] usb usb1-port3: couldn't allocate usb_device + +And: + +[ 0.637409] xhci_hcd 0000:00:14.0: Error while assigning device slot ID +[ 0.637417] xhci_hcd 0000:00:14.0: Max number of devices this xHCI host supports is 32. +[ 0.637421] usb usb1-port1: couldn't allocate usb_device + +And: + +[ 0.753372] xhci_hcd 0000:00:14.0: ERROR: unexpected setup context command completion code 0x0. +[ 0.753373] usb 1-3: hub failed to enable device, error -22 +[ 0.753400] xhci_hcd 0000:00:14.0: Error while assigning device slot ID +[ 0.753402] xhci_hcd 0000:00:14.0: Max number of devices this xHCI host supports is 32. +[ 0.753403] usb usb1-port3: couldn't allocate usb_device + +And: + +[ 11.018386] usb 1-3: device descriptor read/all, error -110 + +And: + +[ 5.753838] xhci_hcd 0000:00:14.0: Timeout while waiting for setup device command + +Tested with 200 reboots, resulting in no USB hub init related errors. + +Fixes: 638139eb95d2 ("usb: hub: allow to process more usb hub events in parallel") +Link: https://lkml.kernel.org/g/CAP-bSRb=A0iEYobdGCLpwynS7pkxpt_9ZnwyZTPVAoy0Y=Zo3Q@mail.gmail.com +Signed-off-by: Chris Bainbridge +[changed git commit description style for checkpatch -Mathias] +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 49 +++++++++++++++++++++++++++++------------------- + drivers/usb/host/xhci.h | 2 + + 2 files changed, 32 insertions(+), 19 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3682,18 +3682,21 @@ int xhci_alloc_dev(struct usb_hcd *hcd, + { + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + unsigned long flags; +- int ret; ++ int ret, slot_id; + struct xhci_command *command; + + command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); + if (!command) + return 0; + ++ /* xhci->slot_id and xhci->addr_dev are not thread-safe */ ++ mutex_lock(&xhci->mutex); + spin_lock_irqsave(&xhci->lock, flags); + command->completion = &xhci->addr_dev; + ret = xhci_queue_slot_control(xhci, command, TRB_ENABLE_SLOT, 0); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); ++ mutex_unlock(&xhci->mutex); + xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); + kfree(command); + return 0; +@@ -3702,8 +3705,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, + spin_unlock_irqrestore(&xhci->lock, flags); + + wait_for_completion(command->completion); ++ slot_id = xhci->slot_id; ++ mutex_unlock(&xhci->mutex); + +- if (!xhci->slot_id || command->status != COMP_SUCCESS) { ++ if (!slot_id || command->status != COMP_SUCCESS) { + xhci_err(xhci, "Error while assigning device slot ID\n"); + xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", + HCS_MAX_SLOTS( +@@ -3728,11 +3733,11 @@ int xhci_alloc_dev(struct usb_hcd *hcd, + * xhci_discover_or_reset_device(), which may be called as part of + * mass storage driver error handling. + */ +- if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { ++ if (!xhci_alloc_virt_device(xhci, slot_id, udev, GFP_NOIO)) { + xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); + goto disable_slot; + } +- udev->slot_id = xhci->slot_id; ++ udev->slot_id = slot_id; + + #ifndef CONFIG_USB_DEFAULT_PERSIST + /* +@@ -3778,12 +3783,15 @@ static int xhci_setup_device(struct usb_ + struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + u64 temp_64; +- struct xhci_command *command; ++ struct xhci_command *command = NULL; ++ ++ mutex_lock(&xhci->mutex); + + if (!udev->slot_id) { + xhci_dbg_trace(xhci, trace_xhci_dbg_address, + "Bad Slot ID %d", udev->slot_id); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; + } + + virt_dev = xhci->devs[udev->slot_id]; +@@ -3796,7 +3804,8 @@ static int xhci_setup_device(struct usb_ + */ + xhci_warn(xhci, "Virt dev invalid for slot_id 0x%x!\n", + udev->slot_id); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; + } + + if (setup == SETUP_CONTEXT_ONLY) { +@@ -3804,13 +3813,15 @@ static int xhci_setup_device(struct usb_ + if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == + SLOT_STATE_DEFAULT) { + xhci_dbg(xhci, "Slot already in default state\n"); +- return 0; ++ goto out; + } + } + + command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); +- if (!command) +- return -ENOMEM; ++ if (!command) { ++ ret = -ENOMEM; ++ goto out; ++ } + + command->in_ctx = virt_dev->in_ctx; + command->completion = &xhci->addr_dev; +@@ -3820,8 +3831,8 @@ static int xhci_setup_device(struct usb_ + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +- kfree(command); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out; + } + /* + * If this is the first Set Address since device plug-in or +@@ -3848,8 +3859,7 @@ static int xhci_setup_device(struct usb_ + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg_trace(xhci, trace_xhci_dbg_address, + "FIXME: allocate a command ring segment"); +- kfree(command); +- return ret; ++ goto out; + } + xhci_ring_cmd_db(xhci); + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -3896,10 +3906,8 @@ static int xhci_setup_device(struct usb_ + ret = -EINVAL; + break; + } +- if (ret) { +- kfree(command); +- return ret; +- } ++ if (ret) ++ goto out; + temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); + xhci_dbg_trace(xhci, trace_xhci_dbg_address, + "Op regs DCBAA ptr = %#016llx", temp_64); +@@ -3932,8 +3940,10 @@ static int xhci_setup_device(struct usb_ + xhci_dbg_trace(xhci, trace_xhci_dbg_address, + "Internal device address = %d", + le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); ++out: ++ mutex_unlock(&xhci->mutex); + kfree(command); +- return 0; ++ return ret; + } + + int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) +@@ -4855,6 +4865,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, + return 0; + } + ++ mutex_init(&xhci->mutex); + xhci->cap_regs = hcd->regs; + xhci->op_regs = hcd->regs + + HC_LENGTH(readl(&xhci->cap_regs->hc_capbase)); +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1497,6 +1497,8 @@ struct xhci_hcd { + struct list_head lpm_failed_devs; + + /* slot enabling and address device helpers */ ++ /* these are not thread safe so use mutex */ ++ struct mutex mutex; + struct completion addr_dev; + int slot_id; + /* For USB 3.0 LPM enable/disable. */ diff --git a/queue-4.0/usb-make-module-xhci_hcd-removable.patch b/queue-4.0/usb-make-module-xhci_hcd-removable.patch new file mode 100644 index 00000000000..68fd2e0c1a1 --- /dev/null +++ b/queue-4.0/usb-make-module-xhci_hcd-removable.patch @@ -0,0 +1,39 @@ +From b04c846ceaad42f9e37f3626c7e8f457603863f0 Mon Sep 17 00:00:00 2001 +From: Arthur Demchenkov +Date: Tue, 19 May 2015 16:30:50 +0300 +Subject: usb: make module xhci_hcd removable + +From: Arthur Demchenkov + +commit b04c846ceaad42f9e37f3626c7e8f457603863f0 upstream. + +Fixed regression. After commit 29e409f0f761 ("xhci: Allow xHCI drivers to +be built as separate modules") the module xhci_hcd became non-removable. +That behaviour is not expected and there're no notes about it in commit +message. The module should be removable as it blocks PM suspend/resume +functions (Debian Bug#666406). + +Signed-off-by: Arthur Demchenkov +Reviewed-by: Andrew Bresticker +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -5022,4 +5022,12 @@ static int __init xhci_hcd_init(void) + BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); + return 0; + } ++ ++/* ++ * If an init function is provided, an exit function must also be provided ++ * to allow module unload. ++ */ ++static void __exit xhci_hcd_fini(void) { } ++ + module_init(xhci_hcd_init); ++module_exit(xhci_hcd_fini); diff --git a/queue-4.0/usb-serial-ftdi_sio-add-support-for-a-motion-tracker-development-board.patch b/queue-4.0/usb-serial-ftdi_sio-add-support-for-a-motion-tracker-development-board.patch new file mode 100644 index 00000000000..7fdadbbaeaf --- /dev/null +++ b/queue-4.0/usb-serial-ftdi_sio-add-support-for-a-motion-tracker-development-board.patch @@ -0,0 +1,41 @@ +From 1df5b888f54070a373a73b34488cc78c2365b7b4 Mon Sep 17 00:00:00 2001 +From: Patrick Riphagen +Date: Tue, 19 May 2015 10:03:01 +0200 +Subject: USB: serial: ftdi_sio: Add support for a Motion Tracker Development Board + +From: Patrick Riphagen + +commit 1df5b888f54070a373a73b34488cc78c2365b7b4 upstream. + +This adds support for new Xsens device, Motion Tracker Development Board, +using Xsens' own Vendor ID + +Signed-off-by: Patrick Riphagen +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 1 + + drivers/usb/serial/ftdi_sio_ids.h | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -699,6 +699,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(XSENS_VID, XSENS_AWINDA_DONGLE_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_AWINDA_STATION_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_CONVERTER_PID) }, ++ { USB_DEVICE(XSENS_VID, XSENS_MTDEVBOARD_PID) }, + { USB_DEVICE(XSENS_VID, XSENS_MTW_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OMNI1509) }, + { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -155,6 +155,7 @@ + #define XSENS_AWINDA_STATION_PID 0x0101 + #define XSENS_AWINDA_DONGLE_PID 0x0102 + #define XSENS_MTW_PID 0x0200 /* Xsens MTw */ ++#define XSENS_MTDEVBOARD_PID 0x0300 /* Motion Tracker Development Board */ + #define XSENS_CONVERTER_PID 0xD00D /* Xsens USB-serial converter */ + + /* Xsens devices using FTDI VID */ diff --git a/queue-4.0/x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch b/queue-4.0/x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch new file mode 100644 index 00000000000..11e38e8efa1 --- /dev/null +++ b/queue-4.0/x86-asm-irq-stop-relying-on-magic-jmp-behavior-for-early_idt_handlers.patch @@ -0,0 +1,251 @@ +From 425be5679fd292a3c36cb1fe423086708a99f11a Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Fri, 22 May 2015 16:15:47 -0700 +Subject: x86/asm/irq: Stop relying on magic JMP behavior for early_idt_handlers + +From: Andy Lutomirski + +commit 425be5679fd292a3c36cb1fe423086708a99f11a upstream. + +The early_idt_handlers asm code generates an array of entry +points spaced nine bytes apart. It's not really clear from that +code or from the places that reference it what's going on, and +the code only works in the first place because GAS never +generates two-byte JMP instructions when jumping to global +labels. + +Clean up the code to generate the correct array stride (member size) +explicitly. This should be considerably more robust against +screw-ups, as GAS will warn if a .fill directive has a negative +count. Using '. =' to advance would have been even more robust +(it would generate an actual error if it tried to move +backwards), but it would pad with nulls, confusing anyone who +tries to disassemble the code. The new scheme should be much +clearer to future readers. + +While we're at it, improve the comments and rename the array and +common code. + +Binutils may start relaxing jumps to non-weak labels. If so, +this change will fix our build, and we may need to backport this +change. + +Before, on x86_64: + + 0000000000000000 : + 0: 6a 00 pushq $0x0 + 2: 6a 00 pushq $0x0 + 4: e9 00 00 00 00 jmpq 9 + 5: R_X86_64_PC32 early_idt_handler-0x4 + ... + 48: 66 90 xchg %ax,%ax + 4a: 6a 08 pushq $0x8 + 4c: e9 00 00 00 00 jmpq 51 + 4d: R_X86_64_PC32 early_idt_handler-0x4 + ... + 117: 6a 00 pushq $0x0 + 119: 6a 1f pushq $0x1f + 11b: e9 00 00 00 00 jmpq 120 + 11c: R_X86_64_PC32 early_idt_handler-0x4 + +After: + + 0000000000000000 : + 0: 6a 00 pushq $0x0 + 2: 6a 00 pushq $0x0 + 4: e9 14 01 00 00 jmpq 11d + ... + 48: 6a 08 pushq $0x8 + 4a: e9 d1 00 00 00 jmpq 120 + 4f: cc int3 + 50: cc int3 + ... + 117: 6a 00 pushq $0x0 + 119: 6a 1f pushq $0x1f + 11b: eb 03 jmp 120 + 11d: cc int3 + 11e: cc int3 + 11f: cc int3 + +Signed-off-by: Andy Lutomirski +Acked-by: H. Peter Anvin +Cc: Binutils +Cc: Borislav Petkov +Cc: H.J. Lu +Cc: Jan Beulich +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/ac027962af343b0c599cbfcf50b945ad2ef3d7a8.1432336324.git.luto@kernel.org +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/segment.h | 15 +++++++++++++-- + arch/x86/kernel/head64.c | 2 +- + arch/x86/kernel/head_32.S | 33 ++++++++++++++++++--------------- + arch/x86/kernel/head_64.S | 20 +++++++++++--------- + 4 files changed, 43 insertions(+), 27 deletions(-) + +--- a/arch/x86/include/asm/segment.h ++++ b/arch/x86/include/asm/segment.h +@@ -200,10 +200,21 @@ + #define TLS_SIZE (GDT_ENTRY_TLS_ENTRIES * 8) + + #ifdef __KERNEL__ ++ ++/* ++ * early_idt_handler_array is an array of entry points referenced in the ++ * early IDT. For simplicity, it's a real array with one entry point ++ * every nine bytes. That leaves room for an optional 'push $0' if the ++ * vector has no error code (two bytes), a 'push $vector_number' (two ++ * bytes), and a jump to the common entry code (up to five bytes). ++ */ ++#define EARLY_IDT_HANDLER_SIZE 9 ++ + #ifndef __ASSEMBLY__ +-extern const char early_idt_handlers[NUM_EXCEPTION_VECTORS][2+2+5]; ++ ++extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; + #ifdef CONFIG_TRACING +-#define trace_early_idt_handlers early_idt_handlers ++# define trace_early_idt_handler_array early_idt_handler_array + #endif + + /* +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -167,7 +167,7 @@ asmlinkage __visible void __init x86_64_ + clear_bss(); + + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) +- set_intr_gate(i, early_idt_handlers[i]); ++ set_intr_gate(i, early_idt_handler_array[i]); + load_idt((const struct desc_ptr *)&idt_descr); + + copy_bootdata(__va(real_mode_data)); +--- a/arch/x86/kernel/head_32.S ++++ b/arch/x86/kernel/head_32.S +@@ -477,21 +477,22 @@ is486: + __INIT + setup_once: + /* +- * Set up a idt with 256 entries pointing to ignore_int, +- * interrupt gates. It doesn't actually load idt - that needs +- * to be done on each CPU. Interrupts are enabled elsewhere, +- * when we can be relatively sure everything is ok. ++ * Set up a idt with 256 interrupt gates that push zero if there ++ * is no error code and then jump to early_idt_handler_common. ++ * It doesn't actually load the idt - that needs to be done on ++ * each CPU. Interrupts are enabled elsewhere, when we can be ++ * relatively sure everything is ok. + */ + + movl $idt_table,%edi +- movl $early_idt_handlers,%eax ++ movl $early_idt_handler_array,%eax + movl $NUM_EXCEPTION_VECTORS,%ecx + 1: + movl %eax,(%edi) + movl %eax,4(%edi) + /* interrupt gate, dpl=0, present */ + movl $(0x8E000000 + __KERNEL_CS),2(%edi) +- addl $9,%eax ++ addl $EARLY_IDT_HANDLER_SIZE,%eax + addl $8,%edi + loop 1b + +@@ -523,26 +524,28 @@ setup_once: + andl $0,setup_once_ref /* Once is enough, thanks */ + ret + +-ENTRY(early_idt_handlers) ++ENTRY(early_idt_handler_array) + # 36(%esp) %eflags + # 32(%esp) %cs + # 28(%esp) %eip + # 24(%rsp) error code + i = 0 + .rept NUM_EXCEPTION_VECTORS +- .if (EXCEPTION_ERRCODE_MASK >> i) & 1 +- ASM_NOP2 +- .else ++ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 + pushl $0 # Dummy error code, to make stack frame uniform + .endif + pushl $i # 20(%esp) Vector number +- jmp early_idt_handler ++ jmp early_idt_handler_common + i = i + 1 ++ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc + .endr +-ENDPROC(early_idt_handlers) ++ENDPROC(early_idt_handler_array) + +- /* This is global to keep gas from relaxing the jumps */ +-ENTRY(early_idt_handler) ++early_idt_handler_common: ++ /* ++ * The stack is the hardware frame, an error code or zero, and the ++ * vector number. ++ */ + cld + + cmpl $2,(%esp) # X86_TRAP_NMI +@@ -602,7 +605,7 @@ ex_entry: + is_nmi: + addl $8,%esp /* drop vector number and error code */ + iret +-ENDPROC(early_idt_handler) ++ENDPROC(early_idt_handler_common) + + /* This is the default interrupt "handler" :-) */ + ALIGN +--- a/arch/x86/kernel/head_64.S ++++ b/arch/x86/kernel/head_64.S +@@ -321,26 +321,28 @@ bad_address: + jmp bad_address + + __INIT +- .globl early_idt_handlers +-early_idt_handlers: ++ENTRY(early_idt_handler_array) + # 104(%rsp) %rflags + # 96(%rsp) %cs + # 88(%rsp) %rip + # 80(%rsp) error code + i = 0 + .rept NUM_EXCEPTION_VECTORS +- .if (EXCEPTION_ERRCODE_MASK >> i) & 1 +- ASM_NOP2 +- .else ++ .ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1 + pushq $0 # Dummy error code, to make stack frame uniform + .endif + pushq $i # 72(%rsp) Vector number +- jmp early_idt_handler ++ jmp early_idt_handler_common + i = i + 1 ++ .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc + .endr ++ENDPROC(early_idt_handler_array) + +-/* This is global to keep gas from relaxing the jumps */ +-ENTRY(early_idt_handler) ++early_idt_handler_common: ++ /* ++ * The stack is the hardware frame, an error code or zero, and the ++ * vector number. ++ */ + cld + + cmpl $2,(%rsp) # X86_TRAP_NMI +@@ -412,7 +414,7 @@ ENTRY(early_idt_handler) + is_nmi: + addq $16,%rsp # drop vector number and error code + INTERRUPT_RETURN +-ENDPROC(early_idt_handler) ++ENDPROC(early_idt_handler_common) + + __INITDATA +