hello ppl i have programed a kernel module for linux to communicate with devices through serial port. I don't use the linux serial layer abstraction cause i want to have a time-check timeout for byte to byte in the communication. So i use the inb,outb commands in my module. The problem is that my module is only running in my PC (amd athlon 1000 chipset via kt133a). in all other pc's although i can see in /proc/interrupts that my module is there e.x 4: 0 XT-PIC my_module when i send a character out to the serial port with outb my interrupt handler routine isn't executed. in the lab i use an old pentium 2 400 with intel 440bx chipset and it doesn't work. i have also tried in pc with sis and nvidia chipset and in all of them i have the same problem. Are the uart registers in all motherboards in the same addresses or this changes through manufacturer? thanks
kernel programming serial uart problem
Started by ●January 19, 2006
Reply by ●January 19, 20062006-01-19
gxatzipavlis wrote:> hello ppl > > i have programed a kernel module for linux to communicate with devices > through serial port. I don't use the linux serial layer abstraction cause > i want to have a time-check timeout for byte to byte in the communication. > So i use the inb,outb commands in my module. The problem is that my module > is only running in my PC (amd athlon 1000 chipset via kt133a). in all > other pc's although i can see in /proc/interrupts that my module is there > > e.x 4: 0 XT-PIC my_module > > when i send a character out to the serial port with outb my interrupt > handler routine isn't executed. in the lab i use an old pentium 2 400 with > intel 440bx chipset and it doesn't work. > i have also tried in pc with sis and nvidia chipset and in all of them i > have the same problem. Are the uart registers in all motherboards in the > same addresses or this changes through manufacturer?I assume that you do register the interrupts to the kernel correctly. There are four common address bases for serial chips in PC: - 0x2e8 - 0x2f8 - 0x3e8 - 0x3f8 The commonly used interrupts are 3 and 4. For PCI-based interfaces you have to read the addresses from the PCi configuration space. To have a look: cat /proc/pci HTH -- Tauno Voipio tauno voipio (at) iki fi
Reply by ●January 19, 20062006-01-19
On Thu, 19 Jan 2006 17:26:38 +0000, Tauno Voipio wrote:> gxatzipavlis wrote: >> hello ppl >> >> i have programed a kernel module for linux to communicate with devices >> through serial port. I don't use the linux serial layer abstraction cause >> i want to have a time-check timeout for byte to byte in the communication. >> So i use the inb,outb commands in my module. The problem is that my module >> is only running in my PC (amd athlon 1000 chipset via kt133a). in all >> other pc's although i can see in /proc/interrupts that my module is there >> >> e.x 4: 0 XT-PIC my_module >> >> when i send a character out to the serial port with outb my interrupt >> handler routine isn't executed. in the lab i use an old pentium 2 400 with >> intel 440bx chipset and it doesn't work. >> i have also tried in pc with sis and nvidia chipset and in all of them i >> have the same problem. Are the uart registers in all motherboards in the >> same addresses or this changes through manufacturer? > > I assume that you do register the interrupts to > the kernel correctly. > > There are four common address bases for serial chips in PC: > > - 0x2e8 > - 0x2f8 > - 0x3e8 > - 0x3f8 > > The commonly used interrupts are 3 and 4. > > For PCI-based interfaces you have to read the addresses > from the PCi configuration space. To have a look: > > cat /proc/pci > > HTHi do all the necessery work. the fact is that it works in my pc so i register interrupts. i use the 03f8/4 io_base/irq combination. I have tried with serial support on and off from kernel and it works so my driver doesn't infect the kernel if it has serial support. static int driver_init_module(void){ ... request_region(eib_io, BYTE , eib_dev); //eib_io=0x03f8 BYTE=8 eib_dev=eib0 //eib_irq=4 retval = request_irq(eib_irq,interrupt_handler,SA_INTERRUPT,eib_dev,NULL); if(retval) { release_region(eib_io, BYTE); return retval; } //eib_major=61 experimental eib_node=/dev/eib0 retval = register_chrdev( eib_major , eib_node , &eib_fops ); if(retval<0) { release_region( eib_io, BYTE ); free_irq(eib_irq, NULL); return retval; } init_serial(); ... } static void init_serial(void){ outb( UART_LCR_DLAB , eib_io + UART_LCR ); //set d_lab outb(0X06,eib_io+UART_DLL); outb(0X00,eib_io+UART_DLM); //set_baud 19200 outb( 0x00 , eib_io + UART_LCR ); //unset dlab outb(UART_LCR_WLEN8|UART_LCR_PARITY|UART_LCR_EPAR,eib_io+UART_LCR); //set 8E1 for the communication outb( UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI , eib_io+UART_IER); //set receive and transmit interrupts outb( 0x00 ,eib_io+UART_FCR ); //no fifo //printk(KERN_INFO"%d %d\n",inb(eib_io+UART_IIR),inb(eib_io+UART_IIR)); } if i insmod the module the interrupt is registered and can be seen from the proc file system in my PC after init_serial() executed, the uart transmiter has no data, so it generates an interrupt. ISR routine is then executed and continue... in other pc after init_serial() executed the ISR routine isn't executed for the very simple reason that the uart hasn't interrupt the cpu. if i printk the UART_IIR register 2 times (in comments) i get 2 1 which means that the first time interrupt was pending and in the first time that no interrupt is pending.So i guess that uart has send the interrupt but the cpu hasn't been interrupted... any ideas?
Reply by ●January 19, 20062006-01-19
gxatzipavlis wrote:> On Thu, 19 Jan 2006 17:26:38 +0000, Tauno Voipio wrote: > > >>gxatzipavlis wrote: > > i do all the necessery work. the fact is that it works in my pc so i > register interrupts. i use the 03f8/4 io_base/irq combination. I have > tried with serial support on and off from kernel and it works so my driver > doesn't infect the kernel if it has serial support. >Good ... I'd next try the 0x2f8 / 3 combination. -- Tauno Voipio tauno voipio (at) iki fi
Reply by ●January 19, 20062006-01-19
gxatzipavlis wrote:> when i send a character out to the serial port with outb my interrupt > handler routine isn't executed.You didn't forget to set OUT2 in the MCR register? (that is used to gate the IRQ line on standard PC platforms) -- Wil
Reply by ●January 19, 20062006-01-19
Have you turned on the OUT2 line on the UART? In PC architecture this is used as a gate for the UART interrupt sources. It's bit 3 of the Modem Control Register. There are a few chipsets that don't honour this scheme - but I think most do. Regards.
Reply by ●January 20, 20062006-01-20
On Thu, 19 Jan 2006 23:44:38 +0000, Alfie wrote:> > > Have you turned on the OUT2 line on the UART? In PC architecture this > is used as a gate for the UART interrupt sources. It's bit 3 of the > Modem Control Register. > > There are a few chipsets that don't honour this scheme - but I think > most do. > > Regards.my friend u save me!!!!!!!!!!!!!!!!!! i spend 1,5 month in that stupid think!!! another time i should read the specs with more attention by the way do u know in what i/o chips the out2 works and in what it don't?