From: Matti Linnanvuori <mattilinnanvuori@yahoo.com>
To: Arjan van de Ven <arjan@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
linux-kernel@vger.kernel.org, Alan Cox <alan@lxorguk.ukuu.org.uk>
Subject: Do not deprecate binary semaphore or do allow mutex in software interrupt contexts
Date: Tue, 11 Sep 2007 22:39:21 -0700 (PDT) [thread overview]
Message-ID: <698652.90161.qm@web52004.mail.re2.yahoo.com> (raw)
The following code seems to me to be a valid example of a binary semaphore (mutex) in a timer:
//timer called 10 times a second
static void status_timer(unsigned long device)
{
struct etp_device_private *dp = (struct etp_device_private *)device;
if (unlikely(dp->status_interface == 0))
dp->status_interface = INTERFACES_PER_DEVICE - 1;
else
dp->status_interface--;
//DBG_PRINT ("%s: In status timer, interface:0x%x.\n",etp_NAME, dp->status_interface);
idt_los_interrupt_1(dp, dp->status_interface);
if (likely(!dp->reset))
// reset the timer:
mod_timer(&dp->status_timer, jiffies + HZ / 10);
}
static inline void read_idt_register_interrupt(struct etp_device_private *dp,
unsigned reg)
{
DBG_PRINT("read_idt_register_interrupt to mutex_lock.\n");
if (unlikely(down_trylock(&dp->semaphore)))
return; /* Do not read because failed to lock. */
if (likely
(!dp->status
&& !(inl((void *)(dp->ioaddr + REG_E1_CTRL)) & E1_ACCESS_ON))) {
outl(((reg << E1_REGISTER_SHIFT) & E1_REGISTER_MASK)
| E1_DIR_READ | E1_ACCESS_ON,
(void *)(dp->ioaddr + REG_E1_CTRL));
dp->status = 1;
DBG_PRINT("read_idt_register_interrupt set status read.\n");
} else
DBG_PRINT
("read_idt_register_interrupt did not set status %u read.\n",
dp->status);
DBG_PRINT
("read_idt_register_interrupt do not wait for result here, read in tasklet.\n");
}
//for getting los information with interrupt:
void idt_los_interrupt_1(struct etp_device_private *dp, unsigned interface)
{
read_idt_register_if_interrupt(dp, E1_TRNCVR_LINE_STATUS0_REG,
interface);
}
static void e1_access_task(unsigned long data) //called after e1_access_interrupt
{
struct etp_device_private *dp = (struct etp_device_private *)data;
struct etp_interface_private *ip;
unsigned int interface, error;
bool los;
//check if los status was read:
if (unlikely(!dp->status)) {
DBG_PRINT("e1_access_task wakes up user.\n");
wake_up(&dp->e1_access_q);
return;
}
error =
idt_los_interrupt_2(dp->ioaddr, &interface, &los,
dp->pci_dev->device);
//DBG_PRINT ("%s: In e1 task, error:0x%x, interface:0x%x, los:0x%x.\n",
// etp_NAME, error, interface, los);
dp->status = 0;
up(&dp->semaphore);
DBG_PRINT("e1_access_task got error %u.\n", error);
if (unlikely(error))
return;
//update los status:
ip = &dp->interface_privates[interface];
ip->los = los;
//update status:
if ((ip->if_mode == IF_MODE_CLOSED) || //interface closed or
(ip->los)) { //link down
set_led(LED_CTRL_OFF, ip);
if (netif_carrier_ok(ip->ch_priv.this_netdev))
netif_carrier_off(ip->ch_priv.this_netdev);
} else { //link up and interface opened
if (!netif_carrier_ok(ip->ch_priv.this_netdev))
netif_carrier_on(ip->ch_priv.this_netdev);
if (ip->if_mode == IF_MODE_HDLC) {
set_led(LED_CTRL_TRAFFIC, ip);
} else { //ip->if_mode == IF_MODE_TIMESLOT
set_led(LED_CTRL_ON, ip);
}
}
}
int idt_los_interrupt_2(u8 * ioaddr, unsigned *interface, bool * los,
unsigned pci_device_id)
{ //returns 0 in success
unsigned int value = inl((void *)(ioaddr + REG_E1_CTRL));
//if access not ended:
if (value & E1_ACCESS_ON) {
return 1;
}
//if access not to los status register
if ((value & E1_REGISTER_MASK_NO_IF) !=
(E1_TRNCVR_LINE_STATUS0_REG << E1_REGISTER_SHIFT)) {
return 1;
}
//get interface
*interface =
idt_if_to_if((value & E1_REGISTER_MASK_IF) >>
E1_REGISTER_SHIFT_IF, pci_device_id);
*los = value & 0x1;
return 0;
}
int write_idt_register_lock(unsigned device, unsigned reg, u32 value)
{
struct etp_device_private *etp = get_dev_priv(device);
unsigned ctrl;
DBG_PRINT("write_idt_register_lock to mutex lock device %u.\n", device);
down(&etp->semaphore);
if (unlikely(etp->reset)) {
up(&etp->semaphore);
DBG_PRINT
("write_idt_register_lock device %u unusable.\n", device);
return -ENXIO;
}
DBG_PRINT("write_idt_register_lock mutex locked device %u.\n", device);
do {
DBG_PRINT
("write_idt_register_lock to wait_event_timeout device %u.\n",
device);
wait_event_timeout(etp->e1_access_q,
!((ctrl =
inl((void *)(etp->ioaddr + REG_E1_CTRL)))
& E1_ACCESS_ON), HZ / 500);
}
while (ctrl & E1_ACCESS_ON);
DBG_PRINT("write_idt_register_lock to outl device %u.\n", device);
outl(((reg << E1_REGISTER_SHIFT) & E1_REGISTER_MASK) |
E1_DIR_WRITE | E1_ACCESS_ON | (value & E1_DATA_MASK),
(void *)(etp->ioaddr + REG_E1_CTRL));
up(&etp->semaphore);
DBG_PRINT("write_idt_register_lock mutex unlocked device %u.\n",
device);
return 0;
}
Copyright (C) 2006 Jouni Kujala, Flexibilis Oy.
__________________________________
Alles was der Gesundheit und Entspannung dient. BE A BETTER MEDIZINMANN! www.yahoo.de/clever
next reply other threads:[~2007-09-12 5:39 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-12 5:39 Matti Linnanvuori [this message]
-- strict thread matches above, loose matches on Subject: below --
2007-09-11 17:29 Do not deprecate binary semaphore or do allow mutex in software interrupt contexts Matti Linnanvuori
2007-09-11 19:22 ` Arjan van de Ven
2007-09-11 16:20 Matti Linnanvuori
2007-09-11 16:50 ` Peter Zijlstra
2007-09-11 18:22 ` Arjan van de Ven
2007-09-11 13:20 Matti Linnanvuori
2007-09-11 14:36 ` Arjan van de Ven
2007-09-11 13:56 ` Alan Cox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=698652.90161.qm@web52004.mail.re2.yahoo.com \
--to=mattilinnanvuori@yahoo.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=arjan@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox