From: Linus Torvalds Date: Wed, 7 Mar 2007 01:32:45 +0000 (-0800) Subject: Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa X-Git-Tag: firefly_0821_release~30770 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cba5a641ca7887dc371486681dac887869d1c7b7;hp=6185af1f4254a53563fe6d6af652f5775fc70e25;p=firefly-linux-kernel-4.4.55.git Merge branch 'linus' of /linux/kernel/git/perex/alsa * 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: [ALSA] version 1.0.14rc3 [ALSA] cmipci - Allow to disable integrated FM port [ALSA] hda-codec - Fix logic error in headphone mute for Conexant codecs [ALSA] hda-codec - Add missing Mic Boost for AD1986A codec [ALSA] ac97 - Add Thinkpad X31 and R40 to AD1981x blacklist [ALSA] Add missing sysfs device assignment for ALSA PCI drivers [ALSA] hda-codec - Define pin configs for MacBooks [ALSA] hda-codec - Add missing Mic Boost controls for ALC262 [ALSA] soc - WM9712 PCM volume [ALSA] soc - Fix WM9712 register cache entry [ALSA] hda-codec - Add method for configuring Mac Pro without PCI SSID [ALSA] hda-codec - Add LFE support on Dell M90 --- diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 03eb5ed503f7..6e92ba61f7c0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1685,6 +1685,22 @@ and is between 256 and 4096 characters. It is defined in the file stifb= [HW] Format: bpp:[:[:...]] + sunrpc.pool_mode= + [NFS] + Control how the NFS server code allocates CPUs to + service thread pools. Depending on how many NICs + you have and where their interrupts are bound, this + option will affect which CPUs will do NFS serving. + Note: this parameter cannot be changed while the + NFS server is running. + + auto the server chooses an appropriate mode + automatically using heuristics + global a single global pool contains all CPUs + percpu one pool for each CPU + pernode one pool for each NUMA node (equivalent + to global on non-NUMA machines) + swiotlb= [IA-64] Number of I/O TLB slabs switches= [HW,M68k] diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index 875d8a6ecc02..602660df455c 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -24,7 +24,6 @@ * an extra value to store the TSC freq */ unsigned int tsc_khz; -unsigned long long (*custom_sched_clock)(void); int tsc_disable; diff --git a/arch/i386/kernel/vmitime.c b/arch/i386/kernel/vmitime.c index 8dc72d575666..9dfb17739b67 100644 --- a/arch/i386/kernel/vmitime.c +++ b/arch/i386/kernel/vmitime.c @@ -123,12 +123,10 @@ static struct clocksource clocksource_vmi = { static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id); static struct irqaction vmi_timer_irq = { - vmi_timer_interrupt, - SA_INTERRUPT, - CPU_MASK_NONE, - "VMI-alarm", - NULL, - NULL + .handler = vmi_timer_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "VMI-alarm", }; /* Alarm rate */ diff --git a/arch/mips/momentum/jaguar_atx/platform.c b/arch/mips/momentum/jaguar_atx/platform.c index 771e55f39875..561844878a90 100644 --- a/arch/mips/momentum/jaguar_atx/platform.c +++ b/arch/mips/momentum/jaguar_atx/platform.c @@ -48,6 +48,8 @@ static struct resource mv64x60_eth0_resources[] = { }; static struct mv643xx_eth_platform_data eth0_pd = { + .port_number = 0, + .tx_sram_addr = MV_SRAM_BASE_ETH0, .tx_sram_size = MV_SRAM_TXRING_SIZE, .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, @@ -77,6 +79,8 @@ static struct resource mv64x60_eth1_resources[] = { }; static struct mv643xx_eth_platform_data eth1_pd = { + .port_number = 1, + .tx_sram_addr = MV_SRAM_BASE_ETH1, .tx_sram_size = MV_SRAM_TXRING_SIZE, .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, @@ -105,7 +109,9 @@ static struct resource mv64x60_eth2_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth2_pd; +static struct mv643xx_eth_platform_data eth2_pd = { + .port_number = 2, +}; static struct platform_device eth2_device = { .name = MV643XX_ETH_NAME, diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c index b80733f0c66d..44e4c3fc7403 100644 --- a/arch/mips/momentum/ocelot_3/platform.c +++ b/arch/mips/momentum/ocelot_3/platform.c @@ -48,6 +48,8 @@ static struct resource mv64x60_eth0_resources[] = { }; static struct mv643xx_eth_platform_data eth0_pd = { + .port_number = 0, + .tx_sram_addr = MV_SRAM_BASE_ETH0, .tx_sram_size = MV_SRAM_TXRING_SIZE, .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, @@ -77,6 +79,8 @@ static struct resource mv64x60_eth1_resources[] = { }; static struct mv643xx_eth_platform_data eth1_pd = { + .port_number = 1, + .tx_sram_addr = MV_SRAM_BASE_ETH1, .tx_sram_size = MV_SRAM_TXRING_SIZE, .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, @@ -105,7 +109,9 @@ static struct resource mv64x60_eth2_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth2_pd; +static struct mv643xx_eth_platform_data eth2_pd = { + .port_number = 2, +}; static struct platform_device eth2_device = { .name = MV643XX_ETH_NAME, diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c index f7cd303f3eba..7780aa0c6555 100644 --- a/arch/mips/momentum/ocelot_c/platform.c +++ b/arch/mips/momentum/ocelot_c/platform.c @@ -47,6 +47,8 @@ static struct resource mv64x60_eth0_resources[] = { }; static struct mv643xx_eth_platform_data eth0_pd = { + .port_number = 0, + .tx_sram_addr = MV_SRAM_BASE_ETH0, .tx_sram_size = MV_SRAM_TXRING_SIZE, .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, @@ -76,6 +78,8 @@ static struct resource mv64x60_eth1_resources[] = { }; static struct mv643xx_eth_platform_data eth1_pd = { + .port_number = 1, + .tx_sram_addr = MV_SRAM_BASE_ETH1, .tx_sram_size = MV_SRAM_TXRING_SIZE, .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 6ad4b1a72c96..71045677559a 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c @@ -58,6 +58,7 @@ static struct resource mv643xx_eth0_resources[] = { static struct mv643xx_eth_platform_data eth0_pd = { + .port_number = 0, .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, @@ -87,6 +88,7 @@ static struct resource mv643xx_eth1_resources[] = { }; static struct mv643xx_eth_platform_data eth1_pd = { + .port_number = 1, .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index 3b039c30a439..a6f8b686ea83 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c @@ -339,7 +339,9 @@ static struct resource mv64x60_eth0_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth0_pd; +static struct mv643xx_eth_platform_data eth0_pd = { + .port_number = 0, +}; static struct platform_device eth0_device = { .name = MV643XX_ETH_NAME, @@ -362,7 +364,9 @@ static struct resource mv64x60_eth1_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth1_pd; +static struct mv643xx_eth_platform_data eth1_pd = { + .port_number = 1, +}; static struct platform_device eth1_device = { .name = MV643XX_ETH_NAME, @@ -385,7 +389,9 @@ static struct resource mv64x60_eth2_resources[] = { }, }; -static struct mv643xx_eth_platform_data eth2_pd; +static struct mv643xx_eth_platform_data eth2_pd = { + .port_number = 2, +}; static struct platform_device eth2_device = { .name = MV643XX_ETH_NAME, diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index 2a32e5e8e9c9..3c798cdde550 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -158,12 +158,12 @@ static int kern_do_signal(struct pt_regs *regs) clear_thread_flag(TIF_RESTORE_SIGMASK); sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } - return(handled_sig); + return handled_sig; } int do_signal(void) { - return(kern_do_signal(¤t->thread.regs)); + return kern_do_signal(¤t->thread.regs); } /* @@ -186,5 +186,5 @@ long sys_sigsuspend(int history0, int history1, old_sigset_t mask) long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) { - return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs))); + return do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)); } diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 9b34fe65949a..dda06789bcb0 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -419,9 +419,12 @@ void map_stub_pages(int fd, unsigned long code, .offset = code_offset } } }); n = os_write_file(fd, &mmop, sizeof(mmop)); - if(n != sizeof(mmop)) + if(n != sizeof(mmop)){ + printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", + code, code_fd, (unsigned long long) code_offset); panic("map_stub_pages : /proc/mm map for code failed, " "err = %d\n", -n); + } if ( stack ) { __u64 map_offset; diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index 1df231a26244..d221214d2ed5 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c @@ -16,6 +16,7 @@ void usr2_handler(int sig, union uml_pt_regs *regs) CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); } +/* Initialized from linux_main() */ void (*sig_info[NSIG])(int, union uml_pt_regs *); void os_fill_handlinfo(struct kern_handlers h) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index cacb1c816e35..17ee97f3a99b 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -406,22 +406,6 @@ config BLK_DEV_RAM_BLOCKSIZE setups function - apparently needed by the rd_load_image routine that supposes the filesystem in the image uses a 1024 blocksize. -config BLK_DEV_INITRD - bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" - depends on BROKEN || !FRV - help - The initial RAM filesystem is a ramfs which is loaded by the - boot loader (loadlin or lilo) and that is mounted as root - before the normal boot procedure. It is typically used to - load modules needed to mount the "real" root file system, - etc. See for details. - - If RAM disk support (BLK_DEV_RAM) is also included, this - also enables initial RAM disk (initrd) support and adds - 15 Kbytes (more on some other architectures) to the kernel size. - - If unsure say Y. - config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media" depends on !UML diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 05dfe357527c..0c716ee905d7 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1291,13 +1291,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index) if (inq_buff == NULL) goto mem_msg; + /* testing to see if 16-byte CDBs are already being used */ + if (h->cciss_read == CCISS_READ_16) { + cciss_read_capacity_16(h->ctlr, drv_index, 1, + &total_size, &block_size); + goto geo_inq; + } + cciss_read_capacity(ctlr, drv_index, 1, &total_size, &block_size); - /* total size = last LBA + 1 */ - /* FFFFFFFF + 1 = 0, cannot have a logical volume of size 0 */ - /* so we assume this volume this must be >2TB in size */ - if (total_size == (__u32) 0) { + /* if read_capacity returns all F's this volume is >2TB in size */ + /* so we switch to 16-byte CDB's for all read/write ops */ + if (total_size == 0xFFFFFFFFULL) { cciss_read_capacity_16(ctlr, drv_index, 1, &total_size, &block_size); h->cciss_read = CCISS_READ_16; @@ -1306,6 +1312,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index) h->cciss_read = CCISS_READ_10; h->cciss_write = CCISS_WRITE_10; } +geo_inq: cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, inq_buff, &h->drv[drv_index]); @@ -1917,13 +1924,14 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, drv->raid_level = inq_buff->data_byte[8]; } drv->block_size = block_size; - drv->nr_blocks = total_size; + drv->nr_blocks = total_size + 1; t = drv->heads * drv->sectors; if (t > 1) { - unsigned rem = sector_div(total_size, t); + sector_t real_size = total_size + 1; + unsigned long rem = sector_div(real_size, t); if (rem) - total_size++; - drv->cylinders = total_size; + real_size++; + drv->cylinders = real_size; } } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); @@ -1953,16 +1961,16 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, ctlr, buf, sizeof(ReadCapdata_struct), 1, logvol, 0, NULL, TYPE_CMD); if (return_code == IO_OK) { - *total_size = be32_to_cpu(*(__u32 *) buf->total_size)+1; + *total_size = be32_to_cpu(*(__u32 *) buf->total_size); *block_size = be32_to_cpu(*(__u32 *) buf->block_size); } else { /* read capacity command failed */ printk(KERN_WARNING "cciss: read capacity failed\n"); *total_size = 0; *block_size = BLOCK_SIZE; } - if (*total_size != (__u32) 0) + if (*total_size != 0) printk(KERN_INFO " blocks= %llu block_size= %d\n", - (unsigned long long)*total_size, *block_size); + (unsigned long long)*total_size+1, *block_size); kfree(buf); return; } @@ -1989,7 +1997,7 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, 1, logvol, 0, NULL, TYPE_CMD); } if (return_code == IO_OK) { - *total_size = be64_to_cpu(*(__u64 *) buf->total_size)+1; + *total_size = be64_to_cpu(*(__u64 *) buf->total_size); *block_size = be32_to_cpu(*(__u32 *) buf->block_size); } else { /* read capacity command failed */ printk(KERN_WARNING "cciss: read capacity failed\n"); @@ -1997,7 +2005,7 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, *block_size = BLOCK_SIZE; } printk(KERN_INFO " blocks= %llu block_size= %d\n", - (unsigned long long)*total_size, *block_size); + (unsigned long long)*total_size+1, *block_size); kfree(buf); return; } @@ -3119,8 +3127,9 @@ static void cciss_getgeometry(int cntl_num) } cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); - /* total_size = last LBA + 1 */ - if(total_size == (__u32) 0) { + /* If read_capacity returns all F's the logical is >2TB */ + /* so we switch to 16-byte CDBs for all read/write ops */ + if(total_size == 0xFFFFFFFFULL) { cciss_read_capacity_16(cntl_num, i, 0, &total_size, &block_size); hba[cntl_num]->cciss_read = CCISS_READ_16; @@ -3395,7 +3404,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, return -1; } -static void __devexit cciss_remove_one(struct pci_dev *pdev) +static void cciss_remove_one(struct pci_dev *pdev) { ctlr_info_t *tmp_ptr; int i, j; @@ -3419,9 +3428,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) memset(flush_buf, 0, 4); return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL, TYPE_CMD); - if (return_code != IO_OK) { - printk(KERN_WARNING "Error Flushing cache on controller %d\n", - i); + if (return_code == IO_OK) { + printk(KERN_INFO "Completed flushing cache on controller %d\n", i); + } else { + printk(KERN_WARNING "Error flushing cache on controller %d\n", i); } free_irq(hba[i]->intr[2], hba[i]); @@ -3472,6 +3482,7 @@ static struct pci_driver cciss_pci_driver = { .probe = cciss_init_one, .remove = __devexit_p(cciss_remove_one), .id_table = cciss_pci_device_id, /* id_table */ + .shutdown = cciss_remove_one, }; /* diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index 0eb62841e9b0..6d3840e629de 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -99,9 +99,8 @@ do_crypt(void *src, void *dst, int len, u32 flags) static unsigned int geode_aes_crypt(struct geode_aes_op *op) { - u32 flags = 0; - int iflags; + unsigned long iflags; if (op->len == 0 || op->src == op->dst) return 0; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 5046a1661342..4a73e8b2428d 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -376,10 +376,11 @@ static inline void mmc_set_ios(struct mmc_host *host) { struct mmc_ios *ios = &host->ios; - pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", + pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " + "width %u timing %u\n", mmc_hostname(host), ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, ios->vdd, - ios->bus_width); + ios->bus_width, ios->timing); host->ops->set_ios(host, ios); } @@ -809,6 +810,7 @@ static void mmc_power_up(struct mmc_host *host) host->ios.chip_select = MMC_CS_DONTCARE; host->ios.power_mode = MMC_POWER_UP; host->ios.bus_width = MMC_BUS_WIDTH_1; + host->ios.timing = MMC_TIMING_LEGACY; mmc_set_ios(host); mmc_delay(1); @@ -828,6 +830,7 @@ static void mmc_power_off(struct mmc_host *host) host->ios.chip_select = MMC_CS_DONTCARE; host->ios.power_mode = MMC_POWER_OFF; host->ios.bus_width = MMC_BUS_WIDTH_1; + host->ios.timing = MMC_TIMING_LEGACY; mmc_set_ios(host); } @@ -1112,46 +1115,50 @@ static void mmc_process_ext_csds(struct mmc_host *host) continue; } - /* Activate highspeed support. */ - cmd.opcode = MMC_SWITCH; - cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (EXT_CSD_HS_TIMING << 16) | - (1 << 8) | - EXT_CSD_CMD_SET_NORMAL; - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; + if (host->caps & MMC_CAP_MMC_HIGHSPEED) { + /* Activate highspeed support. */ + cmd.opcode = MMC_SWITCH; + cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_HS_TIMING << 16) | + (1 << 8) | + EXT_CSD_CMD_SET_NORMAL; + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); - if (err != MMC_ERR_NONE) { - printk("%s: failed to switch card to mmc v4 " - "high-speed mode.\n", - mmc_hostname(card->host)); - continue; - } + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) { + printk("%s: failed to switch card to mmc v4 " + "high-speed mode.\n", + mmc_hostname(card->host)); + continue; + } - mmc_card_set_highspeed(card); + mmc_card_set_highspeed(card); - /* Check for host support for wide-bus modes. */ - if (!(host->caps & MMC_CAP_4_BIT_DATA)) { - continue; + host->ios.timing = MMC_TIMING_SD_HS; + mmc_set_ios(host); } - /* Activate 4-bit support. */ - cmd.opcode = MMC_SWITCH; - cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (EXT_CSD_BUS_WIDTH << 16) | - (EXT_CSD_BUS_WIDTH_4 << 8) | - EXT_CSD_CMD_SET_NORMAL; - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; + /* Check for host support for wide-bus modes. */ + if (host->caps & MMC_CAP_4_BIT_DATA) { + /* Activate 4-bit support. */ + cmd.opcode = MMC_SWITCH; + cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_BUS_WIDTH << 16) | + (EXT_CSD_BUS_WIDTH_4 << 8) | + EXT_CSD_CMD_SET_NORMAL; + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; - err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); - if (err != MMC_ERR_NONE) { - printk("%s: failed to switch card to " - "mmc v4 4-bit bus mode.\n", - mmc_hostname(card->host)); - continue; - } + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) { + printk("%s: failed to switch card to " + "mmc v4 4-bit bus mode.\n", + mmc_hostname(card->host)); + continue; + } - host->ios.bus_width = MMC_BUS_WIDTH_4; + host->ios.bus_width = MMC_BUS_WIDTH_4; + mmc_set_ios(host); + } } kfree(ext_csd); @@ -1241,6 +1248,9 @@ static void mmc_read_switch_caps(struct mmc_host *host) unsigned char *status; struct scatterlist sg; + if (!(host->caps & MMC_CAP_SD_HIGHSPEED)) + return; + status = kmalloc(64, GFP_KERNEL); if (!status) { printk(KERN_WARNING "%s: Unable to allocate buffer for " @@ -1332,6 +1342,9 @@ static void mmc_read_switch_caps(struct mmc_host *host) } mmc_card_set_highspeed(card); + + host->ios.timing = MMC_TIMING_SD_HS; + mmc_set_ios(host); } kfree(status); diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 7522f76b15ec..d749f08601b8 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -606,7 +606,6 @@ static void sdhci_finish_command(struct sdhci_host *host) static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) { int div; - u8 ctrl; u16 clk; unsigned long timeout; @@ -615,13 +614,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); - ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); - if (clock > 25000000) - ctrl |= SDHCI_CTRL_HISPD; - else - ctrl &= ~SDHCI_CTRL_HISPD; - writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); - if (clock == 0) goto out; @@ -761,10 +753,17 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) sdhci_set_power(host, ios->vdd); ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL); + if (ios->bus_width == MMC_BUS_WIDTH_4) ctrl |= SDHCI_CTRL_4BITBUS; else ctrl &= ~SDHCI_CTRL_4BITBUS; + + if (ios->timing == MMC_TIMING_SD_HS) + ctrl |= SDHCI_CTRL_HISPD; + else + ctrl &= ~SDHCI_CTRL_HISPD; + writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); mmiowb(); @@ -994,7 +993,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) intmask = readl(host->ioaddr + SDHCI_INT_STATUS); - if (!intmask) { + if (!intmask || intmask == 0xffffffff) { result = IRQ_NONE; goto out; } @@ -1080,6 +1079,13 @@ static int sdhci_suspend (struct pci_dev *pdev, pm_message_t state) pci_save_state(pdev); pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + + for (i = 0;i < chip->num_slots;i++) { + if (!chip->hosts[i]) + continue; + free_irq(chip->hosts[i]->irq, chip->hosts[i]); + } + pci_disable_device(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, state)); @@ -1108,6 +1114,11 @@ static int sdhci_resume (struct pci_dev *pdev) continue; if (chip->hosts[i]->flags & SDHCI_USE_DMA) pci_set_master(pdev); + ret = request_irq(chip->hosts[i]->irq, sdhci_irq, + IRQF_SHARED, chip->hosts[i]->slot_descr, + chip->hosts[i]); + if (ret) + return ret; sdhci_init(chip->hosts[i]); mmiowb(); ret = mmc_resume_host(chip->hosts[i]->mmc); @@ -1274,6 +1285,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) mmc->f_max = host->max_clk; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK; + if (caps & SDHCI_CAN_DO_HISPD) + mmc->caps |= MMC_CAP_SD_HIGHSPEED; + mmc->ocr_avail = 0; if (caps & SDHCI_CAN_VDD_330) mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34; @@ -1282,13 +1296,6 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) if (caps & SDHCI_CAN_VDD_180) mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; - if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) { - printk(KERN_ERR "%s: Controller reports > 25 MHz base clock," - " but no high speed support.\n", - host->slot_descr); - mmc->f_max = 25000000; - } - if (mmc->ocr_avail == 0) { printk(KERN_ERR "%s: Hardware doesn't report any " "support voltages.\n", host->slot_descr); diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 716a47210aa3..72995777f809 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -822,11 +822,17 @@ static int vortex_resume(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct vortex_private *vp = netdev_priv(dev); + int err; if (dev && vp) { pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); - pci_enable_device(pdev); + err = pci_enable_device(pdev); + if (err) { + printk(KERN_WARNING "%s: Could not enable device \n", + dev->name); + return err; + } pci_set_master(pdev); if (request_irq(dev->irq, vp->full_bus_master_rx ? &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) { diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ea73ebff4387..e4724d874e7c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -861,6 +862,28 @@ static void bond_mc_delete(struct bonding *bond, void *addr, int alen) } } + +/* + * Retrieve the list of registered multicast addresses for the bonding + * device and retransmit an IGMP JOIN request to the current active + * slave. + */ +static void bond_resend_igmp_join_requests(struct bonding *bond) +{ + struct in_device *in_dev; + struct ip_mc_list *im; + + rcu_read_lock(); + in_dev = __in_dev_get_rcu(bond->dev); + if (in_dev) { + for (im = in_dev->mc_list; im; im = im->next) { + ip_mc_rejoin_group(im); + } + } + + rcu_read_unlock(); +} + /* * Totally destroys the mc_list in bond */ @@ -874,6 +897,7 @@ static void bond_mc_list_destroy(struct bonding *bond) kfree(dmi); dmi = bond->mc_list; } + bond->mc_list = NULL; } /* @@ -967,6 +991,7 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) { dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); } + bond_resend_igmp_join_requests(bond); } } @@ -3423,15 +3448,21 @@ void bond_register_arp(struct bonding *bond) { struct packet_type *pt = &bond->arp_mon_pt; + if (pt->type) + return; + pt->type = htons(ETH_P_ARP); - pt->dev = NULL; /*bond->dev;XXX*/ + pt->dev = bond->dev; pt->func = bond_arp_rcv; dev_add_pack(pt); } void bond_unregister_arp(struct bonding *bond) { - dev_remove_pack(&bond->arp_mon_pt); + struct packet_type *pt = &bond->arp_mon_pt; + + dev_remove_pack(pt); + pt->type = 0; } /*---------------------------- Hashing Policies -----------------------------*/ @@ -4011,42 +4042,6 @@ out: return 0; } -static void bond_activebackup_xmit_copy(struct sk_buff *skb, - struct bonding *bond, - struct slave *slave) -{ - struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); - struct ethhdr *eth_data; - u8 *hwaddr; - int res; - - if (!skb2) { - printk(KERN_ERR DRV_NAME ": Error: " - "bond_activebackup_xmit_copy(): skb_copy() failed\n"); - return; - } - - skb2->mac.raw = (unsigned char *)skb2->data; - eth_data = eth_hdr(skb2); - - /* Pick an appropriate source MAC address - * -- use slave's perm MAC addr, unless used by bond - * -- otherwise, borrow active slave's perm MAC addr - * since that will not be used - */ - hwaddr = slave->perm_hwaddr; - if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN)) - hwaddr = bond->curr_active_slave->perm_hwaddr; - - /* Set source MAC address appropriately */ - memcpy(eth_data->h_source, hwaddr, ETH_ALEN); - - res = bond_dev_queue_xmit(bond, skb2, slave->dev); - if (res) - dev_kfree_skb(skb2); - - return; -} /* * in active-backup mode, we know that bond->curr_active_slave is always valid if @@ -4067,21 +4062,6 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d if (!bond->curr_active_slave) goto out; - /* Xmit IGMP frames on all slaves to ensure rapid fail-over - for multicast traffic on snooping switches */ - if (skb->protocol == __constant_htons(ETH_P_IP) && - skb->nh.iph->protocol == IPPROTO_IGMP) { - struct slave *slave, *active_slave; - int i; - - active_slave = bond->curr_active_slave; - bond_for_each_slave_from_to(bond, slave, i, active_slave->next, - active_slave->prev) - if (IS_UP(slave->dev) && - (slave->link == BOND_LINK_UP)) - bond_activebackup_xmit_copy(skb, bond, slave); - } - res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev); out: diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index be2ddbb6ef56..9ba21e0f27c5 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1309,7 +1309,7 @@ static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address, static int mv643xx_eth_probe(struct platform_device *pdev) { struct mv643xx_eth_platform_data *pd; - int port_num = pdev->id; + int port_num; struct mv643xx_private *mp; struct net_device *dev; u8 *p; @@ -1319,6 +1319,12 @@ static int mv643xx_eth_probe(struct platform_device *pdev) int duplex = DUPLEX_HALF; int speed = 0; /* default to auto-negotiation */ + pd = pdev->dev.platform_data; + if (pd == NULL) { + printk(KERN_ERR "No mv643xx_eth_platform_data\n"); + return -ENODEV; + } + dev = alloc_etherdev(sizeof(struct mv643xx_private)); if (!dev) return -ENOMEM; @@ -1331,8 +1337,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) BUG_ON(!res); dev->irq = res->start; - mp->port_num = port_num; - dev->open = mv643xx_eth_open; dev->stop = mv643xx_eth_stop; dev->hard_start_xmit = mv643xx_eth_start_xmit; @@ -1373,39 +1377,40 @@ static int mv643xx_eth_probe(struct platform_device *pdev) spin_lock_init(&mp->lock); + port_num = pd->port_number; + /* set default config values */ eth_port_uc_addr_get(dev, dev->dev_addr); mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE; mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE; - pd = pdev->dev.platform_data; - if (pd) { - if (is_valid_ether_addr(pd->mac_addr)) - memcpy(dev->dev_addr, pd->mac_addr, 6); + if (is_valid_ether_addr(pd->mac_addr)) + memcpy(dev->dev_addr, pd->mac_addr, 6); - if (pd->phy_addr || pd->force_phy_addr) - ethernet_phy_set(port_num, pd->phy_addr); + if (pd->phy_addr || pd->force_phy_addr) + ethernet_phy_set(port_num, pd->phy_addr); - if (pd->rx_queue_size) - mp->rx_ring_size = pd->rx_queue_size; + if (pd->rx_queue_size) + mp->rx_ring_size = pd->rx_queue_size; - if (pd->tx_queue_size) - mp->tx_ring_size = pd->tx_queue_size; + if (pd->tx_queue_size) + mp->tx_ring_size = pd->tx_queue_size; - if (pd->tx_sram_size) { - mp->tx_sram_size = pd->tx_sram_size; - mp->tx_sram_addr = pd->tx_sram_addr; - } - - if (pd->rx_sram_size) { - mp->rx_sram_size = pd->rx_sram_size; - mp->rx_sram_addr = pd->rx_sram_addr; - } + if (pd->tx_sram_size) { + mp->tx_sram_size = pd->tx_sram_size; + mp->tx_sram_addr = pd->tx_sram_addr; + } - duplex = pd->duplex; - speed = pd->speed; + if (pd->rx_sram_size) { + mp->rx_sram_size = pd->rx_sram_size; + mp->rx_sram_addr = pd->rx_sram_addr; } + duplex = pd->duplex; + speed = pd->speed; + + mp->port_num = port_num; + /* Hook up MII support for ethtool */ mp->mii.dev = dev; mp->mii.mdio_read = mv643xx_mdio_read; diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 5c57433cb306..c6172a77a6d7 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -2024,6 +2024,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) struct netdev_private *np = netdev_priv(dev); void __iomem * ioaddr = ns_ioaddr(dev); unsigned entry; + unsigned long flags; /* Note: Ordering is important here, set the field with the "ownership" bit last, and only then increment cur_tx. */ @@ -2037,7 +2038,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]); - spin_lock_irq(&np->lock); + spin_lock_irqsave(&np->lock, flags); if (!np->hands_off) { np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | skb->len); @@ -2056,7 +2057,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb_irq(skb); np->stats.tx_dropped++; } - spin_unlock_irq(&np->lock); + spin_unlock_irqrestore(&np->lock, flags); dev->trans_start = jiffies; @@ -2222,6 +2223,8 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) pkt_len = (desc_status & DescSizeMask) - 4; if ((desc_status&(DescMore|DescPktOK|DescRxLong)) != DescPktOK){ if (desc_status & DescMore) { + unsigned long flags; + if (netif_msg_rx_err(np)) printk(KERN_WARNING "%s: Oversized(?) Ethernet " @@ -2236,12 +2239,12 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) * reset procedure documented in * AN-1287. */ - spin_lock_irq(&np->lock); + spin_lock_irqsave(&np->lock, flags); reset_rx(dev); reinit_rx(dev); writel(np->ring_dma, ioaddr + RxRingPtr); check_link(dev); - spin_unlock_irq(&np->lock); + spin_unlock_irqrestore(&np->lock, flags); /* We'll enable RX on exit from this * function. */ @@ -2396,8 +2399,19 @@ static struct net_device_stats *get_stats(struct net_device *dev) #ifdef CONFIG_NET_POLL_CONTROLLER static void natsemi_poll_controller(struct net_device *dev) { + struct netdev_private *np = netdev_priv(dev); + disable_irq(dev->irq); - intr_handler(dev->irq, dev); + + /* + * A real interrupt might have already reached us at this point + * but NAPI might still haven't called us back. As the interrupt + * status register is cleared by reading, we should prevent an + * interrupt loss in this case... + */ + if (!np->intr_status) + intr_handler(dev->irq, dev); + enable_irq(dev->irq); } #endif diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 36f9d988278f..4d94ba7899bf 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1234,14 +1234,14 @@ static void pcnet32_rx_entry(struct net_device *dev, skb_put(skb, pkt_len); /* Make room */ pci_dma_sync_single_for_cpu(lp->pci_dev, lp->rx_dma_addr[entry], - PKT_BUF_SZ - 2, + pkt_len, PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, (unsigned char *)(lp->rx_skbuff[entry]->data), pkt_len, 0); pci_dma_sync_single_for_device(lp->pci_dev, lp->rx_dma_addr[entry], - PKT_BUF_SZ - 2, + pkt_len, PCI_DMA_FROMDEVICE); } lp->stats.rx_bytes += skb->len; diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index fb2b53051635..b3750f284279 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -968,10 +968,10 @@ static void mdio_write(struct net_device *net_dev, int phy_id, int location, static u16 sis900_reset_phy(struct net_device *net_dev, int phy_addr) { - int i = 0; + int i; u16 status; - while (i++ < 2) + for (i = 0; i < 2; i++) status = mdio_read(net_dev, phy_addr, MII_STATUS); mdio_write( net_dev, phy_addr, MII_CONTROL, MII_CNTL_RESET ); @@ -1430,7 +1430,7 @@ static void sis900_auto_negotiate(struct net_device *net_dev, int phy_addr) int i = 0; u32 status; - while (i++ < 2) + for (i = 0; i < 2; i++) status = mdio_read(net_dev, phy_addr, MII_STATUS); if (!(status & MII_STAT_LINK)){ @@ -1466,9 +1466,9 @@ static void sis900_read_mode(struct net_device *net_dev, int *speed, int *duplex int phy_addr = sis_priv->cur_phy; u32 status; u16 autoadv, autorec; - int i = 0; + int i; - while (i++ < 2) + for (i = 0; i < 2; i++) status = mdio_read(net_dev, phy_addr, MII_STATUS); if (!(status & MII_STAT_LINK)) diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index dacea4fd3337..c82befa209a2 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -1685,7 +1685,7 @@ static const struct ethtool_ops de_ethtool_ops = { .get_regs = de_get_regs, }; -static void __init de21040_get_mac_address (struct de_private *de) +static void __devinit de21040_get_mac_address (struct de_private *de) { unsigned i; @@ -1703,7 +1703,7 @@ static void __init de21040_get_mac_address (struct de_private *de) } } -static void __init de21040_get_media_info(struct de_private *de) +static void __devinit de21040_get_media_info(struct de_private *de) { unsigned int i; @@ -1765,7 +1765,7 @@ static unsigned __devinit tulip_read_eeprom(void __iomem *regs, int location, in return retval; } -static void __init de21041_get_srom_info (struct de_private *de) +static void __devinit de21041_get_srom_info (struct de_private *de) { unsigned i, sa_offset = 0, ofs; u8 ee_data[DE_EEPROM_SIZE + 6] = {}; diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 7f59a3d4fda2..24a29c99ba94 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -143,9 +143,16 @@ #define DMFE_TX_TIMEOUT ((3*HZ)/2) /* tx packet time-out time 1.5 s" */ #define DMFE_TX_KICK (HZ/2) /* tx packet Kick-out time 0.5 s" */ -#define DMFE_DBUG(dbug_now, msg, value) if (dmfe_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value)) +#define DMFE_DBUG(dbug_now, msg, value) \ + do { \ + if (dmfe_debug || (dbug_now)) \ + printk(KERN_ERR DRV_NAME ": %s %lx\n",\ + (msg), (long) (value)); \ + } while (0) -#define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half"); +#define SHOW_MEDIA_TYPE(mode) \ + printk (KERN_INFO DRV_NAME ": Change Speed to %sMhz %s duplex\n" , \ + (mode & 1) ? "100":"10", (mode & 4) ? "full":"half"); /* CR9 definition: SROM/MII */ @@ -163,10 +170,20 @@ #define SROM_V41_CODE 0x14 -#define SROM_CLK_WRITE(data, ioaddr) outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5); +#define SROM_CLK_WRITE(data, ioaddr) \ + outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \ + udelay(5); \ + outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr); \ + udelay(5); \ + outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \ + udelay(5); + +#define __CHK_IO_SIZE(pci_id, dev_rev) \ + (( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? \ + DM9102A_IO_SIZE: DM9102_IO_SIZE) -#define __CHK_IO_SIZE(pci_id, dev_rev) ( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? DM9102A_IO_SIZE: DM9102_IO_SIZE -#define CHK_IO_SIZE(pci_dev, dev_rev) __CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev) +#define CHK_IO_SIZE(pci_dev, dev_rev) \ + (__CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev)) /* Sten Check */ #define DEVICE net_device @@ -187,7 +204,7 @@ struct rx_desc { struct dmfe_board_info { u32 chip_id; /* Chip vendor/Device ID */ u32 chip_revision; /* Chip revision */ - struct DEVICE *dev; /* net device */ + struct DEVICE *next_dev; /* next device */ struct pci_dev *pdev; /* PCI device */ spinlock_t lock; @@ -231,7 +248,6 @@ struct dmfe_board_info { u8 media_mode; /* user specify media mode */ u8 op_mode; /* real work media mode */ u8 phy_addr; - u8 link_failed; /* Ever link failed */ u8 wait_reset; /* Hardware failed, need to reset */ u8 dm910x_chk_mode; /* Operating mode check */ u8 first_in_callback; /* Flag to record state */ @@ -329,7 +345,7 @@ static void dmfe_program_DM9802(struct dmfe_board_info *); static void dmfe_HPNA_remote_cmd_chk(struct dmfe_board_info * ); static void dmfe_set_phyxcer(struct dmfe_board_info *); -/* DM910X network baord routine ---------------------------- */ +/* DM910X network board routine ---------------------------- */ /* * Search DM910X board ,allocate space and register it @@ -356,7 +372,8 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, SET_NETDEV_DEV(dev, &pdev->dev); if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { - printk(KERN_WARNING DRV_NAME ": 32-bit PCI DMA not available.\n"); + printk(KERN_WARNING DRV_NAME + ": 32-bit PCI DMA not available.\n"); err = -ENODEV; goto err_out_free; } @@ -399,11 +416,12 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, /* Init system & device */ db = netdev_priv(dev); - db->dev = dev; - /* Allocate Tx/Rx descriptor memory */ - db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr); - db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, &db->buf_pool_dma_ptr); + db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * + DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr); + + db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * + TX_DESC_CNT + 4, &db->buf_pool_dma_ptr); db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr; db->first_tx_desc_dma = db->desc_pool_dma_ptr; @@ -428,7 +446,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, dev->poll_controller = &poll_dmfe; #endif dev->ethtool_ops = &netdev_ethtool_ops; - netif_carrier_off(db->dev); + netif_carrier_off(dev); spin_lock_init(&db->lock); pci_read_config_dword(pdev, 0x50, &pci_pmr); @@ -440,7 +458,8 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, /* read 64 word srom data */ for (i = 0; i < 64; i++) - ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr, i)); + ((u16 *) db->srom)[i] = + cpu_to_le16(read_srom_word(db->ioaddr, i)); /* Set Node address */ for (i = 0; i < 6; i++) @@ -482,14 +501,17 @@ static void __devexit dmfe_remove_one (struct pci_dev *pdev) DMFE_DBUG(0, "dmfe_remove_one()", 0); if (dev) { + + unregister_netdev(dev); + pci_free_consistent(db->pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, db->desc_pool_ptr, db->desc_pool_dma_ptr); pci_free_consistent(db->pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, db->buf_pool_ptr, db->buf_pool_dma_ptr); - unregister_netdev(dev); pci_release_regions(pdev); free_netdev(dev); /* free board information */ + pci_set_drvdata(pdev, NULL); } @@ -509,7 +531,8 @@ static int dmfe_open(struct DEVICE *dev) DMFE_DBUG(0, "dmfe_open", 0); - ret = request_irq(dev->irq, &dmfe_interrupt, IRQF_SHARED, dev->name, dev); + ret = request_irq(dev->irq, &dmfe_interrupt, + IRQF_SHARED, dev->name, dev); if (ret) return ret; @@ -518,7 +541,6 @@ static int dmfe_open(struct DEVICE *dev) db->tx_packet_cnt = 0; db->tx_queue_cnt = 0; db->rx_avail_cnt = 0; - db->link_failed = 1; db->wait_reset = 0; db->first_in_callback = 0; @@ -650,7 +672,8 @@ static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev) /* No Tx resource check, it never happen nromally */ if (db->tx_queue_cnt >= TX_FREE_DESC_CNT) { spin_unlock_irqrestore(&db->lock, flags); - printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n", db->tx_queue_cnt); + printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n", + db->tx_queue_cnt); return 1; } @@ -722,7 +745,8 @@ static int dmfe_stop(struct DEVICE *dev) #if 0 /* show statistic counter */ - printk(DRV_NAME ": FU:%lx EC:%lx LC:%lx NC:%lx LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n", + printk(DRV_NAME ": FU:%lx EC:%lx LC:%lx NC:%lx" + " LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n", db->tx_fifo_underrun, db->tx_excessive_collision, db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier, db->tx_jabber_timeout, db->reset_count, db->reset_cr8, @@ -905,7 +929,7 @@ static inline u32 cal_CRC(unsigned char * Data, unsigned int Len, u8 flag) static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) { struct rx_desc *rxptr; - struct sk_buff *skb; + struct sk_buff *skb, *newskb; int rxlen; u32 rdes0; @@ -919,7 +943,9 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) db->rx_avail_cnt--; db->interval_rx_cnt++; - pci_unmap_single(db->pdev, le32_to_cpu(rxptr->rdes2), RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE); + pci_unmap_single(db->pdev, le32_to_cpu(rxptr->rdes2), + RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE); + if ( (rdes0 & 0x300) != 0x300) { /* A packet without First/Last flag */ /* reuse this SKB */ @@ -956,9 +982,11 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) } else { /* Good packet, send to upper layer */ /* Shorst packet used new SKB */ - if ( (rxlen < RX_COPY_SIZE) && - ( (skb = dev_alloc_skb(rxlen + 2) ) - != NULL) ) { + if ((rxlen < RX_COPY_SIZE) && + ((newskb = dev_alloc_skb(rxlen + 2)) + != NULL)) { + + skb = newskb; /* size less than COPY_SIZE, allocate a rxlen SKB */ skb->dev = dev; skb_reserve(skb, 2); /* 16byte align */ @@ -1069,6 +1097,8 @@ static void dmfe_timer(unsigned long data) struct dmfe_board_info *db = netdev_priv(dev); unsigned long flags; + int link_ok, link_ok_phy; + DMFE_DBUG(0, "dmfe_timer()", 0); spin_lock_irqsave(&db->lock, flags); @@ -1078,7 +1108,8 @@ static void dmfe_timer(unsigned long data) if (db->chip_type && (db->chip_id==PCI_DM9102_ID)) { db->cr6_data &= ~0x40000; update_cr6(db->cr6_data, db->ioaddr); - phy_write(db->ioaddr, db->phy_addr, 0, 0x1000, db->chip_id); + phy_write(db->ioaddr, + db->phy_addr, 0, 0x1000, db->chip_id); db->cr6_data |= 0x40000; update_cr6(db->cr6_data, db->ioaddr); db->timer.expires = DMFE_TIMER_WUT + HZ * 2; @@ -1139,21 +1170,41 @@ static void dmfe_timer(unsigned long data) (db->chip_revision == 0x02000010)) ) { /* DM9102A Chip */ if (tmp_cr12 & 2) - tmp_cr12 = 0x0; /* Link failed */ + link_ok = 0; else - tmp_cr12 = 0x3; /* Link OK */ + link_ok = 1; } + else + /*0x43 is used instead of 0x3 because bit 6 should represent + link status of external PHY */ + link_ok = (tmp_cr12 & 0x43) ? 1 : 0; + + + /* If chip reports that link is failed it could be because external + PHY link status pin is not conected correctly to chip + To be sure ask PHY too. + */ + + /* need a dummy read because of PHY's register latch*/ + phy_read (db->ioaddr, db->phy_addr, 1, db->chip_id); + link_ok_phy = (phy_read (db->ioaddr, + db->phy_addr, 1, db->chip_id) & 0x4) ? 1 : 0; - if ( !(tmp_cr12 & 0x3) && !db->link_failed ) { + if (link_ok_phy != link_ok) { + DMFE_DBUG (0, "PHY and chip report different link status", 0); + link_ok = link_ok | link_ok_phy; + } + + if ( !link_ok && netif_carrier_ok(dev)) { /* Link Failed */ DMFE_DBUG(0, "Link Failed", tmp_cr12); - db->link_failed = 1; - netif_carrier_off(db->dev); + netif_carrier_off(dev); /* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */ /* AUTO or force 1M Homerun/Longrun don't need */ if ( !(db->media_mode & 0x38) ) - phy_write(db->ioaddr, db->phy_addr, 0, 0x1000, db->chip_id); + phy_write(db->ioaddr, db->phy_addr, + 0, 0x1000, db->chip_id); /* AUTO mode, if INT phyxcer link failed, select EXT device */ if (db->media_mode & DMFE_AUTO) { @@ -1162,21 +1213,19 @@ static void dmfe_timer(unsigned long data) db->cr6_data&=~0x00000200; /* bit9=0, HD mode */ update_cr6(db->cr6_data, db->ioaddr); } - } else - if ((tmp_cr12 & 0x3) && db->link_failed) { - DMFE_DBUG(0, "Link link OK", tmp_cr12); - db->link_failed = 0; - - /* Auto Sense Speed */ - if ( (db->media_mode & DMFE_AUTO) && - dmfe_sense_speed(db) ) - db->link_failed = 1; - else - netif_carrier_on(db->dev); - dmfe_process_mode(db); - /* SHOW_MEDIA_TYPE(db->op_mode); */ + } else if (!netif_carrier_ok(dev)) { + + DMFE_DBUG(0, "Link link OK", tmp_cr12); + + /* Auto Sense Speed */ + if ( !(db->media_mode & DMFE_AUTO) || !dmfe_sense_speed(db)) { + netif_carrier_on(dev); + SHOW_MEDIA_TYPE(db->op_mode); } + dmfe_process_mode(db); + } + /* HPNA remote command check */ if (db->HPNA_command & 0xf00) { db->HPNA_timer--; @@ -1221,7 +1270,7 @@ static void dmfe_dynamic_reset(struct DEVICE *dev) db->tx_packet_cnt = 0; db->tx_queue_cnt = 0; db->rx_avail_cnt = 0; - db->link_failed = 1; + netif_carrier_off(dev); db->wait_reset = 0; /* Re-initilize DM910X board */ @@ -1259,7 +1308,8 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb) if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) { rxptr->rx_skb_ptr = skb; - rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); + rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, + skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); wmb(); rxptr->rdes0 = cpu_to_le32(0x80000000); db->rx_avail_cnt++; @@ -1291,8 +1341,11 @@ static void dmfe_descriptor_init(struct dmfe_board_info *db, unsigned long ioadd outl(db->first_tx_desc_dma, ioaddr + DCR4); /* TX DESC address */ /* rx descriptor start pointer */ - db->first_rx_desc = (void *)db->first_tx_desc + sizeof(struct tx_desc) * TX_DESC_CNT; - db->first_rx_desc_dma = db->first_tx_desc_dma + sizeof(struct tx_desc) * TX_DESC_CNT; + db->first_rx_desc = (void *)db->first_tx_desc + + sizeof(struct tx_desc) * TX_DESC_CNT; + + db->first_rx_desc_dma = db->first_tx_desc_dma + + sizeof(struct tx_desc) * TX_DESC_CNT; db->rx_insert_ptr = db->first_rx_desc; db->rx_ready_ptr = db->first_rx_desc; outl(db->first_rx_desc_dma, ioaddr + DCR3); /* RX DESC address */ @@ -1470,7 +1523,8 @@ static void allocate_rx_buffer(struct dmfe_board_info *db) if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) break; rxptr->rx_skb_ptr = skb; /* FIXME (?) */ - rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); + rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, + RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); wmb(); rxptr->rdes0 = cpu_to_le32(0x80000000); rxptr = rxptr->next_rx_desc; @@ -1510,7 +1564,8 @@ static u16 read_srom_word(long ioaddr, int offset) for (i = 16; i > 0; i--) { outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr); udelay(5); - srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0); + srom_data = (srom_data << 1) | + ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0); outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); udelay(5); } @@ -1537,9 +1592,11 @@ static u8 dmfe_sense_speed(struct dmfe_board_info * db) if ( (phy_mode & 0x24) == 0x24 ) { if (db->chip_id == PCI_DM9132_ID) /* DM9132 */ - phy_mode = phy_read(db->ioaddr, db->phy_addr, 7, db->chip_id) & 0xf000; + phy_mode = phy_read(db->ioaddr, + db->phy_addr, 7, db->chip_id) & 0xf000; else /* DM9102/DM9102A */ - phy_mode = phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id) & 0xf000; + phy_mode = phy_read(db->ioaddr, + db->phy_addr, 17, db->chip_id) & 0xf000; /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */ switch (phy_mode) { case 0x1000: db->op_mode = DMFE_10MHF; break; @@ -1576,8 +1633,11 @@ static void dmfe_set_phyxcer(struct dmfe_board_info *db) /* DM9009 Chip: Phyxcer reg18 bit12=0 */ if (db->chip_id == PCI_DM9009_ID) { - phy_reg = phy_read(db->ioaddr, db->phy_addr, 18, db->chip_id) & ~0x1000; - phy_write(db->ioaddr, db->phy_addr, 18, phy_reg, db->chip_id); + phy_reg = phy_read(db->ioaddr, + db->phy_addr, 18, db->chip_id) & ~0x1000; + + phy_write(db->ioaddr, + db->phy_addr, 18, phy_reg, db->chip_id); } /* Phyxcer capability setting */ @@ -1650,10 +1710,12 @@ static void dmfe_process_mode(struct dmfe_board_info *db) case DMFE_100MHF: phy_reg = 0x2000; break; case DMFE_100MFD: phy_reg = 0x2100; break; } - phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id); + phy_write(db->ioaddr, + db->phy_addr, 0, phy_reg, db->chip_id); if ( db->chip_type && (db->chip_id == PCI_DM9102_ID) ) mdelay(20); - phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id); + phy_write(db->ioaddr, + db->phy_addr, 0, phy_reg, db->chip_id); } } } @@ -1663,7 +1725,8 @@ static void dmfe_process_mode(struct dmfe_board_info *db) * Write a word to Phy register */ -static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data, u32 chip_id) +static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, + u16 phy_data, u32 chip_id) { u16 i; unsigned long ioaddr; @@ -1689,11 +1752,13 @@ static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data /* Send Phy address */ for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); + phy_write_1bit(ioaddr, + phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); /* Send register address */ for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0); + phy_write_1bit(ioaddr, + offset & i ? PHY_DATA_1 : PHY_DATA_0); /* written trasnition */ phy_write_1bit(ioaddr, PHY_DATA_1); @@ -1701,7 +1766,8 @@ static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data /* Write a word data to PHY controller */ for ( i = 0x8000; i > 0; i >>= 1) - phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0); + phy_write_1bit(ioaddr, + phy_data & i ? PHY_DATA_1 : PHY_DATA_0); } } @@ -1738,11 +1804,13 @@ static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id) /* Send Phy address */ for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); + phy_write_1bit(ioaddr, + phy_addr & i ? PHY_DATA_1 : PHY_DATA_0); /* Send register address */ for (i = 0x10; i > 0; i = i >> 1) - phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0); + phy_write_1bit(ioaddr, + offset & i ? PHY_DATA_1 : PHY_DATA_0); /* Skip transition state */ phy_read_1bit(ioaddr); @@ -1963,7 +2031,8 @@ static void dmfe_HPNA_remote_cmd_chk(struct dmfe_board_info * db) /* Check remote device status match our setting ot not */ if ( phy_reg != (db->HPNA_command & 0x0f00) ) { - phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command, db->chip_id); + phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command, + db->chip_id); db->HPNA_timer=8; } else db->HPNA_timer=600; /* Match, every 10 minutes, check */ @@ -2003,8 +2072,11 @@ module_param(HPNA_tx_cmd, byte, 0); module_param(HPNA_NoiseFloor, byte, 0); module_param(SF_mode, byte, 0); MODULE_PARM_DESC(debug, "Davicom DM9xxx enable debugging (0-1)"); -MODULE_PARM_DESC(mode, "Davicom DM9xxx: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA"); -MODULE_PARM_DESC(SF_mode, "Davicom DM9xxx special function (bit 0: VLAN, bit 1 Flow Control, bit 2: TX pause packet)"); +MODULE_PARM_DESC(mode, "Davicom DM9xxx: " + "Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA"); + +MODULE_PARM_DESC(SF_mode, "Davicom DM9xxx special function " + "(bit 0: VLAN, bit 1 Flow Control, bit 2: TX pause packet)"); /* Description: * when user used insmod to add module, system invoked init_module() diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 885e73d731c2..dab88b958d6e 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3598,17 +3598,20 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Move to next BD in the ring */ if (!(bd_status & T_W)) - ugeth->txBd[txQ] = bd + sizeof(struct qe_bd); + bd += sizeof(struct qe_bd); else - ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ]; + bd = ugeth->p_tx_bd_ring[txQ]; /* If the next BD still needs to be cleaned up, then the bds are full. We need to tell the kernel to stop sending us stuff. */ if (bd == ugeth->confBd[txQ]) { if (!netif_queue_stopped(dev)) netif_stop_queue(dev); + return NETDEV_TX_BUSY; } + ugeth->txBd[txQ] = bd; + if (ugeth->p_scheduler) { ugeth->cpucount[txQ]++; /* Indicate to QE that there are more Tx bds ready for @@ -3620,7 +3623,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irq(&ugeth->lock); - return 0; + return NETDEV_TX_OK; } static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) @@ -3722,7 +3725,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd = ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) break; ugeth->stats.tx_packets++; @@ -3741,10 +3744,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Advance the confirmation BD pointer */ if (!(bd_status & T_W)) - ugeth->confBd[txQ] += sizeof(struct qe_bd); + bd += sizeof(struct qe_bd); else - ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ]; + bd = ugeth->p_tx_bd_ring[txQ]; + bd_status = in_be32((u32 *)bd); } + ugeth->confBd[txQ] = bd; return 0; } diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index b8f0a11e8f31..7f5a59836818 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -677,8 +677,6 @@ config FB_S1D13XXX config FB_NVIDIA tristate "nVidia Framebuffer Support" depends on FB && PCI - select I2C_ALGOBIT if FB_NVIDIA_I2C - select I2C if FB_NVIDIA_I2C select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT select FB_MODE_HELPERS select FB_CFB_FILLRECT @@ -697,6 +695,7 @@ config FB_NVIDIA config FB_NVIDIA_I2C bool "Enable DDC Support" depends on FB_NVIDIA + select FB_DDC help This enables I2C support for nVidia Chipsets. This is used only for getting EDID information from the attached display @@ -716,7 +715,6 @@ config FB_NVIDIA_BACKLIGHT config FB_RIVA tristate "nVidia Riva support" depends on FB && PCI - select FB_DDC if FB_RIVA_I2C select FB_BACKLIGHT if FB_RIVA_BACKLIGHT select FB_MODE_HELPERS select FB_CFB_FILLRECT @@ -734,6 +732,7 @@ config FB_RIVA config FB_RIVA_I2C bool "Enable DDC Support" depends on FB_RIVA + select FB_DDC help This enables I2C support for nVidia Chipsets. This is used only for getting EDID information from the attached display @@ -812,8 +811,6 @@ config FB_INTEL depends on FB && EXPERIMENTAL && PCI && X86 select AGP select AGP_INTEL - select I2C_ALGOBIT if FB_INTEL_I2C - select I2C if FB_INTEL_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -846,6 +843,7 @@ config FB_INTEL_DEBUG config FB_INTEL_I2C bool "DDC/I2C for Intel framebuffer support" depends on FB_INTEL + select FB_DDC default y help Say Y here if you want DDC/I2C support for your on-board Intel graphics. @@ -924,8 +922,8 @@ config FB_MATROX_G config FB_MATROX_I2C tristate "Matrox I2C support" - depends on FB_MATROX && I2C - select I2C_ALGOBIT + depends on FB_MATROX + select FB_DDC ---help--- This drivers creates I2C buses which are needed for accessing the DDC (I2C) bus present on all Matroxes, an I2C bus which @@ -993,7 +991,6 @@ config FB_MATROX_MULTIHEAD config FB_RADEON tristate "ATI Radeon display support" depends on FB && PCI - select FB_DDC if FB_RADEON_I2C select FB_BACKLIGHT if FB_RADEON_BACKLIGHT select FB_MODE_HELPERS select FB_CFB_FILLRECT @@ -1018,6 +1015,7 @@ config FB_RADEON config FB_RADEON_I2C bool "DDC/I2C for ATI Radeon support" depends on FB_RADEON + select FB_DDC default y help Say Y here if you want DDC/I2C support for your Radeon board. @@ -1125,7 +1123,6 @@ config FB_S3 config FB_SAVAGE tristate "S3 Savage support" depends on FB && PCI && EXPERIMENTAL - select FB_DDC if FB_SAVAGE_I2C select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA @@ -1142,6 +1139,7 @@ config FB_SAVAGE config FB_SAVAGE_I2C bool "Enable DDC2 Support" depends on FB_SAVAGE + select FB_DDC help This enables I2C support for S3 Savage Chipsets. This is used only for getting EDID information from the attached display diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index f72faff33c0c..dc62f8e282b4 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h @@ -284,7 +284,8 @@ static inline void aty_st_8(int regindex, u8 val, const struct atyfb_par *par) #endif } -#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || defined (CONFIG_FB_ATY_GENERIC_LCD) +#if defined(CONFIG_PM) || defined(CONFIG_PMAC_BACKLIGHT) || \ +defined (CONFIG_FB_ATY_GENERIC_LCD) || defined (CONFIG_FB_ATY_BACKLIGHT) extern void aty_st_lcd(int index, u32 val, const struct atyfb_par *par); extern u32 aty_ld_lcd(int index, const struct atyfb_par *par); #endif diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index a50b303093a7..43f62d8ee41d 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c @@ -12,6 +12,11 @@ #include #include #include + +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif + #include "nv_local.h" #include "nv_type.h" #include "nv_proto.h" diff --git a/fs/buffer.c b/fs/buffer.c index e8504b65176c..1d0852fa728b 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2365,6 +2365,10 @@ failed: } EXPORT_SYMBOL(nobh_prepare_write); +/* + * Make sure any changes to nobh_commit_write() are reflected in + * nobh_truncate_page(), since it doesn't call commit_write(). + */ int nobh_commit_write(struct file *file, struct page *page, unsigned from, unsigned to) { @@ -2466,6 +2470,11 @@ int nobh_truncate_page(struct address_space *mapping, loff_t from) memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); + /* + * It would be more correct to call aops->commit_write() + * here, but this is more efficient. + */ + SetPageUptodate(page); set_page_dirty(page); } unlock_page(page); diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 5fe13593b57f..6247628bdaed 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,10 @@ +Verison 1.48 +------------ +Fix mtime bouncing around from local idea of last write times to remote time. +Fix hang (in i_size_read) when simultaneous size update of same remote file +on smp system corrupts sequence number. Do not reread unnecessarily partial page +(which we are about to overwrite anyway) when writing out file opened rw. + Version 1.47 ------------ Fix oops in list_del during mount caused by unaligned string. diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index a26f26ed5a17..6ecd9d6ba3f3 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_CIFS) += cifs.o -cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o +cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o diff --git a/fs/cifs/TODO b/fs/cifs/TODO index 68372946dc92..d7b9c27c942d 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO @@ -18,7 +18,9 @@ better) d) Kerberos/SPNEGO session setup support - (started) -e) NTLMv2 authentication (mostly implemented) +e) NTLMv2 authentication (mostly implemented - double check +that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in +fs/cifs/connect.c) f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM @@ -88,11 +90,12 @@ w) Finish up the dos time conversion routines needed to return old server time to the client (default time, of now or time 0 is used now for these very old servers) -x) Add support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers) +x) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers) +need to add ability to set time to server (utimes command) y) Finish testing of Windows 9x/Windows ME server support (started). -KNOWN BUGS (updated April 29, 2005) +KNOWN BUGS (updated February 26, 2007) ==================================== See http://bugzilla.samba.org - search on product "CifsVFS" for current bug list. @@ -107,11 +110,6 @@ but recognizes them succeed but still return access denied (appears to be Windows server not cifs client problem) and has not been reproduced recently. NTFS partitions do not have this problem. -4) debug connectathon lock test case 10 which fails against -Samba (may be unmappable due to POSIX to Windows lock model -differences but worth investigating). Also debug Samba to -see why lock test case 7 takes longer to complete to Samba -than to Windows. Misc testing to do ================== @@ -119,7 +117,7 @@ Misc testing to do types. Try nested symlinks (8 deep). Return max path name in stat -f information 2) Modify file portion of ltp so it can run against a mounted network -share and run it against cifs vfs. +share and run it against cifs vfs in automated fashion. 3) Additional performance testing and optimization using iozone and similar - there are some easy changes that can be done to parallelize sequential writes, diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index bc2c0ac27169..faba4d69fe91 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1,7 +1,7 @@ /* * fs/cifs/cifsfs.c * - * Copyright (C) International Business Machines Corp., 2002,2004 + * Copyright (C) International Business Machines Corp., 2002,2007 * Author(s): Steve French (sfrench@us.ibm.com) * * Common Internet FileSystem (CIFS) client @@ -47,7 +47,11 @@ #ifdef CONFIG_CIFS_QUOTA static struct quotactl_ops cifs_quotactl_ops; -#endif +#endif /* QUOTA */ + +#ifdef CONFIG_CIFS_EXPERIMENTAL +extern struct export_operations cifs_export_ops; +#endif /* EXPERIMENTAL */ int cifsFYI = 0; int cifsERROR = 1; @@ -62,8 +66,8 @@ unsigned int extended_security = CIFSSEC_DEF; unsigned int sign_CIFS_PDUs = 1; extern struct task_struct * oplockThread; /* remove sparse warning */ struct task_struct * oplockThread = NULL; -extern struct task_struct * dnotifyThread; /* remove sparse warning */ -struct task_struct * dnotifyThread = NULL; +/* extern struct task_struct * dnotifyThread; remove sparse warning */ +static struct task_struct * dnotifyThread = NULL; static const struct super_operations cifs_super_ops; unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; module_param(CIFSMaxBufSize, int, 0); @@ -110,6 +114,10 @@ cifs_read_super(struct super_block *sb, void *data, sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_op = &cifs_super_ops; +#ifdef CONFIG_CIFS_EXPERIMENTAL + if(experimEnabled != 0) + sb->s_export_op = &cifs_export_ops; +#endif /* EXPERIMENTAL */ /* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ #ifdef CONFIG_CIFS_QUOTA diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index c97c08eb481a..2c2c384894d8 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -38,8 +38,8 @@ extern const struct address_space_operations cifs_addr_ops_smallbuf; /* Functions related to super block operations */ /* extern const struct super_operations cifs_super_ops;*/ extern void cifs_read_inode(struct inode *); -extern void cifs_delete_inode(struct inode *); -/* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */ +/*extern void cifs_delete_inode(struct inode *);*/ /* BB not needed yet */ +/* extern void cifs_write_inode(struct inode *); */ /* BB not needed yet */ /* Functions related to inodes */ extern const struct inode_operations cifs_dir_inode_ops; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 74d3ccbb103b..e4de8eba4780 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -525,15 +525,17 @@ require use of the stronger protocol */ */ GLOBAL_EXTERN struct smbUidInfo *GlobalUidList[UID_HASH]; -GLOBAL_EXTERN struct list_head GlobalServerList; /* BB not implemented yet */ +/* GLOBAL_EXTERN struct list_head GlobalServerList; BB not implemented yet */ GLOBAL_EXTERN struct list_head GlobalSMBSessionList; GLOBAL_EXTERN struct list_head GlobalTreeConnectionList; GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */ GLOBAL_EXTERN struct list_head GlobalOplock_Q; -GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */ -GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q;/* DirNotify response queue */ +/* Outstanding dir notify requests */ +GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; +/* DirNotify response queue */ +GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* * Global transaction id (XID) information diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 2498d644827c..0efdf35aab2c 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -220,6 +220,9 @@ */ #define CIFS_NO_HANDLE 0xFFFF +#define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL +#define NO_CHANGE_32 0xFFFFFFFFUL + /* IPC$ in ASCII */ #define CIFS_IPC_RESOURCE "\x49\x50\x43\x24" diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 6148b82170c4..32eb1acab630 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -43,7 +43,7 @@ extern void _FreeXid(unsigned int); #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,(int)rc));} extern char *build_path_from_dentry(struct dentry *); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); -extern void renew_parental_timestamps(struct dentry *direntry); +/* extern void renew_parental_timestamps(struct dentry *direntry);*/ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, struct smb_hdr * /* input */ , struct smb_hdr * /* out */ , diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 24364106b8f9..48fc0c2ab0e5 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -4803,6 +4803,16 @@ setPermsRetry: pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; + /* Samba server ignores set of file size to zero due to bugs in some + older clients, but we should be precise - we use SetFileSize to + set file size and do not want to truncate file size to zero + accidently as happened on one Samba server beta by putting + zero instead of -1 here */ + data_offset->EndOfFile = NO_CHANGE_64; + data_offset->NumOfBytes = NO_CHANGE_64; + data_offset->LastStatusChange = NO_CHANGE_64; + data_offset->LastAccessTime = NO_CHANGE_64; + data_offset->LastModificationTime = NO_CHANGE_64; data_offset->Uid = cpu_to_le64(uid); data_offset->Gid = cpu_to_le64(gid); /* better to leave device as zero when it is */ diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 66b825ade3e1..3fad638d26d3 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -31,7 +31,7 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" -void +static void renew_parental_timestamps(struct dentry *direntry) { /* BB check if there is a way to get the kernel to do this or if we really need this */ diff --git a/fs/cifs/export.c b/fs/cifs/export.c new file mode 100644 index 000000000000..1d716392c3aa --- /dev/null +++ b/fs/cifs/export.c @@ -0,0 +1,52 @@ +/* + * fs/cifs/export.c + * + * Copyright (C) International Business Machines Corp., 2007 + * Author(s): Steve French (sfrench@us.ibm.com) + * + * Common Internet FileSystem (CIFS) client + * + * Operations related to support for exporting files via NFSD + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + /* + * See Documentation/filesystems/Exporting + * and examples in fs/exportfs + */ + +#include + +#ifdef CONFIG_CIFS_EXPERIMENTAL + +static struct dentry *cifs_get_parent(struct dentry *dentry) +{ + /* BB need to add code here eventually to enable export via NFSD */ + return ERR_PTR(-EACCES); +} + +struct export_operations cifs_export_ops = { + .get_parent = cifs_get_parent, +/* Following five export operations are unneeded so far and can default */ +/* .get_dentry = + .get_name = + .find_exported_dentry = + .decode_fh = + .encode_fs = */ + }; + +#endif /* EXPERIMENTAL */ + diff --git a/fs/cifs/file.c b/fs/cifs/file.c index a1265c9bfec0..2d3275bedb55 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -879,18 +879,19 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, cifs_stats_bytes_written(pTcon, total_written); /* since the write may have blocked check these pointers again */ - if (file->f_path.dentry) { - if (file->f_path.dentry->d_inode) { - struct inode *inode = file->f_path.dentry->d_inode; - inode->i_ctime = inode->i_mtime = - current_fs_time(inode->i_sb); - if (total_written > 0) { - if (*poffset > file->f_path.dentry->d_inode->i_size) - i_size_write(file->f_path.dentry->d_inode, + if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { + struct inode *inode = file->f_path.dentry->d_inode; +/* Do not update local mtime - server will set its actual value on write + * inode->i_ctime = inode->i_mtime = + * current_fs_time(inode->i_sb);*/ + if (total_written > 0) { + spin_lock(&inode->i_lock); + if (*poffset > file->f_path.dentry->d_inode->i_size) + i_size_write(file->f_path.dentry->d_inode, *poffset); - } - mark_inode_dirty_sync(file->f_path.dentry->d_inode); + spin_unlock(&inode->i_lock); } + mark_inode_dirty_sync(file->f_path.dentry->d_inode); } FreeXid(xid); return total_written; @@ -1012,18 +1013,18 @@ static ssize_t cifs_write(struct file *file, const char *write_data, cifs_stats_bytes_written(pTcon, total_written); /* since the write may have blocked check these pointers again */ - if (file->f_path.dentry) { - if (file->f_path.dentry->d_inode) { + if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { /*BB We could make this contingent on superblock ATIME flag too */ -/* file->f_path.dentry->d_inode->i_ctime = - file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;*/ - if (total_written > 0) { - if (*poffset > file->f_path.dentry->d_inode->i_size) - i_size_write(file->f_path.dentry->d_inode, - *poffset); - } - mark_inode_dirty_sync(file->f_path.dentry->d_inode); +/* file->f_path.dentry->d_inode->i_ctime = + file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;*/ + if (total_written > 0) { + spin_lock(&file->f_path.dentry->d_inode->i_lock); + if (*poffset > file->f_path.dentry->d_inode->i_size) + i_size_write(file->f_path.dentry->d_inode, + *poffset); + spin_unlock(&file->f_path.dentry->d_inode->i_lock); } + mark_inode_dirty_sync(file->f_path.dentry->d_inode); } FreeXid(xid); return total_written; @@ -1400,6 +1401,7 @@ static int cifs_commit_write(struct file *file, struct page *page, xid = GetXid(); cFYI(1, ("commit write for page %p up to position %lld for %d", page, position, to)); + spin_lock(&inode->i_lock); if (position > inode->i_size) { i_size_write(inode, position); /* if (file->private_data == NULL) { @@ -1429,6 +1431,7 @@ static int cifs_commit_write(struct file *file, struct page *page, cFYI(1, (" SetEOF (commit write) rc = %d", rc)); } */ } + spin_unlock(&inode->i_lock); if (!PageUptodate(page)) { position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset; /* can not rely on (or let) writepage write this data */ @@ -1989,34 +1992,52 @@ static int cifs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { int rc = 0; - loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; + loff_t i_size; + loff_t offset; + cFYI(1, ("prepare write for page %p from %d to %d",page,from,to)); - if (!PageUptodate(page)) { - /* if (to - from != PAGE_CACHE_SIZE) { - void *kaddr = kmap_atomic(page, KM_USER0); + if (PageUptodate(page)) + return 0; + + /* If we are writing a full page it will be up to date, + no need to read from the server */ + if ((to == PAGE_CACHE_SIZE) && (from == 0)) { + SetPageUptodate(page); + return 0; + } + + offset = (loff_t)page->index << PAGE_CACHE_SHIFT; + i_size = i_size_read(page->mapping->host); + + if ((offset >= i_size) || + ((from == 0) && (offset + to) >= i_size)) { + /* + * We don't need to read data beyond the end of the file. + * zero it, and set the page uptodate + */ + void *kaddr = kmap_atomic(page, KM_USER0); + + if (from) memset(kaddr, 0, from); + if (to < PAGE_CACHE_SIZE) memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); - flush_dcache_page(page); - kunmap_atomic(kaddr, KM_USER0); - } */ - /* If we are writing a full page it will be up to date, - no need to read from the server */ - if ((to == PAGE_CACHE_SIZE) && (from == 0)) - SetPageUptodate(page); - + flush_dcache_page(page); + kunmap_atomic(kaddr, KM_USER0); + SetPageUptodate(page); + } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) { /* might as well read a page, it is fast enough */ - if ((file->f_flags & O_ACCMODE) != O_WRONLY) { - rc = cifs_readpage_worker(file, page, &offset); - } else { - /* should we try using another file handle if there is one - - how would we lock it to prevent close of that handle - racing with this read? - In any case this will be written out by commit_write */ - } + rc = cifs_readpage_worker(file, page, &offset); + } else { + /* we could try using another file handle if there is one - + but how would we lock it to prevent close of that handle + racing with this read? In any case + this will be written out by commit_write so is fine */ } - /* BB should we pass any errors back? - e.g. if we do not have read access to the file */ + /* we do not need to pass errors back + e.g. if we do not have read access to the file + because cifs_commit_write will do the right thing. -- shaggy */ + return 0; } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 37c6ce87416b..86b9dbbd8441 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -143,10 +143,10 @@ int cifs_get_inode_info_unix(struct inode **pinode, inode->i_gid = le64_to_cpu(findData.Gid); inode->i_nlink = le64_to_cpu(findData.Nlinks); + spin_lock(&inode->i_lock); if (is_size_safe_to_change(cifsInfo, end_of_file)) { /* can not safely change the file size here if the client is writing to it due to potential races */ - i_size_write(inode, end_of_file); /* blksize needs to be multiple of two. So safer to default to @@ -162,6 +162,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* for this calculation */ inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; } + spin_unlock(&inode->i_lock); if (num_of_bytes < end_of_file) cFYI(1, ("allocation size less than end of file")); @@ -496,6 +497,8 @@ int cifs_get_inode_info(struct inode **pinode, /* BB add code here - validate if device or weird share or device type? */ } + + spin_lock(&inode->i_lock); if (is_size_safe_to_change(cifsInfo, le64_to_cpu(pfindData->EndOfFile))) { /* can not safely shrink the file size here if the client is writing to it due to potential races */ @@ -506,6 +509,7 @@ int cifs_get_inode_info(struct inode **pinode, inode->i_blocks = (512 - 1 + le64_to_cpu( pfindData->AllocationSize)) >> 9; } + spin_unlock(&inode->i_lock); inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); @@ -834,8 +838,10 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) if (!rc) { drop_nlink(inode); + spin_lock(&direntry->d_inode->i_lock); i_size_write(direntry->d_inode,0); clear_nlink(direntry->d_inode); + spin_unlock(&direntry->d_inode->i_lock); } cifsInode = CIFS_I(direntry->d_inode); @@ -1128,6 +1134,52 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from) return rc; } +static int cifs_vmtruncate(struct inode * inode, loff_t offset) +{ + struct address_space *mapping = inode->i_mapping; + unsigned long limit; + + spin_lock(&inode->i_lock); + if (inode->i_size < offset) + goto do_expand; + /* + * truncation of in-use swapfiles is disallowed - it would cause + * subsequent swapout to scribble on the now-freed blocks. + */ + if (IS_SWAPFILE(inode)) { + spin_unlock(&inode->i_lock); + goto out_busy; + } + i_size_write(inode, offset); + spin_unlock(&inode->i_lock); + unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); + truncate_inode_pages(mapping, offset); + goto out_truncate; + +do_expand: + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; + if (limit != RLIM_INFINITY && offset > limit) { + spin_unlock(&inode->i_lock); + goto out_sig; + } + if (offset > inode->i_sb->s_maxbytes) { + spin_unlock(&inode->i_lock); + goto out_big; + } + i_size_write(inode, offset); + spin_unlock(&inode->i_lock); +out_truncate: + if (inode->i_op && inode->i_op->truncate) + inode->i_op->truncate(inode); + return 0; +out_sig: + send_sig(SIGXFSZ, current, 0); +out_big: + return -EFBIG; +out_busy: + return -ETXTBSY; +} + int cifs_setattr(struct dentry *direntry, struct iattr *attrs) { int xid; @@ -1244,7 +1296,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) */ if (rc == 0) { - rc = vmtruncate(direntry->d_inode, attrs->ia_size); + rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size); cifs_truncate_page(direntry->d_inode->i_mapping, direntry->d_inode->i_size); } else @@ -1379,9 +1431,11 @@ cifs_setattr_exit: return rc; } +#if 0 void cifs_delete_inode(struct inode *inode) { cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode)); /* may have to add back in if and when safe distributed caching of directories added e.g. via FindNotify */ } +#endif diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index c444798f0740..44cfb528797d 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -3,7 +3,7 @@ * * Directory search handling * - * Copyright (C) International Business Machines Corp., 2004, 2005 + * Copyright (C) International Business Machines Corp., 2004, 2007 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -226,6 +226,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, atomic_set(&cifsInfo->inUse, 1); } + spin_lock(&tmp_inode->i_lock); if (is_size_safe_to_change(cifsInfo, end_of_file)) { /* can not safely change the file size here if the client is writing to it due to potential races */ @@ -235,6 +236,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, /* for this calculation, even though the reported blocksize is larger */ tmp_inode->i_blocks = (512 - 1 + allocation_size) >> 9; } + spin_unlock(&tmp_inode->i_lock); if (allocation_size < end_of_file) cFYI(1, ("May be sparse file, allocation less than file size")); @@ -355,6 +357,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode, tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); + spin_lock(&tmp_inode->i_lock); if (is_size_safe_to_change(cifsInfo, end_of_file)) { /* can not safely change the file size here if the client is writing to it due to potential races */ @@ -364,6 +367,7 @@ static void unix_fill_in_inode(struct inode *tmp_inode, /* for this calculation, not the real blocksize */ tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; } + spin_unlock(&tmp_inode->i_lock); if (S_ISREG(tmp_inode->i_mode)) { cFYI(1, ("File inode")); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index f80007eaebf4..5f468459a1e2 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -499,7 +499,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, due to last connection to this server being unmounted */ if (signal_pending(current)) { /* if signal pending do not hold up user for full smb timeout - but we still give response a change to complete */ + but we still give response a chance to complete */ timeout = 2 * HZ; } @@ -587,7 +587,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, } out: - DeleteMidQEntry(midQ); atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); @@ -681,7 +680,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, due to last connection to this server being unmounted */ if (signal_pending(current)) { /* if signal pending do not hold up user for full smb timeout - but we still give response a change to complete */ + but we still give response a chance to complete */ timeout = 2 * HZ; } @@ -765,7 +764,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, } out: - DeleteMidQEntry(midQ); atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 14939ddf74f1..7285c94956c4 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -576,6 +576,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) server->packet = vmalloc(NCP_PACKET_SIZE); if (server->packet == NULL) goto out_nls; + server->txbuf = vmalloc(NCP_PACKET_SIZE); + if (server->txbuf == NULL) + goto out_packet; + server->rxbuf = vmalloc(NCP_PACKET_SIZE); + if (server->rxbuf == NULL) + goto out_txbuf; sock->sk->sk_data_ready = ncp_tcp_data_ready; sock->sk->sk_error_report = ncp_tcp_error_report; @@ -597,7 +603,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) error = ncp_connect(server); ncp_unlock_server(server); if (error < 0) - goto out_packet; + goto out_rxbuf; DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb)); error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */ @@ -666,8 +672,12 @@ out_disconnect: ncp_lock_server(server); ncp_disconnect(server); ncp_unlock_server(server); -out_packet: +out_rxbuf: ncp_stop_tasks(server); + vfree(server->rxbuf); +out_txbuf: + vfree(server->txbuf); +out_packet: vfree(server->packet); out_nls: #ifdef CONFIG_NCPFS_NLS @@ -723,6 +733,8 @@ static void ncp_put_super(struct super_block *sb) kfree(server->priv.data); kfree(server->auth.object_name); + vfree(server->rxbuf); + vfree(server->txbuf); vfree(server->packet); sb->s_fs_info = NULL; kfree(server); diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index e496d8b65e92..e37df8d5fe70 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -55,10 +56,11 @@ static int _send(struct socket *sock, const void *buff, int len) struct ncp_request_reply { struct list_head req; wait_queue_head_t wq; - struct ncp_reply_header* reply_buf; + atomic_t refs; + unsigned char* reply_buf; size_t datalen; int result; - enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE } status; + enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; struct kvec* tx_ciov; size_t tx_totallen; size_t tx_iovlen; @@ -67,6 +69,32 @@ struct ncp_request_reply { u_int32_t sign[6]; }; +static inline struct ncp_request_reply* ncp_alloc_req(void) +{ + struct ncp_request_reply *req; + + req = kmalloc(sizeof(struct ncp_request_reply), GFP_KERNEL); + if (!req) + return NULL; + + init_waitqueue_head(&req->wq); + atomic_set(&req->refs, (1)); + req->status = RQ_IDLE; + + return req; +} + +static void ncp_req_get(struct ncp_request_reply *req) +{ + atomic_inc(&req->refs); +} + +static void ncp_req_put(struct ncp_request_reply *req) +{ + if (atomic_dec_and_test(&req->refs)) + kfree(req); +} + void ncp_tcp_data_ready(struct sock *sk, int len) { struct ncp_server *server = sk->sk_user_data; @@ -101,14 +129,17 @@ void ncpdgram_timeout_call(unsigned long v) schedule_work(&server->timeout_tq); } -static inline void ncp_finish_request(struct ncp_request_reply *req, int result) +static inline void ncp_finish_request(struct ncp_server *server, struct ncp_request_reply *req, int result) { req->result = result; + if (req->status != RQ_ABANDONED) + memcpy(req->reply_buf, server->rxbuf, req->datalen); req->status = RQ_DONE; wake_up_all(&req->wq); + ncp_req_put(req); } -static void __abort_ncp_connection(struct ncp_server *server, struct ncp_request_reply *aborted, int err) +static void __abort_ncp_connection(struct ncp_server *server) { struct ncp_request_reply *req; @@ -118,31 +149,19 @@ static void __abort_ncp_connection(struct ncp_server *server, struct ncp_request req = list_entry(server->tx.requests.next, struct ncp_request_reply, req); list_del_init(&req->req); - if (req == aborted) { - ncp_finish_request(req, err); - } else { - ncp_finish_request(req, -EIO); - } + ncp_finish_request(server, req, -EIO); } req = server->rcv.creq; if (req) { server->rcv.creq = NULL; - if (req == aborted) { - ncp_finish_request(req, err); - } else { - ncp_finish_request(req, -EIO); - } + ncp_finish_request(server, req, -EIO); server->rcv.ptr = NULL; server->rcv.state = 0; } req = server->tx.creq; if (req) { server->tx.creq = NULL; - if (req == aborted) { - ncp_finish_request(req, err); - } else { - ncp_finish_request(req, -EIO); - } + ncp_finish_request(server, req, -EIO); } } @@ -160,10 +179,12 @@ static inline void __ncp_abort_request(struct ncp_server *server, struct ncp_req break; case RQ_QUEUED: list_del_init(&req->req); - ncp_finish_request(req, err); + ncp_finish_request(server, req, err); break; case RQ_INPROGRESS: - __abort_ncp_connection(server, req, err); + req->status = RQ_ABANDONED; + break; + case RQ_ABANDONED: break; } } @@ -177,7 +198,7 @@ static inline void ncp_abort_request(struct ncp_server *server, struct ncp_reque static inline void __ncptcp_abort(struct ncp_server *server) { - __abort_ncp_connection(server, NULL, 0); + __abort_ncp_connection(server); } static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req) @@ -294,6 +315,11 @@ static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_r static inline void __ncp_start_request(struct ncp_server *server, struct ncp_request_reply *req) { + /* we copy the data so that we do not depend on the caller + staying alive */ + memcpy(server->txbuf, req->tx_iov[1].iov_base, req->tx_iov[1].iov_len); + req->tx_iov[1].iov_base = server->txbuf; + if (server->ncp_sock->type == SOCK_STREAM) ncptcp_start_request(server, req); else @@ -308,6 +334,7 @@ static int ncp_add_request(struct ncp_server *server, struct ncp_request_reply * printk(KERN_ERR "ncpfs: tcp: Server died\n"); return -EIO; } + ncp_req_get(req); if (server->tx.creq || server->rcv.creq) { req->status = RQ_QUEUED; list_add_tail(&req->req, &server->tx.requests); @@ -409,7 +436,7 @@ void ncpdgram_rcv_proc(struct work_struct *work) server->timeout_last = NCP_MAX_RPC_TIMEOUT; mod_timer(&server->timeout_tm, jiffies + NCP_MAX_RPC_TIMEOUT); } else if (reply.type == NCP_REPLY) { - result = _recv(sock, (void*)req->reply_buf, req->datalen, MSG_DONTWAIT); + result = _recv(sock, server->rxbuf, req->datalen, MSG_DONTWAIT); #ifdef CONFIG_NCPFS_PACKET_SIGNING if (result >= 0 && server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) { if (result < 8 + 8) { @@ -419,7 +446,7 @@ void ncpdgram_rcv_proc(struct work_struct *work) result -= 8; hdrl = sock->sk->sk_family == AF_INET ? 8 : 6; - if (sign_verify_reply(server, ((char*)req->reply_buf) + hdrl, result - hdrl, cpu_to_le32(result), ((char*)req->reply_buf) + result)) { + if (sign_verify_reply(server, server->rxbuf + hdrl, result - hdrl, cpu_to_le32(result), server->rxbuf + result)) { printk(KERN_INFO "ncpfs: Signature violation\n"); result = -EIO; } @@ -428,7 +455,7 @@ void ncpdgram_rcv_proc(struct work_struct *work) #endif del_timer(&server->timeout_tm); server->rcv.creq = NULL; - ncp_finish_request(req, result); + ncp_finish_request(server, req, result); __ncp_next_request(server); mutex_unlock(&server->rcv.creq_mutex); continue; @@ -478,12 +505,6 @@ void ncpdgram_timeout_proc(struct work_struct *work) mutex_unlock(&server->rcv.creq_mutex); } -static inline void ncp_init_req(struct ncp_request_reply* req) -{ - init_waitqueue_head(&req->wq); - req->status = RQ_IDLE; -} - static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) { int result; @@ -601,8 +622,8 @@ skipdata:; goto skipdata; } req->datalen = datalen - 8; - req->reply_buf->type = NCP_REPLY; - server->rcv.ptr = (unsigned char*)(req->reply_buf) + 2; + ((struct ncp_reply_header*)server->rxbuf)->type = NCP_REPLY; + server->rcv.ptr = server->rxbuf + 2; server->rcv.len = datalen - 10; server->rcv.state = 1; break; @@ -615,12 +636,12 @@ skipdata:; case 1: req = server->rcv.creq; if (req->tx_type != NCP_ALLOC_SLOT_REQUEST) { - if (req->reply_buf->sequence != server->sequence) { + if (((struct ncp_reply_header*)server->rxbuf)->sequence != server->sequence) { printk(KERN_ERR "ncpfs: tcp: Bad sequence number\n"); __ncp_abort_request(server, req, -EIO); return -EIO; } - if ((req->reply_buf->conn_low | (req->reply_buf->conn_high << 8)) != server->connection) { + if ((((struct ncp_reply_header*)server->rxbuf)->conn_low | (((struct ncp_reply_header*)server->rxbuf)->conn_high << 8)) != server->connection) { printk(KERN_ERR "ncpfs: tcp: Connection number mismatch\n"); __ncp_abort_request(server, req, -EIO); return -EIO; @@ -628,14 +649,14 @@ skipdata:; } #ifdef CONFIG_NCPFS_PACKET_SIGNING if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) { - if (sign_verify_reply(server, (unsigned char*)(req->reply_buf) + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) { + if (sign_verify_reply(server, server->rxbuf + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) { printk(KERN_ERR "ncpfs: tcp: Signature violation\n"); __ncp_abort_request(server, req, -EIO); return -EIO; } } #endif - ncp_finish_request(req, req->datalen); + ncp_finish_request(server, req, req->datalen); nextreq:; __ncp_next_request(server); case 2: @@ -645,7 +666,7 @@ skipdata:; server->rcv.state = 0; break; case 3: - ncp_finish_request(server->rcv.creq, -EIO); + ncp_finish_request(server, server->rcv.creq, -EIO); goto nextreq; case 5: info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len); @@ -675,28 +696,39 @@ void ncp_tcp_tx_proc(struct work_struct *work) } static int do_ncp_rpc_call(struct ncp_server *server, int size, - struct ncp_reply_header* reply_buf, int max_reply_size) + unsigned char* reply_buf, int max_reply_size) { int result; - struct ncp_request_reply req; - - ncp_init_req(&req); - req.reply_buf = reply_buf; - req.datalen = max_reply_size; - req.tx_iov[1].iov_base = server->packet; - req.tx_iov[1].iov_len = size; - req.tx_iovlen = 1; - req.tx_totallen = size; - req.tx_type = *(u_int16_t*)server->packet; - - result = ncp_add_request(server, &req); - if (result < 0) { - return result; - } - if (wait_event_interruptible(req.wq, req.status == RQ_DONE)) { - ncp_abort_request(server, &req, -EIO); + struct ncp_request_reply *req; + + req = ncp_alloc_req(); + if (!req) + return -ENOMEM; + + req->reply_buf = reply_buf; + req->datalen = max_reply_size; + req->tx_iov[1].iov_base = server->packet; + req->tx_iov[1].iov_len = size; + req->tx_iovlen = 1; + req->tx_totallen = size; + req->tx_type = *(u_int16_t*)server->packet; + + result = ncp_add_request(server, req); + if (result < 0) + goto out; + + if (wait_event_interruptible(req->wq, req->status == RQ_DONE)) { + ncp_abort_request(server, req, -EINTR); + result = -EINTR; + goto out; } - return req.result; + + result = req->result; + +out: + ncp_req_put(req); + + return result; } /* @@ -751,11 +783,6 @@ static int ncp_do_request(struct ncp_server *server, int size, DDPRINTK("do_ncp_rpc_call returned %d\n", result); - if (result < 0) { - /* There was a problem with I/O, so the connections is - * no longer usable. */ - ncp_invalidate_conn(server); - } return result; } diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 8813990304fe..85a668680f82 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -431,6 +431,8 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) new_parent_dentry = new_parent ? new_parent->dentry : sysfs_mount->mnt_sb->s_root; + if (old_parent_dentry->d_inode == new_parent_dentry->d_inode) + return 0; /* nothing to move */ again: mutex_lock(&old_parent_dentry->d_inode->i_mutex); if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { diff --git a/include/asm-i386/tsc.h b/include/asm-i386/tsc.h index e997891cc7cc..84016ff481b9 100644 --- a/include/asm-i386/tsc.h +++ b/include/asm-i386/tsc.h @@ -1 +1,67 @@ -#include +/* + * linux/include/asm-i386/tsc.h + * + * i386 TSC related functions + */ +#ifndef _ASM_i386_TSC_H +#define _ASM_i386_TSC_H + +#include + +/* + * Standard way to access the cycle counter. + */ +typedef unsigned long long cycles_t; + +extern unsigned int cpu_khz; +extern unsigned int tsc_khz; + +static inline cycles_t get_cycles(void) +{ + unsigned long long ret = 0; + +#ifndef CONFIG_X86_TSC + if (!cpu_has_tsc) + return 0; +#endif + +#if defined(CONFIG_X86_GENERIC) || defined(CONFIG_X86_TSC) + rdtscll(ret); +#endif + return ret; +} + +/* Like get_cycles, but make sure the CPU is synchronized. */ +static __always_inline cycles_t get_cycles_sync(void) +{ + unsigned long long ret; +#ifdef X86_FEATURE_SYNC_RDTSC + unsigned eax; + + /* + * Don't do an additional sync on CPUs where we know + * RDTSC is already synchronous: + */ + alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC, + "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); +#else + sync_core(); +#endif + rdtscll(ret); + + return ret; +} + +extern void tsc_init(void); +extern void mark_tsc_unstable(void); +extern int unsynchronized_tsc(void); +extern void init_tsc_clocksource(void); + +/* + * Boot-time check whether the TSCs are synchronized across + * all CPUs/cores: + */ +extern void check_tsc_sync_source(int cpu); +extern void check_tsc_sync_target(void); + +#endif diff --git a/include/asm-i386/vmi_time.h b/include/asm-i386/vmi_time.h index 1f971eb7f71e..94d0a12a4114 100644 --- a/include/asm-i386/vmi_time.h +++ b/include/asm-i386/vmi_time.h @@ -61,6 +61,14 @@ extern void apic_vmi_timer_interrupt(void); #ifdef CONFIG_NO_IDLE_HZ extern int vmi_stop_hz_timer(void); extern void vmi_account_time_restart_hz_timer(void); +#else +static inline int vmi_stop_hz_timer(void) +{ + return 0; +} +static inline void vmi_account_time_restart_hz_timer(void) +{ +} #endif /* diff --git a/include/asm-x86_64/tsc.h b/include/asm-x86_64/tsc.h index 26c3e9828288..d66ba6ef25f6 100644 --- a/include/asm-x86_64/tsc.h +++ b/include/asm-x86_64/tsc.h @@ -1,67 +1 @@ -/* - * linux/include/asm-x86_64/tsc.h - * - * x86_64 TSC related functions - */ -#ifndef _ASM_x86_64_TSC_H -#define _ASM_x86_64_TSC_H - -#include - -/* - * Standard way to access the cycle counter. - */ -typedef unsigned long long cycles_t; - -extern unsigned int cpu_khz; -extern unsigned int tsc_khz; - -static inline cycles_t get_cycles(void) -{ - unsigned long long ret = 0; - -#ifndef CONFIG_X86_TSC - if (!cpu_has_tsc) - return 0; -#endif - -#if defined(CONFIG_X86_GENERIC) || defined(CONFIG_X86_TSC) - rdtscll(ret); -#endif - return ret; -} - -/* Like get_cycles, but make sure the CPU is synchronized. */ -static __always_inline cycles_t get_cycles_sync(void) -{ - unsigned long long ret; -#ifdef X86_FEATURE_SYNC_RDTSC - unsigned eax; - - /* - * Don't do an additional sync on CPUs where we know - * RDTSC is already synchronous: - */ - alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC, - "=a" (eax), "0" (1) : "ebx","ecx","edx","memory"); -#else - sync_core(); -#endif - rdtscll(ret); - - return ret; -} - -extern void tsc_init(void); -extern void mark_tsc_unstable(void); -extern int unsynchronized_tsc(void); -extern void init_tsc_clocksource(void); - -/* - * Boot-time check whether the TSCs are synchronized across - * all CPUs/cores: - */ -extern void check_tsc_sync_source(int cpu); -extern void check_tsc_sync_target(void); - -#endif +#include diff --git a/include/linux/audit.h b/include/linux/audit.h index 229fa012c893..773e30df11ee 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -24,6 +24,7 @@ #ifndef _LINUX_AUDIT_H_ #define _LINUX_AUDIT_H_ +#include #include /* The netlink messages for the audit system is divided into blocks: diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 3bef961b58b1..5bdbc744e773 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -47,7 +47,7 @@ enum hrtimer_restart { * HRTIMER_CB_IRQSAFE: Callback may run in hardirq context * HRTIMER_CB_IRQSAFE_NO_RESTART: Callback may run in hardirq context and * does not restart the timer - * HRTIMER_CB_IRQSAFE_NO_SOFTIRQ: Callback must run in softirq context + * HRTIMER_CB_IRQSAFE_NO_SOFTIRQ: Callback must run in hardirq context * Special mode for tick emultation */ enum hrtimer_cb_mode { @@ -139,7 +139,7 @@ struct hrtimer_sleeper { }; /** - * struct hrtimer_base - the timer base for a specific clock + * struct hrtimer_clock_base - the timer base for a specific clock * @cpu_base: per cpu clock base * @index: clock type index for per_cpu support when moving a * timer to a base on another cpu. diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 9dbb525c5178..a113fe68d8a1 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -218,5 +218,7 @@ extern void ip_mc_up(struct in_device *); extern void ip_mc_down(struct in_device *); extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr); extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr); +extern void ip_mc_rejoin_group(struct ip_mc_list *im); + #endif #endif diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 913e5752569f..bfcef8a1ad8b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -62,6 +62,12 @@ struct mmc_ios { #define MMC_BUS_WIDTH_1 0 #define MMC_BUS_WIDTH_4 2 + + unsigned char timing; /* timing specification used */ + +#define MMC_TIMING_LEGACY 0 +#define MMC_TIMING_MMC_HS 1 +#define MMC_TIMING_SD_HS 2 }; struct mmc_host_ops { @@ -87,6 +93,8 @@ struct mmc_host { #define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ #define MMC_CAP_MULTIWRITE (1 << 1) /* Can accurately report bytes sent to card on error */ #define MMC_CAP_BYTEBLOCK (1 << 2) /* Can do non-log2 block sizes */ +#define MMC_CAP_MMC_HIGHSPEED (1 << 3) /* Can do MMC high-speed timing */ +#define MMC_CAP_SD_HIGHSPEED (1 << 4) /* Can do SD high-speed timing */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h index e7d4da1cc9fa..c6d4ab86b83c 100644 --- a/include/linux/mv643xx.h +++ b/include/linux/mv643xx.h @@ -1288,6 +1288,7 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_NAME "mv643xx_eth" struct mv643xx_eth_platform_data { + int port_number; u16 force_phy_addr; /* force override if phy_addr == 0 */ u16 phy_addr; diff --git a/include/linux/ncp_fs_sb.h b/include/linux/ncp_fs_sb.h index a503052138bd..6330fc76b00f 100644 --- a/include/linux/ncp_fs_sb.h +++ b/include/linux/ncp_fs_sb.h @@ -50,6 +50,8 @@ struct ncp_server { int packet_size; unsigned char *packet; /* Here we prepare requests and receive replies */ + unsigned char *txbuf; /* Storage for current request */ + unsigned char *rxbuf; /* Storage for reply to current request */ int lock; /* To prevent mismatch in protocols. */ struct mutex mutex; diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 83b3c7b433aa..35fa4d5aadd0 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -194,9 +194,7 @@ static inline void svc_putu32(struct kvec *iov, __be32 val) union svc_addr_u { struct in_addr addr; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct in6_addr addr6; -#endif }; /* diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index cccea0a0feb4..7909687557bf 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -66,7 +66,7 @@ struct svc_sock { * Function prototypes. */ int svc_makesock(struct svc_serv *, int, unsigned short, int flags); -void svc_close_socket(struct svc_sock *); +void svc_force_close_socket(struct svc_sock *); int svc_recv(struct svc_rqst *, long); int svc_send(struct svc_rqst *); void svc_drop(struct svc_rqst *); diff --git a/init/Kconfig b/init/Kconfig index f977086e118a..b170aa1d43bd 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -304,6 +304,22 @@ config RELAY If unsure, say N. +config BLK_DEV_INITRD + bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" + depends on BROKEN || !FRV + help + The initial RAM filesystem is a ramfs which is loaded by the + boot loader (loadlin or lilo) and that is mounted as root + before the normal boot procedure. It is typically used to + load modules needed to mount the "real" root file system, + etc. See for details. + + If RAM disk support (BLK_DEV_RAM) is also included, this + also enables initial RAM disk (initrd) support and adds + 15 Kbytes (more on some other architectures) to the kernel size. + + If unsure say Y. + if BLK_DEV_INITRD source "usr/Kconfig" diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 0b5ecbe5f045..554ac368be79 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -731,7 +731,8 @@ asmlinkage long sys_mq_unlink(const char __user *u_name) if (IS_ERR(name)) return PTR_ERR(name); - mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex); + mutex_lock_nested(&mqueue_mnt->mnt_root->d_inode->i_mutex, + I_MUTEX_PARENT); dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name)); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index de93a8176ca6..ec4cb9f3e3b7 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -540,19 +540,19 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, /* * Switch to high resolution mode */ -static void hrtimer_switch_to_hres(void) +static int hrtimer_switch_to_hres(void) { struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases); unsigned long flags; if (base->hres_active) - return; + return 1; local_irq_save(flags); if (tick_init_highres()) { local_irq_restore(flags); - return; + return 0; } base->hres_active = 1; base->clock_base[CLOCK_REALTIME].resolution = KTIME_HIGH_RES; @@ -565,13 +565,14 @@ static void hrtimer_switch_to_hres(void) local_irq_restore(flags); printk(KERN_INFO "Switched to high resolution mode on CPU %d\n", smp_processor_id()); + return 1; } #else static inline int hrtimer_hres_active(void) { return 0; } static inline int hrtimer_is_hres_enabled(void) { return 0; } -static inline void hrtimer_switch_to_hres(void) { } +static inline int hrtimer_switch_to_hres(void) { return 0; } static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base) { } static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, struct hrtimer_clock_base *base) @@ -1130,6 +1131,9 @@ static inline void run_hrtimer_queue(struct hrtimer_cpu_base *cpu_base, if (base->softirq_time.tv64 <= timer->expires.tv64) break; +#ifdef CONFIG_HIGH_RES_TIMERS + WARN_ON_ONCE(timer->cb_mode == HRTIMER_CB_IRQSAFE_NO_SOFTIRQ); +#endif timer_stats_account_hrtimer(timer); fn = timer->function; @@ -1173,7 +1177,8 @@ void hrtimer_run_queues(void) * deadlock vs. xtime_lock. */ if (tick_check_oneshot_change(!hrtimer_is_hres_enabled())) - hrtimer_switch_to_hres(); + if (hrtimer_switch_to_hres()) + return; hrtimer_get_softirq_time(cpu_base); diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 95f6657fff73..51a4dd0f1b74 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -81,29 +81,34 @@ config SOFTWARE_SUSPEND bool "Software Suspend" depends on PM && SWAP && ((X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)) ---help--- - Enable the possibility of suspending the machine. - It doesn't need ACPI or APM. - You may suspend your machine by 'swsusp' or 'shutdown -z