コード例 #1
0
ファイル: services.c プロジェクト: freenas/freenas
static int
services_init(void)
{
	struct sysctl_oid *stree, *tmptree, *tmptree2;

	g_services = malloc(sizeof(*g_services),
		M_FREENAS_SYSCTL, M_ZERO | M_WAITOK);

	/* Services node */
	if ((stree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(g_freenas_sysctl_tree), OID_AUTO,
		"services", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add services node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		stree, &g_services->s_st)) != 0) {
		FAILRET("Failed to add services timeout node.\n", -1);
	}

	/* AFP node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"afp", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add afp node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->afp.s_st)) != 0) {
		FAILRET("Failed to add afp timeout node.\n", -1);
	}

	/* Domain Controller node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"domaincontroller", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add domain controller node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->dc.s_st)) != 0) {
		FAILRET("Failed to add domain controller timeout node.\n", -1);
	}

	g_services->dc.s_st.restart = 180;

	/* FTP node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"ftp", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add ftp node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->ftp.s_st)) != 0) {
		FAILRET("Failed to add ftp timeout node.\n", -1);
	}

	/* iSCSI node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"iscsi", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add iscsi node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->iscsi.s_st)) != 0) {
		FAILRET("Failed to add iscsi timeout node.\n", -1);
	}

	/* LLDP node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"lldp", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add lldp node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->lldp.s_st)) != 0) {
		FAILRET("Failed to add lldp timeout node.\n", -1);
	}

	/* NFS node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"nfs", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add nfs node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->nfs.s_st)) != 0) {
		FAILRET("Failed to add nfs timeout node.\n", -1);
	}

	/* Rsync node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"rsync", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add rsync node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->rsync.s_st)) != 0) {
		FAILRET("Failed to add rsync timeout node.\n", -1);
	}

	/* S3 node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"s3", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add s3 node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->s3.s_st)) != 0) {
		FAILRET("Failed to add s3 timeout node.\n", -1);
	}

	/* S.M.A.R.T. node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"smart", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add smart node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->smart.s_st)) != 0) {
		FAILRET("Failed to add smart timeout node.\n", -1);
	}

	/* SMB node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"smb", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add smb node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->smb.s_st)) != 0) {
		FAILRET("Failed to add smb timeout node.\n", -1);
	}

	g_services->smb.config.server_min_protocol = SMB2_02;
	g_services->smb.config.server_max_protocol = SMB3;
	g_services->smb.config.server_multi_channel = 0;

	/* SMB config */
	if ((tmptree2 = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(tmptree), OID_AUTO,
		"config", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add SMB config node.\n", -1);
	}
	
	SYSCTL_ADD_PROC(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(tmptree2), OID_AUTO,
		"server_min_protocol", CTLTYPE_STRING|CTLFLAG_RW,
		&g_services->smb.config.server_min_protocol, 0,
		sysctl_smb_server_proto, "A", "server min protocol");

	SYSCTL_ADD_PROC(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(tmptree2), OID_AUTO,
		"server_max_protocol", CTLTYPE_STRING|CTLFLAG_RW,
		&g_services->smb.config.server_max_protocol, 0,
		sysctl_smb_server_proto, "A", "server max protocol");

	SYSCTL_ADD_UINT(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(tmptree2), OID_AUTO,
		"server_multi_channel", CTLFLAG_RW,
		&g_services->smb.config.server_multi_channel, 0,
		"server multi channel support");

	/* SNMP node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"snmp", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add snmp node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->snmp.s_st)) != 0) {
		FAILRET("Failed to add snmp timeout node.\n", -1);
	}

	/* SSH node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"ssh", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add ssh node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->ssh.s_st)) != 0) {
		FAILRET("Failed to add ssh timeout node.\n", -1);
	}

	/* TFTP node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"tftp", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add tftp node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->tftp.s_st)) != 0) {
		FAILRET("Failed to add tftp timeout node.\n", -1);
	}

	/* UPS node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"ups", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add ups node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->ups.s_st)) != 0) {
		FAILRET("Failed to add ups timeout node.\n", -1);
	}

	/* WebDAV node */
	if ((tmptree = SYSCTL_ADD_NODE(&g_freenas_sysctl_ctx,
		SYSCTL_CHILDREN(stree), OID_AUTO,
		"webdav", CTLFLAG_RD, NULL, NULL)) == NULL) {
		FAILRET("Failed to add webdav node.\n", -1);
	}
	if ((freenas_sysctl_add_timeout_tree(&g_freenas_sysctl_ctx,
		tmptree, &g_services->webdav.s_st)) != 0) {
		FAILRET("Failed to add webdav timeout node.\n", -1);
	}

	return (0);
}
コード例 #2
0
ファイル: ti_i2c.c プロジェクト: coyizumi/cs111
static int
ti_i2c_attach(device_t dev)
{
	int err, rid;
	phandle_t node;
	struct ti_i2c_softc *sc;
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid_list *tree;
	uint16_t fifosz;

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

	/* Get the i2c device id from FDT. */
	node = ofw_bus_get_node(dev);
	if ((OF_getencprop(node, "i2c-device-id", &sc->device_id,
	    sizeof(sc->device_id))) <= 0) {
		device_printf(dev, "missing i2c-device-id attribute in FDT\n");
		return (ENXIO);
	}

	/* Get the memory resource for the register mapping. */
	rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->sc_mem_res == NULL) {
		device_printf(dev, "Cannot map registers.\n");
		return (ENXIO);
	}

	/* Allocate our IRQ resource. */
	rid = 0;
	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_ACTIVE | RF_SHAREABLE);
	if (sc->sc_irq_res == NULL) {
		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
		device_printf(dev, "Cannot allocate interrupt.\n");
		return (ENXIO);
	}

	TI_I2C_LOCK_INIT(sc);

	/* First of all, we _must_ activate the H/W. */
	err = ti_i2c_activate(dev);
	if (err) {
		device_printf(dev, "ti_i2c_activate failed\n");
		goto out;
	}

	/* Read the version number of the I2C module */
	sc->sc_rev = ti_i2c_read_2(sc, I2C_REG_REVNB_HI) & 0xff;

	/* Get the fifo size. */
	fifosz = ti_i2c_read_2(sc, I2C_REG_BUFSTAT);
	fifosz >>= I2C_BUFSTAT_FIFODEPTH_SHIFT;
	fifosz &= I2C_BUFSTAT_FIFODEPTH_MASK;

	device_printf(dev, "I2C revision %d.%d FIFO size: %d bytes\n",
	    sc->sc_rev >> 4, sc->sc_rev & 0xf, 8 << fifosz);

	/* Set the FIFO threshold to 5 for now. */
	sc->sc_fifo_trsh = 5;

	ctx = device_get_sysctl_ctx(dev);
	tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "i2c_clock",
	    CTLFLAG_RD | CTLTYPE_UINT | CTLFLAG_MPSAFE, dev, 0,
	    ti_i2c_sysctl_clk, "IU", "I2C bus clock");

	/* Activate the interrupt. */
	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
	    NULL, ti_i2c_intr, sc, &sc->sc_irq_h);
	if (err)
		goto out;

	/* Attach the iicbus. */
	if ((sc->sc_iicbus = device_add_child(dev, "iicbus", -1)) == NULL) {
		device_printf(dev, "could not allocate iicbus instance\n");
		err = ENXIO;
		goto out;
	}

	/* Probe and attach the iicbus */
	bus_generic_attach(dev);

out:
	if (err) {
		ti_i2c_deactivate(dev);
		TI_I2C_LOCK_DESTROY(sc);
	}

	return (err);
}
コード例 #3
0
static void
adb_init_trackpad(device_t dev)
{
	struct adb_mouse_softc *sc;
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid *tree;

	size_t r1_len;
	u_char r1[8];
	u_char r2[8];

	sc = device_get_softc(dev);

	r1_len = adb_read_register(dev, 1, r1);

	/* An Extended Mouse register1 must return 8 bytes. */
	if (r1_len != 8)
		return;

	if((r1[6] != 0x0d))
	{
		r1[6] = 0x0d;
		
		adb_write_register(dev, 1, 8, r1); 
      
		r1_len = adb_read_register(dev, 1, r1);
      
		if (r1[6] != 0x0d)
		{
			device_printf(dev, "ADB Mouse = 0x%x "
				      "(non-Extended Mode)\n", r1[6]);
			return;
		} else {
			device_printf(dev, "ADB Mouse = 0x%x "
				      "(Extended Mode)\n", r1[6]);
			
			/* Set ADB Extended Features to default values,
			   enabled. */
			r2[0] = 0x19; /* Clicking: 0x19 disabled 0x99 enabled */
			r2[1] = 0x94; /* Dragging: 0x14 disabled 0x94 enabled */
			r2[2] = 0x19;
			r2[3] = 0xff; /* DragLock: 0xff disabled 0xb2 enabled */
			r2[4] = 0xb2;
			r2[5] = 0x8a;
			r2[6] = 0x1b;
		       
			r2[7] = 0x57;  /* 0x57 bits 3:0 for W mode */
			
			adb_write_register(dev, 2, 8, r2);
			
		}
	}

	/*
	 * Set up sysctl
	 */
	ctx = device_get_sysctl_ctx(dev);
	tree = device_get_sysctl_tree(dev);
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tapping",
			CTLTYPE_INT | CTLFLAG_RW, sc, 0, adb_tapping_sysctl,
			"I", "Tapping the pad causes button events");
	return;
}
コード例 #4
0
ファイル: acpi_battery.c プロジェクト: 2asoft/freebsd
static int
acpi_battery_init(void)
{
    struct acpi_softc	*sc;
    device_t		 dev;
    int	 		 error;

    ACPI_SERIAL_ASSERT(battery);

    error = ENXIO;
    dev = devclass_get_device(devclass_find("acpi"), 0);
    if (dev == NULL)
	goto out;
    sc = device_get_softc(dev);

    error = acpi_register_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl,
	NULL);
    if (error != 0)
	goto out;
    error = acpi_register_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl,
	NULL);
    if (error != 0)
	goto out;
    error = acpi_register_ioctl(ACPIIO_BATT_GET_BIF, acpi_battery_ioctl, NULL);
    if (error != 0)
	goto out;
    error = acpi_register_ioctl(ACPIIO_BATT_GET_BST, acpi_battery_ioctl, NULL);
    if (error != 0)
	goto out;

    sysctl_ctx_init(&acpi_battery_sysctl_ctx);
    acpi_battery_sysctl_tree = SYSCTL_ADD_NODE(&acpi_battery_sysctl_ctx,
	SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "battery", CTLFLAG_RD,
	0, "battery status and info");
    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
	OID_AUTO, "life", CTLTYPE_INT | CTLFLAG_RD,
	&acpi_battery_battinfo.cap, 0, acpi_battery_sysctl, "I",
	"percent capacity remaining");
    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
	OID_AUTO, "time", CTLTYPE_INT | CTLFLAG_RD,
	&acpi_battery_battinfo.min, 0, acpi_battery_sysctl, "I",
	"remaining time in minutes");
    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
	OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RD,
	&acpi_battery_battinfo.state, 0, acpi_battery_sysctl, "I",
	"current status flags");
    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
	OID_AUTO, "units", CTLTYPE_INT | CTLFLAG_RD,
	NULL, 0, acpi_battery_units_sysctl, "I", "number of batteries");
    SYSCTL_ADD_INT(&acpi_battery_sysctl_ctx,
	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
	OID_AUTO, "info_expire", CTLFLAG_RW,
	&acpi_battery_info_expire, 0,
	"time in seconds until info is refreshed");

    acpi_batteries_initted = TRUE;

out:
    if (error != 0) {
	acpi_deregister_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl);
	acpi_deregister_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl);
	acpi_deregister_ioctl(ACPIIO_BATT_GET_BIF, acpi_battery_ioctl);
	acpi_deregister_ioctl(ACPIIO_BATT_GET_BST, acpi_battery_ioctl);
    }
    return (error);
}
コード例 #5
0
static int
ufoma_attach(device_t self)
{
	struct ufoma_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	usbd_device_handle dev = uaa->device;
	usb_config_descriptor_t *cd;
	usb_interface_descriptor_t *id;
	usb_endpoint_descriptor_t *ed;
	usb_mcpc_acm_descriptor *mad;
	struct ucom_softc *ucom = &sc->sc_ucom;
	const char *devname,*modename;
	int ctl_notify;
	int i,err;
	int elements;
	uByte *mode;
	struct sysctl_ctx_list *sctx;
	struct sysctl_oid *soid;
	
	ucom->sc_dev = self;
	ucom->sc_udev = dev;
	sc->sc_ctl_iface = uaa->iface;
	mtx_init(&sc->sc_mtx, "ufoma", NULL, MTX_DEF);	

	cd = usbd_get_config_descriptor(ucom->sc_udev);
	id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
	sc->sc_ctl_iface_no = id->bInterfaceNumber;
	
	devname = device_get_nameunit(self);
	device_printf(self, "iclass %d/%d ifno:%d\n",
	    id->bInterfaceClass, id->bInterfaceSubClass, sc->sc_ctl_iface_no);

	ctl_notify = -1;
	for (i = 0; i < id->bNumEndpoints; i++) {
		ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
		if (ed == NULL)
			continue;

		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
		    (ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT) {
			ctl_notify = ed->bEndpointAddress;
		}
	}

	if(ctl_notify== -1){
		/*NOTIFY is mandatory.*/
		printf("NOTIFY interface not found\n");
		goto error;
	}

	err = usbd_open_pipe_intr(sc->sc_ctl_iface, ctl_notify, 
	    USBD_SHORT_XFER_OK, &sc->sc_notify_pipe, sc, &sc->sc_notify_buf,
	    sizeof(sc->sc_notify_buf), ufoma_intr, USBD_DEFAULT_INTERVAL);
	if(err){
		printf("PIPE open error %d\n", err);
		goto error;
	}
	mad = ufoma_get_intconf(cd, id , UDESC_VS_INTERFACE, UDESCSUB_MCPC_ACM);
	if(mad ==NULL){
		goto error;
	}

	printf("%s:Supported Mode:", devname);
	for(mode = mad->bMode; 
	    mode < ((uByte *)mad + mad->bFunctionLength); mode++){
		modename = ufoma_mode_to_str(*mode);
		if(modename){
			printf("%s", ufoma_mode_to_str(*mode));
		}else{
			printf("(%x)", *mode);
		}
		if(mode != ((uByte*)mad + mad->bFunctionLength-1)){
			printf(",");
		}
	}
	printf("\n");

	if((mad->bType == UMCPC_ACM_TYPE_AB5)
	   ||(mad->bType == UMCPC_ACM_TYPE_AB6)){
		/*These does not have data interface*/
		sc->sc_is_ucom = 0;
		ufoma_init_pseudo_ucom(sc);
	}else{
		if(ufoma_init_modem(sc, uaa)){
			goto error;
		}
	}
	elements = mad->bFunctionLength - sizeof(*mad)+1;

	sc->sc_msgxf = usbd_alloc_xfer(ucom->sc_udev);
	sc->sc_nummsg = 0;

	/*Initialize Mode vars.*/
	sc->sc_modetable = malloc(elements + 1, M_USBDEV, M_WAITOK);
	sc->sc_modetable[0] = elements + 1;
	bcopy(mad->bMode, &sc->sc_modetable[1], elements);
	sc->sc_currentmode = UMCPC_ACM_MODE_UNLINKED;
	sc->sc_modetoactivate = mad->bMode[0];
	/*Sysctls*/
	sctx = device_get_sysctl_ctx(self);
	soid = device_get_sysctl_tree(self);

	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "supportmode",
			CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_support,
			"A", "Supporting port role");

	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "currentmode",
			CTLFLAG_RD|CTLTYPE_STRING, sc, 0, ufoma_sysctl_current,
			"A", "Current port role");

	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "openmode",
			CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open,
			"A", "Mode to transit when port is opened");
	return 0;
 error:
	if(sc->sc_modetable)
		free(sc->sc_modetable, M_USBDEV);
	return EIO;
}
コード例 #6
0
ファイル: xenbusb.c プロジェクト: 2trill2spill/freebsd
/**
 * Create read-only systcl nodes for xenbusb device ivar data.
 *
 * \param dev  The XenBus device instance to register with sysctl.
 */
static void
xenbusb_device_sysctl_init(device_t dev)
{
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid      *tree;

	ctx  = device_get_sysctl_ctx(dev);
	tree = device_get_sysctl_tree(dev);

        SYSCTL_ADD_PROC(ctx,
			SYSCTL_CHILDREN(tree),
			OID_AUTO,
			"xenstore_path",
			CTLTYPE_STRING | CTLFLAG_RD,
			dev,
			XENBUS_IVAR_NODE,
			xenbusb_device_sysctl_handler,
			"A",
			"XenStore path to device");

        SYSCTL_ADD_PROC(ctx,
			SYSCTL_CHILDREN(tree),
			OID_AUTO,
			"xenbus_dev_type",
			CTLTYPE_STRING | CTLFLAG_RD,
			dev,
			XENBUS_IVAR_TYPE,
			xenbusb_device_sysctl_handler,
			"A",
			"XenBus device type");

        SYSCTL_ADD_PROC(ctx,
			SYSCTL_CHILDREN(tree),
			OID_AUTO,
			"xenbus_connection_state",
			CTLTYPE_STRING | CTLFLAG_RD,
			dev,
			XENBUS_IVAR_STATE,
			xenbusb_device_sysctl_handler,
			"A",
			"XenBus state of peer connection");

        SYSCTL_ADD_PROC(ctx,
			SYSCTL_CHILDREN(tree),
			OID_AUTO,
			"xenbus_peer_domid",
			CTLTYPE_INT | CTLFLAG_RD,
			dev,
			XENBUS_IVAR_OTHEREND_ID,
			xenbusb_device_sysctl_handler,
			"I",
			"Xen domain ID of peer");

        SYSCTL_ADD_PROC(ctx,
			SYSCTL_CHILDREN(tree),
			OID_AUTO,
			"xenstore_peer_path",
			CTLTYPE_STRING | CTLFLAG_RD,
			dev,
			XENBUS_IVAR_OTHEREND_PATH,
			xenbusb_device_sysctl_handler,
			"A",
			"XenStore path to peer device");
}
コード例 #7
0
ファイル: bhnd_pmu.c プロジェクト: jaredmcneill/freebsd
/**
 * Default bhnd_pmu driver implementation of DEVICE_ATTACH().
 * 
 * @param dev PMU device.
 * @param res The PMU device registers. The driver will maintain a borrowed
 * reference to this resource for the lifetime of the device.
 */
int
bhnd_pmu_attach(device_t dev, struct bhnd_resource *res)
{
	struct bhnd_pmu_softc	*sc;
	struct sysctl_ctx_list	*ctx;
	struct sysctl_oid	*tree;
	devclass_t		 bhnd_class;
	device_t		 core, bus;
	int			 error;

	sc = device_get_softc(dev);
	sc->dev = dev;
	sc->quirks = 0;
	sc->res = res;

	/* Fetch capability flags */
	sc->caps = bhnd_bus_read_4(sc->res, BHND_PMU_CAP);

	/* Find the bus-attached core */
	bhnd_class = devclass_find("bhnd");
	core = sc->dev;
	while ((bus = device_get_parent(core)) != NULL) {
		if (device_get_devclass(bus) == bhnd_class)
			break;

		core = bus;
	}

	if (core == NULL) {
		device_printf(sc->dev, "bhnd bus not found\n");
		return (ENXIO);
	}

	/* Fetch chip and board info */
	sc->cid = *bhnd_get_chipid(core);

	if ((error = bhnd_read_board_info(core, &sc->board))) {
		device_printf(sc->dev, "error fetching board info: %d\n",
		    error);
		return (ENXIO);
	}

	/* Locate ChipCommon device */
	sc->chipc_dev = bhnd_find_child(bus, BHND_DEVCLASS_CC, 0);
	if (sc->chipc_dev == NULL) {
		device_printf(sc->dev, "chipcommon device not found\n");
		return (ENXIO);
	}

	/* Initialize query state */
	error = bhnd_pmu_query_init(&sc->query, dev, sc->cid, &bhnd_pmu_res_io,
	    sc);
	if (error)
		return (error);
	sc->io = sc->query.io; 
	sc->io_ctx = sc->query.io_ctx;

	BPMU_LOCK_INIT(sc);

	/* Set quirk flags */
	switch (sc->cid.chip_id) {
	case BHND_CHIPID_BCM4328:
	case BHND_CHIPID_BCM5354:
		/* HTAVAIL/ALPAVAIL are bitswapped in CLKCTL */
		sc->quirks |= BPMU_QUIRK_CLKCTL_CCS0;
		break;
	default:
		break;
	}

	/* Initialize PMU */
	if ((error = bhnd_pmu_init(sc))) {
		device_printf(sc->dev, "PMU init failed: %d\n", error);
		goto failed;
	}

	/* Set up sysctl nodes */
	ctx = device_get_sysctl_ctx(dev);
	tree = device_get_sysctl_tree(dev);

	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
	    "bus_freq", CTLTYPE_UINT | CTLFLAG_RD, sc, 0,
	    bhnd_pmu_sysctl_bus_freq, "IU", "Bus clock frequency");

	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
	    "cpu_freq", CTLTYPE_UINT | CTLFLAG_RD, sc, 0,
	    bhnd_pmu_sysctl_cpu_freq, "IU", "CPU clock frequency");
	
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
	    "mem_freq", CTLTYPE_UINT | CTLFLAG_RD, sc, 0,
	    bhnd_pmu_sysctl_mem_freq, "IU", "Memory clock frequency");

	return (0);

failed:
	BPMU_LOCK_DESTROY(sc);
	bhnd_pmu_query_fini(&sc->query);
	return (error);
}
コード例 #8
0
ファイル: randomdev_soft.c プロジェクト: AhmadTux/freebsd
/* ARGSUSED */
void
random_yarrow_init(void)
{
	int error, i;
	struct harvest *np;
	struct sysctl_oid *random_o, *random_sys_o, *random_sys_harvest_o;
	enum esource e;

	random_o = SYSCTL_ADD_NODE(&random_clist,
	    SYSCTL_STATIC_CHILDREN(_kern),
	    OID_AUTO, "random", CTLFLAG_RW, 0,
	    "Software Random Number Generator");

	random_yarrow_init_alg(&random_clist, random_o);

	random_sys_o = SYSCTL_ADD_NODE(&random_clist,
	    SYSCTL_CHILDREN(random_o),
	    OID_AUTO, "sys", CTLFLAG_RW, 0,
	    "Entropy Device Parameters");

	SYSCTL_ADD_PROC(&random_clist,
	    SYSCTL_CHILDREN(random_sys_o),
	    OID_AUTO, "seeded", CTLTYPE_INT | CTLFLAG_RW,
	    &random_systat.seeded, 1, random_check_boolean, "I",
	    "Seeded State");

	random_sys_harvest_o = SYSCTL_ADD_NODE(&random_clist,
	    SYSCTL_CHILDREN(random_sys_o),
	    OID_AUTO, "harvest", CTLFLAG_RW, 0,
	    "Entropy Sources");

	SYSCTL_ADD_PROC(&random_clist,
	    SYSCTL_CHILDREN(random_sys_harvest_o),
	    OID_AUTO, "ethernet", CTLTYPE_INT | CTLFLAG_RW,
	    &harvest.ethernet, 1, random_check_boolean, "I",
	    "Harvest NIC entropy");
	SYSCTL_ADD_PROC(&random_clist,
	    SYSCTL_CHILDREN(random_sys_harvest_o),
	    OID_AUTO, "point_to_point", CTLTYPE_INT | CTLFLAG_RW,
	    &harvest.point_to_point, 1, random_check_boolean, "I",
	    "Harvest serial net entropy");
	SYSCTL_ADD_PROC(&random_clist,
	    SYSCTL_CHILDREN(random_sys_harvest_o),
	    OID_AUTO, "interrupt", CTLTYPE_INT | CTLFLAG_RW,
	    &harvest.interrupt, 1, random_check_boolean, "I",
	    "Harvest IRQ entropy");
	SYSCTL_ADD_PROC(&random_clist,
	    SYSCTL_CHILDREN(random_sys_harvest_o),
	    OID_AUTO, "swi", CTLTYPE_INT | CTLFLAG_RW,
	    &harvest.swi, 0, random_check_boolean, "I",
	    "Harvest SWI entropy");

	/* Initialise the harvest fifos */
	STAILQ_INIT(&emptyfifo.head);
	emptyfifo.count = 0;
	for (i = 0; i < EMPTYBUFFERS; i++) {
		np = malloc(sizeof(struct harvest), M_ENTROPY, M_WAITOK);
		STAILQ_INSERT_TAIL(&emptyfifo.head, np, next);
	}
	for (e = RANDOM_START; e < ENTROPYSOURCE; e++) {
		STAILQ_INIT(&harvestfifo[e].head);
		harvestfifo[e].count = 0;
	}

	mtx_init(&harvest_mtx, "entropy harvest mutex", NULL, MTX_SPIN);

	/* Start the hash/reseed thread */
	error = kproc_create(random_kthread, NULL,
	    &random_kthread_proc, RFHIGHPID, 0, "yarrow");
	if (error != 0)
		panic("Cannot create entropy maintenance thread.");

	/* Register the randomness harvesting routine */
	random_yarrow_init_harvester(random_harvest_internal,
	    random_yarrow_read);
}
コード例 #9
0
ファイル: usb_ethernet.c プロジェクト: coyizumi/cs111
static void
ue_attach_post_task(struct usb_proc_msg *_task)
{
	struct usb_ether_cfg_task *task =
	    (struct usb_ether_cfg_task *)_task;
	struct usb_ether *ue = task->ue;
	struct ifnet *ifp;
	int error;
	char num[14];			/* sufficient for 32 bits */

	/* first call driver's post attach routine */
	ue->ue_methods->ue_attach_post(ue);

	UE_UNLOCK(ue);

	ue->ue_unit = alloc_unr(ueunit);
	usb_callout_init_mtx(&ue->ue_watchdog, ue->ue_mtx, 0);
	sysctl_ctx_init(&ue->ue_sysctl_ctx);

	error = 0;
	CURVNET_SET_QUIET(vnet0);
	ifp = if_alloc(IFT_ETHER);
	if (ifp == NULL) {
		device_printf(ue->ue_dev, "could not allocate ifnet\n");
		goto fail;
	}

	ifp->if_softc = ue;
	if_initname(ifp, "ue", ue->ue_unit);
	if (ue->ue_methods->ue_attach_post_sub != NULL) {
		ue->ue_ifp = ifp;
		error = ue->ue_methods->ue_attach_post_sub(ue);
	} else {
		ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
		if (ue->ue_methods->ue_ioctl != NULL)
			ifp->if_ioctl = ue->ue_methods->ue_ioctl;
		else
			ifp->if_ioctl = uether_ioctl;
		ifp->if_start = ue_start;
		ifp->if_init = ue_init;
		IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
		ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
		IFQ_SET_READY(&ifp->if_snd);
		ue->ue_ifp = ifp;

		if (ue->ue_methods->ue_mii_upd != NULL &&
		    ue->ue_methods->ue_mii_sts != NULL) {
			/* device_xxx() depends on this */
			mtx_lock(&Giant);
			error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp,
			    ue_ifmedia_upd, ue->ue_methods->ue_mii_sts,
			    BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0);
			mtx_unlock(&Giant);
		}
	}

	if (error) {
		device_printf(ue->ue_dev, "attaching PHYs failed\n");
		goto fail;
	}

	if_printf(ifp, "<USB Ethernet> on %s\n", device_get_nameunit(ue->ue_dev));
	ether_ifattach(ifp, ue->ue_eaddr);
	/* Tell upper layer we support VLAN oversized frames. */
	if (ifp->if_capabilities & IFCAP_VLAN_MTU)
		ifp->if_hdrlen = sizeof(struct ether_vlan_header);

	CURVNET_RESTORE();

	snprintf(num, sizeof(num), "%u", ue->ue_unit);
	ue->ue_sysctl_oid = SYSCTL_ADD_NODE(&ue->ue_sysctl_ctx,
	    &SYSCTL_NODE_CHILDREN(_net, ue),
	    OID_AUTO, num, CTLFLAG_RD, NULL, "");
	SYSCTL_ADD_PROC(&ue->ue_sysctl_ctx,
	    SYSCTL_CHILDREN(ue->ue_sysctl_oid), OID_AUTO,
	    "%parent", CTLTYPE_STRING | CTLFLAG_RD, ue, 0,
	    ue_sysctl_parent, "A", "parent device");

	UE_LOCK(ue);
	return;

fail:
	CURVNET_RESTORE();
	free_unr(ueunit, ue->ue_unit);
	if (ue->ue_ifp != NULL) {
		if_free(ue->ue_ifp);
		ue->ue_ifp = NULL;
	}
	UE_LOCK(ue);
	return;
}
コード例 #10
0
ファイル: adb_kbd.c プロジェクト: ele7enxxh/dtrace-pf
static int 
adb_kbd_attach(device_t dev) 
{
	struct adb_kbd_softc *sc;
	keyboard_switch_t *sw;
	uint32_t fkeys;
	phandle_t handle;

	sw = kbd_get_switch(KBD_DRIVER_NAME);
	if (sw == NULL) {
		return ENXIO;
	}

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	sc->sc_mode = K_RAW;
	sc->sc_state = 0;
	sc->have_led_control = 0;
	sc->buffers = 0;

	/* Try stepping forward to the extended keyboard protocol */
	adb_set_device_handler(dev,3);

	mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
	callout_init(&sc->sc_repeater, 0);

#ifdef AKBD_EMULATE_ATKBD
	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
            sizeof(fkey_tab) / sizeof(fkey_tab[0]));
#else
	#error ADB raw mode not implemented
#endif

	KBD_FOUND_DEVICE(&sc->sc_kbd);
	KBD_PROBE_DONE(&sc->sc_kbd);
	KBD_INIT_DONE(&sc->sc_kbd);
	KBD_CONFIG_DONE(&sc->sc_kbd);

	(*sw->enable)(&sc->sc_kbd);

	kbd_register(&sc->sc_kbd);

#ifdef KBD_INSTALL_CDEV
	if (kbd_attach(&sc->sc_kbd)) {
		adb_kbd_detach(dev);
		return ENXIO;
	}
#endif

	/* Check if we can read out the LED state from 
	   this keyboard by reading the key state register */
	if (adb_read_register(dev, 2, NULL) == 2)
		sc->have_led_control = 1;

	adb_set_autopoll(dev,1);

	handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
	if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
	    &fkeys, sizeof(fkeys)) != -1) {
		static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
		    "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
		struct sysctl_ctx_list *ctx;
		struct sysctl_oid *tree;
		int i;

		if (bootverbose)
			device_printf(dev, "Keyboard has embedded Fn keys\n");

		for (i = 0; i < 12; i++) {
			uint32_t keyval;
			char buf[3];
			if (OF_getprop(handle, key_names[i], &keyval,
			    sizeof(keyval)) < 0)
				continue;
			buf[0] = 1;
			buf[1] = i+1;
			buf[2] = keyval;
			adb_write_register(dev, 0, 3, buf);
		}
		adb_write_register(dev, 1, 2, &(uint16_t){0});

		ctx = device_get_sysctl_ctx(dev);
		tree = device_get_sysctl_tree(dev);

		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
		    "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, adb_fn_keys, "I",
		    "Set the Fn keys to be their F-key type as default");
	}

	return (0);
}
コード例 #11
0
static int
powernow_init(void)
{
	uint64_t	status;
	size_t		len    , freq_len;
	uint32_t	maxfid, maxvid, i;
	struct k8pnow_cpu_state *cstate;
	struct k8pnow_state *state;
	const char     *techname;
	u_int32_t	regs  [4];
	cpuspeed = 0;
	struct sysctl_oid *oid, *leaf;

	do_cpuid(0x80000000, regs);
	if (regs[0] < 0x80000007)
		return 1;
	do_cpuid(0x80000007, regs);
	if (!(regs[3] & AMD_PN_FID_VID))
		return 2;
	/* Extended CPUID signature value */
	do_cpuid(0x80000001, regs);
	cstate = kmalloc(sizeof(struct k8pnow_cpu_state), M_DEVBUF, M_WAITOK);
	cstate->n_states = 0;

	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
	maxfid = PN8_STA_MFID(status);
	maxvid = PN8_STA_MVID(status);

	if (PN8_STA_SFID(status) != PN8_STA_MFID(status))
		techname = "PowerNow!";
	else
		techname = "Cool`n'Quiet";
	k8pnow_states(cstate, regs[0], maxfid, maxvid);
	len = 0;
	if (cstate->n_states) {
		freq_len = cstate->n_states * (sizeof("9999 ") - 1) + 1;
		kprintf("%s speeds:",
			techname);
		for (i = cstate->n_states; i > 0; i--) {
			state = &cstate->state_table[i - 1];
			kprintf(" %d", state->freq);
			len += ksnprintf(freqs_available + len, freq_len - len, "%d%s",
					 state->freq,
					 i > 1 ? " " : "");
		}
		kprintf(" MHz\n");
		k8pnow_current_state = cstate;
		k8_powernow_setperf(k8_get_curfreq());
	} else {
		kfree(cstate, M_DEVBUF);
		kprintf("powernow: no power states found\n");
		return 3;
	}

	/*
	 * Setup the sysctl sub-tree machdep.powernow.*
	 */
	oid = SYSCTL_ADD_NODE(&machdep_powernow_ctx,
		     SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, "powernow",
			      CTLFLAG_RD, NULL, "");
	if (oid == NULL)
		return (EOPNOTSUPP);
	oid = SYSCTL_ADD_NODE(&machdep_powernow_ctx, SYSCTL_CHILDREN(oid),
			      OID_AUTO, "frequency", CTLFLAG_RD, NULL, "");
	if (oid == NULL)
		return (EOPNOTSUPP);
	leaf = SYSCTL_ADD_PROC(&machdep_powernow_ctx, SYSCTL_CHILDREN(oid),
		      OID_AUTO, "target", CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
			       powernow_sysctl_helper, "I",
			       "Target CPU frequency for AMD PowerNow!");
	if (leaf == NULL)
		return (EOPNOTSUPP);
	leaf = SYSCTL_ADD_PROC(&machdep_powernow_ctx, SYSCTL_CHILDREN(oid),
		     OID_AUTO, "current", CTLTYPE_INT | CTLFLAG_RD, NULL, 0,
			       powernow_sysctl_helper, "I",
			       "Current CPU frequency for AMD PowerNow!");
	if (leaf == NULL)
		return (EOPNOTSUPP);
	leaf = SYSCTL_ADD_STRING(&machdep_powernow_ctx, SYSCTL_CHILDREN(oid),
			 OID_AUTO, "available", CTLFLAG_RD, freqs_available,
				 sizeof(freqs_available),
			      "CPU frequencies supported by AMD PowerNow!");
	if (leaf == NULL)
		return (EOPNOTSUPP);
	return (0);
}
コード例 #12
0
ファイル: yarrow.c プロジェクト: Alkzndr/freebsd
void
random_yarrow_init_alg(struct sysctl_ctx_list *clist)
{
	int i;
	struct sysctl_oid *random_yarrow_o;

	/* Yarrow parameters. Do not adjust these unless you have
	 * have a very good clue about what they do!
	 */
	random_yarrow_o = SYSCTL_ADD_NODE(clist,
		SYSCTL_STATIC_CHILDREN(_kern_random),
		OID_AUTO, "yarrow", CTLFLAG_RW, 0,
		"Yarrow Parameters");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"gengateinterval", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.gengateinterval, 10,
		random_check_uint_gengateinterval, "I",
		"Generation gate interval");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"bins", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.bins, 10,
		random_check_uint_bins, "I",
		"Execution time tuner");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"fastthresh", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.pool[0].thresh, (3*(BLOCKSIZE*8))/4,
		random_check_uint_fastthresh, "I",
		"Fast reseed threshold");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"slowthresh", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.pool[1].thresh, (BLOCKSIZE*8),
		random_check_uint_slowthresh, "I",
		"Slow reseed threshold");

	SYSCTL_ADD_PROC(clist,
		SYSCTL_CHILDREN(random_yarrow_o), OID_AUTO,
		"slowoverthresh", CTLTYPE_INT|CTLFLAG_RW,
		&random_state.slowoverthresh, 2,
		random_check_uint_slowoverthresh, "I",
		"Slow over-threshold reseed");

	random_state.gengateinterval = 10;
	random_state.bins = 10;
	random_state.pool[0].thresh = (3*(BLOCKSIZE*8))/4;
	random_state.pool[1].thresh = (BLOCKSIZE*8);
	random_state.slowoverthresh = 2;
	random_state.which = FAST;

	/* Initialise the fast and slow entropy pools */
	for (i = 0; i < 2; i++)
		randomdev_hash_init(&random_state.pool[i].hash);

	/* Clear the counter */
	clear_counter();

	/* Set up a lock for the reseed process */
	mtx_init(&random_reseed_mtx, "Yarrow reseed", NULL, MTX_DEF);
}
コード例 #13
0
ファイル: bcm2835_cpufreq.c プロジェクト: fengsi/freebsd
static int
bcm2835_cpufreq_attach(device_t dev)
{
	struct bcm2835_cpufreq_softc *sc;
	struct sysctl_oid *oid;
	int err;

	/* set self dev */
	sc = device_get_softc(dev);
	sc->dev = dev;

	/* initial values */
	sc->arm_max_freq = -1;
	sc->arm_min_freq = -1;
	sc->core_max_freq = -1;
	sc->core_min_freq = -1;
	sc->sdram_max_freq = -1;
	sc->sdram_min_freq = -1;
	sc->max_voltage_core = 0;
	sc->min_voltage_core = 0;

	/* create VC mbox buffer */
	sc->dma_size = PAGE_SIZE;
	err = bus_dma_tag_create(
	    bus_get_dma_tag(sc->dev),
	    PAGE_SIZE, 0,		/* alignment, boundary */
	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
	    BUS_SPACE_MAXADDR,		/* highaddr */
	    NULL, NULL,			/* filter, filterarg */
	    sc->dma_size, 1,		/* maxsize, nsegments */
	    sc->dma_size, 0,		/* maxsegsize, flags */
	    NULL, NULL,			/* lockfunc, lockarg */
	    &sc->dma_tag);
	if (err) {
		device_printf(dev, "can't create DMA tag\n");
		return (ENXIO);
	}

	err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0,
	    &sc->dma_map);
	if (err) {
		bus_dma_tag_destroy(sc->dma_tag);
		device_printf(dev, "can't allocate dmamem\n");
		return (ENXIO);
	}

	err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf,
	    sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0);
	if (err) {
		bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
		bus_dma_tag_destroy(sc->dma_tag);
		device_printf(dev, "can't load DMA map\n");
		return (ENXIO);
	}
	/* OK, ready to use VC buffer */

	/* setup sysctl at first device */
	if (device_get_unit(dev) == 0) {
		sysctl_ctx_init(&bcm2835_sysctl_ctx);
		/* create node for hw.cpufreq */
		oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx,
		    SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq",
		    CTLFLAG_RD, NULL, "");

		/* Frequency (Hz) */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_arm_freq, "IU",
		    "ARM frequency (Hz)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_core_freq, "IU",
		    "Core frequency (Hz)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_sdram_freq, "IU",
		    "SDRAM frequency (Hz)");

		/* Turbo state */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_turbo, "IU",
		    "Disables dynamic clocking");

		/* Voltage (offset from 1.2V in units of 0.025V) */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
		    sysctl_bcm2835_cpufreq_voltage_core, "I",
		    "ARM/GPU core voltage"
		    "(offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram, "I",
		    "SDRAM voltage (offset from 1.2V in units of 0.025V)");

		/* Voltage individual SDRAM */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I",
		    "SDRAM controller voltage"
		    "(offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I",
		    "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc,
		    0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I",
		    "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");

		/* Temperature */
		SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
		    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
		    sysctl_bcm2835_cpufreq_temperature, "I",
		    "SoC temperature (thousandths of a degree C)");
	}

	/* ARM->VC lock */
	sema_init(&vc_sema, 1, "vcsema");

	/* register callback for using mbox when interrupts are enabled */
	sc->init_hook.ich_func = bcm2835_cpufreq_init;
	sc->init_hook.ich_arg = sc;

	if (config_intrhook_establish(&sc->init_hook) != 0) {
		bus_dmamap_unload(sc->dma_tag, sc->dma_map);
		bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
		bus_dma_tag_destroy(sc->dma_tag);
		device_printf(dev, "config_intrhook_establish failed\n");
		return (ENOMEM);
	}

	/* this device is controlled by cpufreq(4) */
	cpufreq_register(dev);

	return (0);
}
コード例 #14
0
ファイル: bcm2835_cpufreq.c プロジェクト: fengsi/freebsd
static void
bcm2835_cpufreq_init(void *arg)
{
	struct bcm2835_cpufreq_softc *sc = arg;
	struct sysctl_ctx_list *ctx;
	device_t cpu;
	int arm_freq, core_freq, sdram_freq;
	int arm_max_freq, arm_min_freq, core_max_freq, core_min_freq;
	int sdram_max_freq, sdram_min_freq;
	int voltage_core, voltage_sdram_c, voltage_sdram_i, voltage_sdram_p;
	int max_voltage_core, min_voltage_core;
	int max_voltage_sdram_c, min_voltage_sdram_c;
	int max_voltage_sdram_i, min_voltage_sdram_i;
	int max_voltage_sdram_p, min_voltage_sdram_p;
	int turbo, temperature;

	VC_LOCK(sc);

	/* current clock */
	arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_ARM);
	core_freq = bcm2835_cpufreq_get_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_CORE);
	sdram_freq = bcm2835_cpufreq_get_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_SDRAM);

	/* max/min clock */
	arm_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_ARM);
	arm_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_ARM);
	core_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_CORE);
	core_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_CORE);
	sdram_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_SDRAM);
	sdram_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
	    BCM2835_MBOX_CLOCK_ID_SDRAM);

	/* turbo mode */
	turbo = bcm2835_cpufreq_get_turbo(sc);
	if (turbo > 0)
		sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
	else
		sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;

	/* voltage */
	voltage_core = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_CORE);
	voltage_sdram_c = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
	voltage_sdram_i = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
	voltage_sdram_p = bcm2835_cpufreq_get_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);

	/* current values (offset from 1.2V) */
	sc->voltage_core = voltage_core;
	sc->voltage_sdram = voltage_sdram_c;
	sc->voltage_sdram_c = voltage_sdram_c;
	sc->voltage_sdram_i = voltage_sdram_i;
	sc->voltage_sdram_p = voltage_sdram_p;

	/* max/min voltage */
	max_voltage_core = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_CORE);
	min_voltage_core = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_CORE);
	max_voltage_sdram_c = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
	max_voltage_sdram_i = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
	max_voltage_sdram_p = bcm2835_cpufreq_get_max_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
	min_voltage_sdram_c = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
	min_voltage_sdram_i = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
	min_voltage_sdram_p = bcm2835_cpufreq_get_min_voltage(sc,
	    BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);

	/* temperature */
	temperature = bcm2835_cpufreq_get_temperature(sc);

	/* show result */
	if (cpufreq_verbose || bootverbose) {
		device_printf(sc->dev, "Boot settings:\n");
		device_printf(sc->dev,
		    "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
		    HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
		    (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");

		device_printf(sc->dev,
		    "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n",
		    HZ2MHZ(arm_max_freq), HZ2MHZ(arm_min_freq),
		    HZ2MHZ(core_max_freq), HZ2MHZ(core_min_freq),
		    HZ2MHZ(sdram_max_freq), HZ2MHZ(sdram_min_freq));

		device_printf(sc->dev,
		    "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, "
		    "SDRAM_P %dmV\n",
		    OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c),
		    OFFSET2MVOLT(voltage_sdram_i), 
		    OFFSET2MVOLT(voltage_sdram_p));

		device_printf(sc->dev,
		    "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, "
		    "SDRAM_P %d/%dmV\n",
		    OFFSET2MVOLT(max_voltage_core),
		    OFFSET2MVOLT(min_voltage_core),
		    OFFSET2MVOLT(max_voltage_sdram_c),
		    OFFSET2MVOLT(min_voltage_sdram_c),
		    OFFSET2MVOLT(max_voltage_sdram_i),
		    OFFSET2MVOLT(min_voltage_sdram_i),
		    OFFSET2MVOLT(max_voltage_sdram_p),
		    OFFSET2MVOLT(min_voltage_sdram_p));

		device_printf(sc->dev,
		    "Temperature %d.%dC\n", (temperature / 1000),
		    (temperature % 1000) / 100);
	} else { /* !cpufreq_verbose && !bootverbose */
		device_printf(sc->dev,
		    "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
		    HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
		    (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
	}

	/* keep in softc (MHz/mV) */
	sc->arm_max_freq = HZ2MHZ(arm_max_freq);
	sc->arm_min_freq = HZ2MHZ(arm_min_freq);
	sc->core_max_freq = HZ2MHZ(core_max_freq);
	sc->core_min_freq = HZ2MHZ(core_min_freq);
	sc->sdram_max_freq = HZ2MHZ(sdram_max_freq);
	sc->sdram_min_freq = HZ2MHZ(sdram_min_freq);
	sc->max_voltage_core = OFFSET2MVOLT(max_voltage_core);
	sc->min_voltage_core = OFFSET2MVOLT(min_voltage_core);

	/* if turbo is on, set to max values */
	if (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) {
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
		    arm_max_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
		    core_max_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc,
		    BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_max_freq);
		DELAY(TRANSITION_LATENCY);
	} else {
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
		    arm_min_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
		    core_min_freq);
		DELAY(TRANSITION_LATENCY);
		bcm2835_cpufreq_set_clock_rate(sc,
		    BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_min_freq);
		DELAY(TRANSITION_LATENCY);
	}

	VC_UNLOCK(sc);

	/* add human readable temperature to dev.cpu node */
	cpu = device_get_parent(sc->dev);
	if (cpu != NULL) {
		ctx = device_get_sysctl_ctx(cpu);
		SYSCTL_ADD_PROC(ctx,
		    SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), OID_AUTO,
		    "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
		    sysctl_bcm2835_devcpu_temperature, "IK",
		    "Current SoC temperature");
	}

	/* release this hook (continue boot) */
	config_intrhook_disestablish(&sc->init_hook);
}
コード例 #15
0
ファイル: ieee80211_freebsd.c プロジェクト: Alkzndr/freebsd
void
ieee80211_sysctl_vattach(struct ieee80211vap *vap)
{
	struct ifnet *ifp = vap->iv_ifp;
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid *oid;
	char num[14];			/* sufficient for 32 bits */

	ctx = (struct sysctl_ctx_list *) malloc(sizeof(struct sysctl_ctx_list),
		M_DEVBUF, M_NOWAIT | M_ZERO);
	if (ctx == NULL) {
		if_printf(ifp, "%s: cannot allocate sysctl context!\n",
			__func__);
		return;
	}
	sysctl_ctx_init(ctx);
	snprintf(num, sizeof(num), "%u", ifp->if_dunit);
	oid = SYSCTL_ADD_NODE(ctx, &SYSCTL_NODE_CHILDREN(_net, wlan),
		OID_AUTO, num, CTLFLAG_RD, NULL, "");
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"%parent", CTLTYPE_STRING | CTLFLAG_RD, vap->iv_ic, 0,
		ieee80211_sysctl_parent, "A", "parent device");
	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"driver_caps", CTLFLAG_RW, &vap->iv_caps, 0,
		"driver capabilities");
#ifdef IEEE80211_DEBUG
	vap->iv_debug = ieee80211_debug;
	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"debug", CTLFLAG_RW, &vap->iv_debug, 0,
		"control debugging printfs");
#endif
	SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"bmiss_max", CTLFLAG_RW, &vap->iv_bmiss_max, 0,
		"consecutive beacon misses before scanning");
	/* XXX inherit from tunables */
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"inact_run", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_run, 0,
		ieee80211_sysctl_inact, "I",
		"station inactivity timeout (sec)");
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"inact_probe", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_probe, 0,
		ieee80211_sysctl_inact, "I",
		"station inactivity probe timeout (sec)");
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"inact_auth", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_auth, 0,
		ieee80211_sysctl_inact, "I",
		"station authentication timeout (sec)");
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
		"inact_init", CTLTYPE_INT | CTLFLAG_RW, &vap->iv_inact_init, 0,
		ieee80211_sysctl_inact, "I",
		"station initial state timeout (sec)");
	if (vap->iv_htcaps & IEEE80211_HTC_HT) {
		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
			"ampdu_mintraffic_bk", CTLFLAG_RW,
			&vap->iv_ampdu_mintraffic[WME_AC_BK], 0,
			"BK traffic tx aggr threshold (pps)");
		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
			"ampdu_mintraffic_be", CTLFLAG_RW,
			&vap->iv_ampdu_mintraffic[WME_AC_BE], 0,
			"BE traffic tx aggr threshold (pps)");
		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
			"ampdu_mintraffic_vo", CTLFLAG_RW,
			&vap->iv_ampdu_mintraffic[WME_AC_VO], 0,
			"VO traffic tx aggr threshold (pps)");
		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
			"ampdu_mintraffic_vi", CTLFLAG_RW,
			&vap->iv_ampdu_mintraffic[WME_AC_VI], 0,
			"VI traffic tx aggr threshold (pps)");
	}
	if (vap->iv_caps & IEEE80211_C_DFS) {
		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
			"radar", CTLTYPE_INT | CTLFLAG_RW, vap->iv_ic, 0,
			ieee80211_sysctl_radar, "I", "simulate radar event");
	}
	vap->iv_sysctl = ctx;
	vap->iv_oid = oid;
}
コード例 #16
0
static int
ubt_attach(device_t self)
{
	struct ubt_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);

	usb_config_descriptor_t *cd;
	usb_endpoint_descriptor_t *ed;
	int err;
	uint8_t count, i;

	DPRINTFN(50, "ubt_attach: sc=%p\n", sc);

	sc->sc_udev = uaa->device;
	sc->sc_dev = self;

	/*
	 * Move the device into the configured state
	 */
	err = usbd_set_config_index(sc->sc_udev, 0, 1);
	if (err) {
		kprintf("%s: failed to set configuration idx 0: %s\n",
		    device_get_nameunit(sc->sc_dev), usbd_errstr(err));

		return ENXIO;
	}

	/*
	 * Interface 0 must have 3 endpoints
	 *	1) Interrupt endpoint to receive HCI events
	 *	2) Bulk IN endpoint to receive ACL data
	 *	3) Bulk OUT endpoint to send ACL data
	 */
	err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface0);
	if (err) {
		kprintf("%s: Could not get interface 0 handle %s (%d)\n",
				device_get_nameunit(sc->sc_dev), usbd_errstr(err), err);

		return ENXIO;
	}

	sc->sc_evt_addr = -1;
	sc->sc_aclrd_addr = -1;
	sc->sc_aclwr_addr = -1;

	count = 0;
	(void)usbd_endpoint_count(sc->sc_iface0, &count);

	for (i = 0 ; i < count ; i++) {
		int dir, type;

		ed = usbd_interface2endpoint_descriptor(sc->sc_iface0, i);
		if (ed == NULL) {
			kprintf("%s: could not read endpoint descriptor %d\n",
			    device_get_nameunit(sc->sc_dev), i);

			return ENXIO;
		}

		dir = UE_GET_DIR(ed->bEndpointAddress);
		type = UE_GET_XFERTYPE(ed->bmAttributes);

		if (dir == UE_DIR_IN && type == UE_INTERRUPT)
			sc->sc_evt_addr = ed->bEndpointAddress;
		else if (dir == UE_DIR_IN && type == UE_BULK)
			sc->sc_aclrd_addr = ed->bEndpointAddress;
		else if (dir == UE_DIR_OUT && type == UE_BULK)
			sc->sc_aclwr_addr = ed->bEndpointAddress;
	}

	if (sc->sc_evt_addr == -1) {
		kprintf("%s: missing INTERRUPT endpoint on interface 0\n",
				device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}
	if (sc->sc_aclrd_addr == -1) {
		kprintf("%s: missing BULK IN endpoint on interface 0\n",
				device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}
	if (sc->sc_aclwr_addr == -1) {
		kprintf("%s: missing BULK OUT endpoint on interface 0\n",
				device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}

	/*
	 * Interface 1 must have 2 endpoints
	 *	1) Isochronous IN endpoint to receive SCO data
	 *	2) Isochronous OUT endpoint to send SCO data
	 *
	 * and will have several configurations, which can be selected
	 * via a sysctl variable. We select config 0 to start, which
	 * means that no SCO data will be available.
	 */
	err = usbd_device2interface_handle(sc->sc_udev, 1, &sc->sc_iface1);
	if (err) {
		kprintf("%s: Could not get interface 1 handle %s (%d)\n",
		    device_get_nameunit(sc->sc_dev), usbd_errstr(err), err);

		return ENXIO;
	}

	cd = usbd_get_config_descriptor(sc->sc_udev);
	if (cd == NULL) {
		kprintf("%s: could not get config descriptor\n",
			device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}

	sc->sc_alt_config = usbd_get_no_alts(cd, 1);

	/* set initial config */
	err = ubt_set_isoc_config(sc);
	if (err) {
		kprintf("%s: ISOC config failed\n",
			device_get_nameunit(sc->sc_dev));

		return ENXIO;
	}

	/* Attach HCI */
	sc->sc_unit = hci_attach(&ubt_hci, sc->sc_dev, 0);

	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
			   sc->sc_dev);

	sc->sc_ok = 1;

	sysctl_ctx_init(&sc->sysctl_ctx);
	sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
					  SYSCTL_STATIC_CHILDREN(_hw),
					  OID_AUTO,
					  device_get_nameunit(sc->sc_dev),
					  CTLFLAG_RD, 0, "");

	if (sc->sysctl_tree == NULL) {
		/* Failure isn't fatal */
		device_printf(sc->sc_dev, "Unable to create sysctl tree\n");
		return 0;
	}

	SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
			OID_AUTO, "config", CTLTYPE_INT|CTLFLAG_RW, (void *)sc,
			0, ubt_sysctl_config, "I", "Configuration number");
	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
		       OID_AUTO, "alt_config", CTLFLAG_RD, &sc->sc_alt_config,
		       0, "Number of alternate configurations");
	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
		       OID_AUTO, "sco_rxsize", CTLFLAG_RD, &sc->sc_scord_size,
		       0, "Max SCO receive size");
	SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
		       OID_AUTO, "sco_wrsize", CTLFLAG_RD, &sc->sc_scowr_size,
		       0, "Max SCO transmit size");

	return 0;
}
コード例 #17
0
ファイル: uhso.c プロジェクト: cyrilmagsuci/freebsd
static int
uhso_attach(device_t self)
{
	struct uhso_softc *sc = device_get_softc(self);
	struct usb_attach_arg *uaa = device_get_ivars(self);
	struct usb_interface_descriptor *id;
	struct sysctl_ctx_list *sctx;
	struct sysctl_oid *soid;
	struct sysctl_oid *tree = NULL, *tty_node;
	struct ucom_softc *ucom;
	struct uhso_tty *ht;
	int i, error, port;
	void *probe_f;
	usb_error_t uerr;
	char *desc;

	sc->sc_dev = self;
	sc->sc_udev = uaa->device;
	mtx_init(&sc->sc_mtx, "uhso", NULL, MTX_DEF);
	ucom_ref(&sc->sc_super_ucom);

	sc->sc_radio = 1;

	id = usbd_get_interface_descriptor(uaa->iface);
	sc->sc_ctrl_iface_no = id->bInterfaceNumber;

	sc->sc_iface_no = uaa->info.bIfaceNum;
	sc->sc_iface_index = uaa->info.bIfaceIndex;

	/* Setup control pipe */
	uerr = usbd_transfer_setup(uaa->device,
	    &sc->sc_iface_index, sc->sc_ctrl_xfer,
	    uhso_ctrl_config, UHSO_CTRL_MAX, sc, &sc->sc_mtx);
	if (uerr) {
		device_printf(self, "Failed to setup control pipe: %s\n",
		    usbd_errstr(uerr));
		goto out;
	}

	if (USB_GET_DRIVER_INFO(uaa) == UHSO_STATIC_IFACE)
		probe_f = uhso_probe_iface_static;
	else if (USB_GET_DRIVER_INFO(uaa) == UHSO_AUTO_IFACE)
		probe_f = uhso_probe_iface_auto;
	else
		goto out;

	error = uhso_probe_iface(sc, uaa->info.bIfaceNum, probe_f);
	if (error != 0)
		goto out;

	sctx = device_get_sysctl_ctx(sc->sc_dev);
	soid = device_get_sysctl_tree(sc->sc_dev);

	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "type",
	    CTLFLAG_RD, uhso_port[UHSO_IFACE_PORT(sc->sc_type)], 0,
	    "Port available at this interface");
	SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "radio",
	    CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0, uhso_radio_sysctl, "I", "Enable radio");

	/*
	 * The default interface description on most Option devices isn't
	 * very helpful. So we skip device_set_usb_desc and set the
	 * device description manually.
	 */
	device_set_desc_copy(self, uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)]); 
	/* Announce device */
	device_printf(self, "<%s port> at <%s %s> on %s\n",
	    uhso_port_type[UHSO_IFACE_PORT_TYPE(sc->sc_type)],
	    usb_get_manufacturer(uaa->device),
	    usb_get_product(uaa->device),
	    device_get_nameunit(device_get_parent(self)));

	if (sc->sc_ttys > 0) {
		SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "ports",
		    CTLFLAG_RD, &sc->sc_ttys, 0, "Number of attached serial ports");

		tree = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
		    "port", CTLFLAG_RD, NULL, "Serial ports");
	}

	/*
	 * Loop through the number of found TTYs and create sysctl
	 * nodes for them.
	 */
	for (i = 0; i < sc->sc_ttys; i++) {
		ht = &sc->sc_tty[i];
		ucom = &sc->sc_ucom[i];

		if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX)
			port = uhso_mux_port_map[ht->ht_muxport];
		else
			port = UHSO_IFACE_PORT_TYPE(sc->sc_type);

		desc = uhso_port_type_sysctl[port];

		tty_node = SYSCTL_ADD_NODE(sctx, SYSCTL_CHILDREN(tree), OID_AUTO,
		    desc, CTLFLAG_RD, NULL, "");

		ht->ht_name[0] = 0;
		if (sc->sc_ttys == 1)
			snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit);
		else {
			snprintf(ht->ht_name, 32, "cuaU%d.%d",
			    ucom->sc_super->sc_unit, ucom->sc_subunit);
		}

		desc = uhso_port_type[port];
		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
		    "tty", CTLFLAG_RD, ht->ht_name, 0, "");
		SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(tty_node), OID_AUTO,
		    "desc", CTLFLAG_RD, desc, 0, "");

		if (bootverbose)
			device_printf(sc->sc_dev,
			    "\"%s\" port at %s\n", desc, ht->ht_name);
	}

	return (0);
out:
	uhso_detach(sc->sc_dev);
	return (ENXIO);
}
コード例 #18
0
void
oce_add_sysctls(POCE_SOFTC sc)
{

	struct sysctl_ctx_list *ctx = &sc->sysctl_ctx;
	struct sysctl_oid *tree = sc->sysctl_tree;
	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
	struct sysctl_oid *stats_node;

	SYSCTL_ADD_STRING(ctx, child,
			OID_AUTO, "component_revision",
			CTLTYPE_INT | CTLFLAG_RD,
			&component_revision,
			sizeof(component_revision),
			"EMULEX One-Connect device driver revision");

	SYSCTL_ADD_STRING(ctx, child,
			OID_AUTO, "firmware_version",
			CTLTYPE_INT | CTLFLAG_RD,
			&sc->fw_version,
			sizeof(sc->fw_version),
			"EMULEX One-Connect Firmware Version");

	SYSCTL_ADD_INT(ctx, child,
			OID_AUTO, "max_rsp_handled",
			CTLTYPE_INT | CTLFLAG_RW,
			&oce_max_rsp_handled,
			sizeof(oce_max_rsp_handled),
			"Maximum receive frames handled per interrupt");

	if ((sc->function_mode & FNM_FLEX10_MODE) ||
	    (sc->function_mode & FNM_UMC_MODE))
		SYSCTL_ADD_UINT(ctx, child,
				OID_AUTO, "speed",
				CTLFLAG_RD,
				&sc->qos_link_speed,
				0,"QOS Speed");
	else
		SYSCTL_ADD_UINT(ctx, child,
				OID_AUTO, "speed",
				CTLFLAG_RD,
				&sc->speed,
				0,"Link Speed");

	if (sc->function_mode & FNM_UMC_MODE)
		SYSCTL_ADD_UINT(ctx, child,
				OID_AUTO, "pvid",
				CTLFLAG_RD,
				&sc->pvid,
				0,"PVID");

	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "loop_back",
		CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0,
		oce_sysctl_loopback, "I", "Loop Back Tests");

	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_upgrade",
		CTLTYPE_STRING | CTLFLAG_RW, (void *)sc, 0,
		oce_sys_fwupgrade, "A", "Firmware ufi file");

        /*
         *  Dumps Transceiver data
	 *  "sysctl hw.oce0.sfp_vpd_dump=0"
         *  "sysctl -x hw.oce0.sfp_vpd_dump_buffer" for hex dump
         *  "sysctl -b hw.oce0.sfp_vpd_dump_buffer > sfp.bin" for binary dump
         */
	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "sfp_vpd_dump",
			CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, oce_sysctl_sfp_vpd_dump,
			"I", "Initiate a sfp_vpd_dump operation");
	SYSCTL_ADD_OPAQUE(ctx, child, OID_AUTO, "sfp_vpd_dump_buffer",
			CTLFLAG_RD, sfp_vpd_dump_buffer,
			TRANSCEIVER_DATA_SIZE, "IU", "Access sfp_vpd_dump buffer");

	stats_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats",
				CTLFLAG_RD, NULL, "Ethernet Statistics");

	if (IS_BE(sc) || IS_SH(sc))
		oce_add_stats_sysctls_be3(sc, ctx, stats_node);
	else
		oce_add_stats_sysctls_xe201(sc, ctx, stats_node);


}
コード例 #19
0
ファイル: atk0110.c プロジェクト: AhmadTux/freebsd
static void
aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st)
{
	ACPI_STATUS		s;
	ACPI_BUFFER		b;
	ACPI_OBJECT		*bp, *o;
	int			i, n;
	const char		*node;
	char			name[] = "?SIF";
	struct aibs_sensor	*as;
	struct sysctl_oid	*so;

	switch (st) {
	case AIBS_VOLT:
		node = "volt";
		name[0] = 'V';
		break;
	case AIBS_TEMP:
		node = "temp";
		name[0] = 'T';
		break;
	case AIBS_FAN:
		node = "fan";
		name[0] = 'F';
		break;
	default:
		return;
	}

	b.Length = ACPI_ALLOCATE_BUFFER;
	s = AcpiEvaluateObjectTyped(sc->sc_ah, name, NULL, &b,
	    ACPI_TYPE_PACKAGE);
	if (ACPI_FAILURE(s)) {
		device_printf(sc->sc_dev, "%s not found\n", name);
		return;
	}

	bp = b.Pointer;
	o = bp->Package.Elements;
	if (o[0].Type != ACPI_TYPE_INTEGER) {
		device_printf(sc->sc_dev, "%s[0]: invalid type\n", name);
		AcpiOsFree(b.Pointer);
		return;
	}

	n = o[0].Integer.Value;
	if (bp->Package.Count - 1 < n) {
		device_printf(sc->sc_dev, "%s: invalid package\n", name);
		AcpiOsFree(b.Pointer);
		return;
	} else if (bp->Package.Count - 1 > n) {
		int on = n;

#ifdef AIBS_MORE_SENSORS
		n = bp->Package.Count - 1;
#endif
		device_printf(sc->sc_dev, "%s: malformed package: %i/%i"
		    ", assume %i\n", name, on, bp->Package.Count - 1, n);
	}
	if (n < 1) {
		device_printf(sc->sc_dev, "%s: no members in the package\n",
		    name);
		AcpiOsFree(b.Pointer);
		return;
	}

	as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO);
	if (as == NULL) {
		device_printf(sc->sc_dev, "%s: malloc fail\n", name);
		AcpiOsFree(b.Pointer);
		return;
	}
	switch (st) {
	case AIBS_VOLT:
		sc->sc_asens_volt = as;
		break;
	case AIBS_TEMP:
		sc->sc_asens_temp = as;
		break;
	case AIBS_FAN:
		sc->sc_asens_fan = as;
		break;
	}

	/* sysctl subtree for sensors of this type */
	so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev),
	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), st,
	    node, CTLFLAG_RD, NULL, NULL);

	for (i = 0, o++; i < n; i++, o++) {
		ACPI_OBJECT	*oi;
		char		si[3];
		const char	*desc;

		/* acpica5 automatically evaluates the referenced package */
		if (o[0].Type != ACPI_TYPE_PACKAGE) {
			device_printf(sc->sc_dev,
			    "%s: %i: not a package: %i type\n",
			    name, i, o[0].Type);
			continue;
		}
		oi = o[0].Package.Elements;
		if (o[0].Package.Count != 5 ||
		    oi[0].Type != ACPI_TYPE_INTEGER ||
		    oi[1].Type != ACPI_TYPE_STRING ||
		    oi[2].Type != ACPI_TYPE_INTEGER ||
		    oi[3].Type != ACPI_TYPE_INTEGER ||
		    oi[4].Type != ACPI_TYPE_INTEGER) {
			device_printf(sc->sc_dev,
			    "%s: %i: invalid package\n",
			    name, i);
			continue;
		}
		as[i].i = oi[0].Integer.Value;
		desc = oi[1].String.Pointer;
		as[i].l = oi[2].Integer.Value;
		as[i].h = oi[3].Integer.Value;
		as[i].t = st;
#ifdef AIBS_VERBOSE
		device_printf(sc->sc_dev, "%c%i: "
		    "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64"  "
		    "0x%"PRIx64"\n",
		    name[0], i,
		    as[i].i, desc, (int64_t)as[i].l, (int64_t)as[i].h,
		    oi[4].Integer.Value);
#endif
		snprintf(si, sizeof(si), "%i", i);
		SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev),
		    SYSCTL_CHILDREN(so), i, si, CTLTYPE_INT | CTLFLAG_RD,
		    sc, st, aibs_sysctl, st == AIBS_TEMP ? "IK" : "I", desc);
	}

	AcpiOsFree(b.Pointer);
}
コード例 #20
0
ファイル: acpi_fujitsu.c プロジェクト: AhmadTux/freebsd
/*
 * Initializes the names of the ACPI control methods and grabs
 * the current state of all of the ACPI hotkeys into the softc.
 */
static uint8_t
acpi_fujitsu_init(struct acpi_fujitsu_softc *sc)
{
	struct acpi_softc *acpi_sc;
	int i, exists;

	ACPI_SERIAL_ASSERT(fujitsu);

	/* Setup all of the names for each control method */
	sc->_sta.name = "_STA";
	sc->gbll.name = "GBLL";
	sc->gbls.name = "GBLS";
	sc->ghks.name = "GHKS";
	sc->gmou.name = "GMOU";
	sc->gsif.name = "GSIF";
	sc->gvol.name = "GVOL";
	sc->ghks.name = "GHKS";
	sc->gsif.name = "GSIF";
	sc->rbll.name = "RBLL";
	sc->rvol.name = "RVOL";

	/* Determine what hardware functionality is available */
	acpi_fujitsu_check_hardware(sc);

	/* Build the sysctl tree */
	acpi_sc = acpi_device_get_parent_softc(sc->dev);
	sysctl_ctx_init(&sc->sysctl_ctx);
	sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
	    SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
	    OID_AUTO, "fujitsu", CTLFLAG_RD, 0, "");

	for (i = 0; sysctl_table[i].name != NULL; i++) {
		switch(sysctl_table[i].method) {
			case METHOD_GMOU:
				exists = sc->gmou.exists;
				break;
			case METHOD_GBLL:
				exists = sc->gbll.exists;
				break;
			case METHOD_GBLS:
				exists = sc->gbls.exists;
				break;
			case METHOD_GVOL:
			case METHOD_MUTE:
				exists = sc->gvol.exists;
				break;
			case METHOD_RVOL:
				exists = sc->rvol.exists;
				break;
			case METHOD_RBLL:
				exists = sc->rbll.exists;
				break;
			default:
				/* Allow by default */
				exists = 1;
				break;
		}
		if(!exists)
			continue;
		SYSCTL_ADD_PROC(&sc->sysctl_ctx,
		    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
		    sysctl_table[i].name,
		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
		    sc, i, acpi_fujitsu_sysctl, "I",
		    sysctl_table[i].description);
	}


	/* Set the hotkeys to their initial states */
	if (!acpi_fujitsu_update(sc)) {
		device_printf(sc->dev, "Couldn't init hotkey states\n");
		return (FALSE);
	}

	return (TRUE);
}
コード例 #21
0
ファイル: acpi_thermal.c プロジェクト: Alkzndr/freebsd
static int
acpi_tz_attach(device_t dev)
{
    struct acpi_tz_softc	*sc;
    struct acpi_softc		*acpi_sc;
    int				error;
    char			oidname[8];

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    sc = device_get_softc(dev);
    sc->tz_dev = dev;
    sc->tz_handle = acpi_get_handle(dev);
    sc->tz_requested = TZ_ACTIVE_NONE;
    sc->tz_active = TZ_ACTIVE_UNKNOWN;
    sc->tz_thflags = TZ_THFLAG_NONE;
    sc->tz_cooling_proc = NULL;
    sc->tz_cooling_proc_running = FALSE;
    sc->tz_cooling_active = FALSE;
    sc->tz_cooling_updated = FALSE;
    sc->tz_cooling_enabled = FALSE;

    /*
     * Parse the current state of the thermal zone and build control
     * structures.  We don't need to worry about interference with the
     * control thread since we haven't fully attached this device yet.
     */
    if ((error = acpi_tz_establish(sc)) != 0)
	return (error);

    /*
     * Register for any Notify events sent to this zone.
     */
    AcpiInstallNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY,
			     acpi_tz_notify_handler, sc);

    /*
     * Create our sysctl nodes.
     *
     * XXX we need a mechanism for adding nodes under ACPI.
     */
    if (device_get_unit(dev) == 0) {
	acpi_sc = acpi_device_get_parent_softc(dev);
	sysctl_ctx_init(&acpi_tz_sysctl_ctx);
	acpi_tz_sysctl_tree = SYSCTL_ADD_NODE(&acpi_tz_sysctl_ctx,
			      SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
			      OID_AUTO, "thermal", CTLFLAG_RD, 0, "");
	SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx,
		       SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
		       OID_AUTO, "min_runtime", CTLFLAG_RW,
		       &acpi_tz_min_runtime, 0,
		       "minimum cooling run time in sec");
	SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx,
		       SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
		       OID_AUTO, "polling_rate", CTLFLAG_RW,
		       &acpi_tz_polling_rate, 0, "monitor polling interval in seconds");
	SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx,
		       SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO,
		       "user_override", CTLFLAG_RW, &acpi_tz_override, 0,
		       "allow override of thermal settings");
    }
    sysctl_ctx_init(&sc->tz_sysctl_ctx);
    sprintf(oidname, "tz%d", device_get_unit(dev));
    sc->tz_sysctl_tree = SYSCTL_ADD_NODE(&sc->tz_sysctl_ctx,
					 SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
					 OID_AUTO, oidname, CTLFLAG_RD, 0, "");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD,
		    &sc->tz_temperature, 0, sysctl_handle_int,
		    "IK", "current thermal zone temperature");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "active", CTLTYPE_INT | CTLFLAG_RW,
		    sc, 0, acpi_tz_active_sysctl, "I", "cooling is active");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "passive_cooling", CTLTYPE_INT | CTLFLAG_RW,
		    sc, 0, acpi_tz_cooling_sysctl, "I",
		    "enable passive (speed reduction) cooling");

    SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		   OID_AUTO, "thermal_flags", CTLFLAG_RD,
		   &sc->tz_thflags, 0, "thermal zone flags");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "_PSV", CTLTYPE_INT | CTLFLAG_RW,
		    sc, offsetof(struct acpi_tz_softc, tz_zone.psv),
		    acpi_tz_temp_sysctl, "IK", "passive cooling temp setpoint");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW,
		    sc, offsetof(struct acpi_tz_softc, tz_zone.hot),
		    acpi_tz_temp_sysctl, "IK",
		    "too hot temp setpoint (suspend now)");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "_CRT", CTLTYPE_INT | CTLFLAG_RW,
		    sc, offsetof(struct acpi_tz_softc, tz_zone.crt),
		    acpi_tz_temp_sysctl, "IK",
		    "critical temp setpoint (shutdown now)");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "_ACx", CTLTYPE_INT | CTLFLAG_RD,
		    &sc->tz_zone.ac, sizeof(sc->tz_zone.ac),
		    sysctl_handle_opaque, "IK", "");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "_TC1", CTLTYPE_INT | CTLFLAG_RW,
		    sc, offsetof(struct acpi_tz_softc, tz_zone.tc1),
		    acpi_tz_passive_sysctl, "I",
		    "thermal constant 1 for passive cooling");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "_TC2", CTLTYPE_INT | CTLFLAG_RW,
		    sc, offsetof(struct acpi_tz_softc, tz_zone.tc2),
		    acpi_tz_passive_sysctl, "I",
		    "thermal constant 2 for passive cooling");
    SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
		    OID_AUTO, "_TSP", CTLTYPE_INT | CTLFLAG_RW,
		    sc, offsetof(struct acpi_tz_softc, tz_zone.tsp),
		    acpi_tz_passive_sysctl, "I",
		    "thermal sampling period for passive cooling");

    /*
     * Create thread to service all of the thermal zones.  Register
     * our power profile event handler.
     */
    sc->tz_event = EVENTHANDLER_REGISTER(power_profile_change,
	acpi_tz_power_profile, sc, 0);
    if (acpi_tz_proc == NULL) {
	error = kproc_create(acpi_tz_thread, NULL, &acpi_tz_proc,
	    RFHIGHPID, 0, "acpi_thermal");
	if (error != 0) {
	    device_printf(sc->tz_dev, "could not create thread - %d", error);
	    goto out;
	}
    }

    /*
     * Create a thread to handle passive cooling for 1st zone which
     * has _PSV, _TSP, _TC1 and _TC2.  Users can enable it for other
     * zones manually for now.
     *
     * XXX We enable only one zone to avoid multiple zones conflict
     * with each other since cpufreq currently sets all CPUs to the
     * given frequency whereas it's possible for different thermal
     * zones to specify independent settings for multiple CPUs.
     */
    if (acpi_tz_cooling_unit < 0 && acpi_tz_cooling_is_available(sc))
	sc->tz_cooling_enabled = TRUE;
    if (sc->tz_cooling_enabled) {
	error = acpi_tz_cooling_thread_start(sc);
	if (error != 0) {
	    sc->tz_cooling_enabled = FALSE;
	    goto out;
	}
	acpi_tz_cooling_unit = device_get_unit(dev);
    }

    /*
     * Flag the event handler for a manual invocation by our timeout.
     * We defer it like this so that the rest of the subsystem has time
     * to come up.  Don't bother evaluating/printing the temperature at
     * this point; on many systems it'll be bogus until the EC is running.
     */
    sc->tz_flags |= TZ_FLAG_GETPROFILE;

out:
    if (error != 0) {
	EVENTHANDLER_DEREGISTER(power_profile_change, sc->tz_event);
	AcpiRemoveNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY,
	    acpi_tz_notify_handler);
	sysctl_ctx_free(&sc->tz_sysctl_ctx);
    }
    return_VALUE (error);
}
コード例 #22
0
ファイル: usb_ethernet.c プロジェクト: kusumi/DragonFlyBSD
static void
ue_attach_post_task(struct usb_proc_msg *_task)
{
	struct usb_ether_cfg_task *task =
	    (struct usb_ether_cfg_task *)_task;
	struct usb_ether *ue = task->ue;
	struct ifnet *ifp = uether_getifp(ue);
	int error;
	char num[14];			/* sufficient for 32 bits */

	/* first call driver's post attach routine */
	ue->ue_methods->ue_attach_post(ue);

	UE_UNLOCK(ue);

	KKASSERT(!lockowned(ue->ue_lock));
	ue->ue_unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(ue), 0);
	usb_callout_init_mtx(&ue->ue_watchdog, ue->ue_lock, 0);
	sysctl_ctx_init(&ue->ue_sysctl_ctx);

	KKASSERT(!lockowned(ue->ue_lock));
	error = 0;

	ifp->if_softc = ue;
	if_initname(ifp, "ue", ue->ue_unit);
	if (ue->ue_methods->ue_attach_post_sub != NULL) {
		error = ue->ue_methods->ue_attach_post_sub(ue);
		KKASSERT(!lockowned(ue->ue_lock));
	} else {
		ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
		if (ue->ue_methods->ue_ioctl != NULL)
			ifp->if_ioctl = ue->ue_methods->ue_ioctl;
		else
			ifp->if_ioctl = uether_ioctl;
		ifp->if_start = ue_start;
		ifp->if_init = ue_init;
		ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
		ifq_set_ready(&ifp->if_snd);

		if (ue->ue_methods->ue_mii_upd != NULL &&
		    ue->ue_methods->ue_mii_sts != NULL) {
			error = mii_phy_probe(ue->ue_dev, &ue->ue_miibus, 
					      ue_ifmedia_upd, ue->ue_methods->ue_mii_sts);
		}
	}

	if (error) {
		device_printf(ue->ue_dev, "attaching PHYs failed\n");
		goto fail;
	}

	if_printf(ifp, "<USB Ethernet> on %s\n", device_get_nameunit(ue->ue_dev));
	ether_ifattach(ifp, ue->ue_eaddr, NULL);
	/* Tell upper layer we support VLAN oversized frames. */
	if (ifp->if_capabilities & IFCAP_VLAN_MTU)
		ifp->if_hdrlen = sizeof(struct ether_vlan_header);

	ksnprintf(num, sizeof(num), "%u", ue->ue_unit);
	ue->ue_sysctl_oid = SYSCTL_ADD_NODE(&ue->ue_sysctl_ctx,
	    &SYSCTL_NODE_CHILDREN(_net, ue),
	    OID_AUTO, num, CTLFLAG_RD, NULL, "");
	SYSCTL_ADD_PROC(&ue->ue_sysctl_ctx,
	    SYSCTL_CHILDREN(ue->ue_sysctl_oid), OID_AUTO,
	    "%parent", CTLTYPE_STRING | CTLFLAG_RD, ue, 0,
	    ue_sysctl_parent, "A", "parent device");

	KKASSERT(!lockowned(ue->ue_lock));
	UE_LOCK(ue);
	return;

fail:
	devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(ue), ue->ue_unit);
	UE_LOCK(ue);
	return;
}
コード例 #23
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));
}
コード例 #24
0
static void
vmbus_chan_sysctl_create(struct vmbus_channel *chan)
{
	struct sysctl_oid *ch_tree, *chid_tree, *br_tree;
	struct sysctl_ctx_list *ctx;
	uint32_t ch_id;
	char name[16];

	/*
	 * Add sysctl nodes related to this channel to this
	 * channel's sysctl ctx, so that they can be destroyed
	 * independently upon close of this channel, which can
	 * happen even if the device is not detached.
	 */
	ctx = &chan->ch_sysctl_ctx;
	sysctl_ctx_init(ctx);

	/*
	 * Create dev.NAME.UNIT.channel tree.
	 */
	ch_tree = SYSCTL_ADD_NODE(ctx,
	    SYSCTL_CHILDREN(device_get_sysctl_tree(chan->ch_dev)),
	    OID_AUTO, "channel", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
	if (ch_tree == NULL)
		return;

	/*
	 * Create dev.NAME.UNIT.channel.CHANID tree.
	 */
	if (VMBUS_CHAN_ISPRIMARY(chan))
		ch_id = chan->ch_id;
	else
		ch_id = chan->ch_prichan->ch_id;
	snprintf(name, sizeof(name), "%d", ch_id);
	chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree),
	    OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
	if (chid_tree == NULL)
		return;

	if (!VMBUS_CHAN_ISPRIMARY(chan)) {
		/*
		 * Create dev.NAME.UNIT.channel.CHANID.sub tree.
		 */
		ch_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree),
		    OID_AUTO, "sub", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
		if (ch_tree == NULL)
			return;

		/*
		 * Create dev.NAME.UNIT.channel.CHANID.sub.SUBIDX tree.
		 *
		 * NOTE:
		 * chid_tree is changed to this new sysctl tree.
		 */
		snprintf(name, sizeof(name), "%d", chan->ch_subidx);
		chid_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(ch_tree),
		    OID_AUTO, name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
		if (chid_tree == NULL)
			return;

		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
		    "chanid", CTLFLAG_RD, &chan->ch_id, 0, "channel id");
	}

	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
	    "cpu", CTLFLAG_RD, &chan->ch_cpuid, 0, "owner CPU id");
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
	    "mnf", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
	    chan, 0, vmbus_chan_sysctl_mnf, "I",
	    "has monitor notification facilities");

	br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
	    "br", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
	if (br_tree != NULL) {
		/*
		 * Create sysctl tree for RX bufring.
		 */
		vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_rxbr, "rx");
		/*
		 * Create sysctl tree for TX bufring.
		 */
		vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_txbr, "tx");
	}
}
コード例 #25
0
/*
 * The function called at load/unload.
 */
static int
load(module_t mod, int cmd, void *arg)
{
	int error;

	error = 0;
	switch (cmd) {
	case MOD_LOAD:
		/* Initialize the contexts */
		printf("Initializing contexts and creating subtrees.\n\n");
		sysctl_ctx_init(&clist);
		sysctl_ctx_init(&clist1);
		sysctl_ctx_init(&clist2);
		/*
		 * Create two partially overlapping subtrees, belonging
		 * to different contexts.
		 */
		printf("TREE		ROOT		  NAME\n");
		a_root = SYSCTL_ADD_NODE(&clist,
			SYSCTL_STATIC_CHILDREN(/* top of sysctl tree */),
			OID_AUTO, "dyn_sysctl", CTLFLAG_RW, 0,
			"dyn_sysctl root node");
		a_root = SYSCTL_ADD_NODE(&clist1,
			SYSCTL_STATIC_CHILDREN(/* top of sysctl tree */),
			OID_AUTO, "dyn_sysctl", CTLFLAG_RW, 0,
			"dyn_sysctl root node");
		if (a_root == NULL) {
			printf("SYSCTL_ADD_NODE failed!\n");
			return (EINVAL);
		}
		SYSCTL_ADD_LONG(&clist, SYSCTL_CHILDREN(a_root),
		    OID_AUTO, "long_a", CTLFLAG_RW, &a, "just to try");
		SYSCTL_ADD_INT(&clist, SYSCTL_CHILDREN(a_root),
		    OID_AUTO, "int_b", CTLFLAG_RW, &b, 0, "just to try 1");
		a_root1 = SYSCTL_ADD_NODE(&clist, SYSCTL_CHILDREN(a_root),
		    OID_AUTO, "nextlevel", CTLFLAG_RD, 0, "one level down");
		SYSCTL_ADD_STRING(&clist, SYSCTL_CHILDREN(a_root1),
		    OID_AUTO, "string_c", CTLFLAG_RD, c, 0, "just to try 2");
		printf("1. (%p)	/		  dyn_sysctl\n", &clist);

		/* Add a subtree under already existing category */
		a_root1 = SYSCTL_ADD_NODE(&clist, SYSCTL_STATIC_CHILDREN(_kern),
		    OID_AUTO, "dyn_sysctl", CTLFLAG_RW, 0, "dyn_sysctl root node");
		if (a_root1 == NULL) {
			printf("SYSCTL_ADD_NODE failed!\n");
			return (EINVAL);
		}
		SYSCTL_ADD_PROC(&clist, SYSCTL_CHILDREN(a_root1),
		    OID_AUTO, "procedure", CTLTYPE_STRING | CTLFLAG_RD,
		    NULL, 0, sysctl_dyn_sysctl_test, "A",
		    "I can be here, too");
		printf("   (%p)	/kern		  dyn_sysctl\n", &clist);

		/* Overlap second tree with the first. */
		b_root = SYSCTL_ADD_NODE(&clist1, SYSCTL_CHILDREN(a_root),
		    OID_AUTO, "nextlevel", CTLFLAG_RD, 0, "one level down");
		SYSCTL_ADD_STRING(&clist1, SYSCTL_CHILDREN(b_root),
		    OID_AUTO, "string_c1", CTLFLAG_RD, c, 0, "just to try 2");
		printf("2. (%p)	/		  dyn_sysctl	(overlapping #1)\n", &clist1);

		/*
		 * And now do something stupid. Connect another subtree to
		 * dynamic oid.
		 * WARNING: this is an example of WRONG use of dynamic sysctls.
		 */
		b_root=SYSCTL_ADD_NODE(&clist2, SYSCTL_CHILDREN(a_root1),
		    OID_AUTO, "bad", CTLFLAG_RW, 0, "dependent node");
		SYSCTL_ADD_STRING(&clist2, SYSCTL_CHILDREN(b_root),
		    OID_AUTO, "string_c", CTLFLAG_RD, c, 0, "shouldn't panic");
		printf("3. (%p)	/kern/dyn_sysctl  bad		(WRONG!)\n", &clist2);
		break;
	case MOD_UNLOAD:
		printf("1. Try to free ctx1 (%p): ", &clist);
		if (sysctl_ctx_free(&clist) != 0)
			printf("failed: expected. Need to remove ctx3 first.\n");
		else
			printf("HELP! sysctl_ctx_free(%p) succeeded. EXPECT PANIC!!!\n", &clist);
		printf("2. Try to free ctx3 (%p): ", &clist2);
		if (sysctl_ctx_free(&clist2) != 0) {
			printf("sysctl_ctx_free(%p) failed!\n", &clist2);
			/* Remove subtree forcefully... */
			sysctl_remove_oid(b_root, 1, 1);
			printf("sysctl_remove_oid(%p) succeeded\n", b_root);
		} else
			printf("Ok\n");
		printf("3. Try to free ctx1 (%p) again: ", &clist);
		if (sysctl_ctx_free(&clist) != 0) {
			printf("sysctl_ctx_free(%p) failed!\n", &clist);
			/* Remove subtree forcefully... */
			sysctl_remove_oid(a_root1, 1, 1);
			printf("sysctl_remove_oid(%p) succeeded\n", a_root1);
		} else
			printf("Ok\n");
		printf("4. Try to free ctx2 (%p): ", &clist1);
		if (sysctl_ctx_free(&clist1) != 0) {
			printf("sysctl_ctx_free(%p) failed!\n", &clist1);
			/* Remove subtree forcefully... */
			sysctl_remove_oid(a_root, 1, 1);
		} else
			printf("Ok\n");
		break;
	default:
		error = EOPNOTSUPP;
		break;
	}
	return (error);
}
コード例 #26
0
ファイル: ioat.c プロジェクト: woodsb02/freebsd-base-graphics
static void
ioat_setup_sysctl(device_t device)
{
	struct sysctl_oid_list *par, *statpar, *state, *hammer;
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid *tree, *tmp;
	struct ioat_softc *ioat;

	ioat = DEVICE2SOFTC(device);
	ctx = device_get_sysctl_ctx(device);
	tree = device_get_sysctl_tree(device);
	par = SYSCTL_CHILDREN(tree);

	SYSCTL_ADD_INT(ctx, par, OID_AUTO, "version", CTLFLAG_RD,
	    &ioat->version, 0, "HW version (0xMM form)");
	SYSCTL_ADD_UINT(ctx, par, OID_AUTO, "max_xfer_size", CTLFLAG_RD,
	    &ioat->max_xfer_size, 0, "HW maximum transfer size");
	SYSCTL_ADD_INT(ctx, par, OID_AUTO, "intrdelay_supported", CTLFLAG_RD,
	    &ioat->intrdelay_supported, 0, "Is INTRDELAY supported");
	SYSCTL_ADD_U16(ctx, par, OID_AUTO, "intrdelay_max", CTLFLAG_RD,
	    &ioat->intrdelay_max, 0,
	    "Maximum configurable INTRDELAY on this channel (microseconds)");

	tmp = SYSCTL_ADD_NODE(ctx, par, OID_AUTO, "state", CTLFLAG_RD, NULL,
	    "IOAT channel internal state");
	state = SYSCTL_CHILDREN(tmp);

	SYSCTL_ADD_UINT(ctx, state, OID_AUTO, "ring_size_order", CTLFLAG_RD,
	    &ioat->ring_size_order, 0, "SW descriptor ring size order");
	SYSCTL_ADD_UINT(ctx, state, OID_AUTO, "head", CTLFLAG_RD, &ioat->head,
	    0, "SW descriptor head pointer index");
	SYSCTL_ADD_UINT(ctx, state, OID_AUTO, "tail", CTLFLAG_RD, &ioat->tail,
	    0, "SW descriptor tail pointer index");
	SYSCTL_ADD_UINT(ctx, state, OID_AUTO, "hw_head", CTLFLAG_RD,
	    &ioat->hw_head, 0, "HW DMACOUNT");

	SYSCTL_ADD_UQUAD(ctx, state, OID_AUTO, "last_completion", CTLFLAG_RD,
	    ioat->comp_update, "HW addr of last completion");

	SYSCTL_ADD_INT(ctx, state, OID_AUTO, "is_resize_pending", CTLFLAG_RD,
	    &ioat->is_resize_pending, 0, "resize pending");
	SYSCTL_ADD_INT(ctx, state, OID_AUTO, "is_completion_pending",
	    CTLFLAG_RD, &ioat->is_completion_pending, 0, "completion pending");
	SYSCTL_ADD_INT(ctx, state, OID_AUTO, "is_reset_pending", CTLFLAG_RD,
	    &ioat->is_reset_pending, 0, "reset pending");
	SYSCTL_ADD_INT(ctx, state, OID_AUTO, "is_channel_running", CTLFLAG_RD,
	    &ioat->is_channel_running, 0, "channel running");

	SYSCTL_ADD_PROC(ctx, state, OID_AUTO, "chansts",
	    CTLTYPE_STRING | CTLFLAG_RD, ioat, 0, sysctl_handle_chansts, "A",
	    "String of the channel status");

	SYSCTL_ADD_U16(ctx, state, OID_AUTO, "intrdelay", CTLFLAG_RD,
	    &ioat->cached_intrdelay, 0,
	    "Current INTRDELAY on this channel (cached, microseconds)");

	tmp = SYSCTL_ADD_NODE(ctx, par, OID_AUTO, "hammer", CTLFLAG_RD, NULL,
	    "Big hammers (mostly for testing)");
	hammer = SYSCTL_CHILDREN(tmp);

	SYSCTL_ADD_PROC(ctx, hammer, OID_AUTO, "force_hw_reset",
	    CTLTYPE_INT | CTLFLAG_RW, ioat, 0, sysctl_handle_reset, "I",
	    "Set to non-zero to reset the hardware");
	SYSCTL_ADD_PROC(ctx, hammer, OID_AUTO, "force_hw_error",
	    CTLTYPE_INT | CTLFLAG_RW, ioat, 0, sysctl_handle_error, "I",
	    "Set to non-zero to inject a recoverable hardware error");

	tmp = SYSCTL_ADD_NODE(ctx, par, OID_AUTO, "stats", CTLFLAG_RD, NULL,
	    "IOAT channel statistics");
	statpar = SYSCTL_CHILDREN(tmp);

	SYSCTL_ADD_UQUAD(ctx, statpar, OID_AUTO, "interrupts", CTLFLAG_RW,
	    &ioat->stats.interrupts,
	    "Number of interrupts processed on this channel");
	SYSCTL_ADD_UQUAD(ctx, statpar, OID_AUTO, "descriptors", CTLFLAG_RW,
	    &ioat->stats.descriptors_processed,
	    "Number of descriptors processed on this channel");
	SYSCTL_ADD_UQUAD(ctx, statpar, OID_AUTO, "submitted", CTLFLAG_RW,
	    &ioat->stats.descriptors_submitted,
	    "Number of descriptors submitted to this channel");
	SYSCTL_ADD_UQUAD(ctx, statpar, OID_AUTO, "errored", CTLFLAG_RW,
	    &ioat->stats.descriptors_error,
	    "Number of descriptors failed by channel errors");
	SYSCTL_ADD_U32(ctx, statpar, OID_AUTO, "halts", CTLFLAG_RW,
	    &ioat->stats.channel_halts, 0,
	    "Number of times the channel has halted");
	SYSCTL_ADD_U32(ctx, statpar, OID_AUTO, "last_halt_chanerr", CTLFLAG_RW,
	    &ioat->stats.last_halt_chanerr, 0,
	    "The raw CHANERR when the channel was last halted");

	SYSCTL_ADD_PROC(ctx, statpar, OID_AUTO, "desc_per_interrupt",
	    CTLTYPE_STRING | CTLFLAG_RD, ioat, 0, sysctl_handle_dpi, "A",
	    "Descriptors per interrupt");
}
コード例 #27
0
ファイル: opal_sensor.c プロジェクト: derekmarcotte/freebsd
static int
opal_sensor_attach(device_t dev)
{
	struct opal_sensor_softc *sc;
	struct sysctl_ctx_list *ctx;
	struct sysctl_oid *tree;
	char		type[8];
	phandle_t	node;
	cell_t		sensor_id;
	int		i;

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

	node = ofw_bus_get_node(dev);
	
	if (OF_getencprop(node, "sensor-data", &sensor_id, sizeof(sensor_id)) < 0) {
		device_printf(dev, "Missing sensor ID\n");
		return (ENXIO);
	}
	if (OF_getprop(node, "sensor-type", type, sizeof(type)) < 0) {
		device_printf(dev, "Missing sensor type\n");
		return (ENXIO);
	}
	
	sc->sc_type = -1;
	for (i = 0; i < OPAL_SENSOR_MAX; i++) {
		if (strcmp(type, opal_sensor_types[i]) == 0) {
			sc->sc_type = i;
			break;
		}
	}
	if (sc->sc_type == -1) {
		device_printf(dev, "Unknown sensor type '%s'\n", type);
		return (ENXIO);
	}

	ctx = device_get_sysctl_ctx(dev);
	tree = device_get_sysctl_tree(dev);

	sc->sc_handle = sensor_id;
	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
	    "sensor", CTLTYPE_INT | CTLFLAG_RD, sc, sensor_id,
	    opal_sensor_sysctl, (sc->sc_type == OPAL_SENSOR_TEMP) ? "IK" : "I",
	    "current value");

	SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "type",
	    CTLFLAG_RD, __DECONST(char *, opal_sensor_types[sc->sc_type]),
	    0, "");

	OF_getprop_alloc(node, "label", (void **)&sc->sc_label);
	SYSCTL_ADD_STRING(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "label",
	    CTLFLAG_RD, sc->sc_label, 0, "");

	if (OF_getprop(node, "sensor-data-min",
	    &sensor_id, sizeof(sensor_id)) > 0) {
		sc->sc_min_handle = sensor_id;
		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
		    "sensor_min", CTLTYPE_INT | CTLFLAG_RD, sc, sensor_id,
		    opal_sensor_sysctl,
		    (sc->sc_type == OPAL_SENSOR_TEMP) ? "IK" : "I",
		    "minimum value");
	}

	if (OF_getprop(node, "sensor-data-max",
	    &sensor_id, sizeof(sensor_id)) > 0) {
		sc->sc_max_handle = sensor_id;
		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
		    "sensor_max", CTLTYPE_INT | CTLFLAG_RD, sc, sensor_id,
		    opal_sensor_sysctl,
		    (sc->sc_type == OPAL_SENSOR_TEMP) ? "IK" : "I",
		    "maximum value");
	}

	SENSOR_LOCK_INIT(sc);

	return (0);
}
コード例 #28
0
ファイル: imx6_anatop.c プロジェクト: OpenKod/src
static void
cpufreq_initialize(struct imx6_anatop_softc *sc)
{
	uint32_t cfg3speed;
	struct oppt * op;

	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
	    OID_AUTO, "cpu_mhz", CTLFLAG_RD, &sc->cpu_curmhz, 0, 
	    "CPU frequency");

	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6), 
	    OID_AUTO, "cpu_minmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
	    cpufreq_sysctl_minmhz, "IU", "Minimum CPU frequency");

	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
	    OID_AUTO, "cpu_maxmhz", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
	    cpufreq_sysctl_maxmhz, "IU", "Maximum CPU frequency");

	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
	    OID_AUTO, "cpu_maxmhz_hw", CTLFLAG_RD, &sc->cpu_maxmhz_hw, 0, 
	    "Maximum CPU frequency allowed by hardware");

	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_imx6),
	    OID_AUTO, "cpu_overclock_enable", CTLFLAG_RWTUN, 
	    &sc->cpu_overclock_enable, 0, 
	    "Allow setting CPU frequency higher than cpu_maxmhz_hw");

	/*
	 * XXX 24mhz shouldn't be hard-coded, should get this from imx6_ccm
	 * (even though in the real world it will always be 24mhz).  Oh wait a
	 * sec, I never wrote imx6_ccm.
	 */
	sc->refosc_mhz = 24;

	/*
	 * Get the maximum speed this cpu can be set to.  The values in the
	 * OCOTP CFG3 register are not documented in the reference manual.
	 * The following info was in an archived email found via web search:
	 *   - 2b'11: 1200000000Hz;
	 *   - 2b'10: 996000000Hz;
	 *   - 2b'01: 852000000Hz; -- i.MX6Q Only, exclusive with 996MHz.
	 *   - 2b'00: 792000000Hz;
	 * The default hardware max speed can be overridden by a tunable.
	 */
	cfg3speed = (fsl_ocotp_read_4(FSL_OCOTP_CFG3) & 
	    FSL_OCOTP_CFG3_SPEED_MASK) >> FSL_OCOTP_CFG3_SPEED_SHIFT;
	sc->cpu_maxmhz_hw = imx6_ocotp_mhz_tab[cfg3speed];
	sc->cpu_maxmhz = sc->cpu_maxmhz_hw;

	TUNABLE_INT_FETCH("hw.imx6.cpu_overclock_enable",
	    &sc->cpu_overclock_enable);

	TUNABLE_INT_FETCH("hw.imx6.cpu_minmhz", &sc->cpu_minmhz);
	op = cpufreq_nearest_oppt(sc, sc->cpu_minmhz);
	sc->cpu_minmhz = op->mhz;
	sc->cpu_minmv = op->mv;

	TUNABLE_INT_FETCH("hw.imx6.cpu_maxmhz", &sc->cpu_maxmhz);
	op = cpufreq_nearest_oppt(sc, sc->cpu_maxmhz);
	sc->cpu_maxmhz = op->mhz;
	sc->cpu_maxmv = op->mv;

	/*
	 * Set the CPU to maximum speed.
	 *
	 * We won't have thermal throttling until interrupts are enabled, but we
	 * want to run at full speed through all the device init stuff.  This
	 * basically assumes that a single core can't overheat before interrupts
	 * are enabled; empirical testing shows that to be a safe assumption.
	 */
	cpufreq_set_clock(sc, op);
}
コード例 #29
0
ファイル: am335x_lcd.c プロジェクト: ele7enxxh/dtrace-pf
static int
am335x_lcd_attach(device_t dev)
{
    struct am335x_lcd_softc *sc;
    int rid;
    int div;
    struct panel_info panel;
    uint32_t reg, timing0, timing1, timing2;
    struct sysctl_ctx_list *ctx;
    struct sysctl_oid *tree;
    uint32_t burst_log;
    int err;
    size_t dma_size;

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

    if (am335x_read_panel_info(dev, &panel))
        return (ENXIO);

    int ref_freq = 0;
    ti_prcm_clk_enable(LCDC_CLK);
    if (ti_prcm_clk_get_source_freq(LCDC_CLK, &ref_freq)) {
        device_printf(dev, "Can't get reference frequency\n");
        return (ENXIO);
    }

    rid = 0;
    sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
                                            RF_ACTIVE);
    if (!sc->sc_mem_res) {
        device_printf(dev, "cannot allocate memory window\n");
        return (ENXIO);
    }

    rid = 0;
    sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
                                            RF_ACTIVE);
    if (!sc->sc_irq_res) {
        bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
        device_printf(dev, "cannot allocate interrupt\n");
        return (ENXIO);
    }

    if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
                       NULL, am335x_lcd_intr, sc,
                       &sc->sc_intr_hl) != 0) {
        bus_release_resource(dev, SYS_RES_IRQ, rid,
                             sc->sc_irq_res);
        bus_release_resource(dev, SYS_RES_MEMORY, rid,
                             sc->sc_mem_res);
        device_printf(dev, "Unable to setup the irq handler.\n");
        return (ENXIO);
    }

    LCD_LOCK_INIT(sc);

    /* Panle initialization */
    dma_size = round_page(panel.panel_width*panel.panel_height*panel.bpp/8);

    /*
     * Now allocate framebuffer memory
     */
    err = bus_dma_tag_create(
              bus_get_dma_tag(dev),
              4, 0,		/* alignment, boundary */
              BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
              BUS_SPACE_MAXADDR,		/* highaddr */
              NULL, NULL,			/* filter, filterarg */
              dma_size, 1,			/* maxsize, nsegments */
              dma_size, 0,			/* maxsegsize, flags */
              NULL, NULL,			/* lockfunc, lockarg */
              &sc->sc_dma_tag);
    if (err)
        goto fail;

    err = bus_dmamem_alloc(sc->sc_dma_tag, (void **)&sc->sc_fb_base,
                           BUS_DMA_COHERENT, &sc->sc_dma_map);

    if (err) {
        device_printf(dev, "cannot allocate framebuffer\n");
        goto fail;
    }

    err = bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, sc->sc_fb_base,
                          dma_size, am335x_fb_dmamap_cb, &sc->sc_fb_phys, BUS_DMA_NOWAIT);

    if (err) {
        device_printf(dev, "cannot load DMA map\n");
        goto fail;
    }

    /* Make sure it's blank */
    memset(sc->sc_fb_base, 0x00, dma_size);

    /* Calculate actual FB Size */
    sc->sc_fb_size = panel.panel_width*panel.panel_height*panel.bpp/8;

    /* Only raster mode is supported */
    reg = CTRL_RASTER_MODE;
    div = am335x_lcd_calc_divisor(ref_freq, panel.panel_pxl_clk);
    reg |= (div << CTRL_DIV_SHIFT);
    LCD_WRITE4(sc, LCD_CTRL, reg);

    /* Set timing */
    timing0 = timing1 = timing2 = 0;

    /* Horizontal back porch */
    timing0 |= (panel.panel_hbp & 0xff) << RASTER_TIMING_0_HBP_SHIFT;
    timing2 |= ((panel.panel_hbp >> 8) & 3) << RASTER_TIMING_2_HBPHI_SHIFT;
    /* Horizontal front porch */
    timing0 |= (panel.panel_hfp & 0xff) << RASTER_TIMING_0_HFP_SHIFT;
    timing2 |= ((panel.panel_hfp >> 8) & 3) << RASTER_TIMING_2_HFPHI_SHIFT;
    /* Horizontal sync width */
    timing0 |= (panel.panel_hsw & 0x3f) << RASTER_TIMING_0_HSW_SHIFT;
    timing2 |= ((panel.panel_hsw >> 6) & 0xf) << RASTER_TIMING_2_HSWHI_SHIFT;

    /* Vertical back porch, front porch, sync width */
    timing1 |= (panel.panel_vbp & 0xff) << RASTER_TIMING_1_VBP_SHIFT;
    timing1 |= (panel.panel_vfp & 0xff) << RASTER_TIMING_1_VFP_SHIFT;
    timing1 |= (panel.panel_vsw & 0x3f) << RASTER_TIMING_1_VSW_SHIFT;

    /* Pixels per line */
    timing0 |= (((panel.panel_width - 1) >> 10) & 1)
               << RASTER_TIMING_0_PPLMSB_SHIFT;
    timing0 |= (((panel.panel_width - 1) >> 4) & 0x3f)
               << RASTER_TIMING_0_PPLLSB_SHIFT;

    /* Lines per panel */
    timing1 |= ((panel.panel_height - 1) & 0x3ff)
               << RASTER_TIMING_1_LPP_SHIFT;
    timing2 |= (((panel.panel_height - 1) >> 10 ) & 1)
               << RASTER_TIMING_2_LPP_B10_SHIFT;

    /* clock signal settings */
    if (panel.sync_ctrl)
        timing2 |= RASTER_TIMING_2_PHSVS;
    if (panel.sync_edge)
        timing2 |= RASTER_TIMING_2_PHSVS_RISE;
    else
        timing2 |= RASTER_TIMING_2_PHSVS_FALL;
    if (panel.invert_line_clock)
        timing2 |= RASTER_TIMING_2_IHS;
    if (panel.invert_frm_clock)
        timing2 |= RASTER_TIMING_2_IVS;
    if (panel.panel_invert_pxl_clk)
        timing2 |= RASTER_TIMING_2_IPC;

    /* AC bias */
    timing2 |= (panel.ac_bias << RASTER_TIMING_2_ACB_SHIFT);
    timing2 |= (panel.ac_bias_intrpt << RASTER_TIMING_2_ACBI_SHIFT);

    LCD_WRITE4(sc, LCD_RASTER_TIMING_0, timing0);
    LCD_WRITE4(sc, LCD_RASTER_TIMING_1, timing1);
    LCD_WRITE4(sc, LCD_RASTER_TIMING_2, timing2);

    /* DMA settings */
    reg = LCDDMA_CTRL_FB0_FB1;
    /* Find power of 2 for current burst size */
    switch (panel.dma_burst_sz) {
    case 1:
        burst_log = 0;
        break;
    case 2:
        burst_log = 1;
        break;
    case 4:
        burst_log = 2;
        break;
    case 8:
        burst_log = 3;
        break;
    case 16:
    default:
        burst_log = 4;
        break;
    }
    reg |= (burst_log << LCDDMA_CTRL_BURST_SIZE_SHIFT);
    /* XXX: FIFO TH */
    reg |= (0 << LCDDMA_CTRL_TH_FIFO_RDY_SHIFT);
    LCD_WRITE4(sc, LCD_LCDDMA_CTRL, reg);

    LCD_WRITE4(sc, LCD_LCDDMA_FB0_BASE, sc->sc_fb_phys);
    LCD_WRITE4(sc, LCD_LCDDMA_FB0_CEILING, sc->sc_fb_phys + sc->sc_fb_size - 1);
    LCD_WRITE4(sc, LCD_LCDDMA_FB1_BASE, sc->sc_fb_phys);
    LCD_WRITE4(sc, LCD_LCDDMA_FB1_CEILING, sc->sc_fb_phys + sc->sc_fb_size - 1);

    /* Enable LCD */
    reg = RASTER_CTRL_LCDTFT;
    reg |= (panel.fdd << RASTER_CTRL_REQDLY_SHIFT);
    reg |= (PALETTE_DATA_ONLY << RASTER_CTRL_PALMODE_SHIFT);
    if (panel.bpp >= 24)
        reg |= RASTER_CTRL_TFT24;
    if (panel.bpp == 32)
        reg |= RASTER_CTRL_TFT24_UNPACKED;
    LCD_WRITE4(sc, LCD_RASTER_CTRL, reg);

    LCD_WRITE4(sc, LCD_CLKC_ENABLE,
               CLKC_ENABLE_DMA | CLKC_ENABLE_LDID | CLKC_ENABLE_CORE);

    LCD_WRITE4(sc, LCD_CLKC_RESET, CLKC_RESET_MAIN);
    DELAY(100);
    LCD_WRITE4(sc, LCD_CLKC_RESET, 0);

    reg = IRQ_EOF1 | IRQ_EOF0 | IRQ_FUF | IRQ_PL |
          IRQ_ACB | IRQ_SYNC_LOST |  IRQ_RASTER_DONE |
          IRQ_FRAME_DONE;
    LCD_WRITE4(sc, LCD_IRQENABLE_SET, reg);

    reg = LCD_READ4(sc, LCD_RASTER_CTRL);
    reg |= RASTER_CTRL_LCDEN;
    LCD_WRITE4(sc, LCD_RASTER_CTRL, reg);

    LCD_WRITE4(sc, LCD_SYSCONFIG,
               SYSCONFIG_STANDBY_SMART | SYSCONFIG_IDLE_SMART);

    /* Init backlight interface */
    ctx = device_get_sysctl_ctx(sc->sc_dev);
    tree = device_get_sysctl_tree(sc->sc_dev);
    sc->sc_oid = SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
                                 "backlight", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
                                 am335x_lcd_sysctl_backlight, "I", "LCD backlight");
    sc->sc_backlight = 0;
    /* Check if eCAS interface is available at this point */
    if (am335x_pwm_config_ecas(PWM_UNIT,
                               PWM_PERIOD, PWM_PERIOD) == 0)
        sc->sc_backlight = 100;

    err = (sc_attach_unit(device_get_unit(dev),
                          device_get_flags(dev) | SC_AUTODETECT_KBD));

    if (err) {
        device_printf(dev, "failed to attach syscons\n");
        goto fail;
    }

    am335x_lcd_syscons_setup((vm_offset_t)sc->sc_fb_base, sc->sc_fb_phys, &panel);

    return (0);

fail:
    return (err);
}
コード例 #30
0
static int
est_init(void)
{
	char			hwmodel[128];
	int			mib[] = { CTL_HW, HW_MODEL };
	size_t			modellen = sizeof(hwmodel);
	struct sysctl_oid	*oid, *leaf;
	uint64_t		msr;
	int			mv;
	size_t			len, freq_len;
	int			err;
	size_t			i;

	if ((cpu_feature2 & CPUID2_EST) == 0) {
		kprintf("Enhanced SpeedStep unsupported on this hardware.\n");
		return(EOPNOTSUPP);
	}

	modellen = sizeof(hwmodel);
	err = kernel_sysctl(mib, 2, hwmodel, &modellen, NULL, 0, NULL);
	if (err) {
		kprintf("kernel_sysctl hw.model failed\n");
		return(err);
	}

	msr = rdmsr(MSR_PERF_STATUS);
	mv = MSR2MV(msr);
	kprintf("%s (%d mV) ", est_desc, mv);

	est_fqlist = findcpu(hwmodel, mv);
	if (est_fqlist == NULL) {
		kprintf(" - unknown CPU or operating point"
		       "(cpu_id:%#x, msr:%#jx).\n", cpu_id, (intmax_t)msr);
		return(EOPNOTSUPP);
	}

	/*
	 * OK, tell the user the available frequencies.
	 */
	fsbmult = est_fqlist->fsbmult;
	kprintf("%d MHz\n", MSR2MHZ(msr));

	freq_len = est_fqlist->tablec * (sizeof("9999 ")-1) + 1;
	if (freq_len >= sizeof(freqs_available)) {
		kprintf("increase the size of freqs_available[]\n");
		return(ENOMEM);
	}
	freqs_available[0] = '\0';
	len = 0;
	for (i = 0; i < est_fqlist->tablec; i++) {
		len += ksnprintf(freqs_available + len, freq_len - len, "%d%s",
		    est_fqlist->table[i].mhz,
		    i < est_fqlist->tablec - 1 ? " " : "");
	}
	kprintf("%s frequencies available (MHz): %s\n", est_desc,
	       freqs_available);

	/*
	 * Setup the sysctl sub-tree machdep.est.*
	 */
	oid = SYSCTL_ADD_NODE(&machdep_est_ctx,
	    SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, "est",
	    CTLFLAG_RD, NULL, "");
	if (oid == NULL)
		return(EOPNOTSUPP);
	oid = SYSCTL_ADD_NODE(&machdep_est_ctx, SYSCTL_CHILDREN(oid),
	    OID_AUTO, "frequency", CTLFLAG_RD, NULL, "");
	if (oid == NULL)
		return(EOPNOTSUPP);
	leaf = SYSCTL_ADD_PROC(&machdep_est_ctx, SYSCTL_CHILDREN(oid),
	    OID_AUTO, "target", CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
	    est_sysctl_helper, "I",
	    "Target CPU frequency for Enhanced SpeedStep");
	if (leaf == NULL)
		return(EOPNOTSUPP);
	leaf = SYSCTL_ADD_PROC(&machdep_est_ctx, SYSCTL_CHILDREN(oid),
	    OID_AUTO, "current", CTLTYPE_INT | CTLFLAG_RD, NULL, 0,
	    est_sysctl_helper, "I",
	    "Current CPU frequency for Enhanced SpeedStep");
	if (leaf == NULL)
		return(EOPNOTSUPP);
	leaf = SYSCTL_ADD_STRING(&machdep_est_ctx, SYSCTL_CHILDREN(oid),
	    OID_AUTO, "available", CTLFLAG_RD, freqs_available,
	    sizeof(freqs_available),
	    "CPU frequencies supported by Enhanced SpeedStep");
	if (leaf == NULL)
		return(EOPNOTSUPP);

	return(0);
}