Re: selfmade serial driver problem with chipset other than VIA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[email protected] 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?

[email protected] 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)


-
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/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux