Char: isicom, cleanup locking
PATCH 1/3 Char: isicom, cleanup locking
isicom, cleanup locking
don't spin processor when not needed (use sleep instead of delay). Don't release the lock when needed in next iteration -- this actually fixes a bug -- missing braces
---
commit af05316f4ba7503ae531f3afdb5264c10e3b8e2c
tree 2fac39ab09e16f20329fc785beeb7607b6ed8bc9
parent a9dbc0b98956d548b1aee3f55b3799a12946ace4
author Jiri Slaby <[email protected]> Sun, 20 May 2007 21:32:42 +0200 committer Jiri Slaby <[email protected]> Sun, 20 May 2007 21:32:42 +0200
drivers/char/isicom.c | 65 ++++++++++++++++++++----------------------------- 1 files changed, 27 insertions(+), 38 deletions(-)
drivers/char/isicom.c +27 -38
@@ -243,17 +243,18 @@ static inline int WaitTillCardIsFree(u16 base)static int lock_card (struct isi_board *card) { -char retries;unsigned long base = card->base; +unsigned int retries, a; -for (retries =0 ; retries <100 ; retries++) { +for (retries =0 ; retries <10 ; retries++) {spin_lock_irqsave (&card->card_lock, card->flags); -if (inw (base +0xe ) &0x1 ) { -return 1 ; - }else { -spin_unlock_irqrestore (&card->card_lock, card->flags); -udelay (1000 );/* 1ms */ +for (a =0 ; a <10 ; a++) { +if (inw (base +0xe ) &0x1 ) +return 1 ; +udelay (10 ); } +spin_unlock_irqrestore (&card->card_lock, card->flags); +msleep (10 ); }printk (KERN_WARNING "ISICOM: Failed to lock Card (0x%lx)\n" , card->base);
@@ -261,23 +262,6 @@ static int lock_card(struct isi_board *card)return 0 ;/* Failed to acquire the card! */ } -static int lock_card_at_interrupt (struct isi_board *card) -{ -unsigned char retries; -unsigned long base = card->base; - -for (retries =0 ; retries <200 ; retries++) { -spin_lock_irqsave (&card->card_lock, card->flags); - -if (inw (base +0xe ) &0x1 ) -return 1 ; -else -spin_unlock_irqrestore (&card->card_lock, card->flags); - } -/* Failing in interrupt is an acceptable event */ -return 0 ;/* Failed to acquire the card! */ -} -static void unlock_card (struct isi_board *card) {spin_unlock_irqrestore (&card->card_lock, card->flags);
@@ -415,6 +399,8 @@ static inline int __isicom_paranoia_check(struct isi_port const *port,static void isicom_tx (unsigned long _data) { +unsigned long flags; +unsigned int retries;short count = (BOARD_COUNT -1 ), card, base;short txcount, wrd, residue, word_count, cnt;struct isi_port *port;
@@ -435,32 +421,34 @@ static void isicom_tx(unsigned long _data) count = isi_card[card].port_count; port = isi_card[card].ports; base = isi_card[card].base; + +spin_lock_irqsave (&isi_card[card].card_lock, flags); +for (retries =0 ; retries <100 ; retries++) { +if (inw (base +0xe ) &0x1 ) +break ; +udelay (2 ); + } +if (retries >=100 ) + goto unlock; +for (;count >0 ;count--, port++) { -if (!lock_card_at_interrupt (&isi_card[card])) -continue ;/* port not active or tx disabled to force flow control */ if (!(port->flags &ASYNC_INITIALIZED ) || !(port->status &ISI_TXOK )) -unlock_card (&isi_card[card]);continue ; tty = port->tty; - -if (tty ==NULL ) { -unlock_card (&isi_card[card]); +if (tty ==NULL )continue ; - } txcount =min_t (short,TX_SIZE , port->xmit_cnt); -if (txcount <=0 || tty->stopped || tty->hw_stopped) { -unlock_card (&isi_card[card]); +if (txcount <=0 || tty->stopped || tty->hw_stopped)continue ; - } -if (!(inw (base +0x02 ) & (1 << port->channel))) { -unlock_card (&isi_card[card]); + +if (!(inw (base +0x02 ) & (1 << port->channel)))continue ; - } +pr_dbg ("txing %d bytes, port%d.\n" , txcount, port->channel +1 ); outw((port->channel << isi_card[card].shift_count) | txcount,
@@ -508,9 +496,10 @@ static void isicom_tx(unsigned long _data) port->status &= ~ISI_TXOK ;if (port->xmit_cnt <=WAKEUP_CHARS )tty_wakeup (tty); -unlock_card (&isi_card[card]); } +unlock: +spin_unlock_irqrestore (&isi_card[card].card_lock, flags);/* schedule another tx for hopefully in about 10ms */ sched_again:if (!re_schedule) {
PATCH 2/3 Char: isicom, del_timer at exit
isicom, del_timer at exit
---
commit 017f1314b3de8cf20bfff7df0d3d55e6498de104
tree 938fec328f3b24588575540771f65c8fadeaf961
parent af05316f4ba7503ae531f3afdb5264c10e3b8e2c
author Jiri Slaby <[email protected]> Sun, 20 May 2007 21:43:42 +0200 committer Jiri Slaby <[email protected]> Sun, 20 May 2007 21:43:42 +0200
drivers/char/isicom.c | 12 +----------- 1 files changed, 1 insertions(+), 11 deletions(-)
drivers/char/isicom.c +1 -11
@@ -171,9 +171,6 @@ static struct pci_driver isicom_driver = {static int prev_card =3 ;/* start servicing isi_card[0] */ static struct tty_driver *isicom_normal; -static DECLARE_COMPLETION (isi_timerdone); -static char re_schedule =1 ; -static void isicom_tx (unsigned long _data);static void isicom_start (struct tty_struct *tty);
@@ -502,11 +499,6 @@ unlock:spin_unlock_irqrestore (&isi_card[card].card_lock, flags);/* schedule another tx for hopefully in about 10ms */ sched_again: -if (!re_schedule) { -complete (&isi_timerdone); -return ; - } -mod_timer (&tx, jiffies +msecs_to_jiffies (10 )); }
@@ -1890,9 +1882,7 @@ error: static void __exit isicom_exit(void) { - re_schedule =0 ; - -wait_for_completion_timeout (&isi_timerdone,HZ ); +del_timer_sync (&tx);pci_unregister_driver (&isicom_driver);tty_unregister_driver (isicom_normal);
PATCH 3/3 Char: isicom, proper variables types
In reply to Jiri Slabyisicom, proper variables types
irq is int, base is unsigned long
---
commit 2c1fb6b2f7c17ab752e56220a0b7e84fbe6d3448
tree 1b4ceff6aacaae2ad1548c2efa202d7d0c3d92ba
parent 017f1314b3de8cf20bfff7df0d3d55e6498de104
author Jiri Slaby <[email protected]> Sun, 20 May 2007 23:20:41 +0200 committer Jiri Slaby <[email protected]> Sun, 20 May 2007 23:20:41 +0200
drivers/char/isicom.c | 18 +++++++----------- 1 files changed, 7 insertions(+), 11 deletions(-)
drivers/char/isicom.c +7 -11
@@ -184,7 +184,7 @@ static signed char linuxb_to_isib[] = {struct isi_board {unsigned long base; -unsigned char irq; +int irq;unsigned char port_count;unsigned short status;unsigned short port_status;/* each bit for each port */
@@ -224,7 +224,7 @@ static struct isi_port isi_ports[PORT_COUNT];* it wants to talk. */ -static inline int WaitTillCardIsFree (u16 base) +static inline int WaitTillCardIsFree (unsigned long base) {unsigned int count =0 ;unsigned int a =in_atomic ();/* do we run under spinlock? */
@@ -396,9 +396,9 @@ static inline int __isicom_paranoia_check(struct isi_port const *port,static void isicom_tx (unsigned long _data) { -unsigned long flags; +unsigned long flags, base;unsigned int retries; -short count = (BOARD_COUNT -1 ), card, base; +short count = (BOARD_COUNT -1 ), card;short txcount, wrd, residue, word_count, cnt;struct isi_port *port;struct tty_struct *tty;
@@ -1730,17 +1730,13 @@ static unsigned int card_count;static int __devinit isicom_probe (struct pci_dev *pdev,const struct pci_device_id *ent) { -unsigned int ioaddr, signature, index; +unsigned int signature, index;int retval = -EPERM ; -u8 pciirq;struct isi_board *board =NULL ;if (card_count >=BOARD_COUNT ) goto err; - 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 */
@@ -1751,8 +1747,8 @@ static int __devinit isicom_probe(struct pci_dev *pdev, } board->index = index; - board->base = ioaddr; - board->irq = pciirq; + board->base =pci_resource_start (pdev,3 ); + board->irq = pdev->irq; card_count++;pci_set_drvdata (pdev, board);