static int
led_attach(device_t dev)
{
    struct led_softc *sc = device_get_softc(dev);
    struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));

    sc->sc_dev = dev;
    sc->sc_iot = sa->sc_iot;
    /* NB: write anywhere works, use first location */
    if (bus_space_map(sc->sc_iot, CAMBRIA_OCTAL_LED_HWBASE, sizeof(uint8_t),
                      0, &sc->sc_ioh)) {
        device_printf(dev, "cannot map LED latch (0x%lx)",
                      CAMBRIA_OCTAL_LED_HWBASE);
        return ENXIO;
    }

    sc->sc_leds[0] = led_create(led_A, sc, "A");
    sc->sc_leds[1] = led_create(led_B, sc, "B");
    sc->sc_leds[2] = led_create(led_C, sc, "C");
    sc->sc_leds[3] = led_create(led_D, sc, "D");
    sc->sc_leds[4] = led_create(led_E, sc, "E");
    sc->sc_leds[5] = led_create(led_F, sc, "F");
    sc->sc_leds[6] = led_create(led_G, sc, "G");
    sc->sc_leds[7] = led_create(led_H, sc, "H");

    return 0;
}
示例#2
0
static int
auxio_attach_common(struct auxio_softc *sc)
{
	struct resource *res;
	int i;

	for (i = 0; i < sc->sc_nauxio; i++) {
		sc->sc_rid[i] = i;
		res = bus_alloc_resource_any(sc->sc_dev, SYS_RES_MEMORY,
		    &sc->sc_rid[i], RF_ACTIVE);
		if (res == NULL) {
			device_printf(sc->sc_dev,
			    "could not allocate resources\n");
			goto attach_fail;
		}
		sc->sc_res[i] = res;
		sc->sc_regt[i] = rman_get_bustag(res);
		sc->sc_regh[i] = rman_get_bushandle(res);
	}

	sc->sc_led_stat = auxio_led_read(sc) & AUXIO_LED_LED;
	sc->sc_led_dev = led_create(auxio_led_func, sc, "auxioled");
	/* turn on the LED */
	auxio_led_func(sc, 1);

	return (0);

attach_fail:
	auxio_free_resource(sc);

	return (ENXIO);
}
示例#3
0
static int
rbled_attach(device_t dev)
{
	struct rbled_softc *sc;
	phandle_t node;
	cell_t gp[2];

	sc = device_get_softc(dev);
	node = ofw_bus_get_node(dev);

	if (OF_getprop(node, "user_led", gp, sizeof(gp)) <= 0)
		return (ENXIO);
	
	sc->sc_gpio = OF_device_from_xref(gp[0]);
	if (sc->sc_gpio == NULL) {
		device_printf(dev, "No GPIO resource found!\n");
		return (ENXIO);
	}
	sc->sc_ledpin = gp[1];

	sc->sc_led = led_create(rbled_toggle, sc, "user_led");

	if (sc->sc_led == NULL)
		return (ENXIO);

	return (0);
}
static int
fled_attach(device_t dev)
{
    struct fled_softc *sc = device_get_softc(dev);

    sc->sc_led = led_create(fled_cb, dev, "front");

    return 0;
}
示例#5
0
void
terasic_de4led_attach(struct terasic_de4led_softc *sc)
{
	const char *cmd;

	TERASIC_DE4LED_LOCK_INIT(sc);

	/*
	 * Clear the LED array before we start.
	 */
	TERASIC_DE4LED_LOCK(sc);
	TERASIC_DE4LED_CLEARBAR(sc);
	terasic_de4led_update(sc);
	TERASIC_DE4LED_UNLOCK(sc);

	/*
	 * Register the LED array with led(4).
	 */
	sc->tdl_leds[0] = led_create(led_0, sc, "de4led_0");
	sc->tdl_leds[1] = led_create(led_1, sc, "de4led_1");
	sc->tdl_leds[2] = led_create(led_2, sc, "de4led_2");
	sc->tdl_leds[3] = led_create(led_3, sc, "de4led_3");
	sc->tdl_leds[4] = led_create(led_4, sc, "de4led_4");
	sc->tdl_leds[5] = led_create(led_5, sc, "de4led_5");
	sc->tdl_leds[6] = led_create(led_6, sc, "de4led_6");
	sc->tdl_leds[7] = led_create(led_7, sc, "de4led_7");

	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_0_cmd", &cmd) == 0)
		led_set("de4led_0", cmd);
	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_1_cmd", &cmd) == 0)
		led_set("de4led_1", cmd);
	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_2_cmd", &cmd) == 0)
		led_set("de4led_2", cmd);
	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_3_cmd", &cmd) == 0)
		led_set("de4led_3", cmd);
	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_4_cmd", &cmd) == 0)
		led_set("de4led_4", cmd);
	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_5_cmd", &cmd) == 0)
		led_set("de4led_5", cmd);
	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_6_cmd", &cmd) == 0)
		led_set("de4led_6", cmd);
	if (resource_string_value(device_get_name(sc->tdl_dev),
	    sc->tdl_unit, "de4led_7_cmd", &cmd) == 0)
		led_set("de4led_7", cmd);
}
示例#6
0
文件: 7seg.c 项目: lemoce/7seg
SeteSeg * seteSeg_create (char initPort, char isCathod, char isOn)
{
  SeteSeg * my7Seg = (SeteSeg *) malloc (sizeof(SeteSeg));

  for (int i = 0; i < 8; i++) 
    {
      my7Seg->segs[i] = led_create (initPort+i,(isCathod)?isOn:!isOn);
    }

  my7Seg->cathod = isCathod;

  return my7Seg;
}
示例#7
0
static int
epic_attach(device_t dev)
{
    struct epic_softc *sc;

    sc = device_get_softc(dev);
    if (bus_alloc_resources(dev, epic_res_spec, sc->sc_res)) {
        device_printf(dev, "failed to allocate resources\n");
        bus_release_resources(dev, epic_res_spec, sc->sc_res);
        return (ENXIO);
    }

    EPIC_LOCK_INIT(sc);

    if (bootverbose)
        device_printf(dev, "version 0x%x\n",
                      EPIC_FW_LED_READ(sc, EPIC_FW_VERSION));

    sc->sc_led_dev_alert = led_create(epic_led_alert, sc, "alert");
    sc->sc_led_dev_power = led_create(epic_led_power, sc, "power");

    return (0);
}
static int
led_avila_attach(device_t dev)
{
	struct led_avila_softc *sc = device_get_softc(dev);
	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));

	sc->sc_dev = dev;
	sc->sc_iot = sa->sc_iot;
	sc->sc_gpio_ioh = sa->sc_gpio_ioh;

	/* Configure LED GPIO pin as output */
	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER,
	    GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER) &~ GPIO_LED_STATUS_BIT);

	sc->sc_led = led_create(led_func, sc, "gpioled");

	led_func(sc, 1);		/* Turn on LED */

	return (0);
}
示例#9
0
文件: gpioled.c 项目: Lxg1582/freebsd
static int
gpioled_attach(device_t dev)
{
	struct gpioled_softc *sc;
#ifdef FDT
	phandle_t node;
	char *name;
#else
	const char *name;
#endif

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	sc->sc_busdev = device_get_parent(dev);
	GPIOLED_LOCK_INIT(sc);
#ifdef FDT
	name = NULL;
	if ((node = ofw_bus_get_node(dev)) == -1)
		return (ENXIO);
	if (OF_getprop_alloc(node, "label", 1, (void **)&name) == -1)
		OF_getprop_alloc(node, "name", 1, (void **)&name);
#else
	if (resource_string_value(device_get_name(dev), 
	    device_get_unit(dev), "name", &name))
		name = NULL;
#endif

	sc->sc_leddev = led_create(gpioled_control, sc, name ? name :
	    device_get_nameunit(dev));
#ifdef FDT
	if (name != NULL)
		free(name, M_OFWPROP);
#endif

	return (0);
}
示例#10
0
static int
sysctl_machdep_elan_gpio_config(SYSCTL_HANDLER_ARGS)
{
	u_int u, v;
	int i, np, ne;
	int error;
	char buf[32];
	char tmp[10];

	error = SYSCTL_OUT(req, gpio_config, 33);
	if (error != 0 || req->newptr == NULL)
		return (error);
	if (req->newlen != 32)
		return (EINVAL);
	error = SYSCTL_IN(req, buf, 32);
	if (error != 0)
		return (error);
	/* Disallow any disabled pins and count pps and echo */
	np = ne = 0;
	for (i = 0; i < 32; i++) {
		if (gpio_config[i] == '-' && buf[i] == '.')
			buf[i] = gpio_config[i];
		if (gpio_config[i] == '-' && buf[i] != '-')
			return (EPERM);
		if (buf[i] == 'P') {
			np++;
			if (np > 1)
				return (EINVAL);
		}
		if (buf[i] == 'e' || buf[i] == 'E') {
			ne++;
			if (ne > 1)
				return (EINVAL);
		}
		if (buf[i] != 'L' && buf[i] != 'l'
#ifdef CPU_ELAN_PPS
		    && buf[i] != 'P' && buf[i] != 'E' && buf[i] != 'e'
#endif /* CPU_ELAN_PPS */
		    && buf[i] != '.' && buf[i] != '-')
			return (EINVAL);
	}
#ifdef CPU_ELAN_PPS
	if (np == 0)
		pps_a = pps_d = 0;
	if (ne == 0)
		echo_a = echo_d = 0;
#endif
	for (i = 0; i < 32; i++) {
		u = 1 << (i & 0xf);
		if (i >= 16)
			v = 2;
		else
			v = 0;
#ifdef CPU_SOEKRIS
		if (i == 9)
			;
		else
#endif
		if (buf[i] != 'l' && buf[i] != 'L' && led_dev[i] != NULL) {
			led_destroy(led_dev[i]);	
			led_dev[i] = NULL;
			mmcrptr[(0xc2a + v) / 2] &= ~u;
		}
		switch (buf[i]) {
#ifdef CPU_ELAN_PPS
		case 'P':
			pps_d = u;
			pps_a = 0xc30 + v;
			pps_ap[0] = &mmcrptr[pps_a / 2];
			pps_ap[1] = &elan_mmcr->GPTMR2CNT;
			pps_ap[2] = &elan_mmcr->GPTMR1CNT;
			mmcrptr[(0xc2a + v) / 2] &= ~u;
			gpio_config[i] = buf[i];
			break;
		case 'e':
		case 'E':
			echo_d = u;
			if (buf[i] == 'E')
				echo_a = 0xc34 + v;
			else
				echo_a = 0xc38 + v;
			mmcrptr[(0xc2a + v) / 2] |= u;
			gpio_config[i] = buf[i];
			break;
#endif /* CPU_ELAN_PPS */
		case 'l':
		case 'L':
			if (buf[i] == 'L')
				led_cookie[i] = (0xc34 + v) | (u << 16);
			else
				led_cookie[i] = (0xc38 + v) | (u << 16);
			if (led_dev[i])
				break;
			sprintf(tmp, "gpio%d", i);
			mmcrptr[(0xc2a + v) / 2] |= u;
			gpio_config[i] = buf[i];
			led_dev[i] =
			    led_create(gpio_led, &led_cookie[i], tmp);
			break;
		case '.':
			gpio_config[i] = buf[i];
			break;
		case '-':
		default:
			break;
		}
	}
	return (0);
}
示例#11
0
static int
clkbrd_attach(device_t dev)
{
	struct clkbrd_softc *sc;
	int i, slots;
	uint8_t r;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;

	for (i = CLKBRD_CF; i <= CLKBRD_CLKVER; i++) {
		sc->sc_rid[i] = i;
		sc->sc_res[i] = bus_alloc_resource_any(sc->sc_dev,
		    SYS_RES_MEMORY, &sc->sc_rid[i], RF_ACTIVE);
		if (sc->sc_res[i] == NULL) {
			if (i != CLKBRD_CLKVER) {
				device_printf(sc->sc_dev,
				    "could not allocate resource %d\n", i);
				goto fail;
			}
			continue;
		}
		sc->sc_bt[i] = rman_get_bustag(sc->sc_res[i]);
		sc->sc_bh[i] = rman_get_bushandle(sc->sc_res[i]);
		if (i == CLKBRD_CLKVER)
			sc->sc_flags |= CLKBRD_HAS_CLKVER;
	}

	slots = 4;
	r = bus_space_read_1(sc->sc_bt[CLKBRD_CLK], sc->sc_bh[CLKBRD_CLK],
	    CLK_STS1);
	switch (r & CLK_STS1_SLOTS_MASK) {
	case CLK_STS1_SLOTS_16:
		slots = 16;
		break;
	case CLK_STS1_SLOTS_8:
		slots = 8;
		break;
	case CLK_STS1_SLOTS_4:
		if (sc->sc_flags & CLKBRD_HAS_CLKVER) {
			r = bus_space_read_1(sc->sc_bt[CLKBRD_CLKVER],
			    sc->sc_bh[CLKBRD_CLKVER], CLKVER_SLOTS);
			if (r != 0 &&
			    (r & CLKVER_SLOTS_MASK) == CLKVER_SLOTS_PLUS)
				slots = 5;
		}
	}

	device_printf(sc->sc_dev, "Sun Enterprise Exx00 machine: %d slots\n",
	    slots);

	sc->sc_clk_ctrl = bus_space_read_1(sc->sc_bt[CLKBRD_CLK],
	    sc->sc_bh[CLKBRD_CLK], CLK_CTRL);
	sc->sc_led_dev = led_create(clkbrd_led_func, sc, "clockboard");

	return (0);

 fail:
	clkbrd_free_resources(sc);

	return (ENXIO);
}
示例#12
0
static int
ahci_em_attach(device_t dev)
{
	device_t parent = device_get_parent(dev);
	struct ahci_controller *ctlr = device_get_softc(parent);
	struct ahci_enclosure *enc = device_get_softc(dev);
	struct cam_devq *devq;
	int i, c, rid, error;
	char buf[32];

	enc->dev = dev;
	enc->quirks = ctlr->quirks;
	enc->channels = ctlr->channels;
	enc->ichannels = ctlr->ichannels;
	mtx_init(&enc->mtx, "AHCI enclosure lock", NULL, MTX_DEF);
	rid = 0;
	if (!(enc->r_memc = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &rid, RF_ACTIVE))) {
		mtx_destroy(&enc->mtx);
		return (ENXIO);
	}
	enc->capsem = ATA_INL(enc->r_memc, 0);
	rid = 1;
	if (!(enc->r_memt = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &rid, RF_ACTIVE))) {
		error = ENXIO;
		goto err0;
	}
	if ((enc->capsem & (AHCI_EM_XMT | AHCI_EM_SMB)) == 0) {
		rid = 2;
		if (!(enc->r_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
		    &rid, RF_ACTIVE))) {
			error = ENXIO;
			goto err0;
		}
	} else
		enc->r_memr = NULL;
	mtx_lock(&enc->mtx);
	if (ahci_em_reset(dev) != 0) {
	    error = ENXIO;
	    goto err1;
	}
	rid = ATA_IRQ_RID;
	/* Create the device queue for our SIM. */
	devq = cam_simq_alloc(1);
	if (devq == NULL) {
		device_printf(dev, "Unable to allocate SIM queue\n");
		error = ENOMEM;
		goto err1;
	}
	/* Construct SIM entry */
	enc->sim = cam_sim_alloc(ahciemaction, ahciempoll, "ahciem", enc,
	    device_get_unit(dev), &enc->mtx,
	    1, 0, devq);
	if (enc->sim == NULL) {
		cam_simq_free(devq);
		device_printf(dev, "Unable to allocate SIM\n");
		error = ENOMEM;
		goto err1;
	}
	if (xpt_bus_register(enc->sim, dev, 0) != CAM_SUCCESS) {
		device_printf(dev, "unable to register xpt bus\n");
		error = ENXIO;
		goto err2;
	}
	if (xpt_create_path(&enc->path, /*periph*/NULL, cam_sim_path(enc->sim),
	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
		device_printf(dev, "Unable to create path\n");
		error = ENXIO;
		goto err3;
	}
	mtx_unlock(&enc->mtx);
	if (bootverbose) {
		device_printf(dev, "Caps:%s%s%s%s%s%s%s%s\n",
		    (enc->capsem & AHCI_EM_PM) ? " PM":"",
		    (enc->capsem & AHCI_EM_ALHD) ? " ALHD":"",
		    (enc->capsem & AHCI_EM_XMT) ? " XMT":"",
		    (enc->capsem & AHCI_EM_SMB) ? " SMB":"",
		    (enc->capsem & AHCI_EM_SGPIO) ? " SGPIO":"",
		    (enc->capsem & AHCI_EM_SES2) ? " SES-2":"",
		    (enc->capsem & AHCI_EM_SAFTE) ? " SAF-TE":"",
		    (enc->capsem & AHCI_EM_LED) ? " LED":"");
	}
	if ((enc->capsem & AHCI_EM_LED)) {
		for (c = 0; c < enc->channels; c++) {
			if ((enc->ichannels & (1 << c)) == 0)
				continue;
			for (i = 0; i < AHCI_NUM_LEDS; i++) {
				enc->leds[c * AHCI_NUM_LEDS + i].dev = dev;
				enc->leds[c * AHCI_NUM_LEDS + i].num =
				    c * AHCI_NUM_LEDS + i;
			}
			if ((enc->capsem & AHCI_EM_ALHD) == 0) {
				snprintf(buf, sizeof(buf), "%s.%d.act",
				    device_get_nameunit(parent), c);
				enc->leds[c * AHCI_NUM_LEDS + 0].led =
				    led_create(ahci_em_led,
				    &enc->leds[c * AHCI_NUM_LEDS + 0], buf);
			}
			snprintf(buf, sizeof(buf), "%s.%d.locate",
			    device_get_nameunit(parent), c);
			enc->leds[c * AHCI_NUM_LEDS + 1].led =
			    led_create(ahci_em_led,
			    &enc->leds[c * AHCI_NUM_LEDS + 1], buf);
			snprintf(buf, sizeof(buf), "%s.%d.fault",
			    device_get_nameunit(parent), c);
			enc->leds[c * AHCI_NUM_LEDS + 2].led =
			    led_create(ahci_em_led,
			    &enc->leds[c * AHCI_NUM_LEDS + 2], buf);
		}
	}
	return (0);

err3:
	xpt_bus_deregister(cam_sim_path(enc->sim));
err2:
	cam_sim_free(enc->sim, /*free_devq*/TRUE);
err1:
	mtx_unlock(&enc->mtx);
	if (enc->r_memr)
		bus_release_resource(dev, SYS_RES_MEMORY, 2, enc->r_memr);
err0:
	if (enc->r_memt)
		bus_release_resource(dev, SYS_RES_MEMORY, 1, enc->r_memt);
	bus_release_resource(dev, SYS_RES_MEMORY, 0, enc->r_memc);
	mtx_destroy(&enc->mtx);
	return (error);
}
示例#13
0
static int
smu_attach(device_t dev)
{
	struct smu_softc *sc;
	phandle_t	node, child;
	uint8_t		data[12];

	sc = device_get_softc(dev);

	mtx_init(&sc->sc_mtx, "smu", NULL, MTX_DEF);
	sc->sc_cur_cmd = NULL;
	sc->sc_doorbellirqid = -1;

	sc->sc_u3 = 0;
	if (OF_finddevice("/u3") != -1)
		sc->sc_u3 = 1;

	/*
	 * Map the mailbox area. This should be determined from firmware,
	 * but I have not found a simple way to do that.
	 */
	bus_dma_tag_create(NULL, 16, 0, BUS_SPACE_MAXADDR_32BIT,
	    BUS_SPACE_MAXADDR, NULL, NULL, PAGE_SIZE, 1, PAGE_SIZE, 0, NULL,
	    NULL, &(sc->sc_dmatag));
	sc->sc_bt = &bs_le_tag;
	bus_space_map(sc->sc_bt, SMU_MAILBOX, 4, 0, &sc->sc_mailbox);

	/*
	 * Allocate the command buffer. This can be anywhere in the low 4 GB
	 * of memory.
	 */
	bus_dmamem_alloc(sc->sc_dmatag, (void **)&sc->sc_cmd, BUS_DMA_WAITOK | 
	    BUS_DMA_ZERO, &sc->sc_cmd_dmamap);
	bus_dmamap_load(sc->sc_dmatag, sc->sc_cmd_dmamap,
	    sc->sc_cmd, PAGE_SIZE, smu_phys_callback, sc, 0);
	STAILQ_INIT(&sc->sc_cmdq);

	/*
	 * Set up handlers to change CPU voltage when CPU frequency is changed.
	 */
	EVENTHANDLER_REGISTER(cpufreq_pre_change, smu_cpufreq_pre_change, dev,
	    EVENTHANDLER_PRI_ANY);
	EVENTHANDLER_REGISTER(cpufreq_post_change, smu_cpufreq_post_change, dev,
	    EVENTHANDLER_PRI_ANY);

	/*
	 * Detect and attach child devices.
	 */
	node = ofw_bus_get_node(dev);
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		char name[32];
		memset(name, 0, sizeof(name));
		OF_getprop(child, "name", name, sizeof(name));

		if (strncmp(name, "rpm-fans", 9) == 0 ||
		    strncmp(name, "fans", 5) == 0)
			smu_attach_fans(dev, child);

		if (strncmp(name, "sensors", 8) == 0)
			smu_attach_sensors(dev, child);

		if (strncmp(name, "smu-i2c-control", 15) == 0)
			smu_attach_i2c(dev, child);
	}

	/* Some SMUs have the I2C children directly under the bus. */
	smu_attach_i2c(dev, node);

	/*
	 * Collect calibration constants.
	 */
	smu_get_datablock(dev, SMU_CPUTEMP_CAL, data, sizeof(data));
	sc->sc_cpu_diode_scale = (data[4] << 8) + data[5];
	sc->sc_cpu_diode_offset = (data[6] << 8) + data[7];

	smu_get_datablock(dev, SMU_CPUVOLT_CAL, data, sizeof(data));
	sc->sc_cpu_volt_scale = (data[4] << 8) + data[5];
	sc->sc_cpu_volt_offset = (data[6] << 8) + data[7];
	sc->sc_cpu_curr_scale = (data[8] << 8) + data[9];
	sc->sc_cpu_curr_offset = (data[10] << 8) + data[11];

	smu_get_datablock(dev, SMU_SLOTPW_CAL, data, sizeof(data));
	sc->sc_slots_pow_scale = (data[4] << 8) + data[5];
	sc->sc_slots_pow_offset = (data[6] << 8) + data[7];

	/*
	 * Set up LED interface
	 */
	sc->sc_leddev = led_create(smu_set_sleepled, dev, "sleepled");

	/*
	 * Reset on power loss behavior
	 */

	SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
            SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
	    "server_mode", CTLTYPE_INT | CTLFLAG_RW, dev, 0,
	    smu_server_mode, "I", "Enable reboot after power failure");

	/*
	 * Set up doorbell interrupt.
	 */
	sc->sc_doorbellirqid = 0;
	sc->sc_doorbellirq = bus_alloc_resource_any(smu_doorbell, SYS_RES_IRQ,
	    &sc->sc_doorbellirqid, RF_ACTIVE);
	bus_setup_intr(smu_doorbell, sc->sc_doorbellirq,
	    INTR_TYPE_MISC | INTR_MPSAFE, NULL, smu_doorbell_intr, dev,
	    &sc->sc_doorbellirqcookie);
	powerpc_config_intr(rman_get_start(sc->sc_doorbellirq),
	    INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);

	/*
	 * Connect RTC interface.
	 */
	clock_register(dev, 1000);

	/*
	 * Learn about shutdown events
	 */
	EVENTHANDLER_REGISTER(shutdown_final, smu_shutdown, dev,
	    SHUTDOWN_PRI_LAST);

	return (bus_generic_attach(dev));
}
示例#14
0
SCI_STATUS isci_controller_initialize(struct ISCI_CONTROLLER *controller)
{
	SCIC_USER_PARAMETERS_T scic_user_parameters;
	SCI_CONTROLLER_HANDLE_T scic_controller_handle;
	char led_name[64];
	unsigned long tunable;
	uint32_t io_shortage;
	uint32_t fail_on_timeout;
	int i;

	scic_controller_handle =
	    scif_controller_get_scic_handle(controller->scif_controller_handle);

	if (controller->isci->oem_parameters_found == TRUE)
	{
		scic_oem_parameters_set(
		    scic_controller_handle,
		    &controller->oem_parameters,
		    (uint8_t)(controller->oem_parameters_version));
	}

	scic_user_parameters_get(scic_controller_handle, &scic_user_parameters);

	if (TUNABLE_ULONG_FETCH("hw.isci.no_outbound_task_timeout", &tunable))
		scic_user_parameters.sds1.no_outbound_task_timeout =
		    (uint8_t)tunable;

	if (TUNABLE_ULONG_FETCH("hw.isci.ssp_max_occupancy_timeout", &tunable))
		scic_user_parameters.sds1.ssp_max_occupancy_timeout =
		    (uint16_t)tunable;

	if (TUNABLE_ULONG_FETCH("hw.isci.stp_max_occupancy_timeout", &tunable))
		scic_user_parameters.sds1.stp_max_occupancy_timeout =
		    (uint16_t)tunable;

	if (TUNABLE_ULONG_FETCH("hw.isci.ssp_inactivity_timeout", &tunable))
		scic_user_parameters.sds1.ssp_inactivity_timeout =
		    (uint16_t)tunable;

	if (TUNABLE_ULONG_FETCH("hw.isci.stp_inactivity_timeout", &tunable))
		scic_user_parameters.sds1.stp_inactivity_timeout =
		    (uint16_t)tunable;

	if (TUNABLE_ULONG_FETCH("hw.isci.max_speed_generation", &tunable))
		for (i = 0; i < SCI_MAX_PHYS; i++)
			scic_user_parameters.sds1.phys[i].max_speed_generation =
			    (uint8_t)tunable;

	scic_user_parameters_set(scic_controller_handle, &scic_user_parameters);

	/* Scheduler bug in SCU requires SCIL to reserve some task contexts as a
	 *  a workaround - one per domain.
	 */
	controller->queue_depth = SCI_MAX_IO_REQUESTS - SCI_MAX_DOMAINS;

	if (TUNABLE_INT_FETCH("hw.isci.controller_queue_depth",
	    &controller->queue_depth)) {
		controller->queue_depth = max(1, min(controller->queue_depth,
		    SCI_MAX_IO_REQUESTS - SCI_MAX_DOMAINS));
	}

	/* Reserve one request so that we can ensure we have one available TC
	 *  to do internal device resets.
	 */
	controller->sim_queue_depth = controller->queue_depth - 1;

	/* Although we save one TC to do internal device resets, it is possible
	 *  we could end up using several TCs for simultaneous device resets
	 *  while at the same time having CAM fill our controller queue.  To
	 *  simulate this condition, and how our driver handles it, we can set
	 *  this io_shortage parameter, which will tell CAM that we have a
	 *  large queue depth than we really do.
	 */
	io_shortage = 0;
	TUNABLE_INT_FETCH("hw.isci.io_shortage", &io_shortage);
	controller->sim_queue_depth += io_shortage;

	fail_on_timeout = 1;
	TUNABLE_INT_FETCH("hw.isci.fail_on_task_timeout", &fail_on_timeout);
	controller->fail_on_task_timeout = fail_on_timeout;

	/* Attach to CAM using xpt_bus_register now, then immediately freeze
	 *  the simq.  It will get released later when initial domain discovery
	 *  is complete.
	 */
	controller->has_been_scanned = FALSE;
	mtx_lock(&controller->lock);
	isci_controller_attach_to_cam(controller);
	xpt_freeze_simq(controller->sim, 1);
	mtx_unlock(&controller->lock);

	for (i = 0; i < SCI_MAX_PHYS; i++) {
		controller->phys[i].handle = scic_controller_handle;
		controller->phys[i].index = i;

		/* fault */
		controller->phys[i].led_fault = 0;
		sprintf(led_name, "isci.bus%d.port%d.fault", controller->index, i);
		controller->phys[i].cdev_fault = led_create(isci_led_fault_func,
		    &controller->phys[i], led_name);
			
		/* locate */
		controller->phys[i].led_locate = 0;
		sprintf(led_name, "isci.bus%d.port%d.locate", controller->index, i);
		controller->phys[i].cdev_locate = led_create(isci_led_locate_func,
		    &controller->phys[i], led_name);
	}

	return (scif_controller_initialize(controller->scif_controller_handle));
}