This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
MPC860: quicc_smc_serial_driver change
- From: nprasad3 at gmu dot edu
- To: ecos-patches at ecos dot sourceware dot org
- Date: Wed, 07 Jan 2004 13:55:50 -0500
- Subject: MPC860: quicc_smc_serial_driver change
Hi,
I am not sure if this is the correct format for patch submission. If not please let me know and I'll send it in the correct format.
Issue: [BUF_SIZE : 0, *polling* mode]
------------------------------------------------------
1. putc starts filling in the buffer (after the buffer is full, txbd->length is beyond smc_chan->txsize) and flush routine keeps getting called.
2. txbd->length gets reset only in the interrupt handler (*which was never set because outbound buffer length is 0*) and hence this never takes place.
The following change allows use of 1 buffer, buffer is marked to be sent and then we just wait and reset the length.
Nirmal
---------------------------------------------------------------------------------
--- quicc_smc_serial-old.c 2003-03-20 13:48:28.000000000 -0500
+++ quicc_smc_serial.c 2004-01-07 13:52:57.265625000 -0500
@@ -512,38 +512,66 @@ quicc_smc_serial_flush(quicc_smc_serial_
// Send a character to the device output buffer.
// Return 'true' if character is sent to device
static bool
-quicc_smc_serial_putc(serial_channel *chan, unsigned char c)
+quicc_sxx_serial_putc(serial_channel *chan, unsigned char c)
{
- quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;
+ quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;
volatile struct cp_bufdesc *txbd, *txfirst;
+ volatile struct smc_uart_pram *pram = (volatile struct smc_uart_pram *)smc_chan->pram;
EPPC *eppc = eppc_base();
bool res;
+
cyg_drv_dsr_lock(); // Avoid race condition testing pointers
- txbd = (struct cp_bufdesc *)((char *)eppc + smc_chan->pram->tbptr);
- txfirst = txbd;
- // Scan for a non-busy buffer
- while (txbd->ctrl & QUICC_BD_CTL_Ready) {
- // This buffer is busy, move to next one
- if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
- txbd = smc_chan->tbase;
- } else {
- txbd++;
- }
- if (txbd == txfirst) break; // Went all the way around
- }
- smc_chan->txbd = txbd;
- if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0) {
- // Transmit buffer is not full/busy
- txbd->buffer[txbd->length++] = c;
- if (txbd->length == smc_chan->txsize) {
- // This buffer is now full, tell SMC to start processing it
- quicc_smc_serial_flush(smc_chan);
- }
- res = true;
- } else {
- // No space
- res = false;
- }
+ txbd = (struct cp_bufdesc *)((char *)eppc + pram->tbptr);
+
+ /*-- NP (Polling) --*/
+ if(chan->out_cbuf.len == 0) {
+ if(txbd->ctrl & QUICC_BD_CTL_Ready) {
+ // no space in buffer
+ res = false;
+ } else {
+ // add character to buffer
+ res = true;
+ txbd->buffer[txbd->length++] = c;
+ if(txbd->length == smc_chan->txsize) {
+ // This buffer is now full, tell SMC to start processing it
+ quicc_sxx_serial_flush(smc_chan);
+ // wait for buffer to be sent
+ while(txbd->ctrl & QUICC_BD_CTL_Ready);
+ // reset interrupt bit
+ txbd->ctrl &= ~QUICC_BD_CTL_Int;
+ // reset length
+ txbd->length = 0;
+ }
+ }
+ } else {
+ txfirst = txbd;
+
+ // Scan for a non-busy buffer
+ while (txbd->ctrl & QUICC_BD_CTL_Ready) {
+ // This buffer is busy, move to next one
+ if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
+ txbd = smc_chan->tbase;
+ } else {
+ txbd++;
+ }
+ if (txbd == txfirst) break; // Went all the way around
+ }
+ smc_chan->txbd = txbd;
+ if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0) {
+ // Transmit buffer is not full/busy
+ txbd->buffer[txbd->length++] = c;
+ if (txbd->length == smc_chan->txsize) {
+ // This buffer is now full, tell SMC to start processing it
+ quicc_sxx_serial_flush(smc_chan);
+ }
+ res = true;
+ } else {
+ // No space
+ res = false;
+ }
+ }
+ /*-- NP (Polling) --*/
+
cyg_drv_dsr_unlock();
return res;
}