public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Remove cli() from R3964 line discipline.
@ 2002-07-29 10:43 David Woodhouse
  0 siblings, 0 replies; only message in thread
From: David Woodhouse @ 2002-07-29 10:43 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

I did this ages ago but never submitted it because I never got round to 
testing it. I still haven't tested it, but it ought to work, and the code 
is definitely broken without it...

===== drivers/char/n_r3964.c 1.9 vs edited =====
--- 1.9/drivers/char/n_r3964.c	Thu May 23 17:07:43 2002
+++ edited/drivers/char/n_r3964.c	Mon Jul 29 11:39:36 2002
@@ -13,6 +13,12 @@
  * L. Haag
  *
  * $Log: n_r3964.c,v $
+ * Revision 1.10  2001/03/18 13:02:24  dwmw2
+ * Fix timer usage, use spinlocks properly.
+ *
+ * Revision 1.9  2001/03/18 12:52:14  dwmw2
+ * Merge changes in 2.4.2
+ *
  * Revision 1.8  2000/03/23 14:14:54  dwmw2
  * Fix race in sleeping in r3964_read()
  *
@@ -110,8 +116,6 @@
 #define TRACE_Q(fmt, arg...) /**/
 #endif
 
-static void on_timer_1(void*);
-static void on_timer_2(void*);
 static void add_tx_queue(struct r3964_info *, struct r3964_block_header *);
 static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code);
 static void put_char(struct r3964_info *pInfo, unsigned char ch);
@@ -120,7 +124,7 @@
 static void transmit_block(struct r3964_info *pInfo);
 static void receive_char(struct r3964_info *pInfo, const unsigned char c);
 static void receive_error(struct r3964_info *pInfo, const char flag);
-static void on_timeout(struct r3964_info *pInfo);
+static void on_timeout(unsigned long priv);
 static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg);
 static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char *buf);
 static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
@@ -217,7 +221,7 @@
 {
    int status;
    
-   printk ("r3964: Philips r3964 Driver $Revision: 1.8 $\n");
+   printk ("r3964: Philips r3964 Driver $Revision: 1.10 $\n");
 
    /*
     * Register the tty line discipline
@@ -247,40 +251,11 @@
  * Protocol implementation routines
  *************************************************************/
 
-static void on_timer_1(void *arg)
-{
-   struct r3964_info *pInfo = (struct r3964_info *)arg;
-  
-   if(pInfo->count_down)
-   {
-      if(!--pInfo->count_down)
-      {
-         on_timeout(pInfo);
-      }
-   }
-   queue_task(&pInfo->bh_2, &tq_timer);
-}
-
-static void on_timer_2(void *arg)
-{
-   struct r3964_info *pInfo = (struct r3964_info *)arg;
-  
-   if(pInfo->count_down)
-   {
-      if(!--pInfo->count_down)
-      {
-         on_timeout(pInfo);
-      }
-   }
-   queue_task(&pInfo->bh_1, &tq_timer);
-}
-
 static void add_tx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader)
 {
    unsigned long flags;
    
-   save_flags(flags);
-   cli();
+   spin_lock_irqsave(&pInfo->lock, flags);
 
    pHeader->next = NULL;
 
@@ -294,7 +269,7 @@
       pInfo->tx_last = pHeader;
    }
    
-   restore_flags(flags);
+   spin_unlock_irqrestore(&pInfo->lock, flags);
 
    TRACE_Q("add_tx_queue %x, length %d, tx_first = %x", 
           (int)pHeader, pHeader->length, (int)pInfo->tx_first );
@@ -337,8 +312,7 @@
       wake_up_interruptible (&pInfo->read_wait);
    }
 
-   save_flags(flags);
-   cli();
+   spin_lock_irqsave(&pInfo->lock, flags);
 
    pInfo->tx_first = pHeader->next;
    if(pInfo->tx_first==NULL)
@@ -346,7 +320,7 @@
       pInfo->tx_last = NULL;
    }
 
-   restore_flags(flags);
+   spin_unlock_irqrestore(&pInfo->lock, flags);
 
    kfree(pHeader);
    TRACE_M("remove_from_tx_queue - kfree %x",(int)pHeader);
@@ -359,8 +333,7 @@
 {
    unsigned long flags;
    
-   save_flags(flags);
-   cli();
+   spin_lock_irqsave(&pInfo->lock, flags);
 
    pHeader->next = NULL;
 
@@ -375,7 +348,7 @@
    }
    pInfo->blocks_in_rx_queue++;
    
-   restore_flags(flags);
+   spin_unlock_irqrestore(&pInfo->lock, flags);
 
    TRACE_Q("add_rx_queue: %x, length = %d, rx_first = %x, count = %d",
           (int)pHeader, pHeader->length,
@@ -396,8 +369,7 @@
    TRACE_Q("remove_from_rx_queue: %x, length %d",
           (int)pHeader, (int)pHeader->length );
 
-   save_flags(flags);
-   cli();
+   spin_lock_irqsave(&pInfo->lock, flags);
 
    if(pInfo->rx_first == pHeader)
    {
@@ -430,7 +402,7 @@
       }
    }
 
-   restore_flags(flags);
+   spin_unlock_irqrestore(&pInfo->lock, flags);
 
    kfree(pHeader);
    TRACE_M("remove_from_rx_queue - kfree %x",(int)pHeader);
@@ -471,17 +443,16 @@
    unsigned long flags;
    
 
-   save_flags(flags);
-   cli();
+   spin_lock_irqsave(&pInfo->lock, flags);
 
    if((pInfo->state == R3964_IDLE) && (pInfo->tx_first!=NULL))
    {
       pInfo->state = R3964_TX_REQUEST;
-      pInfo->count_down = R3964_TO_QVZ;
       pInfo->nRetry=0;
       pInfo->flags &= ~R3964_ERROR;
-      
-      restore_flags(flags);
+      mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+
+      spin_unlock_irqrestore(&pInfo->lock, flags);
 
       TRACE_PS("trigger_transmit - sent STX");
 
@@ -492,7 +463,7 @@
    }
    else
    {
-      restore_flags(flags);
+      spin_unlock_irqrestore(&pInfo->lock, flags);
    }
 }
 
@@ -506,8 +477,8 @@
       put_char(pInfo, STX);
       flush(pInfo);
       pInfo->state = R3964_TX_REQUEST;
-      pInfo->count_down = R3964_TO_QVZ;
       pInfo->nRetry++;
+      mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
    }
    else
    {
@@ -566,7 +537,7 @@
          put_char(pInfo, pInfo->bcc);
       }
       pInfo->state = R3964_WAIT_FOR_TX_ACK;
-      pInfo->count_down = R3964_TO_QVZ;
+      mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
    }
    flush(pInfo);
 }
@@ -601,8 +572,8 @@
       if(pInfo->nRetry<R3964_MAX_RETRIES)
       {
          pInfo->state=R3964_WAIT_FOR_RX_REPEAT;
-         pInfo->count_down = R3964_TO_RX_PANIC;
          pInfo->nRetry++;
+	 mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC);
       }
       else
       {
@@ -616,7 +587,7 @@
    /* received block; submit DLE: */
    put_char(pInfo, DLE);
    flush(pInfo);
-   pInfo->count_down=0;
+   del_timer_sync(&pInfo->tmr);
    TRACE_PS(" rx success: got %d chars", length);
 
    /* prepare struct r3964_block_header: */
@@ -701,7 +672,7 @@
             TRACE_PE("TRANSMITTING - got illegal char");
  
             pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY;
-            pInfo->count_down = R3964_TO_ZVZ;
+	    mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
          }
          break;
       case R3964_WAIT_FOR_TX_ACK:
@@ -728,7 +699,7 @@
             {
                TRACE_PE("IDLE - got STX but no space in rx_queue!");
                pInfo->state=R3964_WAIT_FOR_RX_BUF;
-               pInfo->count_down = R3964_TO_NO_BUF;
+	       mod_timer(&pInfo->tmr, R3964_TO_NO_BUF);
                break;
             }
 start_receiving:
@@ -738,8 +709,8 @@
             pInfo->last_rx = 0;
             pInfo->flags &= ~R3964_ERROR;
             pInfo->state=R3964_RECEIVING;
-            pInfo->count_down = R3964_TO_ZVZ;
-            pInfo->nRetry = 0;
+	    mod_timer(&pInfo->tmr, R3964_TO_ZVZ);
+	    pInfo->nRetry = 0;
             put_char(pInfo, DLE);
             flush(pInfo);
             pInfo->bcc = 0;
@@ -765,7 +736,7 @@
                if(pInfo->flags & R3964_BCC)
                {
                   pInfo->state = R3964_WAIT_FOR_BCC;
-                  pInfo->count_down = R3964_TO_ZVZ;
+		  mod_timer(&pInfo->tmr, R3964_TO_ZVZ);
                }
                else 
                {
@@ -777,7 +748,7 @@
                pInfo->last_rx = c;
 char_to_buf:
                pInfo->rx_buf[pInfo->rx_position++] = c;
-               pInfo->count_down = R3964_TO_ZVZ;
+	       mod_timer(&pInfo->tmr, R3964_TO_ZVZ);
             }
          }
         /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */ 
@@ -818,8 +789,10 @@
     }
 }
 
-static void on_timeout(struct r3964_info *pInfo)
+static void on_timeout(unsigned long priv)
 {
+   struct r3964_info *pInfo = (void *)priv;
+
    switch(pInfo->state)
    {
       case R3964_TX_REQUEST:
@@ -926,6 +899,7 @@
             return -ENOMEM;
 
          TRACE_PS("add client %d to client list", pid);
+	 spin_lock_init(&pClient->lock);
          pClient->sig_flags=arg;
          pClient->pid = pid;
          pClient->next=pInfo->firstClient;
@@ -989,8 +963,7 @@
          return;
       }
 
-      save_flags(flags);
-      cli();
+      spin_lock_irqsave(&pClient->lock, flags);
 
       pMsg->msg_id = msg_id;
       pMsg->arg    = arg;
@@ -1014,7 +987,7 @@
       {
          pBlock->locks++;
       }
-      restore_flags(flags);
+      spin_unlock_irqrestore(&pClient->lock, flags);
    }
    else
    {
@@ -1049,8 +1022,7 @@
 
    if(pClient->first_msg)
    {
-      save_flags(flags);
-      cli();
+      spin_lock_irqsave(&pClient->lock, flags);
 
       pMsg = pClient->first_msg;
       pClient->first_msg = pMsg->next;
@@ -1065,7 +1037,7 @@
         remove_client_block(pInfo, pClient);
         pClient->next_block_to_read = pMsg->block;
       }
-      restore_flags(flags);
+      spin_unlock_irqrestore(&pClient->lock, flags);
    }
    return pMsg;
 }
@@ -1137,6 +1109,7 @@
       return -ENOMEM;
    }
 
+   spin_lock_init(&pInfo->lock);
    pInfo->tty = tty;
    init_waitqueue_head (&pInfo->read_wait);
    pInfo->priority = R3964_MASTER;
@@ -1149,26 +1122,13 @@
    pInfo->firstClient=NULL;
    pInfo->state=R3964_IDLE;
    pInfo->flags = R3964_DEBUG;
-   pInfo->count_down = 0;
    pInfo->nRetry = 0;
    
    tty->disc_data = pInfo;
 
-   /*
-    * Add 'on_timer' to timer task queue
-    * (will be called from timer bh)
-    */
-   INIT_LIST_HEAD(&pInfo->bh_1.list);
-   pInfo->bh_1.sync = 0;
-   pInfo->bh_1.routine = &on_timer_1;
-   pInfo->bh_1.data = pInfo;
-   
-   INIT_LIST_HEAD(&pInfo->bh_2.list);
-   pInfo->bh_2.sync = 0;
-   pInfo->bh_2.routine = &on_timer_2;
-   pInfo->bh_2.data = pInfo;
-
-   queue_task(&pInfo->bh_1, &tq_timer);
+   INIT_LIST_HEAD(&pInfo->tmr.list);
+   pInfo->tmr.data = (unsigned long)pInfo;
+   pInfo->tmr.function = on_timeout;
 
    return 0;
 }
@@ -1187,12 +1147,7 @@
      * Make sure that our task queue isn't activated.  If it
      * is, take it out of the linked list.
      */
-    spin_lock_irqsave(&tqueue_lock, flags);
-    if (pInfo->bh_1.sync)
-    	list_del(&pInfo->bh_1.list);
-    if (pInfo->bh_2.sync)
-    	list_del(&pInfo->bh_2.list);
-    spin_unlock_irqrestore(&tqueue_lock, flags);
+    del_timer_sync(&pInfo->tmr);
 
    /* Remove client-structs and message queues: */
     pClient=pInfo->firstClient;
@@ -1213,11 +1168,10 @@
        pClient=pNext;
     }
     /* Remove jobs from tx_queue: */
-	save_flags(flags);
-        cli();
+        spin_lock_irqsave(&pInfo->lock, flags);
 	pHeader=pInfo->tx_first;
 	pInfo->tx_first=pInfo->tx_last=NULL;
-	restore_flags(flags);
+	spin_unlock_irqrestore(&pInfo->lock, flags);
 	
     while(pHeader)
 	{
@@ -1430,10 +1384,9 @@
    if(pClient)
      {
        poll_wait(file, &pInfo->read_wait, wait);
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&pInfo->lock, flags);
        pMsg=pClient->first_msg;
-       restore_flags(flags);
+       spin_unlock_irqrestore(&pInfo->lock, flags);
        if(pMsg)
 	   result |= POLLIN | POLLRDNORM;
      }
===== include/linux/n_r3964.h 1.2 vs edited =====
--- 1.2/include/linux/n_r3964.h	Tue Feb  5 07:38:17 2002
+++ edited/include/linux/n_r3964.h	Mon Jul 29 11:38:46 2002
@@ -13,6 +13,12 @@
  * L. Haag
  *
  * $Log: r3964.h,v $
+ * Revision 1.3  2001/03/18 13:02:24  dwmw2
+ * Fix timer usage, use spinlocks properly.
+ *
+ * Revision 1.2  2001/03/18 12:53:15  dwmw2
+ * Merge changes in 2.4.2
+ *
  * Revision 1.1.1.1  1998/10/13 16:43:14  dwmw2
  * This'll screw the version control
  *
@@ -103,8 +109,9 @@
 struct r3964_message;
 
 struct r3964_client_info {
+	spinlock_t     lock;
 	pid_t          pid;
-    unsigned int   sig_flags;
+	unsigned int   sig_flags;
 
 	struct r3964_client_info *next;
 
@@ -186,6 +193,7 @@
 
 
 struct r3964_info {
+	spinlock_t     lock;
 	struct tty_struct *tty;
 	unsigned char priority;
 	unsigned char *rx_buf;            /* ring buffer */
@@ -209,11 +217,8 @@
 	unsigned int state;
 	unsigned int flags;
 
-	int count_down;
-    int nRetry;
-
-    struct tq_struct bh_1;
-    struct tq_struct bh_2;
+	struct timer_list tmr;
+	int nRetry;
 };
 
 #endif	

--
dwmw2



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-07-29 10:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-07-29 10:43 [PATCH] Remove cli() from R3964 line discipline David Woodhouse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox