From: Henry Andersen <HQA2330@nifty.ne.jp>
To: linux-kernel@vger.kernel.org
Subject: [PATCH] 2.5.44 update axnet_cs.c to support AX88790 chipset
Date: Sun, 27 Oct 2002 11:02:17 +0900 [thread overview]
Message-ID: <20021027110217.1ea4aa53.HQA2330@nifty.ne.jp> (raw)
Hi,
I update the axnet_cs.c to support Asix AX88790 chipset.
This code comes from the stand-alone pcmcia-cs axnet_cs.c ver1.26.
>eth0: Asix AX88790: io 0x300, irq 5, hw_addr 00:40:26:xx:xx:xx
>eth0: found link beat
>eth0: autonegotiation complete: 100baseT-FD selected
--- drivers/net/pcmcia/axnet_cs.c.orig Sat Oct 19 13:01:57 2002
+++ drivers/net/pcmcia/axnet_cs.c Sat Oct 26 21:22:16 2002
@@ -11,7 +11,7 @@
Copyright (C) 2001 David A. Hinds -- dahinds@users.sourceforge.net
- axnet_cs.c 1.11 2001/06/12 12:42:40
+ axnet_cs.c 1.26 2002/02/17 23:30:21
The network driver code is based on Donald Becker's NE2000 code:
@@ -20,7 +20,7 @@
Director, National Security Agency. This software may be used and
distributed according to the terms of the GNU General Public License,
incorporated herein by reference.
- Donald Becker may be reached at becker@cesdis1.gsfc.nasa.gov
+ Donald Becker may be reached at becker@scyld.com
======================================================================*/
@@ -33,14 +33,13 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
-#include <linux/ethtool.h>
-#include <asm/uaccess.h>
+#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/byteorder.h>
#include <linux/netdevice.h>
-#include "ax8390.h"
+#include "../8390.h"
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
@@ -53,34 +52,25 @@
#define AXNET_CMD 0x00
#define AXNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */
#define AXNET_RESET 0x1f /* Issue a read to reset, a write to clear. */
-#define AXNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */
#define AXNET_MII_EEP 0x14 /* Offset of MII access port */
+#define AXNET_TEST 0x15 /* Offset of TEST Register port */
+#define AXNET_GPIO 0x17 /* Offset of General Purpose Register Port */
#define AXNET_START_PG 0x40 /* First page of TX buffer */
#define AXNET_STOP_PG 0x80 /* Last page +1 of RX ring */
#define AXNET_RDC_TIMEOUT 0x02 /* Max wait in jiffies for Tx RDC */
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"axnet_cs.c 1.11 2001/06/12 12:42:40 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
-#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb);
-#define skb_tx_check(dev, skb)
-#define add_rx_bytes(stats, n) (stats)->rx_bytes += n;
-#define add_tx_bytes(stats, n) (stats)->tx_bytes += n;
-#define netif_mark_up(dev) do { } while (0)
-#define netif_mark_down(dev) do { } while (0)
+#define IS_AX88190 0x0001
+#define IS_AX88790 0x0002
/*====================================================================*/
-/* Parameters that can be set with 'insmod' */
+/* Module parameters */
+
+MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
+MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
+MODULE_LICENSE("GPL");
#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
@@ -89,9 +79,14 @@
static int irq_list[4] = { -1 };
MODULE_PARM(irq_list, "1-4i");
-/* Ugh! Let the user hardwire the hardware address for queer cards */
-static int hw_addr[6] = { 0, /* ... */ };
-MODULE_PARM(hw_addr, "6i");
+#ifdef PCMCIA_DEBUG
+INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version =
+"axnet_cs.c 1.26 2002/02/17 23:30:21 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
/*====================================================================*/
@@ -122,6 +117,12 @@
static dev_info_t dev_info = "axnet_cs";
static dev_link_t *dev_list;
+static int axdev_init(struct net_device *dev);
+static void AX88190_init(struct net_device *dev, int startp);
+static int ax_open(struct net_device *dev);
+static int ax_close(struct net_device *dev);
+static void ax_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
/*====================================================================*/
typedef struct axnet_dev_t {
@@ -134,6 +135,7 @@
u_short link_status;
u_char duplex_flag;
int phy_id;
+ int flags;
} axnet_dev_t;
/*======================================================================
@@ -212,7 +214,7 @@
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- ethdev_init(dev);
+ axdev_init(dev);
dev->init = &axnet_init;
dev->open = &axnet_open;
dev->stop = &axnet_close;
@@ -304,7 +306,7 @@
{0x00, EN0_RCNTHI},
{0x00, EN0_IMR}, /* Mask completion irq. */
{0xFF, EN0_ISR},
- {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
+ {E8390_RXOFF|0x40, EN0_RXCR}, /* 0x60 Set to monitor */
{E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
{0x10, EN0_RCNTLO},
{0x00, EN0_RCNTHI},
@@ -333,30 +335,6 @@
/*======================================================================
- This should be totally unnecessary... but when we can't figure
- out the hardware address any other way, we'll let the user hard
- wire it when the module is initialized.
-
-======================================================================*/
-
-static int get_hwired(dev_link_t *link)
-{
- struct net_device *dev = link->priv;
- int i;
-
- for (i = 0; i < 6; i++)
- if (hw_addr[i] != 0) break;
- if (i == 6)
- return 0;
-
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = hw_addr[i];
-
- return 1;
-} /* get_hwired */
-
-/*======================================================================
-
axnet_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
@@ -421,7 +399,8 @@
CS_CHECK(GetTupleData, handle, &tuple);
CS_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
+ /* don't trust the CIS on this; Linksys got it wrong */
+ link->conf.Present = 0x63;
/* Configure card */
link->state |= DEV_CONFIG;
@@ -442,7 +421,7 @@
if ((cfg->index == 0) || (cfg->io.nwin == 0))
goto next_entry;
- link->conf.ConfigIndex = cfg->index;
+ link->conf.ConfigIndex = 0x05;
/* For multifunction cards, by convention, we configure the
network function with window 0, and serial with window 1 */
if (io->nwin > 1) {
@@ -482,9 +461,9 @@
goto failed;
}
- if (!get_prom(link) && !get_hwired(link)) {
- printk(KERN_NOTICE "axnet_cs: unable to read hardware net"
- " address for io base %#3lx\n", dev->base_addr);
+ if (!get_prom(link)) {
+ printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
+ printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n");
unregister_netdev(dev);
goto failed;
}
@@ -503,15 +482,37 @@
link->dev = &info->node;
link->state &= ~DEV_CONFIG_PENDING;
- printk(KERN_INFO "%s: Asix AX88190: io %#3lx, irq %d, hw_addr ",
- dev->name, dev->base_addr, dev->irq);
+ if (inb(dev->base_addr + AXNET_TEST) != 0)
+ info->flags |= IS_AX88790;
+ else
+ info->flags |= IS_AX88190;
+
+ printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, hw_addr ",
+ dev->name, ((info->flags & IS_AX88790) ? 7 : 1),
+ dev->base_addr, dev->irq);
for (i = 0; i < 6; i++)
printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
+ if (info->flags & IS_AX88790)
+ outb(0x10, dev->base_addr + AXNET_GPIO); /* select Internal PHY */
+
for (i = 0; i < 32; i++) {
j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
if ((j != 0) && (j != 0xffff)) break;
}
+
+
+ /* Maybe PHY is in power down mode. (PPD_SET = 1)
+ Bit 2 of CCSR is active low. */
+ if (i == 32) {
+ conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 };
+ CardServices(AccessConfigurationRegister, link->handle, ®);
+ for (i = 0; i < 32; i++) {
+ j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
+ if ((j != 0) && (j != 0xffff)) break;
+ }
+ }
+
info->phy_id = (i < 32) ? i : -1;
if (i < 32) {
DEBUG(0, " MII transceiver at index %d, status %x.\n", i, j);
@@ -544,7 +545,7 @@
if (link->open) {
DEBUG(1, "axnet_cs: release postponed, '%s' still open\n",
- info->node.dev_name);
+ ((axnet_dev_t *)(link->priv))->node.dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
@@ -604,7 +605,7 @@
CardServices(RequestConfiguration, link->handle, &link->conf);
if (link->open) {
axnet_reset_8390(&info->dev);
- NS8390_init(&info->dev, 1);
+ AX88190_init(&info->dev, 1);
netif_device_attach(&info->dev);
}
}
@@ -694,7 +695,7 @@
info->watchdog.expires = jiffies + HZ;
add_timer(&info->watchdog);
- return ei_open(dev);
+ return ax_open(dev);
} /* axnet_open */
/*====================================================================*/
@@ -706,11 +707,11 @@
DEBUG(2, "axnet_close('%s')\n", dev->name);
+ ax_close(dev);
free_irq(dev->irq, dev);
link->open--;
netif_stop_queue(dev);
- netif_mark_down(dev);
del_timer(&info->watchdog);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
@@ -757,7 +758,7 @@
{
axnet_dev_t *info = dev_id;
info->stale = 0;
- ei_interrupt(irq, dev_id, regs);
+ ax_interrupt(irq, dev_id, regs);
}
static void ei_watchdog(u_long arg)
@@ -809,7 +810,7 @@
else
printk(KERN_INFO "%s: link partner did not autonegotiate\n",
dev->name);
- NS8390_init(dev, 1);
+ AX88190_init(dev, 1);
}
info->link_status = link;
}
@@ -819,27 +820,6 @@
add_timer(&info->watchdog);
}
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
-{
- u32 ethcmd;
-
- if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
- return -EFAULT;
-
- switch (ethcmd) {
- case ETHTOOL_GDRVINFO: {
- struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-
- strncpy(info.driver, "axnet_cs", sizeof(info.driver)-1);
- if (copy_to_user(useraddr, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- }
-
- return -EOPNOTSUPP;
-}
-
/*====================================================================*/
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -848,8 +828,6 @@
u16 *data = (u16 *)&rq->ifr_data;
ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
switch (cmd) {
- case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCDEVPRIVATE:
data[0] = info->phy_id;
case SIOCDEVPRIVATE+1:
@@ -940,7 +918,7 @@
if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "axnet_cs: Card Services release "
"does not match!\n");
- return -1;
+ return -EINVAL;
}
register_pccard_driver(&dev_info, &axnet_attach, &axnet_detach);
return 0;
@@ -969,10 +947,11 @@
This software may be used and distributed according to the terms
of the GNU General Public License, incorporated herein by reference.
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
+ The author may be reached as becker@scyld.com, or C/O
+ Scyld Computing Corporation
+ 410 Severn Ave., Suite 210
+ Annapolis MD 21403
+
This is the chip-specific code for many 8390-based ethernet adaptors.
This is not a complete driver, it must be combined with board-specific
code such as ne.c, wd.c, 3c503.c, etc.
@@ -982,7 +961,6 @@
a simple innocent change. Please contact me or Donald if you think
you have found something that needs changing. -- PG
-
Changelog:
Paul Gortmaker : remove set_bit lock, other cleanups.
@@ -1006,8 +984,8 @@
*/
-static const char *version =
- "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+static const char *version_8390 =
+ "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n";
#include <asm/uaccess.h>
#include <asm/bitops.h>
@@ -1087,25 +1065,23 @@
* them.
*/
-
-\f
/**
- * ei_open - Open/initialize the board.
+ * ax_open - Open/initialize the board.
* @dev: network device to initialize
*
* This routine goes all-out, setting everything
* up anew at each open, even though many of these registers should only
* need to be set once at boot.
*/
-static int ei_open(struct net_device *dev)
+static int ax_open(struct net_device *dev)
{
unsigned long flags;
struct ei_device *ei_local = (struct ei_device *) dev->priv;
- /* This can't happen unless somebody forgot to call ethdev_init(). */
+ /* This can't happen unless somebody forgot to call axdev_init(). */
if (ei_local == NULL)
{
- printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name);
+ printk(KERN_EMERG "%s: ax_open passed a non-existent device!\n", dev->name);
return -ENXIO;
}
@@ -1124,35 +1100,36 @@
*/
spin_lock_irqsave(&ei_local->page_lock, flags);
- NS8390_init(dev, 1);
+ AX88190_init(dev, 1);
/* Set the flag before we drop the lock, That way the IRQ arrives
after its set and we get no silly warnings */
- netif_mark_up(dev);
netif_start_queue(dev);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
ei_local->irqlock = 0;
return 0;
}
+#define dev_lock(dev) (((struct ei_device *)(dev)->priv)->page_lock)
+
/**
- * ei_close - shut down network device
+ * ax_close - shut down network device
* @dev: network device to close
*
- * Opposite of ei_open(). Only used when "ifconfig <devname> down" is done.
+ * Opposite of ax_open(). Only used when "ifconfig <devname> down" is done.
*/
-static int ei_close(struct net_device *dev)
+int ax_close(struct net_device *dev)
{
- unsigned long flags;
+ unsigned long flags;
- /*
- * Hold the page lock during close
- */
-
- spin_lock_irqsave(&((struct ei_device *)dev->priv)->page_lock, flags);
- NS8390_init(dev, 0);
- spin_unlock_irqrestore(&((struct ei_device *)dev->priv)->page_lock, flags);
- netif_stop_queue(dev);
- return 0;
+ /*
+ * Hold the page lock during close
+ */
+
+ spin_lock_irqsave(&dev_lock(dev), flags);
+ AX88190_init(dev, 0);
+ spin_unlock_irqrestore(&dev_lock(dev), flags);
+ netif_stop_queue(dev);
+ return 0;
}
/**
@@ -1194,7 +1171,7 @@
/* Try to restart the card. Perhaps the user has fixed something. */
ei_reset_8390(dev);
- NS8390_init(dev, 1);
+ AX88190_init(dev, 1);
spin_unlock(&ei_local->page_lock);
enable_irq(dev->irq);
@@ -1217,7 +1194,6 @@
unsigned long flags;
netif_stop_queue(dev);
- skb_tx_check(dev, skb);
length = skb->len;
@@ -1230,7 +1206,6 @@
outb_p(0x00, e8390_base + EN0_IMR);
spin_unlock_irqrestore(&ei_local->page_lock, flags);
-
/*
* Slow phase with lock held.
*/
@@ -1243,8 +1218,6 @@
send_length = ETH_ZLEN < length ? length : ETH_ZLEN;
-#ifdef EI_PINGPONG
-
/*
* We have two Tx slots available for use. Find the first free
* slot, and then perform some sanity checks. With two Tx bufs,
@@ -1313,22 +1286,6 @@
else
netif_start_queue(dev);
-#else /* EI_PINGPONG */
-
- /*
- * Only one Tx buffer in use. You need two Tx bufs to come close to
- * back-to-back transmits. Expect a 20 -> 25% performance hit on
- * reasonable hardware if you only use one Tx buffer.
- */
-
- ei_block_output(dev, length, skb->data, ei_local->tx_start_page);
- ei_local->txing = 1;
- NS8390_trigger_send(dev, send_length, ei_local->tx_start_page);
- dev->trans_start = jiffies;
- netif_stop_queue(dev);
-
-#endif /* EI_PINGPONG */
-
/* Turn 8390 interrupts back on. */
ei_local->irqlock = 0;
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
@@ -1336,14 +1293,14 @@
spin_unlock(&ei_local->page_lock);
enable_irq(dev->irq);
- DEV_KFREE_SKB (skb);
- add_tx_bytes(&ei_local->stat, send_length);
+ dev_kfree_skb (skb);
+ ei_local->stat.tx_bytes += send_length;
return 0;
}
\f
/**
- * ei_interrupt - handle the interrupts from an 8390
+ * ax_interrupt - handle the interrupts from an 8390
* @irq: interrupt number
* @dev_id: a pointer to the net_device
* @regs: unused
@@ -1355,7 +1312,7 @@
* needed.
*/
-static void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static void ax_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
struct net_device *dev = dev_id;
long e8390_base;
@@ -1522,8 +1479,6 @@
struct ei_device *ei_local = (struct ei_device *) dev->priv;
int status = inb(e8390_base + EN0_TSR);
-#ifdef EI_PINGPONG
-
/*
* There are two Tx buffers, see which one finished, and trigger
* the send of another one if it exists.
@@ -1566,13 +1521,6 @@
// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",
// dev->name, ei_local->lasttx);
-#else /* EI_PINGPONG */
- /*
- * Single Tx buffer: mark it free so another packet can be loaded.
- */
- ei_local->txing = 0;
-#endif
-
/* Minimize Tx latency: update the statistics after we restart TXing. */
if (status & ENTSR_COL)
ei_local->stat.collisions++;
@@ -1680,7 +1628,7 @@
netif_rx(skb);
dev->last_rx = jiffies;
ei_local->stat.rx_packets++;
- add_rx_bytes(&ei_local->stat, pkt_len);
+ ei_local->stat.rx_bytes += pkt_len;
if (pkt_stat & ENRSR_PHY)
ei_local->stat.multicast++;
}
@@ -1826,11 +1774,11 @@
long e8390_base = dev->base_addr;
if(dev->flags&IFF_PROMISC)
- outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR);
+ outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR);
else if(dev->flags&IFF_ALLMULTI || dev->mc_list)
- outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR);
+ outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR);
else
- outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
+ outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR);
}
/*
@@ -1838,28 +1786,28 @@
* be parallel to just about everything else. Its also fairly quick and
* not called too often. Must protect against both bh and irq users
*/
-
+
static void set_multicast_list(struct net_device *dev)
{
unsigned long flags;
- spin_lock_irqsave(&((struct ei_device *)dev->priv)->page_lock, flags);
+ spin_lock_irqsave(&dev_lock(dev), flags);
do_set_multicast_list(dev);
- spin_unlock_irqrestore(&((struct ei_device *)dev->priv)->page_lock, flags);
+ spin_unlock_irqrestore(&dev_lock(dev), flags);
}
/**
- * ethdev_init - init rest of 8390 device struct
+ * axdev_init - init rest of 8390 device struct
* @dev: network device structure to init
*
* Initialize the rest of the 8390 device structure. Do NOT __init
* this, as it is used by 8390 based modular drivers too.
*/
-static int ethdev_init(struct net_device *dev)
+static int axdev_init(struct net_device *dev)
{
if (ei_debug > 1)
- printk(version);
+ printk(version_8390);
if (dev->priv == NULL)
{
@@ -1882,20 +1830,18 @@
return 0;
}
\f
-
-
/* This page of functions should be 8390 generic */
/* Follow National Semi's recommendations for initializing the "NIC". */
/**
- * NS8390_init - initialize 8390 hardware
+ * AX88190_init - initialize 8390 hardware
* @dev: network device to initialize
* @startp: boolean. non-zero value to initiate chip processing
*
* Must be called with lock held.
*/
-static void NS8390_init(struct net_device *dev, int startp)
+static void AX88190_init(struct net_device *dev, int startp)
{
axnet_dev_t *info = (axnet_dev_t *)dev;
long e8390_base = dev->base_addr;
@@ -1912,7 +1858,7 @@
outb_p(0x00, e8390_base + EN0_RCNTLO);
outb_p(0x00, e8390_base + EN0_RCNTHI);
/* Set to monitor and loopback mode -- this is vital!. */
- outb_p(E8390_RXOFF, e8390_base + EN0_RXCR); /* 0x20 */
+ outb_p(E8390_RXOFF|0x40, e8390_base + EN0_RXCR); /* 0x60 */
outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */
/* Set the transmit page and receive ring. */
outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR);
@@ -1956,7 +1902,7 @@
outb_p(E8390_TXCONFIG | info->duplex_flag,
e8390_base + EN0_TXCR); /* xmit on. */
/* 3c503 TechMan says rxconfig only after the NIC is started. */
- outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); /* rx on, */
+ outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); /* rx on, */
do_set_multicast_list(dev); /* (re)load the mcast table */
}
}
reply other threads:[~2002-10-27 1:57 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20021027110217.1ea4aa53.HQA2330@nifty.ne.jp \
--to=hqa2330@nifty.ne.jp \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.