From a1415ee65500597e19c0ac44872db66105bad0e7 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Tue, 28 Feb 2006 20:24:07 -0800 Subject: [PATCH 001/178] [PATCH] e1000: revert to single descriptor for legacy receive path A recent patch attempted to enable more efficient memory usage by using only 2kB descriptors for jumbo frames. The method used to implement this has since been commented upon as "illegal" and in recent kernels even causes a BUG when receiving ip fragments while using jumbo frames. This patch simply goes back to the way things were. We expect some complaints due to order 3 allocations failing to come back due to this change. Signed-off-by: Jesse Brandeburg --- drivers/net/e1000/e1000.h | 3 - drivers/net/e1000/e1000_main.c | 117 +++++++++++++-------------------- 2 files changed, 45 insertions(+), 75 deletions(-) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 27c77306193b..99baf0e099fc 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -225,9 +225,6 @@ struct e1000_rx_ring { struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *rx_skb_top; - struct sk_buff *rx_skb_prev; - /* cpu for rx queue */ int cpu; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 31e332935e5a..5b7d0f425af2 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -103,7 +103,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "6.3.9-k2"DRIVERNAPI +#define DRV_VERSION "6.3.9-k4"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; @@ -1635,8 +1635,6 @@ setup_rx_desc_die: rxdr->next_to_clean = 0; rxdr->next_to_use = 0; - rxdr->rx_skb_top = NULL; - rxdr->rx_skb_prev = NULL; return 0; } @@ -1713,8 +1711,23 @@ e1000_setup_rctl(struct e1000_adapter *adapter) rctl |= adapter->rx_buffer_len << 0x11; } else { rctl &= ~E1000_RCTL_SZ_4096; - rctl &= ~E1000_RCTL_BSEX; - rctl |= E1000_RCTL_SZ_2048; + rctl |= E1000_RCTL_BSEX; + switch (adapter->rx_buffer_len) { + case E1000_RXBUFFER_2048: + default: + rctl |= E1000_RCTL_SZ_2048; + rctl &= ~E1000_RCTL_BSEX; + break; + case E1000_RXBUFFER_4096: + rctl |= E1000_RCTL_SZ_4096; + break; + case E1000_RXBUFFER_8192: + rctl |= E1000_RCTL_SZ_8192; + break; + case E1000_RXBUFFER_16384: + rctl |= E1000_RCTL_SZ_16384; + break; + } } #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT @@ -2107,16 +2120,6 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter, } } - /* there also may be some cached data in our adapter */ - if (rx_ring->rx_skb_top) { - dev_kfree_skb(rx_ring->rx_skb_top); - - /* rx_skb_prev will be wiped out by rx_skb_top */ - rx_ring->rx_skb_top = NULL; - rx_ring->rx_skb_prev = NULL; - } - - size = sizeof(struct e1000_buffer) * rx_ring->count; memset(rx_ring->buffer_info, 0, size); size = sizeof(struct e1000_ps_page) * rx_ring->count; @@ -3106,24 +3109,27 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) break; } - /* since the driver code now supports splitting a packet across - * multiple descriptors, most of the fifo related limitations on - * jumbo frame traffic have gone away. - * simply use 2k descriptors for everything. - * - * NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN - * means we reserve 2 more, this pushes us to allocate from the next - * larger slab size - * i.e. RXBUFFER_2048 --> size-4096 slab */ - /* recent hardware supports 1KB granularity */ if (adapter->hw.mac_type > e1000_82547_rev_2) { - adapter->rx_buffer_len = - ((max_frame < E1000_RXBUFFER_2048) ? - max_frame : E1000_RXBUFFER_2048); + adapter->rx_buffer_len = max_frame; E1000_ROUNDUP(adapter->rx_buffer_len, 1024); - } else - adapter->rx_buffer_len = E1000_RXBUFFER_2048; + } else { + if(unlikely((adapter->hw.mac_type < e1000_82543) && + (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) { + DPRINTK(PROBE, ERR, "Jumbo Frames not supported " + "on 82542\n"); + return -EINVAL; + } else { + if(max_frame <= E1000_RXBUFFER_2048) + adapter->rx_buffer_len = E1000_RXBUFFER_2048; + else if(max_frame <= E1000_RXBUFFER_4096) + adapter->rx_buffer_len = E1000_RXBUFFER_4096; + else if(max_frame <= E1000_RXBUFFER_8192) + adapter->rx_buffer_len = E1000_RXBUFFER_8192; + else if(max_frame <= E1000_RXBUFFER_16384) + adapter->rx_buffer_len = E1000_RXBUFFER_16384; + } + } netdev->mtu = new_mtu; @@ -3620,7 +3626,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, uint8_t last_byte; unsigned int i; int cleaned_count = 0; - boolean_t cleaned = FALSE, multi_descriptor = FALSE; + boolean_t cleaned = FALSE; i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC(*rx_ring, i); @@ -3652,43 +3658,12 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, length = le16_to_cpu(rx_desc->length); - skb_put(skb, length); - - if (!(status & E1000_RXD_STAT_EOP)) { - if (!rx_ring->rx_skb_top) { - rx_ring->rx_skb_top = skb; - rx_ring->rx_skb_top->len = length; - rx_ring->rx_skb_prev = skb; - } else { - if (skb_shinfo(rx_ring->rx_skb_top)->frag_list) { - rx_ring->rx_skb_prev->next = skb; - skb->prev = rx_ring->rx_skb_prev; - } else { - skb_shinfo(rx_ring->rx_skb_top)->frag_list = skb; - } - rx_ring->rx_skb_prev = skb; - rx_ring->rx_skb_top->data_len += length; - } + if (unlikely(!(status & E1000_RXD_STAT_EOP))) { + /* All receives must fit into a single buffer */ + E1000_DBG("%s: Receive packet consumed multiple" + " buffers\n", netdev->name); + dev_kfree_skb_irq(skb); goto next_desc; - } else { - if (rx_ring->rx_skb_top) { - if (skb_shinfo(rx_ring->rx_skb_top) - ->frag_list) { - rx_ring->rx_skb_prev->next = skb; - skb->prev = rx_ring->rx_skb_prev; - } else - skb_shinfo(rx_ring->rx_skb_top) - ->frag_list = skb; - - rx_ring->rx_skb_top->data_len += length; - rx_ring->rx_skb_top->len += - rx_ring->rx_skb_top->data_len; - - skb = rx_ring->rx_skb_top; - multi_descriptor = TRUE; - rx_ring->rx_skb_top = NULL; - rx_ring->rx_skb_prev = NULL; - } } if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) { @@ -3712,10 +3687,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, * performance for small packets with large amounts * of reassembly being done in the stack */ #define E1000_CB_LENGTH 256 - if ((length < E1000_CB_LENGTH) && - !rx_ring->rx_skb_top && - /* or maybe (status & E1000_RXD_STAT_EOP) && */ - !multi_descriptor) { + if (length < E1000_CB_LENGTH) { struct sk_buff *new_skb = dev_alloc_skb(length + NET_IP_ALIGN); if (new_skb) { @@ -3729,7 +3701,8 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, skb = new_skb; skb_put(skb, length); } - } + } else + skb_put(skb, length); /* end copybreak code */ From 82d56e6d2e616bee0e712330bad06b634f007a46 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Fri, 27 Jan 2006 19:15:02 +0100 Subject: [PATCH 002/178] [PATCH] pcmcia: properly handle pseudo multi-function devices The second pseudo multi-function device of a PCMCIA card may only be configured once the first one is initialized. Therefore, delay the registration of the second device until the first one is initialized. Signed-off-by: Dominik Brodowski pcmcia_state.device_add_pending) { + s->pcmcia_state.device_add_pending = 1; + schedule_work(&s->device_add); + } + return; +} static int pcmcia_device_probe(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; + struct pcmcia_device_id *did; struct pcmcia_socket *s; int ret = 0; @@ -392,6 +401,19 @@ static int pcmcia_device_probe(struct device * dev) } ret = p_drv->probe(p_dev); + if (ret) + goto put_module; + + /* handle pseudo multifunction devices: + * there are at most two pseudo multifunction devices. + * if we're matching against the first, schedule a + * call which will then check whether there are two + * pseudo devices, and if not, add the second one. + */ + did = (struct pcmcia_device_id *) p_dev->dev.driver_data; + if ((did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && + (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) + pcmcia_add_pseudo_device(p_dev->socket); put_module: if (ret) @@ -660,15 +682,6 @@ static void pcmcia_delayed_add_pseudo_device(void *data) s->pcmcia_state.device_add_pending = 0; } -static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s) -{ - if (!s->pcmcia_state.device_add_pending) { - s->pcmcia_state.device_add_pending = 1; - schedule_work(&s->device_add); - } - return; -} - static int pcmcia_requery(struct device *dev, void * _data) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); @@ -755,15 +768,6 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, } if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { - /* handle pseudo multifunction devices: - * there are at most two pseudo multifunction devices. - * if we're matching against the first, schedule a - * call which will then check whether there are two - * pseudo devices, and if not, add the second one. - */ - if (dev->device_no == 0) - pcmcia_add_pseudo_device(dev->socket); - if (dev->device_no != did->device_no) return 0; } From 42935656914b813c99f91cbac421fe677a6f34ab Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 25 Jan 2006 06:36:32 -0800 Subject: [PATCH 003/178] [PATCH] pcmcia: add another ide-cs CF card id Add another CF card ID. Signed-off-by: David Brownell Signed-off-by: Dominik Brodowski --- drivers/ide/legacy/ide-cs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 4c2af9020905..6213bd3caee5 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -445,6 +445,7 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728), PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1), PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), + PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), From f0892b89e3c19c7d805825ca12511d26dcdf6415 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Tue, 28 Feb 2006 01:18:29 -0500 Subject: [PATCH 004/178] [PATCH] pcmcia: Add macro to match PCMCIA cards by numeric ID and first vendor string This is needed to distinguish Intersil and non-Intersil cards with numeric ID 0x0156, 0x0002. Signed-off-by: Pavel Roskin Signed-off-by: Dominik Brodowski --- include/pcmcia/device_id.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/pcmcia/device_id.h b/include/pcmcia/device_id.h index 346d81ece287..e04e0b0d9a25 100644 --- a/include/pcmcia/device_id.h +++ b/include/pcmcia/device_id.h @@ -72,6 +72,15 @@ .prod_id = { (v1), (v2), (v3), (v4) }, \ .prod_id_hash = { (vh1), (vh2), (vh3), (vh4) }, } +#define PCMCIA_DEVICE_MANF_CARD_PROD_ID1(manf, card, v1, vh1) { \ + .match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \ + PCMCIA_DEV_ID_MATCH_CARD_ID| \ + PCMCIA_DEV_ID_MATCH_PROD_ID1, \ + .manf_id = (manf), \ + .card_id = (card), \ + .prod_id = { (v1), NULL, NULL, NULL }, \ + .prod_id_hash = { (vh1), 0, 0, 0 }, } + /* multi-function devices */ From 40e3cad61197fce63853e778db020f7637d988f2 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Tue, 28 Feb 2006 01:18:31 -0500 Subject: [PATCH 005/178] [PATCH] pcmcia: avoid binding hostap_cs to Orinoco cards Don't just use cards with PCMCIA ID 0x0156, 0x0002. Make sure that the vendor string is "Intersil" or "INTERSIL" Signed-off-by: Pavel Roskin Signed-off-by: Dominik Brodowski --- drivers/net/wireless/hostap/hostap_cs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 8bc0b528548f..f8f4503475f9 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -877,7 +877,6 @@ static struct pcmcia_device_id hostap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), - PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030b), PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), @@ -891,6 +890,10 @@ static struct pcmcia_device_id hostap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), + PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL", + 0x74c5e40d), + PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil", + 0x4b801a17), PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), PCMCIA_DEVICE_PROD_ID1234( From 2fe22a8bba0c3a60db58dfdcaa200f8528c057e4 Mon Sep 17 00:00:00 2001 From: Jesse Allen Date: Mon, 20 Feb 2006 22:08:18 -0800 Subject: [PATCH 006/178] [PATCH] pcmcia: add id for AMB8110 PC Card The axnet_cs driver can support the AMB8110 PC Card, so add the id for it. In the old pcmcia-cs config file, this card is listed with the comment "not specific enough". The last entry in the axnet_ids has the same comment. They are disabled, and for good reason as it was originally identified by the MANFID, and that is shared with several cards that use both the pcnet_cs driver and axnet_cs driver. I tried my AMB8110 with pcnet_cs, and found that it works fine, and I cannot find a reason for either, except that the old config file recommended axnet_cs. Signed-off-by: Jesse Allen Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/net/pcmcia/axnet_cs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 01ddfc8cce3f..aa5581369399 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -806,6 +806,7 @@ static struct pcmcia_device_id axnet_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106), PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), + PCMCIA_DEVICE_PROD_ID12("AmbiCom,Inc.", "Fast Ethernet PC Card(AMB8110)", 0x49b020a7, 0x119cc9fc), PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef), PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef), PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1), From 67bc620006a30cf5dcbf409dbbd4fd93179ddfb1 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 14 Feb 2006 09:21:26 +0100 Subject: [PATCH 007/178] [PATCH] pcmcia: CM4000, CM4040 Driver fixes Using this patch, Omnikey CardMan 4000 and 4040 devices automatically get their device nodes created by udev. Also, we now check for (and handle) failure of pcmcia_register_driver() Signed-off-by: Harald Welte Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/cm4000_cs.c | 24 +++++++++++++++++++++--- drivers/char/pcmcia/cm4040_cs.c | 23 ++++++++++++++++++++--- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 649677b5dc36..5fdf18515433 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -13,11 +13,12 @@ * * (C) 2000,2001,2002,2003,2004 Omnikey AG * - * (C) 2005 Harald Welte + * (C) 2005-2006 Harald Welte * - Adhere to Kernel CodingStyle * - Port to 2.6.13 "new" style PCMCIA * - Check for copy_{from,to}_user return values * - Use nonseekable_open() + * - add class interface for udev device creation * * All rights reserved. Licensed under dual BSD/GPL license. */ @@ -56,7 +57,7 @@ module_param(pc_debug, int, 0600); #else #define DEBUGP(n, rdr, x, args...) #endif -static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte"; +static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte"; #define T_1SEC (HZ) #define T_10MSEC msecs_to_jiffies(10) @@ -156,6 +157,7 @@ struct cm4000_dev { /*queue*/ 4*sizeof(wait_queue_head_t)) static dev_link_t *dev_table[CM4000_MAX_DEV]; +static struct class *cmm_class; /* This table doesn't use spaces after the comma between fields and thus * violates CodingStyle. However, I don't really think wrapping it around will @@ -1937,6 +1939,9 @@ static int cm4000_attach(struct pcmcia_device *p_dev) link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; cm4000_config(link, i); + class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, + "cmm%d", i); + return 0; } @@ -1962,6 +1967,8 @@ static void cm4000_detach(struct pcmcia_device *p_dev) dev_table[devno] = NULL; kfree(dev); + class_device_destroy(cmm_class, MKDEV(major, devno)); + return; } @@ -1995,8 +2002,18 @@ static struct pcmcia_driver cm4000_driver = { static int __init cmm_init(void) { + int rc; + printk(KERN_INFO "%s\n", version); - pcmcia_register_driver(&cm4000_driver); + + cmm_class = class_create(THIS_MODULE, "cardman_4000"); + if (!cmm_class) + return -1; + + rc = pcmcia_register_driver(&cm4000_driver); + if (rc < 0) + return rc; + major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME @@ -2012,6 +2029,7 @@ static void __exit cmm_exit(void) printk(KERN_INFO MODULE_NAME ": unloading\n"); pcmcia_unregister_driver(&cm4000_driver); unregister_chrdev(major, DEVICE_NAME); + class_destroy(cmm_class); }; module_init(cmm_init); diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 46eb371bf17e..466e33bab029 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -3,12 +3,13 @@ * * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/) * - * (C) 2005 Harald Welte + * (C) 2005-2006 Harald Welte * - add support for poll() * - driver cleanup * - add waitqueues * - adhere to linux kernel coding style and policies * - support 2.6.13 "new style" pcmcia interface + * - add class interface for udev device creation * * The device basically is a USB CCID compliant device that has been * attached to an I/O-Mapped FIFO. @@ -53,7 +54,7 @@ module_param(pc_debug, int, 0600); #endif static char *version = -"OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte"; +"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte"; #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) @@ -67,6 +68,7 @@ static char *version = static void reader_release(dev_link_t *link); static int major; +static struct class *cmx_class; #define BS_READABLE 0x01 #define BS_WRITABLE 0x02 @@ -696,6 +698,9 @@ static int reader_attach(struct pcmcia_device *p_dev) link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; reader_config(link, i); + class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, + "cmx%d", i); + return 0; } @@ -721,6 +726,8 @@ static void reader_detach(struct pcmcia_device *p_dev) dev_table[devno] = NULL; kfree(dev); + class_device_destroy(cmx_class, MKDEV(major, devno)); + return; } @@ -755,8 +762,17 @@ static struct pcmcia_driver reader_driver = { static int __init cm4040_init(void) { + int rc; + printk(KERN_INFO "%s\n", version); - pcmcia_register_driver(&reader_driver); + cmx_class = class_create(THIS_MODULE, "cardman_4040"); + if (!cmx_class) + return -1; + + rc = pcmcia_register_driver(&reader_driver); + if (rc < 0) + return rc; + major = register_chrdev(0, DEVICE_NAME, &reader_fops); if (major < 0) { printk(KERN_WARNING MODULE_NAME @@ -771,6 +787,7 @@ static void __exit cm4040_exit(void) printk(KERN_INFO MODULE_NAME ": unloading\n"); pcmcia_unregister_driver(&reader_driver); unregister_chrdev(major, DEVICE_NAME); + class_destroy(cmx_class); } module_init(cm4040_init); From 6b7a6c94c9c15b2664b568ead83e6b3aaf60d65c Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 21 Feb 2006 11:57:30 -0500 Subject: [PATCH 008/178] [PATCH] ocfs2: fix -Wformat warnings when building UML on x86-64 The check to determine which format string is appopriate for u64 and friends works in most cases, but UML on x86_64 doesn't define CONFIG_X86_64, so it results in screen fulls of compile-time warnings. This patch fixes it to handle that case. fs/ocfs2/cluster/masklog.h | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Signed-off-by: Jeff Mahoney Signed-off-by: Mark Fasheh --- fs/ocfs2/cluster/masklog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h index e8c56a3d9c64..2cadc3009c83 100644 --- a/fs/ocfs2/cluster/masklog.h +++ b/fs/ocfs2/cluster/masklog.h @@ -256,7 +256,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits; } \ } while (0) -#if (BITS_PER_LONG == 32) || defined(CONFIG_X86_64) +#if (BITS_PER_LONG == 32) || defined(CONFIG_X86_64) || (defined(CONFIG_UML_X86) && defined(CONFIG_64BIT)) #define MLFi64 "lld" #define MLFu64 "llu" #define MLFx64 "llx" From d3178bcdd41b050e221337d7f5e30b3c58d4015a Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Fri, 24 Feb 2006 17:23:36 -0800 Subject: [PATCH 009/178] [PATCH] ocfs2: remove pointless max journal size limit Signed-off-by: Mark Fasheh --- fs/ocfs2/ocfs2_fs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index dfb8a5bedfc8..c5b1ac547c15 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h @@ -138,7 +138,6 @@ /* Journal limits (in bytes) */ #define OCFS2_MIN_JOURNAL_SIZE (4 * 1024 * 1024) -#define OCFS2_MAX_JOURNAL_SIZE (500 * 1024 * 1024) struct ocfs2_system_inode_info { char *si_name; From d267a56c883b350a2fa80f1daf4636809e3f8e67 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Thu, 23 Feb 2006 13:23:39 -0800 Subject: [PATCH 010/178] [PATCH] ocfs2: remove unused code Remove some #ifdef'd out code which was inadvertantly introduced in our initial merge. Signed-off-by: Mark Fasheh --- fs/ocfs2/file.c | 51 +----------------------------------------------- fs/ocfs2/ocfs2.h | 3 --- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 1715bc90e705..8a4048b55fdc 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -933,9 +933,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; loff_t newsize, saved_pos; -#ifdef OCFS2_ORACORE_WORKAROUNDS - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); -#endif mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, (unsigned int)count, @@ -951,14 +948,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, return -EIO; } -#ifdef OCFS2_ORACORE_WORKAROUNDS - /* ugh, work around some applications which open everything O_DIRECT + - * O_APPEND and really don't mean to use O_DIRECT. */ - if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS && - (filp->f_flags & O_APPEND) && (filp->f_flags & O_DIRECT)) - filp->f_flags &= ~O_DIRECT; -#endif - mutex_lock(&inode->i_mutex); /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ if (filp->f_flags & O_DIRECT) { @@ -1079,27 +1068,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb); -#ifdef OCFS2_ORACORE_WORKAROUNDS - if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS && - filp->f_flags & O_DIRECT) { - unsigned int saved_flags = filp->f_flags; - int sector_size = 1 << osb->s_sectsize_bits; - - if ((saved_pos & (sector_size - 1)) || - (count & (sector_size - 1)) || - ((unsigned long)buf & (sector_size - 1))) { - filp->f_flags |= O_SYNC; - filp->f_flags &= ~O_DIRECT; - } - - ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, - &iocb->ki_pos); - - filp->f_flags = saved_flags; - } else -#endif - ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, - &iocb->ki_pos); + ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); @@ -1140,9 +1109,6 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, int ret = 0, rw_level = -1, have_alloc_sem = 0; struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; -#ifdef OCFS2_ORACORE_WORKAROUNDS - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); -#endif mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, (unsigned int)count, @@ -1155,21 +1121,6 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, goto bail; } -#ifdef OCFS2_ORACORE_WORKAROUNDS - if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS) { - if (filp->f_flags & O_DIRECT) { - int sector_size = 1 << osb->s_sectsize_bits; - - if ((pos & (sector_size - 1)) || - (count & (sector_size - 1)) || - ((unsigned long)buf & (sector_size - 1)) || - (i_size_read(inode) & (sector_size -1))) { - filp->f_flags &= ~O_DIRECT; - } - } - } -#endif - /* * buffered reads protect themselves in ->readpage(). O_DIRECT reads * need locks to protect pending reads from racing with truncate. diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 8d8e4779df92..19360e3d842e 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -174,9 +174,6 @@ enum ocfs2_mount_options OCFS2_MOUNT_NOINTR = 1 << 2, /* Don't catch signals */ OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */ OCFS2_MOUNT_DATA_WRITEBACK = 1 << 4, /* No data ordering */ -#ifdef OCFS2_ORACORE_WORKAROUNDS - OCFS2_MOUNT_COMPAT_OCFS = 1 << 30, /* ocfs1 compatibility mode */ -#endif }; #define OCFS2_OSB_SOFT_RO 0x0001 From 362342f68e331f080d0438f08af1e2c570b0b5fe Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Tue, 21 Feb 2006 16:46:33 -0800 Subject: [PATCH 011/178] [PATCH] ocfs2: remove non existing function prototypes Remove some prototypes from tcp.h for functions which have long been gone. Signed-off-by: Mark Fasheh --- fs/ocfs2/cluster/tcp.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fs/ocfs2/cluster/tcp.h b/fs/ocfs2/cluster/tcp.h index a6f4585501c8..616ff2b8434a 100644 --- a/fs/ocfs2/cluster/tcp.h +++ b/fs/ocfs2/cluster/tcp.h @@ -85,13 +85,10 @@ enum { O2NET_DRIVER_READY, }; -int o2net_init_tcp_sock(struct inode *inode); int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len, u8 target_node, int *status); int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *vec, size_t veclen, u8 target_node, int *status); -int o2net_broadcast_message(u32 msg_type, u32 key, void *data, u32 len, - struct inode *group); int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, o2net_msg_handler_func *func, void *data, @@ -107,7 +104,5 @@ void o2net_disconnect_node(struct o2nm_node *node); int o2net_init(void); void o2net_exit(void); -int o2net_proc_init(struct proc_dir_entry *parent); -void o2net_proc_exit(struct proc_dir_entry *parent); #endif /* O2CLUSTER_TCP_H */ From 800d11420dfdad3a50630ff424d7782660ad558c Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 1 Mar 2006 15:16:26 +0900 Subject: [PATCH 012/178] [MIPS] Use USECS_PER_SEC / HZ instead of tick_usec in do_gettimeofday. The 'tick_usec' is USER_HZ period in usec. do_gettimeofday() should use kernel HZ value. Here is a patch for MIPS. It seems m32r, m68k and sparc have same problem though their HZ and USER_HZ are same for now. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/time.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 7050b4ffffcd..42c94c771afb 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -163,7 +163,7 @@ void do_gettimeofday(struct timeval *tv) unsigned long seq; unsigned long lost; unsigned long usec, sec; - unsigned long max_ntp_tick = tick_usec - tickadj; + unsigned long max_ntp_tick; do { seq = read_seqbegin(&xtime_lock); @@ -178,12 +178,13 @@ void do_gettimeofday(struct timeval *tv) * Better to lose some accuracy than have time go backwards.. */ if (unlikely(time_adjust < 0)) { + max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj; usec = min(usec, max_ntp_tick); if (lost) usec += lost * max_ntp_tick; } else if (unlikely(lost)) - usec += lost * tick_usec; + usec += lost * (USEC_PER_SEC / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); From 895928b8380cc697ac56e9732cedf549c0a4f79c Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 21 Feb 2006 16:54:00 -0800 Subject: [PATCH 013/178] [PATCH] ocfs2: complete failure recovery for nodemanager init This patch finishes cleaning up the node manager allocations if it fails to initialize. Signed-off-by: Jeff Mahoney Signed-off-by: Mark Fasheh --- fs/ocfs2/cluster/nodemanager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index cf7828f23361..e1fceb8aa32d 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -756,7 +756,7 @@ static int __init init_o2nm(void) if (!ocfs2_table_header) { printk(KERN_ERR "nodemanager: unable to register sysctl\n"); ret = -ENOMEM; /* or something. */ - goto out; + goto out_o2net; } ret = o2net_register_hb_callbacks(); @@ -780,6 +780,8 @@ out_callbacks: o2net_unregister_hb_callbacks(); out_sysctl: unregister_sysctl_table(ocfs2_table_header); +out_o2net: + o2net_exit(); out: return ret; } From b4df6ed8db0c387d38292e31f00adc4cd297ed5a Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Wed, 22 Feb 2006 17:35:08 -0800 Subject: [PATCH 014/178] [PATCH] ocfs2: fix orphan recovery deadlock Orphan dir recovery can deadlock with another process in ocfs2_delete_inode() in some corner cases. Fix this by tracking recovery state more closely and allowing it to handle inode wipes which might deadlock. Signed-off-by: Mark Fasheh --- fs/ocfs2/heartbeat.c | 1 + fs/ocfs2/inode.c | 46 +++++++++++++++- fs/ocfs2/journal.c | 124 ++++++++++++++++++++++++++++++++----------- fs/ocfs2/ocfs2.h | 4 ++ fs/ocfs2/super.c | 11 ++++ 5 files changed, 154 insertions(+), 32 deletions(-) diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index 0bbd22f46c80..cbfd45a97a63 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c @@ -67,6 +67,7 @@ void ocfs2_init_node_maps(struct ocfs2_super *osb) ocfs2_node_map_init(&osb->mounted_map); ocfs2_node_map_init(&osb->recovery_map); ocfs2_node_map_init(&osb->umount_map); + ocfs2_node_map_init(&osb->osb_recovering_orphan_dirs); } static void ocfs2_do_node_down(int node_num, diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 8122489c5762..315472a5c192 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -41,6 +41,7 @@ #include "dlmglue.h" #include "extent_map.h" #include "file.h" +#include "heartbeat.h" #include "inode.h" #include "journal.h" #include "namei.h" @@ -544,6 +545,42 @@ bail: return status; } +/* + * Serialize with orphan dir recovery. If the process doing + * recovery on this orphan dir does an iget() with the dir + * i_mutex held, we'll deadlock here. Instead we detect this + * and exit early - recovery will wipe this inode for us. + */ +static int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb, + int slot) +{ + int ret = 0; + + spin_lock(&osb->osb_lock); + if (ocfs2_node_map_test_bit(osb, &osb->osb_recovering_orphan_dirs, slot)) { + mlog(0, "Recovery is happening on orphan dir %d, will skip " + "this inode\n", slot); + ret = -EDEADLK; + goto out; + } + /* This signals to the orphan recovery process that it should + * wait for us to handle the wipe. */ + osb->osb_orphan_wipes[slot]++; +out: + spin_unlock(&osb->osb_lock); + return ret; +} + +static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb, + int slot) +{ + spin_lock(&osb->osb_lock); + osb->osb_orphan_wipes[slot]--; + spin_unlock(&osb->osb_lock); + + wake_up(&osb->osb_wipe_event); +} + static int ocfs2_wipe_inode(struct inode *inode, struct buffer_head *di_bh) { @@ -555,6 +592,11 @@ static int ocfs2_wipe_inode(struct inode *inode, /* We've already voted on this so it should be readonly - no * spinlock needed. */ orphaned_slot = OCFS2_I(inode)->ip_orphaned_slot; + + status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); + if (status) + return status; + orphan_dir_inode = ocfs2_get_system_file_inode(osb, ORPHAN_DIR_SYSTEM_INODE, orphaned_slot); @@ -597,6 +639,7 @@ bail_unlock_dir: brelse(orphan_dir_bh); bail: iput(orphan_dir_inode); + ocfs2_signal_wipe_completion(osb, orphaned_slot); return status; } @@ -822,7 +865,8 @@ void ocfs2_delete_inode(struct inode *inode) status = ocfs2_wipe_inode(inode, di_bh); if (status < 0) { - mlog_errno(status); + if (status != -EDEADLK) + mlog_errno(status); goto bail_unlock_inode; } diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index d329c9df90ae..4be801f4559b 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1408,21 +1408,17 @@ bail: return status; } -static int ocfs2_recover_orphans(struct ocfs2_super *osb, - int slot) +static int ocfs2_queue_orphans(struct ocfs2_super *osb, + int slot, + struct inode **head) { - int status = 0; - int have_disk_lock = 0; - struct inode *inode = NULL; - struct inode *iter; + int status; struct inode *orphan_dir_inode = NULL; + struct inode *iter; unsigned long offset, blk, local; struct buffer_head *bh = NULL; struct ocfs2_dir_entry *de; struct super_block *sb = osb->sb; - struct ocfs2_inode_info *oi; - - mlog(0, "Recover inodes from orphan dir in slot %d\n", slot); orphan_dir_inode = ocfs2_get_system_file_inode(osb, ORPHAN_DIR_SYSTEM_INODE, @@ -1430,17 +1426,15 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, if (!orphan_dir_inode) { status = -ENOENT; mlog_errno(status); - goto out; - } + return status; + } mutex_lock(&orphan_dir_inode->i_mutex); status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0); if (status < 0) { - mutex_unlock(&orphan_dir_inode->i_mutex); mlog_errno(status); goto out; } - have_disk_lock = 1; offset = 0; iter = NULL; @@ -1451,11 +1445,10 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, if (!bh) status = -EINVAL; if (status < 0) { - mutex_unlock(&orphan_dir_inode->i_mutex); if (bh) brelse(bh); mlog_errno(status); - goto out; + goto out_unlock; } local = 0; @@ -1465,11 +1458,10 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, if (!ocfs2_check_dir_entry(orphan_dir_inode, de, bh, local)) { - mutex_unlock(&orphan_dir_inode->i_mutex); status = -EINVAL; mlog_errno(status); brelse(bh); - goto out; + goto out_unlock; } local += le16_to_cpu(de->rec_len); @@ -1504,18 +1496,95 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, mlog(0, "queue orphan %"MLFu64"\n", OCFS2_I(iter)->ip_blkno); - OCFS2_I(iter)->ip_next_orphan = inode; - inode = iter; + /* No locking is required for the next_orphan + * queue as there is only ever a single + * process doing orphan recovery. */ + OCFS2_I(iter)->ip_next_orphan = *head; + *head = iter; } brelse(bh); } - mutex_unlock(&orphan_dir_inode->i_mutex); +out_unlock: ocfs2_meta_unlock(orphan_dir_inode, 0); - have_disk_lock = 0; - +out: + mutex_unlock(&orphan_dir_inode->i_mutex); iput(orphan_dir_inode); - orphan_dir_inode = NULL; + return status; +} + +static int ocfs2_orphan_recovery_can_continue(struct ocfs2_super *osb, + int slot) +{ + int ret; + + spin_lock(&osb->osb_lock); + ret = !osb->osb_orphan_wipes[slot]; + spin_unlock(&osb->osb_lock); + return ret; +} + +static void ocfs2_mark_recovering_orphan_dir(struct ocfs2_super *osb, + int slot) +{ + spin_lock(&osb->osb_lock); + /* Mark ourselves such that new processes in delete_inode() + * know to quit early. */ + ocfs2_node_map_set_bit(osb, &osb->osb_recovering_orphan_dirs, slot); + while (osb->osb_orphan_wipes[slot]) { + /* If any processes are already in the middle of an + * orphan wipe on this dir, then we need to wait for + * them. */ + spin_unlock(&osb->osb_lock); + wait_event_interruptible(osb->osb_wipe_event, + ocfs2_orphan_recovery_can_continue(osb, slot)); + spin_lock(&osb->osb_lock); + } + spin_unlock(&osb->osb_lock); +} + +static void ocfs2_clear_recovering_orphan_dir(struct ocfs2_super *osb, + int slot) +{ + ocfs2_node_map_clear_bit(osb, &osb->osb_recovering_orphan_dirs, slot); +} + +/* + * Orphan recovery. Each mounted node has it's own orphan dir which we + * must run during recovery. Our strategy here is to build a list of + * the inodes in the orphan dir and iget/iput them. The VFS does + * (most) of the rest of the work. + * + * Orphan recovery can happen at any time, not just mount so we have a + * couple of extra considerations. + * + * - We grab as many inodes as we can under the orphan dir lock - + * doing iget() outside the orphan dir risks getting a reference on + * an invalid inode. + * - We must be sure not to deadlock with other processes on the + * system wanting to run delete_inode(). This can happen when they go + * to lock the orphan dir and the orphan recovery process attempts to + * iget() inside the orphan dir lock. This can be avoided by + * advertising our state to ocfs2_delete_inode(). + */ +static int ocfs2_recover_orphans(struct ocfs2_super *osb, + int slot) +{ + int ret = 0; + struct inode *inode = NULL; + struct inode *iter; + struct ocfs2_inode_info *oi; + + mlog(0, "Recover inodes from orphan dir in slot %d\n", slot); + + ocfs2_mark_recovering_orphan_dir(osb, slot); + ret = ocfs2_queue_orphans(osb, slot, &inode); + ocfs2_clear_recovering_orphan_dir(osb, slot); + + /* Error here should be noted, but we want to continue with as + * many queued inodes as we've got. */ + if (ret) + mlog_errno(ret); while (inode) { oi = OCFS2_I(inode); @@ -1541,14 +1610,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb, inode = iter; } -out: - if (have_disk_lock) - ocfs2_meta_unlock(orphan_dir_inode, 0); - - if (orphan_dir_inode) - iput(orphan_dir_inode); - - return status; + return ret; } static int ocfs2_wait_on_mount(struct ocfs2_super *osb) diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 19360e3d842e..e89de9b6e491 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -287,6 +287,10 @@ struct ocfs2_super struct inode *osb_tl_inode; struct buffer_head *osb_tl_bh; struct work_struct osb_truncate_log_wq; + + struct ocfs2_node_map osb_recovering_orphan_dirs; + unsigned int *osb_orphan_wipes; + wait_queue_head_t osb_wipe_event; }; #define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 046824b6b625..8dd3aafec499 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1325,6 +1325,16 @@ static int ocfs2_initialize_super(struct super_block *sb, } mlog(ML_NOTICE, "max_slots for this device: %u\n", osb->max_slots); + init_waitqueue_head(&osb->osb_wipe_event); + osb->osb_orphan_wipes = kcalloc(osb->max_slots, + sizeof(*osb->osb_orphan_wipes), + GFP_KERNEL); + if (!osb->osb_orphan_wipes) { + status = -ENOMEM; + mlog_errno(status); + goto bail; + } + osb->s_feature_compat = le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_compat); osb->s_feature_ro_compat = @@ -1638,6 +1648,7 @@ static void ocfs2_delete_osb(struct ocfs2_super *osb) if (osb->slot_info) ocfs2_free_slot_info(osb->slot_info); + kfree(osb->osb_orphan_wipes); /* FIXME * This belongs in journal shutdown, but because we have to * allocate osb->journal at the start of ocfs2_initalize_osb(), From 93cc9ac4555a9b95c78b2f5dfe536fe8196002a7 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Mon, 27 Feb 2006 16:53:05 -0800 Subject: [PATCH 015/178] ocfs2: Set .owner on masklog sysfs attributes. Signed-off-by: Joel Becker Signed-off-by: Mark Fasheh --- fs/ocfs2/cluster/masklog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index fd741cea5705..636593bf4d17 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c @@ -74,6 +74,7 @@ struct mlog_attribute { #define define_mask(_name) { \ .attr = { \ .name = #_name, \ + .owner = THIS_MODULE, \ .mode = S_IRUGO | S_IWUSR, \ }, \ .mask = ML_##_name, \ From 110ba90858a7f619ff26c6b9b43c27b3c0872335 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Tue, 28 Feb 2006 17:58:36 -0800 Subject: [PATCH 016/178] ocfs2: Respond to on-disk corruption in the extent map code. The extent map code has long noticed when the on-disk extent information is corrupt. However, so far it has only returned an error. We should take the filesystem read-only, as it is corrupt. Signed-off-by: Joel Becker Signed-off-by: Mark Fasheh --- fs/ocfs2/extent_map.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index b6ba292e9544..e6f207eebab4 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -181,6 +181,12 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode, ret = -EBADR; if (rec_end > OCFS2_I(inode)->ip_clusters) { mlog_errno(ret); + ocfs2_error(inode->i_sb, + "Extent %d at e_blkno %"MLFu64" of inode %"MLFu64" goes past ip_clusters of %u\n", + i, + le64_to_cpu(rec->e_blkno), + OCFS2_I(inode)->ip_blkno, + OCFS2_I(inode)->ip_clusters); goto out_free; } @@ -226,6 +232,12 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode, ret = -EBADR; if (blkno) { mlog_errno(ret); + ocfs2_error(inode->i_sb, + "Multiple extents for (cpos = %u, clusters = %u) on inode %"MLFu64"; e_blkno %"MLFu64" and rec %d at e_blkno %"MLFu64"\n", + cpos, clusters, + OCFS2_I(inode)->ip_blkno, + blkno, i, + le64_to_cpu(rec->e_blkno)); goto out_free; } @@ -238,6 +250,10 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode, */ ret = -EBADR; if (!blkno) { + ocfs2_error(inode->i_sb, + "No record found for (cpos = %u, clusters = %u) on inode %"MLFu64"\n", + cpos, clusters, + OCFS2_I(inode)->ip_blkno); mlog_errno(ret); goto out_free; } @@ -266,6 +282,20 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode, for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) { rec = &el->l_recs[i]; + + if ((le32_to_cpu(rec->e_cpos) + le32_to_cpu(rec->e_clusters)) > + OCFS2_I(inode)->ip_clusters) { + ret = -EBADR; + mlog_errno(ret); + ocfs2_error(inode->i_sb, + "Extent %d at e_blkno %"MLFu64" of inode %"MLFu64" goes past ip_clusters of %u\n", + i, + le64_to_cpu(rec->e_blkno), + OCFS2_I(inode)->ip_blkno, + OCFS2_I(inode)->ip_clusters); + return ret; + } + ret = ocfs2_extent_map_insert(inode, rec, le16_to_cpu(el->l_tree_depth)); if (ret) { @@ -526,6 +556,10 @@ static int ocfs2_extent_map_insert(struct inode *inode, OCFS2_I(inode)->ip_map.em_clusters) { ret = -EBADR; mlog_errno(ret); + ocfs2_error(inode->i_sb, + "Zero e_clusters on non-tail extent record at e_blkno %"MLFu64" on inode %"MLFu64"\n", + le64_to_cpu(rec->e_blkno), + OCFS2_I(inode)->ip_blkno); return ret; } @@ -588,12 +622,12 @@ static int ocfs2_extent_map_insert(struct inode *inode, * Existing record in the extent map: * * cpos = 10, len = 10 - * |---------| + * |---------| * * New Record: * * cpos = 10, len = 20 - * |------------------| + * |------------------| * * The passed record is the new on-disk record. The new_clusters value * is how many clusters were added to the file. If the append is a From b7668c72d2ae004363fb0588600bfa942e1b245c Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 28 Feb 2006 23:28:01 -0800 Subject: [PATCH 017/178] [PATCH] ocfs2: added source addr to bind() in o2net_start_connect() to prevent confusion when a virtual ip is created on the same interface Signed-off-by: Sunil Mushran Signed-off-by: Mark Fasheh --- fs/ocfs2/cluster/tcp.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index d22d4cf08db1..0f60cc0d3985 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -1318,7 +1318,7 @@ static void o2net_start_connect(void *arg) { struct o2net_node *nn = arg; struct o2net_sock_container *sc = NULL; - struct o2nm_node *node = NULL; + struct o2nm_node *node = NULL, *mynode = NULL; struct socket *sock = NULL; struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; int ret = 0; @@ -1334,6 +1334,12 @@ static void o2net_start_connect(void *arg) goto out; } + mynode = o2nm_get_node_by_num(o2nm_this_node()); + if (mynode == NULL) { + ret = 0; + goto out; + } + spin_lock(&nn->nn_lock); /* see if we already have one pending or have given up */ if (nn->nn_sc || nn->nn_persistent_error) @@ -1361,12 +1367,14 @@ static void o2net_start_connect(void *arg) sock->sk->sk_allocation = GFP_ATOMIC; myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = (__force u32)mynode->nd_ipv4_address; myaddr.sin_port = (__force u16)htons(0); /* any port */ ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, sizeof(myaddr)); if (ret) { - mlog(0, "bind failed: %d\n", ret); + mlog(ML_ERROR, "bind failed with %d at address %u.%u.%u.%u\n", + ret, NIPQUAD(mynode->nd_ipv4_address)); goto out; } @@ -1407,6 +1415,8 @@ out: sc_put(sc); if (node) o2nm_node_put(node); + if (mynode) + o2nm_node_put(mynode); return; } From 81f2094a631df1ba275f4d4bd7ea5bacfd8dbcfc Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Tue, 28 Feb 2006 17:31:22 -0800 Subject: [PATCH 018/178] [PATCH] ocfs2: use hlists for lockres hash Switch from list_head to hlist_head. Make the size of the hash dependent upon the allocated area, rather than a constant. Signed-off-by: Mark Fasheh --- fs/ocfs2/dlm/dlmcommon.h | 8 +++----- fs/ocfs2/dlm/dlmdebug.c | 12 +++++------- fs/ocfs2/dlm/dlmdomain.c | 39 +++++++++++++++++++------------------- fs/ocfs2/dlm/dlmmaster.c | 4 ++-- fs/ocfs2/dlm/dlmrecovery.c | 23 +++++++++++----------- 5 files changed, 41 insertions(+), 45 deletions(-) diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 23ceaa7127b4..9c772583744a 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -37,9 +37,7 @@ #define DLM_THREAD_SHUFFLE_INTERVAL 5 // flush everything every 5 passes #define DLM_THREAD_MS 200 // flush at least every 200 ms -#define DLM_HASH_BITS 7 -#define DLM_HASH_SIZE (1 << DLM_HASH_BITS) -#define DLM_HASH_MASK (DLM_HASH_SIZE - 1) +#define DLM_HASH_BUCKETS (PAGE_SIZE / sizeof(struct hlist_head)) enum dlm_ast_type { DLM_AST = 0, @@ -87,7 +85,7 @@ enum dlm_ctxt_state { struct dlm_ctxt { struct list_head list; - struct list_head *resources; + struct hlist_head *lockres_hash; struct list_head dirty_list; struct list_head purge_list; struct list_head pending_asts; @@ -217,7 +215,7 @@ struct dlm_lock_resource { /* WARNING: Please see the comment in dlm_init_lockres before * adding fields here. */ - struct list_head list; + struct hlist_node hash_node; struct kref refs; /* please keep these next 3 in this order diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index f339fe27975a..54f61b76ab51 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c @@ -117,8 +117,8 @@ EXPORT_SYMBOL_GPL(dlm_print_one_lock); void dlm_dump_lock_resources(struct dlm_ctxt *dlm) { struct dlm_lock_resource *res; - struct list_head *iter; - struct list_head *bucket; + struct hlist_node *iter; + struct hlist_head *bucket; int i; mlog(ML_NOTICE, "struct dlm_ctxt: %s, node=%u, key=%u\n", @@ -129,12 +129,10 @@ void dlm_dump_lock_resources(struct dlm_ctxt *dlm) } spin_lock(&dlm->spinlock); - for (i=0; iresources[i]); - list_for_each(iter, bucket) { - res = list_entry(iter, struct dlm_lock_resource, list); + for (i=0; ilockres_hash[i]); + hlist_for_each_entry(res, iter, bucket, hash_node) dlm_print_one_lock_resource(res); - } } spin_unlock(&dlm->spinlock); } diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 6ee30837389c..8f3a9e3106fd 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -77,26 +77,26 @@ static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm); void __dlm_unhash_lockres(struct dlm_lock_resource *lockres) { - list_del_init(&lockres->list); + hlist_del_init(&lockres->hash_node); dlm_lockres_put(lockres); } void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { - struct list_head *bucket; + struct hlist_head *bucket; struct qstr *q; assert_spin_locked(&dlm->spinlock); q = &res->lockname; q->hash = full_name_hash(q->name, q->len); - bucket = &(dlm->resources[q->hash & DLM_HASH_MASK]); + bucket = &(dlm->lockres_hash[q->hash % DLM_HASH_BUCKETS]); /* get a reference for our hashtable */ dlm_lockres_get(res); - list_add_tail(&res->list, bucket); + hlist_add_head(&res->hash_node, bucket); } struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, @@ -104,9 +104,9 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, unsigned int len) { unsigned int hash; - struct list_head *iter; + struct hlist_node *iter; struct dlm_lock_resource *tmpres=NULL; - struct list_head *bucket; + struct hlist_head *bucket; mlog_entry("%.*s\n", len, name); @@ -114,11 +114,11 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm, hash = full_name_hash(name, len); - bucket = &(dlm->resources[hash & DLM_HASH_MASK]); + bucket = &(dlm->lockres_hash[hash % DLM_HASH_BUCKETS]); /* check for pre-existing lock */ - list_for_each(iter, bucket) { - tmpres = list_entry(iter, struct dlm_lock_resource, list); + hlist_for_each(iter, bucket) { + tmpres = hlist_entry(iter, struct dlm_lock_resource, hash_node); if (tmpres->lockname.len == len && memcmp(tmpres->lockname.name, name, len) == 0) { dlm_lockres_get(tmpres); @@ -193,8 +193,8 @@ static int dlm_wait_on_domain_helper(const char *domain) static void dlm_free_ctxt_mem(struct dlm_ctxt *dlm) { - if (dlm->resources) - free_page((unsigned long) dlm->resources); + if (dlm->lockres_hash) + free_page((unsigned long) dlm->lockres_hash); if (dlm->name) kfree(dlm->name); @@ -303,10 +303,10 @@ static void dlm_migrate_all_locks(struct dlm_ctxt *dlm) mlog(0, "Migrating locks from domain %s\n", dlm->name); restart: spin_lock(&dlm->spinlock); - for (i=0; iresources[i])) { - res = list_entry(dlm->resources[i].next, - struct dlm_lock_resource, list); + for (i = 0; i < DLM_HASH_BUCKETS; i++) { + while (!hlist_empty(&dlm->lockres_hash[i])) { + res = hlist_entry(dlm->lockres_hash[i].first, + struct dlm_lock_resource, hash_node); /* need reference when manually grabbing lockres */ dlm_lockres_get(res); /* this should unhash the lockres @@ -1191,18 +1191,17 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, goto leave; } - dlm->resources = (struct list_head *) __get_free_page(GFP_KERNEL); - if (!dlm->resources) { + dlm->lockres_hash = (struct hlist_head *) __get_free_page(GFP_KERNEL); + if (!dlm->lockres_hash) { mlog_errno(-ENOMEM); kfree(dlm->name); kfree(dlm); dlm = NULL; goto leave; } - memset(dlm->resources, 0, PAGE_SIZE); - for (i=0; iresources[i]); + for (i=0; ilockres_hash[i]); strcpy(dlm->name, domain); dlm->key = key; diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 2e2e95e69499..847dd3cc4cf5 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -564,7 +564,7 @@ static void dlm_lockres_release(struct kref *kref) /* By the time we're ready to blow this guy away, we shouldn't * be on any lists. */ - BUG_ON(!list_empty(&res->list)); + BUG_ON(!hlist_unhashed(&res->hash_node)); BUG_ON(!list_empty(&res->granted)); BUG_ON(!list_empty(&res->converting)); BUG_ON(!list_empty(&res->blocked)); @@ -605,7 +605,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, init_waitqueue_head(&res->wq); spin_lock_init(&res->spinlock); - INIT_LIST_HEAD(&res->list); + INIT_HLIST_NODE(&res->hash_node); INIT_LIST_HEAD(&res->granted); INIT_LIST_HEAD(&res->converting); INIT_LIST_HEAD(&res->blocked); diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index ed76bda1a534..1e232000f3f7 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -1693,7 +1693,10 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm, u8 dead_node, u8 new_master) { int i; - struct list_head *iter, *iter2, *bucket; + struct list_head *iter, *iter2; + struct hlist_node *hash_iter; + struct hlist_head *bucket; + struct dlm_lock_resource *res; mlog_entry_void(); @@ -1717,10 +1720,9 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm, * for now we need to run the whole hash, clear * the RECOVERING state and set the owner * if necessary */ - for (i=0; iresources[i]); - list_for_each(iter, bucket) { - res = list_entry (iter, struct dlm_lock_resource, list); + for (i = 0; i < DLM_HASH_BUCKETS; i++) { + bucket = &(dlm->lockres_hash[i]); + hlist_for_each_entry(res, hash_iter, bucket, hash_node) { if (res->state & DLM_LOCK_RES_RECOVERING) { if (res->owner == dead_node) { mlog(0, "(this=%u) res %.*s owner=%u " @@ -1852,10 +1854,10 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node) { - struct list_head *iter; + struct hlist_node *iter; struct dlm_lock_resource *res; int i; - struct list_head *bucket; + struct hlist_head *bucket; struct dlm_lock *lock; @@ -1876,10 +1878,9 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node) * can be kicked again to see if any ASTs or BASTs * need to be fired as a result. */ - for (i=0; iresources[i]); - list_for_each(iter, bucket) { - res = list_entry (iter, struct dlm_lock_resource, list); + for (i = 0; i < DLM_HASH_BUCKETS; i++) { + bucket = &(dlm->lockres_hash[i]); + hlist_for_each_entry(res, iter, bucket, hash_node) { /* always prune any $RECOVERY entries for dead nodes, * otherwise hangs can occur during later recovery */ if (dlm_is_recovery_lock(res->lockname.name, From e5cef95d58d1e711b0bd6b00018278a06defb274 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 1 Mar 2006 13:46:00 -0800 Subject: [PATCH 019/178] [PATCH] fix build breakage in eeh.c in 2.6.16-rc5-git5 This patch should fixe a problem with eeh_add_device_late() not being defined in the ppc64 build process, causing the build to break. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- include/asm-powerpc/eeh.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h index 7dfb408fe2ca..eb392032e19b 100644 --- a/include/asm-powerpc/eeh.h +++ b/include/asm-powerpc/eeh.h @@ -61,6 +61,7 @@ void __init pci_addr_cache_build(void); * to finish the eeh setup for this device. */ void eeh_add_device_early(struct device_node *); +void eeh_add_device_late(struct pci_dev *dev); void eeh_add_device_tree_early(struct device_node *); void eeh_add_device_tree_late(struct pci_bus *); From 140ffcec4def3ee3af7565b2cf1d3b2580f7e180 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 2 Mar 2006 02:54:28 -0800 Subject: [PATCH 020/178] [PATCH] out_of_memory() locking fix I seem to have lost this read_unlock(). While we're there, let's turn that interruptible sleep unto uninterruptible, so we don't get a busywait if signal_pending(). (Again. We seem to have a habit of doing this). Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/oom_kill.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index c86c737d2433..78747afad6b0 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -355,6 +355,7 @@ retry: } out: + read_unlock(&tasklist_lock); cpuset_unlock(); if (mm) mmput(mm); @@ -364,5 +365,5 @@ out: * retry to allocate memory unless "p" is current */ if (!test_thread_flag(TIF_MEMDIE)) - schedule_timeout_interruptible(1); + schedule_timeout_uninterruptible(1); } From 77a3313551afd53c90012e5a87f7f2b2195fc67e Mon Sep 17 00:00:00 2001 From: John Bowler Date: Thu, 2 Mar 2006 02:54:29 -0800 Subject: [PATCH 021/178] [PATCH] "drivers/mtd/redboot.c: recognise a foreign byte sex partition table" update Sync up the recent redboot fix with MTD CVS. It uses the correct swab() functions. Cc: John Bowler Cc: David Woodhouse Cc: Thomas Gleixner Cc: Martin Michlmayr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/redboot.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index d01b6a9198e0..8815c8dbef2d 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -1,5 +1,5 @@ /* - * $Id: redboot.c,v 1.18 2005/11/07 11:14:21 gleixner Exp $ + * $Id: redboot.c,v 1.19 2005/12/01 10:03:51 dwmw2 Exp $ * * Parse RedBoot-style Flash Image System (FIS) tables and * produce a Linux partition array to match. @@ -92,10 +92,10 @@ static int parse_redboot_partitions(struct mtd_info *master, if (!memcmp(buf[i].name, "FIS directory", 14)) { /* This is apparently the FIS directory entry for the * FIS directory itself. The FIS directory size is - * one erase block, if the buf[i].size field is + * one erase block; if the buf[i].size field is * swab32(erasesize) then we know we are looking at * a byte swapped FIS directory - swap all the entries! - * (NOTE: this is 'size' not 'data_length', size is + * (NOTE: this is 'size' not 'data_length'; size is * the full size of the entry.) */ if (swab32(buf[i].size) == master->erasesize) { @@ -104,15 +104,13 @@ static int parse_redboot_partitions(struct mtd_info *master, /* The unsigned long fields were written with the * wrong byte sex, name and pad have no byte sex. */ -# define do_swab32(x) (x) = swab32(x) - do_swab32(buf[j].flash_base); - do_swab32(buf[j].mem_base); - do_swab32(buf[j].size); - do_swab32(buf[j].entry_point); - do_swab32(buf[j].data_length); - do_swab32(buf[j].desc_cksum); - do_swab32(buf[j].file_cksum); -# undef do_swab32 + swab32s(&buf[j].flash_base); + swab32s(&buf[j].mem_base); + swab32s(&buf[j].size); + swab32s(&buf[j].entry_point); + swab32s(&buf[j].data_length); + swab32s(&buf[j].desc_cksum); + swab32s(&buf[j].file_cksum); } } break; From 6a3124a3946c16159c3faf83e62ffdb5d1134b3a Mon Sep 17 00:00:00 2001 From: Latchesar Ionkov Date: Thu, 2 Mar 2006 02:54:30 -0800 Subject: [PATCH 022/178] [PATCH] v9fs: fix atomic create open In order to assure atomic create+open v9fs stores the open fid produced by v9fs_vfs_create in the dentry, from where v9fs_file_open retrieves it and associates it with the open file. This patch modifies v9fs to use nameidata.intent.open values to do the atomic create+open. Signed-off-by: Latchesar Ionkov Signed-off-by: Eric Van Hensbergen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/9p/fid.c | 73 ++----- fs/9p/fid.h | 5 +- fs/9p/v9fs_vfs.h | 1 + fs/9p/vfs_file.c | 118 +++++------ fs/9p/vfs_inode.c | 510 +++++++++++++++++++++++++++++----------------- fs/9p/vfs_super.c | 12 +- 6 files changed, 401 insertions(+), 318 deletions(-) diff --git a/fs/9p/fid.c b/fs/9p/fid.c index eda449778fa5..c27f546dd25b 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -40,7 +40,7 @@ * */ -static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) +int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; dprintk(DEBUG_9P, "fid %d (%p) dentry %s (%p)\n", fid->fid, fid, @@ -68,14 +68,11 @@ static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) * */ -struct v9fs_fid *v9fs_fid_create(struct dentry *dentry, - struct v9fs_session_info *v9ses, int fid, int create) +struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) { struct v9fs_fid *new; - dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n", - dentry, fid, create); - + dprintk(DEBUG_9P, "fid create fid %d\n", fid); new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); if (new == NULL) { dprintk(DEBUG_ERROR, "Out of Memory\n"); @@ -85,19 +82,13 @@ struct v9fs_fid *v9fs_fid_create(struct dentry *dentry, new->fid = fid; new->v9ses = v9ses; new->fidopen = 0; - new->fidcreate = create; new->fidclunked = 0; new->iounit = 0; new->rdir_pos = 0; new->rdir_fcall = NULL; + INIT_LIST_HEAD(&new->list); - if (v9fs_fid_insert(new, dentry) == 0) return new; - else { - dprintk(DEBUG_ERROR, "Problems inserting to dentry\n"); - kfree(new); - return NULL; - } } /** @@ -119,7 +110,7 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) { int fidnum, cfidnum, err; - struct v9fs_fid *cfid; + struct v9fs_fid *cfid, *fid; struct dentry *cde; struct v9fs_session_info *v9ses; @@ -158,7 +149,16 @@ static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) cde = cde->d_parent; } - return v9fs_fid_create(dentry, v9ses, fidnum, 0); + fid = v9fs_fid_create(v9ses, fidnum); + if (fid) { + err = v9fs_fid_insert(fid, dentry); + if (err < 0) { + kfree(fid); + goto clunk_fid; + } + } + + return fid; clunk_fid: v9fs_t_clunk(v9ses, fidnum); @@ -179,29 +179,12 @@ clunk_fid: struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) { struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; - struct v9fs_fid *current_fid = NULL; - struct v9fs_fid *temp = NULL; struct v9fs_fid *return_fid = NULL; dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); - if (fid_list) { - list_for_each_entry_safe(current_fid, temp, fid_list, list) { - if (!current_fid->fidcreate) { - return_fid = current_fid; - break; - } - } - - if (!return_fid) - return_fid = current_fid; - } - - /* we are at the root but didn't match */ - if ((!return_fid) && (dentry->d_parent == dentry)) { - /* TODO: clone attach with new uid */ - return_fid = current_fid; - } + if (fid_list) + return_fid = list_entry(fid_list->next, struct v9fs_fid, list); if (!return_fid) { struct dentry *par = current->fs->pwd->d_parent; @@ -228,25 +211,3 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) return return_fid; } - -struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry) -{ - struct list_head *fid_list; - struct v9fs_fid *fid, *ftmp, *ret; - - dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); - fid_list = (struct list_head *)dentry->d_fsdata; - ret = NULL; - if (fid_list) { - list_for_each_entry_safe(fid, ftmp, fid_list, list) { - if (fid->fidcreate && fid->pid == current->pid) { - list_del(&fid->list); - ret = fid; - break; - } - } - } - - dprintk(DEBUG_9P, "return %p\n", ret); - return ret; -} diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 84c673a44c83..7ccf0d064e25 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -33,7 +33,6 @@ struct v9fs_fid { u32 fid; unsigned char fidopen; /* set when fid is opened */ - unsigned char fidcreate; /* set when fid was just created */ unsigned char fidclunked; /* set when fid has already been clunked */ struct v9fs_qid qid; @@ -56,5 +55,5 @@ struct v9fs_fid { struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry); struct v9fs_fid *v9fs_fid_get_created(struct dentry *); void v9fs_fid_destroy(struct v9fs_fid *fid); -struct v9fs_fid *v9fs_fid_create(struct dentry *, - struct v9fs_session_info *v9ses, int fid, int create); +struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); +int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 69cf2905dc90..a759278acaae 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h @@ -51,3 +51,4 @@ int v9fs_dir_release(struct inode *inode, struct file *filp); int v9fs_file_open(struct inode *inode, struct file *file); void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat); void v9fs_dentry_release(struct dentry *); +int v9fs_uflags2omode(int uflags); diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index c7e14d917215..de3a129698da 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -53,94 +53,70 @@ int v9fs_file_open(struct inode *inode, struct file *file) { struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); - struct v9fs_fid *v9fid, *fid; + struct v9fs_fid *vfid; struct v9fs_fcall *fcall = NULL; - int open_mode = 0; - unsigned int iounit = 0; - int newfid = -1; - long result = -1; + int omode; + int fid = V9FS_NOFID; + int err; dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); - v9fid = v9fs_fid_get_created(file->f_dentry); - if (!v9fid) - v9fid = v9fs_fid_lookup(file->f_dentry); - - if (!v9fid) { + vfid = v9fs_fid_lookup(file->f_dentry); + if (!vfid) { dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); return -EBADF; } - if (!v9fid->fidcreate) { - fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); - if (fid == NULL) { - dprintk(DEBUG_ERROR, "Out of Memory\n"); - return -ENOMEM; - } - - fid->fidopen = 0; - fid->fidcreate = 0; - fid->fidclunked = 0; - fid->iounit = 0; - fid->v9ses = v9ses; - - newfid = v9fs_get_idpool(&v9ses->fidpool); - if (newfid < 0) { + fid = v9fs_get_idpool(&v9ses->fidpool); + if (fid < 0) { eprintk(KERN_WARNING, "newfid fails!\n"); return -ENOSPC; } - result = - v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL); - - if (result < 0) { - v9fs_put_idpool(newfid, &v9ses->fidpool); + err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); + if (err < 0) { dprintk(DEBUG_ERROR, "rewalk didn't work\n"); - return -EBADF; - } - - fid->fid = newfid; - v9fid = fid; - /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ - /* translate open mode appropriately */ - open_mode = file->f_flags & 0x3; - - if (file->f_flags & O_EXCL) - open_mode |= V9FS_OEXCL; - - if (v9ses->extended) { - if (file->f_flags & O_TRUNC) - open_mode |= V9FS_OTRUNC; - - if (file->f_flags & O_APPEND) - open_mode |= V9FS_OAPPEND; - } - - result = v9fs_t_open(v9ses, newfid, open_mode, &fcall); - if (result < 0) { - PRINT_FCALL_ERROR("open failed", fcall); - kfree(fcall); - return result; - } - - iounit = fcall->params.ropen.iounit; - kfree(fcall); - } else { - /* create case */ - newfid = v9fid->fid; - iounit = v9fid->iounit; - v9fid->fidcreate = 0; + goto put_fid; } - file->private_data = v9fid; + vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); + if (vfid == NULL) { + dprintk(DEBUG_ERROR, "out of memory\n"); + goto clunk_fid; + } - v9fid->rdir_pos = 0; - v9fid->rdir_fcall = NULL; - v9fid->fidopen = 1; - v9fid->filp = file; - v9fid->iounit = iounit; + /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */ + /* translate open mode appropriately */ + omode = v9fs_uflags2omode(file->f_flags); + err = v9fs_t_open(v9ses, fid, omode, &fcall); + if (err < 0) { + PRINT_FCALL_ERROR("open failed", fcall); + goto destroy_vfid; + } + + file->private_data = vfid; + vfid->fid = fid; + vfid->fidopen = 1; + vfid->fidclunked = 0; + vfid->iounit = fcall->params.ropen.iounit; + vfid->rdir_pos = 0; + vfid->rdir_fcall = NULL; + vfid->filp = file; + kfree(fcall); return 0; + +destroy_vfid: + v9fs_fid_destroy(vfid); + +clunk_fid: + v9fs_t_clunk(v9ses, fid); + +put_fid: + v9fs_put_idpool(fid, &v9ses->fidpool); + kfree(fcall); + + return err; } /** @@ -289,9 +265,7 @@ v9fs_file_write(struct file *filp, const char __user * data, total += result; } while (count); - if(inode->i_mapping->nrpages) invalidate_inode_pages2(inode->i_mapping); - return total; } diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 63e5b0398e8b..dce729d42869 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -125,6 +125,38 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) return res; } +int v9fs_uflags2omode(int uflags) +{ + int ret; + + ret = 0; + switch (uflags&3) { + default: + case O_RDONLY: + ret = V9FS_OREAD; + break; + + case O_WRONLY: + ret = V9FS_OWRITE; + break; + + case O_RDWR: + ret = V9FS_ORDWR; + break; + } + + if (uflags & O_EXCL) + ret |= V9FS_OEXCL; + + if (uflags & O_TRUNC) + ret |= V9FS_OTRUNC; + + if (uflags & O_APPEND) + ret |= V9FS_OAPPEND; + + return ret; +} + /** * v9fs_blank_wstat - helper function to setup a 9P stat structure * @v9ses: 9P session info (for determining extended mode) @@ -163,7 +195,7 @@ v9fs_blank_wstat(struct v9fs_wstat *wstat) struct inode *v9fs_get_inode(struct super_block *sb, int mode) { - struct inode *inode = NULL; + struct inode *inode; struct v9fs_session_info *v9ses = sb->s_fs_info; dprintk(DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); @@ -222,171 +254,135 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) return inode; } -/** - * v9fs_create - helper function to create files and directories - * @dir: directory inode file is being created in - * @file_dentry: dentry file is being created in - * @perm: permissions file is being created with - * @open_mode: resulting open mode for file - * - */ - static int -v9fs_create(struct inode *dir, - struct dentry *file_dentry, - unsigned int perm, unsigned int open_mode) +v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, + u32 perm, u8 mode, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) { - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); - struct super_block *sb = dir->i_sb; - struct v9fs_fid *dirfid = - v9fs_fid_lookup(file_dentry->d_parent); - struct v9fs_fid *fid = NULL; - struct inode *file_inode = NULL; - struct v9fs_fcall *fcall = NULL; - struct v9fs_qid qid; - int dirfidnum = -1; - long newfid = -1; - int result = 0; - unsigned int iounit = 0; - int wfidno = -1; + u32 fid; int err; + struct v9fs_fcall *fcall; - perm = unixmode2p9mode(v9ses, perm); - - dprintk(DEBUG_VFS, "dir: %p dentry: %p perm: %o mode: %o\n", dir, - file_dentry, perm, open_mode); - - if (!dirfid) - return -EBADF; - - dirfidnum = dirfid->fid; - if (dirfidnum < 0) { - dprintk(DEBUG_ERROR, "No fid for the directory #%lu\n", - dir->i_ino); - return -EBADF; - } - - if (file_dentry->d_inode) { - dprintk(DEBUG_ERROR, - "Odd. There is an inode for dir %lu, name :%s:\n", - dir->i_ino, file_dentry->d_name.name); - return -EEXIST; - } - - newfid = v9fs_get_idpool(&v9ses->fidpool); - if (newfid < 0) { + fid = v9fs_get_idpool(&v9ses->fidpool); + if (fid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); - return -ENOSPC; + err = -ENOSPC; + goto error; } - result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall); - if (result < 0) { + err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); + if (err < 0) { PRINT_FCALL_ERROR("clone error", fcall); - v9fs_put_idpool(newfid, &v9ses->fidpool); - newfid = -1; - goto CleanUpFid; + goto error; } - kfree(fcall); - fcall = NULL; - result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name, - perm, open_mode, &fcall); - if (result < 0) { + err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); + if (err < 0) { PRINT_FCALL_ERROR("create fails", fcall); - goto CleanUpFid; + goto error; } - iounit = fcall->params.rcreate.iounit; - qid = fcall->params.rcreate.qid; + if (iounit) + *iounit = fcall->params.rcreate.iounit; + + if (qid) + *qid = fcall->params.rcreate.qid; + + if (fidp) + *fidp = fid; + kfree(fcall); - fcall = NULL; - - if (!(perm&V9FS_DMDIR)) { - fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1); - dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate); - if (!fid) { - result = -ENOMEM; - goto CleanUpFid; - } - - fid->qid = qid; - fid->iounit = iounit; - } else { - err = v9fs_t_clunk(v9ses, newfid); - newfid = -1; - if (err < 0) - dprintk(DEBUG_ERROR, "clunk for mkdir failed: %d\n", err); - } - - /* walk to the newly created file and put the fid in the dentry */ - wfidno = v9fs_get_idpool(&v9ses->fidpool); - if (wfidno < 0) { - eprintk(KERN_WARNING, "no free fids available\n"); - return -ENOSPC; - } - - result = v9fs_t_walk(v9ses, dirfidnum, wfidno, - (char *) file_dentry->d_name.name, &fcall); - if (result < 0) { - PRINT_FCALL_ERROR("clone error", fcall); - v9fs_put_idpool(wfidno, &v9ses->fidpool); - wfidno = -1; - goto CleanUpFid; - } - kfree(fcall); - fcall = NULL; - - if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) { - v9fs_put_idpool(wfidno, &v9ses->fidpool); - - goto CleanUpFid; - } - - if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) || - (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) || - (perm & V9FS_DMDEVICE)) - return 0; - - result = v9fs_t_stat(v9ses, wfidno, &fcall); - if (result < 0) { - PRINT_FCALL_ERROR("stat error", fcall); - goto CleanUpFid; - } - - - file_inode = v9fs_get_inode(sb, - p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode)); - - if ((!file_inode) || IS_ERR(file_inode)) { - dprintk(DEBUG_ERROR, "create inode failed\n"); - result = -EBADF; - goto CleanUpFid; - } - - v9fs_stat2inode(&fcall->params.rstat.stat, file_inode, sb); - kfree(fcall); - fcall = NULL; - file_dentry->d_op = &v9fs_dentry_operations; - d_instantiate(file_dentry, file_inode); - return 0; - CleanUpFid: +error: + if (fid >= 0) + v9fs_put_idpool(fid, &v9ses->fidpool); + + kfree(fcall); + return err; +} + +static struct v9fs_fid* +v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) +{ + int err; + u32 nfid; + struct v9fs_fid *ret; + struct v9fs_fcall *fcall; + + nfid = v9fs_get_idpool(&v9ses->fidpool); + if (nfid < 0) { + eprintk(KERN_WARNING, "no free fids available\n"); + err = -ENOSPC; + goto error; + } + + err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, + &fcall); + + if (err < 0) { + PRINT_FCALL_ERROR("walk error", fcall); + v9fs_put_idpool(nfid, &v9ses->fidpool); + goto error; + } + kfree(fcall); fcall = NULL; + ret = v9fs_fid_create(v9ses, nfid); + if (!ret) { + err = -ENOMEM; + goto clunk_fid; + } - if (newfid >= 0) { - err = v9fs_t_clunk(v9ses, newfid); - if (err < 0) - dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); + err = v9fs_fid_insert(ret, dentry); + if (err < 0) { + v9fs_fid_destroy(ret); + goto clunk_fid; } - if (wfidno >= 0) { - err = v9fs_t_clunk(v9ses, wfidno); - if (err < 0) - dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); + + return ret; + +clunk_fid: + v9fs_t_clunk(v9ses, nfid); + +error: + kfree(fcall); + return ERR_PTR(err); +} + +struct inode * +v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, + struct super_block *sb) +{ + int err, umode; + struct inode *ret; + struct v9fs_fcall *fcall; + + ret = NULL; + err = v9fs_t_stat(v9ses, fid, &fcall); + if (err) { + PRINT_FCALL_ERROR("stat error", fcall); + goto error; } - return result; + + umode = p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode); + ret = v9fs_get_inode(sb, umode); + if (IS_ERR(ret)) { + err = PTR_ERR(ret); + ret = NULL; + goto error; + } + + v9fs_stat2inode(&fcall->params.rstat.stat, ret, sb); + kfree(fcall); + return ret; + +error: + kfree(fcall); + if (ret) + iput(ret); + + return ERR_PTR(err); } /** @@ -440,20 +436,97 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) return result; } +static int +v9fs_open_created(struct inode *inode, struct file *file) +{ + return 0; +} + /** * v9fs_vfs_create - VFS hook to create files * @inode: directory inode that is being deleted * @dentry: dentry that is being deleted - * @perm: create permissions + * @mode: create permissions * @nd: path information * */ static int -v9fs_vfs_create(struct inode *inode, struct dentry *dentry, int perm, +v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { - return v9fs_create(inode, dentry, perm, O_RDWR); + int err; + u32 fid, perm, iounit; + int flags; + struct v9fs_session_info *v9ses; + struct v9fs_fid *dfid, *vfid, *ffid; + struct inode *inode; + struct v9fs_qid qid; + struct file *filp; + + inode = NULL; + vfid = NULL; + v9ses = v9fs_inode2v9ses(dir); + dfid = v9fs_fid_lookup(dentry->d_parent); + perm = unixmode2p9mode(v9ses, mode); + + if (nd && nd->flags & LOOKUP_OPEN) + flags = nd->intent.open.flags - 1; + else + flags = O_RDWR; + + err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, + perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); + + if (err) + goto error; + + vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); + if (IS_ERR(vfid)) { + err = PTR_ERR(vfid); + vfid = NULL; + goto error; + } + + inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + inode = NULL; + goto error; + } + + dentry->d_op = &v9fs_dentry_operations; + d_instantiate(dentry, inode); + + if (nd && nd->flags & LOOKUP_OPEN) { + ffid = v9fs_fid_create(v9ses, fid); + if (!ffid) + return -ENOMEM; + + filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); + if (IS_ERR(filp)) { + v9fs_fid_destroy(ffid); + return PTR_ERR(filp); + } + + ffid->rdir_pos = 0; + ffid->rdir_fcall = NULL; + ffid->fidopen = 1; + ffid->iounit = iounit; + ffid->filp = filp; + filp->private_data = ffid; + } + + return 0; + +error: + if (vfid) + v9fs_fid_destroy(vfid); + + if (inode) + iput(inode); + + return err; } /** @@ -464,9 +537,57 @@ v9fs_vfs_create(struct inode *inode, struct dentry *dentry, int perm, * */ -static int v9fs_vfs_mkdir(struct inode *inode, struct dentry *dentry, int mode) +static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { - return v9fs_create(inode, dentry, mode | S_IFDIR, O_RDONLY); + int err; + u32 fid, perm; + struct v9fs_session_info *v9ses; + struct v9fs_fid *dfid, *vfid; + struct inode *inode; + + inode = NULL; + vfid = NULL; + v9ses = v9fs_inode2v9ses(dir); + dfid = v9fs_fid_lookup(dentry->d_parent); + perm = unixmode2p9mode(v9ses, mode | S_IFDIR); + + err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, + perm, V9FS_OREAD, &fid, NULL, NULL); + + if (err) { + dprintk(DEBUG_ERROR, "create error %d\n", err); + goto error; + } + + err = v9fs_t_clunk(v9ses, fid); + if (err) { + dprintk(DEBUG_ERROR, "clunk error %d\n", err); + goto error; + } + + vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); + if (IS_ERR(vfid)) { + err = PTR_ERR(vfid); + vfid = NULL; + goto error; + } + + inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + inode = NULL; + goto error; + } + + dentry->d_op = &v9fs_dentry_operations; + d_instantiate(dentry, inode); + return 0; + +error: + if (vfid) + v9fs_fid_destroy(vfid); + + return err; } /** @@ -516,9 +637,8 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, return ERR_PTR(-ENOSPC); } - result = - v9fs_t_walk(v9ses, dirfidnum, newfid, (char *)dentry->d_name.name, - NULL); + result = v9fs_t_walk(v9ses, dirfidnum, newfid, + (char *)dentry->d_name.name, NULL); if (result < 0) { v9fs_put_idpool(newfid, &v9ses->fidpool); if (result == -ENOENT) { @@ -551,13 +671,17 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); - fid = v9fs_fid_create(dentry, v9ses, newfid, 0); + fid = v9fs_fid_create(v9ses, newfid); if (fid == NULL) { dprintk(DEBUG_ERROR, "couldn't insert\n"); result = -ENOMEM; goto FreeFcall; } + result = v9fs_fid_insert(fid, dentry); + if (result < 0) + goto FreeFcall; + fid->qid = fcall->params.rstat.stat.qid; dentry->d_op = &v9fs_dentry_operations; @@ -886,8 +1010,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) } /* copy extension buffer into buffer */ - if (fcall->params.rstat.stat.extension.len+1 < buflen) - buflen = fcall->params.rstat.stat.extension.len + 1; + if (fcall->params.rstat.stat.extension.len < buflen) + buflen = fcall->params.rstat.stat.extension.len; memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); buffer[buflen-1] = 0; @@ -951,7 +1075,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) if (!link) link = ERR_PTR(-ENOMEM); else { - len = v9fs_readlink(dentry, link, PATH_MAX); + len = v9fs_readlink(dentry, link, strlen(link)); if (len < 0) { __putname(link); @@ -983,53 +1107,75 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, int mode, const char *extension) { - int err, retval; + int err; + u32 fid, perm; struct v9fs_session_info *v9ses; + struct v9fs_fid *dfid, *vfid; + struct inode *inode; struct v9fs_fcall *fcall; - struct v9fs_fid *fid; struct v9fs_wstat wstat; - v9ses = v9fs_inode2v9ses(dir); - retval = -EPERM; fcall = NULL; + inode = NULL; + vfid = NULL; + v9ses = v9fs_inode2v9ses(dir); + dfid = v9fs_fid_lookup(dentry->d_parent); + perm = unixmode2p9mode(v9ses, mode); if (!v9ses->extended) { dprintk(DEBUG_ERROR, "not extended\n"); - goto free_mem; + return -EPERM; } - /* issue a create */ - retval = v9fs_create(dir, dentry, mode, 0); - if (retval != 0) - goto free_mem; + err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, + perm, V9FS_OREAD, &fid, NULL, NULL); - fid = v9fs_fid_get_created(dentry); - if (!fid) { - dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n"); - goto free_mem; + if (err) + goto error; + + err = v9fs_t_clunk(v9ses, fid); + if (err) + goto error; + + vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); + if (IS_ERR(vfid)) { + err = PTR_ERR(vfid); + vfid = NULL; + goto error; + } + + inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + inode = NULL; + goto error; } /* issue a Twstat */ v9fs_blank_wstat(&wstat); wstat.muid = v9ses->name; wstat.extension = (char *) extension; - retval = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall); - if (retval < 0) { - PRINT_FCALL_ERROR("wstat error", fcall); - goto free_mem; - } - - err = v9fs_t_clunk(v9ses, fid->fid); + err = v9fs_t_wstat(v9ses, vfid->fid, &wstat, &fcall); if (err < 0) { - dprintk(DEBUG_ERROR, "clunk failed: %d\n", err); - goto free_mem; + PRINT_FCALL_ERROR("wstat error", fcall); + goto error; } - d_drop(dentry); /* FID - will this also clunk? */ - -free_mem: kfree(fcall); - return retval; + dentry->d_op = &v9fs_dentry_operations; + d_instantiate(dentry, inode); + return 0; + +error: + kfree(fcall); + if (vfid) + v9fs_fid_destroy(vfid); + + if (inode) + iput(inode); + + return err; + } /** diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 2c4fa75be025..0c85872be51a 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -146,7 +146,6 @@ static struct super_block *v9fs_get_sb(struct file_system_type inode->i_gid = gid; root = d_alloc_root(inode); - if (!root) { retval = -ENOMEM; goto put_back_sb; @@ -157,24 +156,27 @@ static struct super_block *v9fs_get_sb(struct file_system_type stat_result = v9fs_t_stat(v9ses, newfid, &fcall); if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); + kfree(fcall); v9fs_t_clunk(v9ses, newfid); - v9fs_put_idpool(newfid, &v9ses->fidpool); } else { /* Setup the Root Inode */ - root_fid = v9fs_fid_create(root, v9ses, newfid, 0); + kfree(fcall); + root_fid = v9fs_fid_create(v9ses, newfid); if (root_fid == NULL) { retval = -ENOMEM; goto put_back_sb; } + retval = v9fs_fid_insert(root_fid, root); + if (retval < 0) + goto put_back_sb; + root_fid->qid = fcall->params.rstat.stat.qid; root->d_inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb); } - kfree(fcall); - if (stat_result < 0) { retval = stat_result; goto put_back_sb; From 74b8054c730785cd9db093e48f53337e521b6270 Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Thu, 2 Mar 2006 02:54:32 -0800 Subject: [PATCH 023/178] [PATCH] v9fs: fix bug in atomic create open fix Lucho's atomic create+open fix had a bug in the super block initialization causing all mounts to fail. He was freeing an fcall too early. This patch fixes that oversight. Signed-off-by: Eric Van Hensbergen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/9p/vfs_super.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 0c85872be51a..cdf787ee08de 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -160,7 +160,6 @@ static struct super_block *v9fs_get_sb(struct file_system_type v9fs_t_clunk(v9ses, newfid); } else { /* Setup the Root Inode */ - kfree(fcall); root_fid = v9fs_fid_create(v9ses, newfid); if (root_fid == NULL) { retval = -ENOMEM; @@ -168,8 +167,10 @@ static struct super_block *v9fs_get_sb(struct file_system_type } retval = v9fs_fid_insert(root_fid, root); - if (retval < 0) + if (retval < 0) { + kfree(fcall); goto put_back_sb; + } root_fid->qid = fcall->params.rstat.stat.qid; root->d_inode->i_ino = @@ -177,6 +178,8 @@ static struct super_block *v9fs_get_sb(struct file_system_type v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb); } + kfree(fcall); + if (stat_result < 0) { retval = stat_result; goto put_back_sb; From 46f6dac259717551916405ee3388de89fb152bca Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Thu, 2 Mar 2006 02:54:33 -0800 Subject: [PATCH 024/178] [PATCH] v9fs: simplify fid mapping v9fs has been plagued by an over-complicated approach trying to map Linux dentry semantics to Plan 9 fid semantics. Our previous approach called for aggressive flushing of the dcache resulting in several problems (including wierd cwd behavior when running /bin/pwd). This patch dramatically simplifies our handling of this fid management. Fids will not be clunked as promptly, but the new approach is more functionally correct. We now clunk un-open fids only when their dentry ref_count reaches 0 (and d_delete is called). Another simplification is we no longer seek to match fids to the process-id or uid of the action initiator. The uid-matching will need to be revisited when we fix the security model. Signed-off-by: Eric Van Hensbergen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/9p/fid.c | 94 +++------------------------------------------- fs/9p/fid.h | 1 - fs/9p/v9fs.c | 1 + fs/9p/vfs_dentry.c | 45 ++++------------------ 4 files changed, 15 insertions(+), 126 deletions(-) diff --git a/fs/9p/fid.c b/fs/9p/fid.c index c27f546dd25b..c4d13bf904d2 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -1,7 +1,7 @@ /* * V9FS FID Management * - * Copyright (C) 2005 by Eric Van Hensbergen + * Copyright (C) 2005, 2006 by Eric Van Hensbergen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,7 +57,6 @@ int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) } fid->uid = current->uid; - fid->pid = current->pid; list_add(&fid->list, fid_list); return 0; } @@ -88,7 +87,7 @@ struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) new->rdir_fcall = NULL; INIT_LIST_HEAD(&new->list); - return new; + return new; } /** @@ -103,76 +102,14 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) kfree(fid); } -/** - * v9fs_fid_walk_up - walks from the process current directory - * up to the specified dentry. - */ -static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry) -{ - int fidnum, cfidnum, err; - struct v9fs_fid *cfid, *fid; - struct dentry *cde; - struct v9fs_session_info *v9ses; - - v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode); - cfid = v9fs_fid_lookup(current->fs->pwd); - if (cfid == NULL) { - dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n"); - return ERR_PTR(-ENOENT); - } - - cfidnum = cfid->fid; - cde = current->fs->pwd; - /* TODO: take advantage of multiwalk */ - - fidnum = v9fs_get_idpool(&v9ses->fidpool); - if (fidnum < 0) { - dprintk(DEBUG_ERROR, "could not get a new fid num\n"); - err = -ENOENT; - goto clunk_fid; - } - - while (cde != dentry) { - if (cde == cde->d_parent) { - dprintk(DEBUG_ERROR, "can't find dentry\n"); - err = -ENOENT; - goto clunk_fid; - } - - err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL); - if (err < 0) { - dprintk(DEBUG_ERROR, "problem walking to parent\n"); - goto clunk_fid; - } - - cfidnum = fidnum; - cde = cde->d_parent; - } - - fid = v9fs_fid_create(v9ses, fidnum); - if (fid) { - err = v9fs_fid_insert(fid, dentry); - if (err < 0) { - kfree(fid); - goto clunk_fid; - } - } - - return fid; - -clunk_fid: - v9fs_t_clunk(v9ses, fidnum); - return ERR_PTR(err); -} - /** * v9fs_fid_lookup - retrieve the right fid from a particular dentry * @dentry: dentry to look for fid in * @type: intent of lookup (operation or traversal) * - * search list of fids associated with a dentry for a fid with a matching - * thread id or uid. If that fails, look up the dentry's parents to see if you - * can find a matching fid. + * find a fid in the dentry + * + * TODO: only match fids that have the same uid as current user * */ @@ -187,26 +124,7 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) return_fid = list_entry(fid_list->next, struct v9fs_fid, list); if (!return_fid) { - struct dentry *par = current->fs->pwd->d_parent; - int count = 1; - while (par != NULL) { - if (par == dentry) - break; - count++; - if (par == par->d_parent) { - dprintk(DEBUG_ERROR, - "got to root without finding dentry\n"); - break; - } - par = par->d_parent; - } - -/* XXX - there may be some duplication we can get rid of */ - if (par == dentry) { - return_fid = v9fs_fid_walk_up(dentry); - if (IS_ERR(return_fid)) - return_fid = NULL; - } + dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); } return return_fid; diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 7ccf0d064e25..1fc2dd08d75a 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -44,7 +44,6 @@ struct v9fs_fid { struct v9fs_fcall *rdir_fcall; /* management stuff */ - pid_t pid; /* thread associated with this fid */ uid_t uid; /* user associated with this fid */ /* private data */ diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index ef3386549140..61352491ba36 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -397,6 +397,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses, } if (v9ses->afid != ~0) { + dprintk(DEBUG_ERROR, "afid not equal to ~0\n"); if (v9fs_t_clunk(v9ses, v9ses->afid)) dprintk(DEBUG_ERROR, "clunk failed\n"); } diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 2dd806dac9f1..12c9cc926b71 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c @@ -43,47 +43,18 @@ #include "fid.h" /** - * v9fs_dentry_validate - VFS dcache hook to validate cache - * @dentry: dentry that is being validated - * @nd: path data + * v9fs_dentry_delete - called when dentry refcount equals 0 + * @dentry: dentry in question * - * dcache really shouldn't be used for 9P2000 as at all due to - * potential attached semantics to directory traversal (walk). - * - * FUTURE: look into how to use dcache to allow multi-stage - * walks in Plan 9 & potential for better dcache operation which - * would remain valid for Plan 9 semantics. Older versions - * had validation via stat for those interested. However, since - * stat has the same approximate overhead as walk there really - * is no difference. The only improvement would be from a - * time-decay cache like NFS has and that undermines the - * synchronous nature of 9P2000. + * By returning 1 here we should remove cacheing of unused + * dentry components. * */ -static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd) +int v9fs_dentry_delete(struct dentry *dentry) { - struct dentry *dc = current->fs->pwd; - - dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry); - if (v9fs_fid_lookup(dentry)) { - dprintk(DEBUG_VFS, "VALID\n"); - return 1; - } - - while (dc != NULL) { - if (dc == dentry) { - dprintk(DEBUG_VFS, "VALID\n"); - return 1; - } - if (dc == dc->d_parent) - break; - - dc = dc->d_parent; - } - - dprintk(DEBUG_VFS, "INVALID\n"); - return 0; + dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); + return 1; } /** @@ -118,6 +89,6 @@ void v9fs_dentry_release(struct dentry *dentry) } struct dentry_operations v9fs_dentry_operations = { - .d_revalidate = v9fs_dentry_validate, + .d_delete = v9fs_dentry_delete, .d_release = v9fs_dentry_release, }; From 7f99f06f01aa9460b5a18f1b0e0900c90d0a84fc Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Thu, 2 Mar 2006 02:54:34 -0800 Subject: [PATCH 025/178] [PATCH] fix acpi_video_flags on x86-64 acpi_video_flags variable is unsigned long, so it should be set as such. This actually matters on x86-64. Signed-off-by: Stefan Seyfried Signed-off-by: Pavel Machek Cc: "Brown, Len" Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sysctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index acf6c1550f27..de2d9109194e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -667,7 +667,7 @@ static ctl_table kern_table[] = { .data = &acpi_video_flags, .maxlen = sizeof (unsigned long), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_doulongvec_minmax, }, #endif #ifdef CONFIG_IA64 From 685db65e422bfa523b8a9dacb5a658b42b254f05 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 2 Mar 2006 02:54:35 -0800 Subject: [PATCH 026/178] [PATCH] time_interpolator: Use readq_relaxed() instead of readq(). On some platforms readq performs additional work to make sure I/O is done in a coherent way. This is not needed for time retrieval as done by the time interpolator. So we can use readq_relaxed instead which will improve performance. It affects sparc64 and ia64 only. Apparently it makes a significant difference on ia64. Signed-off-by: Christoph Lameter Cc: john stultz Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/timer.c b/kernel/timer.c index fe3a9a9f8328..fc6646fd5aab 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1351,10 +1351,10 @@ static inline u64 time_interpolator_get_cycles(unsigned int src) return x(); case TIME_SOURCE_MMIO64 : - return readq((void __iomem *) time_interpolator->addr); + return readq_relaxed((void __iomem *)time_interpolator->addr); case TIME_SOURCE_MMIO32 : - return readl((void __iomem *) time_interpolator->addr); + return readl_relaxed((void __iomem *)time_interpolator->addr); default: return get_cycles(); } From a57ebfdb2cf9fa60dfa2f403f70ef6c432ca2a62 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 2 Mar 2006 02:54:37 -0800 Subject: [PATCH 027/178] [PATCH] numa_maps: Fix potential crash on non IA64 platforms numa_maps should not scan over huge vmas in order not to cause problems for non IA64 platforms that may have pte entries pointing to huge pages in a variety of ways in their page tables. Add a simple check to ignore vmas containing huge pages. Signed-off-by: Christoph Lameter Cc: Hugh Dickins Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 5643cfed6b0f..1a210088ad80 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1793,7 +1793,8 @@ int show_numa_map(struct seq_file *m, void *v) if (!md) return 0; - check_pgd_range(vma, vma->vm_start, vma->vm_end, + if (!is_vm_hugetlb_page(vma)) + check_pgd_range(vma, vma->vm_start, vma->vm_end, &node_online_map, MPOL_MF_STATS, md); if (md->pages) { From c499ec24c31edf270e777a868ffd0daddcfe7ebd Mon Sep 17 00:00:00 2001 From: "Vladimir V. Saveliev" Date: Thu, 2 Mar 2006 02:54:39 -0800 Subject: [PATCH 028/178] [PATCH] reiserfs: do not check if unsigned < 0 This patch fixes bugs in reiserfs where unsigned integers were checked whether they are less then 0. Signed-off-by: Vladimir V. Saveliev Cc: Neil Brown Signed-off-by: Hans Reiser Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/file.c | 14 +++++++------- fs/reiserfs/inode.c | 8 ++------ fs/reiserfs/journal.c | 3 +-- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index f3473176c83a..be12879bb179 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -1464,13 +1464,11 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t partially overwritten pages, if needed. And lock the pages, so that nobody else can access these until we are done. We get number of actual blocks needed as a result. */ - blocks_to_allocate = - reiserfs_prepare_file_region_for_write(inode, pos, - num_pages, - write_bytes, - prepared_pages); - if (blocks_to_allocate < 0) { - res = blocks_to_allocate; + res = reiserfs_prepare_file_region_for_write(inode, pos, + num_pages, + write_bytes, + prepared_pages); + if (res < 0) { reiserfs_release_claimed_blocks(inode->i_sb, num_pages << (PAGE_CACHE_SHIFT - @@ -1478,6 +1476,8 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t break; } + blocks_to_allocate = res; + /* First we correct our estimate of how many blocks we need */ reiserfs_release_claimed_blocks(inode->i_sb, (num_pages << diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index b33d67bba2fd..d60f6238c66a 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -627,11 +627,6 @@ int reiserfs_get_block(struct inode *inode, sector_t block, reiserfs_write_lock(inode->i_sb); version = get_inode_item_key_version(inode); - if (block < 0) { - reiserfs_write_unlock(inode->i_sb); - return -EIO; - } - if (!file_capable(inode, block)) { reiserfs_write_unlock(inode->i_sb); return -EFBIG; @@ -934,12 +929,13 @@ int reiserfs_get_block(struct inode *inode, sector_t block, //pos_in_item * inode->i_sb->s_blocksize, TYPE_INDIRECT, 3); // key type is unimportant + RFALSE(cpu_key_k_offset(&tmp_key) > cpu_key_k_offset(&key), + "green-805: invalid offset"); blocks_needed = 1 + ((cpu_key_k_offset(&key) - cpu_key_k_offset(&tmp_key)) >> inode->i_sb-> s_blocksize_bits); - RFALSE(blocks_needed < 0, "green-805: invalid offset"); if (blocks_needed == 1) { un = &unf_single; diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index b7a179560ab4..5a9d2722fa0a 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2319,8 +2319,7 @@ static int journal_read(struct super_block *p_s_sb) return 1; } jh = (struct reiserfs_journal_header *)(journal->j_header_bh->b_data); - if (le32_to_cpu(jh->j_first_unflushed_offset) >= 0 && - le32_to_cpu(jh->j_first_unflushed_offset) < + if (le32_to_cpu(jh->j_first_unflushed_offset) < SB_ONDISK_JOURNAL_SIZE(p_s_sb) && le32_to_cpu(jh->j_last_flush_trans_id) > 0) { oldest_start = From 3af1efe8a301f5b1c813f5f761cb1e10d6175605 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Thu, 2 Mar 2006 13:25:26 -0500 Subject: [PATCH 029/178] [PATCH] reiserfs: fix unaligned bitmap usage The bitmaps associated with generation numbers for directory entries are declared as an array of ints. On some platforms, this causes alignment exceptions. The following patch uses the standard bitmap declaration macros to declare the bitmaps, fixing the problem. Originally from Takashi Iwai. Signed-off-by: Takashi Iwai Acked-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/namei.c | 8 ++++---- include/linux/reiserfs_fs.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c8123308e060..284f7852de8b 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -247,7 +247,7 @@ static int linear_search_in_dir_item(struct cpu_key *key, /* mark, that this generation number is used */ if (de->de_gen_number_bit_string) set_bit(GET_GENERATION_NUMBER(deh_offset(deh)), - (unsigned long *)de->de_gen_number_bit_string); + de->de_gen_number_bit_string); // calculate pointer to name and namelen de->de_entry_num = i; @@ -431,7 +431,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, struct reiserfs_de_head *deh; INITIALIZE_PATH(path); struct reiserfs_dir_entry de; - int bit_string[MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1]; + DECLARE_BITMAP(bit_string, MAX_GENERATION_NUMBER + 1); int gen_number; char small_buf[32 + DEH_SIZE]; /* 48 bytes now and we avoid kmalloc if we create file with short name */ @@ -486,7 +486,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, /* find the proper place for the new entry */ memset(bit_string, 0, sizeof(bit_string)); - de.de_gen_number_bit_string = (char *)bit_string; + de.de_gen_number_bit_string = bit_string; retval = reiserfs_find_entry(dir, name, namelen, &path, &de); if (retval != NAME_NOT_FOUND) { if (buffer != small_buf) @@ -508,7 +508,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, } gen_number = - find_first_zero_bit((unsigned long *)bit_string, + find_first_zero_bit(bit_string, MAX_GENERATION_NUMBER + 1); if (gen_number > MAX_GENERATION_NUMBER) { /* there is no free generation number */ diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 7d51149bd793..dad78cecfd20 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -1052,7 +1052,7 @@ struct reiserfs_dir_entry { int de_entrylen; int de_namelen; char *de_name; - char *de_gen_number_bit_string; + unsigned long *de_gen_number_bit_string; __u32 de_dir_id; __u32 de_objectid; From cd8a5673e9abb3fde0a1c25ee63a60fe1908c6f5 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 3 Mar 2006 17:11:40 +1100 Subject: [PATCH 030/178] powerpc: Fix might-sleep warning in program check exception handler On 32-bit, the exception prolog for the program check exception doesn't enable interrupts early on. If it is an illegal instruction exception, we read the instruction in order to emulate certain instructions, and the get_user of the instruction triggers a WARN_ON since interrupts are still disabled. This adds a local_irq_enable() to enable interrupts before reading the instruction. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/traps.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 7509aa6474f2..98660aedeeb7 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -814,6 +814,8 @@ void __kprobes program_check_exception(struct pt_regs *regs) return; } + local_irq_enable(); + /* Try to emulate it if we should. */ if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { switch (emulate_instruction(regs)) { From 76a0ee3d1633b035f4090ab591445ae7b087f129 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 3 Mar 2006 20:50:29 +1100 Subject: [PATCH 031/178] powerpc: Turn off verbose debug output in powermac platform functions This is along the lines suggested by Chris Lumens but goes further in that it leaves the DEBUG symbol undefined, making the DBG macro empty. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/pfunc_base.c | 5 +++++ arch/powerpc/platforms/powermac/pfunc_core.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c index 4ffd2a9832a0..9b7150f10414 100644 --- a/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/arch/powerpc/platforms/powermac/pfunc_base.c @@ -9,7 +9,12 @@ #include #include +#undef DEBUG +#ifdef DEBUG #define DBG(fmt...) printk(fmt) +#else +#define DBG(fmt...) +#endif static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs) { diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 356a739e52b2..4baa75b1d36f 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -20,7 +20,13 @@ #define LOG_PARSE(fmt...) #define LOG_ERROR(fmt...) printk(fmt) #define LOG_BLOB(t,b,c) + +#undef DEBUG +#ifdef DEBUG #define DBG(fmt...) printk(fmt) +#else +#define DBG(fmt...) +#endif /* Command numbers */ #define PMF_CMD_LIST 0 From 0c2aca88bdac4254a13466fb108733d243a118b6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 3 Mar 2006 21:31:25 +1100 Subject: [PATCH 032/178] powerpc32: Fix timebase synchronization on 32-bit powermacs The variable `timebase' used to transfer the current timebase value from one cpu to the other in smp_core99_give/take_timebase was only an unsigned long, i.e. 32 bits on 32-bit machines. It needs to be 64 bits. This makes it a u64, and fixes the issue reported by Kyle Moffett, that the two cpus see wildly different values for the time of day. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 0df2cdcd805c..6d64a9bf3474 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -435,7 +435,7 @@ struct smp_ops_t psurge_smp_ops = { */ static void (*pmac_tb_freeze)(int freeze); -static unsigned long timebase; +static u64 timebase; static int tb_req; static void smp_core99_give_timebase(void) From b55fafc5a800f27beedfdcf8bd1b6baa47e769a9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 3 Mar 2006 17:03:21 +1100 Subject: [PATCH 033/178] [PATCH] powerpc: Fix old g5 issues with windfarm Some of the windfarm sensor modules can initialize on old machines that don't have full windfarm support like non-dual core desktop G5s. Unfortunately, by doing so, they would trigger a bug in their matching algorithm causing them to attach to the wrong bus, thus triggering issues with the i2c core and breaking the thermal driver. This patch fixes the probing issue (so that they will work when a windfarm port is done to these machines) and also prevents for now windfarm to load at all on these machines that still use therm_pm72 to avoid wasting resources. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- drivers/macintosh/windfarm_core.c | 7 +++++ drivers/macintosh/windfarm_cpufreq_clamp.c | 8 ++++++ drivers/macintosh/windfarm_lm75_sensor.c | 32 +++++++++++++++------ drivers/macintosh/windfarm_max6690_sensor.c | 25 +++++++++++----- drivers/macintosh/windfarm_pm112.c | 2 +- 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index bb8d5efe19bf..6c0ba04bc57a 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -35,6 +35,8 @@ #include #include +#include + #include "windfarm.h" #define VERSION "0.2" @@ -465,6 +467,11 @@ static int __init windfarm_core_init(void) { DBG("wf: core loaded\n"); + /* Don't register on old machines that use therm_pm72 for now */ + if (machine_is_compatible("PowerMac7,2") || + machine_is_compatible("PowerMac7,3") || + machine_is_compatible("RackMac3,1")) + return -ENODEV; platform_device_register(&wf_platform_device); return 0; } diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c index 607dbaca69c9..81337cd16e80 100644 --- a/drivers/macintosh/windfarm_cpufreq_clamp.c +++ b/drivers/macintosh/windfarm_cpufreq_clamp.c @@ -8,6 +8,8 @@ #include #include +#include + #include "windfarm.h" #define VERSION "0.3" @@ -74,6 +76,12 @@ static int __init wf_cpufreq_clamp_init(void) { struct wf_control *clamp; + /* Don't register on old machines that use therm_pm72 for now */ + if (machine_is_compatible("PowerMac7,2") || + machine_is_compatible("PowerMac7,3") || + machine_is_compatible("RackMac3,1")) + return -ENODEV; + clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); if (clamp == NULL) return -ENOMEM; diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index 906d3ecae6e6..423bfa2432c0 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -25,7 +25,7 @@ #include "windfarm.h" -#define VERSION "0.1" +#define VERSION "0.2" #undef DEBUG @@ -113,6 +113,7 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, const char *loc) { struct wf_lm75_sensor *lm; + int rc; DBG("wf_lm75: creating %s device at address 0x%02x\n", ds1775 ? "ds1775" : "lm75", addr); @@ -139,9 +140,11 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, lm->i2c.driver = &wf_lm75_driver; strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); - if (i2c_attach_client(&lm->i2c)) { - printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", - ds1775 ? "ds1775" : "lm75", lm->i2c.name); + rc = i2c_attach_client(&lm->i2c); + if (rc) { + printk(KERN_ERR "windfarm: failed to attach %s %s to i2c," + " err %d\n", ds1775 ? "ds1775" : "lm75", + lm->i2c.name, rc); goto fail; } @@ -175,16 +178,22 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) (dev = of_get_next_child(busnode, dev)) != NULL;) { const char *loc = get_property(dev, "hwsensor-location", NULL); - u32 *reg = (u32 *)get_property(dev, "reg", NULL); - DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg); - if (loc == NULL || reg == NULL) + u8 addr; + + /* We must re-match the adapter in order to properly check + * the channel on multibus setups + */ + if (!pmac_i2c_match_adapter(dev, adapter)) + continue; + addr = pmac_i2c_get_dev_addr(dev); + if (loc == NULL || addr == 0) continue; /* real lm75 */ if (device_is_compatible(dev, "lm75")) - wf_lm75_create(adapter, *reg, 0, loc); + wf_lm75_create(adapter, addr, 0, loc); /* ds1775 (compatible, better resolution */ else if (device_is_compatible(dev, "ds1775")) - wf_lm75_create(adapter, *reg, 1, loc); + wf_lm75_create(adapter, addr, 1, loc); } return 0; } @@ -206,6 +215,11 @@ static int wf_lm75_detach(struct i2c_client *client) static int __init wf_lm75_sensor_init(void) { + /* Don't register on old machines that use therm_pm72 for now */ + if (machine_is_compatible("PowerMac7,2") || + machine_is_compatible("PowerMac7,3") || + machine_is_compatible("RackMac3,1")) + return -ENODEV; return i2c_add_driver(&wf_lm75_driver); } diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index 5b9ad6ca7cba..8e99d408fddd 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -17,7 +17,7 @@ #include "windfarm.h" -#define VERSION "0.1" +#define VERSION "0.2" /* This currently only exports the external temperature sensor, since that's all the control loops need. */ @@ -81,7 +81,7 @@ static struct wf_sensor_ops wf_max6690_ops = { static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) { struct wf_6690_sensor *max; - char *name = "u4-temp"; + char *name = "backside-temp"; max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); if (max == NULL) { @@ -118,7 +118,6 @@ static int wf_max6690_attach(struct i2c_adapter *adapter) struct device_node *busnode, *dev = NULL; struct pmac_i2c_bus *bus; const char *loc; - u32 *reg; bus = pmac_i2c_adapter_to_bus(adapter); if (bus == NULL) @@ -126,16 +125,23 @@ static int wf_max6690_attach(struct i2c_adapter *adapter) busnode = pmac_i2c_get_bus_node(bus); while ((dev = of_get_next_child(busnode, dev)) != NULL) { + u8 addr; + + /* We must re-match the adapter in order to properly check + * the channel on multibus setups + */ + if (!pmac_i2c_match_adapter(dev, adapter)) + continue; if (!device_is_compatible(dev, "max6690")) continue; + addr = pmac_i2c_get_dev_addr(dev); loc = get_property(dev, "hwsensor-location", NULL); - reg = (u32 *) get_property(dev, "reg", NULL); - if (!loc || !reg) + if (loc == NULL || addr == 0) continue; - printk("found max6690, loc=%s reg=%x\n", loc, *reg); + printk("found max6690, loc=%s addr=0x%02x\n", loc, addr); if (strcmp(loc, "BACKSIDE")) continue; - wf_max6690_create(adapter, *reg); + wf_max6690_create(adapter, addr); } return 0; @@ -153,6 +159,11 @@ static int wf_max6690_detach(struct i2c_client *client) static int __init wf_max6690_sensor_init(void) { + /* Don't register on old machines that use therm_pm72 for now */ + if (machine_is_compatible("PowerMac7,2") || + machine_is_compatible("PowerMac7,3") || + machine_is_compatible("RackMac3,1")) + return -ENODEV; return i2c_add_driver(&wf_max6690_driver); } diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index c2a4e689c784..17aec8e7476f 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -613,7 +613,7 @@ static void pm112_new_sensor(struct wf_sensor *sr) } else if (!strcmp(sr->name, "slots-power")) { if (slots_power == NULL && wf_get_sensor(sr) == 0) slots_power = sr; - } else if (!strcmp(sr->name, "u4-temp")) { + } else if (!strcmp(sr->name, "backside-temp")) { if (u4_temp == NULL && wf_get_sensor(sr) == 0) u4_temp = sr; } else From e2a002b9a731083c69add71b1f5014bac7dc1770 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 3 Mar 2006 17:13:30 +1100 Subject: [PATCH 034/178] [PATCH] powerpc: Fix windfarm_pm112 not starting all control loops This adds a couple of printk's to windfarm_pm112 to display which control loops are actually starting and fixes a bug where it would not start all loops. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- drivers/macintosh/windfarm_pm112.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c index 17aec8e7476f..ef66bf2778ec 100644 --- a/drivers/macintosh/windfarm_pm112.c +++ b/drivers/macintosh/windfarm_pm112.c @@ -358,6 +358,7 @@ static void backside_fan_tick(void) return; if (!backside_tick) { /* first time; initialize things */ + printk(KERN_INFO "windfarm: Backside control loop started.\n"); backside_param.min = backside_fan->ops->get_min(backside_fan); backside_param.max = backside_fan->ops->get_max(backside_fan); wf_pid_init(&backside_pid, &backside_param); @@ -407,6 +408,7 @@ static void drive_bay_fan_tick(void) return; if (!drive_bay_tick) { /* first time; initialize things */ + printk(KERN_INFO "windfarm: Drive bay control loop started.\n"); drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan); drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan); wf_pid_init(&drive_bay_pid, &drive_bay_prm); @@ -458,6 +460,7 @@ static void slots_fan_tick(void) return; if (!slots_started) { /* first time; initialize things */ + printk(KERN_INFO "windfarm: Slots control loop started.\n"); wf_pid_init(&slots_pid, &slots_param); slots_started = 1; } @@ -504,6 +507,7 @@ static void pm112_tick(void) if (!started) { started = 1; + printk(KERN_INFO "windfarm: CPUs control loops started.\n"); for (i = 0; i < nr_cores; ++i) { if (create_cpu_loop(i) < 0) { failure_state = FAILURE_PERM; @@ -594,8 +598,6 @@ static void pm112_new_sensor(struct wf_sensor *sr) { unsigned int i; - if (have_all_sensors) - return; if (!strncmp(sr->name, "cpu-temp-", 9)) { i = sr->name[9] - '0'; if (sr->name[10] == 0 && i < NR_CORES && From aa5cb02143123289bd37c30c0ad60339f8da0bad Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 1 Mar 2006 15:07:07 +1100 Subject: [PATCH 035/178] [PATCH] powerpc: Expose SMT and L1 icache snoop userland features This patch makes userland aware of the icache snoop capability of the POWER5 (and possibly others in the future) and of SMT capabilities. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 9 ++++++--- include/asm-powerpc/cputable.h | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 10696456a4c6..e4e81374cb9a 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -53,8 +53,10 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); PPC_FEATURE_HAS_MMU) #define COMMON_USER_PPC64 (COMMON_USER | PPC_FEATURE_64) #define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4) -#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5) -#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS) +#define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5 |\ + PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP) +#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\ + PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP) #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ PPC_FEATURE_BOOKE) @@ -267,7 +269,8 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "Cell Broadband Engine", .cpu_features = CPU_FTRS_CELL, .cpu_user_features = COMMON_USER_PPC64 | - PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP, + PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP | + PPC_FEATURE_SMT, .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_be, diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h index 90d005bb4d1c..5638518968c3 100644 --- a/include/asm-powerpc/cputable.h +++ b/include/asm-powerpc/cputable.h @@ -20,6 +20,8 @@ #define PPC_FEATURE_POWER5_PLUS 0x00020000 #define PPC_FEATURE_CELL 0x00010000 #define PPC_FEATURE_BOOKE 0x00008000 +#define PPC_FEATURE_SMT 0x00004000 +#define PPC_FEATURE_ICACHE_SNOOP 0x00002000 #ifdef __KERNEL__ #ifndef __ASSEMBLY__ From 141aa59b5347a4a021e37cfbc2258df9af9392f8 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 3 Mar 2006 16:24:06 +1100 Subject: [PATCH 036/178] [PATCH] powerpc: Fix incorrect pud_ERROR() message The powerpc pud_ERROR() function misleadingly prints a message indicating a pmd error. This patch fixes it. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- include/asm-powerpc/pgtable-4k.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-powerpc/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h index e9590c06ad92..80a7832d2721 100644 --- a/include/asm-powerpc/pgtable-4k.h +++ b/include/asm-powerpc/pgtable-4k.h @@ -88,4 +88,4 @@ (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))) #define pud_ERROR(e) \ - printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pud_val(e)) + printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e)) From ab1b55e21f6977e420341727e9f4a50691057b5e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 3 Mar 2006 10:35:40 +1100 Subject: [PATCH 037/178] [PATCH] powerpc: incorrect rmo_top handling in prom_init On Thu, 2006-03-02 at 19:55 +0100, Olaf Hering wrote: > My iBook1 has 2 memory regions in reg. Depending on how I boot it > (vmlinux+initrd) or zImage.initrd, it will not boot with current Linus > tree. > rmo_top should be 160MB instead of 32MB. On logically-partitioned machines the first element of the reg property in the memory node is defined to be the "RMO" region, i.e. the memory that the processor can access in real mode. On other machines the first element has no special meaning, so only take it to be the RMO region on LPAR machines. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d34fe537400e..813c2cd194c2 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -978,7 +978,7 @@ static void __init prom_init_mem(void) if (size == 0) continue; prom_debug(" %x %x\n", base, size); - if (base == 0) + if (base == 0 && (RELOC(of_platform) & PLATFORM_LPAR)) RELOC(rmo_top) = size; if ((base + size) > RELOC(ram_top)) RELOC(ram_top) = base + size; From 2d748ba1669070a12bab11b19d20fd8daf537ef5 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 27 Feb 2006 00:07:46 -0300 Subject: [PATCH 038/178] V4L/DVB (3336): Bt8xx documentation authors fix - use one Author per line, which allows us to add more authors later without creating a mess. - Add Michael Krufky due to -git commit 2cbeddc976645262dbe036d6ec0825f96af70da3 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/dvb/bt8xx.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt index df6c05453cb5..52ed462061df 100644 --- a/Documentation/dvb/bt8xx.txt +++ b/Documentation/dvb/bt8xx.txt @@ -111,4 +111,8 @@ source: linux/Documentation/video4linux/CARDLIST.bttv If you have problems with this please do ask on the mailing list. -- -Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham +Authors: Richard Walker, + Jamie Honan, + Michael Hunold, + Manu Abraham, + Michael Krufky From 805e660ca32ef63b81203a556f29fef262b95cc0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 27 Feb 2006 00:07:49 -0300 Subject: [PATCH 039/178] V4L/DVB (3337): Drivers/media/dvb/frontends/mt312.c: cleanups This patch contains the following possible cleanups: - update the Kconfig help to mention the VP310 - merge vp310_attach and mt312_attach into a new vp310_mt312_attach to remove some code duplication Signed-off-by: Adrian Bunk Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 2 +- drivers/media/dvb/frontends/Kconfig | 2 +- drivers/media/dvb/frontends/mt312.c | 116 ++++++++-------------- drivers/media/dvb/frontends/mt312.h | 6 +- 4 files changed, 48 insertions(+), 78 deletions(-) diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 390cc3a99ce6..9c7f122826e0 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -526,7 +526,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); } else /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ - if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { + if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { ops = fc->fe->ops; ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 76b6a2aef32f..c676b1e23ab0 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -29,7 +29,7 @@ config DVB_TDA8083 A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_MT312 - tristate "Zarlink MT312 based" + tristate "Zarlink VP310/MT312 based" depends on DVB_CORE help A DVB-S tuner module. Say Y when you want to support this frontend. diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index ec4e641acc64..d3aea83cf218 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c @@ -612,76 +612,6 @@ static void mt312_release(struct dvb_frontend* fe) kfree(state); } -static struct dvb_frontend_ops vp310_mt312_ops; - -struct dvb_frontend* vp310_attach(const struct mt312_config* config, - struct i2c_adapter* i2c) -{ - struct mt312_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); - strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); - - /* check if the demod is there */ - if (mt312_readreg(state, ID, &state->id) < 0) - goto error; - if (state->id != ID_VP310) { - goto error; - } - - /* create dvb_frontend */ - state->frequency = 90; - state->frontend.ops = &state->ops; - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -struct dvb_frontend* mt312_attach(const struct mt312_config* config, - struct i2c_adapter* i2c) -{ - struct mt312_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); - strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); - - /* check if the demod is there */ - if (mt312_readreg(state, ID, &state->id) < 0) - goto error; - if (state->id != ID_MT312) { - goto error; - } - - /* create dvb_frontend */ - state->frequency = 60; - state->frontend.ops = &state->ops; - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - static struct dvb_frontend_ops vp310_mt312_ops = { .info = { @@ -720,6 +650,49 @@ static struct dvb_frontend_ops vp310_mt312_ops = { .set_voltage = mt312_set_voltage, }; +struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, + struct i2c_adapter* i2c) +{ + struct mt312_state* state = NULL; + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->config = config; + state->i2c = i2c; + memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); + + /* check if the demod is there */ + if (mt312_readreg(state, ID, &state->id) < 0) + goto error; + + switch (state->id) { + case ID_VP310: + strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); + state->frequency = 90; + break; + case ID_MT312: + strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); + state->frequency = 60; + break; + default: + printk (KERN_WARNING "Only Zarlink VP310/MT312 are supported chips.\n"); + goto error; + } + + /* create dvb_frontend */ + state->frontend.ops = &state->ops; + state->frontend.demodulator_priv = state; + return &state->frontend; + +error: + kfree(state); + return NULL; +} + module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); @@ -727,5 +700,4 @@ MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver"); MODULE_AUTHOR("Andreas Oberritter "); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(mt312_attach); -EXPORT_SYMBOL(vp310_attach); +EXPORT_SYMBOL(vp310_mt312_attach); diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index b3a53a73a117..074d844f0139 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h @@ -38,10 +38,8 @@ struct mt312_config int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; -extern struct dvb_frontend* mt312_attach(const struct mt312_config* config, - struct i2c_adapter* i2c); +struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, + struct i2c_adapter* i2c); -extern struct dvb_frontend* vp310_attach(const struct mt312_config* config, - struct i2c_adapter* i2c); #endif // MT312_H From 092734b4bb227faddf241b116af14357645d963c Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Mon, 27 Feb 2006 00:07:52 -0300 Subject: [PATCH 040/178] V4L/DVB (3340): Make a struct static Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/bt8xx/bt878.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 34c3189a1a33..356f447ee2ab 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c @@ -382,7 +382,7 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * EXPORT_SYMBOL(bt878_device_control); -struct cards card_list[] __devinitdata = { +static struct cards card_list[] __devinitdata = { { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, From f95cdf261b3164c3e7f62551313be422483806c5 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 27 Feb 2006 00:07:55 -0300 Subject: [PATCH 041/178] V4L/DVB (3341): Upstream sync - make 2 structs static Signed-off-by: Adrian Bunk Acked-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/bt8xx/dst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 3a2ff1cc24b7..0310e3dd07e6 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -602,7 +602,7 @@ static int dst_type_print(u8 type) */ -struct dst_types dst_tlist[] = { +static struct dst_types dst_tlist[] = { { .device_id = "200103A", .offset = 0, From ca659a41373afc40de6276d24d8279bcd547e0a9 Mon Sep 17 00:00:00 2001 From: Karsten Suehring Date: Mon, 27 Feb 2006 00:08:08 -0300 Subject: [PATCH 042/178] V4L/DVB (3347): Pinnacle PCTV 40i: add filtered Composite2 input This patch adds another composite input to the Pinnacle PCTV 100i definition which filters the chrominace signal from the luma input. This improves video quality for Composite signals on the S-Video connector of the card. In addition the name string of the card is changed to include PCTV 40i and 50i since these cards are identical. Signed-off-by: Karsten Suehring Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 8a352597830f..9d48fb372875 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -75,7 +75,7 @@ 74 -> LifeView FlyTV Platinum Mini2 [14c0:1212] 75 -> AVerMedia AVerTVHD MCE A180 [1461:1044] 76 -> SKNet MonsterTV Mobile [1131:4ee9] - 77 -> Pinnacle PCTV 110i (saa7133) [11bd:002e] + 77 -> Pinnacle PCTV 40i/50i/110i (saa7133) [11bd:002e] 78 -> ASUSTeK P7131 Dual [1043:4862] 79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) 80 -> ASUS Digimatrix TV [1043:0210] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 5a35d3b6550d..dcffd8cb960c 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -2392,7 +2392,7 @@ struct saa7134_board saa7134_boards[] = { }}, }, [SAA7134_BOARD_PINNACLE_PCTV_110i] = { - .name = "Pinnacle PCTV 110i (saa7133)", + .name = "Pinnacle PCTV 40i/50i/110i (saa7133)", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_TDA8290, .radio_type = UNSET, @@ -2407,6 +2407,10 @@ struct saa7134_board saa7134_boards[] = { },{ .name = name_comp1, .vmux = 1, + .amux = LINE2, + },{ + .name = name_comp2, + .vmux = 0, .amux = LINE2, },{ .name = name_svideo, From ede224159fa0a11f86e416f19729be701ae77e4f Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Mon, 27 Feb 2006 00:08:11 -0300 Subject: [PATCH 043/178] V4L/DVB (3348): Fixed saa7134 ALSA initialization with multiple cards When multiple cards were installed, only the first card would have audio initialized, because only the first position in the array parameter defaulted to "1" To make things worse, the "enable" parameter wasn't enabled, so there was no workaround. Signed-off-by: Ricardo Cerqueira Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-alsa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index a7a6ab9298a9..7df5e0826e12 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -54,10 +54,12 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; +static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; module_param_array(index, int, NULL, 0444); +module_param_array(enable, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); +MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s)."); #define dprintk(fmt, arg...) if (debug) \ printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg) From 27b547c3a956ec0c04109d150caa5feaee8d80f9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 27 Feb 2006 00:08:17 -0300 Subject: [PATCH 044/178] V4L/DVB (3352): Cxusb: fix lgdt3303 naming The following are specific to lgdt3303, and are being renamed to reflect this. - cxusb_lgdt330x_config renamed to cxusb_lgdt3303_config. - cxusb_lgdt330x_frontend_attach renamed to cxusb_lgdt3303_frontend_attach. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cxusb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index f327fac1688e..162f9795cd89 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -282,7 +282,7 @@ static struct cx22702_config cxusb_cx22702_config = { .pll_set = dvb_usb_pll_set_i2c, }; -static struct lgdt330x_config cxusb_lgdt330x_config = { +static struct lgdt330x_config cxusb_lgdt3303_config = { .demod_address = 0x0e, .demod_chip = LGDT3303, .pll_set = dvb_usb_pll_set_i2c, @@ -357,14 +357,14 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d) return -EIO; } -static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d) +static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_device *d) { if (usb_set_interface(d->udev,0,7) < 0) err("set interface failed"); cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); - if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL) + if ((d->fe = lgdt330x_attach(&cxusb_lgdt3303_config, &d->i2c_adap)) != NULL) return 0; return -EIO; @@ -506,7 +506,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { .streaming_ctrl = cxusb_streaming_ctrl, .power_ctrl = cxusb_power_ctrl, - .frontend_attach = cxusb_lgdt330x_frontend_attach, + .frontend_attach = cxusb_lgdt3303_frontend_attach, .tuner_attach = cxusb_lgh064f_tuner_attach, .i2c_algo = &cxusb_i2c_algo, From 2175771e154d9faf404b2631be39bf7bd36a035e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 27 Feb 2006 00:08:20 -0300 Subject: [PATCH 045/178] V4L/DVB (3354): Fix maximum for the saturation and contrast controls. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 4 ++-- drivers/media/video/saa7115.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 08ffd1f325fc..5588b9a5c430 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -567,7 +567,7 @@ static struct v4l2_queryctrl cx25840_qctrl[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, - .maximum = 255, + .maximum = 127, .step = 1, .default_value = 64, .flags = 0, @@ -576,7 +576,7 @@ static struct v4l2_queryctrl cx25840_qctrl[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", .minimum = 0, - .maximum = 255, + .maximum = 127, .step = 1, .default_value = 64, .flags = 0, diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 048d000941c7..ffd87ce55556 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1027,7 +1027,7 @@ static struct v4l2_queryctrl saa7115_qctrl[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, - .maximum = 255, + .maximum = 127, .step = 1, .default_value = 64, .flags = 0, @@ -1036,7 +1036,7 @@ static struct v4l2_queryctrl saa7115_qctrl[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", .minimum = 0, - .maximum = 255, + .maximum = 127, .step = 1, .default_value = 64, .flags = 0, From 14c255b2b26338fd5cafe62508ba0f0ba798951e Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Mon, 27 Feb 2006 00:09:11 -0300 Subject: [PATCH 046/178] V4L/DVB (3378): Restore power on defaults of tda9887 after tda8290 probe The probing code for tda8290 changes the state of the tda9887 GP ports. The patch assumes that if probing for tda8290 failed, this must be a tda9887 and restores its power on defaults. This should solve the module load order issue with some pinnacle cards. Signed-off-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 4 ++-- drivers/media/video/tda8290.c | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index dcffd8cb960c..cd3788000ff4 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -2187,7 +2187,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = 0x61, .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, + .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE, .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, @@ -2211,7 +2211,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = 0x61, .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, + .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE, .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 7b4fb282ac82..a796a4e1917c 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c @@ -580,9 +580,10 @@ int tda8290_init(struct i2c_client *c) int tda8290_probe(struct i2c_client *c) { - unsigned char soft_reset[] = { 0x00, 0x00 }; - unsigned char easy_mode_b[] = { 0x01, 0x02 }; - unsigned char easy_mode_g[] = { 0x01, 0x04 }; + unsigned char soft_reset[] = { 0x00, 0x00 }; + unsigned char easy_mode_b[] = { 0x01, 0x02 }; + unsigned char easy_mode_g[] = { 0x01, 0x04 }; + unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 }; unsigned char addr_dto_lsb = 0x07; unsigned char data; @@ -599,6 +600,7 @@ int tda8290_probe(struct i2c_client *c) return 0; } } + i2c_master_send(c, restore_9886, 3); return -1; } From 11dc3ffa3b53ba5bfdcc558d7bcd14d67ed0954b Mon Sep 17 00:00:00 2001 From: Johannes Stezenbach Date: Mon, 27 Feb 2006 00:09:20 -0300 Subject: [PATCH 047/178] V4L/DVB (3385): Dvb: fix __init/__exit section references in av7110 driver use __devinit/__devexit/__devexit_p() where appropriate Signed-off-by: Johannes Stezenbach Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110.c | 7 ++++--- drivers/media/dvb/ttpci/av7110_ir.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index d36369e9e88f..cdf7b2c33ad0 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -2477,7 +2477,8 @@ static int frontend_init(struct av7110 *av7110) * The same behaviour of missing VSYNC can be duplicated on budget * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. */ -static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) +static int __devinit av7110_attach(struct saa7146_dev* dev, + struct saa7146_pci_extension_data *pci_ext) { const int length = TS_WIDTH * TS_HEIGHT; struct pci_dev *pdev = dev->pci; @@ -2827,7 +2828,7 @@ err_kfree_0: goto out; } -static int av7110_detach(struct saa7146_dev* saa) +static int __devexit av7110_detach(struct saa7146_dev* saa) { struct av7110 *av7110 = saa->ext_priv; dprintk(4, "%p\n", av7110); @@ -2974,7 +2975,7 @@ static struct saa7146_extension av7110_extension = { .module = THIS_MODULE, .pci_tbl = &pci_tbl[0], .attach = av7110_attach, - .detach = av7110_detach, + .detach = __devexit_p(av7110_detach), .irq_mask = MASK_19 | MASK_03 | MASK_10, .irq_func = av7110_irq, diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index 617e4f6c0ed7..d54bbcdde2cc 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c @@ -208,7 +208,7 @@ static void ir_handler(struct av7110 *av7110, u32 ircom) } -int __init av7110_ir_init(struct av7110 *av7110) +int __devinit av7110_ir_init(struct av7110 *av7110) { static struct proc_dir_entry *e; @@ -248,7 +248,7 @@ int __init av7110_ir_init(struct av7110 *av7110) } -void __exit av7110_ir_exit(struct av7110 *av7110) +void __devexit av7110_ir_exit(struct av7110 *av7110) { int i; From 25d1f0c87dbbe92fcf91b3c6a395dcc9dde7fe94 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Feb 2006 00:07:21 -0300 Subject: [PATCH 048/178] V4L/DVB (3300a): Removing personal email from DVB maintainers Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 9c592aa0280c..c39fb20f8589 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -838,7 +838,6 @@ S: Maintained DVB SUBSYSTEM AND DRIVERS P: LinuxTV.org Project -M: mchehab@infradead.org M: v4l-dvb-maintainer@linuxtv.org L: linux-dvb@linuxtv.org (subscription required) W: http://linuxtv.org/ From 69ca1897317b1fbe73122a5a3bb7d783b2883d88 Mon Sep 17 00:00:00 2001 From: Mattias Nordstrom Date: Mon, 27 Feb 2006 00:09:17 -0300 Subject: [PATCH 049/178] V4L/DVB (3382): Fix stv0297 for qam128 on tt c1500 (saa7146) I have a TT C1500 card (saa7146, STV0297) which had problems tuning channels at QAM128 (like the ones in the Finnish HTV / Welho network). A fix which seems to work perfectly so far is to change the delay for QAM128 to the same values as for QAM256 in stv0297_set_frontend(), Signed-off-by: Mattias Nordstrom Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/stv0297.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index 6122ba754bc5..eb15676d374f 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c @@ -393,10 +393,6 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par break; case QAM_128: - delay = 150; - sweeprate = 1000; - break; - case QAM_256: delay = 200; sweeprate = 500; From 6ba54abe627577270a9baeb1d984bf84fba8b2e7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 27 Feb 2006 15:22:49 -0300 Subject: [PATCH 050/178] V4L/DVB (3399): ELSA EX-VISION 500TV: fix incorrect PCI subsystem ID - ELSA EX-VISION 500TV was incorrectly programmed to have the same subsystem ID as ELSA EX-VISION 300TV, (1048:226b) - This changeset replaces the incorrect subsystem ID (1048:226b) with the correct one (1048:226a) for the ELSA EX-VISION 500TV. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 9d48fb372875..da4fb890165f 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -13,7 +13,7 @@ 12 -> Medion 7134 [16be:0003] 13 -> Typhoon TV+Radio 90031 14 -> ELSA EX-VISION 300TV [1048:226b] - 15 -> ELSA EX-VISION 500TV [1048:226b] + 15 -> ELSA EX-VISION 500TV [1048:226a] 16 -> ASUS TV-FM 7134 [1043:4842,1043:4830,1043:4840] 17 -> AOPEN VA1000 POWER [1131:7133] 18 -> BMK MPEX No Tuner diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index cd3788000ff4..479b01026717 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -2749,7 +2749,7 @@ struct pci_device_id saa7134_pci_tbl[] = { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7130, .subvendor = 0x1048, - .subdevice = 0x226b, + .subdevice = 0x226a, .driver_data = SAA7134_BOARD_ELSA_500TV, },{ .vendor = PCI_VENDOR_ID_PHILIPS, From be6f655d03d2e166134da2ea3c9360c4fe008744 Mon Sep 17 00:00:00 2001 From: Hartmut Hackmann Date: Fri, 3 Mar 2006 12:09:26 -0300 Subject: [PATCH 051/178] V4L/DVB (3395): Fixed Pinnacle 300i DVB-T support - fixed tda9886 port 2 setting - turned remote control receiver off via saa7134 GPIO to avoid i2c hangs - modified tda9886 client calls to direct i2c access to allow proper return to analog mode - allow mode change to V4L2_TUNER_DIGITAL_TV in tuner VIDIOC_S_FREQUENCY client call Signed-off-by: Hartmut Hackmann Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 9 +++++++-- drivers/media/video/saa7134/saa7134-dvb.c | 12 ++++++++---- drivers/media/video/tuner-core.c | 5 +++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 479b01026717..6bc63a4086c1 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -977,7 +977,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_ACTIVE, + .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE, .inputs = {{ .name = name_tv, .vmux = 3, @@ -1666,7 +1666,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_ACTIVE, + .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_INACTIVE, .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, @@ -3205,6 +3205,11 @@ int saa7134_board_init1(struct saa7134_dev *dev) /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); + case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: + /* this turns the remote control chip off to work around a bug in it */ + saa_writeb(SAA7134_GPIO_GPMODE1, 0x80); + saa_writeb(SAA7134_GPIO_GPSTATUS1, 0x80); + break; case SAA7134_BOARD_MONSTERTV_MOBILE: /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 1a536e865277..9db8e13f21c3 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -110,6 +110,7 @@ static int mt352_pinnacle_init(struct dvb_frontend* fe) mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg)); mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg)); mt352_write(fe, irq_cfg, sizeof(irq_cfg)); + return 0; } @@ -117,8 +118,10 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) { - static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE; - static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE; + u8 off[] = { 0x00, 0xf1}; + u8 on[] = { 0x00, 0x71}; + struct i2c_msg msg = {.addr=0x43, .flags=0, .buf=off, .len = sizeof(off)}; + struct saa7134_dev *dev = fe->dvb->priv; struct v4l2_frequency f; @@ -126,9 +129,10 @@ static int mt352_pinnacle_pll_set(struct dvb_frontend* fe, f.tuner = 0; f.type = V4L2_TUNER_DIGITAL_TV; f.frequency = params->frequency / 1000 * 16 / 1000; - saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on); + i2c_transfer(&dev->i2c_adap, &msg, 1); saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f); - saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off); + msg.buf = on; + i2c_transfer(&dev->i2c_adap, &msg, 1); pinnacle_antenna_pwr(dev, antenna_pwr); diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index e7ee619d62c5..b6101bf446d4 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -713,8 +713,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) struct v4l2_frequency *f = arg; switch_v4l2(); - if (V4L2_TUNER_RADIO == f->type && - V4L2_TUNER_RADIO != t->mode) { + if ((V4L2_TUNER_RADIO == f->type && V4L2_TUNER_RADIO != t->mode) + || (V4L2_TUNER_DIGITAL_TV == f->type + && V4L2_TUNER_DIGITAL_TV != t->mode)) { if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") == EINVAL) return 0; From 1285b3a0b0aa2391ac6f6939e6737203c8220f68 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 3 Mar 2006 15:47:25 -0800 Subject: [PATCH 052/178] IB/srp: Don't send task management commands after target removal Just fail abort and reset requests that come in after we've already decided to remove a target. Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srp/ib_srp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 2d2d4ac3525a..960dae5c87d1 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1155,6 +1155,12 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) spin_lock_irq(target->scsi_host->host_lock); + if (target->state == SRP_TARGET_DEAD || + target->state == SRP_TARGET_REMOVED) { + scmnd->result = DID_BAD_TARGET << 16; + goto out; + } + if (scmnd->host_scribble == (void *) -1L) goto out; From 28e02bac9c943ed85a29b41ccb9bf95641b2e263 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Mar 2006 21:05:58 -0500 Subject: [PATCH 053/178] [PATCH] Add missing ifdef for VIA RNG code Almost all the code for the VIA RNG is guarded with __i386__ #ifdefs, the only exception being the enumeration of RNG types which is used to index into the rng_vector ops array. This patch adds an ifdef around that for consistency and since the guard makes a difference when adding new RNG types on non-i386 hardware. Signed-Off-By: Mark Brown Signed-Off-By: Jeff Garzik --- drivers/char/hw_random.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c index b3bc2e37e616..29dc87e59020 100644 --- a/drivers/char/hw_random.c +++ b/drivers/char/hw_random.c @@ -131,7 +131,9 @@ enum { rng_hw_none, rng_hw_intel, rng_hw_amd, +#ifdef __i386__ rng_hw_via, +#endif rng_hw_geode, }; From a7a80d5ad3735554338199b9d976dfda5c10d3c7 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 4 Mar 2006 12:06:51 -0500 Subject: [PATCH 054/178] s2io: set_multicast_list bug The mac_addr variable doesn't get reset between (re)additions of multicast addresses. One byte of all multicast addresses (except the first) can be incorrect. Signed-off-by: Arthur Kepner Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 49b597cbc19a..b7f00d6eb6a6 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -4092,6 +4092,7 @@ static void s2io_set_multicast(struct net_device *dev) i++, mclist = mclist->next) { memcpy(sp->usr_addrs[i].addr, mclist->dmi_addr, ETH_ALEN); + mac_addr = 0; for (j = 0; j < ETH_ALEN; j++) { mac_addr |= mclist->dmi_addr[j]; mac_addr <<= 8; From c05b47704570b015134522c36142cd17bd48640a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 4 Mar 2006 15:00:45 -0800 Subject: [PATCH 055/178] ppc64: make sure to align stack pointer to 16 bytes at boot yaboot is scrogged and calls us with an invalid stack alignment, it seems. Thanks to David Woodhouse to pointing me to the problem. Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/head_64.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 11f2cd5af7dc..9b65029dd2a3 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1537,6 +1537,9 @@ _STATIC(__boot_from_prom) mr r28,r6 mr r27,r7 + /* Align the stack to 16-byte boundary for broken yaboot */ + rldicr r1,r1,0,59 + /* Make sure we are running in 64 bits mode */ bl .enable_64b_mode From b256f9df4a7da248263ed95c2517ddb714f9ca95 Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Sat, 4 Mar 2006 23:01:13 +0000 Subject: [PATCH 056/178] [MMC] au1xmmc: Fix compilation error by using platform_driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/mmc/au1xmmc.c currently doesn't compile; it needs to be converted to use platform_driver. I cannot test this change because of lack of hardware but I followed the drivers this one is based on, and the code is certainly not worse than before. drivers/mmc/au1xmmc.c: At top level: drivers/mmc/au1xmmc.c:1002: error: ‘platform_bus_type’ undeclared here (not in a function) make[2]: *** [drivers/mmc/au1xmmc.o] Error 1 Signed-off-by: Martin Michlmayr Acked-by: Jordan Crouse Signed-off-by: Russell King --- drivers/mmc/au1xmmc.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 227c39a7c1b4..15e12be6bef1 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include @@ -887,7 +887,7 @@ struct mmc_host_ops au1xmmc_ops = { .set_ios = au1xmmc_set_ios, }; -static int au1xmmc_probe(struct device *dev) +static int __devinit au1xmmc_probe(struct platform_device *pdev) { int i, ret = 0; @@ -904,7 +904,7 @@ static int au1xmmc_probe(struct device *dev) disable_irq(AU1100_SD_IRQ); for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) { - struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), dev); + struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); struct au1xmmc_host *host = 0; if (!mmc) { @@ -967,7 +967,7 @@ static int au1xmmc_probe(struct device *dev) return 0; } -static int au1xmmc_remove(struct device *dev) +static int __devexit au1xmmc_remove(struct platform_device *pdev) { int i; @@ -997,23 +997,24 @@ static int au1xmmc_remove(struct device *dev) return 0; } -static struct device_driver au1xmmc_driver = { - .name = DRIVER_NAME, - .bus = &platform_bus_type, +static struct platform_driver au1xmmc_driver = { .probe = au1xmmc_probe, .remove = au1xmmc_remove, .suspend = NULL, - .resume = NULL + .resume = NULL, + .driver = { + .name = DRIVER_NAME, + }, }; static int __init au1xmmc_init(void) { - return driver_register(&au1xmmc_driver); + return platform_driver_register(&au1xmmc_driver); } static void __exit au1xmmc_exit(void) { - driver_unregister(&au1xmmc_driver); + platform_driver_unregister(&au1xmmc_driver); } module_init(au1xmmc_init); From e142c24cf8f471c2a6cb95a4a26923d9621770ff Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Sat, 4 Mar 2006 23:01:39 +0000 Subject: [PATCH 057/178] [MMC] au1xmmc: Fix linking error because mmc_rsp_type doesn't exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/mmc/au1xmmc.c doesn't compile because commit e92251762d02a46177d4105d1744041e3f8bc465 introduced a typo and passes the wrong argument to the mmc_resp_type macro. Error because of the typo: CC drivers/mmc/au1xmmc.o drivers/mmc/au1xmmc.c: In function ‘au1xmmc_send_command’: drivers/mmc/au1xmmc.c:197: warning: implicit declaration of function ‘mmc_rsp_type’ ... LD .tmp_vmlinux1 drivers/built-in.o: In function `au1xmmc_request':au1xmmc.c:(.text+0x89504): undefined reference to `mmc_rsp_type' :au1xmmc.c:(.text+0x8968c): undefined reference to `mmc_rsp_type' make: *** [.tmp_vmlinux1] Error 1 Error because of the wrong argument: CC drivers/mmc/au1xmmc.o drivers/mmc/au1xmmc.c: In function ‘au1xmmc_send_command’: drivers/mmc/au1xmmc.c:197: error: invalid type argument of ‘->’ Signed-off-by: Martin Michlmayr Acked-by: Jordan Crouse Signed-off-by: Russell King --- drivers/mmc/au1xmmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 15e12be6bef1..4e1c61ae536c 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); - switch (mmc_rsp_type(cmd->flags)) { + switch (mmc_resp_type(cmd)) { case MMC_RSP_R1: mmccmd |= SD_CMD_RT_1; break; From 732b82886017e9ceccb27c8b69e9210d5305088a Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Sat, 4 Mar 2006 23:02:10 +0000 Subject: [PATCH 058/178] [MMC] au1xmmc: Fix a compilation warning ('status' is not used) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a trivial compilation warning: CC drivers/mmc/au1xmmc.o drivers/mmc/au1xmmc.c: In function ‘au1xmmc_dma_callback’: drivers/mmc/au1xmmc.c:743: warning: unused variable ‘status’ Signed-off-by: Martin Michlmayr Acked-by: Martin Michlmayr Signed-off-by: Russell King --- drivers/mmc/au1xmmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index 4e1c61ae536c..8d84b045bc83 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c @@ -740,7 +740,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) static void au1xmmc_dma_callback(int irq, void *dev_id, struct pt_regs *regs) { struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id; - u32 status; /* Avoid spurious interrupts */ From e77e6f3be93763ef88ccbaa9e0ebda5360d92f7c Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 5 Mar 2006 03:39:55 +0000 Subject: [PATCH 059/178] [CIFS] Always match oplock break (cache notification) to the right tcp session when multiply mounted. Fixes slow response when cifs client is mounted to shares on multiple servers and oplock break occurs (usually due to attempt to multiply open a file). When treeids on mutiple mounted shares match and we find the wrong match first, we searched for the wrong cached files to send oplock break response for which usually meant that no matching file was found and thus the server would have to timeout the notification. Oplock break timeout is about 20 seconds on some servers so this could cause significantly slower performance on file open calls in a few cases (in particular when multiple shares are mounted from multiple servers, tree ids match, and we have a cached file which is later opened multiple times). This was the most important of the bugs that was found and fixed at Connectathon (interoperability testing event) this week. Acked-by: Shaggy (shaggy@austin.ibm.com) Signed-off-by: Steve French (sfrench@us.ibm.com) --- fs/cifs/cifsproto.h | 2 +- fs/cifs/connect.c | 2 +- fs/cifs/misc.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 3c03aadaff0c..7b25463d3c14 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -52,7 +52,7 @@ extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, int * /* type of buf returned */ , const int long_op); extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); -extern int is_valid_oplock_break(struct smb_hdr *smb); +extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_size_safe_to_change(struct cifsInodeInfo *); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); extern unsigned int smbCalcSize(struct smb_hdr *ptr); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ef5ae6f93c75..2a0c1f4ca0ae 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -630,7 +630,7 @@ multi_t2_fnd: smallbuf = NULL; } wake_up_process(task_to_wake); - } else if ((is_valid_oplock_break(smb_buffer) == FALSE) + } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE) && (isMultiRsp == FALSE)) { cERROR(1, ("No task to wake, unknown frame rcvd!")); cifs_dump_mem("Received Data is: ",(char *)smb_buffer, diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 812c6bb0fe38..432ba15e2c2d 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -475,7 +475,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) return 0; } int -is_valid_oplock_break(struct smb_hdr *buf) +is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) { struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; struct list_head *tmp; @@ -535,7 +535,7 @@ is_valid_oplock_break(struct smb_hdr *buf) read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - if (tcon->tid == buf->Tid) { + if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) { cifs_stats_inc(&tcon->num_oplock_brks); list_for_each(tmp1,&tcon->openFileList){ netfile = list_entry(tmp1,struct cifsFileInfo, From 6e86b89084a60355f0e1fb876ca0cfbca62ee85c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 3 Mar 2006 17:14:51 -0800 Subject: [PATCH 060/178] [BRIDGE]: fix crash in STP Bridge would crash because of uninitailized timer if STP is used and device was inserted into a bridge before bridge was up. This got introduced when the delayed port checking was added. Fix is to not enable STP on port unless bridge is up. Bugzilla: http://bugzilla.kernel.org/show_bug.cgi?id=6140 Dup: http://bugzilla.kernel.org/show_bug.cgi?id=6156 Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 7fa3a5a9971f..8b38c839d539 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -81,26 +81,27 @@ static void port_carrier_check(void *arg) { struct net_device *dev = arg; struct net_bridge_port *p; + struct net_bridge *br; rtnl_lock(); p = dev->br_port; if (!p) goto done; + br = p->br; - if (netif_carrier_ok(p->dev)) { - u32 cost = port_cost(p->dev); + if (netif_carrier_ok(dev)) + p->path_cost = port_cost(dev); - spin_lock_bh(&p->br->lock); - if (p->state == BR_STATE_DISABLED) { - p->path_cost = cost; - br_stp_enable_port(p); + if (br->dev->flags & IFF_UP) { + spin_lock_bh(&br->lock); + if (netif_carrier_ok(dev)) { + if (p->state == BR_STATE_DISABLED) + br_stp_enable_port(p); + } else { + if (p->state != BR_STATE_DISABLED) + br_stp_disable_port(p); } - spin_unlock_bh(&p->br->lock); - } else { - spin_lock_bh(&p->br->lock); - if (p->state != BR_STATE_DISABLED) - br_stp_disable_port(p); - spin_unlock_bh(&p->br->lock); + spin_unlock_bh(&br->lock); } done: rtnl_unlock(); From d32439c0d4cec5c4101477989ee8c7ee1ebfbb0e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 3 Mar 2006 17:15:34 -0800 Subject: [PATCH 061/178] [BRIDGE]: port timer initialization Initialize the STP timers for a port when it is created, rather than when it is enabled. This will prevent future race conditions where timer gets started before port is enabled. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 3 ++- net/bridge/br_stp_if.c | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 8b38c839d539..879b54ed2b4e 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -277,8 +277,9 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, br_init_port(p); p->state = BR_STATE_DISABLED; INIT_WORK(&p->carrier_check, port_carrier_check, dev); - kobject_init(&p->kobj); + br_stp_port_timer_init(p); + kobject_init(&p->kobj); kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR); p->kobj.ktype = &brport_ktype; p->kobj.parent = &(dev->class_dev.kobj); diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 35cf3a074087..23dea1422c9a 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -39,8 +39,6 @@ void br_init_port(struct net_bridge_port *p) p->state = BR_STATE_BLOCKING; p->topology_change_ack = 0; p->config_pending = 0; - - br_stp_port_timer_init(p); } /* called under bridge lock */ From 125a12ccf3eefebff43e3dbf47225141faa5fbe8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 3 Mar 2006 17:16:15 -0800 Subject: [PATCH 062/178] [BRIDGE]: generate kobject remove event The earlier round of kobject/sysfs changes to bridge caused it not to generate a uevent on removal. Don't think any application cares (not sure about Xen) but since it generates add uevent it should generate remove as well. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 879b54ed2b4e..f36b35edd60c 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -169,6 +169,7 @@ static void del_nbp(struct net_bridge_port *p) rcu_assign_pointer(dev->br_port, NULL); + kobject_uevent(&p->kobj, KOBJ_REMOVE); kobject_del(&p->kobj); call_rcu(&p->rcu, destroy_nbp_rcu); From 0f8f325b25919619559f0f47aa46cd7dc2dbef92 Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Fri, 3 Mar 2006 17:49:58 -0800 Subject: [PATCH 063/178] [ATM]: keep atmsvc failure messages quiet Signed-off-by: Chas Williams Signed-off-by: David S. Miller --- net/atm/signaling.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/net/atm/signaling.c b/net/atm/signaling.c index 93ad59a28ef5..31d98b57e1de 100644 --- a/net/atm/signaling.c +++ b/net/atm/signaling.c @@ -39,25 +39,19 @@ static DECLARE_WAIT_QUEUE_HEAD(sigd_sleep); static void sigd_put_skb(struct sk_buff *skb) { #ifdef WAIT_FOR_DEMON - static unsigned long silence; DECLARE_WAITQUEUE(wait,current); add_wait_queue(&sigd_sleep,&wait); while (!sigd) { set_current_state(TASK_UNINTERRUPTIBLE); - if (time_after(jiffies, silence) || silence == 0) { - printk(KERN_INFO "atmsvc: waiting for signaling demon " - "...\n"); - silence = (jiffies+30*HZ)|1; - } + DPRINTK("atmsvc: waiting for signaling demon...\n"); schedule(); } current->state = TASK_RUNNING; remove_wait_queue(&sigd_sleep,&wait); #else if (!sigd) { - if (net_ratelimit()) - printk(KERN_WARNING "atmsvc: no signaling demon\n"); + DPRINTK("atmsvc: no signaling demon\n"); kfree_skb(skb); return; } From c027f5f995d8b6efc934be384085e3e8425638e4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 3 Mar 2006 17:50:37 -0800 Subject: [PATCH 064/178] [ATM]: [fore200e] fix section mismatch warnings Signed-off-by: Sam Ravnborg Signed-off-by: Chas Williams Signed-off-by: David S. Miller --- drivers/atm/fore200e.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 14f6a6201da3..05983a312d50 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -555,7 +555,7 @@ fore200e_pca_reset(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_pca_map(struct fore200e* fore200e) { DPRINTK(2, "device %s being mapped in memory\n", fore200e->name); @@ -589,7 +589,7 @@ fore200e_pca_unmap(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_pca_configure(struct fore200e* fore200e) { struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev; @@ -2125,7 +2125,7 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags) } -static int __init +static int __devinit fore200e_irq_request(struct fore200e* fore200e) { if (request_irq(fore200e->irq, fore200e_interrupt, SA_SHIRQ, fore200e->name, fore200e->atm_dev) < 0) { @@ -2148,7 +2148,7 @@ fore200e_irq_request(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_get_esi(struct fore200e* fore200e) { struct prom_data* prom = fore200e_kmalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA); @@ -2180,7 +2180,7 @@ fore200e_get_esi(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_alloc_rx_buf(struct fore200e* fore200e) { int scheme, magn, nbr, size, i; @@ -2245,7 +2245,7 @@ fore200e_alloc_rx_buf(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_bs_queue(struct fore200e* fore200e) { int scheme, magn, i; @@ -2308,7 +2308,7 @@ fore200e_init_bs_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_rx_queue(struct fore200e* fore200e) { struct host_rxq* rxq = &fore200e->host_rxq; @@ -2368,7 +2368,7 @@ fore200e_init_rx_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_tx_queue(struct fore200e* fore200e) { struct host_txq* txq = &fore200e->host_txq; @@ -2431,7 +2431,7 @@ fore200e_init_tx_queue(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init_cmd_queue(struct fore200e* fore200e) { struct host_cmdq* cmdq = &fore200e->host_cmdq; @@ -2487,7 +2487,7 @@ fore200e_param_bs_queue(struct fore200e* fore200e, } -static int __init +static int __devinit fore200e_initialize(struct fore200e* fore200e) { struct cp_queues __iomem * cpq; @@ -2539,7 +2539,7 @@ fore200e_initialize(struct fore200e* fore200e) } -static void __init +static void __devinit fore200e_monitor_putc(struct fore200e* fore200e, char c) { struct cp_monitor __iomem * monitor = fore200e->cp_monitor; @@ -2551,7 +2551,7 @@ fore200e_monitor_putc(struct fore200e* fore200e, char c) } -static int __init +static int __devinit fore200e_monitor_getc(struct fore200e* fore200e) { struct cp_monitor __iomem * monitor = fore200e->cp_monitor; @@ -2576,7 +2576,7 @@ fore200e_monitor_getc(struct fore200e* fore200e) } -static void __init +static void __devinit fore200e_monitor_puts(struct fore200e* fore200e, char* str) { while (*str) { @@ -2591,7 +2591,7 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str) } -static int __init +static int __devinit fore200e_start_fw(struct fore200e* fore200e) { int ok; @@ -2622,7 +2622,7 @@ fore200e_start_fw(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_load_fw(struct fore200e* fore200e) { u32* fw_data = (u32*) fore200e->bus->fw_data; @@ -2648,7 +2648,7 @@ fore200e_load_fw(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_register(struct fore200e* fore200e) { struct atm_dev* atm_dev; @@ -2675,7 +2675,7 @@ fore200e_register(struct fore200e* fore200e) } -static int __init +static int __devinit fore200e_init(struct fore200e* fore200e) { if (fore200e_register(fore200e) < 0) @@ -2721,7 +2721,7 @@ fore200e_init(struct fore200e* fore200e) return -EBUSY; fore200e_supply(fore200e); - + /* all done, board initialization is now complete */ fore200e->state = FORE200E_STATE_COMPLETE; return 0; From c09966608da7e8cad3468e925ac9062e44fee831 Mon Sep 17 00:00:00 2001 From: Ian McDonald Date: Fri, 3 Mar 2006 17:54:46 -0800 Subject: [PATCH 065/178] [DCCP] ccid3: Divide by zero fix In rare circumstances 0 is returned by dccp_li_hist_calc_i_mean which leads to a divide by zero in ccid3_hc_rx_packet_recv. Explicitly check for zero return now. Update copyright notice at same time. Found by Arnaldo. Signed-off-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/dccp/ccids/ccid3.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index aa68e0ab274d..35d1d347541c 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -2,7 +2,7 @@ * net/dccp/ccids/ccid3.c * * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. - * Copyright (c) 2005 Ian McDonald + * Copyright (c) 2005-6 Ian McDonald * * An implementation of the DCCP protocol * @@ -1033,9 +1033,13 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb) p_prev = hcrx->ccid3hcrx_p; /* Calculate loss event rate */ - if (!list_empty(&hcrx->ccid3hcrx_li_hist)) + if (!list_empty(&hcrx->ccid3hcrx_li_hist)) { + u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist); + /* Scaling up by 1000000 as fixed decimal */ - hcrx->ccid3hcrx_p = 1000000 / dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist); + if (i_mean != 0) + hcrx->ccid3hcrx_p = 1000000 / i_mean; + } if (hcrx->ccid3hcrx_p > p_prev) { ccid3_hc_rx_send_feedback(sk); From 4d000d5b9689734006d89fe9b7597c758b74a9fb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 4 Mar 2006 23:23:56 -0800 Subject: [PATCH 066/178] [SPARC64]: Mark __ex_table section correctly. We must use the "a" (allocate) attribute every time we emit an entry into the __ex_table section. For consistency, use "a" instead of #alloc which is some Solaris compat cruft GNU as provides on Sparc. Signed-off-by: David S. Miller --- arch/sparc64/kernel/sys32.S | 2 +- arch/sparc64/kernel/una_asm.S | 4 ++-- arch/sparc64/lib/U1copy_from_user.S | 2 +- arch/sparc64/lib/U1copy_to_user.S | 2 +- arch/sparc64/lib/U3copy_from_user.S | 2 +- arch/sparc64/lib/U3copy_to_user.S | 2 +- arch/sparc64/lib/bzero.S | 2 +- arch/sparc64/lib/copy_in_user.S | 2 +- arch/sparc64/lib/csum_copy_from_user.S | 2 +- arch/sparc64/lib/csum_copy_to_user.S | 2 +- arch/sparc64/lib/strlen_user.S | 2 +- arch/sparc64/lib/strncpy_from_user.S | 2 +- arch/sparc64/solaris/entry64.S | 2 +- include/asm-sparc64/futex.h | 2 +- include/asm-sparc64/uaccess.h | 12 ++++++------ 15 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index 60b59375aa78..c4a1cef4b1e5 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -318,7 +318,7 @@ do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) nop nop - .section __ex_table + .section __ex_table,"a" .align 4 .word 1b, __retl_efault, 2b, __retl_efault .word 3b, __retl_efault, 4b, __retl_efault diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S index 1f5b5b708ce7..be183fe41443 100644 --- a/arch/sparc64/kernel/una_asm.S +++ b/arch/sparc64/kernel/una_asm.S @@ -47,7 +47,7 @@ __do_int_store: mov 0, %o0 .size __do_int_store, .-__do_int_store - .section __ex_table + .section __ex_table,"a" .word 4b, __retl_efault .word 5b, __retl_efault .word 6b, __retl_efault @@ -129,7 +129,7 @@ do_int_load: mov 0, %o0 .size __do_int_load, .-__do_int_load - .section __ex_table + .section __ex_table,"a" .word 4b, __retl_efault .word 5b, __retl_efault .word 6b, __retl_efault diff --git a/arch/sparc64/lib/U1copy_from_user.S b/arch/sparc64/lib/U1copy_from_user.S index 93146a81e2d3..3192b0bf4fab 100644 --- a/arch/sparc64/lib/U1copy_from_user.S +++ b/arch/sparc64/lib/U1copy_from_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/U1copy_to_user.S b/arch/sparc64/lib/U1copy_to_user.S index 1fccc521e2bd..d1210ffb0b82 100644 --- a/arch/sparc64/lib/U1copy_to_user.S +++ b/arch/sparc64/lib/U1copy_to_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/U3copy_from_user.S b/arch/sparc64/lib/U3copy_from_user.S index df600b667e48..f5bfc8d9d216 100644 --- a/arch/sparc64/lib/U3copy_from_user.S +++ b/arch/sparc64/lib/U3copy_from_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/U3copy_to_user.S b/arch/sparc64/lib/U3copy_to_user.S index f337f22ed82e..2334f111bb0c 100644 --- a/arch/sparc64/lib/U3copy_to_user.S +++ b/arch/sparc64/lib/U3copy_to_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/bzero.S b/arch/sparc64/lib/bzero.S index 21a933ffb7c2..1d2abcfa4e52 100644 --- a/arch/sparc64/lib/bzero.S +++ b/arch/sparc64/lib/bzero.S @@ -92,7 +92,7 @@ __bzero_done: .align 4; \ 99: retl; \ mov %o1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/copy_in_user.S b/arch/sparc64/lib/copy_in_user.S index 816076c0bc06..650af3f21f78 100644 --- a/arch/sparc64/lib/copy_in_user.S +++ b/arch/sparc64/lib/copy_in_user.S @@ -13,7 +13,7 @@ .align 4; \ 99: retl; \ mov 1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/csum_copy_from_user.S b/arch/sparc64/lib/csum_copy_from_user.S index 817ebdae39f8..a22eddbe5dba 100644 --- a/arch/sparc64/lib/csum_copy_from_user.S +++ b/arch/sparc64/lib/csum_copy_from_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov -1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/csum_copy_to_user.S b/arch/sparc64/lib/csum_copy_to_user.S index c2f9463ea1e2..d5b12f441f02 100644 --- a/arch/sparc64/lib/csum_copy_to_user.S +++ b/arch/sparc64/lib/csum_copy_to_user.S @@ -9,7 +9,7 @@ .align 4; \ 99: retl; \ mov -1, %o0; \ - .section __ex_table; \ + .section __ex_table,"a";\ .align 4; \ .word 98b, 99b; \ .text; \ diff --git a/arch/sparc64/lib/strlen_user.S b/arch/sparc64/lib/strlen_user.S index 9ed54ba14fc6..114ed111e251 100644 --- a/arch/sparc64/lib/strlen_user.S +++ b/arch/sparc64/lib/strlen_user.S @@ -85,7 +85,7 @@ __strnlen_user: retl clr %o0 - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .word 10b, 30b diff --git a/arch/sparc64/lib/strncpy_from_user.S b/arch/sparc64/lib/strncpy_from_user.S index e1264650ca7a..b2f499f79427 100644 --- a/arch/sparc64/lib/strncpy_from_user.S +++ b/arch/sparc64/lib/strncpy_from_user.S @@ -125,7 +125,7 @@ __strncpy_from_user: add %o2, %o3, %o0 .size __strncpy_from_user, .-__strncpy_from_user - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .word 60b, __retl_efault .word 61b, __retl_efault diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S index eb314ed23cdb..f170324e8bf2 100644 --- a/arch/sparc64/solaris/entry64.S +++ b/arch/sparc64/solaris/entry64.S @@ -217,7 +217,7 @@ solaris_unimplemented: ba,pt %xcc, ret_from_solaris nop - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .word exen, exenf diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h index 0caf60147e97..34c4b43d3f98 100644 --- a/include/asm-sparc64/futex.h +++ b/include/asm-sparc64/futex.h @@ -20,7 +20,7 @@ "4: ba 3b\n" \ " mov %5, %0\n" \ " .previous\n" \ - " .section __ex_table,#alloc\n" \ + " .section __ex_table,\"a\"\n" \ " .align 4\n" \ " .word 1b, 4b\n" \ " .word 2b, 4b\n" \ diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h index 203e8eee6351..c91d1e38eac6 100644 --- a/include/asm-sparc64/uaccess.h +++ b/include/asm-sparc64/uaccess.h @@ -136,7 +136,7 @@ __asm__ __volatile__( \ "b 2b\n\t" \ " mov %3, %0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\t" \ ".previous\n\n\t" \ @@ -148,7 +148,7 @@ if (__builtin_constant_p(ret) && ret == -EFAULT) \ __asm__ __volatile__( \ "/* Put user asm ret, inline. */\n" \ "1:\t" "st"#size "a %1, [%2] %%asi\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, __ret_efault\n\n\t" \ ".previous\n\n\t" \ @@ -163,7 +163,7 @@ __asm__ __volatile__( \ "ret\n\t" \ " restore %%g0, %3, %%o0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ ".previous\n\n\t" \ @@ -206,7 +206,7 @@ __asm__ __volatile__( \ "b 2b\n\t" \ " mov %3, %0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ ".previous\n\t" \ @@ -218,7 +218,7 @@ if (__builtin_constant_p(retval) && retval == -EFAULT) \ __asm__ __volatile__( \ "/* Get user asm ret, inline. */\n" \ "1:\t" "ld"#size "a [%1] %%asi, %0\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b,__ret_efault\n\n\t" \ ".previous\n\t" \ @@ -233,7 +233,7 @@ __asm__ __volatile__( \ "ret\n\t" \ " restore %%g0, %2, %%o0\n\n\t" \ ".previous\n\t" \ - ".section __ex_table,#alloc\n\t" \ + ".section __ex_table,\"a\"\n\t" \ ".align 4\n\t" \ ".word 1b, 3b\n\n\t" \ ".previous\n\t" \ From 7a171cdcb6ce82cc5e4bd7cb8eab172a43395f87 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 5 Mar 2006 00:31:22 +0000 Subject: [PATCH 067/178] [SERIAL] Fix two bugs in parport_serial Steinar H. Gunderson reported: - For some reason, it detects the 9845 as a 9735 -- it appears this is simply related to the ordering in parport_serial_pci_tbl[]. If we move the 9845 up above the 9735, it prints out 9710:9845, but no change in behaviour. (We didn't find out why this was the case; we left it alone since it didn't affect our problem.) - The card has no parallel port (at least no physical ones), yet it reports (via its subsystem ID of 0x0014) one parallel port and four serial ports. The probe for the parallel port fails, and the driver just aborts. Thus, it doesn't find the serial ports. Fix the debugging code to use dev_dbg, but don't bother displaying the PCI ID of the detected board (that's accessible via other means.) Also, arrange for parport_register() to return 0 even if it finds no ports. Signed-off-by: Russell King --- drivers/parport/parport_serial.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 166de3507780..10845253c9e0 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -312,8 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev, { struct parport_pc_pci *card; struct parport_serial_private *priv = pci_get_drvdata (dev); - int i = id->driver_data, n; - int success = 0; + int n, success = 0; priv->par = cards[id->driver_data]; card = &priv->par; @@ -344,10 +343,8 @@ static int __devinit parport_register (struct pci_dev *dev, "hi" as an offset (see SYBA def.) */ /* TODO: test if sharing interrupts works */ - printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, " - "I/O at %#lx(%#lx)\n", - parport_serial_pci_tbl[i].vendor, - parport_serial_pci_tbl[i].device, io_lo, io_hi); + dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " + "%#lx(%#lx)\n", io_lo, io_hi); port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, dev); if (port) { @@ -359,7 +356,7 @@ static int __devinit parport_register (struct pci_dev *dev, if (card->postinit_hook) card->postinit_hook (dev, card, !success); - return success ? 0 : 1; + return 0; } static int __devinit parport_serial_pci_probe (struct pci_dev *dev, From 2d66806d740eeb410aa785bd7fba3bd24bb082c1 Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Sun, 5 Mar 2006 01:16:00 +0300 Subject: [PATCH 068/178] [PATCH] chelsio: fix kmalloc failure in t1_espi_create memset() is called before check. Signed-off-by: Eric Sesterhenn Signed-off-by: Alexey Dobriyan Signed-off-by: Jeff Garzik --- drivers/net/chelsio/espi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c index 230642571c92..e824acaf188a 100644 --- a/drivers/net/chelsio/espi.c +++ b/drivers/net/chelsio/espi.c @@ -296,9 +296,7 @@ void t1_espi_destroy(struct peespi *espi) struct peespi *t1_espi_create(adapter_t *adapter) { - struct peespi *espi = kmalloc(sizeof(*espi), GFP_KERNEL); - - memset(espi, 0, sizeof(*espi)); + struct peespi *espi = kzalloc(sizeof(*espi), GFP_KERNEL); if (espi) espi->adapter = adapter; From 264132bc62fe071d0ff378c1103bae9d33212f10 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 6 Mar 2006 12:10:07 -0800 Subject: [PATCH 069/178] Fix "check_slabp" printout size calculation We want to use the "struct slab" size, not the size of the pointer to same. As it is, we'd not print out the last entry pointers in the slab (where is ~10, depending on whether it's a 32-bit or 64-bit kernel). Gaah, that slab code was written by somebody who likes unreadable crud. Signed-off-by: Linus Torvalds --- mm/slab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/slab.c b/mm/slab.c index add05d808a4a..2b0b1519bb74 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2554,7 +2554,7 @@ static void check_slabp(struct kmem_cache *cachep, struct slab *slabp) "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n", cachep->name, cachep->num, slabp, slabp->inuse); for (i = 0; - i < sizeof(slabp) + cachep->num * sizeof(kmem_bufctl_t); + i < sizeof(*slabp) + cachep->num * sizeof(kmem_bufctl_t); i++) { if ((i % 16) == 0) printk("\n%03x:", i); From 91c0bce29e4050a59ee5fdc1192b60bbf8693a6d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 6 Mar 2006 13:25:52 -0800 Subject: [PATCH 070/178] [PATCH] USB Serial: fix use-after-free bug in usb-serial core This fixes a use-after-free bug in the usb-serial core. It is simple to trigger this (open a usb-serial port, then yank the device out before closing the port.) Thanks to Stefan Seyfried for reporting this, and to the slab debugging code which enabled it to be tracked down. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/usb/serial/usb-serial.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4dd6865d32b0..b5c96e74a903 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -242,8 +242,10 @@ static void serial_close(struct tty_struct *tty, struct file * filp) down(&port->sem); - if (port->open_count == 0) - goto out; + if (port->open_count == 0) { + up(&port->sem); + return; + } --port->open_count; if (port->open_count == 0) { @@ -260,10 +262,8 @@ static void serial_close(struct tty_struct *tty, struct file * filp) module_put(port->serial->type->driver.owner); } - kref_put(&port->serial->kref, destroy_serial); - -out: up(&port->sem); + kref_put(&port->serial->kref, destroy_serial); } static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) From 8ba7b0a14b2ec19583bedbcdbea7f1c5008fc922 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 6 Mar 2006 17:38:49 -0800 Subject: [PATCH 071/178] Add early-boot-safety check to cond_resched() Just to be safe, we should not trigger a conditional reschedule during the early boot sequence. We've historically done some questionable early on, and the safety warnings in __might_sleep() are generally turned off during that period, so there might be problems lurking. This affects CONFIG_PREEMPT_VOLUNTARY, which takes over might_sleep() to cause a voluntary conditional reschedule. Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/sched.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sched.c b/kernel/sched.c index 12d291bf3379..3454bb869fd0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4028,6 +4028,8 @@ static inline void __cond_resched(void) */ if (unlikely(preempt_count())) return; + if (unlikely(system_state != SYSTEM_RUNNING)) + return; do { add_preempt_count(PREEMPT_ACTIVE); schedule(); From f716d8303345698728d9f8ce76a82a795a5be275 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 6 Mar 2006 17:41:44 -0800 Subject: [PATCH 072/178] Allocate 96 bytes for SCSI sense data reply The SCSI layer uses SCSI_SENSE_BUFFERSIZE (96) for the sense buffer size, even though some other code uses "sizeof(struct request_sense)" (which is 64 bytes). Allocate the buffer using the bigger of the two for safety. Signed-off-by: Linus Torvalds --- drivers/scsi/sr_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 5d02ff4db6cc..b65462f76484 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -192,7 +192,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) SDev = cd->device; if (!sense) { - sense = kmalloc(sizeof(*sense), GFP_KERNEL); + sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); if (!sense) { err = -ENOMEM; goto out; From 9888e6fa7b68d9c8cc2c162a90979825ab45150a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 6 Mar 2006 17:44:43 -0800 Subject: [PATCH 073/178] slab: clarify and fix calculate_slab_order() If we triggered the 'offslab_limit' test, we would return with cachep->gfporder incremented once too many times. This clarifies the logic somewhat, and fixes that bug. Signed-off-by: Linus Torvalds --- mm/slab.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 2b0b1519bb74..f2e92dc1c9ce 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1628,36 +1628,36 @@ static inline size_t calculate_slab_order(struct kmem_cache *cachep, size_t size, size_t align, unsigned long flags) { size_t left_over = 0; + int gfporder; - for (;; cachep->gfporder++) { + for (gfporder = 0 ; gfporder <= MAX_GFP_ORDER; gfporder++) { unsigned int num; size_t remainder; - if (cachep->gfporder > MAX_GFP_ORDER) { - cachep->num = 0; - break; - } - - cache_estimate(cachep->gfporder, size, align, flags, - &remainder, &num); + cache_estimate(gfporder, size, align, flags, &remainder, &num); if (!num) continue; + /* More than offslab_limit objects will cause problems */ - if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) + if ((flags & CFLGS_OFF_SLAB) && num > offslab_limit) break; + /* Found something acceptable - save it away */ cachep->num = num; + cachep->gfporder = gfporder; left_over = remainder; /* * Large number of objects is good, but very large slabs are * currently bad for the gfp()s. */ - if (cachep->gfporder >= slab_break_gfp_order) + if (gfporder >= slab_break_gfp_order) break; - if ((left_over * 8) <= (PAGE_SIZE << cachep->gfporder)) - /* Acceptable internal fragmentation */ + /* + * Acceptable internal fragmentation? + */ + if ((left_over * 8) <= (PAGE_SIZE << gfporder)) break; } return left_over; From ff3aea0e68bfd46120ce2d08bc1f8240fa2bd36a Mon Sep 17 00:00:00 2001 From: Dave Johnson Date: Mon, 6 Mar 2006 15:42:36 -0800 Subject: [PATCH 074/178] [PATCH] cramfs mounts provide corrupted content since 2.6.15 Fix handling of cramfs images created by util-linux containing empty regular files. Images created by cramfstools 1.x were ok. Fill out inode contents in cramfs_iget5_set() instead of get_cramfs_inode() to prevent issues if cramfs_iget5_test() is called with I_LOCK|I_NEW still set. Signed-off-by: Dave Johnson Cc: Olaf Hering Cc: Chris Mason Cc: Andreas Gruenbacher Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/cramfs/inode.c | 60 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 7fe85415ae7c..8ad52f5bf255 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -36,7 +36,7 @@ static DECLARE_MUTEX(read_mutex); /* These two macros may change in future, to provide better st_ino semantics. */ -#define CRAMINO(x) ((x)->offset?(x)->offset<<2:1) +#define CRAMINO(x) (((x)->offset && (x)->size)?(x)->offset<<2:1) #define OFFSET(x) ((x)->i_ino) @@ -66,8 +66,36 @@ static int cramfs_iget5_test(struct inode *inode, void *opaque) static int cramfs_iget5_set(struct inode *inode, void *opaque) { + static struct timespec zerotime; struct cramfs_inode *cramfs_inode = opaque; + inode->i_mode = cramfs_inode->mode; + inode->i_uid = cramfs_inode->uid; + inode->i_size = cramfs_inode->size; + inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; + inode->i_blksize = PAGE_CACHE_SIZE; + inode->i_gid = cramfs_inode->gid; + /* Struct copy intentional */ + inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; inode->i_ino = CRAMINO(cramfs_inode); + /* inode->i_nlink is left 1 - arguably wrong for directories, + but it's the best we can do without reading the directory + contents. 1 yields the right result in GNU find, even + without -noleaf option. */ + if (S_ISREG(inode->i_mode)) { + inode->i_fop = &generic_ro_fops; + inode->i_data.a_ops = &cramfs_aops; + } else if (S_ISDIR(inode->i_mode)) { + inode->i_op = &cramfs_dir_inode_operations; + inode->i_fop = &cramfs_directory_operations; + } else if (S_ISLNK(inode->i_mode)) { + inode->i_op = &page_symlink_inode_operations; + inode->i_data.a_ops = &cramfs_aops; + } else { + inode->i_size = 0; + inode->i_blocks = 0; + init_special_inode(inode, inode->i_mode, + old_decode_dev(cramfs_inode->size)); + } return 0; } @@ -77,37 +105,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode), cramfs_iget5_test, cramfs_iget5_set, cramfs_inode); - static struct timespec zerotime; - if (inode && (inode->i_state & I_NEW)) { - inode->i_mode = cramfs_inode->mode; - inode->i_uid = cramfs_inode->uid; - inode->i_size = cramfs_inode->size; - inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; - inode->i_blksize = PAGE_CACHE_SIZE; - inode->i_gid = cramfs_inode->gid; - /* Struct copy intentional */ - inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; - inode->i_ino = CRAMINO(cramfs_inode); - /* inode->i_nlink is left 1 - arguably wrong for directories, - but it's the best we can do without reading the directory - contents. 1 yields the right result in GNU find, even - without -noleaf option. */ - if (S_ISREG(inode->i_mode)) { - inode->i_fop = &generic_ro_fops; - inode->i_data.a_ops = &cramfs_aops; - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &cramfs_dir_inode_operations; - inode->i_fop = &cramfs_directory_operations; - } else if (S_ISLNK(inode->i_mode)) { - inode->i_op = &page_symlink_inode_operations; - inode->i_data.a_ops = &cramfs_aops; - } else { - inode->i_size = 0; - inode->i_blocks = 0; - init_special_inode(inode, inode->i_mode, - old_decode_dev(cramfs_inode->size)); - } unlock_new_inode(inode); } return inode; From 1e4b27df55166ce3b276f55bab223fa4ae8c5525 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Mon, 6 Mar 2006 15:42:37 -0800 Subject: [PATCH 075/178] [PATCH] i4l: add new PCI IDs for HFC-S PCI Add new PCI IDs for HFC-S PCI based ISDN TA 'Primux II S0' and 'Primux II S0' from Gerdes AG Signed-off-by: Martin Bachem Signed-off-by: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/config.c | 2 ++ drivers/isdn/hisax/hfc_pci.c | 2 ++ include/linux/pci_ids.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 8159bcecd0c2..df9d65201819 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -1929,6 +1929,8 @@ static struct pci_device_id hisax_pci_tbl[] __initdata = { {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, PCI_ANY_ID, PCI_ANY_ID}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, PCI_ANY_ID, PCI_ANY_ID}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, PCI_ANY_ID, PCI_ANY_ID}, diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 4866fc32d8d9..91d25acb5ede 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -51,6 +51,8 @@ static const PCI_ENTRY id_list[] = {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"}, {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B700, "Primux II S0", "B700"}, + {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B701, "Primux II S0 NT", "B701"}, {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"}, {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"}, {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"}, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 82b83da25d77..1709b5009d2e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1752,6 +1752,8 @@ #define PCI_DEVICE_ID_CCD_B00B 0xb00b #define PCI_DEVICE_ID_CCD_B00C 0xb00c #define PCI_DEVICE_ID_CCD_B100 0xb100 +#define PCI_DEVICE_ID_CCD_B700 0xb700 +#define PCI_DEVICE_ID_CCD_B701 0xb701 #define PCI_VENDOR_ID_EXAR 0x13a8 #define PCI_DEVICE_ID_EXAR_XR17C152 0x0152 From 7cb9478f0d5b2424af974646dcbe10ce7c19b550 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Mon, 6 Mar 2006 15:42:39 -0800 Subject: [PATCH 076/178] [PATCH] i4l: fix refcounting problem with ttyIx devices If the same ttyIx device was opened by two processes the module was not released and so the usage count went never to zero again. This oneliner fixes the issue. Signed-off-by: Oskar Senft Signed-off-by: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/i4l/isdn_tty.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 393633681f49..aeaa1db74bd8 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1682,6 +1682,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp) #ifdef ISDN_DEBUG_MODEM_OPEN printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n"); #endif + module_put(info->owner); return; } info->flags |= ISDN_ASYNC_CLOSING; From b05121b29e8af45ccb424bf71dadc1d04bd23f03 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Mon, 6 Mar 2006 15:42:41 -0800 Subject: [PATCH 077/178] [PATCH] i4l: fix compatiblity issue with big endian systems This patch fix some compatiblity issues with big endian systems Signed-off-by: Martin Bachem Signed-off-by: Karsten Keil Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/hfc_usb.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index ca5b4a3b683e..262c44127419 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -1,7 +1,7 @@ /* * hfc_usb.c * - * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $ + * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ * * modular HiSax ISDN driver for Colognechip HFC-S USB chip * @@ -45,7 +45,7 @@ #include "hfc_usb.h" static const char *hfcusb_revision = - "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ "; + "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; /* Hisax debug support * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG @@ -219,7 +219,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) for (i = 0; list[i].name != NULL; i++) if (list[i].num == num) return (list[i].name); - return ""; + return ""; } @@ -235,9 +235,9 @@ ctrl_start_transfer(hfcusb_data * hfc) hfc->ctrl_urb->transfer_buffer = NULL; hfc->ctrl_urb->transfer_buffer_length = 0; hfc->ctrl_write.wIndex = - hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg; + cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg); hfc->ctrl_write.wValue = - hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val; + cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val); usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC); /* start transfer */ } @@ -1282,7 +1282,7 @@ usb_init(hfcusb_data * hfc) /* init the background machinery for control requests */ hfc->ctrl_read.bRequestType = 0xc0; hfc->ctrl_read.bRequest = 1; - hfc->ctrl_read.wLength = 1; + hfc->ctrl_read.wLength = cpu_to_le16(1); hfc->ctrl_write.bRequestType = 0x40; hfc->ctrl_write.bRequest = 0; hfc->ctrl_write.wLength = 0; @@ -1373,9 +1373,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) vend_idx = 0xffff; for (i = 0; hfcusb_idtab[i].idVendor; i++) { - if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor - && dev->descriptor.idProduct == - hfcusb_idtab[i].idProduct) { + if ((le16_to_cpu(dev->descriptor.idVendor) == hfcusb_idtab[i].idVendor) + && (le16_to_cpu(dev->descriptor.idProduct) == hfcusb_idtab[i].idProduct)) { vend_idx = i; continue; } @@ -1516,8 +1515,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_transfer_mode = USB_INT; packet_size = - ep->desc. - wMaxPacketSize; + le16_to_cpu(ep->desc.wMaxPacketSize); break; case USB_ENDPOINT_XFER_BULK: if (ep_addr & 0x80) @@ -1545,8 +1543,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_transfer_mode = USB_BULK; packet_size = - ep->desc. - wMaxPacketSize; + le16_to_cpu(ep->desc.wMaxPacketSize); break; case USB_ENDPOINT_XFER_ISOC: if (ep_addr & 0x80) @@ -1574,8 +1571,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_transfer_mode = USB_ISOC; iso_packet_size = - ep->desc. - wMaxPacketSize; + le16_to_cpu(ep->desc.wMaxPacketSize); break; default: context-> @@ -1588,10 +1584,8 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) fifonum = cidx; context->fifos[cidx].hfc = context; - context->fifos[cidx]. - usb_packet_maxlen = - ep->desc. - wMaxPacketSize; + context->fifos[cidx].usb_packet_maxlen = + le16_to_cpu(ep->desc.wMaxPacketSize); context->fifos[cidx]. intervall = ep->desc.bInterval; From f7c09bd972b7111b8c69bf57a189571edd4d4a7d Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 6 Mar 2006 15:42:42 -0800 Subject: [PATCH 078/178] [PATCH] x86: fix potential jiffies overflow in timer_resume() i386 timer_resume is updating jiffies, not jiffies_64. It looks there is a potential overflow problem. And jiffies_64 and wall_jiffies should be protected by xtime_lock. Signed-off-by: Atsushi Nemoto Cc: john stultz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index a14d594bfbeb..9d3074759856 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -412,9 +412,9 @@ static int timer_resume(struct sys_device *dev) write_seqlock_irqsave(&xtime_lock, flags); xtime.tv_sec = sec; xtime.tv_nsec = 0; - write_sequnlock_irqrestore(&xtime_lock, flags); - jiffies += sleep_length; + jiffies_64 += sleep_length; wall_jiffies += sleep_length; + write_sequnlock_irqrestore(&xtime_lock, flags); if (last_timer->resume) last_timer->resume(); cur_timer = last_timer; From 69239749e1ac4f3496906aa4267cb9f61ce52c9c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 6 Mar 2006 15:42:45 -0800 Subject: [PATCH 079/178] [PATCH] fix next_timer_interrupt() for hrtimer Also from Thomas Gleixner Function next_timer_interrupt() got broken with a recent patch 6ba1b91213e81aa92b5cf7539f7d2a94ff54947c as sys_nanosleep() was moved to hrtimer. This broke things as next_timer_interrupt() did not check hrtimer tree for next event. Function next_timer_interrupt() is needed with dyntick (CONFIG_NO_IDLE_HZ, VST) implementations, as the system can be in idle when next hrtimer event was supposed to happen. At least ARM and S390 currently use next_timer_interrupt(). Signed-off-by: Thomas Gleixner Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/kernel/time.c | 10 ++++++---- include/linux/hrtimer.h | 4 ++++ kernel/hrtimer.c | 35 +++++++++++++++++++++++++++++++++++ kernel/timer.c | 16 ++++++++++++++++ 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index d7d932c02866..d6bd435a6857 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -422,12 +422,14 @@ static int timer_dyn_tick_disable(void) void timer_dyn_reprogram(void) { struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; + unsigned long next, seq; - if (dyn_tick) { - write_seqlock(&xtime_lock); - if (dyn_tick->state & DYN_TICK_ENABLED) + if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) { + next = next_timer_interrupt(); + do { + seq = read_seqbegin(&xtime_lock); dyn_tick->reprogram(next_timer_interrupt() - jiffies); - write_sequnlock(&xtime_lock); + } while (read_seqretry(&xtime_lock, seq)); } } diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 6361544bb6ae..6401c31d6add 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -116,6 +116,10 @@ extern int hrtimer_try_to_cancel(struct hrtimer *timer); extern ktime_t hrtimer_get_remaining(const struct hrtimer *timer); extern int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp); +#ifdef CONFIG_NO_IDLE_HZ +extern ktime_t hrtimer_get_next_event(void); +#endif + static inline int hrtimer_active(const struct hrtimer *timer) { return timer->state == HRTIMER_PENDING; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 5ae51f1bc7c8..14bc9cfa6399 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -505,6 +505,41 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer) return rem; } +#ifdef CONFIG_NO_IDLE_HZ +/** + * hrtimer_get_next_event - get the time until next expiry event + * + * Returns the delta to the next expiry event or KTIME_MAX if no timer + * is pending. + */ +ktime_t hrtimer_get_next_event(void) +{ + struct hrtimer_base *base = __get_cpu_var(hrtimer_bases); + ktime_t delta, mindelta = { .tv64 = KTIME_MAX }; + unsigned long flags; + int i; + + for (i = 0; i < MAX_HRTIMER_BASES; i++, base++) { + struct hrtimer *timer; + + spin_lock_irqsave(&base->lock, flags); + if (!base->first) { + spin_unlock_irqrestore(&base->lock, flags); + continue; + } + timer = rb_entry(base->first, struct hrtimer, node); + delta.tv64 = timer->expires.tv64; + spin_unlock_irqrestore(&base->lock, flags); + delta = ktime_sub(delta, base->get_time()); + if (delta.tv64 < mindelta.tv64) + mindelta.tv64 = delta.tv64; + } + if (mindelta.tv64 < 0) + mindelta.tv64 = 0; + return mindelta; +} +#endif + /** * hrtimer_init - initialize a timer to the given clock * diff --git a/kernel/timer.c b/kernel/timer.c index fc6646fd5aab..8256f3f5ec0d 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -489,9 +489,21 @@ unsigned long next_timer_interrupt(void) struct list_head *list; struct timer_list *nte; unsigned long expires; + unsigned long hr_expires = MAX_JIFFY_OFFSET; + ktime_t hr_delta; tvec_t *varray[4]; int i, j; + hr_delta = hrtimer_get_next_event(); + if (hr_delta.tv64 != KTIME_MAX) { + struct timespec tsdelta; + tsdelta = ktime_to_timespec(hr_delta); + hr_expires = timespec_to_jiffies(&tsdelta); + if (hr_expires < 3) + return hr_expires + jiffies; + } + hr_expires += jiffies; + base = &__get_cpu_var(tvec_bases); spin_lock(&base->t_base.lock); expires = base->timer_jiffies + (LONG_MAX >> 1); @@ -542,6 +554,10 @@ found: } } spin_unlock(&base->t_base.lock); + + if (time_before(hr_expires, expires)) + return hr_expires; + return expires; } #endif From 5c8338904653365bfb92385b38915becb903d8bb Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Mon, 6 Mar 2006 15:42:46 -0800 Subject: [PATCH 080/178] [PATCH] s390: fix compile with VIRT_CPU_ACCOUNTING=n When CONFIG_VIRT_CPU_ACCOUNTING is not defined compiling fails with an undefined reference to account_vtime(). Signed-off-by: Jan Blunck Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-s390/system.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index b2e65e8bf812..6a89dbb03c1e 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -118,6 +118,8 @@ static inline void sched_cacheflush(void) extern void account_vtime(struct task_struct *); extern void account_tick_vtime(struct task_struct *); extern void account_system_vtime(struct task_struct *); +#else +#define account_vtime(x) do { /* empty */ } while (0) #endif #define finish_arch_switch(prev) do { \ From 47f3fc94cf39c08b1ed29e00e0f8ff6c9095fa12 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 6 Mar 2006 15:42:47 -0800 Subject: [PATCH 081/178] [PATCH] add missing pm_power_off's Add the missing pm_power_off's for the h8300, v850 and xtensa architectures. Signed-off-by: Adrian Bunk Cc: Yoshinori Sato Cc: Miles Bader Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/kernel/process.c | 3 +++ arch/v850/kernel/process.c | 3 +++ arch/xtensa/kernel/process.c | 3 +++ 3 files changed, 9 insertions(+) diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index ed79ae20e88d..dd344f112cfe 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -45,6 +45,9 @@ #include #include +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + asmlinkage void ret_from_fork(void); /* diff --git a/arch/v850/kernel/process.c b/arch/v850/kernel/process.c index eb909937958b..621111ddf907 100644 --- a/arch/v850/kernel/process.c +++ b/arch/v850/kernel/process.c @@ -30,6 +30,9 @@ #include #include +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + extern void ret_from_fork (void); diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index f1f596644bfc..64a649eb883f 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -64,6 +64,9 @@ EXPORT_SYMBOL(init_task); struct task_struct *current_set[NR_CPUS] = {&init_task, }; +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); + #if XCHAL_CP_NUM > 0 From 78679302fe428f4f3dc853a51ee24f306010d874 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Mon, 6 Mar 2006 15:42:49 -0800 Subject: [PATCH 082/178] [PATCH] memory-hotplug compile fix include/linux/memory_hotplug.h:53: warning: 'struct page' declared inside parameter list (akpm: I tossed in a couple more possibly-needed-sometime struct decls too) Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memory_hotplug.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 01f03bc06eff..968b1aa3732c 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -6,6 +6,10 @@ #include #include +struct page; +struct zone; +struct pglist_data; + #ifdef CONFIG_MEMORY_HOTPLUG /* * pgdat resizing functions From a615fa83959896f8eac76c235953fb164cd1a9b9 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Mon, 6 Mar 2006 15:42:50 -0800 Subject: [PATCH 083/178] [PATCH] Increase max kmalloc size for very large systems Systems with extemely large numbers of nodes or cpus need to kmalloc structures larger than is currently supported. This patch increases the maximum supported size for very large systems. This patch should have no effect on current systems. (akpm: why not just use alloc_pages() for sysfs_cpus?) Signed-off-by: Jack Steiner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kmalloc_sizes.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/kmalloc_sizes.h b/include/linux/kmalloc_sizes.h index d82d4c05c12d..bda23e00ed71 100644 --- a/include/linux/kmalloc_sizes.h +++ b/include/linux/kmalloc_sizes.h @@ -19,8 +19,10 @@ CACHE(32768) CACHE(65536) CACHE(131072) -#ifndef CONFIG_MMU +#if (NR_CPUS > 512) || (MAX_NUMNODES > 256) || !defined(CONFIG_MMU) CACHE(262144) +#endif +#ifndef CONFIG_MMU CACHE(524288) CACHE(1048576) #ifdef CONFIG_LARGE_ALLOCS From 5aee405c662ca644980c184774277fc6d0769a84 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 6 Mar 2006 15:42:51 -0800 Subject: [PATCH 084/178] [PATCH] time: add barrier after updating jiffies_64 Add a compiler barrier so that we don't read jiffies before updating jiffies_64. Signed-off-by: Atsushi Nemoto Cc: Ralf Baechle Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/timer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/timer.c b/kernel/timer.c index 8256f3f5ec0d..bf7c4193b936 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -941,6 +941,8 @@ static inline void update_times(void) void do_timer(struct pt_regs *regs) { jiffies_64++; + /* prevent loading jiffies before storing new jiffies_64 value. */ + barrier(); update_times(); softlockup_tick(regs); } From 2fbf182ed00a71c35e53329c2010df2baf8a89c6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 6 Mar 2006 15:42:51 -0800 Subject: [PATCH 085/178] [PATCH] alsa: fix error paths in snd_ctl_elem_add() Fix bugs in error paths of snd_ctl_elem_add() - NULL reference - double free (already freed in snd_ctl_add()) Signed-off-by: Takashi Iwai Cc: Jaroslav Kysela Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/core/control.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/core/control.c b/sound/core/control.c index abd62f943726..0c29679a8576 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -959,17 +959,15 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl.private_free = snd_ctl_elem_user_free; _kctl = snd_ctl_new(&kctl, access); if (_kctl == NULL) { - kfree(_kctl->private_data); + kfree(ue); return -ENOMEM; } _kctl->private_data = ue; for (idx = 0; idx < _kctl->count; idx++) _kctl->vd[idx].owner = file; err = snd_ctl_add(card, _kctl); - if (err < 0) { - snd_ctl_free_one(_kctl); + if (err < 0) return err; - } down_write(&card->controls_rwsem); card->user_ctl_count++; From 397874dfe9862b494e1fdcd2baef4ac432d224c8 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Mon, 6 Mar 2006 15:42:53 -0800 Subject: [PATCH 086/178] [PATCH] numa_maps update Change the format of numa_maps to be more compact and contain additional information that is useful for managing and troubleshooting memory on a NUMA system. Numa_maps can now also support huge pages. Fixes: 1. More compact format. Only display fields if they contain additional information. 2. Always display information for all vmas. The old numa_maps did not display vma with no mapped entries. This was a bit confusing because page migration removes ptes for file backed vmas. After page migration a part of the vmas vanished. 3. Rename maxref to maxmap. This is the maximum mapcount of all the pages in a vma and may be used as an indicator as to how many processes may be using a certain vma. 4. Include the ability to scan over huge page vmas. New items shown: dirty Number of pages in a vma that have either the dirty bit set in the page_struct or in the pte. file= The file backing the pages if any stack Stack area heap Heap area huge Huge page area. The number of pages shows is the number of huge pages not the regular sized pages. swapcache Number of pages with swap references. Must be >0 in order to be shown. active Number of active pages. Only displayed if different from the number of pages mapped. writeback Number of pages under writeback. Only displayed if >0. Sample ouput of a process using huge pages: 00000000 default 2000000000000000 default file=/lib/ld-2.3.90.so mapped=13 mapmax=30 N0=13 2000000000044000 default file=/lib/ld-2.3.90.so anon=2 dirty=2 swapcache=2 N2=2 2000000000064000 default file=/lib/librt-2.3.90.so mapped=2 active=1 N1=1 N3=1 2000000000074000 default file=/lib/librt-2.3.90.so 2000000000080000 default file=/lib/librt-2.3.90.so anon=1 swapcache=1 N2=1 2000000000084000 default 2000000000088000 default file=/lib/libc-2.3.90.so mapped=52 mapmax=32 active=48 N0=52 20000000002bc000 default file=/lib/libc-2.3.90.so 20000000002c8000 default file=/lib/libc-2.3.90.so anon=3 dirty=2 swapcache=3 active=2 N1=1 N2=2 20000000002d4000 default anon=1 swapcache=1 N1=1 20000000002d8000 default file=/lib/libpthread-2.3.90.so mapped=8 mapmax=3 active=7 N2=2 N3=6 20000000002fc000 default file=/lib/libpthread-2.3.90.so 2000000000308000 default file=/lib/libpthread-2.3.90.so anon=1 dirty=1 swapcache=1 N1=1 200000000030c000 default anon=1 dirty=1 swapcache=1 N1=1 2000000000320000 default anon=1 dirty=1 N1=1 200000000071c000 default 2000000000720000 default anon=2 dirty=2 swapcache=1 N1=1 N2=1 2000000000f1c000 default 2000000000f20000 default anon=2 dirty=2 swapcache=1 active=1 N2=1 N3=1 200000000171c000 default 2000000001720000 default anon=1 dirty=1 swapcache=1 N1=1 2000000001b20000 default 2000000001b38000 default file=/lib/libgcc_s.so.1 mapped=2 N1=2 2000000001b48000 default file=/lib/libgcc_s.so.1 2000000001b54000 default file=/lib/libgcc_s.so.1 anon=1 dirty=1 active=0 N1=1 2000000001b58000 default file=/lib/libunwind.so.7.0.0 mapped=2 active=1 N1=2 2000000001b74000 default file=/lib/libunwind.so.7.0.0 2000000001b80000 default file=/lib/libunwind.so.7.0.0 2000000001b84000 default 4000000000000000 default file=/media/huge/test9 mapped=1 N1=1 6000000000000000 default file=/media/huge/test9 anon=1 dirty=1 active=0 N1=1 6000000000004000 default heap 607fffff7fffc000 default anon=1 dirty=1 swapcache=1 N2=1 607fffffff06c000 default stack anon=1 dirty=1 active=0 N1=1 8000000060000000 default file=/mnt/huge/test0 huge dirty=3 N1=3 8000000090000000 default file=/mnt/huge/test1 huge dirty=3 N0=1 N2=2 80000000c0000000 default file=/mnt/huge/test2 huge dirty=3 N1=1 N3=2 Signed-off-by: Christoph Lameter Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 128 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 99 insertions(+), 29 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 1a210088ad80..d80fa7d8f720 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -197,7 +197,7 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes) return policy; } -static void gather_stats(struct page *, void *); +static void gather_stats(struct page *, void *, int pte_dirty); static void migrate_page_add(struct page *page, struct list_head *pagelist, unsigned long flags); @@ -239,7 +239,7 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, continue; if (flags & MPOL_MF_STATS) - gather_stats(page, private); + gather_stats(page, private, pte_dirty(*pte)); else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) migrate_page_add(page, private, flags); else @@ -1753,67 +1753,137 @@ static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol) struct numa_maps { unsigned long pages; unsigned long anon; - unsigned long mapped; + unsigned long active; + unsigned long writeback; unsigned long mapcount_max; + unsigned long dirty; + unsigned long swapcache; unsigned long node[MAX_NUMNODES]; }; -static void gather_stats(struct page *page, void *private) +static void gather_stats(struct page *page, void *private, int pte_dirty) { struct numa_maps *md = private; int count = page_mapcount(page); - if (count) - md->mapped++; - - if (count > md->mapcount_max) - md->mapcount_max = count; - md->pages++; + if (pte_dirty || PageDirty(page)) + md->dirty++; + + if (PageSwapCache(page)) + md->swapcache++; + + if (PageActive(page)) + md->active++; + + if (PageWriteback(page)) + md->writeback++; if (PageAnon(page)) md->anon++; + if (count > md->mapcount_max) + md->mapcount_max = count; + md->node[page_to_nid(page)]++; cond_resched(); } +static void check_huge_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + struct numa_maps *md) +{ + unsigned long addr; + struct page *page; + + for (addr = start; addr < end; addr += HPAGE_SIZE) { + pte_t *ptep = huge_pte_offset(vma->vm_mm, addr & HPAGE_MASK); + pte_t pte; + + if (!ptep) + continue; + + pte = *ptep; + if (pte_none(pte)) + continue; + + page = pte_page(pte); + if (!page) + continue; + + gather_stats(page, md, pte_dirty(*ptep)); + } +} + int show_numa_map(struct seq_file *m, void *v) { struct task_struct *task = m->private; struct vm_area_struct *vma = v; struct numa_maps *md; + struct file *file = vma->vm_file; + struct mm_struct *mm = vma->vm_mm; int n; char buffer[50]; - if (!vma->vm_mm) + if (!mm) return 0; md = kzalloc(sizeof(struct numa_maps), GFP_KERNEL); if (!md) return 0; - if (!is_vm_hugetlb_page(vma)) - check_pgd_range(vma, vma->vm_start, vma->vm_end, - &node_online_map, MPOL_MF_STATS, md); + mpol_to_str(buffer, sizeof(buffer), + get_vma_policy(task, vma, vma->vm_start)); - if (md->pages) { - mpol_to_str(buffer, sizeof(buffer), - get_vma_policy(task, vma, vma->vm_start)); + seq_printf(m, "%08lx %s", vma->vm_start, buffer); - seq_printf(m, "%08lx %s pages=%lu mapped=%lu maxref=%lu", - vma->vm_start, buffer, md->pages, - md->mapped, md->mapcount_max); - - if (md->anon) - seq_printf(m," anon=%lu",md->anon); - - for_each_online_node(n) - if (md->node[n]) - seq_printf(m, " N%d=%lu", n, md->node[n]); - - seq_putc(m, '\n'); + if (file) { + seq_printf(m, " file="); + seq_path(m, file->f_vfsmnt, file->f_dentry, "\n\t= "); + } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { + seq_printf(m, " heap"); + } else if (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack) { + seq_printf(m, " stack"); } + + if (is_vm_hugetlb_page(vma)) { + check_huge_range(vma, vma->vm_start, vma->vm_end, md); + seq_printf(m, " huge"); + } else { + check_pgd_range(vma, vma->vm_start, vma->vm_end, + &node_online_map, MPOL_MF_STATS, md); + } + + if (!md->pages) + goto out; + + if (md->anon) + seq_printf(m," anon=%lu",md->anon); + + if (md->dirty) + seq_printf(m," dirty=%lu",md->dirty); + + if (md->pages != md->anon && md->pages != md->dirty) + seq_printf(m, " mapped=%lu", md->pages); + + if (md->mapcount_max > 1) + seq_printf(m, " mapmax=%lu", md->mapcount_max); + + if (md->swapcache) + seq_printf(m," swapcache=%lu", md->swapcache); + + if (md->active < md->pages && !is_vm_hugetlb_page(vma)) + seq_printf(m," active=%lu", md->active); + + if (md->writeback) + seq_printf(m," writeback=%lu", md->writeback); + + for_each_online_node(n) + if (md->node[n]) + seq_printf(m, " N%d=%lu", n, md->node[n]); +out: + seq_putc(m, '\n'); kfree(md); if (m->count < m->size) From e8c3b5a6faf50b426cd8d06912a52e24837a73ad Mon Sep 17 00:00:00 2001 From: Edgar Hucek Date: Mon, 6 Mar 2006 15:42:54 -0800 Subject: [PATCH 087/178] [PATCH] EFI: Fix gdt load This patch makes the kernel bootable again on ia32 EFI systems. Signed-off-by: Edgar Hucek Cc: Matt Domsch Cc: Zachary Amsden Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/efi.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index e3e42fd62401..c9cad7ba0d2d 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -70,10 +70,13 @@ static void efi_call_phys_prelog(void) { unsigned long cr4; unsigned long temp; + struct Xgt_desc_struct *cpu_gdt_descr; spin_lock(&efi_rt_lock); local_irq_save(efi_rt_eflags); + cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); + /* * If I don't have PSE, I should just duplicate two entries in page * directory. If I have PSE, I just need to duplicate one entry in @@ -103,18 +106,17 @@ static void efi_call_phys_prelog(void) */ local_flush_tlb(); - per_cpu(cpu_gdt_descr, 0).address = - __pa(per_cpu(cpu_gdt_descr, 0).address); - load_gdt((struct Xgt_desc_struct *)__pa(&per_cpu(cpu_gdt_descr, 0))); + cpu_gdt_descr->address = __pa(cpu_gdt_descr->address); + load_gdt(cpu_gdt_descr); } static void efi_call_phys_epilog(void) { unsigned long cr4; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); - per_cpu(cpu_gdt_descr, 0).address = - (unsigned long)__va(per_cpu(cpu_gdt_descr, 0).address); - load_gdt((struct Xgt_desc_struct *)__va(&per_cpu(cpu_gdt_descr, 0))); + cpu_gdt_descr->address = __va(cpu_gdt_descr->address); + load_gdt(cpu_gdt_descr); cr4 = read_cr4(); From ecbd3a632c8198744655b769c5c2b5a1455c1fba Mon Sep 17 00:00:00 2001 From: Peter Staubach Date: Mon, 6 Mar 2006 15:42:56 -0800 Subject: [PATCH 088/178] [PATCH] ramfs needs to update directory m/ctime on symlink ramfs neglects to update the directory mtime and ctime fields when creating a new symbolic link. Ramfs was modified in 2.6.15 to update these fields when other types of entries are created. The symlink support is separate from that other support, so that change did not cover quite all of the possibilities. All of the directory content manipulation entry points now seem to be covered with respect to these time field updates. Signed-off-by: Peter Staubach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ramfs/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index cde5d48994ae..14bd2246fb6d 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -137,6 +137,7 @@ static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * inode->i_gid = dir->i_gid; d_instantiate(dentry, inode); dget(dentry); + dir->i_mtime = dir->i_ctime = CURRENT_TIME; } else iput(inode); } From 5ddfae16bddb12104fff63c36fb5901f1a3729fc Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Mon, 6 Mar 2006 15:42:57 -0800 Subject: [PATCH 089/178] [PATCH] smaps: hugepages fix smaps doesn't have a hugepage pagetable walker. Skip walking hugepage vmas. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 0eaad41f4658..35787f907f12 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -289,7 +289,7 @@ static int show_smap(struct seq_file *m, void *v) struct mem_size_stats mss; memset(&mss, 0, sizeof mss); - if (vma->vm_mm) + if (vma->vm_mm && !is_vm_hugetlb_page(vma)) smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); return show_map_internal(m, v, &mss); } From ad820c5dd47dff9397ef1e94388bc6577983f68b Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Mon, 6 Mar 2006 15:42:58 -0800 Subject: [PATCH 090/178] [PATCH] smaps: shared fix The point of the smaps "shared" is to count the number of pages that are mapped by more than one process, according to Mauricio Lin. However, smaps uses page_count for this, so it will return a false positive for every page that is mapped by just that one process, which is also in pagecache or swapcache. There are false positive situations for anonymous pages not in swapcache as well: - page reclaim, migration - get_user_pages (eg. direct-io, ptrace) Use page_mapcount instead, to count the number of mappings to the page. Use vm_normal_page so that weird things like /dev/mem aren't counted either. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/task_mmu.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 35787f907f12..91b7c15ab373 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -204,7 +204,6 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, { pte_t *pte, ptent; spinlock_t *ptl; - unsigned long pfn; struct page *page; pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); @@ -214,12 +213,12 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, continue; mss->resident += PAGE_SIZE; - pfn = pte_pfn(ptent); - if (!pfn_valid(pfn)) + + page = vm_normal_page(vma, addr, ptent); + if (!page) continue; - page = pfn_to_page(pfn); - if (page_count(page) >= 2) { + if (page_mapcount(page) >= 2) { if (pte_dirty(ptent)) mss->shared_dirty += PAGE_SIZE; else From cdd440fe9f2e83b1e268148647126440799b71fc Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 6 Mar 2006 15:42:59 -0800 Subject: [PATCH 091/178] [PATCH] windfarm license fix The Windfarm PID module lacks a licence, it should be GPL, here it is Signed-off-by: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/windfarm_pid.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c index 0842432e27ad..f10efb28cae4 100644 --- a/drivers/macintosh/windfarm_pid.c +++ b/drivers/macintosh/windfarm_pid.c @@ -143,3 +143,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) return st->target; } EXPORT_SYMBOL_GPL(wf_cpu_pid_run); + +MODULE_AUTHOR("Benjamin Herrenschmidt "); +MODULE_DESCRIPTION("PID algorithm for PowerMacs thermal control"); +MODULE_LICENSE("GPL"); From de1d9c033f32ce39bf60e25be3b8624225fa9181 Mon Sep 17 00:00:00 2001 From: Bastian Blank Date: Mon, 6 Mar 2006 15:43:00 -0800 Subject: [PATCH 092/178] [PATCH] s390: fix match in ccw modalias Fix matching of devmodel in modaliases. It breaks automatic loading of any dasd module. Cc: Heiko Carstens Cc: Martin Schwidefsky Acked-by: Cornelia Huck Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/mod/file2alias.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index be97caf664bb..c164b230ad6f 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -246,7 +246,7 @@ static int do_ccw_entry(const char *filename, id->cu_model); ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, id->dev_type); - ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, + ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, id->dev_model); return 1; } From 15730ddbf745fbda9001b8bbd71977ac66bf5f41 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 6 Mar 2006 15:43:02 -0800 Subject: [PATCH 093/178] [PATCH] s390: improve response code handling in chsc_enable_facility() Rather than checking for some known failures, check positively for the success response code 0x0001 and return -EIO for unrecognized failure response codes. Signed-off-by: Cornelia Huck Cc: Greg Smith Cc: Heiko Carstens Cc: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/s390/cio/chsc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 8cf9905d484b..f4183d660258 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -1115,6 +1115,9 @@ chsc_enable_facility(int operation_code) goto out; } switch (sda_area->response.code) { + case 0x0001: /* everything ok */ + ret = 0; + break; case 0x0003: /* invalid request block */ case 0x0007: ret = -EINVAL; @@ -1123,6 +1126,8 @@ chsc_enable_facility(int operation_code) case 0x0101: /* facility not provided */ ret = -EOPNOTSUPP; break; + default: /* something went wrong */ + ret = -EIO; } out: free_page((unsigned long)sda_area); From 72f2afb8a6858edd9335cd158eb21053a0c2c39a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 6 Mar 2006 19:28:35 -0800 Subject: [PATCH 094/178] [TG3]: Add DMA address workaround Add DMA workaround for chips that do not support full 64-bit DMA addresses. 5714, 5715, and 5780 chips only support DMA addresses less than 40 bits. On 64-bit systems with IOMMU, set the dma_mask to 40-bit so that pci_map_xxx() calls will map the DMA address below 40 bits if necessary. On 64-bit systems without IOMMU, set the dma_mask to 64-bit and check for DMA addresses exceeding the limit in tg3_start_xmit(). 5788 only supports 32-bit DMA so need to set the mask appropriately also. Thanks to Chris Elmquist at SGI for reporting and helping to debug the problem on 5714. Thanks to David Miller for explaining the HIGHMEM and DMA stuff. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 87 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 28 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e8e92c853e89..15545620ab0e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3532,9 +3532,23 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) (base + len + 8 < base)); } +/* Test for DMA addresses > 40-bit */ +static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, + int len) +{ +#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) + return (((u64) mapping + len) > DMA_40BIT_MASK); + return 0; +#else + return 0; +#endif +} + static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32); -static int tigon3_4gb_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, +/* Workaround 4GB and 40-bit hardware DMA bugs. */ +static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb, u32 last_plus_one, u32 *start, u32 base_flags, u32 mss) { @@ -3742,6 +3756,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) if (tg3_4g_overflow_test(mapping, len)) would_hit_hwbug = 1; + if (tg3_40bit_overflow_test(tp, mapping, len)) + would_hit_hwbug = 1; + if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tg3_set_txd(tp, entry, mapping, len, base_flags, (i == last)|(mss << 1)); @@ -3763,7 +3780,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) /* If the workaround fails due to memory/mapping * failure, silently drop this packet. */ - if (tigon3_4gb_hwbug_workaround(tp, skb, last_plus_one, + if (tigon3_dma_hwbug_workaround(tp, skb, last_plus_one, &start, base_flags, mss)) goto out_unlock; @@ -10608,8 +10625,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, unsigned long tg3reg_base, tg3reg_len; struct net_device *dev; struct tg3 *tp; - int i, err, pci_using_dac, pm_cap; + int i, err, pm_cap; char str[40]; + u64 dma_mask, persist_dma_mask; if (tg3_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -10646,26 +10664,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_free_res; } - /* Configure DMA attributes. */ - err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); - if (!err) { - pci_using_dac = 1; - err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - if (err < 0) { - printk(KERN_ERR PFX "Unable to obtain 64 bit DMA " - "for consistent allocations\n"); - goto err_out_free_res; - } - } else { - err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (err) { - printk(KERN_ERR PFX "No usable DMA configuration, " - "aborting.\n"); - goto err_out_free_res; - } - pci_using_dac = 0; - } - tg3reg_base = pci_resource_start(pdev, 0); tg3reg_len = pci_resource_len(pdev, 0); @@ -10679,8 +10677,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - if (pci_using_dac) - dev->features |= NETIF_F_HIGHDMA; dev->features |= NETIF_F_LLTX; #if TG3_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; @@ -10765,6 +10761,44 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, goto err_out_iounmap; } + /* 5714, 5715 and 5780 cannot support DMA addresses > 40-bit. + * On 64-bit systems with IOMMU, use 40-bit dma_mask. + * On 64-bit systems without IOMMU, use 64-bit dma_mask and + * do DMA address check in tg3_start_xmit(). + */ + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) { + persist_dma_mask = dma_mask = DMA_40BIT_MASK; +#ifdef CONFIG_HIGHMEM + dma_mask = DMA_64BIT_MASK; +#endif + } else if (tp->tg3_flags2 & TG3_FLG2_IS_5788) + persist_dma_mask = dma_mask = DMA_32BIT_MASK; + else + persist_dma_mask = dma_mask = DMA_64BIT_MASK; + + /* Configure DMA attributes. */ + if (dma_mask > DMA_32BIT_MASK) { + err = pci_set_dma_mask(pdev, dma_mask); + if (!err) { + dev->features |= NETIF_F_HIGHDMA; + err = pci_set_consistent_dma_mask(pdev, + persist_dma_mask); + if (err < 0) { + printk(KERN_ERR PFX "Unable to obtain 64 bit " + "DMA for consistent allocations\n"); + goto err_out_iounmap; + } + } + } + if (err || dma_mask == DMA_32BIT_MASK) { + err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (err) { + printk(KERN_ERR PFX "No usable DMA configuration, " + "aborting.\n"); + goto err_out_iounmap; + } + } + tg3_init_bufmgr_config(tp); #if TG3_TSO_SUPPORT != 0 @@ -10833,9 +10867,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } else tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS; - if (tp->tg3_flags2 & TG3_FLG2_IS_5788) - dev->features &= ~NETIF_F_HIGHDMA; - /* flow control autonegotiation is default behavior */ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; From 6a0e243069b09a323255f6e847c87d531961cd96 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 7 Mar 2006 14:42:27 +0000 Subject: [PATCH 095/178] [ARM] 3352/1: DSB required for the completion of a TLB maintenance operation Patch from Catalin Marinas Chapter B2.7.3 in the latest ARM ARM (with v6 information) states that the completion of a TLB maintenance operation is only guaranteed by the execution of a DSB (Data Syncronization Barrier, formerly Data Write Barrier or Drain Write Buffer). Note that a DSB is only needed in the flush_tlb_kernel_* functions since the completion is guaranteed by a mode change (i.e. switching back to user mode) for the flush_tlb_user_* functions. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/Kconfig | 2 +- arch/arm/mm/tlb-v6.S | 1 + include/asm-arm/tlbflush.h | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 15dc1a0dffbb..9f80fa502f8f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -78,7 +78,7 @@ menu "System Type" choice prompt "ARM system type" - default ARCH_RPC + default ARCH_VERSATILE config ARCH_CLPS7500 bool "Cirrus-CL-PS7500FE" diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S index 6f76b89ef46e..fd6adde39091 100644 --- a/arch/arm/mm/tlb-v6.S +++ b/arch/arm/mm/tlb-v6.S @@ -80,6 +80,7 @@ ENTRY(v6wbi_flush_kern_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b + mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier mov pc, lr .section ".text.init", #alloc, #execinstr diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h index 9387a5e1ffe0..0c2acc944a0a 100644 --- a/include/asm-arm/tlbflush.h +++ b/include/asm-arm/tlbflush.h @@ -340,6 +340,12 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr)); if (tlb_flag(TLB_V6_I_PAGE)) asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr)); + + /* The ARM ARM states that the completion of a TLB maintenance + * operation is only guaranteed by a DSB instruction + */ + if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE)) + asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero)); } /* From d19e9974084b4024abcfcfc9d8676c90d26994bb Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 7 Mar 2006 09:16:35 -0800 Subject: [PATCH 096/178] Simplify fifo_open() locking logic We don't do interruptible waits for the pipe mutex anywhere else any more either, so don't do it in fifo_open() either. Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds --- fs/fifo.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/fs/fifo.c b/fs/fifo.c index 923371b753ab..d13fcd3ec803 100644 --- a/fs/fifo.c +++ b/fs/fifo.c @@ -34,10 +34,7 @@ static int fifo_open(struct inode *inode, struct file *filp) { int ret; - ret = -ERESTARTSYS; - if (mutex_lock_interruptible(PIPE_MUTEX(*inode))) - goto err_nolock_nocleanup; - + mutex_lock(PIPE_MUTEX(*inode)); if (!inode->i_pipe) { ret = -ENOMEM; if(!pipe_new(inode)) @@ -140,8 +137,6 @@ err: err_nocleanup: mutex_unlock(PIPE_MUTEX(*inode)); - -err_nolock_nocleanup: return ret; } From c4432c41b0c74d770ebc5e0a4fc3df3d00dfc131 Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Tue, 7 Mar 2006 21:04:59 +0000 Subject: [PATCH 097/178] [SERIAL] ip22zilog: Fix oops on runlevel change with serial console Incorrect uart_write_wakeup() calls cause reference to a NULL tty pointer. This has been fixed in the sunsab and sunzilog serial drivers in October 2005. Update the ip22zilog, which is based on sunzilog, accordingly. Signed-off-by: Martin Michlmayr Signed-off-by: Russell King port.info == NULL) goto ack_tx_int; xmit = &up->port.info->xmit; - if (uart_circ_empty(xmit)) { - uart_write_wakeup(&up->port); + if (uart_circ_empty(xmit)) goto ack_tx_int; - } if (uart_tx_stopped(&up->port)) goto ack_tx_int; From 744bfe4c25716a7cfc5690aeab8d572b43d7c916 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Tue, 7 Mar 2006 22:48:29 +0000 Subject: [PATCH 098/178] [ARM] 3353/1: NAS100d: protect nas100d_power_exit() with machine_is_nas100d() Patch from Alessandro Zummo nas100d_power_exit(void) gets some protection to avoid freeing an irq when it is not appropriate to do so. Signed-off-by: Rod Whitby Signed-off-by: Alessandro Zummo Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/nas100d-power.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-ixp4xx/nas100d-power.c b/arch/arm/mach-ixp4xx/nas100d-power.c index 2bec69bfa715..99d333d7ebdd 100644 --- a/arch/arm/mach-ixp4xx/nas100d-power.c +++ b/arch/arm/mach-ixp4xx/nas100d-power.c @@ -56,6 +56,9 @@ static int __init nas100d_power_init(void) static void __exit nas100d_power_exit(void) { + if (!(machine_is_nas100d())) + return; + free_irq(NAS100D_RB_IRQ, NULL); } From 850a9a4e3c019ce67e3bc29c810ac213ec4c169e Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 7 Mar 2006 14:56:12 -0800 Subject: [PATCH 099/178] [NETFILTER] ip_queue: Fix wrong skb->len == nlmsg_len assumption The size of the skb carrying the netlink message is not equivalent to the length of the actual netlink message due to padding. ip_queue matches the length of the payload against the original packet size to determine if packet mangling is desired, due to the above wrong assumption arbitary packets may not be mangled depening on their original size. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv4/netfilter/ip_queue.c | 2 +- net/ipv6/netfilter/ip6_queue.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 36339eb39e17..08f80e2ea2aa 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -524,7 +524,7 @@ ipq_rcv_skb(struct sk_buff *skb) write_unlock_bh(&queue_lock); status = ipq_receive_peer(NLMSG_DATA(nlh), type, - skblen - NLMSG_LENGTH(0)); + nlmsglen - NLMSG_LENGTH(0)); if (status < 0) RCV_SKB_FAIL(status); diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 5027bbe6415e..af0635084df8 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -522,7 +522,7 @@ ipq_rcv_skb(struct sk_buff *skb) write_unlock_bh(&queue_lock); status = ipq_receive_peer(NLMSG_DATA(nlh), type, - skblen - NLMSG_LENGTH(0)); + nlmsglen - NLMSG_LENGTH(0)); if (status < 0) RCV_SKB_FAIL(status); From ea0e92a613a1caf85583c83cd131cef7d0f5571d Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Tue, 7 Mar 2006 15:23:25 -0800 Subject: [PATCH 100/178] [IA64] Increase severity of MCA recovery messages The MCA recovery messages are currently KERN_DEBUG, so they don't show up in /var/log/messages (by default). Increase the severity to KERN_ERR, for the initial message (and also add the physical address to this message). Leave the successful isolation message as KERN_DEBUG, but increase the severity when isolation fails to KERN_CRIT. [Russ' patch made these all KERN_CRIT] Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- arch/ia64/kernel/mca_drv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 8fd93afa75a7..53ffb0633c70 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -123,8 +123,9 @@ mca_page_isolate(unsigned long paddr) void mca_handler_bh(unsigned long paddr) { - printk(KERN_DEBUG "OS_MCA: process [pid: %d](%s) encounters MCA.\n", - current->pid, current->comm); + printk(KERN_ERR + "OS_MCA: process [pid: %d](%s) encounters MCA (paddr=%lx)\n", + current->pid, current->comm, paddr); spin_lock(&mca_bh_lock); switch (mca_page_isolate(paddr)) { @@ -132,7 +133,7 @@ mca_handler_bh(unsigned long paddr) printk(KERN_DEBUG "Page isolation: ( %lx ) success.\n", paddr); break; case ISOLATE_NG: - printk(KERN_DEBUG "Page isolation: ( %lx ) failure.\n", paddr); + printk(KERN_CRIT "Page isolation: ( %lx ) failure.\n", paddr); break; default: break; From 57ebc9918f8747c9db7e65659dfd632d4db99e3a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 2 Mar 2006 16:59:50 -0700 Subject: [PATCH 101/178] [IA64] gensparse_defconfig: turn on PNPACPI Turn on CONFIG_PNPACPI. I recently removed 8250_acpi.c. All devices previously claimed by 8250_acpi.c should now be claimed by 8250_pnp.c. This depends on having CONFIG_PNPACPI so ACPI devices show up as PNP devices. All other ia64 defconfigs either have CONFIG_PNPACPI already, or don't have 8250 support turned on at all. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/configs/gensparse_defconfig | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 184678fe7832..744fd2f79f61 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.16-rc5 -# Mon Feb 27 16:15:43 2006 +# Thu Mar 2 16:39:10 2006 # # @@ -312,7 +312,13 @@ CONFIG_FW_LOADER=m # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -357,6 +363,7 @@ CONFIG_BLK_DEV_IDESCSI=m # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -525,6 +532,7 @@ CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set # # ARCnet devices From 6c5e62159cdef89d8385958c9d8c88efa867110c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 3 Mar 2006 15:33:47 -0700 Subject: [PATCH 102/178] [IA64] don't report !sn2 or !summit hardware as an error This stuff is all in the generic ia64 kernel, and the new initcall error reporting complains about them. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/kernel/cyclone.c | 2 +- arch/ia64/sn/kernel/sn2/sn2_smp.c | 2 +- arch/ia64/sn/kernel/tiocx.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c index 6ade3790ce07..e00b21514f7c 100644 --- a/arch/ia64/kernel/cyclone.c +++ b/arch/ia64/kernel/cyclone.c @@ -36,7 +36,7 @@ int __init init_cyclone_clock(void) u32* volatile cyclone_timer; /* Cyclone MPMC0 register */ if (!use_cyclone) - return -ENODEV; + return 0; printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n"); diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 24eefb2fc55f..b2e1e746b47f 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c @@ -446,7 +446,7 @@ static struct proc_dir_entry *proc_sn2_ptc; static int __init sn2_ptc_init(void) { if (!ia64_platform_is("sn2")) - return -ENOSYS; + return 0; if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) { printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME); diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 8a56f8b5ffa2..99cb28e74295 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -484,7 +484,7 @@ static int __init tiocx_init(void) int found_tiocx_device = 0; if (!ia64_platform_is("sn2")) - return -ENODEV; + return 0; bus_register(&tiocx_bus_type); From f032f90809ebbbd28feb90f97add2e0a869a42ed Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 3 Mar 2006 15:34:34 -0700 Subject: [PATCH 103/178] [IA64] SGI SN drivers: don't report !sn2 hardware as an error This stuff is all in the generic ia64 kernel, and the new initcall error reporting complains about them. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- drivers/char/mmtimer.c | 2 +- drivers/serial/sn_console.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index c92378121b4c..1b05fa688996 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -675,7 +675,7 @@ static int __init mmtimer_init(void) cnodeid_t node, maxn = -1; if (!ia64_platform_is("sn2")) - return -1; + return 0; /* * Sanity check the cycles/sec variable diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 43e67d6c29d4..60ea4a3f0713 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c @@ -820,7 +820,7 @@ static int __init sn_sal_module_init(void) int retval; if (!ia64_platform_is("sn2")) - return -ENODEV; + return 0; printk(KERN_INFO "sn_console: Console driver init\n"); From e1c48554ae295de984eee83a7798e7fb394a1629 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Fri, 3 Mar 2006 16:42:26 -0600 Subject: [PATCH 104/178] [IA64] mca recovery return value when no bus check When there is no bus check, the return code should be failure, not success. Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- arch/ia64/kernel/mca_drv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 53ffb0633c70..e883d85906db 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -568,10 +568,15 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, return 0; /* - * If there is no bus error, record is weird but we need not to recover. + * The cache check and bus check bits have four possible states + * cc bc + * 0 0 Weird record, not recovered + * 1 0 Cache error, not recovered + * 0 1 I/O error, attempt recovery + * 1 1 Memory error, attempt recovery */ if (psp->bc == 0 || pbci == NULL) - return 1; + return 0; /* * Sorry, we cannot handle so many. From 1bd79336a426c5e4f3bab142407059ceb12cadf9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 8 Mar 2006 13:24:22 +1100 Subject: [PATCH 105/178] powerpc: Fix various syscall/signal/swapcontext bugs A careful reading of the recent changes to the system call entry/exit paths revealed several problems, plus some things that could be simplified and improved: * 32-bit wasn't testing the _TIF_NOERROR bit in the syscall fast exit path, so it was only doing anything with it once it saw some other bit being set. In other words, the noerror behaviour would apply to the next system call where we had to reschedule or deliver a signal, which is not necessarily the current system call. * 32-bit wasn't doing the call to ptrace_notify in the syscall exit path when the _TIF_SINGLESTEP bit was set. * _TIF_RESTOREALL was in both _TIF_USER_WORK_MASK and _TIF_PERSYSCALL_MASK, which is odd since _TIF_RESTOREALL is only set by system calls. I took it out of _TIF_USER_WORK_MASK. * On 64-bit, _TIF_RESTOREALL wasn't causing the non-volatile registers to be restored (unless perhaps a signal was delivered or the syscall was traced or single-stepped). Thus the non-volatile registers weren't restored on exit from a signal handler. We probably got away with it mostly because signal handlers written in C wouldn't alter the non-volatile registers. * On 32-bit I simplified the code and made it more like 64-bit by making the syscall exit path jump to ret_from_except to handle preemption and signal delivery. * 32-bit was calling do_signal unnecessarily when _TIF_RESTOREALL was set - but I think because of that 32-bit was actually restoring the non-volatile registers on exit from a signal handler. * I changed the order of enabling interrupts and saving the non-volatile registers before calling do_syscall_trace_leave; now we enable interrupts first. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/asm-offsets.c | 1 - arch/powerpc/kernel/entry_32.S | 95 ++++++++----------------------- arch/powerpc/kernel/entry_64.S | 94 +++++++----------------------- arch/powerpc/kernel/ptrace.c | 5 +- arch/powerpc/kernel/signal_32.c | 19 ++----- arch/powerpc/kernel/signal_64.c | 9 +-- arch/powerpc/kernel/systbl.S | 2 +- arch/ppc/kernel/asm-offsets.c | 1 - arch/ppc/kernel/entry.S | 95 ++++++++----------------------- include/asm-powerpc/thread_info.h | 8 +-- 10 files changed, 78 insertions(+), 251 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 840aad43a98b..c9a660e4c2db 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -92,7 +92,6 @@ int main(void) DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); - DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame)); DEFINE(TI_TASK, offsetof(struct thread_info, task)); #ifdef CONFIG_PPC32 DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index f20a67261ec7..4827ca1ec89b 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -227,7 +227,7 @@ ret_from_syscall: MTMSRD(r10) lwz r9,TI_FLAGS(r12) li r8,-_LAST_ERRNO - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) bne- syscall_exit_work cmplw 0,r3,r8 blt+ syscall_exit_cont @@ -287,8 +287,10 @@ syscall_dotrace: syscall_exit_work: andi. r0,r9,_TIF_RESTOREALL - bne- 2f - cmplw 0,r3,r8 + beq+ 0f + REST_NVGPRS(r1) + b 2f +0: cmplw 0,r3,r8 blt+ 1f andi. r0,r9,_TIF_NOERROR bne- 1f @@ -302,9 +304,7 @@ syscall_exit_work: 2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) beq 4f - /* Clear per-syscall TIF flags if any are set, but _leave_ - _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that - yet. */ + /* Clear per-syscall TIF flags if any are set. */ li r11,_TIF_PERSYSCALL_MASK addi r12,r12,TI_FLAGS @@ -318,8 +318,13 @@ syscall_exit_work: subi r12,r12,TI_FLAGS 4: /* Anything which requires enabling interrupts? */ - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS) - beq 7f + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) + beq ret_from_except + + /* Re-enable interrupts */ + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* Save NVGPRS if they're not saved already */ lwz r4,_TRAP(r1) @@ -328,71 +333,11 @@ syscall_exit_work: SAVE_NVGPRS(r1) li r4,0xc00 stw r4,_TRAP(r1) - - /* Re-enable interrupts */ -5: ori r10,r10,MSR_EE - SYNC - MTMSRD(r10) - - andi. r0,r9,_TIF_SAVE_NVGPRS - bne save_user_nvgprs - -save_user_nvgprs_cont: - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - beq 7f - +5: addi r3,r1,STACK_FRAME_OVERHEAD bl do_syscall_trace_leave - REST_NVGPRS(r1) + b ret_from_except_full -6: lwz r3,GPR3(r1) - LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ - SYNC - MTMSRD(r10) /* disable interrupts again */ - rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ - lwz r9,TI_FLAGS(r12) -7: - andi. r0,r9,_TIF_NEED_RESCHED - bne 8f - lwz r5,_MSR(r1) - andi. r5,r5,MSR_PR - beq ret_from_except - andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK - beq ret_from_except - b do_user_signal -8: - ori r10,r10,MSR_EE - SYNC - MTMSRD(r10) /* re-enable interrupts */ - bl schedule - b 6b - -save_user_nvgprs: - lwz r8,TI_SIGFRAME(r12) - -.macro savewords start, end - 1: stw \start,4*(\start)(r8) - .section __ex_table,"a" - .align 2 - .long 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savewords "(\start+1)",\end - .endif -.endm - savewords 14,31 - b save_user_nvgprs_cont - - -save_user_nvgprs_fault: - li r3,11 /* SIGSEGV */ - lwz r4,TI_TASK(r12) - bl force_sigsegv - - rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ - lwz r9,TI_FLAGS(r12) - b save_user_nvgprs_cont - #ifdef SHOW_SYSCALLS do_show_syscall: #ifdef SHOW_SYSCALLS_TASK @@ -490,6 +435,14 @@ ppc_clone: stw r0,_TRAP(r1) /* register set saved */ b sys_clone + .globl ppc_swapcontext +ppc_swapcontext: + SAVE_NVGPRS(r1) + lwz r0,_TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,_TRAP(r1) /* register set saved */ + b sys_swapcontext + /* * Top-level page fault handling. * This is in assembler because if do_page_fault tells us that @@ -683,7 +636,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ /* Check current_thread_info()->flags */ rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r9,TI_FLAGS(r9) - andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_RESTORE_SIGMASK) + andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED) bne do_work restore_user: diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 388f861b8ed1..24be0cf86d7f 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -160,7 +160,7 @@ syscall_exit: mtmsrd r10,1 ld r9,TI_FLAGS(r12) li r11,-_LAST_ERRNO - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR|_TIF_RESTORE_SIGMASK) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) bne- syscall_exit_work cmpld r3,r11 ld r5,_CCR(r1) @@ -216,8 +216,10 @@ syscall_exit_work: If TIF_NOERROR is set, just save r3 as it is. */ andi. r0,r9,_TIF_RESTOREALL - bne- 2f - cmpld r3,r11 /* r10 is -LAST_ERRNO */ + beq+ 0f + REST_NVGPRS(r1) + b 2f +0: cmpld r3,r11 /* r10 is -LAST_ERRNO */ blt+ 1f andi. r0,r9,_TIF_NOERROR bne- 1f @@ -229,9 +231,7 @@ syscall_exit_work: 2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) beq 4f - /* Clear per-syscall TIF flags if any are set, but _leave_ - _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that - yet. */ + /* Clear per-syscall TIF flags if any are set. */ li r11,_TIF_PERSYSCALL_MASK addi r12,r12,TI_FLAGS @@ -240,10 +240,9 @@ syscall_exit_work: stdcx. r10,0,r12 bne- 3b subi r12,r12,TI_FLAGS - -4: bl .save_nvgprs - /* Anything else left to do? */ - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS) + +4: /* Anything else left to do? */ + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) beq .ret_from_except_lite /* Re-enable interrupts */ @@ -251,26 +250,10 @@ syscall_exit_work: ori r10,r10,MSR_EE mtmsrd r10,1 - andi. r0,r9,_TIF_SAVE_NVGPRS - bne save_user_nvgprs - - /* If tracing, re-enable interrupts and do it */ -save_user_nvgprs_cont: - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - beq 5f - + bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl .do_syscall_trace_leave - REST_NVGPRS(r1) - clrrdi r12,r1,THREAD_SHIFT - - /* Disable interrupts again and handle other work if any */ -5: mfmsr r10 - rldicl r10,r10,48,1 - rotldi r10,r10,16 - mtmsrd r10,1 - - b .ret_from_except_lite + b .ret_from_except /* Save non-volatile GPRs, if not already saved. */ _GLOBAL(save_nvgprs) @@ -282,51 +265,6 @@ _GLOBAL(save_nvgprs) std r0,_TRAP(r1) blr - -save_user_nvgprs: - ld r10,TI_SIGFRAME(r12) - andi. r0,r9,_TIF_32BIT - beq- save_user_nvgprs_64 - - /* 32-bit save to userspace */ - -.macro savewords start, end - 1: stw \start,4*(\start)(r10) - .section __ex_table,"a" - .align 3 - .llong 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savewords "(\start+1)",\end - .endif -.endm - savewords 14,31 - b save_user_nvgprs_cont - -save_user_nvgprs_64: - /* 64-bit save to userspace */ - -.macro savelongs start, end - 1: std \start,8*(\start)(r10) - .section __ex_table,"a" - .align 3 - .llong 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savelongs "(\start+1)",\end - .endif -.endm - savelongs 14,31 - b save_user_nvgprs_cont - -save_user_nvgprs_fault: - li r3,11 /* SIGSEGV */ - ld r4,TI_TASK(r12) - bl .force_sigsegv - - clrrdi r12,r1,THREAD_SHIFT - ld r9,TI_FLAGS(r12) - b save_user_nvgprs_cont /* * The sigsuspend and rt_sigsuspend system calls can call do_signal @@ -352,6 +290,16 @@ _GLOBAL(ppc_clone) bl .sys_clone b syscall_exit +_GLOBAL(ppc32_swapcontext) + bl .save_nvgprs + bl .compat_sys_swapcontext + b syscall_exit + +_GLOBAL(ppc64_swapcontext) + bl .save_nvgprs + bl .sys_swapcontext + b syscall_exit + _GLOBAL(ret_from_fork) bl .schedule_tail REST_NVGPRS(r1) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 400793c71304..bcb83574335b 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -561,10 +561,7 @@ void do_syscall_trace_leave(struct pt_regs *regs) regs->result); if ((test_thread_flag(TIF_SYSCALL_TRACE) -#ifdef CONFIG_PPC64 - || test_thread_flag(TIF_SINGLESTEP) -#endif - ) + || test_thread_flag(TIF_SINGLESTEP)) && (current->ptrace & PT_PTRACED)) do_syscall_trace(); } diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index bd837b5dbf06..d7a4e814974d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -151,10 +151,7 @@ static inline int save_general_regs(struct pt_regs *regs, elf_greg_t64 *gregs = (elf_greg_t64 *)regs; int i; - if (!FULL_REGS(regs)) { - set_thread_flag(TIF_SAVE_NVGPRS); - current_thread_info()->nvgprs_frame = frame->mc_gregs; - } + WARN_ON(!FULL_REGS(regs)); for (i = 0; i <= PT_RESULT; i ++) { if (i == 14 && !FULL_REGS(regs)) @@ -215,15 +212,7 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka, static inline int save_general_regs(struct pt_regs *regs, struct mcontext __user *frame) { - if (!FULL_REGS(regs)) { - /* Zero out the unsaved GPRs to avoid information - leak, and set TIF_SAVE_NVGPRS to ensure that the - registers do actually get saved later. */ - memset(®s->gpr[14], 0, 18 * sizeof(unsigned long)); - current_thread_info()->nvgprs_frame = &frame->mc_gregs; - set_thread_flag(TIF_SAVE_NVGPRS); - } - + WARN_ON(!FULL_REGS(regs)); return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); } @@ -826,8 +815,8 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int } long sys_swapcontext(struct ucontext __user *old_ctx, - struct ucontext __user *new_ctx, - int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) + struct ucontext __user *new_ctx, + int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) { unsigned char tmp; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 497a5d3df359..4324f8a8ba24 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -118,14 +118,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, err |= __put_user(0, &sc->v_regs); #endif /* CONFIG_ALTIVEC */ err |= __put_user(&sc->gp_regs, &sc->regs); - if (!FULL_REGS(regs)) { - /* Zero out the unsaved GPRs to avoid information - leak, and set TIF_SAVE_NVGPRS to ensure that the - registers do actually get saved later. */ - memset(®s->gpr[14], 0, 18 * sizeof(unsigned long)); - set_thread_flag(TIF_SAVE_NVGPRS); - current_thread_info()->nvgprs_frame = &sc->gp_regs; - } + WARN_ON(!FULL_REGS(regs)); err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE); err |= __put_user(signr, &sc->signal); diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 8a9f994ed917..1ad55f0466fd 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -288,7 +288,7 @@ COMPAT_SYS(clock_settime) COMPAT_SYS(clock_gettime) COMPAT_SYS(clock_getres) COMPAT_SYS(clock_nanosleep) -COMPAT_SYS(swapcontext) +SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext) COMPAT_SYS(tgkill) COMPAT_SYS(utimes) COMPAT_SYS(statfs64) diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c index 7964bf660e92..77e4dc780f8c 100644 --- a/arch/ppc/kernel/asm-offsets.c +++ b/arch/ppc/kernel/asm-offsets.c @@ -131,7 +131,6 @@ main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); - DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame)); DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index a48b950722a1..3a2815978488 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -227,7 +227,7 @@ ret_from_syscall: MTMSRD(r10) lwz r9,TI_FLAGS(r12) li r8,-_LAST_ERRNO - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) bne- syscall_exit_work cmplw 0,r3,r8 blt+ syscall_exit_cont @@ -287,8 +287,10 @@ syscall_dotrace: syscall_exit_work: andi. r0,r9,_TIF_RESTOREALL - bne- 2f - cmplw 0,r3,r8 + beq+ 0f + REST_NVGPRS(r1) + b 2f +0: cmplw 0,r3,r8 blt+ 1f andi. r0,r9,_TIF_NOERROR bne- 1f @@ -302,9 +304,7 @@ syscall_exit_work: 2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) beq 4f - /* Clear per-syscall TIF flags if any are set, but _leave_ - _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that - yet. */ + /* Clear per-syscall TIF flags if any are set. */ li r11,_TIF_PERSYSCALL_MASK addi r12,r12,TI_FLAGS @@ -318,8 +318,13 @@ syscall_exit_work: subi r12,r12,TI_FLAGS 4: /* Anything which requires enabling interrupts? */ - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS) - beq 7f + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) + beq ret_from_except + + /* Re-enable interrupts */ + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* Save NVGPRS if they're not saved already */ lwz r4,TRAP(r1) @@ -328,71 +333,11 @@ syscall_exit_work: SAVE_NVGPRS(r1) li r4,0xc00 stw r4,TRAP(r1) - - /* Re-enable interrupts */ -5: ori r10,r10,MSR_EE - SYNC - MTMSRD(r10) - - andi. r0,r9,_TIF_SAVE_NVGPRS - bne save_user_nvgprs - -save_user_nvgprs_cont: - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - beq 7f - +5: addi r3,r1,STACK_FRAME_OVERHEAD bl do_syscall_trace_leave - REST_NVGPRS(r1) + b ret_from_except_full -6: lwz r3,GPR3(r1) - LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ - SYNC - MTMSRD(r10) /* disable interrupts again */ - rlwinm r12,r1,0,0,18 /* current_thread_info() */ - lwz r9,TI_FLAGS(r12) -7: - andi. r0,r9,_TIF_NEED_RESCHED - bne 8f - lwz r5,_MSR(r1) - andi. r5,r5,MSR_PR - beq ret_from_except - andi. r0,r9,_TIF_SIGPENDING - beq ret_from_except - b do_user_signal -8: - ori r10,r10,MSR_EE - SYNC - MTMSRD(r10) /* re-enable interrupts */ - bl schedule - b 6b - -save_user_nvgprs: - lwz r8,TI_SIGFRAME(r12) - -.macro savewords start, end - 1: stw \start,4*(\start)(r8) - .section __ex_table,"a" - .align 2 - .long 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savewords "(\start+1)",\end - .endif -.endm - savewords 14,31 - b save_user_nvgprs_cont - - -save_user_nvgprs_fault: - li r3,11 /* SIGSEGV */ - lwz r4,TI_TASK(r12) - bl force_sigsegv - - rlwinm r12,r1,0,0,18 /* current_thread_info() */ - lwz r9,TI_FLAGS(r12) - b save_user_nvgprs_cont - #ifdef SHOW_SYSCALLS do_show_syscall: #ifdef SHOW_SYSCALLS_TASK @@ -490,6 +435,14 @@ ppc_clone: stw r0,TRAP(r1) /* register set saved */ b sys_clone + .globl ppc_swapcontext +ppc_swapcontext: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_swapcontext + /* * Top-level page fault handling. * This is in assembler because if do_page_fault tells us that @@ -683,7 +636,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ /* Check current_thread_info()->flags */ rlwinm r9,r1,0,0,18 lwz r9,TI_FLAGS(r9) - andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) + andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED) bne do_work restore_user: diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index 237fc2b72974..ffc7462d77ba 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h @@ -37,7 +37,6 @@ struct thread_info { int preempt_count; /* 0 => preemptable, <0 => BUG */ struct restart_block restart_block; - void __user *nvgprs_frame; /* low level flags - has atomic operations done on it */ unsigned long flags ____cacheline_aligned_in_smp; }; @@ -120,7 +119,6 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 10 #define TIF_SECCOMP 11 /* secure computing */ #define TIF_RESTOREALL 12 /* Restore all regs (implies NOERROR) */ -#define TIF_SAVE_NVGPRS 13 /* Save r14-r31 in signal frame */ #define TIF_NOERROR 14 /* Force successful syscall return */ #define TIF_RESTORE_SIGMASK 15 /* Restore signal mask in do_signal */ @@ -137,15 +135,13 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SINGLESTEP (1< Date: Fri, 24 Feb 2006 18:53:00 -0300 Subject: [PATCH 106/178] V4L/DVB (3403): Workaround to fix initialization for Nexus CA Workaround for Nexus CA: Debi test fails unless first debi write is repeated. Signed-off-by: Marco Schluessler Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110_hw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index b2e63e9fc053..0bb6e74ae7f0 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c @@ -245,6 +245,9 @@ int av7110_bootarm(struct av7110 *av7110) /* test DEBI */ iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); + /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */ + iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); + if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) { printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: " "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", From 8a59822f68996c1f525a8ed87447a4dbc27ada0b Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 7 Mar 2006 22:20:23 -0300 Subject: [PATCH 107/178] V4L/DVB (3413): Typos grab bag of the month Typos grab bag of the month. Eyeballed by jmc@ in OpenBSD. Signed-off-by: Alexey Dobriyan Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/demux.h | 2 +- drivers/media/dvb/dvb-usb/dvb-usb-init.c | 2 +- drivers/media/dvb/dvb-usb/dvb-usb.h | 2 +- drivers/media/dvb/ttpci/av7110.c | 2 +- drivers/media/video/cpia.c | 2 +- drivers/media/video/videocodec.h | 2 +- drivers/media/video/zr36050.c | 2 +- drivers/media/video/zr36060.c | 2 +- drivers/media/video/zr36120_i2c.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h index 9f025825b2d2..0c1d87c5227a 100644 --- a/drivers/media/dvb/dvb-core/demux.h +++ b/drivers/media/dvb/dvb-core/demux.h @@ -216,7 +216,7 @@ struct dmx_frontend { /*--------------------------------------------------------------------------*/ /* - * Flags OR'ed in the capabilites field of struct dmx_demux. + * Flags OR'ed in the capabilities field of struct dmx_demux. */ #define DMX_TS_FILTERING 1 diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 716f8bf528cd..ce34a55e5c24 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -47,7 +47,7 @@ static int dvb_usb_init(struct dvb_usb_device *d) d->state = DVB_USB_STATE_INIT; -/* check the capabilites and set appropriate variables */ +/* check the capabilities and set appropriate variables */ /* speed - when running at FULL speed we need a HW PID filter */ if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) { diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 5e5d21ad93c9..d4909e5c67e0 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -87,7 +87,7 @@ struct dvb_usb_device; /** * struct dvb_usb_properties - properties of a dvb-usb-device - * @caps: capabilites of the DVB USB device. + * @caps: capabilities of the DVB USB device. * @pid_filter_count: number of PID filter position in the optional hardware * PID-filter. * diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index cdf7b2c33ad0..7c6ccb96b157 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -1439,7 +1439,7 @@ static int check_firmware(struct av7110* av7110) len = ntohl(*(u32*) ptr); ptr += 4; if (len >= 512) { - printk("dvb-ttpci: dpram file is way to big.\n"); + printk("dvb-ttpci: dpram file is way too big.\n"); return -EINVAL; } if (crc != crc32_le(0, ptr, len)) { diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 9f59541155d9..85d964b5b33c 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -3369,7 +3369,7 @@ static int cpia_do_ioctl(struct inode *inode, struct file *file, //DBG("cpia_ioctl: %u\n", ioctlnr); switch (ioctlnr) { - /* query capabilites */ + /* query capabilities */ case VIDIOCGCAP: { struct video_capability *b = arg; diff --git a/drivers/media/video/videocodec.h b/drivers/media/video/videocodec.h index 156ae57096fe..b1239ac7f371 100644 --- a/drivers/media/video/videocodec.h +++ b/drivers/media/video/videocodec.h @@ -56,7 +56,7 @@ the slave is bound to it). Otherwise it doesn't need this functions and therfor they may not be initialized. - The other fuctions are just for convenience, as they are for shure used by + The other fuctions are just for convenience, as they are for sure used by most/all of the codecs. The last ones may be ommited, too. See the structure declaration below for more information and which data has diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c index bd0cd28543ca..6699725be605 100644 --- a/drivers/media/video/zr36050.c +++ b/drivers/media/video/zr36050.c @@ -159,7 +159,7 @@ zr36050_wait_end (struct zr36050 *ptr) while (!(zr36050_read_status1(ptr) & 0x4)) { udelay(1); - if (i++ > 200000) { // 200ms, there is for shure something wrong!!! + if (i++ > 200000) { // 200ms, there is for sure something wrong!!! dprintk(1, "%s: timout at wait_end (last status: 0x%02x)\n", ptr->name, ptr->status1); diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c index 28fa31a5f150..d8dd003a7aad 100644 --- a/drivers/media/video/zr36060.c +++ b/drivers/media/video/zr36060.c @@ -161,7 +161,7 @@ zr36060_wait_end (struct zr36060 *ptr) while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) { udelay(1); - if (i++ > 200000) { // 200ms, there is for shure something wrong!!! + if (i++ > 200000) { // 200ms, there is for sure something wrong!!! dprintk(1, "%s: timout at wait_end (last status: 0x%02x)\n", ptr->name, ptr->status); diff --git a/drivers/media/video/zr36120_i2c.c b/drivers/media/video/zr36120_i2c.c index 6bfe84d657f1..21fde43a6aed 100644 --- a/drivers/media/video/zr36120_i2c.c +++ b/drivers/media/video/zr36120_i2c.c @@ -65,7 +65,7 @@ void attach_inform(struct i2c_bus *bus, int id) case I2C_DRIVERID_VIDEODECODER: DEBUG(printk(CARD_INFO "decoder attached\n",CARD)); - /* fetch the capabilites of the decoder */ + /* fetch the capabilities of the decoder */ rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc); if (rv) { DEBUG(printk(CARD_DEBUG "decoder is not V4L aware!\n",CARD)); From f78bb8ad482267b92c122f0e37a7dce69c880247 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Mar 2006 10:33:05 -0800 Subject: [PATCH 108/178] slab: fix calculate_slab_order() for SLAB_RECLAIM_ACCOUNT Instead of having a hard-to-read and confusing conditional in the caller, just make the slab order calculation handle this special case, since it's simple and obvious there. Signed-off-by: Linus Torvalds --- mm/slab.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index f2e92dc1c9ce..6ad6bd5a0b3e 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1647,6 +1647,14 @@ static inline size_t calculate_slab_order(struct kmem_cache *cachep, cachep->gfporder = gfporder; left_over = remainder; + /* + * A VFS-reclaimable slab tends to have most allocations + * as GFP_NOFS and we really don't want to have to be allocating + * higher-order pages when we are unable to shrink dcache. + */ + if (flags & SLAB_RECLAIM_ACCOUNT) + break; + /* * Large number of objects is good, but very large slabs are * currently bad for the gfp()s. @@ -1869,17 +1877,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, size = ALIGN(size, align); - if ((flags & SLAB_RECLAIM_ACCOUNT) && size <= PAGE_SIZE) { - /* - * A VFS-reclaimable slab tends to have most allocations - * as GFP_NOFS and we really don't want to have to be allocating - * higher-order pages when we are unable to shrink dcache. - */ - cachep->gfporder = 0; - cache_estimate(cachep->gfporder, size, align, flags, - &left_over, &cachep->num); - } else - left_over = calculate_slab_order(cachep, size, align, flags); + left_over = calculate_slab_order(cachep, size, align, flags); if (!cachep->num) { printk("kmem_cache_create: couldn't create cache %s.\n", name); From a19cbd4bf258840ade3b6ee9e9256006d0644e09 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Mar 2006 14:03:09 -0800 Subject: [PATCH 109/178] Mark the pipe file operations static They aren't used (nor even really usable) outside of pipe.c anyway Signed-off-by: Linus Torvalds --- fs/pipe.c | 6 +++--- include/linux/fs.h | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/fs/pipe.c b/fs/pipe.c index d722579df79a..8aada8e426f4 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -605,7 +605,7 @@ struct file_operations rdwr_fifo_fops = { .fasync = pipe_rdwr_fasync, }; -struct file_operations read_pipe_fops = { +static struct file_operations read_pipe_fops = { .llseek = no_llseek, .read = pipe_read, .readv = pipe_readv, @@ -617,7 +617,7 @@ struct file_operations read_pipe_fops = { .fasync = pipe_read_fasync, }; -struct file_operations write_pipe_fops = { +static struct file_operations write_pipe_fops = { .llseek = no_llseek, .read = bad_pipe_r, .write = pipe_write, @@ -629,7 +629,7 @@ struct file_operations write_pipe_fops = { .fasync = pipe_write_fasync, }; -struct file_operations rdwr_pipe_fops = { +static struct file_operations rdwr_pipe_fops = { .llseek = no_llseek, .read = pipe_read, .readv = pipe_readv, diff --git a/include/linux/fs.h b/include/linux/fs.h index e059da947007..0cc34b1c42c9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1418,9 +1418,6 @@ extern int is_bad_inode(struct inode *); extern struct file_operations read_fifo_fops; extern struct file_operations write_fifo_fops; extern struct file_operations rdwr_fifo_fops; -extern struct file_operations read_pipe_fops; -extern struct file_operations write_pipe_fops; -extern struct file_operations rdwr_pipe_fops; extern int fs_may_remount_ro(struct super_block *); From 1c6cc5fd32978ffdc4d0acf8592d3901adefbdad Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Tue, 7 Mar 2006 21:55:20 -0800 Subject: [PATCH 110/178] [PATCH] powerpc: restore eeh_add_device_late() prototype stub We fixed this: arch/powerpc/platforms/pseries/eeh.c: In function `eeh_add_device_tree_late': arch/powerpc/platforms/pseries/eeh.c:901: warning: implicit declaration of function `eeh_add_device_late' arch/powerpc/platforms/pseries/eeh.c: At top level: arch/powerpc/platforms/pseries/eeh.c:918: error: conflicting types for 'eeh_add_device_late' arch/powerpc/platforms/pseries/eeh.c:901: error: previous implicit declaration of 'eeh_add_device_late' was here make[2]: *** [arch/powerpc/platforms/pseries/eeh.o] Error 1 But we forgot the !CONFIG_EEH stub. Signed-off-by: Mark Fasheh Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-powerpc/eeh.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h index eb392032e19b..5207758a6dd9 100644 --- a/include/asm-powerpc/eeh.h +++ b/include/asm-powerpc/eeh.h @@ -118,6 +118,8 @@ static inline void pci_addr_cache_build(void) { } static inline void eeh_add_device_early(struct device_node *dn) { } +static inline void eeh_add_device_late(struct pci_dev *dev) { } + static inline void eeh_remove_device(struct pci_dev *dev) { } static inline void eeh_add_device_tree_early(struct device_node *dn) { } From d5f735e52fb41e032b0db08aa20c02dbb9cd0db3 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 7 Mar 2006 21:55:20 -0800 Subject: [PATCH 111/178] [PATCH] serial core: work around sub-driver bugs We're presently getting oopses because Bluetooth (and possibly other) drivers are calling core functions after things have been shut down. So rather than oopsing, let's drop a warning then take avoiding action, so the machine survives. Once all the sub-drivers are fixed up we can remove the take-avoiding-action part. Signed-off-by: Pavel Machek Cc: Russell King Cc: Marcel Holtmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/serial_core.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 95fb4939c675..cc1faa31d124 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -71,6 +71,11 @@ static void uart_change_pm(struct uart_state *state, int pm_state); void uart_write_wakeup(struct uart_port *port) { struct uart_info *info = port->info; + /* + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ + BUG_ON(!info); tasklet_schedule(&info->tlet); } @@ -471,14 +476,26 @@ static void uart_flush_chars(struct tty_struct *tty) } static int -uart_write(struct tty_struct *tty, const unsigned char * buf, int count) +uart_write(struct tty_struct *tty, const unsigned char *buf, int count) { struct uart_state *state = tty->driver_data; - struct uart_port *port = state->port; - struct circ_buf *circ = &state->info->xmit; + struct uart_port *port; + struct circ_buf *circ; unsigned long flags; int c, ret = 0; + /* + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ + if (!state || !state->info) { + WARN_ON(1); + return -EL3HLT; + } + + port = state->port; + circ = &state->info->xmit; + if (!circ->buf) return 0; @@ -521,6 +538,15 @@ static void uart_flush_buffer(struct tty_struct *tty) struct uart_port *port = state->port; unsigned long flags; + /* + * This means you called this function _after_ the port was + * closed. No cookie for you. + */ + if (!state || !state->info) { + WARN_ON(1); + return; + } + DPRINTK("uart_flush_buffer(%d) called\n", tty->index); spin_lock_irqsave(&port->lock, flags); From 7f709ed0e3ccd3e88e0632b69f00174e83f8d98b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 7 Mar 2006 21:55:22 -0800 Subject: [PATCH 112/178] [PATCH] numa_maps-update fix Fix the mm/mempolicy.c build for !CONFIG_HUGETLB_PAGE. Cc: Christoph Lameter Cc: Martin Bligh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index d80fa7d8f720..954981b14303 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1789,6 +1789,7 @@ static void gather_stats(struct page *page, void *private, int pte_dirty) cond_resched(); } +#ifdef CONFIG_HUGETLB_PAGE static void check_huge_range(struct vm_area_struct *vma, unsigned long start, unsigned long end, struct numa_maps *md) @@ -1814,6 +1815,13 @@ static void check_huge_range(struct vm_area_struct *vma, gather_stats(page, md, pte_dirty(*ptep)); } } +#else +static inline void check_huge_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + struct numa_maps *md) +{ +} +#endif int show_numa_map(struct seq_file *m, void *v) { From 4d6660eb3665f22d16aff466eb9d45df6102b254 Mon Sep 17 00:00:00 2001 From: Phillip Susi Date: Tue, 7 Mar 2006 21:55:24 -0800 Subject: [PATCH 113/178] [PATCH] udf: fix uid/gid options and add uid/gid=ignore and forget options Fix a bug in udf where it would write uid/gid = 0 to the disk for files owned by the id given with the uid=/gid= mount options. It also adds 4 new mount options: uid/gid=forget and uid/gid=ignore. Without any options the id in core and on disk always match. Giving uid/gid=nnn specifies a default ID to be used in core when the on disk ID is -1. uid/gid=ignore forces the in core ID to allways be used no matter what the on disk ID is. uid/gid=forget forces the on disk ID to always be written out as -1. The use of these options allows you to override ownerships on a disk or disable ownwership information from being written, allowing the media to be used portably between different computers and possibly different users without permissions issues that would require root to correct. Signed-off-by: Phillip Susi Cc: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/udf/inode.c | 16 ++++++++++++---- fs/udf/super.c | 18 +++++++++++++++++- fs/udf/udf_sb.h | 4 ++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 395e582ee542..d04cff2273b6 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1045,10 +1045,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) } inode->i_uid = le32_to_cpu(fe->uid); - if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid; + if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb, + UDF_FLAG_UID_IGNORE)) + inode->i_uid = UDF_SB(inode->i_sb)->s_uid; inode->i_gid = le32_to_cpu(fe->gid); - if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid; + if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb, + UDF_FLAG_GID_IGNORE)) + inode->i_gid = UDF_SB(inode->i_sb)->s_gid; inode->i_nlink = le16_to_cpu(fe->fileLinkCount); if (!inode->i_nlink) @@ -1335,10 +1339,14 @@ udf_update_inode(struct inode *inode, int do_sync) return err; } - if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) + if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) + fe->uid = cpu_to_le32(-1); + else if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) fe->uid = cpu_to_le32(inode->i_uid); - if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) + if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) + fe->gid = cpu_to_le32(-1); + else if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) fe->gid = cpu_to_le32(inode->i_gid); udfperms = ((inode->i_mode & S_IRWXO) ) | diff --git a/fs/udf/super.c b/fs/udf/super.c index 4a6f49adc609..368d8f81fe54 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -269,7 +269,7 @@ enum { Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, Opt_rootdir, Opt_utf8, Opt_iocharset, - Opt_err + Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore }; static match_table_t tokens = { @@ -282,6 +282,10 @@ static match_table_t tokens = { {Opt_adinicb, "adinicb"}, {Opt_shortad, "shortad"}, {Opt_longad, "longad"}, + {Opt_uforget, "uid=forget"}, + {Opt_uignore, "uid=ignore"}, + {Opt_gforget, "gid=forget"}, + {Opt_gignore, "gid=ignore"}, {Opt_gid, "gid=%u"}, {Opt_uid, "uid=%u"}, {Opt_umask, "umask=%o"}, @@ -414,6 +418,18 @@ udf_parse_options(char *options, struct udf_options *uopt) uopt->flags |= (1 << UDF_FLAG_NLS_MAP); break; #endif + case Opt_uignore: + uopt->flags |= (1 << UDF_FLAG_UID_IGNORE); + break; + case Opt_uforget: + uopt->flags |= (1 << UDF_FLAG_UID_FORGET); + break; + case Opt_gignore: + uopt->flags |= (1 << UDF_FLAG_GID_IGNORE); + break; + case Opt_gforget: + uopt->flags |= (1 << UDF_FLAG_GID_FORGET); + break; default: printk(KERN_ERR "udf: bad mount option \"%s\" " "or missing value\n", p); diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 663669810be6..110f8d62616f 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h @@ -20,6 +20,10 @@ #define UDF_FLAG_VARCONV 8 #define UDF_FLAG_NLS_MAP 9 #define UDF_FLAG_UTF8 10 +#define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */ +#define UDF_FLAG_UID_IGNORE 12 /* use sb uid instead of on disk uid */ +#define UDF_FLAG_GID_FORGET 13 +#define UDF_FLAG_GID_IGNORE 14 #define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001 #define UDF_PART_FLAG_UNALLOC_TABLE 0x0002 From 81c29a857d3c8d6ea9c4f20d196c36bf0a07c615 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 7 Mar 2006 21:55:27 -0800 Subject: [PATCH 114/178] [PATCH] idle threads should have a sane ->timestamp value Idle threads should have a sane ->timestamp value, to avoid init kernel thread(s) from inheriting it and causing miscalculations in try_to_wake_up(). Reported-by: Mike Galbraith . Signed-off-by: Ingo Molnar Cc: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/sched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/sched.c b/kernel/sched.c index 3454bb869fd0..e82c99f1db64 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4335,6 +4335,7 @@ void __devinit init_idle(task_t *idle, int cpu) runqueue_t *rq = cpu_rq(cpu); unsigned long flags; + idle->timestamp = sched_clock(); idle->sleep_avg = 0; idle->array = NULL; idle->prio = MAX_PRIO; From 707ced0d718e89b52b13aa55a64653083e792cca Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 7 Mar 2006 21:55:28 -0800 Subject: [PATCH 115/178] [PATCH] __get_unaligned() gcc-4 fix If the 'ptr' is a const, this code cause "assignment of read-only variable" error on gcc 4.x. Use __u64 instead of __typeof__(*(ptr)) for temporary variable to get rid of errors on gcc 4.x. Signed-off-by: Atsushi Nemoto Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/unaligned.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h index 4dc8ddb401c1..09ec447fe2af 100644 --- a/include/asm-generic/unaligned.h +++ b/include/asm-generic/unaligned.h @@ -78,7 +78,7 @@ static inline void __ustw(__u16 val, __u16 *addr) #define __get_unaligned(ptr, size) ({ \ const void *__gu_p = ptr; \ - __typeof__(*(ptr)) val; \ + __u64 val; \ switch (size) { \ case 1: \ val = *(const __u8 *)__gu_p; \ @@ -95,7 +95,7 @@ static inline void __ustw(__u16 val, __u16 *addr) default: \ bad_unaligned_access_length(); \ }; \ - val; \ + (__typeof__(*(ptr)))val; \ }) #define __put_unaligned(val, ptr, size) \ From b884e25784f62a1c740d2e4c1ce19cb89644e986 Mon Sep 17 00:00:00 2001 From: GOTO Masanori Date: Tue, 7 Mar 2006 21:55:29 -0800 Subject: [PATCH 116/178] [PATCH] x86: Fix i386 nmi_watchdog that does not trigger die_nmi Fix i386 nmi_watchdog that does not meet watchdog timeout condition. It does not hit die_nmi when it should be triggered, because the current nmi_watchdog_tick in arch/i386/kernel/nmi.c never count up alert_counter like this: void nmi_watchdog_tick (struct pt_regs * regs) { if (last_irq_sums[cpu] == sum) { alert_counter[cpu]++; <- count up alert_counter, but if (alert_counter[cpu] == 5*nmi_hz) die_nmi(regs, "NMI Watchdog detected LOCKUP"); alert_counter[cpu] = 0; <- reset alert_counter This patch changes it back to the previous and working version. This was found and originally written by Kohta NAKASHIMA. (akpm: also uninline write_watchdog_counter(), saving 184 byets) Signed-off-by: GOTO Masanori Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/nmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 63f39a7e2c96..be87c5e2ee95 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -357,7 +357,7 @@ static void clear_msr_range(unsigned int base, unsigned int n) wrmsr(base+i, 0, 0); } -static inline void write_watchdog_counter(const char *descr) +static void write_watchdog_counter(const char *descr) { u64 count = (u64)cpu_khz * 1000; @@ -544,7 +544,7 @@ void nmi_watchdog_tick (struct pt_regs * regs) * die_nmi will return ONLY if NOTIFY_STOP happens.. */ die_nmi(regs, "NMI Watchdog detected LOCKUP"); - + } else { last_irq_sums[cpu] = sum; alert_counter[cpu] = 0; } From e2bab3d92486fb781f4d06f56339264ed1492392 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 7 Mar 2006 21:55:31 -0800 Subject: [PATCH 117/178] [PATCH] percpu_counter_sum() Implement percpu_counter_sum(). This is a more accurate but slower version of percpu_counter_read_positive(). We need this for Alex's speedup-ext3_statfs patch and for the nr_file accounting fix. Otherwise these things would be too inaccurate on large CPU counts. Cc: Ravikiran G Thirumalai Cc: Alex Tomas Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/percpu_counter.h | 6 ++++++ mm/swap.c | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index bd6708e2c027..682525511c9e 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -39,6 +39,7 @@ static inline void percpu_counter_destroy(struct percpu_counter *fbc) } void percpu_counter_mod(struct percpu_counter *fbc, long amount); +long percpu_counter_sum(struct percpu_counter *fbc); static inline long percpu_counter_read(struct percpu_counter *fbc) { @@ -92,6 +93,11 @@ static inline long percpu_counter_read_positive(struct percpu_counter *fbc) return fbc->count; } +static inline long percpu_counter_sum(struct percpu_counter *fbc) +{ + return percpu_counter_read_positive(fbc); +} + #endif /* CONFIG_SMP */ static inline void percpu_counter_inc(struct percpu_counter *fbc) diff --git a/mm/swap.c b/mm/swap.c index cce3dda59c59..e9ec06d845e8 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -489,13 +489,34 @@ void percpu_counter_mod(struct percpu_counter *fbc, long amount) if (count >= FBC_BATCH || count <= -FBC_BATCH) { spin_lock(&fbc->lock); fbc->count += count; + *pcount = 0; spin_unlock(&fbc->lock); - count = 0; + } else { + *pcount = count; } - *pcount = count; put_cpu(); } EXPORT_SYMBOL(percpu_counter_mod); + +/* + * Add up all the per-cpu counts, return the result. This is a more accurate + * but much slower version of percpu_counter_read_positive() + */ +long percpu_counter_sum(struct percpu_counter *fbc) +{ + long ret; + int cpu; + + spin_lock(&fbc->lock); + ret = fbc->count; + for_each_cpu(cpu) { + long *pcount = per_cpu_ptr(fbc->counters, cpu); + ret += *pcount; + } + spin_unlock(&fbc->lock); + return ret < 0 ? 0 : ret; +} +EXPORT_SYMBOL(percpu_counter_sum); #endif /* From 21a1ea9eb40411d4ee29448c53b9e4c0654d6ceb Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Tue, 7 Mar 2006 21:55:33 -0800 Subject: [PATCH 118/178] [PATCH] rcu batch tuning This patch adds new tunables for RCU queue and finished batches. There are two types of controls - number of completed RCU updates invoked in a batch (blimit) and monitoring for high rate of incoming RCUs on a cpu (qhimark, qlowmark). By default, the per-cpu batch limit is set to a small value. If the input RCU rate exceeds the high watermark, we do two things - force quiescent state on all cpus and set the batch limit of the CPU to INTMAX. Setting batch limit to INTMAX forces all finished RCUs to be processed in one shot. If we have more than INTMAX RCUs queued up, then we have bigger problems anyway. Once the incoming queued RCUs fall below the low watermark, the batch limit is set to the default. Signed-off-by: Dipankar Sarma Cc: "Paul E. McKenney" Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/kernel-parameters.txt | 13 +++++ include/linux/rcupdate.h | 6 ++- kernel/rcupdate.c | 76 ++++++++++++++++++++++------- 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 75205391b335..bad5987c4727 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1284,6 +1284,19 @@ running once the system is up. New name for the ramdisk parameter. See Documentation/ramdisk.txt. + rcu.blimit= [KNL,BOOT] Set maximum number of finished + RCU callbacks to process in one batch. + + rcu.qhimark= [KNL,BOOT] Set threshold of queued + RCU callbacks over which batch limiting is disabled. + + rcu.qlowmark= [KNL,BOOT] Set threshold of queued + RCU callbacks below which batch limiting is re-enabled. + + rcu.rsinterval= [KNL,BOOT,SMP] Set the number of additional + RCU callbacks to queued before forcing reschedule + on all cpus. + rdinit= [KNL] Format: Run specified binary instead of /init from the ramdisk, diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index b87aefa082e2..c2ec6c77874e 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -98,13 +98,17 @@ struct rcu_data { long batch; /* Batch # for current RCU batch */ struct rcu_head *nxtlist; struct rcu_head **nxttail; - long count; /* # of queued items */ + long qlen; /* # of queued callbacks */ struct rcu_head *curlist; struct rcu_head **curtail; struct rcu_head *donelist; struct rcu_head **donetail; + long blimit; /* Upper limit on a processed batch */ int cpu; struct rcu_head barrier; +#ifdef CONFIG_SMP + long last_rs_qlen; /* qlen during the last resched */ +#endif }; DECLARE_PER_CPU(struct rcu_data, rcu_data); diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 0cf8146bd585..8cf15a569fcd 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -67,7 +67,43 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L }; /* Fake initialization required by compiler */ static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; -static int maxbatch = 10000; +static int blimit = 10; +static int qhimark = 10000; +static int qlowmark = 100; +#ifdef CONFIG_SMP +static int rsinterval = 1000; +#endif + +static atomic_t rcu_barrier_cpu_count; +static struct semaphore rcu_barrier_sema; +static struct completion rcu_barrier_completion; + +#ifdef CONFIG_SMP +static void force_quiescent_state(struct rcu_data *rdp, + struct rcu_ctrlblk *rcp) +{ + int cpu; + cpumask_t cpumask; + set_need_resched(); + if (unlikely(rdp->qlen - rdp->last_rs_qlen > rsinterval)) { + rdp->last_rs_qlen = rdp->qlen; + /* + * Don't send IPI to itself. With irqs disabled, + * rdp->cpu is the current cpu. + */ + cpumask = rcp->cpumask; + cpu_clear(rdp->cpu, cpumask); + for_each_cpu_mask(cpu, cpumask) + smp_send_reschedule(cpu); + } +} +#else +static inline void force_quiescent_state(struct rcu_data *rdp, + struct rcu_ctrlblk *rcp) +{ + set_need_resched(); +} +#endif /** * call_rcu - Queue an RCU callback for invocation after a grace period. @@ -92,17 +128,13 @@ void fastcall call_rcu(struct rcu_head *head, rdp = &__get_cpu_var(rcu_data); *rdp->nxttail = head; rdp->nxttail = &head->next; - - if (unlikely(++rdp->count > 10000)) - set_need_resched(); - + if (unlikely(++rdp->qlen > qhimark)) { + rdp->blimit = INT_MAX; + force_quiescent_state(rdp, &rcu_ctrlblk); + } local_irq_restore(flags); } -static atomic_t rcu_barrier_cpu_count; -static struct semaphore rcu_barrier_sema; -static struct completion rcu_barrier_completion; - /** * call_rcu_bh - Queue an RCU for invocation after a quicker grace period. * @head: structure to be used for queueing the RCU updates. @@ -131,12 +163,12 @@ void fastcall call_rcu_bh(struct rcu_head *head, rdp = &__get_cpu_var(rcu_bh_data); *rdp->nxttail = head; rdp->nxttail = &head->next; - rdp->count++; -/* - * Should we directly call rcu_do_batch() here ? - * if (unlikely(rdp->count > 10000)) - * rcu_do_batch(rdp); - */ + + if (unlikely(++rdp->qlen > qhimark)) { + rdp->blimit = INT_MAX; + force_quiescent_state(rdp, &rcu_bh_ctrlblk); + } + local_irq_restore(flags); } @@ -199,10 +231,12 @@ static void rcu_do_batch(struct rcu_data *rdp) next = rdp->donelist = list->next; list->func(list); list = next; - rdp->count--; - if (++count >= maxbatch) + rdp->qlen--; + if (++count >= rdp->blimit) break; } + if (rdp->blimit == INT_MAX && rdp->qlen <= qlowmark) + rdp->blimit = blimit; if (!rdp->donelist) rdp->donetail = &rdp->donelist; else @@ -473,6 +507,7 @@ static void rcu_init_percpu_data(int cpu, struct rcu_ctrlblk *rcp, rdp->quiescbatch = rcp->completed; rdp->qs_pending = 0; rdp->cpu = cpu; + rdp->blimit = blimit; } static void __devinit rcu_online_cpu(int cpu) @@ -567,7 +602,12 @@ void synchronize_kernel(void) synchronize_rcu(); } -module_param(maxbatch, int, 0); +module_param(blimit, int, 0); +module_param(qhimark, int, 0); +module_param(qlowmark, int, 0); +#ifdef CONFIG_SMP +module_param(rsinterval, int, 0); +#endif EXPORT_SYMBOL_GPL(rcu_batches_completed); EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */ EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */ From 529bf6be5c04f2e869d07bfdb122e9fd98ade714 Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Tue, 7 Mar 2006 21:55:35 -0800 Subject: [PATCH 119/178] [PATCH] fix file counting I have benchmarked this on an x86_64 NUMA system and see no significant performance difference on kernbench. Tested on both x86_64 and powerpc. The way we do file struct accounting is not very suitable for batched freeing. For scalability reasons, file accounting was constructor/destructor based. This meant that nr_files was decremented only when the object was removed from the slab cache. This is susceptible to slab fragmentation. With RCU based file structure, consequent batched freeing and a test program like Serge's, we just speed this up and end up with a very fragmented slab - llm22:~ # cat /proc/sys/fs/file-nr 587730 0 758844 At the same time, I see only a 2000+ objects in filp cache. The following patch I fixes this problem. This patch changes the file counting by removing the filp_count_lock. Instead we use a separate percpu counter, nr_files, for now and all accesses to it are through get_nr_files() api. In the sysctl handler for nr_files, we populate files_stat.nr_files before returning to user. Counting files as an when they are created and destroyed (as opposed to inside slab) allows us to correctly count open files with RCU. Signed-off-by: Dipankar Sarma Cc: "Paul E. McKenney" Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/dcache.c | 2 +- fs/file_table.c | 89 ++++++++++++++++++++++++++++---------------- include/linux/file.h | 2 - include/linux/fs.h | 1 + kernel/sysctl.c | 5 ++- net/unix/af_unix.c | 2 +- 6 files changed, 63 insertions(+), 38 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index a173bba32666..11dc83092d4a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1736,7 +1736,7 @@ void __init vfs_caches_init(unsigned long mempages) SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC, filp_ctor, filp_dtor); + SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); dcache_init(mempages); inode_init(mempages); diff --git a/fs/file_table.c b/fs/file_table.c index 768b58167543..44fabeaa9415 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -5,6 +5,7 @@ * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */ +#include #include #include #include @@ -19,41 +20,20 @@ #include #include #include +#include +#include + +#include /* sysctl tunables... */ struct files_stat_struct files_stat = { .max_files = NR_FILE }; -EXPORT_SYMBOL(files_stat); /* Needed by unix.o */ - /* public. Not pretty! */ - __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); +__cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); -static DEFINE_SPINLOCK(filp_count_lock); - -/* slab constructors and destructors are called from arbitrary - * context and must be fully threaded - use a local spinlock - * to protect files_stat.nr_files - */ -void filp_ctor(void *objp, struct kmem_cache *cachep, unsigned long cflags) -{ - if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { - unsigned long flags; - spin_lock_irqsave(&filp_count_lock, flags); - files_stat.nr_files++; - spin_unlock_irqrestore(&filp_count_lock, flags); - } -} - -void filp_dtor(void *objp, struct kmem_cache *cachep, unsigned long dflags) -{ - unsigned long flags; - spin_lock_irqsave(&filp_count_lock, flags); - files_stat.nr_files--; - spin_unlock_irqrestore(&filp_count_lock, flags); -} +static struct percpu_counter nr_files __cacheline_aligned_in_smp; static inline void file_free_rcu(struct rcu_head *head) { @@ -63,9 +43,45 @@ static inline void file_free_rcu(struct rcu_head *head) static inline void file_free(struct file *f) { + percpu_counter_dec(&nr_files); call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); } +/* + * Return the total number of open files in the system + */ +static int get_nr_files(void) +{ + return percpu_counter_read_positive(&nr_files); +} + +/* + * Return the maximum number of open files in the system + */ +int get_max_files(void) +{ + return files_stat.max_files; +} +EXPORT_SYMBOL_GPL(get_max_files); + +/* + * Handle nr_files sysctl + */ +#if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) +int proc_nr_files(ctl_table *table, int write, struct file *filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + files_stat.nr_files = get_nr_files(); + return proc_dointvec(table, write, filp, buffer, lenp, ppos); +} +#else +int proc_nr_files(ctl_table *table, int write, struct file *filp, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return -ENOSYS; +} +#endif + /* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or * we run out of memory. @@ -78,14 +94,20 @@ struct file *get_empty_filp(void) /* * Privileged users can go above max_files */ - if (files_stat.nr_files >= files_stat.max_files && - !capable(CAP_SYS_ADMIN)) - goto over; + if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { + /* + * percpu_counters are inaccurate. Do an expensive check before + * we go and fail. + */ + if (percpu_counter_sum(&nr_files) >= files_stat.max_files) + goto over; + } f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); if (f == NULL) goto fail; + percpu_counter_inc(&nr_files); memset(f, 0, sizeof(*f)); if (security_file_alloc(f)) goto fail_sec; @@ -101,10 +123,10 @@ struct file *get_empty_filp(void) over: /* Ran out of filps - report that */ - if (files_stat.nr_files > old_max) { + if (get_nr_files() > old_max) { printk(KERN_INFO "VFS: file-max limit %d reached\n", - files_stat.max_files); - old_max = files_stat.nr_files; + get_max_files()); + old_max = get_nr_files(); } goto fail; @@ -276,4 +298,5 @@ void __init files_init(unsigned long mempages) if (files_stat.max_files < NR_FILE) files_stat.max_files = NR_FILE; files_defer_init(); + percpu_counter_init(&nr_files); } diff --git a/include/linux/file.h b/include/linux/file.h index 418b6101b59a..9901b850f2e4 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -60,8 +60,6 @@ extern void put_filp(struct file *); extern int get_unused_fd(void); extern void FASTCALL(put_unused_fd(unsigned int fd)); struct kmem_cache; -extern void filp_ctor(void * objp, struct kmem_cache *cachep, unsigned long cflags); -extern void filp_dtor(void * objp, struct kmem_cache *cachep, unsigned long dflags); extern struct file ** alloc_fd_array(int); extern void free_fd_array(struct file **, int); diff --git a/include/linux/fs.h b/include/linux/fs.h index 0cc34b1c42c9..51c0c93bdf93 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -35,6 +35,7 @@ struct files_stat_struct { int max_files; /* tunable */ }; extern struct files_stat_struct files_stat; +extern int get_max_files(void); struct inodes_stat_t { int nr_inodes; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index de2d9109194e..32b48e8ee36e 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -50,6 +50,9 @@ #include #include +extern int proc_nr_files(ctl_table *table, int write, struct file *filp, + void __user *buffer, size_t *lenp, loff_t *ppos); + #if defined(CONFIG_SYSCTL) /* External variables not in a header file. */ @@ -943,7 +946,7 @@ static ctl_table fs_table[] = { .data = &files_stat, .maxlen = 3*sizeof(int), .mode = 0444, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_nr_files, }, { .ctl_name = FS_MAXFILE, diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 1b5989b1b670..c323cc6a28b0 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -547,7 +547,7 @@ static struct sock * unix_create1(struct socket *sock) struct sock *sk = NULL; struct unix_sock *u; - if (atomic_read(&unix_nr_socks) >= 2*files_stat.max_files) + if (atomic_read(&unix_nr_socks) >= 2*get_max_files()) goto out; sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1); From e96fb230cc97760e448327c0de612cfba94ca7bf Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 7 Mar 2006 21:55:36 -0800 Subject: [PATCH 120/178] [PATCH] jffs2: avoid divide-by-zero Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jffs2/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 3e51dd1da8aa..cf55b221fc2b 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -233,7 +233,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) c->nextblock->dirty_size = 0; } #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) { + if (!jffs2_can_mark_obsolete(c) && c->wbuf_pagesize && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) { /* If we're going to start writing into a block which already contains data, and the end of the data isn't page-aligned, skip a little and align it. */ From 331c46591414f7f92b1cec048009abe89892ee79 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Tue, 7 Mar 2006 21:55:37 -0800 Subject: [PATCH 121/178] [PATCH] s390: fix strnlen_user return value strnlen_user is supposed to return then length count + 1 if no terminating \0 is found, and it should return 0 on exception. Found by David Howells . Signed-off-by: Gerald Schaefer Signed-off-by: Heiko Carstens Acked-By: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/lib/uaccess.S | 6 +++--- arch/s390/lib/uaccess64.S | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S index 88fc94fe6488..5d59e2625048 100644 --- a/arch/s390/lib/uaccess.S +++ b/arch/s390/lib/uaccess.S @@ -198,12 +198,12 @@ __strnlen_user_asm: 0: srst %r2,%r1 jo 0b sacf 0 - jh 1f # \0 found in string ? ahi %r2,1 # strnlen_user result includes the \0 -1: slr %r2,%r3 + # or return count+1 if \0 not found + slr %r2,%r3 br %r14 2: sacf 0 - lhi %r2,-EFAULT + slr %r2,%r2 # return 0 on exception br %r14 .section __ex_table,"a" .long 0b,2b diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S index 50219786fc7a..19b41a33c230 100644 --- a/arch/s390/lib/uaccess64.S +++ b/arch/s390/lib/uaccess64.S @@ -194,12 +194,12 @@ __strnlen_user_asm: 0: srst %r2,%r1 jo 0b sacf 0 - jh 1f # \0 found in string ? aghi %r2,1 # strnlen_user result includes the \0 -1: slgr %r2,%r3 + # or return count+1 if \0 not found + slgr %r2,%r3 br %r14 2: sacf 0 - lghi %r2,-EFAULT + slgr %r2,%r2 # return 0 on exception br %r14 .section __ex_table,"a" .quad 0b,2b From fbcae7eafcf7dfb315602de935d7ca85574e5c11 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 7 Mar 2006 21:55:38 -0800 Subject: [PATCH 122/178] [PATCH] s390: iucv message limit for smsg The message limit on the iucv connect call for the smsg module is too low. Therefore increase the smsg message limit to 255. Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/s390/net/smsgiucv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index d6469baa7e16..72118ee68954 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -168,7 +168,7 @@ smsg_init(void) driver_unregister(&smsg_driver); return -EIO; /* better errno ? */ } - rc = iucv_connect (&smsg_pathid, 1, 0, "*MSG ", 0, 0, 0, 0, + rc = iucv_connect (&smsg_pathid, 255, 0, "*MSG ", 0, 0, 0, 0, smsg_handle, 0); if (rc) { printk(KERN_ERR "SMSGIUCV: failed to connect to *MSG"); From 90f0094dc607abe384a412bfb7199fb667ab0735 Mon Sep 17 00:00:00 2001 From: Horst Hummel Date: Tue, 7 Mar 2006 21:55:39 -0800 Subject: [PATCH 123/178] [PATCH] s390: dasd partition detection DASD allows to open a device as soon as gendisk is registered, which means the device is a fake device (capacity=0) and we do know nothing about blocksize and partitions at that point of time. In case the device is opened by someone, the bdev and inode creation is done with the fake device info and the following partition detection code is just using the wrong data. To avoid this modify the DASD state machine to make sure that the open is rejected until the device analysis is either finished or an unformatted device was detected. Signed-off-by: Horst Hummel Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/s390/block/dasd.c | 38 +++++++++++++++++++++++++-------- drivers/s390/block/dasd_genhd.c | 2 -- drivers/s390/block/dasd_int.h | 7 +++--- drivers/s390/block/dasd_proc.c | 3 +++ fs/partitions/ibm.c | 16 ++++++++------ 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index af1d5b404cee..33157c84d1d3 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -215,9 +215,10 @@ dasd_state_basic_to_known(struct dasd_device * device) * interrupt for this detection ccw uses the kernel event daemon to * trigger the call to dasd_change_state. All this is done in the * discipline code, see dasd_eckd.c. - * After the analysis ccw is done (do_analysis returned 0 or error) - * the block device is setup. Either a fake disk is added to allow - * formatting or a proper device request queue is created. + * After the analysis ccw is done (do_analysis returned 0) the block + * device is setup. + * In case the analysis returns an error, the device setup is stopped + * (a fake disk was already added to allow formatting). */ static inline int dasd_state_basic_to_ready(struct dasd_device * device) @@ -227,13 +228,19 @@ dasd_state_basic_to_ready(struct dasd_device * device) rc = 0; if (device->discipline->do_analysis != NULL) rc = device->discipline->do_analysis(device); - if (rc) + if (rc) { + if (rc != -EAGAIN) + device->state = DASD_STATE_UNFMT; return rc; + } + /* make disk known with correct capacity */ dasd_setup_queue(device); + set_capacity(device->gdp, device->blocks << device->s2b_shift); device->state = DASD_STATE_READY; - if (dasd_scan_partitions(device) != 0) + rc = dasd_scan_partitions(device); + if (rc) device->state = DASD_STATE_BASIC; - return 0; + return rc; } /* @@ -253,6 +260,15 @@ dasd_state_ready_to_basic(struct dasd_device * device) device->state = DASD_STATE_BASIC; } +/* + * Back to basic. + */ +static inline void +dasd_state_unfmt_to_basic(struct dasd_device * device) +{ + device->state = DASD_STATE_BASIC; +} + /* * Make the device online and schedule the bottom half to start * the requeueing of requests from the linux request queue to the @@ -319,8 +335,12 @@ dasd_decrease_state(struct dasd_device *device) if (device->state == DASD_STATE_READY && device->target <= DASD_STATE_BASIC) dasd_state_ready_to_basic(device); - - if (device->state == DASD_STATE_BASIC && + + if (device->state == DASD_STATE_UNFMT && + device->target <= DASD_STATE_BASIC) + dasd_state_unfmt_to_basic(device); + + if (device->state == DASD_STATE_BASIC && device->target <= DASD_STATE_KNOWN) dasd_state_basic_to_known(device); @@ -1722,7 +1742,7 @@ dasd_open(struct inode *inp, struct file *filp) goto out; } - if (device->state < DASD_STATE_BASIC) { + if (device->state <= DASD_STATE_BASIC) { DBF_DEV_EVENT(DBF_ERR, device, " %s", " Cannot open unrecognized device"); rc = -ENODEV; diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 65dc844b975c..fce2835e7d19 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c @@ -100,8 +100,6 @@ dasd_scan_partitions(struct dasd_device * device) { struct block_device *bdev; - /* Make the disk known. */ - set_capacity(device->gdp, device->blocks << device->s2b_shift); bdev = bdget_disk(device->gdp, 0); if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) return -ENODEV; diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 0592354cc604..7cb0b9e78a6a 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -26,7 +26,7 @@ * new: the dasd_device structure is allocated. * known: the discipline for the device is identified. * basic: the device can do basic i/o. - * accept: the device is analysed (format is known). + * unfmt: the device could not be analyzed (format is unknown). * ready: partition detection is done and the device is can do block io. * online: the device accepts requests from the block device queue. * @@ -47,8 +47,9 @@ #define DASD_STATE_NEW 0 #define DASD_STATE_KNOWN 1 #define DASD_STATE_BASIC 2 -#define DASD_STATE_READY 3 -#define DASD_STATE_ONLINE 4 +#define DASD_STATE_UNFMT 3 +#define DASD_STATE_READY 4 +#define DASD_STATE_ONLINE 5 #include #include diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 2d5da3c75ca7..4c1acc8daa82 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c @@ -93,6 +93,9 @@ dasd_devices_show(struct seq_file *m, void *v) case DASD_STATE_BASIC: seq_printf(m, "basic"); break; + case DASD_STATE_UNFMT: + seq_printf(m, "unnformatted"); + break; case DASD_STATE_READY: case DASD_STATE_ONLINE: seq_printf(m, "active "); diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 78010ad60e47..1e4a93835fed 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c @@ -52,6 +52,7 @@ int ibm_partition(struct parsed_partitions *state, struct block_device *bdev) { int blocksize, offset, size; + loff_t i_size; dasd_information_t *info; struct hd_geometry *geo; char type[5] = {0,}; @@ -63,6 +64,13 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) unsigned char *data; Sector sect; + blocksize = bdev_hardsect_size(bdev); + if (blocksize <= 0) + return 0; + i_size = i_size_read(bdev->bd_inode); + if (i_size == 0) + return 0; + if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) goto out_noinfo; if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) @@ -73,9 +81,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) goto out_noioctl; - - if ((blocksize = bdev_hardsect_size(bdev)) <= 0) - goto out_badsect; /* * Get volume label, extract name and type. @@ -111,7 +116,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) } else { printk("CMS1/%8s:", name); offset = (info->label_block + 1); - size = bdev->bd_inode->i_size >> 9; + size = i_size >> 9; } put_partition(state, 1, offset*(blocksize >> 9), size-offset*(blocksize >> 9)); @@ -168,7 +173,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) else printk("(nonl)/%8s:", name); offset = (info->label_block + 1); - size = (bdev->bd_inode->i_size >> 9); + size = i_size >> 9; put_partition(state, 1, offset*(blocksize >> 9), size-offset*(blocksize >> 9)); } @@ -180,7 +185,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) return 1; out_readerr: -out_badsect: out_noioctl: kfree(label); out_nolab: From ed2da193fe6671fe4d7e34041bae40308d18247f Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 7 Mar 2006 21:55:40 -0800 Subject: [PATCH 124/178] [PATCH] x86: cpu model calculation for family 6 cpu The x86_model calculation also applies for family 6. early_cpu_detect does the right thing, but generic_identify misses. Signed-off-by: Shaohua Li Cc: Dave Jones Cc: "Seth, Rohit" Acked-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 4ecd4b326ded..e6bd095ae108 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -278,10 +278,10 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) c->x86_capability[4] = excap; c->x86 = (tfms >> 8) & 15; c->x86_model = (tfms >> 4) & 15; - if (c->x86 == 0xf) { + if (c->x86 == 0xf) c->x86 += (tfms >> 20) & 0xff; + if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; - } c->x86_mask = tfms & 15; } else { /* Have CPUID level 0 only - unheard of */ From 731805b49489055c1548f7ccfbd44c9b84013264 Mon Sep 17 00:00:00 2001 From: Latchesar Ionkov Date: Tue, 7 Mar 2006 21:55:42 -0800 Subject: [PATCH 125/178] [PATCH] v9fs: fix for access to unitialized variables or freed memory Miscellaneous fixes related to accessing uninitialized variables or memory that was already freed. Signed-off-by: Latchesar Ionkov Cc: Eric Van Hensbergen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/9p/9p.c | 1 - fs/9p/trans_fd.c | 1 + fs/9p/vfs_inode.c | 8 +++----- fs/9p/vfs_super.c | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/9p/9p.c b/fs/9p/9p.c index 1a6d08761f39..f86a28d1d6a6 100644 --- a/fs/9p/9p.c +++ b/fs/9p/9p.c @@ -111,7 +111,6 @@ static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, if (!rc) return; - dprintk(DEBUG_9P, "tcall id %d rcall id %d\n", tc->id, rc->id); v9ses = a; if (rc->id == RCLUNK) v9fs_put_idpool(fid, &v9ses->fidpool); diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c index 1a28ef97a3d1..5b2ce21b10fa 100644 --- a/fs/9p/trans_fd.c +++ b/fs/9p/trans_fd.c @@ -80,6 +80,7 @@ static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len) if (!trans || trans->status != Connected || !ts) return -EIO; + oldfs = get_fs(); set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos); diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index dce729d42869..3ad8455f8577 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -265,8 +265,7 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, fid = v9fs_get_idpool(&v9ses->fidpool); if (fid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); - err = -ENOSPC; - goto error; + return -ENOSPC; } err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); @@ -313,8 +312,7 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) nfid = v9fs_get_idpool(&v9ses->fidpool); if (nfid < 0) { eprintk(KERN_WARNING, "no free fids available\n"); - err = -ENOSPC; - goto error; + return ERR_PTR(-ENOSPC); } err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, @@ -612,7 +610,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, int result = 0; dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", - dir, dentry->d_iname, dentry, nameidata); + dir, dentry->d_name.name, dentry, nameidata); sb = dir->i_sb; v9ses = v9fs_inode2v9ses(dir); diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index cdf787ee08de..d05318fa684e 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -156,7 +156,6 @@ static struct super_block *v9fs_get_sb(struct file_system_type stat_result = v9fs_t_stat(v9ses, newfid, &fcall); if (stat_result < 0) { dprintk(DEBUG_ERROR, "stat error\n"); - kfree(fcall); v9fs_t_clunk(v9ses, newfid); } else { /* Setup the Root Inode */ From 07ed76b2a085a31f427c2a912a562627947dc7de Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 7 Mar 2006 21:55:46 -0800 Subject: [PATCH 126/178] [PATCH] slab: allocate larger cache_cache if order 0 fails kmem_cache_init() incorrectly assumes that the cache_cache object will fit in an order 0 allocation. On very large systems, this is not true. Change the code to try larger order allocations if order 0 fails. Signed-off-by: Jack Steiner Cc: Manfred Spraul Cc: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index 6ad6bd5a0b3e..61800b88e241 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -1124,6 +1124,7 @@ void __init kmem_cache_init(void) struct cache_sizes *sizes; struct cache_names *names; int i; + int order; for (i = 0; i < NUM_INIT_LISTS; i++) { kmem_list3_init(&initkmem_list3[i]); @@ -1167,11 +1168,15 @@ void __init kmem_cache_init(void) cache_cache.buffer_size = ALIGN(cache_cache.buffer_size, cache_line_size()); - cache_estimate(0, cache_cache.buffer_size, cache_line_size(), 0, - &left_over, &cache_cache.num); + for (order = 0; order < MAX_ORDER; order++) { + cache_estimate(order, cache_cache.buffer_size, + cache_line_size(), 0, &left_over, &cache_cache.num); + if (cache_cache.num) + break; + } if (!cache_cache.num) BUG(); - + cache_cache.gfporder = order; cache_cache.colour = left_over / cache_cache.colour_off; cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) + sizeof(struct slab), cache_line_size()); From 62287fbb54b4af71dc5a4918350f81a4cd467788 Mon Sep 17 00:00:00 2001 From: Matt Mackall Date: Tue, 7 Mar 2006 21:55:47 -0800 Subject: [PATCH 127/178] [PATCH] dac960: add disk entropy in request completions Signed-off-by: Matt Mackall Tested-by: Anders K. Pedersen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/DAC960.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 6ede1f352c29..37b8cda3e8bc 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include "DAC960.h" @@ -3463,7 +3464,7 @@ static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command, Command->SegmentCount, Command->DmaDirection); if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) { - + add_disk_randomness(Request->rq_disk); end_that_request_last(Request, UpToDate); if (Command->Completion) { From 2ec5e3a867d63d04932e11c6097f63760d9be3fe Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Tue, 7 Mar 2006 21:55:48 -0800 Subject: [PATCH 128/178] [PATCH] fix kexec asm While testing kexec and kdump we hit problems where the new kernel would freeze or instantly reboot. The easiest way to trigger it was to kexec a kernel compiled for CONFIG_M586 on an athlon cpu. Compiling for CONFIG_MK7 instead would work fine. The patch fixes a few problems with the kexec inline asm. Signed-off-by: Chris Mason Acked-by: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/machine_kexec.c | 14 +++++++------- arch/x86_64/kernel/machine_kexec.c | 2 +- include/asm-powerpc/kexec.h | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c index a912fed48482..f73d7374a2ba 100644 --- a/arch/i386/kernel/machine_kexec.c +++ b/arch/i386/kernel/machine_kexec.c @@ -116,13 +116,13 @@ static void load_segments(void) __asm__ __volatile__ ( "\tljmp $"STR(__KERNEL_CS)",$1f\n" "\t1:\n" - "\tmovl $"STR(__KERNEL_DS)",%eax\n" - "\tmovl %eax,%ds\n" - "\tmovl %eax,%es\n" - "\tmovl %eax,%fs\n" - "\tmovl %eax,%gs\n" - "\tmovl %eax,%ss\n" - ); + "\tmovl $"STR(__KERNEL_DS)",%%eax\n" + "\tmovl %%eax,%%ds\n" + "\tmovl %%eax,%%es\n" + "\tmovl %%eax,%%fs\n" + "\tmovl %%eax,%%gs\n" + "\tmovl %%eax,%%ss\n" + ::: "eax", "memory"); #undef STR #undef __STR } diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c index 89fab51e20f4..25ac8a3faae6 100644 --- a/arch/x86_64/kernel/machine_kexec.c +++ b/arch/x86_64/kernel/machine_kexec.c @@ -140,7 +140,7 @@ static void load_segments(void) "\tmovl %0,%%ss\n" "\tmovl %0,%%fs\n" "\tmovl %0,%%gs\n" - : : "a" (__KERNEL_DS) + : : "a" (__KERNEL_DS) : "memory" ); } diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h index bda2f217e6fe..6a2af2f6853b 100644 --- a/include/asm-powerpc/kexec.h +++ b/include/asm-powerpc/kexec.h @@ -93,7 +93,8 @@ static inline void crash_setup_regs(struct pt_regs *newregs, "mfxer %0\n" "std %0, 296(%2)\n" : "=&r" (tmp1), "=&r" (tmp2) - : "b" (newregs)); + : "b" (newregs) + : "memory"); } } #else From d8117ce5a679ff1f48df247da30fb62c16d562c5 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 7 Mar 2006 19:05:32 -0800 Subject: [PATCH 129/178] [IA64] Fix race in the accessed/dirty bit handlers A pte may be zapped by the swapper, exiting process, unmapping or page migration while the accessed or dirty bit handers are about to run. In that case the accessed bit or dirty is set on an zeroed pte which leads the VM to conclude that this is a swap pte. This may lead to - Messages from the vm like swap_free: Bad swap file entry 4000000000000000 - Processes being aborted swap_dup: Bad swap file entry 4000000000000000 VM: killing process .... Page migration is particular suitable for the creation of this race since it needs to remove and restore page table entries. The fix here is to check for the present bit and simply not update the pte if the page is not present anymore. If the page is not present then the fault handler should run next which will take care of the problem by bringing the page back and then mark the page dirty or move it onto the active list. Signed-off-by: Christoph Lameter Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 9f80569a32b0..dcd906fe5749 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -561,11 +561,12 @@ ENTRY(dirty_bit) ;; // avoid RAW on r18 mov ar.ccv=r18 // set compare value for cmpxchg or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits + tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit ;; - cmpxchg8.acq r26=[r17],r25,ar.ccv +(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only update if page is present mov r24=PAGE_SHIFT<<2 ;; - cmp.eq p6,p7=r26,r18 +(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present ;; (p6) itc.d r25 // install updated PTE ;; @@ -626,11 +627,12 @@ ENTRY(iaccess_bit) ;; mov ar.ccv=r18 // set compare value for cmpxchg or r25=_PAGE_A,r18 // set the accessed bit + tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit ;; - cmpxchg8.acq r26=[r17],r25,ar.ccv +(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page present mov r24=PAGE_SHIFT<<2 ;; - cmp.eq p6,p7=r26,r18 +(p6) cmp.eq p6,p7=r26,r18 // Only if page present ;; (p6) itc.i r25 // install updated PTE ;; @@ -680,11 +682,12 @@ ENTRY(daccess_bit) ;; // avoid RAW on r18 mov ar.ccv=r18 // set compare value for cmpxchg or r25=_PAGE_A,r18 // set the dirty bit + tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit ;; - cmpxchg8.acq r26=[r17],r25,ar.ccv +(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page is present mov r24=PAGE_SHIFT<<2 ;; - cmp.eq p6,p7=r26,r18 +(p6) cmp.eq p6,p7=r26,r18 // Only if page is present ;; (p6) itc.d r25 // install updated PTE /* From 1efa3c05f8640c37ba89d54dfaa18504d21986ce Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 8 Mar 2006 16:46:08 -0800 Subject: [PATCH 130/178] [NET] compat ifconf: fix limits A recent change to compat. dev_ifconf() in fs/compat_ioctl.c causes ifconf data to be truncated 1 entry too early when copying it to userspace. The correct amount of data (length) is returned, but the final entry is empty (zero, not filled in). The for-loop 'i' check should use <= to allow the final struct ifreq32 to be copied. I also used the ifconf-corruption program in kernel bugzilla #4746 to make sure that this change does not re-introduce the corruption. Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- fs/compat_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 537ac70edfe5..c666769a875d 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -446,7 +446,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg) ifr = ifc.ifc_req; ifr32 = compat_ptr(ifc32.ifcbuf); for (i = 0, j = 0; - i + sizeof (struct ifreq32) < ifc32.ifc_len && j < ifc.ifc_len; + i + sizeof (struct ifreq32) <= ifc32.ifc_len && j < ifc.ifc_len; i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) return -EFAULT; From f9262c12c0084ddba445a9a42e98994018e51400 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 8 Mar 2006 17:57:25 -0800 Subject: [PATCH 131/178] [PATCH] i386: port ATI timer fix from x86_64 to i386 II ATI chipsets tend to generate double timer interrupts for the local APIC timer when both the 8254 and the IO-APIC timer pins are enabled. This is because they route it to both and the result is anded together and the CPU ends up processing it twice. This patch changes check_timer to disable the 8254 routing for interrupt 0. I think it would be safe on all chipsets actually (i tested it on a couple and it worked everywhere) and Windows seems to do it in a similar way, but to be conservative this patch only enables this mode on ATI (and adds options to enable/disable too) Ported over from a similar x86-64 change. I reused the ACPI earlyquirk infrastructure for the ATI bridge check, but tweaked it a bit to work even without ACPI. Inspired by a patch from Chuck Ebbert, but redone. Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/kernel-parameters.txt | 6 ++++++ arch/i386/kernel/Makefile | 2 +- arch/i386/kernel/acpi/Makefile | 2 +- arch/i386/kernel/acpi/boot.c | 3 --- arch/i386/kernel/acpi/earlyquirk.c | 8 ++++++++ arch/i386/kernel/io_apic.c | 19 ++++++++++++++++++- arch/i386/kernel/setup.c | 4 ++++ include/asm-i386/apic.h | 2 ++ 8 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index bad5987c4727..fc99075e0af4 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -335,6 +335,12 @@ running once the system is up. timesource is not avalible, it defaults to PIT. Format: { pit | tsc | cyclone | pmtmr } + disable_8254_timer + enable_8254_timer + [IA32/X86_64] Disable/Enable interrupt 0 timer routing + over the 8254 in addition to over the IO-APIC. The + kernel tries to set a sensible default. + hpet= [IA-32,HPET] option to disable HPET and use PIT. Format: disable diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 53bb9a79e274..65656c033d70 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -11,7 +11,7 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ obj-y += cpu/ obj-y += timers/ -obj-$(CONFIG_ACPI) += acpi/ +obj-y += acpi/ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o obj-$(CONFIG_MCA) += mca.o obj-$(CONFIG_X86_MSR) += msr.o diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile index d51c7313cae8..7e9ac99354f4 100644 --- a/arch/i386/kernel/acpi/Makefile +++ b/arch/i386/kernel/acpi/Makefile @@ -1,4 +1,4 @@ -obj-y := boot.o +obj-$(CONFIG_ACPI) += boot.o obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 79577f0ace98..f1a21945963d 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -1111,9 +1111,6 @@ int __init acpi_boot_table_init(void) disable_acpi(); return error; } -#ifdef __i386__ - check_acpi_pci(); -#endif acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index f1b9d2a46dab..2e3b643a4dc4 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -7,14 +7,22 @@ #include #include #include +#include static int __init check_bridge(int vendor, int device) { +#ifdef CONFIG_ACPI /* According to Nvidia all timer overrides are bogus. Just ignore them all. */ if (vendor == PCI_VENDOR_ID_NVIDIA) { acpi_skip_timer_override = 1; } +#endif + if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { + timer_over_8254 = 0; + printk(KERN_INFO "ATI board detected. Disabling timer routing " + "over 8254.\n"); + } return 0; } diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 235822b3f41b..39d9a5fa907e 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -51,6 +51,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); +int timer_over_8254 __initdata = 1; + /* * Is the SiS APIC rmw bug present ? * -1 = don't know, 0 = no, 1 = yes @@ -2267,7 +2269,8 @@ static inline void check_timer(void) apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); timer_ack = 1; - enable_8259A_irq(0); + if (timer_over_8254 > 0) + enable_8259A_irq(0); pin1 = find_isa_irq_pin(0, mp_INT); apic1 = find_isa_irq_apic(0, mp_INT); @@ -2392,6 +2395,20 @@ void __init setup_IO_APIC(void) print_IO_APIC(); } +static int __init setup_disable_8254_timer(char *s) +{ + timer_over_8254 = -1; + return 1; +} +static int __init setup_enable_8254_timer(char *s) +{ + timer_over_8254 = 2; + return 1; +} + +__setup("disable_8254_timer", setup_disable_8254_timer); +__setup("enable_8254_timer", setup_enable_8254_timer); + /* * Called after all the initialization is done. If we didnt find any * APIC bugs then we can allow the modify fast path diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 51e513b4f72d..ab62a9f4701e 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1599,6 +1599,10 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled) efi_map_memmap(); +#ifdef CONFIG_X86_IO_APIC + check_acpi_pci(); /* Checks more than just ACPI actually */ +#endif + #ifdef CONFIG_ACPI /* * Parse the ACPI tables for possible boot-time SMP configuration. diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h index d30b8571573f..ff9ac8d19eb2 100644 --- a/include/asm-i386/apic.h +++ b/include/asm-i386/apic.h @@ -137,6 +137,8 @@ void switch_APIC_timer_to_ipi(void *cpumask); void switch_ipi_to_APIC_timer(void *cpumask); #define ARCH_APICTIMER_STOPS_ON_C3 1 +extern int timer_over_8254; + #else /* !CONFIG_X86_LOCAL_APIC */ static inline void lapic_shutdown(void) { } From 5ee1af9f519e6dc5a7d7912e87a1aaec857c8818 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 8 Mar 2006 17:57:26 -0800 Subject: [PATCH 132/178] [PATCH] block: disable block layer bouncing for most memory on 64bit systems The low level PCI DMA mapping functions should handle it in most cases. This should fix problems with depleting the DMA zone early. The old code used precious GFP_DMA memory in many cases where it was not needed. Signed-off-by: Andi Kleen Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- block/ll_rw_blk.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 03d9c82b0fe7..0ef2971a9e82 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -625,26 +625,31 @@ static inline int ordered_bio_endio(struct request *rq, struct bio *bio, * Different hardware can have different requirements as to what pages * it can do I/O directly to. A low level driver can call * blk_queue_bounce_limit to have lower memory pages allocated as bounce - * buffers for doing I/O to pages residing above @page. By default - * the block layer sets this to the highest numbered "low" memory page. + * buffers for doing I/O to pages residing above @page. **/ void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) { unsigned long bounce_pfn = dma_addr >> PAGE_SHIFT; + int dma = 0; - /* - * set appropriate bounce gfp mask -- unfortunately we don't have a - * full 4GB zone, so we have to resort to low memory for any bounces. - * ISA has its own < 16MB zone. - */ - if (bounce_pfn < blk_max_low_pfn) { - BUG_ON(dma_addr < BLK_BOUNCE_ISA); + q->bounce_gfp = GFP_NOIO; +#if BITS_PER_LONG == 64 + /* Assume anything <= 4GB can be handled by IOMMU. + Actually some IOMMUs can handle everything, but I don't + know of a way to test this here. */ + if (bounce_pfn < (0xffffffff>>PAGE_SHIFT)) + dma = 1; + q->bounce_pfn = max_low_pfn; +#else + if (bounce_pfn < blk_max_low_pfn) + dma = 1; + q->bounce_pfn = bounce_pfn; +#endif + if (dma) { init_emergency_isa_pool(); q->bounce_gfp = GFP_NOIO | GFP_DMA; - } else - q->bounce_gfp = GFP_NOIO; - - q->bounce_pfn = bounce_pfn; + q->bounce_pfn = bounce_pfn; + } } EXPORT_SYMBOL(blk_queue_bounce_limit); From cf028d1715cfa8db1ad95ed9ee479b7a0b9e1cc5 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 2 Mar 2006 16:50:12 +0000 Subject: [PATCH 133/178] [MIPS] Threaten removal of code for NEC DDB5074 and DDB5476 evaluation boards. What: Support for NEC DDB5074 and DDB5476 evaluation boards. When: June 2006 Why: Board specific code doesn't build anymore since ~2.6.0 and no users have complained indicating there is no more need for these boards. This should really be considered a last call. Who: Ralf Baechle --- Documentation/feature-removal-schedule.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index be5ae600f533..81bc51369f59 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -180,3 +180,12 @@ Why: These events are not correct, and do not properly let userspace know when a file system has been mounted or unmounted. Userspace should poll the /proc/mounts file instead to detect this properly. Who: Greg Kroah-Hartman + +--------------------------- + +What: Support for NEC DDB5074 and DDB5476 evaluation boards. +When: June 2006 +Why: Board specific code doesn't build anymore since ~2.6.0 and no + users have complained indicating there is no more need for these + boards. This should really be considered a last call. +Who: Ralf Baechle From cec2f0ca29fe99eec5e4012e5fb341fce64e578b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 3 Mar 2006 17:35:15 +0000 Subject: [PATCH 134/178] [MIPS] A struct console.setup function may not be __init. Signed-off-by: Ralf Baechle --- arch/mips/arc/arc_con.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/arc/arc_con.c b/arch/mips/arc/arc_con.c index 51785a6a7328..bc32fe64f42a 100644 --- a/arch/mips/arc/arc_con.c +++ b/arch/mips/arc/arc_con.c @@ -24,7 +24,7 @@ static void prom_console_write(struct console *co, const char *s, } } -static int __init prom_console_setup(struct console *co, char *options) +static int prom_console_setup(struct console *co, char *options) { return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE); } From ec28f3065795ed3be7413368efd7f63d7b81e82d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 5 Mar 2006 00:45:33 +0000 Subject: [PATCH 135/178] [MIPS] Enable highmem for all MIPS32 and MIPS64 processors. In case a particular system doesn't support highmem the runtime checks will ensure nothing bad is going to happen. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 767de847b4ab..3a0f89d2c8dc 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1053,6 +1053,7 @@ config CPU_MIPS32_R1 depends on SYS_HAS_CPU_MIPS32_R1 select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL + select CPU_SUPPORTS_HIGHMEM help Choose this option to build a kernel for release 1 or later of the MIPS32 architecture. Most modern embedded systems with a 32-bit @@ -1069,6 +1070,7 @@ config CPU_MIPS32_R2 depends on SYS_HAS_CPU_MIPS32_R2 select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL + select CPU_SUPPORTS_HIGHMEM help Choose this option to build a kernel for release 2 or later of the MIPS32 architecture. Most modern embedded systems with a 32-bit @@ -1082,6 +1084,7 @@ config CPU_MIPS64_R1 select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HIGHMEM help Choose this option to build a kernel for release 1 or later of the MIPS64 architecture. Many modern embedded systems with a 64-bit @@ -1099,6 +1102,7 @@ config CPU_MIPS64_R2 select CPU_HAS_PREFETCH select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL + select CPU_SUPPORTS_HIGHMEM help Choose this option to build a kernel for release 2 or later of the MIPS64 architecture. Many modern embedded systems with a 64-bit From bb7d83f74477b41a2dee71771805c8447cdaa70f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 8 Mar 2006 14:13:04 +0000 Subject: [PATCH 136/178] [MIPS] Discard .exit.text at runtime. At times gcc will place bits of __exit functions into .rodata. If compiled into the kernle itself we used to discard .exit.text - but not the bits left in .rodata. While harmless this did at times result in a large number of warnings. So until gcc fixes this, discard .exit.text at runtime. Signed-off-by: Ralf Baechle --- arch/mips/kernel/vmlinux.lds.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index ff699dbb99f7..2ad0cedf29fe 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -106,6 +106,9 @@ SECTIONS .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT + /* .exit.text is discarded at runtime, not link time, to deal with + references from .rodata */ + .exit.text : { *(.exit.text) } . = ALIGN(_PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } @@ -133,7 +136,6 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.exit.text) *(.exit.data) *(.exitcall.exit) From 3367fd50757459ae7490b9dfa59b60fedc283821 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 8 Mar 2006 14:22:27 +0000 Subject: [PATCH 137/178] [MIPS] Momentum: Resurrect after things were moved around a while ago. Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq-mv6434x.c | 8 +++++--- arch/mips/momentum/jaguar_atx/prom.c | 2 +- arch/mips/momentum/jaguar_atx/setup.c | 5 +++-- arch/mips/momentum/ocelot_c/irq.c | 2 +- arch/mips/momentum/ocelot_c/prom.c | 2 +- arch/mips/momentum/ocelot_c/setup.c | 27 ++++++++++++++------------- arch/mips/pci/pci-ocelot-c.c | 6 ++++-- 7 files changed, 29 insertions(+), 23 deletions(-) diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 0ac067f45cf5..0613f1f36b1b 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -11,12 +11,14 @@ #include #include #include -#include -#include #include +#include +#include + +#include #include #include -#include +#include static unsigned int irq_base; diff --git a/arch/mips/momentum/jaguar_atx/prom.c b/arch/mips/momentum/jaguar_atx/prom.c index aae7a802767a..1cadaa92946a 100644 --- a/arch/mips/momentum/jaguar_atx/prom.c +++ b/arch/mips/momentum/jaguar_atx/prom.c @@ -21,10 +21,10 @@ #include #include #include +#include #include #include -#include #include #include "jaguar_atx_fpga.h" diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c index 301d67226d72..2699917b640a 100644 --- a/arch/mips/momentum/jaguar_atx/setup.c +++ b/arch/mips/momentum/jaguar_atx/setup.c @@ -2,7 +2,7 @@ * BRIEF MODULE DESCRIPTION * Momentum Computer Jaguar-ATX board dependent boot routines * - * Copyright (C) 1996, 1997, 2001, 2004 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 1996, 1997, 2001, 04, 06 Ralf Baechle (ralf@linux-mips.org) * Copyright (C) 2000 RidgeRun, Inc. * Copyright (C) 2001 Red Hat, Inc. * Copyright (C) 2002 Momentum Computer @@ -55,6 +55,8 @@ #include #include #include +#include + #include #include #include @@ -64,7 +66,6 @@ #include #include #include -#include #include "jaguar_atx_fpga.h" diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c index 300fe8e4fbe8..a5764bc20e36 100644 --- a/arch/mips/momentum/ocelot_c/irq.c +++ b/arch/mips/momentum/ocelot_c/irq.c @@ -41,11 +41,11 @@ #include #include #include +#include #include #include #include #include -#include #include extern asmlinkage void ocelot_handle_int(void); diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c index 5b6809724b15..e92364482c7b 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c @@ -19,10 +19,10 @@ #include #include #include +#include #include #include -#include #include #include "ocelot_c_fpga.h" diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 15998d8a9341..bd02e60d037a 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -64,9 +65,9 @@ #include #include #include +#include #include #include -#include #include "ocelot_c_fpga.h" unsigned long marvell_base; @@ -252,22 +253,22 @@ void __init plat_setup(void) /* shut down ethernet ports, just to be sure our memory doesn't get * corrupted by random ethernet traffic. */ - MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); - MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); - MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); - MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); + MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); + MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); do {} - while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); + while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); do {} - while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); + while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); do {} - while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); + while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); do {} - while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); - MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), - MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); - MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), - MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); + while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); + MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0), + MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); + MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1), + MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); /* Turn off the Bit-Error LED */ OCELOT_FPGA_WRITE(0x80, CLR); diff --git a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c index 1d84d36e034d..027759f7c904 100644 --- a/arch/mips/pci/pci-ocelot-c.c +++ b/arch/mips/pci/pci-ocelot-c.c @@ -3,15 +3,17 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2004, 06 by Ralf Baechle (ralf@linux-mips.org) */ #include #include -#include +#include #include +#include + /* * We assume the address ranges have already been setup appropriately by * the firmware. PMON in case of the Ocelot C does that. From 1443e483e34d2ead97215bd8496b34b0d3fbc2c0 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 8 Mar 2006 15:37:26 +0000 Subject: [PATCH 138/178] [MIPS] Scatter a bunch of __init over tlbex.c. Found by make buildcheck. Signed-off-by: Ralf Baechle --- arch/mips/mm/tlbex.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 0f9485806bac..ac4f4bfaae50 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -280,69 +280,69 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...) } #define I_u1u2u3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, unsigned int c) \ { \ build_insn(buf, insn##op, a, b, c); \ } #define I_u2u1u3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, unsigned int c) \ { \ build_insn(buf, insn##op, b, a, c); \ } #define I_u3u1u2(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, unsigned int c) \ { \ build_insn(buf, insn##op, b, c, a); \ } #define I_u1u2s3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, signed int c) \ { \ build_insn(buf, insn##op, a, b, c); \ } #define I_u2s3u1(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ signed int b, unsigned int c) \ { \ build_insn(buf, insn##op, c, a, b); \ } #define I_u2u1s3(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b, signed int c) \ { \ build_insn(buf, insn##op, b, a, c); \ } #define I_u1u2(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ unsigned int b) \ { \ build_insn(buf, insn##op, a, b); \ } #define I_u1s2(op) \ - static inline void i##op(u32 **buf, unsigned int a, \ + static inline void __init i##op(u32 **buf, unsigned int a, \ signed int b) \ { \ build_insn(buf, insn##op, a, b); \ } #define I_u1(op) \ - static inline void i##op(u32 **buf, unsigned int a) \ + static inline void __init i##op(u32 **buf, unsigned int a) \ { \ build_insn(buf, insn##op, a); \ } #define I_0(op) \ - static inline void i##op(u32 **buf) \ + static inline void __init i##op(u32 **buf) \ { \ build_insn(buf, insn##op); \ } @@ -623,42 +623,42 @@ static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel, } /* convenience functions for labeled branches */ -static void __attribute__((unused)) il_bltz(u32 **p, struct reloc **r, - unsigned int reg, enum label_id l) +static void __init __attribute__((unused)) + il_bltz(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) { r_mips_pc16(r, *p, l); i_bltz(p, reg, 0); } -static void __attribute__((unused)) il_b(u32 **p, struct reloc **r, +static void __init __attribute__((unused)) il_b(u32 **p, struct reloc **r, enum label_id l) { r_mips_pc16(r, *p, l); i_b(p, 0); } -static void il_beqz(u32 **p, struct reloc **r, unsigned int reg, +static void __init il_beqz(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) { r_mips_pc16(r, *p, l); i_beqz(p, reg, 0); } -static void __attribute__((unused)) +static void __init __attribute__((unused)) il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) { r_mips_pc16(r, *p, l); i_beqzl(p, reg, 0); } -static void il_bnez(u32 **p, struct reloc **r, unsigned int reg, +static void __init il_bnez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) { r_mips_pc16(r, *p, l); i_bnez(p, reg, 0); } -static void il_bgezl(u32 **p, struct reloc **r, unsigned int reg, +static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) { r_mips_pc16(r, *p, l); From fd2a4f1183d1e6802457d70cea067396236ed64b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 8 Mar 2006 16:04:32 +0000 Subject: [PATCH 139/178] [MIPS] Undefine scr_writew and scr_readw in . This is gluing the build of cirrusfb but really the mess that would need cleaning and fixing is