IO delay, port 0x80, and BIOS POST codes
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 7 lines · Martin Wilck
Quoted 4 lines · Thunder from the hill
I also remember this been discussed anually. Making it configurable with a warning might be a solution, but that's nothing we could decide. Maybe add a config option? It night be a [DANGEROUS] one, so the guys and gals who might compile are warned of changing this.
Quoted 7 lines
It doesn't even have to be a config option - a line
/* Port used for dummy writes for I/O delays */ /* Change this only if you know what you're doing ! */ #define
DUMMY_IO_PORT0x80in a header file would perfectly suffice.
That effectively already exists. You just need to change the __SLOW_DOWN_IO macro in include/asm-i387/io.h
-Andi
Quoted 10 lines · Andi Kleen
Quoted 7 lines
It doesn't even have to be a config option - a line
/* Port used for dummy writes for I/O delays */ /* Change this only if you know what you're doing ! */ #define
DUMMY_IO_PORT0x80in a header file would perfectly suffice.
That effectively already exists. You just need to change the
__SLOW_DOWN_IOmacro ininclude/asm-i387/io.h
No, that doesn't cover all accesses to port 80. I am still searching.
Signature · 4 lines
Martin Wilck Phone: +49 5251 8 15113 Fujitsu Siemens Computers Fax: +49 5251 8 20409 Heinz-Nixdorf-Ring 1 mailto:[email protected] D-33106 Paderborn http://www.fujitsu-siemens.com/primergy
Quoted 8 lines · Martin Wilck
Quoted 6 lines · Andi Kleen
Quoted 6 lines
It doesn't even have to be a config option - a line
/* Port used for dummy writes for I/O delays */ /* Change this only if you know what you're doing ! */ #define
DUMMY_IO_PORT0x80
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
in a header file would perfectly suffice.
That effectively already exists. You just need to change the
__SLOW_DOWN_IOmacro ininclude/asm-i387/io.hNo, that doesn't cover all accesses to port 80. I am still searching.
It should. I would consider all other accesses a bug.
It is possible that some driver used it for private debugging and left it in by mistake. These should be removed.
-Andi
PATCH 1/1 Cleanup port 0x80 use (was: Re: IO delay ...)
Hi,
this patch makes the use of the "dummy" port 0x80 globally configurable through a macro in the (new) file asm-i386/iodelay.h.
I think nobody wants to see this in the configuration menus.
I have tried to capture all accesses to port 0x80, although some may have escaped.
Even if nobody wants to use anything other than 0x80 in the near future, I think the patch is useful because grepping the source for 0x80 is really no fun.
With the patch, our BIOS post code LEDs really stand still.
I am still wondering, though, why this method of getting a delay is used so often. IMO in most places one could use udelay(1) instead, with much less risk of doing wrong.
Martin
Signature · 208 lines
Martin Wilck Phone: +49 5251 8 15113 Fujitsu Siemens Computers Fax: +49 5251 8 20409 Heinz-Nixdorf-Ring 1 mailto:[email protected] D-33106 Paderborn http://www.fujitsu-siemens.com/primergy --- ./include/asm-i386/io.h.orig Fri Mar 15 17:23:15 2002 +++ ./include/asm-i386/io.h Fri Mar 15 18:30:03 2002 @@ -221,17 +221,9 @@ #endif /* __KERNEL__ */ -#ifdef SLOW_IO_BY_JUMPING -#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" -#else -#define __SLOW_DOWN_IO "\noutb %%al,$0x80" -#endif - -#ifdef REALLY_SLOW_IO -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO -#else -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO -#endif +/* Moved the __SLOW_DOWN_IO macros to a separate file + * that can be included by setup.S */ +#include <asm/iodelay.h> #ifdef CONFIG_MULTIQUAD extern void *xquad_portio; /* Where the IO area was mapped */ --- ./include/asm-i386/floppy.h.orig Fri Mar 15 17:23:15 2002 +++ ./include/asm-i386/floppy.h Fri Mar 15 17:55:04 2002 @@ -89,8 +89,7 @@ jmp 5f 4: movb (%2),%0 outb %b0,%w4 -5: decw %w4 - outb %0,$0x80 +5: decw %w4" __SLOW_DOWN_IO " decl %1 incl %2 testl %1,%1 --- ./include/asm-i386/iodelay.h.orig Fri Mar 15 18:31:01 2002 +++ ./include/asm-i386/iodelay.h Fri Mar 15 18:30:36 2002 @@ -0,0 +1,25 @@ +#ifndef _ASM_IODELAY_H +#define _ASM_IODELAY_H + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else + + /* + * The dummy IO port to use for delays. + * Change only if you really know what you're doing + * Default value: 0x80 + * Other values that have been suggested: 0x19, 0x42, 0xe2, 0xed + * Both macros must be changed to capture all I/O delays in the kernel. + */ +#define __SLOW_DOWN_IO_PORT 0x80 +#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +#endif --- ./drivers/char/serial.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/char/serial.c Fri Mar 15 17:24:13 2002 @@ -3661,12 +3661,12 @@ scratch = serial_inp(info, UART_IER); serial_outp(info, UART_IER, 0); #ifdef __i386__ - outb(0xff, 0x080); + outb(0xff,__SLOW_DOWN_IO_PORT); #endif scratch2 = serial_inp(info, UART_IER); serial_outp(info, UART_IER, 0x0F); #ifdef __i386__ - outb(0, 0x080); + outb(0xff,__SLOW_DOWN_IO_PORT); #endif scratch3 = serial_inp(info, UART_IER); serial_outp(info, UART_IER, scratch); --- ./drivers/char/riscom8.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/char/riscom8.c Fri Mar 15 17:24:13 2002 @@ -278,10 +278,10 @@ /* Are the I/O ports here ? */ rc_out(bp, CD180_PPRL, 0x5a); - outb(0xff, 0x80); + outb(0xff, __SLOW_DOWN_IO_PORT); val1 = rc_in(bp, CD180_PPRL); rc_out(bp, CD180_PPRL, 0xa5); - outb(0x00, 0x80); + outb(0x00, __SLOW_DOWN_IO_PORT); val2 = rc_in(bp, CD180_PPRL); if ((val1 != 0x5a) || (val2 != 0xa5)) { --- ./drivers/scsi/atp870u.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/scsi/atp870u.c Fri Mar 15 17:24:13 2002 @@ -1042,7 +1042,7 @@ tmport = dev->ioport + 0x1b; outb(0x02, tmport); - outb(0, 0x80); + outb(0, __SLOW_DOWN_IO_PORT); val = 0x0080; /* bsy */ tmport = dev->ioport + 0x1c; @@ -1051,7 +1051,7 @@ outw(val, tmport); val |= 0x0004; /* msg */ outw(val, tmport); - inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ + inb(__SLOW_DOWN_IO_PORT); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ outw(val, tmport); mydlyu(0xffff); /* recommanded SCAM selection response time */ @@ -1062,7 +1062,7 @@ if ((inb(tmport) & 0x04) != 0) { goto wait_nomsg; } - outb(1, 0x80); + outb(1, __SLOW_DOWN_IO_PORT); mydlyu(100); for (n = 0; n < 0x30000; n++) { if ((inb(tmport) & 0x80) != 0) { /* bsy ? */ @@ -1078,13 +1078,13 @@ } goto TCM_SYNC; wait_io1: - inb(0x80); + inb(__SLOW_DOWN_IO_PORT); val |= 0x8003; /* io,cd,db7 */ outw(val, tmport); - inb(0x80); + inb(__SLOW_DOWN_IO_PORT); val &= 0x00bf; /* no sel */ outw(val, tmport); - outb(2, 0x80); + outb(2, __SLOW_DOWN_IO_PORT); TCM_SYNC: mydlyu(0x800); if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ @@ -1103,18 +1103,18 @@ val &= 0x00ff; /* synchronization */ val |= 0x3f00; fun_scam(dev, &val); - outb(3, 0x80); + outb(3, __SLOW_DOWN_IO_PORT); val &= 0x00ff; /* isolation */ val |= 0x2000; fun_scam(dev, &val); - outb(4, 0x80); + outb(4, __SLOW_DOWN_IO_PORT); i = 8; j = 0; TCM_ID: if ((inw(tmport) & 0x2000) == 0) { goto TCM_ID; } - outb(5, 0x80); + outb(5, __SLOW_DOWN_IO_PORT); val &= 0x00ff; /* get ID_STRING */ val |= 0x2000; k = fun_scam(dev, &val); --- ./drivers/video/sis/sis_main.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/video/sis/sis_main.c Fri Mar 15 17:27:16 2002 @@ -2308,7 +2308,7 @@ u8 reg; int nRes; - outb (0x77, 0x80); + outb (0x77, __SLOW_DOWN_IO_PORT); if (sisfb_off) return -ENXIO; --- ./arch/i386/boot/setup.S.orig Fri Mar 15 17:23:15 2002 +++ ./arch/i386/boot/setup.S Fri Mar 15 18:33:12 2002 @@ -54,6 +54,7 @@ #include <asm/boot.h> #include <asm/e820.h> #include <asm/page.h> +#include <asm/iodelay.h> /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55 @@ -65,6 +66,7 @@ # ... and the former contents of CS DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020 +DELAY_PORT = __SLOW_DOWN_IO_PORT # port for IO delay (0x80) .code16 .globl begtext, begdata, begbss, endtext, enddata, endbss @@ -1001,7 +1003,7 @@ # Delay is needed after doing I/O delay: - outb %al,$0x80 + outb %al,$DELAY_PORT ret # Descriptor tables
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
Quoted 3 lines
I am still wondering, though, why this method of getting a delay is used so often. IMO in most places one could use udelay(1) instead, with much less risk of doing wrong.
udelay(1) I don't believe is enough. Unfortunately I can't find my documentation on the ISA bus which covers the timeout for acknowledging an address cycle. Otherwise for tsc capable boxes I agree entirely.
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
In reply to Martin WilckFollowup to: <[email protected]> By author: Alan Cox <[email protected]> In newsgroup: linux.dev.kernel
Quoted 9 lines
Quoted 4 lines
I am still wondering, though, why this method of getting a delay is used so often. IMO in most places one could use udelay(1) instead, with much less risk of doing wrong.
udelay(1) I don't believe is enough. Unfortunately I can't find my documentation on the ISA bus which covers the timeout for acknowledging an address cycle. Otherwise for tsc capable boxes I agree entirely.
The ISA bus doesn't time out; a cycle on the ISA bus just happens, and the fact that noone is there to listen doesn't seem to matter.
The delay is something like 8 cycles @ 8.3 MHz or around 1 ms. However, an important thing to note is that this delay applies *at the southbridge*. An OUT is a fully synchronizing operation, so it doesn't just give a 1 ms delay due to the ISA bus cycle, but it also makes sure everything else in the system is completed before the timing counter even starts to tick.
Of course, if all you're doing is IOIO (on an x86!) it doesn't matter -- IOIO is fully synchronizing anyway.
-hpa
Signature · 3 lines
<[email protected]> at work, <[email protected]> in private! "Unix gives you enough rope to shoot yourself in the foot." http://www.zytor.com/~hpa/puzzle.txt <[email protected]>
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
Quoted 5 lines
Quoted 3 lines
documentation on the ISA bus which covers the timeout for acknowledging an address cycle. Otherwise for tsc capable boxes I agree entirely.
The ISA bus doesn't time out; a cycle on the ISA bus just happens, and the fact that noone is there to listen doesn't seem to matter.
Not so simple. I found my IEEE draft 8)
The address out comes from the chipset (southbridge now days). The sequence is
BALE high
Output address
BALE low
Set IORC/IOWC etc
Wait for NOWS while watching IOCHRDY
NOWS low says - card now ready
IOCHRDY high suppresses the wait state timer count
The default timeout is 4 wait states, which is 6 bus clocks for a failure Maybe 7 - Im not clear if the final cycle to recover and start again is always there.
Quoted 1 line
The delay is something like 8 cycles @ 8.3 MHz or around 1 ms.
1uS ?
Alan
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
Quoted 5 lines · Alan Cox
Quoted 2 lines
The delay is something like 8 cycles @ 8.3 MHz or around 1 ms.
1uS ?
1 µs, right :-/
-hpa
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
In reply to Martin WilckIn article <[email protected]>,
Quoted 3 lines · H. Peter Anvin
The ISA bus doesn't time out; a cycle on the ISA bus just happens, and the fact that noone is there to listen doesn't seem to matter.
The ISA bus doesn't time out, but the PCI access before it gets forwarded to the ISA bus _does_, if the ISA bus is decoded using nagative decoding.
This is why it's important that there not be a motherboard PCI device that can decode the port - because if there is, the access is potentially a much faster PCI-only decode.
Note that this really only matters on low-end machines anyway, as the whole "inb_p()" thing tends to be used only for old ISA devices. If you have a new machine that is all PCI, I doubt that port 80h access matters not at all.
(Another way of saying it: if you have a machine with a PCI POST card, none of this will matter)
Linus
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
In reply to Andi KleenReview
Quoted 2 lines · Martin Wilck
(quoted diff) +2
-0+#define __SLOW_DOWN_IO_PORT 0x80 +#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
You may want to change the above to:
#define __SLOW_DOWN_IO_ASM "\noutb %%al,$__SLOW_DOWN_IO_PORT"
Review
Quoted 1 line
(quoted diff) +1
-0+ outb(3, __SLOW_DOWN_IO_PORT);
You may also want to replace the above entirely with a macro, like:
#define __SLOW_DOWN_IO outb(3, __SLOW_DOWN_IO_PORT)
so that on architectures that don't need/have this ISA nonsense can just replace __SLOW_DOWN_IO with something else like udelay.
arch/i386/boot/setup.S line 72
Quoted 10 lines
arch/i386/boot/setup.S renamed from arch/i386/boot/setup.S.orig +1
-0@@ -65,6 +66,7 @@ # ... and the former contents of CS DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020 +DELAY_PORT = __SLOW_DOWN_IO_PORT # port for IO delay (0x80) .code16 .globl begtext, begdata, begbss, endtext, enddata, endbss
May as well just stick with a single define here (i.e. remove DELAY_PORT).
arch/i386/boot/setup.S line 1007
Quoted 7 lines
arch/i386/boot/setup.S renamed from arch/i386/boot/setup.S.orig +1
-1@@ -1001,7 +1003,7 @@ # Delay is needed after doing I/O delay: - outb %al,$0x80 + outb %al,$DELAY_PORT ret
And use __SLOW_DOWN_IO_ASM here.
Cheers, Andreas
--
Andreas Dilger \ "If a man ate a pound of pasta and a pound of antipasto,
\ would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/ -- Dogbert
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
Quoted 5 lines · Andreas Dilger
Review
Quoted 2 lines
(quoted diff) +2
-0+#define __SLOW_DOWN_IO_PORT 0x80 +#define __SLOW_DOWN_IO "\noutb %%al,$0x80"You may want to change the above to:
#define__SLOW_DOWN_IO_ASM"\noutb %%al,$__SLOW_DOWN_IO_PORT"
Won't work, cpp doesn't substitute between double quotes. (at least the one I'm using). Or am I gettimng something wrong here??
Quoted 5 lines
You may also want to replace the above entirely with a macro, like:
#define__SLOW_DOWN_IOoutb(3, __SLOW_DOWN_IO_PORT)so that on architectures that don't need/have this ISA nonsense can just replace
__SLOW_DOWN_IOwith something else like udelay.
I wanted to change as little as possible, generated code was intended to be binary-identical with old code if the port is set to 0x80.
Currently source files can #define "SLOW_IO_BY_JUMPING" to avoid writing to the dummy port. Perhaps someone should introduce SLOW_IO_BY_UDELAY or so.
Quoted 1 line
May as well just stick with a single define here (i.e. remove
DELAY_PORT).
OK.
Please take a look at the new version below.
(Changed only setup.S code, and some comments).
Martin
Signature · 202 lines
Martin Wilck Phone: +49 5251 8 15113 Fujitsu Siemens Computers Fax: +49 5251 8 20409 Heinz-Nixdorf-Ring 1 mailto:[email protected] D-33106 Paderborn http://www.fujitsu-siemens.com/primergy --- ./include/asm-i386/io.h.orig Fri Mar 15 17:23:15 2002 +++ ./include/asm-i386/io.h Fri Mar 15 18:30:03 2002 @@ -221,17 +221,9 @@ #endif /* __KERNEL__ */ -#ifdef SLOW_IO_BY_JUMPING -#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" -#else -#define __SLOW_DOWN_IO "\noutb %%al,$0x80" -#endif - -#ifdef REALLY_SLOW_IO -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO -#else -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO -#endif +/* Moved the __SLOW_DOWN_IO macros to a separate file + * that can be included by setup.S */ +#include <asm/iodelay.h> #ifdef CONFIG_MULTIQUAD extern void *xquad_portio; /* Where the IO area was mapped */ --- ./include/asm-i386/floppy.h.orig Fri Mar 15 17:23:15 2002 +++ ./include/asm-i386/floppy.h Fri Mar 15 17:55:04 2002 @@ -89,8 +89,7 @@ jmp 5f 4: movb (%2),%0 outb %b0,%w4 -5: decw %w4 - outb %0,$0x80 +5: decw %w4" __SLOW_DOWN_IO " decl %1 incl %2 testl %1,%1 --- ./include/asm-i386/iodelay.h.orig Fri Mar 15 18:31:01 2002 +++ ./include/asm-i386/iodelay.h Fri Mar 15 21:14:17 2002 @@ -0,0 +1,28 @@ +#ifndef _ASM_IODELAY_H +#define _ASM_IODELAY_H + +/* File suitable for inclusion by setup.S, normally included via <asm/io.h> */ + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else + +/* + * The dummy IO port to use for delays. + * Change only if you really know what you're doing + * Default value: 0x80 + * Other values that have been suggested: 0x19, 0x42, 0xe2, 0xed + * Both macros must be changed to modify all IO delays in the kernel. + */ + +#define __SLOW_DOWN_IO_PORT 0x80 +#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +#endif --- ./drivers/char/serial.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/char/serial.c Fri Mar 15 17:24:13 2002 @@ -3661,12 +3661,12 @@ scratch = serial_inp(info, UART_IER); serial_outp(info, UART_IER, 0); #ifdef __i386__ - outb(0xff, 0x080); + outb(0xff,__SLOW_DOWN_IO_PORT); #endif scratch2 = serial_inp(info, UART_IER); serial_outp(info, UART_IER, 0x0F); #ifdef __i386__ - outb(0, 0x080); + outb(0xff,__SLOW_DOWN_IO_PORT); #endif scratch3 = serial_inp(info, UART_IER); serial_outp(info, UART_IER, scratch); --- ./drivers/char/riscom8.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/char/riscom8.c Fri Mar 15 17:24:13 2002 @@ -278,10 +278,10 @@ /* Are the I/O ports here ? */ rc_out(bp, CD180_PPRL, 0x5a); - outb(0xff, 0x80); + outb(0xff, __SLOW_DOWN_IO_PORT); val1 = rc_in(bp, CD180_PPRL); rc_out(bp, CD180_PPRL, 0xa5); - outb(0x00, 0x80); + outb(0x00, __SLOW_DOWN_IO_PORT); val2 = rc_in(bp, CD180_PPRL); if ((val1 != 0x5a) || (val2 != 0xa5)) { --- ./drivers/scsi/atp870u.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/scsi/atp870u.c Fri Mar 15 17:24:13 2002 @@ -1042,7 +1042,7 @@ tmport = dev->ioport + 0x1b; outb(0x02, tmport); - outb(0, 0x80); + outb(0, __SLOW_DOWN_IO_PORT); val = 0x0080; /* bsy */ tmport = dev->ioport + 0x1c; @@ -1051,7 +1051,7 @@ outw(val, tmport); val |= 0x0004; /* msg */ outw(val, tmport); - inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ + inb(__SLOW_DOWN_IO_PORT); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ outw(val, tmport); mydlyu(0xffff); /* recommanded SCAM selection response time */ @@ -1062,7 +1062,7 @@ if ((inb(tmport) & 0x04) != 0) { goto wait_nomsg; } - outb(1, 0x80); + outb(1, __SLOW_DOWN_IO_PORT); mydlyu(100); for (n = 0; n < 0x30000; n++) { if ((inb(tmport) & 0x80) != 0) { /* bsy ? */ @@ -1078,13 +1078,13 @@ } goto TCM_SYNC; wait_io1: - inb(0x80); + inb(__SLOW_DOWN_IO_PORT); val |= 0x8003; /* io,cd,db7 */ outw(val, tmport); - inb(0x80); + inb(__SLOW_DOWN_IO_PORT); val &= 0x00bf; /* no sel */ outw(val, tmport); - outb(2, 0x80); + outb(2, __SLOW_DOWN_IO_PORT); TCM_SYNC: mydlyu(0x800); if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ @@ -1103,18 +1103,18 @@ val &= 0x00ff; /* synchronization */ val |= 0x3f00; fun_scam(dev, &val); - outb(3, 0x80); + outb(3, __SLOW_DOWN_IO_PORT); val &= 0x00ff; /* isolation */ val |= 0x2000; fun_scam(dev, &val); - outb(4, 0x80); + outb(4, __SLOW_DOWN_IO_PORT); i = 8; j = 0; TCM_ID: if ((inw(tmport) & 0x2000) == 0) { goto TCM_ID; } - outb(5, 0x80); + outb(5, __SLOW_DOWN_IO_PORT); val &= 0x00ff; /* get ID_STRING */ val |= 0x2000; k = fun_scam(dev, &val); --- ./drivers/video/sis/sis_main.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/video/sis/sis_main.c Fri Mar 15 17:27:16 2002 @@ -2308,7 +2308,7 @@ u8 reg; int nRes; - outb (0x77, 0x80); + outb (0x77, __SLOW_DOWN_IO_PORT); if (sisfb_off) return -ENXIO; --- ./arch/i386/boot/setup.S.orig Fri Mar 15 17:23:15 2002 +++ ./arch/i386/boot/setup.S Fri Mar 15 20:50:13 2002 @@ -54,6 +54,7 @@ #include <asm/boot.h> #include <asm/e820.h> #include <asm/page.h> +#include <asm/iodelay.h> /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55 @@ -1001,7 +1002,7 @@ # Delay is needed after doing I/O delay: - outb %al,$0x80 + outb %al,$__SLOW_DOWN_IO_PORT ret # Descriptor tables
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
In reply to Andreas DilgerQuoted 8 lines · Martin Wilck
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+#define __SLOW_DOWN_IO_PORT 0x80 +#define __SLOW_DOWN_IO "\noutb %%al,$0x80"You may want to change the above to:
#define__SLOW_DOWN_IO_ASM"\noutb %%al,$__SLOW_DOWN_IO_PORT"Won't work, cpp doesn't substitute between double quotes. (at least the one I'm using). Or am I gettimng something wrong here??
As long as __SLOW_DOWN_IO_PORT is a simple constant, you can just use this instead:
#define __SLOW_DOWN_IO_ASM "\noutb %%al,$" #__SLOW_DOWN_IO_PORT
-- Jamie
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
Quoted 4 lines · Jamie Lokier
As long as
__SLOW_DOWN_IO_PORTis a simple constant, you can just use this instead:#define __SLOW_DOWN_IO_ASM "\noutb %%al,$" #__SLOW_DOWN_IO_PORT
What cpp are you guys using? Mine does stringification (#s) only with arguments of function-like macros. However
#define __SLOW_DOWN_IO_P(p) "\noutb %%al,%" #p #define __SLOW_DOWN_IO __SLOW_DOWN_IO(__SLOW_DOWN_IO_PORT)
won't work, either, because cpp does not recursively substitute macros for stringification, so in the above _SLOW_DOWN_IO wuold evaluate as "\noutb %%al,$__SLOW_DOWN_IO_PORT" - bad.
I have tried a number of things to make this a single cpp line, but they all don't work. The only way would be to change the way the inb_p ... macros are coded.
It is possible to write
#define __SLOW_DOWN_IO __asm__ ("outb %%al, %0" : : "i" (__SLOW_DOWN_IO_PORT));
but only if one modifies the definitions of inb_p etc which are so complex that I don't dare touch them now.
Please note that, as an intermediate solution, my patch reduces explicit usage of the constant 0x80 from ~20 in 8 different source files to 2 immediately following each other in 1 source file.
Martin
Signature · 4 lines
Martin Wilck Phone: +49 5251 8 15113 Fujitsu Siemens Computers Fax: +49 5251 8 20409 Heinz-Nixdorf-Ring 1 mailto:[email protected] D-33106 Paderborn http://www.fujitsu-siemens.com/primergy
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
Quoted 9 lines · Martin Wilck
Quoted 4 lines · Jamie Lokier
As long as
__SLOW_DOWN_IO_PORTis a simple constant, you can just use this instead:#define __SLOW_DOWN_IO_ASM "\noutb %%al,$" #__SLOW_DOWN_IO_PORTWhat cpp are you guys using? Mine does stringification (#s) only with arguments of function-like macros. However
Recent 2.4 and 2.5 kernels have include/linux/stringify.h. This should work.
#define __SLOW_DOWN_IO_ASM "\noutb %%al,$" __stringify(__SLOW_DOWN_IO_PORT)
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
Quoted 2 lines · Keith Owens
Recent 2.4 and 2.5 kernels have
include/linux/stringify.h. This should work.
OK, that's it. Thanks a lot Keith!
Please find the new patch below.
Martin
Signature · 199 lines
Martin Wilck Phone: +49 5251 8 15113 Fujitsu Siemens Computers Fax: +49 5251 8 20409 Heinz-Nixdorf-Ring 1 mailto:[email protected] D-33106 Paderborn http://www.fujitsu-siemens.com/primergy --- ./include/asm-i386/io.h.orig Fri Mar 15 17:23:15 2002 +++ ./include/asm-i386/io.h Fri Mar 15 18:30:03 2002 @@ -221,17 +221,9 @@ #endif /* __KERNEL__ */ -#ifdef SLOW_IO_BY_JUMPING -#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" -#else -#define __SLOW_DOWN_IO "\noutb %%al,$0x80" -#endif - -#ifdef REALLY_SLOW_IO -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO -#else -#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO -#endif +/* Moved the __SLOW_DOWN_IO macros to a separate file + * that can be included by setup.S */ +#include <asm/iodelay.h> #ifdef CONFIG_MULTIQUAD extern void *xquad_portio; /* Where the IO area was mapped */ --- ./include/asm-i386/floppy.h.orig Fri Mar 15 17:23:15 2002 +++ ./include/asm-i386/floppy.h Fri Mar 15 17:55:04 2002 @@ -89,8 +89,7 @@ jmp 5f 4: movb (%2),%0 outb %b0,%w4 -5: decw %w4 - outb %0,$0x80 +5: decw %w4" __SLOW_DOWN_IO " decl %1 incl %2 testl %1,%1 --- ./include/asm-i386/iodelay.h.orig Fri Mar 15 18:31:01 2002 +++ ./include/asm-i386/iodelay.h Mon Mar 18 12:17:20 2002 @@ -0,0 +1,25 @@ +#ifndef _ASM_IODELAY_H +#define _ASM_IODELAY_H + +/* + * The dummy IO port to use for delays. + * Change only if you really know what you're doing !! + * Default value: 0x80. + * Other values that have been suggested: 0x19, 0x42, 0xe2, 0xed. + */ +#define __SLOW_DOWN_IO_PORT 0x80 + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else +#include <linux/stringify.h> +#define __SLOW_DOWN_IO "\noutb %%al,$" __stringify(__SLOW_DOWN_IO_PORT) +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +#endif --- ./drivers/char/serial.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/char/serial.c Fri Mar 15 17:24:13 2002 @@ -3661,12 +3661,12 @@ scratch = serial_inp(info, UART_IER); serial_outp(info, UART_IER, 0); #ifdef __i386__ - outb(0xff, 0x080); + outb(0xff,__SLOW_DOWN_IO_PORT); #endif scratch2 = serial_inp(info, UART_IER); serial_outp(info, UART_IER, 0x0F); #ifdef __i386__ - outb(0, 0x080); + outb(0xff,__SLOW_DOWN_IO_PORT); #endif scratch3 = serial_inp(info, UART_IER); serial_outp(info, UART_IER, scratch); --- ./drivers/char/riscom8.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/char/riscom8.c Fri Mar 15 17:24:13 2002 @@ -278,10 +278,10 @@ /* Are the I/O ports here ? */ rc_out(bp, CD180_PPRL, 0x5a); - outb(0xff, 0x80); + outb(0xff, __SLOW_DOWN_IO_PORT); val1 = rc_in(bp, CD180_PPRL); rc_out(bp, CD180_PPRL, 0xa5); - outb(0x00, 0x80); + outb(0x00, __SLOW_DOWN_IO_PORT); val2 = rc_in(bp, CD180_PPRL); if ((val1 != 0x5a) || (val2 != 0xa5)) { --- ./drivers/scsi/atp870u.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/scsi/atp870u.c Fri Mar 15 17:24:13 2002 @@ -1042,7 +1042,7 @@ tmport = dev->ioport + 0x1b; outb(0x02, tmport); - outb(0, 0x80); + outb(0, __SLOW_DOWN_IO_PORT); val = 0x0080; /* bsy */ tmport = dev->ioport + 0x1c; @@ -1051,7 +1051,7 @@ outw(val, tmport); val |= 0x0004; /* msg */ outw(val, tmport); - inb(0x80); /* 2 deskew delay(45ns*2=90ns) */ + inb(__SLOW_DOWN_IO_PORT); /* 2 deskew delay(45ns*2=90ns) */ val &= 0x007f; /* no bsy */ outw(val, tmport); mydlyu(0xffff); /* recommanded SCAM selection response time */ @@ -1062,7 +1062,7 @@ if ((inb(tmport) & 0x04) != 0) { goto wait_nomsg; } - outb(1, 0x80); + outb(1, __SLOW_DOWN_IO_PORT); mydlyu(100); for (n = 0; n < 0x30000; n++) { if ((inb(tmport) & 0x80) != 0) { /* bsy ? */ @@ -1078,13 +1078,13 @@ } goto TCM_SYNC; wait_io1: - inb(0x80); + inb(__SLOW_DOWN_IO_PORT); val |= 0x8003; /* io,cd,db7 */ outw(val, tmport); - inb(0x80); + inb(__SLOW_DOWN_IO_PORT); val &= 0x00bf; /* no sel */ outw(val, tmport); - outb(2, 0x80); + outb(2, __SLOW_DOWN_IO_PORT); TCM_SYNC: mydlyu(0x800); if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ @@ -1103,18 +1103,18 @@ val &= 0x00ff; /* synchronization */ val |= 0x3f00; fun_scam(dev, &val); - outb(3, 0x80); + outb(3, __SLOW_DOWN_IO_PORT); val &= 0x00ff; /* isolation */ val |= 0x2000; fun_scam(dev, &val); - outb(4, 0x80); + outb(4, __SLOW_DOWN_IO_PORT); i = 8; j = 0; TCM_ID: if ((inw(tmport) & 0x2000) == 0) { goto TCM_ID; } - outb(5, 0x80); + outb(5, __SLOW_DOWN_IO_PORT); val &= 0x00ff; /* get ID_STRING */ val |= 0x2000; k = fun_scam(dev, &val); --- ./drivers/video/sis/sis_main.c.orig Fri Mar 15 17:23:15 2002 +++ ./drivers/video/sis/sis_main.c Fri Mar 15 17:27:16 2002 @@ -2308,7 +2308,7 @@ u8 reg; int nRes; - outb (0x77, 0x80); + outb (0x77, __SLOW_DOWN_IO_PORT); if (sisfb_off) return -ENXIO; --- ./arch/i386/boot/setup.S.orig Fri Mar 15 17:23:15 2002 +++ ./arch/i386/boot/setup.S Fri Mar 15 20:50:13 2002 @@ -54,6 +54,7 @@ #include <asm/boot.h> #include <asm/e820.h> #include <asm/page.h> +#include <asm/iodelay.h> /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55 @@ -1001,7 +1002,7 @@ # Delay is needed after doing I/O delay: - outb %al,$0x80 + outb %al,$__SLOW_DOWN_IO_PORT ret # Descriptor tables
Re: [PATCH] Cleanup port 0x80 use (was: Re: IO delay ...)
In reply to Jamie LokierQuoted 7 lines · Martin Wilck
Quoted 4 lines
As long as
__SLOW_DOWN_IO_PORTis a simple constant, you can just use this instead:#define __SLOW_DOWN_IO_ASM "\noutb %%al,$" #__SLOW_DOWN_IO_PORTWhat cpp are you guys using? Mine does stringification (#s) only with arguments of function-like macros.
You're right, my error. You need to use an argument, as has already been pointed out -- <linux/stringify.h>.
-- Jamie