From 5ade71f5e49d280c300a21d7ebeb42ec454e34c7 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 25 Oct 2006 19:42:38 +0200 Subject: [PATCH] --- yaml --- r: 44191 b: refs/heads/master c: e0b19b83656731fc93f9a82592ebcad82c3e0944 h: refs/heads/master i: 44189: bb439ac3282832bdf75de2d908804c95bfa8dd62 44187: 6cd87ce2b2eabc65714cf66e9dc4e214d9956dfc 44183: a4bff5d9cd65b43d905938e5cf0e9bfac88378eb 44175: a9d33bc4509a2d8814a4c1f201fe44d29824d85d 44159: ee8aaf56d589e71cfa2fb82959be087f83c7095b v: v3 --- [refs] | 2 +- trunk/arch/mips/kernel/reset.c | 2 - trunk/arch/mips/kernel/vmlinux.lds.S | 4 +- trunk/arch/mips/lib/csum_partial_copy.c | 3 - trunk/arch/mips/mm/cache.c | 1 - trunk/drivers/mmc/at91_mci.c | 170 ++++---- trunk/drivers/net/Kconfig | 8 - trunk/drivers/net/chelsio/cxgb2.c | 23 +- trunk/drivers/net/chelsio/sge.c | 115 +++--- trunk/drivers/net/chelsio/sge.h | 4 +- trunk/drivers/net/macb.c | 8 +- trunk/drivers/net/macb.h | 6 +- trunk/drivers/net/myri10ge/myri10ge.c | 498 ++++++++++++------------ trunk/drivers/net/smc91x.h | 90 +++++ trunk/drivers/net/ucc_geth.c | 12 +- trunk/fs/proc/proc_misc.c | 12 +- trunk/include/asm-generic/vmlinux.lds.h | 1 - trunk/include/asm-mips/pci.h | 6 - trunk/include/asm-mips/ptrace.h | 8 - trunk/include/asm-mips/system.h | 9 + trunk/include/linux/init.h | 1 - trunk/include/linux/kernel.h | 2 + trunk/init/initramfs.c | 6 +- trunk/init/main.c | 15 +- trunk/init/version.c | 5 + 25 files changed, 543 insertions(+), 468 deletions(-) diff --git a/[refs] b/[refs] index 037346b4822a..ffebeded6b40 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 116140b7f5c9182c86a4e419f81684209357aea7 +refs/heads/master: e0b19b83656731fc93f9a82592ebcad82c3e0944 diff --git a/trunk/arch/mips/kernel/reset.c b/trunk/arch/mips/kernel/reset.c index 060563a712b6..621037db2290 100644 --- a/trunk/arch/mips/kernel/reset.c +++ b/trunk/arch/mips/kernel/reset.c @@ -23,8 +23,6 @@ void (*_machine_restart)(char *command); void (*_machine_halt)(void); void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); - void machine_restart(char *command) { if (_machine_restart) diff --git a/trunk/arch/mips/kernel/vmlinux.lds.S b/trunk/arch/mips/kernel/vmlinux.lds.S index 2f4508f55fca..79f0317d84ac 100644 --- a/trunk/arch/mips/kernel/vmlinux.lds.S +++ b/trunk/arch/mips/kernel/vmlinux.lds.S @@ -109,6 +109,9 @@ SECTIONS .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT + /* .exit.text is discarded at runtime, not link time, to deal with + references from .rodata */ + .exit.text : { *(.exit.text) } . = ALIGN(_PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } @@ -136,7 +139,6 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.exit.text) *(.exit.data) *(.exitcall.exit) diff --git a/trunk/arch/mips/lib/csum_partial_copy.c b/trunk/arch/mips/lib/csum_partial_copy.c index 06771040a267..1720f2ceeeae 100644 --- a/trunk/arch/mips/lib/csum_partial_copy.c +++ b/trunk/arch/mips/lib/csum_partial_copy.c @@ -7,7 +7,6 @@ * Copyright (C) 1998, 1999 Ralf Baechle */ #include -#include #include #include #include @@ -30,8 +29,6 @@ __wsum csum_partial_copy_nocheck(const void *src, return sum; } -EXPORT_SYMBOL(csum_partial_copy_nocheck); - /* * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. diff --git a/trunk/arch/mips/mm/cache.c b/trunk/arch/mips/mm/cache.c index 1f954a238a63..caf807ded514 100644 --- a/trunk/arch/mips/mm/cache.c +++ b/trunk/arch/mips/mm/cache.c @@ -32,7 +32,6 @@ void (*local_flush_data_cache_page)(void * addr); void (*flush_data_cache_page)(unsigned long addr); void (*flush_icache_all)(void); -EXPORT_SYMBOL_GPL(local_flush_data_cache_page); EXPORT_SYMBOL(flush_data_cache_page); #ifdef CONFIG_DMA_NONCOHERENT diff --git a/trunk/drivers/mmc/at91_mci.c b/trunk/drivers/mmc/at91_mci.c index 4633dbc9a90f..cc0546998367 100644 --- a/trunk/drivers/mmc/at91_mci.c +++ b/trunk/drivers/mmc/at91_mci.c @@ -87,25 +87,9 @@ static struct clk *mci_clk; -/* - * Read from a MCI register. - */ -static inline unsigned long at91_mci_read(unsigned int reg) -{ - void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI; +#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) +#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) - return __raw_readl(mci_base + reg); -} - -/* - * Write to a MCI register. - */ -static inline void at91_mci_write(unsigned int reg, unsigned long value) -{ - void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI; - - __raw_writel(value, mci_base + reg); -} /* * Low level type for this driver @@ -116,6 +100,8 @@ struct at91mci_host struct mmc_command *cmd; struct mmc_request *request; + void __iomem *baseaddr; + struct at91_mmc_data *board; int present; @@ -217,13 +203,13 @@ static void at91mci_pre_dma_read(struct at91mci_host *host) /* Check to see if this needs filling */ if (i == 0) { - if (at91_mci_read(AT91_PDC_RCR) != 0) { + if (at91_mci_read(host, AT91_PDC_RCR) != 0) { pr_debug("Transfer active in current\n"); continue; } } else { - if (at91_mci_read(AT91_PDC_RNCR) != 0) { + if (at91_mci_read(host, AT91_PDC_RNCR) != 0) { pr_debug("Transfer active in next\n"); continue; } @@ -240,12 +226,12 @@ static void at91mci_pre_dma_read(struct at91mci_host *host) pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); if (i == 0) { - at91_mci_write(AT91_PDC_RPR, sg->dma_address); - at91_mci_write(AT91_PDC_RCR, sg->length / 4); + at91_mci_write(host, AT91_PDC_RPR, sg->dma_address); + at91_mci_write(host, AT91_PDC_RCR, sg->length / 4); } else { - at91_mci_write(AT91_PDC_RNPR, sg->dma_address); - at91_mci_write(AT91_PDC_RNCR, sg->length / 4); + at91_mci_write(host, AT91_PDC_RNPR, sg->dma_address); + at91_mci_write(host, AT91_PDC_RNCR, sg->length / 4); } } @@ -308,8 +294,8 @@ static void at91mci_post_dma_read(struct at91mci_host *host) if (host->transfer_index < data->sg_len) at91mci_pre_dma_read(host); else { - at91_mci_write(AT91_MCI_IER, AT91_MCI_RXBUFF); - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); + at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); } pr_debug("post dma read done\n"); @@ -326,11 +312,11 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) pr_debug("Handling the transmit\n"); /* Disable the transfer */ - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); + at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); /* Now wait for cmd ready */ - at91_mci_write(AT91_MCI_IDR, AT91_MCI_TXBUFE); - at91_mci_write(AT91_MCI_IER, AT91_MCI_NOTBUSY); + at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY); cmd = host->cmd; if (!cmd) return; @@ -344,21 +330,21 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host) /* * Enable the controller */ -static void at91_mci_enable(void) +static void at91_mci_enable(struct at91mci_host *host) { - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN); - at91_mci_write(AT91_MCI_IDR, 0xFFFFFFFF); - at91_mci_write(AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); - at91_mci_write(AT91_MCI_MR, 0x834A); - at91_mci_write(AT91_MCI_SDCR, 0x0); + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); + at91_mci_write(host, AT91_MCI_IDR, 0xFFFFFFFF); + at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); + at91_mci_write(host, AT91_MCI_MR, 0x834A); + at91_mci_write(host, AT91_MCI_SDCR, 0x0); } /* * Disable the controller */ -static void at91_mci_disable(void) +static void at91_mci_disable(struct at91mci_host *host) { - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST); } /* @@ -378,13 +364,13 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ /* Not sure if this is needed */ #if 0 - if ((at91_mci_read(AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { + if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) { pr_debug("Clearing timeout\n"); - at91_mci_write(AT91_MCI_ARGR, 0); - at91_mci_write(AT91_MCI_CMDR, AT91_MCI_OPDCMD); - while (!(at91_mci_read(AT91_MCI_SR) & AT91_MCI_CMDRDY)) { + at91_mci_write(host, AT91_MCI_ARGR, 0); + at91_mci_write(host, AT91_MCI_CMDR, AT91_MCI_OPDCMD); + while (!(at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_CMDRDY)) { /* spin */ - pr_debug("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR)); + pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR)); } } #endif @@ -432,31 +418,31 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ * Set the arguments and send the command */ pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n", - cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91_MCI_MR)); + cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR)); if (!data) { - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS); - at91_mci_write(AT91_PDC_RPR, 0); - at91_mci_write(AT91_PDC_RCR, 0); - at91_mci_write(AT91_PDC_RNPR, 0); - at91_mci_write(AT91_PDC_RNCR, 0); - at91_mci_write(AT91_PDC_TPR, 0); - at91_mci_write(AT91_PDC_TCR, 0); - at91_mci_write(AT91_PDC_TNPR, 0); - at91_mci_write(AT91_PDC_TNCR, 0); - - at91_mci_write(AT91_MCI_ARGR, cmd->arg); - at91_mci_write(AT91_MCI_CMDR, cmdr); + at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS); + at91_mci_write(host, AT91_PDC_RPR, 0); + at91_mci_write(host, AT91_PDC_RCR, 0); + at91_mci_write(host, AT91_PDC_RNPR, 0); + at91_mci_write(host, AT91_PDC_RNCR, 0); + at91_mci_write(host, AT91_PDC_TPR, 0); + at91_mci_write(host, AT91_PDC_TCR, 0); + at91_mci_write(host, AT91_PDC_TNPR, 0); + at91_mci_write(host, AT91_PDC_TNCR, 0); + + at91_mci_write(host, AT91_MCI_ARGR, cmd->arg); + at91_mci_write(host, AT91_MCI_CMDR, cmdr); return AT91_MCI_CMDRDY; } - mr = at91_mci_read(AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */ - at91_mci_write(AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); + mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff; /* zero block length and PDC mode */ + at91_mci_write(host, AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE); /* * Disable the PDC controller */ - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); + at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); if (cmdr & AT91_MCI_TRCMD_START) { data->bytes_xfered = 0; @@ -485,8 +471,8 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ pr_debug("Transmitting %d bytes\n", host->total_length); - at91_mci_write(AT91_PDC_TPR, host->physical_address); - at91_mci_write(AT91_PDC_TCR, host->total_length / 4); + at91_mci_write(host, AT91_PDC_TPR, host->physical_address); + at91_mci_write(host, AT91_PDC_TCR, host->total_length / 4); ier = AT91_MCI_TXBUFE; } } @@ -496,14 +482,14 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_ * the data sheet says */ - at91_mci_write(AT91_MCI_ARGR, cmd->arg); - at91_mci_write(AT91_MCI_CMDR, cmdr); + at91_mci_write(host, AT91_MCI_ARGR, cmd->arg); + at91_mci_write(host, AT91_MCI_CMDR, cmdr); if (cmdr & AT91_MCI_TRCMD_START) { if (cmdr & AT91_MCI_TRDIR) - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTEN); + at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTEN); else - at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTEN); + at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTEN); } return ier; } @@ -520,7 +506,7 @@ static void at91mci_process_command(struct at91mci_host *host, struct mmc_comman pr_debug("setting ier to %08X\n", ier); /* Stop on errors or the required value */ - at91_mci_write(AT91_MCI_IER, 0xffff0000 | ier); + at91_mci_write(host, AT91_MCI_IER, 0xffff0000 | ier); } /* @@ -548,19 +534,19 @@ static void at91mci_completed_command(struct at91mci_host *host) struct mmc_command *cmd = host->cmd; unsigned int status; - at91_mci_write(AT91_MCI_IDR, 0xffffffff); + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); - cmd->resp[0] = at91_mci_read(AT91_MCI_RSPR(0)); - cmd->resp[1] = at91_mci_read(AT91_MCI_RSPR(1)); - cmd->resp[2] = at91_mci_read(AT91_MCI_RSPR(2)); - cmd->resp[3] = at91_mci_read(AT91_MCI_RSPR(3)); + cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0)); + cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1)); + cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); + cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); if (host->buffer) { dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address); host->buffer = NULL; } - status = at91_mci_read(AT91_MCI_SR); + status = at91_mci_read(host, AT91_MCI_SR); pr_debug("Status = %08X [%08X %08X %08X %08X]\n", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); @@ -617,12 +603,12 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (ios->clock == 0) { /* Disable the MCI controller */ - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS); + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS); clkdiv = 0; } else { /* Enable the MCI controller */ - at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN); + at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN); if ((at91_master_clock % (ios->clock * 2)) == 0) clkdiv = ((at91_master_clock / ios->clock) / 2) - 1; @@ -634,15 +620,15 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) { pr_debug("MMC: Setting controller bus width to 4\n"); - at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) | AT91_MCI_SDCBUS); + at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) | AT91_MCI_SDCBUS); } else { pr_debug("MMC: Setting controller bus width to 1\n"); - at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); + at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); } /* Set the clock divider */ - at91_mci_write(AT91_MCI_MR, (at91_mci_read(AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); + at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); /* maybe switch power to the card */ if (host->board->vcc_pin) { @@ -668,14 +654,14 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) unsigned int int_status; - int_status = at91_mci_read(AT91_MCI_SR); - pr_debug("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR), - int_status & at91_mci_read(AT91_MCI_IMR)); + int_status = at91_mci_read(host, AT91_MCI_SR); + pr_debug("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(host, AT91_MCI_IMR), + int_status & at91_mci_read(host, AT91_MCI_IMR)); - if ((int_status & at91_mci_read(AT91_MCI_IMR)) & 0xffff0000) + if ((int_status & at91_mci_read(host, AT91_MCI_IMR)) & 0xffff0000) completed = 1; - int_status &= at91_mci_read(AT91_MCI_IMR); + int_status &= at91_mci_read(host, AT91_MCI_IMR); if (int_status & AT91_MCI_UNRE) pr_debug("MMC: Underrun error\n"); @@ -705,7 +691,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (int_status & AT91_MCI_RXBUFF) { pr_debug("RX buffer full\n"); - at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); } if (int_status & AT91_MCI_ENDTX) { @@ -719,7 +705,7 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) if (int_status & AT91_MCI_NOTBUSY) { pr_debug("Card is ready\n"); - at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY); + at91_mci_write(host, AT91_MCI_IER, AT91_MCI_CMDRDY); } if (int_status & AT91_MCI_DTIP) { @@ -743,11 +729,11 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) completed = 1; } } - at91_mci_write(AT91_MCI_IDR, int_status); + at91_mci_write(host, AT91_MCI_IDR, int_status); if (completed) { pr_debug("Completed command\n"); - at91_mci_write(AT91_MCI_IDR, 0xffffffff); + at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); at91mci_completed_command(host); } @@ -769,7 +755,7 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host) present ? "insert" : "remove"); if (!present) { pr_debug("****** Resetting SD-card bus width ******\n"); - at91_mci_write(AT91_MCI_SDCR, 0); + at91_mci_write(host, AT91_MCI_SDCR, 0); } mmc_detect_change(host->mmc, msecs_to_jiffies(100)); } @@ -809,8 +795,6 @@ static int at91_mci_probe(struct platform_device *pdev) int ret; pr_debug("Probe MCI devices\n"); - at91_mci_disable(); - at91_mci_enable(); mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev); if (!mmc) { @@ -848,6 +832,14 @@ static int at91_mci_probe(struct platform_device *pdev) } clk_enable(mci_clk); /* Enable the peripheral clock */ + host->baseaddr = (void __iomem *)AT91_VA_BASE_MCI; + + /* + * Reset hardware + */ + at91_mci_disable(host); + at91_mci_enable(host); + /* * Allocate the MCI interrupt */ @@ -906,7 +898,7 @@ static int at91_mci_remove(struct platform_device *pdev) } mmc_remove_host(mmc); - at91_mci_disable(); + at91_mci_disable(host); free_irq(AT91RM9200_ID_MCI, host); mmc_free_host(mmc); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 8aa8dd02b910..9de0eed6755b 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2384,14 +2384,6 @@ config CHELSIO_T1_1G Enables support for Chelsio's gigabit Ethernet PCI cards. If you are using only 10G cards say 'N' here. -config CHELSIO_T1_NAPI - bool "Use Rx Polling (NAPI)" - depends on CHELSIO_T1 - default y - help - NAPI is a driver API designed to reduce CPU and interrupt load - when the driver is receiving lots of packets from the card. - config EHEA tristate "eHEA Ethernet support" depends on IBMEBUS diff --git a/trunk/drivers/net/chelsio/cxgb2.c b/trunk/drivers/net/chelsio/cxgb2.c index fd5d821f3f2a..de48eadddbc4 100644 --- a/trunk/drivers/net/chelsio/cxgb2.c +++ b/trunk/drivers/net/chelsio/cxgb2.c @@ -220,8 +220,9 @@ static int cxgb_up(struct adapter *adapter) t1_interrupts_clear(adapter); - adapter->params.has_msi = !disable_msi && !pci_enable_msi(adapter->pdev); - err = request_irq(adapter->pdev->irq, t1_interrupt, + adapter->params.has_msi = !disable_msi && pci_enable_msi(adapter->pdev) == 0; + err = request_irq(adapter->pdev->irq, + t1_select_intr_handler(adapter), adapter->params.has_msi ? 0 : IRQF_SHARED, adapter->name, adapter); if (err) { @@ -763,7 +764,18 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) { struct adapter *adapter = dev->priv; - adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs; + /* + * If RX coalescing is requested we use NAPI, otherwise interrupts. + * This choice can be made only when all ports and the TOE are off. + */ + if (adapter->open_device_map == 0) + adapter->params.sge.polling = c->use_adaptive_rx_coalesce; + + if (adapter->params.sge.polling) { + adapter->params.sge.rx_coalesce_usecs = 0; + } else { + adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs; + } adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce; adapter->params.sge.sample_interval_usecs = c->rate_sample_interval; t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge); @@ -932,7 +944,7 @@ static void t1_netpoll(struct net_device *dev) struct adapter *adapter = dev->priv; local_irq_save(flags); - t1_interrupt(adapter->pdev->irq, adapter); + t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter); local_irq_restore(flags); } #endif @@ -1153,10 +1165,7 @@ static int __devinit init_one(struct pci_dev *pdev, #ifdef CONFIG_NET_POLL_CONTROLLER netdev->poll_controller = t1_netpoll; #endif -#ifdef CONFIG_CHELSIO_T1_NAPI netdev->weight = 64; - netdev->poll = t1_poll; -#endif SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); } diff --git a/trunk/drivers/net/chelsio/sge.c b/trunk/drivers/net/chelsio/sge.c index 659cb2252e44..0ca8d876e16f 100644 --- a/trunk/drivers/net/chelsio/sge.c +++ b/trunk/drivers/net/chelsio/sge.c @@ -1413,20 +1413,16 @@ static int sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) if (unlikely(adapter->vlan_grp && p->vlan_valid)) { st->vlan_xtract++; -#ifdef CONFIG_CHELSIO_T1_NAPI + if (adapter->params.sge.polling) vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, ntohs(p->vlan)); -#else + else vlan_hwaccel_rx(skb, adapter->vlan_grp, ntohs(p->vlan)); -#endif - } else { -#ifdef CONFIG_CHELSIO_T1_NAPI + } else if (adapter->params.sge.polling) netif_receive_skb(skb); -#else + else netif_rx(skb); -#endif - } return 0; } @@ -1576,7 +1572,6 @@ static int process_responses(struct adapter *adapter, int budget) return budget; } -#ifdef CONFIG_CHELSIO_T1_NAPI /* * A simpler version of process_responses() that handles only pure (i.e., * non data-carrying) responses. Such respones are too light-weight to justify @@ -1624,76 +1619,92 @@ static int process_pure_responses(struct adapter *adapter, struct respQ_e *e) * or protection from interrupts as data interrupts are off at this point and * other adapter interrupts do not interfere. */ -int t1_poll(struct net_device *dev, int *budget) +static int t1_poll(struct net_device *dev, int *budget) { struct adapter *adapter = dev->priv; int effective_budget = min(*budget, dev->quota); - int work_done = process_responses(adapter, effective_budget); + int work_done = process_responses(adapter, effective_budget); *budget -= work_done; dev->quota -= work_done; if (work_done >= effective_budget) return 1; - spin_lock_irq(&adapter->async_lock); __netif_rx_complete(dev); - writel(adapter->sge->respQ.cidx, adapter->regs + A_SG_SLEEPING); - writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, - adapter->regs + A_PL_ENABLE); - spin_unlock_irq(&adapter->async_lock); + /* + * Because we don't atomically flush the following write it is + * possible that in very rare cases it can reach the device in a way + * that races with a new response being written plus an error interrupt + * causing the NAPI interrupt handler below to return unhandled status + * to the OS. To protect against this would require flushing the write + * and doing both the write and the flush with interrupts off. Way too + * expensive and unjustifiable given the rarity of the race. + */ + writel(adapter->sge->respQ.cidx, adapter->regs + A_SG_SLEEPING); return 0; } +/* + * Returns true if the device is already scheduled for polling. + */ +static inline int napi_is_scheduled(struct net_device *dev) +{ + return test_bit(__LINK_STATE_RX_SCHED, &dev->state); +} + /* * NAPI version of the main interrupt handler. */ -irqreturn_t t1_interrupt(int irq, void *data) +static irqreturn_t t1_interrupt_napi(int irq, void *data) { + int handled; struct adapter *adapter = data; - struct net_device *dev = adapter->sge->netdev; struct sge *sge = adapter->sge; - u32 cause; - int handled = 0; + struct respQ *q = &adapter->sge->respQ; - cause = readl(adapter->regs + A_PL_CAUSE); - if (cause == 0 || cause == ~0) - return IRQ_NONE; + /* + * Clear the SGE_DATA interrupt first thing. Normally the NAPI + * handler has control of the response queue and the interrupt handler + * can look at the queue reliably only once it knows NAPI is off. + * We can't wait that long to clear the SGE_DATA interrupt because we + * could race with t1_poll rearming the SGE interrupt, so we need to + * clear the interrupt speculatively and really early on. + */ + writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); spin_lock(&adapter->async_lock); - if (cause & F_PL_INTR_SGE_DATA) { - struct respQ *q = &adapter->sge->respQ; + if (!napi_is_scheduled(sge->netdev)) { struct respQ_e *e = &q->entries[q->cidx]; - handled = 1; - writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); - - if (e->GenerationBit == q->genbit && - __netif_rx_schedule_prep(dev)) { - if (e->DataValid || process_pure_responses(adapter, e)) { - /* mask off data IRQ */ - writel(adapter->slow_intr_mask, - adapter->regs + A_PL_ENABLE); - __netif_rx_schedule(sge->netdev); - goto unlock; - } - /* no data, no NAPI needed */ - netif_poll_enable(dev); - - } - writel(q->cidx, adapter->regs + A_SG_SLEEPING); - } else - handled = t1_slow_intr_handler(adapter); - + if (e->GenerationBit == q->genbit) { + if (e->DataValid || + process_pure_responses(adapter, e)) { + if (likely(__netif_rx_schedule_prep(sge->netdev))) + __netif_rx_schedule(sge->netdev); + else if (net_ratelimit()) + printk(KERN_INFO + "NAPI schedule failure!\n"); + } else + writel(q->cidx, adapter->regs + A_SG_SLEEPING); + + handled = 1; + goto unlock; + } else + writel(q->cidx, adapter->regs + A_SG_SLEEPING); + } else if (readl(adapter->regs + A_PL_CAUSE) & F_PL_INTR_SGE_DATA) { + printk(KERN_ERR "data interrupt while NAPI running\n"); + } + + handled = t1_slow_intr_handler(adapter); if (!handled) sge->stats.unhandled_irqs++; -unlock: + unlock: spin_unlock(&adapter->async_lock); return IRQ_RETVAL(handled != 0); } -#else /* * Main interrupt handler, optimized assuming that we took a 'DATA' * interrupt. @@ -1709,7 +1720,7 @@ irqreturn_t t1_interrupt(int irq, void *data) * 5. If we took an interrupt, but no valid respQ descriptors was found we * let the slow_intr_handler run and do error handling. */ -irqreturn_t t1_interrupt(int irq, void *cookie) +static irqreturn_t t1_interrupt(int irq, void *cookie) { int work_done; struct respQ_e *e; @@ -1741,7 +1752,11 @@ irqreturn_t t1_interrupt(int irq, void *cookie) spin_unlock(&adapter->async_lock); return IRQ_RETVAL(work_done != 0); } -#endif + +irq_handler_t t1_select_intr_handler(adapter_t *adapter) +{ + return adapter->params.sge.polling ? t1_interrupt_napi : t1_interrupt; +} /* * Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it. @@ -2018,6 +2033,7 @@ static void sge_tx_reclaim_cb(unsigned long data) */ int t1_sge_set_coalesce_params(struct sge *sge, struct sge_params *p) { + sge->netdev->poll = t1_poll; sge->fixed_intrtimer = p->rx_coalesce_usecs * core_ticks_per_usec(sge->adapter); writel(sge->fixed_intrtimer, sge->adapter->regs + A_SG_INTRTIMER); @@ -2218,6 +2234,7 @@ struct sge * __devinit t1_sge_create(struct adapter *adapter, p->coalesce_enable = 0; p->sample_interval_usecs = 0; + p->polling = 0; return sge; nomem_port: diff --git a/trunk/drivers/net/chelsio/sge.h b/trunk/drivers/net/chelsio/sge.h index d132a0ef2a22..7ceb0117d039 100644 --- a/trunk/drivers/net/chelsio/sge.h +++ b/trunk/drivers/net/chelsio/sge.h @@ -76,9 +76,7 @@ struct sge *t1_sge_create(struct adapter *, struct sge_params *); int t1_sge_configure(struct sge *, struct sge_params *); int t1_sge_set_coalesce_params(struct sge *, struct sge_params *); void t1_sge_destroy(struct sge *); -irqreturn_t t1_interrupt(int irq, void *cookie); -int t1_poll(struct net_device *, int *); - +irq_handler_t t1_select_intr_handler(adapter_t *adapter); int t1_start_xmit(struct sk_buff *skb, struct net_device *dev); void t1_set_vlan_accel(struct adapter *adapter, int on_off); void t1_sge_start(struct sge *); diff --git a/trunk/drivers/net/macb.c b/trunk/drivers/net/macb.c index 25b559b5d5ed..bd0ce98c939c 100644 --- a/trunk/drivers/net/macb.c +++ b/trunk/drivers/net/macb.c @@ -264,12 +264,12 @@ static void macb_update_stats(struct macb *bp) WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); for(; p < end; p++, reg++) - *p += __raw_readl(reg); + *p += readl(reg); } -static void macb_periodic_task(struct work_struct *work) +static void macb_periodic_task(void *arg) { - struct macb *bp = container_of(work, struct macb, periodic_task.work); + struct macb *bp = arg; macb_update_stats(bp); macb_check_media(bp, 1, 0); @@ -1088,7 +1088,7 @@ static int __devinit macb_probe(struct platform_device *pdev) dev->base_addr = regs->start; - INIT_DELAYED_WORK(&bp->periodic_task, macb_periodic_task); + INIT_WORK(&bp->periodic_task, macb_periodic_task, bp); mutex_init(&bp->mdio_mutex); init_completion(&bp->mdio_complete); diff --git a/trunk/drivers/net/macb.h b/trunk/drivers/net/macb.h index 27bf0ae0f0bb..8c253db69881 100644 --- a/trunk/drivers/net/macb.h +++ b/trunk/drivers/net/macb.h @@ -250,9 +250,9 @@ /* Register access macros */ #define macb_readl(port,reg) \ - __raw_readl((port)->regs + MACB_##reg) + readl((port)->regs + MACB_##reg) #define macb_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + MACB_##reg) + writel((value), (port)->regs + MACB_##reg) struct dma_desc { u32 addr; @@ -377,7 +377,7 @@ struct macb { unsigned int rx_pending, tx_pending; - struct delayed_work periodic_task; + struct work_struct periodic_task; struct mutex mdio_mutex; struct completion mdio_complete; diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 94ac168be593..81f127a78afa 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -71,7 +71,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.1.0" +#define MYRI10GE_VERSION_STR "1.0.0" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -92,13 +92,8 @@ MODULE_LICENSE("Dual BSD/GPL"); #define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff) #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff -#define MYRI10GE_ALLOC_ORDER 0 -#define MYRI10GE_ALLOC_SIZE ((1 << MYRI10GE_ALLOC_ORDER) * PAGE_SIZE) -#define MYRI10GE_MAX_FRAGS_PER_FRAME (MYRI10GE_MAX_ETHER_MTU/MYRI10GE_ALLOC_SIZE + 1) - struct myri10ge_rx_buffer_state { - struct page *page; - int page_offset; + struct sk_buff *skb; DECLARE_PCI_UNMAP_ADDR(bus) DECLARE_PCI_UNMAP_LEN(len) }; @@ -121,14 +116,9 @@ struct myri10ge_rx_buf { u8 __iomem *wc_fifo; /* w/c rx dma addr fifo address */ struct mcp_kreq_ether_recv *shadow; /* host shadow of recv ring */ struct myri10ge_rx_buffer_state *info; - struct page *page; - dma_addr_t bus; - int page_offset; int cnt; - int fill_cnt; int alloc_fail; int mask; /* number of rx slots -1 */ - int watchdog_needed; }; struct myri10ge_tx_buf { @@ -160,7 +150,6 @@ struct myri10ge_priv { struct myri10ge_rx_buf rx_big; struct myri10ge_rx_done rx_done; int small_bytes; - int big_bytes; struct net_device *dev; struct net_device_stats stats; u8 __iomem *sram; @@ -249,6 +238,11 @@ module_param(myri10ge_force_firmware, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_force_firmware, "Force firmware to assume aligned completions\n"); +static int myri10ge_skb_cross_4k = 0; +module_param(myri10ge_skb_cross_4k, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(myri10ge_skb_cross_4k, + "Can a small skb cross a 4KB boundary?\n"); + static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; module_param(myri10ge_initial_mtu, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n"); @@ -272,10 +266,6 @@ static int myri10ge_debug = -1; /* defaults above */ module_param(myri10ge_debug, int, 0); MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); -static int myri10ge_fill_thresh = 256; -module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); - #define MYRI10GE_FW_OFFSET 1024*1024 #define MYRI10GE_HIGHPART_TO_U32(X) \ (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0) @@ -283,9 +273,9 @@ MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8) -static inline void put_be32(__be32 val, __be32 __iomem * p) +static inline void put_be32(__be32 val, __be32 __iomem *p) { - __raw_writel((__force __u32) val, (__force void __iomem *)p); + __raw_writel((__force __u32)val, (__force void __iomem *)p); } static int @@ -814,179 +804,194 @@ myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst, mb(); } -static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum) +/* + * Set of routines to get a new receive buffer. Any buffer which + * crosses a 4KB boundary must start on a 4KB boundary due to PCIe + * wdma restrictions. We also try to align any smaller allocation to + * at least a 16 byte boundary for efficiency. We assume the linux + * memory allocator works by powers of 2, and will not return memory + * smaller than 2KB which crosses a 4KB boundary. If it does, we fall + * back to allocating 2x as much space as required. + * + * We intend to replace large (>4KB) skb allocations by using + * pages directly and building a fraglist in the near future. + */ + +static inline struct sk_buff *myri10ge_alloc_big(struct net_device *dev, + int bytes) { - struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data); + struct sk_buff *skb; + unsigned long data, roundup; - if ((skb->protocol == htons(ETH_P_8021Q)) && - (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) || - vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) { - skb->csum = hw_csum; - skb->ip_summed = CHECKSUM_COMPLETE; - } + skb = netdev_alloc_skb(dev, bytes + 4096 + MXGEFW_PAD); + if (skb == NULL) + return NULL; + + /* Correct skb->truesize so that socket buffer + * accounting is not confused the rounding we must + * do to satisfy alignment constraints. + */ + skb->truesize -= 4096; + + data = (unsigned long)(skb->data); + roundup = (-data) & (4095); + skb_reserve(skb, roundup); + return skb; } -static inline void -myri10ge_rx_skb_build(struct sk_buff *skb, u8 * va, - struct skb_frag_struct *rx_frags, int len, int hlen) +/* Allocate 2x as much space as required and use whichever portion + * does not cross a 4KB boundary */ +static inline struct sk_buff *myri10ge_alloc_small_safe(struct net_device *dev, + unsigned int bytes) { - struct skb_frag_struct *skb_frags; - - skb->len = skb->data_len = len; - skb->truesize = len + sizeof(struct sk_buff); - /* attach the page(s) */ - - skb_frags = skb_shinfo(skb)->frags; - while (len > 0) { - memcpy(skb_frags, rx_frags, sizeof(*skb_frags)); - len -= rx_frags->size; - skb_frags++; - rx_frags++; - skb_shinfo(skb)->nr_frags++; - } - - /* pskb_may_pull is not available in irq context, but - * skb_pull() (for ether_pad and eth_type_trans()) requires - * the beginning of the packet in skb_headlen(), move it - * manually */ - memcpy(skb->data, va, hlen); - skb_shinfo(skb)->frags[0].page_offset += hlen; - skb_shinfo(skb)->frags[0].size -= hlen; - skb->data_len -= hlen; - skb->tail += hlen; - skb_pull(skb, MXGEFW_PAD); + struct sk_buff *skb; + unsigned long data, boundary; + + skb = netdev_alloc_skb(dev, 2 * (bytes + MXGEFW_PAD) - 1); + if (unlikely(skb == NULL)) + return NULL; + + /* Correct skb->truesize so that socket buffer + * accounting is not confused the rounding we must + * do to satisfy alignment constraints. + */ + skb->truesize -= bytes + MXGEFW_PAD; + + data = (unsigned long)(skb->data); + boundary = (data + 4095UL) & ~4095UL; + if ((boundary - data) >= (bytes + MXGEFW_PAD)) + return skb; + + skb_reserve(skb, boundary - data); + return skb; } -static void -myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, - int bytes, int watchdog) +/* Allocate just enough space, and verify that the allocated + * space does not cross a 4KB boundary */ +static inline struct sk_buff *myri10ge_alloc_small(struct net_device *dev, + int bytes) { - struct page *page; - int idx; + struct sk_buff *skb; + unsigned long roundup, data, end; + + skb = netdev_alloc_skb(dev, bytes + 16 + MXGEFW_PAD); + if (unlikely(skb == NULL)) + return NULL; + + /* Round allocated buffer to 16 byte boundary */ + data = (unsigned long)(skb->data); + roundup = (-data) & 15UL; + skb_reserve(skb, roundup); + /* Verify that the data buffer does not cross a page boundary */ + data = (unsigned long)(skb->data); + end = data + bytes + MXGEFW_PAD - 1; + if (unlikely(((end >> 12) != (data >> 12)) && (data & 4095UL))) { + printk(KERN_NOTICE + "myri10ge_alloc_small: small skb crossed 4KB boundary\n"); + myri10ge_skb_cross_4k = 1; + dev_kfree_skb_any(skb); + skb = myri10ge_alloc_small_safe(dev, bytes); + } + return skb; +} - if (unlikely(rx->watchdog_needed && !watchdog)) - return; +static inline int +myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct myri10ge_priv *mgp, + int bytes, int idx) +{ + struct net_device *dev = mgp->dev; + struct pci_dev *pdev = mgp->pdev; + struct sk_buff *skb; + dma_addr_t bus; + int len, retval = 0; - /* try to refill entire ring */ - while (rx->fill_cnt != (rx->cnt + rx->mask + 1)) { - idx = rx->fill_cnt & rx->mask; + bytes += VLAN_HLEN; /* account for 802.1q vlan tag */ - if ((bytes < MYRI10GE_ALLOC_SIZE / 2) && - (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) { - /* we can use part of previous page */ - get_page(rx->page); - } else { - /* we need a new page */ - page = - alloc_pages(GFP_ATOMIC | __GFP_COMP, - MYRI10GE_ALLOC_ORDER); - if (unlikely(page == NULL)) { - if (rx->fill_cnt - rx->cnt < 16) - rx->watchdog_needed = 1; - return; - } - rx->page = page; - rx->page_offset = 0; - rx->bus = pci_map_page(mgp->pdev, page, 0, - MYRI10GE_ALLOC_SIZE, - PCI_DMA_FROMDEVICE); - } - rx->info[idx].page = rx->page; - rx->info[idx].page_offset = rx->page_offset; - /* note that this is the address of the start of the - * page */ - pci_unmap_addr_set(&rx->info[idx], bus, rx->bus); - rx->shadow[idx].addr_low = - htonl(MYRI10GE_LOWPART_TO_U32(rx->bus) + rx->page_offset); - rx->shadow[idx].addr_high = - htonl(MYRI10GE_HIGHPART_TO_U32(rx->bus)); - - /* start next packet on a cacheline boundary */ - rx->page_offset += SKB_DATA_ALIGN(bytes); - rx->fill_cnt++; - - /* copy 8 descriptors to the firmware at a time */ - if ((idx & 7) == 7) { - if (rx->wc_fifo == NULL) - myri10ge_submit_8rx(&rx->lanai[idx - 7], - &rx->shadow[idx - 7]); - else { - mb(); - myri10ge_pio_copy(rx->wc_fifo, - &rx->shadow[idx - 7], 64); - } + if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ ) + skb = myri10ge_alloc_big(dev, bytes); + else if (myri10ge_skb_cross_4k) + skb = myri10ge_alloc_small_safe(dev, bytes); + else + skb = myri10ge_alloc_small(dev, bytes); + + if (unlikely(skb == NULL)) { + rx->alloc_fail++; + retval = -ENOBUFS; + goto done; + } + + /* set len so that it only covers the area we + * need mapped for DMA */ + len = bytes + MXGEFW_PAD; + + bus = pci_map_single(pdev, skb->data, len, PCI_DMA_FROMDEVICE); + rx->info[idx].skb = skb; + pci_unmap_addr_set(&rx->info[idx], bus, bus); + pci_unmap_len_set(&rx->info[idx], len, len); + rx->shadow[idx].addr_low = htonl(MYRI10GE_LOWPART_TO_U32(bus)); + rx->shadow[idx].addr_high = htonl(MYRI10GE_HIGHPART_TO_U32(bus)); + +done: + /* copy 8 descriptors (64-bytes) to the mcp at a time */ + if ((idx & 7) == 7) { + if (rx->wc_fifo == NULL) + myri10ge_submit_8rx(&rx->lanai[idx - 7], + &rx->shadow[idx - 7]); + else { + mb(); + myri10ge_pio_copy(rx->wc_fifo, + &rx->shadow[idx - 7], 64); } } + return retval; } -static inline void -myri10ge_unmap_rx_page(struct pci_dev *pdev, - struct myri10ge_rx_buffer_state *info, int bytes) +static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum) { - /* unmap the recvd page if we're the only or last user of it */ - if (bytes >= MYRI10GE_ALLOC_SIZE / 2 || - (info->page_offset + 2 * bytes) > MYRI10GE_ALLOC_SIZE) { - pci_unmap_page(pdev, (pci_unmap_addr(info, bus) - & ~(MYRI10GE_ALLOC_SIZE - 1)), - MYRI10GE_ALLOC_SIZE, PCI_DMA_FROMDEVICE); + struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data); + + if ((skb->protocol == htons(ETH_P_8021Q)) && + (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) || + vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) { + skb->csum = hw_csum; + skb->ip_summed = CHECKSUM_COMPLETE; } } -#define MYRI10GE_HLEN 64 /* The number of bytes to copy from a - * page into an skb */ - -static inline int +static inline unsigned long myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, int bytes, int len, __wsum csum) { + dma_addr_t bus; struct sk_buff *skb; - struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; - int i, idx, hlen, remainder; - struct pci_dev *pdev = mgp->pdev; - struct net_device *dev = mgp->dev; - u8 *va; + int idx, unmap_len; - len += MXGEFW_PAD; idx = rx->cnt & rx->mask; - va = page_address(rx->info[idx].page) + rx->info[idx].page_offset; - prefetch(va); - /* Fill skb_frag_struct(s) with data from our receive */ - for (i = 0, remainder = len; remainder > 0; i++) { - myri10ge_unmap_rx_page(pdev, &rx->info[idx], bytes); - rx_frags[i].page = rx->info[idx].page; - rx_frags[i].page_offset = rx->info[idx].page_offset; - if (remainder < MYRI10GE_ALLOC_SIZE) - rx_frags[i].size = remainder; - else - rx_frags[i].size = MYRI10GE_ALLOC_SIZE; - rx->cnt++; - idx = rx->cnt & rx->mask; - remainder -= MYRI10GE_ALLOC_SIZE; - } - - hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN; + rx->cnt++; - /* allocate an skb to attach the page(s) to. */ + /* save a pointer to the received skb */ + skb = rx->info[idx].skb; + bus = pci_unmap_addr(&rx->info[idx], bus); + unmap_len = pci_unmap_len(&rx->info[idx], len); - skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16); - if (unlikely(skb == NULL)) { - mgp->stats.rx_dropped++; - do { - i--; - put_page(rx_frags[i].page); - } while (i != 0); + /* try to replace the received skb */ + if (myri10ge_getbuf(rx, mgp, bytes, idx)) { + /* drop the frame -- the old skbuf is re-cycled */ + mgp->stats.rx_dropped += 1; return 0; } - /* Attach the pages to the skb, and trim off any padding */ - myri10ge_rx_skb_build(skb, va, rx_frags, len, hlen); - if (skb_shinfo(skb)->frags[0].size <= 0) { - put_page(skb_shinfo(skb)->frags[0].page); - skb_shinfo(skb)->nr_frags = 0; - } - skb->protocol = eth_type_trans(skb, dev); - skb->dev = dev; + /* unmap the recvd skb */ + pci_unmap_single(mgp->pdev, bus, unmap_len, PCI_DMA_FROMDEVICE); + + /* mcp implicitly skips 1st bytes so that packet is properly + * aligned */ + skb_reserve(skb, MXGEFW_PAD); + /* set the length of the frame */ + skb_put(skb, len); + + skb->protocol = eth_type_trans(skb, mgp->dev); if (mgp->csum_flag) { if ((skb->protocol == htons(ETH_P_IP)) || (skb->protocol == htons(ETH_P_IPV6))) { @@ -995,8 +1000,9 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, } else myri10ge_vlan_ip_csum(skb, csum); } + netif_receive_skb(skb); - dev->last_rx = jiffies; + mgp->dev->last_rx = jiffies; return 1; } @@ -1073,7 +1079,7 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) length, checksum); else rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big, - mgp->big_bytes, + mgp->dev->mtu + ETH_HLEN, length, checksum); rx_packets += rx_ok; rx_bytes += rx_ok * (unsigned long)length; @@ -1088,14 +1094,6 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit) rx_done->cnt = cnt; mgp->stats.rx_packets += rx_packets; mgp->stats.rx_bytes += rx_bytes; - - /* restock receive rings if needed */ - if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh) - myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, - mgp->small_bytes + MXGEFW_PAD, 0); - if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh) - myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); - } static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) @@ -1486,48 +1484,56 @@ static int myri10ge_allocate_rings(struct net_device *dev) goto abort_with_rx_small_info; /* Fill the receive rings */ - mgp->rx_big.cnt = 0; - mgp->rx_small.cnt = 0; - mgp->rx_big.fill_cnt = 0; - mgp->rx_small.fill_cnt = 0; - mgp->rx_small.page_offset = MYRI10GE_ALLOC_SIZE; - mgp->rx_big.page_offset = MYRI10GE_ALLOC_SIZE; - mgp->rx_small.watchdog_needed = 0; - mgp->rx_big.watchdog_needed = 0; - myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, - mgp->small_bytes + MXGEFW_PAD, 0); - if (mgp->rx_small.fill_cnt < mgp->rx_small.mask + 1) { - printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n", - dev->name, mgp->rx_small.fill_cnt); - goto abort_with_rx_small_ring; + for (i = 0; i <= mgp->rx_small.mask; i++) { + status = myri10ge_getbuf(&mgp->rx_small, mgp, + mgp->small_bytes, i); + if (status) { + printk(KERN_ERR + "myri10ge: %s: alloced only %d small bufs\n", + dev->name, i); + goto abort_with_rx_small_ring; + } } - myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0); - if (mgp->rx_big.fill_cnt < mgp->rx_big.mask + 1) { - printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n", - dev->name, mgp->rx_big.fill_cnt); - goto abort_with_rx_big_ring; + for (i = 0; i <= mgp->rx_big.mask; i++) { + status = + myri10ge_getbuf(&mgp->rx_big, mgp, dev->mtu + ETH_HLEN, i); + if (status) { + printk(KERN_ERR + "myri10ge: %s: alloced only %d big bufs\n", + dev->name, i); + goto abort_with_rx_big_ring; + } } return 0; abort_with_rx_big_ring: - for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) { - int idx = i & mgp->rx_big.mask; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx], - mgp->big_bytes); - put_page(mgp->rx_big.info[idx].page); + for (i = 0; i <= mgp->rx_big.mask; i++) { + if (mgp->rx_big.info[i].skb != NULL) + dev_kfree_skb_any(mgp->rx_big.info[i].skb); + if (pci_unmap_len(&mgp->rx_big.info[i], len)) + pci_unmap_single(mgp->pdev, + pci_unmap_addr(&mgp->rx_big.info[i], + bus), + pci_unmap_len(&mgp->rx_big.info[i], + len), + PCI_DMA_FROMDEVICE); } abort_with_rx_small_ring: - for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) { - int idx = i & mgp->rx_small.mask; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx], - mgp->small_bytes + MXGEFW_PAD); - put_page(mgp->rx_small.info[idx].page); + for (i = 0; i <= mgp->rx_small.mask; i++) { + if (mgp->rx_small.info[i].skb != NULL) + dev_kfree_skb_any(mgp->rx_small.info[i].skb); + if (pci_unmap_len(&mgp->rx_small.info[i], len)) + pci_unmap_single(mgp->pdev, + pci_unmap_addr(&mgp->rx_small.info[i], + bus), + pci_unmap_len(&mgp->rx_small.info[i], + len), + PCI_DMA_FROMDEVICE); } - kfree(mgp->rx_big.info); abort_with_rx_small_info: @@ -1560,24 +1566,30 @@ static void myri10ge_free_rings(struct net_device *dev) mgp = netdev_priv(dev); - for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) { - idx = i & mgp->rx_big.mask; - if (i == mgp->rx_big.fill_cnt - 1) - mgp->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx], - mgp->big_bytes); - put_page(mgp->rx_big.info[idx].page); + for (i = 0; i <= mgp->rx_big.mask; i++) { + if (mgp->rx_big.info[i].skb != NULL) + dev_kfree_skb_any(mgp->rx_big.info[i].skb); + if (pci_unmap_len(&mgp->rx_big.info[i], len)) + pci_unmap_single(mgp->pdev, + pci_unmap_addr(&mgp->rx_big.info[i], + bus), + pci_unmap_len(&mgp->rx_big.info[i], + len), + PCI_DMA_FROMDEVICE); + } + + for (i = 0; i <= mgp->rx_small.mask; i++) { + if (mgp->rx_small.info[i].skb != NULL) + dev_kfree_skb_any(mgp->rx_small.info[i].skb); + if (pci_unmap_len(&mgp->rx_small.info[i], len)) + pci_unmap_single(mgp->pdev, + pci_unmap_addr(&mgp->rx_small.info[i], + bus), + pci_unmap_len(&mgp->rx_small.info[i], + len), + PCI_DMA_FROMDEVICE); } - for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) { - idx = i & mgp->rx_small.mask; - if (i == mgp->rx_small.fill_cnt - 1) - mgp->rx_small.info[idx].page_offset = - MYRI10GE_ALLOC_SIZE; - myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx], - mgp->small_bytes + MXGEFW_PAD); - put_page(mgp->rx_small.info[idx].page); - } tx = &mgp->tx; while (tx->done != tx->req) { idx = tx->done & tx->mask; @@ -1645,18 +1657,19 @@ static int myri10ge_open(struct net_device *dev) */ if (dev->mtu <= ETH_DATA_LEN) - /* enough for a TCP header */ - mgp->small_bytes = (128 > SMP_CACHE_BYTES) - ? (128 - MXGEFW_PAD) - : (SMP_CACHE_BYTES - MXGEFW_PAD); + mgp->small_bytes = 128; /* enough for a TCP header */ else - /* enough for a vlan encapsulated ETH_DATA_LEN frame */ - mgp->small_bytes = VLAN_ETH_FRAME_LEN; + mgp->small_bytes = ETH_FRAME_LEN; /* enough for an ETH_DATA_LEN frame */ /* Override the small buffer size? */ if (myri10ge_small_bytes > 0) mgp->small_bytes = myri10ge_small_bytes; + /* If the user sets an obscenely small MTU, adjust the small + * bytes down to nearly nothing */ + if (mgp->small_bytes >= (dev->mtu + ETH_HLEN)) + mgp->small_bytes = 64; + /* get the lanai pointers to the send and receive rings */ status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0); @@ -1692,23 +1705,17 @@ static int myri10ge_open(struct net_device *dev) mgp->rx_big.wc_fifo = NULL; } + status = myri10ge_allocate_rings(dev); + if (status != 0) + goto abort_with_nothing; + /* Firmware needs the big buff size as a power of 2. Lie and * tell him the buffer is larger, because we only use 1 * buffer/pkt, and the mtu will prevent overruns. */ - big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD; - if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) { - while ((big_pow2 & (big_pow2 - 1)) != 0) - big_pow2++; - mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD; - } else { - big_pow2 = MYRI10GE_ALLOC_SIZE; - mgp->big_bytes = big_pow2; - } - - status = myri10ge_allocate_rings(dev); - if (status != 0) - goto abort_with_nothing; + big_pow2 = dev->mtu + ETH_HLEN + MXGEFW_PAD; + while ((big_pow2 & (big_pow2 - 1)) != 0) + big_pow2++; /* now give firmware buffers sizes, and MTU */ cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; @@ -2199,7 +2206,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev) struct myri10ge_cmd cmd; struct myri10ge_priv *mgp; struct dev_mc_list *mc_list; - __be32 data[2] = { 0, 0 }; + __be32 data[2] = {0, 0}; int err; mgp = netdev_priv(dev); @@ -2618,7 +2625,7 @@ static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp) static void myri10ge_watchdog(struct work_struct *work) { struct myri10ge_priv *mgp = - container_of(work, struct myri10ge_priv, watchdog_work); + container_of(work, struct myri10ge_priv, watchdog_work); u32 reboot; int status; u16 cmd, vendor; @@ -2691,21 +2698,6 @@ static void myri10ge_watchdog_timer(unsigned long arg) struct myri10ge_priv *mgp; mgp = (struct myri10ge_priv *)arg; - - if (mgp->rx_small.watchdog_needed) { - myri10ge_alloc_rx_pages(mgp, &mgp->rx_small, - mgp->small_bytes + MXGEFW_PAD, 1); - if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt >= - myri10ge_fill_thresh) - mgp->rx_small.watchdog_needed = 0; - } - if (mgp->rx_big.watchdog_needed) { - myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 1); - if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt >= - myri10ge_fill_thresh) - mgp->rx_big.watchdog_needed = 0; - } - if (mgp->tx.req != mgp->tx.done && mgp->tx.done == mgp->watchdog_tx_done && mgp->watchdog_tx_req != mgp->watchdog_tx_done) diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index d2767e6584a9..9367c574477a 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -362,6 +362,96 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define SMC_IRQ_FLAGS (0) +#elif defined(CONFIG_ARCH_VERSATILE) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define SMC_IRQ_FLAGS (0) + +#elif defined(CONFIG_ARCH_VERSATILE) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define SMC_IRQ_FLAGS (0) + +#elif defined(CONFIG_ARCH_VERSATILE) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define SMC_IRQ_FLAGS (0) + +#elif defined(CONFIG_ARCH_VERSATILE) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define SMC_IRQ_FLAGS (0) + +#elif defined(CONFIG_ARCH_VERSATILE) + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) +#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) + +#define SMC_IRQ_FLAGS (0) + #else #define SMC_CAN_USE_8BIT 1 diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index 8243150f5b05..1f05511fa390 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -194,9 +194,9 @@ static void enqueue(struct list_head *node, struct list_head *lh) { unsigned long flags; - spin_lock_irqsave(&ugeth_lock, flags); + spin_lock_irqsave(ugeth_lock, flags); list_add_tail(node, lh); - spin_unlock_irqrestore(&ugeth_lock, flags); + spin_unlock_irqrestore(ugeth_lock, flags); } #endif /* CONFIG_UGETH_FILTERING */ @@ -204,14 +204,14 @@ static struct list_head *dequeue(struct list_head *lh) { unsigned long flags; - spin_lock_irqsave(&ugeth_lock, flags); + spin_lock_irqsave(ugeth_lock, flags); if (!list_empty(lh)) { struct list_head *node = lh->next; list_del(node); - spin_unlock_irqrestore(&ugeth_lock, flags); + spin_unlock_irqrestore(ugeth_lock, flags); return node; } else { - spin_unlock_irqrestore(&ugeth_lock, flags); + spin_unlock_irqrestore(ugeth_lock, flags); return NULL; } } @@ -1852,8 +1852,6 @@ static int init_phy(struct net_device *dev) mii_info->mdio_read = &read_phy_reg; mii_info->mdio_write = &write_phy_reg; - spin_lock_init(&mii_info->mdio_lock); - ugeth->mii_info = mii_info; spin_lock_irq(&ugeth->lock); diff --git a/trunk/fs/proc/proc_misc.c b/trunk/fs/proc/proc_misc.c index 92ea7743fe8f..dc3e580d1dca 100644 --- a/trunk/fs/proc/proc_misc.c +++ b/trunk/fs/proc/proc_misc.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include @@ -254,15 +253,8 @@ static int version_read_proc(char *page, char **start, off_t off, { int len; - /* FIXED STRING! Don't touch! */ - len = snprintf(page, PAGE_SIZE, - "%s version %s" - " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")" - " (" LINUX_COMPILER ")" - " %s\n", - utsname()->sysname, - utsname()->release, - utsname()->version); + len = sprintf(page, linux_banner, + utsname()->release, utsname()->version); return proc_calc_metrics(page, start, off, count, eof, len); } diff --git a/trunk/include/asm-generic/vmlinux.lds.h b/trunk/include/asm-generic/vmlinux.lds.h index 7437ccaada77..6e9fcebbf89f 100644 --- a/trunk/include/asm-generic/vmlinux.lds.h +++ b/trunk/include/asm-generic/vmlinux.lds.h @@ -242,7 +242,6 @@ *(.initcall4s.init) \ *(.initcall5.init) \ *(.initcall5s.init) \ - *(.initcallrootfs.init) \ *(.initcall6.init) \ *(.initcall6s.init) \ *(.initcall7.init) \ diff --git a/trunk/include/asm-mips/pci.h b/trunk/include/asm-mips/pci.h index 7f0f120ca07c..c4d68bebdca6 100644 --- a/trunk/include/asm-mips/pci.h +++ b/trunk/include/asm-mips/pci.h @@ -187,10 +187,4 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev) /* Do platform specific device initialization at pci_enable_device() time */ extern int pcibios_plat_dev_init(struct pci_dev *dev); -/* Chances are this interrupt is wired PC-style ... */ -static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) -{ - return channel ? 15 : 14; -} - #endif /* _ASM_PCI_H */ diff --git a/trunk/include/asm-mips/ptrace.h b/trunk/include/asm-mips/ptrace.h index 8a1f2b6f04ac..30bf555faeaa 100644 --- a/trunk/include/asm-mips/ptrace.h +++ b/trunk/include/asm-mips/ptrace.h @@ -82,14 +82,6 @@ struct pt_regs { extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit); -extern NORET_TYPE void die(const char *, struct pt_regs *); - -static inline void die_if_kernel(const char *str, struct pt_regs *regs) -{ - if (unlikely(!user_mode(regs))) - die(str, regs); -} - #endif #endif /* _ASM_PTRACE_H */ diff --git a/trunk/include/asm-mips/system.h b/trunk/include/asm-mips/system.h index 5e1289c85ed9..9428057a50cf 100644 --- a/trunk/include/asm-mips/system.h +++ b/trunk/include/asm-mips/system.h @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -335,6 +336,14 @@ extern void *set_except_vector(int n, void *addr); extern unsigned long ebase; extern void per_cpu_trap_init(void); +extern NORET_TYPE void die(const char *, struct pt_regs *); + +static inline void die_if_kernel(const char *str, struct pt_regs *regs) +{ + if (unlikely(!user_mode(regs))) + die(str, regs); +} + extern int stop_a_enabled; /* diff --git a/trunk/include/linux/init.h b/trunk/include/linux/init.h index 5a593a1dec1e..5eb5d24b7680 100644 --- a/trunk/include/linux/init.h +++ b/trunk/include/linux/init.h @@ -111,7 +111,6 @@ extern void setup_arch(char **); #define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s) #define fs_initcall(fn) __define_initcall("5",fn,5) #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s) -#define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs) #define device_initcall(fn) __define_initcall("6",fn,6) #define device_initcall_sync(fn) __define_initcall("6s",fn,6s) #define late_initcall(fn) __define_initcall("7",fn,7) diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index b0c4a05a4b0c..e8bfac34d2ba 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -17,6 +17,8 @@ #include #include +extern const char linux_banner[]; + #define INT_MAX ((int)(~0U>>1)) #define INT_MIN (-INT_MAX - 1) #define UINT_MAX (~0U) diff --git a/trunk/init/initramfs.c b/trunk/init/initramfs.c index 4fa0f7977de1..85f04037ade1 100644 --- a/trunk/init/initramfs.c +++ b/trunk/init/initramfs.c @@ -526,7 +526,7 @@ static void __init free_initrd(void) #endif -static int __init populate_rootfs(void) +void __init populate_rootfs(void) { char *err = unpack_to_rootfs(__initramfs_start, __initramfs_end - __initramfs_start, 0); @@ -544,7 +544,7 @@ static int __init populate_rootfs(void) unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start, 0); free_initrd(); - return 0; + return; } printk("it isn't (%s); looks like an initrd\n", err); fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700); @@ -565,6 +565,4 @@ static int __init populate_rootfs(void) #endif } #endif - return 0; } -rootfs_initcall(populate_rootfs); diff --git a/trunk/init/main.c b/trunk/init/main.c index e3f0bb20b4dd..036f97c0c34c 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -94,6 +94,7 @@ extern void pidmap_init(void); extern void prio_tree_init(void); extern void radix_tree_init(void); extern void free_initmem(void); +extern void populate_rootfs(void); extern void driver_init(void); extern void prepare_namespace(void); #ifdef CONFIG_ACPI @@ -482,12 +483,6 @@ void __init __attribute__((weak)) smp_setup_processor_id(void) { } -static const char linux_banner[] = - "Linux version " UTS_RELEASE - " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")" - " (" LINUX_COMPILER ")" - " " UTS_VERSION "\n"; - asmlinkage void __init start_kernel(void) { char * command_line; @@ -514,7 +509,7 @@ asmlinkage void __init start_kernel(void) boot_cpu_init(); page_address_init(); printk(KERN_NOTICE); - printk(linux_banner); + printk(linux_banner, UTS_RELEASE, UTS_VERSION); setup_arch(&command_line); unwind_setup(); setup_per_cpu_areas(); @@ -744,6 +739,12 @@ static int init(void * unused) cpuset_init_smp(); + /* + * Do this before initcalls, because some drivers want to access + * firmware files. + */ + populate_rootfs(); + do_basic_setup(); /* diff --git a/trunk/init/version.c b/trunk/init/version.c index 9d96d36501ca..2a5dfcd1c2e6 100644 --- a/trunk/init/version.c +++ b/trunk/init/version.c @@ -33,3 +33,8 @@ struct uts_namespace init_uts_ns = { }, }; EXPORT_SYMBOL_GPL(init_uts_ns); + +const char linux_banner[] = + "Linux version %s (" LINUX_COMPILE_BY "@" + LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") %s\n"; +