Re: [PATCH 27/36] tty: synclinkmp: Mark never checked 'readval' as __always_unused

2020-11-05 Thread Paul Fulghum


Another candidate for removal is drivers/char/pcmcia/synclink_cs.c

Everything I said about synclink.c/synclinkmp.c is true of that as well: the 
hardware stopped being manufactured decades ago and is not available for 
testing. The possibility of these cards still being around/functional for use 
with the latest kernel is about zero.

If Lee Jones does wants to add that to his patch, great. If not then I can do 
so.

(I resent this message in plain text after it was rejected for HTML, sorry if 
anyone got a duplicate.)


> On Nov 5, 2020, at 3:27 AM, Lee Jones  wrote:
> 
> Will post the removal patches when my tests finish.


Re: [PATCH 27/36] tty: synclinkmp: Mark never checked 'readval' as __always_unused

2020-11-05 Thread Paul Fulghum



> On Nov 5, 2020, at 1:10 AM, Jiri Slaby  wrote:
> 
> OK, let the loop alone. I would bet a half a pig that noone is able to test 
> this driver. But one has to write this for someone to raise and admit they 
> are still using it. In fact, there are _4_ google replies to "Microgate 
> Corporation" "SyncLink Multiport Adapter" "lspci".



The hardware used with synclink.c and synclinkmp.c has not been manufactured 
for 15 years and was low volume. The chances of either driver still being in 
use is very low. Not even Microgate (me) has the ability to test either anymore 
(no hardware). I don’t know the policy about driver removal, but I think both 
could be removed without upsetting anyone.

synclink_gt.c is still in production and the driver still actively used.

If there are no objections to removing the the old drivers 
(synclink.c/synclink_mp.c) I could make a patch to do so tomorrow (it is 1:30am 
here now). Nothing eliminates niggling warnings like removing dead code.











Re: [PATCH] tty/n_hdlc: fix sleep in !TASK_RUNNING state warning

2019-01-04 Thread Paul Fulghum



> On Jan 4, 2019, at 2:23 AM, Tetsuo Handa  
> wrote:
> 
> But why not to clarify what are appropriate sanity checks?
> ...
> want a cleanup for scripts/checkpatch.pl .


These are good goals. I avoid purely cosmetic patches. I do not object to 
cosmetic patches from others that do not change behavior.

The checks that concern you deal with changing tty line disciplines. Dealing 
with line discipline changes has been an ongoing issue since n_hdlc was derived 
from other line disciplines 20 years ago, with major overhauls along the way. 
It is complex: driver layers shifting during operation while dealing properly 
with opens, closes, hangups, and sleeping operations. Patches have been added 
to the latest unreleased kernel to address line discipline changes, it is still 
evolving.

Why are the existing line discipline checks in n_hdlc where they are? Becasue 
that’s how they evolved from where they started to accomodate these changes. 
There are not many and their function is known: has the line discipline changed 
at that point? I know that is not satisfying but coming up with a definitive 
comment saying a check is absolutely required in one place and not in another 
requires more insight into the long history of a moving target than I have. 
Without that insight I would not alter existing checks in code that is not 
causing problems.

Re: [PATCH] tty/n_hdlc: fix sleep in !TASK_RUNNING state warning

2019-01-03 Thread Paul Fulghum



> On Jan 3, 2019, at 3:32 AM, Tetsuo Handa  
> wrote:
> 
> On 2019/01/03 18:09, Jiri Slaby wrote:
>> On 02. 01. 19, 16:04, Tetsuo Handa wrote:
>>> +   if (wait_event_interruptible(tty->read_wait,
>>> +(ret = -EIO, test_bit(TTY_OTHER_CLOSED, &tty->flags)) ||
>>> +(ret = 0, tty_hung_up_p(file)) ||
>>> +(rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list)) != NULL ||
>>> +(ret = -EAGAIN, tty_io_nonblock(tty, file
>>> +   return -EINTR;
>> 
>> Oh, that looks really ugly. Could you move all this to a function
>> returning a bool and taking &ret and &rbuf as parameters?
>> 
> 
> OK. Something like this?


I agree with Jiri that placing all the conditional logic in a single expression 
is difficult to read.

But exchanging that many locals with a separate function defeats the original 
purpose of
simplifying code and this implementation changes the logic (write no
longer checks for line discipline changing under it during wait).

Converting to wait_event_interruptible where possible is a good goal but this 
instance
may be better left alone. The current structure mirrors the existing n_tty line 
discipline.




Re: [PATCH] tty/n_hdlc: fix sleep in !TASK_RUNNING state warning

2019-01-02 Thread Paul Fulghum



> On Jan 2, 2019, at 7:04 AM, Tetsuo Handa  
> wrote:
> 
> On 2019/01/01 12:11, Paul Fulghum wrote:
>> NAK to this patch. It causes lost wakeups in both read and write paths.
>> 
>> The write path does not need changing.
>> 
>> The read path can be fixed by setting current to TASK_RUNNING at the top of 
>> the if (rbuf) block
>> so the warning is not triggered by copy_to_user(). If this block runs the 
>> condition is satisfied
>> and it breaks out of the polling loop where it is already being set to 
>> TASK_RUNNING and removed
>> from the wait queue. This particular path just needs to account for the 
>> copy_to_user which occurs
>> before breaking out.
>> 
>> I’ll make a patch to do this when I have the ability to test it in a day or 
>> two.
>> 
> 
> OK. Then, any chance it is rewritten using wait_event_interruptible() in 
> order to reduce lines?
> ( wait_event_interruptible() automatically calls might_sleep(), but is it 
> acceptable for you? )
> 

This looks good to me. I applied it and tested blocking (sleep/no sleep) and 
non-blocking (success/EAGAIN) paths for both read and write.

[PATCH] tty/n_hdlc: fix __might_sleep warning

2019-01-01 Thread Paul Fulghum
Fix __might_sleep warning in tty/n_hdlc.c read due to copy_to_user call while 
current is TASK_INTERRUPTIBLE.
This is a false positive since the code path does not depend on current state 
remaining TASK_INTERRUPTIBLE.
The loop breaks out and sets TASK_RUNNING after calling copy_to_user. 
This patch supresses the warning by setting TASK_RUNNING before calling 
copy_to_user.

[1] 
https://syzkaller.appspot.com/bug?id=17d5de7f1fcab794cb8c40032f893f52de899324

Signed-off-by: Paul Fulghum 
Reported-by: syzbot 
Cc: Greg Kroah-Hartman 
Cc: Tetsuo Handa 
Cc: Arnd Bergmann 
Cc: Alan Cox 
—
--- a/drivers/tty/n_hdlc.c  2018-12-23 15:55:59.0 -0800
+++ b/drivers/tty/n_hdlc.c  2019-01-01 11:44:47.148153954 -0800
@@ -597,6 +597,7 @@ static ssize_t n_hdlc_tty_read(struct tt
/* too large for caller's buffer */
ret = -EOVERFLOW;
} else {
+   __set_current_state(TASK_RUNNING);
if (copy_to_user(buf, rbuf->buf, rbuf->count))
ret = -EFAULT;
else

 

Re: [PATCH] tty/n_hdlc: fix sleep in !TASK_RUNNING state warning

2018-12-31 Thread Paul Fulghum



On Dec 31, 2018, at 7:11 PM, Paul Fulghum  wrote:

NAK to this patch. It causes lost wakeups in both read and write paths.

The write path does not need changing.

The read path can be fixed by setting current to TASK_RUNNING at the top of the 
if (rbuf) block so the warning is not triggered by copy_to_user(). If this 
block runs the condition is satisfied and it breaks out of the polling loop 
where it is already being set to TASK_RUNNING and removed from the wait queue. 
This particular path just needs to account for the copy_to_user which occurs 
before breaking out.

I’ll make a patch to do this when I have the ability to test it in a day or two.


> On Dec 29, 2018, at 3:48 AM, Tetsuo Handa 
>  wrote:
> 
> syzbot is hitting __might_sleep() warning [1], for commit 1035b63d3c6fc34a
> ("n_hdlc: fix read and write locking") changed to set TASK_INTERRUPTIBLE
> state before calling copy_to_user(). Let's set TASK_INTERRUPTIBLE state
> immediately before calling schedule().
> 
> [1] 
> https://syzkaller.appspot.com/bug?id=17d5de7f1fcab794cb8c40032f893f52de899324
> 
> Signed-off-by: Tetsuo Handa 
> Reported-by: syzbot 
> Cc: Paul Fulghum 
> Cc: Arnd Bergmann 
> Cc: Alan Cox 
> ---
> drivers/tty/n_hdlc.c | 7 +++
> 1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
> index dabb391..7835489 100644
> --- a/drivers/tty/n_hdlc.c
> +++ b/drivers/tty/n_hdlc.c
> @@ -589,8 +589,6 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, 
> struct file *file,
>   if (tty_hung_up_p(file))
>   break;
> 
> - set_current_state(TASK_INTERRUPTIBLE);
> -
>   rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
>   if (rbuf) {
>   if (rbuf->count > nr) {
> @@ -617,6 +615,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, 
> struct file *file,
>   break;
>   }
> 
> + set_current_state(TASK_INTERRUPTIBLE);
>   schedule();
> 
>   if (signal_pending(current)) {
> @@ -673,8 +672,6 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, 
> struct file *file,
>   add_wait_queue(&tty->write_wait, &wait);
> 
>   for (;;) {
> - set_current_state(TASK_INTERRUPTIBLE);
> - 
>   tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
>   if (tbuf)
>   break;
> @@ -683,6 +680,8 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, 
> struct file *file,
>   error = -EAGAIN;
>   break;
>   }
> +
> + set_current_state(TASK_INTERRUPTIBLE);
>   schedule();
>   
>   n_hdlc = tty2n_hdlc (tty);
> -- 
> 1.8.3.1
> 
> 

--
Paul Fulghum
MicroGate Systems, Ltd.
=Customer Driven, by Design=
(512) 345-7791 x102 (Voice)
(512) 343-9046 (Fax)
Central Time Zone (GMT -5h)
www.microgate.com



[PATCH] synclink fix ldisc buffer argument

2012-12-03 Thread Paul Fulghum
Fix call to line discipline receive_buf by synclink drivers.
Dummy flag buffer argument is ignored by N_HDLC line discipline but might
be of insufficient size if accessed by a different line discipline
selected by mistake. flag buffer allocation now matches max size of data
buffer. Unused char_buf buffers are removed.

Signed-off-by: Paul Fulghum 

--- a/drivers/char/pcmcia/synclink_cs.c 2012-11-26 14:15:45.0 -0600
+++ b/drivers/char/pcmcia/synclink_cs.c 2012-12-03 10:51:40.0 -0600
@@ -210,7 +210,7 @@ typedef struct _mgslpc_info {
char testing_irq;
unsigned int init_error;/* startup error (DIAGS)*/
 
-   char flag_buf[MAX_ASYNC_BUFFER_SIZE];
+   char *flag_buf;
bool drop_rts_on_tx_done;
 
struct  _input_signal_eventsinput_signal_events;
@@ -2666,6 +2666,14 @@ static int rx_alloc_buffers(MGSLPC_INFO 
if (info->rx_buf == NULL)
return -ENOMEM;
 
+   /* unused flag buffer to satisfy receive_buf calling interface */
+   info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL);
+   if (!info->flag_buf) {
+   kfree(info->rx_buf);
+   info->rx_buf = NULL;
+   return -ENOMEM;
+   }
+   
rx_reset_buffers(info);
return 0;
 }
@@ -2674,6 +2682,8 @@ static void rx_free_buffers(MGSLPC_INFO 
 {
kfree(info->rx_buf);
info->rx_buf = NULL;
+   kfree(info->flag_buf);
+   info->flag_buf = NULL;
 }
 
 static int claim_resources(MGSLPC_INFO *info)
--- a/drivers/tty/synclink.c2012-11-26 14:15:45.0 -0600
+++ b/drivers/tty/synclink.c2012-12-03 10:51:56.0 -0600
@@ -291,8 +291,7 @@ struct mgsl_struct {
bool lcr_mem_requested;
 
u32 misc_ctrl_value;
-   char flag_buf[MAX_ASYNC_BUFFER_SIZE];
-   char char_buf[MAX_ASYNC_BUFFER_SIZE];   
+   char *flag_buf;
bool drop_rts_on_tx_done;
 
bool loopmode_insert_requested;
@@ -3891,7 +3890,13 @@ static int mgsl_alloc_intermediate_rxbuf
info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL 
| GFP_DMA);
if ( info->intermediate_rxbuffer == NULL )
return -ENOMEM;
-
+   /* unused flag buffer to satisfy receive_buf calling interface */
+   info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL);
+   if (!info->flag_buf) {
+   kfree(info->intermediate_rxbuffer);
+   info->intermediate_rxbuffer = NULL;
+   return -ENOMEM;
+   }
return 0;
 
 }  /* end of mgsl_alloc_intermediate_rxbuffer_memory() */
@@ -3910,6 +3915,8 @@ static void mgsl_free_intermediate_rxbuf
 {
kfree(info->intermediate_rxbuffer);
info->intermediate_rxbuffer = NULL;
+   kfree(info->flag_buf);
+   info->flag_buf = NULL;
 
 }  /* end of mgsl_free_intermediate_rxbuffer_memory() */
 
--- a/drivers/tty/synclinkmp.c  2012-11-26 14:15:45.0 -0600
+++ b/drivers/tty/synclinkmp.c  2012-12-03 10:52:09.0 -0600
@@ -262,8 +262,7 @@ typedef struct _synclinkmp_info {
bool sca_statctrl_requested;
 
u32 misc_ctrl_value;
-   char flag_buf[MAX_ASYNC_BUFFER_SIZE];
-   char char_buf[MAX_ASYNC_BUFFER_SIZE];
+   char *flag_buf;
bool drop_rts_on_tx_done;
 
struct  _input_signal_eventsinput_signal_events;
@@ -3544,6 +3543,13 @@ static int alloc_tmp_rx_buf(SLMP_INFO *i
info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL);
if (info->tmp_rx_buf == NULL)
return -ENOMEM;
+   /* unused flag buffer to satisfy receive_buf calling interface */
+   info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL);
+   if (!info->flag_buf) {
+   kfree(info->tmp_rx_buf);
+   info->tmp_rx_buf = NULL;
+   return -ENOMEM;
+   }
return 0;
 }
 
@@ -3551,6 +3557,8 @@ static void free_tmp_rx_buf(SLMP_INFO *i
 {
kfree(info->tmp_rx_buf);
info->tmp_rx_buf = NULL;
+   kfree(info->flag_buf);
+   info->flag_buf = NULL;
 }
 
 static int claim_resources(SLMP_INFO *info)
--- a/drivers/tty/synclink_gt.c 2012-11-26 14:15:45.0 -0600
+++ b/drivers/tty/synclink_gt.c 2012-12-03 11:00:15.0 -0600
@@ -317,8 +317,7 @@ struct slgt_info {
unsigned char *tx_buf;
int tx_count;
 
-   char flag_buf[MAX_ASYNC_BUFFER_SIZE];
-   char char_buf[MAX_ASYNC_BUFFER_SIZE];
+   char *flag_buf;
bool drop_rts_on_tx_done;
struct  _input_signal_eventsinput_signal_events;
 
@@ -3355,11 +3354,24 @@ static int block_til_ready(struct tty_st
return retval;
 }
 
+/*
+ * allocate buffers used for calling line discipline receive_buf
+ * directly in synchronous mode
+ * note: add 5 bytes to max frame size to allow appending
+ * 32-bit CRC and status byte when configured to 

Re: [PATCH] synclink fix ldisc buffer argument

2012-12-03 Thread Paul Fulghum
On 12/2/2012 8:20 PM, Chen Gang wrote:
> pardon (I am just learning)
>   does 65535 mean HDLC_MAX_FRAME_SIZE ?
>   why do we need info->max_frame_size >= 4096 ?
> in drivers/tty/synclink_gt.c:
> 3550 if (info->max_frame_size < 4096)
> 3551 info->max_frame_size = 4096;
> 3552 else if (info->max_frame_size > 65535)
> 3553 info->max_frame_size = 65535;
> 3554
>  ...
> 3603 info->max_frame_size = 4096;

The hardware can send and receive HDLC frames up to
64K in size. The driver defaults to 4K max frame size
to save buffer space for the common case
(line 3603 in alloc_dev()).

The module parameter max_frame_size can override the default
in add_device() (lines 3550-3554 are from add_device()
range checking the module parameter)

> if possible:
>   can we move the relative comments (which are inside function) to the
> location just above ldisc_receive_buf ?

The added comment from my first patch described the reuse
of the data buffer as the flag buffer. Alan prefers to use
a zero initialized dummy buffer for the flag buffer argument.
Doing it that way, the comment is not needed.

-- 
Paul Fulghum
MicroGate Systems, Ltd.
=Customer Driven, by Design=
(800)444-1982 (US Sales)
(512)345-7791 x102 (Direct)
(512)343-9046 (Fax)
Central Time Zone (GMT -6h)
www.microgate.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] synclink fix ldisc buffer argument

2012-11-30 Thread Paul Fulghum
Fix call to line discipline receive_buf by synclink drivers.
Dummy flag buffer argument is ignored by N_HDLC line discipline but might
be of insufficient size if accessed by a different line discipline
selected by mistake. Calls are changed to use data buffer argument for
both data and flag buffer so valid memory is provided if the wrong
line discipline is used. Unused char_buf and flag_buf are removed.

Signed-off-by: Paul Fulghum 


--- a/drivers/char/pcmcia/synclink_cs.c 2012-11-26 14:15:45.0 -0600
+++ b/drivers/char/pcmcia/synclink_cs.c 2012-11-30 12:50:23.0 -0600
@@ -210,7 +210,6 @@ typedef struct _mgslpc_info {
char testing_irq;
unsigned int init_error;/* startup error (DIAGS)*/
 
-   char flag_buf[MAX_ASYNC_BUFFER_SIZE];
bool drop_rts_on_tx_done;
 
struct  _input_signal_eventsinput_signal_events;
@@ -3707,7 +3706,16 @@ static bool rx_get_frame(MGSLPC_INFO *in
hdlcdev_rx(info, buf->data, framesize);
else
 #endif
-   ldisc_receive_buf(tty, buf->data, 
info->flag_buf, framesize);
+   {
+   /*
+* Call N_HDLC line discipline directly to 
maintain
+* frame boundaries. Reuse the data buffer 
argument for the
+* flag buffer argument. The flag buffer is 
ignored by N_HDLC.
+* If a different line discipline is selected 
by mistake it
+* will have valid memory for both arguments.
+*/
+   ldisc_receive_buf(tty, buf->data, buf->data, 
framesize);
+   }
}
}
 
--- a/drivers/tty/synclink.c2012-11-26 14:15:45.0 -0600
+++ b/drivers/tty/synclink.c2012-11-30 12:59:29.0 -0600
@@ -291,8 +291,6 @@ struct mgsl_struct {
bool lcr_mem_requested;
 
u32 misc_ctrl_value;
-   char flag_buf[MAX_ASYNC_BUFFER_SIZE];
-   char char_buf[MAX_ASYNC_BUFFER_SIZE];   
bool drop_rts_on_tx_done;
 
bool loopmode_insert_requested;
@@ -6661,7 +6659,17 @@ static bool mgsl_get_rx_frame(struct mgs

hdlcdev_rx(info,info->intermediate_rxbuffer,framesize);
else
 #endif
-   ldisc_receive_buf(tty, 
info->intermediate_rxbuffer, info->flag_buf, framesize);
+   {
+   /*
+* Call N_HDLC line discipline directly to 
maintain
+* frame boundaries. Reuse the data buffer 
argument for the
+* flag buffer argument. The flag buffer is 
ignored by N_HDLC.
+* If a different line discipline is selected 
by mistake it
+* will have valid memory for both arguments.
+*/
+   ldisc_receive_buf(tty, 
info->intermediate_rxbuffer,
+ info->intermediate_rxbuffer, 
framesize);
+   }
}
}
/* Free the buffers used by this frame. */
@@ -6833,7 +6841,15 @@ static bool mgsl_get_raw_rx_frame(struct
memcpy( info->intermediate_rxbuffer, 
pBufEntry->virt_addr, framesize);
info->icount.rxok++;
 
-   ldisc_receive_buf(tty, info->intermediate_rxbuffer, 
info->flag_buf, framesize);
+   /*
+* Call N_HDLC line discipline directly to maintain
+* block boundaries. Reuse the data buffer argument for 
the
+* flag buffer argument. The flag buffer is ignored by 
N_HDLC.
+* If a different line discipline is selected by 
mistake it
+* will have valid memory for both arguments.
+*/
+   ldisc_receive_buf(tty, info->intermediate_rxbuffer,
+  info->intermediate_rxbuffer, 
framesize);
}
 
/* Free the buffers used by this frame. */
--- a/drivers/tty/synclinkmp.c  2012-11-26 14:15:45.0 -0600
+++ b/drivers/tty/synclinkmp.c  2012-11-30 13:01:36.0 -0600
@@ -262,8 +262,6 @@ typedef struct _synclinkmp_info {
bool sca_statctrl_requested;
 
u32 misc_ctrl_value;
-   char flag_buf[MAX_ASYNC_BUFFER_SIZE];
-   char char_buf[MAX_ASYNC_BUFFER_SIZE];
bool drop_rts_on_tx_done;
 
struct  _input_signal_eventsinput_signal_events;
@@ -4979,8 +4977,17 @@ CheckAgain:
hdlcdev_rx(info,info->tmp_r

Re: [Suggestion] drivers/tty: drivers/char/: for MAX_ASYNC_BUFFER_SIZE

2012-11-30 Thread Paul Fulghum
On 11/29/2012 8:52 PM, Chen Gang wrote:
> 于 2012年11月30日 02:32, Greg KH 写道:
>> On Thu, Nov 29, 2012 at 01:57:59PM +0800, Chen Gang wrote:
>>>> And, I really don't understand here, why do you want to change this?
>>>> What is it going to change?  And why?
>>>
>>> Why:
>>>   for the context MGSLPC_INFO *info in drivers/char/pcmcia/synclink_cs.c
>>> info->max_frame_size can be the value between 4096 .. 65535 (can be
>>> set by its module input parameter)
>>> info->flag_buf length is 4096 (MAX_ASYNC_BUFFER_SIZE)
>>>   in function rx_get_frame
>>> the framesize is limit by info->max_frame_size, but may still be
>>> larger that 4096.
>>> when call function ldisc_receive_buf, info->flag_buf is equal to
>>> 4096, but framesize can be more than 4096. it will cause memory over flow.

The confusion centers on calling the line discipline receive_buf
function with a data buffer larger than the flag buffer.

The synclink drivers support asynchronous and synchronous (HDLC)
serial communications.

In asynchronous mode, the tty flip buffer is used to feed
data to the line discipline. In this mode, the above argument
does not apply. The receive_buf function is not called directly.

In synchronous mode, the driver calls the line discipline
receive_buf function directly to feed one HDLC frame
of data per call. Maintaining frame boundaries is needed
in this mode. This is done only with the N_HDLC line
discipline which expects this format and ignores the flag buffer.
The flag buffer passed is just a place holder to meet the
calling conventions of the line discipline receive_buf function.

The only danger is if:
1. driver is configured for synchronous mode
2. driver is configured for frames > 4K
3. line discipline other than N_HDLC is selected

In this case the line discipline might try to access
beyond the end of the flag buffer. This is a non-functional
configuration that would not occur on purpose.

Increasing the flag buffer size would prevent a problem
in this degenerate case of purposeful misconfiguration.
This would be at the expense of larger allocations that are
not used.

I think the correct fix is for me to change the direct
calls to pass the same buffer for both data and flag and
add a comment describing the fact the flag buffer is ignored
when using N_HDLC. That way a misconfigured setup won't
cause problems and no unneeded allocations are made.

My suggestion is to leave it as is for now until I can make
those changes. I admit the current code is ugly enough to
cause confusion (sorry Chen Gang), but I don't see any immediate danger.

-- 
Paul Fulghum
MicroGate Systems, Ltd.
=Customer Driven, by Design=
(800)444-1982 (US Sales)
(512)345-7791 x102 (Direct)
(512)343-9046 (Fax)
Central Time Zone (GMT -6h)
www.microgate.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial port regression caused by "Char: tty_ioctl, use wait_event_interruptible_timeout" patch

2008-02-05 Thread Paul Fulghum

Jiri Slaby wrote:

It should be fixed already as of
git-describe db99247a
v2.6.24-rc6-95-gdb99247

So since 2.6.24-rc7.

Maybe we should consider the fix for 2.6.23 too.


Whoops, I missed that.
Problem solved :-)

Thanks,
Paul
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial port regression caused by "Char: tty_ioctl, use wait_event_interruptible_timeout" patch

2008-02-05 Thread Paul Fulghum

Rick Warner wrote:
This modification solved my problem.  Will this change go into mainline, or 
will we need to maintain our own branch of the kernel to keep this working?


It should be accepted into mainline as it restores
the original behavior. I'll put together a patch
submission tomorrow unless Jiri beats me to it.

Thanks,
Paul

--
Paul Fulghum
Microgate Systems, Ltd.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial port regression caused by "Char: tty_ioctl, use wait_event_interruptible_timeout" patch

2008-02-05 Thread Paul Fulghum

Paul Fulghum wrote:

Instead of reverting the patch can you try modifying
this part of the patch:

+   if (wait_event_interruptible_timeout(tty->write_wait,
+   !tty->driver->chars_in_buffer(tty), timeout))
+   return;

by changing it to:

+   if (wait_event_interruptible_timeout(tty->write_wait,
+   !tty->driver->chars_in_buffer(tty), timeout) < 0)
+   return;

It looks like the patch changed the behavior of
tty_wait_until_sent by not calling the driver
specific wait_until_sent if a timeout occurs.


I mispoke, the patch changed the behavior by not
calling the driver specific wait_until_sent if
the condition is true.

Original behavior:
call driver->wait_until_sent() on
timeout or true condition
(skip for signal)

Patch behavior:
call driver->wait_until_sent() only
on timeout (rc == 0)
(skip for signal or true)

By modifying the patch as described above,
the original behavior is restored.

--
Paul Fulghum
Microgate Systems, Ltd.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial port regression caused by "Char: tty_ioctl, use wait_event_interruptible_timeout" patch

2008-02-05 Thread Paul Fulghum

Rick Warner wrote:
I narrowed down the problem doing a binary search on git snapshots between .22 
and .23, and found the breakage between git6 and git7.  Further isolating it 
found the patch mentioned in the subject to be the cause.  I reversed the 
patch in the .23 source and it now works properly.


Should the code be reverted back as I did, or is there something I should 
change in our userspace code that reads from the serial port to correct it 
instead?


Instead of reverting the patch can you try modifying
this part of the patch:

+   if (wait_event_interruptible_timeout(tty->write_wait,
+   !tty->driver->chars_in_buffer(tty), timeout))
+   return;

by changing it to:

+   if (wait_event_interruptible_timeout(tty->write_wait,
+   !tty->driver->chars_in_buffer(tty), timeout) < 0)
+   return;

It looks like the patch changed the behavior of
tty_wait_until_sent by not calling the driver
specific wait_until_sent if a timeout occurs.

--
Paul Fulghum
Microgate Systems, Ltd.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] synclink_gt fix missed serial input signal changes

2008-01-28 Thread Paul Fulghum
Fix missed serial input signal changes caused by rereading the
serial status register during interrupt processing. Now
processing is performed on original status register value.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/drivers/char/synclink_gt.c2008-01-24 16:58:37.0 -0600
+++ b/drivers/char/synclink_gt.c2008-01-28 12:22:22.0 -0600
@@ -2040,37 +2040,41 @@ static void bh_transmit(struct slgt_info
tty_wakeup(tty);
 }
 
-static void dsr_change(struct slgt_info *info)
+static void dsr_change(struct slgt_info *info, unsigned short status)
 {
-   get_signals(info);
+   if (status & BIT3) {
+   info->signals |= SerialSignal_DSR;
+   info->input_signal_events.dsr_up++;
+   } else {
+   info->signals &= ~SerialSignal_DSR;
+   info->input_signal_events.dsr_down++;
+   }
DBGISR(("dsr_change %s signals=%04X\n", info->device_name, 
info->signals));
if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_DSR);
return;
}
info->icount.dsr++;
-   if (info->signals & SerialSignal_DSR)
-   info->input_signal_events.dsr_up++;
-   else
-   info->input_signal_events.dsr_down++;
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
 }
 
-static void cts_change(struct slgt_info *info)
+static void cts_change(struct slgt_info *info, unsigned short status)
 {
-   get_signals(info);
+   if (status & BIT2) {
+   info->signals |= SerialSignal_CTS;
+   info->input_signal_events.cts_up++;
+   } else {
+   info->signals &= ~SerialSignal_CTS;
+   info->input_signal_events.cts_down++;
+   }
DBGISR(("cts_change %s signals=%04X\n", info->device_name, 
info->signals));
if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_CTS);
return;
}
info->icount.cts++;
-   if (info->signals & SerialSignal_CTS)
-   info->input_signal_events.cts_up++;
-   else
-   info->input_signal_events.cts_down++;
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
@@ -2091,20 +2095,21 @@ static void cts_change(struct slgt_info 
}
 }
 
-static void dcd_change(struct slgt_info *info)
+static void dcd_change(struct slgt_info *info, unsigned short status)
 {
-   get_signals(info);
+   if (status & BIT1) {
+   info->signals |= SerialSignal_DCD;
+   info->input_signal_events.dcd_up++;
+   } else {
+   info->signals &= ~SerialSignal_DCD;
+   info->input_signal_events.dcd_down++;
+   }
DBGISR(("dcd_change %s signals=%04X\n", info->device_name, 
info->signals));
if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_DCD);
return;
}
info->icount.dcd++;
-   if (info->signals & SerialSignal_DCD) {
-   info->input_signal_events.dcd_up++;
-   } else {
-   info->input_signal_events.dcd_down++;
-   }
 #if SYNCLINK_GENERIC_HDLC
if (info->netcount) {
if (info->signals & SerialSignal_DCD)
@@ -2127,20 +2132,21 @@ static void dcd_change(struct slgt_info 
}
 }
 
-static void ri_change(struct slgt_info *info)
+static void ri_change(struct slgt_info *info, unsigned short status)
 {
-   get_signals(info);
+   if (status & BIT0) {
+   info->signals |= SerialSignal_RI;
+   info->input_signal_events.ri_up++;
+   } else {
+   info->signals &= ~SerialSignal_RI;
+   info->input_signal_events.ri_down++;
+   }
DBGISR(("ri_change %s signals=%04X\n", info->device_name, 
info->signals));
if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
slgt_irq_off(info, IRQ_RI);
return;
}
-   info->icount.dcd++;
-   if (info->signals & SerialSignal_RI) {
-   info->input_signal_events.ri_up++;
-   } else {
-   info->input_signal_events.ri_down++;
-   }
+   info->icount.rng++;
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
info->pending_bh |= BH_STATUS;
@@ -2191,13 +2197,13 @@ static void isr_serial(struct slgt_info 
}
 
if (status & IRQ_DSR)
-   

Re: [PATCH 2/2] Char: tty, add tty_schedule_wakeup

2007-11-01 Thread Paul Fulghum

Jiri Slaby wrote:

+ * Functionally the same as tty_wakeup, but it can be used in hot
+ * paths. since the wakeup is scheduled and done in the future.



I'm not familiar with the terminology 'hot paths',
what do you mean by that?

Do you have an example of where you intend to
use this new facility? The patch does not include
such an example so it is difficult for me to see
why you are adding this function.

--
Paul Fulghum
Microgate Systems, Ltd
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] synclink_gt fix module reference

2007-08-14 Thread Paul Fulghum
Get module reference on open() by generic HDLC
to prevent module from unloading while interface
is active.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/drivers/char/synclink_gt.c2007-07-08 18:32:17.0 -0500
+++ b/drivers/char/synclink_gt.c2007-08-14 12:27:50.0 -0500
@@ -1570,6 +1570,9 @@ static int hdlcdev_open(struct net_devic
int rc;
unsigned long flags;
 
+   if (!try_module_get(THIS_MODULE))
+   return -EBUSY;
+
DBGINFO(("%s hdlcdev_open\n", dev->name));
 
/* generic HDLC layer open processing */
@@ -1639,6 +1642,7 @@ static int hdlcdev_close(struct net_devi
info->netcount=0;
spin_unlock_irqrestore(&info->netlock, flags);
 
+   module_put(THIS_MODULE);
return 0;
 }
 


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 55] drivers/char/n_hdlc.c: kmalloc + memset conversion to kzalloc

2007-08-08 Thread Paul Fulghum

Krzysztof Halasa wrote:

Mariusz Kozlowski <[EMAIL PROTECTED]> writes:


Signed-off-by: Mariusz Kozlowski <[EMAIL PROTECTED]>

 drivers/char/n_hdlc.c | 27451 -> 27413 (-38 bytes)
 drivers/char/n_hdlc.o | 107068 -> 107088 (+20 bytes)


BTW: drivers/char/n_hdlc is a very different thing than these
in drivers/net/wan/ and I have no connection with it. Not sure
who is responsible, if anyone.


I am, my email is at the top of n_hdlc.c but there
is no maintainers entry.

--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Serial buffer memory leak

2007-08-08 Thread Paul Fulghum
On Wed, 2007-08-08 at 16:32 +0100, Alan Cox wrote:

> Ok try this for size folks. Use tty->flags bits for the flush status.
> Wait for the flag to clear again before returning
> Fix the doc error noted
> Fix flush of empty queue leaving stale flushpending
> 
> 
> Signed-off-by: Alan Cox <[EMAIL PROTECTED]>

It looks good and clean.

I compiled and tested the patch with interleaved
tcflush() and read() calls, allowing random amounts
of receive data to accumulate between each call.

Acked-by: Paul Fulghum <[EMAIL PROTECTED]>

Thanks,
Paul

--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Serial buffer memory leak

2007-08-08 Thread Paul Fulghum
On Wed, 2007-08-08 at 16:28 +0200, Laurent Pinchart wrote:

> The patch fixes the problem (at least under the test conditions that lead me 
> to discover it in the first place). Thanks Alan.

It works here also, but I see a problem.

By deferring the flush, ioctl(TCFLSH) returns immediately
even though there is possibly still receive data being fed
to the ldisc.

If this is followed immediately by a read() then the
application gets unexpected (stale) data defeating the
purpose of the TCFLSH.

tty_buffer_flush() needs to wait for buf.flushpending to clear.

 
--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Serial buffer memory leak

2007-08-08 Thread Paul Fulghum
On Wed, 2007-08-08 at 14:45 +0100, Alan Cox wrote:
> > I'm not familiar enough with the tty code to decide what the proper fix 
> > should 
> > be. I'll try to write a patch if someone could point me in the right 
> > direction.
> 
> Something like this perhaps ?

That looks good, a little better than the solution
I was first considering. I'm compiling now.

This was a nasty bug for me to introduce :-(
Good work in finding this Laurent.

--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Serial buffer memory leak

2007-08-08 Thread Paul Fulghum

Laurent Pinchart wrote:
Patch c5c34d4862e18ef07c1276d233507f540fb5a532 (tty: flush flip buffer on 
ldisc input queue flush) introduces a race condition which can lead to memory 
leaks.


The problem can be triggered when tcflush() is called when data are being 
pushed to the line discipline driver by flush_to_ldisc().


flush_to_ldisc() releases tty->buf.lock when calling the line discipline 
receive_buf function. At that poing tty_buffer_flush() kicks in and sets both 
tty->buf.head and tty->buf.tail to NULL. When flush_to_ldisc() finishes, it 
restores tty->buf.head but doesn't touch tty->buf.tail. This corrups the 
buffer queue, and the next call to tty_buffer_request_room() will allocate a 
new buffer and overwrite tty->buf.head. The previous buffer is then lost 
forever without being released.


Your description is clear enough, I'll make the patch.

Thanks,
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial flow control appears broken

2007-08-05 Thread Paul Fulghum
2.2.5 is using the same UART setup (trigger level of 8) as
the current code. There is no obvious difference in the
interrupt setup (same devices on the same interrupts).

So I have no helpful suggestions :-(

--
Paul


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial flow control appears broken

2007-08-04 Thread Paul Fulghum

Lee Howard wrote:
And in repeat tests it is quite evident that IDE disk activity is, 
indeed, at least part of the problem.  As IDE disk activity increases an 
increased amount of data coming in on the serial port goes missing.


Lee, you mentioned 2.2.x kernels did not exhibit this problem.

Was this on the same hardware you are currently testing?
Which 2.2.x version were you using?
Was the 2.2.x serial driver also identifying the UART as a 16550A?
Can you get /proc/interrupts output
from both the current setup and the 2.2.x setup?

It would be interesting to compare the interrupt
assignment and UART setup between the versions.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial flow control appears broken

2007-07-27 Thread Paul Fulghum
On Fri, 2007-07-27 at 13:48 -0700, Lee Howard wrote:
> Here's the output:
> 
> type: 4
> line: 1
> line: 760
>  irq: 3
>flags: 1358954688
>   xmit_fifo_size: 16
>   custom_divisor: 0
>baud_base: 115200

OK, the FIFO should be enabled.

What is known:

* The error is a hardware FIFO overrun.
  - observed message is in n_tty due to driver setting TTY_OVERRUN

* The RTS/CTS flow control is not involved
  - this is done only by the ldisc in response to buffer levels
  - you verified crtscts is set
  - you did not observed RTS change when 'overflow error' logged
  - you did observe RTS change when application stopped reading

So this seems to be a latency issue reading the receive
FIFO in the ISR. The current rx FIFO trigger level
should be 8 bytes (UART_FCR_R_TRIG_10) which gives the
ISR 694usec to get the data at 115200bps.

IIRC, in 2.2.X kernels this defaulted to 4 bytes
(TRIG_01) which gave a little more time to service the interrupt.

How does the data rate affect the frequency of the overrun errors?
Does 57600bps make them go away?

--
Paul




-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial flow control appears broken

2007-07-27 Thread Paul Fulghum

Tilman Schmidt wrote:

Could this be related?

http://lkml.org/lkml/2007/7/18/245

Quote:
"I've recently found (using 2.6.21.4) that configuring a serial ports
(ST16654) which use the 8250 driver using setserial results in the
UART's FIFOs being disabled (unless you specify autoconfig)."


That would make sense.

Lee's error is a hardware FIFO overrun which could occur
if the FIFO is being disabled as described in your
link (by trying to set the uart type with setserial).

Since the tty flow control is only triggered
by the line discipline in response to ldisc
buffer levels and not hardware FIFO overruns,
you would never see any flow control action
as reported by Lee.


--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial flow control appears broken

2007-07-27 Thread Paul Fulghum
OK, I see where TTY_OVERRUN is set:
include/linux/serial_core.h:uart_insert_char()


--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial flow control appears broken

2007-07-27 Thread Paul Fulghum
On Fri, 2007-07-27 at 12:22 -0600, Robert Hancock wrote:

> In this situation, though, it appears it's not the TTY buffers that are 
> filling but the UART's own buffer. I would think this must be caused by 
> some kind of interrupt latency that results in not draining the FIFO in 
> time.

You are right, this error is output when the character flag TTY_OVERRUN
is encountered by n_tty.c which should be set by the driver
in response to a hardware FIFO overrun (not an ldisc buffer overrun).

I can't see anyplace in serial_core.c or 8250.c that sets TTY_OVERRUN.

 
--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial flow control appears broken

2007-07-27 Thread Paul Fulghum
On Fri, 2007-07-27 at 12:22 -0600, Robert Hancock wrote:
> Maciej W. Rozycki wrote:
> >  The TTY line discipline driver could do that based on the amount of 
> > received data present in its buffer.  And it should if asked to (a brief 
> > look at drivers/char/n_tty.c reveals it does; obviously there may be a bug 
> 
> Really, where? In my look through the code I haven't found any mechanism 
> that would result in RTS being lowered based on TTY buffers filling up, 
> at least not in the 8250 case.

serial_core.c:uart_throttle()
serial_core.c:uart_unthrottle()

These are called by N_TTY in response to buffer levels.
 
--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Fwd: PROBLEM: serial port receive buffers not being flushed properly

2007-07-27 Thread Paul Fulghum
From: [EMAIL PROTECTED]
> [1.] PROBLEM: serial port receive buffers not being flushed properly
> [2.] After calling tcflush() or ioctl() with the TCFLSH argument,
> an ioctl() with the FIONREAD argument reports 0 bytes available
> for reading. However, a subsequent select() and read() of the port
> returns data. This problem is seen in 2.6.21.1 and 2.6.20,
> but is not seen in version 2.6.17.14. Other versions have
> not been tested.

There is receive buffering between the serial driver and
line discipline. The line discipline processes FIONREAD
and TCFLSH with regard to the line discipline receive
buffers but not the intermediate buffering.

In 2.6.17 the intermediate buffering pushed
receive data to the line discipline without
regard for tty->receive_room, so if the ldisc buffers
were full the data was lost.

In 2.6.18 the intermediate buffering was changed to
hold receive data until the line discipline could
accept it.

So in 2.6.17 all the extra data you sent was simply
discarded and flushing the ldisc buffers cleared all
of the receive data. Starting with 2.6.18, flushing the
ldisc buffers just allowed the intermediate buffering to
start feeding more data to the ldisc. This results in the
receive data you see after a TCFLSH.

Starting with 2.6.22 TCFLSH is processed by the intermediate
buffering as well as the ldisc to eliminate any remaining
receive data in the intermediate buffering.


--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] synclink_gt fix transmit DMA stall

2007-07-26 Thread Paul Fulghum
Fix transmit DMA stall when write() called in window after
previous transmit DMA completes but before previous serial
transmission completes.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/drivers/char/synclink_gt.c2007-07-08 18:32:17.0 -0500
+++ b/drivers/char/synclink_gt.c2007-07-26 10:39:56.0 -0500
@@ -1,5 +1,5 @@
 /*
- * $Id: synclink_gt.c,v 4.36 2006/08/28 20:47:14 paulkf Exp $
+ * $Id: synclink_gt.c,v 4.50 2007/07/25 19:29:25 paulkf Exp $
  *
  * Device driver for Microgate SyncLink GT serial adapters.
  *
@@ -93,7 +93,7 @@
  * module identification
  */
 static char *driver_name = "SyncLink GT";
-static char *driver_version  = "$Revision: 4.36 $";
+static char *driver_version  = "$Revision: 4.50 $";
 static char *tty_driver_name = "synclink_gt";
 static char *tty_dev_prefix  = "ttySLG";
 MODULE_LICENSE("GPL");
@@ -479,6 +479,7 @@ static void tx_set_idle(struct slgt_info
 static unsigned int free_tbuf_count(struct slgt_info *info);
 static void reset_tbufs(struct slgt_info *info);
 static void tdma_reset(struct slgt_info *info);
+static void tdma_start(struct slgt_info *info);
 static void tx_load(struct slgt_info *info, const char *buf, unsigned int 
count);
 
 static void get_signals(struct slgt_info *info);
@@ -912,6 +913,8 @@ start:
spin_lock_irqsave(&info->lock,flags);
if (!info->tx_active)
tx_start(info);
+   else
+   tdma_start(info);
spin_unlock_irqrestore(&info->lock,flags);
}
 
@@ -3880,44 +3883,58 @@ static void tx_start(struct slgt_info *i
slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE);
/* clear tx idle and underrun status bits */
wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + 
IRQ_TXUNDER));
-
-   if (!(rd_reg32(info, TDCSR) & BIT0)) {
-   /* tx DMA stopped, restart tx DMA */
-   tdma_reset(info);
-   /* set 1st descriptor address */
-   wr_reg32(info, TDDAR, 
info->tbufs[info->tbuf_start].pdesc);
-   switch(info->params.mode) {
-   case MGSL_MODE_RAW:
-   case MGSL_MODE_MONOSYNC:
-   case MGSL_MODE_BISYNC:
-   wr_reg32(info, TDCSR, BIT2 + BIT0); /* 
IRQ + DMA enable */
-   break;
-   default:
-   wr_reg32(info, TDCSR, BIT0); /* DMA 
enable */
-   }
-   }
-
if (info->params.mode == MGSL_MODE_HDLC)
mod_timer(&info->tx_timer, jiffies +
msecs_to_jiffies(5000));
} else {
-   tdma_reset(info);
-   /* set 1st descriptor address */
-   wr_reg32(info, TDDAR, 
info->tbufs[info->tbuf_start].pdesc);
-
slgt_irq_off(info, IRQ_TXDATA);
slgt_irq_on(info, IRQ_TXIDLE);
/* clear tx idle status bit */
wr_reg16(info, SSR, IRQ_TXIDLE);
-
-   /* enable tx DMA */
-   wr_reg32(info, TDCSR, BIT0);
}
-
+   tdma_start(info);
info->tx_active = 1;
}
 }
 
+/*
+ * start transmit DMA if inactive and there are unsent buffers
+ */
+static void tdma_start(struct slgt_info *info)
+{
+   unsigned int i;
+
+   if (rd_reg32(info, TDCSR) & BIT0)
+   return;
+
+   /* transmit DMA inactive, check for unsent buffers */
+   i = info->tbuf_start;
+   while (!desc_count(info->tbufs[i])) {
+   if (++i == info->tbuf_count)
+   i = 0;
+   if (i == info->tbuf_current)
+   return;
+   }
+   info->tbuf_start = i;
+
+   /* there are unsent buffers, start transmit DMA */
+
+   /* reset needed if previous error condition */
+   tdma_reset(info);
+
+   /* set 1st descriptor address */
+   wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
+   switch(info->params.mode) {
+   case MGSL_MODE_RAW:
+   case MGSL_MODE_MONOSYNC:
+   case MGSL_MODE_BISYNC:
+   wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
+   break;
+   default:
+   wr_reg32(info, TDCSR, BIT0); /* DMA enable */
+   }
+}
+
 static void tx_stop(struct slgt_info *info)
 {
unsigned short val;
@@ -4651,8 +4668,8 @@ static unsigned i

Re: [PATCH] Use tty_schedule in VT code.

2007-07-18 Thread Paul Fulghum

James Simmons wrote:

Done. I still smell a dead lock issue tho.


Yes, but it is an existing problem that was kicked
about with no real resolution.

No one can blame you for that! :-)

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-07-18 Thread Paul Fulghum
On Wed, 2007-07-18 at 19:17 +0100, James Simmons wrote:

> I have no problem leaving at one. Here is the new patch. I did address the 
> problem with tty_flip_buffer_push in this patch. It is possible for a 
> driver to call tty_flip_buffer_push within a interrupt context if they
> set the low_latency flag.
> --- a/drivers/char/tty_io.c
> +++ b/drivers/char/tty_io.c
> @@ -3647,11 +3647,7 @@ void tty_flip_buffer_push(struct tty_struct *tty)
>   if (tty->buf.tail != NULL)
>   tty->buf.tail->commit = tty->buf.tail->used;
>   spin_unlock_irqrestore(&tty->buf.lock, flags);
> -
> - if (tty->low_latency)
> - flush_to_ldisc(&tty->buf.work.work);
> - else
> - schedule_delayed_work(&tty->buf.work, 1);
> + schedule_delayed_work(&tty->buf.work, 1);
>  }

While I have no problem with this, it would be a significant
behavior change (more so than changing the initial delay to 0).

IIRC, when the serial_core dead lock was being debugged
(by Russel King with some Dell guy who reported it 1-2 years ago) 
this change was suggested and rejected because some callers
are not running at IRQ context and want to use low_latency.
In the end, I think they decided to leave the correct use of
low_latency WRT running in IRQ context to the caller.

It might be safest to drop this portion so you can get the
obvious part of the patch accepted (consolidating
the redundant xxx_schedule_flip functions).
 
--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-07-17 Thread Paul Fulghum

James Simmons wrote:

James Simmons, le Tue 17 Jul 2007 19:37:57 +0100, a écrit :

-   schedule_delayed_work(&t->buf.work, 0);

It was schedule_delayed_work(&t->buf.work, 1); in con_schedule_flip() ;
could that matter?


I did not detect any regressions.


The console behavior stays exactly the same as the patch
changes tty_schedule_flip to use the 0 delay. The change
to tty_schedule_flip() to use 0 delay also is OK. I had
looked at this when James originally posted this patch and found:

I looked further back and in the 2.4 kernels this scheduling
was done with the timer task queue (process receive data on
next timer tick).

I guess the schedule_delayed_work() with a time delay of 1
was the best approximation of the previous behavior.

There is no logical reason to delay the first attempt at
processing receive data so schedule_delayed_work() in
tty_schedule_flip() should be changed to 0 (as was the
case for con_schedule_flip).

The schedule_delayed_work in flush_to_ldisc() will continue
to use a delay of 1 if the ldisc can't accept more data.
This allows the user app and ldisc to catch up.

Subsequent calls to tty_schedule_flip won't affect
this 'back off' delay because once the work is scheduled
(with a delay of 1) new scheduling calls are ignored for
the same work structure.

I've been testing the change to 0 in tty_schedule_flip()
under various loads and data rates with no ill effects.


--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-07-17 Thread Paul Fulghum

James Simmons wrote:
The low_latency is used by the drivers in the case where its 
not in a interrupt context. Well we are trusting the drivers.

Now if it is true what you said then tty_flip_buffer_push has
a bug. Looking at several drivers including serial devices
they set the low_latency flag.


The generic serial driver (8250) is the one that was
dead locking when that code originally existed.
It was setting low_latency and calling from interrupt context.


And the initial schedule has no reason to add the extra delay.


So do you support a non delay work queue as well?


No, the delay work must be used for flush_to_ldisc()
so it makes no sense to define two different work queues
(one delayed and one not) for the same work.

I support your patch.

The current stuff works and your patch works.
With your patch, you actually reduce initial
latency for processing receive data.

Whichever way everyone else wants to go.


--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-07-17 Thread Paul Fulghum

Linus Torvalds wrote:

-   schedule_delayed_work(&tty->buf.work, 1);
+   schedule_delayed_work(&tty->buf.work, 0);


Is there any real reason for this?

I think that patch is bogus. Either it should stay at 1, or the whole work 
should be a non-scheduled one instead.


Do we really need to handle it asap for the console, or is it ok to wait 
for the next tick, like the regular tty case used to?


And if we need to handle it asap, why the "delayed"?


The scheduling is to move the processing out of interrupt context.
The receive data is often extracted from the hardware
at interrupt time and then queued for processing.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-07-17 Thread Paul Fulghum

James Simmons wrote:
Because sometimes you do want the delay. In other parts of the tty 
code we do delay. What should be done is 


Correct, so we must stick with the delayed work structure
which requires calling the delayed work function.


if (tty->low_latency)
flush_to_ldisc(&tty->buf.work.work);
else
schedule_delayed_work(&tty->buf.work, 1);

Is this acceptable to you?


That does not make sense to me.

If you are calling from interrupt context, you do not want
to call flush_to_ldisc() directly regardless of low_latency.
This used to be the way it was done and it ended up causing
deadlocks in just that situation.

And the initial schedule has no reason to add the extra delay.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] tty restore locked ioctl file op

2007-06-09 Thread Paul Fulghum

Björn Steinbrink wrote:

Sorry for the delay, your mails didn't make it into my inbox, and I
usually just mark threads on which I'm Cc'ed as read in my lkml mailbox,
thus I didn't notice it earlier. Any traces of the lost mails on your
side?


No clues on this end.


The patch works as expected, no Oops in sight. Regarding the
reproducability, it might be that it was easier to trigger on rc1. When
I retried today with rc4, I only got 2 Oopses in a minute, while the
first test had spitten out about 20 Oopses in 10 seconds (not sure if I
really had rc1 running back then, though).


I'm sure it's very timing dependent.
I'm confident with this fix.

Thanks for your help.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] tty restore locked ioctl file op

2007-06-08 Thread Paul Fulghum
Restore tty locked ioctl handler which was replaced with
an unlocked ioctl handler in hung_up_tty_fops by the patch:

commit e10cc1df1d2014f68a4bdcf73f6dd122c4561f94
Author: Paul Fulghum <[EMAIL PROTECTED]>
Date:   Thu May 10 22:22:50 2007 -0700

tty: add compat_ioctl

This was reported in:
[Bug 8473] New: Oops: 0010 [1] SMP

The bug is caused by switching to hung_up_tty_fops in do_tty_hangup.
An ioctl call can be waiting on BLK after testing for existence of
the locked ioctl handler in the normal tty fops, but before calling
the locked ioctl handler. If a hangup occurs at that point, the
locked ioctl fop is NULL and an oops occurs.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/drivers/char/tty_io.c 2007-06-08 14:26:10.0 -0500
+++ b/drivers/char/tty_io.c 2007-06-08 14:28:58.0 -0500
@@ -1173,8 +1173,14 @@ static unsigned int hung_up_tty_poll(str
return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
 }
 
-static long hung_up_tty_ioctl(struct file * file,
- unsigned int cmd, unsigned long arg)
+static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
+unsigned int cmd, unsigned long arg)
+{
+   return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
+}
+
+static long hung_up_tty_compat_ioctl(struct file * file,
+unsigned int cmd, unsigned long arg)
 {
return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
 }
@@ -1222,8 +1228,8 @@ static const struct file_operations hung
.read   = hung_up_tty_read,
.write  = hung_up_tty_write,
.poll   = hung_up_tty_poll,
-   .unlocked_ioctl = hung_up_tty_ioctl,
-   .compat_ioctl   = hung_up_tty_ioctl,
+   .ioctl  = hung_up_tty_ioctl,
+   .compat_ioctl   = hung_up_tty_compat_ioctl,
.release= tty_release,
 };
 



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Bug 8473] New: Oops: 0010 [1] SMP

2007-06-08 Thread Paul Fulghum
On Fri, 2007-06-08 at 10:16 -0500, Paul Fulghum wrote:
> On Fri, 2007-06-08 at 05:06 +0200, Björn Steinbrink wrote:
> > This is do_tty_hangup() exchanging the fops while we're waiting for the
> > lock. The new fops (hung_up_tty_fops) only have the unlocked variant and
> > thus we Oops our way.
...
> Here is a patch that restores the locked ioctl for hung_up_tty_ioctl.
> Can you try it and see if it removes your oops?

Unfortunately I can't get the timing right to trigger this,
but it is very clear the locked ioctl fop must not be
allowed to disappear like my original patch allows.

Andrew:

Would you prefer I resend the entire compat ioctl patch or
submit an incremental patch like in my message I'm quoting above?

-- 
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Bug 8473] New: Oops: 0010 [1] SMP

2007-06-08 Thread Paul Fulghum
On Fri, 2007-06-08 at 05:06 +0200, Björn Steinbrink wrote:
> This is do_tty_hangup() exchanging the fops while we're waiting for the
> lock. The new fops (hung_up_tty_fops) only have the unlocked variant and
> thus we Oops our way.
> 
> The following program reproduces it quite easily on a SMP box. I'm
> running it from X as root like this:
> while true; do xterm /path/to/program; done

I am unable to reproduce the oops on either i386 SMP or x86_64 SMP
using your test program. This is against plain 2.6.21 with only
my compat ioctl patch applied.

Here is a patch that restores the locked ioctl for hung_up_tty_ioctl.
Can you try it and see if it removes your oops?

--- a/drivers/char/tty_io.c 2007-06-08 10:07:39.0 -0500
+++ b/drivers/char/tty_io.c 2007-06-08 10:09:59.0 -0500
@@ -1150,8 +1150,14 @@ static unsigned int hung_up_tty_poll(str
return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
 }
 
-static long hung_up_tty_ioctl(struct file * file,
- unsigned int cmd, unsigned long arg)
+static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
+unsigned int cmd, unsigned long arg)
+{
+   return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
+}
+
+static long hung_up_tty_compat_ioctl(struct file * file,
+unsigned int cmd, unsigned long arg)
 {
return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
 }
@@ -1199,8 +1205,8 @@ static const struct file_operations hung
.read   = hung_up_tty_read,
.write  = hung_up_tty_write,
.poll   = hung_up_tty_poll,
-   .unlocked_ioctl = hung_up_tty_ioctl,
-   .compat_ioctl   = hung_up_tty_ioctl,
+   .ioctl  = hung_up_tty_ioctl,
+   .compat_ioctl   = hung_up_tty_compat_ioctl,
.release= tty_release,
 };
 


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Bug 8473] New: Oops: 0010 [1] SMP

2007-06-08 Thread Paul Fulghum
On Thu, 2007-06-07 at 20:16 -0700, Andrew Morton wrote:
> On Fri, 8 Jun 2007 05:06:29 +0200 Björn Steinbrink <[EMAIL PROTECTED]> wrote:
> > This is do_tty_hangup() exchanging the fops while we're waiting for the
> > lock. The new fops (hung_up_tty_fops) only have the unlocked variant and
> > thus we Oops our way.
> 
> ah, yes, that explains it, thanks.  Culprit:
> 
> commit e10cc1df1d2014f68a4bdcf73f6dd122c4561f94
> Author: Paul Fulghum <[EMAIL PROTECTED]>
> Date:   Thu May 10 22:22:50 2007 -0700
> 
> tty: add compat_ioctl
> 
> Add compat_ioctl method for tty code to allow processing of 32 bit ioctl
> calls on 64 bit systems by tty core, tty drivers, and line disciplines.

OK, the change of hung_up_tty_ioctl() from locked to unlocked
is not necessary for this patch. On the surface it seemed a clever
way of not needing two different functions to do the same simple:

return cmd == TIOCSPGRP ? -ENOTTY : -EIO;

which does not need any locking for its own sake. But clearly
the hangup behavior requires the locked version.

I'll redo the patch with hung_up_tty_ioctl remaining locked.

That will separate the compat ioctl stuff from this issue.

-- 
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/1] Char: n_hdlc, allow RESTARTSYS retval of tty write

2007-05-24 Thread Paul Fulghum
On Thu, 2007-05-24 at 14:28 +0200, Jiri Slaby wrote:
> n_hdlc, allow RESTARTSYS retval of tty write
> 
> Cc: Paul Fulghum <[EMAIL PROTECTED]>
> Signed-off-by: Jiri Slaby <[EMAIL PROTECTED]>
> 

Acked-by: Paul Fulghum <[EMAIL PROTECTED]>
 
--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-05-09 Thread Paul Fulghum

James Simmons wrote:

Great Here is the patch updated with the delay value set to zero.


Acked-by: Paul Fulghum <[EMAIL PROTECTED]>

You should submit this to
Andrew Morton <[EMAIL PROTECTED]>
so it can get into the mm tree.

--
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-05-09 Thread Paul Fulghum

Paul Fulghum wrote:

As the tty flip buffer code has evolved, that delay value of 1
was carried along. It may have had some historical purpose, but
I can't figure it out and it appears to have no use currently.


I looked further back and in the 2.4 kernels this scheduling
was done with the timer task queue (process receive data on
next timer tick).

I guess the schedule_delayed_work() with a time delay of 1
was the best approximation of the previous behavior.

There is no logical reason to delay the first attempt at
processing receive data so schedule_delayed_work() in
tty_schedule_flip() should be changed to 0 (as was the
case for con_schedule_flip).

The schedule_delayed_work in flush_to_ldisc() will continue
to use a delay of 1 if the ldisc can't accept more data.
This allows the user app and ldisc to catch up.

Subsequent calls to tty_schedule_flip won't affect
this 'back off' delay because once the work is scheduled
(with a delay of 1) new scheduling calls are ignored for
the same work structure.

I've been testing the change to 0 in tty_schedule_flip()
under various loads and data rates with no ill effects.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] synclink_gt add compat_ioctl

2007-05-09 Thread Paul Fulghum
Add support for 32 bit ioctl on 64 bit systems for synclink_gt

Cc: Arnd Bergmann <[EMAIL PROTECTED]>
Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/include/linux/Kbuild  2007-04-25 22:08:32.0 -0500
+++ b/include/linux/Kbuild  2007-05-09 10:11:22.0 -0500
@@ -140,7 +140,6 @@ header-y += snmp.h
 header-y += sockios.h
 header-y += som.h
 header-y += sound.h
-header-y += synclink.h
 header-y += telephony.h
 header-y += termios.h
 header-y += ticable.h
@@ -315,6 +314,7 @@ unifdef-y += sonypi.h
 unifdef-y += soundcard.h
 unifdef-y += stat.h
 unifdef-y += stddef.h
+unifdef-y += synclink.h
 unifdef-y += sysctl.h
 unifdef-y += tcp.h
 unifdef-y += time.h
--- a/include/linux/synclink.h  2007-04-25 22:08:32.0 -0500
+++ b/include/linux/synclink.h  2007-05-09 10:37:20.0 -0500
@@ -291,4 +291,29 @@ struct gpio_desc {
 #define MGSL_IOCGGPIO  _IOR(MGSL_MAGIC_IOC,17,struct gpio_desc)
 #define MGSL_IOCWAITGPIO   _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc)
 
+#ifdef __KERNEL__
+/* provide 32 bit ioctl compatibility on 64 bit systems */
+#ifdef CONFIG_COMPAT
+#include 
+struct MGSL_PARAMS32
+{
+   compat_ulong_t  mode;
+   unsigned char   loopback;
+   unsigned short  flags;
+   unsigned char   encoding;
+   compat_ulong_t  clock_speed;
+   unsigned char   addr_filter;
+   unsigned short  crc_type;
+   unsigned char   preamble_length;
+   unsigned char   preamble;
+   compat_ulong_t  data_rate;
+   unsigned char   data_bits;
+   unsigned char   stop_bits;
+   unsigned char   parity;
+};
+#define MGSL_IOCSPARAMS32 _IOW(MGSL_MAGIC_IOC,0,struct MGSL_PARAMS32)
+#define MGSL_IOCGPARAMS32 _IOR(MGSL_MAGIC_IOC,1,struct MGSL_PARAMS32)
+#endif
+#endif
+
 #endif /* _SYNCLINK_H_ */
--- a/drivers/char/synclink_gt.c2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/synclink_gt.c2007-05-09 10:12:29.0 -0500
@@ -1171,6 +1171,112 @@ static int ioctl(struct tty_struct *tty,
 }
 
 /*
+ * support for 32 bit ioctl calls on 64 bit systems
+ */
+#ifdef CONFIG_COMPAT
+static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*user_params)
+{
+   struct MGSL_PARAMS32 tmp_params;
+
+   DBGINFO(("%s get_params32\n", info->device_name));
+   tmp_params.mode= (compat_ulong_t)info->params.mode;
+   tmp_params.loopback= info->params.loopback;
+   tmp_params.flags   = info->params.flags;
+   tmp_params.encoding= info->params.encoding;
+   tmp_params.clock_speed = (compat_ulong_t)info->params.clock_speed;
+   tmp_params.addr_filter = info->params.addr_filter;
+   tmp_params.crc_type= info->params.crc_type;
+   tmp_params.preamble_length = info->params.preamble_length;
+   tmp_params.preamble= info->params.preamble;
+   tmp_params.data_rate   = (compat_ulong_t)info->params.data_rate;
+   tmp_params.data_bits   = info->params.data_bits;
+   tmp_params.stop_bits   = info->params.stop_bits;
+   tmp_params.parity  = info->params.parity;
+   if (copy_to_user(user_params, &tmp_params, sizeof(struct 
MGSL_PARAMS32)))
+   return -EFAULT;
+   return 0;
+}
+
+static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*new_params)
+{
+   struct MGSL_PARAMS32 tmp_params;
+
+   DBGINFO(("%s set_params32\n", info->device_name));
+   if (copy_from_user(&tmp_params, new_params, sizeof(struct 
MGSL_PARAMS32)))
+   return -EFAULT;
+
+   spin_lock(&info->lock);
+   info->params.mode= tmp_params.mode;
+   info->params.loopback= tmp_params.loopback;
+   info->params.flags   = tmp_params.flags;
+   info->params.encoding= tmp_params.encoding;
+   info->params.clock_speed = tmp_params.clock_speed;
+   info->params.addr_filter = tmp_params.addr_filter;
+   info->params.crc_type= tmp_params.crc_type;
+   info->params.preamble_length = tmp_params.preamble_length;
+   info->params.preamble= tmp_params.preamble;
+   info->params.data_rate   = tmp_params.data_rate;
+   info->params.data_bits   = tmp_params.data_bits;
+   info->params.stop_bits   = tmp_params.stop_bits;
+   info->params.parity  = tmp_params.parity;
+   spin_unlock(&info->lock);
+
+   change_params(info);
+
+   return 0;
+}
+
+static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
+unsigned int cmd, unsigned long arg)
+{
+   struct slgt_info *info = tty->driver_data;
+   int rc = -ENOIOCTLCMD;
+
+   if (sanity_check(info, tty->name, "compat_ioctl"))
+   return -ENODEV;
+   DBGINFO(("%s compat_i

Re: [PATCH] synclink_gt add compat_ioctl

2007-05-08 Thread Paul Fulghum

Arnd Bergmann wrote:

To solve this, you can to change include/linux/Kbuild to list
synclink.h as unifdef-y instead of header-y, and put the parts
that you don't want to be in user space inside of #ifdef __KERNEL__.

Alternatively, you can put these kernel-internal definitions into
a private header file in drivers/char that does not get installed
in the first place. That would be particularly useful if you can
also move other parts of linux/synclink.h into the private header,
when they are not part of the external ABI.


Understood. That is the last piece to the puzzle.

I think the first approach would be better as
synclink.h is all interface definitions. The kernel
specific parts are in the individual synclink drivers
(such as register definitions, etc). The only exception
to this is now the ioctl32 structures and I would hate
to break out a whole new header just for that.

Thanks again for your targeted and informative help.
(Thanks to Andrew for your patience in dealing
with a patch that never should have been submitted.)

--
Paul






-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] synclink_gt add compat_ioctl

2007-05-08 Thread Paul Fulghum
On Sun, 2007-05-06 at 02:27 +0200, Arnd Bergmann wrote:

> Now that you mention the duplication, this sounds wrong as well. The easiest
> solution is probably to just put the definition of your data structure
> inside of #ifdef CONFIG_COMPAT in the header file.

The structure definition was already inside of #ifdef CONFIG_COMPAT

The problem is including linux/compat.h inside of synclink.h
causes an error on i386. The headerscheck facility is spitting
out an error even if the #include  is inside of
#ifdef CONFIG_COMPAT

make[3]: *** No rule to make target
`/usr/src/devel/usr/include/linux/.check.synclink.h', needed by
`__headerscheck'.  Stop.

linux/kexec.h includes linux/compat.h without a similar error,
though that is inside of a #ifdef CONFIG_KEXEC

Moving linux/compat.h from synclink.h to synclink_gt.c
removes the error.

This is the last error standing in my way and I'm trying
to figure out the rules for when and where you are allowed
to use compat.h, I'm not familiar with the headerscheck
facility so I'm not sure what it is looking for and the
error is not very helpful. There is nothing in Documentation
covering it.

--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] Use tty_schedule in VT code.

2007-05-08 Thread Paul Fulghum
On Tue, 2007-05-08 at 21:10 +0100, James Simmons wrote:
> 
> This patch has the VT subsystem use tty_schedule_flip instead of 
> con_schedule_flip. There are two ways we can approach this. We can
> do the below path or extend tty_schedule_flip to accept a time field.
> Comments welcomed.

This looks reasonable.

I don't think a time field is necessary. In fact, I think the
scheduled_delayed_work() in tty_schedule_flip() should use a
time of 0 just like con_schedule_flip().

As the tty flip buffer code has evolved, that delay value of 1
was carried along. It may have had some historical purpose, but
I can't figure it out and it appears to have no use currently.

It would be better for performance to process the receive data
as soon as possible (delay value of 0).


--
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] tty flush flip buffer on ldisc input queue flush

2007-05-07 Thread Paul Fulghum
Flush the tty flip buffer when the line discipline
input queue is flushed, including the user call
tcflush(TCIFLUSH/TCIOFLUSH). This prevents unexpected
stale data after a user application calls tcflush().

Cc: Alan Cox <[EMAIL PROTECTED]>
Cc: Antonino Ingargiola <[EMAIL PROTECTED]>
Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/drivers/char/tty_io.c 2007-05-04 05:46:55.0 -0500
+++ b/drivers/char/tty_io.c 2007-05-05 03:23:46.0 -0500
@@ -365,6 +365,29 @@ static void tty_buffer_free(struct tty_s
 }
 
 /**
+ * tty_buffer_flush-   flush full tty buffers
+ * @tty: tty to flush
+ *
+ * flush all the buffers containing receive data
+ *
+ * Locking: none
+ */
+
+static void tty_buffer_flush(struct tty_struct *tty)
+{
+   struct tty_buffer *thead;
+   unsigned long flags;
+
+   spin_lock_irqsave(&tty->buf.lock, flags);
+   while((thead = tty->buf.head) != NULL) {
+   tty->buf.head = thead->next;
+   tty_buffer_free(tty, thead);
+   }
+   tty->buf.tail = NULL;
+   spin_unlock_irqrestore(&tty->buf.lock, flags);
+}
+
+/**
  * tty_buffer_find -   find a free tty buffer
  * @tty: tty owning the buffer
  * @size: characters wanted
@@ -1240,6 +1263,7 @@ void tty_ldisc_flush(struct tty_struct *
ld->flush_buffer(tty);
tty_ldisc_deref(ld);
}
+   tty_buffer_flush(tty);
 }
 
 EXPORT_SYMBOL_GPL(tty_ldisc_flush);
@@ -3336,6 +3360,15 @@ int tty_ioctl(struct inode * inode, stru
case TIOCMBIC:
case TIOCMBIS:
return tty_tiocmset(tty, file, cmd, p);
+   case TCFLSH:
+   switch (arg) {
+   case TCIFLUSH:
+   case TCIOFLUSH:
+   /* flush tty buffer and allow ldisc to process 
ioctl */
+   tty_buffer_flush(tty);
+   break;
+   }
+   break;
}
if (tty->driver->ioctl) {
retval = (tty->driver->ioctl)(tty, file, cmd, arg);



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-06 Thread Paul Fulghum

Alan Cox wrote:

On Sat, 5 May 2007 20:07:15 +0200
Oliver Neukum <[EMAIL PROTECTED]> wrote:

should I understand this so that, if tty_buffer_request_room() returns
less than requested, the rest of the data should be dropped on the
floor?


If it returns NULL then either there is > 64K buffered (we can adjust
that if anyone shows need - its just for sanity) or the system is out of
RAM. 



It sounds bad, but I think dropping the data make sense with the
new tty buffering code.

My interpretation of the tty buffering is that
it is intended to be the main receive buffer facility
for the driver.

It simplifies and centralizes these functions so
the driver does not need implement policies such as when to
flush for user request, expand under load, crop when too large.

It should not be the driver's responsibility to
try and work around the tty buffering if it becomes full.
That adds other complexity such as when the driver should
attempt to push the data again: when more data is received?
after a timeout?

If the tty buffering runs dry, then maybe put out an error message.
If the losses occur too often then the tty buffering code needs to
be adjusted.

--
Paul


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-06 Thread Paul Fulghum

Antonino Ingargiola wrote:

For my use case would be more sensible to accept the new data and
discard the older one in the tty buffer: the tty buffer would be a
moving window of the most recent incoming data. This because if
someone does not read the incoming data maybe he's not interested in
it. When he finally reads the data (assuming there was buffer
underrun) he's likely interested to the more recent chunk of incoming
data and not to an "head" of the data firstly received. Since I
acquire measurement data from serial this make perfect sense for me.
But does this make sense in general too?


There is no one policy here that will make everyone happy.
Some will want all the data before some was lost,
others the data after some was lost.

The real goal is to minimize any data loss.


However, whatever policy the buffer uses, the fundamental point it's that
when I flush the input buffer I should be sure that each byte read
after the flush is *new* (current) data and not old one. This because
when the input stream can be stopped I can check that there are 0 byte
in the buffer, but when the stream can't be stopped I must use a
flush-and-sleep (multiple times) heuristic before I can read a single
*reliable* byte.


The flush minimizes stale data the application must process.
As Alan said in his response there are other sources of
stale data beyond the kernel's control. But we absolutely should
be flushing all buffers we control.

In the end, if more reliability is needed the application must
implement its own discipline of framing (defining block boundaries) and
checking (CRC) on the raw data stream.

--
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-05 Thread Paul Fulghum
On Sat, 2007-05-05 at 18:58 +0200, Antonino Ingargiola wrote:
> This patch does not solve the problem with the cdc_acd driver. I still
> need to flush two times to really flush the input. And the "secondary
> buffer" still seems 26 bytes (as before).

I missed a bit, try this.

--- a/drivers/usb/class/cdc-acm.c   2007-04-25 22:08:32.0 -0500
+++ b/drivers/usb/class/cdc-acm.c   2007-05-05 12:03:19.0 -0500
@@ -335,8 +335,6 @@ static void acm_rx_tasklet(unsigned long
spin_lock_irqsave(&acm->throttle_lock, flags);
throttled = acm->throttle;
spin_unlock_irqrestore(&acm->throttle_lock, flags);
-   if (throttled)
-   return;
 
 next_buffer:
spin_lock_irqsave(&acm->read_lock, flags);
@@ -355,18 +353,9 @@ next_buffer:
spin_lock_irqsave(&acm->throttle_lock, flags);
throttled = acm->throttle;
spin_unlock_irqrestore(&acm->throttle_lock, flags);
-   if (!throttled)
-   tty_insert_flip_string(tty, buf->base, buf->size);
+   tty_insert_flip_string(tty, buf->base, buf->size);
tty_flip_buffer_push(tty);
 
-   if (throttled) {
-   dbg("Throttling noticed");
-   spin_lock_irqsave(&acm->read_lock, flags);
-   list_add(&buf->list, &acm->filled_read_bufs);
-   spin_unlock_irqrestore(&acm->read_lock, flags);
-   return;
-   }
-
spin_lock_irqsave(&acm->read_lock, flags);
list_add(&buf->list, &acm->spare_read_bufs);
spin_unlock_irqrestore(&acm->read_lock, flags);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-05 Thread Paul Fulghum
On Sat, 2007-05-05 at 18:46 +0200, Oliver Neukum wrote:
> Am Samstag, 5. Mai 2007 18:08 schrieb Paul Fulghum:
> > I would argue that cdc-acm should do the same as the serial driver.
> 
> Has this been tested?
> If so we could reduce the complexity of the throtteling logic in the usb
> drivers.

Antonino is doing so now.

I think Alan nailed it: with the old tty buffering the extra
logic was required to avoid data loss. The new tty buffering
handles large blocks of data with no problem.

Removing this part of the throttle logic makes
the input flushing mechanism complete.

--
Paul


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-05 Thread Paul Fulghum
On Sat, 2007-05-05 at 11:08 -0500, Paul Fulghum wrote:
> I would argue that cdc-acm should do the same as the serial driver.

Try this patch for the usb ports. (I don't have that hardware)

--- a/drivers/usb/class/cdc-acm.c   2007-04-25 22:08:32.0 -0500
+++ b/drivers/usb/class/cdc-acm.c   2007-05-05 11:12:10.0 -0500
@@ -355,18 +355,9 @@ next_buffer:
spin_lock_irqsave(&acm->throttle_lock, flags);
throttled = acm->throttle;
spin_unlock_irqrestore(&acm->throttle_lock, flags);
-   if (!throttled)
-   tty_insert_flip_string(tty, buf->base, buf->size);
+   tty_insert_flip_string(tty, buf->base, buf->size);
tty_flip_buffer_push(tty);
 
-   if (throttled) {
-   dbg("Throttling noticed");
-   spin_lock_irqsave(&acm->read_lock, flags);
-   list_add(&buf->list, &acm->filled_read_bufs);
-   spin_unlock_irqrestore(&acm->read_lock, flags);
-   return;
-   }
-
spin_lock_irqsave(&acm->read_lock, flags);
list_add(&buf->list, &acm->spare_read_bufs);
spin_unlock_irqrestore(&acm->read_lock, flags);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] synclink_gt add compat_ioctl

2007-05-05 Thread Paul Fulghum

Arnd Bergmann wrote:

On Friday 04 May 2007, Paul Fulghum wrote:

- It is fishy that apart from one outlier in kexec.h, synclink.h is the
  only header file which uses compat_ulong_t.  Are we doing this right?

Arnd, do you have any comment on this?


I think most others just define the compat data structures in the
same file that implements the headers, inside the same #ifdef that
hides the functions using them.
This makes sense, because the data structures here don't define
an interface, but rather describe what the interface looks like
in the 32 bit case.


OK, moving the compatible structure declarations from the header
to the individual source files will fix all the header mess and
the odd compilation errors on i386 when using the compat.h header
inside of another header.

That declaration will need to be duplicated in each driver that
uses it (4 drivers in my case). In that sense (a structure declaration
used by multiple code modules) it does seem like an interface definition.

If that is what is needed, I will do it.

--
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-05 Thread Paul Fulghum
On Fri, 2007-05-04 at 17:30 -0600, Paul Fulghum wrote:
> OK, this behavior is so unexpected I must be missing
> something basic.

And so I was. Try this patch.

--- a/drivers/char/tty_io.c 2007-05-04 05:46:55.0 -0500
+++ b/drivers/char/tty_io.c 2007-05-05 03:23:46.0 -0500
@@ -365,6 +365,29 @@ static void tty_buffer_free(struct tty_s
 }
 
 /**
+ * tty_buffer_flush-   flush full tty buffers
+ * @tty: tty to flush
+ *
+ * flush all the buffers containing receive data
+ *
+ * Locking: none
+ */
+
+static void tty_buffer_flush(struct tty_struct *tty)
+{
+   struct tty_buffer *thead;
+   unsigned long flags;
+
+   spin_lock_irqsave(&tty->buf.lock, flags);
+   while((thead = tty->buf.head) != NULL) {
+   tty->buf.head = thead->next;
+   tty_buffer_free(tty, thead);
+   }
+   tty->buf.tail = NULL;
+   spin_unlock_irqrestore(&tty->buf.lock, flags);
+}
+
+/**
  * tty_buffer_find -   find a free tty buffer
  * @tty: tty owning the buffer
  * @size: characters wanted
@@ -1240,6 +1263,7 @@ void tty_ldisc_flush(struct tty_struct *
ld->flush_buffer(tty);
tty_ldisc_deref(ld);
}
+   tty_buffer_flush(tty);
 }
 
 EXPORT_SYMBOL_GPL(tty_ldisc_flush);
@@ -3336,6 +3360,15 @@ int tty_ioctl(struct inode * inode, stru
case TIOCMBIC:
case TIOCMBIS:
return tty_tiocmset(tty, file, cmd, p);
+   case TCFLSH:
+   switch (arg) {
+   case TCIFLUSH:
+   case TCIOFLUSH:
+   /* flush tty buffer and allow ldisc to process 
ioctl */
+   tty_buffer_flush(tty);
+   break;
+   }
+   break;
}
if (tty->driver->ioctl) {
retval = (tty->driver->ioctl)(tty, file, cmd, arg);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-05 Thread Paul Fulghum
On Sat, 2007-05-05 at 10:43 -0600, Paul Fulghum wrote:
> There is not an input flush method for the tty driver
> and individual drivers don't process that ioctl.
> The tty drivers I've seen immediately pass receive data to the
> tty buffering and I'm not sure why a driver would
> behave otherwise.

cdc-acm does its own buffering.

In your case, the line discipline throttled the tty device
because the ldisc buffer was full.

If the line discipline throttles the driver input,
the cdc-acm driver stops giving data to the tty buffering
and instead stores them internally.

In the serial driver this usually just results in dropping
RTS to signal the remote end to stop sending. The serial
driver always immediately gives receive data to the tty buffering
without regard to the throttled state.

I would argue that cdc-acm should do the same as the serial driver.

--
Paul


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-05 Thread Paul Fulghum

Antonino Ingargiola wrote:

The patch now boot properly and solves
completely the testcase with two serial lines:


Good, thanks for testing.


I think this patch should be included in mainline, since if one flushes
the input buffer, really want to flush the entire buffer chain and
doesn't want to read any old data _after_ a flush.


I will submit the patch, it's clearly needed.


However I also tested a usb-serial device (that uses the cdc-acm
driver) and in this case I still need _two_ flushInput() to totally
flush the input buffer.

There can be another *secondary buffer* in the usb-serial driver? Can
this buffer be emptied out too?


Very possible, but I'm not familiar with that.

There is not an input flush method for the tty driver
and individual drivers don't process that ioctl.
The tty drivers I've seen immediately pass receive data to the
tty buffering and I'm not sure why a driver would
behave otherwise.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] synclink_gt add compat_ioctl

2007-05-04 Thread Paul Fulghum

Andrew Morton wrote:

On Thu, 03 May 2007 13:01:17 -0500
Paul Fulghum <[EMAIL PROTECTED]> wrote:


Add compat_ioctl handler to synclink_gt driver.


i386 allmodconfig:

make[3]: *** No rule to make target 
`/usr/src/devel/usr/include/linux/.check.synclink.h', needed by 
`__headerscheck'.  Stop.

I got tired of this patch - I think I'll drop it.


This all seems to be related to the use of compat_ulong_t

Since my original patch worked fine using unsigned int,
how about I go back to that?


--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum
Antonino:

Can you try two tests (with my patch applied):

1. comment out the tty_flush_buffer() call in tty_ldisc_flush() and test

2. uncomment (reenable) the above call and comment out the
tty_flush_buffer() call in tty_ioctl() and test

Thanks,
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum

Antonino Ingargiola wrote:

"With the patch, flushing the input results effectively in a complete flush.
However after doing the flush I can't read [further] chars [sent to
the serial port]
without closing and reopening the port. I've verified this behavior both
communicating between two serial ports and both communicating with an
usb-serial device (driver cdc-acm)."


OK, this behavior is so unexpected I must be missing
something basic. Not being able to reproduce this myself
is a problem. If I think of something I'll post.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] tty add compat_ioctl

2007-05-04 Thread Paul Fulghum

Arnd Bergmann wrote:

- The return value of the new compat_ioctl methods should probably
'int', not 'long'. We've had the discussion before and then
decided not to change the existing compat_ioctl and 
unlocked_ioctl functions -- even though int is more appropriate,

but having the same prototype has the advantage that a driver
can use the same function for both ->ioctl and ->compat_ioctl
if all calls are compatible.


Any comments on this or should I assume that
compat_ioctl() will stay with ulong return type?

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] synclink_gt add compat_ioctl

2007-05-04 Thread Paul Fulghum

Andrew Morton wrote:

In file included from drivers/char/synclink_gt.c:85:
include/linux/synclink.h:175: error: expected specifier-qualifier-list before 
'compat_ulong_t'

- We might as well do the same ifdef-avoidery trick around compat_ioctl()
  too.  That required that it be renamed.

- It is fishy that apart from one outlier in kexec.h, synclink.h is the
  only header file which uses compat_ulong_t.  Are we doing this right?


Arnd, do you have any comment on this?

It seems like the compatible types should be available
in something that is already commonly used like linux/types.h

I'm fine with it either way. I'm not in
a position to be making those kinds of decisions
for widely used infrastructure, so I'll leave
that for someone further up the food chain.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum
On Fri, 2007-05-04 at 21:06 +0200, Antonino Ingargiola wrote:

> Filling with echo console-screen.sh I've found that the blocking command is:
> 
> unicode_start 2> /dev/null || true
> 
> or at least the echo before this command is the last shown.

I still don't know what is blocking.

It is possible some tty device is operating with an improperly
initialized tty structure. I vaguely remember some console code
creating its own minimally initialized 'dummy' tty structure.

This might be causing the new flush code to hang.

Try this patch which does not call the flush unless a line
discipline is attached to the tty. That should indicate
a normally initialized tty structure.

--- a/drivers/char/tty_io.c 2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/tty_io.c 2007-05-04 12:15:18.0 -0500
@@ -365,6 +365,28 @@ static void tty_buffer_free(struct tty_s
 }
 
 /**
+ * tty_buffer_flush-   flush full tty buffers
+ * @tty: tty to flush
+ *
+ * flush all the buffers containing receive data
+ *
+ * Locking: none
+ */
+
+static void tty_buffer_flush(struct tty_struct *tty)
+{
+   struct tty_buffer *thead;
+   unsigned long flags;
+
+   spin_lock_irqsave(&tty->buf.lock, flags);
+   while((thead = tty->buf.head) != NULL) {
+   tty->buf.head = thead->next;
+   tty_buffer_free(tty, thead);
+   }
+   spin_unlock_irqrestore(&tty->buf.lock, flags);
+}
+
+/**
  * tty_buffer_find -   find a free tty buffer
  * @tty: tty owning the buffer
  * @size: characters wanted
@@ -1236,8 +1258,10 @@ void tty_ldisc_flush(struct tty_struct *
 {
struct tty_ldisc *ld = tty_ldisc_ref(tty);
if(ld) {
-   if(ld->flush_buffer)
+   if(ld->flush_buffer) {
ld->flush_buffer(tty);
+   tty_buffer_flush(tty);
+   }
tty_ldisc_deref(ld);
}
 }
@@ -3336,6 +3360,20 @@ int tty_ioctl(struct inode * inode, stru
case TIOCMBIC:
case TIOCMBIS:
return tty_tiocmset(tty, file, cmd, p);
+   case TCFLSH:
+   switch (arg) {
+   case TCIFLUSH:
+   case TCIOFLUSH:
+   /* flush tty buffer and allow ldisc to process 
ioctl */
+   ld = tty_ldisc_ref_wait(tty);
+   if (ld) {
+   if (ld->ioctl)
+   tty_buffer_flush(tty);
+   tty_ldisc_deref(ld);
+   }
+   break;
+   }
+   break;
}
if (tty->driver->ioctl) {
retval = (tty->driver->ioctl)(tty, file, cmd, arg);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] tty_set_ldisc receive_room fix

2007-05-04 Thread Paul Fulghum
Fix tty_set_ldisc in tty_io.c so that tty->receive_room is
only cleared if actually changing line disciplines.

Without this fix a problem occurs when requesting the line
discipline to change to the same line discipline. In this case
tty->receive_room is cleared but ldisc->open() is not called
to set tty->receive_room back to a sane value. The result
is that tty->receive_room is stuck at 0 preventing the tty
flip buffer from passing receive data to the line discipline.

For example: a switch from N_TTY to N_TTY followed by
a select() call for read input results in data never being
received because tty->receive_room is stuck at zero.

A switch from N_TTY to N_TTY followed by
a read() call works because the read() call itself
sets tty->receive_room correctly (but select does not).

Previously (< 2.6.18) this was not a problem because
the tty flip buffer pushed data to the line discipline
without regard for tty->receive room.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>


--- a/drivers/char/tty_io.c 2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/tty_io.c 2007-05-04 14:25:08.0 -0500
@@ -936,13 +936,6 @@ restart:
return -EINVAL;
 
/*
-*  No more input please, we are switching. The new ldisc
-*  will update this value in the ldisc open function
-*/
-
-   tty->receive_room = 0;
-
-   /*
 *  Problem: What do we do if this blocks ?
 */
 
@@ -953,6 +946,13 @@ restart:
return 0;
}
 
+   /*
+*  No more input please, we are switching. The new ldisc
+*  will update this value in the ldisc open function
+*/
+
+   tty->receive_room = 0;
+
o_ldisc = tty->ldisc;
o_tty = tty->link;
 


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum
On Fri, 2007-05-04 at 19:25 +0200, Antonino Ingargiola wrote:

> No. Ehmm ... I've an usb keybord and vga monitor on a standard desktop pc.

OK, I'm stumped.

I don't see how my patch could cause the machine to not boot
and I'm not seeing that behavior here.

-- 
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum
On Fri, 2007-05-04 at 19:13 +0200, Antonino Ingargiola wrote:
> On 5/4/07, Paul Fulghum <[EMAIL PROTECTED]> wrote:
> > Antonino Ingargiola wrote:
> > > The system blocks during booting. I can unblock it with SysReq+K but
> > > then I'm unable to log into X.
> >
> > Hmmm, it tests here with no problem.
> >
> > Does reversing the patch and rebuilding the kernel fix the boot?
> 
> The kernel to which I applied the patch was vanilla 2.6.21.1, and it
> is the one I'm currently running (no config changes or other patches).

Are you using a serial port as console?

-- 
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum

Antonino Ingargiola wrote:

The system blocks during booting. I can unblock it with SysReq+K but
then I'm unable to log into X.


Hmmm, it tests here with no problem.

Does reversing the patch and rebuilding the kernel fix the boot?

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum
Here is a patch against 2.6.21 which flushes the tty flip buffer
on ioctl(TCFLSH) for input.

--- a/drivers/char/tty_io.c 2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/tty_io.c 2007-05-04 09:30:01.0 -0500
@@ -365,6 +365,28 @@ static void tty_buffer_free(struct tty_s
 }
 
 /**
+ * tty_buffer_flush-   flush full tty buffers
+ * @tty: tty to flush
+ *
+ * flush all the buffers containing receive data
+ *
+ * Locking: none
+ */
+
+static void tty_buffer_flush(struct tty_struct *tty)
+{
+   struct tty_buffer *thead;
+   unsigned long flags;
+
+   spin_lock_irqsave(&tty->buf.lock, flags);
+   while((thead = tty->buf.head) != NULL) {
+   tty->buf.head = thead->next;
+   tty_buffer_free(tty, thead);
+   }
+   spin_unlock_irqrestore(&tty->buf.lock, flags);
+}
+
+/**
  * tty_buffer_find -   find a free tty buffer
  * @tty: tty owning the buffer
  * @size: characters wanted
@@ -1240,6 +1262,7 @@ void tty_ldisc_flush(struct tty_struct *
ld->flush_buffer(tty);
tty_ldisc_deref(ld);
}
+   tty_buffer_flush(tty);
 }
 
 EXPORT_SYMBOL_GPL(tty_ldisc_flush);
@@ -3336,6 +3359,15 @@ int tty_ioctl(struct inode * inode, stru
case TIOCMBIC:
case TIOCMBIS:
return tty_tiocmset(tty, file, cmd, p);
+   case TCFLSH:
+   switch (arg) {
+   case TCIFLUSH:
+   case TCIOFLUSH:
+   /* flush tty buffer and allow ldisc to process 
ioctl */
+   tty_buffer_flush(tty);
+   break;
+   }
+   break;
}
if (tty->driver->ioctl) {
retval = (tty->driver->ioctl)(tty, file, cmd, arg);


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum

Paul Fulghum wrote:

A new function to flush the tty flip buffer needs to
be added and then called from tty_io.c:tty_ldisc_flush().


That is not enough.

It looks like tty_ioctl() needs to process ioctl(TCFLSH)
to clear the flip buffer before passing that ioctl
to the line discipline.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [SOLVED] Serial buffer corruption [was Re: FTDI usb-serial possible bug]

2007-05-04 Thread Paul Fulghum

Antonino Ingargiola wrote:

Nope. In python I use the flushInput() method of the serial object
defined by the pyserial library[0]. The method does just this system
call:

termios.tcflush(self.fd, TERMIOS.TCIFLUSH)

that I think is correct.


There is intermediate buffering between the driver and
the line discipline called the tty flip buffer.

receive data flow:
driver --> tty flip --> line discipline --> application

When you flush input, the line disciplines flush_buffer() method
is called to clear any data residing the in the line discipline.

This does not affect the tty flip buffer
or hardware receive FIFOs.

I suspect the biggest problem is the data in the
tty flip buffer.

A new function to flush the tty flip buffer needs to
be added and then called from tty_io.c:tty_ldisc_flush().

Then a call to tcflush(TCIFLUSH) will clear both buffers.

This still would not clear any data in the hardware
receive FIFOs.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] tty add compat_ioctl

2007-05-03 Thread Paul Fulghum

Paul Fulghum wrote:

Arnd Bergmann wrote:
- In your driver you don't get the big kernel lock in the 
compat_ioctl function. I assume that this is correct for

the particular driver, but it may be nice if you could
consequently also add an unlocked_ioctl function that can
be used without the BKL for native ioctls. It would be good
to hear an opinon on this from someone who has an insight
in tty locking issues though, so I'm Cc:ing some people
who have touched that recently.


I don't count on higher level locking for
synchronization issues specific to the driver.

I thought the current compat_ioctl() was already
meant to *not* have the BKL just like unlocked_ioctl.
My thought was that any driver getting a recent update
like compat_ioctl() would need to be reviewed for BKL
safety and take the lock manually if necessary.


Nevermind. I misread what you wrote (I'm tired).
Yes, adding an unlocked_ioctl() makes sense.

--
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] tty add compat_ioctl

2007-05-03 Thread Paul Fulghum

Arnd Bergmann wrote:

- The return value of the new compat_ioctl methods should probably
'int', not 'long'. We've had the discussion before and then
decided not to change the existing compat_ioctl and 
unlocked_ioctl functions -- even though int is more appropriate,

but having the same prototype has the advantage that a driver
can use the same function for both ->ioctl and ->compat_ioctl
if all calls are compatible.


I noticed that but thought the change in return value type
had some higher purpose I had not perceived. If it can be int
that would be the way to go.

- In your driver you don't get the big kernel lock in the 
compat_ioctl function. I assume that this is correct for

the particular driver, but it may be nice if you could
consequently also add an unlocked_ioctl function that can
be used without the BKL for native ioctls. It would be good
to hear an opinon on this from someone who has an insight
in tty locking issues though, so I'm Cc:ing some people
who have touched that recently.


I don't count on higher level locking for
synchronization issues specific to the driver.

I thought the current compat_ioctl() was already
meant to *not* have the BKL just like unlocked_ioctl.
My thought was that any driver getting a recent update
like compat_ioctl() would need to be reviewed for BKL
safety and take the lock manually if necessary.

Drivers that are falling behind wont have a compat_ioctl
defined at all.

--
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] synclink_gt add compat_ioctl

2007-05-03 Thread Paul Fulghum
Add compat_ioctl handler to synclink_gt driver.

The one case requiring a separate 32 bit handler could be
removed by redefining the associated structure in
a way compatible with both 32 and 64 bit systems. But that
approach would break existing native 64 bit user applications.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/include/linux/synclink.h  2007-04-25 22:08:32.0 -0500
+++ b/include/linux/synclink.h  2007-05-03 12:44:09.0 -0500
@@ -9,6 +9,8 @@
  * the terms of the GNU Public License (GPL)
  */
 
+#include 
+
 #ifndef _SYNCLINK_H_
 #define _SYNCLINK_H_
 #define SYNCLINK_H_VERSION 3.6
@@ -167,6 +169,24 @@ typedef struct _MGSL_PARAMS
 
 } MGSL_PARAMS, *PMGSL_PARAMS;
 
+/* provide 32 bit ioctl compatibility on 64 bit systems */
+struct MGSL_PARAMS32
+{
+   compat_ulong_t  mode;
+   unsigned char   loopback;
+   unsigned short  flags;
+   unsigned char   encoding;
+   compat_ulong_t  clock_speed;
+   unsigned char   addr_filter;
+   unsigned short  crc_type;
+   unsigned char   preamble_length;
+   unsigned char   preamble;
+   compat_ulong_t  data_rate;
+   unsigned char   data_bits;
+   unsigned char   stop_bits;
+   unsigned char   parity;
+};
+
 #define MICROGATE_VENDOR_ID 0x13c0
 #define SYNCLINK_DEVICE_ID 0x0010
 #define MGSCC_DEVICE_ID 0x0020
@@ -276,6 +296,8 @@ struct gpio_desc {
 #define MGSL_MAGIC_IOC 'm'
 #define MGSL_IOCSPARAMS_IOW(MGSL_MAGIC_IOC,0,struct 
_MGSL_PARAMS)
 #define MGSL_IOCGPARAMS_IOR(MGSL_MAGIC_IOC,1,struct 
_MGSL_PARAMS)
+#define MGSL_IOCSPARAMS32  _IOW(MGSL_MAGIC_IOC,0,struct MGSL_PARAMS32)
+#define MGSL_IOCGPARAMS32  _IOR(MGSL_MAGIC_IOC,1,struct MGSL_PARAMS32)
 #define MGSL_IOCSTXIDLE_IO(MGSL_MAGIC_IOC,2)
 #define MGSL_IOCGTXIDLE_IO(MGSL_MAGIC_IOC,3)
 #define MGSL_IOCTXENABLE   _IO(MGSL_MAGIC_IOC,4)
--- a/drivers/char/synclink_gt.c2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/synclink_gt.c2007-05-03 12:40:36.0 -0500
@@ -73,6 +73,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -530,6 +531,10 @@ static int  set_interface(struct slgt_in
 static int  set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 static int  get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 static int  wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
+#ifdef CONFIG_COMPAT
+static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*new_params);
+static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*new_params);
+#endif
 
 /*
  * driver functions
@@ -1170,6 +1175,55 @@ static int ioctl(struct tty_struct *tty,
return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static long compat_ioctl(struct tty_struct *tty, struct file *file,
+unsigned int cmd, unsigned long arg)
+{
+   struct slgt_info *info = tty->driver_data;
+   int rc = -ENOIOCTLCMD;
+
+   if (sanity_check(info, tty->name, "compat_ioctl"))
+   return -ENODEV;
+   DBGINFO(("%s compat_ioctl() cmd=%08X\n", info->device_name, cmd));
+
+   switch (cmd) {
+
+   case MGSL_IOCSPARAMS32:
+   rc = set_params32(info, compat_ptr(arg));
+   break;
+
+   case MGSL_IOCGPARAMS32:
+   rc = get_params32(info, compat_ptr(arg));
+   break;
+
+   case MGSL_IOCGPARAMS:
+   case MGSL_IOCSPARAMS:
+   case MGSL_IOCGTXIDLE:
+   case MGSL_IOCGSTATS:
+   case MGSL_IOCWAITEVENT:
+   case MGSL_IOCGIF:
+   case MGSL_IOCSGPIO:
+   case MGSL_IOCGGPIO:
+   case MGSL_IOCWAITGPIO:
+   case TIOCGICOUNT:
+   rc = ioctl(tty, file, cmd, (unsigned long)(compat_ptr(arg)));
+   break;
+
+   case MGSL_IOCSTXIDLE:
+   case MGSL_IOCTXENABLE:
+   case MGSL_IOCRXENABLE:
+   case MGSL_IOCTXABORT:
+   case TIOCMIWAIT:
+   case MGSL_IOCSIF:
+   rc = ioctl(tty, file, cmd, arg);
+   break;
+   }
+
+   DBGINFO(("%s compat_ioctl() cmd=%08X rc=%d\n", info->device_name, cmd, 
rc));
+   return rc;
+}
+#endif
+
 /*
  * proc fs support
  */
@@ -2507,6 +2561,60 @@ static int set_params(struct slgt_info *
return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*user_params)
+{
+   struct MGSL_PARAMS32 tmp_params;
+
+   DBGINFO(("%s get_params32\n", info->device_name));
+   tmp_params.mode= (compat_ulong_t)info->params.mode;
+   tmp_params.loopback= info->params.loopback;
+   tmp_params.flags   = info->params.flags;
+   tmp_params.encoding= info->params.encoding;
+   tmp_params.clock_speed = (compat_ulong_t)info->params.clock_speed;
+   tmp_params.addr_filter 

[PATCH] tty add compat_ioctl

2007-05-03 Thread Paul Fulghum
Add compat_ioctl method for tty code to allow processing
of 32 bit ioctl calls on 64 bit systems by tty core,
tty drivers, and line disciplines.

Based on patch by Arnd Bergmann:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0511.0/1732.html

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>
CC: Arnd Bergmann <[EMAIL PROTECTED]>

--- a/drivers/char/n_tty.c  2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/n_tty.c  2007-05-01 11:00:47.0 -0500
@@ -1544,21 +1544,18 @@ static unsigned int normal_poll(struct t
 }
 
 struct tty_ldisc tty_ldisc_N_TTY = {
-   TTY_LDISC_MAGIC,/* magic */
-   "n_tty",/* name */
-   0,  /* num */
-   0,  /* flags */
-   n_tty_open, /* open */
-   n_tty_close,/* close */
-   n_tty_flush_buffer, /* flush_buffer */
-   n_tty_chars_in_buffer,  /* chars_in_buffer */
-   read_chan,  /* read */
-   write_chan, /* write */
-   n_tty_ioctl,/* ioctl */
-   n_tty_set_termios,  /* set_termios */
-   normal_poll,/* poll */
-   NULL,   /* hangup */
-   n_tty_receive_buf,  /* receive_buf */
-   n_tty_write_wakeup  /* write_wakeup */
+   .magic   = TTY_LDISC_MAGIC,
+   .name= "n_tty",
+   .open= n_tty_open,
+   .close   = n_tty_close,
+   .flush_buffer= n_tty_flush_buffer,
+   .chars_in_buffer = n_tty_chars_in_buffer,
+   .read= read_chan,
+   .write   = write_chan,
+   .ioctl   = n_tty_ioctl,
+   .set_termios = n_tty_set_termios,
+   .poll= normal_poll,
+   .receive_buf = n_tty_receive_buf,
+   .write_wakeup= n_tty_write_wakeup
 };
 
--- a/include/linux/tty_driver.h2007-04-25 22:08:32.0 -0500
+++ b/include/linux/tty_driver.h2007-05-03 10:03:52.0 -0500
@@ -52,6 +52,11 @@
  * This routine allows the tty driver to implement
  * device-specific ioctl's.  If the ioctl number passed in cmd
  * is not recognized by the driver, it should return ENOIOCTLCMD.
+ *
+ * long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+ * unsigned int cmd, unsigned long arg);
+ *
+ * implement ioctl processing for 32 bit process on 64 bit system
  * 
  * void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
  *
@@ -132,6 +137,8 @@ struct tty_operations {
int  (*chars_in_buffer)(struct tty_struct *tty);
int  (*ioctl)(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+   long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+unsigned int cmd, unsigned long arg);
void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
void (*throttle)(struct tty_struct * tty);
void (*unthrottle)(struct tty_struct * tty);
@@ -193,6 +200,8 @@ struct tty_driver {
int  (*chars_in_buffer)(struct tty_struct *tty);
int  (*ioctl)(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+   long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+unsigned int cmd, unsigned long arg);
void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
void (*throttle)(struct tty_struct * tty);
void (*unthrottle)(struct tty_struct * tty);
--- a/drivers/char/tty_io.c 2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/tty_io.c 2007-05-03 10:42:35.0 -0500
@@ -153,6 +153,11 @@ static int tty_open(struct inode *, stru
 static int tty_release(struct inode *, struct file *);
 int tty_ioctl(struct inode * inode, struct file * file,
  unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long tty_compat_ioctl(struct file * file, unsigned int cmd, unsigned long arg);
+#else
+#define tty_compat_ioctl NULL
+#endif
 static int tty_fasync(int fd, struct file * filp, int on);
 static void release_tty(struct tty_struct *tty, int idx);
 static struct pid *__proc_set_tty(struct task_struct *tsk,
@@ -1145,8 +1150,8 @@ static unsigned int hung_up_tty_poll(str
return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
 }
 
-static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
-unsigned int cmd, unsigned long arg)
+static long hung_up_tty_ioctl(struct file * file,
+ unsigned int cmd, unsigned long arg)
 {
return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
 }
@@ -1157,6 +1162,7 @@ static const struct file_operations tty_
.write  = tty_write,
.poll   = tty_poll,
.ioctl  = tty_ioctl,
+   .compat_ioct

Re: [PATCH] synclink_gt use dynamic tty device registration

2007-05-03 Thread Paul Fulghum
On Thu, 2007-05-03 at 00:05 -0700, Andrew Morton wrote:
> On Wed, 02 May 2007 11:17:33 -0500 Paul Fulghum <[EMAIL PROTECTED]> wrote:
> 
> > Change synclink_gt driver to use dynamic tty device registration.
> > 
> > ...
> >
> > +   for (i=0; i < port_count; ++i)
> > +   tty_register_device(serial_driver, port_array[i]->line, 
> > &(port_array[i]->pdev->dev));
> > ...
> > +   for (info=slgt_device_list ; info != NULL ; 
> > info=info->next_device)
> > +   tty_unregister_device(serial_driver, info->line);
> > ...
> > +   if ((rc = pci_register_driver(&pci_driver)) < 0) {
> 
> hm, not a big fan of kernel coding style, I see.

It varies. If this idiom bothers you, I can split it into 2 lines.

> What's going to happen here if tty_register_device() fails?

Then the device will not be accessible as a tty device.
It may still be accessible as a network device.
On driver unload, tty_unregister_device() does nothing because
the device was never created.

In this case, tracking the return value does not change anything.
I could add a printk on error to better inform the user that the
kernel's plumbing went south.

-- 
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] synclink_gt add compat_ioctl

2007-05-02 Thread Paul Fulghum

Arnd Bergmann wrote:

The same function contains a copy_from_user(), which cannot
be called with interrupts disabled, so yes, I am very certain
it will not change.


Good point.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] synclink_gt add compat_ioctl

2007-05-02 Thread Paul Fulghum

Arnd Bergmann wrote:

+   case MGSL_IOCGPARAMS32:
+   rc = get_params32(info, (struct MGSL_PARAMS32 __user 
*)compat_ptr(arg));
+   break;


No need for the cast here.


OK, for some reason I remember getting a warning
error without it. I must have been mistaken.


+
+   spin_lock_irqsave(&info->lock, flags);


no need for _irqsave, just use spin_{,un}lock_irq() when you know that
interrupts are enabled.


That makes me a little uneasy. The locking
mechanisms (and just about everything else) above the driver
seem to change frequently. This involves not just the VFS but
the tty core as well.

If you are confident this will not change, I will
switch to spin_lock(). I used spin_lock_irqsave() to be
more robust against changes to behavior outside my driver.


+/* provide 32 bit ioctl compatibility on 64 bit systems */
+struct MGSL_PARAMS32
+{
+   unsigned intmode;
+   unsigned char   loopback;
+   unsigned short  flags;
+   unsigned char   encoding;
+   unsigned intclock_speed;
+   unsigned char   addr_filter;
+   unsigned short  crc_type;
+   unsigned char   preamble_length;
+   unsigned char   preamble;
+   unsigned intdata_rate;
+   unsigned char   data_bits;
+   unsigned char   stop_bits;
+   unsigned char   parity;
+};


The definition is correct, but by convention it would be better to use
compat_ulong_t instead of unsigned int for those fields that are an
unsigned long in native mode.


OK

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] tty add compat_ioctl method

2007-05-02 Thread Paul Fulghum

Arnd Bergmann wrote:


Looks ok mostly. Just some details:
...

+#ifdef CONFIG_COMPAT
+   long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+unsigned int cmd, unsigned long arg);
+#endif


I wouldn't hide this inside of an #ifdef. The structures are all static
and therefore a single field per driver doesn't add much bload, but
being able to always assign the .compat_ioctl pointer makes the code
somewhat nicer


OK


--- a/drivers/char/tty_io.c 2006-11-29 15:57:37.0 -0600
+++ b/drivers/char/tty_io.c 2007-04-30 14:51:01.0 -0500
@@ -151,6 +151,9 @@ static int tty_open(struct inode *, stru
 static int tty_release(struct inode *, struct file *);
 int tty_ioctl(struct inode * inode, struct file * file,
  unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long tty_compat_ioctl(struct file * file, unsigned int cmd, unsigned long arg);
+#endif
 static int tty_fasync(int fd, struct file * filp, int on);
 static void release_mem(struct tty_struct *tty, int idx);


declarations should never be hidden inside of an #ifdef. If you want to be
extra clever here, you can do


OK, I have no problem with that.
A declaration without implementation won't generate a warning?


#ifdef CONFIG_COMPAT
long tty_compat_ioctl(struct file * file, unsigned int cmd, unsigned long arg);
#else
#define tty_compat_ioctl NULL
#endif

then you don't need an #ifdef in the code setting the function pointers.


OK


+   tty = (struct tty_struct *)file->private_data;


no need for the cast, ->private_data is void*.


Yes, an easy fix.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] synclink_gt add compat_ioctl

2007-05-02 Thread Paul Fulghum
Add compat_ioctl handler to synclink_gt driver.

The one case requiring a separate 32 bit handler could be
removed by redefining the associated structure in
a way compatible with both 32 and 64 bit systems. But that
approach would break existing native 64 bit user applications.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>


--- a/drivers/char/synclink_gt.c2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/synclink_gt.c2007-05-02 14:52:48.0 -0500
@@ -73,6 +73,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -530,6 +531,10 @@ static int  set_interface(struct slgt_in
 static int  set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 static int  get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 static int  wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
+#ifdef CONFIG_COMPAT
+static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*new_params);
+static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*new_params);
+#endif
 
 /*
  * driver functions
@@ -1170,6 +1175,55 @@ static int ioctl(struct tty_struct *tty,
return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static long compat_ioctl(struct tty_struct *tty, struct file *file,
+unsigned int cmd, unsigned long arg)
+{
+   struct slgt_info *info = tty->driver_data;
+   int rc = -ENOIOCTLCMD;
+
+   if (sanity_check(info, tty->name, "compat_ioctl"))
+   return -ENODEV;
+   DBGINFO(("%s compat_ioctl() cmd=%08X\n", info->device_name, cmd));
+
+   switch (cmd) {
+
+   case MGSL_IOCSPARAMS32:
+   rc = set_params32(info, (struct MGSL_PARAMS32 __user 
*)compat_ptr(arg));
+   break;
+
+   case MGSL_IOCGPARAMS32:
+   rc = get_params32(info, (struct MGSL_PARAMS32 __user 
*)compat_ptr(arg));
+   break;
+
+   case MGSL_IOCGPARAMS:
+   case MGSL_IOCSPARAMS:
+   case MGSL_IOCGTXIDLE:
+   case MGSL_IOCGSTATS:
+   case MGSL_IOCWAITEVENT:
+   case MGSL_IOCGIF:
+   case MGSL_IOCSGPIO:
+   case MGSL_IOCGGPIO:
+   case MGSL_IOCWAITGPIO:
+   case TIOCGICOUNT:
+   rc = ioctl(tty, file, cmd, (unsigned long)(compat_ptr(arg)));
+   break;
+
+   case MGSL_IOCSTXIDLE:
+   case MGSL_IOCTXENABLE:
+   case MGSL_IOCRXENABLE:
+   case MGSL_IOCTXABORT:
+   case TIOCMIWAIT:
+   case MGSL_IOCSIF:
+   rc = ioctl(tty, file, cmd, arg);
+   break;
+   }
+
+   DBGINFO(("%s compat_ioctl() cmd=%08X rc=%d\n", info->device_name, cmd, 
rc));
+   return rc;
+}
+#endif
+
 /*
  * proc fs support
  */
@@ -2507,6 +2561,61 @@ static int set_params(struct slgt_info *
return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*user_params)
+{
+   struct MGSL_PARAMS32 tmp_params;
+
+   DBGINFO(("%s get_params32\n", info->device_name));
+   tmp_params.mode= (unsigned int)info->params.mode;
+   tmp_params.loopback= info->params.loopback;
+   tmp_params.flags   = info->params.flags;
+   tmp_params.encoding= info->params.encoding;
+   tmp_params.clock_speed = (unsigned int)info->params.clock_speed;
+   tmp_params.addr_filter = info->params.addr_filter;
+   tmp_params.crc_type= info->params.crc_type;
+   tmp_params.preamble_length = info->params.preamble_length;
+   tmp_params.preamble= info->params.preamble;
+   tmp_params.data_rate   = (unsigned int)info->params.data_rate;
+   tmp_params.data_bits   = info->params.data_bits;
+   tmp_params.stop_bits   = info->params.stop_bits;
+   tmp_params.parity  = info->params.parity;
+   if (copy_to_user(user_params, &tmp_params, sizeof(struct 
MGSL_PARAMS32)))
+   return -EFAULT;
+   return 0;
+}
+
+static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user 
*new_params)
+{
+   unsigned long flags;
+   struct MGSL_PARAMS32 tmp_params;
+
+   DBGINFO(("%s set_params32\n", info->device_name));
+   if (copy_from_user(&tmp_params, new_params, sizeof(struct 
MGSL_PARAMS32)))
+   return -EFAULT;
+
+   spin_lock_irqsave(&info->lock, flags);
+   info->params.mode= tmp_params.mode;
+   info->params.loopback= tmp_params.loopback;
+   info->params.flags   = tmp_params.flags;
+   info->params.encoding= tmp_params.encoding;
+   info->params.clock_speed = tmp_params.clock_speed;
+   info->params.addr_filter = tmp_params.addr_filter;
+   info->params.crc_type= tmp_params.crc_type;
+   info->params.preamble_leng

[PATCH] tty add compat_ioctl method

2007-05-02 Thread Paul Fulghum
Add compat_ioctl method for tty code to allow processing
of 32 bit ioctl calls on 64 bit systems by tty core,
tty drivers, and line disciplines.

Based on patch by Arnd Bergmann:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0511.0/1732.html

This patch does not remove tty ioctl entries in compat_ioctl.[ch]
That will be implemented in a separate patch.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>
CC: Arnd Bergmann <[EMAIL PROTECTED]>

--- a/drivers/char/n_tty.c  2007-04-30 15:13:19.0 -0500
+++ b/drivers/char/n_tty.c  2007-04-30 15:17:28.0 -0500
@@ -1545,21 +1545,18 @@ static unsigned int normal_poll(struct t
 }
 
 struct tty_ldisc tty_ldisc_N_TTY = {
-   TTY_LDISC_MAGIC,/* magic */
-   "n_tty",/* name */
-   0,  /* num */
-   0,  /* flags */
-   n_tty_open, /* open */
-   n_tty_close,/* close */
-   n_tty_flush_buffer, /* flush_buffer */
-   n_tty_chars_in_buffer,  /* chars_in_buffer */
-   read_chan,  /* read */
-   write_chan, /* write */
-   n_tty_ioctl,/* ioctl */
-   n_tty_set_termios,  /* set_termios */
-   normal_poll,/* poll */
-   NULL,   /* hangup */
-   n_tty_receive_buf,  /* receive_buf */
-   n_tty_write_wakeup  /* write_wakeup */
+   .magic   = TTY_LDISC_MAGIC,
+   .name= "n_tty",
+   .open= n_tty_open,
+   .close   = n_tty_close,
+   .flush_buffer= n_tty_flush_buffer,
+   .chars_in_buffer = n_tty_chars_in_buffer,
+   .read= read_chan,
+   .write   = write_chan,
+   .ioctl   = n_tty_ioctl,
+   .set_termios = n_tty_set_termios,
+   .poll= normal_poll,
+   .receive_buf = n_tty_receive_buf,
+   .write_wakeup= n_tty_write_wakeup
 };
 
--- a/include/linux/tty_driver.h2006-11-29 15:57:37.0 -0600
+++ b/include/linux/tty_driver.h2007-04-30 14:05:02.0 -0500
@@ -132,6 +132,10 @@ struct tty_operations {
int  (*chars_in_buffer)(struct tty_struct *tty);
int  (*ioctl)(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+   long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+unsigned int cmd, unsigned long arg);
+#endif
void (*set_termios)(struct tty_struct *tty, struct termios * old);
void (*throttle)(struct tty_struct * tty);
void (*unthrottle)(struct tty_struct * tty);
@@ -193,6 +197,10 @@ struct tty_driver {
int  (*chars_in_buffer)(struct tty_struct *tty);
int  (*ioctl)(struct tty_struct *tty, struct file * file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+   long (*compat_ioctl)(struct tty_struct *tty, struct file * file,
+unsigned int cmd, unsigned long arg);
+#endif
void (*set_termios)(struct tty_struct *tty, struct termios * old);
void (*throttle)(struct tty_struct * tty);
void (*unthrottle)(struct tty_struct * tty);
--- a/drivers/char/tty_io.c 2006-11-29 15:57:37.0 -0600
+++ b/drivers/char/tty_io.c 2007-04-30 14:51:01.0 -0500
@@ -151,6 +151,9 @@ static int tty_open(struct inode *, stru
 static int tty_release(struct inode *, struct file *);
 int tty_ioctl(struct inode * inode, struct file * file,
  unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+long tty_compat_ioctl(struct file * file, unsigned int cmd, unsigned long arg);
+#endif
 static int tty_fasync(int fd, struct file * filp, int on);
 static void release_mem(struct tty_struct *tty, int idx);
 
@@ -1153,8 +1156,8 @@ static unsigned int hung_up_tty_poll(str
return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
 }
 
-static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
-unsigned int cmd, unsigned long arg)
+static long hung_up_tty_ioctl(struct file * file,
+ unsigned int cmd, unsigned long arg)
 {
return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
 }
@@ -1165,6 +1168,9 @@ static const struct file_operations tty_
.write  = tty_write,
.poll   = tty_poll,
.ioctl  = tty_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = tty_compat_ioctl,
+#endif
.open   = tty_open,
.release= tty_release,
.fasync = tty_fasync,
@@ -1177,6 +1183,9 @@ static const struct file_operations ptmx
.write  = tty_write,
.poll   = tty_poll,
.ioctl  = tty_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = tty_compat_ioctl,
+#endif
.open

[PATCH] synclink_gt use dynamic tty device registration

2007-05-02 Thread Paul Fulghum
Change synclink_gt driver to use dynamic tty device registration.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>


--- a/drivers/char/synclink_gt.c2007-04-25 22:08:32.0 -0500
+++ b/drivers/char/synclink_gt.c2007-05-02 11:11:34.0 -0500
@@ -3415,6 +3415,9 @@ static void device_init(int adapter_num,
}
}
}
+
+   for (i=0; i < port_count; ++i)
+   tty_register_device(serial_driver, port_array[i]->line, 
&(port_array[i]->pdev->dev));
 }
 
 static int __devinit init_one(struct pci_dev *dev,
@@ -3466,6 +3469,8 @@ static void slgt_cleanup(void)
printk("unload %s %s\n", driver_name, driver_version);
 
if (serial_driver) {
+   for (info=slgt_device_list ; info != NULL ; 
info=info->next_device)
+   tty_unregister_device(serial_driver, info->line);
if ((rc = tty_unregister_driver(serial_driver)))
DBGERR(("tty_unregister_driver error=%d\n", rc));
put_tty_driver(serial_driver);
@@ -3506,23 +3511,10 @@ static int __init slgt_init(void)
 
printk("%s %s\n", driver_name, driver_version);
 
-   slgt_device_count = 0;
-   if ((rc = pci_register_driver(&pci_driver)) < 0) {
-   printk("%s pci_register_driver error=%d\n", driver_name, rc);
-   return rc;
-   }
-   pci_registered = 1;
-
-   if (!slgt_device_list) {
-   printk("%s no devices found\n",driver_name);
-   pci_unregister_driver(&pci_driver);
-   return -ENODEV;
-   }
-
serial_driver = alloc_tty_driver(MAX_DEVICES);
if (!serial_driver) {
-   rc = -ENOMEM;
-   goto error;
+   printk("%s can't allocate tty driver\n", driver_name);
+   return -ENOMEM;
}
 
/* Initialize the tty_driver structure */
@@ -3539,7 +3531,7 @@ static int __init slgt_init(void)
B9600 | CS8 | CREAD | HUPCL | CLOCAL;
serial_driver->init_termios.c_ispeed = 9600;
serial_driver->init_termios.c_ospeed = 9600;
-   serial_driver->flags = TTY_DRIVER_REAL_RAW;
+   serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
tty_set_operations(serial_driver, &ops);
if ((rc = tty_register_driver(serial_driver)) < 0) {
DBGERR(("%s can't register serial driver\n", driver_name));
@@ -3552,6 +3544,16 @@ static int __init slgt_init(void)
driver_name, driver_version,
serial_driver->major);
 
+   slgt_device_count = 0;
+   if ((rc = pci_register_driver(&pci_driver)) < 0) {
+   printk("%s pci_register_driver error=%d\n", driver_name, rc);
+   goto error;
+   }
+   pci_registered = 1;
+
+   if (!slgt_device_list)
+   printk("%s no devices found\n",driver_name);
+
return 0;
 
 error:


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: compat_ioctl question

2007-04-26 Thread Paul Fulghum

Arnd Bergmann wrote:

So you are interested in the MGSL_* set of ioctls, right?
AFAICS, they are all compatible, with the exception of
MGSL_IOCGPARAMS and MGSL_IOCSPARAMS.

Fortunately, these two have different ioctl numbers on
64 bit, so you can define a new
 
#define MGSL_IOCSPARAMS32 _IOR(MGSL_MAGIC_IOC,0,struct _MGSL_PARAMS32)

#define MGSL_IOCGPARAMS32 _IOR(MGSL_MAGIC_IOC,1,struct _MGSL_PARAMS32)

and handle both versions in the ioctl function.


I missed that approach, thanks.


Yes, that would be the right solution. I've started this
some time ago, but never finished it:
http://www.uwsg.iu.edu/hypermail/linux/kernel/0511.0/1732.html


Currently the tty file ops do not include that and
tty_io.c does not register a compat_ioctl(), instead
relying on compat_ioctl.h and compat_ioctl.c


Just adding the hook in tty_io.c should be trivial, please do that.
If you like, you can also move the vt ioctls in order to reduce
the size of fs/compat_ioctl.c.


I'll look at that.

You have given me precisely the information I need.

I just wanted to be sure I did not pursue a dead end
and have people go 'e... why did you do it that way?'

Thanks,
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: compat_ioctl question

2007-04-26 Thread Paul Fulghum

Arnd Bergmann wrote:

It depends a lot on what your specific driver does in the ioctl
handler, but normally you should define a compat_ioctl() function.
What driver are you talking about?


drivers/char/synclink.c
drivers/char/synclinkmp.c
drivers/char/synclink_gt.c
drivers/char/pcmcia/synclink_cs.c

All use the same set of ioctl() codes that
are peculiar to the synclink drivers.

Defining compat_ioctl() seems to be the best way, but
that will require modifying the base tty code to allow
the individual tty drivers to register compat_ioctl().

Currently the tty file ops do not include that and
tty_io.c does not register a compat_ioctl(), instead
relying on compat_ioctl.h and compat_ioctl.c

--
Paul

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


compat_ioctl question

2007-04-26 Thread Paul Fulghum
I need to add ioctl translations for my driver to
allow 32 bit access on 64 bit systems.

After digging through the kernel code there seems to be
3 methods of doing this:

1. define compat_ioctl() file operation for device and
implement translation code in individual driver
2. add COMPATIBLE_IOCTL entry to include/linux/compat_ioctl.h
to mark an ioctl code as the same in any environment
3. add HANDLE_IOCTL entry to fs/compat_ioctl.c with translation code
implemented in the same file

There is no way to implement #1 for a tty driver without
modifying the kernel tty code to allow registration of a
compat_ioctl() handler.

#3 would put a lot of driver specific stuff in a common
kernel file. This method also seems to break if there
is an ioctl code collision.

All of these methods involve changes to code outside of my driver.

--

Before I spend a lot of time on this I need to know what the
officially sanctioned method is. I haven't found any definitive
documentation and a review of mailing list archives does not
suggest a prevailing opinion.

Does anyone have pointers on which way would be most likely
to be accepted as a patch?

Thanks,
Paul


-- 
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: question on tty open and close

2007-03-28 Thread Paul Fulghum

Alan Cox wrote:

It breaks if any existing driver is doing no cleanup in ->open() when it
fails but relying upon ->close() being called. That is what needs
auditing first of all.


Yes, I did not think of that.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: question on tty open and close

2007-03-28 Thread Paul Fulghum

Alan Cox wrote:

I'm also not aware of any reason other than history, which means if
someone cares to double check the other drivers there really shouldn't be
an obstacle to "fixing" this behaviour.

Unless anyone knows different ?


As long as the new behavior continues to call
driver->close() if driver->open() succeeds
then I see no problem.

If individual drivers are correctly doing internal
reference counting to handle driver->close() calls
without a preceding successful driver->open() call
(usually just doing nothing), then they should
continue to operate correctly without the extra
and unnecessary driver->close().

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Serial related oops

2007-02-22 Thread Paul Fulghum

On Thu, Feb 22, 2007 at 03:02:46PM +, Jose Goncalves wrote:

What I find real hard to understand is why a hardware fault happens
always in the same software instruction! I would expect a hardware fault
to hit randomly...


I've experienced just such a hardware fault.

The Infineon DSCC4 serial controller has a hardware bug
in the PCI request/grant handling that can lead to the
device driving the PCI bus in conflict with another device.

While the results were random (as the oops in this problem
seem to be), the trigger was always activating certain
devices in combination.

In your case, altering the timing/behavior of the serial
device during open may be provoking the hardware fault.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: how to limit flip buffer size in tty driver?

2007-02-20 Thread Paul Fulghum

Arjan van de Ven wrote:

On Tue, 2007-02-20 at 15:50 +0300, Mockern wrote:

Thank you Alan for your respond,

Could you help me with a problem which I have with my tty driver, please?



I suspect Alan would be able to help you a whole lot better if you
actually included the full source code of your driver...


Not to mention responding to the previous advice
of others (including myself and Theodore) who stated
there is no magic function in a driver that
directly supports the user mode cat program, and that
he should look at the tty settings controllable by stty.
(in particular clocal)

I also suggested running cat on a standard serial port
and getting that working first. Then applying those stty
settings to his custom device/driver.

(Background: he says other user mode programs work
to read/write but that cat < /dev/foocustom does nothing.)

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: serial and tty driver

2007-02-17 Thread Paul Fulghum

Mockern wrote:

I have a question, what is really difference between serial and tty
drivers?

As I understand tty is high level and communicates with user space. 


The serial core implements many of the details of a tty
driver in a common place so that individual hardware drivers
(serial drivers) only need implement the hardware specific code.

This prevents duplicating tty logic in many drivers,
with the possibility of mistakes/inconsistency in the
different tty drivers.

The stand alone tty drivers are mostly legacy code from
the time before serial core that have not been ported
to be a serial drivers.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: line discipline and tty driver

2007-02-17 Thread Paul Fulghum

Mockern wrote:
> When it's necessary to use line discipline in tty driver
> (to call ldisc.write(), ldisc.read(), ldisc.receive_buf())
> and when I can ignore line discipline in my tty driver?

You should not call any of these from your driver.

transmit data is sent first to the line discipline
ldisc.write() which then calls into your driver write() method

your driver passes receive data to the ldisc through
the tty flip buffer functions.

--
Paul
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [BUG]: 2.6.19.2: Weird serial core issue

2007-02-01 Thread Paul Fulghum

Aubrey Li wrote:

But When I type "ENTER" key,

I got

cflag = 0x1cb1, old = 0x80001cb1
cflag = 0x1cb1, old = 0x1cb1

That means terminal setting is back to crtscts disabled. But here I
didn't do anything to disable it, I just type "ENTER", crtscts setting
should keep enabled. What makes it back to disabled? Now I guess there
must be something wrong with serial core.


Is there an mgetty or similar program monitoring
the same serial port?

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Strange problem with tty layer

2007-01-26 Thread Paul Fulghum

Lennart Sorensen wrote:

I am not sure actually.  I just open /dev/ttyn0 and /dev/ttyn1 and write
to one, and read from the other.  I didn't even know about the line
diciplines actually.  How do I tell which one I am using?


ioctl(TIOCSETD/TIOCGETD) sets/returns an integer identifier
that can be compared agains the N_XXX macros. If you are
not explicitly setting this then is is probably the default N_TTY.

Also at the application level, look at tcsetattr() for setting
the termios features. Look specifically at the c_cc[VTIME] and c_cc[VMIN]
members of the termios structure. These settings control how
much data must be available before returning data to a read().
Try VTIME=0 and VMIN=1.

Since your 'missing' data is always on the tail end, maybe
VMIN is set to 64 or something.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Strange problem with tty layer

2007-01-26 Thread Paul Fulghum

Lennart Sorensen wrote:

Well it turns out that didn't help.  Neither does 2.6.18 (that one was
the easiest newer one to try).  It does seem as if the error rate is
lower with 2.6.18 than with 2.6.16, so perhaps there was more than one
place that could cause losses in the tty buffering.  I had only 2
failures in 15 hours with 2.6.18, rather than a whole lot of failures
with 2.6.16.  I guess I will have to try 2.6.19 or even something newer.


You can eliminate the tty buffering altogether
by observing what gets passed to the line discipline.

I assume you are using the default line discipline N_TTY.

Look at what is passed to drivers/char/n_tty.c:n_tty_receive_buf()
If all the data gets that far, then there is some issue
with the line discipline or something further downstream.
If not, then the problem is with the tty buffering (assuming
you are correct that all data gets to the tty buffering code
followed by a tty_flip_buffer_push call).

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Strange problem with tty layer

2007-01-24 Thread Paul Fulghum

Lennart Sorensen wrote:

I have confirmed that the driver does in fact receive all the
characters, and that they are correct, and that they are being passed to
the tty layer using tty_insert_flip_string, and that it returns that all
the characters have been passed to the tty layer.  The user space
application however still doesn't see the last few characters (when it
fails).

The problem seems to occour every few hours of testing on a 266MHz Geode
SC1200.  When I change the clock to 133MHz, it happens every few minutes
instead (so much more frequently).  I suspect there is some race
condition that allows the tty layer to not get around to processing all
the data in the buffer, even when asked for data by the application
(which is waiting on the serial port using select, with a 4s timeout).


In 2.6.16 the tty buffering pushes data to the line
discipline without regard to tty->receive_room.
If the line discipline can't keep up, the data gets dropped.
I observed this data loss at higher speeds when
placing the system under heavy load.

2.6.18 added code to respect tty->receive_room.

This may or may not be your problem, but you should
be able to check by adding a conditional printk
to drivers/char/tty_io.c:flush_to_ldisc()

If tty->receive_room is less than the size of the buffer
passed to disc->receive_buf() then you are losing data.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: tty->low_latency + irq context

2007-01-02 Thread Paul Fulghum
On Tue, 2007-01-02 at 11:17 -0600, Hollis Blanchard wrote:
> On Tue, 2006-12-26 at 01:08 +0059, Jiri Slaby wrote:
> >  *  Queue a push of the terminal flip buffers to the line discipline. 
> > This
> >  *  function must not be called from IRQ context if tty->low_latency is 
> > set.
> > 
> > But some drivers (mxser, nozomi, hvsi...) sets low_latency to 1 in _open and
> > calls tty_flip_buffer_push in isr or in functions, which are called from 
> > isr.
> > Is the comment correct or the drivers?
> 
> The comment would be true if tty_flip_buffer_push() attempted to block
> with tty->low_latency set, but it doesn't AFAICS. One possibility for
> deadlock is if the tty->buf.lock spinlock is taken on behalf of a user
> process...

There is no deadlock on tty->buf.lock,
which is always acquired with spin_lock_irqsave()
and is only used by the tty buffering code.

The only deadlock I know of with the current tty buffering code
is calling tty_flip_buffer_push() with low_latency
set and from the ISR of a driver that has a problem
with the line discipline calling back into the driver.

The standard serial core has (or at least had the last time
I looked) this problem with the N_TTY ldisc:

driver gets internal spinlock in ISR
driver calls tty_flip_buffer_push with low_latency = 1
flush_to_ldisc() immediately passes data to line discipline
line discipline calls back into driver
driver tries again to get internal spinlock

With low_latency == 1, flush_to_ldisc() is deferred
until the ISR is complete and the internal spinlock is released.

I forget the exact driver callback that caused this.

-- 
Paul Fulghum
Microgate Systems, Ltd

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: tty->low_latency + irq context

2007-01-02 Thread Paul Fulghum

Paul Fulghum wrote:

With low_latency == 1, flush_to_ldisc() is deferred
until the ISR is complete and the internal spinlock is released.


Oops, I meant low_latency == 0 of course.

--
Paul Fulghum
Microgate Systems, Ltd.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] generic HDLC synclink config mismatch fix

2006-12-01 Thread Paul Fulghum
Fix compile errors on mismatch between generic HDLC
and synclink drivers.

Notes:

generic HDLC support for synclink drivers is *optional*
so you can't just use depend on in Kconfig

This solution is deemed the best after 7 months of review
and criticism by many developers including AKPM. Read the
threads on LKML before posting about this solution.

Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>

--- a/drivers/char/synclink.c   2006-11-29 15:57:37.0 -0600
+++ b/drivers/char/synclink.c   2006-12-01 14:38:13.0 -0600
@@ -101,8 +101,10 @@
 #include 
 #include 
 
-#ifdef CONFIG_HDLC_MODULE
-#define CONFIG_HDLC 1
+#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && 
defined(CONFIG_SYNCLINK_MODULE))
+#define SYNCLINK_GENERIC_HDLC 1
+#else
+#define SYNCLINK_GENERIC_HDLC 0
 #endif
 
 #define GET_USER(error,value,addr) error = get_user(value,addr)
@@ -320,7 +322,7 @@ struct mgsl_struct {
int dosyncppp;
spinlock_t netlock;
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
struct net_device *netdev;
 #endif
 };
@@ -728,7 +730,7 @@ static void usc_loopmode_send_done( stru
 
 static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, 
unsigned long arg);
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
 static void hdlcdev_tx_done(struct mgsl_struct *info);
 static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size);
@@ -1276,7 +1278,7 @@ static void mgsl_isr_transmit_status( st
info->drop_rts_on_tx_done = 0;
}
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else 
@@ -1341,7 +1343,7 @@ static void mgsl_isr_io_pin( struct mgsl
info->input_signal_events.dcd_up++;
} else
info->input_signal_events.dcd_down++;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount) {
if (status & MISCSTATUS_DCD)
netif_carrier_on(info->netdev);
@@ -4312,7 +4314,7 @@ static void mgsl_add_device( struct mgsl
info->max_frame_size );
}
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_init(info);
 #endif
 
@@ -4470,7 +4472,7 @@ static void synclink_cleanup(void)
 
info = mgsl_device_list;
while(info) {
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
hdlcdev_exit(info);
 #endif
mgsl_release_resources(info);
@@ -6644,7 +6646,7 @@ static int mgsl_get_rx_frame(struct mgsl
return_frame = 1;
}
framesize = 0;
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
{
struct net_device_stats *stats = 
hdlc_stats(info->netdev);
stats->rx_errors++;
@@ -6720,7 +6722,7 @@ static int mgsl_get_rx_frame(struct mgsl
*ptmp);
}
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)

hdlcdev_rx(info,info->intermediate_rxbuffer,framesize);
else
@@ -7624,7 +7626,7 @@ static void mgsl_tx_timeout(unsigned lon
 
spin_unlock_irqrestore(&info->irq_spinlock,flags);

-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
if (info->netcount)
hdlcdev_tx_done(info);
else
@@ -7700,7 +7702,7 @@ static int usc_loopmode_active( struct m
return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ;
 }
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
 
 /**
  * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
--- a/drivers/char/pcmcia/synclink_cs.c 2006-11-29 15:57:37.0 -0600
+++ b/drivers/char/pcmcia/synclink_cs.c 2006-12-01 14:38:25.0 -0600
@@ -75,8 +75,10 @@
 #include 
 #include 
 
-#ifdef CONFIG_HDLC_MODULE
-#define CONFIG_HDLC 1
+#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && 
defined(CONFIG_SYNCLINK_CS_MODULE))
+#define SYNCLINK_GENERIC_HDLC 1
+#else
+#define SYNCLINK_GENERIC_HDLC 0
 #endif
 
 #define GET_USER(error,value,addr) error = get_user(value,addr)
@@ -235,7 +237,7 @@ typedef struct _mgslpc_info {
int dosyncppp;
spinlock_t netlock;
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
struct net_device *netdev;
 #endif
 
@@ -392,7 +394,7 @@ static void tx_timeout(unsigned long con
 
 static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long 
arg);
 
-#ifdef CONFIG_HDLC
+#if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
 static void hdlcdev_tx_done(MGSLPC_INFO *info);
 static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size);
@@ -1060,7 +1062,7 @@ 

  1   2   >