* [PATCH 1/5] Char: isicom, fix locking in isr
@ 2006-12-16 1:09 Jiri Slaby
2006-12-16 1:09 ` [PATCH 4/5] Char: isicom, check card state " Jiri Slaby
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Jiri Slaby @ 2006-12-16 1:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
isicom, fix locking in isr
2 spin_unlocks are omitted in the interrupt handler. Put them there to fix
up deadlocking on UP.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
commit f2d37e8d3de070f8cda48a454f7b991d29b310be
tree 23027dcdc3215fbb488577edb9610322956edb0b
parent 5df5a993999b94d728cedfa669eba2b0b58e16d7
author Jiri Slaby <jirislaby@gmail.com> Wed, 13 Dec 2006 23:10:48 +0100
committer Jiri Slaby <jirislaby@gmail.com> Fri, 15 Dec 2006 20:29:34 +0059
drivers/char/isicom.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 0362740..836e967 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -563,6 +563,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
port = card->ports + channel;
if (!(port->flags & ASYNC_INITIALIZED)) {
outw(0x0000, base+0x04); /* enable interrupts */
+ spin_unlock(&card->card_lock);
return IRQ_HANDLED;
}
@@ -677,6 +678,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
tty_flip_buffer_push(tty);
}
outw(0x0000, base+0x04); /* enable interrupts */
+ spin_unlock(&card->card_lock);
return IRQ_HANDLED;
}
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/5] Char: isicom, check card state in isr
2006-12-16 1:09 [PATCH 1/5] Char: isicom, fix locking in isr Jiri Slaby
@ 2006-12-16 1:09 ` Jiri Slaby
2006-12-16 1:09 ` [PATCH 3/5] Char: isicom, augment card_reset Jiri Slaby
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Jiri Slaby @ 2006-12-16 1:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
isicom, check card state in isr
Check if the card really interrupted us by reading its IO space and
eventualy return IRQ_NONE.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
commit 601667e4ee38183358ea8f7980537bb8c09d8728
tree ccb1c085309ad35178f8d741e7c074308ae277ee
parent 405c17b09b010b41f6ec2388a11777e4048c7976
author Jiri Slaby <jirislaby@gmail.com> Fri, 15 Dec 2006 23:29:57 +0059
committer Jiri Slaby <jirislaby@gmail.com> Fri, 15 Dec 2006 23:29:57 +0059
drivers/char/isicom.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 7968160..f4faa76 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -539,6 +539,11 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
return IRQ_NONE;
base = card->base;
+
+ /* did the card interrupt us? */
+ if (!(inw(base + 0x0e) & 0x02))
+ return IRQ_NONE;
+
spin_lock(&card->card_lock);
/*
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/5] Char: isicom, fix probe race
2006-12-16 1:09 [PATCH 1/5] Char: isicom, fix locking in isr Jiri Slaby
2006-12-16 1:09 ` [PATCH 4/5] Char: isicom, check card state " Jiri Slaby
2006-12-16 1:09 ` [PATCH 3/5] Char: isicom, augment card_reset Jiri Slaby
@ 2006-12-16 1:09 ` Jiri Slaby
2006-12-18 23:27 ` Andrew Morton
2006-12-16 1:09 ` [PATCH 5/5] Char: isicom, support higher rates Jiri Slaby
3 siblings, 1 reply; 7+ messages in thread
From: Jiri Slaby @ 2006-12-16 1:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
isicom, fix probe race
Fix two race conditions in the probe function with mutex.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
commit e7087b32ad4b5ee1240fa7f9ba46a9b4566fe424
tree 28bc5ad2a47c03e1b7a09fce22afbe7000955e97
parent f2d37e8d3de070f8cda48a454f7b991d29b310be
author Jiri Slaby <jirislaby@gmail.com> Fri, 15 Dec 2006 21:08:11 +0059
committer Jiri Slaby <jirislaby@gmail.com> Fri, 15 Dec 2006 21:08:11 +0059
drivers/char/isicom.c | 26 ++++++++++++++++----------
1 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 836e967..5d2c345 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1732,22 +1732,25 @@ end:
/*
* Insmod can set static symbols so keep these static
*/
-static int card;
+static unsigned int card_count;
static int __devinit isicom_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+ static DEFINE_MUTEX(probe_lock);
unsigned int ioaddr, signature, index;
int retval = -EPERM;
- u8 pciirq;
struct isi_board *board = NULL;
- if (card >= BOARD_COUNT)
+ mutex_lock(&probe_lock);
+ if (card_count >= BOARD_COUNT) {
+ mutex_unlock(&probe_lock);
goto err;
+ }
+ card_count++;
ioaddr = pci_resource_start(pdev, 3);
/* i.e at offset 0x1c in the PCI configuration register space. */
- pciirq = pdev->irq;
dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
/* allot the first empty slot in the array */
@@ -1759,8 +1762,9 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
board->index = index;
board->base = ioaddr;
- board->irq = pciirq;
- card++;
+ board->irq = pdev->irq;
+
+ mutex_unlock(&probe_lock);
pci_set_drvdata(pdev, board);
@@ -1770,7 +1774,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
"will be disabled.\n", board->base, board->base + 15,
index + 1);
retval = -EBUSY;
- goto err;
+ goto err_dec;
}
retval = request_irq(board->irq, isicom_interrupt,
@@ -1799,8 +1803,10 @@ errunri:
free_irq(board->irq, board);
errunrr:
pci_release_region(pdev, 3);
-err:
+err_dec:
+ card_count--;
board->base = 0;
+err:
return retval;
}
@@ -1814,6 +1820,8 @@ static void __devexit isicom_remove(struct pci_dev *pdev)
free_irq(board->irq, board);
pci_release_region(pdev, 3);
+ card_count--;
+ board->base = 0;
}
static int __init isicom_init(void)
@@ -1821,8 +1829,6 @@ static int __init isicom_init(void)
int retval, idx, channel;
struct isi_port *port;
- card = 0;
-
for(idx = 0; idx < BOARD_COUNT; idx++) {
port = &isi_ports[idx * 16];
isi_card[idx].ports = port;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/5] Char: isicom, augment card_reset
2006-12-16 1:09 [PATCH 1/5] Char: isicom, fix locking in isr Jiri Slaby
2006-12-16 1:09 ` [PATCH 4/5] Char: isicom, check card state " Jiri Slaby
@ 2006-12-16 1:09 ` Jiri Slaby
2006-12-16 1:09 ` [PATCH 2/5] Char: isicom, fix probe race Jiri Slaby
2006-12-16 1:09 ` [PATCH 5/5] Char: isicom, support higher rates Jiri Slaby
3 siblings, 0 replies; 7+ messages in thread
From: Jiri Slaby @ 2006-12-16 1:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
isicom, augment card_reset
- add 0xee to signatures
- change long delays to sleeps
- make one sleep shorter not to wait 3s
- portcount == 16 is also correct
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
commit 405c17b09b010b41f6ec2388a11777e4048c7976
tree 4954b33027ee87193bfe91109d6fbc8b12c4e71a
parent e7087b32ad4b5ee1240fa7f9ba46a9b4566fe424
author Jiri Slaby <jirislaby@gmail.com> Fri, 15 Dec 2006 22:20:14 +0059
committer Jiri Slaby <jirislaby@gmail.com> Fri, 15 Dec 2006 22:20:14 +0059
drivers/char/isicom.c | 39 ++++++++++++++++++++++-----------------
1 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 5d2c345..7968160 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1501,7 +1501,7 @@ static int __devinit reset_card(struct pci_dev *pdev,
{
struct isi_board *board = pci_get_drvdata(pdev);
unsigned long base = board->base;
- unsigned int portcount = 0;
+ unsigned int sig, portcount = 0;
int retval = 0;
dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
@@ -1509,27 +1509,35 @@ static int __devinit reset_card(struct pci_dev *pdev,
inw(base + 0x8);
- mdelay(10);
+ msleep(10);
outw(0, base + 0x8); /* Reset */
- msleep(3000);
+ msleep(1000);
- *signature = inw(base + 0x4) & 0xff;
+ sig = inw(base + 0x4) & 0xff;
+
+ if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
+ sig != 0xee) {
+ dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
+ "bad I/O Port Address 0x%lx).\n", card + 1, base);
+ dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
+ retval = -EIO;
+ goto end;
+ }
+
+ msleep(10);
portcount = inw(base + 0x2);
- if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
- (portcount != 4) && (portcount != 8))) {
- dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
- inw(base + 0x2), inw(base + 0xe));
- dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
- "(Possible bad I/O Port Address 0x%lx).\n",
- card + 1, base);
+ if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
+ portcount != 8 && portcount != 16)) {
+ dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.",
+ card + 1);
retval = -EIO;
goto end;
}
- switch (*signature) {
+ switch (sig) {
case 0xa5:
case 0xbb:
case 0xdd:
@@ -1537,16 +1545,13 @@ static int __devinit reset_card(struct pci_dev *pdev,
board->shift_count = 12;
break;
case 0xcc:
+ case 0xee:
board->port_count = 16;
board->shift_count = 11;
break;
- default:
- dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible "
- "bad I/O Port Address 0x%lx).\n", card + 1, base);
- dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature);
- retval = -EIO;
}
dev_info(&pdev->dev, "-Done\n");
+ *signature = sig;
end:
return retval;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/5] Char: isicom, support higher rates
2006-12-16 1:09 [PATCH 1/5] Char: isicom, fix locking in isr Jiri Slaby
` (2 preceding siblings ...)
2006-12-16 1:09 ` [PATCH 2/5] Char: isicom, fix probe race Jiri Slaby
@ 2006-12-16 1:09 ` Jiri Slaby
3 siblings, 0 replies; 7+ messages in thread
From: Jiri Slaby @ 2006-12-16 1:09 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
isicom, support higher rates
Add support for higher baud rates (coming from original isi driver).
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
---
commit 8b380d8b1c3ff7d09d68d467d2f135774cab4086
tree d1e9332d7dc76c5f1d80f936bca71312d0bcb07b
parent 601667e4ee38183358ea8f7980537bb8c09d8728
author Jiri Slaby <jirislaby@gmail.com> Sat, 16 Dec 2006 02:05:20 +0059
committer Jiri Slaby <jirislaby@gmail.com> Sat, 16 Dec 2006 02:05:20 +0059
drivers/char/isicom.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index f4faa76..60df87c 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -183,7 +183,7 @@ static DEFINE_TIMER(tx, isicom_tx, 0, 0);
/* baud index mappings from linux defns to isi */
static signed char linuxb_to_isib[] = {
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
};
struct isi_board {
@@ -709,7 +709,8 @@ static void isicom_config_port(struct isi_port *port)
* respectively.
*/
- if (baud < 1 || baud > 2)
+ /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
+ if (baud < 1 || baud > 4)
port->tty->termios->c_cflag &= ~CBAUDEX;
else
baud += 15;
@@ -725,6 +726,10 @@ static void isicom_config_port(struct isi_port *port)
baud++; /* 57.6 Kbps */
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baud +=2; /* 115 Kbps */
+ if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ baud += 3; /* 230 kbps*/
+ if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ baud += 4; /* 460 kbps*/
}
if (linuxb_to_isib[baud] == -1) {
/* hang up */
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/5] Char: isicom, fix probe race
2006-12-16 1:09 ` [PATCH 2/5] Char: isicom, fix probe race Jiri Slaby
@ 2006-12-18 23:27 ` Andrew Morton
2006-12-18 23:48 ` Jiri Slaby
0 siblings, 1 reply; 7+ messages in thread
From: Andrew Morton @ 2006-12-18 23:27 UTC (permalink / raw)
To: Jiri Slaby; +Cc: linux-kernel
On Sat, 16 Dec 2006 02:09:48 +0100 (CET)
Jiri Slaby <jirislaby@gmail.com> wrote:
> isicom, fix probe race
>
> Fix two race conditions in the probe function with mutex.
>
> ...
>
> static int __devinit isicom_probe(struct pci_dev *pdev,
> const struct pci_device_id *ent)
> {
> + static DEFINE_MUTEX(probe_lock);
hm. How can isicom_probe() race with itself? Even with the dreaded
multithreaded-pci-probing? It's only called once, by a single thread.
Confused.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/5] Char: isicom, fix probe race
2006-12-18 23:27 ` Andrew Morton
@ 2006-12-18 23:48 ` Jiri Slaby
0 siblings, 0 replies; 7+ messages in thread
From: Jiri Slaby @ 2006-12-18 23:48 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel
Andrew Morton wrote:
> On Sat, 16 Dec 2006 02:09:48 +0100 (CET)
> Jiri Slaby <jirislaby@gmail.com> wrote:
>
>> isicom, fix probe race
>>
>> Fix two race conditions in the probe function with mutex.
>>
>> ...
>>
>> static int __devinit isicom_probe(struct pci_dev *pdev,
>> const struct pci_device_id *ent)
>> {
>> + static DEFINE_MUTEX(probe_lock);
>
> hm. How can isicom_probe() race with itself? Even with the dreaded
> multithreaded-pci-probing? It's only called once, by a single thread.
>
> Confused.
Yeah, I'm a little bit too now. One of developers want me to do this some time
ago and I did it without deep thinking about that. Now, I did it again and as
you wrote, it's completely unreasonable. Please, throw it
(char-isicom-fix-probe-race.patch) away.
thanks,
--
http://www.fi.muni.cz/~xslaby/ Jiri Slaby
faculty of informatics, masaryk university, brno, cz
e-mail: jirislaby gmail com, gpg pubkey fingerprint:
B674 9967 0407 CE62 ACC8 22A0 32CC 55C3 39D4 7A7E
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-12-18 23:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-12-16 1:09 [PATCH 1/5] Char: isicom, fix locking in isr Jiri Slaby
2006-12-16 1:09 ` [PATCH 4/5] Char: isicom, check card state " Jiri Slaby
2006-12-16 1:09 ` [PATCH 3/5] Char: isicom, augment card_reset Jiri Slaby
2006-12-16 1:09 ` [PATCH 2/5] Char: isicom, fix probe race Jiri Slaby
2006-12-18 23:27 ` Andrew Morton
2006-12-18 23:48 ` Jiri Slaby
2006-12-16 1:09 ` [PATCH 5/5] Char: isicom, support higher rates Jiri Slaby
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).