Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nutdrv_qx driver for Ablerex model PR#2 #1135

Merged
merged 22 commits into from Jan 21, 2022

Conversation

Ablerexsoftware
Copy link
Contributor

I am sorry for that.
We set a new branch and repush it for nutdrv_qx driver for Ablerex model, please review

@jimklimov
Copy link
Member

jimklimov commented Oct 19, 2021

Thank you, it is much more manageable now, and great thanks for the patience and persistence to get this done right :) Seems you git added the drivers/Makefile.am in a way that lost a few NUT upstream changes, I'll try to post the fixes back, but otherwise looks structurally great!

On non-coding side, it would be beneficial to also update the documentation similar to those seen in https://github.com/networkupstools/nut/pull/979/files -- at least:

  • docs/man/nutdrv_qx.txt and docs/nutdrv_qx-subdrivers.txt list the available subdrivers;
  • something else if applicable (is there any toggle to pick the new subdriver explicitly? some suggestion for ups.conf, udev or similar USB support to map the VID/PID particularly to Ablerex driver?);
  • and/or perhaps the docs/acknowledgements.txt section for vendor-backed contributions to NUT codebase like proposed at 851d2f7

Regarding VID/PID, should there be a change to USB_DEVICE table like at https://github.com/networkupstools/nut/pull/979/files#diff-12d702aa91ce0aee7706c1aa0275279fc8059acc58e69088116528e1b20509b7R446-R447 below?

-	{ USB_DEVICE(0xffff, 0x0000), &krauler_subdriver }, /* Ablerex 625L USB */
+	{ USB_DEVICE(0xffff, 0x0000), &ablerex_subdriver },	/* Ablerex 625L USB */
+	{ USB_DEVICE(0x1cb0, 0x0035), &ablerex_subdriver },	/* Ablerex Dk+ 6kVA USB */

For maintainer context, I believe this PR follows up from earlier contribution attempts in PRs #1123 and #979.

@jimklimov
Copy link
Member

On codebase side, seems there are a few complaints from CI checks, e.g.:

[2021-10-19T02:14:21.480Z] nutdrv_qx.c: In function 'ablerex_command':
[2021-10-19T02:14:21.480Z] nutdrv_qx.c:1395:53: error: passing argument 6 of 'usb_control_msg'
    from incompatible pointer type [-Werror=incompatible-pointer-types]
[2021-10-19T02:14:21.480Z]  1395 |   ret = usb_control_msg(udev, 0x21, 0x09, 0x305, 0, &tmp, 47, 1000);
[2021-10-19T02:14:21.480Z]       |                                                     ^~~~
[2021-10-19T02:14:21.480Z]       |                                                     |
[2021-10-19T02:14:21.480Z]       |                                                     char (*)[64]

[2021-10-19T02:14:21.480Z] In file included from usb-common.h:26,
[2021-10-19T02:14:21.480Z]                  from libusb.h:35,
[2021-10-19T02:14:21.480Z]                  from nutdrv_qx.c:47:

[2021-10-19T02:14:21.480Z] /usr/include/usb.h:295:45: note: expected 'char *' but argument is of type 'char (*)[64]'
[2021-10-19T02:14:21.480Z]   295 |    int request, int value, int index, char *bytes,
[2021-10-19T02:14:21.480Z]       |                                       ~~~~~~^~~~~

[2021-10-19T02:14:21.480Z] nutdrv_qx.c:1402:53: error: passing argument 6 of 'usb_control_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
[2021-10-19T02:14:21.480Z]  1402 |   ret = usb_control_msg(udev, 0xA1, 0x01, 0x305, 0, &tmpryy, 47, 1000);
[2021-10-19T02:14:21.480Z]       |                                                     ^~~~~~~
[2021-10-19T02:14:21.480Z]       |                                                     |
[2021-10-19T02:14:21.480Z]       |                                                     char (*)[64]

[2021-10-19T02:14:21.480Z] In file included from usb-common.h:26,
[2021-10-19T02:14:21.480Z]                  from libusb.h:35,
[2021-10-19T02:14:21.480Z]                  from nutdrv_qx.c:47:

[2021-10-19T02:14:21.480Z] /usr/include/usb.h:295:45: note: expected 'char *' but argument is of type 'char (*)[64]'
[2021-10-19T02:14:21.480Z]   295 |    int request, int value, int index, char *bytes,
[2021-10-19T02:14:21.480Z]       |                                       ~~~~~~^~~~~

[2021-10-19T02:14:21.480Z] nutdrv_qx.c:1371:6: error: unused variable 'i' [-Werror=unused-variable]
[2021-10-19T02:14:21.480Z]  1371 |  int i;
[2021-10-19T02:14:21.480Z]       |      ^

[2021-10-19T02:14:21.480Z] nutdrv_qx.c:1369:63: error: unused parameter 'buflen' [-Werror=unused-parameter]
[2021-10-19T02:14:21.480Z]  1369 | static int ablerex_command(const char *cmd, char *buf, size_t buflen)
[2021-10-19T02:14:21.480Z]       |                                                        ~~~~~~~^~~~~~

[2021-10-19T02:14:21.480Z] At top level:
[2021-10-19T02:14:21.480Z] nutdrv_qx.c:1531:14: error: 'ablerex_ext_subdriver' defined but not used [-Werror=unused-function]
[2021-10-19T02:14:21.480Z]  1531 | static void *ablerex_ext_subdriver(USBDevice_t *device)
[2021-10-19T02:14:21.480Z]       |              ^~~~~~~~~~~~~~~~~~~~~
[2021-10-19T02:14:21.480Z] cc1: all warnings being treated as errors
[2021-10-19T02:14:21.480Z] *** Error code 1

Copy link
Member

@jimklimov jimklimov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the very least, there are a few codebase fixes needed to pass CI builds cleanly.

Also, some documentation changes are recommended above.

@Ablerexsoftware
Copy link
Contributor Author

Ablerexsoftware commented Oct 21, 2021 via email

@Ablerexsoftware
Copy link
Contributor Author

Ablerexsoftware commented Nov 1, 2021

Hi! Sir,
I have a question as below consult with you.
Regarding VID/PID, should there be a change to USB_DEVICE table like at https://github.com/networkupstools/nut/pull/979/files#diff-12d702aa91ce0aee7706c1aa0275279fc8059acc58e69088116528e1b20509b7R446-R447 below?

If we added the USB_DEVICDE table as below at nutdrv_qx.c
USB_DEVICE(0xffff, 0x0000), NULL, NULL, &krauler_subdriver
USB_DEVICE(0xffff, 0x0000), NULL, NULL, &ablerex_subdriver
We found the krauler_subdriver have the same parameters as ablerex_subdriver
When the scanner for USB device, how to identify krauler_subdriver or ablerex_subdriver if I connected the UPS of Ablerex model?
It is right? Maybe I have misunderstood?
Please kindly give us comments on that.
Thank you for your help.

@jimklimov
Copy link
Member

jimklimov commented Nov 1, 2021

Hello. Given that the line in question at https://github.com/networkupstools/nut/blob/master/drivers/nutdrv_qx.c#L1460 has a comment that it is, for example, to handle "Ablerex 625L USB", I supposed that the new vendor-backed subdriver for the same/related device would be the replacement for the original one. At worst, users can select the subdriver explicitly in their ups.conf options.

Otherwise, the two commonly NULL columns in this table are for vendor and product identification strings matching -- see qx_is_usb_device_supported() at https://github.com/networkupstools/nut/blob/master/drivers/nutdrv_qx.c#L1481 which should allow different products using same USB interface chips to be supported with appropriate subdrivers.

ADDON NOTE: I think in some drivers I've also seen hooks for more thorough device interaction to make sure it is a supported one by the specific subdriver, or move on to a better match, but can't quickly point a finger so maybe it was not done in nutdrv_qx driver family yet. Maybe what I saw back then was just code to differentiate closely related devices supported altogether by the same subdriver.

On pedantic side, tell the HW people that this is exactly the situation why the USB Forum organization is there, to license vendor (and product) IDs, same as standard authorities for DNS names, IP addresses and ports, phone numbers or whatever, and why kidnapping bogus numbers like "0x0000" and "0xffff" (or any other "owned" by someone) is a cheap but bad idea interops-wise ;)

@Ablerexsoftware
Copy link
Contributor Author

Hi Sir,
Thank you for your comments and I agree.
"I supposed that the new vendor-backed subdriver for the same/related device would be the replacement for the original one."
We will modify the nutdrv_qx.c and replace krauler_subdriver with ablerex_subdriver.
as below
--------------------------------nutdrv_qx.c ---------------------------------------------
USB_DEVICE(0xffff, 0x0000), NULL, NULL, &krauler_subdriver
^^^^^^^^^^^^^^--> replace with ablerex_subdriver
also modify blazer_usb.c and replace krauler_subdriver with ablerex_subdriver.
--------------------------blazer_usb.c----------------------------------------------------
{ USB_DEVICE(0xffff, 0x0000), &krauler_subdriver }, /* Ablerex 625L USB */
^^^^^^^^^^^^^^^ -->replace with ablerex_subdriver
I think the ablerex_subdriver will provide more and whole function for the user.
Is it right?
Do you agree to the above modification?

@jimklimov
Copy link
Member

Regarding blazer_usb.c - no, with changes of this PR that driver wouldn't gain an ablerex_subdriver() to reference. I believe that was the focus of #979, shunned by community precisely because we develop the new Qx protocol support in the framework of nutdrv_qx driver which absorbed older separate ones (to be deleted after some releases).

@jimklimov
Copy link
Member

jimklimov commented Nov 2, 2021

As for nutdrv_qx replacing the wholesale support for vendor ffff product 0000 -- not sure. Grepping in sources of https://github.com/networkupstools/nut-ddl I see several hits of devices known to have been supported at some point, apparently by krauler_subdriver if none other responded to that VID/PID combination:

nut-ddl$ git grep -E '(ups.productid: 0000|ups.vendorid: ffff)'

Atlantis_Land/Atlantis_Land__OnePower_551_A03-P551_v1.2__blazer_usb__2.6.4__01.dev:ups.productid: 0000
Atlantis_Land/Atlantis_Land__OnePower_551_A03-P551_v1.2__blazer_usb__2.6.4__01.dev:ups.vendorid: ffff

IPAR/IPAR__Mini_Energy_ME_800__megatec_usb__2.6.0__01.dev:ups.productid: 0000
IPAR/IPAR__Mini_Energy_ME_800__megatec_usb__2.6.0__01.dev:ups.vendorid: ffff

Liebert/Liebert__PSA1500__blazer_usb__2.6.0__01.dev:ups.productid: 0000
Liebert/Liebert__PSA1500__blazer_usb__2.6.0__01.dev:ups.vendorid: ffff

UPSonic/UPSonic__IRT1000__blazer_usb__2.7.1__01.dev:ups.productid: 0000
UPSonic/UPSonic__IRT1000__blazer_usb__2.7.1__01.dev:ups.vendorid: ffff

Are you sure at least those would be well supported by the new subdriver? (Maybe yes, if someone is same OEM for all the brands)

If not, I would ask you to explore adding a line in that table in nutdrv_qx.c before the all-matching one with NULLs like this:

+	{ USB_DEVICE(0xffff, 0x0000),	"Ablerex",		NULL,			&ablerex_subdriver },
 	{ USB_DEVICE(0xffff, 0x0000),	NULL,		NULL,			&krauler_subdriver },

If your devices expose some other "iVendor" names in USB discovery, you can add more lines to match those.

As seen in https://github.com/networkupstools/nut/blob/master/drivers/nutdrv_qx.c#L1497 the comparison is done with strcasecmp() -- for case-insensitive but otherwise exactly matched strings.

@Ablerexsoftware
Copy link
Contributor Author

Hi sir,
I checked with our sales to confirm these UPS models that are our OEM Customer.
After checking our BOM list, the communication protocol of the firmware of those ups is following Ablerex standard. one of those UPS was the end of life due to Ablerex stopping to produce and sell, like UPSonic IRT1000.

;------------------------------------------------------------------------------
Atlantis_Land/Atlantis_Land__OnePower_551_A03-P551_v1.2__blazer_usb__2.6.4__01.dev:ups.productid: 0000
Atlantis_Land/Atlantis_Land__OnePower_551_A03-P551_v1.2__blazer_usb__2.6.4__01.dev:ups.vendorid: ffff

IPAR/IPAR__Mini_Energy_ME_800__megatec_usb__2.6.0__01.dev:ups.productid: 0000
IPAR/IPAR__Mini_Energy_ME_800__megatec_usb__2.6.0__01.dev:ups.vendorid: ffff

Liebert/Liebert__PSA1500__blazer_usb__2.6.0__01.dev:ups.productid: 0000
Liebert/Liebert__PSA1500__blazer_usb__2.6.0__01.dev:ups.vendorid: ffff

UPSonic/UPSonic__IRT1000__blazer_usb__2.7.1__01.dev:ups.productid: 0000
UPSonic/UPSonic__IRT1000__blazer_usb__2.7.1__01.dev:ups.vendorid: ffff
;------------------------------------------------------------------------------

I believe the internal firmware of UPS will be compatible with the currently existing(krauler_subdriver at 0xffff/0x0000) and even if change to new driver( ablerex_subdriver) will be compatible, too.
In the other hand, we have many OEM customers and use Ablerex usb chip that we coding like above UPS list, we still need the original PID/VID for our customers and provide more function on the USB. Our many OEM customers have their own "iProduct" and "iVendor". If we can not provide our USB function via the original recognition method, they can not get our new usb function directly on their stock UPS. That’s why we can not fixed the "iVendor" according to your suggestion.

@jimklimov
Copy link
Member

jimklimov commented Nov 16, 2021

In that case, I think this vid:pid can be reassigned to new subdriver by default; if some users' devices won't be handled well, their config files can request another. I'll mention that in release notes.

@Ablerexsoftware
Copy link
Contributor Author

@jimklimov According to our explanation for this PR, we need your support, so please kindly give us some comments.

@Ablerexsoftware
Copy link
Contributor Author

Ablerexsoftware commented Nov 16, 2021

@jimklimov
May I confirm with you again?
Because of I worry about a misunderstanding what you mean.
In this case we can add new subdriver and use the same VIDPID(0xFFFF/0x0000) at nutdrv_qx.c.
as below

;-----------------------------------------------------------------------------------------------------------------
Add--> { USB_DEVICE(0xffff, 0x0000), "NULL", NULL, &ablerex_subdriver },
Remove--> { USB_DEVICE(0xffff, 0x0000), NULL, NULL, &krauler_subdriver },

Is that right, please?

@clepple clepple removed their request for review November 16, 2021 11:29
@jimklimov
Copy link
Member

Sorry for the delay - Yes, in this case that seems to be the acceptable approach.

@jimklimov
Copy link
Member

jimklimov commented Nov 22, 2021

Note: there are several CI warnings, regarding libusb method argument types (they varied for different library generations) and some unused variables and methods:

[2021-11-17T07:07:36.445Z] /usr/lib/ccache/gcc-10 -DHAVE_CONFIG_H -I. -I../include   -I/srv/libvirt/abuild/jenkins-nut/workspace/nut_nut_PR-1135@3/tmp/include -I../include  -I/usr/include/neon   -I/usr/include/modbus -DQX_SERIAL -DQX_USB -I/srv/libvirt/abuild/jenkins-nut/workspace/nut_nut_PR-1135@3/tmp/include -std=gnu11 -m64 -Wall -Wextra -Wsign-compare -pedantic -Werror -MT nutdrv_qx-nutdrv_qx.o -MD -MP -MF .deps/nutdrv_qx-nutdrv_qx.Tpo -c -o nutdrv_qx-nutdrv_qx.o `test -f 'nutdrv_qx.c' || echo './'`nutdrv_qx.c
[2021-11-17T07:07:36.445Z] nutdrv_qx.c: In function 'ablerex_command':
[2021-11-17T07:07:36.445Z] nutdrv_qx.c:1417:53: error: passing argument 6 of 'usb_control_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
[2021-11-17T07:07:36.445Z]  1417 |   ret = usb_control_msg(udev, 0x21, 0x09, 0x305, 0, &tmp, 47, 1000);
[2021-11-17T07:07:36.445Z]       |                                                     ^~~~
[2021-11-17T07:07:36.445Z]       |                                                     |
[2021-11-17T07:07:36.445Z]       |                                                     char (*)[64]
[2021-11-17T07:07:36.445Z] In file included from usb-common.h:26,
[2021-11-17T07:07:36.445Z]                  from libusb.h:35,
[2021-11-17T07:07:36.445Z]                  from nutdrv_qx.c:47:
[2021-11-17T07:07:36.445Z] /usr/include/usb.h:313:30: note: expected 'char *' but argument is of type 'char (*)[64]'
[2021-11-17T07:07:36.445Z]   313 |  int value, int index, char *bytes, int size, int timeout);
[2021-11-17T07:07:36.445Z]       |                        ~~~~~~^~~~~
[2021-11-17T07:07:36.445Z] nutdrv_qx.c:1424:53: error: passing argument 6 of 'usb_control_msg' from incompatible pointer type [-Werror=incompatible-pointer-types]
[2021-11-17T07:07:36.445Z]  1424 |   ret = usb_control_msg(udev, 0xA1, 0x01, 0x305, 0, &tmpryy, 47, 1000);
[2021-11-17T07:07:36.445Z]       |                                                     ^~~~~~~
[2021-11-17T07:07:36.445Z]       |                                                     |
[2021-11-17T07:07:36.445Z]       |                                                     char (*)[64]
[2021-11-17T07:07:36.445Z] In file included from usb-common.h:26,
[2021-11-17T07:07:36.445Z]                  from libusb.h:35,
[2021-11-17T07:07:36.445Z]                  from nutdrv_qx.c:47:
[2021-11-17T07:07:36.445Z] /usr/include/usb.h:313:30: note: expected 'char *' but argument is of type 'char (*)[64]'
[2021-11-17T07:07:36.445Z]   313 |  int value, int index, char *bytes, int size, int timeout);
[2021-11-17T07:07:36.445Z]       |                        ~~~~~~^~~~~
[2021-11-17T07:07:36.445Z] nutdrv_qx.c:1396:6: error: unused variable 'i' [-Werror=unused-variable]
[2021-11-17T07:07:36.445Z]  1396 |  int i;
[2021-11-17T07:07:36.445Z]       |      ^
[2021-11-17T07:07:36.445Z] nutdrv_qx.c:1394:63: error: unused parameter 'buflen' [-Werror=unused-parameter]
[2021-11-17T07:07:36.445Z]  1394 | static int ablerex_command(const char *cmd, char *buf, size_t buflen)
[2021-11-17T07:07:36.445Z]       |                                                        ~~~~~~~^~~~~~
[2021-11-17T07:07:36.445Z] At top level:
[2021-11-17T07:07:36.445Z] nutdrv_qx.c:1551:14: error: 'ablerex_ext_subdriver' defined but not used [-Werror=unused-function]
[2021-11-17T07:07:36.445Z]  1551 | static void *ablerex_ext_subdriver(USBDevice_t *device)
[2021-11-17T07:07:36.445Z]       |              ^~~~~~~~~~~~~~~~~~~~~
[2021-11-17T07:07:36.445Z] cc1: all warnings being treated as errors
[2021-11-17T07:07:36.445Z] make[1]: *** [Makefile:1875: nutdrv_qx-nutdrv_qx.o] Error 1
[2021-11-17T07:07:36.704Z] make[1]: Target 'all' not remade because of errors.

Some of this is very similar to something rectified with libusb-1.0 and libusb-1.0+0.1 branches in recently processed PRs #479 and #1184 (e.g. char* vs unsigned char* buffers can be just cast), other items are unique to this new development. A few can benefit from NUT_UNUSED_*() macros or removing the unneeded items.

@Ablerexsoftware
Copy link
Contributor Author

We update the PR to modify the ci warning, replace Ablerex_subdriver and documents. Please kindly review.

@jimklimov
Copy link
Member

jimklimov commented Dec 21, 2021

Weird... Got this issue on some of the CI platforms:

[2021-12-21T09:21:47.623Z] nutdrv_qx.c:1665:2: error: initialization from incompatible pointer type [-Werror]
[2021-12-21T09:21:47.623Z]   { USB_DEVICE(0xffff, 0x0000), NULL,  NULL,   &ablerex_subdriver }, /* Ablerex 625L USB */
[2021-12-21T09:21:47.623Z]   ^
[2021-12-21T09:21:47.623Z] nutdrv_qx.c:1665:2: error: (near initialization for 'qx_usb_id[1].fun') [-Werror]

...but looking at it closer, I'd expect it to be all over the place.

It highlighted a naming deficiency in this driver, where something_subdriver in some contexts is a struct subdriver_t defined in the subdriver-specific source file - including the ablerex_subdriver; and in other cases same naming pattern applies to a method (defined usually right in the nutdrv_qx.c to activate the something_command() to handle the current run-time behavior of the driver daemon), and the pointer to such method is the field initializer for USB_DEVICE macro (and struct behind it).

One recent example that had both sorts of the name defined was fabula_hunnox_subdriver() and struct hunnox_subdriver.

Updating PR to introduce the ablerex_subdriver_fun() for this.

@jimklimov
Copy link
Member

Hooray! Looks good to me and passed the CI build matrix now.

Would you please be able to test the currently proposed codebase (refreshed from this PR source branch) against your devices, to make sure the fixes did not break actual hardware support?

@Ablerexsoftware
Copy link
Contributor Author

The below link drawing is for the new driver test result. Please Kindly check for us.
https://imgur.com/Wfjo5Sa
If we want to update the "driver.list.in". Can we re-push this file to this PR or need pull requests for new PR?
If this PR was approved by nut, Please kindly spend time to merge this PR into master.
I think this PR will replace the PR (” Add support for Ablerex Dk+ #979”). I suggest closing the #979. Do you agree?

@jimklimov
Copy link
Member

jimklimov commented Dec 29, 2021 via email

@Ablerexsoftware
Copy link
Contributor Author

I'm sorry for too late reply to your message. this PR(#1135) will support PR(#979). We update and post the UPS data of device-data dumps to https://github.com/networkupstools/nut-ddl.

@jimklimov
Copy link
Member

Updated with current improvements from master branch (including libusb-1.0 support and some bug fixes that remained for "fightwarn effort", so now default warnings level is higher). If the next builds pass CI farm okay, hoping to merge this soon.

Great thanks for the effort (large part of that sadly and unavoidably being the rituals needed to make this work well for everyone in the community).

@jimklimov
Copy link
Member

CI says (and review confirms) this PR needs some more changes to adjust to the upstream-master codebase evolution. In particular due to the libusb-1.0 support merge, the usb_strerror is no longer correct but nut_usb_strerror should now cover it for both API versions.

https://lgtm.com/projects/g/networkupstools/nut/logs/rev/pr-d6923ac181c1ffac41c0234b20ccc1a969269753/lang:cpp/stage:Build%20merge_214749fad50530fd8ca5bfd04bcf8e4a90cf0532

@jimklimov jimklimov merged commit 4443fb0 into networkupstools:master Jan 21, 2022
@jimklimov
Copy link
Member

Congratulations, this PR finally looks good to CI - no warnings, no conflicts (one agent went AWOL in last iteration, not your fault).
Merged, thanks for the great patience and nice contribution!

@Ablerexsoftware
Copy link
Contributor Author

Thanks for your guidance and help to make this PR can be merged smoothly.
In addition, how should we do if we want to add a new model in the
"Hardware compatibility list" of Network UPS Tools?

@jimklimov
Copy link
Member

jimklimov commented Jan 26, 2022 via email

@Ablerexsoftware
Copy link
Contributor Author

Thank you for kindly providing the information to us.
We have pulled the ddl files to nut-ddl repository for this PR before.
Does the website need to be refreshed by the Nut team or do we still pull the repository to refresh? Please kindly tell me which repository, if we need to pull the PR to refresh the website.

@jimklimov
Copy link
Member

jimklimov commented Jan 28, 2022 via email

@jimklimov
Copy link
Member

Website updates progressed last weekend, so the main https://networkupstools.org/ site should track master branches of NUT and DDL more closely (and the older "historic" releases published in sub-sites for reference of their users stuck with the older codebase).

The compatibility information from git should be up there now.

@Ablerexsoftware
Copy link
Contributor Author

Thank you for updating the information to us.
May I consult about the Nut package of Linux?
Does the nut package was updated to the latest(with the same master branches of git)? if we download and install it directly from Linux system(e.g. Ubuntu..)

@jimklimov
Copy link
Member

jimklimov commented Feb 14, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Qx protocol driver Driver based on Megatec Q<number> such as new nutdrv_qx, or obsoleted blazer and some others ready / code review Author (and CI) consider the PR worthy of human rewievers' time ready / gonna merge The PR is in final cycles leading to merge unless someone logs an objection before we hit the button
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants