pci_parse_slot(char *opt)
{
	struct businfo *bi;
	struct slotinfo *si;
	char *emul, *config, *str, *cp, *b = NULL;
	int error, bnum, snum, fnum;

	error = -1;
	str = strdup(opt);
	if (!str) {
		fprintf(stderr, "%s: strdup returns NULL\n", __func__);
		return -1;
	}

	emul = config = NULL;
	cp = str;
	str = strsep(&cp, ",");
	if (cp) {
		emul = strsep(&cp, ",");
		/* for boot device */
		if (cp && *cp == 'b' && *(cp+1) == ',')
			b = strsep(&cp, ",");
		config = cp;
	} else {
		pci_parse_slot_usage(opt);
		goto done;
	}

	/* <bus>:<slot>:<func> */
	if (parse_bdf(str, &bnum, &snum, &fnum, 10) != 0)
		snum = -1;

	if (bnum < 0 || bnum >= MAXBUSES || snum < 0 || snum >= MAXSLOTS ||
	    fnum < 0 || fnum >= MAXFUNCS) {
		pci_parse_slot_usage(opt);
		goto done;
	}

	if (pci_businfo[bnum] == NULL)
		pci_businfo[bnum] = calloc(1, sizeof(struct businfo));

	bi = pci_businfo[bnum];
	si = &bi->slotinfo[snum];

	if (si->si_funcs[fnum].fi_name != NULL) {
		fprintf(stderr, "pci slot %d:%d already occupied!\n",
			snum, fnum);
		goto done;
	}

	if (pci_emul_finddev(emul) == NULL) {
		fprintf(stderr, "pci slot %d:%d: unknown device \"%s\"\n",
			snum, fnum, emul);
		goto done;
	}

	error = 0;
	si->si_funcs[fnum].fi_name = emul;
	/* saved fi param in case reboot */
	si->si_funcs[fnum].fi_param_saved = config;

	if (b != NULL) {
		if ((strcmp("virtio-blk", emul) == 0) &&  (b != NULL) &&
			(strchr(b, 'b') != NULL)) {
			vsbl_set_bdf(bnum, snum, fnum);
		}
	}
done:
	if (error)
		free(str);

	return error;
}
pci_parse_slot(char *opt)
{
	struct businfo *bi;
	struct slotinfo *si;
	char *emul, *config, *str, *cp, *b = NULL;
	int error, bnum, snum, fnum;

	error = -1;
	str = strdup(opt);
	if (!str) {
		fprintf(stderr, "%s: strdup returns NULL\n", __func__);
		return -1;
	}

	emul = config = NULL;
	cp = str;
	str = strsep(&cp, ",");
	if (cp) {
		emul = strsep(&cp, ",");
		 
		if (cp && *cp == 'b' && *(cp+1) == ',')
			b = strsep(&cp, ",");
		config = cp;
	} else {
		pci_parse_slot_usage(opt);
		goto done;
	}

	 
	if (parse_bdf(str, &bnum, &snum, &fnum, 10) != 0)
		snum = -1;

	if (bnum < 0 || bnum >= MAXBUSES || snum < 0 || snum >= MAXSLOTS ||
	    fnum < 0 || fnum >= MAXFUNCS) {
		pci_parse_slot_usage(opt);
		goto done;
	}

	if (pci_businfo[bnum] == NULL)
		pci_businfo[bnum] = calloc(1, sizeof(struct businfo));

	bi = pci_businfo[bnum];
	si = &bi->slotinfo[snum];

	if (si->si_funcs[fnum].fi_name != NULL) {
		fprintf(stderr, "pci slot %d:%d already occupied!\n",
			snum, fnum);
		goto done;
	}

	if (pci_emul_finddev(emul) == NULL) {
		fprintf(stderr, "pci slot %d:%d: unknown device \"%s\"\n",
			snum, fnum, emul);
		goto done;
	}

	error = 0;
	si->si_funcs[fnum].fi_name = emul;
	 
	si->si_funcs[fnum].fi_param_saved = config;

	if (b != NULL) {
		if ((strcmp("virtio-blk", emul) == 0) &&  (b != NULL) &&
			(strchr(b, 'b') != NULL)) {
			vsbl_set_bdf(bnum, snum, fnum);
		}
	}
done:
	if (error)
		free(str);

	return error;
}