From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Return-Path: Date: Tue, 27 Nov 2018 01:21:27 +0100 From: Anatolij Gustschin Subject: Re: [PATCH v2 2/3] spi: add FTDI MPSSE SPI controller driver Message-ID: <20181127012127.24e455b6@crub> In-Reply-To: <20181121124237.GC8059@sirena.org.uk> References: <20181120002821.12794-1-agust@denx.de> <20181120002821.12794-3-agust@denx.de> <20181121124237.GC8059@sirena.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable To: Mark Brown Cc: linux-usb@vger.kernel.org, linux-spi@vger.kernel.org, linux-fpga@vger.kernel.org, linux-kernel@vger.kernel.org, gregkh@linuxfoundation.org, atull@kernel.org, mdf@kernel.org List-ID: On Wed, 21 Nov 2018 12:42:37 +0000 Mark Brown broonie@kernel.org wrote: ... >> obj-$(CONFIG_SPI_ZYNQMP_GQSPI) +=3D spi-zynqmp-gqspi.o >> +obj-$(CONFIG_SPI_FTDI_MPSSE) +=3D spi-ftdi-mpsse.o >> =20 >> # SPI slave protocol handlers >> obj-$(CONFIG_SPI_SLAVE_TIME) +=3D spi-slave-time.o =20 > >Please keep the Makefile sorted. Will fix it in v3. >> +++ b/drivers/spi/spi-ftdi-mpsse.c >> @@ -0,0 +1,673 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * FTDI FT232H MPSSE SPI controller driver =20 > >Please make the entire comment block here a C++ one so it looks more >consistent. Okay. >> + struct gpiod_lookup_table *lookup[13]; =20 > >This magic number for the size of the lookup table is not good. Will fix it in v3. >> +static void ftdi_spi_chipselect(struct ftdi_spi *priv, struct spi_devic= e *spi, >> + bool value) >> +{ >> + int cs =3D spi->chip_select; >> + >> + dev_dbg(&priv->master->dev, "%s: CS %d, cs mode %d, val %d\n", >> + __func__, cs, (spi->mode & SPI_CS_HIGH), value); >> + >> + gpiod_set_raw_value_cansleep(priv->cs_gpios[cs], value); >> +} =20 > >This is just a gpio chip select - can't it be handled by the core chip >select code? spi core chip select code doesn't use gpio_desc based API yet. But it can be handled using .set_cs(), I'll convert the driver to use .set_cs(). >> + remaining =3D len; >> + do { >> + stride =3D min_t(size_t, remaining, SZ_64K - 3); =20 > >Rather than having a magic number for the buffer size it would be better >to either have a driver specific constant that's used consistently or >just use sizeof() when it's referenced in the code. That way if the >buffer size is changed nothing will get missed. sizeof() is better choice here, will use it in v3. >> + /* Last transfer with cs_change set, stop keeping CS */ >> + if (list_is_last(&t->transfer_list, &msg->transfers)) { >> + keep_cs =3D true; >> + break; >> + } >> + ftdi_spi_chipselect(priv, spi, !(spi->mode & SPI_CS_HIGH)); >> + usleep_range(10, 15); >> + ftdi_spi_chipselect(priv, spi, spi->mode & SPI_CS_HIGH); =20 > >I'm not clear what this is intended to do? It's overall not clear to me >that the driver needs to use transfer_one_message and not transfer_one, >the latter keeps more of the code in common code. It has been a while since I started with this driver, I don't remember the intention of this chip select toggling here. I'll convert the driver to use .transfer_one(). >> + /* Find max. slave chipselect number */ >> + num_cs =3D pd->spi_info_len; >> + for (i =3D 0; i < num_cs; i++) { >> + if (max_cs < pd->spi_info[i].chip_select) >> + max_cs =3D pd->spi_info[i].chip_select; >> + } >> + >> + if (max_cs > 12) { >> + dev_err(dev, "Invalid max CS in platform data: %d\n", max_cs); >> + return -EINVAL; >> + } >> + dev_dbg(dev, "CS count %d, max CS %d\n", num_cs, max_cs); >> + max_cs +=3D 1; /* including CS0 */ =20 > >Why not just size the array based on the platform data? The driver must also support multiple SPI slaves with additional control pins (besides SPI chip-select gpios). There are devices with not adjacent chip-select gpios or devices with single chip-select gpio starting at some offset. The array size is not always the number of chip-selects or the max. chip-select, e.g.: $ tree /sys/bus/spi/devices/ /sys/bus/spi/devices/ =E2=94=9C=E2=94=80=E2=94=80 spi0.4 -> ../../../devices/pci0000:00/0000:00:1= d.0/usb2/2-1/2-1.2/2-1.2.4/2-1.2.4:1.0/ftdi-mpsse-spi.0/spi_master/spi0/spi= 0.4 =E2=94=9C=E2=94=80=E2=94=80 spi1.0 -> ../../../devices/pci0000:00/0000:00:1= d.0/usb2/2-1/2-1.2/2-1.2.3/2-1.2.3:1.0/ftdi-mpsse-spi.1/spi_master/spi1/spi= 1.0 =E2=94=9C=E2=94=80=E2=94=80 spi1.12 -> ../../../devices/pci0000:00/0000:00:= 1d.0/usb2/2-1/2-1.2/2-1.2.3/2-1.2.3:1.0/ftdi-mpsse-spi.1/spi_master/spi1/sp= i1.12 =E2=94=9C=E2=94=80=E2=94=80 spi1.4 -> ../../../devices/pci0000:00/0000:00:1= d.0/usb2/2-1/2-1.2/2-1.2.3/2-1.2.3:1.0/ftdi-mpsse-spi.1/spi_master/spi1/spi= 1.4 =E2=94=94=E2=94=80=E2=94=80 spi1.8 -> ../../../devices/pci0000:00/0000:00:1= d.0/usb2/2-1/2-1.2/2-1.2.3/2-1.2.3:1.0/ftdi-mpsse-spi.1/spi_master/spi1/spi= 1.8 $ sudo cat /sys/kernel/debug/gpio gpiochip1: GPIOs 486-498, parent: usb/2-1.2.3:1.0, ftdi-mpsse-gpio.1, can s= leep: gpio-486 (mpsse.1-CS |spi-cs ) out hi ACTIVE LOW gpio-487 (mpsse.1-GPIOL0 |confd ) in hi=20 gpio-488 (mpsse.1-GPIOL1 |nstat ) in hi ACTIVE LOW gpio-489 (mpsse.1-GPIOL2 |nconfig ) out hi ACTIVE LOW gpio-490 (mpsse.1-GPIOL3 |spi-cs ) out hi ACTIVE LOW gpio-491 (mpsse.1-GPIOH0 |confd ) in hi=20 gpio-492 (mpsse.1-GPIOH1 |nstat ) in hi ACTIVE LOW gpio-493 (mpsse.1-GPIOH2 |nconfig ) out hi ACTIVE LOW gpio-494 (mpsse.1-GPIOH3 |spi-cs ) out hi ACTIVE LOW gpio-495 (mpsse.1-GPIOH4 |confd ) in hi=20 gpio-496 (mpsse.1-GPIOH5 |nstat ) in hi ACTIVE LOW gpio-497 (mpsse.1-GPIOH6 |nconfig ) out hi ACTIVE LOW gpio-498 (mpsse.1-GPIOH7 |spi-cs ) out hi=20 gpiochip0: GPIOs 499-511, parent: usb/2-1.2.4:1.0, ftdi-mpsse-gpio.0, can s= leep: gpio-499 (mpsse.0-CS ) gpio-500 (mpsse.0-GPIOL0 ) gpio-501 (mpsse.0-GPIOL1 ) gpio-502 (mpsse.0-GPIOL2 ) gpio-503 (mpsse.0-GPIOL3 |spi-cs ) out hi ACTIVE LOW gpio-504 (mpsse.0-GPIOH0 |confd ) in hi=20 gpio-505 (mpsse.0-GPIOH1 |nstat ) in hi ACTIVE LOW gpio-506 (mpsse.0-GPIOH2 |nconfig ) out hi ACTIVE LOW gpio-507 (mpsse.0-GPIOH3 ) gpio-508 (mpsse.0-GPIOH4 ) gpio-509 (mpsse.0-GPIOH5 ) gpio-510 (mpsse.0-GPIOH6 ) gpio-511 (mpsse.0-GPIOH7 ) Thanks, Anatolij From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v2,2/3] spi: add FTDI MPSSE SPI controller driver From: Anatolij Gustschin Message-Id: <20181127012127.24e455b6@crub> Date: Tue, 27 Nov 2018 01:21:27 +0100 To: Mark Brown Cc: linux-usb@vger.kernel.org, linux-spi@vger.kernel.org, linux-fpga@vger.kernel.org, linux-kernel@vger.kernel.org, gregkh@linuxfoundation.org, atull@kernel.org, mdf@kernel.org List-ID: T24gV2VkLCAyMSBOb3YgMjAxOCAxMjo0MjozNyArMDAwMApNYXJrIEJyb3duIGJyb29uaWVAa2Vy bmVsLm9yZyB3cm90ZToKLi4uCj4+ICBvYmotJChDT05GSUdfU1BJX1pZTlFNUF9HUVNQSSkJCSs9 IHNwaS16eW5xbXAtZ3FzcGkubwo+PiArb2JqLSQoQ09ORklHX1NQSV9GVERJX01QU1NFKQkJKz0g c3BpLWZ0ZGktbXBzc2Uubwo+PiAgCj4+ICAjIFNQSSBzbGF2ZSBwcm90b2NvbCBoYW5kbGVycwo+ PiAgb2JqLSQoQ09ORklHX1NQSV9TTEFWRV9USU1FKQkJKz0gc3BpLXNsYXZlLXRpbWUubyAgCj4K PlBsZWFzZSBrZWVwIHRoZSBNYWtlZmlsZSBzb3J0ZWQuCgpXaWxsIGZpeCBpdCBpbiB2My4KCj4+ ICsrKyBiL2RyaXZlcnMvc3BpL3NwaS1mdGRpLW1wc3NlLmMKPj4gQEAgLTAsMCArMSw2NzMgQEAK Pj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wCj4+ICsvKgo+PiArICogRlRE SSBGVDIzMkggTVBTU0UgU1BJIGNvbnRyb2xsZXIgZHJpdmVyICAKPgo+UGxlYXNlIG1ha2UgdGhl IGVudGlyZSBjb21tZW50IGJsb2NrIGhlcmUgYSBDKysgb25lIHNvIGl0IGxvb2tzIG1vcmUKPmNv bnNpc3RlbnQuCgpPa2F5LgoKPj4gKwlzdHJ1Y3QgZ3Bpb2RfbG9va3VwX3RhYmxlICpsb29rdXBb MTNdOyAgCj4KPlRoaXMgbWFnaWMgbnVtYmVyIGZvciB0aGUgc2l6ZSBvZiB0aGUgbG9va3VwIHRh YmxlIGlzIG5vdCBnb29kLgoKV2lsbCBmaXggaXQgaW4gdjMuCgo+PiArc3RhdGljIHZvaWQgZnRk aV9zcGlfY2hpcHNlbGVjdChzdHJ1Y3QgZnRkaV9zcGkgKnByaXYsIHN0cnVjdCBzcGlfZGV2aWNl ICpzcGksCj4+ICsJCQkJYm9vbCB2YWx1ZSkKPj4gK3sKPj4gKwlpbnQgY3MgPSBzcGktPmNoaXBf c2VsZWN0Owo+PiArCj4+ICsJZGV2X2RiZygmcHJpdi0+bWFzdGVyLT5kZXYsICIlczogQ1MgJWQs IGNzIG1vZGUgJWQsIHZhbCAlZFxuIiwKPj4gKwkJX19mdW5jX18sIGNzLCAoc3BpLT5tb2RlICYg U1BJX0NTX0hJR0gpLCB2YWx1ZSk7Cj4+ICsKPj4gKwlncGlvZF9zZXRfcmF3X3ZhbHVlX2NhbnNs ZWVwKHByaXYtPmNzX2dwaW9zW2NzXSwgdmFsdWUpOwo+PiArfSAgCj4KPlRoaXMgaXMganVzdCBh IGdwaW8gY2hpcCBzZWxlY3QgLSBjYW4ndCBpdCBiZSBoYW5kbGVkIGJ5IHRoZSBjb3JlIGNoaXAK PnNlbGVjdCBjb2RlPwoKc3BpIGNvcmUgY2hpcCBzZWxlY3QgY29kZSBkb2Vzbid0IHVzZSBncGlv X2Rlc2MgYmFzZWQgQVBJIHlldC4KQnV0IGl0IGNhbiBiZSBoYW5kbGVkIHVzaW5nIC5zZXRfY3Mo KSwgSSdsbCBjb252ZXJ0IHRoZSBkcml2ZXIKdG8gdXNlIC5zZXRfY3MoKS4KCj4+ICsJcmVtYWlu aW5nID0gbGVuOwo+PiArCWRvIHsKPj4gKwkJc3RyaWRlID0gbWluX3Qoc2l6ZV90LCByZW1haW5p bmcsIFNaXzY0SyAtIDMpOyAgCj4KPlJhdGhlciB0aGFuIGhhdmluZyBhIG1hZ2ljIG51bWJlciBm b3IgdGhlIGJ1ZmZlciBzaXplIGl0IHdvdWxkIGJlIGJldHRlcgo+dG8gZWl0aGVyIGhhdmUgYSBk cml2ZXIgc3BlY2lmaWMgY29uc3RhbnQgdGhhdCdzIHVzZWQgY29uc2lzdGVudGx5IG9yCj5qdXN0 IHVzZSBzaXplb2YoKSB3aGVuIGl0J3MgcmVmZXJlbmNlZCBpbiB0aGUgY29kZS4gIFRoYXQgd2F5 IGlmIHRoZQo+YnVmZmVyIHNpemUgaXMgY2hhbmdlZCBub3RoaW5nIHdpbGwgZ2V0IG1pc3NlZC4K CnNpemVvZigpIGlzIGJldHRlciBjaG9pY2UgaGVyZSwgd2lsbCB1c2UgaXQgaW4gdjMuCgo+PiAr CQkvKiBMYXN0IHRyYW5zZmVyIHdpdGggY3NfY2hhbmdlIHNldCwgc3RvcCBrZWVwaW5nIENTICov Cj4+ICsJCWlmIChsaXN0X2lzX2xhc3QoJnQtPnRyYW5zZmVyX2xpc3QsICZtc2ctPnRyYW5zZmVy cykpIHsKPj4gKwkJCWtlZXBfY3MgPSB0cnVlOwo+PiArCQkJYnJlYWs7Cj4+ICsJCX0KPj4gKwkJ ZnRkaV9zcGlfY2hpcHNlbGVjdChwcml2LCBzcGksICEoc3BpLT5tb2RlICYgU1BJX0NTX0hJR0gp KTsKPj4gKwkJdXNsZWVwX3JhbmdlKDEwLCAxNSk7Cj4+ICsJCWZ0ZGlfc3BpX2NoaXBzZWxlY3Qo cHJpdiwgc3BpLCBzcGktPm1vZGUgJiBTUElfQ1NfSElHSCk7ICAKPgo+SSdtIG5vdCBjbGVhciB3 aGF0IHRoaXMgaXMgaW50ZW5kZWQgdG8gZG8/ICBJdCdzIG92ZXJhbGwgbm90IGNsZWFyIHRvIG1l Cj50aGF0IHRoZSBkcml2ZXIgbmVlZHMgdG8gdXNlIHRyYW5zZmVyX29uZV9tZXNzYWdlIGFuZCBu b3QgdHJhbnNmZXJfb25lLAo+dGhlIGxhdHRlciBrZWVwcyBtb3JlIG9mIHRoZSBjb2RlIGluIGNv bW1vbiBjb2RlLgoKSXQgaGFzIGJlZW4gYSB3aGlsZSBzaW5jZSBJIHN0YXJ0ZWQgd2l0aCB0aGlz IGRyaXZlciwgSSBkb24ndCByZW1lbWJlcgp0aGUgaW50ZW50aW9uIG9mIHRoaXMgY2hpcCBzZWxl Y3QgdG9nZ2xpbmcgaGVyZS4gSSdsbCBjb252ZXJ0IHRoZQpkcml2ZXIgdG8gdXNlIC50cmFuc2Zl cl9vbmUoKS4KCj4+ICsJLyogRmluZCBtYXguIHNsYXZlIGNoaXBzZWxlY3QgbnVtYmVyICovCj4+ ICsJbnVtX2NzID0gcGQtPnNwaV9pbmZvX2xlbjsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgbnVtX2Nz OyBpKyspIHsKPj4gKwkJaWYgKG1heF9jcyA8IHBkLT5zcGlfaW5mb1tpXS5jaGlwX3NlbGVjdCkK Pj4gKwkJCW1heF9jcyA9IHBkLT5zcGlfaW5mb1tpXS5jaGlwX3NlbGVjdDsKPj4gKwl9Cj4+ICsK Pj4gKwlpZiAobWF4X2NzID4gMTIpIHsKPj4gKwkJZGV2X2VycihkZXYsICJJbnZhbGlkIG1heCBD UyBpbiBwbGF0Zm9ybSBkYXRhOiAlZFxuIiwgbWF4X2NzKTsKPj4gKwkJcmV0dXJuIC1FSU5WQUw7 Cj4+ICsJfQo+PiArCWRldl9kYmcoZGV2LCAiQ1MgY291bnQgJWQsIG1heCBDUyAlZFxuIiwgbnVt X2NzLCBtYXhfY3MpOwo+PiArCW1heF9jcyArPSAxOyAvKiBpbmNsdWRpbmcgQ1MwICovICAKPgo+ V2h5IG5vdCBqdXN0IHNpemUgdGhlIGFycmF5IGJhc2VkIG9uIHRoZSBwbGF0Zm9ybSBkYXRhPwoK VGhlIGRyaXZlciBtdXN0IGFsc28gc3VwcG9ydCBtdWx0aXBsZSBTUEkgc2xhdmVzIHdpdGggYWRk aXRpb25hbCBjb250cm9sCnBpbnMgKGJlc2lkZXMgU1BJIGNoaXAtc2VsZWN0IGdwaW9zKS4gVGhl cmUgYXJlIGRldmljZXMgd2l0aCBub3QgYWRqYWNlbnQKY2hpcC1zZWxlY3QgZ3Bpb3Mgb3IgZGV2 aWNlcyB3aXRoIHNpbmdsZSBjaGlwLXNlbGVjdCBncGlvIHN0YXJ0aW5nIGF0CnNvbWUgb2Zmc2V0 LiBUaGUgYXJyYXkgc2l6ZSBpcyBub3QgYWx3YXlzIHRoZSBudW1iZXIgb2YgY2hpcC1zZWxlY3Rz Cm9yIHRoZSBtYXguIGNoaXAtc2VsZWN0LCBlLmcuOgoKJCB0cmVlIC9zeXMvYnVzL3NwaS9kZXZp Y2VzLwovc3lzL2J1cy9zcGkvZGV2aWNlcy8K4pSc4pSA4pSAIHNwaTAuNCAtPiAuLi8uLi8uLi9k ZXZpY2VzL3BjaTAwMDA6MDAvMDAwMDowMDoxZC4wL3VzYjIvMi0xLzItMS4yLzItMS4yLjQvMi0x LjIuNDoxLjAvZnRkaS1tcHNzZS1zcGkuMC9zcGlfbWFzdGVyL3NwaTAvc3BpMC40CuKUnOKUgOKU gCBzcGkxLjAgLT4gLi4vLi4vLi4vZGV2aWNlcy9wY2kwMDAwOjAwLzAwMDA6MDA6MWQuMC91c2Iy LzItMS8yLTEuMi8yLTEuMi4zLzItMS4yLjM6MS4wL2Z0ZGktbXBzc2Utc3BpLjEvc3BpX21hc3Rl ci9zcGkxL3NwaTEuMArilJzilIDilIAgc3BpMS4xMiAtPiAuLi8uLi8uLi9kZXZpY2VzL3BjaTAw MDA6MDAvMDAwMDowMDoxZC4wL3VzYjIvMi0xLzItMS4yLzItMS4yLjMvMi0xLjIuMzoxLjAvZnRk aS1tcHNzZS1zcGkuMS9zcGlfbWFzdGVyL3NwaTEvc3BpMS4xMgrilJzilIDilIAgc3BpMS40IC0+ IC4uLy4uLy4uL2RldmljZXMvcGNpMDAwMDowMC8wMDAwOjAwOjFkLjAvdXNiMi8yLTEvMi0xLjIv Mi0xLjIuMy8yLTEuMi4zOjEuMC9mdGRpLW1wc3NlLXNwaS4xL3NwaV9tYXN0ZXIvc3BpMS9zcGkx LjQK4pSU4pSA4pSAIHNwaTEuOCAtPiAuLi8uLi8uLi9kZXZpY2VzL3BjaTAwMDA6MDAvMDAwMDow MDoxZC4wL3VzYjIvMi0xLzItMS4yLzItMS4yLjMvMi0xLjIuMzoxLjAvZnRkaS1tcHNzZS1zcGku MS9zcGlfbWFzdGVyL3NwaTEvc3BpMS44CgokIHN1ZG8gY2F0IC9zeXMva2VybmVsL2RlYnVnL2dw aW8KZ3Bpb2NoaXAxOiBHUElPcyA0ODYtNDk4LCBwYXJlbnQ6IHVzYi8yLTEuMi4zOjEuMCwgZnRk aS1tcHNzZS1ncGlvLjEsIGNhbiBzbGVlcDoKIGdwaW8tNDg2IChtcHNzZS4xLUNTICAgICAgICAg IHxzcGktY3MgICAgICAgICAgICAgICkgb3V0IGhpIEFDVElWRSBMT1cKIGdwaW8tNDg3IChtcHNz ZS4xLUdQSU9MMCAgICAgIHxjb25mZCAgICAgICAgICAgICAgICkgaW4gIGhpIAogZ3Bpby00ODgg KG1wc3NlLjEtR1BJT0wxICAgICAgfG5zdGF0ICAgICAgICAgICAgICAgKSBpbiAgaGkgQUNUSVZF IExPVwogZ3Bpby00ODkgKG1wc3NlLjEtR1BJT0wyICAgICAgfG5jb25maWcgICAgICAgICAgICAg KSBvdXQgaGkgQUNUSVZFIExPVwogZ3Bpby00OTAgKG1wc3NlLjEtR1BJT0wzICAgICAgfHNwaS1j cyAgICAgICAgICAgICAgKSBvdXQgaGkgQUNUSVZFIExPVwogZ3Bpby00OTEgKG1wc3NlLjEtR1BJ T0gwICAgICAgfGNvbmZkICAgICAgICAgICAgICAgKSBpbiAgaGkgCiBncGlvLTQ5MiAobXBzc2Uu MS1HUElPSDEgICAgICB8bnN0YXQgICAgICAgICAgICAgICApIGluICBoaSBBQ1RJVkUgTE9XCiBn cGlvLTQ5MyAobXBzc2UuMS1HUElPSDIgICAgICB8bmNvbmZpZyAgICAgICAgICAgICApIG91dCBo aSBBQ1RJVkUgTE9XCiBncGlvLTQ5NCAobXBzc2UuMS1HUElPSDMgICAgICB8c3BpLWNzICAgICAg ICAgICAgICApIG91dCBoaSBBQ1RJVkUgTE9XCiBncGlvLTQ5NSAobXBzc2UuMS1HUElPSDQgICAg ICB8Y29uZmQgICAgICAgICAgICAgICApIGluICBoaSAKIGdwaW8tNDk2IChtcHNzZS4xLUdQSU9I NSAgICAgIHxuc3RhdCAgICAgICAgICAgICAgICkgaW4gIGhpIEFDVElWRSBMT1cKIGdwaW8tNDk3 IChtcHNzZS4xLUdQSU9INiAgICAgIHxuY29uZmlnICAgICAgICAgICAgICkgb3V0IGhpIEFDVElW RSBMT1cKIGdwaW8tNDk4IChtcHNzZS4xLUdQSU9INyAgICAgIHxzcGktY3MgICAgICAgICAgICAg ICkgb3V0IGhpIAoKZ3Bpb2NoaXAwOiBHUElPcyA0OTktNTExLCBwYXJlbnQ6IHVzYi8yLTEuMi40 OjEuMCwgZnRkaS1tcHNzZS1ncGlvLjAsIGNhbiBzbGVlcDoKIGdwaW8tNDk5IChtcHNzZS4wLUNT ICAgICAgICAgICkKIGdwaW8tNTAwIChtcHNzZS4wLUdQSU9MMCAgICAgICkKIGdwaW8tNTAxICht cHNzZS4wLUdQSU9MMSAgICAgICkKIGdwaW8tNTAyIChtcHNzZS4wLUdQSU9MMiAgICAgICkKIGdw aW8tNTAzIChtcHNzZS4wLUdQSU9MMyAgICAgIHxzcGktY3MgICAgICAgICAgICAgICkgb3V0IGhp IEFDVElWRSBMT1cKIGdwaW8tNTA0IChtcHNzZS4wLUdQSU9IMCAgICAgIHxjb25mZCAgICAgICAg ICAgICAgICkgaW4gIGhpIAogZ3Bpby01MDUgKG1wc3NlLjAtR1BJT0gxICAgICAgfG5zdGF0ICAg ICAgICAgICAgICAgKSBpbiAgaGkgQUNUSVZFIExPVwogZ3Bpby01MDYgKG1wc3NlLjAtR1BJT0gy ICAgICAgfG5jb25maWcgICAgICAgICAgICAgKSBvdXQgaGkgQUNUSVZFIExPVwogZ3Bpby01MDcg KG1wc3NlLjAtR1BJT0gzICAgICAgKQogZ3Bpby01MDggKG1wc3NlLjAtR1BJT0g0ICAgICAgKQog Z3Bpby01MDkgKG1wc3NlLjAtR1BJT0g1ICAgICAgKQogZ3Bpby01MTAgKG1wc3NlLjAtR1BJT0g2 ICAgICAgKQogZ3Bpby01MTEgKG1wc3NlLjAtR1BJT0g3ICAgICAgKQoKVGhhbmtzLApBbmF0b2xp ago=