aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/via-velocity.c
Commit message (Collapse)AuthorAge
* via-velocity: Fix DMA mapping length errors on transmit.Dave Jones2009-03-13
| | | | | | | | | | | From: Dave Jones <davej@redhat.com> The dma-debug changes caught that this driver uses the wrong DMA mapping length when skb_padto() does something. With suggestions from Eric Dumazet. Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: fix hot spinroel kluin2009-01-20
| | | | | | | while(--j >= 0) keeps spinning when j is unsigned: Signed-off-by: Roel Kluin <roel.kluin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* netdev: add missing set_mac_address hookStephen Hemminger2009-01-11
| | | | | | | | Many drivers lost the ability to set ethernet address accidently during the net_device_ops conversion. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* netdev: add more functions to netdevice opsStephen Hemminger2008-11-20
| | | | | | | | | | | | This patch moves neigh_setup and hard_start_xmit into the network device ops structure. For bisection, fix all the previously converted drivers as well. Bonding driver took the biggest hit on this. Added a prefetch of the hard_start_xmit in the fast path to try and reduce any impact this would have. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: convert to net_device_opsStephen Hemminger2008-11-20
| | | | | | | Convert this driver to network device ops. Compile tested only. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* Merge branch 'master' of ↵David S. Miller2008-11-19
|\ | | | | | | | | | | | | | | | | master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6 Conflicts: drivers/isdn/i4l/isdn_net.c fs/cifs/connect.c
| * via-velocity: enable perfect filtering for multicast packetsJoey Zhuo2008-11-16
| | | | | | | | | | | | Signed-off-by: Joey Zhuo <joeyzhuo@via.com.tw> Acked-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* | drivers/net: Kill now superfluous ->last_rx stores.David S. Miller2008-11-04
|/ | | | | | | | | | | | | The generic packet receive code takes care of setting netdev->last_rx when necessary, for the sake of the bonding ARP monitor. Drivers need not do it any more. Some cases had to be skipped over because the drivers were making use of the ->last_rx value themselves. Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: use driver string instead of dev->name before register_netdev()Sven Hartge2008-10-27
| | | | | | | | | | | | | | | | | | | | | | | This patch corrects a message bug in the via-velocity driver which bothered me for some time. The messages printed during device init look like the following: [ 8.486422] eth%d: set value of parameter Wake On Lan options to 0 ^^! [ 8.487340] eth0: VIA Networking Velocity Family Gigabit Ethernet Adapter Note the unresolved format string. dev->name is unavailable before register_netdev, so use dev_driver_string(&pdev->dev), which is also consistent with other drivers. "char *devname" parameters had to be converted to "const char *devname" to be consistent with dev_driver_string return value. Signed-off-by: Sven Hartge <sven@svenhartge.de> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* net: Rationalise email address: Network Specific PartsAlan Cox2008-10-13
| | | | | | | | | | Clean up the various different email addresses of mine listed in the code to a single current and valid address. As Dave says his network merges for 2.6.28 are now done this seems a good point to send them in where they won't risk disrupting real changes. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: Fix warnings on sparc64.Francois Romieu2008-10-08
| | | | | | As reported by Meelis Roos. Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: velocity_init_{rd/tx}_ring use kcalloc(..., GFP_KERNEL).Francois Romieu2008-07-31
| | | | | | | | | Allocate and free everyting outside of the locked section. Spotted-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Fixed-by: Seguier Regis <rseguier@e-teleport.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
* via-velocity: separated struct allow wholesale copy during MTU changes.Francois Romieu2008-07-31
| | | | | | | It should help people fix the bugs in my code :o) Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
* via-velocity: add velocity_set_rxbufsize helperFrancois Romieu2008-07-11
| | | | | | | It removes a dependancy from velocity_init_rd_ring to dev->mtu. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* via-velocity: move residual free rx descriptors count register updateFrancois Romieu2008-07-11
| | | | | | | | | | | | | | | | | | | | | Updates of the RBRDU have two different meanings depending on their context: 1. the receiving process has not started - the value which is written into the RBRDU register is supposed to be the free rx descriptors count (rounded to a multiple of 4) 2. the receiving process is running - the value increments the count above (sic) The update is currently issued deep inside the rx replenish chain (see velocity_give_many_rx_descs). Let's propagate enough information to the caller so that the rx replenish functions do not depend on hardware any more. It is needed to perform the Rx/Tx buffers housekeeping when MTU changes. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* via-velocity: lean and clean velocity_init_ringsFrancois Romieu2008-07-11
| | | | | | | | | - PCI consistent areas need no memset - use dev_err instead of plain printk - avoid a few casts Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* via-velocity: remove the bounce buffersFrancois Romieu2008-07-11
| | | | | | | | | | | | | | | | | | | | | | Executive summary: the bounce buffers are in my way - they use something like a 64 * 1500 bytes area of PCI consistent area - they are not resized when the MTU changes - they are used - to hand-pad undersized packets. skb_pad anyone ? - to linearize fragmented skbs whose fragment count goes beyond the 7 fragments hardware limit in order to claim scatter-gather support Actually the SG code is commented out and I wonder if it could not be implemented (ab-)using the large send feature of the chipset since the latter should support some multi-descriptor packet transmitting. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Fixed-by: Séguier Régis <rseguier@e-teleport.net> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* via-velocity: use memmoveStephen Hemminger2008-05-22
| | | | | | | Use memmove to handle overlapping copy of data. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* via-velocity: use netdev_alloc_skbStephen Hemminger2008-05-22
| | | | | | | | | | Use netdev_alloc_skb for rx buffer allocation. This sets skb->dev and can be overriden for NUMA machines. Change code to return new buffer rather than call by reference. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* via-velocity: fix vlan receiptFrancois Romieu2008-04-25
| | | | | | | | | | | | | | | | | - vlans were using a single CAM register (see mac_set_vlan_cam) - setting the address filtering registers for vlans is not needed when there is no vlan The non-tagged interface is filtered out as soon as a tagged (!= 0) interface is created. Its traffic appears again when an zero-tagged interface is created. Tested on Via Epia SN (VT6130 chipset) with several vlans whose tag was above or beyond 255. Signed-off-by: Séguier Régis <rseguier@e-teleport.net> Acked-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
* [NET] NETNS: Omit net_device->nd_net without CONFIG_NET_NS.YOSHIFUJI Hideaki2008-03-25
| | | | | | | | Introduce per-net_device inlines: dev_net(), dev_net_set(). Without CONFIG_NET_NS, no namespace other than &init_net exists. Let's explicitly define them to help compiler optimizations. Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
* [NETNS]: Disable inetaddr notifiers in namespaces other than initial.Denis V. Lunev2008-02-28
| | | | | | | ip_fib_init is kept enabled. It is already namespace-aware. Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
* [IPV4]: Remove ifa != NULL check.Denis V. Lunev2008-02-28
| | | | | | | | | | This is a callback registered to inet address notifier chain. The check is useless as: - ifa is always != NULL - similar checks are abscent in all other notifiers. Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: section fixAndrew Morton2008-02-10
| | | | | | | | | | | | | | | From: Andrew Morton <akpm@linux-foundation.org> gcc-3.4.4 on powerpc: drivers/net/via-velocity.c:443: error: chip_info_table causes a section type conflict on this one I had to remove the __devinitdata too. Don't know why. Cc: Jeff Garzik <jeff@garzik.org> Cc: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
* big-endian support for via-velocityAl Viro2008-02-03
| | | | | | | | | | | * kill bitfields * annotate * add missing conversions * fix a couple of brainos in zerocopy stuff (fortunately, it's ifdef'ed out) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: don't oops on MTU change (resend)Stephen Hemminger2007-12-01
| | | | | | | | | | The VIA veloicty driver needs the following to allow changing MTU when down. The buffer size needs to be computed when device is brought up, not when device is initialized. This also fixes a bug where the buffer size was computed differently on change_mtu versus initial setting. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
* [VIA_VELOCITY]: Don't oops on MTU change.Stephen Hemminger2007-11-14
| | | | | | | | Simple mtu change when device is down. Fix http://bugzilla.kernel.org/show_bug.cgi?id=9382. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
* Fix misspellings of "system", "controller", "interrupt" and "necessary".Robert P. J. Day2007-10-19
| | | | | | | | Fix the various misspellings of "system", controller", "interrupt" and "[un]necessary". Signed-off-by: Robert P. J. Day <rpjday@mindspring.com> Signed-off-by: Adrian Bunk <bunk@kernel.org>
* via-velocity: more cleanupStephen Hemminger2007-10-10
| | | | | | | | | | | | Per Al's suggestion, get rid of the stupid stuff: Remove cam_type switch, And deinline things that aren't important for speed. And make big macro and inline. And remove some dead/unused code. And use const char * for chip name. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
* via-velocity: use standard VLAN interface (resend)Stephen Hemminger2007-10-10
| | | | | | | | | | | | | | The via-velocity is using a non-standard VLAN interface configured via module parameters (yuck). Replace with the standard acceleration interface. It solves a number of problems with being able to handle multiple vlans, and dynamically reconfigure. This is compile tested only, don't have this board. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
* [NET]: Nuke SET_MODULE_OWNER macro.Ralf Baechle2007-10-10
| | | | | | | | | | | | It's been a useless no-op for long enough in 2.6 so I figured it's time to remove it. The number of people that could object because they're maintaining unified 2.4 and 2.6 drivers is probably rather small. [ Handled drivers added by netdev tree and some missed IRDA cases... -DaveM ] Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: David S. Miller <davem@davemloft.net>
* drivers/net/via-velocity.c: mostly kmalloc + memset conversion to kcallocMariusz Kozlowski2007-10-10
| | | | | | | | | | | Signed-off-by: Mariusz Kozlowski <m.kozlowski@tuxland.pl> drivers/net/via-velocity.c | 88263 -> 88120 (-143 bytes) drivers/net/via-velocity.o | 254264 -> 253828 (-436 bytes) drivers/net/via-velocity.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) Signed-off-by: Jeff Garzik <jeff@garzik.org>
* in-string typos of "error"Eddy L O Jansson2007-07-31
| | | | | | | | | | | | One patch for two trivial typos of 'error' with three R's, appearing in message strings. There's a bunch more of the same in comments, not dealt with here. Signed-off-by: Eddy L O Jansson <eddy@klopper.net> Cc: Roman Zippel <zippel@linux-m68k.org> Cc: Roland Dreier <rolandd@cisco.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* PCI: Change all drivers to use pci_device->revisionAuke Kok2007-07-11
| | | | | | | | | | | | | | | | | | | | Instead of all drivers reading pci config space to get the revision ID, they can now use the pci_device->revision member. This exposes some issues where drivers where reading a word or a dword for the revision number, and adding useless error-handling around the read. Some drivers even just read it for no purpose of all. In devices where the revision ID is being copied over and used in what appears to be the equivalent of hotpath, I have left the copy code and the cached copy as not to influence the driver's performance. Compile tested with make all{yes,mod}config on x86_64 and i386. Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Acked-by: Dave Jones <davej@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
* typo in via-velocity.cDave Jones2007-06-09
| | | | | | | http://bugzilla.kernel.org/show_bug.cgi?id=8160 Signed-off-by: Dave Jones <davej@redhat.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
* [SK_BUFF]: Introduce skb_copy_from_linear_data{_offset}Arnaldo Carvalho de Melo2007-04-26
| | | | | | | To clearly state the intent of copying from linear sk_buffs, _offset being a overly long variant but interesting for the sake of saving some bytes. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
* [SK_BUFF]: Introduce ip_hdr(), remove skb->nh.iphArnaldo Carvalho de Melo2007-04-26
| | | | | Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* [ETH]: Make eth_type_trans set skb->dev like the other *_type_transArnaldo Carvalho de Melo2007-04-26
| | | | | | | One less thing for drivers writers to worry about. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity uses INET interfacesRandy Dunlap2006-12-26
| | | | | | | | | | | | | | | | | | | | | | | | | | via-velocity doesn't build when CONFIG_INET=n: drivers/built-in.o: In function `velocity_unregister_notifier': via-velocity.c:(.text+0xe9b46): undefined reference to `unregister_inetaddr_notifier' drivers/built-in.o: In function `velocity_init_module': via-velocity.c:(.init.text+0xa027): undefined reference to `register_inetaddr_notifier' I wanted to make this change in drivers/net/Kconfig, but this isn't legal kconfig language: config VIA_VELOCITY tristate "VIA Velocity support" depends on NET_PCI && PCI + depends on INET if PM select CRC32 select CRC_CCITT select MII so fix it in via-velocity.c instead. Builds with all 4 combinations of CONFIG_NET & CONFIG_PM. Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
* [PATCH] crc32: replace bitreverse by bitrev32Akinobu Mita2006-12-08
| | | | | | | | | | | This patch replaces bitreverse() by bitrev32. The only users of bitreverse() are crc32 itself and via-velocity. Cc: Jeff Garzik <jgarzik@pobox.com> Cc: Matt Domsch <Matt_Domsch@dell.com> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
* IRQ: Maintain regs pointer globally rather than passing to IRQ handlersDavid Howells2006-10-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Maintain a per-CPU global "struct pt_regs *" variable which can be used instead of passing regs around manually through all ~1800 interrupt handlers in the Linux kernel. The regs pointer is used in few places, but it potentially costs both stack space and code to pass it around. On the FRV arch, removing the regs parameter from all the genirq function results in a 20% speed up of the IRQ exit path (ie: from leaving timer_interrupt() to leaving do_IRQ()). Where appropriate, an arch may override the generic storage facility and do something different with the variable. On FRV, for instance, the address is maintained in GR28 at all times inside the kernel as part of general exception handling. Having looked over the code, it appears that the parameter may be handed down through up to twenty or so layers of functions. Consider a USB character device attached to a USB hub, attached to a USB controller that posts its interrupts through a cascaded auxiliary interrupt controller. A character device driver may want to pass regs to the sysrq handler through the input layer which adds another few layers of parameter passing. I've build this code with allyesconfig for x86_64 and i386. I've runtested the main part of the code on FRV and i386, though I can't test most of the drivers. I've also done partial conversion for powerpc and MIPS - these at least compile with minimal configurations. This will affect all archs. Mostly the changes should be relatively easy. Take do_IRQ(), store the regs pointer at the beginning, saving the old one: struct pt_regs *old_regs = set_irq_regs(regs); And put the old one back at the end: set_irq_regs(old_regs); Don't pass regs through to generic_handle_irq() or __do_IRQ(). In timer_interrupt(), this sort of change will be necessary: - update_process_times(user_mode(regs)); - profile_tick(CPU_PROFILING, regs); + update_process_times(user_mode(get_irq_regs())); + profile_tick(CPU_PROFILING); I'd like to move update_process_times()'s use of get_irq_regs() into itself, except that i386, alone of the archs, uses something other than user_mode(). Some notes on the interrupt handling in the drivers: (*) input_dev() is now gone entirely. The regs pointer is no longer stored in the input_dev struct. (*) finish_unlinks() in drivers/usb/host/ohci-q.c needs checking. It does something different depending on whether it's been supplied with a regs pointer or not. (*) Various IRQ handler function pointers have been moved to type irq_handler_t. Signed-Off-By: David Howells <dhowells@redhat.com> (cherry picked from 1b16e7ac850969f38b375e511e3fa2f474a33867 commit)
* Merge branch 'upstream-linus' of ↵Linus Torvalds2006-09-24
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6 * 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (217 commits) net/ieee80211: fix more crypto-related build breakage [PATCH] Spidernet: add ethtool -S (show statistics) [NET] GT96100: Delete bitrotting ethernet driver [PATCH] mv643xx_eth: restrict to 32-bit PPC_MULTIPLATFORM [PATCH] Cirrus Logic ep93xx ethernet driver r8169: the MMIO region of the 8167 stands behin BAR#1 e1000, ixgb: Remove pointless wrappers [PATCH] Remove powerpc specific parts of 3c509 driver [PATCH] s2io: Switch to pci_get_device [PATCH] gt96100: move to pci_get_device API [PATCH] ehea: bugfix for register access functions [PATCH] e1000 disable device on PCI error drivers/net/phy/fixed: #if 0 some incomplete code drivers/net: const-ify ethtool_ops declarations [PATCH] ethtool: allow const ethtool_ops [PATCH] sky2: big endian [PATCH] sky2: fiber support [PATCH] sky2: tx pause bug fix drivers/net: Trim trailing whitespace [PATCH] ehea: IBM eHEA Ethernet Device Driver ... Manually resolved conflicts in drivers/net/ixgb/ixgb_main.c and drivers/net/sky2.c related to CHECKSUM_HW/CHECKSUM_PARTIAL changes by commit 84fa7933a33f806bbbaae6775e87459b1ec584c0 that just happened to be next to unrelated changes in this update.
| * drivers/net: const-ify ethtool_ops declarationsJeff Garzik2006-09-13
| | | | | | | | Signed-off-by: Jeff Garzik <jeff@garzik.org>
| * drivers/net: Trim trailing whitespaceJeff Garzik2006-09-13
| | | | | | | | Signed-off-by: Jeff Garzik <jeff@garzik.org>
| * Merge branch 'tmp' into upstreamJeff Garzik2006-09-12
| |\
| | * [PATCH] Remove more unnecessary driver printk'sAndy Gospodarek2006-09-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As I promised last week, here is the first pass at removing all unnecessary printk's that exist in network device drivers currently in promiscuous mode. The duplicate messages are not needed so they have been removed. Some of these drivers are quite old and might not need an update, but I did them all anyway. I am currently auditing the remaining conditional printk's and will send out a patch for those soon. Signed-off-by: Andy Gospodarek <andy@greyhouse.net> Signed-off-by: Jeff Garzik <jeff@garzik.org>
| * | drivers/net: Remove deprecated use of pci_module_init()Jeff Garzik2006-08-19
| |/ | | | | | | | | | | | | From: Michal Piotrowski <michal.k.k.piotrowski@gmail.com> Signed-off-by: Michal Piotrowski <michal.k.k.piotrowski@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
* / [NET]: Replace CHECKSUM_HW by CHECKSUM_PARTIAL/CHECKSUM_COMPLETEPatrick McHardy2006-09-22
|/ | | | | | | | | | | Replace CHECKSUM_HW by CHECKSUM_PARTIAL (for outgoing packets, whose checksum still needs to be completed) and CHECKSUM_COMPLETE (for incoming packets, device supplied full checksum). Patch originally from Herbert Xu, updated by myself for 2.6.18-rc3. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
* via-velocity: fix speed and link status reported by ethtoolJay Cliburn2006-07-20
| | | | | | | | | The via-velocity driver reports incorrect speed and link detected status as viewed by ethtool (and probably other tools). This patch fixes those incorrect reports and prettifies a long line. Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
* [netdrvr] use dev_xxx() printk helpers, rather than dev_printk(KERN_xxx, ...Jeff Garzik2006-07-05
| | | | | | Suggested by Jiri Slaby. Signed-off-by: Jeff Garzik <jeff@garzik.org>