I have just tested your patch on 8260 and it fixes the problem when printk is called from interrupt context while data is printed from user mode application. GREAT!
I also ported the patch to 860 (as said earlier, code is almost the same), but it hung at boot up, just after printing "Calibrating delay loop..." :-(
I remember I had such problems in the past (on 860), when calling "spin_lock_irqsave/restore" from interrupt context. If I use function "in_interrupt()" to avoid calling them from interrupt, everything works fine, and the bug is effectively fixed.
I just don't know where is the problem??? It looks like there is a bug on 860 using "local_irq_save/restore" in interrupt context?!?
I'm working with 2.4.19.
--------------------------------------------
Jean-Denis Boyer, Eng.
Software Designer
M5T Centre d'Excellence en Télécom Inc.
4283 Garlock Street
Sherbrooke (Québec)
J1L 2C8 CANADA
(819)829-3972 x241
--------------------------------------------
-----Original Message-----
From: Steffen Rumler [mailto:Steffen.Rumler@siemens.com]
Sent: 15 septembre, 2003 06:18
To: linuxppc
Subject: Re: Problem of concurrency in arch/ppc/8260_io/uart.c
Hi,
I have seen a similar problem for the 2.4.20.
When I force a lot of console output via the following command:
while true; do cd /; ls -R; done
and type-in some letters in parallel, the console
becomes crazy.
I have added some instrumentation in order to dump the
TX Buffer Descriptor Table. I have found that the
hardware pointer (TBPTR) and the software pointer (tx_cur)
are not more synchronized together:
>> make new rlogin session <<
/root# cd /proc/driver
/root# cat uart-bdtables; cat mpc82xx/smc1_pram | grep SMC1_PRAM_TBPTR
TX BD table
(000 at 0xfff005f0) status: 0x1000 len: 0001 addr: 0x001bb084
(001 at 0xfff005f8) status: 0x1000 len: 0001 addr: 0x001bb0a4
* (002 at 0xfff00600) status: 0x1000 len: 0001 addr: 0x001bb0c4
(003 at 0xfff00608) status: 0x3000 len: 0004 addr: 0x001bb0e4
SMC1_PRAM_TBPTR 0x20 2 0600
--> hardware and software pointer still synchronized
>> force console to become crazy (see above) <<
/root# cat uart-bdtables; cat mpc82xx/smc1_pram | grep SMC1_PRAM_TBPTR
TX BD table (tbptr: 0x00000088)
(000 at 0xfff005f0) status: 0x1000 len: 0003 addr: 0x001bb084
* (001 at 0xfff005f8) status: 0x1000 len: 0021 addr: 0x001bb0a4
(002 at 0xfff00600) status: 0x1000 len: 0001 addr: 0x001bb0c4
(003 at 0xfff00608) status: 0x3000 len: 0001 addr: 0x001bb0e4
SMC1_PRAM_TBPTR 0x20 2 0600
--> hardware and software pointer NOT more synchronized
>> make additional console output: echo foo >/dev/console <<
/root# cat uart-bdtables; cat mpc82xx/smc1_pram | grep SMC1_PRAM_TBPTR
* (000 at 0xfff005f0) status: 0x1000 len: 0003 addr: 0x001bb084
(001 at 0xfff005f8) status: 0x9000 len: 0004 addr: 0x001bb0a4
(002 at 0xfff00600) status: 0x1000 len: 0001 addr: 0x001bb0c4
(003 at 0xfff00608) status: 0x3000 len: 0001 addr: 0x001bb0e4
SMC1_PRAM_TBPTR 0x20 2 05f0
--> hardware pointer hangs at 0x5f0 because R-Bit not set, but
at 0x5f8
Inside uart.c, there are the following output routines:
rs_8xx_put_char()
rs_8xx_write()
rs_8xx_send_xchar()
my_console_write()
I think there must be a synchronization accessing the
TX BD table. I suggest the patch attached.
Best Regards
Steffen
--
--------------------------------------------------------------
Steffen Rumler
ICN CP D NT SW 7
Siemens AG
Hofmannstr. 51 Email: Steffen.Rumler@siemens.com
D-81359 Munich Phone: +49 89 722-44061
Germany Fax : +49 89 722-36703
--------------------------------------------------------------
I have just tested your patch on 8260 and it fixes the problem when printk is called from interrupt context while data is
printed from user mode application. GREAT!
I also ported the patch to 860 (as said earlier, code is almost the same), but it hung at boot up, just after printing
"Calibrating delay loop..." :-(
I remember I had such problems in the past (on 860), when calling "spin_lock_irqsave/restore" from interrupt context. If
I use function "in_interrupt()" to avoid calling them from interrupt, everything works fine, and the bug is effectively fixed.
I just don't know where is the problem??? It looks like there is a bug on 860 using "local_irq_save/restore" in interrupt
context?!?
The patch is a little broken w.r.t my_console_write, the last "if(info)" should be a
"if(ser->info)". Don't know why it works on 82xx as is, it should not.
However, this patch also adds lots of IRQ latency. I think the idea is right, but one must
reduce time with IRQ's off. It looks easy for all functions, but not for my_console_write()
Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
From: Dan Malek <hidden> Date: 2003-09-15 18:53:56
Jean-Denis Boyer wrote:
I have just tested your patch on 8260 and it fixes the problem when printk is called ...
The use of printk is strictly a debug function. If it is necessary to see
it print out pretty, then use a different I/O path for the application or
dump out the log buffer separately. Serial ports don't guarantee any
transactional operation with multiple users, printk isn't any different
although it does the bad thing of blocking interrupts while it processes
the message.
Adding this patch adds lots of interrupt latency and I would recommend
against it. It appears there is a bug that should be fixed to ensure
the proper synchronization of the BDs, but not with such large scale
blocking of interrupts.
Thanks.
-- Dan
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
I have just tested your patch on 8260 and it fixes the problem when printk is called ...
The use of printk is strictly a debug function. If it is necessary to see
it print out pretty, then use a different I/O path for the application or
dump out the log buffer separately. Serial ports don't guarantee any
transactional operation with multiple users, printk isn't any different
although it does the bad thing of blocking interrupts while it processes
the message.
hmm, it does not block interrupts as is, does it? Only if you apply the patch?
Adding this patch adds lots of interrupt latency and I would recommend
against it. It appears there is a bug that should be fixed to ensure
the proper synchronization of the BDs, but not with such large scale
blocking of interrupts.
Agreed, but is there another mechanism but to disable interrupts? I can't think of any.
It is possible to shrink the window with interrupts off dramatically.
Jocke
I have just tested your patch on 8260 and it fixes the problem when printk is called ...
The use of printk is strictly a debug function. If it is necessary to see
it print out pretty, then use a different I/O path for the application or
dump out the log buffer separately. Serial ports don't guarantee any
transactional operation with multiple users, printk isn't any different
although it does the bad thing of blocking interrupts while it processes
the message.
hmm, it does not block interrupts as is, does it? Only if you apply the patch?
quoted
Adding this patch adds lots of interrupt latency and I would recommend
against it. It appears there is a bug that should be fixed to ensure
the proper synchronization of the BDs, but not with such large scale
blocking of interrupts.
Agreed, but is there another mechanism but to disable interrupts? I can't think of any.
It is possible to shrink the window with interrupts off dramatically.
Jocke
quoted
Thanks.
-- Dan
OK, here is my attempt to fix the 8xx uart driver. With this
patch I can no longer break the console from user space. Against fairly recent
linuxppc_devel snapshot. Please comment/apply.
Summary:
- uses local_irq_save()/local_irq_restore() around tx_cur accesses.
I haved tried to minimize the time between local_irq_save() and local_irq_restore()
- Fixed a bug around copy_from_user() in rs_8xx_write().
- my_console_write() is still buggy. It takes a little more effort to fix
this function. It should be fixed since a spurious printk can screw/lock your console.
- fixed 4 trivial warnings as well.
Jocke
Index: arch/ppc/8xx_io/uart.c
===================================================================
RCS file: /home/cvsadmin/cvsroot/kernel/linuxppc/arch/ppc/8xx_io/uart.c,v
retrieving revision 1.7
diff -u -r1.7 uart.c
@@ -1075,7 +1076,16 @@if(!tty)return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);+while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);
@@ -1083,14 +1093,6 @@bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;-/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;--info->tx_cur=(cbd_t*)bdp;}staticintrs_8xx_write(structtty_struct*tty,intfrom_user,
@@ -1100,6 +1102,7 @@ser_info_t*info=(ser_info_t*)tty->driver_data;volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;#ifdef CONFIG_KGDB_CONSOLE/* Try to let stub handle output. Returns true if it did. */
@@ -1113,44 +1116,46 @@if(!tty)return0;-bdp=info->tx_cur;-while(1){c=MIN(count,TX_BUF_SIZE);if(c<=0)break;+local_irq_save(flags);+bdp=info->tx_cur;if(bdp->cbd_sc&BD_SC_READY){info->flags|=TX_WAKEUP;+local_irq_restore(flags);break;}cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);if(from_user){-if(copy_from_user((void*)cp,buf,c)){+c-=copy_from_user((void*)cp,buf,c);+if(!c){if(!ret)ret=-EFAULT;+local_irq_restore(flags);break;}}else{memcpy((void*)cp,buf,c);}-+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);+bdp->cbd_datlen=c;bdp->cbd_sc|=BD_SC_READY;buf+=c;count-=c;ret+=c;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;-info->tx_cur=(cbd_t*)bdp;}returnret;}
@@ -1210,28 +1215,28 @@{volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;ser_info_t*info=(ser_info_t*)tty->driver_data;if(serial_paranoia_check(info,tty->device,"rs_send_char"))return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);*cp=ch;bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;--info->tx_cur=(cbd_t*)bdp;}/*
@@ -3073,10 +3082,10 @@bdp->cbd_bufaddr=iopa(mem_addr);(bdp+1)->cbd_bufaddr=iopa(mem_addr+4);-consinfo.rx_va_base=mem_addr;-consinfo.rx_bd_base=bdp;-consinfo.tx_va_base=mem_addr+4;-consinfo.tx_bd_base=bdp+1;+consinfo.rx_va_base=(unsignedchar*)mem_addr;+consinfo.rx_bd_base=(cbd_t*)bdp;+consinfo.tx_va_base=(unsignedchar*)(mem_addr+4);+consinfo.tx_bd_base=(cbd_t*)(bdp+1);/* For the receive, set empty and wrap.*Fortransmit,setwrap.
OK, here is my attempt to fix the 8xx uart driver. With this
patch I can no longer break the console from user space. Against fairly recent
linuxppc_devel snapshot. Please comment/apply.
Summary:
- uses local_irq_save()/local_irq_restore() around tx_cur accesses.
I haved tried to minimize the time between local_irq_save() and local_irq_restore()
- Fixed a bug around copy_from_user() in rs_8xx_write().
- my_console_write() is still buggy. It takes a little more effort to fix
this function. It should be fixed since a spurious printk can screw/lock your console.
I am taking a stab at my_console_write() as well. I have something that works well
for me, but i am unsure if I have broken KGDB/XMON support. In my new my_console_write()
I must know the length of the TX buffer in the TXBD. The TX buffer length when the console
is fully operational is TX_BUF_SIZE. Before that, in serial_console_setup, the length
is 4 bytes. But what is the TX buffer length before serial_console_setup has run(that's
when KGB/XMON is active)?
Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
OK, here is my attempt to fix the 8xx uart driver. With this
patch I can no longer break the console from user space. Against fairly recent
linuxppc_devel snapshot. Please comment/apply.
Summary:
- uses local_irq_save()/local_irq_restore() around tx_cur accesses.
I haved tried to minimize the time between local_irq_save() and local_irq_restore()
- Fixed a bug around copy_from_user() in rs_8xx_write().
- my_console_write() is still buggy. It takes a little more effort to fix
this function. It should be fixed since a spurious printk can screw/lock your console.
I am taking a stab at my_console_write() as well. I have something that works well
for me, but i am unsure if I have broken KGDB/XMON support. In my new my_console_write()
I must know the length of the TX buffer in the TXBD. The TX buffer length when the console
is fully operational is TX_BUF_SIZE. Before that, in serial_console_setup, the length
is 4 bytes. But what is the TX buffer length before serial_console_setup has run(that's
when KGB/XMON is active)?
Jocke
Here is a version that fixes my_console_write as well. The KGDB/XMON question above is still open.
Currently TX buffer length assumption is >=4
Anyone intressted?
Jocke
Index: arch/ppc/8xx_io/uart.c
===================================================================
RCS file: /home/cvsadmin/cvsroot/kernel/linuxppc/arch/ppc/8xx_io/uart.c,v
retrieving revision 1.7
diff -u -r1.7 uart.c
@@ -1075,7 +1076,16 @@if(!tty)return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);+while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);
@@ -1083,14 +1093,6 @@bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;-/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;--info->tx_cur=(cbd_t*)bdp;}staticintrs_8xx_write(structtty_struct*tty,intfrom_user,
@@ -1100,6 +1102,7 @@ser_info_t*info=(ser_info_t*)tty->driver_data;volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;#ifdef CONFIG_KGDB_CONSOLE/* Try to let stub handle output. Returns true if it did. */
@@ -1113,44 +1116,46 @@if(!tty)return0;-bdp=info->tx_cur;-while(1){c=MIN(count,TX_BUF_SIZE);if(c<=0)break;+local_irq_save(flags);+bdp=info->tx_cur;if(bdp->cbd_sc&BD_SC_READY){info->flags|=TX_WAKEUP;+local_irq_restore(flags);break;}cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);if(from_user){-if(copy_from_user((void*)cp,buf,c)){+c-=copy_from_user((void*)cp,buf,c);+if(!c){if(!ret)ret=-EFAULT;+local_irq_restore(flags);break;}}else{memcpy((void*)cp,buf,c);}-+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);+bdp->cbd_datlen=c;bdp->cbd_sc|=BD_SC_READY;buf+=c;count-=c;ret+=c;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;-info->tx_cur=(cbd_t*)bdp;}returnret;}
@@ -1210,28 +1215,28 @@{volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;ser_info_t*info=(ser_info_t*)tty->driver_data;if(serial_paranoia_check(info,tty->device,"rs_send_char"))return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);*cp=ch;bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;--info->tx_cur=(cbd_t*)bdp;}/*
@@ -2273,40 +2283,41 @@*wesimplyusethesinglebufferallocated.*/if((info=(ser_info_t*)ser->info)!=NULL){-bdp=info->tx_cur;bdbase=info->tx_bd_base;-}-else{-/* Pointer to UART in parameter ram.-*/+max_tx_size=TX_BUF_SIZE;+}else{+/* Pointer to UART in parameter ram. */up=(smc_uart_t*)&cpmp->cp_dparam[ser->port];--/* Get the address of the host memory buffer.-*/-bdp=bdbase=(cbd_t*)&cpmp->cp_dpmem[up->smc_tbase];+/* Get the address of the host memory buffer.*/info=&consinfo;+info->tx_bd_base=(cbd_t*)bdbase=(cbd_t*)&cpmp->cp_dpmem[up->smc_tbase];+info->tx_cur=(cbd_t*)bdbase;+max_tx_size=4;/* Early serial acces has this */}-/*-*Weneedtogracefullyshutdownthetransmitter,disable-*interrupts,thensendourbytesout.-*/+cr_missing=0;+while(1){+c=MIN(max_tx_size,count);+if(c<=0)+break;-/*-*Now,doeachcharacter.Thisisnotasbadasitlooks-*sincethisisaholdingFIFOandnotatransmittingFIFO.-*Wecouldaddthecomplexityoffillingtheentiretransmit-*buffer,butwewouldjustwaitlongerbetweenaccesses......-*/-for(i=0;i<count;i++,s++){+local_irq_save(flags);+bdp=info->tx_cur;+bdbase=info->tx_bd_base;+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=(cbd_t*)bdbase;+else+info->tx_cur=(cbd_t*)(bdp+1);+local_irq_restore(flags);+/* Wait for transmitter fifo to empty.*Readyindicatesoutputisready,andxmtisdoing*that,notthatitisreadyforustosend.*/while(bdp->cbd_sc&BD_SC_READY);-/* Send the character out.+/* Send the characters out.*IfthebufferaddressisintheCPMDPRAM,don't*convertit.*/
@@ -2314,55 +2325,32 @@cp=(u_char*)(bdp->cbd_bufaddr);elsecp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);-*cp=*s;--bdp->cbd_datlen=1;-bdp->cbd_sc|=BD_SC_READY;--if(bdp->cbd_sc&BD_SC_WRAP)-bdp=bdbase;-else-bdp++;--/* if a LF, also do CR... */-if(*s==10){-while(bdp->cbd_sc&BD_SC_READY);--/* This 'if' below will never be true, but a few-*peoplearguedwithmethatitwasa"bug by-*inspection" that is was easier to add the code-*thancontinuethediscussion.Theonlytime-*thebufferaddressisinDPRAMisduringearly-*usebykgdb/xmon,whichformattheirownpackets-*andwenevergethere.--Dan-*/-if((uint)(bdp->cbd_bufaddr)>(uint)IMAP_ADDR)-cp=(u_char*)(bdp->cbd_bufaddr);-else-cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);-*cp=13;-bdp->cbd_datlen=1;-bdp->cbd_sc|=BD_SC_READY;-if(bdp->cbd_sc&BD_SC_WRAP){-bdp=bdbase;-}-else{-bdp++;-}+i=1;/* Keeps track of consumed TX buffer space */+if(cr_missing){+/* Previus loop didn't have room for the CR, insert it first in this */+*cp++='\r';+i++;}-}--/*-*Finally,Waitfortransmitter&holdingregistertoempty-*andrestoretheIER-*/-while(bdp->cbd_sc&BD_SC_READY);+cr_missing=0;+for(;i<=c;i++){+if((*cp++=*s++)!='\n')+continue;/* Copy bytes until a NewLine is found */+/* NewLine found, see if there is space in the TX buffer to add a CR */+if(i<max_tx_size){+*cp++='\r';/* yes, there is space to add a CR */+i++;+}else+cr_missing=1;/* No space in the TX buffer,+remberitsoitcanbeinsertedinthenextloop*/+}+count-=(c-cr_missing);+bdp->cbd_datlen=i-1;+bdp->cbd_sc|=BD_SC_READY;-if(info)-info->tx_cur=(cbd_t*)bdp;+}+/* while (bdp->cbd_sc & BD_SC_READY); is this really needed? */}-staticvoidserial_console_write(structconsole*c,constchar*s,unsignedcount){
@@ -3073,10 +3061,10 @@bdp->cbd_bufaddr=iopa(mem_addr);(bdp+1)->cbd_bufaddr=iopa(mem_addr+4);-consinfo.rx_va_base=mem_addr;-consinfo.rx_bd_base=bdp;-consinfo.tx_va_base=mem_addr+4;-consinfo.tx_bd_base=bdp+1;+consinfo.rx_va_base=(unsignedchar*)mem_addr;+consinfo.rx_bd_base=(cbd_t*)bdp;+consinfo.tx_va_base=(unsignedchar*)(mem_addr+4);+consinfo.tx_bd_base=(cbd_t*)(bdp+1);/* For the receive, set empty and wrap.*Fortransmit,setwrap.
From: Dan Malek <hidden> Date: 2003-09-17 14:58:36
Joakim Tjernlund wrote:
I am taking a stab at my_console_write() as well. I have something that works well
for me, but i am unsure if I have broken KGDB/XMON support.
You better check it. The reason for all of the complexity in there is to
support that. Lots of time was spent making kgdb/xmon work correctly, and
to break it or toss it away would kinda piss me off.
....In my new my_console_write()
I must know the length of the TX buffer in the TXBD.
Why?
...But what is the TX buffer length before serial_console_setup has run(that's
when KGB/XMON is active)?
Whatever the boot rom initializes.
-- Dan
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
I am taking a stab at my_console_write() as well. I have something that works well
for me, but i am unsure if I have broken KGDB/XMON support.
You better check it. The reason for all of the complexity in there is to
support that. Lots of time was spent making kgdb/xmon work correctly, and
to break it or toss it away would kinda piss me off.
Yes, so much I already figured :). I am trying to get it right. Care to test KGDB/XMON
when i am done?
quoted
....In my new my_console_write()
I must know the length of the TX buffer in the TXBD.
Why?
I don't want to disable interrupts for every char transmitted. I therefore fill
the TX BD as much as possible and that is why I need to know the length of the TX buffer.
quoted
...But what is the TX buffer length before serial_console_setup has run(that's
when KGB/XMON is active)?
Whatever the boot rom initializes.
OK, then I will assume TX buffer length of 1, until serial_console_setup has run and
initialize it to 4.
Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
OK, then I will assume TX buffer length of 1, until serial_console_setup has run and
initialize it to 4.
Jocke
Here we go again. This patch adds the above. I am unable to break it, please try to :)
Index: arch/ppc/8xx_io/uart.c
===================================================================
RCS file: /home/cvsadmin/cvsroot/kernel/linuxppc/arch/ppc/8xx_io/uart.c,v
retrieving revision 1.7
diff -u -r1.7 uart.c
@@ -81,7 +81,11 @@#define TX_WAKEUP ASYNC_SHARE_IRQstaticchar*serial_name="CPM UART driver";-staticchar*serial_version="0.03";+staticchar*serial_version="0.04";++/* TX buffer length used by my_console_write.+Assumeminumunlengthuntilitgetssetbythisdriver*/+staticintconsole_tx_buf_len=1;staticDECLARE_TASK_QUEUE(tq_serial);
@@ -196,6 +200,7 @@/* The number of buffer descriptors and their sizes.*/+#define EARLY_BUF_SIZE 4#define RX_NUM_FIFO 4#define RX_BUF_SIZE 32#define TX_NUM_FIFO 4
@@ -1075,7 +1081,16 @@if(!tty)return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);+while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);
@@ -1083,14 +1098,6 @@bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;-/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;--info->tx_cur=(cbd_t*)bdp;}staticintrs_8xx_write(structtty_struct*tty,intfrom_user,
@@ -1100,6 +1107,7 @@ser_info_t*info=(ser_info_t*)tty->driver_data;volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;#ifdef CONFIG_KGDB_CONSOLE/* Try to let stub handle output. Returns true if it did. */
@@ -1113,44 +1121,46 @@if(!tty)return0;-bdp=info->tx_cur;-while(1){c=MIN(count,TX_BUF_SIZE);if(c<=0)break;+local_irq_save(flags);+bdp=info->tx_cur;if(bdp->cbd_sc&BD_SC_READY){info->flags|=TX_WAKEUP;+local_irq_restore(flags);break;}cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);if(from_user){-if(copy_from_user((void*)cp,buf,c)){+c-=copy_from_user((void*)cp,buf,c);+if(!c){if(!ret)ret=-EFAULT;+local_irq_restore(flags);break;}}else{memcpy((void*)cp,buf,c);}-+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);+bdp->cbd_datlen=c;bdp->cbd_sc|=BD_SC_READY;buf+=c;count-=c;ret+=c;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;-info->tx_cur=(cbd_t*)bdp;}returnret;}
@@ -1210,28 +1220,28 @@{volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;ser_info_t*info=(ser_info_t*)tty->driver_data;if(serial_paranoia_check(info,tty->device,"rs_send_char"))return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);*cp=ch;bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;--info->tx_cur=(cbd_t*)bdp;}/*
@@ -2273,40 +2288,39 @@*wesimplyusethesinglebufferallocated.*/if((info=(ser_info_t*)ser->info)!=NULL){-bdp=info->tx_cur;bdbase=info->tx_bd_base;-}-else{-/* Pointer to UART in parameter ram.-*/+}else{+/* Pointer to UART in parameter ram. */up=(smc_uart_t*)&cpmp->cp_dparam[ser->port];--/* Get the address of the host memory buffer.-*/-bdp=bdbase=(cbd_t*)&cpmp->cp_dpmem[up->smc_tbase];+/* Get the address of the host memory buffer.*/info=&consinfo;+info->tx_bd_base=(cbd_t*)bdbase=(cbd_t*)&cpmp->cp_dpmem[up->smc_tbase];+info->tx_cur=(cbd_t*)bdbase;}+max_tx_size=console_tx_buf_len;+cr_missing=0;+while(1){+c=MIN(max_tx_size,count);+if(c<=0)+break;-/*-*Weneedtogracefullyshutdownthetransmitter,disable-*interrupts,thensendourbytesout.-*/--/*-*Now,doeachcharacter.Thisisnotasbadasitlooks-*sincethisisaholdingFIFOandnotatransmittingFIFO.-*Wecouldaddthecomplexityoffillingtheentiretransmit-*buffer,butwewouldjustwaitlongerbetweenaccesses......-*/-for(i=0;i<count;i++,s++){+local_irq_save(flags);+bdp=info->tx_cur;+bdbase=info->tx_bd_base;+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=(cbd_t*)bdbase;+else+info->tx_cur=(cbd_t*)(bdp+1);+local_irq_restore(flags);+/* Wait for transmitter fifo to empty.*Readyindicatesoutputisready,andxmtisdoing*that,notthatitisreadyforustosend.*/while(bdp->cbd_sc&BD_SC_READY);-/* Send the character out.+/* Send the characters out.*IfthebufferaddressisintheCPMDPRAM,don't*convertit.*/
@@ -2314,55 +2328,32 @@cp=(u_char*)(bdp->cbd_bufaddr);elsecp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);-*cp=*s;--bdp->cbd_datlen=1;-bdp->cbd_sc|=BD_SC_READY;--if(bdp->cbd_sc&BD_SC_WRAP)-bdp=bdbase;-else-bdp++;--/* if a LF, also do CR... */-if(*s==10){-while(bdp->cbd_sc&BD_SC_READY);--/* This 'if' below will never be true, but a few-*peoplearguedwithmethatitwasa"bug by-*inspection" that is was easier to add the code-*thancontinuethediscussion.Theonlytime-*thebufferaddressisinDPRAMisduringearly-*usebykgdb/xmon,whichformattheirownpackets-*andwenevergethere.--Dan-*/-if((uint)(bdp->cbd_bufaddr)>(uint)IMAP_ADDR)-cp=(u_char*)(bdp->cbd_bufaddr);-else-cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);-*cp=13;-bdp->cbd_datlen=1;-bdp->cbd_sc|=BD_SC_READY;-if(bdp->cbd_sc&BD_SC_WRAP){-bdp=bdbase;-}-else{-bdp++;-}+i=1;/* Keeps track of consumed TX buffer space */+if(cr_missing){+/* Previus loop didn't have room for the CR, insert it first in this */+*cp++='\r';+i++;+}+cr_missing=0;+for(;i<=c;i++){+if((*cp++=*s++)!='\n')+continue;/* Copy bytes until a NewLine is found */+/* NewLine found, see if there is space in the TX buffer to add a CR */+if(i<max_tx_size){+*cp++='\r';/* yes, there is space to add a CR */+i++;+}else+cr_missing=1;/* No space in the TX buffer,+remberitsoitcanbeinsertedinthenextloop*/}-}--/*-*Finally,Waitfortransmitter&holdingregistertoempty-*andrestoretheIER-*/-while(bdp->cbd_sc&BD_SC_READY);+count-=(c-cr_missing);+bdp->cbd_datlen=i-1;+bdp->cbd_sc|=BD_SC_READY;-if(info)-info->tx_cur=(cbd_t*)bdp;+}+/* while (bdp->cbd_sc & BD_SC_READY); is this really needed? */}-staticvoidserial_console_write(structconsole*c,constchar*s,unsignedcount){
@@ -3059,7 +3050,7 @@*memoryyetbecausevmallocatorisn'tinitialized*duringthisearlyconsoleinit.*/-dp_addr=m8xx_cpm_dpalloc(8);+dp_addr=m8xx_cpm_dpalloc(2*EARLY_BUF_SIZE);mem_addr=(uint)(&cpmp->cp_dpmem[dp_addr]);/* Allocate space for two buffer descriptors in the DP ram.
@@ -3073,10 +3064,10 @@bdp->cbd_bufaddr=iopa(mem_addr);(bdp+1)->cbd_bufaddr=iopa(mem_addr+4);-consinfo.rx_va_base=mem_addr;-consinfo.rx_bd_base=bdp;-consinfo.tx_va_base=mem_addr+4;-consinfo.tx_bd_base=bdp+1;+consinfo.rx_va_base=(unsignedchar*)mem_addr;+consinfo.rx_bd_base=(cbd_t*)bdp;+consinfo.tx_va_base=(unsignedchar*)(mem_addr+EARLY_BUF_SIZE);+consinfo.tx_bd_base=(cbd_t*)(bdp+1);/* For the receive, set empty and wrap.*Fortransmit,setwrap.
@@ -3177,7 +3168,7 @@/* Set up the baud rate generator.*/m8xx_cpm_setbrg((ser-rs_table),bd->bi_baudrate);-+console_tx_buf_len=EARLY_BUF_SIZE;return0;}
On Wed, Sep 17, 2003 at 06:33:06PM +0200, Joakim Tjernlund wrote:
quoted
quoted
Whatever the boot rom initializes.
OK, then I will assume TX buffer length of 1, until serial_console_setup has run and
initialize it to 4.
Jocke
Here we go again. This patch adds the above. I am unable to break it, please try to :)
What tree is this against, specifically? It doesn't apply cleanly to
2_4_devel, 2_4 or kernel.org.
I've just moved a bunch of Dan's old changes from _devel out to a tree
Marcelo pulls from as well as linuxppc-2.4, so can you please re-do this
patch against that tree? Thanks.
--
Tom Rini
http://gate.crashing.org/~trini/
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
On Wed, Sep 17, 2003 at 06:33:06PM +0200, Joakim Tjernlund wrote:
quoted
quoted
quoted
Whatever the boot rom initializes.
OK, then I will assume TX buffer length of 1, until serial_console_setup has run and
initialize it to 4.
Jocke
Here we go again. This patch adds the above. I am unable to break it, please try to :)
What tree is this against, specifically? It doesn't apply cleanly to
2_4_devel, 2_4 or kernel.org.
It is against 2_4_devel minus the recent white space cleanup, as far as I can tell.
I should apply if you ignore white space differences. Can you try?
I've just moved a bunch of Dan's old changes from _devel out to a tree
Marcelo pulls from as well as linuxppc-2.4, so can you please re-do this
patch against that tree? Thanks.
I can only run & patch against 2_4_devel since I have made custom changes to my tree.
My tree is a bit behind right now, sorry.
From: Dan Malek <hidden> Date: 2003-09-26 22:20:53
Tom Rini wrote:
KGDB still works for me. Dan, any final thoughts / comments /
objections?
In the last patch I saw, we are blocking interrupts for quite a while,
across a copy_from_user(), in 8xx_write(). This can cause large
interrupt latencies due to page faults, it would be nice if could fix that.
Thanks.
-- Dan
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
KGDB still works for me. Dan, any final thoughts / comments /
objections?
In the last patch I saw, we are blocking interrupts for quite a while,
across a copy_from_user(), in 8xx_write().
Yes, thats correct. I did try different ways around that but the only thing that
would work is to make copy_from_user() copy to i tmp buf and then copy the
tmp buf into the BD. Would that be better?
Jocke
This can cause large
interrupt latencies due to page faults, it would be nice if could fix that.
-- Dan
From: Dan Malek <hidden> Date: 2003-09-26 23:12:20
Joakim Tjernlund wrote:
Yes, thats correct. I did try different ways around that but the only thing that
would work is to make copy_from_user() copy to i tmp buf and then copy the
tmp buf into the BD. Would that be better?
I wonder what happens if we mark a buffer ready with a count of zero?
Since the typical case is no page fault, I would just update the BD ptr
early, use the buffer, mark it ready. If you get a fault, put a zero
for the count and mark it ready. If that freaks out the CPM, put one
byte of zero into the buffer and give it a count of 1. Then you just have
to hold the lock across the update of the BD ptr, just like everywhere else.
-- Dan
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Yes, thats correct. I did try different ways around that but the only thing that
would work is to make copy_from_user() copy to i tmp buf and then copy the
tmp buf into the BD. Would that be better?
I wonder what happens if we mark a buffer ready with a count of zero?
Since the typical case is no page fault, I would just update the BD ptr
early, use the buffer, mark it ready. If you get a fault, put a zero
for the count and mark it ready.
I tried that and it broke the CPM.
If that freaks out the CPM, put one
byte of zero into the buffer and give it a count of 1. Then you just have
to hold the lock across the update of the BD ptr, just like everywhere else.
That will work, but wont the zero show up on the console? hmm, since
the zero count will be very unlikely case anyhow, I can live with that.
Jocke
If that freaks out the CPM, put one
byte of zero into the buffer and give it a count of 1. Then you just have
to hold the lock across the update of the BD ptr, just like everywhere else.
That will work, but wont the zero show up on the console? hmm, since
the zero count will be very unlikely case anyhow, I can live with that.
OK, this patch does the above. I left my test function(err_copy_from_user)
to simulate bad copy_from_user() copies every now and then. Just remove
it and change the call in rs_8xx_write when you have tested it.
Works great for me, not even jove(emacs like editor) will break it.
Jocke
Index: arch/ppc/8xx_io/uart.c
===================================================================
RCS file: /home/cvsadmin/cvsroot/kernel/linuxppc/arch/ppc/8xx_io/uart.c,v
retrieving revision 1.7
diff -u -r1.7 uart.c
@@ -81,7 +81,11 @@#define TX_WAKEUP ASYNC_SHARE_IRQstaticchar*serial_name="CPM UART driver";-staticchar*serial_version="0.03";+staticchar*serial_version="0.04";++/* TX buffer length used by my_console_write.+Assumeminumunlengthuntilitgetssetbythisdriver*/+staticintconsole_tx_buf_len=1;staticDECLARE_TASK_QUEUE(tq_serial);
@@ -196,6 +200,7 @@/* The number of buffer descriptors and their sizes.*/+#define EARLY_BUF_SIZE 4#define RX_NUM_FIFO 4#define RX_BUF_SIZE 32#define TX_NUM_FIFO 4
@@ -1075,7 +1081,16 @@if(!tty)return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);+while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);
@@ -1083,14 +1098,20 @@bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;-/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;+}+interr_copy_from_user(void*to,void*from,intlen)+{+staticinterr;+intres;++err=(err+1)%13;-info->tx_cur=(cbd_t*)bdp;+res=copy_from_user(to,from,len);+if(!err&&len>1)+returnlen-1;/* partial copy */+if(!err)+returnlen;/* nothing copied */+returnres;}staticintrs_8xx_write(structtty_struct*tty,intfrom_user,
@@ -1100,6 +1121,7 @@ser_info_t*info=(ser_info_t*)tty->driver_data;volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;#ifdef CONFIG_KGDB_CONSOLE/* Try to let stub handle output. Returns true if it did. */
@@ -1113,44 +1135,47 @@if(!tty)return0;-bdp=info->tx_cur;-while(1){c=MIN(count,TX_BUF_SIZE);if(c<=0)break;+local_irq_save(flags);+bdp=info->tx_cur;if(bdp->cbd_sc&BD_SC_READY){info->flags|=TX_WAKEUP;+local_irq_restore(flags);break;}+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);-if(from_user){-if(copy_from_user((void*)cp,buf,c)){-if(!ret)-ret=-EFAULT;-break;-}-}else{+if(from_user)+c-=err_copy_from_user((void*)cp,buf,c);+elsememcpy((void*)cp,buf,c);++if(c){+bdp->cbd_datlen=c;+bdp->cbd_sc|=BD_SC_READY;+}else{+bdp->cbd_datlen=1;/* Need to TX at least 1 char to keep CPM sane */+*cp=0;+bdp->cbd_sc|=BD_SC_READY;+if(!ret)+ret=-EFAULT;+break;}--bdp->cbd_datlen=c;-bdp->cbd_sc|=BD_SC_READY;-buf+=c;count-=c;ret+=c;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;-info->tx_cur=(cbd_t*)bdp;}returnret;}
@@ -1210,28 +1235,28 @@{volatilecbd_t*bdp;unsignedchar*cp;+unsignedlongflags;ser_info_t*info=(ser_info_t*)tty->driver_data;if(serial_paranoia_check(info,tty->device,"rs_send_char"))return;+local_irq_save(flags);bdp=info->tx_cur;+/* Get next BD.+*/+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=info->tx_bd_base;+else+info->tx_cur=(cbd_t*)bdp+1;+local_irq_restore(flags);while(bdp->cbd_sc&BD_SC_READY);cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);*cp=ch;bdp->cbd_datlen=1;bdp->cbd_sc|=BD_SC_READY;--/* Get next BD.-*/-if(bdp->cbd_sc&BD_SC_WRAP)-bdp=info->tx_bd_base;-else-bdp++;--info->tx_cur=(cbd_t*)bdp;}/*
@@ -2273,40 +2303,39 @@*wesimplyusethesinglebufferallocated.*/if((info=(ser_info_t*)ser->info)!=NULL){-bdp=info->tx_cur;bdbase=info->tx_bd_base;-}-else{-/* Pointer to UART in parameter ram.-*/+}else{+/* Pointer to UART in parameter ram. */up=(smc_uart_t*)&cpmp->cp_dparam[ser->port];--/* Get the address of the host memory buffer.-*/-bdp=bdbase=(cbd_t*)&cpmp->cp_dpmem[up->smc_tbase];+/* Get the address of the host memory buffer.*/info=&consinfo;+info->tx_bd_base=(cbd_t*)bdbase=(cbd_t*)&cpmp->cp_dpmem[up->smc_tbase];+info->tx_cur=(cbd_t*)bdbase;}+max_tx_size=console_tx_buf_len;+cr_missing=0;+while(1){+c=MIN(max_tx_size,count);+if(c<=0)+break;-/*-*Weneedtogracefullyshutdownthetransmitter,disable-*interrupts,thensendourbytesout.-*/--/*-*Now,doeachcharacter.Thisisnotasbadasitlooks-*sincethisisaholdingFIFOandnotatransmittingFIFO.-*Wecouldaddthecomplexityoffillingtheentiretransmit-*buffer,butwewouldjustwaitlongerbetweenaccesses......-*/-for(i=0;i<count;i++,s++){+local_irq_save(flags);+bdp=info->tx_cur;+bdbase=info->tx_bd_base;+if(bdp->cbd_sc&BD_SC_WRAP)+info->tx_cur=(cbd_t*)bdbase;+else+info->tx_cur=(cbd_t*)(bdp+1);+local_irq_restore(flags);+/* Wait for transmitter fifo to empty.*Readyindicatesoutputisready,andxmtisdoing*that,notthatitisreadyforustosend.*/while(bdp->cbd_sc&BD_SC_READY);-/* Send the character out.+/* Send the characters out.*IfthebufferaddressisintheCPMDPRAM,don't*convertit.*/
@@ -2314,55 +2343,32 @@cp=(u_char*)(bdp->cbd_bufaddr);elsecp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);-*cp=*s;--bdp->cbd_datlen=1;-bdp->cbd_sc|=BD_SC_READY;--if(bdp->cbd_sc&BD_SC_WRAP)-bdp=bdbase;-else-bdp++;--/* if a LF, also do CR... */-if(*s==10){-while(bdp->cbd_sc&BD_SC_READY);--/* This 'if' below will never be true, but a few-*peoplearguedwithmethatitwasa"bug by-*inspection" that is was easier to add the code-*thancontinuethediscussion.Theonlytime-*thebufferaddressisinDPRAMisduringearly-*usebykgdb/xmon,whichformattheirownpackets-*andwenevergethere.--Dan-*/-if((uint)(bdp->cbd_bufaddr)>(uint)IMAP_ADDR)-cp=(u_char*)(bdp->cbd_bufaddr);-else-cp=info->tx_va_base+((bdp-info->tx_bd_base)*TX_BUF_SIZE);-*cp=13;-bdp->cbd_datlen=1;-bdp->cbd_sc|=BD_SC_READY;-if(bdp->cbd_sc&BD_SC_WRAP){-bdp=bdbase;-}-else{-bdp++;-}+i=1;/* Keeps track of consumed TX buffer space */+if(cr_missing){+/* Previus loop didn't have room for the CR, insert it first in this */+*cp++='\r';+i++;+}+cr_missing=0;+for(;i<=c;i++){+if((*cp++=*s++)!='\n')+continue;/* Copy bytes until a NewLine is found */+/* NewLine found, see if there is space in the TX buffer to add a CR */+if(i<max_tx_size){+*cp++='\r';/* yes, there is space to add a CR */+i++;+}else+cr_missing=1;/* No space in the TX buffer,+remberitsoitcanbeinsertedinthenextloop*/}-}--/*-*Finally,Waitfortransmitter&holdingregistertoempty-*andrestoretheIER-*/-while(bdp->cbd_sc&BD_SC_READY);+count-=(c-cr_missing);+bdp->cbd_datlen=i-1;+bdp->cbd_sc|=BD_SC_READY;-if(info)-info->tx_cur=(cbd_t*)bdp;+}+/* while (bdp->cbd_sc & BD_SC_READY); is this really needed? */}-staticvoidserial_console_write(structconsole*c,constchar*s,unsignedcount){
@@ -3059,7 +3065,7 @@*memoryyetbecausevmallocatorisn'tinitialized*duringthisearlyconsoleinit.*/-dp_addr=m8xx_cpm_dpalloc(8);+dp_addr=m8xx_cpm_dpalloc(2*EARLY_BUF_SIZE);mem_addr=(uint)(&cpmp->cp_dpmem[dp_addr]);/* Allocate space for two buffer descriptors in the DP ram.
@@ -3073,10 +3079,10 @@bdp->cbd_bufaddr=iopa(mem_addr);(bdp+1)->cbd_bufaddr=iopa(mem_addr+4);-consinfo.rx_va_base=mem_addr;-consinfo.rx_bd_base=bdp;-consinfo.tx_va_base=mem_addr+4;-consinfo.tx_bd_base=bdp+1;+consinfo.rx_va_base=(unsignedchar*)mem_addr;+consinfo.rx_bd_base=(cbd_t*)bdp;+consinfo.tx_va_base=(unsignedchar*)(mem_addr+EARLY_BUF_SIZE);+consinfo.tx_bd_base=(cbd_t*)(bdp+1);/* For the receive, set empty and wrap.*Fortransmit,setwrap.
@@ -3177,7 +3183,7 @@/* Set up the baud rate generator.*/m8xx_cpm_setbrg((ser-rs_table),bd->bi_baudrate);-+console_tx_buf_len=EARLY_BUF_SIZE;return0;}
On Sat, Sep 27, 2003 at 03:43:51PM +0200, Joakim Tjernlund wrote:
quoted
quoted
If that freaks out the CPM, put one
byte of zero into the buffer and give it a count of 1. Then you just have
to hold the lock across the update of the BD ptr, just like everywhere else.
That will work, but wont the zero show up on the console? hmm, since
the zero count will be very unlikely case anyhow, I can live with that.
OK, this patch does the above. I left my test function(err_copy_from_user)
to simulate bad copy_from_user() copies every now and then. Just remove
it and change the call in rs_8xx_write when you have tested it.
Works great for me, not even jove(emacs like editor) will break it.
From: Kumar Gala <hidden> Date: 2003-10-01 14:26:29
Did I miss something or did is someone moving this patch from 8xx to
8260? It looks like Tom's commit of Joakim's work was for 8xx.
- kumar
On Tuesday, September 30, 2003, at 10:28 AM, Dan Malek wrote:
On Wed, Oct 01, 2003 at 09:26:29AM -0500, Kumar Gala wrote:
Did I miss something or did is someone moving this patch from 8xx to
8260? It looks like Tom's commit of Joakim's work was for 8xx.
No one has moved this to 8260 as no one with access to hw (not me,
easily) has time to do it. If you can, I'll apply it.
--
Tom Rini
http://gate.crashing.org/~trini/
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
From: Gary Thomas <hidden> Date: 2003-10-01 14:48:56
On Wed, 2003-10-01 at 08:32, Tom Rini wrote:
On Wed, Oct 01, 2003 at 09:26:29AM -0500, Kumar Gala wrote:
quoted
Did I miss something or did is someone moving this patch from 8xx to
8260? It looks like Tom's commit of Joakim's work was for 8xx.
No one has moved this to 8260 as no one with access to hw (not me,
easily) has time to do it. If you can, I'll apply it.
I'll be glad to test this as well (sadly I don't have time today to
help with moving the patch). I have access to both 8xx and 82xx boards.
--
Gary Thomas [off-list ref]
MLB Associates
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
What about linuxppc_2_4_devel? Is that also "non preferred"?
Yes.
Rather than lots of URLs that are NOT recommended, is there one that is?
Also, you refer to 2.4.21-pre but I thought we had moved onto 2.4.23-pre
now. Is the ppc tree really that much out-of-date?
Very much in need of getting rid of the CPM memory leak in 2.4.21 so I
have a very acute interest in getting the latest & greatest!!
--
Robin Gilks
Senior Design Engineer Phone: (+64)(3) 357 1569
Tait Electronics Fax : (+64)(3) 359 4632
PO Box 1645 Christchurch Email : robin.gilks@tait.co.nz
New Zealand
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
What about linuxppc_2_4_devel? Is that also "non preferred"?
Yes.
Rather than lots of URLs that are NOT recommended, is there one that is?
For the moment it's "whatever you have now is probably fine". For
2.4.23 I would like to get most of _devel cleaned out, wrt 8xx. This
will probably leave out some 'new' boards that Wolfgang sent out a long
time ago (FWIW, once I get everything else out I do plan to ask Wolfgang
if he wants to re-submit those boards or verify there's nothing new
needed to what's in _devel or something).
If you have a new board, or a bug fix, current kernel.org (BK, snapshots
of BK, just official releases) is best.
Also, you refer to 2.4.21-pre but I thought we had moved onto 2.4.23-pre
now. Is the ppc tree really that much out-of-date?
It's in the linuxppc-2.4 tree. I'll try and get it to Marcelo in time
for 2.4.21-pre7.
Say, how up to date is Marcelo's tree in general
with respect to linuxppc_2_4_devel? Does it have
the ppc405 support stuff?
We have been using a linuxppc_2_4_devel snapshot from
a year or so ago on the ppc405, and it'd be nice to be able to
move to a vanilla kernel someday.
Thanks,
Dan
--
Dan Kegel
http://www.kegel.comhttp://counter.li.org/cgi-bin/runscript/display-person.cgi?user=78045
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/