Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Jul 1999 19:32:41 +0200
From:      Nicolas Souchu <nsouch@teaser.fr>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        current@FreeBSD.ORG, des@flood.ping.uio.no, obrien@NUXI.com, sobomax@altavista.net
Subject:   Re: PLIP is still broken :(
Message-ID:  <19990725193241.48737@breizh.teaser.fr>
In-Reply-To: <199907242335.JAA10442@godzilla.zeta.org.au>; from Bruce Evans on Sun, Jul 25, 1999 at 09:35:36AM %2B1000
References:  <199907242335.JAA10442@godzilla.zeta.org.au>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Jul 25, 1999 at 09:35:36AM +1000, Bruce Evans wrote:
>
>>>Possible quick fix (hack): change all the spltty()'s in lpt.c to
>>>splnet()'s.  lpt isn't a tty driver; it just abuses spltty().  Abusing
>>>splnet() instead should work OK for lpt and fix if_plip.
>>
>>This seems good until the intr stuff handle dynamic update of a interrupt spl.
>>Is there some work in progress on that?
>
>Not much.  ppc needs to do most of the work by registering its interrupt
>with the correct interrupt maskptr for the currently attached device.
>This may involve unregistering the interrupt when the device changes.
>The generic code could help here by supporting atomic changing of
>interrupt maskptrs without unregistering the interrupt.  Otherwise,
>the generic code is missing mainly update of the interrupt masks when
>an interrupt is unregistered.

For the low level side, we could consider something like the following code.
But this shall be called by the nexus layer and then needs generic newbus
support (as you said above, didn't you?).

/*
 * Switch an irq from a maskptr to another without unregistering the irq
 * handler.
 * This function is supposed to work with only one handler per irq.
 */
void
switch_masks(intrmask_t *oldmaskptr, intrmask_t *newmaskptr, int irq)
{
	int s;
	intrec *idesc;
	intrmask_t mask = 1 << irq;

	if ((oldmaskptr == NULL) || (newmaskptr == NULL))
		return;

	if (((idesc = find_idesc(oldmaskptr, irq)) == NULL) ||
		(find_idesc(newmaskptr, irq) != NULL))
		return;

	/* block all interrupts */
	s = splhigh();

	/* update the irq mask ptr */
	idesc->maskptr = newmaskptr;

	/* remove the irq from the old mask and add it to the new one */
	INTRUNMASK(*oldmaskptr, mask);
	INTRMASK(*newmaskptr, mask);

	/* we need to update all values in the intr_mask[irq] array */
	update_intr_masks();
	/* update mask in chains of the interrupt multiplex handler as well */
	update_mux_masks();

	/* restore interrupts */
	splx(s);

	return;
}

Your opinion?

Nicholas.

-- 
nsouch@teaser.fr / nsouch@freebsd.org
FreeBSD - Turning PCs into workstations - http://www.FreeBSD.org


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990725193241.48737>