Subject: Re: config_attach_pseudo(cfdata, aux)
To: Valeriy E. Ushakov <uwe@ptc.spbu.ru>
From: Iain Hibbert <plunky@rya-online.net>
List: tech-kern
Date: 03/20/2006 21:12:24
On Mon, 20 Mar 2006, Valeriy E. Ushakov wrote:

> On Mon, Mar 20, 2006 at 18:24:24 +0000, Iain Hibbert wrote:
>
> > Am creating pseudo device instances and have some attach arguments
> > that the device would like to see, but config_attach_pseudo() does
> > not pass aux arguments through to the device attach routine as
> > config_found() would.
> >
> > I can configure the device externally (I get the softc back and can
> > twiddle it directly) but it seems cleaner for the device attach()
> > routine to handle that. Would this patch be ok to enable that?
>
> Can you provide usage example?

No, so far its secret :)

This is for Bluetooth HID support. After I aborted trying to inject events
directly, I have a control file /dev/bthidctl that does nothing but take
ioctl(BTHID_ATTACH, bthid_attach_args). The ioctl code, after checking the
input, creates a new instance of pseudo-device bthidev to represent the
HID device, but I have the attach_args that configure it, which consists
of the device address, the HID descriptor, the address of the local device
which is used to contact it, and the channel numbers it wants to be
contacted on plus a couple of flags.

So, I find that the bthidev_attach() routine which would normally be used
to do device configuration, attaching child devices etc actually has
nothing to do but init a callout structure. What I have (below) is not
especially ugly, but it seems in the wrong context. If I could pass the
attach args through, I think it would be better.

iain

	/*
	 * create a new instance of the pseudo device
	 */
	sc = (struct bthidev_softc *)config_attach_pseudo(&bthidev_cfdata);
	if (sc == NULL)
		return ENXIO;

	/*
	 * copy over our config info
	 */
	bdaddr_copy(&sc->sc_laddr, &ba->bc_laddr);
	bdaddr_copy(&sc->sc_raddr, &ba->bc_raddr);
	sc->sc_ctlpsm = ba->bc_ctl;
	sc->sc_intpsm = ba->bc_int;

	sc->sc_flags = ba->bc_flags;
	if (sc->sc_flags & BTHID_INITIATE)
		sc->sc_flags |= BTHID_CONNECT;

	sc->sc_desc = malloc(ba->bc_dlen, M_BLUETOOTH, M_WAITOK);
	if (sc->sc_desc == NULL) {
		err = ENOMEM;
		break;
	}
	copyin(ba->bc_desc, sc->sc_desc, ba->bc_dlen);
	sc->sc_dlen = ba->bc_dlen;

	/*
	 * configure our children
	 */
	err = bthidev_configure(sc);
	if (err)
		break;

	/*
	 * start bluetooth connections
	 */
	if ((sc->sc_flags & BTHID_INITIATE) == 0) {
		err = bthidev_listen(sc);
		if (err)
			break;
	}

	if (sc->sc_flags & BTHID_CONNECT) {
		err = bthidev_connect(sc);
		if (err)
			break;
	}