示例#1
0
static int
atkbdc_attach(device_t dev)
{
	atkbdc_softc_t	*sc;
	struct resource *port;
	int		unit;
	int		error;
	int		rid;
	int		i;

	unit = device_get_unit(dev);
	sc = *(atkbdc_softc_t **)device_get_softc(dev);
	if (sc == NULL) {
		/*
		 * We have to maintain two copies of the kbdc_softc struct,
		 * as the low-level console needs to have access to the
		 * keyboard controller before kbdc is probed and attached. 
		 * kbdc_soft[] contains the default entry for that purpose.
		 * See atkbdc.c. XXX
		 */
		sc = atkbdc_get_softc(unit);
		if (sc == NULL)
			return ENOMEM;
	}

	/* XXX should track resource in softc */
	rid = 0;
	port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
				  0, ~0, IO_KBDSIZE, RF_ACTIVE);
	if (!port)
		return ENXIO;
	error = atkbdc_attach_unit(unit, sc, rman_get_start(port));
	if (error)
		return error;
	*(atkbdc_softc_t **)device_get_softc(dev) = sc;

	/*
	 * Add all devices configured to be attached to atkbdc0.
	 */
	for (i = resource_query_string(-1, "at", "atkbdc0");
	     i != -1;
	     i = resource_query_string(i, "at", "atkbdc0")) {
		atkbdc_add_device(dev, resource_query_name(i),
				  resource_query_unit(i));
	}

	/*
	 * and atkbdc?
	 */
	for (i = resource_query_string(-1, "at", "atkbdc");
	     i != -1;
	     i = resource_query_string(i, "at", "atkbdc")) {
		atkbdc_add_device(dev, resource_query_name(i),
				  resource_query_unit(i));
	}

	bus_generic_attach(dev);

	return 0;
}
示例#2
0
static int
atkbdc_isa_attach(device_t dev)
{
	atkbdc_softc_t	*sc;
	int		unit;
	int		error;
	int		rid;

	unit = device_get_unit(dev);
	sc = *(atkbdc_softc_t **)device_get_softc(dev);
	if (sc == NULL) {
		/*
		 * We have to maintain two copies of the kbdc_softc struct,
		 * as the low-level console needs to have access to the
		 * keyboard controller before kbdc is probed and attached.
		 * kbdc_soft[] contains the default entry for that purpose.
		 * See atkbdc.c. XXX
		 */
		sc = atkbdc_get_softc(unit);
		if (sc == NULL)
			return ENOMEM;
	}

	rid = 0;
	sc->retry = 5000;
	sc->port0 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
					   RF_ACTIVE);
	if (sc->port0 == NULL)
		return ENXIO;
	rid = 1;
	sc->port1 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
					   RF_ACTIVE);
	if (sc->port1 == NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
		return ENXIO;
	}

	/*
	 * If the device is not created by the PnP BIOS or ACPI, then
	 * the hint for the IRQ is on the child atkbd device, not the
	 * keyboard controller, so this can fail.
	 */
	rid = 0;
	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);

	error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
	if (error) {
		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
		bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
		if (sc->irq != NULL)
			bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
		return error;
	}
	*(atkbdc_softc_t **)device_get_softc(dev) = sc;

	bus_generic_probe(dev);
	bus_generic_attach(dev);

	return 0;
}
static int
atkbdc_isa_attach(device_t dev)
{
	atkbdc_softc_t	*sc;
	int		unit;
	int		error;
	int		rid;

	unit = device_get_unit(dev);
	sc = *(atkbdc_softc_t **)device_get_softc(dev);
	if (sc == NULL) {
		/*
		 * We have to maintain two copies of the kbdc_softc struct,
		 * as the low-level console needs to have access to the
		 * keyboard controller before kbdc is probed and attached.
		 * kbdc_soft[] contains the default entry for that purpose.
		 * See atkbdc.c. XXX
		 */
		sc = atkbdc_get_softc(unit);
		if (sc == NULL)
			return ENOMEM;
	}

	rid = 0;
	sc->port0 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
					   RF_ACTIVE);
	if (sc->port0 == NULL)
		return ENXIO;
	rid = 1;
	sc->port1 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
					   RF_ACTIVE);
	if (sc->port1 == NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
		return ENXIO;
	}

	error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
	if (error) {
		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
		bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
		return error;
	}
	*(atkbdc_softc_t **)device_get_softc(dev) = sc;

	bus_generic_attach(dev);

	return 0;
}
示例#4
0
static int
atkbdc_ebus_attach(device_t dev)
{
	atkbdc_softc_t *sc;
	atkbdc_device_t *adi;
	device_t cdev;
	phandle_t child;
	u_long count, intr, start;
	int children, error, rid, unit;
	char *cname, *dname;

	unit = device_get_unit(dev);
	sc = *(atkbdc_softc_t **)device_get_softc(dev);
	if (sc == NULL) {
		/*
		 * We have to maintain two copies of the kbdc_softc struct,
		 * as the low-level console needs to have access to the
		 * keyboard controller before kbdc is probed and attached.
		 * kbdc_soft[] contains the default entry for that purpose.
		 * See atkbdc.c. XXX
		 */
		sc = atkbdc_get_softc(unit);
		if (sc == NULL)
			return (ENOMEM);
		device_set_softc(dev, sc);
	}

	rid = 0;
	if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) {
		device_printf(dev,
		    "cannot determine command/data port resource\n");
		return (ENXIO);
	}
	sc->retry = 5000;
	sc->port0 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start,
	    1, RF_ACTIVE);
	if (sc->port0 == NULL) {
		device_printf(dev,
		    "cannot allocate command/data port resource\n");
		return (ENXIO);
	}

	rid = 1;
	if (bus_get_resource(dev, SYS_RES_MEMORY, rid, &start, &count) != 0) {
		device_printf(dev, "cannot determine status port resource\n");
		error = ENXIO;
		goto fail_port0;
	}
	start += KBD_STATUS_PORT;
	sc->port1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start,
	    1, RF_ACTIVE);
	if (sc->port1 == NULL) {
		device_printf(dev, "cannot allocate status port resource\n");
		error = ENXIO;
		goto fail_port0;
	}

	error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
	if (error != 0) {
		device_printf(dev, "atkbdc_attach_unit failed\n");
		goto fail_port1;
	}

	/* Attach children. */
	children = 0;
	for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
	    child = OF_peer(child)) {
		if ((OF_getprop_alloc(child, "name", 1, (void **)&cname)) == -1)
			continue;
		if (children >= 2) {
			device_printf(dev,
			    "<%s>: only two children per 8042 supported\n",
			    cname);
			free(cname, M_OFWPROP);
			continue;
		}
		adi = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV,
		    M_NOWAIT | M_ZERO);
		if (adi == NULL) {
			device_printf(dev, "<%s>: malloc failed\n", cname);
			free(cname, M_OFWPROP);
			continue;
		}
		if (strcmp(cname, "kb_ps2") == 0) {
			adi->rid = KBDC_RID_KBD;
			dname = ATKBD_DRIVER_NAME;
		} else if (strcmp(cname, "kdmouse") == 0) {
			adi->rid = KBDC_RID_AUX;
			dname = PSM_DRIVER_NAME;
		} else {
			device_printf(dev, "<%s>: unknown device\n", cname);
			free(adi, M_ATKBDDEV);
			free(cname, M_OFWPROP);
			continue;
		}
		intr = bus_get_resource_start(dev, SYS_RES_IRQ, adi->rid);
		if (intr == 0) {
			device_printf(dev,
			    "<%s>: cannot determine interrupt resource\n",
			    cname);
			free(adi, M_ATKBDDEV);
			free(cname, M_OFWPROP);
			continue;
		}
		resource_list_init(&adi->resources);
		resource_list_add(&adi->resources, SYS_RES_IRQ, adi->rid,
		    intr, intr, 1);
		if ((cdev = device_add_child(dev, dname, -1)) == NULL) {
			device_printf(dev, "<%s>: device_add_child failed\n",
			    cname);
			resource_list_free(&adi->resources);
			free(adi, M_ATKBDDEV);
			free(cname, M_OFWPROP);
			continue;
		}
		device_set_ivars(cdev, adi);
		children++;
	}

	error = bus_generic_attach(dev);
	if (error != 0) {
		device_printf(dev, "bus_generic_attach failed\n");
		goto fail_port1;
	}

	return (0);

 fail_port1:
	bus_release_resource(dev, SYS_RES_MEMORY, 1, sc->port1);
 fail_port0:
	bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->port0);

	return (error);
}
示例#5
0
static int
atkbdc_attach(device_t dev)
{
	atkbdc_softc_t	*sc;
	int		unit;
	int		error;
	int		rid;
	int		i;

	lwkt_gettoken(&tty_token);
	unit = device_get_unit(dev);
	sc = *(atkbdc_softc_t **)device_get_softc(dev);
	if (sc == NULL) {
		/*
		 * We have to maintain two copies of the kbdc_softc struct,
		 * as the low-level console needs to have access to the
		 * keyboard controller before kbdc is probed and attached. 
		 * kbdc_soft[] contains the default entry for that purpose.
		 * See atkbdc.c. XXX
		 */
		sc = atkbdc_get_softc(unit);
		if (sc == NULL) {
			lwkt_reltoken(&tty_token);
			return ENOMEM;
		}
	}

	rid = 0;
	sc->port0 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
				       RF_ACTIVE);
	if (sc->port0 == NULL) {
		lwkt_reltoken(&tty_token);
		return ENXIO;
	}
	rid = 1;
	sc->port1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
				       RF_ACTIVE);
	if (sc->port1 == NULL) {
		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
		lwkt_reltoken(&tty_token);
		return ENXIO;
	}

	error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
	if (error) {
		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
		bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
		lwkt_reltoken(&tty_token);
		return error;
	}
	*(atkbdc_softc_t **)device_get_softc(dev) = sc;

	/*
	 * Add all devices configured to be attached to atkbdc0.
	 */
	for (i = resource_query_string(-1, "at", device_get_nameunit(dev));
	     i != -1;
	     i = resource_query_string(i, "at", device_get_nameunit(dev))) {
		atkbdc_add_device(dev, resource_query_name(i),
				  resource_query_unit(i));
	}

	/*
	 * and atkbdc?
	 */
	for (i = resource_query_string(-1, "at", device_get_name(dev));
	     i != -1;
	     i = resource_query_string(i, "at", device_get_name(dev))) {
		atkbdc_add_device(dev, resource_query_name(i),
				  resource_query_unit(i));
	}

	bus_generic_attach(dev);

	lwkt_reltoken(&tty_token);
	return 0;
}