示例#1
0
static int
efinet_dev_print(int verbose)
{
	CHAR16 *text;
	EFI_HANDLE h;
	int unit, ret = 0;

	printf("%s devices:", efinet_dev.dv_name);
	if ((ret = pager_output("\n")) != 0)
		return (ret);

	for (unit = 0, h = efi_find_handle(&efinet_dev, 0);
	    h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) {
		printf("    %s%d:", efinet_dev.dv_name, unit);
		if (verbose) {
			text = efi_devpath_name(efi_lookup_devpath(h));
			if (text != NULL) {
				printf("    %S", text);
				efi_free_devpath_name(text);
			}
		}
		if ((ret = pager_output("\n")) != 0)
			break;
	}
	return (ret);
}
示例#2
0
static int
find_currdev(EFI_LOADED_IMAGE *img, struct devsw **dev, int *unit,
    uint64_t *extra)
{
	EFI_DEVICE_PATH *devpath, *copy;
	EFI_HANDLE h;

	/*
	 * Try the device handle from our loaded image first.  If that
	 * fails, use the device path from the loaded image and see if
	 * any of the nodes in that path match one of the enumerated
	 * handles.
	 */
	if (efi_handle_lookup(img->DeviceHandle, dev, unit, extra) == 0)
		return (0);

	copy = NULL;
	devpath = efi_lookup_image_devpath(IH);
	while (devpath != NULL) {
		h = efi_devpath_handle(devpath);
		if (h == NULL)
			break;

		if (efi_handle_lookup(h, dev, unit, extra) == 0) {
			if (copy != NULL)
				free(copy);
			return (0);
		}

		if (copy != NULL)
			free(copy);
		devpath = efi_lookup_devpath(h);
		if (devpath != NULL) {
			copy = efi_devpath_trim(devpath);
			devpath = copy;
		}
	}

	/* Try to fallback on first device */
	if (devsw[0] != NULL) {
		*dev = devsw[0];
		return (0);
	}
	return (ENOENT);
}
示例#3
0
文件: efinet.c 项目: 2asoft/freebsd
static void
efinet_dev_print(int verbose)
{
	CHAR16 *text;
	EFI_HANDLE h;
	int unit;

	pager_open();
	for (unit = 0, h = efi_find_handle(&efinet_dev, 0);
	    h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) {
		printf("    %s%d:", efinet_dev.dv_name, unit);
		text = efi_devpath_name(efi_lookup_devpath(h));
		if (text != NULL) {
			printf("    %S", text);
			efi_free_devpath_name(text);
		}
		if (pager_output("\n"))
			break;
	}
	pager_close();
}
示例#4
0
static int
efipart_init(void) 
{
	EFI_BLOCK_IO *blkio;
	EFI_DEVICE_PATH *devpath, *devpathcpy, *tmpdevpath, *node;
	EFI_HANDLE *hin, *hout, *aliases, handle;
	EFI_STATUS status;
	UINTN sz;
	u_int n, nin, nout, nrdisk;
	int err;

	sz = 0;
	hin = NULL;
	status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, 0);
	if (status == EFI_BUFFER_TOO_SMALL) {
		hin = (EFI_HANDLE *)malloc(sz * 3);
		status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz,
		    hin);
		if (EFI_ERROR(status))
			free(hin);
	}
	if (EFI_ERROR(status))
		return (efi_status_to_errno(status));

	/* Filter handles to only include FreeBSD partitions. */
	nin = sz / sizeof(EFI_HANDLE);
	hout = hin + nin;
	aliases = hout + nin;
	nout = 0;
	nrdisk = 0;

	bzero(aliases, nin * sizeof(EFI_HANDLE));
	pdinfo = malloc(nin * sizeof(*pdinfo));
	if (pdinfo == NULL)
		return (ENOMEM);

	for (n = 0; n < nin; n++) {
		devpath = efi_lookup_devpath(hin[n]);
		if (devpath == NULL) {
			continue;
		}

		status = BS->HandleProtocol(hin[n], &blkio_guid,
		    (void**)&blkio);
		if (EFI_ERROR(status))
			continue;
		if (!blkio->Media->LogicalPartition) {
			nrdisk++;
			continue;
		}

		/*
		 * If we come across a logical partition of subtype CDROM
		 * it doesn't refer to the CD filesystem itself, but rather
		 * to any usable El Torito boot image on it. In this case
		 * we try to find the parent device and add that instead as
		 * that will be the CD filesystem.
		 */
		node = efi_devpath_last_node(devpath);
		if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
		    DevicePathSubType(node) == MEDIA_CDROM_DP) {
			devpathcpy = efi_devpath_trim(devpath);
			tmpdevpath = devpathcpy;
			status = BS->LocateDevicePath(&blkio_guid, &tmpdevpath,
			    &handle);
			free(devpathcpy);
			if (EFI_ERROR(status))
				continue;
			hout[nout] = handle;
			aliases[nout] = hin[n];
		} else
			hout[nout] = hin[n];
		nout++;
		pdinfo[npdinfo].pd_open = 0;
		pdinfo[npdinfo].pd_bcache = NULL;
		pdinfo[npdinfo].pd_unit = npdinfo;
		npdinfo++;
	}

	bcache_add_dev(npdinfo);
	err = efi_register_handles(&efipart_dev, hout, aliases, nout);
	free(hin);

	if (nout == 0 && nrdisk > 0)
		printf("Found %d disk(s) but no logical partition\n", nrdisk);
	return (err);
}
示例#5
0
static int
efinet_dev_init()
{
	struct netif_dif *dif;
	struct netif_stats *stats;
	EFI_DEVICE_PATH *devpath, *node;
	EFI_SIMPLE_NETWORK *net;
	EFI_HANDLE *handles, *handles2;
	EFI_STATUS status;
	UINTN sz;
	int err, i, nifs;
	extern struct devsw netdev;

	sz = 0;
	handles = NULL;
	status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL);
	if (status == EFI_BUFFER_TOO_SMALL) {
		handles = (EFI_HANDLE *)malloc(sz);
		status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz,
		    handles);
		if (EFI_ERROR(status))
			free(handles);
	}
	if (EFI_ERROR(status))
		return (efi_status_to_errno(status));
	handles2 = (EFI_HANDLE *)malloc(sz);
	if (handles2 == NULL) {
		free(handles);
		return (ENOMEM);
	}
	nifs = 0;
	for (i = 0; i < sz / sizeof(EFI_HANDLE); i++) {
		devpath = efi_lookup_devpath(handles[i]);
		if (devpath == NULL)
			continue;
		if ((node = efi_devpath_last_node(devpath)) == NULL)
			continue;

		if (DevicePathType(node) != MESSAGING_DEVICE_PATH ||
		    DevicePathSubType(node) != MSG_MAC_ADDR_DP)
			continue;

		/*
		 * Open the network device in exclusive mode. Without this
		 * we will be racing with the UEFI network stack. It will
		 * pull packets off the network leading to lost packets.
		 */
		status = BS->OpenProtocol(handles[i], &sn_guid, (void **)&net,
		    IH, NULL, EFI_OPEN_PROTOCOL_EXCLUSIVE);
		if (status != EFI_SUCCESS) {
			printf("Unable to open network interface %d for "
			    "exclusive access: %lu\n", i,
			    EFI_ERROR_CODE(status));
		}

		handles2[nifs] = handles[i];
		nifs++;
	}
	free(handles);
	if (nifs == 0) {
		err = ENOENT;
		goto done;
	}

	err = efi_register_handles(&efinet_dev, handles2, NULL, nifs);
	if (err != 0)
		goto done;

	efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));
	stats = calloc(nifs, sizeof(struct netif_stats));
	if (efinetif.netif_ifs == NULL || stats == NULL) {
		free(efinetif.netif_ifs);
		free(stats);
		efinetif.netif_ifs = NULL;
		err = ENOMEM;
		goto done;
	}
	efinetif.netif_nifs = nifs;

	for (i = 0; i < nifs; i++) {

		dif = &efinetif.netif_ifs[i];
		dif->dif_unit = i;
		dif->dif_nsel = 1;
		dif->dif_stats = &stats[i];
		dif->dif_private = handles2[i];
	}

	efinet_dev.dv_open = netdev.dv_open;
	efinet_dev.dv_close = netdev.dv_close;
	efinet_dev.dv_strategy = netdev.dv_strategy;

done:
	free(handles2);
	return (err);
}