linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] iio: imu: inv_mpu6050: client enumeration
@ 2015-01-30 22:25 Srinivas Pandruvada
  2015-01-30 22:25 ` [PATCH v3] iio: imu: inv_mpu6050: Create mux clients for ACPI Srinivas Pandruvada
  2015-02-03 19:16 ` [PATCH v3] iio: imu: inv_mpu6050: client enumeration Jonathan Cameron
  0 siblings, 2 replies; 5+ messages in thread
From: Srinivas Pandruvada @ 2015-01-30 22:25 UTC (permalink / raw)
  To: jic23; +Cc: wsa, lars, linux-iio, Srinivas Pandruvada

Last comment from Jonathan was
"
This all looks fine to me, though ideally I'd like some input from
others, more familiar with the dmi stuff etc and from Wolfram / others
wrt to the approach.
"

So anybody have a better suggestion, I am still open to take them.
Otherwise please consider as a merge candidate.

v3
Add CONFIG_ACPI protection to avoid compiler warning.

v2
Add CONFIG_ACPI to call creation of mux clients, instead of relying
on ACPI_HANDLE not present for non ACPI platforms
It is possible that there is no secondary address, this is not an error.

v1
This is an option if auto detect is not desired. 
Here using ACPI magic, by parsing both standard and vendor ACPI
data.

v0
Using autodetect feature.
Using HWMON class as other places in the system for mux and
client sensor drivers.

Srinivas Pandruvada (1):
  iio: imu: inv_mpu6050: Create mux clients for ACPI

 drivers/iio/imu/inv_mpu6050/Makefile       |   2 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 211 +++++++++++++++++++++++++++++
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |   7 +
 drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h  |   3 +
 4 files changed, 222 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c

-- 
1.9.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3] iio: imu: inv_mpu6050: Create mux clients for ACPI
  2015-01-30 22:25 [PATCH v3] iio: imu: inv_mpu6050: client enumeration Srinivas Pandruvada
@ 2015-01-30 22:25 ` Srinivas Pandruvada
  2015-02-03 19:16 ` [PATCH v3] iio: imu: inv_mpu6050: client enumeration Jonathan Cameron
  1 sibling, 0 replies; 5+ messages in thread
From: Srinivas Pandruvada @ 2015-01-30 22:25 UTC (permalink / raw)
  To: jic23; +Cc: wsa, lars, linux-iio, Srinivas Pandruvada

This is a follow up patches after adding i2c mux adapter for bypass
mode. Potentially many different types of sensor can be attached to
INVMPU6XXX device, which can be connected to main cpu i2c bus in
bypass mode.
Why do we need this?
The system ACPI table entry will consist of only one device for
INV6XXX, assuming that this driver will handle all connected sensors.
That is not true for the Linux driver. There are bunch of IIO drivers
for each sensors, hence we created a mux on this device. So to load
these additional drivers, we need to create i2c devices for them
in this driver using this mux adapter.

There are multiple options:
1. Use the auto detect feature, this needs a new i2c class for the
adapter as the existing HWMON class is not acceptable. Also the
autodetect has overhead of executing detect method for each
matching class of adapters.
This is a simple implementation. This option was previously submitted
with not a happy feedback.

2. Option is use ACPI magic and parse the configuration data. What
we need to create a i2c device at a minimum is address and a name.
Address can be obtained for secondary device in more or less in a
standard way from using _CRS element. But there is no name. To get
name we need to process proprietary vendor data. Not having name is
not fun, as you have to create device using the device name of
INVN6XXXX, respecting driver duplicate name space restriction.
Also each client driver needs to have this name in the id table.
Since multiple driver can be loaded, the driver should be able to
detect its presence and gracefully exit for the other client driver
to take it over.
So we use two step process:
- Use DMI to id platform and parse propritery data. This is not uncommon
for many x86 platform specific driver. We will get both name and address.
The change created necessary infrastructure to add more properitery vendor
data parsing.
- If DMI match fails, then create device on INV6XXX-client (we can't
create with same name as INV6XXX as it will cause duplicate name and driver
model will reject.) With this each client sensor driver which needs to get
attached via INV6XXXX, need this name in the id table and detect the
physical presence of sensor in probe and exit if not found.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 drivers/iio/imu/inv_mpu6050/Makefile       |   2 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 211 +++++++++++++++++++++++++++++
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |   7 +
 drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h  |   3 +
 4 files changed, 222 insertions(+), 1 deletion(-)
 create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c

diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
index 3a677c7..f566f6a 100644
--- a/drivers/iio/imu/inv_mpu6050/Makefile
+++ b/drivers/iio/imu/inv_mpu6050/Makefile
@@ -3,4 +3,4 @@
 #
 
 obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o
-inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
+inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o inv_mpu_acpi.o
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
new file mode 100644
index 0000000..1c982a5
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
@@ -0,0 +1,211 @@
+/*
+ * inv_mpu_acpi: ACPI processing for creating client devices
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#ifdef CONFIG_ACPI
+
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/dmi.h>
+#include <linux/acpi.h>
+#include "inv_mpu_iio.h"
+
+enum inv_mpu_product_name {
+	INV_MPU_NOT_MATCHED,
+	INV_MPU_ASUS_T100TA,
+};
+
+static enum inv_mpu_product_name matched_product_name;
+
+static int __init asus_t100_matched(const struct dmi_system_id *d)
+{
+	matched_product_name = INV_MPU_ASUS_T100TA;
+
+	return 0;
+}
+
+static const struct dmi_system_id inv_mpu_dev_list[] = {
+	{
+	.callback = asus_t100_matched,
+	.ident = "Asus Transformer Book T100",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"),
+		},
+	},
+	/* Add more matching tables here..*/
+	{}
+};
+
+static int asus_acpi_get_sensor_info(struct acpi_device *adev,
+				     struct i2c_client *client,
+				     struct i2c_board_info *info)
+{
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	int i;
+	acpi_status status;
+	union acpi_object *cpm;
+
+	status = acpi_evaluate_object(adev->handle, "CNF0", NULL, &buffer);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	cpm = buffer.pointer;
+	for (i = 0; i < cpm->package.count; ++i) {
+		union acpi_object *elem;
+		int j;
+
+		elem = &(cpm->package.elements[i]);
+		for (j = 0; j < elem->package.count; ++j) {
+			union acpi_object *sub_elem;
+
+			sub_elem = &(elem->package.elements[j]);
+			if (sub_elem->type == ACPI_TYPE_STRING)
+				strlcpy(info->type, sub_elem->string.pointer,
+					sizeof(info->type));
+			else if (sub_elem->type == ACPI_TYPE_INTEGER) {
+				if (sub_elem->integer.value != client->addr) {
+					info->addr = sub_elem->integer.value;
+					break; /* Not a MPU6500 primary */
+				}
+			}
+		}
+	}
+
+	kfree(buffer.pointer);
+
+	return cpm->package.count;
+}
+
+static int acpi_i2c_check_resource(struct acpi_resource *ares, void *data)
+{
+	u32 *addr = data;
+
+	if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
+		struct acpi_resource_i2c_serialbus *sb;
+
+		sb = &ares->data.i2c_serial_bus;
+		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
+			if (*addr)
+				*addr |= (sb->slave_address << 16);
+			else
+				*addr = sb->slave_address;
+		}
+	}
+
+	/* Tell the ACPI core that we already copied this address */
+	return 1;
+}
+
+static int inv_mpu_process_acpi_config(struct i2c_client *client,
+				       unsigned short *primary_addr,
+				       unsigned short *secondary_addr)
+{
+	const struct acpi_device_id *id;
+	struct acpi_device *adev;
+	u32 i2c_addr = 0;
+	LIST_HEAD(resources);
+	int ret;
+
+	id = acpi_match_device(client->dev.driver->acpi_match_table,
+			       &client->dev);
+	if (!id)
+		return -ENODEV;
+
+	adev = ACPI_COMPANION(&client->dev);
+	if (!adev)
+		return -ENODEV;
+
+	ret = acpi_dev_get_resources(adev, &resources,
+				     acpi_i2c_check_resource, &i2c_addr);
+	if (ret < 0)
+		return ret;
+
+	acpi_dev_free_resource_list(&resources);
+	*primary_addr = i2c_addr & 0x0000ffff;
+	*secondary_addr = (i2c_addr & 0xffff0000) >> 16;
+
+	return 0;
+}
+
+int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st)
+{
+
+	st->mux_client = NULL;
+	if (ACPI_HANDLE(&st->client->dev)) {
+		struct i2c_board_info info;
+		struct acpi_device *adev;
+		int ret = -1;
+
+		adev = ACPI_COMPANION(&st->client->dev);
+		memset(&info, 0, sizeof(info));
+
+		dmi_check_system(inv_mpu_dev_list);
+		switch (matched_product_name) {
+		case INV_MPU_ASUS_T100TA:
+			ret = asus_acpi_get_sensor_info(adev, st->client,
+							&info);
+			break;
+		/* Add more matched product processing here */
+		default:
+			break;
+		}
+
+		if (ret < 0) {
+			/* No matching DMI, so create device on INV6XX type */
+			unsigned short primary, secondary;
+
+			ret = inv_mpu_process_acpi_config(st->client, &primary,
+							  &secondary);
+			if (!ret && secondary) {
+				char *name;
+
+				info.addr = secondary;
+				strlcpy(info.type, dev_name(&adev->dev),
+					sizeof(info.type));
+				name = strchr(info.type, ':');
+				if (name)
+					*name = '\0';
+				strlcat(info.type, "-client",
+					sizeof(info.type));
+			} else
+				return 0; /* no secondary addr, which is OK */
+		}
+		st->mux_client = i2c_new_device(st->mux_adapter, &info);
+		if (!st->mux_client)
+			return -ENODEV;
+
+	}
+
+	return 0;
+}
+
+void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st)
+{
+	if (st->mux_client)
+		i2c_unregister_device(st->mux_client);
+}
+#else
+
+#include "inv_mpu_iio.h"
+
+int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st)
+{
+	return 0;
+}
+
+void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st)
+{
+}
+#endif
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index d8d5bed..5613f3a 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -825,8 +825,14 @@ static int inv_mpu_probe(struct i2c_client *client,
 		goto out_unreg_device;
 	}
 
+	result = inv_mpu_acpi_create_mux_client(st);
+	if (result)
+		goto out_del_mux;
+
 	return 0;
 
+out_del_mux:
+	i2c_del_mux_adapter(st->mux_adapter);
 out_unreg_device:
 	iio_device_unregister(indio_dev);
 out_remove_trigger:
@@ -841,6 +847,7 @@ static int inv_mpu_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct inv_mpu6050_state *st = iio_priv(indio_dev);
 
+	inv_mpu_acpi_delete_mux_client(st);
 	i2c_del_mux_adapter(st->mux_adapter);
 	iio_device_unregister(indio_dev);
 	inv_mpu6050_remove_trigger(st);
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index aa837de..db0a4a2 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -121,6 +121,7 @@ struct inv_mpu6050_state {
 	spinlock_t time_stamp_lock;
 	struct i2c_client *client;
 	struct i2c_adapter *mux_adapter;
+	struct i2c_client *mux_client;
 	unsigned int powerup_count;
 	struct inv_mpu6050_platform_data plat_data;
 	DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
@@ -251,3 +252,5 @@ int inv_reset_fifo(struct iio_dev *indio_dev);
 int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask);
 int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val);
 int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on);
+int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st);
+void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3] iio: imu: inv_mpu6050: client enumeration
  2015-01-30 22:25 [PATCH v3] iio: imu: inv_mpu6050: client enumeration Srinivas Pandruvada
  2015-01-30 22:25 ` [PATCH v3] iio: imu: inv_mpu6050: Create mux clients for ACPI Srinivas Pandruvada
@ 2015-02-03 19:16 ` Jonathan Cameron
  2015-02-21 18:06   ` Jonathan Cameron
  1 sibling, 1 reply; 5+ messages in thread
From: Jonathan Cameron @ 2015-02-03 19:16 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: wsa, lars, linux-iio

On 30/01/15 22:25, Srinivas Pandruvada wrote:
> Last comment from Jonathan was
> "
> This all looks fine to me, though ideally I'd like some input from
> others, more familiar with the dmi stuff etc and from Wolfram / others
> wrt to the approach.
> "
Given timing, (just missed likely merge this cycle) we now have a reasonable
amount of time.  So lets leave this a little while yet...
> 
> So anybody have a better suggestion, I am still open to take them.
> Otherwise please consider as a merge candidate.
> 
> v3
> Add CONFIG_ACPI protection to avoid compiler warning.
> 
> v2
> Add CONFIG_ACPI to call creation of mux clients, instead of relying
> on ACPI_HANDLE not present for non ACPI platforms
> It is possible that there is no secondary address, this is not an error.
> 
> v1
> This is an option if auto detect is not desired. 
> Here using ACPI magic, by parsing both standard and vendor ACPI
> data.
> 
> v0
> Using autodetect feature.
> Using HWMON class as other places in the system for mux and
> client sensor drivers.
> 
> Srinivas Pandruvada (1):
>   iio: imu: inv_mpu6050: Create mux clients for ACPI
> 
>  drivers/iio/imu/inv_mpu6050/Makefile       |   2 +-
>  drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 211 +++++++++++++++++++++++++++++
>  drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |   7 +
>  drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h  |   3 +
>  4 files changed, 222 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v3] iio: imu: inv_mpu6050: client enumeration
  2015-02-03 19:16 ` [PATCH v3] iio: imu: inv_mpu6050: client enumeration Jonathan Cameron
@ 2015-02-21 18:06   ` Jonathan Cameron
  2015-02-25 12:03     ` Jonathan Cameron
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Cameron @ 2015-02-21 18:06 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: wsa, lars, linux-iio

On 03/02/15 19:16, Jonathan Cameron wrote:
> On 30/01/15 22:25, Srinivas Pandruvada wrote:
>> Last comment from Jonathan was
>> "
>> This all looks fine to me, though ideally I'd like some input from
>> others, more familiar with the dmi stuff etc and from Wolfram / others
>> wrt to the approach.
>> "
> Given timing, (just missed likely merge this cycle) we now have a reasonable
> amount of time.  So lets leave this a little while yet...
I no one else has any comments on this than I'm going to take it pretty soon
as is.

Jonathan
>>
>> So anybody have a better suggestion, I am still open to take them.
>> Otherwise please consider as a merge candidate.
>>
>> v3
>> Add CONFIG_ACPI protection to avoid compiler warning.
>>
>> v2
>> Add CONFIG_ACPI to call creation of mux clients, instead of relying
>> on ACPI_HANDLE not present for non ACPI platforms
>> It is possible that there is no secondary address, this is not an error.
>>
>> v1
>> This is an option if auto detect is not desired. 
>> Here using ACPI magic, by parsing both standard and vendor ACPI
>> data.
>>
>> v0
>> Using autodetect feature.
>> Using HWMON class as other places in the system for mux and
>> client sensor drivers.
>>
>> Srinivas Pandruvada (1):
>>   iio: imu: inv_mpu6050: Create mux clients for ACPI
>>
>>  drivers/iio/imu/inv_mpu6050/Makefile       |   2 +-
>>  drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 211 +++++++++++++++++++++++++++++
>>  drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |   7 +
>>  drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h  |   3 +
>>  4 files changed, 222 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v3] iio: imu: inv_mpu6050: client enumeration
  2015-02-21 18:06   ` Jonathan Cameron
@ 2015-02-25 12:03     ` Jonathan Cameron
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Cameron @ 2015-02-25 12:03 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: wsa, lars, linux-iio

On 21/02/15 18:06, Jonathan Cameron wrote:
> On 03/02/15 19:16, Jonathan Cameron wrote:
>> On 30/01/15 22:25, Srinivas Pandruvada wrote:
>>> Last comment from Jonathan was
>>> "
>>> This all looks fine to me, though ideally I'd like some input from
>>> others, more familiar with the dmi stuff etc and from Wolfram / others
>>> wrt to the approach.
>>> "
>> Given timing, (just missed likely merge this cycle) we now have a reasonable
>> amount of time.  So lets leave this a little while yet...
> I no one else has any comments on this than I'm going to take it pretty soon
> as is.
> 
> Jonathan
Applied to the togreg branch of iio.git.  Will be pushed out as testing
for the autobuilders to play sometime soonish.
(travelling until Friday)

Jonathan
>>>
>>> So anybody have a better suggestion, I am still open to take them.
>>> Otherwise please consider as a merge candidate.
>>>
>>> v3
>>> Add CONFIG_ACPI protection to avoid compiler warning.
>>>
>>> v2
>>> Add CONFIG_ACPI to call creation of mux clients, instead of relying
>>> on ACPI_HANDLE not present for non ACPI platforms
>>> It is possible that there is no secondary address, this is not an error.
>>>
>>> v1
>>> This is an option if auto detect is not desired. 
>>> Here using ACPI magic, by parsing both standard and vendor ACPI
>>> data.
>>>
>>> v0
>>> Using autodetect feature.
>>> Using HWMON class as other places in the system for mux and
>>> client sensor drivers.
>>>
>>> Srinivas Pandruvada (1):
>>>   iio: imu: inv_mpu6050: Create mux clients for ACPI
>>>
>>>  drivers/iio/imu/inv_mpu6050/Makefile       |   2 +-
>>>  drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 211 +++++++++++++++++++++++++++++
>>>  drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |   7 +
>>>  drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h  |   3 +
>>>  4 files changed, 222 insertions(+), 1 deletion(-)
>>>  create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
>>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-02-25 20:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-30 22:25 [PATCH v3] iio: imu: inv_mpu6050: client enumeration Srinivas Pandruvada
2015-01-30 22:25 ` [PATCH v3] iio: imu: inv_mpu6050: Create mux clients for ACPI Srinivas Pandruvada
2015-02-03 19:16 ` [PATCH v3] iio: imu: inv_mpu6050: client enumeration Jonathan Cameron
2015-02-21 18:06   ` Jonathan Cameron
2015-02-25 12:03     ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).