Exemplo n.º 1
0
static int parse_filter(int argc, char **argv, int i, struct pci_filter *filter)
{
  char *c = argv[i++];
  char *d;

  if (!c[1] || !strchr("sd", c[1]))
    parse_err("Invalid option -%c", c[1]);
  if (c[2])
    d = (c[2] == '=') ? c+3 : c+2;
  else if (i < argc)
    d = argv[i++];
  else
    parse_err("Option -%c requires an argument", c[1]);
  switch (c[1])
    {
    case 's':
      if (d = pci_filter_parse_slot(filter, d))
	parse_err("Unable to parse filter -s %s", d);
      break;
    case 'd':
      if (d = pci_filter_parse_id(filter, d))
	parse_err("Unable to parse filter -d %s", d);
      break;
    default:
      parse_err("Unknown filter option -%c", c[1]);
    }

  return i;
}
static struct pci_dev *
create_pci_dev(struct pci_access * pci, char * slot)
{
    struct pci_filter filter;
    pci_filter_init(pci, &filter);
    if (pci_filter_parse_slot(&filter, slot))
    {
        fprintf(stderr, "Failed to parse device id %s\n", slot);
        goto pci_filter_parse_failed;
    }

    pci_init(pci);

    struct pci_dev * dev = pci_get_dev(pci,
                                       filter.domain,
                                       filter.bus,
                                       filter.slot,
                                       filter.func);
    if (! dev)
    {
        fprintf(stderr, "Failed to allocate dev\n");
        goto pci_get_dev_failed;
    }

    pci_fill_info(dev, PCI_FILL_IDENT);

    return dev;

pci_get_dev_failed:
pci_filter_parse_failed:
    return NULL;
}
Exemplo n.º 3
0
/* pcidev_init gets an array of allowed PCI device IDs and returns a pointer to struct pci_dev iff exactly one
 * match was found. If the "pci=bb:dd.f" programmer parameter was specified, a match is only considered if it
 * also matches the specified bus:device.function.
 * For convenience, this function also registers its own undo handlers.
 */
struct pci_dev *pcidev_init(const struct dev_entry *devs, int bar)
{
	struct pci_dev *dev;
	struct pci_dev *found_dev = NULL;
	struct pci_filter filter;
	char *pcidev_bdf;
	char *msg = NULL;
	int found = 0;
	int i;
	uintptr_t addr = 0;

	if (pci_init_common() != 0)
		return NULL;
	pci_filter_init(pacc, &filter);

	/* Filter by bb:dd.f (if supplied by the user). */
	pcidev_bdf = extract_programmer_param("pci");
	if (pcidev_bdf != NULL) {
		if ((msg = pci_filter_parse_slot(&filter, pcidev_bdf))) {
			msg_perr("Error: %s\n", msg);
			return NULL;
		}
	}
	free(pcidev_bdf);

	for (dev = pacc->devices; dev; dev = dev->next) {
		if (pci_filter_match(&filter, dev)) {
			/* Check against list of supported devices. */
			for (i = 0; devs[i].device_name != NULL; i++)
				if ((dev->vendor_id == devs[i].vendor_id) &&
				    (dev->device_id == devs[i].device_id))
					break;
			/* Not supported, try the next one. */
			if (devs[i].device_name == NULL)
				continue;

			msg_pdbg("Found \"%s %s\" (%04x:%04x, BDF %02x:%02x.%x).\n", devs[i].vendor_name,
				 devs[i].device_name, dev->vendor_id, dev->device_id, dev->bus, dev->dev,
				 dev->func);
			if (devs[i].status == NT)
				msg_pinfo("===\nThis PCI device is UNTESTED. Please report the 'flashrom -p "
					  "xxxx' output \n"
					  "to [email protected] if it works for you. Please add the name "
					  "of your\n"
					  "PCI device to the subject. Thank you for your help!\n===\n");

			/* FIXME: We should count all matching devices, not
			 * just those with a valid BAR.
			 */
			if ((addr = pcidev_readbar(dev, bar)) != 0) {
				found_dev = dev;
				found++;
			}
		}
	}

	/* Only continue if exactly one supported PCI dev has been found. */
	if (found == 0) {
		msg_perr("Error: No supported PCI device found.\n");
		return NULL;
	} else if (found > 1) {
		msg_perr("Error: Multiple supported PCI devices found. Use 'flashrom -p xxxx:pci=bb:dd.f' \n"
			 "to explicitly select the card with the given BDF (PCI bus, device, function).\n");
		return NULL;
	}

	return found_dev;
}
Exemplo n.º 4
0
int main (int argc, char *argv[])
{
	struct pci_access *pacc;
	struct pci_dev *dev;
	struct pci_filter filter;
	char *msg;
	uint16_t command;
	int v1_1 = 0, i2c;

	if (argc != 2 &&
	    ((argc != 3) ||
	     (!(v1_1 = !strcmp(argv[2], "1.1")) && strcmp(argv[2], "1.0")))) {
		fprintf(stderr,
			"VT6307 OHCI mode config\n"
			"Version 0.9\n"
			"Copyright (C) 2007 Krzysztof Halasa <*****@*****.**>\n"
			"\n"
			"Usage: vt6307ohciver <pci_device> [ 1.0 | 1.1 ]\n");
		exit(1);
	}

	if (iopl(3)) {
		fprintf(stderr, "iopl() failed (must be root)\n");
		exit(1);
	}

	pacc = pci_alloc();
	pci_filter_init(pacc, &filter);
	if ((msg = pci_filter_parse_slot(&filter, argv[1]))) {
		fprintf(stderr, "Invalid pci_device\n");
		exit(1);
	}

	filter.vendor = VENDOR_ID;
	filter.device = DEVICE_ID;

	pci_init(pacc);
	pci_scan_bus(pacc);

	for (dev = pacc->devices; dev; dev = dev->next)
		if (pci_filter_match(&filter, dev))
			break;

	if (!dev) {
		fprintf(stderr, "Device %s not found\n", argv[2]);
		exit(1);
	}

	pci_fill_info(dev, PCI_FILL_BASES | PCI_FILL_SIZES);

	if (dev->size[0] != MEM_SIZE || dev->size[1] != IO_SIZE) {
		fprintf(stderr, "Unexpected MEM/IO region size, is it"
			" VT6307 chip?\n");
		exit(1);
	}

	command = pci_read_word(dev, PCI_COMMAND);

	if ((command & PCI_COMMAND_IO) == 0) {
		fprintf(stderr, "Device disabled, trying to enable it\n");
		pci_write_word(dev, PCI_COMMAND, command | PCI_COMMAND_IO);
	}

	io_ports = dev->base_addr[1] & PCI_BASE_ADDRESS_IO_MASK;

	i2c = (inl(io_ports + 0x20) & 0x80) ? 0 : 1;

	fprintf(stderr, "I/O region #1 is at %04X\n", io_ports);
	fprintf(stderr, "It seems your VT6307 chip is connected to %s "
		"EEPROM\n", i2c ? "I^2C (24c01 or similar)" : "93c46");

	if (argc == 3) {
		/* enable direct access to pins */
		outl_p(inl(io_ports) | 0x80, io_ports);
		if (i2c)
			write_i2c(0x22, v1_1 ? 8 : 0);
		else
			write_4w(0x11, v1_1 ? 8 : 0);
		/* disable direct access to pins */
		outl_p(0x20, io_ports + 0x20);
		fprintf(stderr, "Please reboot\n");
	} else
		display(dev->base_addr[0] & PCI_BASE_ADDRESS_MEM_MASK);

	if ((command & PCI_COMMAND_IO) == 0) {
		fprintf(stderr, "Disabling device\n");
		pci_write_word(dev, PCI_COMMAND, command);
	}

	exit(0);
}