diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-03-23 09:33:07 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-03-23 09:33:07 +0000 |
commit | c2929ecdf6cba5d5e5fd09c52e465e5f4a22fb83 (patch) | |
tree | 7b5913df4dd00bff1f70cfbdea7b627db43728a8 /xenolinux-2.4.25-sparse/arch | |
parent | 6d303dacab7a3f0cd3e06471acd623b48de83d0e (diff) | |
download | xen-c2929ecdf6cba5d5e5fd09c52e465e5f4a22fb83.tar.gz xen-c2929ecdf6cba5d5e5fd09c52e465e5f4a22fb83.tar.bz2 xen-c2929ecdf6cba5d5e5fd09c52e465e5f4a22fb83.zip |
bitkeeper revision 1.820 (40600453bCkH6oPCubNeqIe3OBUXGQ)
io.h:
new file
Many files:
Further IO virtualisation patches.
Diffstat (limited to 'xenolinux-2.4.25-sparse/arch')
6 files changed, 114 insertions, 39 deletions
diff --git a/xenolinux-2.4.25-sparse/arch/xeno/config.in b/xenolinux-2.4.25-sparse/arch/xeno/config.in index 39e821556a..209bbe6d51 100644 --- a/xenolinux-2.4.25-sparse/arch/xeno/config.in +++ b/xenolinux-2.4.25-sparse/arch/xeno/config.in @@ -107,6 +107,10 @@ bool 'Networking support' CONFIG_NET bool 'PCI support' CONFIG_PCI if [ "$CONFIG_PCI" = "y" ]; then tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX + tristate 'Intel(R) PRO/1000 Gigabit Ethernet support' CONFIG_E1000 + if [ "$CONFIG_E1000" != "n" ]; then + bool ' Use Rx Polling (NAPI)' CONFIG_E1000_NAPI + fi fi source drivers/pci/Config.in diff --git a/xenolinux-2.4.25-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.25-sparse/arch/xeno/drivers/network/network.c index 0a1bce2bfa..c5d25442e2 100644 --- a/xenolinux-2.4.25-sparse/arch/xeno/drivers/network/network.c +++ b/xenolinux-2.4.25-sparse/arch/xeno/drivers/network/network.c @@ -58,8 +58,8 @@ struct net_private * {tx,rx}_skbs store outstanding skbuffs. The first entry in each * array is an index into a chain of free entries. */ - struct sk_buff *tx_skbs[TX_RING_SIZE+1]; - struct sk_buff *rx_skbs[RX_RING_SIZE+1]; + struct sk_buff *tx_skbs[XENNET_TX_RING_SIZE+1]; + struct sk_buff *rx_skbs[XENNET_RX_RING_SIZE+1]; }; /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ @@ -143,9 +143,9 @@ static int network_open(struct net_device *dev) memset(np->net_idx, 0, sizeof(*np->net_idx)); /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ - for ( i = 0; i <= TX_RING_SIZE; i++ ) + for ( i = 0; i <= XENNET_TX_RING_SIZE; i++ ) np->tx_skbs[i] = (void *)(i+1); - for ( i = 0; i <= RX_RING_SIZE; i++ ) + for ( i = 0; i <= XENNET_RX_RING_SIZE; i++ ) np->rx_skbs[i] = (void *)(i+1); wmb(); @@ -196,7 +196,8 @@ static void network_tx_buf_gc(struct net_device *dev) } while ( prod != np->net_idx->tx_resp_prod ); - if ( np->tx_full && ((np->net_idx->tx_req_prod - prod) < TX_RING_SIZE) ) + if ( np->tx_full && + ((np->net_idx->tx_req_prod - prod) < XENNET_TX_RING_SIZE) ) { np->tx_full = 0; if ( np->state == STATE_ACTIVE ) @@ -223,7 +224,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) netop_t netop; NET_RING_IDX i = np->net_idx->rx_req_prod; - if ( unlikely((i - np->rx_resp_cons) == RX_RING_SIZE) || + if ( unlikely((i - np->rx_resp_cons) == XENNET_RX_RING_SIZE) || unlikely(np->state != STATE_ACTIVE) ) return; @@ -246,7 +247,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->rx_bufs_to_notify++; } - while ( (++i - np->rx_resp_cons) != RX_RING_SIZE ); + while ( (++i - np->rx_resp_cons) != XENNET_RX_RING_SIZE ); /* * We may have allocated buffers which have entries outstanding in the page @@ -258,7 +259,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->net_idx->rx_event = np->rx_resp_cons + 1; /* Batch Xen notifications. */ - if ( np->rx_bufs_to_notify > (RX_RING_SIZE/4) ) + if ( np->rx_bufs_to_notify > (XENNET_RX_RING_SIZE/4) ) { netop.cmd = NETOP_PUSH_BUFFERS; netop.vif = np->idx; @@ -313,7 +314,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) network_tx_buf_gc(dev); - if ( (i - np->tx_resp_cons) == (TX_RING_SIZE - 1) ) + if ( (i - np->tx_resp_cons) == (XENNET_TX_RING_SIZE - 1) ) { np->tx_full = 1; netif_stop_queue(dev); diff --git a/xenolinux-2.4.25-sparse/arch/xeno/drivers/vnetif/vnetif.c b/xenolinux-2.4.25-sparse/arch/xeno/drivers/vnetif/vnetif.c index 465dd18233..91f3c5c17e 100644 --- a/xenolinux-2.4.25-sparse/arch/xeno/drivers/vnetif/vnetif.c +++ b/xenolinux-2.4.25-sparse/arch/xeno/drivers/vnetif/vnetif.c @@ -58,8 +58,8 @@ struct net_private * {tx,rx}_skbs store outstanding skbuffs. The first entry in each * array is an index into a chain of free entries. */ - struct sk_buff *tx_skbs[TX_RING_SIZE+1]; - struct sk_buff *rx_skbs[RX_RING_SIZE+1]; + struct sk_buff *tx_skbs[XENNET_TX_RING_SIZE+1]; + struct sk_buff *rx_skbs[XENNET_RX_RING_SIZE+1]; }; /* Access macros for acquiring freeing slots in {tx,rx}_skbs[]. */ @@ -143,9 +143,9 @@ static int network_open(struct net_device *dev) memset(np->net_idx, 0, sizeof(*np->net_idx)); /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */ - for ( i = 0; i <= TX_RING_SIZE; i++ ) + for ( i = 0; i <= XENNET_TX_RING_SIZE; i++ ) np->tx_skbs[i] = (void *)(i+1); - for ( i = 0; i <= RX_RING_SIZE; i++ ) + for ( i = 0; i <= XENNET_RX_RING_SIZE; i++ ) np->rx_skbs[i] = (void *)(i+1); wmb(); @@ -196,7 +196,8 @@ static void network_tx_buf_gc(struct net_device *dev) } while ( prod != np->net_idx->tx_resp_prod ); - if ( np->tx_full && ((np->net_idx->tx_req_prod - prod) < TX_RING_SIZE) ) + if ( np->tx_full && + ((np->net_idx->tx_req_prod - prod) < XENNET_TX_RING_SIZE) ) { np->tx_full = 0; if ( np->state == STATE_ACTIVE ) @@ -223,7 +224,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) netop_t netop; NET_RING_IDX i = np->net_idx->rx_req_prod; - if ( unlikely((i - np->rx_resp_cons) == RX_RING_SIZE) || + if ( unlikely((i - np->rx_resp_cons) == XENNET_RX_RING_SIZE) || unlikely(np->state != STATE_ACTIVE) ) return; @@ -246,7 +247,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->rx_bufs_to_notify++; } - while ( (++i - np->rx_resp_cons) != RX_RING_SIZE ); + while ( (++i - np->rx_resp_cons) != XENNET_RX_RING_SIZE ); /* * We may have allocated buffers which have entries outstanding in the page @@ -258,7 +259,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->net_idx->rx_event = np->rx_resp_cons + 1; /* Batch Xen notifications. */ - if ( np->rx_bufs_to_notify > (RX_RING_SIZE/4) ) + if ( np->rx_bufs_to_notify > (XENNET_RX_RING_SIZE/4) ) { netop.cmd = NETOP_PUSH_BUFFERS; netop.vif = np->idx; @@ -313,7 +314,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) network_tx_buf_gc(dev); - if ( (i - np->tx_resp_cons) == (TX_RING_SIZE - 1) ) + if ( (i - np->tx_resp_cons) == (XENNET_TX_RING_SIZE - 1) ) { np->tx_full = 1; netif_stop_queue(dev); diff --git a/xenolinux-2.4.25-sparse/arch/xeno/kernel/hypervisor.c b/xenolinux-2.4.25-sparse/arch/xeno/kernel/hypervisor.c index 64a3590362..7c6aca05c5 100644 --- a/xenolinux-2.4.25-sparse/arch/xeno/kernel/hypervisor.c +++ b/xenolinux-2.4.25-sparse/arch/xeno/kernel/hypervisor.c @@ -7,8 +7,9 @@ */ #include <linux/config.h> -#include <asm/atomic.h> #include <linux/irq.h> +#include <linux/kernel_stat.h> +#include <asm/atomic.h> #include <asm/hypervisor.h> #include <asm/system.h> #include <asm/ptrace.h> @@ -18,6 +19,40 @@ int nr_multicall_ents = 0; static unsigned long event_mask = 0; +asmlinkage unsigned int do_physirq(int irq, struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + unsigned long irqs; + shared_info_t *shared = HYPERVISOR_shared_info; + + /* do this manually */ + kstat.irqs[cpu][irq]++; + ack_hypervisor_event(irq); + + barrier(); + irqs = xchg(&shared->physirq_pend, 0); + + __asm__ __volatile__ ( + " push %1 ;" + " sub $4,%%esp ;" + " jmp 3f ;" + "1: btrl %%eax,%0 ;" /* clear bit */ + " mov %%eax,(%%esp) ;" + " call do_IRQ ;" /* do_IRQ(event) */ + "3: bsfl %0,%%eax ;" /* %eax == bit # */ + " jnz 1b ;" + " add $8,%%esp ;" + /* we use %ebx because it is callee-saved */ + : : "b" (irqs), "r" (regs) + /* clobbered by callback function calls */ + : "eax", "ecx", "edx", "memory" ); + + /* do this manually */ + end_hypervisor_event(irq); + + return 0; +} + void do_hypervisor_callback(struct pt_regs *regs) { unsigned long events, flags; @@ -32,6 +67,12 @@ void do_hypervisor_callback(struct pt_regs *regs) events = xchg(&shared->events, 0); events &= event_mask; + if ( (events & EVENT_PHYSIRQ) != 0 ) + { + do_physirq(_EVENT_PHYSIRQ, regs); + events &= ~EVENT_PHYSIRQ; + } + __asm__ __volatile__ ( " push %1 ;" " sub $4,%%esp ;" diff --git a/xenolinux-2.4.25-sparse/arch/xeno/kernel/i386_ksyms.c b/xenolinux-2.4.25-sparse/arch/xeno/kernel/i386_ksyms.c index e62ca85c04..6744999039 100644 --- a/xenolinux-2.4.25-sparse/arch/xeno/kernel/i386_ksyms.c +++ b/xenolinux-2.4.25-sparse/arch/xeno/kernel/i386_ksyms.c @@ -9,7 +9,7 @@ #include <linux/interrupt.h> #include <linux/smp_lock.h> #include <linux/pm.h> -//XXX ??? #include <linux/pci.h> +#include <linux/pci.h> #include <linux/apm_bios.h> #include <linux/kernel.h> #include <linux/string.h> @@ -68,6 +68,8 @@ EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(apm_info); //EXPORT_SYMBOL(gdt); EXPORT_SYMBOL(empty_zero_page); +EXPORT_SYMBOL(phys_to_machine_mapping); + #ifdef CONFIG_DEBUG_IOVIRT EXPORT_SYMBOL(__io_virt_debug); @@ -101,6 +103,16 @@ EXPORT_SYMBOL(__generic_copy_from_user); EXPORT_SYMBOL(__generic_copy_to_user); EXPORT_SYMBOL(strnlen_user); + +EXPORT_SYMBOL(pci_alloc_consistent); +EXPORT_SYMBOL(pci_free_consistent); + +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pcibios_penalize_isa_irq); +EXPORT_SYMBOL(pci_mem_start); +#endif + + #ifdef CONFIG_X86_USE_3DNOW EXPORT_SYMBOL(_mmx_memcpy); EXPORT_SYMBOL(mmx_clear_page); diff --git a/xenolinux-2.4.25-sparse/arch/xeno/kernel/physirq.c b/xenolinux-2.4.25-sparse/arch/xeno/kernel/physirq.c index 3a6083b24e..1f7a8e4fee 100644 --- a/xenolinux-2.4.25-sparse/arch/xeno/kernel/physirq.c +++ b/xenolinux-2.4.25-sparse/arch/xeno/kernel/physirq.c @@ -38,7 +38,9 @@ static unsigned int startup_physirq_event(unsigned int irq) printk("startup_physirq_event %d\n", irq); /* - * install a interrupt handler for physirq event when called thefirst tim + * install a interrupt handler for physirq event when called first time + * we actually are never executing the handler as _EVENT_PHYSIRQ is + * handled specially in hypervisor.c But we need to enable the event etc. */ if ( !setup_event_handler ) { @@ -66,23 +68,51 @@ static unsigned int startup_physirq_event(unsigned int irq) } return 0; } +/* + * This is a dummy interrupt handler. + * It should never be called. events for physical interrupts are handled + * differently in hypervisor.c + */ +static void physirq_interrupt(int irq, void *unused, struct pt_regs *ptregs) +{ + printk("XXX This should never be called!"); +} + +/* + * IRQ is not needed anymore. + */ static void shutdown_physirq_event(unsigned int irq) { + physdev_op_t op; + int err; - /* call xen to free IRQ */ + printk("shutdown_phys_irq called."); + /* + * tell hypervisor + */ + op.cmd = PHYSDEVOP_FREE_IRQ; + op.u.free_irq.irq = irq; + if ( (err = HYPERVISOR_physdev_op(&op)) != 0 ) + { + printk(KERN_ALERT "could not free IRQ %d\n", irq); + return; + } + return; } static void enable_physirq_event(unsigned int irq) { - /* XXX just enable all interrupts for now */ + /* XXX just enable all phys interrupts for now */ + enable_irq(HYPEREVENT_IRQ(_EVENT_PHYSIRQ)); } static void disable_physirq_event(unsigned int irq) { - /* XXX just disable all interrupts for now */ + /* XXX just disable all phys interrupts for now */ + disable_irq(HYPEREVENT_IRQ(_EVENT_PHYSIRQ)); } static void ack_physirq_event(unsigned int irq) @@ -100,6 +130,7 @@ static void end_physirq_event(unsigned int irq) { int err; physdev_op_t op; + /* call hypervisor */ op.cmd = PHYSDEVOP_FINISHED_IRQ; op.u.finished_irq.irq = irq; @@ -123,21 +154,6 @@ static struct hw_interrupt_type physirq_irq_type = { }; -/* - * this interrupt handler demuxes the virt phys event and the virt phys - * bitmask and calls the interrupt handlers for virtualised physical interrupts - */ -static void physirq_interrupt(int irq, void *unused, struct pt_regs *ptregs) -{ -#if 0 - unsigned long flags; - int virq; - local_irq_save(flags); - do_IRQ(virq); - local_irq_restore(flags); -#endif -} - void __init physirq_init(void) { |