aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/requirements.txt
Commit message (Collapse)AuthorAgeFilesLines
* Changed dependency files. Fixed a typo.Patrick Lehmann2021-07-021-6/+4
|
* Pin pyVHDLModel to v0.11.1.Patrick Lehmann2021-07-011-2/+2
|
* New command line interface for DOM.Patrick Lehmann2021-07-011-0/+3
|
* Minor changes.Patrick Lehmann2021-07-011-1/+1
|
* Added missing import.Patrick Lehmann2021-07-011-2/+2
|
* More DOM improvements (#1806)Patrick Lehmann2021-06-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * First try to handle names. * Reworked names. * Reworked range expressions. * Handle AttributeNames. * Added handling of file declaration and attribute declarations. * Improved error outputs. * Handle protected types. * Make black happy with ugly code. * Handle Null literal and File parameters. * File type and physical type. * Don't fail on reported syntax errors. Catch call errors into libghdl. * Improved Sanity checks for pyGHDL.dom. * Load sourcecode via Python and process in-memory. Fixed testcases. * Added package instantiations and packages with generics. * Added UseClause, AttributeSpecification and PhysicalTypes. * Improved pretty-printing. * Fixed AttributeName in subtype indication. * Get code position of IIR nodes. * Added DOMMixin into all derived classes. * Mark as not yet implemented. * Pinned pyVHDLModel version to v0.10.4. * Removed xfail in LSP test. Bumped requirement of pyVHDLModel to v0.10.4. Fixed some Codacy issues. (cherry picked from commit f64e7ed7c3d69cbf84cd60db8e9b085e90b846cb)
* Minor fixes and pinned pyVHDLModel version to v0.10.3.Patrick Lehmann2021-06-231-2/+2
|
* setup.py: get a zipfile instead of using gitumarcor2021-06-231-1/+1
| | | | (cherry picked from commit 541815223c0df0fb2cdd227d3ca9e5a82135dc28)
* Renamed AllVHDLSources to Sanity.Patrick Lehmann2021-06-221-1/+2
| | | | | Improved glob in Sanity check. Bound requirement for pyVHDLModel to Git branch.
* Incremented dependency to pyVHDLModel to v0.10.2.Patrick Lehmann2021-06-221-1/+1
|
* pyGHDL: pin pyVHDLModelumarcor2021-06-221-1/+1
|
* pyGHDL: bump pyVHDLModel to 0.10.1umarcor2021-06-191-1/+1
|
* Increment requirement pyVHDLModel to v0.10.0.Patrick Lehmann2021-06-171-1/+1
|
* Updates to the dom namespace in pyGHDL.Patrick Lehmann2021-06-171-1/+1
|
* pyGHDL: remove dependency on attrTristan Gingold2021-01-161-3/+0
|
* Added 'attrs' to the dependency list.Patrick Lehmann2021-01-051-0/+3
|
* Lowering required Python version to 3.7.Patrick Lehmann2020-12-291-1/+1
|
* Tiny improvements.Patrick Lehmann2020-12-281-0/+2
nos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; } .highlight .hll { background-color: #ffffcc } .highlight { background: #ffffff; } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2020, Google Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that 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.
 */

#include "programmer.h"
#include "spi.h"
#include "usb_device.h"

#include <assert.h>
#include <libusb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * Possibly extract a programmer parameter and use it to initialize the given
 * match value structure.
 */
static void usb_match_value_init(struct usb_match_value *match,
				 char const *parameter)
{
	char *string = extract_programmer_param(parameter);

	match->name = parameter;

	if (string) {
		match->set = 1;
		match->value = strtol(string, NULL, 0);
	} else {
		match->set = 0;
	}

	free(string);
}

#define USB_MATCH_VALUE_INIT(NAME)			\
	usb_match_value_init(&match->NAME, #NAME)

void usb_match_init(struct usb_match *match)
{
	USB_MATCH_VALUE_INIT(vid);
	USB_MATCH_VALUE_INIT(pid);
	USB_MATCH_VALUE_INIT(bus);
	USB_MATCH_VALUE_INIT(address);
	USB_MATCH_VALUE_INIT(config);
	USB_MATCH_VALUE_INIT(interface);
	USB_MATCH_VALUE_INIT(altsetting);
	USB_MATCH_VALUE_INIT(class);
	USB_MATCH_VALUE_INIT(subclass);
	USB_MATCH_VALUE_INIT(protocol);
}

void usb_match_value_default(struct usb_match_value *value,
			     long int default_value)
{
	if (value->set)
		return;

	value->set   = 1;
	value->value = default_value;
}

/*
 * Match the value against a possible user supplied parameter.
 *
 * Return:
 *     0: The user supplied the given parameter and it did not match the value.
 *     1: Either the user didn't supply the parameter, or they did and it
 *        matches the given value.
 */
static int check_match(struct usb_match_value const *match_value, int value)
{
	int reject = match_value->set && (match_value->value != value);

	if (reject)
		msg_pdbg("USB: Rejecting device because %s = %d != %d\n",
			 match_value->name,
			 value,
			 match_value->value);

	return !reject;
}

/*
 * Allocate a copy of device and add it to the head of the devices list.
 */
static void add_device(struct usb_device *device,
		       struct usb_device **devices)
{
	struct usb_device *copy = malloc(sizeof(struct usb_device));

	assert(copy != NULL);

	*copy = *device;

	copy->next = *devices;
	*devices = copy;

	libusb_ref_device(copy->device);
}

/*
 * Look through the interfaces of the current device config for a match. Stop
 * looking after the first valid match is found.
 *
 * Return:
 *     0: No matching interface was found.
 *     1: A complete match was found and added to the devices list.
 */
static int find_interface(struct usb_match const *match,
			  struct usb_device *current,
			  struct usb_device **devices)
{
	int i, j;

	for (i = 0; i < current->config_descriptor->bNumInterfaces; ++i) {
		struct libusb_interface const *interface;

		interface = &current->config_descriptor->interface[i];

		for (j = 0; j < interface->num_altsetting; ++j) {
			struct libusb_interface_descriptor const *descriptor;

			descriptor = &interface->altsetting[j];

			if (check_match(&match->interface,
					descriptor->bInterfaceNumber) &&
			    check_match(&match->altsetting,
					descriptor->bAlternateSetting) &&
			    check_match(&match->class,
					descriptor->bInterfaceClass) &&
			    check_match(&match->subclass,
					descriptor->bInterfaceSubClass) &&
			    check_match(&match->protocol,
					descriptor->bInterfaceProtocol)) {
				current->interface_descriptor = descriptor;
				add_device(current, devices);
				msg_pdbg("USB: Found matching device\n");
				return 1;
			}
		}
	}

	return 0;
}

/*
 * Look through the configs of the current device for a match.  Stop looking
 * after the first valid match is found.
 *
 * Return:
 *     0: All configurations successfully checked, one may have been added to
 *        the list.
 *     non-zero: There was a failure while checking for a match.
 */
static int find_config(struct usb_match const *match,
		       struct usb_device *current,
		       struct libusb_device_descriptor const *device_descriptor,
		       struct usb_device **devices)
{
	int i;

	for (i = 0; i < device_descriptor->bNumConfigurations; ++i) {
		int ret = LIBUSB(libusb_get_config_descriptor(
				current->device, i,
				&current->config_descriptor));
		if (ret != 0) {
			msg_perr("USB: Failed to get config descriptor");
			return ret;
		}

		if (check_match(&match->config,
				current->config_descriptor->
				bConfigurationValue) &&
		    find_interface(match, current, devices))
			break;

		libusb_free_config_descriptor(current->config_descriptor);
	}

	return 0;
}

int usb_device_find(struct usb_match const *match, struct usb_device **devices)
{
	libusb_device **list;
	ssize_t         count;
	ssize_t         i;

	*devices = NULL;

	int ret = LIBUSB(count = libusb_get_device_list(NULL, &list));
	if (ret != 0) {
		msg_perr("USB: Failed to get device list");
		return ret;
	}

	for (i = 0; i < count; ++i) {
		struct libusb_device_descriptor descriptor;
		struct usb_device               current = {
			.device = list[i],
			.handle = NULL,
			.next   = NULL,
		};

		uint8_t bus     = libusb_get_bus_number(list[i]);
		uint8_t address = libusb_get_device_address(list[i]);

		msg_pdbg("USB: Inspecting device (Bus %d, Address %d)\n",
			 bus,
			 address);

		ret = LIBUSB(libusb_get_device_descriptor(list[i],
							  &descriptor));
		      if (ret != 0) {
			      msg_perr("USB: Failed to get device descriptor");
			      free(*devices);
			      *devices = NULL;
			      return ret;
		      }

		if (check_match(&match->vid,     descriptor.idVendor) &&
		    check_match(&match->pid,     descriptor.idProduct) &&
		    check_match(&match->bus,     bus) &&
		    check_match(&match->address, address)) {
			ret = find_config(match,
					  &current,
					  &descriptor,
					  devices);
			if (ret != 0) {
				msg_perr("USB: Failed to find config");
				return ret;
			}
		}
	}

	libusb_free_device_list(list, 1);

	return (*devices == NULL);
}

/*
 * If the underlying libusb device is not open, open it.
 *
 * Return:
 *     0: The device was already open or was successfully opened.
 *     non-zero: There was a failure while opening the device.
 */
static int usb_device_open(struct usb_device *device)
{
	if (device->handle == NULL) {
		int ret = LIBUSB(libusb_open(device->device, &device->handle));
		if (ret != 0) {
			msg_perr("USB: Failed to open device\n");
			return ret;
		}
	}

	return 0;
}

int usb_device_show(char const *prefix, struct usb_device *device)
{
	struct libusb_device_descriptor descriptor;
	unsigned char                   product[256];
	int ret;

	ret = usb_device_open(device);
	if (ret != 0) {
	       msg_perr("USB: Failed to open device\n");
	       return ret;
	}

	ret = LIBUSB(libusb_get_device_descriptor(device->device, &descriptor));
	if (ret != 0) {
		msg_perr("USB: Failed to get device descriptor\n");
		return ret;
	}

	ret = LIBUSB(libusb_get_string_descriptor_ascii(
			     device->handle,
			     descriptor.iProduct,
			     product,
			     sizeof(product)));
	if (ret != 0) {
		msg_perr("USB: Failed to get device product string\n");
		return ret;
	}

	product[255] = '\0';

	msg_perr("%sbus=0x%02x,address=0x%02x | %s\n",
		 prefix,
		 libusb_get_bus_number(device->device),
		 libusb_get_device_address(device->device),
		 product);

	return 0;
}

int usb_device_claim(struct usb_device *device)
{
	int current_config;

	int ret = usb_device_open(device);
	if (ret != 0) {
		msg_perr("USB: Failed to open device\n");
		return ret;
	}

	ret = LIBUSB(libusb_get_configuration(device->handle,
					      &current_config));
	if (ret != 0) {
		msg_perr("USB: Failed to get current device configuration\n");
		return ret;
	}

	if (current_config != device->config_descriptor->bConfigurationValue) {
		ret = LIBUSB(libusb_set_configuration(
				     device->handle,
				     device->
				     config_descriptor->
				     bConfigurationValue));
		if (ret != 0) {
			msg_perr("USB: Failed to set new configuration from %d to %d\n",
					current_config,
					device->config_descriptor->bConfigurationValue);
			return ret;
		}
	}

	ret = LIBUSB(libusb_set_auto_detach_kernel_driver(device->handle, 1));
	if (ret != 0) {
		msg_perr("USB: Failed to enable auto kernel driver detach\n");
		return ret;
	}

	ret = LIBUSB(libusb_claim_interface(device->handle,
					    device->
					    interface_descriptor->
					    bInterfaceNumber));
	if (ret != 0) {
		msg_perr("USB: Could not claim device interface %d\n",
				device->interface_descriptor->bInterfaceNumber);
		return ret;
	}

	if (device->interface_descriptor->bAlternateSetting != 0) {
		ret = LIBUSB(libusb_set_interface_alt_setting(
				     device->handle,
				     device->
				     interface_descriptor->
				     bInterfaceNumber,
				     device->
				     interface_descriptor->
				     bAlternateSetting));
		if (ret != 0) {
			msg_perr("USB: Failed to set alternate setting %d\n",
					device->interface_descriptor->bAlternateSetting);
			return ret;
		}
	}

	return 0;
}

struct usb_device *usb_device_free(struct usb_device *device)
{
	struct usb_device *next = device->next;

	if (device->handle != NULL)
		libusb_close(device->handle);

	/*
	 * This unref balances the ref added in the add_device function.
	 */
	libusb_unref_device(device->device);
	libusb_free_config_descriptor(device->config_descriptor);

	free(device);

	return next;
}