Exemple #1
0
/*    
 * Quiz the BIOS for disk devices, save a little info about them.
 */
static int
bd_init(void) 
{
    int		base, unit;
    int		da_drive=0, n=-0x10;

    /* sequence 0x90, 0x80, 0xa0 */
    for (base = 0x90; base <= 0xa0; base += n, n += 0x30) {
	for (unit = base; (nbdinfo < MAXBDDEV) || ((unit & 0x0f) < 4); unit++) {
	    bdinfo[nbdinfo].bd_open = 0;
	    bdinfo[nbdinfo].bd_bcache = NULL;
	    bdinfo[nbdinfo].bd_unit = unit;
	    bdinfo[nbdinfo].bd_flags = (unit & 0xf0) == 0x90 ? BD_FLOPPY : 0;

	    if (!bd_int13probe(&bdinfo[nbdinfo])){
		if (((unit & 0xf0) == 0x90 && (unit & 0x0f) < 4) ||
		    ((unit & 0xf0) == 0xa0 && (unit & 0x0f) < 6))
		    continue;	/* Target IDs are not contiguous. */
		else
		    break;
	    }

	    if (bdinfo[nbdinfo].bd_flags & BD_FLOPPY){
		/* available 1.44MB access? */
		if (*(u_char *)PTOV(0xA15AE) & (1<<(unit & 0xf))) {
		    /* boot media 1.2MB FD? */
		    if ((*(u_char *)PTOV(0xA1584) & 0xf0) != 0x90)
		        bdinfo[nbdinfo].bd_unit = 0x30 + (unit & 0xf);
		}
	    }
	    else {
		if ((unit & 0xF0) == 0xA0)	/* SCSI HD or MO */
		    bdinfo[nbdinfo].bd_da_unit = da_drive++;
	    }
	    /* XXX we need "disk aliases" to make this simpler */
	    printf("BIOS drive %c: is disk%d\n", 
		   'A' + nbdinfo, nbdinfo);
	    nbdinfo++;
	}
    }
    bcache_add_dev(nbdinfo);
    return(0);
}
Exemple #2
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;
	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 illumos partitions. */
	nin = sz / sizeof(EFI_HANDLE);
	hout = hin + nin;
	aliases = hout + nin;
	nout = 0;

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

	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++;
		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);
	return (err);
}