From: Jonathan Cameron <jic23@kernel.org>
To: Gene Chen <gene.chen.richtek@gmail.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>,
knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net,
linux-iio@vger.kernel.org,
linux-arm Mailing List <linux-arm-kernel@lists.infradead.org>,
"moderated list:ARM/Mediatek SoC support"
<linux-mediatek@lists.infradead.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Gene Chen <gene_chen@richtek.com>,
Wilma.Wu@mediatek.com, shufan_lee@richtek.com,
cy_huang@richtek.com, benjamin.chao@mediatek.com
Subject: Re: [PATCH v4 3/3] iio: adc: mt6360: Add ADC driver for MT6360
Date: Sat, 19 Sep 2020 14:20:05 +0100 [thread overview]
Message-ID: <20200919142005.18e3e11f@archlinux> (raw)
In-Reply-To: <CAE+NS35RkbHOqrFoEE2MS109hTKowZO3jmT_oTpSmCRnY-87Lg@mail.gmail.com>
On Fri, 18 Sep 2020 16:04:43 +0800
Gene Chen <gene.chen.richtek@gmail.com> wrote:
> Jonathan Cameron <jic23@kernel.org> 於 2020年9月18日 週五 上午1:53寫道:
> >
> > On Wed, 16 Sep 2020 01:36:09 +0800
> > Gene Chen <gene.chen.richtek@gmail.com> wrote:
> >
> > > From: Gene Chen <gene_chen@richtek.com>
> > >
> > > Add MT6360 ADC driver include Charger Current, Voltage, and
> > > Temperature.
> > >
> > > Signed-off-by: Gene Chen <gene_chen@richtek.com>
> > Comments inline.
...
> > > + if (ret)
> > > + goto out_adc_lock;
> > > +
> > > + start_t = ktime_get();
> > > + predict_end_t = ktime_add_ms(mad->last_off_timestamps[channel], 2 * ADC_WAIT_TIME_MS);
> > > +
> > > + if (ktime_after(start_t, predict_end_t))
> > > + pre_wait_time = ADC_WAIT_TIME_MS;
> > > + else
> > > + pre_wait_time = 3 * ADC_WAIT_TIME_MS;
> > > +
> > > + msleep(pre_wait_time);
> > > +
> > > + while (true) {
> > > + ret = regmap_raw_read(mad->regmap, MT6360_REG_PMUADCRPT1, rpt, sizeof(rpt));
> > > + if (ret)
> > > + goto out_adc_conv;
> > > +
> > > + /*
> > > + * There are two functions, ZCV and TypeC OTP, running ADC VBAT and TS in
> > > + * background, and ADC samples are taken on a fixed frequency no matter read the
> > > + * previous one or not.
> > > + * To avoid conflict, We set minimum time threshold after enable ADC and
> > > + * check report channel is the same.
> > > + * The worst case is run the same ADC twice and background function is also running,
> > > + * ADC conversion sequence is desire channel before start ADC, background ADC,
> > > + * desire channel after start ADC.
> > > + * So the minimum correct data is three times of typical conversion time.
> > > + */
> > > + if ((rpt[0] & MT6360_RPTCH_MASK) == channel)
> > > + break;
> > > +
> > > + msleep(ADC_WAIT_TIME_MS);
> > > + }
> > > +
> > > + /* rpt[1]: ADC_HI_BYTE, rpt[2]: ADC_LOW_BYTE */
> > > + *val = be16_to_cpup((__be16 *)(rpt + 1));
> >
> > To be entirely safe, probably need that to be an unaligned read?
> >
>
> Maybe I can change to "*val = rpt[1] << 8 | rpt[2];".
> It's more abvious.
That would definitely be safe so do that.
>
> > > + ret = IIO_VAL_INT;
> > > +
> > > +out_adc_conv:
> > > + /* Only keep ADC enable */
> > > + adc_enable = cpu_to_be16(MT6360_ADCEN_MASK);
> > > + regmap_raw_write(mad->regmap, MT6360_REG_PMUADCCFG, (void *)&adc_enable, sizeof(__be16));
> >
> > sizeof(adc_enable)
> >
>
> ACK
>
> > > + mad->last_off_timestamps[channel] = ktime_get();
> > > + /* Config prefer channel to NO_PREFER */
> > > + regmap_update_bits(mad->regmap, MT6360_REG_PMUADCRPT1, MT6360_PREFERCH_MASK,
> > > + MT6360_NO_PREFER << MT6360_PREFERCH_SHFT);
> > > +out_adc_lock:
> > > + mutex_unlock(&mad->adc_lock);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int mt6360_adc_read_scale(struct mt6360_adc_data *mad, int channel, int *val, int *val2)
> > > +{
> > > + unsigned int regval;
> > > + int ret;
> > > +
> > > + switch (channel) {
> > > + case MT6360_CHAN_USBID:
> > > + fallthrough;
> >
> > I don't think we need fallthrough for cases
> > with nothing in them.
> >
>
> Every channel needs set " *val = 2500" for scale.
> Do you mean change as below?
>
> switch (channel) {
> case MT6360_CHAN_USBID:
> case MT6360_CHAN_VSYS:
> case MT6360_CHAN_VBAT:
> case MT6360_CHAN_CHG_VDDP:
> case MT6360_CHAN_VREF_TS:
> fallthrough;
Don't need this fallthrough.
fallthrough is only needed if something is done in the
case statement. I believe the checker is clever enough to
assume that a set of case statements with nothing inbetween
them are deliberate.
> case MT6360_CHAN_TS:
> *val = 1250;
> return IIO_VAL_INT;
>
...
> > > +
> > > +static irqreturn_t mt6360_adc_trigger_handler(int irq, void *p)
> > > +{
> > > + struct iio_poll_func *pf = p;
> > > + struct iio_dev *indio_dev = pf->indio_dev;
> > > + struct mt6360_adc_data *mad = iio_priv(indio_dev);
> > > + struct {
> > > + u16 values[MT6360_CHAN_MAX];
> >
> > There is a hole in here I think? (MT6360_CHAN_MAX is 11?)
> > If so we need to explicitly memset the structure to avoid any
> > risk of kernel data leakage to userspace.
Make sure you deal with this in v5!
> >
> > > + int64_t timestamp;
> > > + } data;
> >
> > I guess we know this is on a platform with 64bit alignment for int64_t's
> > (unlike x86_64 for example)
> >
>
> Do you mean change as below?
> struct {
> u16 values[MT6360_CHAN_MAX];
> int64_t timestamp; __aligned(8)
> } data;
You can do that, or we can rely on the fact this part is never used
on a platform where that isn't guaranteed anyway.
>
> > > + int i = 0, bit, val, ret;
...
WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron <jic23@kernel.org>
To: Gene Chen <gene.chen.richtek@gmail.com>
Cc: Gene Chen <gene_chen@richtek.com>,
lars@metafoo.de, linux-iio@vger.kernel.org,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
cy_huang@richtek.com, benjamin.chao@mediatek.com,
"moderated list:ARM/Mediatek SoC support"
<linux-mediatek@lists.infradead.org>,
pmeerw@pmeerw.net, knaack.h@gmx.de,
Matthias Brugger <matthias.bgg@gmail.com>,
Wilma.Wu@mediatek.com,
linux-arm Mailing List <linux-arm-kernel@lists.infradead.org>,
shufan_lee@richtek.com
Subject: Re: [PATCH v4 3/3] iio: adc: mt6360: Add ADC driver for MT6360
Date: Sat, 19 Sep 2020 14:20:05 +0100 [thread overview]
Message-ID: <20200919142005.18e3e11f@archlinux> (raw)
In-Reply-To: <CAE+NS35RkbHOqrFoEE2MS109hTKowZO3jmT_oTpSmCRnY-87Lg@mail.gmail.com>
On Fri, 18 Sep 2020 16:04:43 +0800
Gene Chen <gene.chen.richtek@gmail.com> wrote:
> Jonathan Cameron <jic23@kernel.org> 於 2020年9月18日 週五 上午1:53寫道:
> >
> > On Wed, 16 Sep 2020 01:36:09 +0800
> > Gene Chen <gene.chen.richtek@gmail.com> wrote:
> >
> > > From: Gene Chen <gene_chen@richtek.com>
> > >
> > > Add MT6360 ADC driver include Charger Current, Voltage, and
> > > Temperature.
> > >
> > > Signed-off-by: Gene Chen <gene_chen@richtek.com>
> > Comments inline.
...
> > > + if (ret)
> > > + goto out_adc_lock;
> > > +
> > > + start_t = ktime_get();
> > > + predict_end_t = ktime_add_ms(mad->last_off_timestamps[channel], 2 * ADC_WAIT_TIME_MS);
> > > +
> > > + if (ktime_after(start_t, predict_end_t))
> > > + pre_wait_time = ADC_WAIT_TIME_MS;
> > > + else
> > > + pre_wait_time = 3 * ADC_WAIT_TIME_MS;
> > > +
> > > + msleep(pre_wait_time);
> > > +
> > > + while (true) {
> > > + ret = regmap_raw_read(mad->regmap, MT6360_REG_PMUADCRPT1, rpt, sizeof(rpt));
> > > + if (ret)
> > > + goto out_adc_conv;
> > > +
> > > + /*
> > > + * There are two functions, ZCV and TypeC OTP, running ADC VBAT and TS in
> > > + * background, and ADC samples are taken on a fixed frequency no matter read the
> > > + * previous one or not.
> > > + * To avoid conflict, We set minimum time threshold after enable ADC and
> > > + * check report channel is the same.
> > > + * The worst case is run the same ADC twice and background function is also running,
> > > + * ADC conversion sequence is desire channel before start ADC, background ADC,
> > > + * desire channel after start ADC.
> > > + * So the minimum correct data is three times of typical conversion time.
> > > + */
> > > + if ((rpt[0] & MT6360_RPTCH_MASK) == channel)
> > > + break;
> > > +
> > > + msleep(ADC_WAIT_TIME_MS);
> > > + }
> > > +
> > > + /* rpt[1]: ADC_HI_BYTE, rpt[2]: ADC_LOW_BYTE */
> > > + *val = be16_to_cpup((__be16 *)(rpt + 1));
> >
> > To be entirely safe, probably need that to be an unaligned read?
> >
>
> Maybe I can change to "*val = rpt[1] << 8 | rpt[2];".
> It's more abvious.
That would definitely be safe so do that.
>
> > > + ret = IIO_VAL_INT;
> > > +
> > > +out_adc_conv:
> > > + /* Only keep ADC enable */
> > > + adc_enable = cpu_to_be16(MT6360_ADCEN_MASK);
> > > + regmap_raw_write(mad->regmap, MT6360_REG_PMUADCCFG, (void *)&adc_enable, sizeof(__be16));
> >
> > sizeof(adc_enable)
> >
>
> ACK
>
> > > + mad->last_off_timestamps[channel] = ktime_get();
> > > + /* Config prefer channel to NO_PREFER */
> > > + regmap_update_bits(mad->regmap, MT6360_REG_PMUADCRPT1, MT6360_PREFERCH_MASK,
> > > + MT6360_NO_PREFER << MT6360_PREFERCH_SHFT);
> > > +out_adc_lock:
> > > + mutex_unlock(&mad->adc_lock);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int mt6360_adc_read_scale(struct mt6360_adc_data *mad, int channel, int *val, int *val2)
> > > +{
> > > + unsigned int regval;
> > > + int ret;
> > > +
> > > + switch (channel) {
> > > + case MT6360_CHAN_USBID:
> > > + fallthrough;
> >
> > I don't think we need fallthrough for cases
> > with nothing in them.
> >
>
> Every channel needs set " *val = 2500" for scale.
> Do you mean change as below?
>
> switch (channel) {
> case MT6360_CHAN_USBID:
> case MT6360_CHAN_VSYS:
> case MT6360_CHAN_VBAT:
> case MT6360_CHAN_CHG_VDDP:
> case MT6360_CHAN_VREF_TS:
> fallthrough;
Don't need this fallthrough.
fallthrough is only needed if something is done in the
case statement. I believe the checker is clever enough to
assume that a set of case statements with nothing inbetween
them are deliberate.
> case MT6360_CHAN_TS:
> *val = 1250;
> return IIO_VAL_INT;
>
...
> > > +
> > > +static irqreturn_t mt6360_adc_trigger_handler(int irq, void *p)
> > > +{
> > > + struct iio_poll_func *pf = p;
> > > + struct iio_dev *indio_dev = pf->indio_dev;
> > > + struct mt6360_adc_data *mad = iio_priv(indio_dev);
> > > + struct {
> > > + u16 values[MT6360_CHAN_MAX];
> >
> > There is a hole in here I think? (MT6360_CHAN_MAX is 11?)
> > If so we need to explicitly memset the structure to avoid any
> > risk of kernel data leakage to userspace.
Make sure you deal with this in v5!
> >
> > > + int64_t timestamp;
> > > + } data;
> >
> > I guess we know this is on a platform with 64bit alignment for int64_t's
> > (unlike x86_64 for example)
> >
>
> Do you mean change as below?
> struct {
> u16 values[MT6360_CHAN_MAX];
> int64_t timestamp; __aligned(8)
> } data;
You can do that, or we can rely on the fact this part is never used
on a platform where that isn't guaranteed anyway.
>
> > > + int i = 0, bit, val, ret;
...
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron <jic23@kernel.org>
To: Gene Chen <gene.chen.richtek@gmail.com>
Cc: Gene Chen <gene_chen@richtek.com>,
lars@metafoo.de, linux-iio@vger.kernel.org,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
cy_huang@richtek.com, benjamin.chao@mediatek.com,
"moderated list:ARM/Mediatek SoC support"
<linux-mediatek@lists.infradead.org>,
pmeerw@pmeerw.net, knaack.h@gmx.de,
Matthias Brugger <matthias.bgg@gmail.com>,
Wilma.Wu@mediatek.com,
linux-arm Mailing List <linux-arm-kernel@lists.infradead.org>,
shufan_lee@richtek.com
Subject: Re: [PATCH v4 3/3] iio: adc: mt6360: Add ADC driver for MT6360
Date: Sat, 19 Sep 2020 14:20:05 +0100 [thread overview]
Message-ID: <20200919142005.18e3e11f@archlinux> (raw)
In-Reply-To: <CAE+NS35RkbHOqrFoEE2MS109hTKowZO3jmT_oTpSmCRnY-87Lg@mail.gmail.com>
On Fri, 18 Sep 2020 16:04:43 +0800
Gene Chen <gene.chen.richtek@gmail.com> wrote:
> Jonathan Cameron <jic23@kernel.org> 於 2020年9月18日 週五 上午1:53寫道:
> >
> > On Wed, 16 Sep 2020 01:36:09 +0800
> > Gene Chen <gene.chen.richtek@gmail.com> wrote:
> >
> > > From: Gene Chen <gene_chen@richtek.com>
> > >
> > > Add MT6360 ADC driver include Charger Current, Voltage, and
> > > Temperature.
> > >
> > > Signed-off-by: Gene Chen <gene_chen@richtek.com>
> > Comments inline.
...
> > > + if (ret)
> > > + goto out_adc_lock;
> > > +
> > > + start_t = ktime_get();
> > > + predict_end_t = ktime_add_ms(mad->last_off_timestamps[channel], 2 * ADC_WAIT_TIME_MS);
> > > +
> > > + if (ktime_after(start_t, predict_end_t))
> > > + pre_wait_time = ADC_WAIT_TIME_MS;
> > > + else
> > > + pre_wait_time = 3 * ADC_WAIT_TIME_MS;
> > > +
> > > + msleep(pre_wait_time);
> > > +
> > > + while (true) {
> > > + ret = regmap_raw_read(mad->regmap, MT6360_REG_PMUADCRPT1, rpt, sizeof(rpt));
> > > + if (ret)
> > > + goto out_adc_conv;
> > > +
> > > + /*
> > > + * There are two functions, ZCV and TypeC OTP, running ADC VBAT and TS in
> > > + * background, and ADC samples are taken on a fixed frequency no matter read the
> > > + * previous one or not.
> > > + * To avoid conflict, We set minimum time threshold after enable ADC and
> > > + * check report channel is the same.
> > > + * The worst case is run the same ADC twice and background function is also running,
> > > + * ADC conversion sequence is desire channel before start ADC, background ADC,
> > > + * desire channel after start ADC.
> > > + * So the minimum correct data is three times of typical conversion time.
> > > + */
> > > + if ((rpt[0] & MT6360_RPTCH_MASK) == channel)
> > > + break;
> > > +
> > > + msleep(ADC_WAIT_TIME_MS);
> > > + }
> > > +
> > > + /* rpt[1]: ADC_HI_BYTE, rpt[2]: ADC_LOW_BYTE */
> > > + *val = be16_to_cpup((__be16 *)(rpt + 1));
> >
> > To be entirely safe, probably need that to be an unaligned read?
> >
>
> Maybe I can change to "*val = rpt[1] << 8 | rpt[2];".
> It's more abvious.
That would definitely be safe so do that.
>
> > > + ret = IIO_VAL_INT;
> > > +
> > > +out_adc_conv:
> > > + /* Only keep ADC enable */
> > > + adc_enable = cpu_to_be16(MT6360_ADCEN_MASK);
> > > + regmap_raw_write(mad->regmap, MT6360_REG_PMUADCCFG, (void *)&adc_enable, sizeof(__be16));
> >
> > sizeof(adc_enable)
> >
>
> ACK
>
> > > + mad->last_off_timestamps[channel] = ktime_get();
> > > + /* Config prefer channel to NO_PREFER */
> > > + regmap_update_bits(mad->regmap, MT6360_REG_PMUADCRPT1, MT6360_PREFERCH_MASK,
> > > + MT6360_NO_PREFER << MT6360_PREFERCH_SHFT);
> > > +out_adc_lock:
> > > + mutex_unlock(&mad->adc_lock);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int mt6360_adc_read_scale(struct mt6360_adc_data *mad, int channel, int *val, int *val2)
> > > +{
> > > + unsigned int regval;
> > > + int ret;
> > > +
> > > + switch (channel) {
> > > + case MT6360_CHAN_USBID:
> > > + fallthrough;
> >
> > I don't think we need fallthrough for cases
> > with nothing in them.
> >
>
> Every channel needs set " *val = 2500" for scale.
> Do you mean change as below?
>
> switch (channel) {
> case MT6360_CHAN_USBID:
> case MT6360_CHAN_VSYS:
> case MT6360_CHAN_VBAT:
> case MT6360_CHAN_CHG_VDDP:
> case MT6360_CHAN_VREF_TS:
> fallthrough;
Don't need this fallthrough.
fallthrough is only needed if something is done in the
case statement. I believe the checker is clever enough to
assume that a set of case statements with nothing inbetween
them are deliberate.
> case MT6360_CHAN_TS:
> *val = 1250;
> return IIO_VAL_INT;
>
...
> > > +
> > > +static irqreturn_t mt6360_adc_trigger_handler(int irq, void *p)
> > > +{
> > > + struct iio_poll_func *pf = p;
> > > + struct iio_dev *indio_dev = pf->indio_dev;
> > > + struct mt6360_adc_data *mad = iio_priv(indio_dev);
> > > + struct {
> > > + u16 values[MT6360_CHAN_MAX];
> >
> > There is a hole in here I think? (MT6360_CHAN_MAX is 11?)
> > If so we need to explicitly memset the structure to avoid any
> > risk of kernel data leakage to userspace.
Make sure you deal with this in v5!
> >
> > > + int64_t timestamp;
> > > + } data;
> >
> > I guess we know this is on a platform with 64bit alignment for int64_t's
> > (unlike x86_64 for example)
> >
>
> Do you mean change as below?
> struct {
> u16 values[MT6360_CHAN_MAX];
> int64_t timestamp; __aligned(8)
> } data;
You can do that, or we can rely on the fact this part is never used
on a platform where that isn't guaranteed anyway.
>
> > > + int i = 0, bit, val, ret;
...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-09-19 13:20 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-15 17:36 [PATCH v4 0/3] iio: adc: mt6360: Add ADC driver for MT6360 Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-15 17:36 ` [PATCH v4 1/3] dt-bindings: iio: adc: add bindings doc for MT6360 ADC Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-17 17:33 ` Jonathan Cameron
2020-09-17 17:33 ` Jonathan Cameron
2020-09-17 17:33 ` Jonathan Cameron
2020-09-15 17:36 ` [PATCH v4 2/3] Documentation: ABI: testing: mt6360: Add ADC sysfs guideline Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-17 17:42 ` Jonathan Cameron
2020-09-17 17:42 ` Jonathan Cameron
2020-09-17 17:42 ` Jonathan Cameron
2020-09-18 7:21 ` Gene Chen
2020-09-18 7:21 ` Gene Chen
2020-09-18 7:21 ` Gene Chen
2020-09-18 8:03 ` Jonathan Cameron
2020-09-18 8:03 ` Jonathan Cameron
2020-09-18 8:03 ` Jonathan Cameron
2020-09-18 10:33 ` Gene Chen
2020-09-18 10:33 ` Gene Chen
2020-09-18 10:33 ` Gene Chen
2020-09-18 15:12 ` Jonathan Cameron
2020-09-18 15:12 ` Jonathan Cameron
2020-09-18 15:12 ` Jonathan Cameron
2020-09-15 17:36 ` [PATCH v4 3/3] iio: adc: mt6360: Add ADC driver for MT6360 Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-15 17:36 ` Gene Chen
2020-09-17 17:53 ` Jonathan Cameron
2020-09-17 17:53 ` Jonathan Cameron
2020-09-17 17:53 ` Jonathan Cameron
2020-09-18 8:04 ` Gene Chen
2020-09-18 8:04 ` Gene Chen
2020-09-18 8:04 ` Gene Chen
2020-09-19 13:20 ` Jonathan Cameron [this message]
2020-09-19 13:20 ` Jonathan Cameron
2020-09-19 13:20 ` Jonathan Cameron
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=20200919142005.18e3e11f@archlinux \
--to=jic23@kernel.org \
--cc=Wilma.Wu@mediatek.com \
--cc=benjamin.chao@mediatek.com \
--cc=cy_huang@richtek.com \
--cc=gene.chen.richtek@gmail.com \
--cc=gene_chen@richtek.com \
--cc=knaack.h@gmx.de \
--cc=lars@metafoo.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=matthias.bgg@gmail.com \
--cc=pmeerw@pmeerw.net \
--cc=shufan_lee@richtek.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.