Example #1
0
void
OF_init(int (*openfirm)(void *))
{
	phandle_t options;
	char	  mode[sizeof("true")];

	openfirmware = openfirm;

	if ((chosen = OF_finddevice("/chosen")) == -1)
		OF_exit();
	if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1) {
		memory = OF_open("/memory");
		if (memory == -1)
			memory = OF_open("/memory@0");
		if (memory == -1)
			OF_exit();
	}
	if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1)
		OF_exit();

	/*
	 * Check if we run in real mode. If so, we do not need to map
	 * memory later on.
	 */
	options = OF_finddevice("/options");
	if (OF_getprop(options, "real-mode?", mode, sizeof(mode)) > 0 &&
	    strcmp(mode, "true") == 0)
		real_mode = 1;
}
Example #2
0
static int
ofwd_strategy(void *devdata, int flag __unused, daddr_t dblk, size_t size,
    char *buf, size_t *rsize)
{
	struct ofw_devdesc *dp = (struct ofw_devdesc *)devdata;
	daddr_t pos;
	int n;

	if (dp != kdp) {
		if (kdp != NULL) {
#if !defined(__powerpc__)
			OF_close(kdp->d_handle);
#endif
			kdp = NULL;
		}
		if ((dp->d_handle = OF_open(dp->d_path)) == -1)
			return (ENOENT);
		kdp = dp;
	}

	pos = dblk * 512;
	do {
		if (OF_seek(dp->d_handle, pos) < 0)
			return (EIO);
		n = OF_read(dp->d_handle, buf, size);
		if (n < 0 && n != -2)
			return (EIO);
	} while (n == -2);
	*rsize = size;
	return (0);
}
Example #3
0
vt_efb_initialize(struct fb_info *info)
#endif
{
#ifdef	FDT
	char name[64];
	cell_t retval;
	ihandle_t ih;
	int i;

	/* Open display device, thereby initializing it */
	memset(name, 0, sizeof(name));
	OF_package_to_path(node, name, sizeof(name));
	ih = OF_open(name);
#endif

	/*
	 * Set up the color map
	 */
	switch (info->fb_depth) {
	case 8:
		vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
		    0x7, 5, 0x7, 2, 0x3, 0);
		break;
	case 15:
		vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
		    0x1f, 10, 0x1f, 5, 0x1f, 0);
		break;
	case 16:
		vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
		    0x1f, 11, 0x3f, 5, 0x1f, 0);
		break;
	case 24:
	case 32:
#if BYTE_ORDER == BIG_ENDIAN
		vt_generate_cons_palette(info->fb_cmap,
		    COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16);
#else
		vt_generate_cons_palette(info->fb_cmap,
		    COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0);
#endif
#ifdef	FDT
		for (i = 0; i < 16; i++) {
			OF_call_method("color!", ih, 4, 1,
			    (cell_t)((info->fb_cmap[i] >> 16) & 0xff),
			    (cell_t)((info->fb_cmap[i] >> 8) & 0xff),
			    (cell_t)((info->fb_cmap[i] >> 0) & 0xff),
			    (cell_t)i, &retval);
		}
#endif
		break;

	default:
		panic("Unknown color space fb_depth %d", info->fb_depth);
		break;
	}
}
Example #4
0
static void
ofwn_init(struct iodesc *desc, void *machdep_hint)
{
	phandle_t	netdev;
	char		path[64];
	char		*ch;
	int		pathlen;

	pathlen = OF_getprop(chosen, "bootpath", path, 64);
	if ((ch = index(path, ':')) != NULL)
		*ch = '\0';
	netdev = OF_finddevice(path);
#ifdef __sparc64__
	if (OF_getprop(netdev, "mac-address", desc->myea, 6) == -1)
#else
	if (OF_getprop(netdev, "local-mac-address", desc->myea, 6) == -1)
#endif
		goto punt;

	printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea));

	if ((netinstance = OF_open(path)) == -1) {
		printf("Could not open network device.\n");
		goto punt;
	}

#if defined(NETIF_DEBUG)
	printf("ofwn_init: Open Firmware instance handle: %08x\n", netinstance);
#endif

#ifndef __sparc64__
	dmabuf = NULL;
	if (OF_call_method("dma-alloc", netinstance, 1, 1, (64 * 1024), &dmabuf)
	    < 0) {   
		printf("Failed to allocate DMA buffer (got %08x).\n", dmabuf);
		goto punt;
	}

#if defined(NETIF_DEBUG)
	printf("ofwn_init: allocated DMA buffer: %08x\n", dmabuf);
#endif
#endif

	return;

punt:
	printf("\n");
	printf("Could not boot from %s.\n", path);
	OF_enter();
}
Example #5
0
static int
ofwd_open(struct open_file *f, ...)
{
	struct ofw_devdesc *dp;
	phandle_t handle;
	va_list vl;

	va_start(vl, f);
	dp = va_arg(vl, struct ofw_devdesc *);
	va_end(vl);
	if ((handle = OF_open(dp->d_path)) == -1) {
		printf("ofwd_open: Could not open %s\n", dp->d_path);
		return 1;
	}
	dp->d_handle = handle;
	return 0;
}
Example #6
0
static void
ofnet_attach(struct device *parent, struct device *self, void *aux)
{
	struct ofnet_softc *of = device_private(self);
	struct ifnet *ifp = &of->sc_ethercom.ec_if;
	struct ofbus_attach_args *oba = aux;
	char path[256];
	int l;
	u_int8_t myaddr[ETHER_ADDR_LEN];

	of->sc_phandle = oba->oba_phandle;
#if NIPKDB_OFN > 0
	if (kifp &&
	    kifp->unit - 1 == device_unit(&of->sc_dev) &&
	    OF_instance_to_package(kifp->port) == oba->oba_phandle)  {
		ipkdb_of = of;
		of->sc_ihandle = kifp->port;
	} else
#endif
	if ((l = OF_package_to_path(oba->oba_phandle, path,
	    sizeof path - 1)) < 0 ||
	    l >= sizeof path ||
	    (path[l] = 0, !(of->sc_ihandle = OF_open(path))))
		panic("ofnet_attach: unable to open");
	if (OF_getprop(oba->oba_phandle, "mac-address", myaddr,
	    sizeof myaddr) < 0)
		panic("ofnet_attach: no mac-address");
	printf(": address %s\n", ether_sprintf(myaddr));

	callout_init(&of->sc_callout, 0);

	strlcpy(ifp->if_xname, device_xname(&of->sc_dev), IFNAMSIZ);
	ifp->if_softc = of;
	ifp->if_start = ofnet_start;
	ifp->if_ioctl = ofnet_ioctl;
	ifp->if_watchdog = ofnet_watchdog;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp, myaddr);
}
Example #7
0
int
hfs_open(char *path, struct open_file *f)
{
	int chosen;
	char bootpath[128], *cp;

	if ((chosen = OF_finddevice("/chosen")) == -1)
		return ENXIO;
	bzero(bootpath, sizeof bootpath);
	OF_getprop(chosen, "bootpath", bootpath, sizeof bootpath);

	cp = strrchr(bootpath, ',');
	if (cp == NULL)
		return ENXIO;

	strlcpy(cp + 1, path, bootpath + sizeof bootpath - (cp + 1));
	OF_fd = OF_open(bootpath);
	if (OF_fd == -1)
		return ENOENT;
	return 0;
}
Example #8
0
static void
fix_cardbus_bridge(int node, pci_chipset_tag_t pc, pcitag_t tag)
{
	uint32_t bus_number = 0xffffffff;
	pcireg_t bi;
	int bus, dev, fn, ih, len;
	char path[256];

#if PB3400_CARDBUS_HACK
	int root_node;

	root_node = OF_finddevice("/");
	if (of_compatible(root_node, pb3400_compat) != -1) {

		bus_number = cardbus_number;
		cardbus_number++;
	} else {
#endif		
		ih = OF_open(path);
		OF_call_method("load-ata", ih, 0, 0);
		OF_close(ih);

		OF_getprop(node, "AAPL,bus-id", &bus_number,
		    sizeof(bus_number));
#if PB3400_CARDBUS_HACK
	}
#endif
	if (bus_number != 0xffffffff) {

		len = OF_package_to_path(node, path, sizeof(path));
		path[len] = 0;
		aprint_verbose("\n%s: fixing bus number to %d", path, bus_number);
		pci_decompose_tag(pc, tag, &bus, &dev, &fn);
		bi = pci_conf_read(pc, tag, PPB_REG_BUSINFO);
		bi &= 0xff000000;
		/* XXX subordinate is always 32 here */
		bi |= (bus & 0xff) | (bus_number << 8) | 0x200000;
		pci_conf_write(pc, tag, PPB_REG_BUSINFO, bi);
	}
}
Example #9
0
static int
ofwfb_set_mode(video_adapter_t *adp, int mode)
{
	struct ofwfb_softc *sc;
	char name[64];
	ihandle_t ih;
	int i, retval;

	sc = (struct ofwfb_softc *)adp;

	if (ofwfb_reset_on_switch) {
		/*
		 * Open the display device, which will initialize it.
		 */

		memset(name, 0, sizeof(name));
		OF_package_to_path(sc->sc_node, name, sizeof(name));
		ih = OF_open(name);

		if (sc->sc_depth == 8) {
			/*
			 * Install the ISO6429 colormap - older OFW systems
			 * don't do this by default
			 */
			for (i = 0; i < 16; i++) {
				OF_call_method("color!", ih, 4, 1,
						   ofwfb_cmap[i].red,
						   ofwfb_cmap[i].green,
						   ofwfb_cmap[i].blue,
						   i,
						   &retval);
			}
		}
	}

	ofwfb_blank_display(&sc->sc_va, V_DISPLAY_ON);

	return (0);
}
Example #10
0
static int
ofwd_open(struct open_file *f, ...)
{
	struct ofw_devdesc *dp;
	va_list vl;

	va_start(vl, f);
	dp = va_arg(vl, struct ofw_devdesc *);
	va_end(vl);

	if (dp != kdp) {
		if (kdp != NULL) {
			OF_close(kdp->d_handle);
			kdp = NULL;
		}
		if ((dp->d_handle = OF_open(dp->d_path)) == -1) {
			printf("%s: Could not open %s\n", __func__,
			    dp->d_path);
			return (ENOENT);
		}
		kdp = dp;
	}
	return (0);
}
Example #11
0
int
devopen(struct open_file *of, const char *name, char **file)
{
	char *cp;
	char partition;
	char fname[256];
	char buf[DEV_BSIZE];
	struct disklabel label;
	int handle, part;
	int error = 0;
#ifdef SOFTRAID
	char volno;
#endif

	if (ofdev.handle != -1)
		panic("devopen");
	if (of->f_flags != F_READ)
		return EPERM;
	DNPRINTF(BOOT_D_OFDEV, "devopen: you want %s\n", name);
	if (strlcpy(fname, name, sizeof fname) >= sizeof fname)
		return ENAMETOOLONG;
#ifdef SOFTRAID
	if (bootdev_dip) {
		if (fname[0] == 's' && fname[1] == 'r' &&
		    '0' <= fname[2] && fname[2] <= '9') {
			volno = fname[2];
			if ('a' <= fname[3] &&
			    fname[3] <= 'a' + MAXPARTITIONS) {
				partition = fname[3];
				if (fname[4] == ':')
					cp = &fname[5];
				else
					cp = &fname[4];
			} else {
				partition = 'a';
				cp = &fname[3];
			}
		} else {
			volno = '0';
			partition = 'a';
			cp = &fname[0];
		}
		snprintf(buf, sizeof buf, "sr%c:%c", volno, partition);
		if (strlcpy(opened_name, buf, sizeof opened_name)
		    >= sizeof opened_name)
			return ENAMETOOLONG;
		*file = opened_name + strlen(opened_name);
		if (!*cp) {
			if (strlcpy(buf, DEFAULT_KERNEL, sizeof buf)
			    >= sizeof buf)
				return ENAMETOOLONG;
		} else {
			if (snprintf(buf, sizeof buf, "%s%s",
			    *cp == '/' ? "" : "/", cp) >= sizeof buf)
				return ENAMETOOLONG;
		}
		if (strlcat(opened_name, buf, sizeof opened_name) >=
		    sizeof opened_name)
			return ENAMETOOLONG;
	} else {
#endif
		cp = filename(fname, &partition);
		if (cp) {
			if (strlcpy(buf, cp, sizeof buf) >= sizeof buf)
				return ENAMETOOLONG;
			*cp = 0;
		}
		if (!cp || !*buf) {
			if (strlcpy(buf, DEFAULT_KERNEL, sizeof buf)
			    >= sizeof buf)
				return ENAMETOOLONG;
		}
		if (!*fname) {
			if (strlcpy(fname, bootdev, sizeof fname)
			    >= sizeof fname)
				return ENAMETOOLONG;
		}
		if (strlcpy(opened_name, fname,
		    partition ? (sizeof opened_name) - 2 : sizeof opened_name)
		    >= sizeof opened_name)
			return ENAMETOOLONG;
		if (partition) {
			cp = opened_name + strlen(opened_name);
			*cp++ = ':';
			*cp++ = partition;
			*cp = 0;
		}
		if (*buf != '/') {
			if (strlcat(opened_name, "/", sizeof opened_name) >=
			    sizeof opened_name)
				return ENAMETOOLONG;
		}
		if (strlcat(opened_name, buf, sizeof opened_name) >=
		    sizeof opened_name)
			return ENAMETOOLONG;
		*file = opened_name + strlen(fname) + 1;
#ifdef SOFTRAID
	}
#endif
	DNPRINTF(BOOT_D_OFDEV, "devopen: trying %s\n", fname);
#ifdef SOFTRAID
	if (bootdev_dip) {
		/* Redirect to the softraid boot volume. */
		struct partition *pp;

		bzero(&ofdev, sizeof ofdev);
		ofdev.type = OFDEV_SOFTRAID;

		if (partition) {
			if (partition < 'a' ||
			    partition >= 'a' + MAXPARTITIONS) {
			    	printf("invalid partition '%c'\n", partition);
				return EINVAL;
			}
			part = partition - 'a';
			pp = &bootdev_dip->disklabel.d_partitions[part];
			if (pp->p_fstype == FS_UNUSED || pp->p_size == 0) {
			    	printf("invalid partition '%c'\n", partition);
				return EINVAL;
			}
			bootdev_dip->sr_vol->sbv_part = partition;
		} else
			bootdev_dip->sr_vol->sbv_part = 'a';

		of->f_dev = devsw;
		of->f_devdata = &ofdev;

#ifdef SPARC_BOOT_UFS
		bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]);
#else
#error "-DSOFTRAID requires -DSPARC_BOOT_UFS"
#endif
		return 0;
	}
#endif
	if ((handle = OF_finddevice(fname)) == -1)
		return ENOENT;
	DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname);
	if (OF_getprop(handle, "name", buf, sizeof buf) < 0)
		return ENXIO;
	DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf);
	if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0)
		return ENXIO;
	DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf);
	DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname);
	if ((handle = OF_open(fname)) == -1) {
		DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname);
		return ENXIO;
	}
	DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname);
	bzero(&ofdev, sizeof ofdev);
	ofdev.handle = handle;
	ofdev.type = OFDEV_DISK;
	ofdev.bsize = DEV_BSIZE;
	if (!strcmp(buf, "block")) {
		error = load_disklabel(&ofdev, &label);
		if (error && error != ERDLAB)
			goto bad;
		else if (error == ERDLAB) {
			if (partition)
				/* User specified a parititon, but there is none */
				goto bad;
			/* No, label, just use complete disk */
			ofdev.partoff = 0;
		} else {
			part = partition ? partition - 'a' : 0;
			ofdev.partoff = label.d_partitions[part].p_offset;
			DNPRINTF(BOOT_D_OFDEV, "devopen: setting partition %d "
			    "offset %x\n", part, ofdev.partoff);
		}
		
		of->f_dev = devsw;
		of->f_devdata = &ofdev;
#ifdef SPARC_BOOT_UFS
		bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]);
#endif
#ifdef SPARC_BOOT_HSFS
		bcopy(&file_system_cd9660, &file_system[nfsys++],
		    sizeof file_system[0]);
#endif
		DNPRINTF(BOOT_D_OFDEV, "devopen: return 0\n");
		return 0;
	}
#ifdef NETBOOT
	if (!strcmp(buf, "network")) {
		ofdev.type = OFDEV_NET;
		of->f_dev = devsw;
		of->f_devdata = &ofdev;
		bcopy(&file_system_nfs, file_system, sizeof file_system[0]);
		nfsys = 1;
		if (error = net_open(&ofdev))
			goto bad;
		return 0;
	}
#endif
	error = EFTYPE;
bad:
	DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n",
	    error);
	OF_close(handle);
	ofdev.handle = -1;
	return error;
}
Example #12
0
int
devopen(struct open_file *of, const char *name, char **file)
{
	char *cp;
	char partition;
	char fname[256];
	char buf[DEV_BSIZE];
	struct disklabel label;
	int handle, part;
	size_t read;
	char *errmsg = NULL;
	int error = 0;

	if (ofdev.handle != -1)
		panic("devopen");
	if (of->f_flags != F_READ)
		return EPERM;
	DNPRINTF(BOOT_D_OFDEV, "devopen: you want %s\n", name);
	strlcpy(fname, name, sizeof fname);
	cp = filename(fname, &partition);
	if (cp) {
		strlcpy(buf, cp, sizeof buf);
		*cp = 0;
	}
	if (!cp || !*buf)
		strlcpy(buf, DEFAULT_KERNEL, sizeof buf);
	if (!*fname)
		strlcpy(fname, bootdev, sizeof fname);
	strlcpy(opened_name, fname, sizeof opened_name);
	if (partition) {
		cp = opened_name + strlen(opened_name);
		*cp++ = ':';
		*cp++ = partition;
		*cp = 0;
	}
	if (*buf != '/')
		strlcat(opened_name, "/", sizeof opened_name);
	strlcat(opened_name, buf, sizeof opened_name);
	*file = opened_name + strlen(fname) + 1;
	DNPRINTF(BOOT_D_OFDEV, "devopen: trying %s\n", fname);
	if ((handle = OF_finddevice(fname)) == -1)
		return ENOENT;
	DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname);
	if (OF_getprop(handle, "name", buf, sizeof buf) < 0)
		return ENXIO;
	DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf);
	if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0)
		return ENXIO;
	DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf);
	DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname);
	if ((handle = OF_open(fname)) == -1) {
		DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname);
		return ENXIO;
	}
	DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname);
	bzero(&ofdev, sizeof ofdev);
	ofdev.handle = handle;
	if (!strcmp(buf, "block")) {
		ofdev.type = OFDEV_DISK;
		ofdev.bsize = DEV_BSIZE;
		/* First try to find a disklabel without MBR partitions */
		DNPRINTF(BOOT_D_OFDEV, "devopen: trying to read disklabel\n");
		if (strategy(&ofdev, F_READ,
			     LABELSECTOR, DEV_BSIZE, buf, &read) != 0
		    || read != DEV_BSIZE
		    || (errmsg = getdisklabel(buf, &label))) {
#ifdef BOOT_DEBUG
			if (errmsg)
				DNPRINTF(BOOT_D_OFDEV,
				    "devopen: getdisklabel says %s\n", errmsg);
#endif
			/* Else try MBR partitions */
			errmsg = search_label(&ofdev, LABELSECTOR, buf,
			    &label, 0);
			if (errmsg) { 
				printf("devopen: search_label says %s\n", errmsg);
				error = ERDLAB;
			}
			if (error && error != ERDLAB)
				goto bad;
		}

		if (error == ERDLAB) {
			if (partition)
				/* User specified a parititon, but there is none */
				goto bad;
			/* No, label, just use complete disk */
			ofdev.partoff = 0;
		} else {
			part = partition ? partition - 'a' : 0;
			ofdev.partoff = label.d_partitions[part].p_offset;
			DNPRINTF(BOOT_D_OFDEV, "devopen: setting partition %d "
			    "offset %x\n", part, ofdev.partoff);
		}
		
		of->f_dev = devsw;
		of->f_devdata = &ofdev;
#ifdef SPARC_BOOT_UFS
		bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]);
#endif
#ifdef SPARC_BOOT_HSFS
		bcopy(&file_system_cd9660, &file_system[nfsys++],
		    sizeof file_system[0]);
#endif
		DNPRINTF(BOOT_D_OFDEV, "devopen: return 0\n");
		return 0;
	}
#ifdef NETBOOT
	if (!strcmp(buf, "network")) {
		ofdev.type = OFDEV_NET;
		of->f_dev = devsw;
		of->f_devdata = &ofdev;
		bcopy(&file_system_nfs, file_system, sizeof file_system[0]);
		nfsys = 1;
		if (error = net_open(&ofdev))
			goto bad;
		return 0;
	}
#endif
	error = EFTYPE;
bad:
	DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n",
	    error);
	OF_close(handle);
	ofdev.handle = -1;
	return error;
}
Example #13
0
static void
rtas_setup(void *junk)
{
	ihandle_t rtasi;
	cell_t rtas_size = 0, rtas_ptr;
	char path[31];
	int result;

	rtas = OF_finddevice("/rtas");
	if (rtas == -1) {
		rtas = 0;
		return;
	}
	OF_package_to_path(rtas, path, sizeof(path));
	rtasi = OF_open(path);
	if (rtasi == 0) {
		rtas = 0;
		printf("Error initializing RTAS: could not open node\n");
		return;
	}

	mtx_init(&rtas_mtx, "RTAS", MTX_DEF, 0);

	/* RTAS must be called with everything turned off in MSR */
	rtasmsr = mfmsr();
	rtasmsr &= ~(PSL_IR | PSL_DR | PSL_EE | PSL_SE);
	#ifdef __powerpc64__
	rtasmsr &= ~PSL_SF;
	#endif

	/*
	 * Allocate rtas_size + one page of contiguous, wired physical memory
	 * that can fit into a 32-bit address space and accessed from real mode.
	 * This is used both to bounce arguments and for RTAS private data.
	 *
	 * It must be 4KB-aligned and not cross a 256 MB boundary.
	 */

	OF_getprop(rtas, "rtas-size", &rtas_size, sizeof(rtas_size));
	rtas_size = round_page(rtas_size);
	rtas_bounce_virt = contigmalloc(rtas_size + PAGE_SIZE, M_RTAS, 0, 0,
	    ulmin(platform_real_maxaddr(), BUS_SPACE_MAXADDR_32BIT),
	    4096, 256*1024*1024);

	rtas_private_data = vtophys(rtas_bounce_virt);
	rtas_bounce_virt += rtas_size;	/* Actual bounce area */
	rtas_bounce_phys = vtophys(rtas_bounce_virt);
	rtas_bounce_size = PAGE_SIZE;

	/*
	 * Instantiate RTAS. We always use the 32-bit version.
	 */

	result = OF_call_method("instantiate-rtas", rtasi, 1, 1,
	    (cell_t)rtas_private_data, &rtas_ptr);
	OF_close(rtasi);

	if (result != 0) {
		rtas = 0;
		rtas_ptr = 0;
		printf("Error initializing RTAS (%d)\n", result);
		return;
	}

	rtas_entry = (uintptr_t)(rtas_ptr);
}
Example #14
0
/*
 * Called back during autoconfiguration for each device found
 */
void
device_register(device_t dev, void *aux)
{
	device_t busdev = device_parent(dev);
	int ofnode = 0;

	/*
	 * We don't know the type of 'aux' - it depends on the
	 * bus this device attaches to. We are only interested in
	 * certain bus types, this only is used to find the boot
	 * device.
	 */
	if (busdev == NULL) {
		/*
		 * Ignore mainbus0 itself, it certainly is not a boot
		 * device.
		 */
	} else if (device_is_a(busdev, "mainbus")) {
		struct mainbus_attach_args *ma = aux;

		ofnode = ma->ma_node;
	} else if (device_is_a(busdev, "pci")) {
		struct pci_attach_args *pa = aux;

		ofnode = PCITAG_NODE(pa->pa_tag);
	} else if (device_is_a(busdev, "sbus") || device_is_a(busdev, "dma")
	    || device_is_a(busdev, "ledma")) {
		struct sbus_attach_args *sa = aux;

		ofnode = sa->sa_node;
	} else if (device_is_a(busdev, "ebus")) {
		struct ebus_attach_args *ea = aux;

		ofnode = ea->ea_node;
	} else if (device_is_a(busdev, "iic")) {
		struct i2c_attach_args *ia = aux;

		if (ia->ia_name == NULL)	/* indirect config */
			return;

		ofnode = (int)ia->ia_cookie;
	} else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) {
		struct scsipibus_attach_args *sa = aux;
		struct scsipi_periph *periph = sa->sa_periph;
		int off = 0;

		/*
		 * There are two "cd" attachments:
		 *   atapibus -> atabus -> controller
		 *   scsibus -> controller
		 * We want the node of the controller.
		 */
		if (device_is_a(busdev, "atapibus")) {
			busdev = device_parent(busdev);
			/*
			 * if the atapibus is connected to the secondary
			 * channel of the atabus, we need an offset of 2
			 * to match OF's idea of the target number.
			 * (i.e. on U5/U10 "cdrom" and "disk2" have the
			 * same target encoding, though different names)
			 */
			if (periph->periph_channel->chan_channel == 1)
				off = 2;
		}
		ofnode = device_ofnode(device_parent(busdev));
		dev_path_drive_match(dev, ofnode, periph->periph_target + off,
		    0, periph->periph_lun);
		return;
	} else if (device_is_a(dev, "wd")) {
		struct ata_device *adev = aux;

		ofnode = device_ofnode(device_parent(busdev));
		dev_path_drive_match(dev, ofnode, adev->adev_channel*2+
		    adev->adev_drv_data->drive, 0, 0);
		return;
	}

	if (busdev == NULL)
		return;

	if (ofnode != 0) {
		uint8_t eaddr[ETHER_ADDR_LEN];
		char tmpstr[32];
		char tmpstr2[32];
		int node;
		uint32_t id = 0;
		uint64_t nwwn = 0, pwwn = 0;
		prop_dictionary_t dict;
		prop_data_t blob;
		prop_number_t pwwnd = NULL, nwwnd = NULL;
		prop_number_t idd = NULL;

		device_setofnode(dev, ofnode);
		dev_path_exact_match(dev, ofnode);

		if (OF_getprop(ofnode, "name", tmpstr, sizeof(tmpstr)) <= 0)
			tmpstr[0] = 0;
		if (OF_getprop(ofnode, "device_type", tmpstr2, sizeof(tmpstr2)) <= 0)
			tmpstr2[0] = 0;

		/*
		 * If this is a network interface, note the
		 * mac address.
		 */
		if (strcmp(tmpstr, "network") == 0
		   || strcmp(tmpstr, "ethernet") == 0
		   || strcmp(tmpstr2, "network") == 0
		   || strcmp(tmpstr2, "ethernet") == 0
		   || OF_getprop(ofnode, "mac-address", &eaddr, sizeof(eaddr))
		      >= ETHER_ADDR_LEN
		   || OF_getprop(ofnode, "local-mac-address", &eaddr, sizeof(eaddr))
		      >= ETHER_ADDR_LEN) {

			dict = device_properties(dev);

			/*
			 * Is it a network interface with FCode?
			 */
			if (strcmp(tmpstr, "network") == 0 ||
			    strcmp(tmpstr2, "network") == 0) {
				prop_dictionary_set_bool(dict,
				    "without-seeprom", true);
				prom_getether(ofnode, eaddr);
			} else {
				if (!prom_get_node_ether(ofnode, eaddr))
					goto noether;
			}
			blob = prop_data_create_data(eaddr, ETHER_ADDR_LEN);
			prop_dictionary_set(dict, "mac-address", blob);
			prop_object_release(blob);
			of_to_dataprop(dict, ofnode, "shared-pins",
			    "shared-pins");
		}
noether:

		/* is this a FC node? */
		if (strcmp(tmpstr, "scsi-fcp") == 0) {

			dict = device_properties(dev);

			if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn))
			    == sizeof(pwwn)) {
				pwwnd = 
				    prop_number_create_unsigned_integer(pwwn);
				prop_dictionary_set(dict, "port-wwn", pwwnd);
				prop_object_release(pwwnd);
			}

			if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn))
			    == sizeof(nwwn)) {
				nwwnd = 
				    prop_number_create_unsigned_integer(nwwn);
				prop_dictionary_set(dict, "node-wwn", nwwnd);
				prop_object_release(nwwnd);
			}
		}

		/* is this an spi device?  look for scsi-initiator-id */
		if (strcmp(tmpstr2, "scsi") == 0 ||
		    strcmp(tmpstr2, "scsi-2") == 0) {

			dict = device_properties(dev);

			for (node = ofnode; node != 0; node = OF_parent(node)) {
				if (OF_getprop(node, "scsi-initiator-id", &id,
				    sizeof(id)) <= 0)
					continue;

				idd = prop_number_create_unsigned_integer(id);
				prop_dictionary_set(dict,
						    "scsi-initiator-id", idd);
				prop_object_release(idd);
				break;
			}
		}
	}

	/*
	 * Check for I2C busses and add data for their direct configuration.
	 */
	if (device_is_a(dev, "iic")) {
		int busnode = device_ofnode(busdev);

		if (busnode) {
			prop_dictionary_t props = device_properties(busdev);
			prop_object_t cfg = prop_dictionary_get(props,
				"i2c-child-devices");
			if (!cfg) {
				int node;
				const char *name;

				/*
				 * pmu's i2c devices are under the "i2c" node,
				 * so find it out.
				 */
				name = prom_getpropstring(busnode, "name");
				if (strcmp(name, "pmu") == 0) {
					for (node = OF_child(busnode);
					     node != 0; node = OF_peer(node)) {
						name = prom_getpropstring(node,
						    "name");
						if (strcmp(name, "i2c") == 0) {
							busnode = node;
							break;
						}
					}
				}

				of_enter_i2c_devs(props, busnode,
				    sizeof(cell_t));
			}
		}

		/*
		 * Add SPARCle spdmem devices (0x50 and 0x51) that the
		 * firmware does not know about.
		 */
		if (!strcmp(machine_model, "TAD,SPARCLE")) {
			prop_dictionary_t props = device_properties(busdev);
			prop_array_t cfg = prop_array_create();
			int i;

			DPRINTF(ACDB_PROBE, ("\nAdding spdmem for SPARCle "));
			for (i = 0x50; i <= 0x51; i++) {
				prop_dictionary_t spd =
				    prop_dictionary_create();
				prop_dictionary_set_cstring(spd, "name",
				    "dimm-spd");
				prop_dictionary_set_uint32(spd, "addr", i);
				prop_dictionary_set_uint64(spd, "cookie", 0);
				prop_array_add(cfg, spd);
				prop_object_release(spd);
			}
			prop_dictionary_set(props, "i2c-child-devices", cfg);
			prop_object_release(cfg);
			
		}
	}

	/* set properties for PCI framebuffers */
	if (device_is_a(busdev, "pci")) {
		/* see if this is going to be console */
		struct pci_attach_args *pa = aux;
		prop_dictionary_t dict;
		int sub;
		int console = 0;

		dict = device_properties(dev);

		/* we only care about display devices from here on */
		if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
			return;

		console = (ofnode == console_node);

		if (!console) {
			/*
			 * see if any child matches since OF attaches
			 * nodes for each head and /chosen/stdout
			 * points to the head rather than the device
			 * itself in this case
			 */
			sub = OF_child(ofnode);
			while ((sub != 0) && (sub != console_node)) {
				sub = OF_peer(sub);
			}
			if (sub == console_node) {
				console = true;
			}
		}

		copyprops(busdev, ofnode, dict, console);

		if (console) {
			uint64_t cmap_cb;
			prop_dictionary_set_uint32(dict,
			    "instance_handle", console_instance);

			gfb_cb.gcc_cookie = 
			    (void *)(intptr_t)console_instance;
			gfb_cb.gcc_set_mapreg = of_set_palette;
			cmap_cb = (uint64_t)(uintptr_t)&gfb_cb;
			prop_dictionary_set_uint64(dict,
			    "cmap_callback", cmap_cb);
		}
#ifdef notyet 
		else {
			int width;

			/*
			 * the idea is to 'open' display devices with no useful
			 * properties, in the hope that the firmware will
			 * properly initialize them and we can run things like
			 * genfb on them
			 */
			if (OF_getprop(node, "width", &width, sizeof(width))
			    != 4) {
				instance = OF_open(name);
#endif
	}
}

/*
 * Called back after autoconfiguration of a device is done
 */
void
device_register_post_config(device_t dev, void *aux)
{
	if (booted_device == NULL && device_is_a(dev, "sd")) {
		struct scsipibus_attach_args *sa = aux;
		struct scsipi_periph *periph = sa->sa_periph;
		uint64_t wwn = 0;
		int ofnode;

		/*
		 * If this is a FC-AL drive it will have
		 * aquired its WWN device property by now,
		 * so we can properly match it.
		 */
		if (prop_dictionary_get_uint64(device_properties(dev),
		    "port-wwn", &wwn)) {
			/*
			 * Different to what we do in device_register,
			 * we do not pass the "controller" ofnode,
			 * because FC-AL devices attach below a "fp" node,
			 * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk
			 * and we need the parent of "disk" here.
			 */
			ofnode = device_ofnode(
			    device_parent(device_parent(dev)));
			for (ofnode = OF_child(ofnode);
			    ofnode != 0 && booted_device == NULL;
			    ofnode = OF_peer(ofnode)) {
				dev_path_drive_match(dev, ofnode,
				    periph->periph_target,
				    wwn, periph->periph_lun);
			}
		}
	}
}

static void
copyprops(device_t busdev, int node, prop_dictionary_t dict, int is_console)
{
	device_t cntrlr;
	prop_dictionary_t psycho;
	paddr_t fbpa, mem_base = 0;
	uint32_t temp, fboffset;
	uint32_t fbaddr = 0;
	int options;
	char output_device[256];
	char *pos;

	cntrlr = device_parent(busdev);
	if (cntrlr != NULL) {
		psycho = device_properties(cntrlr);
		prop_dictionary_get_uint64(psycho, "mem_base", &mem_base);
	}

	if (is_console)
		prop_dictionary_set_bool(dict, "is_console", 1);

	of_to_uint32_prop(dict, node, "width", "width");
	of_to_uint32_prop(dict, node, "height", "height");
	of_to_uint32_prop(dict, node, "linebytes", "linebytes");
	if (!of_to_uint32_prop(dict, node, "depth", "depth") &&
	    /* Some cards have an extra space in the property name */
	    !of_to_uint32_prop(dict, node, "depth ", "depth")) {
		/*
		 * XXX we should check linebytes vs. width but those
		 * FBs that don't have a depth property ( /chaos/control... )
		 * won't have linebytes either
		 */
		prop_dictionary_set_uint32(dict, "depth", 8);
	}

	OF_getprop(node, "address", &fbaddr, sizeof(fbaddr));
	if (fbaddr != 0) {
	
		pmap_extract(pmap_kernel(), fbaddr, &fbpa);
#ifdef DEBUG
		printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base,
		    (unsigned long)fbpa);
#endif
		if (mem_base == 0) {
			/* XXX this is guesswork */
			fboffset = (uint32_t)(fbpa & 0xffffffff);
		}
			fboffset = (uint32_t)(fbpa - mem_base);
		prop_dictionary_set_uint32(dict, "address", fboffset);
	}

	if (!of_to_dataprop(dict, node, "EDID", "EDID"))
		of_to_dataprop(dict, node, "edid", "EDID");

	temp = 0;
	if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) {

		OF_getprop(OF_parent(node), "ATY,RefCLK", &temp,
		    sizeof(temp));
	}
	if (temp != 0)
		prop_dictionary_set_uint32(dict, "refclk", temp / 10);

	/*
	 * finally, let's see if there's a video mode specified in
	 * output-device and pass it on so drivers like radeonfb
	 * can do their thing
	 */

	if (!is_console)
		return;

	options = OF_finddevice("/options");
	if ((options == 0) || (options == -1))
		return;
	if (OF_getprop(options, "output-device", output_device, 256) == 0)
		return;
	/* find the mode string if there is one */
	pos = strstr(output_device, ":r");
	if (pos == NULL)
		return;
	prop_dictionary_set_cstring(dict, "videomode", pos + 2);
}

static void
of_set_palette(void *cookie, int index, int r, int g, int b)
{
	int ih = (int)((intptr_t)cookie);

	OF_call_method_1("color!", ih, 4, r, g, b, index);
}
Example #15
0
void
bmac_attach(struct device *parent, struct device *self, void *aux)
{
	struct confargs *ca = aux;
	struct bmac_softc *sc = (void *)self;
	struct ifnet *ifp = &sc->sc_if;
	struct mii_data *mii = &sc->sc_mii;
	u_char laddr[6];

	callout_init(&sc->sc_tick_ch, 0);

	sc->sc_flags =0;
	if (strcmp(ca->ca_name, "ethernet") == 0) {
		char name[64];

		memset(name, 0, 64);
		OF_package_to_path(ca->ca_node, name, sizeof(name));
		OF_open(name);
		sc->sc_flags |= BMAC_BMACPLUS;
	}

	ca->ca_reg[0] += ca->ca_baseaddr;
	ca->ca_reg[2] += ca->ca_baseaddr;
	ca->ca_reg[4] += ca->ca_baseaddr;

	sc->sc_iot = ca->ca_tag;
	if (bus_space_map(sc->sc_iot, ca->ca_reg[0], ca->ca_reg[1], 0,
	    &sc->sc_ioh) != 0) {
		aprint_error(": couldn't map %#x", ca->ca_reg[0]);
		return;
	}

	bmac_write_reg(sc, INTDISABLE, NoEventsMask);

	if (OF_getprop(ca->ca_node, "local-mac-address", laddr, 6) == -1 &&
	    OF_getprop(ca->ca_node, "mac-address", laddr, 6) == -1) {
		printf(": cannot get mac-address\n");
		return;
	}
	memcpy(sc->sc_enaddr, laddr, 6);

	sc->sc_txdma = mapiodev(ca->ca_reg[2], PAGE_SIZE);
	sc->sc_rxdma = mapiodev(ca->ca_reg[4], PAGE_SIZE);
	sc->sc_txcmd = dbdma_alloc(BMAC_TXBUFS * sizeof(dbdma_command_t));
	sc->sc_rxcmd = dbdma_alloc((BMAC_RXBUFS + 1) * sizeof(dbdma_command_t));
	sc->sc_txbuf = malloc(BMAC_BUFLEN * BMAC_TXBUFS, M_DEVBUF, M_NOWAIT);
	sc->sc_rxbuf = malloc(BMAC_BUFLEN * BMAC_RXBUFS, M_DEVBUF, M_NOWAIT);
	if (sc->sc_txbuf == NULL || sc->sc_rxbuf == NULL ||
	    sc->sc_txcmd == NULL || sc->sc_rxcmd == NULL) {
		printf("cannot allocate memory\n");
		return;
	}

	printf(" irq %d,%d: address %s\n", ca->ca_intr[0], ca->ca_intr[2],
		ether_sprintf(laddr));

	intr_establish(ca->ca_intr[0], IST_EDGE, IPL_NET, bmac_intr, sc);
	intr_establish(ca->ca_intr[2], IST_EDGE, IPL_NET, bmac_rint, sc);

	memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_ioctl = bmac_ioctl;
	ifp->if_start = bmac_start;
	ifp->if_flags =
		IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
	ifp->if_watchdog = bmac_watchdog;
	IFQ_SET_READY(&ifp->if_snd);

	mii->mii_ifp = ifp;
	mii->mii_readreg = bmac_mii_readreg;
	mii->mii_writereg = bmac_mii_writereg;
	mii->mii_statchg = bmac_mii_statchg;

	sc->sc_ethercom.ec_mii = mii;
	ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus);
	mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
		      MII_OFFSET_ANY, 0);

	/* Choose a default media. */
	if (LIST_FIRST(&mii->mii_phys) == NULL) {
		ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_10_T, 0, NULL);
		ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_10_T);
	} else
		ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO);

	bmac_reset_chip(sc);

	if_attach(ifp);
	ether_ifattach(ifp, sc->sc_enaddr);
}
Example #16
0
static void
ofwpci_attach(device_t parent, device_t self, void *aux)
{
	struct ofwpci_softc *sc = device_private(self);
	pci_chipset_tag_t pc = &sc->sc_pc;
	struct confargs *ca = aux;
	struct pcibus_attach_args pba;
	struct genppc_pci_chipset_businfo *pbi;
	int node = ca->ca_node;
	int i, isprim = 0;
	uint32_t busrange[2];
	char buf[64];
#ifdef PCI_NETBSD_CONFIGURE
	struct extent *ioext, *memext;
#endif

	aprint_normal("\n");

	sc->sc_dev = self;

	/* PCI bus number */
	if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
		return;

	/* bus space map the io ranges */
	sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE;
	sc->sc_iot.pbs_base = 0x00000000;
	if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot,
	    "ofwpci io-space") != 0)
		panic("Can't init ofwpci io tag");

	sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE;
	sc->sc_memt.pbs_base = 0x00000000;
	if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt,
	    "ofwpci mem-space") != 0)
		panic("Can't init ofwpci mem tag");

	aprint_debug("io base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n",
	    sc->sc_iot.pbs_base, sc->sc_iot.pbs_offset, sc->sc_iot.pbs_limit);
	
	aprint_debug("mem base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n",
	    sc->sc_memt.pbs_base, sc->sc_memt.pbs_offset,
	    sc->sc_memt.pbs_limit);
	
	/* are we the primary pci bus? */
	if (of_find_firstchild_byname(OF_finddevice("/"), "pci") == node) {
		int isa_node;

		isprim++;
		/* yes we are, now do we have an ISA child? */
		isa_node = of_find_firstchild_byname(node, "isa");
		if (isa_node != -1) {
			/* isa == pci */
			genppc_isa_io_space_tag = sc->sc_iot;
			genppc_isa_mem_space_tag = sc->sc_memt;
			map_isa_ioregs();
			init_ofppc_interrupt();
			ofppc_init_comcons(isa_node);
		}
	}

	ofwpci_get_chipset_tag(pc);

	pc->pc_node = node;
	i = OF_package_to_path(node, buf, sizeof(buf)-5);
	if (i <= 0)
		panic("Can't determine path for pci node %d", node);
	buf[i] = '\0';
	pc->pc_ihandle = OF_open(buf);
	if (pc->pc_ihandle < 0)
		panic("Can't open device %s", buf);
	pc->pc_bus = busrange[0];
	pc->pc_iot = &sc->sc_iot;
	pc->pc_memt = &sc->sc_memt;

	pbi = malloc(sizeof(struct genppc_pci_chipset_businfo),
	    M_DEVBUF, M_NOWAIT);
	KASSERT(pbi != NULL);
	pbi->pbi_properties = prop_dictionary_create();
	KASSERT(pbi->pbi_properties != NULL);
	SIMPLEQ_INIT(&pc->pc_pbi);
	SIMPLEQ_INSERT_TAIL(&pc->pc_pbi, pbi, next);

	genofw_setup_pciintr_map((void *)pc, pbi, pc->pc_node);
#ifdef PCI_NETBSD_CONFIGURE
	ioext  = extent_create("pciio",
	    modeldata.pciiodata[device_unit(self)].start,
	    modeldata.pciiodata[device_unit(self)].limit,
	    NULL, 0, EX_NOWAIT);
	memext = extent_create("pcimem", sc->sc_memt.pbs_base,
	    sc->sc_memt.pbs_limit-1, NULL, 0, EX_NOWAIT);

	if (pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINESIZE))
		aprint_error("pci_configure_bus() failed\n");

	extent_destroy(ioext);
	extent_destroy(memext);
#endif /* PCI_NETBSD_CONFIGURE */
	memset(&pba, 0, sizeof(pba));
	pba.pba_memt = pc->pc_memt;
	pba.pba_iot = pc->pc_iot;
	pba.pba_dmat = &pci_bus_dma_tag;
	pba.pba_dmat64 = NULL;
	pba.pba_bus = pc->pc_bus;
	pba.pba_bridgetag = NULL;
	pba.pba_pc = pc;
	pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
	config_found_ia(self, "pcibus", &pba, pcibusprint);
}
Example #17
0
int
devopen(struct open_file *of, const char *name, char **file)
{
	char *cp;
	char partition;
	char fname[256];
	char buf[DEV_BSIZE];
	struct disklabel label;
	int handle, part;
	size_t nread;
	int error = 0;

	if (ofdev.handle != -1)
		panic("devopen");
	if (of->f_flags != F_READ)
		return EPERM;
	strcpy(fname, name);
	cp = filename(fname, &partition);
	if (cp) {
		strcpy(buf, cp);
		*cp = 0;
	}
	if (!cp || !*buf)
		return ENOENT;
	if (!*fname)
		strcpy(fname, bootdev);
	strcpy(opened_name, fname);
	if (partition) {
		cp = opened_name + strlen(opened_name);
		*cp++ = ':';
		*cp++ = partition;
		*cp = 0;
	}
	if (*buf != '/')
		strcat(opened_name, "/");
	strcat(opened_name, buf);
	*file = opened_name + strlen(fname) + 1;
	if ((handle = OF_finddevice(fname)) == -1)
		return ENOENT;
	if (OF_getprop(handle, "name", buf, sizeof buf) < 0)
		return ENXIO;
	floppyboot = !strcmp(buf, "floppy");
	if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0)
		return ENXIO;
#if 0
	if (!strcmp(buf, "block"))
		/*
		 * For block devices, indicate raw partition
		 * (:0 in OpenFirmware)
		 */
		strcat(fname, ":0");
#endif
	if ((handle = OF_open(fname)) == -1)
		return ENXIO;
	memset(&ofdev, 0, sizeof ofdev);
	ofdev.handle = handle;
	ofdev.dmabuf = NULL;
	OF_call_method("dma-alloc", handle, 1, 1, MAXPHYS, &ofdev.dmabuf);
	if (!strcmp(buf, "block")) {
		ofdev.type = OFDEV_DISK;
		ofdev.bsize = DEV_BSIZE;
		/* First try to find a disklabel without MBR partitions */
		if (strategy(&ofdev, F_READ,
			     LABELSECTOR, DEV_BSIZE, buf, &nread) != 0
		    || nread != DEV_BSIZE
		    || getdisklabel(buf, &label)) {
			/* Else try MBR partitions */
			error = search_label(&ofdev, 0, buf, &label, 0);
			if (error && error != ERDLAB)
				goto bad;
		}

		if (error == ERDLAB) {
			if (partition)
				/*
				 * User specified a parititon,
				 * but there is none
				 */
				goto bad;
			/* No, label, just use complete disk */
			ofdev.partoff = 0;
		} else {
			part = partition ? partition - 'a' : 0;
			ofdev.partoff = label.d_partitions[part].p_offset;
		}

		of->f_dev = of_devsw;
		of->f_devdata = &ofdev;
		file_system[0] = file_system_ffsv1;
		file_system[1] = file_system_ffsv2;
		file_system[2] = file_system_lfsv1;
		file_system[3] = file_system_lfsv2;
		file_system[4] = file_system_ustarfs;
		file_system[5] = file_system_cd9660;
		file_system[6] = file_system_hfs;
		nfsys = 7;
		return 0;
	}
	if (!strcmp(buf, "network")) {
		ofdev.type = OFDEV_NET;
		of->f_dev = of_devsw;
		of->f_devdata = &ofdev;
		file_system[0] = file_system_nfs;
		nfsys = 1;
		if ((error = net_open(&ofdev)))
			goto bad;
		return 0;
	}
	error = EFTYPE;
bad:
	OF_close(handle);
	ofdev.handle = -1;
	return error;
}
Example #18
0
int
ofdisk_open(dev_t dev, int flags, int fmt, struct lwp *lwp)
{
	struct ofdisk_softc *of;
	char path[256];
	int error, l, part;

	of = device_lookup_private(&ofdisk_cd, DISKUNIT(dev));
	if (of == NULL)
		return ENXIO;

	part = DISKPART(dev);

	mutex_enter(&of->sc_dk.dk_openlock);

	/*
	 * If there are wedges, and this is not RAW_PART, then we
	 * need to fail.
	 */
	if (of->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
		error = EBUSY;
		goto bad1;
	}

	if (!of->sc_ihandle) {
		if ((l = OF_package_to_path(of->sc_phandle, path,
		    sizeof path - 3)) < 0 ||
		    l >= sizeof path - 3) {
			error = ENXIO;
			goto bad1;
		}
		path[l] = 0;

		/*
		 * XXX This is for the benefit of SCSI/IDE disks that don't
		 * XXX have all their childs in the device tree.
		 * XXX YES, I DO THINK THIS IS A BUG IN OPENFIRMWARE!!!
		 * XXX And yes, this is a very gross hack!
		 * XXX See also ofscsi.c
		 */
		if (!strcmp(path + l - 4, "disk")) {
			path[l++] = '@';
			path[l++] = '0' + of->sc_unit;
			path[l] = 0;
		}

		strlcat(path, ":0", sizeof(path));

		if ((of->sc_ihandle = OF_open(path)) == -1) {
			error = ENXIO;
			goto bad1;
		}

		/*
		 * Try to get characteristics of the disk.
		 */
		of->max_transfer = OF_call_method_1("max-transfer",
		    of->sc_ihandle, 0);
		if (of->max_transfer > MAXPHYS)
			of->max_transfer = MAXPHYS;

		ofdisk_getdisklabel(dev);
	}

	switch (fmt) {
	case S_IFCHR:
		of->sc_dk.dk_copenmask |= 1 << part;
		break;
	case S_IFBLK:
		of->sc_dk.dk_bopenmask |= 1 << part;
		break;
	}
	of->sc_dk.dk_openmask =
	    of->sc_dk.dk_copenmask | of->sc_dk.dk_bopenmask;


	error = 0;
 bad1:
	mutex_exit(&of->sc_dk.dk_openlock);
	return (error);
}
Example #19
0
int
devopen(struct open_file *of, const char *name, char **file)
{
	char *cp;
	char partition;
	char fname[256];
	struct disklabel label;
	int handle, part;
	size_t read;
	int error = 0;
	/* allow disk blocks up to 65536 bytes */
	char buf[DEV_BSIZE<<7];

	if (ofdev.handle != -1)
		panic("devopen");
	if (of->f_flags != F_READ)
		return EPERM;

	strcpy(fname, name);
	cp = filename(fname, &partition);
	if (cp) {
		DPRINTF("filename=%s\n", cp);
		strcpy(buf, cp);
		*cp = 0;
	}
	if (!cp || !*buf)
		strcpy(buf, DEFAULT_KERNEL);

	if (!*fname)
		strcpy(fname, bootdev);
	DPRINTF("fname=%s\n", fname);
	strcpy(opened_name, fname);
	if (partition) {
		cp = opened_name + strlen(opened_name);
		*cp++ = ':';
		*cp++ = partition;
		*cp = 0;
	}
	if (*buf != '/')
		strcat(opened_name, "/");
	strcat(opened_name, buf);
	*file = opened_name + strlen(fname) + 1;
	if (partition) {
		*file += 2;
	}

	if ((handle = OF_finddevice(fname)) == -1) {
		DPRINTF("OF_finddevice(\"%s\") failed\n", fname);
		return ENOENT;
	}

	if (OF_getprop(handle, "name", buf, sizeof buf) < 0)
		return ENXIO;
	floppyboot = !strcmp(buf, "floppy");
	if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0)
		return ENXIO;
	if (!strcmp(buf, "block")) {
		/*
		 * For block devices, indicate raw partition
		 * (:0 in OpenFirmware)
		 */
		strcat(fname, ":0");
	}

	DPRINTF("calling OF_open(fname=%s)\n", fname);
	if ((handle = OF_open(fname)) == -1)
		return ENXIO;
	memset(&ofdev, 0, sizeof ofdev);
	ofdev.handle = handle;

	if (!strcmp(buf, "block")) {
		ofdev.type = OFDEV_DISK;
		ofdev.bsize = DEV_BSIZE;

		/* First try to read a disklabel from a NetBSD MBR partition */
		error = search_mbr_label(&ofdev, 0, buf, &label, 0);

		if (error == ERDLAB) {
			/* Try to construct a disklabel from RDB partitions */
			error = search_rdb_label(&ofdev, buf, &label);

			if (error == ERDLAB) {
				/* At last read a raw NetBSD disklabel */
				error = strategy(&ofdev, F_READ, LABELSECTOR,
				    DEV_BSIZE, buf, &read);
				if (error == 0 && read != DEV_BSIZE)
					error = EIO;
				if (error == 0)
					if (getdisklabel(buf, &label) != NULL)
						error = ERDLAB;
			}
		}

		if (error == ERDLAB) {
			if (partition) {
				/*
				 * User specified a partition,
				 * but there is none.
				 */
				goto bad;
			}
			/* No label, just use complete disk */
			ofdev.partoff = 0;
		} else if (error != 0)
			goto bad;
		else {
			part = partition ? partition - 'a' : 0;
			ofdev.partoff = label.d_partitions[part].p_offset;
			if (label.d_partitions[part].p_fstype == FS_RAID) {
#define RF_PROTECTED_SECTORS 64
				ofdev.partoff += RF_PROTECTED_SECTORS;
				DPRINTF("devopen: found RAID partition, "
				    "adjusting offset to %lx\n", ofdev.partoff);
			}
		}
		of->f_dev = devsw;
		of->f_devdata = &ofdev;
		file_system[0] = file_system_ufs;
		file_system[1] = file_system_cd9660;
		file_system[2] = file_system_dosfs;
		nfsys = 3;
		return 0;
	}

	if (!strcmp(buf, "network")) {
		ofdev.type = OFDEV_NET;
		of->f_dev = devsw;
		of->f_devdata = &ofdev;
		file_system[0] = file_system_nfs;
		nfsys = 1;
		if ((error = net_open(&ofdev)) != 0)
			goto bad;
		return 0;
	}

	error = EFTYPE;
    bad:
	OF_close(handle);
	ofdev.handle = -1;
	return error;
}