From: Alan Cox <alan@lxorguk.ukuu.org.uk>
To: linux-kernel@vger.kernel.org
Subject: [PATCH 15/70] rocket: use tty_port
Date: Fri, 20 Jun 2008 21:00:03 +0100 [thread overview]
Message-ID: <20080620200002.1479.6483.stgit@localhost.localdomain> (raw)
In-Reply-To: <20080620195406.1479.12620.stgit@localhost.localdomain>
From: Alan Cox <alan@redhat.com>
Switch the rocketport to use the new tty_port structure
Signed-off-by: Alan Cox <alan@redhat.com>
---
drivers/char/rocket.c | 116 +++++++++++++++++++++++----------------------
drivers/char/rocket_int.h | 9 +--
2 files changed, 61 insertions(+), 64 deletions(-)
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 743dc80..ab04adb 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -434,15 +434,15 @@ static void rp_do_transmit(struct r_port *info)
#endif
if (!info)
return;
- if (!info->tty) {
+ if (!info->port.tty) {
printk(KERN_WARNING "rp: WARNING %s called with "
- "info->tty==NULL\n", __func__);
+ "info->port.tty==NULL\n", __func__);
clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
return;
}
spin_lock_irqsave(&info->slock, flags);
- tty = info->tty;
+ tty = info->port.tty;
info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
/* Loop sending data to FIFO until done or FIFO full */
@@ -502,13 +502,13 @@ static void rp_handle_port(struct r_port *info)
"info->flags & NOT_INIT\n");
return;
}
- if (!info->tty) {
+ if (!info->port.tty) {
printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
- "info->tty==NULL\n");
+ "info->port.tty==NULL\n");
return;
}
cp = &info->channel;
- tty = info->tty;
+ tty = info->port.tty;
IntMask = sGetChanIntID(cp) & info->intmask;
#ifdef ROCKET_DEBUG_INTR
@@ -530,7 +530,7 @@ static void rp_handle_port(struct r_port *info)
tty_hangup(tty);
}
info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
#ifdef ROCKET_DEBUG_INTR
if (IntMask & DELTA_CTS) { /* CTS change */
@@ -650,7 +650,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
info->chan = chan;
info->closing_wait = 3000;
info->close_delay = 50;
- init_waitqueue_head(&info->open_wait);
+ init_waitqueue_head(&info->port.open_wait);
init_completion(&info->close_wait);
info->flags &= ~ROCKET_MODE_MASK;
switch (pc104[board][line]) {
@@ -717,7 +717,7 @@ static void configure_r_port(struct r_port *info,
unsigned rocketMode;
int bits, baud, divisor;
CHANNEL_t *cp;
- struct ktermios *t = info->tty->termios;
+ struct ktermios *t = info->port.tty->termios;
cp = &info->channel;
cflag = t->c_cflag;
@@ -750,7 +750,7 @@ static void configure_r_port(struct r_port *info,
}
/* baud rate */
- baud = tty_get_baud_rate(info->tty);
+ baud = tty_get_baud_rate(info->port.tty);
if (!baud)
baud = 9600;
divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
@@ -768,7 +768,7 @@ static void configure_r_port(struct r_port *info,
sSetBaud(cp, divisor);
/* FIXME: Should really back compute a baud rate from the divisor */
- tty_encode_baud_rate(info->tty, baud, baud);
+ tty_encode_baud_rate(info->port.tty, baud, baud);
if (cflag & CRTSCTS) {
info->intmask |= DELTA_CTS;
@@ -793,15 +793,15 @@ static void configure_r_port(struct r_port *info,
* Handle software flow control in the board
*/
#ifdef ROCKET_SOFT_FLOW
- if (I_IXON(info->tty)) {
+ if (I_IXON(info->port.tty)) {
sEnTxSoftFlowCtl(cp);
- if (I_IXANY(info->tty)) {
+ if (I_IXANY(info->port.tty)) {
sEnIXANY(cp);
} else {
sDisIXANY(cp);
}
- sSetTxXONChar(cp, START_CHAR(info->tty));
- sSetTxXOFFChar(cp, STOP_CHAR(info->tty));
+ sSetTxXONChar(cp, START_CHAR(info->port.tty));
+ sSetTxXOFFChar(cp, STOP_CHAR(info->port.tty));
} else {
sDisTxSoftFlowCtl(cp);
sDisIXANY(cp);
@@ -813,24 +813,24 @@ static void configure_r_port(struct r_port *info,
* Set up ignore/read mask words
*/
info->read_status_mask = STMRCVROVRH | 0xFF;
- if (I_INPCK(info->tty))
+ if (I_INPCK(info->port.tty))
info->read_status_mask |= STMFRAMEH | STMPARITYH;
- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
info->read_status_mask |= STMBREAKH;
/*
* Characters to ignore
*/
info->ignore_status_mask = 0;
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
- if (I_IGNBRK(info->tty)) {
+ if (I_IGNBRK(info->port.tty)) {
info->ignore_status_mask |= STMBREAKH;
/*
* If we're ignoring parity and break indicators,
* ignore overruns too. (For real raw support).
*/
- if (I_IGNPAR(info->tty))
+ if (I_IGNPAR(info->port.tty))
info->ignore_status_mask |= STMRCVROVRH;
}
@@ -863,7 +863,7 @@ static void configure_r_port(struct r_port *info,
}
}
-/* info->count is considered critical, protected by spinlocks. */
+/* info->port.count is considered critical, protected by spinlocks. */
static int block_til_ready(struct tty_struct *tty, struct file *filp,
struct r_port *info)
{
@@ -897,13 +897,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
/*
* Block waiting for the carrier detect and the line to become free. While we are in
- * this loop, info->count is dropped by one, so that rp_close() knows when to free things.
+ * this loop, info->port.count is dropped by one, so that rp_close() knows when to free things.
* We restore it upon exit, either normal or abnormal.
*/
retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ add_wait_queue(&info->port.open_wait, &wait);
#ifdef ROCKET_DEBUG_OPEN
- printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->count);
+ printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->port.count);
#endif
spin_lock_irqsave(&info->slock, flags);
@@ -912,10 +912,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
#else
if (!tty_hung_up_p(filp)) {
extra_count = 1;
- info->count--;
+ info->port.count--;
}
#endif
- info->blocked_open++;
+ info->port.blocked_open++;
spin_unlock_irqrestore(&info->slock, flags);
@@ -940,24 +940,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
}
#ifdef ROCKET_DEBUG_OPEN
printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
- info->line, info->count, info->flags);
+ info->line, info->port.count, info->flags);
#endif
schedule(); /* Don't hold spinlock here, will hang PC */
}
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&info->open_wait, &wait);
+ remove_wait_queue(&info->port.open_wait, &wait);
spin_lock_irqsave(&info->slock, flags);
if (extra_count)
- info->count++;
- info->blocked_open--;
+ info->port.count++;
+ info->port.blocked_open--;
spin_unlock_irqrestore(&info->slock, flags);
#ifdef ROCKET_DEBUG_OPEN
printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
- info->line, info->count);
+ info->line, info->port.count);
#endif
if (retval)
return retval;
@@ -1001,9 +1001,9 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
info->xmit_buf = (unsigned char *) page;
tty->driver_data = info;
- info->tty = tty;
+ info->port.tty = tty;
- if (info->count++ == 0) {
+ if (info->port.count++ == 0) {
atomic_inc(&rp_num_ports_open);
#ifdef ROCKET_DEBUG_OPEN
@@ -1012,7 +1012,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
#endif
}
#ifdef ROCKET_DEBUG_OPEN
- printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->count);
+ printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
#endif
/*
@@ -1048,13 +1048,13 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
* Set up the tty->alt_speed kludge
*/
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
- info->tty->alt_speed = 57600;
+ info->port.tty->alt_speed = 57600;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
- info->tty->alt_speed = 115200;
+ info->port.tty->alt_speed = 115200;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
- info->tty->alt_speed = 230400;
+ info->port.tty->alt_speed = 230400;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
- info->tty->alt_speed = 460800;
+ info->port.tty->alt_speed = 460800;
configure_r_port(info, NULL);
if (tty->termios->c_cflag & CBAUD) {
@@ -1076,7 +1076,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
}
/*
- * Exception handler that closes a serial port. info->count is considered critical.
+ * Exception handler that closes a serial port. info->port.count is considered critical.
*/
static void rp_close(struct tty_struct *tty, struct file *filp)
{
@@ -1089,14 +1089,14 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
return;
#ifdef ROCKET_DEBUG_OPEN
- printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->count);
+ printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
#endif
if (tty_hung_up_p(filp))
return;
spin_lock_irqsave(&info->slock, flags);
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (info->port.count != 1)) {
/*
* Uh, oh. tty->count is 1, which means that the tty
* structure will be freed. Info->count should always
@@ -1105,15 +1105,15 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
* serial port won't be shutdown.
*/
printk(KERN_WARNING "rp_close: bad serial port count; "
- "tty->count is 1, info->count is %d\n", info->count);
- info->count = 1;
+ "tty->count is 1, info->port.count is %d\n", info->port.count);
+ info->port.count = 1;
}
- if (--info->count < 0) {
+ if (--info->port.count < 0) {
printk(KERN_WARNING "rp_close: bad serial port count for "
- "ttyR%d: %d\n", info->line, info->count);
- info->count = 0;
+ "ttyR%d: %d\n", info->line, info->port.count);
+ info->port.count = 0;
}
- if (info->count) {
+ if (info->port.count) {
spin_unlock_irqrestore(&info->slock, flags);
return;
}
@@ -1167,11 +1167,11 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
- if (info->blocked_open) {
+ if (info->port.blocked_open) {
if (info->close_delay) {
msleep_interruptible(jiffies_to_msecs(info->close_delay));
}
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
} else {
if (info->xmit_buf) {
free_page((unsigned long) info->xmit_buf);
@@ -1357,13 +1357,13 @@ static int set_config(struct r_port *info, struct rocket_config __user *new_info
info->closing_wait = new_serial.closing_wait;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
- info->tty->alt_speed = 57600;
+ info->port.tty->alt_speed = 57600;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
- info->tty->alt_speed = 115200;
+ info->port.tty->alt_speed = 115200;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
- info->tty->alt_speed = 230400;
+ info->port.tty->alt_speed = 230400;
if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
- info->tty->alt_speed = 460800;
+ info->port.tty->alt_speed = 460800;
configure_r_port(info, NULL);
return 0;
@@ -1636,13 +1636,13 @@ static void rp_hangup(struct tty_struct *tty)
rp_flush_buffer(tty);
if (info->flags & ROCKET_CLOSING)
return;
- if (info->count)
+ if (info->port.count)
atomic_dec(&rp_num_ports_open);
clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
- info->count = 0;
+ info->port.count = 0;
info->flags &= ~ROCKET_NORMAL_ACTIVE;
- info->tty = NULL;
+ info->port.tty = NULL;
cp = &info->channel;
sDisRxFIFO(cp);
@@ -1653,7 +1653,7 @@ static void rp_hangup(struct tty_struct *tty)
sClrTxXOFF(cp);
info->flags &= ~ROCKET_INITIALIZED;
- wake_up_interruptible(&info->open_wait);
+ wake_up_interruptible(&info->port.open_wait);
}
/*
@@ -1762,7 +1762,7 @@ static int rp_write(struct tty_struct *tty,
/* Write remaining data into the port's xmit_buf */
while (1) {
- if (!info->tty) /* Seemingly obligatory check... */
+ if (!info->port.tty) /* Seemingly obligatory check... */
goto end;
c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
c = min(c, XMIT_BUF_SIZE - info->xmit_head);
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 143cc43..3affc48 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1125,11 +1125,9 @@ Warnings: This function writes the data byte without checking to see if
struct r_port {
int magic;
+ struct tty_port port;
int line;
- int flags;
- int count;
- int blocked_open;
- struct tty_struct *tty;
+ int flags; /* Don't yet match the ASY_ flags!! */
unsigned int board:3;
unsigned int aiop:2;
unsigned int chan:3;
@@ -1148,8 +1146,7 @@ struct r_port {
int read_status_mask;
int cps;
- wait_queue_head_t open_wait;
- struct completion close_wait;
+ struct completion close_wait; /* Not yet matching the core */
spinlock_t slock;
struct mutex write_mtx;
};
next prev parent reply other threads:[~2008-06-20 20:21 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-20 19:57 [PATCH 00/70] tty updates proposed for 2.6.27 Alan Cox
2008-06-20 19:58 ` [PATCH 01/70] tty: Ldisc revamp Alan Cox
2008-06-23 13:39 ` Louis Rilling
2008-06-23 14:11 ` Alan Cox
2008-06-20 19:58 ` [PATCH 02/70] drivers/char/rio/: remove VCS tags Alan Cox
2008-06-20 19:58 ` [PATCH 03/70] drivers/serial/: remove CVS keywords Alan Cox
2008-06-20 19:58 ` [PATCH 04/70] tty: Introduce a tty_port common structure Alan Cox
2008-06-20 19:58 ` [PATCH 05/70] tty.h: clean up Alan Cox
2008-06-20 19:59 ` [PATCH 06/70] epca: use tty_port Alan Cox
2008-06-20 19:59 ` [PATCH 07/70] esp: " Alan Cox
2008-06-20 19:59 ` [PATCH 08/70] gs: " Alan Cox
2008-06-20 19:59 ` [PATCH 09/70] riscom8: " Alan Cox
2008-06-20 19:59 ` [PATCH 10/70] riscom8: remove bogus checks Alan Cox
2008-06-20 19:59 ` [PATCH 11/70] isicom: use tty_port Alan Cox
2008-06-20 19:59 ` [PATCH 12/70] istallion: " Alan Cox
2008-06-20 19:59 ` [PATCH 13/70] moxa: " Alan Cox
2008-06-20 19:59 ` [PATCH 14/70] mxser: " Alan Cox
2008-06-20 20:00 ` Alan Cox [this message]
2008-06-20 20:00 ` [PATCH 16/70] serial: " Alan Cox
2008-06-20 20:00 ` [PATCH 17/70] stallion: " Alan Cox
2008-06-20 20:00 ` [PATCH 18/70] synclink: " Alan Cox
2008-06-20 20:00 ` [PATCH 19/70] tty: Clean up tiocmset Alan Cox
2008-06-20 20:00 ` [PATCH 20/70] cyclades: use tty_port Alan Cox
2008-06-20 20:00 ` [PATCH 21/70] termios: Termios defines for other platforms Alan Cox
2008-06-20 20:00 ` [PATCH 22/70] tty: add more tty_port fields Alan Cox
2008-06-20 20:01 ` [PATCH 24/70] whiteheat: coding style Alan Cox
2008-06-20 20:01 ` [PATCH 25/70] whiteheat: fix bugs found in the tidy and audit Alan Cox
2008-06-20 20:01 ` [PATCH 26/70] belkin_sa: clean up code Alan Cox
2008-06-20 20:01 ` [PATCH 27/70] usb-serial-bus: tidy coding style Alan Cox
2008-06-20 20:01 ` [PATCH 28/70] tty-usb-console: tidy the USB console code Alan Cox
2008-06-20 20:01 ` [PATCH 29/70] tty-usb-console: Fix termios Alan Cox
2008-06-20 20:02 ` [PATCH 30/70] cp2101: coding style Alan Cox
2008-06-20 20:02 ` [PATCH 31/70] cyberjack: Coding style Alan Cox
2008-06-20 20:02 ` [PATCH 32/70] cypress_m8: coding style Alan Cox
2008-06-20 20:02 ` [PATCH 33/70] usb-cypress: There is no 0 case to go with CS5/6/7/8 so remove the test Alan Cox
2008-06-20 20:02 ` [PATCH 34/70] digi_acceleport: coding style Alan Cox
2008-06-20 20:02 ` [PATCH 35/70] empeg: Coding style Alan Cox
2008-06-20 20:02 ` [PATCH 36/70] ftdi_sio: " Alan Cox
2008-06-20 20:02 ` [PATCH 37/70] funsoft: Switch to linux/uaccess Alan Cox
2008-06-20 20:03 ` [PATCH 38/70] garmin_gps: Coding style Alan Cox
2008-06-20 20:03 ` [PATCH 39/70] tty-usb-generic: Code cleanup Alan Cox
2008-06-20 20:03 ` [PATCH 40/70] tty-usb-hp4x: Fix overlong line Alan Cox
2008-06-20 20:03 ` [PATCH 41/70] tty-usb-visor: Coding style Alan Cox
2008-06-20 20:03 ` [PATCH 42/70] tty-usb-io_edgeport: " Alan Cox
2008-06-20 20:03 ` [PATCH 43/70] io_edgeport: Fix various bogus returns to the tty layer Alan Cox
2008-06-20 20:03 ` [PATCH 44/70] usb-serial: Coding style Alan Cox
2008-06-20 20:04 ` [PATCH 45/70] io_ti: Minor coding style Alan Cox
2008-06-20 20:04 ` [PATCH 46/70] ipaq: Coding style Alan Cox
2008-06-20 20:04 ` [PATCH 47/70] tty-usb-ipw: " Alan Cox
2008-06-20 20:04 ` [PATCH 48/70] tty-usb-ir-usb: Clean up to coding style Alan Cox
2008-06-20 20:04 ` [PATCH 49/70] tty-usb-iuu-phoenix: " Alan Cox
2008-06-20 20:04 ` [PATCH 50/70] tty-usb-keyspan: Coding style Alan Cox
2008-06-20 20:04 ` [PATCH 51/70] keyspan: Use string flip functions when possible Alan Cox
2008-06-20 20:04 ` [PATCH 52/70] tty-usb-keyspan-pda: Coding style Alan Cox
2008-06-20 20:05 ` [PATCH 53/70] tty-usb-kl5kusb105: " Alan Cox
2008-06-20 20:05 ` [PATCH 54/70] keyspan_pda: Use string flip functions Alan Cox
2008-06-20 20:05 ` [PATCH 55/70] tty-usb-kobil-sct: Coding style Alan Cox
2008-06-20 20:05 ` [PATCH 56/70] kobil_sct: Fix ioctls Alan Cox
2008-06-20 20:05 ` [PATCH 57/70] tty-usb-mct-u232: Coding style Alan Cox
2008-06-20 20:05 ` [PATCH 58/70] mct_u232: Use flip buffer functions Alan Cox
2008-06-20 20:06 ` [PATCH 59/70] tty-usb-pl2303: Coding style Alan Cox
2008-06-20 20:06 ` [PATCH 60/70] tty-usb-sierra: Coding style - minor Alan Cox
2008-06-20 20:06 ` [PATCH 61/70] tty-usb-spcp8x5: Minor coding style Alan Cox
2008-06-20 20:06 ` [PATCH 62/70] tty-usb-ti-usb: Coding style Alan Cox
2008-06-20 20:06 ` [PATCH 63/70] tty-usb-safe-serial: " Alan Cox
2008-06-20 20:06 ` [PATCH 64/70] tty-usb-oti6858: " Alan Cox
2008-06-20 20:06 ` [PATCH 65/70] tty-usb-option: " Alan Cox
2008-06-20 20:06 ` [PATCH 66/70] tty-usb-omninet: " Alan Cox
2008-06-20 20:07 ` [PATCH 67/70] omninet: Use string flip functions Alan Cox
2008-06-20 20:07 ` [PATCH 68/70] mos7840: remove loads of bogus assignments to status Alan Cox
2008-06-20 20:07 ` [PATCH 69/70] whiteheat: remove unused variable Alan Cox
2008-06-20 20:07 ` [PATCH 70/70] tty-usb-mos7720: Coding style Alan Cox
2008-06-20 23:39 ` [PATCH 00/70] tty updates proposed for 2.6.27 Johannes Weiner
2008-06-21 9:09 ` Greg KH
2008-06-21 10:17 ` (Resend of 23/70 plus reply [PATCH 00/70] tty updates proposed for 2.6.27) Alan Cox
2008-06-21 11:19 ` Adrian Bunk
2008-06-22 17:07 ` Alan Cox
2008-06-22 18:39 ` Greg KH
2008-06-21 13:23 ` [PATCH 00/70] tty updates proposed for 2.6.27 Marcel Holtmann
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=20080620200002.1479.6483.stgit@localhost.localdomain \
--to=alan@lxorguk.ukuu.org.uk \
--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.