Esempio n. 1
0
nl_config_t *
npf_config_retrieve(int fd, bool *active, bool *loaded)
{
	prop_dictionary_t npf_dict;
	nl_config_t *ncf;
	int error;

	error = prop_dictionary_recv_ioctl(fd, IOC_NPF_GETCONF, &npf_dict);
	if (error) {
		return NULL;
	}
	ncf = calloc(1, sizeof(*ncf));
	if (ncf == NULL) {
		prop_object_release(npf_dict);
		return NULL;
	}
	ncf->ncf_dict = npf_dict;
	ncf->ncf_alg_list = prop_dictionary_get(npf_dict, "algs");
	ncf->ncf_rules_list = prop_dictionary_get(npf_dict, "rules");
	ncf->ncf_rproc_list = prop_dictionary_get(npf_dict, "rprocs");
	ncf->ncf_table_list = prop_dictionary_get(npf_dict, "tables");
	ncf->ncf_nat_list = prop_dictionary_get(npf_dict, "translation");

	prop_dictionary_get_bool(npf_dict, "active", active);
	*loaded = (ncf->ncf_rules_list != NULL);
	return ncf;
}
Esempio n. 2
0
int
show_pkg_info_from_metadir(struct xbps_handle *xhp,
			   const char *pkgname,
			   const char *option)
{
	prop_dictionary_t d, pkgdb_d;
	const char *instdate, *pname;
	bool autoinst;

	d = xbps_dictionary_from_metadata_plist(xhp, pkgname, XBPS_PKGPROPS);
	if (d == NULL)
		return EINVAL;

	prop_dictionary_get_cstring_nocopy(d, "pkgname", &pname);
	pkgdb_d = xbps_pkgdb_get_pkgd(xhp, pname, false);
	if (pkgdb_d == NULL) {
		prop_object_release(d);
		return EINVAL;
	}
	if (prop_dictionary_get_cstring_nocopy(pkgdb_d,
	    "install-date", &instdate))
		prop_dictionary_set_cstring_nocopy(d, "install-date",
		    instdate);

	if (prop_dictionary_get_bool(pkgdb_d, "automatic-install", &autoinst))
		prop_dictionary_set_bool(d, "automatic-install", autoinst);

	if (option == NULL)
		show_pkg_info(d);
	else
		show_pkg_info_one(d, option);

	prop_object_release(d);
	return 0;
}
Esempio n. 3
0
static int
setapbridge(prop_dictionary_t env, prop_dictionary_t oenv)
{
	bool on, rc;

	rc = prop_dictionary_get_bool(env, "apbridge", &on);
	assert(rc);
	return set80211(env, IEEE80211_IOC_APBRIDGE, on ? 1 : 0, 0, NULL);
}
Esempio n. 4
0
static int
sethidessid(prop_dictionary_t env, prop_dictionary_t oenv)
{
	bool on, rc;

	rc = prop_dictionary_get_bool(env, "hidessid", &on);
	assert(rc);
	return set80211(env, IEEE80211_IOC_HIDESSID, on ? 1 : 0, 0, NULL);
}
Esempio n. 5
0
/*
 * npf_normalise_ctor: a constructor for the normalisation rule procedure
 * with the given parameters.
 */
static int
npf_normalise_ctor(npf_rproc_t *rp, prop_dictionary_t params)
{
	npf_normalise_t *np;

	/* Create a structure for normalisation parameters. */
	np = kmem_zalloc(sizeof(npf_normalise_t), KM_SLEEP);

	/* IP ID randomisation and IP_DF flag cleansing. */
	prop_dictionary_get_bool(params, "random-id", &np->n_random_id);
	prop_dictionary_get_bool(params, "no-df", &np->n_no_df);

	/* Minimum IP TTL and maximum TCP MSS. */
	prop_dictionary_get_uint32(params, "min-ttl", &np->n_minttl);
	prop_dictionary_get_uint32(params, "max-mss", &np->n_maxmss);

	/* Assign the parameters for this rule procedure. */
	npf_rproc_assign(rp, np);
	return 0;
}
static void
awin_fb_attach(device_t parent, device_t self, void *aux)
{
	struct awin_fb_softc *sc = device_private(self);
	struct awinfb_attach_args * const afb = aux;
	prop_dictionary_t cfg = device_properties(self);
	struct genfb_ops ops;

	if (awin_fb_consoledev == NULL)
		awin_fb_consoledev = self;

	sc->sc_gen.sc_dev = self;
	sc->sc_debedev = parent;
	sc->sc_dmat = afb->afb_dmat;
	sc->sc_dmasegs = afb->afb_dmasegs;
	sc->sc_ndmasegs = afb->afb_ndmasegs;
	sc->sc_mpdev = device_find_by_driver_unit("awinmp", 0);

	prop_dictionary_set_uint32(cfg, "width", afb->afb_width);
	prop_dictionary_set_uint32(cfg, "height", afb->afb_height);
	prop_dictionary_set_uint8(cfg, "depth", 32);
	prop_dictionary_set_uint16(cfg, "linebytes", afb->afb_width * 4);
	prop_dictionary_set_uint32(cfg, "address", 0);
	prop_dictionary_set_uint32(cfg, "virtual_address",
	    (uintptr_t)afb->afb_fb);

	genfb_init(&sc->sc_gen);

	if (sc->sc_gen.sc_width == 0 || sc->sc_gen.sc_fbsize == 0) {
		aprint_normal(": disabled\n");
		return;
	}

	pmf_device_register1(self, NULL, NULL, awin_fb_shutdown);

	memset(&ops, 0, sizeof(ops));
	ops.genfb_ioctl = awin_fb_ioctl;
	ops.genfb_mmap = awin_fb_mmap;

	aprint_naive("\n");

	bool is_console = false;
	prop_dictionary_get_bool(cfg, "is_console", &is_console);

	if (is_console)
		aprint_normal(": switching to framebuffer console\n");
	else
		aprint_normal("\n");

	genfb_attach(&sc->sc_gen, &ops);
}
Esempio n. 7
0
static int
setifpowersave(prop_dictionary_t env, prop_dictionary_t oenv)
{
	struct ieee80211_power power;
	bool on, rc;

	if (direct_ioctl(env, SIOCG80211POWER, &power) == -1)
		err(EXIT_FAILURE, "SIOCG80211POWER");

	rc = prop_dictionary_get_bool(env, "powersave", &on);
	assert(rc);

	power.i_enabled = on ? 1 : 0;
	if (direct_ioctl(env, SIOCS80211POWER, &power) == -1) {
		warn("SIOCS80211POWER");
		return -1;
	}
	return 0;
}
Esempio n. 8
0
File: list.c Progetto: xdave/xbps
int
list_manual_pkgs(struct xbps_handle *xhp,
		 prop_object_t obj,
		 void *arg,
		 bool *loop_done)
{
	const char *pkgver;
	bool automatic = false;

	(void)xhp;
	(void)arg;
	(void)loop_done;

	prop_dictionary_get_bool(obj, "automatic-install", &automatic);
	if (automatic == false) {
		prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);
		printf("%s\n", pkgver);
	}

	return 0;
}
Esempio n. 9
0
static void
awinio_attach(device_t parent, device_t self, void *aux)
{
	struct awinio_softc * const sc = &awinio_sc;
	uint16_t chip_id = awin_chip_id();
	const char *chip_name = awin_chip_name();
	const bool a10_p = chip_id == AWIN_CHIP_ID_A10;
	const bool a20_p = chip_id == AWIN_CHIP_ID_A20;
	const bool a31_p = chip_id == AWIN_CHIP_ID_A31;
	const bool a80_p = chip_id == AWIN_CHIP_ID_A80;
	prop_dictionary_t dict = device_properties(self);

	sc->sc_dev = self;

	sc->sc_bst = &armv7_generic_bs_tag;
	sc->sc_a4x_bst = &armv7_generic_a4x_bs_tag;
	sc->sc_bsh = awin_core_bsh;
	sc->sc_dmat = &awin_dma_tag;
	sc->sc_coherent_dmat = &awin_coherent_dma_tag;

	switch (awin_chip_id()) {
#ifdef ALLWINNER_A80
	case AWIN_CHIP_ID_A80:
		sc->sc_a80_core2_bsh = awin_core2_bsh;
		sc->sc_a80_rcpus_bsh = awin_rcpus_bsh;
		bus_space_subregion(sc->sc_bst, sc->sc_bsh,
		    AWIN_A80_CCU_SCLK_OFFSET, 0x1000, &sc->sc_ccm_bsh);
		bus_space_map(sc->sc_bst, AWIN_A80_USB_PBASE,
		    AWIN_A80_USB_SIZE, 0, &sc->sc_a80_usb_bsh);
		break;
#endif
	default:
		bus_space_subregion(sc->sc_bst, sc->sc_bsh, AWIN_CCM_OFFSET,
		    0x1000, &sc->sc_ccm_bsh);
		break;
	}

	aprint_naive("\n");
	aprint_normal(": %s (0x%04x)\n", chip_name, chip_id);

	const struct awin_locators * const eloc =
	    awin_locators + __arraycount(awin_locators);
	for (const struct awin_locators *loc = awin_locators; loc < eloc; loc++) {
		char prop_name[31];
		bool skip;
		if (loc->loc_port == AWINIOCF_PORT_DEFAULT) {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s", loc->loc_name);
		} else {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s-%d", loc->loc_name, loc->loc_port);
		}
		if (prop_dictionary_get_bool(dict, prop_name, &skip) && skip)
			continue;

		if (loc->loc_flags & AWINIO_ONLY) {
			if (a10_p && !(loc->loc_flags & AWINIO_ONLY_A10))
				continue;
			if (a20_p && !(loc->loc_flags & AWINIO_ONLY_A20))
				continue;
			if (a31_p && !(loc->loc_flags & AWINIO_ONLY_A31))
				continue;
			if (a80_p && !(loc->loc_flags & AWINIO_ONLY_A80))
				continue;
		}

		struct awinio_attach_args aio = {
			.aio_loc = *loc,
			.aio_core_bst = sc->sc_bst,
			.aio_core_a4x_bst = sc->sc_a4x_bst,
			.aio_core_bsh = sc->sc_bsh,
			.aio_ccm_bsh = sc->sc_ccm_bsh,
			.aio_a80_usb_bsh = sc->sc_a80_usb_bsh,
			.aio_a80_core2_bsh = sc->sc_a80_core2_bsh,
			.aio_a80_rcpus_bsh = sc->sc_a80_rcpus_bsh,
			.aio_dmat = sc->sc_dmat,
			.aio_coherent_dmat = sc->sc_coherent_dmat,
		};
		cfdata_t cf = config_search_ia(awinio_find,
		    sc->sc_dev, "awinio", &aio);
		if (cf == NULL) {
			if (loc->loc_flags & AWINIO_REQUIRED)
				panic("%s: failed to find %s!", __func__,
				    loc->loc_name);
			continue;
		}
		config_attach(sc->sc_dev, cf, &aio, awinio_print);
	}
}
Esempio n. 10
0
/*
 * npfctl_load: store passed data i.e. update settings, create passed
 * tables, rules and atomically activate all them.
 */
int
npfctl_load(u_long cmd, void *data)
{
	struct plistref *pref = data;
	prop_dictionary_t npf_dict, errdict;
	prop_array_t alglist, natlist, tables, rprocs, rules, conlist;
	npf_tableset_t *tblset = NULL;
	npf_rprocset_t *rpset = NULL;
	npf_ruleset_t *rlset = NULL;
	npf_ruleset_t *nset = NULL;
	npf_conndb_t *conndb = NULL;
	uint32_t ver = 0;
	size_t nitems;
	bool flush;
	int error;

	/* Retrieve the dictionary. */
#ifndef _NPF_TESTING
	error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_dict);
	if (error)
		return error;
#else
	npf_dict = (prop_dictionary_t)pref;
#endif

	/* Dictionary for error reporting and version check. */
	errdict = prop_dictionary_create();
	prop_dictionary_get_uint32(npf_dict, "version", &ver);
	if (ver != NPF_VERSION) {
		error = EPROGMISMATCH;
		goto fail;
	}

	/* ALGs. */
	alglist = prop_dictionary_get(npf_dict, "algs");
	error = npf_mk_algs(alglist, errdict);
	if (error) {
		goto fail;
	}

	/* NAT policies. */
	natlist = prop_dictionary_get(npf_dict, "nat");
	if ((nitems = prop_array_count(natlist)) > NPF_MAX_RULES) {
		error = E2BIG;
		goto fail;
	}

	nset = npf_ruleset_create(nitems);
	error = npf_mk_natlist(nset, natlist, errdict);
	if (error) {
		goto fail;
	}

	/* Tables. */
	tables = prop_dictionary_get(npf_dict, "tables");
	if ((nitems = prop_array_count(tables)) > NPF_MAX_TABLES) {
		error = E2BIG;
		goto fail;
	}
	tblset = npf_tableset_create(nitems);
	error = npf_mk_tables(tblset, tables, errdict);
	if (error) {
		goto fail;
	}

	/* Rule procedures. */
	rprocs = prop_dictionary_get(npf_dict, "rprocs");
	if ((nitems = prop_array_count(rprocs)) > NPF_MAX_RPROCS) {
		error = E2BIG;
		goto fail;
	}
	rpset = npf_rprocset_create();
	error = npf_mk_rprocs(rpset, rprocs, errdict);
	if (error) {
		goto fail;
	}

	/* Rules. */
	rules = prop_dictionary_get(npf_dict, "rules");
	if ((nitems = prop_array_count(rules)) > NPF_MAX_RULES) {
		error = E2BIG;
		goto fail;
	}

	rlset = npf_ruleset_create(nitems);
	error = npf_mk_rules(rlset, rules, rpset, errdict);
	if (error) {
		goto fail;
	}

	/* Connections (if loading any). */
	if ((conlist = prop_dictionary_get(npf_dict, "conn-list")) != NULL) {
		error = npf_mk_connlist(conlist, nset, &conndb, errdict);
		if (error) {
			goto fail;
		}
	}

	flush = false;
	prop_dictionary_get_bool(npf_dict, "flush", &flush);

	/*
	 * Finally - perform the load.
	 */
	npf_config_load(rlset, tblset, nset, rpset, conndb, flush);

	/* Done.  Since data is consumed now, we shall not destroy it. */
	tblset = NULL;
	rpset = NULL;
	rlset = NULL;
	nset = NULL;
fail:
	/*
	 * Note: destroy rulesets first, to drop references to the tableset.
	 */
	KASSERT(error == 0 || (nset || rpset || rlset || tblset));
	if (nset) {
		npf_ruleset_destroy(nset);
	}
	if (rlset) {
		npf_ruleset_destroy(rlset);
	}
	if (rpset) {
		npf_rprocset_destroy(rpset);
	}
	if (tblset) {
		npf_tableset_destroy(tblset);
	}
	prop_object_release(npf_dict);

	/* Error report. */
#ifndef _NPF_TESTING
	prop_dictionary_set_int32(errdict, "errno", error);
	prop_dictionary_copyout_ioctl(pref, cmd, errdict);
	prop_object_release(errdict);
	error = 0;
#endif
	return error;
}
Esempio n. 11
0
static void
obiosdhc_attach(device_t parent, device_t self, void *aux)
{
    struct obiosdhc_softc * const sc = device_private(self);
    struct obio_attach_args * const oa = aux;
    prop_dictionary_t prop = device_properties(self);
    uint32_t clkd, stat;
    int error, timo, clksft, n;
    bool support8bit = false;
    const char *transfer_mode = "PIO";
#ifdef TI_AM335X
    size_t i;
#endif

    prop_dictionary_get_bool(prop, "8bit", &support8bit);

    sc->sc.sc_dmat = oa->obio_dmat;
    sc->sc.sc_dev = self;
    sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS;
    sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON;
    sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC;
    sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
    if (support8bit)
        sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
#ifdef TI_AM335X
    sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET;
    sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
#endif
#if defined(OMAP_3530)
    sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
#endif
    sc->sc.sc_host = sc->sc_hosts;
    sc->sc.sc_clkbase = 96000;	/* 96MHZ */
    if (!prop_dictionary_get_uint32(prop, "clkmask", &sc->sc.sc_clkmsk))
        sc->sc.sc_clkmsk = 0x0000ffc0;
    sc->sc.sc_vendor_rod = obiosdhc_rod;
    sc->sc.sc_vendor_write_protect = obiosdhc_write_protect;
    sc->sc.sc_vendor_card_detect = obiosdhc_card_detect;
    sc->sc.sc_vendor_bus_clock = obiosdhc_bus_clock;
    sc->sc_bst = oa->obio_iot;

    clksft = ffs(sc->sc.sc_clkmsk) - 1;

    error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0,
                          &sc->sc_bsh);
    if (error) {
        aprint_error_dev(self,
                         "can't map registers: %d\n", error);
        return;
    }

    bus_space_subregion(sc->sc_bst, sc->sc_bsh, OMAP3_SDMMC_SDHC_OFFSET,
                        OMAP3_SDMMC_SDHC_SIZE, &sc->sc_sdhc_bsh);

#if NEDMA > 0
    if (oa->obio_edmabase != -1) {
        cv_init(&sc->sc_edma_cv, "sdhcedma");
        sc->sc_edma_fifo = oa->obio_addr +
                           OMAP3_SDMMC_SDHC_OFFSET + SDHC_DATA;
        obiosdhc_edma_init(sc, oa->obio_edmabase);
        sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
        sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
        sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN;
        sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
        sc->sc.sc_vendor_transfer_data_dma = obiosdhc_edma_xfer_data;
        transfer_mode = "EDMA";
    }
#endif

    aprint_naive("\n");
    aprint_normal(": SDHC controller (%s)\n", transfer_mode);

#ifdef TI_AM335X
    /* XXX Not really AM335X-specific.  */
    for (i = 0; i < __arraycount(am335x_sdhc); i++)
        if ((oa->obio_addr == am335x_sdhc[i].as_base_addr) &&
                (oa->obio_intr == am335x_sdhc[i].as_intr)) {
            prcm_module_enable(&am335x_sdhc[i].as_module);
            break;
        }
    KASSERT(i < __arraycount(am335x_sdhc));
#endif

    /* XXXXXX: Turn-on regulator via I2C. */
    /* XXXXXX: And enable ICLOCK/FCLOCK. */

    /* MMCHS Soft reset */
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
                      SYSCONFIG_SOFTRESET);
    timo = 3000000;	/* XXXX 3 sec. */
    while (timo--) {
        if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSSTATUS) &
                SYSSTATUS_RESETDONE)
            break;
        delay(1);
    }
    if (timo == 0)
        aprint_error_dev(self, "Soft reset timeout\n");
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_SYSCONFIG,
                      SYSCONFIG_ENAWAKEUP | SYSCONFIG_AUTOIDLE | SYSCONFIG_SIDLEMODE_AUTO |
                      SYSCONFIG_CLOCKACTIVITY_FCLK | SYSCONFIG_CLOCKACTIVITY_ICLK);

    sc->sc_ih = intr_establish(oa->obio_intr, IPL_VM, IST_LEVEL,
                               sdhc_intr, &sc->sc);
    if (sc->sc_ih == NULL) {
        aprint_error_dev(self, "failed to establish interrupt %d\n",
                         oa->obio_intr);
        goto fail;
    }

    error = sdhc_host_found(&sc->sc, sc->sc_bst, sc->sc_sdhc_bsh,
                            oa->obio_size - OMAP3_SDMMC_SDHC_OFFSET);
    if (error != 0) {
        aprint_error_dev(self, "couldn't initialize host, error=%d\n",
                         error);
        goto fail;
    }

    /* Set SDVS 1.8v and DTW 1bit mode */
    SDHC_WRITE(sc, SDHC_HOST_CTL,
               SDHC_VOLTAGE_1_8V << (SDHC_VOLTAGE_SHIFT + 8));
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_OD);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_INTCLK_ENABLE |
               SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_HOST_CTL,
               SDHC_READ(sc, SDHC_HOST_CTL) | SDHC_BUS_POWER << 8);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);

    /*
     * 22.6.1.3.1.5 MMCHS Controller INIT Procedure Start
     * from 'OMAP35x Applications Processor  Technical Reference Manual'.
     *
     * During the INIT procedure, the MMCHS controller generates 80 clock
     * periods. In order to keep the 1ms gap, the MMCHS controller should
     * be configured to generate a clock whose frequency is smaller or
     * equal to 80 KHz.
     */

    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
    clkd = CLKD(80);
    n = 1;
    while (clkd & ~(sc->sc.sc_clkmsk >> clksft)) {
        clkd >>= 1;
        n <<= 1;
    }
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | (clkd << clksft));
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);

    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT);
    for (; n > 0; n--) {
        SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
        timo = 3000000;	/* XXXX 3 sec. */
        stat = 0;
        while (!(stat & SDHC_COMMAND_COMPLETE)) {
            stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
            if (--timo == 0)
                break;
            delay(1);
        }
        if (timo == 0) {
            aprint_error_dev(self, "INIT Procedure timeout\n");
            break;
        }
        SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat);
    }
    bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
                      bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
    SDHC_WRITE(sc, SDHC_CLOCK_CTL,
               SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);

    return;

fail:
    if (sc->sc_ih) {
        intr_disestablish(sc->sc_ih);
        sc->sc_ih = NULL;
    }
    bus_space_unmap(sc->sc_bst, sc->sc_bsh, oa->obio_size);
}
Esempio n. 12
0
static void
awin_tcon0_set_video(struct awin_tcon_softc *sc)
{
	int32_t lcd_x, lcd_y, lcd_dclk_freq;
	int32_t lcd_hbp, lcd_ht, lcd_vbp, lcd_vt;
	int32_t lcd_hspw, lcd_vspw, lcd_io_cfg0;
	uint32_t vblk, start_delay;
	prop_dictionary_t cfg = device_properties(sc->sc_dev);
	uint32_t val;
	bool propb;
	bool dualchan = false;
	static struct videomode mode;

	if (!prop_dictionary_get_int32(cfg, "lcd_x", &lcd_x)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_x\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_y", &lcd_y)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_y\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_dclk_freq", &lcd_dclk_freq)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_dclk_freq\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_hbp", &lcd_hbp)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_hbp\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_ht", &lcd_ht)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_ht\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_vbp", &lcd_vbp)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_vbp\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_vt", &lcd_vt)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_vt\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_hspw", &lcd_hspw)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_hspw\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_vspw", &lcd_vspw)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_vspw\n");
		return;
	}
	if (!prop_dictionary_get_int32(cfg, "lcd_io_cfg0", &lcd_io_cfg0)) {
		aprint_error_dev(sc->sc_dev, ": can't read lcd_io_cfg0\n");
		return;
	}

	if (prop_dictionary_get_bool(cfg, "lvds_dual", &propb) && propb)
		dualchan = true;
	if (!awin_gpio_pinset_available(&awin_lvds0_pinset)) {
		aprint_error_dev(sc->sc_dev, "lvds0 pins not available\n");
		return;
	}
	if (dualchan && !awin_gpio_pinset_available(&awin_lvds1_pinset)) {
		aprint_error_dev(sc->sc_dev, "lvds1 pins not available\n");
		return;
	}
	awin_gpio_pinset_acquire(&awin_lvds0_pinset);
	if (dualchan) {
		awin_gpio_pinset_acquire(&awin_lvds1_pinset);
	}
	prop_dictionary_get_cstring_nocopy(cfg, "lcd_power_en",
	    &sc->sc_lcdpwr_pin_name);
	if (sc->sc_lcdpwr_pin_name != NULL) {
		if (!awin_gpio_pin_reserve(
		    sc->sc_lcdpwr_pin_name, &sc->sc_lcdpwr_pin)) {
			aprint_error_dev(sc->sc_dev,
			    "failed to reserve GPIO \"%s\" for LCD power\n",
			    sc->sc_lcdpwr_pin_name);
			sc->sc_lcdpwr_pin_name = NULL;
		} else {
			aprint_verbose_dev(sc->sc_dev,
			    ": using GPIO \"%s\" for LCD power\n", 
			    sc->sc_lcdpwr_pin_name);
		}
	}
	prop_dictionary_get_cstring_nocopy(cfg, "lcd_bl_en",
	    &sc->sc_lcdblk_pin_name);
	if (sc->sc_lcdblk_pin_name != NULL) {
		if (!awin_gpio_pin_reserve(
		    sc->sc_lcdblk_pin_name, &sc->sc_lcdblk_pin)) {
			aprint_error_dev(sc->sc_dev,
			    "failed to reserve GPIO \"%s\" for backlight\n",
			    sc->sc_lcdblk_pin_name);
			sc->sc_lcdblk_pin_name = NULL;
		} else {
			if (sc->sc_lcdpwr_pin_name == NULL) {
				aprint_verbose_dev(sc->sc_dev,
				    ": using GPIO \"%s\" for backlight\n", 
				    sc->sc_lcdblk_pin_name);
			} else {
				aprint_verbose(
				    ", GPIO \"%s\" for backlight\n", 
				    sc->sc_lcdblk_pin_name);
			}
		}
	}

	if (sc->sc_lcdpwr_pin_name != NULL) {
		awin_gpio_pindata_write(&sc->sc_lcdpwr_pin, 1);
	}

	vblk = (lcd_vt / 2) - lcd_y;
	start_delay = (vblk >= 32) ? 30 : (vblk - 2);

	if (lcd_dclk_freq > 150) /* hardware limit ? */
		lcd_dclk_freq = 150;
	awin_tcon_set_pll(sc, lcd_dclk_freq * 1000, 7);

	val = AWIN_TCONx_CTL_EN;
	val |= __SHIFTIN(start_delay, AWIN_TCONx_CTL_START_DELAY);
	/*
	 * the DE selector selects the primary DEBE for this tcon:
	 * 0 selects debe0 for tcon0 and debe1 for tcon1
	 */
	val |= __SHIFTIN(AWIN_TCONx_CTL_SRC_SEL_DE0,
			 AWIN_TCONx_CTL_SRC_SEL);
	TCON_WRITE(sc, AWIN_TCON0_CTL_REG, val);

	val =  (lcd_x - 1) << 16 |  (lcd_y - 1);
	TCON_WRITE(sc, AWIN_TCON0_BASIC0_REG, val);
	val = (lcd_ht - 1) << 16 | (lcd_hbp - 1);
	TCON_WRITE(sc, AWIN_TCON0_BASIC1_REG, val);
	val = (lcd_vt) << 16 | (lcd_vbp - 1);
	TCON_WRITE(sc, AWIN_TCON0_BASIC2_REG, val);
	val =  ((lcd_hspw > 0) ? (lcd_hspw - 1) : 0) << 16;
	val |= ((lcd_vspw > 0) ? (lcd_vspw - 1) : 0);
	TCON_WRITE(sc, AWIN_TCON0_BASIC3_REG, val);

	val = 0;
	if (dualchan)
		val |= AWIN_TCON0_LVDS_IF_DUALCHAN;
	if (prop_dictionary_get_bool(cfg, "lvds_mode_jeida", &propb) && propb)
		val |= AWIN_TCON0_LVDS_IF_MODE_JEIDA;
	if (prop_dictionary_get_bool(cfg, "lvds_18bits", &propb) && propb)
		val |= AWIN_TCON0_LVDS_IF_18BITS;
	TCON_WRITE(sc, AWIN_TCON0_LVDS_IF_REG, val);


	TCON_WRITE(sc, AWIN_TCON0_IO_POL_REG, lcd_io_cfg0);
	TCON_WRITE(sc, AWIN_TCON0_IO_TRI_REG, 0);
	TCON_WRITE(sc, AWIN_TCON_GINT1_REG,
	    __SHIFTIN(start_delay + 2, AWIN_TCON_GINT1_TCON0_LINENO));

	val = 0xf0000000;
	val &= ~AWIN_TCON0_DCLK_DIV;
	val |= __SHIFTIN(sc->sc_clk_div, AWIN_TCON0_DCLK_DIV);
	TCON_WRITE(sc, AWIN_TCON0_DCLK_REG, val);

	mode.dot_clock = lcd_dclk_freq;
	mode.hdisplay = lcd_x;
	mode.hsync_start = lcd_ht - lcd_hbp;
	mode.hsync_end = lcd_hspw + mode.hsync_start;
	mode.htotal = lcd_ht;
	mode.vdisplay = lcd_y;
	mode.vsync_start = lcd_vt - lcd_vbp;
	mode.vsync_end = lcd_vspw + mode.vsync_start;
	mode.vtotal = lcd_vt;
	mode.flags = 0;
	mode.name = NULL;

	awin_debe_set_videomode(sc->sc_debe_unit, &mode);

	/* and finally, enable it */
	awin_debe_enable(sc->sc_debe_unit, true);
	delay(20000);

	val = TCON_READ(sc, AWIN_TCON_GCTL_REG);
	val |= AWIN_TCON_GCTL_EN;
	TCON_WRITE(sc, AWIN_TCON_GCTL_REG, val);
	delay(20000);


	val = TCON_READ(sc, AWIN_TCON0_LVDS_IF_REG);
	val |= AWIN_TCON0_LVDS_IF_EN;
	TCON_WRITE(sc, AWIN_TCON0_LVDS_IF_REG, val);

	/* XXX
	 * magic values here from linux. these are not documented
	 * in the A20 user manual, and other Allwiner LVDS-capable SoC
	 * documentation don't make sense with these values
	 */
	val = TCON_READ(sc, AWIN_TCON_LVDS_ANA0);
	val |= 0x3F310000;
	TCON_WRITE(sc, AWIN_TCON_LVDS_ANA0, val);
	val = TCON_READ(sc, AWIN_TCON_LVDS_ANA0);
	val |= 1 << 22;
	TCON_WRITE(sc, AWIN_TCON_LVDS_ANA0, val);
	delay(2);
	val = TCON_READ(sc, AWIN_TCON_LVDS_ANA1);
	val |= (0x1f << 26 | 0x1f << 10);
	TCON_WRITE(sc, AWIN_TCON_LVDS_ANA1, val);
	delay(2);
	val = TCON_READ(sc, AWIN_TCON_LVDS_ANA1);
	val |= (0x1f << 16 | 0x1f << 0);
	TCON_WRITE(sc, AWIN_TCON_LVDS_ANA1, val);
	val = TCON_READ(sc, AWIN_TCON_LVDS_ANA0);
	val |= 1 << 22;
	TCON_WRITE(sc, AWIN_TCON_LVDS_ANA0, val);

	if (sc->sc_lcdblk_pin_name != NULL) {
		awin_gpio_pindata_write(&sc->sc_lcdblk_pin, 1);
	}
}
Esempio n. 13
0
static void
acer_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa)
{
	struct pciide_channel *cp;
	int channel;
	pcireg_t cr, interface;
	pcireg_t rev = PCI_REVISION(pa->pa_class);
	struct aceride_softc *acer_sc = (struct aceride_softc *)sc;

	if (pciide_chipen(sc, pa) == 0)
		return;

	aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
	    "bus-master DMA support present");
	pciide_mapreg_dma(sc, pa);
	aprint_verbose("\n");
	sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
	if (sc->sc_dma_ok) {
		sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA;
		if (rev >= 0x20) {
			sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA;
			if (rev >= 0xC7)
				sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
			else if (rev >= 0xC4)
				sc->sc_wdcdev.sc_atac.atac_udma_cap = 5;
			else if (rev >= 0xC2)
				sc->sc_wdcdev.sc_atac.atac_udma_cap = 4;
			else
				sc->sc_wdcdev.sc_atac.atac_udma_cap = 2;
		}
		sc->sc_wdcdev.irqack = pciide_irqack;
		if (rev <= 0xc4) {
			sc->sc_wdcdev.dma_init = acer_dma_init;
			aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
			 "using PIO transfers above 137GB as workaround for "
			 "48bit DMA access bug, expect reduced performance\n");
		}
	}

	sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
	sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
	sc->sc_wdcdev.sc_atac.atac_set_modes = acer_setup_channel;
	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
	sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS;
	sc->sc_wdcdev.wdc_maxdrives = 2;

	pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CDRC,
	    (pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CDRC) |
		ACER_CDRC_DMA_EN) & ~ACER_CDRC_FIFO_DISABLE);

	/* Enable "microsoft register bits" R/W. */
	pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR3,
	    pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR3) | ACER_CCAR3_PI);
	pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR1,
	    pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR1) &
	    ~(ACER_CHANSTATUS_RO|PCIIDE_CHAN_RO(0)|PCIIDE_CHAN_RO(1)));
	pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CCAR2,
	    pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CCAR2) &
	    ~ACER_CHANSTATUSREGS_RO);
	cr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG);
	cr |= (PCIIDE_CHANSTATUS_EN << PCI_INTERFACE_SHIFT);
	
	{
		/*
		 * some BIOSes (port-cats ABLE) enable native mode, but don't
		 * setup everything correctly, so allow the forcing of
		 * compat mode
		 */
		bool force_compat_mode;
		bool property_is_set;
		property_is_set = prop_dictionary_get_bool(
				device_properties(sc->sc_wdcdev.sc_atac.atac_dev),
				"ali1543-ide-force-compat-mode",
				&force_compat_mode);
		if (property_is_set && force_compat_mode) {
			cr &= ~((PCIIDE_INTERFACE_PCI(0)
				| PCIIDE_INTERFACE_PCI(1))
				<< PCI_INTERFACE_SHIFT);
		}
	}

	pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG, cr);
	/* Don't use cr, re-read the real register content instead */
	interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag,
	    PCI_CLASS_REG));

	/* From linux: enable "Cable Detection" */
	if (rev >= 0xC2) {
		pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_0x4B,
		    pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_0x4B)
		    | ACER_0x4B_CDETECT);
	}

	wdc_allocate_regs(&sc->sc_wdcdev);
	if (rev == 0xC3) {
		/* install reset bug workaround */
		if (pci_find_device(&acer_sc->pcib_pa, acer_pcib_match) == 0) {
			aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
			    "WARNING: can't find pci-isa bridge\n");
		} else
			sc->sc_wdcdev.reset = acer_do_reset;
	}

	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
	     channel++) {
		cp = &sc->pciide_channels[channel];
		if (pciide_chansetup(sc, channel, interface) == 0)
			continue;
		if ((interface & PCIIDE_CHAN_EN(channel)) == 0) {
			aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
			    "%s channel ignored (disabled)\n", cp->name);
			cp->ata_channel.ch_flags |= ATACH_DISABLED;
			continue;
		}
		/* newer controllers seems to lack the ACER_CHIDS. Sigh */
		pciide_mapchan(pa, cp, interface,
		     (rev >= 0xC2) ? pciide_pci_intr : acer_pci_intr);
	}
}
Esempio n. 14
0
int
xbps_transaction_commit(struct xbps_handle *xhp)
{
    prop_object_t obj;
    prop_object_iterator_t iter;
    size_t i;
    const char *pkgname, *version, *pkgver, *tract;
    int rv = 0;
    bool update, install, sr;

    assert(prop_object_type(xhp->transd) == PROP_TYPE_DICTIONARY);

    update = install = false;
    iter = xbps_array_iter_from_dict(xhp->transd, "packages");
    if (iter == NULL)
        return EINVAL;
    /*
     * Download binary packages (if they come from a remote repository).
     */
    xbps_set_cb_state(xhp, XBPS_STATE_TRANS_DOWNLOAD, 0, NULL, NULL, NULL);
    if ((rv = download_binpkgs(xhp, iter)) != 0)
        goto out;
    /*
     * Check SHA256 hashes for binary packages in transaction.
     */
    xbps_set_cb_state(xhp, XBPS_STATE_TRANS_VERIFY, 0, NULL, NULL, NULL);
    if ((rv = check_binpkgs_hash(xhp, iter)) != 0)
        goto out;
    /*
     * Install, update, configure or remove packages as specified
     * in the transaction dictionary.
     */
    xbps_set_cb_state(xhp, XBPS_STATE_TRANS_RUN, 0, NULL, NULL, NULL);

    i = 0;
    while ((obj = prop_object_iterator_next(iter)) != NULL) {
        if ((xhp->transaction_frequency_flush > 0) &&
                (++i >= xhp->transaction_frequency_flush)) {
            rv = xbps_pkgdb_update(xhp, true);
            if (rv != 0 && rv != ENOENT)
                goto out;

            i = 0;
        }
        update = false;
        prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
        prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
        prop_dictionary_get_cstring_nocopy(obj, "version", &version);
        prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver);

        if (strcmp(tract, "remove") == 0) {
            update = false;
            sr = false;
            /*
             * Remove package.
             */
            prop_dictionary_get_bool(obj, "remove-and-update",
                                     &update);
            prop_dictionary_get_bool(obj, "softreplace", &sr);
            rv = xbps_remove_pkg(xhp, pkgname, version, update, sr);
            if (rv != 0)
                goto out;
        } else if (strcmp(tract, "configure") == 0) {
            /*
             * Reconfigure pending package.
             */
            rv = xbps_configure_pkg(xhp, pkgname, false, false, false);
            if (rv != 0)
                goto out;
        } else {
            /*
             * Install or update a package.
             */
            if (strcmp(tract, "update") == 0)
                update = true;
            else
                install = true;

            if (update) {
                /*
                 * Update a package: execute pre-remove
                 * action if found before unpacking.
                 */
                xbps_set_cb_state(xhp, XBPS_STATE_UPDATE, 0,
                                  pkgname, version, NULL);
                rv = xbps_remove_pkg(xhp, pkgname, version,
                                     true, false);
                if (rv != 0) {
                    xbps_set_cb_state(xhp,
                                      XBPS_STATE_UPDATE_FAIL,
                                      rv, pkgname, version,
                                      "%s: [trans] failed to update "
                                      "package to `%s': %s", pkgver,
                                      version, strerror(rv));
                    goto out;
                }
            } else {
                /* Install a package */
                xbps_set_cb_state(xhp, XBPS_STATE_INSTALL,
                                  0, pkgname, version, NULL);
            }
            /*
             * Unpack binary package.
             */
            if ((rv = xbps_unpack_binary_pkg(xhp, obj)) != 0)
                goto out;
            /*
             * Register package.
             */
            if ((rv = xbps_register_pkg(xhp, obj, false)) != 0)
                goto out;
        }
    }
    prop_object_iterator_reset(iter);

    /* force a flush now packages were removed/unpacked */
    if ((rv = xbps_pkgdb_update(xhp, true)) != 0)
        goto out;

    /* if there are no packages to install or update we are done */
    if (!update && !install)
        goto out;
    /*
     * Configure all unpacked packages.
     */
    xbps_set_cb_state(xhp, XBPS_STATE_TRANS_CONFIGURE, 0, NULL, NULL, NULL);

    i = 0;
    while ((obj = prop_object_iterator_next(iter)) != NULL) {
        if (xhp->transaction_frequency_flush > 0 &&
                ++i >= xhp->transaction_frequency_flush) {
            if ((rv = xbps_pkgdb_update(xhp, true)) != 0)
                goto out;

            i = 0;
        }

        prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract);
        if ((strcmp(tract, "remove") == 0) ||
                (strcmp(tract, "configure") == 0))
            continue;

        prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname);
        prop_dictionary_get_cstring_nocopy(obj, "version", &version);
        update = false;
        if (strcmp(tract, "update") == 0)
            update = true;

        rv = xbps_configure_pkg(xhp, pkgname, false, update, false);
        if (rv != 0)
            goto out;
        /*
         * Notify client callback when a package has been
         * installed or updated.
         */
        if (update) {
            xbps_set_cb_state(xhp, XBPS_STATE_UPDATE_DONE, 0,
                              pkgname, version, NULL);
        } else {
            xbps_set_cb_state(xhp, XBPS_STATE_INSTALL_DONE, 0,
                              pkgname, version, NULL);
        }
    }

    /* Force a flush now that packages are configured */
    rv = xbps_pkgdb_update(xhp, true);
out:
    prop_object_iterator_release(iter);

    return rv;
}
Esempio n. 15
0
static void
igmafb_attach(device_t parent, device_t self, void *aux)
{
    struct igmafb_softc *sc = device_private(self);
    struct igma_attach_args *iaa = (struct igma_attach_args *)aux;
    struct rasops_info *ri;
    prop_dictionary_t dict;
    bool is_console;
    unsigned long defattr;
    struct wsemuldisplaydev_attach_args waa;

    sc->sc_dev = self;

    aprint_normal("\n");

    dict = device_properties(self);
    prop_dictionary_get_bool(dict, "is_console", &is_console);
    if (iaa->iaa_console)
        is_console = true;

    sc->sc_chip = iaa->iaa_chip;

    sc->sc_fbaddr = bus_space_vaddr(sc->sc_chip.gmt, sc->sc_chip.gmh);
    sc->sc_fbsize = 16 * 1024 * 1024;

    igmafb_guess_size(sc, &sc->sc_width, &sc->sc_height);
    sc->sc_depth = 32;
    sc->sc_stride = (sc->sc_width*4 + 511)/512*512;

    aprint_normal("%s: %d x %d, %d bit, stride %d\n", device_xname(self),
                  sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride);

    aprint_normal("%s: %d MB video memory at 0x%p\n", device_xname(self),
                  (int)sc->sc_fbsize >> 20, (void *)sc->sc_chip.gmb);

    sc->sc_vga_save = kmem_alloc(256*1024, KM_SLEEP);

    igmafb_get_brightness(sc, &sc->sc_brightness);
    igmafb_get_brightness_max(sc, &sc->sc_brightness_max);
    sc->sc_backlight = sc->sc_brightness != 0;

    sc->sc_defaultscreen_descr = (struct wsscreen_descr) {
        "default",
        0, 0,
        NULL,
        8, 16,
        WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
        NULL
    };
    sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
    sc->sc_screenlist = (struct wsscreen_list) {
        1, sc->sc_screens
    };

    vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
               &igmafb_accessops);
    sc->vd.init_screen = igmafb_init_screen;

    /* enable hardware display */
    igmafb_set_mode(sc, true);

    ri = &sc->sc_console_screen.scr_ri;

    if (is_console) {
        vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
                          &defattr);

        sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC
                                           | VCONS_NO_COPYROWS | VCONS_NO_COPYCOLS;
        vcons_redraw_screen(&sc->sc_console_screen);

        sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
        sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
        sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
        sc->sc_defaultscreen_descr.ncols = ri->ri_cols;

        wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
                           defattr);
        vcons_replay_msgbuf(&sc->sc_console_screen);
    } else {
        if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
            /* do some minimal setup to avoid weirdness later */
            vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
                              &defattr);
        } else
            (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
    }

    waa.console = is_console;
    waa.scrdata = &sc->sc_screenlist;
    waa.accessops = &igmafb_accessops;
    waa.accesscookie = &sc->vd;

    config_found(sc->sc_dev, &waa, wsemuldisplaydevprint);
}

/*
 * wsdisplay accessops
 */

static int
igmafb_ioctl(void *v, void *vs, u_long cmd, void *data, int flags,
             struct lwp *l)
{
    struct vcons_data *vd = v;
    struct igmafb_softc *sc = vd->cookie;
    struct wsdisplay_fbinfo *wdf;
    struct vcons_screen *ms = vd->active;
    struct wsdisplayio_fbinfo *fbi;
    struct wsdisplay_param *param;
    int val;

    switch (cmd) {
    case WSDISPLAYIO_GTYPE:
        *(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
        return 0;
    case WSDISPLAYIO_GINFO:
        if (ms == NULL)
            return ENODEV;
        wdf = data;
        wdf->width  = ms->scr_ri.ri_width;
        wdf->height = ms->scr_ri.ri_height;
        wdf->depth  = ms->scr_ri.ri_depth;
        wdf->cmsize = 256; /* XXX */
        return 0;
    case WSDISPLAYIO_LINEBYTES:
        if (ms == NULL)
            return ENODEV;
        *(u_int *)data = ms->scr_ri.ri_stride;
        return 0;
    case WSDISPLAYIO_GET_FBINFO:
        fbi = data;
        return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
    case WSDISPLAYIO_SVIDEO:
        val = (*(u_int *)data) != WSDISPLAYIO_VIDEO_OFF;
        sc->sc_backlight = val;
        if (val)
            igmafb_set_brightness(sc, sc->sc_brightness);
        else
            igmafb_set_brightness(sc, 0);
        return 0;
    case WSDISPLAYIO_GETPARAM:
        param = (struct wsdisplay_param *)data;
        switch (param->param) {
        case WSDISPLAYIO_PARAM_BRIGHTNESS:
            param->min = 0;
            param->max = 255;
            if (sc->sc_backlight)
                igmafb_get_brightness(sc, &val);
            else
                val = sc->sc_brightness;
            val = val * 255 / sc->sc_brightness_max;
            param->curval = val;
            return 0;
        case WSDISPLAYIO_PARAM_BACKLIGHT:
            param->min = 0;
            param->max = 1;
            param->curval = sc->sc_backlight;
            return 0;
        }
        return EPASSTHROUGH;
    case WSDISPLAYIO_SETPARAM:
        param = (struct wsdisplay_param *)data;
        switch (param->param) {
        case WSDISPLAYIO_PARAM_BRIGHTNESS:
            val = param->curval;
            if (val < 0)
                val = 0;
            if (val > 255)
                val = 255;
            val = val * sc->sc_brightness_max / 255;
            sc->sc_brightness = val;
            if (sc->sc_backlight)
                igmafb_set_brightness(sc, val);
            return 0;
        case WSDISPLAYIO_PARAM_BACKLIGHT:
            val = param->curval;
            sc->sc_backlight = val;
            if (val)
                igmafb_set_brightness(sc, sc->sc_brightness);
            else
                igmafb_set_brightness(sc, 0);
            return 0;
        }
        return EPASSTHROUGH;
    }

    return EPASSTHROUGH;
}

static paddr_t
igmafb_mmap(void *v, void *vs, off_t offset, int prot)
{
    struct vcons_data *vd = v;
    struct igmafb_softc *sc = vd->cookie;

    if ((offset & PAGE_MASK) != 0)
        return -1;

    if (offset < 0 || offset >= sc->sc_fbsize)
        return -1;

    return bus_space_mmap(sc->sc_chip.gmt, sc->sc_chip.gmb, offset, prot,
                          BUS_SPACE_MAP_LINEAR);
}

static void
igmafb_pollc(void *v, int on)
{
    struct vcons_data *vd = v;
    struct igmafb_softc *sc = vd->cookie;

    if (sc == NULL)
        return;
    if (sc->sc_console_screen.scr_vd == NULL)
        return;

    if (on)
        vcons_enable_polling(&sc->vd);
    else
        vcons_disable_polling(&sc->vd);
}

static void
igmafb_init_screen(void *cookie, struct vcons_screen *scr,
                   int existing, long *defattr)
{
    struct igmafb_softc *sc = cookie;
    struct rasops_info *ri = &scr->scr_ri;

    memset(ri, 0, sizeof(struct rasops_info));

    ri->ri_depth = sc->sc_depth;
    ri->ri_width = sc->sc_width;
    ri->ri_height = sc->sc_height;
    ri->ri_stride = sc->sc_stride;
    ri->ri_flg = RI_CENTER | RI_FULLCLEAR;

    ri->ri_bits = (char *)sc->sc_fbaddr;

    if (existing) {
        ri->ri_flg |= RI_CLEAR;
    }

    switch (sc->sc_depth) {
    case 32:
        ri->ri_rnum = 8;
        ri->ri_gnum = 8;
        ri->ri_bnum = 8;
        ri->ri_rpos = 16;
        ri->ri_gpos = 8;
        ri->ri_bpos = 0;
        break;
    }

    rasops_init(ri, 0, 0);
    ri->ri_caps = WSSCREEN_WSCOLORS;

    rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
                    sc->sc_width / ri->ri_font->fontwidth);

    ri->ri_hw = scr;
}

static void
igmafb_guess_size(struct igmafb_softc *sc, int *widthp, int *heightp)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    int pipe = cd->use_pipe;
    u_int32_t r;

    r = co->read_reg(cd, PIPE_HTOTAL(pipe));
    *widthp = PIPE_HTOTAL_GET_ACTIVE(r);
    r = co->read_reg(cd, PIPE_VTOTAL(pipe));
    *heightp = PIPE_VTOTAL_GET_ACTIVE(r);

    aprint_normal("%s: vga active size %d x %d\n",
                  device_xname(sc->sc_dev),
                  *widthp, *heightp);

    if (*widthp < 640 || *heightp < 400) {
        r = co->read_reg(cd, PF_WINSZ(pipe));
        *widthp  = PF_WINSZ_GET_WIDTH(r);
        *heightp = PF_WINSZ_GET_HEIGHT(r);

        aprint_normal("%s: window size %d x %d\n",
                      device_xname(sc->sc_dev),
                      *widthp, *heightp);
    }

    if (*widthp  < 640) *widthp  = 640;
    if (*heightp < 400) *heightp = 400;
}

static void
igmafb_set_mode(struct igmafb_softc *sc, bool enable)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    int pipe = cd->use_pipe;
    u_int32_t r;
    u_int8_t b;
    int i;

    if (enable) {
        /* disable VGA machinery */
        b = co->read_vga(cd, 0x01);
        co->write_vga(cd, 0x01, b | 0x20);

        /* disable VGA compatible display */
        r = co->read_reg(cd, sc->sc_chip.vga_cntrl);
        co->write_reg(cd, sc->sc_chip.vga_cntrl, r | VGA_CNTRL_DISABLE);

        /* save VGA memory */
        memcpy(sc->sc_vga_save, sc->sc_fbaddr, 256*1024);

        /* configure panel fitter */
        co->write_reg(cd, PF_WINPOS(pipe),
                      PF_WINPOS_VAL(0, 0));
        co->write_reg(cd, PF_WINSZ(pipe),
                      PF_WINSZ_VAL(sc->sc_width, sc->sc_height));

        /* pipe size */
        co->write_reg(cd, PIPE_SRCSZ(pipe),
                      PIPE_SRCSZ_VAL(sc->sc_width, sc->sc_height));

        /* enable pipe */
        co->write_reg(cd, PIPE_CONF(pipe),
                      PIPE_CONF_ENABLE | PIPE_CONF_8BPP);

        /* configure planes */
        r = co->read_reg(cd, PRI_CTRL(pipe));
        r &= ~(PRI_CTRL_PIXFMTMSK | PRI_CTRL_TILED);
        r |= PRI_CTRL_ENABLE | PRI_CTRL_BGR;
        co->write_reg(cd, PRI_CTRL(pipe), r | cd->pri_cntrl);
        co->write_reg(cd, PRI_LINOFF(pipe), 0);
        co->write_reg(cd, PRI_STRIDE(pipe), sc->sc_stride);
        co->write_reg(cd, PRI_SURF(pipe), 0);
        co->write_reg(cd, PRI_TILEOFF(pipe), 0);

        if (cd->quirks & IGMA_PLANESTART_QUIRK)
            igmafb_planestart_quirk(sc);

        if (cd->quirks & IGMA_PFITDISABLE_QUIRK)
            igmafb_pfitdisable_quirk(sc);
    } else {
        /* disable planes */
        co->write_reg(cd, PRI_CTRL(pipe), 0 | cd->pri_cntrl);
        co->write_reg(cd, PRI_LINOFF(pipe), 0);
        co->write_reg(cd, PRI_STRIDE(pipe), 2560);
        co->write_reg(cd, PRI_SURF(pipe), 0);
        co->write_reg(cd, PRI_TILEOFF(pipe), 0);

        /* pipe size */
        co->write_reg(cd, PIPE_SRCSZ(pipe),
                      PIPE_SRCSZ_VAL(720,400));

        /* disable pipe */
        co->write_reg(cd, PIPE_CONF(pipe), 0);
        for (i=0; i<10; ++i) {
            delay(10);
            if ((co->read_reg(cd, PIPE_CONF(pipe)) & PIPE_CONF_STATE) == 0)
                break;
        }

        /* workaround before enabling VGA */
        r = co->read_reg(cd, 0x42000);
        co->write_reg(cd, 0x42000, (r & 0x1fffffff) | 0xa0000000);
        r = co->read_reg(cd, 0x42004);
        co->write_reg(cd, 0x42004, (r & 0xfbffffff) | 0x00000000);

        /* configure panel fitter */
        co->write_reg(cd, PF_WINPOS(pipe),
                      PF_WINPOS_VAL(0, 0));
        co->write_reg(cd, PF_WINSZ(pipe),
                      PF_WINSZ_VAL(sc->sc_width, sc->sc_height));

        /* enable VGA compatible display */
        r = co->read_reg(cd, sc->sc_chip.vga_cntrl);
        co->write_reg(cd, sc->sc_chip.vga_cntrl, r & ~VGA_CNTRL_DISABLE);

        /* enable VGA machinery */
        b = co->read_vga(cd, 0x01);
        co->write_vga(cd, 0x01, b & ~0x20);

        /* restore VGA memory */
        memcpy(sc->sc_fbaddr, sc->sc_vga_save, 256*1024);

        /* enable pipe again */
        co->write_reg(cd, PIPE_CONF(pipe),
                      PIPE_CONF_ENABLE | PIPE_CONF_6BPP | PIPE_CONF_DITHER);
    }
}

static void
igmafb_planestart_quirk(struct igmafb_softc *sc)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    int pipe = cd->use_pipe;
    u_int32_t cntrl, fwbcl;

    /* disable self refresh */
    fwbcl = co->read_reg(cd, FW_BLC_SELF);
    co->write_reg(cd, FW_BLC_SELF, fwbcl & ~FW_BLC_SELF_EN);

    cntrl = co->read_reg(cd, CUR_CNTR(pipe));
    co->write_reg(cd, CUR_CNTR(pipe), 1<<5 | 0x07);

    /* "wait for vblank" */
    delay(40000);

    co->write_reg(cd, CUR_CNTR(pipe), cntrl);
    co->write_reg(cd, CUR_BASE(pipe),
                  co->read_reg(cd, CUR_BASE(pipe)));

    co->write_reg(cd, FW_BLC_SELF, fwbcl);
}

static void
igmafb_pfitdisable_quirk(struct igmafb_softc *sc)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r;

    /* disable i965 panel fitter */
    r = co->read_reg(cd, PF_CTRL_I965);
    co->write_reg(cd, PF_CTRL_I965, r & ~PF_ENABLE);
}

static void
igmafb_get_brightness_max(struct igmafb_softc *sc, int *valp)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r, f;

    r = co->read_reg(cd, cd->backlight_cntrl);
    f = BACKLIGHT_GET_FREQ(r);
    if (f == 0) {
        r = co->read_reg(cd, RAWCLK_FREQ);
        f = r * 1000000 / (200 * 128);
        if (f == 0 || f > 32767)
            f = 125 * 100000 / (200 * 128);
    }

    *valp = f;
}

static void
igmafb_get_brightness(struct igmafb_softc *sc, int *valp)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r, v;

    r = co->read_reg(cd, cd->backlight_cntrl);
    v = BACKLIGHT_GET_CYCLE(r);
    *valp = v;
}

static void
igmafb_set_brightness(struct igmafb_softc *sc, int val)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r, f, l;

    r = co->read_reg(cd, cd->backlight_cntrl);
    f = BACKLIGHT_GET_FREQ(r);
    l = BACKLIGHT_GET_LEGACY(r);

    co->write_reg(cd, cd->backlight_cntrl,
                  BACKLIGHT_VAL(f,l,val));
}
static void
exyo_attach(device_t parent, device_t self, void *aux)
{
	const struct exyo_locators *l = NULL;
	struct exyo_softc * const sc = &exyo_sc;
	prop_dictionary_t dict = device_properties(self);
	size_t nl = 0;

	sc->sc_dev = self;
	sc->sc_bst = &exynos_bs_tag;
	sc->sc_a4x_bst = &exynos_a4x_bs_tag;
	sc->sc_bsh = exynos_core_bsh;
	sc->sc_dmat = &exynos_bus_dma_tag;
	sc->sc_coherent_dmat = &exynos_coherent_bus_dma_tag;

	const uint16_t product_id = EXYNOS_PRODUCT_ID(exynos_soc_id);
	aprint_naive(": Exynos %x\n", product_id);
	aprint_normal(": Exynos %x\n", product_id);

	/* add sysctl nodes */
	exynos_sysctl_cpufreq_init();

	/* add all children */
#if defined(EXYNOS4)
	if (IS_EXYNOS4_P()) {
		l = exynos4_locinfo.locators;
		nl = exynos4_locinfo.nlocators;
	}
#endif
#if defined(EXYNOS5)
	if (IS_EXYNOS5_P()) {
		l = exynos5_locinfo.locators;
		nl = exynos5_locinfo.nlocators;
	}	
#endif 
	KASSERT(l != NULL);
	KASSERT(nl > 0);

	for (const struct exyo_locators *loc = l; loc < l + nl; loc++) {
		char prop_name[31];
		bool skip;

		if (loc->loc_port == EXYOCF_PORT_DEFAULT) {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s", loc->loc_name);
		} else {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s-%d", loc->loc_name, loc->loc_port);
		}
		if (prop_dictionary_get_bool(dict, prop_name, &skip) && skip)
			continue;

		struct exyo_attach_args exyo = {
			.exyo_loc = *loc,
			.exyo_core_bst = sc->sc_bst,
			.exyo_core_a4x_bst = sc->sc_a4x_bst,
			.exyo_core_bsh = sc->sc_bsh,
			.exyo_dmat = sc->sc_dmat,
			.exyo_coherent_dmat = sc->sc_coherent_dmat,
		};
		cfdata_t cf = config_search_ia(exyo_find,
		    sc->sc_dev, "exyo", &exyo);
		if (cf == NULL) {
#ifdef EXYO_REQUIRED
			if (loc->loc_flags & EXYO_REQUIRED)
				panic("%s: failed to find %s!", __func__,
				    loc->loc_name);
#endif
			if (loc->loc_port == EXYOCF_PORT_DEFAULT) {
				aprint_verbose_dev(self, "%s not found\n",
				    loc->loc_name);
			} else {
				aprint_verbose_dev(self, "%s%d not found\n",
				    loc->loc_name, loc->loc_port);
			}
			continue;
		}
		config_attach(sc->sc_dev, cf, &exyo, exyo_print);
	}
}
Esempio n. 17
0
static void
awinio_attach(device_t parent, device_t self, void *aux)
{
	struct awinio_softc * const sc = &awinio_sc;
	const bool a10_p = CPU_ID_CORTEX_A8_P(curcpu()->ci_arm_cpuid);
	const bool a20_p = CPU_ID_CORTEX_A7_P(curcpu()->ci_arm_cpuid);
	prop_dictionary_t dict = device_properties(self);

	sc->sc_dev = self;

	sc->sc_bst = &awin_bs_tag;
	sc->sc_a4x_bst = &awin_a4x_bs_tag;
	sc->sc_bsh = awin_core_bsh;
	sc->sc_dmat = &awin_dma_tag;

	bus_space_subregion(sc->sc_bst, sc->sc_bsh, AWIN_CCM_OFFSET, 0x1000,
	    &sc->sc_ccm_bsh);

	aprint_naive("\n");
	aprint_normal("\n");

	const struct awin_locators * const eloc =
	    awin_locators + __arraycount(awin_locators);
	for (const struct awin_locators *loc = awin_locators; loc < eloc; loc++) {
		char prop_name[31];
		bool skip;
		if (loc->loc_port == AWINIOCF_PORT_DEFAULT) {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s", loc->loc_name);
		} else {
			snprintf(prop_name, sizeof(prop_name),
			    "no-%s-%d", loc->loc_name, loc->loc_port);
		}
		if (prop_dictionary_get_bool(dict, prop_name, &skip) && skip)
			continue;

		if (loc->loc_flags & AWINIO_ONLY) {
			if (a10_p && !(loc->loc_flags & AWINIO_ONLY_A10))
				continue;
			if (a20_p && !(loc->loc_flags & AWINIO_ONLY_A20))
				continue;
		}

		struct awinio_attach_args aio = {
			.aio_loc = *loc,
			.aio_core_bst = sc->sc_bst,
			.aio_core_a4x_bst = sc->sc_a4x_bst,
			.aio_core_bsh = sc->sc_bsh,
			.aio_ccm_bsh = sc->sc_ccm_bsh,
			.aio_dmat = sc->sc_dmat,
		};
		cfdata_t cf = config_search_ia(awinio_find,
		    sc->sc_dev, "awinio", &aio);
		if (cf == NULL) {
			if (loc->loc_flags & AWINIO_REQUIRED)
				panic("%s: failed to find %s!", __func__,
				    loc->loc_name);
			continue;
		}
		config_attach(sc->sc_dev, cf, &aio, awinio_print);
	}
}
Esempio n. 18
0
static void
adm1026_attach(device_t parent, device_t self, void *aux)
{
	struct adm1026_softc *sc = device_private(self);
	struct i2c_attach_args *ia = aux;
	prop_dictionary_t props = device_properties(self);
	uint8_t val, fan_div2;
	int err, div2_val;

	sc->sc_tag = ia->ia_tag;
	sc->sc_address = ia->ia_addr;
	sc->sc_dev = self;
	sc->sc_iic_flags = I2C_F_POLL;	/* Use polling during autoconf */

	sc->sc_multi_read = false;
	prop_dictionary_get_bool(props, "multi_read", &sc->sc_multi_read);
	if (prop_dictionary_get_uint8(props, "fan_div2", &fan_div2) != 0)
		div2_val = fan_div2;
	else
		div2_val = -1;

	(void) adm1026_ident(sc);
	aprint_normal(": ADM1026 hardware monitor: rev. 0x%x, step. 0x%x\n",
	    ADM1026_REVISION(sc->sc_rev), ADM1026_STEPPING(sc->sc_rev));

	/*
	 * Start monitoring if not already monitoring.
	 * Wait 1.8s for the fan readings to stabilise.
	 */
	if ((err = adm1026_read_reg(sc, ADM1026_CONF1, &val)) != 0) {
		aprint_error_dev(sc->sc_dev, ": unable to read conf1\n");
		return;
	}
	if (!(val & ADM1026_CONF1_MONITOR)) {
		aprint_normal_dev(sc->sc_dev,
		    ": starting monitoring, waiting 1.8s for readings\n");
		val |= ADM1026_CONF1_MONITOR;
		if ((err = adm1026_write_reg(sc, ADM1026_CONF1, val)) != 0) {
			aprint_error_dev(sc->sc_dev,
			    ": unable to write conf1\n");
			return;
		}
		delay(1800000);
	}
	sc->sc_cfg[0] = val;

	sc->sc_sme = sysmon_envsys_create();
	sc->sc_nfans = 0;
	adm1026_setup_fans(sc, div2_val);
	sc->sc_ntemps = 0;
	adm1026_setup_temps(sc);
	adm1026_setup_volts(sc);
	aprint_normal_dev(self, "%d fans, %d temperatures, %d voltages\n",
	    sc->sc_nfans, sc->sc_ntemps, sc->sc_ntemps == 3 ? 15 : 17);
	
        sc->sc_sme->sme_name = device_xname(self);
        sc->sc_sme->sme_cookie = sc;
        sc->sc_sme->sme_refresh = adm1026_refresh;
	if (sysmon_envsys_register(sc->sc_sme)) {
		aprint_error_dev(self,
		    "unable to register with sysmon\n");
		sysmon_envsys_destroy(sc->sc_sme);
		return;
	}

	if (!pmf_device_register(self, adm1026_pmf_suspend, adm1026_pmf_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");

	sc->sc_iic_flags = 0;	/* Drop polling flag */

	return;
}
int
siop_pci_attach_common(struct siop_pci_common_softc *pci_sc,
    struct siop_common_softc *siop_sc, struct pci_attach_args *pa,
    int (*intr)(void *))
{
	pci_chipset_tag_t pc = pa->pa_pc;
	pcitag_t tag = pa->pa_tag;
	const char *intrstr;
	pci_intr_handle_t intrhandle;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	pcireg_t memtype;
	prop_dictionary_t dict;
	int memh_valid, ioh_valid;
	bus_addr_t ioaddr, memaddr;
	bool use_pciclock;
	char intrbuf[PCI_INTRSTR_LEN];

	aprint_naive(": SCSI controller\n");

	pci_sc->sc_pp =
	    siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class));
	if (pci_sc->sc_pp == NULL) {
		aprint_error("sym: broken match/attach!!\n");
		return 0;
	}
	/* copy interesting infos about the chip */
	siop_sc->features = pci_sc->sc_pp->features;
#ifdef SIOP_SYMLED    /* XXX Should be a devprop! */
	siop_sc->features |= SF_CHIP_LED0;
#endif
	dict = device_properties(siop_sc->sc_dev);
	if (prop_dictionary_get_bool(dict, "use_pciclock", &use_pciclock))
		if (use_pciclock)
			siop_sc->features |= SF_CHIP_USEPCIC;
	siop_sc->maxburst = pci_sc->sc_pp->maxburst;
	siop_sc->maxoff = pci_sc->sc_pp->maxoff;
	siop_sc->clock_div = pci_sc->sc_pp->clock_div;
	siop_sc->clock_period = pci_sc->sc_pp->clock_period;
	siop_sc->ram_size = pci_sc->sc_pp->ram_size;

	siop_sc->sc_reset = siop_pci_reset;
	aprint_normal(": %s\n", pci_sc->sc_pp->name);
	pci_sc->sc_pc = pc;
	pci_sc->sc_tag = tag;
	siop_sc->sc_dmat = pa->pa_dmat;

	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x14);
	switch (memtype) {
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
		memh_valid = (pci_mapreg_map(pa, 0x14, memtype, 0,
		    &memt, &memh, &memaddr, NULL) == 0);
		break;
	default:
		memh_valid = 0;
	}

	ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, &ioaddr, NULL) == 0);

	if (memh_valid) {
		siop_sc->sc_rt = memt;
		siop_sc->sc_rh = memh;
		siop_sc->sc_raddr = memaddr;
	} else if (ioh_valid) {
		siop_sc->sc_rt = iot;
		siop_sc->sc_rh = ioh;
		siop_sc->sc_raddr = ioaddr;
	} else {
		aprint_error_dev(siop_sc->sc_dev,
		    "unable to map device registers\n");
		return 0;
	}

	if (siop_sc->features & SF_CHIP_RAM) {
		int bar;
		switch (memtype) {
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
			bar = 0x18;
			break;
		case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
			bar = 0x1c;
			break;
		default:
			aprint_error_dev(siop_sc->sc_dev,
			    "invalid memory type %d\n",
			    memtype);
			return 0;
		}
		if (pci_mapreg_map(pa, bar, memtype, 0,
                    &siop_sc->sc_ramt, &siop_sc->sc_ramh,
		    &siop_sc->sc_scriptaddr, NULL) == 0) {
			aprint_normal_dev(siop_sc->sc_dev,
			    "using on-board RAM\n");
		} else {
			aprint_error_dev(siop_sc->sc_dev,
			    "can't map on-board RAM\n");
			siop_sc->features &= ~SF_CHIP_RAM;
		}
	}

	if (pci_intr_map(pa, &intrhandle) != 0) {
		aprint_error_dev(siop_sc->sc_dev, "couldn't map interrupt\n");
		return 0;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle, intrbuf, sizeof(intrbuf));
	pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
	    intr, siop_sc);
	if (pci_sc->sc_ih != NULL) {
		aprint_normal_dev(siop_sc->sc_dev, "interrupting at %s\n",
		    intrstr ? intrstr : "unknown interrupt");
	} else {
		aprint_error_dev(siop_sc->sc_dev,
		    "couldn't establish interrupt");
		if (intrstr != NULL)
			aprint_error(" at %s", intrstr);
		aprint_error("\n");
		return 0;
	}
	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);
	return 1;
}
Esempio n. 20
0
/*
 * npfctl_reload: store passed data i.e. update settings, create passed
 * tables, rules and atomically activate all them.
 */
int
npfctl_reload(u_long cmd, void *data)
{
	struct plistref *pref = data;
	prop_dictionary_t npf_dict, errdict;
	prop_array_t natlist, tables, rprocs, rules;
	npf_tableset_t *tblset = NULL;
	npf_ruleset_t *rlset = NULL;
	npf_ruleset_t *nset = NULL;
	bool flush;
	int error;

	/* Retrieve the dictionary. */
#ifndef _NPF_TESTING
	error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_dict);
	if (error)
		return error;
#else
	npf_dict = (prop_dictionary_t)pref;
#endif

	/* Dictionary for error reporting. */
	errdict = prop_dictionary_create();

	/* NAT policies. */
	nset = npf_ruleset_create();
	natlist = prop_dictionary_get(npf_dict, "translation");
	error = npf_mk_natlist(nset, natlist, errdict);
	if (error) {
		goto fail;
	}

	/* Tables. */
	tblset = npf_tableset_create();
	tables = prop_dictionary_get(npf_dict, "tables");
	error = npf_mk_tables(tblset, tables, errdict);
	if (error) {
		goto fail;
	}

	/* Rules and rule procedures. */
	rlset = npf_ruleset_create();
	rprocs = prop_dictionary_get(npf_dict, "rprocs");
	rules = prop_dictionary_get(npf_dict, "rules");
	error = npf_mk_rules(rlset, rules, rprocs, errdict);
	if (error) {
		goto fail;
	}

	flush = false;
	prop_dictionary_get_bool(npf_dict, "flush", &flush);

	/*
	 * Finally - reload ruleset, tableset and NAT policies.
	 * Operation will be performed as a single transaction.
	 */
	npf_reload(npf_dict, rlset, tblset, nset, flush);

	/* Turn on/off session tracking accordingly. */
	npf_session_tracking(!flush);

	/* Done.  Since data is consumed now, we shall not destroy it. */
	tblset = NULL;
	rlset = NULL;
	nset = NULL;
fail:
	/*
	 * Note: destroy rulesets first, to drop references to the tableset.
	 */
	KASSERT(error == 0 || (nset || rlset || tblset));
	if (nset) {
		npf_ruleset_destroy(nset);
	}
	if (rlset) {
		npf_ruleset_destroy(rlset);
	}
	if (tblset) {
		npf_tableset_destroy(tblset);
	}
	if (error) {
		prop_object_release(npf_dict);
	}

	/* Error report. */
	prop_dictionary_set_int32(errdict, "errno", error);
#ifndef _NPF_TESTING
	prop_dictionary_copyout_ioctl(pref, cmd, errdict);
#endif
	prop_object_release(errdict);
	return 0;
}