114
114
#define DEFAULT_TX_BUF_COUNT 3
115
115
116
116
struct n_hdlc_buf {
117
- struct n_hdlc_buf * link ;
117
+ struct list_head list_item ;
118
118
int count ;
119
119
char buf [1 ];
120
120
};
121
121
122
122
#define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe)
123
123
124
124
struct n_hdlc_buf_list {
125
- struct n_hdlc_buf * head ;
126
- struct n_hdlc_buf * tail ;
125
+ struct list_head list ;
127
126
int count ;
128
127
spinlock_t spinlock ;
129
128
};
@@ -136,7 +135,6 @@ struct n_hdlc_buf_list {
136
135
* @backup_tty - TTY to use if tty gets closed
137
136
* @tbusy - reentrancy flag for tx wakeup code
138
137
* @woke_up - FIXME: describe this field
139
- * @tbuf - currently transmitting tx buffer
140
138
* @tx_buf_list - list of pending transmit frame buffers
141
139
* @rx_buf_list - list of received frame buffers
142
140
* @tx_free_buf_list - list unused transmit frame buffers
@@ -149,7 +147,6 @@ struct n_hdlc {
149
147
struct tty_struct * backup_tty ;
150
148
int tbusy ;
151
149
int woke_up ;
152
- struct n_hdlc_buf * tbuf ;
153
150
struct n_hdlc_buf_list tx_buf_list ;
154
151
struct n_hdlc_buf_list rx_buf_list ;
155
152
struct n_hdlc_buf_list tx_free_buf_list ;
@@ -159,6 +156,8 @@ struct n_hdlc {
159
156
/*
160
157
* HDLC buffer list manipulation functions
161
158
*/
159
+ static void n_hdlc_buf_return (struct n_hdlc_buf_list * buf_list ,
160
+ struct n_hdlc_buf * buf );
162
161
static void n_hdlc_buf_put (struct n_hdlc_buf_list * list ,
163
162
struct n_hdlc_buf * buf );
164
163
static struct n_hdlc_buf * n_hdlc_buf_get (struct n_hdlc_buf_list * list );
@@ -208,16 +207,9 @@ static void flush_tx_queue(struct tty_struct *tty)
208
207
{
209
208
struct n_hdlc * n_hdlc = tty2n_hdlc (tty );
210
209
struct n_hdlc_buf * buf ;
211
- unsigned long flags ;
212
210
213
211
while ((buf = n_hdlc_buf_get (& n_hdlc -> tx_buf_list )))
214
212
n_hdlc_buf_put (& n_hdlc -> tx_free_buf_list , buf );
215
- spin_lock_irqsave (& n_hdlc -> tx_buf_list .spinlock , flags );
216
- if (n_hdlc -> tbuf ) {
217
- n_hdlc_buf_put (& n_hdlc -> tx_free_buf_list , n_hdlc -> tbuf );
218
- n_hdlc -> tbuf = NULL ;
219
- }
220
- spin_unlock_irqrestore (& n_hdlc -> tx_buf_list .spinlock , flags );
221
213
}
222
214
223
215
static struct tty_ldisc_ops n_hdlc_ldisc = {
@@ -283,7 +275,6 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc)
283
275
} else
284
276
break ;
285
277
}
286
- kfree (n_hdlc -> tbuf );
287
278
kfree (n_hdlc );
288
279
289
280
} /* end of n_hdlc_release() */
@@ -402,13 +393,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
402
393
n_hdlc -> woke_up = 0 ;
403
394
spin_unlock_irqrestore (& n_hdlc -> tx_buf_list .spinlock , flags );
404
395
405
- /* get current transmit buffer or get new transmit */
406
- /* buffer from list of pending transmit buffers */
407
-
408
- tbuf = n_hdlc -> tbuf ;
409
- if (!tbuf )
410
- tbuf = n_hdlc_buf_get (& n_hdlc -> tx_buf_list );
411
-
396
+ tbuf = n_hdlc_buf_get (& n_hdlc -> tx_buf_list );
412
397
while (tbuf ) {
413
398
if (debuglevel >= DEBUG_LEVEL_INFO )
414
399
printk ("%s(%d)sending frame %p, count=%d\n" ,
@@ -420,7 +405,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
420
405
421
406
/* rollback was possible and has been done */
422
407
if (actual == - ERESTARTSYS ) {
423
- n_hdlc -> tbuf = tbuf ;
408
+ n_hdlc_buf_return ( & n_hdlc -> tx_buf_list , tbuf ) ;
424
409
break ;
425
410
}
426
411
/* if transmit error, throw frame away by */
@@ -435,10 +420,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
435
420
436
421
/* free current transmit buffer */
437
422
n_hdlc_buf_put (& n_hdlc -> tx_free_buf_list , tbuf );
438
-
439
- /* this tx buffer is done */
440
- n_hdlc -> tbuf = NULL ;
441
-
423
+
442
424
/* wait up sleeping writers */
443
425
wake_up_interruptible (& tty -> write_wait );
444
426
@@ -448,10 +430,12 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
448
430
if (debuglevel >= DEBUG_LEVEL_INFO )
449
431
printk ("%s(%d)frame %p pending\n" ,
450
432
__FILE__ ,__LINE__ ,tbuf );
451
-
452
- /* buffer not accepted by driver */
453
- /* set this buffer as pending buffer */
454
- n_hdlc -> tbuf = tbuf ;
433
+
434
+ /*
435
+ * the buffer was not accepted by driver,
436
+ * return it back into tx queue
437
+ */
438
+ n_hdlc_buf_return (& n_hdlc -> tx_buf_list , tbuf );
455
439
break ;
456
440
}
457
441
}
@@ -749,7 +733,8 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
749
733
int error = 0 ;
750
734
int count ;
751
735
unsigned long flags ;
752
-
736
+ struct n_hdlc_buf * buf = NULL ;
737
+
753
738
if (debuglevel >= DEBUG_LEVEL_INFO )
754
739
printk ("%s(%d)n_hdlc_tty_ioctl() called %d\n" ,
755
740
__FILE__ ,__LINE__ ,cmd );
@@ -763,8 +748,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
763
748
/* report count of read data available */
764
749
/* in next available frame (if any) */
765
750
spin_lock_irqsave (& n_hdlc -> rx_buf_list .spinlock ,flags );
766
- if (n_hdlc -> rx_buf_list .head )
767
- count = n_hdlc -> rx_buf_list .head -> count ;
751
+ buf = list_first_entry_or_null (& n_hdlc -> rx_buf_list .list ,
752
+ struct n_hdlc_buf , list_item );
753
+ if (buf )
754
+ count = buf -> count ;
768
755
else
769
756
count = 0 ;
770
757
spin_unlock_irqrestore (& n_hdlc -> rx_buf_list .spinlock ,flags );
@@ -776,8 +763,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
776
763
count = tty_chars_in_buffer (tty );
777
764
/* add size of next output frame in queue */
778
765
spin_lock_irqsave (& n_hdlc -> tx_buf_list .spinlock ,flags );
779
- if (n_hdlc -> tx_buf_list .head )
780
- count += n_hdlc -> tx_buf_list .head -> count ;
766
+ buf = list_first_entry_or_null (& n_hdlc -> tx_buf_list .list ,
767
+ struct n_hdlc_buf , list_item );
768
+ if (buf )
769
+ count += buf -> count ;
781
770
spin_unlock_irqrestore (& n_hdlc -> tx_buf_list .spinlock ,flags );
782
771
error = put_user (count , (int __user * )arg );
783
772
break ;
@@ -825,14 +814,14 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
825
814
poll_wait (filp , & tty -> write_wait , wait );
826
815
827
816
/* set bits for operations that won't block */
828
- if (n_hdlc -> rx_buf_list .head )
817
+ if (! list_empty ( & n_hdlc -> rx_buf_list .list ) )
829
818
mask |= POLLIN | POLLRDNORM ; /* readable */
830
819
if (test_bit (TTY_OTHER_CLOSED , & tty -> flags ))
831
820
mask |= POLLHUP ;
832
821
if (tty_hung_up_p (filp ))
833
822
mask |= POLLHUP ;
834
823
if (!tty_is_writelocked (tty ) &&
835
- n_hdlc -> tx_free_buf_list .head )
824
+ ! list_empty ( & n_hdlc -> tx_free_buf_list .list ) )
836
825
mask |= POLLOUT | POLLWRNORM ; /* writable */
837
826
}
838
827
return mask ;
@@ -856,7 +845,12 @@ static struct n_hdlc *n_hdlc_alloc(void)
856
845
spin_lock_init (& n_hdlc -> tx_free_buf_list .spinlock );
857
846
spin_lock_init (& n_hdlc -> rx_buf_list .spinlock );
858
847
spin_lock_init (& n_hdlc -> tx_buf_list .spinlock );
859
-
848
+
849
+ INIT_LIST_HEAD (& n_hdlc -> rx_free_buf_list .list );
850
+ INIT_LIST_HEAD (& n_hdlc -> tx_free_buf_list .list );
851
+ INIT_LIST_HEAD (& n_hdlc -> rx_buf_list .list );
852
+ INIT_LIST_HEAD (& n_hdlc -> tx_buf_list .list );
853
+
860
854
/* allocate free rx buffer list */
861
855
for (i = 0 ;i < DEFAULT_RX_BUF_COUNT ;i ++ ) {
862
856
buf = kmalloc (N_HDLC_BUF_SIZE , GFP_KERNEL );
@@ -883,54 +877,66 @@ static struct n_hdlc *n_hdlc_alloc(void)
883
877
884
878
} /* end of n_hdlc_alloc() */
885
879
880
+ /**
881
+ * n_hdlc_buf_return - put the HDLC buffer after the head of the specified list
882
+ * @buf_list - pointer to the buffer list
883
+ * @buf - pointer to the buffer
884
+ */
885
+ static void n_hdlc_buf_return (struct n_hdlc_buf_list * buf_list ,
886
+ struct n_hdlc_buf * buf )
887
+ {
888
+ unsigned long flags ;
889
+
890
+ spin_lock_irqsave (& buf_list -> spinlock , flags );
891
+
892
+ list_add (& buf -> list_item , & buf_list -> list );
893
+ buf_list -> count ++ ;
894
+
895
+ spin_unlock_irqrestore (& buf_list -> spinlock , flags );
896
+ }
897
+
886
898
/**
887
899
* n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
888
- * @list - pointer to buffer list
900
+ * @buf_list - pointer to buffer list
889
901
* @buf - pointer to buffer
890
902
*/
891
- static void n_hdlc_buf_put (struct n_hdlc_buf_list * list ,
903
+ static void n_hdlc_buf_put (struct n_hdlc_buf_list * buf_list ,
892
904
struct n_hdlc_buf * buf )
893
905
{
894
906
unsigned long flags ;
895
- spin_lock_irqsave (& list -> spinlock ,flags );
896
-
897
- buf -> link = NULL ;
898
- if (list -> tail )
899
- list -> tail -> link = buf ;
900
- else
901
- list -> head = buf ;
902
- list -> tail = buf ;
903
- (list -> count )++ ;
904
-
905
- spin_unlock_irqrestore (& list -> spinlock ,flags );
906
-
907
+
908
+ spin_lock_irqsave (& buf_list -> spinlock , flags );
909
+
910
+ list_add_tail (& buf -> list_item , & buf_list -> list );
911
+ buf_list -> count ++ ;
912
+
913
+ spin_unlock_irqrestore (& buf_list -> spinlock , flags );
907
914
} /* end of n_hdlc_buf_put() */
908
915
909
916
/**
910
917
* n_hdlc_buf_get - remove and return an HDLC buffer from list
911
- * @list - pointer to HDLC buffer list
918
+ * @buf_list - pointer to HDLC buffer list
912
919
*
913
920
* Remove and return an HDLC buffer from the head of the specified HDLC buffer
914
921
* list.
915
922
* Returns a pointer to HDLC buffer if available, otherwise %NULL.
916
923
*/
917
- static struct n_hdlc_buf * n_hdlc_buf_get (struct n_hdlc_buf_list * list )
924
+ static struct n_hdlc_buf * n_hdlc_buf_get (struct n_hdlc_buf_list * buf_list )
918
925
{
919
926
unsigned long flags ;
920
927
struct n_hdlc_buf * buf ;
921
- spin_lock_irqsave (& list -> spinlock ,flags );
922
-
923
- buf = list -> head ;
928
+
929
+ spin_lock_irqsave (& buf_list -> spinlock , flags );
930
+
931
+ buf = list_first_entry_or_null (& buf_list -> list ,
932
+ struct n_hdlc_buf , list_item );
924
933
if (buf ) {
925
- list -> head = buf -> link ;
926
- ( list -> count ) -- ;
934
+ list_del ( & buf -> list_item ) ;
935
+ buf_list -> count -- ;
927
936
}
928
- if (!list -> head )
929
- list -> tail = NULL ;
930
-
931
- spin_unlock_irqrestore (& list -> spinlock ,flags );
937
+
938
+ spin_unlock_irqrestore (& buf_list -> spinlock , flags );
932
939
return buf ;
933
-
934
940
} /* end of n_hdlc_buf_get() */
935
941
936
942
static char hdlc_banner [] __initdata =
0 commit comments