From f8e3fe8229d0f6fb0330694f5ec1621417c0dc62 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Oct 14 2010 15:16:09 +0000 Subject: add some patches from sgruska to fix various issues in f-12, thanks! --- diff --git a/add-support-for-ricoh-e822-sdhci.patch b/add-support-for-ricoh-e822-sdhci.patch new file mode 100644 index 0000000..93bc459 --- /dev/null +++ b/add-support-for-ricoh-e822-sdhci.patch @@ -0,0 +1,141 @@ +diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c +index e035664..3d7f790 100644 +--- a/drivers/mmc/host/sdhci-pci.c ++++ b/drivers/mmc/host/sdhci-pci.c +@@ -86,7 +86,30 @@ static int ricoh_probe(struct sdhci_pci_chip *chip) + if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || + chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) + chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; ++ return 0; ++} ++ ++static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot) ++{ ++ slot->host->caps = ++ ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT) ++ & SDHCI_TIMEOUT_CLK_MASK) | ++ ++ ((0x21 << SDHCI_CLOCK_BASE_SHIFT) ++ & SDHCI_CLOCK_BASE_MASK) | + ++ SDHCI_TIMEOUT_CLK_UNIT | ++ SDHCI_CAN_VDD_330 | ++ SDHCI_CAN_DO_SDMA; ++ return 0; ++} ++ ++static int ricoh_mmc_resume(struct sdhci_pci_chip *chip) ++{ ++ /* Apply a delay to allow controller to settle */ ++ /* Otherwise it becomes confused if card state changed ++ during suspend */ ++ msleep(500); + return 0; + } + +@@ -95,6 +118,15 @@ static const struct sdhci_pci_fixes sdhci_ricoh = { + .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, + }; + ++static const struct sdhci_pci_fixes sdhci_ricoh_mmc = { ++ .probe_slot = ricoh_mmc_probe_slot, ++ .resume = ricoh_mmc_resume, ++ .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | ++ SDHCI_QUIRK_CLOCK_BEFORE_RESET | ++ SDHCI_QUIRK_NO_CARD_NO_RESET | ++ SDHCI_QUIRK_MISSING_CAPS ++}; ++ + static const struct sdhci_pci_fixes sdhci_ene_712 = { + .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_BROKEN_DMA, +@@ -307,6 +339,22 @@ static const struct pci_device_id pci_ids[] __devinitdata = { + }, + + { ++ .vendor = PCI_VENDOR_ID_RICOH, ++ .device = 0x843, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc, ++ }, ++ ++ { ++ .vendor = PCI_VENDOR_ID_RICOH, ++ .device = 0xe822, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc, ++ }, ++ ++ { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD, + .subvendor = PCI_ANY_ID, +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index c279fbc..7d4bff0 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -1147,6 +1147,11 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + ++ if (ios->bus_width == MMC_BUS_WIDTH_8) ++ ctrl |= SDHCI_CTRL_8BITBUS; ++ else ++ ctrl &= ~SDHCI_CTRL_8BITBUS; ++ + if (ios->bus_width == MMC_BUS_WIDTH_4) + ctrl |= SDHCI_CTRL_4BITBUS; + else +@@ -1678,7 +1683,8 @@ int sdhci_add_host(struct sdhci_host *host) + host->version); + } + +- caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : ++ sdhci_readl(host, SDHCI_CAPABILITIES); + + if (host->quirks & SDHCI_QUIRK_FORCE_DMA) + host->flags |= SDHCI_USE_SDMA; +diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h +index ce5f1d7..b5e2761 100644 +--- a/drivers/mmc/host/sdhci.h ++++ b/drivers/mmc/host/sdhci.h +@@ -70,6 +70,7 @@ + #define SDHCI_CTRL_ADMA1 0x08 + #define SDHCI_CTRL_ADMA32 0x10 + #define SDHCI_CTRL_ADMA64 0x18 ++#define SDHCI_CTRL_8BITBUS 0x20 + + #define SDHCI_POWER_CONTROL 0x29 + #define SDHCI_POWER_ON 0x01 +@@ -125,7 +126,7 @@ + #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ +- SDHCI_INT_DATA_END_BIT | SDHCI_ADMA_ERROR) ++ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR) + #define SDHCI_INT_ALL_MASK ((unsigned int)-1) + + #define SDHCI_ACMD12_ERR 0x3C +@@ -235,6 +236,10 @@ struct sdhci_host { + /* Controller uses SDCLK instead of TMCLK for data timeouts */ + #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) + ++/* RHEL6 miss some quirks */ ++ ++/* Controller is missing device caps. Use caps provided by host */ ++#define SDHCI_QUIRK_MISSING_CAPS (1<<28) + int irq; /* Device IRQ */ + void __iomem * ioaddr; /* Mapped address */ + +@@ -286,6 +291,8 @@ struct sdhci_host { + + struct timer_list timer; /* Timer for timeouts */ + ++ unsigned int caps; /* Alternative capabilities */ ++ + unsigned long private[0] ____cacheline_aligned; + }; + diff --git a/kernel.spec b/kernel.spec index e20e8a0..94f99a1 100644 --- a/kernel.spec +++ b/kernel.spec @@ -840,6 +840,15 @@ Patch14212: setup_arg_pages-diagnose-excessive-argument-size.patch Patch14220: xen-fix-typo-in-xen-irq-fix.patch +# rhbz#447489 +Patch14224: skge-quirk-to-4gb-dma.patch + +# rhbz#629158 +Patch14225: r8169-fix-dma-allocations.patch + +# rhbz#596475 +Patch14226: add-support-for-ricoh-e822-sdhci.patch + # ============================================================================== %endif @@ -1547,6 +1556,15 @@ ApplyPatch setup_arg_pages-diagnose-excessive-argument-size.patch # Fix typo in Xen patch from 2.6.22 that causes hang on boot. ApplyPatch xen-fix-typo-in-xen-irq-fix.patch +# rhbz#629158 +ApplyPatch r8169-fix-dma-allocations.patch + +# rhbz#447489 +ApplyPatch skge-quirk-to-4gb-dma.patch + +# rhbz#596475 +ApplyPatch add-support-for-ricoh-e822-sdhci.patch + # END OF PATCH APPLICATIONS ==================================================== %endif @@ -2199,6 +2217,11 @@ fi %kernel_variant_files -k vmlinux %{with_kdump} kdump %changelog +* Thu Oct 14 2010 Kyle McMartin +- rhbz447489: skge-quirk-to-4gb-dma.patch +- rhbz629158: r8169-fix-dma-allocations.patch +- rhbz596475: add-support-for-ricoh-e822-sdhci.patch + * Mon Sep 27 2010 Chuck Ebbert 2.6.32.23-170 - Linux 2.6.32.23 - Drop merged patches: diff --git a/r8169-fix-dma-allocations.patch b/r8169-fix-dma-allocations.patch new file mode 100644 index 0000000..aa1e52d --- /dev/null +++ b/r8169-fix-dma-allocations.patch @@ -0,0 +1,199 @@ +diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c +index 62e784a..6608094 100644 +--- a/drivers/net/r8169.c ++++ b/drivers/net/r8169.c +@@ -1201,7 +1201,8 @@ static void rtl8169_update_counters(struct net_device *dev) + if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) + return; + +- counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); ++ counters = dma_alloc_coherent(&tp->pci_dev->dev, sizeof(*counters), ++ &paddr, GFP_KERNEL); + if (!counters) + return; + +@@ -1222,7 +1223,8 @@ static void rtl8169_update_counters(struct net_device *dev) + RTL_W32(CounterAddrLow, 0); + RTL_W32(CounterAddrHigh, 0); + +- pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); ++ dma_free_coherent(&tp->pci_dev->dev, sizeof(*counters), counters, ++ paddr); + } + + static void rtl8169_get_ethtool_stats(struct net_device *dev, +@@ -3300,13 +3302,13 @@ static int rtl8169_open(struct net_device *dev) + * Rx and Tx desscriptors needs 256 bytes alignment. + * pci_alloc_consistent provides more. + */ +- tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES, +- &tp->TxPhyAddr); ++ tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES, ++ &tp->TxPhyAddr, GFP_KERNEL); + if (!tp->TxDescArray) + goto out; + +- tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES, +- &tp->RxPhyAddr); ++ tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES, ++ &tp->RxPhyAddr, GFP_KERNEL); + if (!tp->RxDescArray) + goto err_free_tx_0; + +@@ -3337,11 +3339,11 @@ out: + err_release_ring_2: + rtl8169_rx_clear(tp); + err_free_rx_1: +- pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, +- tp->RxPhyAddr); ++ dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, ++ tp->RxPhyAddr); + err_free_tx_0: +- pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, +- tp->TxPhyAddr); ++ dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, ++ tp->TxPhyAddr); + goto out; + } + +@@ -3974,7 +3976,7 @@ static void rtl8169_free_rx_skb(struct rtl8169_private *tp, + { + struct pci_dev *pdev = tp->pci_dev; + +- pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz, ++ dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(*sk_buff); + *sk_buff = NULL; +@@ -3999,7 +4001,7 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, + static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, + struct net_device *dev, + struct RxDesc *desc, int rx_buf_sz, +- unsigned int align) ++ unsigned int align, gfp_t gfp) + { + struct sk_buff *skb; + dma_addr_t mapping; +@@ -4007,13 +4009,13 @@ static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, + + pad = align ? align : NET_IP_ALIGN; + +- skb = netdev_alloc_skb(dev, rx_buf_sz + pad); ++ skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp); + if (!skb) + goto err_out; + + skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); + +- mapping = pci_map_single(pdev, skb->data, rx_buf_sz, ++ mapping = dma_map_single(&pdev->dev, skb->data, rx_buf_sz, + PCI_DMA_FROMDEVICE); + + rtl8169_map_to_asic(desc, mapping, rx_buf_sz); +@@ -4038,7 +4040,7 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) + } + + static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, +- u32 start, u32 end) ++ u32 start, u32 end, gfp_t gfp) + { + u32 cur; + +@@ -4053,7 +4055,7 @@ static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, + + skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, + tp->RxDescArray + i, +- tp->rx_buf_sz, tp->align); ++ tp->rx_buf_sz, tp->align, gfp); + if (!skb) + break; + +@@ -4081,7 +4083,7 @@ static int rtl8169_init_ring(struct net_device *dev) + memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); + memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); + +- if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC) ++ if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC) + goto err_out; + + rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); +@@ -4098,7 +4100,8 @@ static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, + { + unsigned int len = tx_skb->len; + +- pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE); ++ dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, ++ PCI_DMA_TODEVICE); + desc->opts1 = 0x00; + desc->opts2 = 0x00; + desc->addr = 0x00; +@@ -4244,7 +4247,8 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, + txd = tp->TxDescArray + entry; + len = frag->size; + addr = ((void *) page_address(frag->page)) + frag->page_offset; +- mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE); ++ mapping = dma_map_single(&tp->pci_dev->dev, addr, len, ++ PCI_DMA_TODEVICE); + + /* anti gcc 2.95.3 bugware (sic) */ + status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); +@@ -4318,7 +4322,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, + tp->tx_skb[entry].skb = skb; + } + +- mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE); ++ mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, ++ PCI_DMA_TODEVICE); + + tp->tx_skb[entry].len = len; + txd->addr = cpu_to_le64(mapping); +@@ -4486,8 +4491,9 @@ static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, + if (!skb) + goto out; + +- pci_dma_sync_single_for_cpu(tp->pci_dev, addr, pkt_size, +- PCI_DMA_FROMDEVICE); ++ ++ dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size, ++ PCI_DMA_FROMDEVICE); + skb_reserve(skb, NET_IP_ALIGN); + skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); + *sk_buff = skb; +@@ -4554,11 +4560,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev, + rtl8169_rx_csum(skb, desc); + + if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { +- pci_dma_sync_single_for_device(pdev, addr, ++ dma_sync_single_for_device(&pdev->dev, addr, + pkt_size, PCI_DMA_FROMDEVICE); + rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + } else { +- pci_unmap_single(pdev, addr, tp->rx_buf_sz, ++ dma_unmap_single(&pdev->dev, addr, tp->rx_buf_sz, + PCI_DMA_FROMDEVICE); + tp->Rx_skbuff[entry] = NULL; + } +@@ -4584,7 +4590,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, + count = cur_rx - tp->cur_rx; + tp->cur_rx = cur_rx; + +- delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); ++ delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC); + if (!delta && count && netif_msg_intr(tp)) + printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name); + tp->dirty_rx += delta; +@@ -4770,10 +4776,10 @@ static int rtl8169_close(struct net_device *dev) + + free_irq(dev->irq, dev); + +- pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, +- tp->RxPhyAddr); +- pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, +- tp->TxPhyAddr); ++ dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, ++ tp->RxPhyAddr); ++ dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray, ++ tp->TxPhyAddr); + tp->TxDescArray = NULL; + tp->RxDescArray = NULL; + diff --git a/skge-quirk-to-4gb-dma.patch b/skge-quirk-to-4gb-dma.patch new file mode 100644 index 0000000..ebd146d --- /dev/null +++ b/skge-quirk-to-4gb-dma.patch @@ -0,0 +1,70 @@ +Skge devices installed on some Gigabyte motherboards are not able to +perform 64 dma correctly due to board PCI implementation, so limit +DMA to 32bit if such boards are detected. + +Bug was reported here: +https://bugzilla.redhat.com/show_bug.cgi?id=447489 + +Signed-off-by: Stanislaw Gruszka +Tested-by: Luya Tshimbalanga +--- + drivers/net/skge.c | 22 +++++++++++++++++++++- + 1 files changed, 21 insertions(+), 1 deletions(-) + +diff --git a/drivers/net/skge.c b/drivers/net/skge.c +index a8a6358..571d4c3 100644 +--- a/drivers/net/skge.c ++++ b/drivers/net/skge.c +@@ -43,5 +43,6 @@ + #include + #include ++#include + #include + + #include "skge.h" +@@ -3869,6 +3870,8 @@ static void __devinit skge_show_addr(struct net_device *dev) + netif_info(skge, probe, skge->netdev, "addr %pM\n", dev->dev_addr); + } + ++static int only_32bit_dma; ++ + static int __devinit skge_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { +@@ -3890,7 +3893,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, + + pci_set_master(pdev); + +- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { ++ if (!only_32bit_dma && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + using_dac = 1; + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { +@@ -4148,8 +4151,25 @@ static struct pci_driver skge_driver = { + .shutdown = skge_shutdown, + }; + ++#ifndef CONFIG_DMI ++#warning "DMA quirk for Gigabyte nForce boards will not be applied" ++#endif ++ ++static struct dmi_system_id skge_32bit_dma_boards[] = { ++ { ++ .ident = "Gigabyte nForce boards", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co"), ++ DMI_MATCH(DMI_BOARD_NAME, "nForce"), ++ }, ++ }, ++ {} ++}; ++ + static int __init skge_init_module(void) + { ++ if (dmi_check_system(skge_32bit_dma_boards)) ++ only_32bit_dma = 1; + skge_debug_init(); + return pci_register_driver(&skge_driver); + } +-- +1.5.5.6