Re: [PATCH] powerpc: Fix sigset_t copy

2021-11-10 Thread Finn Thain
On Wed, 10 Nov 2021, Christophe Leroy wrote:

> Le 10/11/2021 à 00:47, Finn Thain a écrit :
> 
> > Christophe, I hope this change is the one you wanted to see upstream 
> > (?). If it is acceptable please add your signed-off-by tag.
> 
> I'm on holidays, I was planing to handle this next week.
> 

OK. I'll leave it with you.

[PATCH] powerpc: Fix sigset_t copy

2021-11-09 Thread Finn Thain
From: Christophe Leroy 

The conversion from __copy_from_user() to __get_user() introduced a
regression in __get_user_sigset() in v5.13. The bug was subsequently
copied and pasted in unsafe_get_user_sigset().

The regression was reported by users of the Xorg packages distributed in
Debian/powerpc --

"The symptoms are that the fb screen goes blank, with the backlight
remaining on and no errors logged in /var/log; wdm (or startx) run
with no effect (I tried logging in in the blind, with no effect).
And they are hard to kill, requiring 'kill -KILL ...'"

Fix the regression by casting the __get_user() assignment lvalue to u64
so that the entire struct gets copied.

Cc: Christophe Leroy 
Cc: Christopher M. Riedl 
Link: 
https://lore.kernel.org/linuxppc-dev/FEtBUOuFPMN4zJy4bIOqz6C4xoliCbTxS7VtMKD6UZkbvEbycUceRgGAd7e9-trRdwVN3hWAbQi0qrNx8Zgn8niTQf2KPVdw-W35czDIaeQ=@protonmail.com/
Fixes: 887f3ceb51cd ("powerpc/signal32: Convert do_setcontext[_tm]() to user 
access block")
Fixes: d3ccc9781560 ("powerpc/signal: Use __get_user() to copy sigset_t")
Reported-and-tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
Christophe, I hope this change is the one you wanted to see upstream (?).
If it is acceptable please add your signed-off-by tag.
---
 arch/powerpc/kernel/signal.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 1f07317964e4..44e736b88e91 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -23,10 +23,10 @@ static inline int __get_user_sigset(sigset_t *dst, const 
sigset_t __user *src)
 {
BUILD_BUG_ON(sizeof(sigset_t) != sizeof(u64));
 
-   return __get_user(dst->sig[0], (u64 __user *)>sig[0]);
+   return __get_user(*(u64 *)>sig[0], (u64 __user *)>sig[0]);
 }
 #define unsafe_get_user_sigset(dst, src, label) \
-   unsafe_get_user((dst)->sig[0], (u64 __user *)&(src)->sig[0], label)
+   unsafe_get_user(*(u64 *)&(dst)->sig[0], (u64 __user *)&(src)->sig[0], 
label)
 
 #ifdef CONFIG_VSX
 extern unsigned long copy_vsx_to_user(void __user *to,
-- 
2.26.3



Re: Fwd: Fwd: X stopped working with 5.14 on iBook

2021-11-04 Thread Finn Thain
On Thu, 4 Nov 2021, Christophe Leroy wrote:

> Le 02/11/2021 à 03:20, Finn Thain a écrit :
> > Hi Christopher,
> > 
> > After many builds and tests, Stan and I were able to determine that this
> > regression only affects builds with CONFIG_USER_NS=y. That is,
> > 
> > d3ccc9781560  + CONFIG_USER_NS=y  -->  fail
> > d3ccc9781560  + CONFIG_USER_NS=n  -->  okay
> > d3ccc9781560~ + CONFIG_USER_NS=y  -->  okay
> > d3ccc9781560~ + CONFIG_USER_NS=n  -->  okay
> > 
> > Stan also tested a PowerMac G3 system and found that the regression is not
> > present there. Thus far, only PowerMac G4 systems are known to be affected
> > (Stan's Cube and Riccardo's PowerBook).
> > 
> > I asked Stan to try v5.15-rc after reverting commit d3ccc9781560.
> > Unexpectedly, this build had the same issue. So, it appears there are
> > multiple bad commits that produce this Xorg failure, of which d3ccc9781560
> > is just the first.
> > 
> > But there's no easy way to identify the other bad commits using bisection.
> > So I've addressed this message to you. Can you help fix this regression?
> > 
> 
> I'm wondering if this commit is really the cause of the problem.
> 
> Are you using GCC 11 ?
> 
> If yes, I think it could be a false positive, fixed by
> https://github.com/linuxppc/linux/commit/7315e457d6bc
> 
> Can you try with GCC 10 or older ?
> 

AFAIK, all of Stan's builds were made with gcc 10.

> Can you cherry pick 7315e457d6bc ("powerpc/uaccess: Fix __get_user() with
> CONFIG_CC_HAS_ASM_GOTO_OUTPUT") on top of d3ccc9781560 and see what happens ?
> 

$ git checkout d3ccc9781560
$ git cherry-pick 7315e457d6bc
Auto-merging arch/powerpc/include/asm/uaccess.h
CONFLICT (content): Merge conflict in arch/powerpc/include/asm/uaccess.h
error: could not apply 7315e457d6bc... powerpc/uaccess: Fix __get_user() with 
CONFIG_CC_HAS_ASM_GOTO_OUTPUT

There is no __get_user_asm2_goto in this tree, and __get_user_asm2 already
has the "=" constraint:

#define __get_user_asm2(x, addr, err)   \
__asm__ __volatile__(   \
"1: lwz%X2 %1, %2\n"\
"2: lwz%X2 %L1, %L2\n"  \
"3:\n"  \
".section .fixup,\"ax\"\n"  \
"4: li %0,%3\n" \
"   li %1,0\n"  \
"   li %1+1,0\n"\
"   b 3b\n" \
".previous\n"   \
EX_TABLE(1b, 4b)\
EX_TABLE(2b, 4b)\
: "=r" (err), "=" (x) \
: "m" (*addr), "i" (-EFAULT), "0" (err)) 

Re: Fwd: Fwd: X stopped working with 5.14 on iBook

2021-11-03 Thread Finn Thain
On Wed, 3 Nov 2021, Andreas Schwab wrote:

> On Nov 02 2021, Finn Thain wrote:
> 
> > After many builds and tests, Stan and I were able to determine that this 
> > regression only affects builds with CONFIG_USER_NS=y. That is,
> >
> > d3ccc9781560  + CONFIG_USER_NS=y  -->  fail
> > d3ccc9781560  + CONFIG_USER_NS=n  -->  okay
> > d3ccc9781560~ + CONFIG_USER_NS=y  -->  okay
> > d3ccc9781560~ + CONFIG_USER_NS=n  -->  okay
> 
> On my iBook G4, X is working alright with 5.15 and CONFIG_USER_NS=y.
> 

Stan said his Cube has these packages installed:

# dpkg --list | grep Xorg
ii  xserver-xorg-core  2:1.20.11-1
  powerpc  Xorg X server - core server
ii  xserver-xorg-legacy2:1.20.11-1
  powerpc  setuid root Xorg server wrapper

I gather that Riccardo also runs Debian SID.

Perhaps there is some interaction between d3ccc9781560, CONFIG_USER_NS and 
the SUID wrapper...

Does your Xorg installation use --enable-suid-wrapper, Andreas?


Re: Fwd: Fwd: X stopped working with 5.14 on iBook

2021-11-01 Thread Finn Thain
Hi Christopher,

After many builds and tests, Stan and I were able to determine that this 
regression only affects builds with CONFIG_USER_NS=y. That is,

d3ccc9781560  + CONFIG_USER_NS=y  -->  fail
d3ccc9781560  + CONFIG_USER_NS=n  -->  okay
d3ccc9781560~ + CONFIG_USER_NS=y  -->  okay
d3ccc9781560~ + CONFIG_USER_NS=n  -->  okay

Stan also tested a PowerMac G3 system and found that the regression is not 
present there. Thus far, only PowerMac G4 systems are known to be affected 
(Stan's Cube and Riccardo's PowerBook).

I asked Stan to try v5.15-rc after reverting commit d3ccc9781560. 
Unexpectedly, this build had the same issue. So, it appears there are 
multiple bad commits that produce this Xorg failure, of which d3ccc9781560 
is just the first.

But there's no easy way to identify the other bad commits using bisection. 
So I've addressed this message to you. Can you help fix this regression?

Regards,
Finn

On Fri, 22 Oct 2021, Christophe Leroy wrote:

> ...
> > 
> >  Forwarded Message 
> > Subject: Fwd: X stopped working with 5.14 on iBook
> > Date: Fri, 22 Oct 2021 11:35:21 -0600
> > From: Stan Johnson
> > To: Christopher M. Riedl 
> > CC: Finn Thain 
> > 
> > Hello Christopher Riedl,
> > 
> > Please see the message below, in which a git bisect identifies a commit
> > which may have stopped X from working on some PowerPC G4 systems
> > (specifically the G4 PowerBook and Cube, possibly others).
> > 
> > I'm not sure how to proceed with further tests. If the identified commit
> > could not have caused the problem, then further testing may be needed.
> > Please let me know if you need any additional information.
> > 
> > Hopefully your e-mail filter will allow messages from yahoo.com addresses.
> > 
> > thanks for your help
> > 
> > -Stan Johnson
> > 
> >  Forwarded Message 
> > Subject: Re: X stopped working with 5.14 on iBook
> > Date: Fri, 22 Oct 2021 11:25:14 -0600
> > From: Stan Johnson
> > To: debian-powe...@lists.debian.org
> > CC: Riccardo Mottola 
> > 
> > On 10/14/21 9:21 PM, Stan Johnson wrote:
> > > ...
> > > Debian's 5.10.0-8 config file works (as expected) with Debian's 5.10.0-8
> > > kernel source.
> > > ...
> > > X works with 5.14 using a tuned config file derived from 5.13 testing.
> > > ...
> > 
> > Update:
> > 
> > The issue originally reported by Riccardo Mottola was that X wasn't
> > working on a PowerBook G4 using Debian's default
> > vmlinux-5.14.0-2-powerpc kernel. I was able to confirm that the X
> > failure also occurs on a G4 Cube. My G4 Cube has Debian SID,
> > sysvinit-core, Xfce and wdm installed. To test whether X works, I
> > disabled wdm, then I log in at the text console and run "startx". When X
> > fails, the screen goes blank and the backlight stays on; when X works,
> > the normal desktop comes up.
> > 
> > X works in mainline v5.12 built using a config file based on Debian's
> > config-5.10.0-8-powerpc.
> > 
> > X fails in mainline v5.13 built using a config file based on Debian's
> > config-5.10.0-8-powerpc.
> > 
> > With much help and advice from Finn Thain, I was able to run a bisect
> > using a config file based on Debian's config-5.10.0-8-powerpc, with
> > v5.12 "good" and v5.13 "bad".
> > 
> > $ git reset --hard
> > HEAD is now at 62fb9874f5da Linux 5.13
> > $ git bisect start v5.13
> > Updating files: 100% (12992/12992), done.
> > Previous HEAD position was 62fb9874f5da Linux 5.13
> > HEAD is now at 9f4ad9e425a1 Linux 5.12
> > $ git bisect bad v5.13
> > $ git bisect good v5.12
> > Bisecting: 8739 revisions left to test after this (roughly 13 steps)
> > > 85f3f17b5db2dd9f8a094a0ddc66135afd22] Merge branch 'md-fixes' of
> > https://git.kernel.org/pub/scm/linux/kernel/git/song/md into block-5.13
> > 
> > After the bisect, git reports this:
> > 
> > --
> > 
> > d3ccc9781560af051554017c702631560bdc0811 is the first bad commit
> > commit d3ccc9781560af051554017c702631560bdc0811
> > Author: Christopher M. Riedl 
> > Date:   Fri Feb 26 19:12:59 2021 -0600
> > 
> >  powerpc/signal: Use __get_user() to copy sigset_t
> > 
> >  Usually sigset_t is exactly 8B which is a "trivial" size and does not
> >  warrant using __copy_from_user(). Use __get_user() directly in
> >  anticipation of future work to remove the trivial size optimizations
> >  from __copy_from_user().
> > 
> >  The ppc32 implementation of get

[PATCH] powerpc/tau: Add 'static' storage qualifier to 'tau_work' definition

2021-08-18 Thread Finn Thain
This patch prevents the following sparse warning.

arch/powerpc/kernel/tau_6xx.c:199:1: sparse: sparse: symbol 'tau_work'
was not declared. Should it be static?

Reported-by: kernel test robot 
Signed-off-by: Finn Thain 
---
 arch/powerpc/kernel/tau_6xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index b9a047d92ec0..8e83d19fe8fa 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -164,7 +164,7 @@ static void tau_work_func(struct work_struct *work)
queue_work(tau_workq, work);
 }
 
-DECLARE_WORK(tau_work, tau_work_func);
+static DECLARE_WORK(tau_work, tau_work_func);
 
 /*
  * setup the TAU
-- 
2.26.3



Re: Debian SID kernel doesn't boot on PowerBook 3400c

2021-08-06 Thread Finn Thain


On Fri, 6 Aug 2021, Stan Johnson wrote:

> $ egrep '(CONFIG_PPC_KUAP|CONFIG_VMAP_STACK)' .config
> CONFIG_PPC_KUAP=y
> CONFIG_PPC_KUAP_DEBUG=y
> CONFIG_VMAP_STACK=y
> $ strings vmlinux | fgrep "Linux version"
> Linux version 5.13.0-pmac-4-g63e3756d1bd ...
> $ cp vmlinux ../vmlinux-5.13.0-pmac-4-g63e3756d1bd-1
> 
> 1) PB 3400c
> vmlinux-5.13.0-pmac-4-g63e3756d1bd-1
> Boots, no errors logging in at (text) fb console. Logging in via ssh and
> running "ls -Rail /usr/include" generated errors (and a hung ssh
> session). Once errors started, they repeated for almost every command.
> See pb3400c-63e3756d1bdf-1.txt.
> 
> 2) Wallstreet
> vmlinux-5.13.0-pmac-4-g63e3756d1bd-1
> X login failed, there were errors ("Oops: Kernel access of bad area",
> "Oops: Exception in kernel mode"). Logging in via SSH, there were no
> additional errors after running "ls -Rail /usr/include" -- the errors
> did not escalate as they did on the PB 3400.
> See Wallstreet-63e3756d1bdf-1.txt.
> 
...
> $ egrep '(CONFIG_PPC_KUAP|CONFIG_VMAP_STACK)' .config
> CONFIG_PPC_KUAP=y
> CONFIG_PPC_KUAP_DEBUG=y
> # CONFIG_VMAP_STACK is not set
> $ strings vmlinux | fgrep "Linux version"
> Linux version 5.13.0-pmac-4-g63e3756d1bd ...
> $ cp vmlinux ../vmlinux-5.13.0-pmac-4-g63e3756d1bd-2
> 
> 3) PB 3400c
> vmlinux-5.13.0-pmac-4-g63e3756d1bd-2
> Filesystem was corrupt from the previous test (probably from all the
> errors during shutdown). After fixing the filesystem:
> Boots, no errors logging in at (text) fb console. Logging in via ssh and
> running "ls -Rail /usr/include" generated a few errors. There didn't
> seem to be as many errors as in the previous test, there were a few
> errors during shutdown but the shutdown was otherwise normal.
> See pb3400c-63e3756d1bdf-2.txt.
> 
> 4) Wallstreet
> vmlinux-5.13.0-pmac-4-g63e3756d1bd-2
> X login worked, and there were no errors. There were no errors during
> ssh access.
> See Wallstreet-63e3756d1bdf-2.txt.
> 

Thanks for collecting these results, Stan. Do you think that the 
successful result from test 4) could have been just chance?

It appears that the bug affecting the Powerbook 3400 is unaffected by 
CONFIG_VMAP_STACK.

Whereas the bug affecting the Powerbook G3 disappears when 
CONFIG_VMAP_STACK is disabled (assuming the result from 4 is reliable).

Either way, these results reiterate that "Oops: Kernel access of bad area, 
sig: 11" was not entirely resolved by "powerpc/32s: Fix napping restore in 
data storage interrupt (DSI)".


Re: Debian SID kernel doesn't boot on PowerBook 3400c

2021-08-06 Thread Finn Thain
On Fri, 6 Aug 2021, Christophe Leroy wrote:

> 
> I have cooked a tentative fix for that KUAP stuff.
> Could you try the branch 'bugtest' at https://github.com/chleroy/linux.git
> 

Thanks, Christophe.

Stan, please test the following build.

$ git remote add chleroy-linux https://github.com/chleroy/linux.git -f -t 
bugtest
...
$ git checkout chleroy-linux/bugtest
HEAD is now at 63e3756d1bdf powerpc/interrupts: Also perform KUAP/KUEP lock and 
usertime accounting on NMI
$ cp ../dot-config-powermac-5.13 .config
$ scripts/config -e CONFIG_PPC_KUAP -e CONFIG_PPC_KUAP_DEBUG -e 
CONFIG_VMAP_STACK
$ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
vmlinux
$ egrep "CONFIG_PPC_KUAP|CONFIG_VMAP_STACK" .config
$ strings vmlinux |grep "Linux version"

If that kernel produces errors, I'd try a second build as well:

$ scripts/config -e CONFIG_PPC_KUAP -e CONFIG_PPC_KUAP_DEBUG -d 
CONFIG_VMAP_STACK
$ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
vmlinux
$ egrep "CONFIG_PPC_KUAP|CONFIG_VMAP_STACK" .config
$ strings vmlinux |grep "Linux version"

Please boot using the same kernel parameters as last time and capture the 
serial console logs. In case we're still dealing with intermittent bugs it 
might be necessary to repeat these tests so I suggest you retain the 
vmlinux files.


Re: Debian SID kernel doesn't boot on PowerBook 3400c

2021-08-06 Thread Finn Thain
On Fri, 6 Aug 2021, Christophe Leroy wrote:

> > > > > 
> > > > > Can you check if they DO NOT happen at preceding commit c16728835~
> > > > > 
> > > 
> > > $ git checkout c16728835~
> > > Previous HEAD position was c16728835eec powerpc/32: Manage KUAP in C
> > > HEAD is now at 0b45359aa2df powerpc/8xx: Create C version of kuap
> > > save/restore/check helpers
> > > $ git am ../message.mbox
> > > warning: Patch sent with format=flowed; space at the end of lines might be
> > > lost.
> > > Applying: powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
> > > $ cp ../dot-config-powermac-5.13 .config
> > > $ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean
> > > olddefconfig vmlinux
> > > 
> > > Linux version 5.12.0-rc3-pmac-00077-gc9f6e8dd045
> > > 
> > > 3) PB 3400c
> > > Hangs at boot (Mac OS screen)
> > > 
> > > 4) Wallstreet
> > > X fails, errors in console log (different than test 2), see
> > > Wallstreet_console-2.txt.
> > > 
> > 
> > This log shows that the errors "xfce4-session[1775]: bus error (7)" and
> > "kernel BUG at arch/powerpc/kernel/interrupt.c:49!" happen prior to commit
> > c16728835eec ("powerpc/32: Manage KUAP in C").
> 
> As mentionned by Nic, this is due to r11 being cloberred. For the time being
> the only r11 clobber identified is the one I have provided a fix for. I'm
> wondering whether it was applied for all further tests or not.
> 

Your fix was applied to this build with "git am ../message.mbox".

> ...
> > > 
> > > > 
> > > > > Could you test with CONFIG_PPC_KUAP and CONFIG_PPC_KUAP_DEBUG
> > > ...
> > > 
> > > $scripts/config -e CONFIG_PPC_KUAP
> > > $ scripts/config -e CONFIG_PPC_KUAP_DEBUG
> > > $ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean
> > > olddefconfig vmlinux
> > > $ grep CONFIG_PPC_KUAP .config
> > > CONFIG_PPC_KUAP=y
> > > CONFIG_PPC_KUAP_DEBUG=y
> > > 
> > > Linux version 5.12.0-rc3-pmac-00078-g5cac2bc3752
> > > 
> > > 9) PB 3400c
> > > Hangs at boot (Mac OS screen)
> > > 
> > > 10) Wallstreet
> > > X failed at first login, worked at second login, one error in console
> > > log ("BUG: Unable to handle kernel instruction fetch"), see
> > > Wallstreet_console-5.txt.
> > > 
> > 
> > One might expect to see "Kernel attempted to write user page (b3399774) -
> > exploit attempt?" again here (see c16728835eec build above) but instead
> > this log says "Oops: Kernel access of bad area, sig: 11".
> 
> Maybe the test should be done a second time. As r11 is garbage it may or 
> may not be a user address. If it is a user address the we get "Kernel 
> attempted to write user page". If it is a random kernel address, we 
> likely get "Kernel access of bad area" instead.
> 

Your fix was applied here also.


Re: Debian SID kernel doesn't boot on PowerBook 3400c

2021-08-05 Thread Finn Thain
(Christophe, you've seen some of this before, however there are new 
results added at the end. I've Cc'd the mailing lists this time.)

On Wed, 4 Aug 2021, Stan Johnson wrote:

> On 8/4/21 8:41 PM, Finn Thain wrote:
> 
> >
> > $ curl 
> > https://lore.kernel.org/lkml/9b64dde3-6ebd-b446-41d9-61e8cb0d8...@csgroup.eu/raw
> > ../message.mbox
> ok
> 
> $ sha1 ../message.mbox
> SHA1 (../message.mbox) = 436ce0adf893c46c84c54607f73c838897caeeea
> 
> >
> > On Wed, 4 Aug 2021, Christophe Leroy wrote:
> >
> >> Can you check if they happen at commit c16728835
> >>
> 
> $ git checkout c16728835eec
> Checking out files: 100% (20728/20728), done.
> Note: checking out 'c16728835eec'.
> 
> You are in 'detached HEAD' state. You can look around, make experimental
> changes and commit them, and you can discard any commits you make in this
> state without impacting any branches by performing another checkout.
> 
> If you want to create a new branch to retain commits you create, you may
> do so (now or later) by using -b with the checkout command again. Example:
> 
>   git checkout -b 
> 
> HEAD is now at c16728835eec powerpc/32: Manage KUAP in C
> $ git am ../message.mbox
> warning: Patch sent with format=flowed; space at the end of lines might be 
> lost.
> Applying: powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
> $ cp ../dot-config-powermac-5.13 .config
> $ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
> vmlinux
> $ strings vmlinux | fgrep 'Linux version'
> Linux version 5.12.0-rc3-pmac-00078-geb51c431b81 (johnson@ThinkPad) 
> (powerpc-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0, GNU ld (GNU Binutils for 
> Debian) 2.31.1) #1 SMP Wed Aug 4 21:50:47 MDT 2021
> 
> 1) PB 3400c
> Hangs at boot (Mac OS screen), no serial console output
> 
> 2) Wallstreet
> X fails, errors ("Kernel attempted to write user page", "BUG: Unable to
> handle kernel instruction fetch"), see Wallstreet_console-1.txt.
> 

The log shows that the error "Kernel attempted to write user page 
(b3399774) - exploit attempt?" happens after commit c16728835eec 
("powerpc/32: Manage KUAP in C").

> >>
> >> Can you check if they DO NOT happen at preceding commit c16728835~
> >>
> 
> $ git checkout c16728835~
> Previous HEAD position was c16728835eec powerpc/32: Manage KUAP in C
> HEAD is now at 0b45359aa2df powerpc/8xx: Create C version of kuap 
> save/restore/check helpers
> $ git am ../message.mbox
> warning: Patch sent with format=flowed; space at the end of lines might be 
> lost.
> Applying: powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
> $ cp ../dot-config-powermac-5.13 .config
> $ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
> vmlinux
> 
> Linux version 5.12.0-rc3-pmac-00077-gc9f6e8dd045
> 
> 3) PB 3400c
> Hangs at boot (Mac OS screen)
> 
> 4) Wallstreet
> X fails, errors in console log (different than test 2), see
> Wallstreet_console-2.txt.
> 

This log shows that the errors "xfce4-session[1775]: bus error (7)" and 
"kernel BUG at arch/powerpc/kernel/interrupt.c:49!" happen prior to commit 
c16728835eec ("powerpc/32: Manage KUAP in C").

> 
> $ git checkout 0b45359aa2df
> ...
> HEAD is now at 0b45359aa2df powerpc/8xx: Create C version of kuap 
> save/restore/check helpers
> $ git am ../message.mbox
> warning: Patch sent with format=flowed; space at the end of lines might be 
> lost.
> Applying: powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
> $ cp ../dot-config-powermac-5.13 .config
> $ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
> vmlinux
> 
> Linux version 5.12.0-rc3-pmac-00077-ge06b29ce146
> 
> 5) PB 3400c
> Hangs at boot (Mac OS screen)
> 
> 6) Wallstreet
> X failed (X login succeeded, but setting up desktop failed), errors in
> console log, see Wallstreet_console-3.txt.
> 

(No need for those two tests: it's exactly the same code and almost the 
same failure modes: "kernel BUG at arch/powerpc/kernel/interrupt.c:50".)

On Thu, 5 Aug 2021, Stan Johnson wrote:

> On 8/5/21 12:47 AM, Finn Thain wrote:
> 
> > On Wed, 4 Aug 2021, Christophe Leroy wrote:
> >
> >> Could you test without CONFIG_PPC_KUAP
> ...
> 
> $ git checkout c16728835eec
> ...
> HEAD is now at c16728835eec powerpc/32: Manage KUAP in C
> $ git am ../message.mbox
> warning: Patch sent with format=flowed; space at the end of lines might be 
> lost.
> Applying: powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE
> $ cp ../dot-config-powermac-5.13 .config
> $ scripts/config -d CONFIG_PPC_KUAP
> $ make ARCH=powerpc C

Re: [PATCH] powerpc/32s: Fix napping restore in data storage interrupt (DSI)

2021-08-04 Thread Finn Thain


On Wed, 4 Aug 2021, Christophe Leroy wrote:

> 
> This patch is related to the bisect you did that pointed to 4c0104a83fc3 
> ("powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE")
> 
> I think maybe the starting point should be to (manually) apply the patch 
> on top of that commit in order to check that the bug to leaded to 
> pointing that commit as 'first bad commit' is now gone.
> 

Stan has now confirmed this. He applied this patch on top of 4c0104a83fc3, 
and it did indeed resolve the bug that 'git bisect' isolated [1]. Thanks 
Christophe.

[1]
https://lore.kernel.org/lkml/666e3ab4-372-27c2-4621-7cc393375...@linux-m68k.org/


Re: [PATCH v3 31/41] powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE

2021-08-03 Thread Finn Thain


On Tue, 3 Aug 2021, Stan Johnson wrote:

> Attached you will find the following six files:
> 
> 1) config-5.13-patched_VMAP.txt
> 2) config-5.13-patched_NO_VMAP.txt
> 3) pb3400c-console-5.13-patched_VMAP.txt (using config 1)
> 4) pb3400c-console-5.13-patched_NO_VMAP.txt (using config 2)
> 5) ws-console-5.13-patched_VMAP.txt (using config 1)
> 6) ws-console-5.13-patched_NO_VMAP.txt (using config 2)
> 

Thanks!

> The command lines in BootX were as follows:
> 
> PB 3400c:
> root=/dev/sda13 console=ttyS0 video=chips65550:vmode:14,cmode:16
> 
> Wallstreet:
> root=/dev/sda12 console=ttyS0 video=ofonly
> 
> Notes:
> 
> For 3), the patch seems to have fixed the "hang-at-boot" at the Mac
> OS screen for the PB 3400c. 

I doubt that. I suspect that this is an unrelated failure that only 
affects the Powerbook 3400 and only intermittently. I say that because 
you've also observed this failure in v5.11.

So we should probably ignore this early-boot failure for the moment. Stan, 
if it happens again, please reboot and retry. That may allow us to make 
progress on the other bugs.

> After a successful boot, I didn't see any errors until I accessed the 
> system via ssh. In an ssh window, I entered "dmesg" (no errors) followed 
> by "ls -Rail /usr/bin", and while that was running, the errors appeared. 

Since Stan has a yahoo email address that isn't allowed past the spam 
filter, I'll paste that portion of the console log he sent --

Kernel attempted to write user page (78a930) - exploit attempt? (uid: 1000)
[ cut here ]
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 1619 at arch/powerpc/mm/fault.c:230 
do_page_fault+0x484/0x720
Modules linked in:
CPU: 0 PID: 1619 Comm: sshd Not tainted 5.13.0-pmac-VMAP #10
NIP:  c001b780 LR: c001b780 CTR: 
REGS: cb981bc0 TRAP: 0700   Not tainted  (5.13.0-pmac-VMAP)
MSR:  00021032   CR: 24942424  XER: 

GPR00: c001b780 cb981c80 c151c1e0 0021 3bff 085b 0027 c8eb644c
GPR08: 0023    24942424 0076f8c8  000186a0
GPR16: afab5544 afab5540 afab553c afab5538 afab5534 afab5530 0004 0078a934
GPR24:   0078a970 0200 c1497b60 0078a930 0300 cb981cc0
NIP [c001b780] do_page_fault+0x484/0x720
LR [c001b780] do_page_fault+0x484/0x720
Call Trace:
[cb981c80] [c001b780] do_page_fault+0x484/0x720 (unreliable)
[cb981cb0] [c000424c] DataAccess_virt+0xd4/0xe4
--- interrupt: 300 at __copy_tofrom_user+0x110/0x20c
NIP:  c001f9bc LR: c0172b04 CTR: 0001
REGS: cb981cc0 TRAP: 0300   Not tainted  (5.13.0-pmac-VMAP)
MSR:  9032   CR: 442444e8  XER: 2000
DAR: 0078a930 DSISR: 0a00
GPR00:  cb981d80 c151c1e0 0078a930 cb981db8 0004 0078a92c 0100
GPR08: 0122 10c279a1 1000 c1800034 242444e2 0076f8c8  000186a0
GPR16: afab5544 afab5540 afab553c afab5538 afab5534 afab5530 0004 0078a934
GPR24:   0078a970 0078a930 cb981dac cb981dac 0001 0004
NIP [c001f9bc] __copy_tofrom_user+0x110/0x20c
LR [c0172b04] core_sys_select+0x3e8/0x594
--- interrupt: 300
[cb981d80] [c0172960] core_sys_select+0x244/0x594 (unreliable)
[cb981ee0] [c0172d98] kern_select+0xe8/0x158
[cb981f30] [c001604c] ret_from_syscall+0x0/0x28
--- interrupt: c00 at 0xa7a4f388
NIP:  a7a4f388 LR: a7a4f35c CTR: 
REGS: cb981f40 TRAP: 0c00   Not tainted  (5.13.0-pmac-VMAP)
MSR:  d032   CR: 240044e2  XER: 2000

GPR00: 008e afab54e0 a73cc7d0 000c 0078a930 0078a970  
GPR08: 0004   a79e45b0 28004462 0076f8c8  000186a0
GPR16: afab5544 afab5540 afab553c afab5538 afab5534 afab5530 0004 00770490
GPR24: afab552f 0004  0078a930  00771734 a7b2fff4 00798cb0
NIP [a7a4f388] 0xa7a4f388
LR [a7a4f35c] 0xa7a4f35c
--- interrupt: c00
Instruction dump:
3884aa30 3863012c 4807685d 807f0080 48042e41 2f83 419e0148 3c80c079
3c60c076 38841b6c 38630174 4801f701 <0fe0> 386b 4bfffe30 3c80c06b
---[ end trace c6ec12d4725e6f89 ]---

> I'll enter the same commands for the other three boots. It may be 
> important that I didn't see errors until there was significant network 
> access.
> 
> For 4), the PB 3400c also booted normally. Errors started after
> logging in via ssh when I entered "dmesg". To be consistent with the
> first test, I followed that with "ls -Rail /usr/bin" and saw more
> errors. A normal reboot ("shutdown -r now") caused even more errors.
> 

Here's the relevant portion of that log:

Kernel attempted to write user page (ba3bc0) - exploit attempt? (uid: 1000)
[ cut here ]
Bug: Write fault blocked by KUAP!
WARNING: CPU: 0 PID: 1609 at arch/powerpc/mm/fault.c:230 
do_page_fault+0x484/0x720
Modules linked in:
CPU: 0 PID: 1609 Comm: bash Not tainted 5.13.0-pmac-NO_VMAP #11
NIP:  c001b780 LR: c001b780 CTR: 
REGS: c3c5bba0 TRAP: 0700   Not tainted  (5.13.0-pmac-NO_VMAP)
MSR:  00021032   CR: 24442424  XER: 

GPR00: c001b780 c3c5bc60 c3842ca0 0021 3bff 

Re: [PATCH] powerpc/32s: Fix napping restore in data storage interrupt (DSI)

2021-08-03 Thread Finn Thain
On Tue, 3 Aug 2021, Christophe Leroy wrote:

> When a DSI (Data Storage Interrupt) is taken while in NAP mode, r11 
> doesn't survive the call to power_save_ppc32_restore().
> 
> So use r1 instead of r11 as they both contain the virtual stack pointer 
> at that point.
> 
> Reported-by: Finn Thain 
> Fixes: 4c0104a83fc3 ("powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE")

Regarding that 'Fixes' tag, this patch has not fixed the failure below, 
unfortunately. But there appears to be several bugs in play here. Can you 
tell us which failure mode is associated with the bug addressed by this 
patch?

[ cut here ]
kernel BUG at arch/powerpc/kernel/interrupt.c:49!
Oops: Exception in kernel mode, sig: 5 [#1]
BE PAGE_SIZE=4K MMU=Hash SMP NR_CPUS=2 PowerMac
Modules linked in:
CPU: 0 PID: 1859 Comm: xfce4-session Not tainted 5.13.0-pmac-VMAP #10
NIP:  c0011474 LR: c0011464 CTR: 
REGS: e2f75e40 TRAP: 0700   Not tainted  (5.13.0-pmac-VMAP)
MSR:  00021032   CR: 2400446c  XER: 2000

GPR00: c001604c e2f75f00 ca284a60   a5205eb0 0008 0020
GPR08: ffc0 0001 501200d9 ce030005 ca285010 00c1f778  
GPR16: 00945b20 009402f8 0001 a6b87550 a51fd000 afb73220 a6b22c78 a6a6aecc
GPR24:  ffc0 0020 0008 a5205eb0  e2f75f40 00ae
NIP [c0011474] system_call_exception+0x60/0x164
LR [c0011464] system_call_exception+0x50/0x164
Call Trace:
[e2f75f00] [9000] 0x9000 (unreliable)
[e2f75f30] [c001604c] ret_from_syscall+0x0/0x28
--- interrupt: c00 at 0xa69d6cb0
NIP:  a69d6cb0 LR: a69d6c3c CTR: 
REGS: e2f75f40 TRAP: 0c00   Not tainted  (5.13.0-pmac-VMAP)
MSR:  d032   CR: 2400446c  XER: 2000

GPR00: 00ae a5205de0 a5687ca0   a5205eb0 0008 0020
GPR08: ffc0 401201ea 401200d9  c158f230 00c1f778  
GPR16: 00945b20 009402f8 0001 a6b87550 a51fd000 afb73220 a6b22c78 a6a6aecc
GPR24: afb72fc8  0001 a5205f30 afb733dc  a6b85ff4 a5205eb0
NIP [a69d6cb0] 0xa69d6cb0
LR [a69d6c3c] 0xa69d6c3c
--- interrupt: c00
Instruction dump:
7cdb3378 93810020 7cbc2b78 93a10024 7c9d2378 93e1002c 7d3f4b78 4800d629
817e0084 931e0088 69690002 5529fffe <0f09> 69694000 552997fe 0f09
---[ end trace c66c6c3c44806276 ]---


Re: Debian SID kernel doesn't boot on PowerBook 3400c

2021-08-03 Thread Finn Thain


On Tue, 3 Aug 2021, Christophe Leroy wrote:

> 
> Looks like the memory errors are linked to KUAP (Kernel Userspace Access 
> Protection). Based on the places the problems happen, I don't think 
> there are any invalid access, so there must be something wrong in the 
> KUAP logic, probably linked to some interrupts happenning in kernel mode 
> while the KUAP window is opened. And because is not selected by default 
> on book3s/32 until 5.14, probably nobody ever tested it in a real 
> environment before you.
> 
> I think the issue may be linked to commit 
> https://github.com/linuxppc/linux/commit/c16728835 which happened 
> between 5.12 and 5.13.

The messages, "Kernel attempted to write user page (c6207c) - exploit 
attempt? (uid: 0)", appear in the console logs generated by v5.13. Those 
logs come from the Powerbook G3 discussion in the other thread. Could that 
be the same bug?


Re: Debian SID kernel doesn't boot on PowerBook 3400c

2021-08-03 Thread Finn Thain
On Tue, 3 Aug 2021, Stan Johnson wrote:

> 
> I'm not sure of the issue you are referencing. If it's the Wallstreet 
> issue, I believe we were waiting to hear back from you regarding the 
> memory errors that crop up with CONFIG_VMAP_STACK=y and mem >464M. 
> Finn, if that is not correct, please let me know.
> 

No, it's not correct. I sent a message dated 3 Aug 2021 with a patch from 
Christophe. I also sent (privately) a message with instructions for 
testing that patch. I will resend these now.


Re: [PATCH v3 31/41] powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE

2021-08-02 Thread Finn Thain
On Mon, 2 Aug 2021, LEROY Christophe wrote:

> Le 01/08/2021 à 03:21, Finn Thain a écrit :
> > On Sat, 31 Jul 2021, Christophe Leroy wrote:
> > 
> > > > 
> > > > Stan Johnson contacted me about a regression in mainline that he
> > > > observed on his G3 Powerbooks. Using 'git bisect' we determined that
> > > > this patch was the cause of the regression, i.e. commit 4c0104a83fc3
> > > > ("powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE").
> > > > 
> > > > When testing 4c0104a83fc and all subsequent builds, various user
> > > > processes were liable to segfault. Here is the console log that Stan
> > > > provided:
> > > 
> > > Hi, i will be able to look at that more in details next week, however I
> > > have a few preliminary qurstions.
> > > 
> > > Can you reliabily reproduce the problem with the said commit, and can
> > > you reliabily run without problem with the parent commit ?
> > 
> > Yes and yes. (I already asked Stan to establish those things before I
> > contacted the list.)
> 
> I think I found the problem with that commit. Can you retry with the following
> change:
> 
> diff --git a/arch/powerpc/kernel/head_book3s_32.S
> b/arch/powerpc/kernel/head_book3s_32.S
> index 0a3d7d4a9ec4..a294103a91a1 100644
> --- a/arch/powerpc/kernel/head_book3s_32.S
> +++ b/arch/powerpc/kernel/head_book3s_32.S
> @@ -299,7 +299,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
>   EXCEPTION_PROLOG_1
>   EXCEPTION_PROLOG_2 0x300 DataAccess handle_dar_dsisr=1
>   prepare_transfer_to_handler
> - lwz r5, _DSISR(r11)
> + lwz r5, _DSISR(r1)
>   andis.  r0, r5, DSISR_DABRMATCH@h
>   bne-1f
>   bl  do_page_fault

That patch doesn't apply to mainline. This version might help.

diff --git a/arch/powerpc/kernel/head_book3s_32.S 
b/arch/powerpc/kernel/head_book3s_32.S
index 764edd860ed4..68e5c0a7e99d 100644
--- a/arch/powerpc/kernel/head_book3s_32.S
+++ b/arch/powerpc/kernel/head_book3s_32.S
@@ -300,7 +300,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
EXCEPTION_PROLOG_1
EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataAccess handle_dar_dsisr=1
prepare_transfer_to_handler
-   lwz r5, _DSISR(r11)
+   lwz r5, _DSISR(r1)
andis.  r0, r5, DSISR_DABRMATCH@h
bne-1f
bl  do_page_fault

Re: [PATCH v3 31/41] powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE

2021-08-01 Thread Finn Thain
On Sun, 1 Aug 2021, Stan Johnson wrote:

> > 
> >> Could you try without CONFIG_VMAP_STACK
> >>
> > 
> > Stan, would you please test the following build:
> > 
> > $ git checkout v5.13
> > $ cp ../dot-config-powermac-5.13 .config
> > $ scripts/config -d CONFIG_VMAP_STACK
> > $ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
> > vmlinux
> > 
> Please see the attached serial console log (four boots):
> 1) v5.13-mac, CONFIG_VMAP_STACK=y, mem=512M (fails)
> 2) v5.13-mac, CONFIG_VMAP_STACK=y, mem=384M (works)
> 3) v5.13-mac, CONFIG_VMAP_STACK=n, mem=512M (works)
> 4) v5.13-mac, CONFIG_VMAP_STACK=n, mem=384M (works)
> 
> My apologies if the extra boots were not needed (due to the time
> difference, I'm trying to anticipate future requests).
> 
> Cutting and pasting Finn's commands above builds a new kernel
> (5.13.0-pmac) with the following in .config:
> 
> $ fgrep VMAP .config
> CONFIG_HAVE_ARCH_VMAP_STACK=y
> CONFIG_VMAP_STACK=y
> 

That's odd. It works correctly here:

$ cp ../dot-config-powermac-5.13 .config
$ grep CONFIG_VMAP_STACK .config
CONFIG_VMAP_STACK=y
$ scripts/config -d CONFIG_VMAP_STACK
$ grep CONFIG_VMAP_STACK .config
# CONFIG_VMAP_STACK is not set

Anyway, I see that you resolved the problem:

> ...
> 
> $ fgrep VMAP .config
> CONFIG_HAVE_ARCH_VMAP_STACK=y
> # CONFIG_VMAP_STACK is not set
> 
> 3) Same as 1 (512M) but with CONFIG_VMAP_STACK not set in v5.13.
> Everything works (no problems with X, no errors logged).
> 
> 4) Same as 2 (384M) but with CONFIG_VMAP_STACK not set in v5.13.
> Everything works (no problems with X, no errors logged).
> 

Thanks for collecting those results.

It appears that Christophe was right. Disabling CONFIG_VMAP_STACK avoids 
the crashes in v5.13. (Enabling CONFIG_VMAP_STACK worked fine in v5.12.)


Re: [PATCH v3 31/41] powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE

2021-07-31 Thread Finn Thain
On Sat, 31 Jul 2021, Christophe Leroy wrote:

> > 
> > Stan Johnson contacted me about a regression in mainline that he 
> > observed on his G3 Powerbooks. Using 'git bisect' we determined that 
> > this patch was the cause of the regression, i.e. commit 4c0104a83fc3 
> > ("powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE").
> > 
> > When testing 4c0104a83fc and all subsequent builds, various user 
> > processes were liable to segfault. Here is the console log that Stan 
> > provided:
> 
> Hi, i will be able to look at that more in details next week, however I 
> have a few preliminary qurstions.
> 
> Can you reliabily reproduce the problem with the said commit, and can 
> you reliabily run without problem with the parent commit ? 

Yes and yes. (I already asked Stan to establish those things before I 
contacted the list.)

> I'm asking because at first look that commit doesn't bring any 
> functionnal change.
> 
> Coukd you provide your .config ?
> 

Please see attached. My understanding is that all of Stan's builds were 
performed like this:

$ cp ../dot-config-powermac-5.13 .config
$ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
vmlinux

> Could you try without CONFIG_VMAP_STACK
> 

Stan, would you please test the following build:

$ git checkout v5.13
$ cp ../dot-config-powermac-5.13 .config
$ scripts/config -d CONFIG_VMAP_STACK
$ make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- -j4 clean olddefconfig 
vmlinux#
# Automatically generated file; DO NOT EDIT.
# Linux/powerpc 5.13.0 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="powerpc-linux-gnu-gcc (btc) 6.4.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=60400
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=22800
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=22800
CONFIG_LLD_VERSION=0
CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO=y
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION="-pmac"
CONFIG_LOCALVERSION_AUTO=y
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_WATCH_QUEUE is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
# CONFIG_USELIB is not set
# CONFIG_AUDIT is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
# end of IRQ subsystem

CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CMOS_UPDATE=y

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
# end of Timers subsystem

CONFIG_BPF=y
CONFIG_HAVE_EBPF_JIT=y

#
# BPF subsystem
#
# CONFIG_BPF_SYSCALL is not set
# CONFIG_BPF_JIT is not set
# end of BPF subsystem

# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_PSI is not set
# end of CPU/Task time and stats accounting

# CONFIG_CPU_ISOLATION is not set

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
CONFIG_TREE_SRCU=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RCU_NEED_SEGCBLIST=y
# end of RCU Subsystem

# CONFIG_IKCONFIG is not set
# CONFIG_IKHEADERS is not set
CONFIG_LOG_BUF_SHIFT=15
CONFIG_LOG_CPU_MAX_BUF_SHIFT=0
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13

#
# Scheduler features
#
# end of Scheduler features

CONFIG_CGROUPS=y
# CONFIG_MEMCG is not set
# CONFIG_BLK_CGROUP is not set
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CGROUP_PIDS is not set
# CONFIG_CGROUP_RDMA is not set
# CONFIG_CGROUP_FREEZER is not set
# CONFIG_CPUSETS is not set
# CONFIG_CGROUP_DEVICE is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_CGROUP_MISC is not set
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_TIME_NS is not set
CONFIG_IPC_NS=y
# CONFIG_USER_NS is not set
CONFIG_PID_NS=y
CONFIG_NET_NS=y
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y
CONFIG_RD_ZSTD=y
# CONFIG_BOOT_CONFIG is not set
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
CONFIG_LD_ORPHAN_WARN=y
CONFIG_SYSCTL=y

Re: [PATCH v3 31/41] powerpc/32: Dismantle EXC_XFER_STD/LITE/TEMPLATE

2021-07-31 Thread Finn Thain
Hi Christophe,

On Fri, 12 Mar 2021, Christophe Leroy wrote:

> In order to get more control in exception prolog, dismantle all non 
> standard exception macros, finishing with EXC_XFER_STD and EXC_XFER_LITE 
> and EXC_XFER_TEMPLATE.
> 
> Also remove transfer_to_handler_full and ret_from_except and 
> ret_from_except_full as they are not used anymore.
> 
> Last parameter of EXCEPTION() is now ignored, will be removed in a later 
> patch to avoid too much churn.
> 
> Signed-off-by: Christophe Leroy 
> ---
>  arch/powerpc/kernel/entry_32.S   | 42 +---
>  arch/powerpc/kernel/head_32.h| 21 
>  arch/powerpc/kernel/head_40x.S   | 33 ---
>  arch/powerpc/kernel/head_8xx.S   | 12 +--
>  arch/powerpc/kernel/head_book3s_32.S | 27 ++-
>  arch/powerpc/kernel/head_booke.h | 49 +++-
>  arch/powerpc/kernel/head_fsl_booke.S | 14 +---
>  7 files changed, 92 insertions(+), 106 deletions(-)
> 

Stan Johnson contacted me about a regression in mainline that he observed 
on his G3 Powerbooks. Using 'git bisect' we determined that this patch was 
the cause of the regression, i.e. commit 4c0104a83fc3 ("powerpc/32: 
Dismantle EXC_XFER_STD/LITE/TEMPLATE").

When testing 4c0104a83fc and all subsequent builds, various user processes 
were liable to segfault. Here is the console log that Stan provided:

[0.00] printk: debug: ignoring loglevel setting.
[0.00] Total memory = 512MB; using 1024kB for hash table
[0.00] Activating Kernel Userspace Execution Prevention
[0.00] Activating Kernel Userspace Access Protection
[0.00] Linux version 5.12.0-rc3-pmac-00067-g4c0104a83fc 
(johnson@ThinkPad) (powerpc-linux-gnu-gcc (Debian 8.3.0-2) 8.3.0, GNU ld (GNU 
Binutils for Debian) 2.31.1) #22 SMP Fri Jul 30 12:15:00 MDT 2021
[0.00] ioremap() called early from probe_one_macio+0x130/0x268. Use 
early_ioremap() instead
[0.00] Found a Gatwick mac-io controller, rev: 0, mapped at 0x(ptrval)
[0.00] ioremap() called early from probe_one_macio+0x130/0x268. Use 
early_ioremap() instead
[0.00] Found a Heathrow mac-io controller, rev: 0, mapped at 0x(ptrval)
[0.00] PowerMac motherboard: PowerBook Wallstreet
[0.00] ioremap() called early from find_via_pmu+0x244/0x56c. Use 
early_ioremap() instead
[0.00] PMU driver v2 initialized for PowerBook G3 Series, firmware: 0a
[0.00] Using PowerMac machine description
[0.00] printk: bootconsole [udbg0] enabled
[0.00] CPU maps initialized for 1 thread per core
[0.00]  (thread shift is 0)
[0.00] -
[0.00] phys_mem_size = 0x2000
[0.00] dcache_bsize  = 0x20
[0.00] icache_bsize  = 0x20
[0.00] cpu_features  = 0x0501a008
[0.00]   possible= 0x277de14a
[0.00]   always  = 0x0100
[0.00] cpu_user_features = 0x8c01 0x
[0.00] mmu_features  = 0x0001
[0.00] Hash_size = 0x10
[0.00] Hash_mask = 0x3fff
[0.00] -
[0.00] ioremap() called early from pmac_setup_arch+0x10c/0x294. Use 
early_ioremap() instead
[0.00] nvram: OF partition at 0x1800
[0.00] nvram: XP partition at 0x1300
[0.00] nvram: NR partition at 0x1400
[0.00] Top of RAM: 0x2000, Total RAM: 0x2000
[0.00] Memory hole size: 0MB
[0.00] Zone ranges:
[0.00]   DMA  [mem 0x-0x1fff]
[0.00]   Normal   empty
[0.00]   HighMem  empty
[0.00] Movable zone start for each node
[0.00] Early memory node ranges
[0.00]   node   0: [mem 0x-0x1fff]
[0.00] Initmem setup node 0 [mem 0x-0x1fff]
[0.00] On node 0 totalpages: 131072
[0.00]   DMA zone: 1024 pages used for memmap
[0.00]   DMA zone: 0 pages reserved
[0.00]   DMA zone: 131072 pages, LIFO batch:31
[0.00] percpu: Embedded 13 pages/cpu s21644 r8192 d23412 u53248
[0.00] pcpu-alloc: s21644 r8192 d23412 u53248 alloc=13*4096
[0.00] pcpu-alloc: [0] 0 [0] 1
[0.00] Built 1 zonelists, mobility grouping on.  Total pages: 130048
[0.00] Kernel command line: root=/dev/sda12 console=ttyS0 console=tty 
printk.time earlyprintk ignore_loglevel video=ofonly
[0.00] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes, 
linear)
[0.00] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes, 
linear)
[0.00] mem auto-init: stack:off, heap alloc:off, heap free:off
[0.00] Memory: 498908K/524288K available (6756K kernel code, 352K 
rwdata, 1276K rodata, 1232K init, 176K bss, 25380K reserved, 0K cma-reserved, 
0K 

[PATCH v2] powerpc/tau: Remove superfluous parameter in alloc_workqueue() call

2021-06-11 Thread Finn Thain
This avoids an (optional) compiler warning:

arch/powerpc/kernel/tau_6xx.c: In function 'TAU_init':
arch/powerpc/kernel/tau_6xx.c:204:30: error: too many arguments for format 
[-Werror=format-extra-args]
  tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0);

Reported-by: Naresh Kamboju 
Fixes: b1c6a0a10bfa ("powerpc/tau: Convert from timer to workqueue")
Signed-off-by: Finn Thain 
---
Changed since v1:
 - Improved commit log message.
---
 arch/powerpc/kernel/tau_6xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index 6c31af7f4fa8..b9a047d92ec0 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -201,7 +201,7 @@ static int __init TAU_init(void)
tau_int_enable = IS_ENABLED(CONFIG_TAU_INT) &&
 !strcmp(cur_cpu_spec->platform, "ppc750");
 
-   tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0);
+   tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1);
if (!tau_workq)
return -ENOMEM;
 
-- 
2.26.3



[PATCH] powerpc/tau: Remove redundant parameter in alloc_workqueue() call

2021-06-10 Thread Finn Thain
This avoids an (optional) compiler warning:

arch/powerpc/kernel/tau_6xx.c: In function 'TAU_init':
arch/powerpc/kernel/tau_6xx.c:204:30: error: too many arguments for format 
[-Werror=format-extra-args]
  tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0);

Reported-by: Naresh Kamboju 
Fixes: b1c6a0a10bfa ("powerpc/tau: Convert from timer to workqueue")
Signed-off-by: Finn Thain 
---
 arch/powerpc/kernel/tau_6xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index 6c31af7f4fa8..b9a047d92ec0 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -201,7 +201,7 @@ static int __init TAU_init(void)
tau_int_enable = IS_ENABLED(CONFIG_TAU_INT) &&
 !strcmp(cur_cpu_spec->platform, "ppc750");
 
-   tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0);
+   tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1);
if (!tau_workq)
return -ENOMEM;
 
-- 
2.26.3



Re: remove the legacy ide driver

2021-03-18 Thread Finn Thain
On Thu, 18 Mar 2021, Christoph Hellwig wrote:

> Hi all,
> 
> we've been trying to get rid of the legacy ide driver for a while now,
> and finally scheduled a removal for 2021, which is three month old now.
> 
> In general distros and most defconfigs have switched to libata long ago,
> but there are a few exceptions.  This series first switches over all
> remaining defconfigs to use libata and then removes the legacy ide
> driver.
> 
> libata mostly covers all hardware supported by the legacy ide driver.
> There are three mips drivers that are not supported, but the linux-mips
> list could not identify any users of those.  There also are two m68k
> drivers that do not have libata equivalents, which might or might not
> have users, so we'll need some input and possibly help from the m68k
> community here.
> 

A few months ago I wrote another patch to move some more platforms away 
from macide but it has not been tested yet. That is not to say you should 
wait. However, my patch does have some changes that are missing from your 
patch series, relating to ide platform devices in arch/m68k/mac/config.c. 
I hope to be able to test this patch before the 5.13 merge window closes.


Re: [PATCH] scsi: target/sbp: remove firewire SBP target driver

2021-01-04 Thread Finn Thain
On Mon, 4 Jan 2021, Bart Van Assche wrote:

> On 6/16/20 7:07 PM, Finn Thain wrote:
> > On Tue, 16 Jun 2020, Bart Van Assche wrote:
> >> As far as I know the sbp driver only has had one user ever and that 
> >> user is no longer user the sbp driver.
> > 
> > So, you estimate the userbase at zero. Can you give a confidence 
> > level? Actual measurement is hard because when end users encounter 
> > breakage, they look for quick workarounds before they undertake post 
> > mortem, log collection, bug reporting, mailing list discussions, 
> > analysis etc.
> 
> (replying to an e-mail from six months ago)
> 
> Hi Finn,
> 
> I am confident that my estimate is an accurate estimate since I have not 
> seen any sbp support requests, sbp bug reports nor any sbp bug fixes 
> since the sbp target driver has been accepted upstream.
> 

That suggests to me that the code that you're hoping to remove 1) has no 
bugs, or 2) has no reported bugs, or 3) has no users at present.

I am confident that your evidence does not support your conclusion (i.e. 
the code will never be used again).

Sometimes, users only appear after the unreported bugs get fixed. I've 
seen it happen.

> > Here's a different question: "Why remove it from the kernel tree?"
> > 
> > If maintaining this code is a burden, is it not the kind of tax that 
> > all developers/users pay to all developers/users? Does this driver 
> > impose an unreasonably high burden for some reason?
> 
> Yes. If anyone wants to change the interface between SCSI target core 
> and SCSI target drivers, all target drivers, including the sbp and FCoE 
> target driver have to be retested.

I'm unaware of such an obligation. API changes happen often. When they do, 
we see good test coverage of commercially viable hardware, some 
best-effort testing of common hardware, and some perfunctory build 
testing.

But that is missing the point, which was about a particular driver, not 
about development process. You have not shown how the target API is 
special, to support your claim that this driver imposes an unreasonable 
burden.

In the interests of making forward progress in this discussion, shall we 
discuss the kind of SCSI Target API changes that you anticipate?

> In other words, keeping unused target drivers inside the kernel tree 
> involves a significant maintenance burden for anyone who wants to modify 
> the interface between the SCSI target core and SCSI target drivers.
> 

Keeping _any_ driver in the kernel involves a maintenance burden. There 
are two good ways to address that.

Firstly, by improving the development process. For example, an API change 
is mostly mechanical work that lends itself to automated refactoring.
Secondly, by involving all interested parties, so that the burden is 
shared.

Of course, there are other ways. E.g. "don't ship code when doing so won't 
turn a profit". That, by the way, was the policy that gave us 10 billion 
Android devices (or more) that don't function with a mainline kernel.

> Additionally, there is a good alternative available for the sbp driver. 
> Every system I know of that is equipped with a Firewire port also has an 
> Ethernet port. So users who want to provide SCSI target functionality on 
> such systems can use any SCSI transport protocol that is compatible with 
> Ethernet (iSCSI, iSER over soft-RoCE, SRP over soft-RoCE, ...).
> 

Ethernet is not always an alternative. That was already discussed in this 
thread. But let's assume for a moment that you can migrate any and all 
users of this driver over to an ethernet driver.

Why would the maintainers of that ethernet driver and its API accept that 
plan, if adding users would extend their maintenance and testing 
obligations? Do you think those maintainers should pay the "kind of tax 
that all developers/users pay to all developers/users?"

> Thanks,
> 
> Bart.
> 


[PATCH] MAINTAINERS: Update 68k Mac entry

2020-12-04 Thread Finn Thain
Two files under drivers/macintosh are actually m68k-only. I think that
patches for these files should be reviewed in the appropriate forum and
merged via the appropriate tree, rather than falling to the powerpc
maintainers to deal with. Update the "M68K ON APPLE MACINTOSH" section
accordingly.

Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Joshua Thompson 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-m...@lists.linux-m68k.org
Signed-off-by: Finn Thain 
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 867157311dc8..e8fa0c9645d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10322,6 +10322,8 @@ L:  linux-m...@lists.linux-m68k.org
 S: Maintained
 W: http://www.mac.linux-m68k.org/
 F: arch/m68k/mac/
+F: drivers/macintosh/adb-iop.c
+F: drivers/macintosh/via-macii.c
 
 M68K ON HP9000/300
 M: Philip Blundell 
-- 
2.26.2



Re: [PATCH] macintosh/adb-iop: Send correct poll command

2020-12-04 Thread Finn Thain
On Fri, 4 Dec 2020, Geert Uytterhoeven wrote:

> Hi Finn,
> 
> On Fri, Nov 20, 2020 at 5:54 AM Finn Thain  wrote:
> > The behaviour of the IOP firmware is not well documented but we do know
> > that IOP message reply data can be used to issue new ADB commands.
> > Use the message reply to better control autopoll behaviour by sending
> > a Talk Register 0 command after every ADB response, not unlike the
> > algorithm in the via-macii driver. This poll command is addressed to
> > that device which last received a Talk command (explicit or otherwise).
> >
> > Cc: Joshua Thompson 
> > Fixes: fa3b5a9929fc ("macintosh/adb-iop: Implement idle -> sending state 
> > transition")
> 
> WARNING: Unknown commit id 'fa3b5a9929fc', maybe rebased or not pulled?
> 
> 32226e817043?
> 

Yes, that's the one. I accidentally gave a commit id from one of my 
backport branches.

> > Tested-by: Stan Johnson 
> > Signed-off-by: Finn Thain 
> 
> Thanks, will queue in the m68k for-v5.11 branch.
> 

Thanks.

> Gr{oetje,eeting}s,
> 
> Geert
> 
> 


Re: [PATCH] macintosh/adb-iop: Always wait for reply message from IOP

2020-12-04 Thread Finn Thain
On Fri, 4 Dec 2020, Geert Uytterhoeven wrote:

> Hi Finn,
> 
> On Fri, Nov 20, 2020 at 5:54 AM Finn Thain  wrote:
> > A recent patch incorrectly altered the adb-iop state machine behaviour
> > and introduced a regression that can appear intermittently as a
> > malfunctioning ADB input device. This seems to be caused when reply
> > packets from different ADB commands become mixed up, especially during
> > the adb bus scan. Fix this by unconditionally entering the awaiting_reply
> > state after sending an explicit command, even when the ADB command won't
> > generate a reply from the ADB device.
> >
> > Cc: Joshua Thompson 
> > Fixes: e2954e5f727f ("macintosh/adb-iop: Implement sending -> idle state 
> > transition")
> > Tested-by: Stan Johnson 
> > Signed-off-by: Finn Thain 
> 
> Thanks for your patch!
> 
> > --- a/drivers/macintosh/adb-iop.c
> > +++ b/drivers/macintosh/adb-iop.c
> > @@ -84,10 +84,7 @@ static void adb_iop_complete(struct iop_msg *msg)
> >
> > local_irq_save(flags);
> >
> > -   if (current_req->reply_expected)
> > -   adb_iop_state = awaiting_reply;
> > -   else
> > -   adb_iop_done();
> > +   adb_iop_state = awaiting_reply;
> >
> > local_irq_restore(flags);
> >  }
> > @@ -95,8 +92,9 @@ static void adb_iop_complete(struct iop_msg *msg)
> >  /*
> >   * Listen for ADB messages from the IOP.
> >   *
> > - * This will be called when unsolicited messages (usually replies to TALK
> > - * commands or autopoll packets) are received.
> > + * This will be called when unsolicited IOP messages are received.
> > + * These IOP messages can carry ADB autopoll responses and also occur
> > + * after explicit ADB commands.
> >   */
> >
> >  static void adb_iop_listen(struct iop_msg *msg)
> > @@ -123,8 +121,10 @@ static void adb_iop_listen(struct iop_msg *msg)
> > if (adb_iop_state == awaiting_reply) {
> > struct adb_request *req = current_req;
> >
> > -   req->reply_len = amsg->count + 1;
> > -   memcpy(req->reply, >cmd, req->reply_len);
> > +   if (req->reply_expected) {
> > +   req->reply_len = amsg->count + 1;
> > +   memcpy(req->reply, >cmd, 
> > req->reply_len);
> > +   }
> 
> So if we're not expecting a reply. It's ignored.
> Just wondering: what kind of messages are being dropped?

I believe they were empty, with flags == ADB_IOP_EXPLICIT|ADB_IOP_TIMEOUT.

> If reply packets from different ADB commands become mixed up, they are 
> still (expected?) replies to messages we sent before. Why shouldn't we 
> depend on receiving the replies?
> 

It turns out that the IOP always generates reply messages, even when the 
ADB command does not produce a reply packet (e.g. ADB Listen command). 

The commit being fixed got that wrong.

So it's not really the ADB reply packets that are being mixed up, it's the 
IOP messages that enclose them. The bug goes like this:

1. CPU sends a message to the IOP, expecting no response because this 
message contains an ADB Listen command. The ADB command is now considered 
complete.

2. CPU sends a second message to the IOP, this time expecting a response 
because this message contains an ADB Talk command. This ADB command needs 
a reply before it can be completed.

3. adb-iop driver receives an IOP message and assumes that it relates to 
the Talk command. It's actually for the previous command. The Talk command 
is now considered complete but it gets the wrong reply data.

4. adb-iop driver gets another IOP response message, which contains the 
actual reply data for the Talk command, but this is dropped (the driver is 
no longer in awaiting_reply state).

Please go ahead and add this analysis to the commit log if you think it 
would help.

> >
> > req_done = true;
> > }
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 
> 


[PATCH v2] m68k: Fix WARNING splat in pmac_zilog driver

2020-11-21 Thread Finn Thain
Don't add platform resources that won't be used. This avoids a
recently-added warning from the driver core, that can show up on a
multi-platform kernel when !MACH_IS_MAC.

[ cut here ]
WARNING: CPU: 0 PID: 0 at drivers/base/platform.c:224 
platform_get_irq_optional+0x8e/0xce
0 is an invalid IRQ number
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.9.0-multi #1
Stack from 004b3f04:
004b3f04 00462c2f 00462c2f 004b3f20 0002e128 004754db 004b6ad4 004b3f4c
0002e19c 004754f7 00e0 00285ba0 0009  004b3f44 
004754db 004b3f64 004b3f74 00285ba0 004754f7 00e0 0009 004754db
004fdf0c 005269e2 004fdf0c  004b3f88 00285cae 004b6964 
004fdf0c 004b3fac 0051cc68 004b6964  004b6964 0200 
0051cc3e 0023c18a 004b3fc0 0051cd8a 004fdf0c 0002 0052b43c 004b3fc8
Call Trace: [<0002e128>] __warn+0xa6/0xd6
 [<0002e19c>] warn_slowpath_fmt+0x44/0x76
 [<00285ba0>] platform_get_irq_optional+0x8e/0xce
 [<00285ba0>] platform_get_irq_optional+0x8e/0xce
 [<00285cae>] platform_get_irq+0x12/0x4c
 [<0051cc68>] pmz_init_port+0x2a/0xa6
 [<0051cc3e>] pmz_init_port+0x0/0xa6
 [<0023c18a>] strlen+0x0/0x22
 [<0051cd8a>] pmz_probe+0x34/0x88
 [<0051cde6>] pmz_console_init+0x8/0x28
 [<00511776>] console_init+0x1e/0x28
 [<0005a3bc>] printk+0x0/0x16
 [<0050a8a6>] start_kernel+0x368/0x4ce
 [<005094f8>] _sinittext+0x4f8/0xc48
random: get_random_bytes called from print_oops_end_marker+0x56/0x80 with 
crng_init=0
---[ end trace 392d8e82eed68d6c ]---

Commit a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is invalid"),
which introduced the WARNING, suggests that testing for irq == 0 is
undesirable. Instead of that comparison, just test for resource existence.

Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Joshua Thompson 
Cc: Greg Kroah-Hartman 
Cc: Jiri Slaby 
Cc: sta...@vger.kernel.org # v5.8+
References: commit a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is 
invalid")
Reported-by: Laurent Vivier 
Signed-off-by: Finn Thain 
---
Changed since v1:
 - Add a comment to explain the need for the global structs.
 - Expand the commit log to better explain the intention of the patch.
---
 arch/m68k/mac/config.c  | 17 +
 drivers/tty/serial/pmac_zilog.c | 14 +-
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 0ac53d87493c..2bea1799b8de 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -777,16 +777,12 @@ static struct resource scc_b_rsrcs[] = {
 struct platform_device scc_a_pdev = {
.name   = "scc",
.id = 0,
-   .num_resources  = ARRAY_SIZE(scc_a_rsrcs),
-   .resource   = scc_a_rsrcs,
 };
 EXPORT_SYMBOL(scc_a_pdev);
 
 struct platform_device scc_b_pdev = {
.name   = "scc",
.id = 1,
-   .num_resources  = ARRAY_SIZE(scc_b_rsrcs),
-   .resource   = scc_b_rsrcs,
 };
 EXPORT_SYMBOL(scc_b_pdev);
 
@@ -813,10 +809,15 @@ static void __init mac_identify(void)
 
/* Set up serial port resources for the console initcall. */
 
-   scc_a_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase + 2;
-   scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
-   scc_b_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase;
-   scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
+   scc_a_rsrcs[0].start = (resource_size_t)mac_bi_data.sccbase + 2;
+   scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
+   scc_a_pdev.num_resources = ARRAY_SIZE(scc_a_rsrcs);
+   scc_a_pdev.resource  = scc_a_rsrcs;
+
+   scc_b_rsrcs[0].start = (resource_size_t)mac_bi_data.sccbase;
+   scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
+   scc_b_pdev.num_resources = ARRAY_SIZE(scc_b_rsrcs);
+   scc_b_pdev.resource  = scc_b_rsrcs;
 
switch (macintosh_config->scc_type) {
case MAC_SCC_PSC:
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 96e7aa479961..216b75ef5048 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -1693,22 +1693,26 @@ static int __init pmz_probe(void)
 
 #else
 
+/* On PCI PowerMacs, pmz_probe() does an explicit search of the OpenFirmware
+ * tree to obtain the device_nodes needed to start the console before the
+ * macio driver. On Macs without OpenFirmware, global platform_devices take
+ * the place of those device_nodes.
+ */
 extern struct platform_device scc_a_pdev, scc_b_pdev;
 
 static int __init pmz_init_port(struct uart_pmac_port *uap)
 {
-   struct resource *r_ports;
-   int irq;
+   struct resource *r_ports, *r_irq;
 
r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0

Re: [PATCH] m68k: Fix WARNING splat in pmac_zilog driver

2020-11-20 Thread Finn Thain
On Fri, 20 Nov 2020, Geert Uytterhoeven wrote:

> Hi Finn,
> 
> On Fri, Nov 20, 2020 at 5:51 AM Finn Thain  wrote:
> > Don't add platform resources that won't be used. This avoids a
> > recently-added warning from the driver core, that can show up on a
> > multi-platform kernel when !MACH_IS_MAC.
> >
> > [ cut here ]
> > WARNING: CPU: 0 PID: 0 at drivers/base/platform.c:224 
> > platform_get_irq_optional+0x8e/0xce
> > 0 is an invalid IRQ number
> > Modules linked in:
> > CPU: 0 PID: 0 Comm: swapper Not tainted 5.9.0-multi #1
> > Stack from 004b3f04:
> > 004b3f04 00462c2f 00462c2f 004b3f20 0002e128 004754db 004b6ad4 
> > 004b3f4c
> > 0002e19c 004754f7 00e0 00285ba0 0009  004b3f44 
> > 
> > 004754db 004b3f64 004b3f74 00285ba0 004754f7 00e0 0009 
> > 004754db
> > 004fdf0c 005269e2 004fdf0c  004b3f88 00285cae 004b6964 
> > 
> > 004fdf0c 004b3fac 0051cc68 004b6964  004b6964 0200 
> > 
> > 0051cc3e 0023c18a 004b3fc0 0051cd8a 004fdf0c 0002 0052b43c 
> > 004b3fc8
> > Call Trace: [<0002e128>] __warn+0xa6/0xd6
> >  [<0002e19c>] warn_slowpath_fmt+0x44/0x76
> >  [<00285ba0>] platform_get_irq_optional+0x8e/0xce
> >  [<00285ba0>] platform_get_irq_optional+0x8e/0xce
> >  [<00285cae>] platform_get_irq+0x12/0x4c
> >  [<0051cc68>] pmz_init_port+0x2a/0xa6
> >  [<0051cc3e>] pmz_init_port+0x0/0xa6
> >  [<0023c18a>] strlen+0x0/0x22
> >  [<0051cd8a>] pmz_probe+0x34/0x88
> >  [<0051cde6>] pmz_console_init+0x8/0x28
> >  [<00511776>] console_init+0x1e/0x28
> >  [<0005a3bc>] printk+0x0/0x16
> >  [<0050a8a6>] start_kernel+0x368/0x4ce
> >  [<005094f8>] _sinittext+0x4f8/0xc48
> > random: get_random_bytes called from print_oops_end_marker+0x56/0x80 with 
> > crng_init=0
> > ---[ end trace 392d8e82eed68d6c ]---
> >
> > Cc: Michael Ellerman 
> > Cc: Benjamin Herrenschmidt 
> > Cc: Paul Mackerras 
> > Cc: Joshua Thompson 
> > Cc: Greg Kroah-Hartman 
> > Cc: Jiri Slaby 
> > Cc: sta...@vger.kernel.org # v5.8+
> > References: commit a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 
> > is invalid")
> > Reported-by: Laurent Vivier 
> > Signed-off-by: Finn Thain 
> > ---
> > The global platform_device structs provide the equivalent of a direct
> > search of the OpenFirmware tree, for platforms that don't have OF.
> > The purpose of that search is discussed in the comments in pmac_zilog.c:
> >
> >  * First, we need to do a direct OF-based probe pass. We
> >  * do that because we want serial console up before the
> >  * macio stuffs calls us back
> >
> > The actual platform bus matching takes place later, with a module_initcall,
> > following the usual pattern.
> 
> I think it would be good for this explanation to be part of the
> actual patch description above.
> 

Thanks for your review.

I take that explanation as read because it was fundamental to the changes 
I made to pmac_zilog.c back in 2009 with commit ec9cbe09899e ("pmac-zilog: 
add platform driver").

IMO, being that it isn't news, it doesn't belong in the changelog. 
However, I agree that it needs to be documented. How about I add a comment 
to pmac_zilog.c?

> > --- a/arch/m68k/mac/config.c
> > +++ b/arch/m68k/mac/config.c
> > @@ -777,16 +777,12 @@ static struct resource scc_b_rsrcs[] = {
> >  struct platform_device scc_a_pdev = {
> > .name   = "scc",
> > .id = 0,
> > -   .num_resources  = ARRAY_SIZE(scc_a_rsrcs),
> > -   .resource   = scc_a_rsrcs,
> >  };
> >  EXPORT_SYMBOL(scc_a_pdev);
> >
> >  struct platform_device scc_b_pdev = {
> > .name   = "scc",
> > .id = 1,
> > -   .num_resources  = ARRAY_SIZE(scc_b_rsrcs),
> > -   .resource   = scc_b_rsrcs,
> >  };
> >  EXPORT_SYMBOL(scc_b_pdev);
> >
> > @@ -813,10 +809,15 @@ static void __init mac_identify(void)
> >
> > /* Set up serial port resources for the console initcall. */
> >
> > -   scc_a_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase + 2;
> > -   scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
> > -   scc_b_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase;
> > -   scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
> > +   scc_a_rsrcs[0].start   

[PATCH] macintosh/adb-iop: Send correct poll command

2020-11-19 Thread Finn Thain
The behaviour of the IOP firmware is not well documented but we do know
that IOP message reply data can be used to issue new ADB commands.
Use the message reply to better control autopoll behaviour by sending
a Talk Register 0 command after every ADB response, not unlike the
algorithm in the via-macii driver. This poll command is addressed to
that device which last received a Talk command (explicit or otherwise).

Cc: Joshua Thompson 
Fixes: fa3b5a9929fc ("macintosh/adb-iop: Implement idle -> sending state 
transition")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 40 +++--
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index f3d1a460fbce..6b26b6a2c463 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -25,6 +25,7 @@
 static struct adb_request *current_req;
 static struct adb_request *last_req;
 static unsigned int autopoll_devs;
+static u8 autopoll_addr;
 
 static enum adb_iop_state {
idle,
@@ -41,6 +42,11 @@ static int adb_iop_autopoll(int);
 static void adb_iop_poll(void);
 static int adb_iop_reset_bus(void);
 
+/* ADB command byte structure */
+#define ADDR_MASK   0xF0
+#define OP_MASK 0x0C
+#define TALK0x0C
+
 struct adb_driver adb_iop_driver = {
.name = "ISM IOP",
.probe= adb_iop_probe,
@@ -96,17 +102,24 @@ static void adb_iop_complete(struct iop_msg *msg)
 static void adb_iop_listen(struct iop_msg *msg)
 {
struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
+   u8 addr = (amsg->cmd & ADDR_MASK) >> 4;
+   u8 op = amsg->cmd & OP_MASK;
unsigned long flags;
bool req_done = false;
 
local_irq_save(flags);
 
-   /* Handle a timeout. Timeout packets seem to occur even after
-* we've gotten a valid reply to a TALK, presumably because of
-* autopolling.
+   /* Responses to Talk commands may be unsolicited as they are
+* produced when the IOP polls devices. They are mostly timeouts.
 */
-
-   if (amsg->flags & ADB_IOP_EXPLICIT) {
+   if (op == TALK && ((1 << addr) & autopoll_devs))
+   autopoll_addr = addr;
+
+   switch (amsg->flags & (ADB_IOP_EXPLICIT |
+  ADB_IOP_AUTOPOLL |
+  ADB_IOP_TIMEOUT)) {
+   case ADB_IOP_EXPLICIT:
+   case ADB_IOP_EXPLICIT | ADB_IOP_TIMEOUT:
if (adb_iop_state == awaiting_reply) {
struct adb_request *req = current_req;
 
@@ -115,12 +128,16 @@ static void adb_iop_listen(struct iop_msg *msg)
 
req_done = true;
}
-   } else if (!(amsg->flags & ADB_IOP_TIMEOUT)) {
-   adb_input(>cmd, amsg->count + 1,
- amsg->flags & ADB_IOP_AUTOPOLL);
+   break;
+   case ADB_IOP_AUTOPOLL:
+   if (((1 << addr) & autopoll_devs) &&
+   amsg->cmd == ADB_READREG(addr, 0))
+   adb_input(>cmd, amsg->count + 1, 1);
+   break;
}
-
-   msg->reply[0] = autopoll_devs ? ADB_IOP_AUTOPOLL : 0;
+   msg->reply[0] = autopoll_addr ? ADB_IOP_AUTOPOLL : 0;
+   msg->reply[1] = 0;
+   msg->reply[2] = autopoll_addr ? ADB_READREG(autopoll_addr, 0) : 0;
iop_complete_message(msg);
 
if (req_done)
@@ -233,6 +250,9 @@ static void adb_iop_set_ap_complete(struct iop_msg *msg)
struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
 
autopoll_devs = (amsg->data[1] << 8) | amsg->data[0];
+   if (autopoll_devs & (1 << autopoll_addr))
+   return;
+   autopoll_addr = autopoll_devs ? (ffs(autopoll_devs) - 1) : 0;
 }
 
 static int adb_iop_autopoll(int devs)
-- 
2.26.2



[PATCH] macintosh/adb-iop: Always wait for reply message from IOP

2020-11-19 Thread Finn Thain
A recent patch incorrectly altered the adb-iop state machine behaviour
and introduced a regression that can appear intermittently as a
malfunctioning ADB input device. This seems to be caused when reply
packets from different ADB commands become mixed up, especially during
the adb bus scan. Fix this by unconditionally entering the awaiting_reply
state after sending an explicit command, even when the ADB command won't
generate a reply from the ADB device.

Cc: Joshua Thompson 
Fixes: e2954e5f727f ("macintosh/adb-iop: Implement sending -> idle state 
transition")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 6b26b6a2c463..0ee327249150 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -84,10 +84,7 @@ static void adb_iop_complete(struct iop_msg *msg)
 
local_irq_save(flags);
 
-   if (current_req->reply_expected)
-   adb_iop_state = awaiting_reply;
-   else
-   adb_iop_done();
+   adb_iop_state = awaiting_reply;
 
local_irq_restore(flags);
 }
@@ -95,8 +92,9 @@ static void adb_iop_complete(struct iop_msg *msg)
 /*
  * Listen for ADB messages from the IOP.
  *
- * This will be called when unsolicited messages (usually replies to TALK
- * commands or autopoll packets) are received.
+ * This will be called when unsolicited IOP messages are received.
+ * These IOP messages can carry ADB autopoll responses and also occur
+ * after explicit ADB commands.
  */
 
 static void adb_iop_listen(struct iop_msg *msg)
@@ -123,8 +121,10 @@ static void adb_iop_listen(struct iop_msg *msg)
if (adb_iop_state == awaiting_reply) {
struct adb_request *req = current_req;
 
-   req->reply_len = amsg->count + 1;
-   memcpy(req->reply, >cmd, req->reply_len);
+   if (req->reply_expected) {
+   req->reply_len = amsg->count + 1;
+   memcpy(req->reply, >cmd, req->reply_len);
+   }
 
req_done = true;
}
-- 
2.26.2



[PATCH] m68k: Fix WARNING splat in pmac_zilog driver

2020-11-19 Thread Finn Thain
Don't add platform resources that won't be used. This avoids a
recently-added warning from the driver core, that can show up on a
multi-platform kernel when !MACH_IS_MAC.

[ cut here ]
WARNING: CPU: 0 PID: 0 at drivers/base/platform.c:224 
platform_get_irq_optional+0x8e/0xce
0 is an invalid IRQ number
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.9.0-multi #1
Stack from 004b3f04:
004b3f04 00462c2f 00462c2f 004b3f20 0002e128 004754db 004b6ad4 004b3f4c
0002e19c 004754f7 00e0 00285ba0 0009  004b3f44 
004754db 004b3f64 004b3f74 00285ba0 004754f7 00e0 0009 004754db
004fdf0c 005269e2 004fdf0c  004b3f88 00285cae 004b6964 
004fdf0c 004b3fac 0051cc68 004b6964  004b6964 0200 
0051cc3e 0023c18a 004b3fc0 0051cd8a 004fdf0c 0002 0052b43c 004b3fc8
Call Trace: [<0002e128>] __warn+0xa6/0xd6
 [<0002e19c>] warn_slowpath_fmt+0x44/0x76
 [<00285ba0>] platform_get_irq_optional+0x8e/0xce
 [<00285ba0>] platform_get_irq_optional+0x8e/0xce
 [<00285cae>] platform_get_irq+0x12/0x4c
 [<0051cc68>] pmz_init_port+0x2a/0xa6
 [<0051cc3e>] pmz_init_port+0x0/0xa6
 [<0023c18a>] strlen+0x0/0x22
 [<0051cd8a>] pmz_probe+0x34/0x88
 [<0051cde6>] pmz_console_init+0x8/0x28
 [<00511776>] console_init+0x1e/0x28
 [<0005a3bc>] printk+0x0/0x16
 [<0050a8a6>] start_kernel+0x368/0x4ce
 [<005094f8>] _sinittext+0x4f8/0xc48
random: get_random_bytes called from print_oops_end_marker+0x56/0x80 with 
crng_init=0
---[ end trace 392d8e82eed68d6c ]---

Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Joshua Thompson 
Cc: Greg Kroah-Hartman 
Cc: Jiri Slaby 
Cc: sta...@vger.kernel.org # v5.8+
References: commit a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is 
invalid")
Reported-by: Laurent Vivier 
Signed-off-by: Finn Thain 
---
The global platform_device structs provide the equivalent of a direct
search of the OpenFirmware tree, for platforms that don't have OF.
The purpose of that search is discussed in the comments in pmac_zilog.c:

 * First, we need to do a direct OF-based probe pass. We
 * do that because we want serial console up before the
 * macio stuffs calls us back

The actual platform bus matching takes place later, with a module_initcall,
following the usual pattern.
---
 arch/m68k/mac/config.c  | 17 +
 drivers/tty/serial/pmac_zilog.c |  9 -
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 0ac53d87493c..2bea1799b8de 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -777,16 +777,12 @@ static struct resource scc_b_rsrcs[] = {
 struct platform_device scc_a_pdev = {
.name   = "scc",
.id = 0,
-   .num_resources  = ARRAY_SIZE(scc_a_rsrcs),
-   .resource   = scc_a_rsrcs,
 };
 EXPORT_SYMBOL(scc_a_pdev);
 
 struct platform_device scc_b_pdev = {
.name   = "scc",
.id = 1,
-   .num_resources  = ARRAY_SIZE(scc_b_rsrcs),
-   .resource   = scc_b_rsrcs,
 };
 EXPORT_SYMBOL(scc_b_pdev);
 
@@ -813,10 +809,15 @@ static void __init mac_identify(void)
 
/* Set up serial port resources for the console initcall. */
 
-   scc_a_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase + 2;
-   scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
-   scc_b_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase;
-   scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
+   scc_a_rsrcs[0].start = (resource_size_t)mac_bi_data.sccbase + 2;
+   scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
+   scc_a_pdev.num_resources = ARRAY_SIZE(scc_a_rsrcs);
+   scc_a_pdev.resource  = scc_a_rsrcs;
+
+   scc_b_rsrcs[0].start = (resource_size_t)mac_bi_data.sccbase;
+   scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
+   scc_b_pdev.num_resources = ARRAY_SIZE(scc_b_rsrcs);
+   scc_b_pdev.resource  = scc_b_rsrcs;
 
switch (macintosh_config->scc_type) {
case MAC_SCC_PSC:
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 96e7aa479961..95abdb305d67 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -1697,18 +1697,17 @@ extern struct platform_device scc_a_pdev, scc_b_pdev;
 
 static int __init pmz_init_port(struct uart_pmac_port *uap)
 {
-   struct resource *r_ports;
-   int irq;
+   struct resource *r_ports, *r_irq;
 
r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
-   irq = platform_get_irq(uap->pdev, 0);
-   if (!r_ports || irq <= 0)
+   r_irq = platform_get_resource(uap->pdev, IORESOURCE_IRQ, 0);
+   if (!r_ports || !r_irq)
return -ENODEV;

Re: [PATCH] serial: pmac_zilog: don't init if zilog is not available

2020-10-22 Thread Finn Thain
On Thu, 22 Oct 2020, Geert Uytterhoeven wrote:

> 
> Thanks for your patch...
> 

You're welcome.

> I can't say I'm a fan of this...
> 

Sorry.

> 
> The real issue is this "extern struct platform_device scc_a_pdev, 
> scc_b_pdev", circumventing the driver framework.
> 
> Can we get rid of that?
> 

Is there a better alternative?

pmz_probe() is called by console_initcall(pmz_console_init) when 
CONFIG_SERIAL_PMACZILOG_CONSOLE=y because this has to happen earlier than 
the normal platform bus probing which takes place later as a typical 
module_initcall.


Re: [PATCH] serial: pmac_zilog: don't init if zilog is not available

2020-10-21 Thread Finn Thain
On Wed, 21 Oct 2020, Laurent Vivier wrote:

> Le 21/10/2020 à 01:43, Finn Thain a écrit :
> 
> > Laurent, can we avoid the irq == 0 warning splat like this?
> > 
> > diff --git a/drivers/tty/serial/pmac_zilog.c 
> > b/drivers/tty/serial/pmac_zilog.c
> > index 96e7aa479961..7db600cd8cc7 100644
> > --- a/drivers/tty/serial/pmac_zilog.c
> > +++ b/drivers/tty/serial/pmac_zilog.c
> > @@ -1701,8 +1701,10 @@ static int __init pmz_init_port(struct 
> > uart_pmac_port *uap)
> > int irq;
> >  
> > r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
> > +   if (!r_ports)
> > +   return -ENODEV;
> > irq = platform_get_irq(uap->pdev, 0);
> > -   if (!r_ports || irq <= 0)
> > +   if (irq <= 0)
> > return -ENODEV;
> >  
> > uap->port.mapbase  = r_ports->start;
> > 
> 
> No, this doesn't fix the problem.
> 

Then I had better stop guessing and start up Aranym...

The patch below seems to fix the problem for me. Does it work on your 
system(s)?

diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index a621fcc1a576..4e802f70333d 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -776,16 +776,12 @@ static struct resource scc_b_rsrcs[] = {
 struct platform_device scc_a_pdev = {
.name   = "scc",
.id = 0,
-   .num_resources  = ARRAY_SIZE(scc_a_rsrcs),
-   .resource   = scc_a_rsrcs,
 };
 EXPORT_SYMBOL(scc_a_pdev);
 
 struct platform_device scc_b_pdev = {
.name   = "scc",
.id = 1,
-   .num_resources  = ARRAY_SIZE(scc_b_rsrcs),
-   .resource   = scc_b_rsrcs,
 };
 EXPORT_SYMBOL(scc_b_pdev);
 
@@ -812,10 +808,15 @@ static void __init mac_identify(void)
 
/* Set up serial port resources for the console initcall. */
 
-   scc_a_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase + 2;
-   scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
-   scc_b_rsrcs[0].start = (resource_size_t) mac_bi_data.sccbase;
-   scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
+   scc_a_rsrcs[0].start = (resource_size_t)mac_bi_data.sccbase + 2;
+   scc_a_rsrcs[0].end   = scc_a_rsrcs[0].start;
+   scc_a_pdev.num_resources = ARRAY_SIZE(scc_a_rsrcs);
+   scc_a_pdev.resource  = scc_a_rsrcs;
+
+   scc_b_rsrcs[0].start = (resource_size_t)mac_bi_data.sccbase;
+   scc_b_rsrcs[0].end   = scc_b_rsrcs[0].start;
+   scc_b_pdev.num_resources = ARRAY_SIZE(scc_b_rsrcs);
+   scc_b_pdev.resource  = scc_b_rsrcs;
 
switch (macintosh_config->scc_type) {
case MAC_SCC_PSC:
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 96e7aa479961..95abdb305d67 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -1697,18 +1697,17 @@ extern struct platform_device scc_a_pdev, scc_b_pdev;
 
 static int __init pmz_init_port(struct uart_pmac_port *uap)
 {
-   struct resource *r_ports;
-   int irq;
+   struct resource *r_ports, *r_irq;
 
r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
-   irq = platform_get_irq(uap->pdev, 0);
-   if (!r_ports || irq <= 0)
+   r_irq = platform_get_resource(uap->pdev, IORESOURCE_IRQ, 0);
+   if (!r_ports || !r_irq)
return -ENODEV;
 
uap->port.mapbase  = r_ports->start;
uap->port.membase  = (unsigned char __iomem *) r_ports->start;
uap->port.iotype   = UPIO_MEM;
-   uap->port.irq  = irq;
+   uap->port.irq  = r_irq->start;
uap->port.uartclk  = ZS_CLOCK;
uap->port.fifosize = 1;
uap->port.ops  = _pops;

Re: [PATCH] serial: pmac_zilog: don't init if zilog is not available

2020-10-20 Thread Finn Thain
On Tue, 20 Oct 2020, Brad Boyer wrote:

> 
> Wouldn't it be better to rearrange this code to only run if the devices 
> are present? This is a macio driver on pmac and a platform driver on 
> mac, so shouldn't it be possible to only run this code when the 
> appropriate entries are present in the right data structures?
> 
> I didn't look at a lot of the other serial drivers, but some other mac 
> drivers have recently been updated to no longer have MACH_IS_MAC checks 
> due to being converted to platform drivers.
> 

Actually, it's not simply a platform driver or macio driver. I think the 
console is supposed to be registered before the normal bus matching takes 
place. Hence this comment in pmac_zilog.c,

/* 
 * First, we need to do a direct OF-based probe pass. We
 * do that because we want serial console up before the
 * macio stuffs calls us back, and since that makes it
 * easier to pass the proper number of channels to
 * uart_register_driver()
 */

Laurent, can we avoid the irq == 0 warning splat like this?

diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 96e7aa479961..7db600cd8cc7 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -1701,8 +1701,10 @@ static int __init pmz_init_port(struct uart_pmac_port 
*uap)
int irq;
 
r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
+   if (!r_ports)
+   return -ENODEV;
irq = platform_get_irq(uap->pdev, 0);
-   if (!r_ports || irq <= 0)
+   if (irq <= 0)
return -ENODEV;
 
uap->port.mapbase  = r_ports->start;


Re: [PATCH 1/9] kernel: add a PF_FORCE_COMPAT flag

2020-09-19 Thread Finn Thain
On Sat, 19 Sep 2020, Arnd Bergmann wrote:

> On Sat, Sep 19, 2020 at 6:21 PM Andy Lutomirski  wrote:
> > On Fri, Sep 18, 2020 at 8:16 AM Christoph Hellwig  wrote:
> > > On Fri, Sep 18, 2020 at 02:58:22PM +0100, Al Viro wrote:
> > > > Said that, why not provide a variant that would take an explicit 
> > > > "is it compat" argument and use it there?  And have the normal one 
> > > > pass in_compat_syscall() to that...
> > >
> > > That would help to not introduce a regression with this series yes. 
> > > But it wouldn't fix existing bugs when io_uring is used to access 
> > > read or write methods that use in_compat_syscall().  One example 
> > > that I recently ran into is drivers/scsi/sg.c.
> 
> Ah, so reading /dev/input/event* would suffer from the same issue, and 
> that one would in fact be broken by your patch in the hypothetical case 
> that someone tried to use io_uring to read /dev/input/event on x32...
> 
> For reference, I checked the socket timestamp handling that has a number 
> of corner cases with time32/time64 formats in compat mode, but none of 
> those appear to be affected by the problem.
> 
> > Aside from the potentially nasty use of per-task variables, one thing 
> > I don't like about PF_FORCE_COMPAT is that it's one-way.  If we're 
> > going to have a generic mechanism for this, shouldn't we allow a full 
> > override of the syscall arch instead of just allowing forcing compat 
> > so that a compat syscall can do a non-compat operation?
> 
> The only reason it's needed here is that the caller is in a kernel 
> thread rather than a system call. Are there any possible scenarios where 
> one would actually need the opposite?
> 

Quite possibly. The ext4 vs. compat getdents bug is still unresolved. 
Please see,
https://lore.kernel.org/lkml/cafeaca9w+jk7_trttnl1p2es1knnpjx9wcuvhflwxlq9aug...@mail.gmail.com/

>Arnd
> 


[PATCH 5/5] powerpc/tau: Disable TAU between measurements

2020-09-04 Thread Finn Thain
Enabling CONFIG_TAU_INT causes random crashes:

Unrecoverable exception 1700 at c0009414 (msr=1000)
Oops: Unrecoverable exception, sig: 6 [#1]
BE PAGE_SIZE=4K MMU=Hash SMP NR_CPUS=2 PowerMac
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.7.0-pmac-00043-gd5f545e1a8593 #5
NIP:  c0009414 LR: c0009414 CTR: c00116fc
REGS: c0799eb8 TRAP: 1700   Not tainted  (5.7.0-pmac-00043-gd5f545e1a8593)
MSR:  1000   CR: 22000228  XER: 0100

GPR00:  c0799f70 c076e300 0080 0291c0ac 00e0 c076e300 00049032
GPR08: 0001 c00116fc  dfbd3200  007f80a8  
GPR16:        c075ce04
GPR24: c075ce04 dfff8880 c07b c075ce04 0008 0001 c079ef98 c079ef5c
NIP [c0009414] arch_cpu_idle+0x24/0x6c
LR [c0009414] arch_cpu_idle+0x24/0x6c
Call Trace:
[c0799f70] [0001] 0x1 (unreliable)
[c0799f80] [c0060990] do_idle+0xd8/0x17c
[c0799fa0] [c0060ba4] cpu_startup_entry+0x20/0x28
[c0799fb0] [c072d220] start_kernel+0x434/0x44c
[c0799ff0] [3860] 0x3860
Instruction dump:
   3d20c07b    7c0802a6
   4e800421    7d2000a6
---[ end trace 3a0c9b5cb216db6b ]---

Resolve this problem by disabling each THRMn comparator when handling
the associated THRMn interrupt and by disabling the TAU entirely when
updating THRMn thresholds.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/powerpc/kernel/tau_6xx.c  | 65 +-
 arch/powerpc/platforms/Kconfig |  9 ++---
 2 files changed, 26 insertions(+), 48 deletions(-)

diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index 614b5b272d9c6..0b4694b8d2482 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -42,8 +42,6 @@ static struct tau_temp
 
 static bool tau_int_enable;
 
-#undef DEBUG
-
 /* TODO: put these in a /proc interface, with some sanity checks, and maybe
  * dynamic adjustment to minimize # of interrupts */
 /* configurable values for step size and how much to expand the window when
@@ -67,42 +65,33 @@ static void set_thresholds(unsigned long cpu)
 
 static void TAUupdate(int cpu)
 {
-   unsigned thrm;
-
-#ifdef DEBUG
-   printk("TAUupdate ");
-#endif
+   u32 thrm;
+   u32 bits = THRM1_TIV | THRM1_TIN | THRM1_V;
 
/* if both thresholds are crossed, the step_sizes cancel out
 * and the window winds up getting expanded twice. */
-   if((thrm = mfspr(SPRN_THRM1)) & THRM1_TIV){ /* is valid? */
-   if(thrm & THRM1_TIN){ /* crossed low threshold */
-   if (tau[cpu].low >= step_size){
-   tau[cpu].low -= step_size;
-   tau[cpu].high -= (step_size - window_expand);
-   }
-   tau[cpu].grew = 1;
-#ifdef DEBUG
-   printk("low threshold crossed ");
-#endif
+   thrm = mfspr(SPRN_THRM1);
+   if ((thrm & bits) == bits) {
+   mtspr(SPRN_THRM1, 0);
+
+   if (tau[cpu].low >= step_size) {
+   tau[cpu].low -= step_size;
+   tau[cpu].high -= (step_size - window_expand);
}
+   tau[cpu].grew = 1;
+   pr_debug("%s: low threshold crossed\n", __func__);
}
-   if((thrm = mfspr(SPRN_THRM2)) & THRM1_TIV){ /* is valid? */
-   if(thrm & THRM1_TIN){ /* crossed high threshold */
-   if (tau[cpu].high <= 127-step_size){
-   tau[cpu].low += (step_size - window_expand);
-   tau[cpu].high += step_size;
-   }
-   tau[cpu].grew = 1;
-#ifdef DEBUG
-   printk("high threshold crossed ");
-#endif
+   thrm = mfspr(SPRN_THRM2);
+   if ((thrm & bits) == bits) {
+   mtspr(SPRN_THRM2, 0);
+
+   if (tau[cpu].high <= 127 - step_size) {
+   tau[cpu].low += (step_size - window_expand);
+   tau[cpu].high += step_size;
}
+   tau[cpu].grew = 1;
+   pr_debug("%s: high threshold crossed\n", __func__);
}
-
-#ifdef DEBUG
-   printk("grew = %d\n", tau[cpu].grew);
-#endif
 }
 
 #ifdef CONFIG_TAU_INT
@@ -127,17 +116,17 @@ void TAUException(struct pt_regs * regs)
 static void tau_timeout(void * info)
 {
int cpu;
-   unsigned long flags;
int size;
int shrink;
 
-   /* disabling interrupts *should* be okay */
-   local_irq_save(flags);
cpu = smp_processor_id();
 
if (!tau_int_enable)
TAUupdate(cpu);
 
+   /* Stop thermal sensor comparisons and interrupts */

[PATCH 4/5] powerpc/tau: Check processor type before enabling TAU interrupt

2020-09-04 Thread Finn Thain
According to Freescale's documentation, MPC74XX processors have an
erratum that prevents the TAU interrupt from working, so don't try to
use it when running on those processors.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/powerpc/kernel/tau_6xx.c  | 33 ++---
 arch/powerpc/platforms/Kconfig |  5 ++---
 2 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index b8d7e7d498e0a..614b5b272d9c6 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -40,6 +40,8 @@ static struct tau_temp
unsigned char grew;
 } tau[NR_CPUS];
 
+static bool tau_int_enable;
+
 #undef DEBUG
 
 /* TODO: put these in a /proc interface, with some sanity checks, and maybe
@@ -54,22 +56,13 @@ static struct tau_temp
 
 static void set_thresholds(unsigned long cpu)
 {
-#ifdef CONFIG_TAU_INT
-   /*
-* setup THRM1,
-* threshold, valid bit, enable interrupts, interrupt when below 
threshold
-*/
-   mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | 
THRM1_TID);
+   u32 maybe_tie = tau_int_enable ? THRM1_TIE : 0;
 
-   /* setup THRM2,
-* threshold, valid bit, enable interrupts, interrupt when above 
threshold
-*/
-   mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE);
-#else
-   /* same thing but don't enable interrupts */
-   mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TID);
-   mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V);
-#endif
+   /* setup THRM1, threshold, valid bit, interrupt when below threshold */
+   mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | maybe_tie | 
THRM1_TID);
+
+   /* setup THRM2, threshold, valid bit, interrupt when above threshold */
+   mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | maybe_tie);
 }
 
 static void TAUupdate(int cpu)
@@ -142,9 +135,8 @@ static void tau_timeout(void * info)
local_irq_save(flags);
cpu = smp_processor_id();
 
-#ifndef CONFIG_TAU_INT
-   TAUupdate(cpu);
-#endif
+   if (!tau_int_enable)
+   TAUupdate(cpu);
 
size = tau[cpu].high - tau[cpu].low;
if (size > min_window && ! tau[cpu].grew) {
@@ -225,6 +217,9 @@ static int __init TAU_init(void)
return 1;
}
 
+   tau_int_enable = IS_ENABLED(CONFIG_TAU_INT) &&
+!strcmp(cur_cpu_spec->platform, "ppc750");
+
tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0);
if (!tau_workq)
return -ENOMEM;
@@ -234,7 +229,7 @@ static int __init TAU_init(void)
queue_work(tau_workq, _work);
 
pr_info("Thermal assist unit using %s, shrink_timer: %d ms\n",
-   IS_ENABLED(CONFIG_TAU_INT) ? "interrupts" : "workqueue", 
shrink_timer);
+   tau_int_enable ? "interrupts" : "workqueue", shrink_timer);
tau_initialized = 1;
 
return 0;
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index fb7515b4fa9c6..9fe36f0b54c1a 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -223,9 +223,8 @@ config TAU
  temperature within 2-4 degrees Celsius. This option shows the current
  on-die temperature in /proc/cpuinfo if the cpu supports it.
 
- Unfortunately, on some chip revisions, this sensor is very inaccurate
- and in many cases, does not work at all, so don't assume the cpu
- temp is actually what /proc/cpuinfo says it is.
+ Unfortunately, this sensor is very inaccurate when uncalibrated, so
+ don't assume the cpu temp is actually what /proc/cpuinfo says it is.
 
 config TAU_INT
bool "Interrupt driven TAU driver (DANGEROUS)"
-- 
2.26.2



[PATCH 2/5] powerpc/tau: Convert from timer to workqueue

2020-09-04 Thread Finn Thain
Since commit 19dbdcb8039cf ("smp: Warn on function calls from softirq
context") the Thermal Assist Unit driver causes a warning like the
following when CONFIG_SMP is enabled.

[ cut here ]
WARNING: CPU: 0 PID: 0 at kernel/smp.c:428 
smp_call_function_many_cond+0xf4/0x38c
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.7.0-pmac #3
NIP:  c00b37a8 LR: c00b3abc CTR: c001218c
REGS: c0799c60 TRAP: 0700   Not tainted  (5.7.0-pmac)
MSR:  00029032   CR: 42000224  XER: 

GPR00: c00b3abc c0799d18 c076e300 c079ef5c c0011fec   
GPR08: 0100 0100 8000  42000224  c079d040 c079d044
GPR16: 0001  0004 c0799da0 c079f054 c07a c07a 
GPR24: c0011fec  c079ef5c c079ef5c    
NIP [c00b37a8] smp_call_function_many_cond+0xf4/0x38c
LR [c00b3abc] on_each_cpu+0x38/0x68
Call Trace:
[c0799d18] [] 0x (unreliable)
[c0799d68] [c00b3abc] on_each_cpu+0x38/0x68
[c0799d88] [c0096704] call_timer_fn.isra.26+0x20/0x7c
[c0799d98] [c0096b40] run_timer_softirq+0x1d4/0x3fc
[c0799df8] [c05b4368] __do_softirq+0x118/0x240
[c0799e58] [c0039c44] irq_exit+0xc4/0xcc
[c0799e68] [c000ade8] timer_interrupt+0x1b0/0x230
[c0799ea8] [c0013520] ret_from_except+0x0/0x14
--- interrupt: 901 at arch_cpu_idle+0x24/0x6c
LR = arch_cpu_idle+0x24/0x6c
[c0799f70] [0001] 0x1 (unreliable)
[c0799f80] [c0060990] do_idle+0xd8/0x17c
[c0799fa0] [c0060ba8] cpu_startup_entry+0x24/0x28
[c0799fb0] [c072d220] start_kernel+0x434/0x44c
[c0799ff0] [3860] 0x3860
Instruction dump:
8129f204 2f89 40beff98 3d20c07a 8929eec4 2f89 40beff88 0fe0
8122 552805de 550802ef 4182ff84 <0fe0> 3860 7f65db78 7f44d378
---[ end trace 34a886e47819c2eb ]---

Don't call on_each_cpu() from a timer callback, call it from a worker
thread instead.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/powerpc/kernel/tau_6xx.c | 38 +--
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index 976d5bc1b5176..268205cc347da 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -13,13 +13,14 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -39,8 +40,6 @@ static struct tau_temp
unsigned char grew;
 } tau[NR_CPUS];
 
-struct timer_list tau_timer;
-
 #undef DEBUG
 
 /* TODO: put these in a /proc interface, with some sanity checks, and maybe
@@ -50,7 +49,7 @@ struct timer_list tau_timer;
 #define step_size  2   /* step size when temp goes out of 
range */
 #define window_expand  1   /* expand the window by this much */
 /* configurable values for shrinking the window */
-#define shrink_timer   2*HZ/* period between shrinking the window */
+#define shrink_timer   2000/* period between shrinking the window */
 #define min_window 2   /* minimum window size, degrees C */
 
 static void set_thresholds(unsigned long cpu)
@@ -187,14 +186,18 @@ static void tau_timeout(void * info)
local_irq_restore(flags);
 }
 
-static void tau_timeout_smp(struct timer_list *unused)
-{
+static struct workqueue_struct *tau_workq;
 
-   /* schedule ourselves to be run again */
-   mod_timer(_timer, jiffies + shrink_timer) ;
+static void tau_work_func(struct work_struct *work)
+{
+   msleep(shrink_timer);
on_each_cpu(tau_timeout, NULL, 0);
+   /* schedule ourselves to be run again */
+   queue_work(tau_workq, work);
 }
 
+DECLARE_WORK(tau_work, tau_work_func);
+
 /*
  * setup the TAU
  *
@@ -227,21 +230,16 @@ static int __init TAU_init(void)
return 1;
}
 
-
-   /* first, set up the window shrinking timer */
-   timer_setup(_timer, tau_timeout_smp, 0);
-   tau_timer.expires = jiffies + shrink_timer;
-   add_timer(_timer);
+   tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0);
+   if (!tau_workq)
+   return -ENOMEM;
 
on_each_cpu(TAU_init_smp, NULL, 0);
 
-   printk("Thermal assist unit ");
-#ifdef CONFIG_TAU_INT
-   printk("using interrupts, ");
-#else
-   printk("using timers, ");
-#endif
-   printk("shrink_timer: %d jiffies\n", shrink_timer);
+   queue_work(tau_workq, _work);
+
+   pr_info("Thermal assist unit using %s, shrink_timer: %d ms\n",
+   IS_ENABLED(CONFIG_TAU_INT) ? "interrupts" : "workqueue", 
shrink_timer);
tau_initialized = 1;
 
return 0;
-- 
2.26.2



[PATCH 3/5] powerpc/tau: Remove duplicated set_thresholds() call

2020-09-04 Thread Finn Thain
The commentary at the call site seems to disagree with the code. The
conditional prevents calling set_thresholds() via the exception handler,
which appears to crash. Perhaps that's because it immediately triggers
another TAU exception. Anyway, calling set_thresholds() from TAUupdate()
is redundant because tau_timeout() does so.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/powerpc/kernel/tau_6xx.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index 268205cc347da..b8d7e7d498e0a 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -110,11 +110,6 @@ static void TAUupdate(int cpu)
 #ifdef DEBUG
printk("grew = %d\n", tau[cpu].grew);
 #endif
-
-#ifndef CONFIG_TAU_INT /* tau_timeout will do this if not using interrupts */
-   set_thresholds(cpu);
-#endif
-
 }
 
 #ifdef CONFIG_TAU_INT
-- 
2.26.2



[PATCH 1/5] powerpc/tau: Use appropriate temperature sample interval

2020-09-04 Thread Finn Thain
According to the MPC750 Users Manual, the SITV value in Thermal
Management Register 3 is 13 bits long. The present code calculates the
SITV value as 60 * 500 cycles. This would overflow to give 10 us on
a 500 MHz CPU rather than the intended 60 us. (But according to the
Microprocessor Datasheet, there is also a factor of 266 that has to be
applied to this value on certain parts i.e. speed sort above 266 MHz.)
Always use the maximum cycle count, as recommended by the Datasheet.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/powerpc/include/asm/reg.h |  2 +-
 arch/powerpc/kernel/tau_6xx.c  | 12 
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 88e6c78100d9b..c750afc62887c 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -815,7 +815,7 @@
 #define THRM1_TIN  (1 << 31)
 #define THRM1_TIV  (1 << 30)
 #define THRM1_THRES(x) ((x&0x7f)<<23)
-#define THRM3_SITV(x)  ((x&0x3fff)<<1)
+#define THRM3_SITV(x)  ((x & 0x1fff) << 1)
 #define THRM1_TID  (1<<2)
 #define THRM1_TIE  (1<<1)
 #define THRM1_V(1<<0)
diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c
index e2ab8a111b693..976d5bc1b5176 100644
--- a/arch/powerpc/kernel/tau_6xx.c
+++ b/arch/powerpc/kernel/tau_6xx.c
@@ -178,15 +178,11 @@ static void tau_timeout(void * info)
 * complex sleep code needs to be added. One mtspr every time
 * tau_timeout is called is probably not a big deal.
 *
-* Enable thermal sensor and set up sample interval timer
-* need 20 us to do the compare.. until a nice 'cpu_speed' function
-* call is implemented, just assume a 500 mhz clock. It doesn't really
-* matter if we take too long for a compare since it's all interrupt
-* driven anyway.
-*
-* use a extra long time.. (60 us @ 500 mhz)
+* The "PowerPC 740 and PowerPC 750 Microprocessor Datasheet"
+* recommends that "the maximum value be set in THRM3 under all
+* conditions."
 */
-   mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E);
+   mtspr(SPRN_THRM3, THRM3_SITV(0x1fff) | THRM3_E);
 
local_irq_restore(flags);
 }
-- 
2.26.2



[PATCH 0/5] powerpc/tau: TAU driver fixes

2020-09-04 Thread Finn Thain
This patch series fixes various bugs in the Thermal Assist Unit driver.
It was tested on 266 MHz and 292 MHz PowerBook G3 laptops.


Finn Thain (5):
  powerpc/tau: Use appropriate temperature sample interval
  powerpc/tau: Convert from timer to workqueue
  powerpc/tau: Remove duplicated set_thresholds() call
  powerpc/tau: Check processor type before enabling TAU interrupt
  powerpc/tau: Disable TAU between measurements

 arch/powerpc/include/asm/reg.h |   2 +-
 arch/powerpc/kernel/tau_6xx.c  | 147 +
 arch/powerpc/platforms/Kconfig |  14 +---
 3 files changed, 62 insertions(+), 101 deletions(-)

-- 
2.26.2



Re: [PATCH 1/9] macintosh/via-macii: Access autopoll_devs when inside lock

2020-08-09 Thread Finn Thain
On Sun, 9 Aug 2020, Guenter Roeck wrote:

> Hi,
> 
> On Sun, Jun 28, 2020 at 02:23:12PM +1000, Finn Thain wrote:
> > The interrupt handler should be excluded when accessing the 
> > autopoll_devs variable.
> > 
> 
> I am quite baffled by this patch. Other than adding an unnecessary lock 
> / unlock sequence,

The new lock/unlock sequence means that the expression (autopoll_devs && 
!current_req) can be understood to be atomic. That makes it easier for me 
to follow (being that both variables are shared state).

> accessing a variable (which is derived from another variable) from 
> inside or outside a lock does not make a difference. If autopoll_devs = 
> devs & 0xfffe is 0 inside the lock, it will just as much be 0 outside 
> the lock, and vice versa.
> 
> Can you explain this in some more detail ? Not that is matters much 
> since the change already made it into mainline, but I would like to 
> understand what if anything I am missing here.
> 

I think the new code is more readable and is obviously free of race 
conditions. It's not obvious to me why the old code was free of race 
conditions but if you can easily establish that by inspection then you are 
a better auditor than I am. Regardless, I'll stick with "Keep It Simple, 
Stupid".


Re: [PATCH 2/9] macintosh/via-macii: Poll the device most likely to respond

2020-08-09 Thread Finn Thain
On Sun, 9 Aug 2020, Guenter Roeck wrote:

> Hi,
> 
> On Sun, Jun 28, 2020 at 02:23:12PM +1000, Finn Thain wrote:
> > Poll the most recently polled device by default, rather than the lowest
> > device address that happens to be enabled in autopoll_devs. This improves
> > input latency. Re-use macii_queue_poll() rather than duplicate that logic.
> > This eliminates a static struct and function.
> > 
> > Fixes: d95fd5fce88f0 ("m68k: Mac II ADB fixes") # v5.0+
> > Tested-by: Stan Johnson 
> > Signed-off-by: Finn Thain 
> 
> With this patch applied, the qemu "q800" emulation no longer works and 
> is stuck in early boot. Any idea why that might be the case, and/or how 
> to debug it ?
> 

The problem you're seeing was mentioned in the cover letter,
https://lore.kernel.org/linux-m68k/cover.1593318192.git.fth...@telegraphics.com.au/

Since this series was merged, Linus' tree is no longer compatible with 
long-standing QEMU bugs.

The best way to fix this is to upgrade QEMU (latest is 5.1.0-rc3). Or use 
the serial console instead of the framebuffer console.

I regret the inconvenience but the alternative was worse: adding code to 
Linux to get compatibility with QEMU bugs (which were added to QEMU due to 
Linux bugs).

My main concern is correct operation on actual hardware, as always. But 
some QEMU developers are working on support for operating systems besides 
Linux.

Therefore, I believe that both QEMU and Linux should aim for compatibility 
with actual hardware and not bug compatibility with each other.


Re: [PATCH v2 13/16] scripts/kallsyms: move ignored symbol types to is_ignored_symbol()

2020-07-20 Thread Finn Thain
On Mon, 20 Jul 2020, Masahiro Yamada wrote:

> 
> I got a similar report before.
> 
> I'd like to know whether or not
> this is the same issue as fixed by
> 7883a14339299773b2ce08dcfd97c63c199a9289
> 

The problem can be observed with 3d77e6a8804ab ("Linux 5.7").
So it appears that 7883a14339299 ("scripts/kallsyms: fix wrong 
kallsyms_relative_base") is not sufficient to fix it.

> 
> Does your problem happen on the latest kernel?

Unfortunately this cross compiler (gcc 4.6.4) is too old to build 
v5.8-rc1 or later. I will have to upgrade.

> Which version of binutils are you using?
> 

This toolchain uses binutils 2.22.

In case it helps,

$ powerpc-linux-gnu-nm -n vmlinux |head  
 w mach_chrp
0005 a LG_CACHELINE_BYTES
0005 a LG_CACHELINE_BYTES
0005 a LG_CACHELINE_BYTES
000c a Hash_bits
001f a CACHELINE_MASK
001f a CACHELINE_MASK
001f a CACHELINE_MASK
0020 a CACHELINE_BYTES
0020 a CACHELINE_BYTES
0020 a CACHELINE_BYTES
0020 a reg
0003ffc0 a Hash_msk
c000 T _start
c000 A _stext
c000 A _text
c00c T __start
c054 t __after_mmu_off
c090 t turn_on_mmu
c0c4 T __secondary_hold
c0dc T __secondary_hold_spinloop
c0e0 T __secondary_hold_acknowledge
c100 t Reset


Re: [PATCH v2 13/16] scripts/kallsyms: move ignored symbol types to is_ignored_symbol()

2020-07-19 Thread Finn Thain
On Sun, 24 Nov 2019, Masahiro Yamada wrote:

> Collect the ignored patterns to is_ignored_symbol().
> 
> Signed-off-by: Masahiro Yamada 

This commit (887df76de67f5) caused a regression in my powerpc builds as it 
causes symbol names to disappear from backtraces:

[ cut here ]
WARNING: CPU: 0 PID: 0 at kernel/smp.c:433 _einittext+0x3f9e5120/0x3feb71b8
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.0-rc7-pmac-00055-g887df76de67f5 
#18
NIP:  c00aef68 LR: c00af114 CTR: c001272c
REGS: c0705c40 TRAP: 0700   Not tainted  (5.4.0-rc7-pmac-00055-g887df76de67f5)
MSR:  00029032   CR: 4244  XER: 

GPR00: 001f0100 c0705cf8 c06dc300 c070af1c c001258c   ef7fb5bc 
GPR08: 0880 0100 0001 0100 4244  c0709040 0004 
GPR16: 0001 c06022b4 c058297c 0022 8cb9  c06d84a0 c071 
GPR24: c071   c070af1c c070af1c  c001258c  
NIP [c00aef68] _einittext+0x3f9e5120/0x3feb71b8
LR [c00af114] _einittext+0x3f9e52cc/0x3feb71b8
Call Trace:
[c0705cf8] [ef006320] 0xef006320 (unreliable)
[c0705d38] [c00af114] _einittext+0x3f9e52cc/0x3feb71b8
[c0705d48] [c00af158] _einittext+0x3f9e5310/0x3feb71b8
[c0705d68] [c0012768] _einittext+0x3f948920/0x3feb71b8
[c0705d78] [c0092c04] _einittext+0x3f9c8dbc/0x3feb71b8
[c0705d88] [c0092d18] _einittext+0x3f9c8ed0/0x3feb71b8
[c0705da8] [c0093a2c] _einittext+0x3f9c9be4/0x3feb71b8
[c0705de8] [c0580224] _einittext+0x3feb63dc/0x3feb71b8
[c0705e48] [c00382ec] _einittext+0x3f96e4a4/0x3feb71b8
[c0705e58] [c000d2a0] _einittext+0x3f943458/0x3feb71b8
[c0705e88] [c001353c] _einittext+0x3f9496f4/0x3feb71b8
--- interrupt: 901 at _einittext+0x3f941058/0x3feb71b8
LR = _einittext+0x3f941058/0x3feb71b8
[c0705f50] [c06cc214] 0xc06cc214 (unreliable)
[c0705f60] [c057fa20] _einittext+0x3feb5bd8/0x3feb71b8
[c0705f70] [c005de48] _einittext+0x3f994000/0x3feb71b8
[c0705f90] [c005e050] _einittext+0x3f994208/0x3feb71b8
[c0705fa0] [c0004cc8] _einittext+0x3f93ae80/0x3feb71b8
[c0705fb0] [c069a36c] _einittext+0x3ffd0524/0x4000
[c0705ff0] [3500] 0x3500
Instruction dump:
7c0803a6 7fa5eb78 7d808120 7ea6ab78 baa10014 38210040 4bfffbb0 7f64db78 
7f85e378 484b31b1 7c601b78 4bfffdf4 <0fe0> 4bfffd60 9421ffe0 7c0802a6 
---[ end trace a06fef4788747c72 ]---


Prior to that (e.g. 97261e1e2240f), I get backtraces like this:

[ cut here ]
WARNING: CPU: 0 PID: 0 at kernel/smp.c:433 smp_call_function_many+0x318/0x320
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.0-rc7-pmac-00054-g97261e1e2240f 
#20
NIP:  c00aef68 LR: c00af114 CTR: c001272c
REGS: c075dc40 TRAP: 0700   Not tainted  (5.4.0-rc7-pmac-00054-g97261e1e2240f)
MSR:  00029032   CR: 4244  XER: 

GPR00: 001f0100 c075dcf8 c0733300 c0762f1c c001258c   ef7fb5bc 
GPR08: 0480 0100 0001 0100 4244  c0761040 0004 
GPR16: 0001 c0658e58 c058297c 0022 8cb9  c072f4a0 c076 
GPR24: c076   c0762f1c c0762f1c  c001258c  
NIP [c00aef68] smp_call_function_many+0x318/0x320
LR [c00af114] smp_call_function+0x34/0x44
Call Trace:
[c075dcf8] [ef006320] 0xef006320 (unreliable)
[c075dd38] [c00af114] smp_call_function+0x34/0x44
[c075dd48] [c00af158] on_each_cpu+0x1c/0x4c
[c075dd68] [c0012768] tau_timeout_smp+0x3c/0x4c
[c075dd78] [c0092c04] call_timer_fn.isra.26+0x20/0x84
[c075dd88] [c0092d18] expire_timers+0xb0/0xc0
[c075dda8] [c0093a2c] run_timer_softirq+0xa4/0x1a4
[c075dde8] [c0580224] __do_softirq+0x11c/0x280
[c075de48] [c00382ec] irq_exit+0xc0/0xd4
[c075de58] [c000d2a0] timer_interrupt+0x154/0x260
[c075de88] [c001353c] ret_from_except+0x0/0x14
--- interrupt: 901 at arch_cpu_idle+0x24/0x78
LR = arch_cpu_idle+0x24/0x78
[c075df50] [c0723214] 0xc0723214 (unreliable)
[c075df60] [c057fa20] default_idle_call+0x38/0x58
[c075df70] [c005de48] do_idle+0xd4/0x17c
[c075df90] [c005e054] cpu_startup_entry+0x24/0x28
[c075dfa0] [c0004cc8] rest_init+0xa8/0xbc
[c075dfb0] [c06f136c] start_kernel+0x40c/0x420
[c075dff0] [3500] 0x3500
Instruction dump:
7c0803a6 7fa5eb78 7d808120 7ea6ab78 baa10014 38210040 4bfffbb0 7f64db78 
7f85e378 484b31b1 7c601b78 4bfffdf4 <0fe0> 4bfffd60 9421ffe0 7c0802a6 
---[ end trace 784c7f15ecd23941 ]---

Has anyone else observed these problems (either the WARNING from 
smp_call_function_many() or the missing symbol names)?

What is the best way to fix this? Should I upgrade binutils?


[PATCH 4/9] macintosh/via-macii: Remove read_done state

2020-06-27 Thread Finn Thain
The driver state machine may enter the 'read_done' state when leaving the
'idle' or 'reading' state. This transition is pointless, as is the extra
interrupt it requires. The interrupt is produced by the transceiver
(even when it has no data to send) because an extra EVEN/ODD toggle
was signalled by the driver. Drop the extra state to simplify the code.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2") # v5.0+
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 70 ++-
 1 file changed, 28 insertions(+), 42 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index 6a5cd7de05baf..d29c87943ca46 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -110,7 +110,6 @@ static enum macii_state {
idle,
sending,
reading,
-   read_done,
 } macii_state;
 
 static struct adb_request *current_req; /* first request struct in the queue */
@@ -411,8 +410,8 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
reply_len = 1;
} else {
/* bus timeout */
-   macii_state = read_done;
reply_len = 0;
+   break;
}
 
/* set ADB state = even for first data byte */
@@ -471,20 +470,6 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
current_req = req->next;
if (req->done)
(*req->done)(req);
-
-   if (!current_req)
-   macii_queue_poll();
-
-   if (current_req && macii_state == idle)
-   macii_start();
-
-   if (macii_state == idle) {
-   /* reset to shift in */
-   via[ACR] &= ~SR_OUT;
-   x = via[SR];
-   /* set ADB state idle - might get SRQ */
-   via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
-   }
break;
}
} else {
@@ -511,12 +496,28 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
} else if (status == ST_ODD && reply_len == 2) {
srq_asserted = true;
} else {
-   macii_state = read_done;
+   macii_state = idle;
+
+   if (bus_timeout)
+   reply_len = 0;
+
+   if (reading_reply) {
+   struct adb_request *req = current_req;
+
+   req->reply_len = reply_len;
+
+   req->complete = 1;
+   current_req = req->next;
+   if (req->done)
+   (*req->done)(req);
+   } else if (reply_len && autopoll_devs) {
+   adb_input(reply_buf, reply_len, 0);
+   }
+   break;
}
}
 
-   if (macii_state == reading &&
-   reply_len < ARRAY_SIZE(reply_buf)) {
+   if (reply_len < ARRAY_SIZE(reply_buf)) {
reply_ptr++;
*reply_ptr = x;
reply_len++;
@@ -526,37 +527,22 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
via[B] ^= ST_MASK;
break;
 
-   case read_done:
-   x = via[SR];
-
-   if (bus_timeout)
-   reply_len = 0;
-
-   if (reading_reply) {
-   reading_reply = 0;
-   req = current_req;
-   req->reply_len = reply_len;
-   req->complete = 1;
-   current_req = req->next;
-   if (req->done)
-   (*req->done)(req);
-   } else if (reply_len && autopoll_devs)
-   adb_input(reply_buf, reply_len, 0);
-
-   macii_state = idle;
+   default:
+   break;
+   }
 
+   if (macii_state == idle) {
if (!current_req)
macii_queue_poll();
 
if (current_req)
macii_start();
 
-   if (macii_state == idle)
+   

[PATCH 9/9] macintosh/via-macii: Clarify definition of macii_init()

2020-06-27 Thread Finn Thain
The function prototype correctly specifies the 'static' storage class.
Let the function definition match the declaration for better readability.

Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index 2f9be4ec7d345..060e03f2264bc 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -140,7 +140,7 @@ static int macii_probe(void)
 }
 
 /* Initialize the driver */
-int macii_init(void)
+static int macii_init(void)
 {
unsigned long flags;
int err;
-- 
2.26.2



[PATCH 0/9] Macintosh II ADB driver fixes

2020-06-27 Thread Finn Thain
Various issues with the via-macii driver have become apparent over the
years. Some examples:

 - A Talk command response can be lost. This can result in phantom devices
being probed or an incorrect device handler ID being retrieved.

 - A reply packet containing a null byte can get truncated. Such packets
are sometimes generated by ADB keyboards.

 - A Talk Register 3 reply from device 15 (that is, command byte 0xFF)
can be mistaken for a bus timeout (empty packet).

This patch series contains fixes for all known bugs in the via-macii
driver, plus a few code style improvements. It has been successfully
tested on an Apple Centris 650 and qemu-system-m68k.

The patched kernel does regress on past QEMU releases, due to ADB
transceiver emulation bugs. Those bugs have been fixed in mainline QEMU.
My thanks go to Mark Cave-Ayland for that effort and for figuring out
the improvements to the signalling between the VIA and the transceiver.

Note to -stable maintainers: these fixes can be cherry-picked without
difficulty, if you have the 5 commits that appeared in v5.0:

b52dce8738938 macintosh/via-macii: Synchronous bus reset
5f93d7081a47e macintosh/via-macii: Remove BUG_ON assertions
5ce6185c2ef4e macintosh/via-macii: Simplify locking
351e5ad327d07 macintosh/via-macii, macintosh/adb-iop: Modernize printk calls
47fd2060660e6 macintosh/via-macii, macintosh/adb-iop: Clean up whitespace

Just for the sake of simplicity, the 'fixes' tags in this series limit
backporting to 'v5.0+'.


Finn Thain (9):
  macintosh/via-macii: Access autopoll_devs when inside lock
  macintosh/via-macii: Poll the device most likely to respond
  macintosh/via-macii: Handle /CTLR_IRQ signal correctly
  macintosh/via-macii: Remove read_done state
  macintosh/via-macii: Handle poll replies correctly
  macintosh/via-macii: Use bool type for reading_reply variable
  macintosh/via-macii: Use unsigned type for autopoll_devs variable
  macintosh/via-macii: Use the stack for reset request storage
  macintosh/via-macii: Clarify definition of macii_init()

 drivers/macintosh/via-macii.c | 324 +++---
 1 file changed, 179 insertions(+), 145 deletions(-)

-- 
2.26.2



[PATCH 8/9] macintosh/via-macii: Use the stack for reset request storage

2020-06-27 Thread Finn Thain
The adb_request struct can be stored on the stack because the request
is synchronous and is completed before the function returns.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index 447273967e1e8..2f9be4ec7d345 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -313,7 +313,7 @@ static void macii_poll(void)
 /* Reset the bus */
 static int macii_reset_bus(void)
 {
-   static struct adb_request req;
+   struct adb_request req;
 
/* Command = 0, Address = ignored */
adb_request(, NULL, ADBREQ_NOSEND, 1, ADB_BUSRESET);
-- 
2.26.2



[PATCH 7/9] macintosh/via-macii: Use unsigned type for autopoll_devs variable

2020-06-27 Thread Finn Thain
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index e143ddb81de34..447273967e1e8 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -125,7 +125,7 @@ static bool srq_asserted;/* have to poll for the device 
that asserted it */
 static u8 last_cmd;  /* the most recent command byte transmitted */
 static u8 last_talk_cmd;/* the most recent Talk command byte transmitted */
 static u8 last_poll_cmd; /* the most recent Talk R0 command byte transmitted */
-static int autopoll_devs;  /* bits set are device addresses to be polled */
+static unsigned int autopoll_devs;  /* bits set are device addresses to poll */
 
 /* Check for MacII style ADB */
 static int macii_probe(void)
@@ -291,7 +291,7 @@ static int macii_autopoll(int devs)
local_irq_save(flags);
 
/* bit 1 == device 1, and so on. */
-   autopoll_devs = devs & 0xFFFE;
+   autopoll_devs = (unsigned int)devs & 0xFFFE;
 
if (!current_req) {
macii_queue_poll();
-- 
2.26.2



[PATCH 6/9] macintosh/via-macii: Use bool type for reading_reply variable

2020-06-27 Thread Finn Thain
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index 8d5ef77b4a435..e143ddb81de34 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -116,7 +116,7 @@ static struct adb_request *current_req; /* first request 
struct in the queue */
 static struct adb_request *last_req; /* last request struct in the queue */
 static unsigned char reply_buf[16];/* storage for autopolled replies */
 static unsigned char *reply_ptr; /* next byte in reply_buf or req->reply */
-static int reading_reply;/* store reply in reply_buf else req->reply */
+static bool reading_reply;   /* store reply in reply_buf else req->reply */
 static int data_index;  /* index of the next byte to send from req->data */
 static int reply_len; /* number of bytes received in reply_buf or req->reply */
 static int status;  /* VIA's ADB status bits captured upon interrupt */
@@ -394,7 +394,7 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
WARN_ON((status & ST_MASK) != ST_IDLE);
 
reply_ptr = reply_buf;
-   reading_reply = 0;
+   reading_reply = false;
 
bus_timeout = false;
srq_asserted = false;
@@ -442,7 +442,7 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
 */
macii_state = reading;
 
-   reading_reply = 0;
+   reading_reply = false;
reply_ptr = reply_buf;
*reply_ptr = last_talk_cmd;
reply_len = 1;
@@ -456,7 +456,7 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
if (req->reply_expected) {
macii_state = reading;
 
-   reading_reply = 1;
+   reading_reply = true;
reply_ptr = req->reply;
*reply_ptr = req->data[1];
reply_len = 1;
@@ -466,7 +466,7 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
} else if ((req->data[1] & OP_MASK) == TALK) {
macii_state = reading;
 
-   reading_reply = 0;
+   reading_reply = false;
reply_ptr = reply_buf;
*reply_ptr = req->data[1];
reply_len = 1;
-- 
2.26.2



[PATCH 5/9] macintosh/via-macii: Handle poll replies correctly

2020-06-27 Thread Finn Thain
Userspace applications may use /dev/adb to send Talk requests. Such
requests always have req->reply_expected == 1. The same is true of Talk
requests sent by the kernel, except for poll requests queued internally
by the via-macii driver. Those requests have req->reply_expected == 0.

Consequently, poll reply packets get treated like autopoll reply packets.
(It doesn't make sense to try to distinguish them.) Always enter 'reading'
state after a poll request, so that the reply gets collected and passed
to adb_input(), and none go missing.

All Talk replies passed to adb_input() come from polling or autopolling,
so call adb_input() with the autopoll parameter set to 1.

Fixes: d95fd5fce88f0 ("m68k: Mac II ADB fixes") # v5.0+
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index d29c87943ca46..8d5ef77b4a435 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -463,6 +463,21 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
 
via[ACR] &= ~SR_OUT;
x = via[SR];
+   } else if ((req->data[1] & OP_MASK) == TALK) {
+   macii_state = reading;
+
+   reading_reply = 0;
+   reply_ptr = reply_buf;
+   *reply_ptr = req->data[1];
+   reply_len = 1;
+
+   via[ACR] &= ~SR_OUT;
+   x = via[SR];
+
+   req->complete = 1;
+   current_req = req->next;
+   if (req->done)
+   (*req->done)(req);
} else {
macii_state = idle;
 
@@ -510,8 +525,9 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
current_req = req->next;
if (req->done)
(*req->done)(req);
-   } else if (reply_len && autopoll_devs) {
-   adb_input(reply_buf, reply_len, 0);
+   } else if (reply_len && autopoll_devs &&
+  reply_buf[0] == last_poll_cmd) {
+   adb_input(reply_buf, reply_len, 1);
}
break;
}
-- 
2.26.2



[PATCH 3/9] macintosh/via-macii: Handle /CTLR_IRQ signal correctly

2020-06-27 Thread Finn Thain
I'm told that the /CTLR_IRQ signal from the ADB transceiver gets
interpreted by MacOS to mean SRQ, bus timeout or end-of-packet depending
on the circumstances, and that Linux's via-macii driver does not
correctly interpret this signal.

Instead, the via-macii driver interprets certain received byte values
(0x00 and 0xFF) as signalling end of packet and bus timeout
(respectively). Problem is, those values can also appear under other
circumstances.

This patch changes the bus timeout, end of packet and SRQ detection logic
to bring it closer to the logic that MacOS reportedly uses.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2") # v5.0+
Reported-by: Mark Cave-Ayland 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 166 --
 1 file changed, 97 insertions(+), 69 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index d4f1a65c5f1fd..6a5cd7de05baf 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -80,6 +80,8 @@ static volatile unsigned char *via;
 /* ADB command byte structure */
 #define ADDR_MASK  0xF0
 #define CMD_MASK   0x0F
+#define OP_MASK0x0C
+#define TALK   0x0C
 
 static int macii_init_via(void);
 static void macii_start(void);
@@ -119,9 +121,10 @@ static int reading_reply;/* store reply in 
reply_buf else req->reply */
 static int data_index;  /* index of the next byte to send from req->data */
 static int reply_len; /* number of bytes received in reply_buf or req->reply */
 static int status;  /* VIA's ADB status bits captured upon interrupt */
-static int last_status;  /* status bits as at previous interrupt */
-static int srq_asserted; /* have to poll for the device that asserted it */
+static bool bus_timeout;   /* no data was sent by the device */
+static bool srq_asserted;/* have to poll for the device that asserted it */
 static u8 last_cmd;  /* the most recent command byte transmitted */
+static u8 last_talk_cmd;/* the most recent Talk command byte transmitted */
 static u8 last_poll_cmd; /* the most recent Talk R0 command byte transmitted */
 static int autopoll_devs;  /* bits set are device addresses to be polled */
 
@@ -170,7 +173,6 @@ static int macii_init_via(void)
 
/* Set up state: idle */
via[B] |= ST_IDLE;
-   last_status = via[B] & (ST_MASK | CTLR_IRQ);
 
/* Shift register on input */
via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT;
@@ -336,13 +338,6 @@ static void macii_start(void)
 * And req->nbytes is the number of bytes of real data plus one.
 */
 
-   /* store command byte */
-   last_cmd = req->data[1];
-
-   /* If this is a Talk Register 0 command, store the command byte */
-   if ((last_cmd & CMD_MASK) == ADB_READREG(0, 0))
-   last_poll_cmd = last_cmd;
-
/* Output mode */
via[ACR] |= SR_OUT;
/* Load data */
@@ -352,6 +347,9 @@ static void macii_start(void)
 
macii_state = sending;
data_index = 2;
+
+   bus_timeout = false;
+   srq_asserted = false;
 }
 
 /*
@@ -360,15 +358,17 @@ static void macii_start(void)
  * generating shift register interrupts (SR_INT) for us. This means there has
  * to be activity on the ADB bus. The chip will poll to achieve this.
  *
- * The basic ADB state machine was left unchanged from the original MacII code
- * by Alan Cox, which was based on the CUDA driver for PowerMac.
- * The syntax of the ADB status lines is totally different on MacII,
- * though. MacII uses the states Command -> Even -> Odd -> Even ->...-> Idle
- * for sending and Idle -> Even -> Odd -> Even ->...-> Idle for receiving.
- * Start and end of a receive packet are signalled by asserting /IRQ on the
- * interrupt line (/IRQ means the CTLR_IRQ bit in port B; not to be confused
- * with the VIA shift register interrupt. /IRQ never actually interrupts the
- * processor, it's just an ordinary input.)
+ * The VIA Port B output signalling works as follows. After the ADB transceiver
+ * sees a transition on the PB4 and PB5 lines it will crank over the VIA shift
+ * register which eventually raises the SR_INT interrupt. The PB4/PB5 outputs
+ * are toggled with each byte as the ADB transaction progresses.
+ *
+ * Request with no reply expected (and empty transceiver buffer):
+ * CMD -> IDLE
+ * Request with expected reply packet (or with buffered autopoll packet):
+ * CMD -> EVEN -> ODD -> EVEN -> ... -> IDLE
+ * Unsolicited packet:
+ * IDLE -> EVEN -> ODD -> EVEN -> ... -> IDLE
  */
 static irqreturn_t macii_interrupt(int irq, void *arg)
 {
@@ -388,31 +388,31 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
}
}
 
-   last_status = status;
status = via[B] & (ST

[PATCH 2/9] macintosh/via-macii: Poll the device most likely to respond

2020-06-27 Thread Finn Thain
Poll the most recently polled device by default, rather than the lowest
device address that happens to be enabled in autopoll_devs. This improves
input latency. Re-use macii_queue_poll() rather than duplicate that logic.
This eliminates a static struct and function.

Fixes: d95fd5fce88f0 ("m68k: Mac II ADB fixes") # v5.0+
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 99 +++
 1 file changed, 53 insertions(+), 46 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index 6aa903529570d..d4f1a65c5f1fd 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -77,6 +77,10 @@ static volatile unsigned char *via;
 #define ST_ODD 0x20/* ADB state: odd data byte */
 #define ST_IDLE0x30/* ADB state: idle, nothing to 
send */
 
+/* ADB command byte structure */
+#define ADDR_MASK  0xF0
+#define CMD_MASK   0x0F
+
 static int macii_init_via(void);
 static void macii_start(void);
 static irqreturn_t macii_interrupt(int irq, void *arg);
@@ -117,7 +121,8 @@ static int reply_len; /* number of bytes received in 
reply_buf or req->reply */
 static int status;  /* VIA's ADB status bits captured upon interrupt */
 static int last_status;  /* status bits as at previous interrupt */
 static int srq_asserted; /* have to poll for the device that asserted it */
-static int command_byte; /* the most recent command byte transmitted */
+static u8 last_cmd;  /* the most recent command byte transmitted */
+static u8 last_poll_cmd; /* the most recent Talk R0 command byte transmitted */
 static int autopoll_devs;  /* bits set are device addresses to be polled */
 
 /* Check for MacII style ADB */
@@ -179,35 +184,49 @@ static int macii_init_via(void)
 /* Send an ADB poll (Talk Register 0 command prepended to the request queue) */
 static void macii_queue_poll(void)
 {
-   /* No point polling the active device as it will never assert SRQ, so
-* poll the next device in the autopoll list. This could leave us
-* stuck in a polling loop if an unprobed device is asserting SRQ.
-* In theory, that could only happen if a device was plugged in after
-* probing started. Unplugging it again will break the cycle.
-* (Simply polling the next higher device often ends up polling almost
-* every device (after wrapping around), which takes too long.)
-*/
-   int device_mask;
-   int next_device;
static struct adb_request req;
+   unsigned char poll_command;
+   unsigned int poll_addr;
 
+   /* This only polls devices in the autopoll list, which assumes that
+* unprobed devices never assert SRQ. That could happen if a device was
+* plugged in after the adb bus scan. Unplugging it again will resolve
+* the problem. This behaviour is similar to MacOS.
+*/
if (!autopoll_devs)
return;
 
-   device_mask = (1 << (((command_byte & 0xF0) >> 4) + 1)) - 1;
-   if (autopoll_devs & ~device_mask)
-   next_device = ffs(autopoll_devs & ~device_mask) - 1;
-   else
-   next_device = ffs(autopoll_devs) - 1;
+   /* The device most recently polled may not be the best device to poll
+* right now. Some other device(s) may have signalled SRQ (the active
+* device won't do that). Or the autopoll list may have been changed.
+* Try polling the next higher address.
+*/
+   poll_addr = (last_poll_cmd & ADDR_MASK) >> 4;
+   if ((srq_asserted && last_cmd == last_poll_cmd) ||
+   !(autopoll_devs & (1 << poll_addr))) {
+   unsigned int higher_devs;
+
+   higher_devs = autopoll_devs & -(1 << (poll_addr + 1));
+   poll_addr = ffs(higher_devs ? higher_devs : autopoll_devs) - 1;
+   }
 
-   adb_request(, NULL, ADBREQ_NOSEND, 1, ADB_READREG(next_device, 0));
+   /* Send a Talk Register 0 command */
+   poll_command = ADB_READREG(poll_addr, 0);
+
+   /* No need to repeat this Talk command. The transceiver will do that
+* as long as it is idle.
+*/
+   if (poll_command == last_cmd)
+   return;
+
+   adb_request(, NULL, ADBREQ_NOSEND, 1, poll_command);
 
req.sent = 0;
req.complete = 0;
req.reply_len = 0;
req.next = current_req;
 
-   if (current_req != NULL) {
+   if (WARN_ON(current_req)) {
current_req = 
} else {
current_req = 
@@ -266,37 +285,22 @@ static int macii_write(struct adb_request *req)
 /* Start auto-polling */
 static int macii_autopoll(int devs)
 {
-   static struct adb_request req;
unsigned long flags;
-   int err = 0;
 
local_irq_save(flags);
 
  

[PATCH 1/9] macintosh/via-macii: Access autopoll_devs when inside lock

2020-06-27 Thread Finn Thain
The interrupt handler should be excluded when accessing the autopoll_devs
variable.

Fixes: d95fd5fce88f0 ("m68k: Mac II ADB fixes") # v5.0+
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-macii.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c
index ac824d7b2dcfc..6aa903529570d 100644
--- a/drivers/macintosh/via-macii.c
+++ b/drivers/macintosh/via-macii.c
@@ -270,15 +270,12 @@ static int macii_autopoll(int devs)
unsigned long flags;
int err = 0;
 
+   local_irq_save(flags);
+
/* bit 1 == device 1, and so on. */
autopoll_devs = devs & 0xFFFE;
 
-   if (!autopoll_devs)
-   return 0;
-
-   local_irq_save(flags);
-
-   if (current_req == NULL) {
+   if (autopoll_devs && !current_req) {
/* Send a Talk Reg 0. The controller will repeatedly transmit
 * this as long as it is idle.
 */
-- 
2.26.2



Re: [PATCH] scsi: target/sbp: remove firewire SBP target driver

2020-06-17 Thread Finn Thain
On Tue, 16 Jun 2020, Martin K. Petersen wrote:

> 
> However, keeping code around is not free.

Right. And removing code isn't free either, if it forces people to find 
workarounds.

> Core interfaces change frequently.  Nobody enjoys having to tweak host 
> templates for 50 devices they have never even heard about.

And yet some people seem to enjoy writing patches that are as trivial as 
they are invasive...

You seem to be making an argument for more automation here, not an 
argument for less code. Or is there some upper bound to the size of the 
kernel, that might be lifted by adding maintainers? (Can you deliver a 
better product by adding more developers to your project?)

> Also, we now live in a reality where there is a constant barrage of 
> build bots and code analyzers sending mail. So the effective cost of 
> keeping code around in the tree is going up.

But if maintenance cost rises due to good analysis, the value of the code 
should rise too. So what's the problem? It seems to me that the real 
problem is too many analyses that generate pedantic noise and no tangible 
improvement in code quality or value.

> I get a substantial amount of code analysis mail about drivers nobody 
> have touched in a decade or more.
> 

When stable, mature code fails analysis, the analysis is also questionable 
(in the absence of real examples).

> Consequently, I am much more inclined to remove drivers than I have been 
> in the past. But I am also very happy to bring them back if somebody 
> uses them or - even better - are willing to step up and maintain them.
> 

You seem to be saying that 1) a driver should be removed when it no longer 
meets the present threshold for code quality and 2) that a low quality 
driver is eligible for re-addition because someone wants to use it.
I don't think you can have it both ways.

> I don't particularly like the notion of a driver being orphaned because 
> all that really means is that the driver transitions from being (at 
> least partially) somebody else's problem to being mine and mine alone.
> 

Yes it's your problem but only on a best-effort basis.

Many issues detected by automatic analyzers can be fixed with automatic 
code transformation tools. This kind of solution works tree-wide, so even 
if some defect in your driver is "yours and yours alone", the solution 
will probably come from others.

This email, like yours, is just hand-waving. So feel free to ignore it or 
(preferably) provide evidence of real defects.


Re: [PATCH] scsi: target/sbp: remove firewire SBP target driver

2020-06-16 Thread Finn Thain
On Tue, 16 Jun 2020, Martin K. Petersen wrote:

> > I haven't used this driver for a long time, but I still own PowerMacs 
> > with firewire, and I know I'm not the only one.
> 

I need to correct what I wrote above. I recall that years ago, when I 
needed to share storage from my Linux box to my PowerBook pismo, I used 
ethernet and the globalSAN iSCSI initiator for Mac OS X (which is no 
longer freely available AFAICS). When I said that I had used the SBP 
target driver before, I misremembered that iSCSI target setup. I've 
actually never used the SBP target driver.

> I also have old 1394 hardware kicking around in the basement. But having 
> worked with FireWire shared storage targets in the past, I have zero 
> desire to ever touch any of that again.
> 
> I could understand an objection if we were to entertain removing sbp2. 
> But really, how many people are setting up FireWire targets?
> 

It's a good question. I don't know the answer.

I have successfully used the Linux sbp2 host driver in the past, and will 
probably need to use it again. Likewise, I can see myself using the sbp 
target driver in the future because that might interoperate with MacOS 9, 
and might provide a bootable device to the PowerMac ROM. iSCSI cannot do 
those things.


Re: [PATCH] scsi: target/sbp: remove firewire SBP target driver

2020-06-16 Thread Finn Thain
On Tue, 16 Jun 2020, Bart Van Assche wrote:

> 
> As far as I know the sbp driver only has had one user ever and that user 
> is no longer user the sbp driver.

So, you estimate the userbase at zero. Can you give a confidence level? 
Actual measurement is hard because when end users encounter breakage, they 
look for quick workarounds before they undertake post mortem, log 
collection, bug reporting, mailing list discussions, analysis etc.

> So why to keep it in the kernel tree?

Answer: for the same reason it was added to the tree.

Here's a different question: "Why remove it from the kernel tree?"

If maintaining this code is a burden, is it not the kind of tax that all 
developers/users pay to all developers/users? Does this driver impose an 
unreasonably high burden for some reason?

The growth of a maintenance burden in general has lead to the invention of 
design patterns and tooling to minize it. So a good argument for removal 
would describe the nature of the problem, because some driver deficiencies 
can be fixed automatically, and some tooling deficiencies can compound an 
otherwise insignificant or common driver deficiency.

There are spin-off benefits from legacy code besides process improvements. 
Building and testing this sort of code has regularly revealed erroneous 
corner cases in commits elsewhere like API changes and refactoring.

Also, legacy code is used by new developers get experience in code 
modernization. And it provides more training material for neural networks 
that need to be taught to recognize patches that raise quality.

Ten or twenty years ago, I doubt that anyone predicted these (and other) 
spin-off benefits. If we can't predict the benefit, how will we project 
the cost, and use that to justify deletion?

Please see also,
http://www.mac.linux-m68k.org/docs/obsolete.php


Re: [PATCH] scsi: target/sbp: remove firewire SBP target driver

2020-06-16 Thread Finn Thain
On Mon, 15 Jun 2020, Chris Boot wrote:

> On 15/06/2020 00:28, Finn Thain wrote:
> > On Sun, 14 Jun 2020, Chris Boot wrote:
> > 
> >> I expect that if someone finds this useful it can stick around (but 
> >> that's not my call).
> > 
> > Who's call is that? If the patch had said "From: Martin K. Petersen" 
> > and "This driver is being removed because it has the following 
> > defects..." that would be some indication of a good-faith willingness 
> > to accept users as developers in the spirit of the GPL, which is what 
> > you seem to be alluding to (?).
> 
> If you're asking me, I'd say it was martin's call:
> 
> > SCSI TARGET SUBSYSTEM   
> >
> > M:  "Martin K. Petersen"
> >
> [...]
> > F:  drivers/target/ 
> >
> > F:  include/target/ 
> >
> 

The question I asked you was intended to make you think. I wasn't asking 
you to search MAINTAINERS for "drivers/target" (I had already done so).

Chris, you can find my name in that file too. That's because I see my role 
as custodian of that particular code. That code lives in the kernel.org 
tree because others put it there and because users find it useful -- not 
merely because it happens to please the official glorious MAINTAINER of 
said code.

If you would ask, "who's call is it to delete drivers/nubus? or 
drivers/scsi/NCR5380.c?" my answer is, I have no idea.

> >> I just don't have the time or inclination or hardware to be able to 
> >> maintain it anymore, so someone else would have to pick it up.
> >>
> > 
> > Which is why most drivers get orphaned, right?
> 
> Sure, but that's not what Martin asked me to do, hence this patch.
> 

Martin said, "I'd appreciate a patch to remove it"

And Bart said, "do you want to keep this driver in the kernel tree?"

AFAICT both comments are quite ambiguous. I don't see an actionable 
request, just an expression of interest from people doing their jobs.

Note well: there is no pay check associated with having a MAINTAINERS file 
entry.


Re: [PATCH] scsi: target/sbp: remove firewire SBP target driver

2020-06-14 Thread Finn Thain
On Sun, 14 Jun 2020, Chris Boot wrote:

> I expect that if someone finds this useful it can stick around (but 
> that's not my call).

Who's call is that? If the patch had said "From: Martin K. Petersen" and 
"This driver is being removed because it has the following defects..." 
that would be some indication of a good-faith willingness to accept users 
as developers in the spirit of the GPL, which is what you seem to be 
alluding to (?).

> I just don't have the time or inclination or hardware to be able to 
> maintain it anymore, so someone else would have to pick it up.
> 

Which is why most drivers get orphaned, right?


Re: [PATCH] scsi: target/sbp: remove firewire SBP target driver

2020-06-13 Thread Finn Thain
On Sat, 13 Jun 2020, Chris Boot wrote:

> I no longer have the time to maintain this subsystem nor the hardware to
> test patches with. 

Then why not patch MAINTAINERS, and orphan it, as per usual practice?

$ git log --oneline MAINTAINERS | grep -i orphan

> It also doesn't appear to have any active users so I doubt anyone will 
> miss it.
> 

It's not unusual that any Linux driver written more than 5 years ago 
"doesn't appear to have any active users".

If a driver has been orphaned and broken in the past, and no-one stepped 
up to fix it within a reasonable period, removal would make sense. But 
that's not the case here.

I haven't used this driver for a long time, but I still own PowerMacs with 
firewire, and I know I'm not the only one.

> Signed-off-by: Chris Boot 
> ---
>  MAINTAINERS |9 -
>  drivers/target/Kconfig  |1 -
>  drivers/target/Makefile |1 -
>  drivers/target/sbp/Kconfig  |   12 -
>  drivers/target/sbp/Makefile |2 -
>  drivers/target/sbp/sbp_target.c | 2350 ---
>  drivers/target/sbp/sbp_target.h |  243 
>  7 files changed, 2618 deletions(-)
>  delete mode 100644 drivers/target/sbp/Kconfig
>  delete mode 100644 drivers/target/sbp/Makefile
>  delete mode 100644 drivers/target/sbp/sbp_target.c
>  delete mode 100644 drivers/target/sbp/sbp_target.h
> 


Re: [PATCH 8/8] macintosh/adb-iop: Implement SRQ autopolling

2020-06-01 Thread Finn Thain
On Mon, 1 Jun 2020, Geert Uytterhoeven wrote:

> >
> > Sure, it could be absorbed by both asm/mac_iop.h and 
> > drivers/macintosh/adb-iop.c [...]
> 
> asm/mac_iop.h doesn't include asm/adb_iop.h (at least not in my tree, 
> but perhaps you have plans to change that?), so there's only a single 
> user.

What I meant by "both" was that part of asm/adb_iop.h could be absorbed by 
drivers/macintosh.adb-iop.c and the rest by asm/mac_iop.h. (And some of it 
could be tossed out.) I suspect that much of arch/m68k/include/asm could 
get the same treatment. But I doubt that there is any pay off, because the 
headers rarely change where they relate to hardware characteristics.


Re: [PATCH 8/8] macintosh/adb-iop: Implement SRQ autopolling

2020-05-31 Thread Finn Thain
On Sun, 31 May 2020, Geert Uytterhoeven wrote:

> Hi Finn,
> 
> On Sun, May 31, 2020 at 1:20 AM Finn Thain  wrote:
> > The adb_driver.autopoll method is needed during ADB bus scan and device
> > address assignment. Implement this method so that the IOP's list of
> > device addresses can be updated. When the list is empty, disable SRQ
> > autopolling.
> >
> > Cc: Joshua Thompson 
> > Cc: Geert Uytterhoeven 
> > Tested-by: Stan Johnson 
> > Signed-off-by: Finn Thain 
> 
> Thanks for your patch!
> 
> Acked-by: Geert Uytterhoeven 
> 

Thanks for your tag.

> >  arch/m68k/include/asm/adb_iop.h |  1 +
> >  drivers/macintosh/adb-iop.c | 32 ++--
> 
> As this header file is used by a single source file only, perhaps it 
> should just be absorbed by the latter?

Sure, it could be absorbed by both asm/mac_iop.h and 
drivers/macintosh/adb-iop.c but I don't see the point...

> Then you no longer need my Acked-by for future changes ;-)
> 

But you shouldn't need to ack this kind of change in the first place.

IMHO, the arch/m68k/mac maintainer should be the one to ack changes to 
both arch/m68k/include/asm/adb_iop.h and drivers/macintosh/adb-iop.c.

Not that I'm complaining (thanks again for your ack!)


[PATCH 5/8] macintosh/adb-iop: Resolve static checker warnings

2020-05-30 Thread Finn Thain
drivers/macintosh/adb-iop.c:215:28: warning: Using plain integer as NULL pointer
drivers/macintosh/adb-iop.c:170:5: warning: symbol 'adb_iop_probe' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:177:5: warning: symbol 'adb_iop_init' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:184:5: warning: symbol 'adb_iop_send_request' was 
not declared. Should it be static?
drivers/macintosh/adb-iop.c:230:5: warning: symbol 'adb_iop_autopoll' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:236:6: warning: symbol 'adb_iop_poll' was not 
declared. Should it be static?
drivers/macintosh/adb-iop.c:241:5: warning: symbol 'adb_iop_reset_bus' was not 
declared. Should it be static?

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 7ecc41bc7358..a2b28e09f2ce 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -166,21 +166,21 @@ static void adb_iop_start(void)
 adb_iop_complete);
 }
 
-int adb_iop_probe(void)
+static int adb_iop_probe(void)
 {
if (!iop_ism_present)
return -ENODEV;
return 0;
 }
 
-int adb_iop_init(void)
+static int adb_iop_init(void)
 {
pr_info("adb: IOP ISM driver v0.4 for Unified ADB\n");
iop_listen(ADB_IOP, ADB_CHAN, adb_iop_listen, "ADB");
return 0;
 }
 
-int adb_iop_send_request(struct adb_request *req, int sync)
+static int adb_iop_send_request(struct adb_request *req, int sync)
 {
int err;
 
@@ -211,7 +211,7 @@ static int adb_iop_write(struct adb_request *req)
 
local_irq_save(flags);
 
-   if (current_req != 0) {
+   if (current_req) {
last_req->next = req;
last_req = req;
} else {
@@ -227,18 +227,18 @@ static int adb_iop_write(struct adb_request *req)
return 0;
 }
 
-int adb_iop_autopoll(int devs)
+static int adb_iop_autopoll(int devs)
 {
/* TODO: how do we enable/disable autopoll? */
return 0;
 }
 
-void adb_iop_poll(void)
+static void adb_iop_poll(void)
 {
iop_ism_irq_poll(ADB_IOP);
 }
 
-int adb_iop_reset_bus(void)
+static int adb_iop_reset_bus(void)
 {
struct adb_request req;
 
-- 
2.26.2



[PATCH 7/8] macintosh/adb-iop: Implement sending -> idle state transition

2020-05-30 Thread Finn Thain
On leaving the 'sending' state, proceed to the 'idle' state if no reply is
expected. Drop redundant test for adb_iop_state == sending && current_req.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index f22792c95d4f..8594e4f9a830 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -77,15 +77,14 @@ static void adb_iop_done(void)
 
 static void adb_iop_complete(struct iop_msg *msg)
 {
-   struct adb_request *req;
unsigned long flags;
 
local_irq_save(flags);
 
-   req = current_req;
-   if ((adb_iop_state == sending) && req && req->reply_expected) {
+   if (current_req->reply_expected)
adb_iop_state = awaiting_reply;
-   }
+   else
+   adb_iop_done();
 
local_irq_restore(flags);
 }
-- 
2.26.2



[PATCH 4/8] macintosh/adb-iop: Access current_req and adb_iop_state when inside lock

2020-05-30 Thread Finn Thain
Drop the redundant local_irq_save/restore() from adb_iop_start() because
the caller has to do it anyway. This is the pattern used in via-macii.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index c3089dacf2e2..7ecc41bc7358 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -137,7 +137,6 @@ static void adb_iop_listen(struct iop_msg *msg)
 
 static void adb_iop_start(void)
 {
-   unsigned long flags;
struct adb_request *req;
struct adb_iopmsg amsg;
 
@@ -146,8 +145,6 @@ static void adb_iop_start(void)
if (!req)
return;
 
-   local_irq_save(flags);
-
/* The IOP takes MacII-style packets, so strip the initial
 * ADB_PACKET byte.
 */
@@ -161,7 +158,6 @@ static void adb_iop_start(void)
 
req->sent = 1;
adb_iop_state = sending;
-   local_irq_restore(flags);
 
/* Now send it. The IOP manager will call adb_iop_complete
 * when the message has been sent.
@@ -208,13 +204,13 @@ static int adb_iop_write(struct adb_request *req)
return -EINVAL;
}
 
-   local_irq_save(flags);
-
req->next = NULL;
req->sent = 0;
req->complete = 0;
req->reply_len = 0;
 
+   local_irq_save(flags);
+
if (current_req != 0) {
last_req->next = req;
last_req = req;
@@ -223,10 +219,11 @@ static int adb_iop_write(struct adb_request *req)
last_req = req;
}
 
-   local_irq_restore(flags);
-
if (adb_iop_state == idle)
adb_iop_start();
+
+   local_irq_restore(flags);
+
return 0;
 }
 
-- 
2.26.2



[PATCH 3/8] macintosh/adb-iop: Adopt bus reset algorithm from via-macii driver

2020-05-30 Thread Finn Thain
This algorithm is slightly shorter and avoids the surprising
adb_iop_start() call in adb_iop_poll().

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index ca3b411b0742..c3089dacf2e2 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -238,24 +238,19 @@ int adb_iop_autopoll(int devs)
 
 void adb_iop_poll(void)
 {
-   if (adb_iop_state == idle)
-   adb_iop_start();
iop_ism_irq_poll(ADB_IOP);
 }
 
 int adb_iop_reset_bus(void)
 {
-   struct adb_request req = {
-   .reply_expected = 0,
-   .nbytes = 2,
-   .data = { ADB_PACKET, 0 },
-   };
-
-   adb_iop_write();
-   while (!req.complete) {
-   adb_iop_poll();
-   schedule();
-   }
+   struct adb_request req;
+
+   /* Command = 0, Address = ignored */
+   adb_request(, NULL, ADBREQ_NOSEND, 1, ADB_BUSRESET);
+   adb_iop_send_request(, 1);
+
+   /* Don't want any more requests during the Global Reset low time. */
+   mdelay(3);
 
return 0;
 }
-- 
2.26.2



[PATCH 2/8] macintosh/adb-iop: Correct comment text

2020-05-30 Thread Finn Thain
This patch improves comment style and corrects some misunderstandings
in the text.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 29 +
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index ce28ff40fb9c..ca3b411b0742 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -101,11 +101,10 @@ static void adb_iop_listen(struct iop_msg *msg)
 
req = current_req;
 
-   /* Handle a timeout. Timeout packets seem to occur even after */
-   /* we've gotten a valid reply to a TALK, so I'm assuming that */
-   /* a "timeout" is actually more like an "end-of-data" signal. */
-   /* We need to send back a timeout packet to the IOP to shut   */
-   /* it up, plus complete the current request, if any.  */
+   /* Handle a timeout. Timeout packets seem to occur even after
+* we've gotten a valid reply to a TALK, presumably because of
+* autopolling.
+*/
 
if (amsg->flags & ADB_IOP_TIMEOUT) {
msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL;
@@ -115,9 +114,6 @@ static void adb_iop_listen(struct iop_msg *msg)
adb_iop_end_req(req, idle);
}
} else {
-   /* TODO: is it possible for more than one chunk of data  */
-   /*   to arrive before the timeout? If so we need to */
-   /*   use reply_ptr here like the other drivers do.  */
if ((adb_iop_state == awaiting_reply) &&
(amsg->flags & ADB_IOP_EXPLICIT)) {
req->reply_len = amsg->count + 1;
@@ -152,23 +148,24 @@ static void adb_iop_start(void)
 
local_irq_save(flags);
 
-   /* The IOP takes MacII-style packets, so */
-   /* strip the initial ADB_PACKET byte.*/
-
+   /* The IOP takes MacII-style packets, so strip the initial
+* ADB_PACKET byte.
+*/
amsg.flags = ADB_IOP_EXPLICIT;
amsg.count = req->nbytes - 2;
 
-   /* amsg.data immediately follows amsg.cmd, effectively making */
-   /* amsg.cmd a pointer to the beginning of a full ADB packet.  */
+   /* amsg.data immediately follows amsg.cmd, effectively making
+*  a pointer to the beginning of a full ADB packet.
+*/
memcpy(, req->data + 1, req->nbytes - 1);
 
req->sent = 1;
adb_iop_state = sending;
local_irq_restore(flags);
 
-   /* Now send it. The IOP manager will call adb_iop_complete */
-   /* when the packet has been sent.  */
-
+   /* Now send it. The IOP manager will call adb_iop_complete
+* when the message has been sent.
+*/
iop_send_message(ADB_IOP, ADB_CHAN, req, sizeof(amsg), (__u8 *),
 adb_iop_complete);
 }
-- 
2.26.2



[PATCH 1/8] macintosh/adb-iop: Remove dead and redundant code

2020-05-30 Thread Finn Thain
Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 29 -
 1 file changed, 29 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index fca31640e3ef..ce28ff40fb9c 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -18,24 +18,16 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include 
 
-/*#define DEBUG_ADB_IOP*/
-
 static struct adb_request *current_req;
 static struct adb_request *last_req;
-#if 0
-static unsigned char reply_buff[16];
-static unsigned char *reply_ptr;
-#endif
 
 static enum adb_iop_state {
idle,
@@ -104,22 +96,11 @@ static void adb_iop_listen(struct iop_msg *msg)
struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
struct adb_request *req;
unsigned long flags;
-#ifdef DEBUG_ADB_IOP
-   int i;
-#endif
 
local_irq_save(flags);
 
req = current_req;
 
-#ifdef DEBUG_ADB_IOP
-   printk("adb_iop_listen %p: rcvd packet, %d bytes: %02X %02X", req,
-  (uint)amsg->count + 2, (uint)amsg->flags, (uint)amsg->cmd);
-   for (i = 0; i < amsg->count; i++)
-   printk(" %02X", (uint)amsg->data[i]);
-   printk("\n");
-#endif
-
/* Handle a timeout. Timeout packets seem to occur even after */
/* we've gotten a valid reply to a TALK, so I'm assuming that */
/* a "timeout" is actually more like an "end-of-data" signal. */
@@ -163,9 +144,6 @@ static void adb_iop_start(void)
unsigned long flags;
struct adb_request *req;
struct adb_iopmsg amsg;
-#ifdef DEBUG_ADB_IOP
-   int i;
-#endif
 
/* get the packet to send */
req = current_req;
@@ -174,13 +152,6 @@ static void adb_iop_start(void)
 
local_irq_save(flags);
 
-#ifdef DEBUG_ADB_IOP
-   printk("adb_iop_start %p: sending packet, %d bytes:", req, req->nbytes);
-   for (i = 0; i < req->nbytes; i++)
-   printk(" %02X", (uint)req->data[i]);
-   printk("\n");
-#endif
-
/* The IOP takes MacII-style packets, so */
/* strip the initial ADB_PACKET byte.*/
 
-- 
2.26.2



[PATCH 0/8] Mac ADB IOP driver fixes

2020-05-30 Thread Finn Thain
The adb-iop driver was never finished. Some deficiencies have become
apparent over the years. For example,

 - Mouse and/or keyboard may stop working if used together

 - SRQ autopoll list cannot be changed

 - Some bugs were found by inspection

This patch series contains fixes for the known bugs in the driver, plus
a few clean-ups.


Finn Thain (8):
  macintosh/adb-iop: Remove dead and redundant code
  macintosh/adb-iop: Correct comment text
  macintosh/adb-iop: Adopt bus reset algorithm from via-macii driver
  macintosh/adb-iop: Access current_req and adb_iop_state when inside
lock
  macintosh/adb-iop: Resolve static checker warnings
  macintosh/adb-iop: Implement idle -> sending state transition
  macintosh/adb-iop: Implement sending -> idle state transition
  macintosh/adb-iop: Implement SRQ autopolling

 arch/m68k/include/asm/adb_iop.h |   1 +
 drivers/macintosh/adb-iop.c | 186 +++-
 2 files changed, 86 insertions(+), 101 deletions(-)

-- 
2.26.2



[PATCH 6/8] macintosh/adb-iop: Implement idle -> sending state transition

2020-05-30 Thread Finn Thain
In the present algorithm, the 'idle' state transition does not take
place until there's a bus timeout. Once idle, the driver does not
automatically proceed with the next request.

Change the algorithm so that queued ADB requests will be sent as soon as
the driver becomes idle. This is to take place after the current IOP
message is completed.

Cc: Joshua Thompson 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/adb-iop.c | 43 +
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index a2b28e09f2ce..f22792c95d4f 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -54,13 +54,19 @@ struct adb_driver adb_iop_driver = {
.reset_bus= adb_iop_reset_bus
 };
 
-static void adb_iop_end_req(struct adb_request *req, int state)
+static void adb_iop_done(void)
 {
+   struct adb_request *req = current_req;
+
+   adb_iop_state = idle;
+
req->complete = 1;
current_req = req->next;
if (req->done)
(*req->done)(req);
-   adb_iop_state = state;
+
+   if (adb_iop_state == idle)
+   adb_iop_start();
 }
 
 /*
@@ -94,37 +100,36 @@ static void adb_iop_complete(struct iop_msg *msg)
 static void adb_iop_listen(struct iop_msg *msg)
 {
struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
-   struct adb_request *req;
unsigned long flags;
+   bool req_done = false;
 
local_irq_save(flags);
 
-   req = current_req;
-
/* Handle a timeout. Timeout packets seem to occur even after
 * we've gotten a valid reply to a TALK, presumably because of
 * autopolling.
 */
 
-   if (amsg->flags & ADB_IOP_TIMEOUT) {
-   msg->reply[0] = ADB_IOP_TIMEOUT | ADB_IOP_AUTOPOLL;
-   msg->reply[1] = 0;
-   msg->reply[2] = 0;
-   if (req && (adb_iop_state != idle)) {
-   adb_iop_end_req(req, idle);
-   }
-   } else {
-   if ((adb_iop_state == awaiting_reply) &&
-   (amsg->flags & ADB_IOP_EXPLICIT)) {
+   if (amsg->flags & ADB_IOP_EXPLICIT) {
+   if (adb_iop_state == awaiting_reply) {
+   struct adb_request *req = current_req;
+
req->reply_len = amsg->count + 1;
memcpy(req->reply, >cmd, req->reply_len);
-   } else {
-   adb_input(>cmd, amsg->count + 1,
- amsg->flags & ADB_IOP_AUTOPOLL);
+
+   req_done = true;
}
-   memcpy(msg->reply, msg->message, IOP_MSG_LEN);
+   } else if (!(amsg->flags & ADB_IOP_TIMEOUT)) {
+   adb_input(>cmd, amsg->count + 1,
+ amsg->flags & ADB_IOP_AUTOPOLL);
}
+
+   msg->reply[0] = ADB_IOP_AUTOPOLL;
iop_complete_message(msg);
+
+   if (req_done)
+   adb_iop_done();
+
local_irq_restore(flags);
 }
 
-- 
2.26.2



[PATCH 8/8] macintosh/adb-iop: Implement SRQ autopolling

2020-05-30 Thread Finn Thain
The adb_driver.autopoll method is needed during ADB bus scan and device
address assignment. Implement this method so that the IOP's list of
device addresses can be updated. When the list is empty, disable SRQ
autopolling.

Cc: Joshua Thompson 
Cc: Geert Uytterhoeven 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/m68k/include/asm/adb_iop.h |  1 +
 drivers/macintosh/adb-iop.c | 32 ++--
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/arch/m68k/include/asm/adb_iop.h b/arch/m68k/include/asm/adb_iop.h
index 195d7fb1268c..6aecd020e2fc 100644
--- a/arch/m68k/include/asm/adb_iop.h
+++ b/arch/m68k/include/asm/adb_iop.h
@@ -29,6 +29,7 @@
 
 #define ADB_IOP_EXPLICIT   0x80/* nonzero if explicit command */
 #define ADB_IOP_AUTOPOLL   0x40/* auto/SRQ polling enabled*/
+#define ADB_IOP_SET_AUTOPOLL   0x20/* set autopoll device list*/
 #define ADB_IOP_SRQ0x04/* SRQ detected*/
 #define ADB_IOP_TIMEOUT0x02/* nonzero if timeout  
*/
 
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c
index 8594e4f9a830..f3d1a460fbce 100644
--- a/drivers/macintosh/adb-iop.c
+++ b/drivers/macintosh/adb-iop.c
@@ -7,10 +7,6 @@
  * 1999-07-01 (jmt) - First implementation for new driver architecture.
  *
  * 1999-07-31 (jmt) - First working version.
- *
- * TODO:
- *
- * o Implement SRQ handling.
  */
 
 #include 
@@ -28,6 +24,7 @@
 
 static struct adb_request *current_req;
 static struct adb_request *last_req;
+static unsigned int autopoll_devs;
 
 static enum adb_iop_state {
idle,
@@ -123,7 +120,7 @@ static void adb_iop_listen(struct iop_msg *msg)
  amsg->flags & ADB_IOP_AUTOPOLL);
}
 
-   msg->reply[0] = ADB_IOP_AUTOPOLL;
+   msg->reply[0] = autopoll_devs ? ADB_IOP_AUTOPOLL : 0;
iop_complete_message(msg);
 
if (req_done)
@@ -231,9 +228,32 @@ static int adb_iop_write(struct adb_request *req)
return 0;
 }
 
+static void adb_iop_set_ap_complete(struct iop_msg *msg)
+{
+   struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
+
+   autopoll_devs = (amsg->data[1] << 8) | amsg->data[0];
+}
+
 static int adb_iop_autopoll(int devs)
 {
-   /* TODO: how do we enable/disable autopoll? */
+   struct adb_iopmsg amsg;
+   unsigned long flags;
+   unsigned int mask = (unsigned int)devs & 0xFFFE;
+
+   local_irq_save(flags);
+
+   amsg.flags = ADB_IOP_SET_AUTOPOLL | (mask ? ADB_IOP_AUTOPOLL : 0);
+   amsg.count = 2;
+   amsg.cmd = 0;
+   amsg.data[0] = mask & 0xFF;
+   amsg.data[1] = (mask >> 8) & 0xFF;
+
+   iop_send_message(ADB_IOP, ADB_CHAN, NULL, sizeof(amsg), (__u8 *),
+adb_iop_set_ap_complete);
+
+   local_irq_restore(flags);
+
return 0;
 }
 
-- 
2.26.2



Re: pata-macio on PowerBook G3: stuck interrupt with MATSHITA CR-174 CD-ROM

2019-07-10 Thread Finn Thain
On Fri, 28 Jun 2019, Finn Thain wrote:

> Hi All,
> 
> I've received a bug report concerning the pata-macio driver, when running 
> on a PowerBook G3 (Wallstreet).
> 
> With CONFIG_PATA_MACIO=n && CONFIG_BLK_DEV_IDE_PMAC=y, everything works.
> 
> With CONFIG_PATA_MACIO=y && CONFIG_BLK_DEV_IDE_PMAC=n, the CD-ROM fails.
> 
> When the CD-ROM mediabay module is swapped for a DVD-ROM mediabay module, 
> everything works (either pata-macio or ide-pmac driver works fine).
> 
> I'm not familiar with ATA device drivers or the "Heathrow" chipset and its 
> ATA interfaces so any hints as to how to debug this would be appreciated.
> 
...
> 
> These logs are from v4.20 but the problem is the same in v5.2-rc2.
> 

In the linux-ide list archive I found the same bug reported in 2.6.33-rc2, 
shortly after the pata-macio driver was merged.

https://lore.kernel.org/linux-ide/19254.17766.674348.933...@pilspetsen.it.uu.se/

That report also involves a Matshita CD-ROM and a Heathrow controller 
(beige G3).

In that thread Ben suggested that the cause may be a firmware bug in the 
drive. Is there a quirk or other workaround for that kind of bug?

I tried removing the controller reset but there was no improvement...

diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c
index 57f2ec71cfc3..b2fd5e20367f 100644
--- a/drivers/ata/pata_macio.c
+++ b/drivers/ata/pata_macio.c
@@ -1096,7 +1096,7 @@ static int pata_macio_common_init(struct pata_macio_priv 
*priv,
priv->host->ports[0]->private_data = priv;
 
/* hard-reset the controller */
-   pata_macio_reset_hw(priv, 0);
+// pata_macio_reset_hw(priv, 0);
pata_macio_apply_timings(priv->host->ports[0], 0);
 
/* Enable bus master if necessary */

-- 


pata-macio on PowerBook G3: stuck interrupt with MATSHITA CR-174 CD-ROM

2019-06-27 Thread Finn Thain
Hi All,

I've received a bug report concerning the pata-macio driver, when running 
on a PowerBook G3 (Wallstreet).

With CONFIG_PATA_MACIO=n && CONFIG_BLK_DEV_IDE_PMAC=y, everything works.

With CONFIG_PATA_MACIO=y && CONFIG_BLK_DEV_IDE_PMAC=n, the CD-ROM fails.

When the CD-ROM mediabay module is swapped for a DVD-ROM mediabay module, 
everything works (either pata-macio or ide-pmac driver works fine).

I'm not familiar with ATA device drivers or the "Heathrow" chipset and its 
ATA interfaces so any hints as to how to debug this would be appreciated.

Here's the log from the CONFIG_PATA_MACIO=y kernel with CD-ROM fitted:

[0.016446] printk: console [ttyS0] enabled
[0.064507] printk: bootconsole [udbg0] disabled
[0.119973] pid_max: default: 32768 minimum: 301
[0.175852] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[0.254862] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[0.343822] rcu: Hierarchical SRCU implementation.
[0.400629] smp: Bringing up secondary CPUs ...
[0.453605] smp: Brought up 1 node, 1 CPU
[0.501683] Using standard scheduler topology
[0.555151] devtmpfs: initialized
[0.594335] Duplicate name in PowerPC,750, renamed to "l2-cache#1"
[0.671377] Duplicate name in pci, renamed to "mac-io#1"
[0.734879] Duplicate name in pci, renamed to "pccard#1"
[0.798672] random: get_random_u32 called from bucket_table_alloc+0x90/0x1a4 
with crng_init=0
[0.900756] clocksource: jiffies: mask: 0x max_cycles: 0x, 
max_idle_ns: 1911260446275 ns
[1.018102] futex hash table entries: 512 (order: 2, 16384 bytes)
[1.091844] NET: Registered protocol family 16
[1.149658] PMU i2c /pci/mac-io/via-pmu
[1.194834]  channel 1 bus 
[1.237542]  channel 2 bus 
[1.283706] PCI: Probing PCI hardware
[1.326481] PCI host bridge to bus :00
[1.374850] pci_bus :00: root bus resource [io  0x-0x7f]
[1.45] pci_bus :00: root bus resource [mem 0xfd00-0xfdff] 
(bus address [0x-0x00ff])
[1.573579] pci_bus :00: root bus resource [mem 0x8000-0xfcff]
[1.656035] pci_bus :00: root bus resource [bus 00-ff]
[1.721896] pci_bus :00: busn_res: [bus 00-ff] end is updated to ff
[1.801465] pci :00:00.0: [1057:0002] type 00 class 0x06
[1.875076] pci :00:0d.0: [106b:0017] type 00 class 0xff
[1.945684] pci :00:0d.0: reg 0x10: [mem 0xf400-0xf407]
[2.021957] pci :00:10.0: [106b:0017] type 00 class 0xff
[2.093150] pci :00:10.0: reg 0x10: [mem 0xf300-0xf307]
[2.169344] pci :00:11.0: [1002:4c50] type 00 class 0x038000
[2.240603] pci :00:11.0: reg 0x10: [mem 0x8200-0x82ff]
[2.315852] pci :00:11.0: reg 0x14: [io  0x0400-0x04ff]
[2.382757] pci :00:11.0: reg 0x18: [mem 0x82fff000-0x82ff]
[2.458076] pci :00:11.0: reg 0x30: [mem 0xfd00-0xfd01 pref]
[2.538627] pci :00:11.0: supports D1 D2
[2.590881] pci :00:13.0: [104c:ac15] type 02 class 0x060700
[2.662054] pci :00:13.0: reg 0x10: [mem 0x81803000-0x81803fff]
[2.738090] pci :00:13.1: [104c:ac15] type 02 class 0x060700
[2.809506] pci :00:13.1: reg 0x10: [mem 0x81802000-0x81802fff]
[2.886775] pci_bus :01: extended config space not accessible
[2.958551] pci_bus :01: busn_res: [bus 01-ff] end is updated to 04
[3.037665] pci_bus :05: extended config space not accessible
[3.111056] pci_bus :05: busn_res: [bus 05-ff] end is updated to 08
[3.190143] pci_bus :00: busn_res: [bus 00-ff] end is updated to 08
[3.269804] PCI: Cannot allocate resource region 2 of device :00:11.0, 
will remap
[3.363779] PCI :00 Cannot reserve Legacy IO [io  0x-0x0fff]
[3.440211] pci :00:13.0: BAR 9: assigned [mem 0x8400-0x87ff 
pref]
[3.526840] pci :00:13.0: BAR 10: assigned [mem 0x8800-0x8bff]
[3.609575] pci :00:13.1: BAR 9: assigned [mem 0x8c00-0x8fff 
pref]
[3.696208] pci :00:13.1: BAR 10: assigned [mem 0x9000-0x93ff]
[3.778818] pci :00:11.0: BAR 6: assigned [mem 0xfd00-0xfd01 
pref]
[3.865615] pci :00:11.0: BAR 2: assigned [mem 0xfd02-0xfd020fff]
[3.947184] pci :00:13.0: BAR 7: assigned [io  0x1000-0x10ff]
[4.020382] pci :00:13.0: BAR 8: assigned [io  0x1100-0x11ff]
[4.093579] pci :00:13.1: BAR 7: assigned [io  0x1200-0x12ff]
[4.166780] pci :00:13.1: BAR 8: assigned [io  0x1300-0x13ff]
[4.239996] pci :00:13.0: CardBus bridge to [bus 01-04]
[4.306908] pci :00:13.0:   bridge window [io  0x1000-0x10ff]
[4.380112] pci :00:13.0:   bridge window [io  0x1100-0x11ff]
[4.453316] pci :00:13.0:   bridge window [mem 0x8400-0x87ff 
pref]
[4.540112] pci :00:13.0:   bridge window [mem 0x8800-0x8bff]
[4.621825] pci :00:13.1: CardBus 

Re: Bisected regression in v5.1 on PowerBook G3 (Wallstreet)

2019-06-26 Thread Finn Thain
On Wed, 26 Jun 2019, Christophe Leroy wrote:

> Hi Finn,
> 
> On 06/26/2019 02:06 AM, Finn Thain wrote:
> > Hi Christophe,
> > 
> > I received a report of a regression between v5.0 and v5.1 which causes 
> > the current release to crash during boot with a machine check 
> > exception. Please see console log below.
> > 
> > Stan (whom I've Cc'd) tells me that this happens on every attempt to 
> > boot. I asked him to try 'git bisect'. The results are given below. 
> > Can you see anything in commit 93c4a162b014 that might explain this?
> 
> Might be a false positive. That commit has a problem, but that problem 
> is fixed by 4622a2d43101 ("powerpc/6xx: fix setup and use of 
> SPRN_SPRG_PGDIR for hash32")
> 
> I would bet your problem is related to commit f7354ccac844 ("powerpc/32: 
> Remove CURRENT_THREAD_INFO and rename TI_CPU"). That problem is fixed by 
> commit 397d2300b08c ("powerpc/32s: fix flush_hash_pages() on SMP") 
> upstream, and in linux 5.1.4 by commit fda49aec2515 on 
> stable/linux-5.1.y
> 

I see. I've just discovered that this issue has already been covered on 
this list. I should have done a bit more research.

> Can you test ?
> 

Stan did some more tests and confirmed that the problem has been fixed in 
397d2300b08c and stable/linux-5.1.y.

Thanks.

-- 

> Thanks
> Christophe
> 


Bisected regression in v5.1 on PowerBook G3 (Wallstreet)

2019-06-26 Thread Finn Thain
Hi Christophe,

I received a report of a regression between v5.0 and v5.1 which causes the 
current release to crash during boot with a machine check exception. 
Please see console log below.

Stan (whom I've Cc'd) tells me that this happens on every attempt to boot. 
I asked him to try 'git bisect'. The results are given below. Can you see 
anything in commit 93c4a162b014 that might explain this?

I can also provide the .config if it would help.


$ cat bisect.log
5.0.0-pmac-ide-03515-g3478588b5136 #2 worked
5.0.0-pmac-ide-05504-gda2577fe63f8 #3 worked
5.0.0-pmac-ide-06224-g67e79a6dc266 #4 worked
5.0.0-pmac-ide-06622-g1fc1cd8399ab #5 worked
5.0.0-rc2-pmac-ide-00215=g9580b71b5a78 #6 failed
5.0.0-rc2-pmac-ide-00113-gfe1ef6bcdb4f #7 worked
5.0.0-rc2-pmac-ide-00164-gd5f17ee96447 #8 failed
5.0.0-rc2-pmac-ide-00138-g84de6ab0e904 #9 failed
5.0.0-rc2-pmac-ide-00125-ge995265252fa #10 worked
5.0.0-rc2-pmac-ide-00131-g93c4a162b014 #11 failed
5.0.0-rc2-pmac-ide-00128-g36da5ff0bea2 #12 worked


93c4a162b014d238a287f8264adb25c009c79e61 is the first bad commit
commit 93c4a162b014d238a287f8264adb25c009c79e61
Author: Christophe Leroy 
Date:   Thu Feb 21 10:37:55 2019 +

powerpc/6xx: Store PGDIR physical address in a SPRG

Use SPRN_SPRG2 to store the current thread PGDIR and
avoid reading thread_struct.pgdir at every TLB miss.

Signed-off-by: Christophe Leroy 
Signed-off-by: Michael Ellerman 

:04 04 dcd7171dff5ba5bf895e4399d9d859c91c5a8293
c51e7def7720499289420ace421cf755bf3bf37e M  arch


[0.00] printk: debug: ignoring loglevel setting.
[0.00] Total memory = 512MB; using 1024kB for hash table (at (ptrval))
[0.00] Linux version 5.1.0-pmac-ide (fthain@nippy) (gcc version 4.6.4 
(btc)) #1 SMP Sun Jun 23 14:46:26 AEST 2019
[0.00] Found a Gatwick mac-io controller, rev: 0, mapped at 0x(ptrval)
[0.00] Found a Heathrow mac-io controller, rev: 0, mapped at 0x(ptrval)
[0.00] PowerMac motherboard: PowerBook Wallstreet
[0.00] PMU driver v2 initialized for PowerBook G3 Series, firmware: 0a
[0.00] Using PowerMac machine description
[0.00] printk: bootconsole [udbg0] enabled
[0.00] CPU maps initialized for 1 thread per core
[0.00]  (thread shift is 0)
[0.00] -
[0.00] Hash_size = 0x10
[0.00] phys_mem_size = 0x2000
[0.00] dcache_bsize  = 0x20
[0.00] icache_bsize  = 0x20
[0.00] cpu_features  = 0x0501a008
[0.00]   possible= 0x2f7ff14b
[0.00]   always  = 0x0100
[0.00] cpu_user_features = 0x8c01 0x
[0.00] mmu_features  = 0x0001
[0.00] Hash  = 0x(ptrval)
[0.00] Hash_mask = 0x3fff
[0.00] -
[0.00] Found Grackle (MPC106) PCI host bridge at 0x8000. 
Firmware bus number: 0->0
[0.00] PCI host bridge /pci (primary) ranges:
[0.00]   IO 0xfe00..0xfe7f -> 0x
[0.00]  MEM 0xfd00..0xfdff -> 
0x 
[0.00]  MEM 0x8000..0xfcff -> 
0x8000 
[0.00] nvram: OF partition at 0x1800
[0.00] nvram: XP partition at 0x1300
[0.00] nvram: NR partition at 0x1400
[0.00] Top of RAM: 0x2000, Total RAM: 0x2000
[0.00] Memory hole size: 0MB
[0.00] Zone ranges:
[0.00]   Normal   [mem 0x-0x1fff]
[0.00]   HighMem  empty
[0.00] Movable zone start for each node
[0.00] Early memory node ranges
[0.00]   node   0: [mem 0x-0x1fff]
[0.00] Initmem setup node 0 [mem 0x-0x1fff]
[0.00] On node 0 totalpages: 131072
[0.00]   Normal zone: 1024 pages used for memmap
[0.00]   Normal zone: 0 pages reserved
[0.00]   Normal zone: 131072 pages, LIFO batch:31
[0.00] percpu: Embedded 14 pages/cpu s24972 r8192 d24180 u57344
[0.00] pcpu-alloc: s24972 r8192 d24180 u57344 alloc=14*4096
[0.00] pcpu-alloc: [0] 0 [0] 1 
[0.00] Built 1 zonelists, mobility grouping on.  Total pages: 130048
[0.00] Kernel command line: root=/dev/hda11 
video=atyfb:vmode:14,cmode:32 ignore_loglevel printk.time console=ttyS0,9600n8 
console=tty
[0.00] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[0.00] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[0.00] Memory: 503332K/524288K available (5468K kernel code, 272K 
rwdata, 1364K rodata, 264K init, 182K bss, 20956K reserved, 0K cma-reserved, 0K 
highmem)
[0.00] Kernel virtual memory layout:
[0.00]   * 0xfffbf000..0xf000  : fixmap
[0.00]   * 

Re: [PATCH v9 00/22] Re-use nvram module

2019-01-22 Thread Finn Thain
On Tue, 22 Jan 2019, Greg Kroah-Hartman wrote:

> On Tue, Jan 15, 2019 at 03:18:56PM +1100, Finn Thain wrote:
> > The "generic" NVRAM module, drivers/char/generic_nvram.c, implements a
> > /dev/nvram misc device. This module is used only by 32-bit PowerPC
> > platforms.
> > 
> > The RTC "CMOS" NVRAM module, drivers/char/nvram.c, also implements a
> > /dev/nvram misc device. This module is now used only by x86 and m68k
> > thanks to commit 3ba9faedc180 ("char: nvram: disable on ARM").
> > 
> > The "generic" module cannot be used by x86 or m68k platforms because it
> > cannot co-exist with the "CMOS" module. One reason for that is the
> > CONFIG_GENERIC_NVRAM kludge in drivers/char/Makefile. Another reason is
> > that automatically loading the appropriate module would be impossible
> > because only one module can provide the char-major-10-144 alias.
> > 
> > A multi-platform kernel binary needs a single, generic module. With this
> > patch series, drivers/char/nvram.c becomes more generic and some of the
> > arch-specific code gets moved under arch/. The nvram module is then
> > usable by all m68k, powerpc and x86 platforms.
> > 
> > This allows for removal of drivers/char/generic_nvram.c as well as a
> > duplicate in arch/powerpc/kernel/nvram_64.c. By reducing the number of
> > /dev/nvram char misc device implementations, the number of bugs and
> > inconsistencies is also reduced.
> > 
> > This approach reduces inconsistencies between PPC32 and PPC64 and also
> > between PPC_PMAC and MAC. A uniform API has benefits for userspace.
> > 
> > For example, some error codes for some ioctl calls become consistent
> > across PowerPC platforms. The uniform API can potentially benefit any
> > bootloader that works across the various platforms having XPRAM
> > (e.g. Emile).
> > 
> > This patch series was tested on Atari, Mac, PowerMac (both 32-bit and
> > 64-bit) and ThinkPad hardware. AFAIK, it has not yet been tested on
> > pSeries or CHRP.
> > 
> > I think there are two possible merge strategies for this patch series.
> > The char misc maintainer could take the entire series. Alternatively,
> > the m68k maintainer could take patches 1 thru 16 (though some of these
> > have nothing to do with m68k) and after those patches reach mainline
> > the powerpc maintainer could take 17 thru 22.
> 
> I just took the whole series, thanks for doing this, looks good.
> 

Thanks, Greg.

I haven't seen any acks from powerpc maintainers yet...

-- 

> greg k-h
> 


[PATCH v9 19/22] powerpc, fbdev: Use NV_CMODE and NV_VMODE only when CONFIG_PPC32 && CONFIG_PPC_PMAC && CONFIG_NVRAM

2019-01-14 Thread Finn Thain
This patch addresses inconsistencies in Mac framebuffer drivers and their
use of Kconfig symbols relating to NVRAM, so PPC64 can use CONFIG_NVRAM.

The defined(CONFIG_NVRAM) condition is replaced with the weaker
IS_REACHABLE(CONFIG_NVRAM) condition, like atari_scsi.

Macintosh framebuffer drivers use default settings for color mode and
video mode that are found in NVRAM. On PCI Macs, MacOS stores display
settings in the Name Registry (NR) partition in NVRAM*. On NuBus Macs,
there is no NR partition and MacOS stores display mode settings in PRAM**.

Early-model Macs are the ones most likely to benefit from these settings,
since they are more likely to have a fixed-frequency monitor connected to
the built-in framebuffer device. Moreover, a single NV_CMODE value and
a single NV_VMODE value provide for only one display.

The NV_CMODE and NV_VMODE constants are apparently offsets into the NR
partition for Old World machines. This also suggests that these defaults
are not useful on later models. The NR partition seems to be optional on
New World machines. CONFIG_NVRAM cannot be enabled on PPC64 at present.

It is safe to say that NVRAM support in PowerMac fbdev drivers is only
applicable to CONFIG_PPC32 so make this condition explicit. This means
matroxfb driver won't crash on PPC64 when CONFIG_NVRAM becomes available
there.

For imsttfb, add the missing CONFIG_NVRAM test to prevent a build failure,
since PPC64 does not implement nvram_read_byte(). Also add a missing
machine_is(powermac) check. Change the inconsistent dependency on
CONFIG_PPC and the matching #ifdef tests to CONFIG_PPC_PMAC.

For valkyriefb, to improve clarity and consistency with the other PowerMac
fbdev drivers, test for CONFIG_PPC_PMAC instead of !CONFIG_MAC. Remove a
bogus comment regarding PRAM.

* See GetPreferredConfiguration and SavePreferredConfiguration in
"Designing PCI Cards and Drivers for Power Macintosh Computers".

** See SetDefaultMode and GetDefaultMode in "Designing Cards and Drivers
for the Macintosh Family".

Signed-off-by: Finn Thain 
---
Changed since v8:
 - Replaced defined(CONFIG_NVRAM) with IS_REACHABLE(CONFIG_NVRAM) as
suggested by James Bottomley.
 - Changed #ifdef to if as suggested by Christophe Leroy.
 - Expanded the patch to include controlfb.c and platinumfb.c due to the
conversion from '#if defined(CONFIG_NVRAM)' to
'if (IS_REACHABLE(CONFIG_NVRAM))'.
---
 drivers/video/fbdev/Kconfig|  2 +-
 drivers/video/fbdev/controlfb.c| 42 --
 drivers/video/fbdev/imsttfb.c  | 23 ++--
 drivers/video/fbdev/matrox/matroxfb_base.c |  5 +--
 drivers/video/fbdev/platinumfb.c   | 21 +--
 drivers/video/fbdev/valkyriefb.c   | 30 ++--
 6 files changed, 48 insertions(+), 75 deletions(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index ae7712c9687a..58a9590c9db6 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -536,7 +536,7 @@ config FB_IMSTT
bool "IMS Twin Turbo display support"
depends on (FB = y) && PCI
select FB_CFB_IMAGEBLIT
-   select FB_MACMODES if PPC
+   select FB_MACMODES if PPC_PMAC
help
  The IMS Twin Turbo is a PCI-based frame buffer card bundled with
  many Macintosh and compatible computers.
diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
index 9cb0ef7ac29e..7af8db28bb80 100644
--- a/drivers/video/fbdev/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
@@ -411,35 +411,23 @@ static int __init init_control(struct fb_info_control *p)
full = p->total_vram == 0x40;
 
/* Try to pick a video mode out of NVRAM if we have one. */
-#ifdef CONFIG_NVRAM
-   if (default_cmode == CMODE_NVRAM) {
+   cmode = default_cmode;
+   if (IS_REACHABLE(CONFIG_NVRAM) && cmode == CMODE_NVRAM)
cmode = nvram_read_byte(NV_CMODE);
-   if(cmode < CMODE_8 || cmode > CMODE_32)
-   cmode = CMODE_8;
-   } else
-#endif
-   cmode=default_cmode;
-#ifdef CONFIG_NVRAM
-   if (default_vmode == VMODE_NVRAM) {
+   if (cmode < CMODE_8 || cmode > CMODE_32)
+   cmode = CMODE_8;
+
+   vmode = default_vmode;
+   if (IS_REACHABLE(CONFIG_NVRAM) && vmode == VMODE_NVRAM)
vmode = nvram_read_byte(NV_VMODE);
-   if (vmode < 1 || vmode > VMODE_MAX ||
-   control_mac_modes[vmode - 1].m[full] < cmode) {
-   sense = read_control_sense(p);
-   printk("Monitor sense value = 0x%x, ", sense);
-   vmode = mac_map_monitor_sense(sense);
-   if (control_mac_modes[vmode - 1].m[full] < cmode)
-   vmode = VMODE_640_480_60;
-   }
-   } else
-#endif
-   {
- 

[PATCH v9 22/22] powerpc: Adopt nvram module for PPC64

2019-01-14 Thread Finn Thain
Adopt nvram module to reduce code duplication. This means CONFIG_NVRAM
becomes available to PPC64 builds. Previously it was only available to
PPC32 builds because it depended on CONFIG_GENERIC_NVRAM.

The IOC_NVRAM_GET_OFFSET ioctl as implemented on PPC64 validates the
offset returned by pmac_get_partition(). Do the same in the nvram module.

Note that the old PPC32 generic_nvram module lacked this test.
So when CONFIG_PPC32 && CONFIG_PPC_PMAC, the IOC_NVRAM_GET_OFFSET ioctl
would have returned 0 (always). But when CONFIG_PPC64 && CONFIG_PPC_PMAC,
the IOC_NVRAM_GET_OFFSET ioctl would have returned -1 (which is -EPERM)
when the requested partition was not found.

With this patch, the result is now -EINVAL on both PPC32 and PPC64 when
the requested PowerMac NVRAM partition is not found. This is a userspace-
visible change, in the non-existent partition case, which would be in
an error path for an IOC_NVRAM_GET_OFFSET ioctl syscall.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
BTW, the IOC_NVRAM_SYNC ioctl call returns an error on PPC64. This patch
retains this behaviour though it might be better to actually perform a sync
since both PPC64 and PPC32 do implement ppc_md.nvram_sync() for Core99.

Changed since v8:
 - Dropped the arch_nvram_ops struct in favour of equivalent ppc_md
method calls. Regardless of the actual implementation, the presence of
this functionality is indicated by CONFIG_HAVE_ARCH_NVRAM_OPS=y.

Changed since v7:
 - Dropped pointless comment edit.
---
 arch/powerpc/Kconfig |   2 +-
 arch/powerpc/kernel/nvram_64.c   | 158 +--
 arch/powerpc/platforms/powermac/Makefile |   2 -
 arch/powerpc/platforms/powermac/setup.c  |   2 +-
 arch/powerpc/platforms/powermac/time.c   |   2 +-
 arch/powerpc/platforms/pseries/nvram.c   |   2 -
 drivers/char/nvram.c |   4 +
 7 files changed, 9 insertions(+), 163 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f62e6a3f9c4e..621912365508 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -178,7 +178,7 @@ config PPC
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
-   select HAVE_ARCH_NVRAM_OPS  if PPC32
+   select HAVE_ARCH_NVRAM_OPS
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_CBPF_JITif !PPC64
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index 38b03a330cd2..244d2462e781 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -7,12 +7,6 @@
  *  2 of the License, or (at your option) any later version.
  *
  * /dev/nvram driver for PPC64
- *
- * This perhaps should live in drivers/char
- *
- * TODO: Split the /dev/nvram part (that one can use
- *   drivers/char/generic_nvram.c) from the arch & partition
- *   parsing code.
  */
 
 #include 
@@ -714,137 +708,6 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
spin_unlock_irqrestore(, flags);
 }
 
-static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   if (ppc_md.nvram_size == NULL)
-   return -ENODEV;
-   return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
-   ppc_md.nvram_size());
-}
-
-
-static ssize_t dev_nvram_read(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   if (!ppc_md.nvram_size) {
-   ret = -ENODEV;
-   goto out;
-   }
-
-   size = ppc_md.nvram_size();
-   if (size < 0) {
-   ret = size;
-   goto out;
-   }
-
-   if (*ppos >= size) {
-   ret = 0;
-   goto out;
-   }
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   tmp = kmalloc(count, GFP_KERNEL);
-   if (!tmp) {
-   ret = -ENOMEM;
-   goto out;
-   }
-
-   ret = ppc_md.nvram_read(tmp, count, ppos);
-   if (ret <= 0)
-   goto out;
-
-   if (copy_to_user(buf, tmp, ret))
-   ret = -EFAULT;
-
-out:
-   kfree(tmp);
-   return ret;
-
-}
-
-static ssize_t dev_nvram_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
-   ssize_t ret;
-   char *tmp = NULL;
-   ssize_t size;
-
-   ret = -ENODEV;
-   if (!ppc_md.nvram_size)
-   goto out;
-
-   ret = 0;
-   size = ppc_md.nvram_size();
-   if (*ppos >= size || size < 0)
-   goto out;
-
-   count = min_t(size_t, count, size - *ppos);
-   count = min(count, PAGE_SIZE);
-
-   tmp = memdup_user(buf, count);
-   if (IS_ERR(tmp)) 

[PATCH v9 15/22] m68k: Dispatch nvram_ops calls to Atari or Mac functions

2019-01-14 Thread Finn Thain
A multi-platform kernel binary has to decide at run-time how to dispatch
the arch_nvram_ops calls. Add a platform-independent arch_nvram_ops
struct for this, to replace the atari-specific one.

Enable CONFIG_HAVE_ARCH_NVRAM_OPS for Macs.

Acked-by: Geert Uytterhoeven 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
Changed since v8:
 - Adopted nvram_read_bytes() and nvram_write_bytes() where possible.
---
 arch/m68k/Kconfig.machine |  1 +
 arch/m68k/atari/nvram.c   | 21 ++--
 arch/m68k/include/asm/atarihw.h   |  6 +++
 arch/m68k/include/asm/macintosh.h |  4 ++
 arch/m68k/kernel/setup_mm.c   | 82 ++-
 arch/m68k/mac/misc.c  | 11 +
 6 files changed, 108 insertions(+), 17 deletions(-)

diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index ad584e3eb8f7..c01e103492fd 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -27,6 +27,7 @@ config MAC
bool "Macintosh support"
depends on MMU
select MMU_MOTOROLA if MMU
+   select HAVE_ARCH_NVRAM_OPS
help
  This option enables support for the Apple Macintosh series of
  computers (yes, there is experimental support now, at least for part
diff --git a/arch/m68k/atari/nvram.c b/arch/m68k/atari/nvram.c
index c347fd206ddf..7000d2443aa3 100644
--- a/arch/m68k/atari/nvram.c
+++ b/arch/m68k/atari/nvram.c
@@ -74,7 +74,7 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
-static long atari_nvram_set_checksum(void)
+long atari_nvram_set_checksum(void)
 {
spin_lock_irq(_lock);
__nvram_set_checksum();
@@ -82,7 +82,7 @@ static long atari_nvram_set_checksum(void)
return 0;
 }
 
-static long atari_nvram_initialize(void)
+long atari_nvram_initialize(void)
 {
loff_t i;
 
@@ -94,7 +94,7 @@ static long atari_nvram_initialize(void)
return 0;
 }
 
-static ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -112,7 +112,7 @@ static ssize_t atari_nvram_read(char *buf, size_t count, 
loff_t *ppos)
return p - buf;
 }
 
-static ssize_t atari_nvram_write(char *buf, size_t count, loff_t *ppos)
+ssize_t atari_nvram_write(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
loff_t i;
@@ -131,22 +131,11 @@ static ssize_t atari_nvram_write(char *buf, size_t count, 
loff_t *ppos)
return p - buf;
 }
 
-static ssize_t atari_nvram_get_size(void)
+ssize_t atari_nvram_get_size(void)
 {
-   if (!MACH_IS_ATARI)
-   return -ENODEV;
return NVRAM_BYTES;
 }
 
-const struct nvram_ops arch_nvram_ops = {
-   .read   = atari_nvram_read,
-   .write  = atari_nvram_write,
-   .get_size   = atari_nvram_get_size,
-   .set_checksum   = atari_nvram_set_checksum,
-   .initialize = atari_nvram_initialize,
-};
-EXPORT_SYMBOL(arch_nvram_ops);
-
 #ifdef CONFIG_PROC_FS
 static struct {
unsigned char val;
diff --git a/arch/m68k/include/asm/atarihw.h b/arch/m68k/include/asm/atarihw.h
index 9000b249d225..533008262b69 100644
--- a/arch/m68k/include/asm/atarihw.h
+++ b/arch/m68k/include/asm/atarihw.h
@@ -33,6 +33,12 @@ extern int atari_dont_touch_floppy_select;
 
 extern int atari_SCC_reset_done;
 
+extern ssize_t atari_nvram_read(char *, size_t, loff_t *);
+extern ssize_t atari_nvram_write(char *, size_t, loff_t *);
+extern ssize_t atari_nvram_get_size(void);
+extern long atari_nvram_set_checksum(void);
+extern long atari_nvram_initialize(void);
+
 /* convenience macros for testing machine type */
 #define MACH_IS_ST ((atari_mch_cookie >> 16) == ATARI_MCH_ST)
 #define MACH_IS_STE((atari_mch_cookie >> 16) == ATARI_MCH_STE && \
diff --git a/arch/m68k/include/asm/macintosh.h 
b/arch/m68k/include/asm/macintosh.h
index 08cee11180e6..d9a08bed4b12 100644
--- a/arch/m68k/include/asm/macintosh.h
+++ b/arch/m68k/include/asm/macintosh.h
@@ -19,6 +19,10 @@ extern void mac_init_IRQ(void);
 extern void mac_irq_enable(struct irq_data *data);
 extern void mac_irq_disable(struct irq_data *data);
 
+extern unsigned char mac_pram_read_byte(int);
+extern void mac_pram_write_byte(unsigned char, int);
+extern ssize_t mac_pram_get_size(void);
+
 /*
  * Macintosh Table
  */
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index ad0195cbe042..528484feff80 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -37,13 +38,14 @@
 #ifdef CONFIG_AMIGA
 #include 
 #endif
-#ifdef CONFIG_ATARI
 #include 
+#ifdef CONFIG_ATARI
 #include 
 #endif
 #ifdef CONFIG_SUN3X
 #include 
 #endif
+#include 
 #include 
 
 #if !FPSTATESIZE || !NR_IRQS
@@ -547,3 +549,81 @@ static int __init adb_probe_sync_enable (cha

[PATCH v9 17/22] powerpc: Define missing ppc_md.nvram_size for CHRP and PowerMac

2019-01-14 Thread Finn Thain
Add the nvram_size() function to those PowerPC platforms that don't already
have one: CHRP and PowerMac. This means that the ppc_md.nvram_size()
function can be called by nvram_get_size().

Since we are addressing CHRP inconsistencies here, rename chrp_nvram_read
and chrp_nvram_write, which break the naming convention used across
powerpc platforms for NVRAM accessor functions.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
Changed since v8:
 - Renamed functions to correspond with ppc_md member names.
---
 arch/powerpc/platforms/chrp/nvram.c | 14 ++
 arch/powerpc/platforms/powermac/nvram.c |  9 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/chrp/nvram.c 
b/arch/powerpc/platforms/chrp/nvram.c
index 791b86398e1d..37ac20ccbb19 100644
--- a/arch/powerpc/platforms/chrp/nvram.c
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -24,7 +24,7 @@ static unsigned int nvram_size;
 static unsigned char nvram_buf[4];
 static DEFINE_SPINLOCK(nvram_lock);
 
-static unsigned char chrp_nvram_read(int addr)
+static unsigned char chrp_nvram_read_val(int addr)
 {
unsigned int done;
unsigned long flags;
@@ -46,7 +46,7 @@ static unsigned char chrp_nvram_read(int addr)
return ret;
 }
 
-static void chrp_nvram_write(int addr, unsigned char val)
+static void chrp_nvram_write_val(int addr, unsigned char val)
 {
unsigned int done;
unsigned long flags;
@@ -64,6 +64,11 @@ static void chrp_nvram_write(int addr, unsigned char val)
spin_unlock_irqrestore(_lock, flags);
 }
 
+static ssize_t chrp_nvram_size(void)
+{
+   return nvram_size;
+}
+
 void __init chrp_nvram_init(void)
 {
struct device_node *nvram;
@@ -85,8 +90,9 @@ void __init chrp_nvram_init(void)
printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
of_node_put(nvram);
 
-   ppc_md.nvram_read_val = chrp_nvram_read;
-   ppc_md.nvram_write_val = chrp_nvram_write;
+   ppc_md.nvram_read_val  = chrp_nvram_read_val;
+   ppc_md.nvram_write_val = chrp_nvram_write_val;
+   ppc_md.nvram_size  = chrp_nvram_size;
 
return;
 }
diff --git a/arch/powerpc/platforms/powermac/nvram.c 
b/arch/powerpc/platforms/powermac/nvram.c
index ae54d7fe68f3..9360cdc408c1 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -147,6 +147,11 @@ static ssize_t core99_nvram_size(void)
 static volatile unsigned char __iomem *nvram_addr;
 static int nvram_mult;
 
+static ssize_t ppc32_nvram_size(void)
+{
+   return NVRAM_SIZE;
+}
+
 static unsigned char direct_nvram_read_byte(int addr)
 {
return in_8(_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
@@ -590,21 +595,25 @@ int __init pmac_nvram_init(void)
nvram_mult = 1;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 1) {
nvram_data = ioremap(r1.start, s1);
nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
ppc_md.nvram_read_val   = direct_nvram_read_byte;
ppc_md.nvram_write_val  = direct_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 2) {
nvram_addr = ioremap(r1.start, s1);
nvram_data = ioremap(r2.start, s2);
ppc_md.nvram_read_val   = indirect_nvram_read_byte;
ppc_md.nvram_write_val  = indirect_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
 #ifdef CONFIG_ADB_PMU
nvram_naddrs = -1;
ppc_md.nvram_read_val   = pmu_nvram_read_byte;
ppc_md.nvram_write_val  = pmu_nvram_write_byte;
+   ppc_md.nvram_size   = ppc32_nvram_size;
 #endif /* CONFIG_ADB_PMU */
} else {
printk(KERN_ERR "Incompatible type of NVRAM\n");
-- 
2.19.2



[PATCH v9 20/22] powerpc: Enable HAVE_ARCH_NVRAM_OPS and disable GENERIC_NVRAM

2019-01-14 Thread Finn Thain
Switch PPC32 kernels from the generic_nvram module to the nvram module.

Also fix a theoretical bug where CHRP omits the chrp_nvram_init() call
when CONFIG_NVRAM_MODULE=m.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
The change in the name of the module is visible to userspace. The module
that implements /dev/nvram on PowerPC now has suitable aliases, i.e.
MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
MODULE_ALIAS("devname:nvram");
so that the device special file can be automatically created and the
module automatically loaded when needed. Previously this was not the case.

Changed since v8:
 - Moved the HAVE_ARCH_NVRAM_OPS symbol to common code as suggested by
Christoph Hellwig.
 - Changed arch_nvram_ops method calls to ppc_md method calls.
 - Removed the now unused nvram_sync() export.

Changed since v7:
 - Improved Kconfig help text for CONFIG_NVRAM.
 - Changed the default for CONFIG_NVRAM, which used to be "n". This is to
reduce the risk that CONFIG_GENERIC_NVRAM=y accidentally gets changed to
CONFIG_NVRAM=n.
---
 arch/powerpc/Kconfig|  6 +-
 arch/powerpc/include/asm/nvram.h|  3 ---
 arch/powerpc/kernel/setup_32.c  | 11 ---
 arch/powerpc/platforms/chrp/Makefile|  2 +-
 arch/powerpc/platforms/chrp/setup.c |  2 +-
 arch/powerpc/platforms/powermac/setup.c |  3 +--
 drivers/char/Kconfig| 19 +--
 include/linux/nvram.h   | 20 
 8 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2890d36eb531..f62e6a3f9c4e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -178,6 +178,7 @@ config PPC
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
+   select HAVE_ARCH_NVRAM_OPS  if PPC32
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_CBPF_JITif !PPC64
@@ -274,11 +275,6 @@ config SYSVIPC_COMPAT
depends on COMPAT && SYSVIPC
default y
 
-# All PPC32s use generic nvram driver through ppc_md
-config GENERIC_NVRAM
-   bool
-   default y if PPC32
-
 config SCHED_OMIT_FRAME_POINTER
bool
default y
diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h
index 56a388da9c4f..629a5cdcc865 100644
--- a/arch/powerpc/include/asm/nvram.h
+++ b/arch/powerpc/include/asm/nvram.h
@@ -78,9 +78,6 @@ extern intpmac_get_partition(int partition);
 extern u8  pmac_xpram_read(int xpaddr);
 extern voidpmac_xpram_write(int xpaddr, u8 data);
 
-/* Synchronize NVRAM */
-extern voidnvram_sync(void);
-
 /* Initialize NVRAM OS partition */
 extern int __init nvram_init_os_partition(struct nvram_os_partition *part);
 
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index f5107796e2d7..c31082233a25 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -148,17 +148,6 @@ static int __init ppc_setup_l3cr(char *str)
 }
 __setup("l3cr=", ppc_setup_l3cr);
 
-#ifdef CONFIG_GENERIC_NVRAM
-
-void nvram_sync(void)
-{
-   if (ppc_md.nvram_sync)
-   ppc_md.nvram_sync();
-}
-EXPORT_SYMBOL(nvram_sync);
-
-#endif /* CONFIG_NVRAM */
-
 static int __init ppc_init(void)
 {
/* clear the progress line */
diff --git a/arch/powerpc/platforms/chrp/Makefile 
b/arch/powerpc/platforms/chrp/Makefile
index 4b3bfadc70fa..dc3465cc8bc6 100644
--- a/arch/powerpc/platforms/chrp/Makefile
+++ b/arch/powerpc/platforms/chrp/Makefile
@@ -1,3 +1,3 @@
 obj-y  += setup.o time.o pegasos_eth.o pci.o
 obj-$(CONFIG_SMP)  += smp.o
-obj-$(CONFIG_NVRAM)+= nvram.o
+obj-$(CONFIG_NVRAM:m=y)+= nvram.o
diff --git a/arch/powerpc/platforms/chrp/setup.c 
b/arch/powerpc/platforms/chrp/setup.c
index e66644e0fb40..e8e804289c8e 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -550,7 +550,7 @@ static void __init chrp_init_IRQ(void)
 static void __init
 chrp_init2(void)
 {
-#ifdef CONFIG_NVRAM
+#if IS_ENABLED(CONFIG_NVRAM)
chrp_nvram_init();
 #endif
 
diff --git a/arch/powerpc/platforms/powermac/setup.c 
b/arch/powerpc/platforms/powermac/setup.c
index 2e8221e20ee8..b47f49cf9c4d 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -316,8 +316,7 @@ static void __init pmac_setup_arch(void)
find_via_pmu();
smu_init();
 
-#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
-defined(CONFIG_PPC64)
+#if IS_ENABLED(CONFIG_NVRAM) || defined(CONFIG_PPC64)
pmac_nvram_init();
 #endif
 #ifdef CONFIG_PPC32
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index ce9979529cf3..72866a004f07 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -244,25 +244,24 @@ 

[PATCH v9 21/22] char/generic_nvram: Remove as unused

2019-01-14 Thread Finn Thain
Signed-off-by: Finn Thain 
---
 drivers/char/Makefile|   6 +-
 drivers/char/generic_nvram.c | 160 ---
 2 files changed, 1 insertion(+), 165 deletions(-)
 delete mode 100644 drivers/char/generic_nvram.c

diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index b8d42b4e979b..fbea7dd12932 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -26,11 +26,7 @@ obj-$(CONFIG_RTC)+= rtc.o
 obj-$(CONFIG_HPET) += hpet.o
 obj-$(CONFIG_EFI_RTC)  += efirtc.o
 obj-$(CONFIG_XILINX_HWICAP)+= xilinx_hwicap/
-ifeq ($(CONFIG_GENERIC_NVRAM),y)
-  obj-$(CONFIG_NVRAM)  += generic_nvram.o
-else
-  obj-$(CONFIG_NVRAM)  += nvram.o
-endif
+obj-$(CONFIG_NVRAM)+= nvram.o
 obj-$(CONFIG_TOSHIBA)  += toshiba.o
 obj-$(CONFIG_DS1620)   += ds1620.o
 obj-$(CONFIG_HW_RANDOM)+= hw_random/
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
deleted file mode 100644
index 0c22b9503e84..
--- a/drivers/char/generic_nvram.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Generic /dev/nvram driver for architectures providing some
- * "generic" hooks, that is :
- *
- * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size
- *
- * Note that an additional hook is supported for PowerMac only
- * for getting the nvram "partition" informations
- *
- */
-
-#define NVRAM_VERSION "1.1"
-
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#ifdef CONFIG_PPC_PMAC
-#include 
-#endif
-
-#define NVRAM_SIZE 8192
-
-static DEFINE_MUTEX(nvram_mutex);
-static ssize_t nvram_len;
-
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
-{
-   return generic_file_llseek_size(file, offset, origin,
-   MAX_LFS_FILESIZE, nvram_len);
-}
-
-static ssize_t read_nvram(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   char __user *p = buf;
-
-   if (!access_ok(buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
-   if (__put_user(nvram_read_byte(i), p))
-   return -EFAULT;
-   *ppos = i;
-   return p - buf;
-}
-
-static ssize_t write_nvram(struct file *file, const char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   unsigned int i;
-   const char __user *p = buf;
-   char c;
-
-   if (!access_ok(buf, count))
-   return -EFAULT;
-   if (*ppos >= nvram_len)
-   return 0;
-   for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
-   if (__get_user(c, p))
-   return -EFAULT;
-   nvram_write_byte(c, i);
-   }
-   *ppos = i;
-   return p - buf;
-}
-
-static int nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-   switch(cmd) {
-#ifdef CONFIG_PPC_PMAC
-   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
-   printk(KERN_WARNING "nvram: Using obsolete 
PMAC_NVRAM_GET_OFFSET ioctl\n");
-   case IOC_NVRAM_GET_OFFSET: {
-   int part, offset;
-
-   if (!machine_is(powermac))
-   return -EINVAL;
-   if (copy_from_user(, (void __user*)arg, sizeof(part)) != 0)
-   return -EFAULT;
-   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
-   return -EINVAL;
-   offset = pmac_get_partition(part);
-   if (copy_to_user((void __user*)arg, , sizeof(offset)) != 
0)
-   return -EFAULT;
-   break;
-   }
-#endif /* CONFIG_PPC_PMAC */
-   case IOC_NVRAM_SYNC:
-   nvram_sync();
-   break;
-   default:
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
-static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned 
long arg)
-{
-   int ret;
-
-   mutex_lock(_mutex);
-   ret = nvram_ioctl(file, cmd, arg);
-   mutex_unlock(_mutex);
-
-   return ret;
-}
-
-const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = read_nvram,
-   .write  = write_nvram,
-   .unlocked_ioctl = nvram_unlocked_ioctl,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   _fops
-};
-
-int __init nvram_init(void)
-{
-   int ret = 0;
-
-   printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
-   NVRAM_VERSION);
-   ret = misc_register(_dev);
-   if (ret != 0)
-   goto out;
-
-  

[PATCH v9 18/22] powerpc: Implement nvram ioctls

2019-01-14 Thread Finn Thain
Add the powerpc-specific ioctls to the nvram module. This allows the nvram
module to replace the generic_nvram module.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
On PPC32, the IOC_NVRAM_SYNC ioctl call always returns 0, even for those
platforms that don't implement ppc_md.nvram_sync. This patch retains
that quirk. It may be better to return an error (which is what PPC64 does).

Changed since v8:
 - Changed #else to fully specified #elif conditional.
 - Changed arch_nvram_ops method calls to ppc_md method calls.
---
 drivers/char/nvram.c  | 38 ++
 include/linux/nvram.h |  2 ++
 2 files changed, 40 insertions(+)

diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index c9e295d73dc5..944f05fddacd 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -48,6 +48,9 @@
 #include 
 #include 
 
+#ifdef CONFIG_PPC
+#include 
+#endif
 
 static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
@@ -283,6 +286,38 @@ static long nvram_misc_ioctl(struct file *file, unsigned 
int cmd,
long ret = -ENOTTY;
 
switch (cmd) {
+#ifdef CONFIG_PPC
+   case OBSOLETE_PMAC_NVRAM_GET_OFFSET:
+   pr_warn("nvram: Using obsolete PMAC_NVRAM_GET_OFFSET ioctl\n");
+   /* fall through */
+   case IOC_NVRAM_GET_OFFSET:
+   ret = -EINVAL;
+#ifdef CONFIG_PPC_PMAC
+   if (machine_is(powermac)) {
+   int part, offset;
+
+   if (copy_from_user(, (void __user *)arg,
+  sizeof(part)) != 0)
+   return -EFAULT;
+   if (part < pmac_nvram_OF || part > pmac_nvram_NR)
+   return -EINVAL;
+   offset = pmac_get_partition(part);
+   if (copy_to_user((void __user *)arg,
+, sizeof(offset)) != 0)
+   return -EFAULT;
+   ret = 0;
+   }
+#endif
+   break;
+   case IOC_NVRAM_SYNC:
+   if (ppc_md.nvram_sync != NULL) {
+   mutex_lock(_mutex);
+   ppc_md.nvram_sync();
+   mutex_unlock(_mutex);
+   }
+   ret = 0;
+   break;
+#elif defined(CONFIG_X86) || defined(CONFIG_M68K)
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
@@ -306,6 +341,7 @@ static long nvram_misc_ioctl(struct file *file, unsigned 
int cmd,
mutex_unlock(_mutex);
}
break;
+#endif /* CONFIG_X86 || CONFIG_M68K */
}
return ret;
 }
@@ -321,12 +357,14 @@ static int nvram_misc_open(struct inode *inode, struct 
file *file)
return -EBUSY;
}
 
+#if defined(CONFIG_X86) || defined(CONFIG_M68K)
/* Prevent multiple writers if the set_checksum ioctl is implemented. */
if ((arch_nvram_ops.set_checksum != NULL) &&
(file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE)) {
spin_unlock(_state_lock);
return -EBUSY;
}
+#endif
 
if (file->f_flags & O_EXCL)
nvram_open_mode |= NVRAM_EXCL;
diff --git a/include/linux/nvram.h b/include/linux/nvram.h
index 9df85703735c..9e3a957c8f1f 100644
--- a/include/linux/nvram.h
+++ b/include/linux/nvram.h
@@ -31,8 +31,10 @@ struct nvram_ops {
void(*write_byte)(unsigned char, int);
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_t *);
+#if defined(CONFIG_X86) || defined(CONFIG_M68K)
long(*initialize)(void);
long(*set_checksum)(void);
+#endif
 };
 
 extern const struct nvram_ops arch_nvram_ops;
-- 
2.19.2



[PATCH v9 13/22] m68k/mac: Fix PRAM accessors

2019-01-14 Thread Finn Thain
PMU-based m68k Macs pre-date PowerMac-style NVRAM. Use the appropriate
PMU commands. Also implement the missing XPRAM accessors for VIA-based
Macs.

Acked-by: Geert Uytterhoeven 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
Changed since v7:
 - Revised PMU response decoding due to via-pmu68k driver replacement.
---
 arch/m68k/mac/misc.c | 43 ++--
 include/uapi/linux/pmu.h |  2 ++
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index af000a015f68..d016ca2e0d10 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -66,23 +66,22 @@ static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
 
-   if (pmu_request(, NULL, 3, PMU_READ_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF) < 0)
+   if (pmu_request(, NULL, 3, PMU_READ_XPRAM,
+   offset & 0xFF, 1) < 0)
return 0;
-   while (!req.complete)
-   pmu_poll();
-   return req.reply[3];
+   pmu_wait_complete();
+
+   return req.reply[0];
 }
 
 static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
 
-   if (pmu_request(, NULL, 4, PMU_WRITE_NVRAM,
-   (offset >> 8) & 0xFF, offset & 0xFF, data) < 0)
+   if (pmu_request(, NULL, 4, PMU_WRITE_XPRAM,
+   offset & 0xFF, 1, data) < 0)
return;
-   while (!req.complete)
-   pmu_poll();
+   pmu_wait_complete();
 }
 #endif /* CONFIG_ADB_PMU */
 
@@ -151,6 +150,16 @@ static void via_rtc_send(__u8 data)
 #define RTC_REG_SECONDS_3   3
 #define RTC_REG_WRITE_PROTECT   13
 
+/*
+ * Inside Mac has no information about two-byte RTC commands but
+ * the MAME/MESS source code has the essentials.
+ */
+
+#define RTC_REG_XPRAM   14
+#define RTC_CMD_XPRAM_READ  (RTC_CMD_READ(RTC_REG_XPRAM) << 8)
+#define RTC_CMD_XPRAM_WRITE (RTC_CMD_WRITE(RTC_REG_XPRAM) << 8)
+#define RTC_CMD_XPRAM_ARG(a)(((a & 0xE0) << 3) | ((a & 0x1F) << 2))
+
 /*
  * Execute a VIA PRAM/RTC command. For read commands
  * data should point to a one-byte buffer for the
@@ -198,11 +207,25 @@ static void via_rtc_command(int command, __u8 *data)
 
 static unsigned char via_pram_read_byte(int offset)
 {
-   return 0;
+   unsigned char temp;
+
+   via_rtc_command(RTC_CMD_XPRAM_READ | RTC_CMD_XPRAM_ARG(offset), );
+
+   return temp;
 }
 
 static void via_pram_write_byte(unsigned char data, int offset)
 {
+   unsigned char temp;
+
+   temp = 0x55;
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), );
+
+   temp = data;
+   via_rtc_command(RTC_CMD_XPRAM_WRITE | RTC_CMD_XPRAM_ARG(offset), );
+
+   temp = 0x55 | RTC_FLG_WRITE_PROTECT;
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), );
 }
 
 /*
diff --git a/include/uapi/linux/pmu.h b/include/uapi/linux/pmu.h
index 97256f90e6df..f2fc1bd80017 100644
--- a/include/uapi/linux/pmu.h
+++ b/include/uapi/linux/pmu.h
@@ -19,7 +19,9 @@
 #define PMU_POWER_CTRL 0x11/* control power of some devices */
 #define PMU_ADB_CMD0x20/* send ADB packet */
 #define PMU_ADB_POLL_OFF   0x21/* disable ADB auto-poll */
+#define PMU_WRITE_XPRAM0x32/* write eXtended Parameter RAM 
*/
 #define PMU_WRITE_NVRAM0x33/* write non-volatile RAM */
+#define PMU_READ_XPRAM 0x3a/* read eXtended Parameter RAM */
 #define PMU_READ_NVRAM 0x3b/* read non-volatile RAM */
 #define PMU_SET_RTC0x30/* set real-time clock */
 #define PMU_READ_RTC   0x38/* read real-time clock */
-- 
2.19.2



[PATCH v9 16/22] char/nvram: Add "devname:nvram" module alias

2019-01-14 Thread Finn Thain
Signed-off-by: Finn Thain 
---
 drivers/char/nvram.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index adcc213c331e..c9e295d73dc5 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -503,3 +503,4 @@ module_exit(nvram_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
+MODULE_ALIAS("devname:nvram");
-- 
2.19.2



[PATCH v9 08/22] char/nvram: Allow the set_checksum and initialize ioctls to be omitted

2019-01-14 Thread Finn Thain
The drivers/char/nvram.c module has previously supported only RTC "CMOS"
NVRAM, for which it provides appropriate checksum ioctls. Make these
ioctls optional so the module can be re-used with other kinds of NVRAM.

The ops struct methods that implement the ioctls now return error
codes so that a multi-platform kernel binary can do the right thing when
running on hardware without a suitable NVRAM.

Signed-off-by: Finn Thain 
---
Changed since v8:
 - Renamed nvram_* functions to avoid name collisions.
---
 drivers/char/nvram.c  | 70 ---
 include/linux/nvram.h |  2 ++
 2 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 2df391f78986..f88ef41d0598 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -136,16 +136,25 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
 }
 
-#if 0
-void nvram_set_checksum(void)
+static long pc_nvram_set_checksum(void)
 {
-   unsigned long flags;
+   spin_lock_irq(_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(_lock);
+   return 0;
+}
 
-   spin_lock_irqsave(_lock, flags);
+static long pc_nvram_initialize(void)
+{
+   ssize_t i;
+
+   spin_lock_irq(_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
__nvram_set_checksum();
-   spin_unlock_irqrestore(_lock, flags);
+   spin_unlock_irq(_lock);
+   return 0;
 }
-#endif  /*  0  */
 
 static ssize_t pc_nvram_get_size(void)
 {
@@ -156,6 +165,8 @@ const struct nvram_ops arch_nvram_ops = {
.read_byte  = pc_nvram_read_byte,
.write_byte = pc_nvram_write_byte,
.get_size   = pc_nvram_get_size,
+   .set_checksum   = pc_nvram_set_checksum,
+   .initialize = pc_nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 #endif /* CONFIG_X86 */
@@ -241,51 +252,50 @@ static ssize_t nvram_misc_write(struct file *file, const 
char __user *buf,
 static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
 unsigned long arg)
 {
-   int i;
+   long ret = -ENOTTY;
 
switch (cmd) {
-
case NVRAM_INIT:
/* initialize NVRAM contents and checksum */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(_mutex);
-   spin_lock_irq(_lock);
-
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   __nvram_write_byte(0, i);
-   __nvram_set_checksum();
-
-   spin_unlock_irq(_lock);
-   mutex_unlock(_mutex);
-   return 0;
-
+   if (arch_nvram_ops.initialize != NULL) {
+   mutex_lock(_mutex);
+   ret = arch_nvram_ops.initialize();
+   mutex_unlock(_mutex);
+   }
+   break;
case NVRAM_SETCKS:
/* just set checksum, contents unchanged (maybe useful after
 * checksum garbaged somehow...) */
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   mutex_lock(_mutex);
-   spin_lock_irq(_lock);
-   __nvram_set_checksum();
-   spin_unlock_irq(_lock);
-   mutex_unlock(_mutex);
-   return 0;
-
-   default:
-   return -ENOTTY;
+   if (arch_nvram_ops.set_checksum != NULL) {
+   mutex_lock(_mutex);
+   ret = arch_nvram_ops.set_checksum();
+   mutex_unlock(_mutex);
+   }
+   break;
}
+   return ret;
 }
 
 static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(_state_lock);
 
+   /* Prevent multiple readers/writers if desired. */
if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
-   (nvram_open_mode & NVRAM_EXCL) ||
-   ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
+   (nvram_open_mode & NVRAM_EXCL)) {
+   spin_unlock(_state_lock);
+   return -EBUSY;
+   }
+
+   /* Prevent multiple writers if the set_checksum ioctl is implemented. */
+   if ((arch_nvram_ops.set_checksum != NULL) &&
+   (file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE)) {
spin_unlock(_state_lock);
return -EBUSY;
}
diff --git a/include/linux/nvram.h b/include/linux/nvram.h
index bb4ea8cc6ea6..31c763087746 100644
--- a/include/linux/nvram.h
+++ b/include/linux/nvram.h
@@ -31,6 +31,8 @@ struct nvram_ops {
void(*write_byte)(unsigned char, int);
ssize_t (*read)(char *, size_t, loff_t *);
ssize_t (*write)(char *, size_t, loff_

[PATCH v9 14/22] macintosh/via-cuda: Don't rely on Cuda to end a transfer

2019-01-14 Thread Finn Thain
Certain Cuda transfers have to be ended by the driver. According
to Apple's open source Cuda driver, as found in mkLinux and XNU, this
applies to any "open ended request such as PRAM read". This fixes an
infinite polling loop in cuda_pram_read_byte().

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 drivers/macintosh/via-cuda.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index bbec6ac0a966..3581abfb0c6a 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -569,6 +569,7 @@ cuda_interrupt(int irq, void *arg)
 unsigned char ibuf[16];
 int ibuf_len = 0;
 int complete = 0;
+bool full;
 
 spin_lock_irqsave(_lock, flags);
 
@@ -656,12 +657,13 @@ cuda_interrupt(int irq, void *arg)
break;
 
 case reading:
-   if (reading_reply ? ARRAY_FULL(current_req->reply, reply_ptr)
- : ARRAY_FULL(cuda_rbuf, reply_ptr))
+   full = reading_reply ? ARRAY_FULL(current_req->reply, reply_ptr)
+: ARRAY_FULL(cuda_rbuf, reply_ptr);
+   if (full)
(void)in_8([SR]);
else
*reply_ptr++ = in_8([SR]);
-   if (!TREQ_asserted(status)) {
+   if (!TREQ_asserted(status) || full) {
if (mcu_is_egret)
assert_TACK();
/* that's all folks */
-- 
2.19.2



[PATCH v9 11/22] m68k/mac: Adopt naming and calling conventions for PRAM routines

2019-01-14 Thread Finn Thain
Adopt the existing *_read_byte and *_write_byte naming convention.
Rename via_pram_readbyte and via_pram_writebyte to avoid confusion.
Adjust calling conventions of mac_pram_* functions to match the
struct nvram_ops methods.

Acked-by: Geert Uytterhoeven 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
Changed since v7:
 - Removed some gratuitous function pointers.
---
 arch/m68k/mac/misc.c | 61 +---
 1 file changed, 23 insertions(+), 38 deletions(-)

diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index 71c4735a31ee..78c807025436 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -37,7 +37,7 @@
 static void (*rom_reset)(void);
 
 #ifdef CONFIG_ADB_CUDA
-static __u8 cuda_read_pram(int offset)
+static unsigned char cuda_pram_read_byte(int offset)
 {
struct adb_request req;
 
@@ -49,7 +49,7 @@ static __u8 cuda_read_pram(int offset)
return req.reply[3];
 }
 
-static void cuda_write_pram(int offset, __u8 data)
+static void cuda_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
 
@@ -62,7 +62,7 @@ static void cuda_write_pram(int offset, __u8 data)
 #endif /* CONFIG_ADB_CUDA */
 
 #ifdef CONFIG_ADB_PMU
-static __u8 pmu_read_pram(int offset)
+static unsigned char pmu_pram_read_byte(int offset)
 {
struct adb_request req;
 
@@ -74,7 +74,7 @@ static __u8 pmu_read_pram(int offset)
return req.reply[3];
 }
 
-static void pmu_write_pram(int offset, __u8 data)
+static void pmu_pram_write_byte(unsigned char data, int offset)
 {
struct adb_request req;
 
@@ -93,7 +93,7 @@ static void pmu_write_pram(int offset, __u8 data)
  * the RTC should be enabled.
  */
 
-static __u8 via_pram_readbyte(void)
+static __u8 via_rtc_recv(void)
 {
int i, reg;
__u8 data;
@@ -120,7 +120,7 @@ static __u8 via_pram_readbyte(void)
return data;
 }
 
-static void via_pram_writebyte(__u8 data)
+static void via_rtc_send(__u8 data)
 {
int i, reg, bit;
 
@@ -157,17 +157,17 @@ static void via_pram_command(int command, __u8 *data)
via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb;
 
if (command & 0xFF00) { /* extended (two-byte) command */
-   via_pram_writebyte((command & 0xFF00) >> 8);
-   via_pram_writebyte(command & 0xFF);
+   via_rtc_send((command & 0xFF00) >> 8);
+   via_rtc_send(command & 0xFF);
is_read = command & 0x8000;
} else {/* one-byte command */
-   via_pram_writebyte(command);
+   via_rtc_send(command);
is_read = command & 0x80;
}
if (is_read) {
-   *data = via_pram_readbyte();
+   *data = via_rtc_recv();
} else {
-   via_pram_writebyte(*data);
+   via_rtc_send(*data);
}
 
/* All done, disable the RTC */
@@ -177,12 +177,12 @@ static void via_pram_command(int command, __u8 *data)
local_irq_restore(flags);
 }
 
-static __u8 via_read_pram(int offset)
+static unsigned char via_pram_read_byte(int offset)
 {
return 0;
 }
 
-static void via_write_pram(int offset, __u8 data)
+static void via_pram_write_byte(unsigned char data, int offset)
 {
 }
 
@@ -326,63 +326,48 @@ static void cuda_shutdown(void)
  *---
  */
 
-void mac_pram_read(int offset, __u8 *buffer, int len)
+unsigned char mac_pram_read_byte(int addr)
 {
-   __u8 (*func)(int);
-   int i;
-
switch (macintosh_config->adb_type) {
case MAC_ADB_IOP:
case MAC_ADB_II:
case MAC_ADB_PB1:
-   func = via_read_pram;
-   break;
+   return via_pram_read_byte(addr);
 #ifdef CONFIG_ADB_CUDA
case MAC_ADB_EGRET:
case MAC_ADB_CUDA:
-   func = cuda_read_pram;
-   break;
+   return cuda_pram_read_byte(addr);
 #endif
 #ifdef CONFIG_ADB_PMU
case MAC_ADB_PB2:
-   func = pmu_read_pram;
-   break;
+   return pmu_pram_read_byte(addr);
 #endif
default:
-   return;
-   }
-   for (i = 0 ; i < len ; i++) {
-   buffer[i] = (*func)(offset++);
+   return 0xFF;
}
 }
 
-void mac_pram_write(int offset, __u8 *buffer, int len)
+void mac_pram_write_byte(unsigned char val, int addr)
 {
-   void (*func)(int, __u8);
-   int i;
-
switch (macintosh_config->adb_type) {
case MAC_ADB_IOP:
case MAC_ADB_II:
case MAC_ADB_PB1:
-   func = via_write_pram;
+   via_pram_write_byte(val, addr);
break;
 #ifdef CONFIG_ADB_CUDA
case MAC_ADB_EGRET:
case MAC_ADB_CUDA:
-   func = cuda_write_pram;
+   cuda_pram_write_byte(val, addr);
 

[PATCH v9 09/22] char/nvram: Implement NVRAM read/write methods

2019-01-14 Thread Finn Thain
Refactor the RTC "CMOS" NVRAM functions so that they can be used as
arch_nvram_ops methods. Checksumming logic is moved from the misc device
operations to the nvram read/write operations. This makes the misc device
implementation more generic.

This preserves the locking mechanism such that "read if checksum valid"
and "write and update checksum" remain atomic operations.

Some platforms implement byte-range read/write methods which are similar
to file_operations struct methods. Other platforms provide only
byte-at-a-time methods. The former are more efficient but may be
unavailable so fall back on the latter methods when necessary.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
Changed since v8:
 - Renamed nvram_* functions to avoid name collisions.
 - Added nvram_read_bytes() and nvram_write_bytes() helpers for use by
those platforms which access NVRAM only one-byte-at-a-time.

Changed since v7:
 - Adopted memdup_user(), like arch/powerpc/kernel/nvram_64.c.
---
 drivers/char/nvram.c  | 120 ++
 include/linux/nvram.h |  32 ++-
 2 files changed, 104 insertions(+), 48 deletions(-)

diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index f88ef41d0598..adcc213c331e 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -41,6 +41,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -161,7 +162,46 @@ static ssize_t pc_nvram_get_size(void)
return NVRAM_BYTES;
 }
 
+static ssize_t pc_nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+   spin_unlock_irq(_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t pc_nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
 const struct nvram_ops arch_nvram_ops = {
+   .read   = pc_nvram_read,
+   .write  = pc_nvram_write,
.read_byte  = pc_nvram_read_byte,
.write_byte = pc_nvram_write_byte,
.get_size   = pc_nvram_get_size,
@@ -184,69 +224,57 @@ static loff_t nvram_misc_llseek(struct file *file, loff_t 
offset, int origin)
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,
   size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   spin_lock_irq(_lock);
+   char *tmp;
+   ssize_t ret;
 
-   if (!__nvram_check_checksum())
-   goto checksum_err;
 
-   for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
-   *tmp = __nvram_read_byte(i);
+   if (!access_ok(buf, count))
+   return -EFAULT;
+   if (*ppos >= nvram_size)
+   return 0;
 
-   spin_unlock_irq(_lock);
+   count = min_t(size_t, count, nvram_size - *ppos);
+   count = min_t(size_t, count, PAGE_SIZE);
 
-   if (copy_to_user(buf, contents, tmp - contents))
-   return -EFAULT;
+   tmp = kmalloc(count, GFP_KERNEL);
+   if (!tmp)
+   return -ENOMEM;
 
-   *ppos = i;
+   ret = nvram_read(tmp, count, ppos);
+   if (ret <= 0)
+   goto out;
 
-   return tmp - contents;
+   if (copy_to_user(buf, tmp, ret)) {
+   *ppos -= ret;
+   ret = -EFAULT;
+   }
 
-checksum_err:
-   spin_unlock_irq(_lock);
-   return -EIO;
+out:
+   kfree(tmp);
+   return ret;
 }
 
 static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
 {
-   unsigned char contents[NVRAM_BYTES];
-   unsigned i = *ppos;
-   unsigned char *tmp;
-
-   if (i >= NVRAM_BYTES)
-   return 0;   /* Past EOF */
-
-   if (count > NVRAM_BYTES - i)
-   count = NVRAM_BYTES - i;
-   if (count > NVRAM_BYTES)
-   return -EFAULT; /* Can't happen, but prove it to gcc */
+   char *tmp;
+   ssize_t ret;
 
-   if (copy_from_user(contents, buf, count))
+   if (!access_ok(buf, count))
return -EFAULT;
+   if (*ppos >= nvram_size)
+   return 0;
 
-   spin_l

[PATCH v9 10/22] m68k/atari: Implement arch_nvram_ops methods and enable CONFIG_HAVE_ARCH_NVRAM_OPS

2019-01-14 Thread Finn Thain
Atari RTC NVRAM uses a checksum so implement the remaining arch_nvram_ops
methods for the set_checksum and initialize ioctls. Enable
CONFIG_HAVE_ARCH_NVRAM_OPS.

Acked-by: Geert Uytterhoeven 
Signed-off-by: Finn Thain 
---
Changed since v8:
 - Moved the HAVE_ARCH_NVRAM_OPS symbol to common code as suggested by
Christoph Hellwig.
 - Renamed functions to avoid name collisions with nvram.h.

Changed since v7:
 - Changed the default for CONFIG_NVRAM, because "select NVRAM" was
removed from ATARI_SCSI in patch 1.
---
 arch/Kconfig  |  3 +++
 arch/m68k/Kconfig.machine |  1 +
 arch/m68k/atari/nvram.c   | 24 
 drivers/char/Kconfig  |  3 ++-
 4 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 4cfb6de48f79..87393fb8141c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -701,6 +701,9 @@ config HAVE_ARCH_HASH
  file which provides platform-specific implementations of some
  functions in  or fs/namei.c.
 
+config HAVE_ARCH_NVRAM_OPS
+   bool
+
 config ISA_BUS_API
def_bool ISA
 
diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index 328ba83d735b..ad584e3eb8f7 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -16,6 +16,7 @@ config ATARI
bool "Atari support"
depends on MMU
select MMU_MOTOROLA if MMU
+   select HAVE_ARCH_NVRAM_OPS
help
  This option enables support for the 68000-based Atari series of
  computers (including the TT, Falcon and Medusa). If you plan to use
diff --git a/arch/m68k/atari/nvram.c b/arch/m68k/atari/nvram.c
index e75adebe6e7d..c347fd206ddf 100644
--- a/arch/m68k/atari/nvram.c
+++ b/arch/m68k/atari/nvram.c
@@ -74,6 +74,26 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static long atari_nvram_set_checksum(void)
+{
+   spin_lock_irq(_lock);
+   __nvram_set_checksum();
+   spin_unlock_irq(_lock);
+   return 0;
+}
+
+static long atari_nvram_initialize(void)
+{
+   loff_t i;
+
+   spin_lock_irq(_lock);
+   for (i = 0; i < NVRAM_BYTES; ++i)
+   __nvram_write_byte(0, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(_lock);
+   return 0;
+}
+
 static ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
 {
char *p = buf;
@@ -113,6 +133,8 @@ static ssize_t atari_nvram_write(char *buf, size_t count, 
loff_t *ppos)
 
 static ssize_t atari_nvram_get_size(void)
 {
+   if (!MACH_IS_ATARI)
+   return -ENODEV;
return NVRAM_BYTES;
 }
 
@@ -120,6 +142,8 @@ const struct nvram_ops arch_nvram_ops = {
.read   = atari_nvram_read,
.write  = atari_nvram_write,
.get_size   = atari_nvram_get_size,
+   .set_checksum   = atari_nvram_set_checksum,
+   .initialize = atari_nvram_initialize,
 };
 EXPORT_SYMBOL(arch_nvram_ops);
 
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index a8cac68de177..ce9979529cf3 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -244,7 +244,8 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on X86 || GENERIC_NVRAM
+   depends on X86 || GENERIC_NVRAM || HAVE_ARCH_NVRAM_OPS
+   default M68K
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
-- 
2.19.2



[PATCH v9 12/22] m68k/mac: Use macros for RTC accesses not magic numbers

2019-01-14 Thread Finn Thain
This is intended to improve code style and not affect code behaviour.

Acked-by: Geert Uytterhoeven 
Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
 arch/m68k/mac/misc.c | 59 ++--
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index 78c807025436..af000a015f68 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -136,6 +136,21 @@ static void via_rtc_send(__u8 data)
}
 }
 
+/*
+ * These values can be found in Inside Macintosh vol. III ch. 2
+ * which has a description of the RTC chip in the original Mac.
+ */
+
+#define RTC_FLG_READBIT(7)
+#define RTC_FLG_WRITE_PROTECT   BIT(7)
+#define RTC_CMD_READ(r) (RTC_FLG_READ | (r << 2))
+#define RTC_CMD_WRITE(r)(r << 2)
+#define RTC_REG_SECONDS_0   0
+#define RTC_REG_SECONDS_1   1
+#define RTC_REG_SECONDS_2   2
+#define RTC_REG_SECONDS_3   3
+#define RTC_REG_WRITE_PROTECT   13
+
 /*
  * Execute a VIA PRAM/RTC command. For read commands
  * data should point to a one-byte buffer for the
@@ -145,13 +160,17 @@ static void via_rtc_send(__u8 data)
  * This function disables all interrupts while running.
  */
 
-static void via_pram_command(int command, __u8 *data)
+static void via_rtc_command(int command, __u8 *data)
 {
unsigned long flags;
int is_read;
 
local_irq_save(flags);
 
+   /* The least significant bits must be 0b01 according to Inside Mac */
+
+   command = (command & ~3) | 1;
+
/* Enable the RTC and make sure the strobe line is high */
 
via1[vBufB] = (via1[vBufB] | VIA1B_vRTCClk) & ~VIA1B_vRTCEnb;
@@ -159,10 +178,10 @@ static void via_pram_command(int command, __u8 *data)
if (command & 0xFF00) { /* extended (two-byte) command */
via_rtc_send((command & 0xFF00) >> 8);
via_rtc_send(command & 0xFF);
-   is_read = command & 0x8000;
+   is_read = command & (RTC_FLG_READ << 8);
} else {/* one-byte command */
via_rtc_send(command);
-   is_read = command & 0x80;
+   is_read = command & RTC_FLG_READ;
}
if (is_read) {
*data = via_rtc_recv();
@@ -201,10 +220,10 @@ static time64_t via_read_time(void)
} result, last_result;
int count = 1;
 
-   via_pram_command(0x81, _result.cdata[3]);
-   via_pram_command(0x85, _result.cdata[2]);
-   via_pram_command(0x89, _result.cdata[1]);
-   via_pram_command(0x8D, _result.cdata[0]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0), _result.cdata[3]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1), _result.cdata[2]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2), _result.cdata[1]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3), _result.cdata[0]);
 
/*
 * The NetBSD guys say to loop until you get the same reading
@@ -212,10 +231,14 @@ static time64_t via_read_time(void)
 */
 
while (1) {
-   via_pram_command(0x81, [3]);
-   via_pram_command(0x85, [2]);
-   via_pram_command(0x89, [1]);
-   via_pram_command(0x8D, [0]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_0),
+   [3]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_1),
+   [2]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_2),
+   [1]);
+   via_rtc_command(RTC_CMD_READ(RTC_REG_SECONDS_3),
+   [0]);
 
if (result.idata == last_result.idata)
return (time64_t)result.idata - RTC_OFFSET;
@@ -254,18 +277,18 @@ static void via_set_rtc_time(struct rtc_time *tm)
/* Clear the write protect bit */
 
temp = 0x55;
-   via_pram_command(0x35, );
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), );
 
data.idata = lower_32_bits(time + RTC_OFFSET);
-   via_pram_command(0x01, [3]);
-   via_pram_command(0x05, [2]);
-   via_pram_command(0x09, [1]);
-   via_pram_command(0x0D, [0]);
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_0), [3]);
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_1), [2]);
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_2), [1]);
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_SECONDS_3), [0]);
 
/* Set the write protect bit */
 
-   temp = 0xD5;
-   via_pram_command(0x35, );
+   temp = 0x55 | RTC_FLG_WRITE_PROTECT;
+   via_rtc_command(RTC_CMD_WRITE(RTC_REG_WRITE_PROTECT), );
 }
 
 static void via_shutdown(void)
-- 
2.19.2



[PATCH v9 07/22] char/nvram: Adopt arch_nvram_ops

2019-01-14 Thread Finn Thain
NVRAMs on different platforms and architectures have different attributes
and access methods. E.g. some platforms have byte-at-a-time accessor
functions while others have byte-range accessor functions. Some have
checksum functionality while others do not. By calling ops struct methods
via the common wrapper functions, the nvram module and other drivers can
make use of the available NVRAM functionality in a portable way.

Signed-off-by: Finn Thain 
---
It might be nice if the NVRAM Kconfig symbol depended only on
HAVE_ARCH_NVRAM_OPS and all the x86 code here were moved to arch/x86.
This driver would then be more "generic". However, that x86 code would
have to be built-in when used by thinkpad_acpi or else a new module
would have to be added to arch/x86 too. Better to avoid that bloat
because most x86 platforms won't benefit.

Changed since v8:
 - Added kernel-doc comment describing the nvram_ops methods.
 - Renamed static nvram_* functions to avoid name collisions.
 - Converted arch_nvram_ops method calls to nvram.h wrapper function calls.
---
 drivers/char/nvram.c  | 30 --
 include/linux/nvram.h | 32 
 2 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index c98775bfd896..2df391f78986 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -52,9 +52,11 @@ static DEFINE_MUTEX(nvram_mutex);
 static DEFINE_SPINLOCK(nvram_state_lock);
 static int nvram_open_cnt; /* #times opened */
 static int nvram_open_mode;/* special open modes */
+static ssize_t nvram_size;
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
+#ifdef CONFIG_X86
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -145,6 +147,19 @@ void nvram_set_checksum(void)
 }
 #endif  /*  0  */
 
+static ssize_t pc_nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read_byte  = pc_nvram_read_byte,
+   .write_byte = pc_nvram_write_byte,
+   .get_size   = pc_nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+#endif /* CONFIG_X86 */
+
 /*
  * The are the file operation function for user access to /dev/nvram
  */
@@ -152,7 +167,7 @@ void nvram_set_checksum(void)
 static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
-   NVRAM_BYTES);
+   nvram_size);
 }
 
 static ssize_t nvram_misc_read(struct file *file, char __user *buf,
@@ -303,8 +318,7 @@ static int nvram_misc_release(struct inode *inode, struct 
file *file)
return 0;
 }
 
-#ifdef CONFIG_PROC_FS
-
+#if defined(CONFIG_X86) && defined(CONFIG_PROC_FS)
 static const char * const floppy_types[] = {
"none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
"3.5'' 2.88M", "3.5'' 2.88M"
@@ -394,7 +408,7 @@ static int nvram_proc_read(struct seq_file *seq, void 
*offset)
 
return 0;
 }
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_X86 && CONFIG_PROC_FS */
 
 static const struct file_operations nvram_misc_fops = {
.owner  = THIS_MODULE,
@@ -416,13 +430,17 @@ static int __init nvram_module_init(void)
 {
int ret;
 
+   nvram_size = nvram_get_size();
+   if (nvram_size < 0)
+   return nvram_size;
+
ret = misc_register(_misc);
if (ret) {
pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
return ret;
}
 
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_X86) && defined(CONFIG_PROC_FS)
if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read)) {
pr_err("nvram: can't create /proc/driver/nvram\n");
misc_deregister(_misc);
@@ -436,7 +454,7 @@ static int __init nvram_module_init(void)
 
 static void __exit nvram_module_exit(void)
 {
-#ifdef CONFIG_PROC_FS
+#if defined(CONFIG_X86) && defined(CONFIG_PROC_FS)
remove_proc_entry("driver/nvram", NULL);
 #endif
misc_deregister(_misc);
diff --git a/include/linux/nvram.h b/include/linux/nvram.h
index 79431dab87a1..bb4ea8cc6ea6 100644
--- a/include/linux/nvram.h
+++ b/include/linux/nvram.h
@@ -5,8 +5,30 @@
 #include 
 #include 
 
+/**
+ * struct nvram_ops - NVRAM functionality made available to drivers
+ * @read: validate checksum (if any) then load a range of bytes from NVRAM
+ * @write: store a range of bytes to NVRAM then update checksum (if any)
+ * @read_byte: load a single byte from NVRAM
+ * @write_byte: store a single byte to NVRAM
+ * @

[PATCH v9 06/22] powerpc: Replace nvram_* extern declarations with standard header

2019-01-14 Thread Finn Thain
Remove the nvram_read_byte() and nvram_write_byte() declarations in
powerpc/include/asm/nvram.h and use the cross-platform static functions
in linux/nvram.h instead.

Tested-by: Stan Johnson 
Signed-off-by: Finn Thain 
---
Changed since v8:
 - Added nvram_read_byte() and nvram_write_byte() functions to avoid a
potential build failure during 'git bisect'.
 - Brought forward some powerpc cleanup to avoid naming collisions with
nvram.h functions.
 - Replaced the ppc_md.nvram_* method wrappers with the ones in nvram.h.
---
 arch/powerpc/include/asm/nvram.h   |  6 --
 arch/powerpc/kernel/setup_32.c | 25 +-
 drivers/char/generic_nvram.c   |  1 +
 drivers/video/fbdev/matrox/matroxfb_base.c |  2 +-
 include/linux/nvram.h  |  3 +++
 5 files changed, 6 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h
index 09a518bb7c03..56a388da9c4f 100644
--- a/arch/powerpc/include/asm/nvram.h
+++ b/arch/powerpc/include/asm/nvram.h
@@ -98,10 +98,4 @@ extern int nvram_write_os_partition(struct 
nvram_os_partition *part,
unsigned int err_type,
unsigned int error_log_cnt);
 
-/* Determine NVRAM size */
-extern ssize_t nvram_get_size(void);
-
-/* Normal access to NVRAM */
-extern unsigned char nvram_read_byte(int i);
-extern void nvram_write_byte(unsigned char c, int i);
 #endif /* _ASM_POWERPC_NVRAM_H */
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 947f904688b0..f5107796e2d7 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -149,30 +150,6 @@ __setup("l3cr=", ppc_setup_l3cr);
 
 #ifdef CONFIG_GENERIC_NVRAM
 
-/* Generic nvram hooks used by drivers/char/gen_nvram.c */
-unsigned char nvram_read_byte(int addr)
-{
-   if (ppc_md.nvram_read_val)
-   return ppc_md.nvram_read_val(addr);
-   return 0xff;
-}
-EXPORT_SYMBOL(nvram_read_byte);
-
-void nvram_write_byte(unsigned char val, int addr)
-{
-   if (ppc_md.nvram_write_val)
-   ppc_md.nvram_write_val(addr, val);
-}
-EXPORT_SYMBOL(nvram_write_byte);
-
-ssize_t nvram_get_size(void)
-{
-   if (ppc_md.nvram_size)
-   return ppc_md.nvram_size();
-   return -1;
-}
-EXPORT_SYMBOL(nvram_get_size);
-
 void nvram_sync(void)
 {
if (ppc_md.nvram_sync)
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index ff5394f47587..0c22b9503e84 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c 
b/drivers/video/fbdev/matrox/matroxfb_base.c
index 838869c6490c..0a4e5bad33f4 100644
--- a/drivers/video/fbdev/matrox/matroxfb_base.c
+++ b/drivers/video/fbdev/matrox/matroxfb_base.c
@@ -111,12 +111,12 @@
 #include "matroxfb_g450.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #ifdef CONFIG_PPC_PMAC
 #include 
-unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
 #endif
diff --git a/include/linux/nvram.h b/include/linux/nvram.h
index a1e01dc89759..79431dab87a1 100644
--- a/include/linux/nvram.h
+++ b/include/linux/nvram.h
@@ -15,8 +15,11 @@ extern const struct nvram_ops arch_nvram_ops;
 
 static inline ssize_t nvram_get_size(void)
 {
+#ifdef CONFIG_PPC
+#else
if (arch_nvram_ops.get_size)
return arch_nvram_ops.get_size();
+#endif
return -ENODEV;
 }
 
-- 
2.19.2



[PATCH v9 05/22] m68k/atari: Implement arch_nvram_ops struct

2019-01-14 Thread Finn Thain
By implementing an arch_nvram_ops struct, a platform can re-use the
drivers/char/nvram.c module without needing any arch-specific code
in that module. Atari does so here.

Acked-by: Geert Uytterhoeven 
Signed-off-by: Finn Thain 
---
Changed since v8:
 - Added static inline wrapper functions to nvram.h.
 - Removed excess whitespace.
 - Renamed functions to avoid collisions with nvram.h wrapper functions.
 - Moved nvram_check_checksum() changes to the preceding patch.
---
 arch/m68k/atari/nvram.c | 49 +
 include/linux/nvram.h   | 14 
 2 files changed, 63 insertions(+)

diff --git a/arch/m68k/atari/nvram.c b/arch/m68k/atari/nvram.c
index 1d767847ffa6..e75adebe6e7d 100644
--- a/arch/m68k/atari/nvram.c
+++ b/arch/m68k/atari/nvram.c
@@ -74,6 +74,55 @@ static void __nvram_set_checksum(void)
__nvram_write_byte(sum, ATARI_CKS_LOC + 1);
 }
 
+static ssize_t atari_nvram_read(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   *p = __nvram_read_byte(i);
+   spin_unlock_irq(_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t atari_nvram_write(char *buf, size_t count, loff_t *ppos)
+{
+   char *p = buf;
+   loff_t i;
+
+   spin_lock_irq(_lock);
+   if (!__nvram_check_checksum()) {
+   spin_unlock_irq(_lock);
+   return -EIO;
+   }
+   for (i = *ppos; count > 0 && i < NVRAM_BYTES; --count, ++i, ++p)
+   __nvram_write_byte(*p, i);
+   __nvram_set_checksum();
+   spin_unlock_irq(_lock);
+
+   *ppos = i;
+   return p - buf;
+}
+
+static ssize_t atari_nvram_get_size(void)
+{
+   return NVRAM_BYTES;
+}
+
+const struct nvram_ops arch_nvram_ops = {
+   .read   = atari_nvram_read,
+   .write  = atari_nvram_write,
+   .get_size   = atari_nvram_get_size,
+};
+EXPORT_SYMBOL(arch_nvram_ops);
+
 #ifdef CONFIG_PROC_FS
 static struct {
unsigned char val;
diff --git a/include/linux/nvram.h b/include/linux/nvram.h
index eb5b52a9a747..a1e01dc89759 100644
--- a/include/linux/nvram.h
+++ b/include/linux/nvram.h
@@ -5,8 +5,18 @@
 #include 
 #include 
 
+struct nvram_ops {
+   ssize_t (*get_size)(void);
+   ssize_t (*read)(char *, size_t, loff_t *);
+   ssize_t (*write)(char *, size_t, loff_t *);
+};
+
+extern const struct nvram_ops arch_nvram_ops;
+
 static inline ssize_t nvram_get_size(void)
 {
+   if (arch_nvram_ops.get_size)
+   return arch_nvram_ops.get_size();
return -ENODEV;
 }
 
@@ -21,11 +31,15 @@ static inline void nvram_write_byte(unsigned char val, int 
addr)
 
 static inline ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
 {
+   if (arch_nvram_ops.read)
+   return arch_nvram_ops.read(buf, count, ppos);
return -ENODEV;
 }
 
 static inline ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
 {
+   if (arch_nvram_ops.write)
+   return arch_nvram_ops.write(buf, count, ppos);
return -ENODEV;
 }
 
-- 
2.19.2



[PATCH v9 02/22] m68k/atari: Move Atari-specific code out of drivers/char/nvram.c

2019-01-14 Thread Finn Thain
Move the m68k-specific code out of the driver to make the driver generic.

I've used 'SPDX-License-Identifier: GPL-2.0+' for the new file because the
old file is covered by MODULE_LICENSE("GPL").

Acked-by: Geert Uytterhoeven 
Signed-off-by: Finn Thain 
---
Changed since v8:
 - Fixed an old bug by adding a missing new line character.

Changed since v7:
 - Added SPDX-License-Identifier.
---
 arch/m68k/atari/Makefile |   2 +
 arch/m68k/atari/nvram.c  | 243 +
 drivers/char/nvram.c | 280 +--
 3 files changed, 280 insertions(+), 245 deletions(-)
 create mode 100644 arch/m68k/atari/nvram.c

diff --git a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
index 0cac723306f9..0b86bb6cfa87 100644
--- a/arch/m68k/atari/Makefile
+++ b/arch/m68k/atari/Makefile
@@ -6,3 +6,5 @@ obj-y   := config.o time.o debug.o ataints.o stdma.o \
atasound.o stram.o
 
 obj-$(CONFIG_ATARI_KBD_CORE)   += atakeyb.o
+
+obj-$(CONFIG_NVRAM:m=y)+= nvram.o
diff --git a/arch/m68k/atari/nvram.c b/arch/m68k/atari/nvram.c
new file mode 100644
index ..a8c457e40b0b
--- /dev/null
+++ b/arch/m68k/atari/nvram.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * CMOS/NV-RAM driver for Atari. Adapted from drivers/char/nvram.c.
+ * Copyright (C) 1997 Roman Hodek 
+ * idea by and with help from Richard Jelinek 
+ * Portions copyright (c) 2001,2002 Sun Microsystems (thoc...@sun.com)
+ * Further contributions from Cesar Barros, Erik Gilling, Tim Hockin and
+ * Wim Van Sebroeck.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define NVRAM_BYTES50
+
+/* It is worth noting that these functions all access bytes of general
+ * purpose memory in the NVRAM - that is to say, they all add the
+ * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not
+ * know about the RTC cruft.
+ */
+
+/* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
+ * rtc_lock held. Due to the index-port/data-port design of the RTC, we
+ * don't want two different things trying to get to it at once. (e.g. the
+ * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
+ */
+
+unsigned char __nvram_read_byte(int i)
+{
+   return CMOS_READ(NVRAM_FIRST_BYTE + i);
+}
+
+unsigned char nvram_read_byte(int i)
+{
+   unsigned long flags;
+   unsigned char c;
+
+   spin_lock_irqsave(_lock, flags);
+   c = __nvram_read_byte(i);
+   spin_unlock_irqrestore(_lock, flags);
+   return c;
+}
+EXPORT_SYMBOL(nvram_read_byte);
+
+/* This races nicely with trying to read with checksum checking */
+void __nvram_write_byte(unsigned char c, int i)
+{
+   CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
+}
+
+void nvram_write_byte(unsigned char c, int i)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(_lock, flags);
+   __nvram_write_byte(c, i);
+   spin_unlock_irqrestore(_lock, flags);
+}
+
+/* On Ataris, the checksum is over all bytes except the checksum bytes
+ * themselves; these are at the very end.
+ */
+#define ATARI_CKS_RANGE_START  0
+#define ATARI_CKS_RANGE_END47
+#define ATARI_CKS_LOC  48
+
+int __nvram_check_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff)) &&
+  (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
+}
+
+int nvram_check_checksum(void)
+{
+   unsigned long flags;
+   int rv;
+
+   spin_lock_irqsave(_lock, flags);
+   rv = __nvram_check_checksum();
+   spin_unlock_irqrestore(_lock, flags);
+   return rv;
+}
+EXPORT_SYMBOL(nvram_check_checksum);
+
+static void __nvram_set_checksum(void)
+{
+   int i;
+   unsigned char sum = 0;
+
+   for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
+   sum += __nvram_read_byte(i);
+   __nvram_write_byte(~sum, ATARI_CKS_LOC);
+   __nvram_write_byte(sum, ATARI_CKS_LOC + 1);
+}
+
+#ifdef CONFIG_PROC_FS
+static struct {
+   unsigned char val;
+   const char *name;
+} boot_prefs[] = {
+   { 0x80, "TOS" },
+   { 0x40, "ASV" },
+   { 0x20, "NetBSD (?)" },
+   { 0x10, "Linux" },
+   { 0x00, "unspecified" },
+};
+
+static const char * const languages[] = {
+   "English (US)",
+   "German",
+   "French",
+   "English (UK)",
+   "Spanish",
+   "Italian",
+   "6 (undefined)",
+   "Swiss (French)",
+   "Swiss (German)",
+};
+
+static const char * const dateformat[] = {
+   "MM%cDD%cYY",
+   "DD%cMM%cY

[PATCH v9 04/22] nvram: Replace nvram_* function exports with static functions

2019-01-14 Thread Finn Thain
Replace nvram_* functions with static functions in nvram.h. These will
become wrappers for struct nvram_ops method calls.

This patch effectively disables existing NVRAM functionality so as to
allow the rest of the series to be bisected without build failures.
That functionality is gradually re-implemented in subsequent patches.

Replace the sole validate-checksum-and-read-byte sequence with a call to
nvram_read() which will gain the same semantics in subsequent patches.

Remove unused exports.

Acked-by: Geert Uytterhoeven 
Signed-off-by: Finn Thain 
---
 arch/m68k/atari/nvram.c   | 39 +++
 drivers/char/nvram.c  | 27 +--
 drivers/scsi/atari_scsi.c |  8 +---
 include/linux/nvram.h | 32 +---
 4 files changed, 38 insertions(+), 68 deletions(-)

diff --git a/arch/m68k/atari/nvram.c b/arch/m68k/atari/nvram.c
index a8c457e40b0b..1d767847ffa6 100644
--- a/arch/m68k/atari/nvram.c
+++ b/arch/m68k/atari/nvram.c
@@ -34,38 +34,17 @@
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
 
-unsigned char nvram_read_byte(int i)
-{
-   unsigned long flags;
-   unsigned char c;
-
-   spin_lock_irqsave(_lock, flags);
-   c = __nvram_read_byte(i);
-   spin_unlock_irqrestore(_lock, flags);
-   return c;
-}
-EXPORT_SYMBOL(nvram_read_byte);
-
 /* This races nicely with trying to read with checksum checking */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
 
-void nvram_write_byte(unsigned char c, int i)
-{
-   unsigned long flags;
-
-   spin_lock_irqsave(_lock, flags);
-   __nvram_write_byte(c, i);
-   spin_unlock_irqrestore(_lock, flags);
-}
-
 /* On Ataris, the checksum is over all bytes except the checksum bytes
  * themselves; these are at the very end.
  */
@@ -73,7 +52,7 @@ void nvram_write_byte(unsigned char c, int i)
 #define ATARI_CKS_RANGE_END47
 #define ATARI_CKS_LOC  48
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned char sum = 0;
@@ -84,18 +63,6 @@ int __nvram_check_checksum(void)
   (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
 }
 
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
-
 static void __nvram_set_checksum(void)
 {
int i;
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index c660cff9faf4..c98775bfd896 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -74,13 +74,12 @@ static int nvram_open_mode; /* special open modes */
  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
-unsigned char __nvram_read_byte(int i)
+static unsigned char __nvram_read_byte(int i)
 {
return CMOS_READ(NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_read_byte);
 
-unsigned char nvram_read_byte(int i)
+static unsigned char pc_nvram_read_byte(int i)
 {
unsigned long flags;
unsigned char c;
@@ -90,16 +89,14 @@ unsigned char nvram_read_byte(int i)
spin_unlock_irqrestore(_lock, flags);
return c;
 }
-EXPORT_SYMBOL(nvram_read_byte);
 
 /* This races nicely with trying to read with checksum checking (nvram_read) */
-void __nvram_write_byte(unsigned char c, int i)
+static void __nvram_write_byte(unsigned char c, int i)
 {
CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
 }
-EXPORT_SYMBOL(__nvram_write_byte);
 
-void nvram_write_byte(unsigned char c, int i)
+static void pc_nvram_write_byte(unsigned char c, int i)
 {
unsigned long flags;
 
@@ -107,14 +104,13 @@ void nvram_write_byte(unsigned char c, int i)
__nvram_write_byte(c, i);
spin_unlock_irqrestore(_lock, flags);
 }
-EXPORT_SYMBOL(nvram_write_byte);
 
 /* On PCs, the checksum is built only over bytes 2..31 */
 #define PC_CKS_RANGE_START 2
 #define PC_CKS_RANGE_END   31
 #define PC_CKS_LOC 32
 
-int __nvram_check_checksum(void)
+static int __nvram_check_checksum(void)
 {
int i;
unsigned short sum = 0;
@@ -126,19 +122,6 @@ int __nvram_check_checksum(void)
__nvram_read_byte(PC_CKS_LOC+1);
return (sum & 0x) == expect;
 }
-EXPORT_SYMBOL(__nvram_check_checksum);
-
-int nvram_check_checksum(void)
-{
-   unsigned long flags;
-   int rv;
-
-   spin_lock_irqsave(_lock, flags);
-   rv = __nvram_check_checksum();
-   spin_unlock_irqrestore(_lock, flags);
-   return rv;
-}
-EXPORT_SYMBOL(nvram_check_checksum);
 
 static void __nvram_set_checksum(void)
 {
diff --git a/drivers/scsi/atar

[PATCH v9 03/22] char/nvram: Re-order functions to remove forward declarations and #ifdefs

2019-01-14 Thread Finn Thain
Also give functions more sensible names: nvram_misc_* for misc device ops,
nvram_proc_* for proc file ops and nvram_module_* for init and exit
functions. This prevents name collisions with nvram.h helper functions
and improves readability.

Signed-off-by: Finn Thain 
---
 drivers/char/nvram.c | 167 +++
 1 file changed, 72 insertions(+), 95 deletions(-)

diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index a9d4652f9e90..c660cff9faf4 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -55,11 +55,6 @@ static int nvram_open_mode;  /* special open modes */
 #define NVRAM_WRITE1 /* opened for writing (exclusive) */
 #define NVRAM_EXCL 2 /* opened with O_EXCL */
 
-#ifdef CONFIG_PROC_FS
-static void pc_nvram_proc_read(unsigned char *contents, struct seq_file *seq,
-  void *offset);
-#endif
-
 /*
  * These functions are provided to be called internally or by other parts of
  * the kernel. It's up to the caller to ensure correct checksum before reading
@@ -171,14 +166,14 @@ void nvram_set_checksum(void)
  * The are the file operation function for user access to /dev/nvram
  */
 
-static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_misc_llseek(struct file *file, loff_t offset, int origin)
 {
return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
NVRAM_BYTES);
 }
 
-static ssize_t nvram_read(struct file *file, char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_read(struct file *file, char __user *buf,
+  size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -206,8 +201,8 @@ static ssize_t nvram_read(struct file *file, char __user 
*buf,
return -EIO;
 }
 
-static ssize_t nvram_write(struct file *file, const char __user *buf,
-   size_t count, loff_t *ppos)
+static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
+   size_t count, loff_t *ppos)
 {
unsigned char contents[NVRAM_BYTES];
unsigned i = *ppos;
@@ -245,8 +240,8 @@ static ssize_t nvram_write(struct file *file, const char 
__user *buf,
return -EIO;
 }
 
-static long nvram_ioctl(struct file *file, unsigned int cmd,
-   unsigned long arg)
+static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
+unsigned long arg)
 {
int i;
 
@@ -286,7 +281,7 @@ static long nvram_ioctl(struct file *file, unsigned int cmd,
}
 }
 
-static int nvram_open(struct inode *inode, struct file *file)
+static int nvram_misc_open(struct inode *inode, struct file *file)
 {
spin_lock(_state_lock);
 
@@ -308,7 +303,7 @@ static int nvram_open(struct inode *inode, struct file 
*file)
return 0;
 }
 
-static int nvram_release(struct inode *inode, struct file *file)
+static int nvram_misc_release(struct inode *inode, struct file *file)
 {
spin_lock(_state_lock);
 
@@ -325,87 +320,6 @@ static int nvram_release(struct inode *inode, struct file 
*file)
return 0;
 }
 
-#ifndef CONFIG_PROC_FS
-static int nvram_add_proc_fs(void)
-{
-   return 0;
-}
-
-#else
-
-static int nvram_proc_read(struct seq_file *seq, void *offset)
-{
-   unsigned char contents[NVRAM_BYTES];
-   int i = 0;
-
-   spin_lock_irq(_lock);
-   for (i = 0; i < NVRAM_BYTES; ++i)
-   contents[i] = __nvram_read_byte(i);
-   spin_unlock_irq(_lock);
-
-   pc_nvram_proc_read(contents, seq, offset);
-
-   return 0;
-}
-
-static int nvram_add_proc_fs(void)
-{
-   if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read))
-   return -ENOMEM;
-   return 0;
-}
-
-#endif /* CONFIG_PROC_FS */
-
-static const struct file_operations nvram_fops = {
-   .owner  = THIS_MODULE,
-   .llseek = nvram_llseek,
-   .read   = nvram_read,
-   .write  = nvram_write,
-   .unlocked_ioctl = nvram_ioctl,
-   .open   = nvram_open,
-   .release= nvram_release,
-};
-
-static struct miscdevice nvram_dev = {
-   NVRAM_MINOR,
-   "nvram",
-   _fops
-};
-
-static int __init nvram_init(void)
-{
-   int ret;
-
-   ret = misc_register(_dev);
-   if (ret) {
-   printk(KERN_ERR "nvram: can't misc_register on minor=%d\n",
-   NVRAM_MINOR);
-   goto out;
-   }
-   ret = nvram_add_proc_fs();
-   if (ret) {
-   printk(KERN_ERR "nvram: can't create /proc/driver/nvram\n");
-   goto outmisc;
-   }
-   ret = 0;
-   printk(KERN_INFO "Non-volatile memory driver v" NVRAM_VERSION "\n"

[PATCH v9 00/22] Re-use nvram module

2019-01-14 Thread Finn Thain
The "generic" NVRAM module, drivers/char/generic_nvram.c, implements a
/dev/nvram misc device. This module is used only by 32-bit PowerPC
platforms.

The RTC "CMOS" NVRAM module, drivers/char/nvram.c, also implements a
/dev/nvram misc device. This module is now used only by x86 and m68k
thanks to commit 3ba9faedc180 ("char: nvram: disable on ARM").

The "generic" module cannot be used by x86 or m68k platforms because it
cannot co-exist with the "CMOS" module. One reason for that is the
CONFIG_GENERIC_NVRAM kludge in drivers/char/Makefile. Another reason is
that automatically loading the appropriate module would be impossible
because only one module can provide the char-major-10-144 alias.

A multi-platform kernel binary needs a single, generic module. With this
patch series, drivers/char/nvram.c becomes more generic and some of the
arch-specific code gets moved under arch/. The nvram module is then
usable by all m68k, powerpc and x86 platforms.

This allows for removal of drivers/char/generic_nvram.c as well as a
duplicate in arch/powerpc/kernel/nvram_64.c. By reducing the number of
/dev/nvram char misc device implementations, the number of bugs and
inconsistencies is also reduced.

This approach reduces inconsistencies between PPC32 and PPC64 and also
between PPC_PMAC and MAC. A uniform API has benefits for userspace.

For example, some error codes for some ioctl calls become consistent
across PowerPC platforms. The uniform API can potentially benefit any
bootloader that works across the various platforms having XPRAM
(e.g. Emile).

This patch series was tested on Atari, Mac, PowerMac (both 32-bit and
64-bit) and ThinkPad hardware. AFAIK, it has not yet been tested on
pSeries or CHRP.

I think there are two possible merge strategies for this patch series.
The char misc maintainer could take the entire series. Alternatively,
the m68k maintainer could take patches 1 thru 16 (though some of these
have nothing to do with m68k) and after those patches reach mainline
the powerpc maintainer could take 17 thru 22.

Changed since v8:
 - Replaced defined(CONFIG_NVRAM) with IS_REACHABLE(CONFIG_NVRAM) as
suggested by James Bottomley.
 - Changed #ifdef to if as suggested by Christophe Leroy.
 - Expanded the fbdev patch to include controlfb.c and platinumfb.c.
 - Added kernel-doc comment to describe struct nvram_ops.
 - Moved the HAVE_ARCH_NVRAM_OPS symbol to common code as suggested
by Christoph Hellwig.
 - Abandoned conversion of powerpc drivers to arch_nvram_ops, as discussed
with Arnd Bergmann.
 - Dropped patch 6 ("x86/thinkpad_acpi: Use arch_nvram_ops methods").
 - Dropped patch 17 ("powerpc: Implement arch_nvram_ops.get_size() ...").
 - Dropped patch 20 ("powerpc, fbdev: Use arch_nvram_ops methods ...").
 - Dropped patch 25 ("powerpc: Remove pmac_xpram_{read,write} functions").
 - Added portable static functions to nvram.h which wrap both arch_nvram_ops
and ppc_md method calls.
 - Re-ordered and revised patches to resolve conflicts with existing extern
definitions in nvram.h and elsewhere.
 - Rebased on v5.0-rc2.
 - Added patch 14 ("macintosh/via-cuda: Don't rely on Cuda to end a transfer").

Changed since v7:
 - Rebased.
 - Dropped patch 9/26, "char/nvram: Use generic fixed_size_llseek()"
because generic_file_llseek_size() was adopted in commit b808b1d632f6.
 - Reordered the m68k and powerpc patches to simplify the merge strategy.
 - Addressed some trivial checkpatch.pl complaints.
 - Improved some commit log entries.
 - Changed the CONFIG_NVRAM default to better approximate the present code.
In particular, the CONFIG_GENERIC_NVRAM default and use of "select NVRAM".
 - Added more tested-by tags.

For older change logs, please refer to,
https://lore.kernel.org/lkml/20151101104202.301856...@telegraphics.com.au/


Finn Thain (22):
  scsi/atari_scsi: Don't select CONFIG_NVRAM
  m68k/atari: Move Atari-specific code out of drivers/char/nvram.c
  char/nvram: Re-order functions to remove forward declarations and
#ifdefs
  nvram: Replace nvram_* function exports with static functions
  m68k/atari: Implement arch_nvram_ops struct
  powerpc: Replace nvram_* extern declarations with standard header
  char/nvram: Adopt arch_nvram_ops
  char/nvram: Allow the set_checksum and initialize ioctls to be omitted
  char/nvram: Implement NVRAM read/write methods
  m68k/atari: Implement arch_nvram_ops methods and enable
CONFIG_HAVE_ARCH_NVRAM_OPS
  m68k/mac: Adopt naming and calling conventions for PRAM routines
  m68k/mac: Use macros for RTC accesses not magic numbers
  m68k/mac: Fix PRAM accessors
  macintosh/via-cuda: Don't rely on Cuda to end a transfer
  m68k: Dispatch nvram_ops calls to Atari or Mac functions
  char/nvram: Add "devname:nvram" module alias
  powerpc: Define missing ppc_md.nvram_size for CHRP and PowerMac
  powerpc: Implement nvram ioctls
  powerpc, fbdev: Use NV_CMODE and NV_V

[PATCH v9 01/22] scsi/atari_scsi: Don't select CONFIG_NVRAM

2019-01-14 Thread Finn Thain
On powerpc, setting CONFIG_NVRAM=n builds a kernel with no NVRAM support.
Setting CONFIG_NVRAM=m enables the /dev/nvram misc device module without
enabling NVRAM support in drivers. Setting CONFIG_NVRAM=y enables the
misc device (built-in) and also enables NVRAM support in drivers.

m68k shares the valkyriefb driver with powerpc, and since that driver uses
NVRAM, it is affected by CONFIG_ATARI_SCSI, because of the use of
"select NVRAM". We can avoid the "select" here, but drivers still have
to interpret the CONFIG_NVRAM symbol consistently regardless of platform.

In this patch and the subsequent fbdev driver patch, the convention is
adopted across all relevant platforms whereby NVRAM functionality gets
enabled in a given device driver when the nvram misc device is built-in
or when both drivers are modules.

Acked-by: Michael Schmitz 
Signed-off-by: Finn Thain 
---
This patch temporarily disables CONFIG_NVRAM on Atari, to prevent build
failures when bisecting the rest of this patch series. It gets enabled
again with the introduction of CONFIG_HAVE_ARCH_NVRAM_OPS, once the
nvram_* global functions have been moved to an ops struct.

Changed since v8:
 - Replaced defined(CONFIG_NVRAM) with IS_REACHABLE(CONFIG_NVRAM) as
suggested by James Bottomley.
 - Changed #ifdef to if as suggested by Christophe Leroy.
---
 drivers/char/Kconfig  | 5 +
 drivers/scsi/Kconfig  | 6 +++---
 drivers/scsi/atari_scsi.c | 2 +-
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 2e2ffe7010aa..a8cac68de177 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -244,7 +244,7 @@ source "drivers/char/hw_random/Kconfig"
 
 config NVRAM
tristate "/dev/nvram support"
-   depends on ATARI || X86 || GENERIC_NVRAM
+   depends on X86 || GENERIC_NVRAM
---help---
  If you say Y here and create a character special file /dev/nvram
  with major number 10 and minor number 144 using mknod ("man mknod"),
@@ -262,9 +262,6 @@ config NVRAM
  should NEVER idly tamper with it. See Ralf Brown's interrupt list
  for a guide to the use of CMOS bytes by your BIOS.
 
- On Atari machines, /dev/nvram is always configured and does not need
- to be selected.
-
  To compile this driver as a module, choose M here: the
  module will be called nvram.
 
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index f38882f6f37d..8f9d9e9fa695 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1369,14 +1369,14 @@ config ATARI_SCSI
tristate "Atari native SCSI support"
depends on ATARI && SCSI
select SCSI_SPI_ATTRS
-   select NVRAM
---help---
  If you have an Atari with built-in NCR5380 SCSI controller (TT,
  Falcon, ...) say Y to get it supported. Of course also, if you have
  a compatible SCSI controller (e.g. for Medusa).
 
- To compile this driver as a module, choose M here: the
- module will be called atari_scsi.
+ To compile this driver as a module, choose M here: the module will
+ be called atari_scsi. If you also enable NVRAM support, the SCSI
+ host's ID is taken from the setting in TT RTC NVRAM.
 
  This driver supports both styles of NCR integration into the
  system: the TT style (separate DMA), and the Falcon style (via
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index a503dc50c4f8..78b43200c99e 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -757,7 +757,7 @@ static int __init atari_scsi_probe(struct platform_device 
*pdev)
 
if (setup_hostid >= 0) {
atari_scsi_template.this_id = setup_hostid & 7;
-   } else {
+   } else if (IS_REACHABLE(CONFIG_NVRAM)) {
/* Test if a host id is set in the NVRam */
if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
unsigned char b = nvram_read_byte(16);
-- 
2.19.2



  1   2   3   4   5   >