linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).