Tech Support > Microsoft Windows > Drivers > Writing to ports
Writing to ports
Posted by Jon Slaughter on September 27th, 2007


I'm trying to speed up reads and writes to the parallel port.

The idea is that instead of writing/reading each register of the port
sequentially I'll read them all at once.

Since I'm using SPP mode there are 3 registers squentially located.

Suppose the base port is B which is also the data register. The Status is B
+ 1 and the Control is B + 2.

What I'd like to do is read/write all them at once using XXXX_PORT_ULONG.

So there is a problem here because I will be reading/writing to B + 3 too.
Now B + 3 is usually going to be the address register in EPP mode.

I'm unsure if this will cause problems? I know one can set the mode of the
port to SPP but it seems risky reading/writing to B + 3 in that it could
cause some big problems? I suppose I can do some tests it and see but
thought I might as well ask too.

Thanks,
Jon


Posted by Ivan Brugiolo [MSFT] on September 28th, 2007


This is not going to fly in general.
You can read if yourself from `253665.pdf`.
I'm pasting here the relevant excerpt.
In any case, the parallel port is so slow, and the CPU so
fast these days, that I would be surprised if any difference can be
measured.

The processor's I/O address space is separate and distinct from the
physical-memory

address space. The I/O address space consists of 216 (64K) individually
addressable

8-bit I/O ports, numbered 0 through FFFFH. I/O port addresses 0F8H through
0FFH

are reserved. Do not assign I/O ports to these addresses. The result of an
attempt to

address beyond the I/O address space limit of FFFFH is
implementation-specific; see

the Developer's Manuals for specific processors for more details.

Any two consecutive 8-bit ports can be treated as a 16-bit port, and any
four consecutive

ports can be a 32-bit port. In this manner, the processor can transfer 8,
16, or

32 bits to or from a device in the I/O address space. Like words in memory,
16-bit

ports should be aligned to even addresses (0, 2, 4, ...) so that all 16 bits
can be

transferred in a single bus cycle. Likewise, 32-bit ports should be aligned
to

addresses that are multiples of four (0, 4, 8, ...). The processor supports
data transfers

to unaligned ports, but there is a performance penalty because one or more

extra bus cycle must be used.

The exact order of bus cycles used to access unaligned ports is undefined
and is not

guaranteed to remain the same in future IA-32 processors. If hardware or
software

requires that I/O ports be written to in a particular order, that order must
be specified

explicitly. For example, to load a word-length I/O port at address 2H and
then

another word port at 4H, two word-length writes must be used, rather than a
single

doubleword write at 2H.

Note that the processor does not mask parity errors for bus cycles to the
I/O address

space. Accessing I/O ports through the I/O address space is thus a possible
source of

parity errors.


--

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"Jon Slaughter" <Jon_Slaughter@Hotmail.com> wrote in message
news:aiUKi.52207$Um6.15803@newssvr12.news.prodigy. net...


Posted by Tim Roberts on September 29th, 2007


"Jon Slaughter" <Jon_Slaughter@Hotmail.com> wrote:
To what? 2 MB/s is the best you can do.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Posted by Jon Slaughter on September 29th, 2007



"Tim Roberts" <timr@probo.com> wrote in message
news:meprf351mc59hio215u5nr8li6adp10fu8@4ax.com...

using Inpout32 Library which essentially just exports WRITE/READ_PORT_UCHAR
to usermode gives me a maximum of rate of about 150khz. In unmanaged C++
this goes up to 330khz. What this means is that a read/write takes about
3us or more.

The lower the better. What I'm trying to do now is move all the work into
the kernel mode driver to avoid any latencies due switches from managed to
unmanaged and user mode to kernel mode.

I'm about 80% finished with the kernel mode driver but it is unoptimized.
One of problems of writing to the ports sequentially is that its possible
that it will introduce a sufficient delay to cause problems. (specially if
there is a task switch inbetween the two)

I'm just trying to avoid any potential issues that might creep up and cause
some hard to find bugs.

Thanks,
Jon



Posted by Jon Slaughter on September 29th, 2007



"Ivan Brugiolo [MSFT]" <ivanbrug@online.microsoft.com> wrote in message
news:%231UD8$ZAIHA.484@TK2MSFTNGP06.phx.gbl...
Not going to fly?

In any case its better to write to the all the registers if one is to modify
them than sequentially because its possible that a task switch might occur
inbetween causing some timing issues. (It shouldn't be a problem but could
be)

I don't think I understand this. What does parity errors have to do with it?
As far as I can tell, what you posted doesn't say anything about why writing
more than a byte to a port is bad.

Thanks,
Jon



Posted by Ivan Brugiolo [MSFT] on September 29th, 2007


In the general case it leads to undefined behaviors,
depending on the address of the port, the size of the registers,
the contiguity of the registers, and the device itself.
In the ISA bus days, all of the above were indeed true.

And, as others pointed out, before you optimize there,
you might have other areas to touch.
--

--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"Jon Slaughter" <Jon_Slaughter@Hotmail.com> wrote in message
news:5qyLi.3343$6p6.2669@newssvr25.news.prodigy.ne t...


Posted by Sergei V on September 30th, 2007


To do so you must be sure that parallel port controller's registers
are mapped (hard-wired) on the parallel bus
and permit for simultaneous r/w.
I do not know, if it is so in your case, but old days it was *not* so.
Parallel port controller had a 8bit-wide bus and registers had to be
read-written one at a time.
So, programmatically your idea seems to be good, but
with hardware you might be less lucky.

My advise: don't do it.
Cheers,
Sergei.


"Jon Slaughter" wrote