From: Greg Kroah-Hartman Date: Tue, 27 Jan 2015 18:34:30 +0000 (-0800) Subject: 3.18-stable patches X-Git-Tag: v3.10.67~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=310863188263bcfdcb56caeabdbaba6dfd223a99;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: cx23885-split-hauppauge-wintv-starburst-from-hvr4400-card-entry.patch ipr-wait-for-aborted-command-responses.patch pci-add-flag-for-devices-where-we-can-t-use-bus-reset.patch pci-add-pci_bus_clip_resource-to-clip-to-fit-upstream-window.patch pci-add-pci_claim_bridge_resource-to-clip-window-if-necessary.patch pci-mark-atheros-ar93xx-to-avoid-bus-reset.patch pci-pass-bridge-device-not-bus-when-updating-bridge-windows.patch vb2-fix-vb2_thread_stop-race-conditions.patch x86-pci-clip-bridge-windows-to-fit-in-upstream-windows.patch --- diff --git a/queue-3.18/cx23885-split-hauppauge-wintv-starburst-from-hvr4400-card-entry.patch b/queue-3.18/cx23885-split-hauppauge-wintv-starburst-from-hvr4400-card-entry.patch new file mode 100644 index 00000000000..150b247b71f --- /dev/null +++ b/queue-3.18/cx23885-split-hauppauge-wintv-starburst-from-hvr4400-card-entry.patch @@ -0,0 +1,137 @@ +From 721f3223f26bbe81c7e55f84188e74d99df50a16 Mon Sep 17 00:00:00 2001 +From: Matthias Schwarzott +Date: Mon, 22 Dec 2014 19:51:39 -0300 +Subject: [media] cx23885: Split Hauppauge WinTV Starburst from HVR4400 card entry + +From: Matthias Schwarzott + +commit 721f3223f26bbe81c7e55f84188e74d99df50a16 upstream. + +Unconditionally attaching Si2161/Si2165 demod driver +breaks Hauppauge WinTV Starburst. +So create own card entry for this. + +Add card name comments to the subsystem ids. + +This fixes a regression introduced in 3.17 by +36efec48e2e6016e05364906720a0ec350a5d768 ([media] cx23885: Add si2165 support for HVR-5500) + +Signed-off-by: Matthias Schwarzott +Tested-by: Antti Palosaari +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/pci/cx23885/cx23885-cards.c | 23 +++++++++++++++++------ + drivers/media/pci/cx23885/cx23885-dvb.c | 11 +++++++++++ + drivers/media/pci/cx23885/cx23885.h | 1 + + 3 files changed, 29 insertions(+), 6 deletions(-) + +--- a/drivers/media/pci/cx23885/cx23885-cards.c ++++ b/drivers/media/pci/cx23885/cx23885-cards.c +@@ -614,7 +614,7 @@ struct cx23885_board cx23885_boards[] = + .portb = CX23885_MPEG_DVB, + }, + [CX23885_BOARD_HAUPPAUGE_HVR4400] = { +- .name = "Hauppauge WinTV-HVR4400", ++ .name = "Hauppauge WinTV-HVR4400/HVR5500", + .porta = CX23885_ANALOG_VIDEO, + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, +@@ -622,6 +622,10 @@ struct cx23885_board cx23885_boards[] = + .tuner_addr = 0x60, /* 0xc0 >> 1 */ + .tuner_bus = 1, + }, ++ [CX23885_BOARD_HAUPPAUGE_STARBURST] = { ++ .name = "Hauppauge WinTV Starburst", ++ .portb = CX23885_MPEG_DVB, ++ }, + [CX23885_BOARD_AVERMEDIA_HC81R] = { + .name = "AVerTV Hybrid Express Slim HC81R", + .tuner_type = TUNER_XC2028, +@@ -910,19 +914,19 @@ struct cx23885_subid cx23885_subids[] = + }, { + .subvendor = 0x0070, + .subdevice = 0xc108, +- .card = CX23885_BOARD_HAUPPAUGE_HVR4400, ++ .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-4400 (Model 121xxx, Hybrid DVB-T/S2, IR) */ + }, { + .subvendor = 0x0070, + .subdevice = 0xc138, +- .card = CX23885_BOARD_HAUPPAUGE_HVR4400, ++ .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ + }, { + .subvendor = 0x0070, + .subdevice = 0xc12a, +- .card = CX23885_BOARD_HAUPPAUGE_HVR4400, ++ .card = CX23885_BOARD_HAUPPAUGE_STARBURST, /* Hauppauge WinTV Starburst (Model 121x00, DVB-S2, IR) */ + }, { + .subvendor = 0x0070, + .subdevice = 0xc1f8, +- .card = CX23885_BOARD_HAUPPAUGE_HVR4400, ++ .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ + }, { + .subvendor = 0x1461, + .subdevice = 0xd939, +@@ -1495,8 +1499,9 @@ void cx23885_gpio_setup(struct cx23885_d + cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ + break; + case CX23885_BOARD_HAUPPAUGE_HVR4400: ++ case CX23885_BOARD_HAUPPAUGE_STARBURST: + /* GPIO-8 tda10071 demod reset */ +- /* GPIO-9 si2165 demod reset */ ++ /* GPIO-9 si2165 demod reset (only HVR4400/HVR5500)*/ + + /* Put the parts into reset and back */ + cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); +@@ -1760,6 +1765,7 @@ void cx23885_card_setup(struct cx23885_d + case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: + case CX23885_BOARD_HAUPPAUGE_HVR4400: ++ case CX23885_BOARD_HAUPPAUGE_STARBURST: + case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: + if (dev->i2c_bus[0].i2c_rc == 0) + hauppauge_eeprom(dev, eeprom+0xc0); +@@ -1864,6 +1870,11 @@ void cx23885_card_setup(struct cx23885_d + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; ++ case CX23885_BOARD_HAUPPAUGE_STARBURST: ++ ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ++ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ++ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ++ break; + case CX23885_BOARD_DVBSKY_T9580: + ts1->gen_ctrl_val = 0x5; /* Parallel */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ +--- a/drivers/media/pci/cx23885/cx23885-dvb.c ++++ b/drivers/media/pci/cx23885/cx23885-dvb.c +@@ -1586,6 +1586,17 @@ static int dvb_register(struct cx23885_t + break; + } + break; ++ case CX23885_BOARD_HAUPPAUGE_STARBURST: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(tda10071_attach, ++ &hauppauge_tda10071_config, ++ &i2c_bus->i2c_adap); ++ if (fe0->dvb.frontend != NULL) { ++ dvb_attach(a8293_attach, fe0->dvb.frontend, ++ &i2c_bus->i2c_adap, ++ &hauppauge_a8293_config); ++ } ++ break; + case CX23885_BOARD_DVBSKY_T9580: + i2c_bus = &dev->i2c_bus[0]; + i2c_bus2 = &dev->i2c_bus[1]; +--- a/drivers/media/pci/cx23885/cx23885.h ++++ b/drivers/media/pci/cx23885/cx23885.h +@@ -93,6 +93,7 @@ + #define CX23885_BOARD_HAUPPAUGE_IMPACTVCBE 43 + #define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP2 44 + #define CX23885_BOARD_DVBSKY_T9580 45 ++#define CX23885_BOARD_HAUPPAUGE_STARBURST 52 + + #define GPIO_0 0x00000001 + #define GPIO_1 0x00000002 diff --git a/queue-3.18/ipr-wait-for-aborted-command-responses.patch b/queue-3.18/ipr-wait-for-aborted-command-responses.patch new file mode 100644 index 00000000000..e605071f542 --- /dev/null +++ b/queue-3.18/ipr-wait-for-aborted-command-responses.patch @@ -0,0 +1,183 @@ +From 6cdb08172bc89f0a39e1643c5e7eab362692fd1b Mon Sep 17 00:00:00 2001 +From: Brian King +Date: Thu, 30 Oct 2014 17:27:10 -0500 +Subject: ipr: wait for aborted command responses + +From: Brian King + +commit 6cdb08172bc89f0a39e1643c5e7eab362692fd1b upstream. + +Fixes a race condition in abort handling that was injected +when multiple interrupt support was added. When only a single +interrupt is present, the adapter guarantees it will send +responses for aborted commands prior to the response for the +abort command itself. With multiple interrupts, these responses +generally come back on different interrupts, so we need to +ensure the abort thread waits until the aborted command is +complete so we don't perform a double completion. This race +condition was being hit frequently in environments which +were triggering command timeouts, which was resulting in +a double completion causing a kernel oops. + +Signed-off-by: Brian King +Reviewed-by: Wendy Xiong +Tested-by: Wendy Xiong +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/ipr.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + drivers/scsi/ipr.h | 1 + 2 files changed, 93 insertions(+) + +--- a/drivers/scsi/ipr.c ++++ b/drivers/scsi/ipr.c +@@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipr + ipr_reinit_ipr_cmnd(ipr_cmd); + ipr_cmd->u.scratch = 0; + ipr_cmd->sibling = NULL; ++ ipr_cmd->eh_comp = NULL; + ipr_cmd->fast_done = fast_done; + init_timer(&ipr_cmd->timer); + } +@@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_ + + scsi_dma_unmap(ipr_cmd->scsi_cmd); + scsi_cmd->scsi_done(scsi_cmd); ++ if (ipr_cmd->eh_comp) ++ complete(ipr_cmd->eh_comp); + list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); + } + +@@ -4853,6 +4856,84 @@ static int ipr_slave_alloc(struct scsi_d + return rc; + } + ++/** ++ * ipr_match_lun - Match function for specified LUN ++ * @ipr_cmd: ipr command struct ++ * @device: device to match (sdev) ++ * ++ * Returns: ++ * 1 if command matches sdev / 0 if command does not match sdev ++ **/ ++static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device) ++{ ++ if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device) ++ return 1; ++ return 0; ++} ++ ++/** ++ * ipr_wait_for_ops - Wait for matching commands to complete ++ * @ipr_cmd: ipr command struct ++ * @device: device to match (sdev) ++ * @match: match function to use ++ * ++ * Returns: ++ * SUCCESS / FAILED ++ **/ ++static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device, ++ int (*match)(struct ipr_cmnd *, void *)) ++{ ++ struct ipr_cmnd *ipr_cmd; ++ int wait; ++ unsigned long flags; ++ struct ipr_hrr_queue *hrrq; ++ signed long timeout = IPR_ABORT_TASK_TIMEOUT; ++ DECLARE_COMPLETION_ONSTACK(comp); ++ ++ ENTER; ++ do { ++ wait = 0; ++ ++ for_each_hrrq(hrrq, ioa_cfg) { ++ spin_lock_irqsave(hrrq->lock, flags); ++ list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { ++ if (match(ipr_cmd, device)) { ++ ipr_cmd->eh_comp = ∁ ++ wait++; ++ } ++ } ++ spin_unlock_irqrestore(hrrq->lock, flags); ++ } ++ ++ if (wait) { ++ timeout = wait_for_completion_timeout(&comp, timeout); ++ ++ if (!timeout) { ++ wait = 0; ++ ++ for_each_hrrq(hrrq, ioa_cfg) { ++ spin_lock_irqsave(hrrq->lock, flags); ++ list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { ++ if (match(ipr_cmd, device)) { ++ ipr_cmd->eh_comp = NULL; ++ wait++; ++ } ++ } ++ spin_unlock_irqrestore(hrrq->lock, flags); ++ } ++ ++ if (wait) ++ dev_err(&ioa_cfg->pdev->dev, "Timed out waiting for aborted commands\n"); ++ LEAVE; ++ return wait ? FAILED : SUCCESS; ++ } ++ } ++ } while (wait); ++ ++ LEAVE; ++ return SUCCESS; ++} ++ + static int ipr_eh_host_reset(struct scsi_cmnd *cmd) + { + struct ipr_ioa_cfg *ioa_cfg; +@@ -5072,11 +5153,17 @@ static int __ipr_eh_dev_reset(struct scs + static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) + { + int rc; ++ struct ipr_ioa_cfg *ioa_cfg; ++ ++ ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; + + spin_lock_irq(cmd->device->host->host_lock); + rc = __ipr_eh_dev_reset(cmd); + spin_unlock_irq(cmd->device->host->host_lock); + ++ if (rc == SUCCESS) ++ rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun); ++ + return rc; + } + +@@ -5254,13 +5341,18 @@ static int ipr_eh_abort(struct scsi_cmnd + { + unsigned long flags; + int rc; ++ struct ipr_ioa_cfg *ioa_cfg; + + ENTER; + ++ ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; ++ + spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); + rc = ipr_cancel_op(scsi_cmd); + spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); + ++ if (rc == SUCCESS) ++ rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun); + LEAVE; + return rc; + } +--- a/drivers/scsi/ipr.h ++++ b/drivers/scsi/ipr.h +@@ -1608,6 +1608,7 @@ struct ipr_cmnd { + struct scsi_device *sdev; + } u; + ++ struct completion *eh_comp; + struct ipr_hrr_queue *hrrq; + struct ipr_ioa_cfg *ioa_cfg; + }; diff --git a/queue-3.18/pci-add-flag-for-devices-where-we-can-t-use-bus-reset.patch b/queue-3.18/pci-add-flag-for-devices-where-we-can-t-use-bus-reset.patch new file mode 100644 index 00000000000..15263791179 --- /dev/null +++ b/queue-3.18/pci-add-flag-for-devices-where-we-can-t-use-bus-reset.patch @@ -0,0 +1,120 @@ +From f331a859e0ee5a898c1f47596eddad4c4f02d657 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Thu, 15 Jan 2015 18:16:04 -0600 +Subject: PCI: Add flag for devices where we can't use bus reset + +From: Alex Williamson + +commit f331a859e0ee5a898c1f47596eddad4c4f02d657 upstream. + +Enable a mechanism for devices to quirk that they do not behave when +doing a PCI bus reset. We require a modest level of spec compliant +behavior in order to do a reset, for instance the device should come +out of reset without throwing errors and PCI config space should be +accessible after reset. This is too much to ask for some devices. + +Link: http://lkml.kernel.org/r/20140923210318.498dacbd@dualc.maya.org +Signed-off-by: Alex Williamson +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci.c | 40 ++++++++++++++++++++++++++++++++++++---- + include/linux/pci.h | 2 ++ + 2 files changed, 38 insertions(+), 4 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -3280,7 +3280,8 @@ static int pci_parent_bus_reset(struct p + { + struct pci_dev *pdev; + +- if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self) ++ if (pci_is_root_bus(dev->bus) || dev->subordinate || ++ !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) + return -ENOTTY; + + list_for_each_entry(pdev, &dev->bus->devices, bus_list) +@@ -3314,7 +3315,8 @@ static int pci_dev_reset_slot_function(s + { + struct pci_dev *pdev; + +- if (dev->subordinate || !dev->slot) ++ if (dev->subordinate || !dev->slot || ++ dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) + return -ENOTTY; + + list_for_each_entry(pdev, &dev->bus->devices, bus_list) +@@ -3566,6 +3568,20 @@ int pci_try_reset_function(struct pci_de + } + EXPORT_SYMBOL_GPL(pci_try_reset_function); + ++/* Do any devices on or below this bus prevent a bus reset? */ ++static bool pci_bus_resetable(struct pci_bus *bus) ++{ ++ struct pci_dev *dev; ++ ++ list_for_each_entry(dev, &bus->devices, bus_list) { ++ if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || ++ (dev->subordinate && !pci_bus_resetable(dev->subordinate))) ++ return false; ++ } ++ ++ return true; ++} ++ + /* Lock devices from the top of the tree down */ + static void pci_bus_lock(struct pci_bus *bus) + { +@@ -3616,6 +3632,22 @@ unlock: + return 0; + } + ++/* Do any devices on or below this slot prevent a bus reset? */ ++static bool pci_slot_resetable(struct pci_slot *slot) ++{ ++ struct pci_dev *dev; ++ ++ list_for_each_entry(dev, &slot->bus->devices, bus_list) { ++ if (!dev->slot || dev->slot != slot) ++ continue; ++ if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || ++ (dev->subordinate && !pci_bus_resetable(dev->subordinate))) ++ return false; ++ } ++ ++ return true; ++} ++ + /* Lock devices from the top of the tree down */ + static void pci_slot_lock(struct pci_slot *slot) + { +@@ -3737,7 +3769,7 @@ static int pci_slot_reset(struct pci_slo + { + int rc; + +- if (!slot) ++ if (!slot || !pci_slot_resetable(slot)) + return -ENOTTY; + + if (!probe) +@@ -3829,7 +3861,7 @@ EXPORT_SYMBOL_GPL(pci_try_reset_slot); + + static int pci_bus_reset(struct pci_bus *bus, int probe) + { +- if (!bus->self) ++ if (!bus->self || !pci_bus_resetable(bus)) + return -ENOTTY; + + if (probe) +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -175,6 +175,8 @@ enum pci_dev_flags { + PCI_DEV_FLAGS_DMA_ALIAS_DEVFN = (__force pci_dev_flags_t) (1 << 4), + /* Use a PCIe-to-PCI bridge alias even if !pci_is_pcie */ + PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS = (__force pci_dev_flags_t) (1 << 5), ++ /* Do not use bus resets for device */ ++ PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), + }; + + enum pci_irq_reroute_variant { diff --git a/queue-3.18/pci-add-pci_bus_clip_resource-to-clip-to-fit-upstream-window.patch b/queue-3.18/pci-add-pci_bus_clip_resource-to-clip-to-fit-upstream-window.patch new file mode 100644 index 00000000000..7ddd1630c01 --- /dev/null +++ b/queue-3.18/pci-add-pci_bus_clip_resource-to-clip-to-fit-upstream-window.patch @@ -0,0 +1,89 @@ +From 0f7e7aee2f37119a32e6e8b63250922442528961 Mon Sep 17 00:00:00 2001 +From: Yinghai Lu +Date: Thu, 15 Jan 2015 16:21:49 -0600 +Subject: PCI: Add pci_bus_clip_resource() to clip to fit upstream window + +From: Yinghai Lu + +commit 0f7e7aee2f37119a32e6e8b63250922442528961 upstream. + +Add pci_bus_clip_resource(). If a PCI-PCI bridge window overlaps an +upstream bridge window but is not completely contained by it, this clips +the downstream window so it fits inside the upstream one. + +No functional change (this adds the function but no callers). + +[bhelgaas: changelog, split into separate patch] +Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 +Reported-by: Marek Kordik +Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") +Signed-off-by: Yinghai Lu +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c +index 73aef51a28f0..8fb16188cd82 100644 +--- a/drivers/pci/bus.c ++++ b/drivers/pci/bus.c +@@ -228,6 +228,49 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, + } + EXPORT_SYMBOL(pci_bus_alloc_resource); + ++/* ++ * The @idx resource of @dev should be a PCI-PCI bridge window. If this ++ * resource fits inside a window of an upstream bridge, do nothing. If it ++ * overlaps an upstream window but extends outside it, clip the resource so ++ * it fits completely inside. ++ */ ++bool pci_bus_clip_resource(struct pci_dev *dev, int idx) ++{ ++ struct pci_bus *bus = dev->bus; ++ struct resource *res = &dev->resource[idx]; ++ struct resource orig_res = *res; ++ struct resource *r; ++ int i; ++ ++ pci_bus_for_each_resource(bus, r, i) { ++ resource_size_t start, end; ++ ++ if (!r) ++ continue; ++ ++ if (resource_type(res) != resource_type(r)) ++ continue; ++ ++ start = max(r->start, res->start); ++ end = min(r->end, res->end); ++ ++ if (start > end) ++ continue; /* no overlap */ ++ ++ if (res->start == start && res->end == end) ++ return false; /* no change */ ++ ++ res->start = start; ++ res->end = end; ++ dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n", ++ &orig_res, res); ++ ++ return true; ++ } ++ ++ return false; ++} ++ + void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } + + /** +diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h +index 8aff29a804ff..d54632a1db43 100644 +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -208,6 +208,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, + void __pci_bus_assign_resources(const struct pci_bus *bus, + struct list_head *realloc_head, + struct list_head *fail_head); ++bool pci_bus_clip_resource(struct pci_dev *dev, int idx); + + /** + * pci_ari_enabled - query ARI forwarding status diff --git a/queue-3.18/pci-add-pci_claim_bridge_resource-to-clip-window-if-necessary.patch b/queue-3.18/pci-add-pci_claim_bridge_resource-to-clip-window-if-necessary.patch new file mode 100644 index 00000000000..053e1c86956 --- /dev/null +++ b/queue-3.18/pci-add-pci_claim_bridge_resource-to-clip-window-if-necessary.patch @@ -0,0 +1,104 @@ +From 8505e729a2f6eb0803ff943a15f133dd10afff3a Mon Sep 17 00:00:00 2001 +From: Yinghai Lu +Date: Thu, 15 Jan 2015 16:21:49 -0600 +Subject: PCI: Add pci_claim_bridge_resource() to clip window if necessary + +From: Yinghai Lu + +commit 8505e729a2f6eb0803ff943a15f133dd10afff3a upstream. + +Add pci_claim_bridge_resource() to claim a PCI-PCI bridge window. This is +like regular pci_claim_resource(), except that if we fail to claim the +window, we check to see if we can reduce the size of the window and try +again. + +This is for scenarios like this: + + pci_bus 0000:00: root bus resource [mem 0xc0000000-0xffffffff] + pci 0000:00:01.0: bridge window [mem 0xbdf00000-0xddefffff 64bit pref] + pci 0000:01:00.0: reg 0x10: [mem 0xc0000000-0xcfffffff pref] + +The 00:01.0 window is illegal: it starts before the host bridge window, so +we have to assume the [0xbdf00000-0xbfffffff] region is inaccessible. We +can make it legal by clipping it to [mem 0xc0000000-0xddefffff 64bit pref]. + +Previously we discarded the 00:01.0 window and tried to reassign that part +of the hierarchy from scratch. That is a problem because Linux doesn't +always assign things optimally. For example, in this case, BIOS put the +01:00.0 device in a prefetchable window below 4GB, but after 5b28541552ef, +Linux puts the prefetchable window above 4GB where the 32-bit 01:00.0 +device can't use it. + +Clipping the 00:01.0 window is less intrusive than completely reassigning +things and is sufficient to let us use most of the BIOS configuration. Of +course, it's possible that devices below 00:01.0 will no longer fit. If +that's the case, we'll have to reassign things. But that's a separate +problem. + +[bhelgaas: changelog, split into separate patch] +Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 +Reported-by: Marek Kordik +Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") +Signed-off-by: Yinghai Lu +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/setup-bus.c | 35 +++++++++++++++++++++++++++++++++++ + include/linux/pci.h | 1 + + 2 files changed, 36 insertions(+) + +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -646,6 +646,41 @@ void pci_setup_bridge(struct pci_bus *bu + __pci_setup_bridge(bus, type); + } + ++ ++int pci_claim_bridge_resource(struct pci_dev *bridge, int i) ++{ ++ if (i < PCI_BRIDGE_RESOURCES || i > PCI_BRIDGE_RESOURCE_END) ++ return 0; ++ ++ if (pci_claim_resource(bridge, i) == 0) ++ return 0; /* claimed the window */ ++ ++ if ((bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI) ++ return 0; ++ ++ if (!pci_bus_clip_resource(bridge, i)) ++ return -EINVAL; /* clipping didn't change anything */ ++ ++ switch (i - PCI_BRIDGE_RESOURCES) { ++ case 0: ++ pci_setup_bridge_io(bridge); ++ break; ++ case 1: ++ pci_setup_bridge_mmio(bridge); ++ break; ++ case 2: ++ pci_setup_bridge_mmio_pref(bridge); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (pci_claim_resource(bridge, i) == 0) ++ return 0; /* claimed a smaller window */ ++ ++ return -EINVAL; ++} ++ + /* Check whether the bridge supports optional I/O and + prefetchable memory ranges. If not, the respective + base/limit registers must be read-only and read as 0. */ +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1062,6 +1062,7 @@ resource_size_t pcibios_retrieve_fw_addr + void pci_bus_assign_resources(const struct pci_bus *bus); + void pci_bus_size_bridges(struct pci_bus *bus); + int pci_claim_resource(struct pci_dev *, int); ++int pci_claim_bridge_resource(struct pci_dev *bridge, int i); + void pci_assign_unassigned_resources(void); + void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge); + void pci_assign_unassigned_bus_resources(struct pci_bus *bus); diff --git a/queue-3.18/pci-mark-atheros-ar93xx-to-avoid-bus-reset.patch b/queue-3.18/pci-mark-atheros-ar93xx-to-avoid-bus-reset.patch new file mode 100644 index 00000000000..798c894ad89 --- /dev/null +++ b/queue-3.18/pci-mark-atheros-ar93xx-to-avoid-bus-reset.patch @@ -0,0 +1,55 @@ +From c3e59ee4e76686b0c84ca8faa1011d10cd4ca1b8 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Thu, 15 Jan 2015 18:17:12 -0600 +Subject: PCI: Mark Atheros AR93xx to avoid bus reset + +From: Alex Williamson + +commit c3e59ee4e76686b0c84ca8faa1011d10cd4ca1b8 upstream. + +Reports against the TL-WDN4800 card indicate that PCI bus reset of this +Atheros device cause system lock-ups and resets. I've also been able to +confirm this behavior on multiple systems. The device never returns from +reset and attempts to access config space of the device after reset result +in hangs. Blacklist bus reset for the device to avoid this issue. + +[bhelgaas: This regression appeared in v3.14. Andreas bisected it to +425c1b223dac ("PCI: Add Virtual Channel to save/restore support"), but we +don't understand the mechanism by which that commit affects the reset +path.] + +[bhelgaas: changelog, references] +Link: http://lkml.kernel.org/r/20140923210318.498dacbd@dualc.maya.org +Reported-by: Andreas Hartmann +Tested-by: Andreas Hartmann +Signed-off-by: Alex Williamson +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/quirks.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3008,6 +3008,20 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_R + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, + quirk_broken_intx_masking); + ++static void quirk_no_bus_reset(struct pci_dev *dev) ++{ ++ dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; ++} ++ ++/* ++ * Atheros AR93xx chips do not behave after a bus reset. The device will ++ * throw a Link Down error on AER-capable systems and regardless of AER, ++ * config space of the device is never accessible again and typically ++ * causes the system to hang or reset when access is attempted. ++ * http://www.spinics.net/lists/linux-pci/msg34797.html ++ */ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); ++ + #ifdef CONFIG_ACPI + /* + * Apple: Shutdown Cactus Ridge Thunderbolt controller. diff --git a/queue-3.18/pci-pass-bridge-device-not-bus-when-updating-bridge-windows.patch b/queue-3.18/pci-pass-bridge-device-not-bus-when-updating-bridge-windows.patch new file mode 100644 index 00000000000..fa1ba3c93e0 --- /dev/null +++ b/queue-3.18/pci-pass-bridge-device-not-bus-when-updating-bridge-windows.patch @@ -0,0 +1,106 @@ +From 3f2f4dc456e9f80849b99d79600a7257690ca4b1 Mon Sep 17 00:00:00 2001 +From: Yinghai Lu +Date: Thu, 15 Jan 2015 10:22:31 -0600 +Subject: PCI: Pass bridge device, not bus, when updating bridge windows + +From: Yinghai Lu + +commit 3f2f4dc456e9f80849b99d79600a7257690ca4b1 upstream. + +pci_setup_bridge_io(), pci_setup_bridge_mmio(), and +pci_setup_bridge_mmio_pref() program the windows of PCI-PCI bridges. +Previously they accepted a pointer to the pci_bus of the secondary bus, +then looked up the bridge leading to that bus. Pass the bridge directly, +which will make it more convenient for future callers. + +No functional change. + +[bhelgaas: changelog, split into separate patch] +Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 +Reported-by: Marek Kordik +Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") +Signed-off-by: Yinghai Lu +Signed-off-by: Bjorn Helgaas +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/setup-bus.c | 21 +++++++++------------ + 1 file changed, 9 insertions(+), 12 deletions(-) + +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -530,9 +530,8 @@ EXPORT_SYMBOL(pci_setup_cardbus); + config space writes, so it's quite possible that an I/O window of + the bridge will have some undesirable address (e.g. 0) after the + first write. Ditto 64-bit prefetchable MMIO. */ +-static void pci_setup_bridge_io(struct pci_bus *bus) ++static void pci_setup_bridge_io(struct pci_dev *bridge) + { +- struct pci_dev *bridge = bus->self; + struct resource *res; + struct pci_bus_region region; + unsigned long io_mask; +@@ -545,7 +544,7 @@ static void pci_setup_bridge_io(struct p + io_mask = PCI_IO_1K_RANGE_MASK; + + /* Set up the top and bottom of the PCI I/O segment for this bus. */ +- res = bus->resource[0]; ++ res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0]; + pcibios_resource_to_bus(bridge->bus, ®ion, res); + if (res->flags & IORESOURCE_IO) { + pci_read_config_word(bridge, PCI_IO_BASE, &l); +@@ -568,15 +567,14 @@ static void pci_setup_bridge_io(struct p + pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); + } + +-static void pci_setup_bridge_mmio(struct pci_bus *bus) ++static void pci_setup_bridge_mmio(struct pci_dev *bridge) + { +- struct pci_dev *bridge = bus->self; + struct resource *res; + struct pci_bus_region region; + u32 l; + + /* Set up the top and bottom of the PCI Memory segment for this bus. */ +- res = bus->resource[1]; ++ res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1]; + pcibios_resource_to_bus(bridge->bus, ®ion, res); + if (res->flags & IORESOURCE_MEM) { + l = (region.start >> 16) & 0xfff0; +@@ -588,9 +586,8 @@ static void pci_setup_bridge_mmio(struct + pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); + } + +-static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) ++static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge) + { +- struct pci_dev *bridge = bus->self; + struct resource *res; + struct pci_bus_region region; + u32 l, bu, lu; +@@ -602,7 +599,7 @@ static void pci_setup_bridge_mmio_pref(s + + /* Set up PREF base/limit. */ + bu = lu = 0; +- res = bus->resource[2]; ++ res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2]; + pcibios_resource_to_bus(bridge->bus, ®ion, res); + if (res->flags & IORESOURCE_PREFETCH) { + l = (region.start >> 16) & 0xfff0; +@@ -630,13 +627,13 @@ static void __pci_setup_bridge(struct pc + &bus->busn_res); + + if (type & IORESOURCE_IO) +- pci_setup_bridge_io(bus); ++ pci_setup_bridge_io(bridge); + + if (type & IORESOURCE_MEM) +- pci_setup_bridge_mmio(bus); ++ pci_setup_bridge_mmio(bridge); + + if (type & IORESOURCE_PREFETCH) +- pci_setup_bridge_mmio_pref(bus); ++ pci_setup_bridge_mmio_pref(bridge); + + pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); + } diff --git a/queue-3.18/series b/queue-3.18/series index 26f0a6bc001..402a4e3dfda 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -15,3 +15,12 @@ drm-i915-fix-mutex-owner-inspection-race-under-debug_mutexes.patch drm-radeon-add-a-dpm-quirk-list.patch drm-radeon-add-si-dpm-quirk-list.patch drm-radeon-use-rv515_ring_start-on-r5xx.patch +pci-pass-bridge-device-not-bus-when-updating-bridge-windows.patch +pci-add-pci_claim_bridge_resource-to-clip-window-if-necessary.patch +pci-add-pci_bus_clip_resource-to-clip-to-fit-upstream-window.patch +x86-pci-clip-bridge-windows-to-fit-in-upstream-windows.patch +pci-add-flag-for-devices-where-we-can-t-use-bus-reset.patch +pci-mark-atheros-ar93xx-to-avoid-bus-reset.patch +ipr-wait-for-aborted-command-responses.patch +cx23885-split-hauppauge-wintv-starburst-from-hvr4400-card-entry.patch +vb2-fix-vb2_thread_stop-race-conditions.patch diff --git a/queue-3.18/vb2-fix-vb2_thread_stop-race-conditions.patch b/queue-3.18/vb2-fix-vb2_thread_stop-race-conditions.patch new file mode 100644 index 00000000000..a57efb4f8b9 --- /dev/null +++ b/queue-3.18/vb2-fix-vb2_thread_stop-race-conditions.patch @@ -0,0 +1,81 @@ +From 6cf11ee6300f38b7cfc43af9b7be2afaa5e05869 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Mon, 19 Jan 2015 06:16:18 -0300 +Subject: [media] vb2: fix vb2_thread_stop race conditions + +From: Hans Verkuil + +commit 6cf11ee6300f38b7cfc43af9b7be2afaa5e05869 upstream. + +The locking scheme inside the vb2 thread is unsafe when stopping the +thread. In particular kthread_stop was called *after* internal data +structures were cleaned up instead of doing that before. In addition, +internal vb2 functions were called after threadio->stop was set to +true and vb2_internal_streamoff was called. This is also not allowed. + +All this led to a variety of race conditions and kernel warnings and/or +oopses. + +Fixed by moving the kthread_stop call up before the cleanup takes +place, and by checking threadio->stop before calling internal vb2 +queuing operations. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/v4l2-core/videobuf2-core.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +--- a/drivers/media/v4l2-core/videobuf2-core.c ++++ b/drivers/media/v4l2-core/videobuf2-core.c +@@ -3142,27 +3142,26 @@ static int vb2_thread(void *data) + prequeue--; + } else { + call_void_qop(q, wait_finish, q); +- ret = vb2_internal_dqbuf(q, &fileio->b, 0); ++ if (!threadio->stop) ++ ret = vb2_internal_dqbuf(q, &fileio->b, 0); + call_void_qop(q, wait_prepare, q); + dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); + } +- if (threadio->stop) +- break; +- if (ret) ++ if (ret || threadio->stop) + break; + try_to_freeze(); + + vb = q->bufs[fileio->b.index]; + if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR)) +- ret = threadio->fnc(vb, threadio->priv); +- if (ret) +- break; ++ if (threadio->fnc(vb, threadio->priv)) ++ break; + call_void_qop(q, wait_finish, q); + if (set_timestamp) + v4l2_get_timestamp(&fileio->b.timestamp); +- ret = vb2_internal_qbuf(q, &fileio->b); ++ if (!threadio->stop) ++ ret = vb2_internal_qbuf(q, &fileio->b); + call_void_qop(q, wait_prepare, q); +- if (ret) ++ if (ret || threadio->stop) + break; + } + +@@ -3231,11 +3230,11 @@ int vb2_thread_stop(struct vb2_queue *q) + threadio->stop = true; + vb2_internal_streamoff(q, q->type); + call_void_qop(q, wait_prepare, q); ++ err = kthread_stop(threadio->thread); + q->fileio = NULL; + fileio->req.count = 0; + vb2_reqbufs(q, &fileio->req); + kfree(fileio); +- err = kthread_stop(threadio->thread); + threadio->thread = NULL; + kfree(threadio); + q->fileio = NULL; diff --git a/queue-3.18/x86-pci-clip-bridge-windows-to-fit-in-upstream-windows.patch b/queue-3.18/x86-pci-clip-bridge-windows-to-fit-in-upstream-windows.patch new file mode 100644 index 00000000000..aba6f531458 --- /dev/null +++ b/queue-3.18/x86-pci-clip-bridge-windows-to-fit-in-upstream-windows.patch @@ -0,0 +1,43 @@ +From 851b09369255a91e77f56d83e3643439ac5b209a Mon Sep 17 00:00:00 2001 +From: Yinghai Lu +Date: Thu, 15 Jan 2015 16:21:49 -0600 +Subject: x86/PCI: Clip bridge windows to fit in upstream windows + +From: Yinghai Lu + +commit 851b09369255a91e77f56d83e3643439ac5b209a upstream. + +Every PCI-PCI bridge window should fit inside an upstream bridge window +because orphaned address space is unreachable from the primary side of the +upstream bridge. If we inherit invalid bridge windows that overlap an +upstream window from firmware, clip them to fit and update the bridge +accordingly. + +[bhelgaas: changelog] +Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491 +Reported-by: Marek Kordik +Tested-by: Marek Kordik +Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources") +Signed-off-by: Yinghai Lu +Signed-off-by: Bjorn Helgaas +CC: Thomas Gleixner +CC: Ingo Molnar +CC: "H. Peter Anvin" +CC: x86@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/pci/i386.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/pci/i386.c ++++ b/arch/x86/pci/i386.c +@@ -216,7 +216,7 @@ static void pcibios_allocate_bridge_reso + continue; + if (r->parent) /* Already allocated */ + continue; +- if (!r->start || pci_claim_resource(dev, idx) < 0) { ++ if (!r->start || pci_claim_bridge_resource(dev, idx) < 0) { + /* + * Something is wrong with the region. + * Invalidate the resource to prevent