From: Wu Hao <hao.wu@intel.com>
To: atull@kernel.org, mdf@kernel.org, linux-fpga@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: linux-api@vger.kernel.org, luwei.kang@intel.com,
yi.z.zhang@intel.com, hao.wu@intel.com,
Xiao Guangrong <guangrong.xiao@linux.intel.com>,
Tim Whisonant <tim.whisonant@intel.com>,
Enno Luebbers <enno.luebbers@intel.com>,
Shiva Rao <shiva.rao@intel.com>,
Christopher Rauer <christopher.rauer@intel.com>
Subject: [PATCH v3 07/21] fpga: dfl: add feature device infrastructure
Date: Mon, 27 Nov 2017 14:42:14 +0800 [thread overview]
Message-ID: <1511764948-20972-8-git-send-email-hao.wu@intel.com> (raw)
In-Reply-To: <1511764948-20972-1-git-send-email-hao.wu@intel.com>
From: Xiao Guangrong <guangrong.xiao@linux.intel.com>
This patch abstracts the common operations of the sub features, and defines
the feature_ops data structure, including init, uinit and ioctl function
pointers. And this patch adds some common helper functions for FME and AFU
drivers, e.g feature_dev_use_begin/end which are used to ensure exclusive
usage of the feature device file.
Signed-off-by: Tim Whisonant <tim.whisonant@intel.com>
Signed-off-by: Enno Luebbers <enno.luebbers@intel.com>
Signed-off-by: Shiva Rao <shiva.rao@intel.com>
Signed-off-by: Christopher Rauer <christopher.rauer@intel.com>
Signed-off-by: Kang Luwei <luwei.kang@intel.com>
Signed-off-by: Zhang Yi <yi.z.zhang@intel.com>
Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
Signed-off-by: Wu Hao <hao.wu@intel.com>
----
v2: rebased
v3: use const for feature_ops.
replace pci related function.
---
drivers/fpga/fpga-dfl.c | 68 +++++++++++++++++++++++++++++++++++++++++
drivers/fpga/fpga-dfl.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 148 insertions(+)
diff --git a/drivers/fpga/fpga-dfl.c b/drivers/fpga/fpga-dfl.c
index ce03b17..1714803 100644
--- a/drivers/fpga/fpga-dfl.c
+++ b/drivers/fpga/fpga-dfl.c
@@ -76,6 +76,74 @@ static enum fpga_id_type feature_dev_id_type(struct platform_device *pdev)
return FPGA_ID_MAX;
}
+int fme_feature_to_resource_index(int feature_id)
+{
+ WARN_ON(feature_id >= FME_FEATURE_ID_MAX);
+ return feature_id;
+}
+
+void fpga_dev_feature_uinit(struct platform_device *pdev)
+{
+ struct feature *feature;
+ struct feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
+
+ fpga_dev_for_each_feature(pdata, feature)
+ if (feature->ops) {
+ feature->ops->uinit(pdev, feature);
+ feature->ops = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(fpga_dev_feature_uinit);
+
+static int
+feature_instance_init(struct platform_device *pdev,
+ struct feature_platform_data *pdata,
+ struct feature *feature, struct feature_driver *drv)
+{
+ int ret;
+
+ WARN_ON(!feature->ioaddr);
+
+ ret = drv->ops->init(pdev, feature);
+ if (ret)
+ return ret;
+
+ feature->ops = drv->ops;
+
+ return ret;
+}
+
+int fpga_dev_feature_init(struct platform_device *pdev,
+ struct feature_driver *feature_drvs)
+{
+ struct feature *feature;
+ struct feature_driver *drv = feature_drvs;
+ struct feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ int ret;
+
+ while (drv->ops) {
+ fpga_dev_for_each_feature(pdata, feature) {
+ /* skip the feature which is not initialized. */
+ if (!feature->name)
+ continue;
+
+ if (!strcmp(drv->name, feature->name)) {
+ ret = feature_instance_init(pdev, pdata,
+ feature, drv);
+ if (ret)
+ goto exit;
+ }
+ }
+ drv++;
+ }
+
+ return 0;
+exit:
+ fpga_dev_feature_uinit(pdev);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(fpga_dev_feature_init);
+
struct fpga_chardev_info {
const char *name;
dev_t devt;
diff --git a/drivers/fpga/fpga-dfl.h b/drivers/fpga/fpga-dfl.h
index 36e2394..e5a1094 100644
--- a/drivers/fpga/fpga-dfl.h
+++ b/drivers/fpga/fpga-dfl.h
@@ -176,12 +176,20 @@
#define PORT_UAFU_DFH DFH
#define PORT_UAFU_SIZE DFH_SIZE
+struct feature_driver {
+ const char *name;
+ const struct feature_ops *ops;
+};
+
struct feature {
const char *name;
int resource_index;
void __iomem *ioaddr;
+ const struct feature_ops *ops;
};
+#define DEV_STATUS_IN_USE 0
+
struct feature_platform_data {
/* list the feature dev to cci_drvdata->port_dev_list. */
struct list_head node;
@@ -189,11 +197,46 @@ struct feature_platform_data {
struct cdev cdev;
struct platform_device *dev;
unsigned int disable_count; /* count for port disable */
+ unsigned long dev_status;
+
+ void *private; /* ptr to feature dev private data */
int num; /* number of features */
struct feature features[0];
};
+static inline int feature_dev_use_begin(struct feature_platform_data *pdata)
+{
+ /* Test and set IN_USE flags to ensure file is exclusively used */
+ if (test_and_set_bit_lock(DEV_STATUS_IN_USE, &pdata->dev_status))
+ return -EBUSY;
+
+ return 0;
+}
+
+static inline void feature_dev_use_end(struct feature_platform_data *pdata)
+{
+ clear_bit_unlock(DEV_STATUS_IN_USE, &pdata->dev_status);
+}
+
+static inline void
+fpga_pdata_set_private(struct feature_platform_data *pdata, void *private)
+{
+ pdata->private = private;
+}
+
+static inline void *fpga_pdata_get_private(struct feature_platform_data *pdata)
+{
+ return pdata->private;
+}
+
+struct feature_ops {
+ int (*init)(struct platform_device *pdev, struct feature *feature);
+ void (*uinit)(struct platform_device *pdev, struct feature *feature);
+ long (*ioctl)(struct platform_device *pdev, struct feature *feature,
+ unsigned int cmd, unsigned long arg);
+};
+
enum fme_feature_id {
FME_FEATURE_ID_HEADER = 0x0,
FME_FEATURE_ID_THERMAL_MGMT = 0x1,
@@ -228,6 +271,10 @@ static inline int feature_platform_data_size(const int num)
num * sizeof(struct feature);
}
+void fpga_dev_feature_uinit(struct platform_device *pdev);
+int fpga_dev_feature_init(struct platform_device *pdev,
+ struct feature_driver *feature_drvs);
+
enum fpga_devt_type {
FPGA_DEVT_FME,
FPGA_DEVT_PORT,
@@ -296,6 +343,15 @@ static inline int fpga_port_reset(struct platform_device *pdev)
return ret;
}
+static inline
+struct platform_device *fpga_inode_to_feature_dev(struct inode *inode)
+{
+ struct feature_platform_data *pdata;
+
+ pdata = container_of(inode->i_cdev, struct feature_platform_data, cdev);
+ return pdata->dev;
+}
+
static inline void __iomem *
get_feature_ioaddr_by_index(struct device *dev, int index)
{
@@ -304,6 +360,21 @@ static inline int fpga_port_reset(struct platform_device *pdev)
return pdata->features[index].ioaddr;
}
+static inline bool is_feature_present(struct device *dev, int index)
+{
+ return !!get_feature_ioaddr_by_index(dev, index);
+}
+
+static inline struct device *
+fpga_pdata_to_parent(struct feature_platform_data *pdata)
+{
+ return pdata->dev->dev.parent->parent;
+}
+
+#define fpga_dev_for_each_feature(pdata, feature) \
+ for ((feature) = (pdata)->features; \
+ (feature) < (pdata)->features + (pdata)->num; (feature)++)
+
static inline bool feature_is_fme(void __iomem *base)
{
u64 v = readq(base + DFH);
@@ -391,4 +462,13 @@ struct platform_device *
return pdev;
}
+
+static inline struct fpga_cdev *
+fpga_pdata_to_fpga_cdev(struct feature_platform_data *pdata)
+{
+ struct device *dev = pdata->dev->dev.parent;
+ struct fpga_region *region = to_fpga_region(dev);
+
+ return container_of(region, struct fpga_cdev, region);
+}
#endif /* __DFL_FPGA_H */
--
1.8.3.1
next prev parent reply other threads:[~2017-11-27 6:42 UTC|newest]
Thread overview: 149+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-27 6:42 [PATCH v3 00/21] Intel FPGA Device Drivers Wu Hao
2017-11-27 6:42 ` [PATCH v3 02/21] fpga: mgr: add region_id to fpga_image_info Wu Hao
[not found] ` <1511764948-20972-3-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-11-29 6:11 ` Moritz Fischer
2017-11-29 6:11 ` Moritz Fischer
2017-12-04 20:26 ` Alan Tull
[not found] ` <CANk1AXTbrD3w=VEzXqTRfebgTYSRNGANthwN_PLVz8WWtxb7CA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-05 3:36 ` Wu Hao
2017-12-05 3:36 ` Wu Hao
2018-01-31 15:35 ` Alan Tull
2018-01-31 15:35 ` Alan Tull
2018-02-01 5:05 ` Wu Hao
2017-11-27 6:42 ` [PATCH v3 03/21] fpga: mgr: add status for fpga-manager Wu Hao
[not found] ` <1511764948-20972-4-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-12-04 20:55 ` Alan Tull
2017-12-04 20:55 ` Alan Tull
[not found] ` <CANk1AXSPQb3=bwaRQsysuiM5NiS6KpKRazP-WNLuus-C=UP6pg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-05 4:08 ` Wu Hao
2017-12-05 4:08 ` Wu Hao
2017-12-12 18:18 ` Alan Tull
[not found] ` <CANk1AXTGdskD9rT5wty1pFeBQ9jK5BhRZFCVbkY3iG9EeEXOvQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-13 4:48 ` Wu Hao
2017-12-13 4:48 ` Wu Hao
[not found] ` <1511764948-20972-1-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-11-27 6:42 ` [PATCH v3 01/21] docs: fpga: add a document for Intel FPGA driver overview Wu Hao
2017-11-27 6:42 ` Wu Hao
2017-12-04 19:55 ` Alan Tull
2017-12-05 3:57 ` Wu Hao
2017-12-05 3:57 ` Wu Hao
2017-12-06 10:04 ` David Laight
[not found] ` <1511764948-20972-2-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-12-20 22:31 ` Alan Tull
2017-12-20 22:31 ` Alan Tull
[not found] ` <CANk1AXTLBWXGUozXJdKRThJwLiHJ==B--DkkE+YRjveA2YvifQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-21 6:02 ` Wu Hao
2017-12-21 6:02 ` Wu Hao
2017-11-27 6:42 ` [PATCH v3 04/21] fpga: add device feature list support Wu Hao
2017-11-27 6:42 ` Wu Hao
[not found] ` <1511764948-20972-5-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-11-29 6:07 ` Moritz Fischer
2017-11-29 6:07 ` Moritz Fischer
2017-11-30 5:59 ` Wu Hao
2017-12-20 22:29 ` Alan Tull
2017-12-21 0:58 ` Alan Tull
[not found] ` <CANk1AXR76T4x=BNcW=ukmcb45GadRPPcrtBDJEjxutCSHuNQNQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-21 7:22 ` Wu Hao
2017-12-21 7:22 ` Wu Hao
2017-12-22 8:45 ` Wu Hao
2018-01-31 23:22 ` Alan Tull
2018-01-31 23:22 ` Alan Tull
2017-11-27 21:26 ` [PATCH v3 00/21] Intel FPGA Device Drivers Alan Tull
2017-11-27 21:26 ` Alan Tull
2017-11-27 6:42 ` [PATCH v3 05/21] fpga: dfl: add chardev support for feature devices Wu Hao
2017-11-27 6:42 ` [PATCH v3 06/21] fpga: dfl: adds fpga_cdev_find_port Wu Hao
2018-02-05 22:08 ` Alan Tull
2018-02-06 2:37 ` Wu Hao
2017-11-27 6:42 ` Wu Hao [this message]
2017-11-27 6:42 ` [PATCH v3 08/21] fpga: add Intel FPGA DFL PCIe device Wu Hao
2017-11-27 10:28 ` David Laight
[not found] ` <f5ae8e5edf88420e89cfbe754407b92e-1XygrNkDbNvwg4NCKwmqgw@public.gmane.org>
2017-11-28 3:15 ` Wu Hao
2017-11-28 3:15 ` Wu Hao
2017-12-04 19:46 ` Alan Tull
2017-12-04 19:46 ` Alan Tull
[not found] ` <CANk1AXRBEcz5_j+v0oTAXfH10hrPbHGabdR8Pqt07exYxYgfCw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-05 3:33 ` Wu Hao
2017-12-05 3:33 ` Wu Hao
2017-12-05 17:00 ` Alan Tull
2017-12-06 5:30 ` Wu Hao
2017-12-06 9:44 ` David Laight
2017-12-06 9:44 ` David Laight
[not found] ` <e73f5bc9bfc54efcb7b7c43c66379452-1XygrNkDbNvwg4NCKwmqgw@public.gmane.org>
2017-12-06 15:29 ` Alan Tull
2017-12-06 15:29 ` Alan Tull
2017-12-06 16:28 ` David Laight
2017-12-06 16:28 ` David Laight
2017-12-06 22:39 ` Alan Tull
2018-02-01 21:59 ` Alan Tull
2018-02-01 21:59 ` Alan Tull
2018-02-13 9:36 ` Wu Hao
2017-12-06 9:34 ` David Laight
2017-12-06 9:34 ` David Laight
[not found] ` <391be54799604c1fb3d7b80c7ad6d111-1XygrNkDbNvwg4NCKwmqgw@public.gmane.org>
2017-12-07 3:47 ` Wu Hao
2017-12-07 3:47 ` Wu Hao
2017-12-06 9:31 ` David Laight
2017-12-06 9:31 ` David Laight
2017-12-06 9:31 ` David Laight
2017-11-27 6:42 ` [PATCH v3 09/21] fpga: intel-dfl-pci: add enumeration for feature devices Wu Hao
[not found] ` <1511764948-20972-10-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-12-07 21:41 ` Alan Tull
2017-12-07 21:41 ` Alan Tull
[not found] ` <CANk1AXQ3+Y6De1i6i0YacUxS+vBzhEfRX_jJ_wQKJOCWmYetxw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-12-08 9:25 ` Wu Hao
2017-12-08 9:25 ` Wu Hao
2017-11-27 6:42 ` [PATCH v3 10/21] fpga: dfl: add FPGA Management Engine driver basic framework Wu Hao
2017-11-27 6:42 ` [PATCH v3 11/21] fpga: dfl: fme: add header sub feature support Wu Hao
[not found] ` <1511764948-20972-12-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2018-02-12 16:51 ` Alan Tull
2018-02-12 16:51 ` Alan Tull
[not found] ` <CANk1AXR2Q4M4c1TOQhR2J_Mz5MjwZWbR0JUXCR5jFVL_kZtcag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-13 3:44 ` Wu Hao
2018-02-13 3:44 ` Wu Hao
2017-11-27 6:42 ` [PATCH v3 12/21] fpga: dfl: fme: add FPGA_GET_API_VERSION/CHECK_EXTENSION ioctls support Wu Hao
[not found] ` <1511764948-20972-13-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2018-01-31 15:31 ` Alan Tull
2018-01-31 15:31 ` Alan Tull
2018-02-01 5:11 ` Wu Hao
2018-02-01 15:11 ` Moritz Fischer
2017-11-27 6:42 ` [PATCH v3 13/21] fpga: dfl: fme: add partial reconfiguration sub feature support Wu Hao
2017-11-27 6:42 ` [PATCH v3 14/21] fpga: dfl: add fpga manager platform driver for FME Wu Hao
[not found] ` <1511764948-20972-15-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2018-02-01 22:00 ` Alan Tull
2018-02-01 22:00 ` Alan Tull
2018-02-02 9:42 ` Wu Hao
2018-02-03 0:26 ` Luebbers, Enno
2018-02-03 0:26 ` Luebbers, Enno
2018-02-03 10:41 ` Moritz Fischer
[not found] ` <20180203104124.luniynyrr6iwxozd-jTBNv906mVBPs60s1yRl3w@public.gmane.org>
2018-02-04 10:05 ` Wu Hao
2018-02-04 10:05 ` Wu Hao
2018-02-05 17:21 ` Alan Tull
2018-02-05 17:21 ` Alan Tull
[not found] ` <CANk1AXRxkUqPqknzb+-apvjZM6MFRom9fscHPmMc8MTYSLpooA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-06 2:17 ` Wu Hao
2018-02-06 2:17 ` Wu Hao
2018-02-06 4:25 ` Alan Tull
[not found] ` <CANk1AXTYtLu_cnKG75FjBRCf5FAoHFj6saNRncYPjQpJoXd1eg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-06 5:23 ` Wu Hao
2018-02-06 5:23 ` Wu Hao
2018-02-06 6:44 ` Moritz Fischer
2018-02-06 6:44 ` Moritz Fischer
[not found] ` <20180203002626.GA51125-8lsKh0Wp6ypIVPrYeAqNvTMJUdESFZ8XQQ4Iyu8u01E@public.gmane.org>
2018-02-04 9:37 ` Wu Hao
2018-02-04 9:37 ` Wu Hao
2018-02-05 18:36 ` Luebbers, Enno
2018-02-05 18:36 ` Luebbers, Enno
[not found] ` <20180205183644.GA52136-8lsKh0Wp6yrYELzPhwCr0YT4S9po1h25@public.gmane.org>
2018-02-06 1:47 ` Wu Hao
2018-02-06 1:47 ` Wu Hao
2018-02-06 4:25 ` Alan Tull
2018-02-06 4:25 ` Alan Tull
[not found] ` <CANk1AXRe85Ns1_cUPdn02yS9Gc6i5cYYhko7snvjfzxQSzUzNA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-06 6:47 ` Wu Hao
2018-02-06 6:47 ` Wu Hao
2018-02-06 18:53 ` Alan Tull
2018-02-06 18:53 ` Alan Tull
2018-02-07 4:52 ` Wu Hao
2018-02-07 22:37 ` Alan Tull
2018-02-07 22:37 ` Alan Tull
2017-11-27 6:42 ` [PATCH v3 15/21] fpga: dfl: add fpga bridge " Wu Hao
[not found] ` <1511764948-20972-16-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2018-01-31 15:16 ` Alan Tull
2018-01-31 15:16 ` Alan Tull
2018-02-01 5:15 ` Wu Hao
2018-02-01 15:11 ` Moritz Fischer
2018-02-01 15:11 ` Moritz Fischer
2017-11-27 6:42 ` [PATCH v3 16/21] fpga: dfl: add fpga region " Wu Hao
2018-01-31 20:46 ` Alan Tull
2018-02-01 5:23 ` Wu Hao
2018-02-01 15:13 ` Moritz Fischer
2017-11-27 6:42 ` [PATCH v3 17/21] fpga: dfl: add FPGA Accelerated Function Unit driver basic framework Wu Hao
2017-11-27 6:42 ` [PATCH v3 18/21] fpga: dfl: afu: add header sub feature support Wu Hao
[not found] ` <1511764948-20972-19-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2018-02-12 17:43 ` Alan Tull
2018-02-12 17:43 ` Alan Tull
[not found] ` <CANk1AXT0s1W99cRvWmT80nB+Buivt9xmjziDAz6pyxY-EJF2Fw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-02-13 3:33 ` Wu Hao
2018-02-13 3:33 ` Wu Hao
2017-11-27 6:42 ` [PATCH v3 19/21] fpga: dfl: afu: add FPGA_GET_API_VERSION/CHECK_EXTENSION ioctls support Wu Hao
[not found] ` <1511764948-20972-20-git-send-email-hao.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2018-01-31 14:52 ` Alan Tull
2018-01-31 14:52 ` Alan Tull
2018-02-01 5:16 ` Wu Hao
2018-02-01 15:13 ` Moritz Fischer
[not found] ` <20180201151309.q3jjx42y6ldcrhc6-y7F9n2Zoz0NnbPI/LkqVKXLzTDPwzsqGqZgBStWHTEI@public.gmane.org>
2018-02-02 9:08 ` Wu Hao
2018-02-02 9:08 ` Wu Hao
2017-11-27 6:42 ` [PATCH v3 20/21] fpga: dfl: afu: add user afu sub feature support Wu Hao
2017-11-27 6:42 ` [PATCH v3 21/21] fpga: dfl: afu: add FPGA_PORT_DMA_MAP/UNMAP ioctls support Wu Hao
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=1511764948-20972-8-git-send-email-hao.wu@intel.com \
--to=hao.wu@intel.com \
--cc=atull@kernel.org \
--cc=christopher.rauer@intel.com \
--cc=enno.luebbers@intel.com \
--cc=guangrong.xiao@linux.intel.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-fpga@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luwei.kang@intel.com \
--cc=mdf@kernel.org \
--cc=shiva.rao@intel.com \
--cc=tim.whisonant@intel.com \
--cc=yi.z.zhang@intel.com \
/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.