* selfmade serial driver problem with chipset other than VIA
[not found] <S964780AbVLSPVy/20051219152154Z+1140@vger.kernel.org>
@ 2005-12-19 16:12 ` giorgos xatzipavlis
0 siblings, 0 replies; 7+ messages in thread
From: giorgos xatzipavlis @ 2005-12-19 16:12 UTC (permalink / raw)
To: linux-kernel
hello people
this is my first attempt to the linux serial mailling list so i
apologize for my mistakes...
i am a newbie in kernel development.
i have made a serial driver cause i want to communicate with a serial
device ( a microcontroller ). I have programmed the driver in my
computer and everything is working ok. I have an AMD 1000Hz, MSI
motherboard with VIA chipset and kernel 2.4.31. I have found
informations from Linux Deveice Drivers book. Everything is working ok
in my computer but the driver isn't working in computers with INTEL and
NVIDIA chipsets. The fact that makes me suspicious about that
is that although my driver is registered in /proc/interrupts
and /proc/ioports (irq 4-ioport 0x03f8) when ever i call outb from my
writer bottomhalf routine the interrupt isn't generated from the
hardware(in machines with inter or nvidia chipset).
the flow chart is somethink like that:
1)user space write (getting the data from user)
2)kernel space write (generating the package that i want to send)
3)writer_bottomhalf (i have the package in writer_buffer indexed by a
bytes_send variable. Call "outb(writer_buffer[bytes_send],MY_UART+UART_TX)" )
4)interrupt handler (bytes_send++ ,so i can send the next character variable,
call "tasklet_schedule(&writer_bottomhalf)" to go to step 3)
in computers with chipsets other than VIA the 4th step (interrupt handler) is
never executed.
any ideas?
thank
^ permalink raw reply [flat|nested] 7+ messages in thread
* selfmade serial driver problem with chipset other than VIA
@ 2005-12-19 21:38 gxatzipavlis
2005-12-20 3:15 ` Paul Fulghum
0 siblings, 1 reply; 7+ messages in thread
From: gxatzipavlis @ 2005-12-19 21:38 UTC (permalink / raw)
To: linux-serial
firstly i would like to apologize cause i send this mail to linux-kernel
mailling list and not to linux serial but linux-serial@vger.kernel.org
don't accept the email.
On Mon, 2005-12-19 at 18:12 +0200, giorgos xatzipavlis wrote:
> hello people
>
> this is my first attempt to the linux serial mailling list so i
> apologize for my mistakes...
>
> i am a newbie in kernel development.
>
> i have made a serial driver cause i want to communicate with a serial
> device ( a microcontroller ). I have programmed the driver in my
> computer and everything is working ok. I have an AMD 1000Hz, MSI
> motherboard with VIA chipset and kernel 2.4.31. I have found
> informations from Linux Deveice Drivers book. Everything is working ok
> in my computer but the driver isn't working in computers with INTEL and
> NVIDIA chipsets. The fact that makes me suspicious about that
> is that although my driver is registered in /proc/interrupts
> and /proc/ioports (irq 4-ioport 0x03f8) when ever i call outb from my
> writer bottomhalf routine the interrupt isn't generated from the
> hardware(in machines with inter or nvidia chipset).
>
> the flow chart is somethink like that:
>
> 1)user space write (getting the data from user)
>
> 2)kernel space write (generating the package that i want to send)
>
> 3)writer_bottomhalf (i have the package in writer_buffer indexed by a
> bytes_send variable. Call
"outb(writer_buffer[bytes_send],MY_UART+UART_TX)" )
>
> 4)interrupt handler (bytes_send++ ,so i can send the next character
variable,
> call "tasklet_schedule(&writer_bottomhalf)" to go to step 3)
>
> in computers with chipsets other than VIA the 4th step (interrupt
handler) is
> never executed.
>
> any ideas?
>
> thank
secondly alan cox respond with:
On Mon, 2005-12-19 at 18:03 +0000, Alan Cox wrote:
> > 2)kernel space write (generating the package that i want to send)
> >
> > 3)writer_bottomhalf (i have the package in writer_buffer indexed by a
> > bytes_send variable. Call
"outb(writer_buffer[bytes_send],MY_UART+UART_TX)" )
> >
> > 4)interrupt handler (bytes_send++ ,so i can send the next
character variable,
> > call "tasklet_schedule(&writer_bottomhalf)" to go to step 3)
> >
> > in computers with chipsets other than VIA the 4th step (interrupt
handler) is
> > never executed.
>
>
> Have you set up the interrupt enables in the 16x50 chip. If you've not
> done that step then it may depend on the vendor/BIOS what state the chip
> is in when you boot.
>
> You might want to print out the registers at boot on each system and
> look at the differences
in the initialization routine i enable the interrupts
"outb( UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI , eib_io+UART_IER);"
where eib_io = 0x03f8.
in the writer_bottomhalf i do:
//bytes_send :index to writer buffer which holds the package
//writer_length :length of the package i want to send
//foo :struct timeval for debugging reasons
if(bytes_send==writer_length){ // i have send the whole package
//starting timer to catch unacknowledged packages
}
else{
outb(writer[bytes_send],eib_io+UART_TX);
printk(KERN_ALERT"sending %x %ld %ld\n",
writer[bytes_send],foo.tv_sec,foo.tv_usec);
}
return;
and in interrupt handler
static void interrupt_handler(int irq, void *dev_id, struct pt_regs
*regs){
// code for other interrupts
if ( inb( eib_io + UART_LSR ) & ( UART_LSR_THRE) ){
bytes_send++;
tasklet_schedule(&writer_tasklet);
return;
}
}
so whenever the interrupt handler is calling i increase the bytes_send
and i return to writer_bottomhalf to send the next character of the
package. My question is that if there are differencies in the
implementation of the UARTS between VIA and other manufacturers?
I can't understand why this piece of shit is working only in VIA.
i use 2.4.31 compiled with the same .config except the processor's type
and chipset support in block devices section(linux serial driver
compiled as a module that i don't load at all).
i can't understand what registers to print during boot as alan proposed
the registers from 0x03f8 - 0x03ff (aka /dev/ttyS0)?
thanks and sorry for the length of the message...
P.S: do i have to send every email to linux-kernel@vger.kernel.org or to
linux-serial@vger.kernel.org
^ permalink raw reply [flat|nested] 7+ messages in thread
* selfmade serial driver problem with chipset other than VIA
@ 2005-12-19 21:42 gxatzipavlis
2005-12-19 22:08 ` linux-os (Dick Johnson)
0 siblings, 1 reply; 7+ messages in thread
From: gxatzipavlis @ 2005-12-19 21:42 UTC (permalink / raw)
To: linux-kernel
firstly i would like to apologize cause i send this mail to linux-kernel
mailling list and not to linux serial but linux-serial@vger.kernel.org
don't accept the email.
On Mon, 2005-12-19 at 18:12 +0200, giorgos xatzipavlis wrote:
> hello people
>
> this is my first attempt to the linux serial mailling list so i
> apologize for my mistakes...
>
> i am a newbie in kernel development.
>
> i have made a serial driver cause i want to communicate with a serial
device ( a microcontroller ). I have programmed the driver in my
computer and everything is working ok. I have an AMD 1000Hz, MSI
motherboard with VIA chipset and kernel 2.4.31. I have found
> informations from Linux Deveice Drivers book. Everything is working ok
in my computer but the driver isn't working in computers with INTEL and
NVIDIA chipsets. The fact that makes me suspicious about that
> is that although my driver is registered in /proc/interrupts
> and /proc/ioports (irq 4-ioport 0x03f8) when ever i call outb from my
writer bottomhalf routine the interrupt isn't generated from the
hardware(in machines with inter or nvidia chipset).
>
> the flow chart is somethink like that:
>
> 1)user space write (getting the data from user)
>
> 2)kernel space write (generating the package that i want to send)
>
> 3)writer_bottomhalf (i have the package in writer_buffer indexed by a
> bytes_send variable. Call
"outb(writer_buffer[bytes_send],MY_UART+UART_TX)" )
>
> 4)interrupt handler (bytes_send++ ,so i can send the next character
variable,
> call "tasklet_schedule(&writer_bottomhalf)" to go to step 3)
>
> in computers with chipsets other than VIA the 4th step (interrupt
handler) is
> never executed.
>
> any ideas?
>
> thank
secondly alan cox respond with:
On Mon, 2005-12-19 at 18:03 +0000, Alan Cox wrote:
> > 2)kernel space write (generating the package that i want to send)
> >
> > 3)writer_bottomhalf (i have the package in writer_buffer indexed by a
> > bytes_send variable. Call
"outb(writer_buffer[bytes_send],MY_UART+UART_TX)" )
> >
> > 4)interrupt handler (bytes_send++ ,so i can send the next
character variable,
> > call "tasklet_schedule(&writer_bottomhalf)" to go to step 3)
> >
> > in computers with chipsets other than VIA the 4th step (interrupt
handler) is
> > never executed.
>
>
> Have you set up the interrupt enables in the 16x50 chip. If you've not
done that step then it may depend on the vendor/BIOS what state the chip
is in when you boot.
>
> You might want to print out the registers at boot on each system and
look at the differences
in the initialization routine i enable the interrupts
"outb( UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI , eib_io+UART_IER);"
where eib_io = 0x03f8.
in the writer_bottomhalf i do:
//bytes_send :index to writer buffer which holds the package
//writer_length :length of the package i want to send
//foo :struct timeval for debugging reasons
if(bytes_send==writer_length){ // i have send the whole package
//starting timer to catch unacknowledged packages
}
else{
outb(writer[bytes_send],eib_io+UART_TX);
printk(KERN_ALERT"sending %x %ld %ld\n",
writer[bytes_send],foo.tv_sec,foo.tv_usec);
}
return;
and in interrupt handler
static void interrupt_handler(int irq, void *dev_id, struct pt_regs *regs){
// code for other interrupts
if ( inb( eib_io + UART_LSR ) & ( UART_LSR_THRE) ){
bytes_send++;
tasklet_schedule(&writer_tasklet);
return;
}
}
so whenever the interrupt handler is calling i increase the bytes_send and
i return to writer_bottomhalf to send the next character of the package.
My question is that if there are differencies in the
implementation of the UARTS between VIA and other manufacturers?
I can't understand why this piece of shit is working only in VIA.
i use 2.4.31 compiled with the same .config except the processor's type
and chipset support in block devices section(linux serial driver
compiled as a module that i don't load at all).
i can't understand what registers to print during boot as alan proposed
the registers from 0x03f8 - 0x03ff (aka /dev/ttyS0)?
thanks and sorry for the length of the message...
P.S: do i have to send every email to linux-kernel@vger.kernel.org or to
linux-serial@vger.kernel.org
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: selfmade serial driver problem with chipset other than VIA
2005-12-19 21:42 gxatzipavlis
@ 2005-12-19 22:08 ` linux-os (Dick Johnson)
0 siblings, 0 replies; 7+ messages in thread
From: linux-os (Dick Johnson) @ 2005-12-19 22:08 UTC (permalink / raw)
To: gxatzipavlis; +Cc: linux-kernel
On Mon, 19 Dec 2005 gxatzipavlis@softnet.tuc.gr wrote:
> firstly i would like to apologize cause i send this mail to linux-kernel
> mailling list and not to linux serial but linux-serial@vger.kernel.org
> don't accept the email.
>
> On Mon, 2005-12-19 at 18:12 +0200, giorgos xatzipavlis wrote:
>> hello people
>>
>> this is my first attempt to the linux serial mailling list so i
>> apologize for my mistakes...
>>
>> i am a newbie in kernel development.
>>
>> i have made a serial driver cause i want to communicate with a serial
> device ( a microcontroller ). I have programmed the driver in my
> computer and everything is working ok. I have an AMD 1000Hz, MSI
> motherboard with VIA chipset and kernel 2.4.31. I have found
>> informations from Linux Deveice Drivers book. Everything is working ok
> in my computer but the driver isn't working in computers with INTEL and
> NVIDIA chipsets. The fact that makes me suspicious about that
>> is that although my driver is registered in /proc/interrupts
>> and /proc/ioports (irq 4-ioport 0x03f8) when ever i call outb from my
> writer bottomhalf routine the interrupt isn't generated from the
> hardware(in machines with inter or nvidia chipset).
>>
>> the flow chart is somethink like that:
>>
>> 1)user space write (getting the data from user)
>>
>> 2)kernel space write (generating the package that i want to send)
>>
>> 3)writer_bottomhalf (i have the package in writer_buffer indexed by a
>> bytes_send variable. Call
> "outb(writer_buffer[bytes_send],MY_UART+UART_TX)" )
>>
>> 4)interrupt handler (bytes_send++ ,so i can send the next character
> variable,
>> call "tasklet_schedule(&writer_bottomhalf)" to go to step 3)
>>
>> in computers with chipsets other than VIA the 4th step (interrupt
> handler) is
>> never executed.
>>
>> any ideas?
>>
>> thank
>
>
> secondly alan cox respond with:
>
> On Mon, 2005-12-19 at 18:03 +0000, Alan Cox wrote:
>>> 2)kernel space write (generating the package that i want to send)
>>>
>>> 3)writer_bottomhalf (i have the package in writer_buffer indexed by a
>>> bytes_send variable. Call
> "outb(writer_buffer[bytes_send],MY_UART+UART_TX)" )
>>>
>>> 4)interrupt handler (bytes_send++ ,so i can send the next
> character variable,
>>> call "tasklet_schedule(&writer_bottomhalf)" to go to step 3)
>>>
>>> in computers with chipsets other than VIA the 4th step (interrupt
> handler) is
>>> never executed.
>>
>>
>> Have you set up the interrupt enables in the 16x50 chip. If you've not
> done that step then it may depend on the vendor/BIOS what state the chip
> is in when you boot.
>>
>> You might want to print out the registers at boot on each system and
> look at the differences
>
>
>
> in the initialization routine i enable the interrupts
>
> "outb( UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI , eib_io+UART_IER);"
>
> where eib_io = 0x03f8.
>
> in the writer_bottomhalf i do:
>
> //bytes_send :index to writer buffer which holds the package
> //writer_length :length of the package i want to send
> //foo :struct timeval for debugging reasons
>
> if(bytes_send==writer_length){ // i have send the whole package
>
> //starting timer to catch unacknowledged packages
>
> }
> else{
> outb(writer[bytes_send],eib_io+UART_TX);
> printk(KERN_ALERT"sending %x %ld %ld\n",
> writer[bytes_send],foo.tv_sec,foo.tv_usec);
> }
> return;
>
> and in interrupt handler
>
> static void interrupt_handler(int irq, void *dev_id, struct pt_regs *regs){
>
> // code for other interrupts
>
> if ( inb( eib_io + UART_LSR ) & ( UART_LSR_THRE) ){
>
> bytes_send++;
> tasklet_schedule(&writer_tasklet);
> return;
>
> }
>
> }
>
> so whenever the interrupt handler is calling i increase the bytes_send and
> i return to writer_bottomhalf to send the next character of the package.
> My question is that if there are differencies in the
> implementation of the UARTS between VIA and other manufacturers?
> I can't understand why this piece of shit is working only in VIA.
> i use 2.4.31 compiled with the same .config except the processor's type
> and chipset support in block devices section(linux serial driver
> compiled as a module that i don't load at all).
>
> i can't understand what registers to print during boot as alan proposed
> the registers from 0x03f8 - 0x03ff (aka /dev/ttyS0)?
>
> thanks and sorry for the length of the message...
>
> P.S: do i have to send every email to linux-kernel@vger.kernel.org or to
> linux-serial@vger.kernel.org
The 8250 and clones generate an interrupt when the TX buffer becomes
empty as well as when the RX buffer contains data. Becoming empty
implies that it must have had something in it. Therefore, you need
to put the first byte from a buffer into the TX buffer without
using interrupts after which your ISR will be able to take over.
A de facto standard way of doing this is to make a tx_send() routine
that can be called from both from the ISR and from the driver
write() routine. After user-mode data are written to a buffer,
the driver write() routine executes tx_send(). This will start
the ball rolling. The tx_send() code is written to handle the
buffer pointer(s) and to do nothing if there are no more data
available.
Cheers,
Dick Johnson
Penguin : Linux version 2.6.13.4 on an i686 machine (5589.56 BogoMips).
Warning : 98.36% of all statistics are fiction.
.
****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.
Thank you.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: selfmade serial driver problem with chipset other than VIA
2005-12-19 21:38 selfmade serial driver problem with chipset other than VIA gxatzipavlis
@ 2005-12-20 3:15 ` Paul Fulghum
0 siblings, 0 replies; 7+ messages in thread
From: Paul Fulghum @ 2005-12-20 3:15 UTC (permalink / raw)
To: gxatzipavlis; +Cc: linux-serial
gxatzipavlis@softnet.tuc.gr wrote:
>>the driver isn't working in computers with INTEL and
>>NVIDIA chipsets... when ever i call outb from my
>>writer bottomhalf routine the interrupt isn't generated from the
>>hardware(in machines with inter or nvidia chipset).
> ...
> i can't understand what registers to print during boot as alan proposed
> the registers from 0x03f8 - 0x03ff (aka /dev/ttyS0)?
If the Line Control Register (LCR) Divisor Latch Access Bit (DLAB)
is set, then offsets 0 and 1 access the divisor latch instead
of the transmit holding register (THR) and interrupt enable register (IER).
You do not state if you initialize that bit to zero.
If that bit is set, that could prevent the THR empty
interrupt you expect.
--
Paul Fulghum
Microgate Systems, Ltd
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: selfmade serial driver problem with chipset other than VIA
@ 2005-12-20 12:30 gxatzipavlis
0 siblings, 0 replies; 7+ messages in thread
From: gxatzipavlis @ 2005-12-20 12:30 UTC (permalink / raw)
To: linux-os; +Cc: linux-kernel
linux-os@analogic.com wrote:
> The 8250 and clones generate an interrupt when the TX buffer becomes
> empty as well as when the RX buffer contains data. Becoming empty
> implies that it must have had something in it. Therefore, you need
> to put the first byte from a buffer into the TX buffer without
> using interrupts after which your ISR will be able to take over.
>
> A de facto standard way of doing this is to make a tx_send() routine
> that can be called from both from the ISR and from the driver
> write() routine. After user-mode data are written to a buffer,
> the driver write() routine executes tx_send(). This will start
> the ball rolling. The tx_send() code is written to handle the
> buffer pointer(s) and to do nothing if there are no more data
> available.
i have such a routine called writer_bottomhalf. Is my bh function.
DECLARE_TASKLET(writer_tasklet,writer_bottomhalf,(unsigned
long)&status);
in write() function:
static ssize_t eib_write(struct file *file, const char *buf, size_t
count, loff_t *offset){
//adding header, checksum and ending character to the user data
tasklet_schedule(&writer_bottomhalf);
return bytes_read_from_user_space;
}
in writer_bottomhalf() function:
static void writer_bottomhalf(unsigned long data){
if(bytes_send==writer_length){
//init timer to check for acks
}
else{
outb(writer[bytes_send], eib_io+UART_TX); //eib_io=0x03f8
printk(KERN_INFO"sending %x\n",writer[bytes_send]);
}
}
in ISR function:
static void interrupt_handler(int irq, void *dev_id, struct pt_regs
*regs){
//do stuff for other interrupts
if ( inb( eib_io + UART_LSR ) & ( UART_LSR_THRE) ){
bytes_send++;
tasklet_schedule(&writer_bottomhalf);
}
}
so i call my bh function from my write() and from my ISR routines.
is their any difference if this routine is a bh or a plain routine as
long as they execute the same code?
paulkf@microgate.com wrote:
> If the Line Control Register (LCR) Divisor Latch Access Bit (DLAB)
> is set, then offsets 0 and 1 access the divisor latch instead
> of the transmit holding register (THR) and interrupt enable register >
> (IER).
>
> You do not state if you initialize that bit to zero.
> If that bit is set, that could prevent the THR empty
> interrupt you expect.
in the init_module function i do:
outb( UART_LCR_DLAB | UART_LCR_WLEN8 | UART_LCR_PARITY | UART_LCR_EPAR ,
eib_io + UART_LCR ); //dlab =1 serial init for 8E1
outb(0X06,eib_io+UART_DLL); //speed set to 19200
outb(0X00,eib_io+UART_DLM);
outb(inb( eib_io + UART_LCR ) & ~UART_LCR_DLAB,eib_io+UART_LCR); //unset
dlab
outb( UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI , eib_io
+UART_IER); //enabling interrupts
i am an unexperienced programmer and my code is awful and buggy but i
can't understand why is working only in my computer and not to any other
x86 machine...? that's why i suspect the chipset manufacturer (maybe the
have the serial address port in another address and not in 0x03f8 or
smth like this)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: selfmade serial driver problem with chipset other than VIA
@ 2006-01-17 14:07 gxatzipavlis
0 siblings, 0 replies; 7+ messages in thread
From: gxatzipavlis @ 2006-01-17 14:07 UTC (permalink / raw)
To: gxatzipavlis; +Cc: linux-serial
hello
a summary of my prob.
i have a problem communicating with serial port in low level programming.
i communicate with inb,outb with serial registers
in my computer everything is working fine. in other m/b with different
chipset my module doesn't work. i have a via kt133 chipset.
linux-os (Dick Johnson) <linux-os@analogic.com> had proposed me some
modifications in my module that i have done but they didn't solved my
problem.
i want a 8E1 format frames in 19200bps so i do
outb( UART_LCR_DLAB , eib_io + UART_LCR );
outb(0X06,eib_io+UART_DLL);
outb(0X00,eib_io+UART_DLM);
outb( 0x00 , eib_io + UART_LCR );
//19200 done
outb( UART_LCR_WLEN8 | UART_LCR_PARITY | UART_LCR_EPAR , eib_io + UART_LCR );
//8E1
outb( UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI , eib_io+UART_IER);
//interrupt when data for receive and when transmiter empty
now when for debuging purpose i print the UART_IIR i get 2 (means that
interrupt pending for transmiter register empty) and UART_IIR gets 1.
when i don't print the UART_IIR i expect to jump to my ISR routine that
has already been registered in the kernel according to "cat
/proc/interrupts" with IRQ 4 and I/O 0x03f8.
i don't have compiled the serial support in the kernel. i have it as a
module that i don't load it.
is there maybe any problem with the APIC controllers that i have to
program myself?
thanks
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-01-17 14:07 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-19 21:38 selfmade serial driver problem with chipset other than VIA gxatzipavlis
2005-12-20 3:15 ` Paul Fulghum
-- strict thread matches above, loose matches on Subject: below --
2006-01-17 14:07 gxatzipavlis
2005-12-20 12:30 gxatzipavlis
2005-12-19 21:42 gxatzipavlis
2005-12-19 22:08 ` linux-os (Dick Johnson)
[not found] <S964780AbVLSPVy/20051219152154Z+1140@vger.kernel.org>
2005-12-19 16:12 ` giorgos xatzipavlis
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.