- Hook up the new locations of the atkbdc(4), atkbd(4) and psm(4) source

files after they were repo-copied to sys/dev/atkbdc. The sources of
  atkbdc(4) and its children were moved to the new location in preparation
  for adding an EBus front-end to atkbdc(4) for use on sparc64; i.e. in
  order to not further scatter them over the whole tree which would have
  been the result of adding atkbdc_ebus.c in e.g. sys/sparc64/ebus. Another
  reason for the repo-copies was that some of the sources were misfiled,
  e.g. sys/isa/atkbd_isa.c wasn't ISA-specific at all but for hanging
  atkbd(4) off of atkbdc(4) and was renamed to atkbd_atkbdc.c accordingly.
  Most of sys/isa/psm.c, i.e. expect for its PSMC PNP part, also isn't
  ISA-specific.
- Separate the parts of atkbdc_isa.c which aren't actually ISA-specific
  but are shareable between different atkbdc(4) bus front-ends into
  atkbdc_subr.c (repo-copied from atkbdc_isa.c). While here use
  bus_generic_rl_alloc_resource() and bus_generic_rl_release_resource()
  respectively in atkbdc_isa.c instead of rolling own versions.
- Add sparc64 MD bits to atkbdc(4) and atkbd(4) and an EBus front-end for
  atkbdc(4). PS/2 controllers and input devices are used on a couple of
  Sun OEM boards and occur on either the EBus or the ISA bus. Depending on
  the board it's either the only on-board mean to connect a keyboard and
  mouse or an alternative to either RS232 or USB devices.
- Wrap the PSMC PNP part of psm.c in #ifdef DEV_ISA so it can be compiled
  without isa(4) (e.g. for EBus-only machines). This ISA-specific part
  isn't separated into its own source file, yet, as it requires more work
  than was feasible for 6.0 in order to do it in a clean way. Actually
  philip@ is working on a rewrite of psm(4) so a more comprehensive
  clean-up and separation of hardware dependent and independent parts is
  expected to happen after 6.0.

Tested on:	i386, sparc64 (AX1105, AXe and AXi boards)
Reviewed by:	philip
This commit is contained in:
Marius Strobl 2005-06-10 20:56:38 +00:00
parent a8e0b2e8ab
commit 520b635320
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147271
22 changed files with 546 additions and 7438 deletions

View file

@ -166,6 +166,12 @@ crypto/blowfish/bf_enc.c optional crypto
crypto/des/des_enc.c optional crypto
dev/advansys/adv_isa.c optional adv isa
dev/aic/aic_isa.c optional aic isa
dev/atkbdc/atkbd.c optional atkbd atkbdc
dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc
dev/atkbdc/atkbdc.c optional atkbdc
dev/atkbdc/atkbdc_isa.c optional atkbdc isa
dev/atkbdc/atkbdc_subr.c optional atkbdc
dev/atkbdc/psm.c optional psm atkbdc
dev/dec/mcclock.c optional mcclock
dev/dec/mcclock_if.m optional mcclock
dev/ed/if_ed_3c503.c optional ed isa ed_3c503
@ -180,8 +186,6 @@ dev/fb/vga.c optional vga
dev/fdc/fdc.c optional fdc
dev/fdc/fdc_isa.c optional fdc isa
dev/hwpmc/hwpmc_alpha.c optional hwpmc
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
@ -202,9 +206,6 @@ dev/syscons/sysmouse.c optional sc
dev/uart/uart_cpu_alpha.c optional uart
geom/geom_bsd.c standard
geom/geom_bsd_enc.c standard
isa/atkbd_isa.c optional atkbd
isa/atkbdc_isa.c optional atkbdc
isa/psm.c optional psm
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
libkern/alpha/bswap16.S standard

View file

@ -132,6 +132,12 @@ crypto/des/des_enc.c optional netsmbcrypto
crypto/des/des_setkey.c optional netsmbcrypto
dev/acpica/acpi_if.m standard
dev/arcmsr/arcmsr.c optional arcmsr pci
dev/atkbdc/atkbd.c optional atkbd atkbdc
dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc
dev/atkbdc/atkbdc.c optional atkbdc
dev/atkbdc/atkbdc_isa.c optional atkbdc isa
dev/atkbdc/atkbdc_subr.c optional atkbdc
dev/atkbdc/psm.c optional psm atkbdc
dev/fb/fb.c optional fb
dev/fb/fb.c optional vga
dev/fb/splash.c optional splash
@ -149,8 +155,6 @@ dev/fdc/fdc_pccard.c optional fdc pccard
dev/hwpmc/hwpmc_amd.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_x86.c optional hwpmc
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
@ -175,9 +179,6 @@ geom/geom_bsd.c standard
geom/geom_bsd_enc.c standard
geom/geom_mbr.c standard
geom/geom_mbr_enc.c standard
isa/atkbd_isa.c optional atkbd
isa/atkbdc_isa.c optional atkbdc
isa/psm.c optional psm
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
kern/link_elf_obj.c standard

View file

@ -145,6 +145,12 @@ dev/ar/if_ar_isa.c optional ar isa
dev/ar/if_ar_pci.c optional ar pci
dev/arl/if_arl.c optional arl
dev/arl/if_arl_isa.c optional arl isa
dev/atkbdc/atkbd.c optional atkbd atkbdc
dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc
dev/atkbdc/atkbdc.c optional atkbdc
dev/atkbdc/atkbdc_isa.c optional atkbdc isa
dev/atkbdc/atkbdc_subr.c optional atkbdc
dev/atkbdc/psm.c optional psm atkbdc
dev/cm/if_cm_isa.c optional cm isa
dev/cp/cpddk.c optional cp
dev/cp/if_cp.c optional cp
@ -185,8 +191,6 @@ dev/if_ndis/if_ndis_pci.c optional ndis cardbus
dev/if_ndis/if_ndis_pci.c optional ndis pci
dev/if_ndis/if_ndis_usb.c optional ndis usb
dev/io/iodev.c optional io
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
@ -448,9 +452,6 @@ i4b/layer1/itjc/i4b_itjc_isac.c optional itjc
i4b/layer1/itjc/i4b_itjc_l1.c optional itjc
i4b/layer1/itjc/i4b_itjc_l1fsm.c optional itjc
#
isa/atkbd_isa.c optional atkbd
isa/atkbdc_isa.c optional atkbdc
isa/psm.c optional psm
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
kern/imgact_aout.c optional compat_aout

View file

@ -48,13 +48,17 @@ crypto/des/des_enc.c optional crypto
crypto/des/des_enc.c optional ipsec ipsec_esp
dev/advansys/adv_isa.c optional adv isa
dev/aic/aic_isa.c optional aic isa
dev/atkbdc/atkbd.c optional atkbd atkbdc
dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc
dev/atkbdc/atkbdc.c optional atkbdc
dev/atkbdc/atkbdc_isa.c optional atkbdc isa
dev/atkbdc/atkbdc_subr.c optional atkbdc
dev/atkbdc/psm.c optional psm atkbdc
dev/fb/fb.c optional fb
dev/fb/fb.c optional vga
dev/fb/splash.c optional splash
dev/fb/vga.c optional vga
dev/hwpmc/hwpmc_ia64.c optional hwpmc
dev/kbd/atkbd.c optional atkbd
dev/kbd/atkbdc.c optional atkbdc
dev/kbd/kbd.c optional atkbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
@ -125,9 +129,6 @@ ia64/ia64/vm_machdep.c standard
ia64/isa/isa.c optional isa
ia64/isa/isa_dma.c optional isa
ia64/pci/pci_cfgreg.c optional pci
isa/atkbd_isa.c optional atkbd
isa/atkbdc_isa.c optional atkbdc
isa/psm.c optional psm
isa/syscons_isa.c optional sc
isa/vga_isa.c optional vga
kern/imgact_elf32.c optional compat_ia32

View file

@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/eventhandler.h>
#include <sys/proc.h>
#include <sys/limits.h>
#include <sys/malloc.h>
@ -51,16 +52,17 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_param.h>
#include <isa/isareg.h>
#endif /* __i386__ */
#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
#include <isa/isareg.h>
#include <dev/atkbdc/atkbdreg.h>
#include <dev/atkbdc/atkbdcreg.h>
static timeout_t atkbd_timeout;
static void atkbd_shutdown_final(void *v);
int
atkbd_probe_unit(int unit, int ctlr, int irq, int flags)
@ -119,6 +121,10 @@ atkbd_attach_unit(int unit, keyboard_t **kbd, int ctlr, int irq, int flags)
if (bootverbose)
(*sw->diag)(*kbd, bootverbose);
EVENTHANDLER_REGISTER(shutdown_final, atkbd_shutdown_final, *kbd,
SHUTDOWN_PRI_DEFAULT);
return 0;
}
@ -839,7 +845,7 @@ atkbd_check_char(keyboard_t *kbd)
static int
atkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
{
/* trasnlate LED_XXX bits into the device specific bits */
/* translate LED_XXX bits into the device specific bits */
static u_char ledmap[8] = {
0, 4, 2, 6, 1, 5, 3, 7,
};
@ -1021,6 +1027,30 @@ atkbd_poll(keyboard_t *kbd, int on)
return 0;
}
static void
atkbd_shutdown_final(void *v)
{
#ifdef __sparc64__
keyboard_t *kbd = v;
KBDC kbdc = ((atkbd_state_t *)kbd->kb_data)->kbdc;
/*
* Turn off the translation in preparation for handing the keyboard
* over to the OFW as the OBP driver doesn't use translation and
* also doesn't disable it itself resulting in a broken keymap at
* the boot prompt. Also disable the aux port and the interrupts as
* the OBP driver doesn't use them, i.e. polls the keyboard. Not
* disabling the interrupts doesn't cause real problems but the
* responsiveness is a bit better when they are turned off.
*/
send_kbd_command(kbdc, KBDC_DISABLE_KBD);
set_controller_command_byte(kbdc,
KBD_AUX_CONTROL_BITS | KBD_KBD_CONTROL_BITS | KBD_TRANSLATION,
KBD_DISABLE_AUX_PORT | KBD_DISABLE_KBD_INT | KBD_ENABLE_KBD_PORT);
send_kbd_command(kbdc, KBDC_ENABLE_KBD);
#endif
}
/* local functions */
static int
@ -1299,11 +1329,10 @@ init_keyboard(KBDC kbdc, int *type, int flags)
}
}
#ifdef __alpha__
#if defined(__alpha__) || defined(__sparc64__)
if (send_kbd_command_and_data(
kbdc, KBDC_SET_SCANCODE_SET, 2) != KBD_ACK) {
printf("atkbd: can't set translation.\n");
}
c |= KBD_TRANSLATION;
#endif

View file

@ -41,11 +41,8 @@ __FBSDID("$FreeBSD$");
#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
#include <dev/atkbdc/atkbdreg.h>
#include <dev/atkbdc/atkbdcreg.h>
typedef struct {
struct resource *intr;
@ -58,7 +55,7 @@ static void atkbdidentify(driver_t *driver, device_t dev);
static int atkbdprobe(device_t dev);
static int atkbdattach(device_t dev);
static int atkbdresume(device_t dev);
static void atkbd_isa_intr(void *arg);
static void atkbdintr(void *arg);
static device_method_t atkbd_methods[] = {
DEVMETHOD(device_identify, atkbdidentify),
@ -139,7 +136,7 @@ atkbdattach(device_t dev)
RF_SHAREABLE | RF_ACTIVE);
if (sc->intr == NULL)
return ENXIO;
error = bus_setup_intr(dev, sc->intr, INTR_TYPE_TTY, atkbd_isa_intr,
error = bus_setup_intr(dev, sc->intr, INTR_TYPE_TTY, atkbdintr,
kbd, &sc->ih);
if (error)
bus_release_resource(dev, SYS_RES_IRQ, rid, sc->intr);
@ -169,7 +166,7 @@ atkbdresume(device_t dev)
}
static void
atkbd_isa_intr(void *arg)
atkbdintr(void *arg)
{
keyboard_t *kbd;

View file

@ -44,10 +44,15 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/atkbdc/atkbdcreg.h>
#include <dev/kbd/atkbdcreg.h>
#ifdef __sparc64__
#include <dev/ofw/openfirm.h>
#include <machine/bus_private.h>
#include <machine/ofw_machdep.h>
#else
#include <isa/isareg.h>
#endif
/* constants */
@ -88,6 +93,10 @@ static atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc };
static int verbose = KBDIO_DEBUG;
#ifdef __sparc64__
static struct bus_space_tag atkbdc_bst_store[MAXKBDC];
#endif
/* function prototypes */
static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
@ -144,14 +153,16 @@ atkbdc_configure(void)
bus_space_tag_t tag;
bus_space_handle_t h0;
bus_space_handle_t h1;
#ifdef __sparc64__
char name[32];
phandle_t chosen, node;
ihandle_t stdin;
bus_addr_t port0;
bus_addr_t port1;
int space;
#else
int port0;
int port1;
port0 = IO_KBD;
resource_int_value("atkbdc", 0, "port", &port0);
port1 = IO_KBD + KBD_STATUS_PORT;
#if 0
resource_int_value("atkbdc", 0, "port", &port0);
#endif
/* XXX: tag should be passed from the caller */
@ -163,16 +174,50 @@ atkbdc_configure(void)
tag = busspace_isa_io;
#elif defined(__ia64__)
tag = IA64_BUS_SPACE_IO;
#elif defined(__sparc64__)
tag = &atkbdc_bst_store[0];
#else
#error "define tag!"
#endif
#ifdef __sparc64__
if ((chosen = OF_finddevice("/chosen")) == -1)
return 0;
if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1)
return 0;
if ((node = OF_instance_to_package(stdin)) == -1)
return 0;
if (OF_getprop(node, "name", name, sizeof(name)) == -1)
return 0;
name[sizeof(name) - 1] = '\0';
if (strcmp(name, "kb_ps2") != 0)
return 0;
/*
* The stdin handle points to an instance of a PS/2 keyboard
* package but we want the 8042 controller, which is the parent
* of that keyboard node.
*/
if ((node = OF_parent(node)) == 0)
return 0;
if (OF_decode_addr(node, 0, &space, &port0) != 0)
return 0;
h0 = sparc64_fake_bustag(space, port0, tag);
bus_space_subregion(tag, h0, KBD_DATA_PORT, 1, &h0);
if (OF_decode_addr(node, 1, &space, &port1) != 0)
return 0;
h1 = sparc64_fake_bustag(space, port1, tag);
bus_space_subregion(tag, h1, KBD_STATUS_PORT, 1, &h1);
#else
port0 = IO_KBD;
resource_int_value("atkbdc", 0, "port", &port0);
port1 = IO_KBD + KBD_STATUS_PORT;
#if notyet
bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
#else
h0 = (bus_space_handle_t)port0;
h1 = (bus_space_handle_t)port1;
#endif
#endif
return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
}

View file

@ -0,0 +1,304 @@
/*-
* Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
* Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* from: FreeBSD: src/sys/isa/atkbdc_isa.c,v 1.31 2005/05/29 04:42:28 nyan
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_kbd.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/kbio.h>
#include <sys/malloc.h>
#include <dev/ofw/ofw_bus.h>
#include <machine/resource.h>
#include <machine/ver.h>
#include <sys/rman.h>
#include <dev/kbd/kbdreg.h>
#include <dev/atkbdc/atkbdreg.h>
#include <dev/atkbdc/atkbdc_subr.h>
#include <dev/atkbdc/atkbdcreg.h>
#include <dev/atkbdc/psm.h>
static device_probe_t atkbdc_ebus_probe;
static device_attach_t atkbdc_ebus_attach;
static device_method_t atkbdc_ebus_methods[] = {
DEVMETHOD(device_probe, atkbdc_ebus_probe),
DEVMETHOD(device_attach, atkbdc_ebus_attach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(bus_print_child, atkbdc_print_child),
DEVMETHOD(bus_read_ivar, atkbdc_read_ivar),
DEVMETHOD(bus_write_ivar, atkbdc_write_ivar),
DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list),
DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
{ 0, 0 }
};
static driver_t atkbdc_ebus_driver = {
ATKBDC_DRIVER_NAME,
atkbdc_ebus_methods,
sizeof(atkbdc_softc_t *),
};
DRIVER_MODULE(atkbdc, ebus, atkbdc_ebus_driver, atkbdc_devclass, 0, 0);
static int
atkbdc_ebus_probe(device_t dev)
{
struct resource *port0, *port1;
u_long count, start;
int error, rid;
if (strcmp(ofw_bus_get_name(dev), "8042") != 0)
return (ENXIO);
/*
* On AXi and AXmp boards the NS16550 (used to connect keyboard/
* mouse) share their IRQ lines with the i8042. Any IRQ activity
* (typically during attach) of the NS16550 used to connect the
* keyboard when actually the PS/2 keyboard is selected in OFW
* causes interaction with the OBP i8042 driver resulting in a
* hang and vice versa. As RS232 keyboards and mice obviously
* aren't meant to be used in parallel with PS/2 ones on these
* boards don't attach to the i8042 in case the PS/2 keyboard
* isn't selected in order to prevent such hangs.
* Note that it's not sufficient here to rely on the '8042' node
* only showing up when a PS/2 keyboard is actually connected as
* the user still might have adjusted the 'keyboard' alias to
* point to the RS232 keyboard.
*/
if ((!strcmp(sparc64_model, "SUNW,UltraAX-MP") ||
!strcmp(sparc64_model, "SUNW,UltraSPARC-IIi-Engine")) &&
OF_finddevice("keyboard") != ofw_bus_get_node(dev)) {
device_disable(dev);
return (ENXIO);
}
device_set_desc(dev, "Keyboard controller (i8042)");
/*
* The '8042' node has two identical 8 addresses wide resources
* which are apparently meant to be used one for the keyboard
* half and the other one for the mouse half. To simplify matters
* we use one for the command/data port resource and the other
* one for the status port resource as the atkbdc(4) back-end
* expects two struct resource rather than two bus space handles.
*/
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);
}
port0 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 1,
RF_ACTIVE);
if (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;
port1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, start, start, 1,
RF_ACTIVE);
if (port1 == NULL) {
device_printf(dev, "cannot allocate status port resource\n");
error = ENXIO;
goto fail_port0;
}
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
if (error != 0)
device_printf(dev, "atkbdc_porbe_unit failed\n");
bus_release_resource(dev, SYS_RES_MEMORY, 1, port1);
fail_port0:
bus_release_resource(dev, SYS_RES_MEMORY, 0, port0);
return (error);
}
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->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);
}

View file

@ -38,57 +38,30 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/kbd/atkbdcreg.h>
#include <dev/atkbdc/atkbdc_subr.h>
#include <dev/atkbdc/atkbdcreg.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
static MALLOC_DEFINE(M_ATKBDDEV, "atkbddev", "AT Keyboard device");
/* children */
typedef struct atkbdc_device {
struct resource_list resources;
int rid;
u_int32_t vendorid;
u_int32_t serial;
u_int32_t logicalid;
u_int32_t compatid;
} atkbdc_device_t;
/* kbdc */
static devclass_t atkbdc_devclass;
static int atkbdc_probe(device_t dev);
static int atkbdc_attach(device_t dev);
static device_t atkbdc_add_child(device_t bus, int order, char *name,
static int atkbdc_isa_probe(device_t dev);
static int atkbdc_isa_attach(device_t dev);
static device_t atkbdc_isa_add_child(device_t bus, int order, char *name,
int unit);
static int atkbdc_print_child(device_t bus, device_t dev);
static int atkbdc_read_ivar(device_t bus, device_t dev, int index,
uintptr_t *val);
static int atkbdc_write_ivar(device_t bus, device_t dev, int index,
uintptr_t val);
static struct resource_list
*atkbdc_get_resource_list (device_t bus, device_t dev);
static struct resource
*atkbdc_alloc_resource(device_t bus, device_t dev, int type,
int *rid, u_long start, u_long end,
u_long count, u_int flags);
static int atkbdc_release_resource(device_t bus, device_t dev, int type,
int rid, struct resource *res);
static device_method_t atkbdc_methods[] = {
DEVMETHOD(device_probe, atkbdc_probe),
DEVMETHOD(device_attach, atkbdc_attach),
static device_method_t atkbdc_isa_methods[] = {
DEVMETHOD(device_probe, atkbdc_isa_probe),
DEVMETHOD(device_attach, atkbdc_isa_attach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(bus_add_child, atkbdc_add_child),
DEVMETHOD(bus_add_child, atkbdc_isa_add_child),
DEVMETHOD(bus_print_child, atkbdc_print_child),
DEVMETHOD(bus_read_ivar, atkbdc_read_ivar),
DEVMETHOD(bus_write_ivar, atkbdc_write_ivar),
DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list),
DEVMETHOD(bus_alloc_resource, atkbdc_alloc_resource),
DEVMETHOD(bus_release_resource, atkbdc_release_resource),
DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
@ -100,9 +73,9 @@ static device_method_t atkbdc_methods[] = {
{ 0, 0 }
};
static driver_t atkbdc_driver = {
static driver_t atkbdc_isa_driver = {
ATKBDC_DRIVER_NAME,
atkbdc_methods,
atkbdc_isa_methods,
sizeof(atkbdc_softc_t *),
};
@ -112,7 +85,7 @@ static struct isa_pnp_id atkbdc_ids[] = {
};
static int
atkbdc_probe(device_t dev)
atkbdc_isa_probe(device_t dev)
{
struct resource *port0;
struct resource *port1;
@ -167,7 +140,7 @@ atkbdc_probe(device_t dev)
}
static int
atkbdc_attach(device_t dev)
atkbdc_isa_attach(device_t dev)
{
atkbdc_softc_t *sc;
int unit;
@ -180,7 +153,7 @@ atkbdc_attach(device_t dev)
/*
* 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.
* keyboard controller before kbdc is probed and attached.
* kbdc_soft[] contains the default entry for that purpose.
* See atkbdc.c. XXX
*/
@ -216,7 +189,7 @@ atkbdc_attach(device_t dev)
}
static device_t
atkbdc_add_child(device_t bus, int order, char *name, int unit)
atkbdc_isa_add_child(device_t bus, int order, char *name, int unit)
{
atkbdc_device_t *ivar;
device_t child;
@ -258,108 +231,5 @@ atkbdc_add_child(device_t bus, int order, char *name, int unit)
return child;
}
static int
atkbdc_print_child(device_t bus, device_t dev)
{
atkbdc_device_t *kbdcdev;
u_long irq;
int flags;
int retval = 0;
kbdcdev = (atkbdc_device_t *)device_get_ivars(dev);
retval += bus_print_child_header(bus, dev);
flags = device_get_flags(dev);
if (flags != 0)
retval += printf(" flags 0x%x", flags);
irq = bus_get_resource_start(dev, SYS_RES_IRQ, kbdcdev->rid);
if (irq != 0)
retval += printf(" irq %ld", irq);
retval += bus_print_child_footer(bus, dev);
return (retval);
}
static int
atkbdc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
switch (index) {
case KBDC_IVAR_VENDORID:
*val = (u_long)ivar->vendorid;
break;
case KBDC_IVAR_SERIAL:
*val = (u_long)ivar->serial;
break;
case KBDC_IVAR_LOGICALID:
*val = (u_long)ivar->logicalid;
break;
case KBDC_IVAR_COMPATID:
*val = (u_long)ivar->compatid;
break;
default:
return ENOENT;
}
return 0;
}
static int
atkbdc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
switch (index) {
case KBDC_IVAR_VENDORID:
ivar->vendorid = (u_int32_t)val;
break;
case KBDC_IVAR_SERIAL:
ivar->serial = (u_int32_t)val;
break;
case KBDC_IVAR_LOGICALID:
ivar->logicalid = (u_int32_t)val;
break;
case KBDC_IVAR_COMPATID:
ivar->compatid = (u_int32_t)val;
break;
default:
return ENOENT;
}
return 0;
}
static struct resource_list
*atkbdc_get_resource_list (device_t bus, device_t dev)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return &ivar->resources;
}
static struct resource
*atkbdc_alloc_resource(device_t bus, device_t dev, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return resource_list_alloc(&ivar->resources, bus, dev, type, rid,
start, end, count, flags);
}
static int
atkbdc_release_resource(device_t bus, device_t dev, int type, int rid,
struct resource *res)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return resource_list_release(&ivar->resources, bus, dev, type, rid,
res);
}
DRIVER_MODULE(atkbdc, isa, atkbdc_driver, atkbdc_devclass, 0, 0);
DRIVER_MODULE(atkbdc, acpi, atkbdc_driver, atkbdc_devclass, 0, 0);
DRIVER_MODULE(atkbdc, isa, atkbdc_isa_driver, atkbdc_devclass, 0, 0);
DRIVER_MODULE(atkbdc, acpi, atkbdc_isa_driver, atkbdc_devclass, 0, 0);

View file

@ -22,6 +22,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* from: FreeBSD: src/sys/isa/atkbdc_isa.c,v 1.31 2005/05/29 04:42:28 nyan Exp
*/
#include <sys/cdefs.h>
@ -38,227 +40,14 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/kbd/atkbdcreg.h>
#include <dev/atkbdc/atkbdc_subr.h>
#include <dev/atkbdc/atkbdcreg.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
MALLOC_DEFINE(M_ATKBDDEV, "atkbddev", "AT Keyboard device");
static MALLOC_DEFINE(M_ATKBDDEV, "atkbddev", "AT Keyboard device");
devclass_t atkbdc_devclass;
/* children */
typedef struct atkbdc_device {
struct resource_list resources;
int rid;
u_int32_t vendorid;
u_int32_t serial;
u_int32_t logicalid;
u_int32_t compatid;
} atkbdc_device_t;
/* kbdc */
static devclass_t atkbdc_devclass;
static int atkbdc_probe(device_t dev);
static int atkbdc_attach(device_t dev);
static device_t atkbdc_add_child(device_t bus, int order, char *name,
int unit);
static int atkbdc_print_child(device_t bus, device_t dev);
static int atkbdc_read_ivar(device_t bus, device_t dev, int index,
uintptr_t *val);
static int atkbdc_write_ivar(device_t bus, device_t dev, int index,
uintptr_t val);
static struct resource_list
*atkbdc_get_resource_list (device_t bus, device_t dev);
static struct resource
*atkbdc_alloc_resource(device_t bus, device_t dev, int type,
int *rid, u_long start, u_long end,
u_long count, u_int flags);
static int atkbdc_release_resource(device_t bus, device_t dev, int type,
int rid, struct resource *res);
static device_method_t atkbdc_methods[] = {
DEVMETHOD(device_probe, atkbdc_probe),
DEVMETHOD(device_attach, atkbdc_attach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(bus_add_child, atkbdc_add_child),
DEVMETHOD(bus_print_child, atkbdc_print_child),
DEVMETHOD(bus_read_ivar, atkbdc_read_ivar),
DEVMETHOD(bus_write_ivar, atkbdc_write_ivar),
DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list),
DEVMETHOD(bus_alloc_resource, atkbdc_alloc_resource),
DEVMETHOD(bus_release_resource, atkbdc_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
{ 0, 0 }
};
static driver_t atkbdc_driver = {
ATKBDC_DRIVER_NAME,
atkbdc_methods,
sizeof(atkbdc_softc_t *),
};
static struct isa_pnp_id atkbdc_ids[] = {
{ 0x0303d041, "Keyboard controller (i8042)" }, /* PNP0303 */
{ 0 }
};
static int
atkbdc_probe(device_t dev)
{
struct resource *port0;
struct resource *port1;
u_long start;
u_long count;
int error;
int rid;
/* check PnP IDs */
if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO)
return ENXIO;
device_set_desc(dev, "Keyboard controller (i8042)");
/*
* Adjust I/O port resources.
* The AT keyboard controller uses two ports (a command/data port
* 0x60 and a status port 0x64), which may be given to us in
* one resource (0x60 through 0x64) or as two separate resources
* (0x60 and 0x64). Furthermore, /boot/device.hints may contain
* just one port, 0x60. We shall adjust resource settings
* so that these two ports are available as two separate resources.
*/
device_quiet(dev);
rid = 0;
if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0)
return ENXIO;
if (count > 1) /* adjust the count */
bus_set_resource(dev, SYS_RES_IOPORT, rid, start, 1);
port0 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
if (port0 == NULL)
return ENXIO;
rid = 1;
if (bus_get_resource(dev, SYS_RES_IOPORT, rid, NULL, NULL) != 0)
bus_set_resource(dev, SYS_RES_IOPORT, 1,
start + KBD_STATUS_PORT, 1);
port1 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
if (port1 == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
return ENXIO;
}
device_verbose(dev);
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
if (error == 0)
bus_generic_probe(dev);
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
return error;
}
static int
atkbdc_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;
}
static device_t
atkbdc_add_child(device_t bus, int order, char *name, int unit)
{
atkbdc_device_t *ivar;
device_t child;
int t;
ivar = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV,
M_NOWAIT | M_ZERO);
if (!ivar)
return NULL;
child = device_add_child_ordered(bus, order, name, unit);
if (child == NULL) {
free(ivar, M_ATKBDDEV);
return child;
}
resource_list_init(&ivar->resources);
ivar->rid = order;
/*
* If the device is not created by the PnP BIOS or ACPI,
* refer to device hints for IRQ.
*/
if (ISA_PNP_PROBE(device_get_parent(bus), bus, atkbdc_ids) != 0) {
if (resource_int_value(name, unit, "irq", &t) != 0)
t = -1;
} else {
t = bus_get_resource_start(bus, SYS_RES_IRQ, ivar->rid);
}
if (t > 0)
resource_list_add(&ivar->resources, SYS_RES_IRQ, ivar->rid,
t, t, 1);
if (resource_disabled(name, unit))
device_disable(child);
device_set_ivars(child, ivar);
return child;
}
static int
int
atkbdc_print_child(device_t bus, device_t dev)
{
atkbdc_device_t *kbdcdev;
@ -280,7 +69,7 @@ atkbdc_print_child(device_t bus, device_t dev)
return (retval);
}
static int
int
atkbdc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
{
atkbdc_device_t *ivar;
@ -305,7 +94,7 @@ atkbdc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
return 0;
}
static int
int
atkbdc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val)
{
atkbdc_device_t *ivar;
@ -330,36 +119,11 @@ atkbdc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val)
return 0;
}
static struct resource_list
*atkbdc_get_resource_list (device_t bus, device_t dev)
struct resource_list
*atkbdc_get_resource_list(device_t bus, device_t dev)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return &ivar->resources;
}
static struct resource
*atkbdc_alloc_resource(device_t bus, device_t dev, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return resource_list_alloc(&ivar->resources, bus, dev, type, rid,
start, end, count, flags);
}
static int
atkbdc_release_resource(device_t bus, device_t dev, int type, int rid,
struct resource *res)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return resource_list_release(&ivar->resources, bus, dev, type, rid,
res);
}
DRIVER_MODULE(atkbdc, isa, atkbdc_driver, atkbdc_devclass, 0, 0);
DRIVER_MODULE(atkbdc, acpi, atkbdc_driver, atkbdc_devclass, 0, 0);

View file

@ -23,26 +23,31 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* from: FreeBSD: src/sys/isa/atkbdc_isa.c,v 1.31 2005/05/29 04:42:28 nyan Exp
* $FreeBSD$
*/
#ifndef _DEV_KBD_ATKBDREG_H_
#define _DEV_KBD_ATKBDREG_H_
#ifndef _DEV_ATKBDC_ATKBDC_SUBR_H_
#define _DEV_ATKBDC_ATKBDC_SUBR_H_
#define ATKBD_DRIVER_NAME "atkbd"
MALLOC_DECLARE(M_ATKBDDEV);
/* device configuration flags (atkbdprobe, atkbdattach) */
#define KB_CONF_FAIL_IF_NO_KBD (1 << 0) /* don't install if no kbd is found */
#define KB_CONF_NO_RESET (1 << 1) /* don't reset the keyboard */
#define KB_CONF_ALT_SCANCODESET (1 << 2) /* assume the XT type keyboard */
#define KB_CONF_NO_PROBE_TEST (1 << 3) /* don't test keyboard during probe */
extern devclass_t atkbdc_devclass;
#ifdef _KERNEL
/* children */
typedef struct atkbdc_device {
struct resource_list resources;
int rid;
u_int32_t vendorid;
u_int32_t serial;
u_int32_t logicalid;
u_int32_t compatid;
} atkbdc_device_t;
int atkbd_probe_unit(int unit, int ctlr, int irq, int flags);
int atkbd_attach_unit(int unit, keyboard_t **kbd,
int ctlr, int irq, int flags);
/* kbdc */
int atkbdc_print_child(device_t bus, device_t dev);
int atkbdc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val);
int atkbdc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val);
struct resource_list *atkbdc_get_resource_list(device_t bus, device_t dev);
#endif
#endif /* !_DEV_KBD_ATKBDREG_H_ */
#endif /* !_DEV_ATKBDC_ATKBDC_SUBR_H_ */

View file

@ -31,8 +31,8 @@
* from kbdio.h,v 1.8 1998/09/25 11:55:46 yokota Exp
*/
#ifndef _DEV_KBD_ATKBDCREG_H_
#define _DEV_KBD_ATKBDCREG_H_
#ifndef _DEV_ATKBDC_ATKBDCREG_H_
#define _DEV_ATKBDC_ATKBDCREG_H_
#include "opt_kbd.h" /* Structures depend on the value if KBDIO_DEBUG */
@ -261,4 +261,4 @@ int set_controller_command_byte(KBDC kbdc, int command, int flag);
#endif /* _KERNEL */
#endif /* !_DEV_KBD_ATKBDCREG_H_ */
#endif /* !_DEV_ATKBDC_ATKBDCREG_H_ */

View file

@ -26,8 +26,8 @@
* $FreeBSD$
*/
#ifndef _DEV_KBD_ATKBDREG_H_
#define _DEV_KBD_ATKBDREG_H_
#ifndef _DEV_ATKBDC_ATKBDREG_H_
#define _DEV_ATKBDC_ATKBDREG_H_
#define ATKBD_DRIVER_NAME "atkbd"
@ -45,4 +45,4 @@ int atkbd_attach_unit(int unit, keyboard_t **kbd,
#endif
#endif /* !_DEV_KBD_ATKBDREG_H_ */
#endif /* !_DEV_ATKBDC_ATKBDREG_H_ */

View file

@ -61,6 +61,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_isa.h"
#include "opt_psm.h"
#include <sys/param.h>
@ -82,8 +83,12 @@ __FBSDID("$FreeBSD$");
#include <sys/mouse.h>
#include <machine/resource.h>
#ifdef DEV_ISA
#include <isa/isavar.h>
#include <dev/kbd/atkbdcreg.h>
#endif
#include <dev/atkbdc/atkbdcreg.h>
#include <dev/atkbdc/psm.h>
/*
* Driver specific options: the following options may be set by
@ -117,7 +122,6 @@ do { \
/* end of driver specific options */
#define PSM_DRIVER_NAME "psm"
#define PSMCPNP_DRIVER_NAME "psmcpnp"
/* input queue */
@ -3469,6 +3473,31 @@ enable_versapad(struct psm_softc *sc)
return TRUE; /* PS/2 absolute mode */
}
/*
* Return true if 'now' is earlier than (start + (secs.usecs)).
* Now may be NULL and the function will fetch the current time from
* getmicrouptime(), or a cached 'now' can be passed in.
* All values should be numbers derived from getmicrouptime().
*/
static int
timeelapsed(start, secs, usecs, now)
const struct timeval *start, *now;
int secs, usecs;
{
struct timeval snow, tv;
/* if there is no 'now' passed in, the get it as a convience. */
if (now == NULL) {
getmicrouptime(&snow);
now = &snow;
}
tv.tv_sec = secs;
tv.tv_usec = usecs;
timevaladd(&tv, start);
return (timevalcmp(&tv, now, <));
}
static int
psmresume(device_t dev)
{
@ -3499,6 +3528,8 @@ psmresume(device_t dev)
DRIVER_MODULE(psm, atkbdc, psm_driver, psm_devclass, 0, 0);
#ifdef DEV_ISA
/*
* This sucks up assignments from PNPBIOS and ACPI.
*/
@ -3629,30 +3660,7 @@ psmcpnp_attach(device_t dev)
return 0;
}
/*
* Return true if 'now' is earlier than (start + (secs.usecs)).
* Now may be NULL and the function will fetch the current time from
* getmicrouptime(), or a cached 'now' can be passed in.
* All values should be numbers derived from getmicrouptime().
*/
static int
timeelapsed(start, secs, usecs, now)
const struct timeval *start, *now;
int secs, usecs;
{
struct timeval snow, tv;
/* if there is no 'now' passed in, the get it as a convience. */
if (now == NULL) {
getmicrouptime(&snow);
now = &snow;
}
tv.tv_sec = secs;
tv.tv_usec = usecs;
timevaladd(&tv, start);
return (timevalcmp(&tv, now, <));
}
DRIVER_MODULE(psmcpnp, isa, psmcpnp_driver, psmcpnp_devclass, 0, 0);
DRIVER_MODULE(psmcpnp, acpi, psmcpnp_driver, psmcpnp_devclass, 0, 0);
#endif /* DEV_ISA */

32
sys/dev/atkbdc/psm.h Normal file
View file

@ -0,0 +1,32 @@
/*-
* Copyright (c) 1992, 1993 Erik Forsberg.
* Copyright (c) 1996, 1997 Kazutaka YOKOTA.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* from: FreeBSD: src/sys/isa/psm.c,v 1.84 2005/01/10 13:05:58 philip
* $FreeBSD$
*/
#ifndef _DEV_ATKBDC_PSM_H_
#define _DEV_ATKBDC_PSM_H_
#define PSM_DRIVER_NAME "psm"
#endif /* !_DEV_ATKBDC_PSM_H_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,264 +0,0 @@
/*-
* Copyright (c) 1996-1999
* Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
* from kbdio.h,v 1.8 1998/09/25 11:55:46 yokota Exp
*/
#ifndef _DEV_KBD_ATKBDCREG_H_
#define _DEV_KBD_ATKBDCREG_H_
#include "opt_kbd.h" /* Structures depend on the value if KBDIO_DEBUG */
/* constants */
/* I/O ports */
#define KBD_STATUS_PORT 4 /* status port, read */
#define KBD_COMMAND_PORT 4 /* controller command port, write */
#define KBD_DATA_PORT 0 /* data port, read/write
* also used as keyboard command
* and mouse command port
*/
/* controller commands (sent to KBD_COMMAND_PORT) */
#define KBDC_SET_COMMAND_BYTE 0x0060
#define KBDC_GET_COMMAND_BYTE 0x0020
#define KBDC_WRITE_TO_AUX 0x00d4
#define KBDC_DISABLE_AUX_PORT 0x00a7
#define KBDC_ENABLE_AUX_PORT 0x00a8
#define KBDC_TEST_AUX_PORT 0x00a9
#define KBDC_DIAGNOSE 0x00aa
#define KBDC_TEST_KBD_PORT 0x00ab
#define KBDC_DISABLE_KBD_PORT 0x00ad
#define KBDC_ENABLE_KBD_PORT 0x00ae
/* controller command byte (set by KBDC_SET_COMMAND_BYTE) */
#define KBD_TRANSLATION 0x0040
#define KBD_RESERVED_BITS 0x0004
#define KBD_OVERRIDE_KBD_LOCK 0x0008
#define KBD_ENABLE_KBD_PORT 0x0000
#define KBD_DISABLE_KBD_PORT 0x0010
#define KBD_ENABLE_AUX_PORT 0x0000
#define KBD_DISABLE_AUX_PORT 0x0020
#define KBD_ENABLE_AUX_INT 0x0002
#define KBD_DISABLE_AUX_INT 0x0000
#define KBD_ENABLE_KBD_INT 0x0001
#define KBD_DISABLE_KBD_INT 0x0000
#define KBD_KBD_CONTROL_BITS (KBD_DISABLE_KBD_PORT | KBD_ENABLE_KBD_INT)
#define KBD_AUX_CONTROL_BITS (KBD_DISABLE_AUX_PORT | KBD_ENABLE_AUX_INT)
/* keyboard device commands (sent to KBD_DATA_PORT) */
#define KBDC_RESET_KBD 0x00ff
#define KBDC_ENABLE_KBD 0x00f4
#define KBDC_DISABLE_KBD 0x00f5
#define KBDC_SET_DEFAULTS 0x00f6
#define KBDC_SEND_DEV_ID 0x00f2
#define KBDC_SET_LEDS 0x00ed
#define KBDC_ECHO 0x00ee
#define KBDC_SET_SCANCODE_SET 0x00f0
#define KBDC_SET_TYPEMATIC 0x00f3
/* aux device commands (sent to KBD_DATA_PORT) */
#define PSMC_RESET_DEV 0x00ff
#define PSMC_ENABLE_DEV 0x00f4
#define PSMC_DISABLE_DEV 0x00f5
#define PSMC_SET_DEFAULTS 0x00f6
#define PSMC_SEND_DEV_ID 0x00f2
#define PSMC_SEND_DEV_STATUS 0x00e9
#define PSMC_SEND_DEV_DATA 0x00eb
#define PSMC_SET_SCALING11 0x00e6
#define PSMC_SET_SCALING21 0x00e7
#define PSMC_SET_RESOLUTION 0x00e8
#define PSMC_SET_STREAM_MODE 0x00ea
#define PSMC_SET_REMOTE_MODE 0x00f0
#define PSMC_SET_SAMPLING_RATE 0x00f3
/* PSMC_SET_RESOLUTION argument */
#define PSMD_RES_LOW 0 /* typically 25ppi */
#define PSMD_RES_MEDIUM_LOW 1 /* typically 50ppi */
#define PSMD_RES_MEDIUM_HIGH 2 /* typically 100ppi (default) */
#define PSMD_RES_HIGH 3 /* typically 200ppi */
#define PSMD_MAX_RESOLUTION PSMD_RES_HIGH
/* PSMC_SET_SAMPLING_RATE */
#define PSMD_MAX_RATE 255 /* FIXME: not sure if it's possible */
/* status bits (KBD_STATUS_PORT) */
#define KBDS_BUFFER_FULL 0x0021
#define KBDS_ANY_BUFFER_FULL 0x0001
#define KBDS_KBD_BUFFER_FULL 0x0001
#define KBDS_AUX_BUFFER_FULL 0x0021
#define KBDS_INPUT_BUFFER_FULL 0x0002
/* return code */
#define KBD_ACK 0x00fa
#define KBD_RESEND 0x00fe
#define KBD_RESET_DONE 0x00aa
#define KBD_RESET_FAIL 0x00fc
#define KBD_DIAG_DONE 0x0055
#define KBD_DIAG_FAIL 0x00fd
#define KBD_ECHO 0x00ee
#define PSM_ACK 0x00fa
#define PSM_RESEND 0x00fe
#define PSM_RESET_DONE 0x00aa
#define PSM_RESET_FAIL 0x00fc
/* aux device ID */
#define PSM_MOUSE_ID 0
#define PSM_BALLPOINT_ID 2
#define PSM_INTELLI_ID 3
#define PSM_EXPLORER_ID 4
#define PSM_4DMOUSE_ID 6
#define PSM_4DPLUS_ID 8
#define PSM_4DPLUS_RFSW35_ID 24
#ifdef _KERNEL
#define ATKBDC_DRIVER_NAME "atkbdc"
/*
* driver specific options: the following options may be set by
* `options' statements in the kernel configuration file.
*/
/* retry count */
#ifndef KBD_MAXRETRY
#define KBD_MAXRETRY 3
#endif
/* timing parameters */
#ifndef KBD_RESETDELAY
#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
#endif
#ifndef KBD_MAXWAIT
#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
#endif
/* I/O recovery time */
#define KBDC_DELAYTIME 20
#define KBDD_DELAYTIME 7
/* debug option */
#ifndef KBDIO_DEBUG
#define KBDIO_DEBUG 0
#endif
/* end of driver specific options */
/* types/structures */
#define KBDQ_BUFSIZE 32
typedef struct _kqueue {
int head;
int tail;
unsigned char q[KBDQ_BUFSIZE];
#if KBDIO_DEBUG >= 2
int call_count;
int qcount;
int max_qcount;
#endif
} kqueue;
struct resource;
typedef struct atkbdc_softc {
struct resource *port0; /* data port */
struct resource *port1; /* status port */
bus_space_tag_t iot;
bus_space_handle_t ioh0;
bus_space_handle_t ioh1;
int command_byte; /* current command byte value */
int command_mask; /* command byte mask bits for kbd/aux devices */
int lock; /* FIXME: XXX not quite a semaphore... */
kqueue kbd; /* keyboard data queue */
kqueue aux; /* auxiliary data queue */
} atkbdc_softc_t;
enum kbdc_device_ivar {
KBDC_IVAR_VENDORID,
KBDC_IVAR_SERIAL,
KBDC_IVAR_LOGICALID,
KBDC_IVAR_COMPATID,
};
typedef caddr_t KBDC;
#define KBDC_RID_KBD 0
#define KBDC_RID_AUX 1
/* function prototypes */
atkbdc_softc_t *atkbdc_get_softc(int unit);
int atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1);
int atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
struct resource *port1);
int atkbdc_configure(void);
KBDC atkbdc_open(int unit);
int kbdc_lock(KBDC kbdc, int lock);
int kbdc_data_ready(KBDC kbdc);
int write_controller_command(KBDC kbdc,int c);
int write_controller_data(KBDC kbdc,int c);
int write_kbd_command(KBDC kbdc,int c);
int write_aux_command(KBDC kbdc,int c);
int send_kbd_command(KBDC kbdc,int c);
int send_aux_command(KBDC kbdc,int c);
int send_kbd_command_and_data(KBDC kbdc,int c,int d);
int send_aux_command_and_data(KBDC kbdc,int c,int d);
int read_controller_data(KBDC kbdc);
int read_kbd_data(KBDC kbdc);
int read_kbd_data_no_wait(KBDC kbdc);
int read_aux_data(KBDC kbdc);
int read_aux_data_no_wait(KBDC kbdc);
void empty_kbd_buffer(KBDC kbdc, int t);
void empty_aux_buffer(KBDC kbdc, int t);
void empty_both_buffers(KBDC kbdc, int t);
int reset_kbd(KBDC kbdc);
int reset_aux_dev(KBDC kbdc);
int test_controller(KBDC kbdc);
int test_kbd_port(KBDC kbdc);
int test_aux_port(KBDC kbdc);
int kbdc_get_device_mask(KBDC kbdc);
void kbdc_set_device_mask(KBDC kbdc, int mask);
int get_controller_command_byte(KBDC kbdc);
int set_controller_command_byte(KBDC kbdc, int command, int flag);
#endif /* _KERNEL */
#endif /* !_DEV_KBD_ATKBDCREG_H_ */

View file

@ -79,7 +79,7 @@
#include <machine/stdarg.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdcreg.h>
#include <dev/atkbdc/atkbdcreg.h>
#include <i386/isa/pcvt/pcvt_conf.h>

View file

@ -1,180 +0,0 @@
/*-
* Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_kbd.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <sys/kbio.h>
#include <dev/kbd/kbdreg.h>
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
typedef struct {
struct resource *intr;
void *ih;
} atkbd_softc_t;
static devclass_t atkbd_devclass;
static void atkbdidentify(driver_t *driver, device_t dev);
static int atkbdprobe(device_t dev);
static int atkbdattach(device_t dev);
static int atkbdresume(device_t dev);
static void atkbd_isa_intr(void *arg);
static device_method_t atkbd_methods[] = {
DEVMETHOD(device_identify, atkbdidentify),
DEVMETHOD(device_probe, atkbdprobe),
DEVMETHOD(device_attach, atkbdattach),
DEVMETHOD(device_resume, atkbdresume),
{ 0, 0 }
};
static driver_t atkbd_driver = {
ATKBD_DRIVER_NAME,
atkbd_methods,
sizeof(atkbd_softc_t),
};
static void
atkbdidentify(driver_t *driver, device_t parent)
{
/* always add at least one child */
BUS_ADD_CHILD(parent, KBDC_RID_KBD, driver->name, device_get_unit(parent));
}
static int
atkbdprobe(device_t dev)
{
struct resource *res;
u_long irq;
int flags;
int rid;
device_set_desc(dev, "AT Keyboard");
/* obtain parameters */
flags = device_get_flags(dev);
/* see if IRQ is available */
rid = KBDC_RID_KBD;
res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (res == NULL) {
if (bootverbose)
device_printf(dev, "unable to allocate IRQ\n");
return ENXIO;
}
irq = rman_get_start(res);
bus_release_resource(dev, SYS_RES_IRQ, rid, res);
/* probe the device */
return atkbd_probe_unit(device_get_unit(dev),
device_get_unit(device_get_parent(dev)),
irq, flags);
}
static int
atkbdattach(device_t dev)
{
atkbd_softc_t *sc;
keyboard_t *kbd;
u_long irq;
int flags;
int rid;
int error;
sc = device_get_softc(dev);
rid = KBDC_RID_KBD;
irq = bus_get_resource_start(dev, SYS_RES_IRQ, rid);
flags = device_get_flags(dev);
error = atkbd_attach_unit(device_get_unit(dev), &kbd,
device_get_unit(device_get_parent(dev)),
irq, flags);
if (error)
return error;
/* declare our interrupt handler */
sc->intr = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->intr == NULL)
return ENXIO;
error = bus_setup_intr(dev, sc->intr, INTR_TYPE_TTY, atkbd_isa_intr,
kbd, &sc->ih);
if (error)
bus_release_resource(dev, SYS_RES_IRQ, rid, sc->intr);
return error;
}
static int
atkbdresume(device_t dev)
{
atkbd_softc_t *sc;
keyboard_t *kbd;
int args[2];
sc = device_get_softc(dev);
kbd = kbd_get_keyboard(kbd_find_keyboard(ATKBD_DRIVER_NAME,
device_get_unit(dev)));
if (kbd) {
kbd->kb_flags &= ~KB_INITIALIZED;
args[0] = device_get_unit(device_get_parent(dev));
args[1] = rman_get_start(sc->intr);
(*kbdsw[kbd->kb_index]->init)(device_get_unit(dev), &kbd,
args, device_get_flags(dev));
(*kbdsw[kbd->kb_index]->clear_state)(kbd);
}
return 0;
}
static void
atkbd_isa_intr(void *arg)
{
keyboard_t *kbd;
kbd = (keyboard_t *)arg;
(*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
}
DRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, 0, 0);

View file

@ -1,365 +0,0 @@
/*-
* Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer as
* the first lines of this file unmodified.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_kbd.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <dev/kbd/atkbdcreg.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
static MALLOC_DEFINE(M_ATKBDDEV, "atkbddev", "AT Keyboard device");
/* children */
typedef struct atkbdc_device {
struct resource_list resources;
int rid;
u_int32_t vendorid;
u_int32_t serial;
u_int32_t logicalid;
u_int32_t compatid;
} atkbdc_device_t;
/* kbdc */
static devclass_t atkbdc_devclass;
static int atkbdc_probe(device_t dev);
static int atkbdc_attach(device_t dev);
static device_t atkbdc_add_child(device_t bus, int order, char *name,
int unit);
static int atkbdc_print_child(device_t bus, device_t dev);
static int atkbdc_read_ivar(device_t bus, device_t dev, int index,
uintptr_t *val);
static int atkbdc_write_ivar(device_t bus, device_t dev, int index,
uintptr_t val);
static struct resource_list
*atkbdc_get_resource_list (device_t bus, device_t dev);
static struct resource
*atkbdc_alloc_resource(device_t bus, device_t dev, int type,
int *rid, u_long start, u_long end,
u_long count, u_int flags);
static int atkbdc_release_resource(device_t bus, device_t dev, int type,
int rid, struct resource *res);
static device_method_t atkbdc_methods[] = {
DEVMETHOD(device_probe, atkbdc_probe),
DEVMETHOD(device_attach, atkbdc_attach),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
DEVMETHOD(bus_add_child, atkbdc_add_child),
DEVMETHOD(bus_print_child, atkbdc_print_child),
DEVMETHOD(bus_read_ivar, atkbdc_read_ivar),
DEVMETHOD(bus_write_ivar, atkbdc_write_ivar),
DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list),
DEVMETHOD(bus_alloc_resource, atkbdc_alloc_resource),
DEVMETHOD(bus_release_resource, atkbdc_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
{ 0, 0 }
};
static driver_t atkbdc_driver = {
ATKBDC_DRIVER_NAME,
atkbdc_methods,
sizeof(atkbdc_softc_t *),
};
static struct isa_pnp_id atkbdc_ids[] = {
{ 0x0303d041, "Keyboard controller (i8042)" }, /* PNP0303 */
{ 0 }
};
static int
atkbdc_probe(device_t dev)
{
struct resource *port0;
struct resource *port1;
u_long start;
u_long count;
int error;
int rid;
/* check PnP IDs */
if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO)
return ENXIO;
device_set_desc(dev, "Keyboard controller (i8042)");
/*
* Adjust I/O port resources.
* The AT keyboard controller uses two ports (a command/data port
* 0x60 and a status port 0x64), which may be given to us in
* one resource (0x60 through 0x64) or as two separate resources
* (0x60 and 0x64). Furthermore, /boot/device.hints may contain
* just one port, 0x60. We shall adjust resource settings
* so that these two ports are available as two separate resources.
*/
device_quiet(dev);
rid = 0;
if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0)
return ENXIO;
if (count > 1) /* adjust the count */
bus_set_resource(dev, SYS_RES_IOPORT, rid, start, 1);
port0 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
if (port0 == NULL)
return ENXIO;
rid = 1;
if (bus_get_resource(dev, SYS_RES_IOPORT, rid, NULL, NULL) != 0)
bus_set_resource(dev, SYS_RES_IOPORT, 1,
start + KBD_STATUS_PORT, 1);
port1 = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
if (port1 == NULL) {
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
return ENXIO;
}
device_verbose(dev);
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
if (error == 0)
bus_generic_probe(dev);
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
return error;
}
static int
atkbdc_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;
}
static device_t
atkbdc_add_child(device_t bus, int order, char *name, int unit)
{
atkbdc_device_t *ivar;
device_t child;
int t;
ivar = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV,
M_NOWAIT | M_ZERO);
if (!ivar)
return NULL;
child = device_add_child_ordered(bus, order, name, unit);
if (child == NULL) {
free(ivar, M_ATKBDDEV);
return child;
}
resource_list_init(&ivar->resources);
ivar->rid = order;
/*
* If the device is not created by the PnP BIOS or ACPI,
* refer to device hints for IRQ.
*/
if (ISA_PNP_PROBE(device_get_parent(bus), bus, atkbdc_ids) != 0) {
if (resource_int_value(name, unit, "irq", &t) != 0)
t = -1;
} else {
t = bus_get_resource_start(bus, SYS_RES_IRQ, ivar->rid);
}
if (t > 0)
resource_list_add(&ivar->resources, SYS_RES_IRQ, ivar->rid,
t, t, 1);
if (resource_disabled(name, unit))
device_disable(child);
device_set_ivars(child, ivar);
return child;
}
static int
atkbdc_print_child(device_t bus, device_t dev)
{
atkbdc_device_t *kbdcdev;
u_long irq;
int flags;
int retval = 0;
kbdcdev = (atkbdc_device_t *)device_get_ivars(dev);
retval += bus_print_child_header(bus, dev);
flags = device_get_flags(dev);
if (flags != 0)
retval += printf(" flags 0x%x", flags);
irq = bus_get_resource_start(dev, SYS_RES_IRQ, kbdcdev->rid);
if (irq != 0)
retval += printf(" irq %ld", irq);
retval += bus_print_child_footer(bus, dev);
return (retval);
}
static int
atkbdc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
switch (index) {
case KBDC_IVAR_VENDORID:
*val = (u_long)ivar->vendorid;
break;
case KBDC_IVAR_SERIAL:
*val = (u_long)ivar->serial;
break;
case KBDC_IVAR_LOGICALID:
*val = (u_long)ivar->logicalid;
break;
case KBDC_IVAR_COMPATID:
*val = (u_long)ivar->compatid;
break;
default:
return ENOENT;
}
return 0;
}
static int
atkbdc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
switch (index) {
case KBDC_IVAR_VENDORID:
ivar->vendorid = (u_int32_t)val;
break;
case KBDC_IVAR_SERIAL:
ivar->serial = (u_int32_t)val;
break;
case KBDC_IVAR_LOGICALID:
ivar->logicalid = (u_int32_t)val;
break;
case KBDC_IVAR_COMPATID:
ivar->compatid = (u_int32_t)val;
break;
default:
return ENOENT;
}
return 0;
}
static struct resource_list
*atkbdc_get_resource_list (device_t bus, device_t dev)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return &ivar->resources;
}
static struct resource
*atkbdc_alloc_resource(device_t bus, device_t dev, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return resource_list_alloc(&ivar->resources, bus, dev, type, rid,
start, end, count, flags);
}
static int
atkbdc_release_resource(device_t bus, device_t dev, int type, int rid,
struct resource *res)
{
atkbdc_device_t *ivar;
ivar = (atkbdc_device_t *)device_get_ivars(dev);
return resource_list_release(&ivar->resources, bus, dev, type, rid,
res);
}
DRIVER_MODULE(atkbdc, isa, atkbdc_driver, atkbdc_devclass, 0, 0);
DRIVER_MODULE(atkbdc, acpi, atkbdc_driver, atkbdc_devclass, 0, 0);

File diff suppressed because it is too large Load diff