示例#1
0
static int
efipart_init(void) 
{
	EFI_BLOCK_IO *blkio;
	EFI_HANDLE *hin, *hout;
	EFI_STATUS status;
	UINTN sz;
	u_int n, nin, nout;
	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 * 2);
		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;
	nout = 0;

	for (n = 0; n < nin; n++) {
		status = BS->HandleProtocol(hin[n], &blkio_guid, &blkio);
		if (EFI_ERROR(status))
			continue;
		if (!blkio->Media->LogicalPartition)
			continue;
		hout[nout] = hin[n];
		nout++;
	}

	err = efi_register_handles(&efipart_dev, hout, nout);
	free(hin);
	return (err);
}
示例#2
0
static int
efifs_dev_init(void) 
{
	EFI_HANDLE *handles;
	EFI_STATUS status;
	UINTN sz;
	int err;

	sz = 0;
	status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz, 0);
	if (status == EFI_BUFFER_TOO_SMALL) {
		handles = (EFI_HANDLE *)malloc(sz);
		status = BS->LocateHandle(ByProtocol, &sfs_guid, 0, &sz,
		    handles);
		if (EFI_ERROR(status))
			free(handles);
	}
	if (EFI_ERROR(status))
		return (efi_status_to_errno(status));
	err = efi_register_handles(&efifs_dev, handles,
	    sz / sizeof(EFI_HANDLE));
	free(handles);
	return (err);
}
示例#3
0
static int
efinet_dev_init(void)
{
	struct netif_dif *dif;
	struct netif_stats *stats;
	EFI_HANDLE *handles;
	EFI_STATUS status;
	UINTN sz;
	int err, i, nifs;

	sz = 0;
	handles = NULL;
	status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz, 0);
	if (status == EFI_BUFFER_TOO_SMALL) {
		handles = (EFI_HANDLE *)malloc(sz);
		status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz,
		    handles);
		if (EFI_ERROR(status))
			free(handles);
	}
	if (EFI_ERROR(status))
		return (efi_status_to_errno(status));
	nifs = sz / sizeof(EFI_HANDLE);
	err = efi_register_handles(&efinet_dev, handles, NULL, nifs);
	free(handles);
	if (err != 0)
		return (err);

	efinetif.netif_nifs = nifs;
	efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));

	stats = calloc(nifs, sizeof(struct netif_stats));

	for (i = 0; i < nifs; i++) {
		EFI_SIMPLE_NETWORK *net;
		EFI_HANDLE h;

		dif = &efinetif.netif_ifs[i];
		dif->dif_unit = -1;

		h = efi_find_handle(&efinet_dev, i);

		/*
		 * 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(h, &sn_guid, (void **)&net,
		    IH, 0, EFI_OPEN_PROTOCOL_EXCLUSIVE);
		if (status != EFI_SUCCESS) {
			printf("Unable to open network interface %d for "
			    "exclusive access\n", i);
		}

		dif->dif_unit = i;
		dif->dif_nsel = 1;
		dif->dif_stats = &stats[i];
		dif->dif_private = h;
	}

	return (0);
}
示例#4
0
文件: efipart.c 项目: jp629/freebsd
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;
	int err;
	size_t devpathlen;

	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;

	bzero(aliases, nin * sizeof(EFI_HANDLE));

	for (n = 0; n < nin; n++) {
		status = BS->HandleProtocol(hin[n], &devpath_guid,
		    (void **)&devpath);
		if (EFI_ERROR(status)) {
			continue;
		}

		node = devpath;
		devpathlen = DevicePathNodeLength(node);
		while (!IsDevicePathEnd(NextDevicePathNode(node))) {
			node = NextDevicePathNode(node);
			devpathlen += DevicePathNodeLength(node);
		}
		devpathlen += DevicePathNodeLength(NextDevicePathNode(node));

		status = BS->HandleProtocol(hin[n], &blkio_guid,
		    (void**)&blkio);
		if (EFI_ERROR(status))
			continue;
		if (!blkio->Media->LogicalPartition)
			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.
		 */
		if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
		    DevicePathSubType(node) == MEDIA_CDROM_DP) {
			devpathcpy = malloc(devpathlen);
			memcpy(devpathcpy, devpath, devpathlen);
			node = devpathcpy;
			while (!IsDevicePathEnd(NextDevicePathNode(node)))
				node = NextDevicePathNode(node);
			SetDevicePathEndNode(node);
			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++;
	}

	err = efi_register_handles(&efipart_dev, hout, aliases, nout);
	free(hin);
	return (err);
}
示例#5
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);
}
示例#6
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);
}