Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
6509fa93
Commit
6509fa93
authored
Jun 26, 2001
by
Uwe Bonnes
Committed by
Alexandre Julliard
Jun 26, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added /dev/parport support for direct port access.
parent
94463871
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
339 additions
and
4 deletions
+339
-4
configure
configure
+0
-0
configure.in
configure.in
+13
-0
config
documentation/samples/config
+8
-0
config.h.in
include/config.h.in
+3
-3
miscemu.h
include/miscemu.h
+6
-0
Makefile.in
msdos/Makefile.in
+1
-0
ioports.c
msdos/ioports.c
+20
-1
ppdev.c
msdos/ppdev.c
+288
-0
No files found.
configure
View file @
6509fa93
This diff is collapsed.
Click to expand it.
configure.in
View file @
6509fa93
...
...
@@ -430,6 +430,19 @@ fi
AC_SUBST(FREETYPELIBS)
AC_SUBST(FREETYPEINCL)
dnl **** Check for parport (currently Linux only) ****
AC_CACHE_CHECK("for parport header/ppdev.h", ac_cv_c_ppdev,
AC_TRY_COMPILE(
[#include <linux/ppdev.h>],
[ioctl (1,PPCLAIM,0)],
[ac_cv_c_ppdev="yes"],
[ac_cv_c_ppdev="no"])
)
if test "$ac_cv_c_ppdev" = "yes"
then
AC_DEFINE(HAVE_PPDEV,1,[Define if we can use ppdev.h for parallel port access])
fi
dnl **** Check for IPX (currently Linux only) ****
AC_CACHE_CHECK("for GNU style IPX support", ac_cv_c_ipx_gnu,
AC_TRY_COMPILE(
...
...
documentation/samples/config
View file @
6509fa93
...
...
@@ -167,6 +167,14 @@ WINE REGISTRY Version 2
[parallelports]
"Lpt1" = "/dev/lp0"
[ppdev]
;; key: io-base of the emulated port
;; value : parport-device{,timeout}
;; timeout for auto closing an open device ( not yet implemented)
;"378" = "/dev/parport0"
;"278" = "/dev/parport1"
;"3bc" = "/dev/parport2"
[spooler]
"FILE:" = "tmp.ps"
"LPT1:" = "|lpr"
...
...
include/config.h.in
View file @
6509fa93
...
...
@@ -40,9 +40,6 @@
/* Define if the X Window System is missing or not being used. */
#undef X_DISPLAY_MISSING
/* Define if lex declares yytext as a char * by default, not a char[]. */
#undef YYTEXT_POINTER
/* Define if .type asm directive must be inside a .def directive */
#undef NEED_TYPE_IN_DEF
...
...
@@ -526,6 +523,9 @@
/* Define if you have the xpg4 library (-lxpg4). */
#undef HAVE_LIBXPG4
/* Define if we can use ppdev.h for parallel port access */
#undef HAVE_PPDEV
/* Set this to 64 to enable 64-bit file support on Linux */
#undef _FILE_OFFSET_BITS
include/miscemu.h
View file @
6509fa93
...
...
@@ -249,6 +249,12 @@ extern void WINAPI XMS_Handler(CONTEXT86*);
/* misc/aspi.c */
extern
void
ASPI_DOS_HandleInt
(
CONTEXT86
*
context
);
/* misc/ppdev.c */
extern
BOOL
IO_pp_outp
(
int
port
,
DWORD
*
res
);
extern
int
IO_pp_inp
(
int
port
,
DWORD
*
res
);
extern
char
IO_pp_init
(
void
);
#define PTR_REAL_TO_LIN(seg,off) \
((void*)(((unsigned int)(seg) << 4) + LOWORD(off)))
...
...
msdos/Makefile.in
View file @
6509fa93
...
...
@@ -36,6 +36,7 @@ C_SRCS = \
int5c.c
\
interrupts.c
\
ioports.c
\
ppdev.c
\
vga.c
\
vxd.c
...
...
msdos/ioports.c
View file @
6509fa93
...
...
@@ -62,13 +62,17 @@ static BYTE cmosimage[64] =
# define DIRECT_IO_ACCESS
#else
# undef DIRECT_IO_ACCESS
# undef PP_IO_ACCESS
#endif
/* linux && __i386__ */
#ifdef DIRECT_IO_ACCESS
extern
int
iopl
(
int
level
);
static
char
do_direct_port_access
=
-
1
;
#ifdef HAVE_PPDEV
static
char
do_pp_port_access
=
-
1
;
/* -1: uninitialized, 1: not available
0: available);*/
#endif
static
char
port_permissions
[
0x10000
];
#define IO_READ 1
...
...
@@ -258,6 +262,13 @@ DWORD IO_inport( int port, int size )
TRACE
(
"%d-byte value from port 0x%02x
\n
"
,
size
,
port
);
#ifdef HAVE_PPDEV
if
(
do_pp_port_access
==
-
1
)
do_pp_port_access
=
IO_pp_init
();
if
((
do_pp_port_access
==
0
)
&&
(
size
==
1
))
if
(
!
IO_pp_inp
(
port
,
&
res
))
return
res
;
#endif
#ifdef DIRECT_IO_ACCESS
if
(
do_direct_port_access
==
-
1
)
IO_port_init
();
if
((
do_direct_port_access
)
...
...
@@ -371,7 +382,15 @@ void IO_outport( int port, int size, DWORD value )
TRACE
(
"IO: 0x%lx (%d-byte value) to port 0x%02x
\n
"
,
value
,
size
,
port
);
#ifdef HAVE_PPDEV
if
(
do_pp_port_access
==
-
1
)
do_pp_port_access
=
IO_pp_init
();
if
((
do_pp_port_access
==
0
)
&&
(
size
==
1
))
if
(
!
IO_pp_outp
(
port
,
&
value
))
return
;
#endif
#ifdef DIRECT_IO_ACCESS
if
(
do_direct_port_access
==
-
1
)
IO_port_init
();
if
((
do_direct_port_access
)
/* Make sure we have access to the port */
...
...
msdos/ppdev.c
0 → 100644
View file @
6509fa93
/*
* Parallel-port device support
*/
#include "config.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
int
);
#ifdef HAVE_PPDEV
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <linux/ppdev.h>
#include "winerror.h"
#include "winreg.h"
typedef
struct
_PPDEVICESTRUCT
{
int
fd
;
/* NULL if device not available */
char
*
devicename
;
int
userbase
;
/* where wine thinks the ports are*/
DWORD
lastaccess
;
/* or NULL if release */
int
timeout
;
/* time in second of inactivity to release the port*/
}
PPDeviceStruct
;
static
PPDeviceStruct
PPDeviceList
[
5
];
static
int
PPDeviceNum
=
0
;
static
int
IO_pp_sort
(
const
void
*
p1
,
const
void
*
p2
)
{
return
((
PPDeviceStruct
*
)
p1
)
->
userbase
-
((
PPDeviceStruct
*
)
p2
)
->
userbase
;
}
/* IO_pp_init
*
* Read the ppdev entries from wine.conf, open the device and check
* for nescessary IOCTRL
* Report verbose about possible errors
*/
char
IO_pp_init
(
void
)
{
char
name
[
80
];
char
buffer
[
1024
];
HKEY
hkey
;
char
temp
[
256
];
int
i
,
idx
=
0
,
fd
,
res
,
userbase
,
nports
=
0
;
char
*
timeout
;
char
ret
=
1
;
int
lasterror
;
TRACE
(
"
\n
"
);
if
(
RegOpenKeyA
(
HKEY_LOCAL_MACHINE
,
"Software
\\
Wine
\\
Wine
\\
Config
\\
ppdev"
,
&
hkey
)
!=
ERROR_SUCCESS
)
return
1
;
for
(;;)
{
DWORD
type
,
count
=
sizeof
(
buffer
),
name_len
=
sizeof
(
name
);
if
(
RegEnumValueA
(
hkey
,
idx
,
name
,
&
name_len
,
NULL
,
&
type
,
buffer
,
&
count
)
!=
ERROR_SUCCESS
)
break
;
idx
++
;
if
(
nports
>
4
)
{
FIXME
(
"Make the PPDeviceList larger then 5 elements
\n
"
);
break
;
}
TRACE
(
"Device '%s' at virtual userbase '%s'
\n
"
,
buffer
,
name
);
timeout
=
strchr
(
buffer
,
','
);
if
(
timeout
)
*
timeout
++=
0
;
fd
=
open
(
buffer
,
O_RDWR
);
lasterror
=
errno
;
if
(
fd
==
-
1
)
{
WARN
(
"Configuration: No access to %s Cause: %s
\n
"
,
buffer
,
strerror
(
lasterror
));
WARN
(
"Rejecting configuration item
\n
"
);
if
(
lasterror
==
ENODEV
)
FIXME
(
"Is the ppdev module loaded?
\n
"
);
continue
;
}
userbase
=
strtol
(
name
,(
char
**
)
NULL
,
16
);
if
(
errno
==
ERANGE
)
{
WARN
(
"Configuration: Invalid base %s for %s
\n
"
,
name
,
buffer
);
WARN
(
"Rejecting configuration item
\n
"
);
continue
;
}
if
(
ioctl
(
fd
,
PPEXCL
,
0
))
{
ERR
(
"PPEXCL IOCTL rejected for device %s
\n
"
,
buffer
);
ERR
(
"Check that PPDEV module is loaded!
\n
"
);
ERR
(
"Perhaps the device is already in use or non-existant
\n
"
);
continue
;
}
if
(
ioctl
(
fd
,
PPCLAIM
,
0
))
{
ERR
(
"PPCLAIM rejected %s
\n
"
,
buffer
);
ERR
(
"Perhaps the device is already in use or non-existant
\n
"
);
continue
;
}
if
(
nports
>
0
)
{
for
(
i
=
0
;
i
<=
nports
;
i
++
)
{
if
(
PPDeviceList
[
i
].
userbase
==
userbase
)
{
WARN
(
"Configuration: %s uses the same virtual ports as %s
\n
"
,
buffer
,
PPDeviceList
[
0
].
devicename
);
WARN
(
"Configuration: Rejecting configuration item"
);
userbase
=
0
;
break
;
}
}
if
(
!
userbase
)
continue
;
}
/* Check for the minimum required IOCTLS */
if
((
ioctl
(
fd
,
PPRDATA
,
&
res
))
||
(
ioctl
(
fd
,
PPRCONTROL
,
&
res
))
||
(
ioctl
(
fd
,
PPRCONTROL
,
&
res
)))
{
ERR
(
"PPUSER IOCTL not available for parport device %s
\n
"
,
temp
);
continue
;
}
PPDeviceList
[
nports
].
devicename
=
malloc
(
sizeof
(
buffer
)
+
1
);
if
(
!
PPDeviceList
[
nports
].
devicename
)
{
ERR
(
"No (more)space for devicename
\n
"
);
break
;
}
strcpy
(
PPDeviceList
[
nports
].
devicename
,
buffer
);
PPDeviceList
[
nports
].
fd
=
fd
;
PPDeviceList
[
nports
].
userbase
=
userbase
;
PPDeviceList
[
nports
].
lastaccess
=
GetTickCount
();
if
(
timeout
)
{
PPDeviceList
[
nports
].
timeout
=
strtol
(
timeout
,(
char
**
)
NULL
,
10
);
if
(
errno
==
ERANGE
)
{
WARN
(
"Configuration:Invalid timeout %s in configuration for %s, Setting to 0
\n
"
,
timeout
,
buffer
);
PPDeviceList
[
nports
].
timeout
=
0
;
}
}
else
PPDeviceList
[
nports
].
timeout
=
0
;
nports
++
;
}
TRACE
(
"found %d ports
\n
"
,
nports
);
RegCloseKey
(
hkey
);
PPDeviceNum
=
nports
;
if
(
nports
>
1
)
/* sort in accending order for userbase for faster access*/
qsort
(
PPDeviceList
,
PPDeviceNum
,
sizeof
(
PPDeviceStruct
),
IO_pp_sort
);
if
(
nports
)
ret
=
0
;
for
(
idx
=
0
;
idx
<
PPDeviceNum
;
idx
++
)
TRACE
(
"found device %s userbase %x fd %x timeout %d
\n
"
,
PPDeviceList
[
idx
].
devicename
,
PPDeviceList
[
idx
].
userbase
,
PPDeviceList
[
idx
].
fd
,
PPDeviceList
[
idx
].
timeout
);
/* FIXME:
register a timer callback perhaps every 30 second to release unused ports
Set lastaccess = 0 as indicator when port was released
*/
return
ret
;
}
/* IO_pp_do_access
*
* Do the actual IOCTL
* Return NULL on success
*/
static
int
IO_pp_do_access
(
int
idx
,
int
ppctl
,
DWORD
*
res
)
{
if
(
!
PPDeviceList
[
idx
].
lastaccess
)
/* TIMER callback has released the device after some time of inactivity
Reclaim the device
!!!!!!THIS MAY UNINTERRUPTIPLE BLOCK IF SOME OTHER DEVICE
!!!!!! HAS CLAIMED THE SAME PORT
*/
if
(
ioctl
(
PPDeviceList
[
idx
].
fd
,
PPCLAIM
,
0
))
{
ERR
(
"Can't reclaim device %s, PPUSER/PPDEV handling confused
\n
"
,
PPDeviceList
[
idx
].
devicename
);
return
1
;
}
PPDeviceList
[
idx
].
lastaccess
=
GetTickCount
();
return
ioctl
(
PPDeviceList
[
idx
].
fd
,
ppctl
,
res
);
}
/* IO_pp_inp
*
* Check if we can satisfy the INP command with some of the configured PPDEV deviced
* Return NULL on success
*/
int
IO_pp_inp
(
int
port
,
DWORD
*
res
)
{
int
idx
,
j
=
0
;
for
(
idx
=
0
;
idx
<
PPDeviceNum
;
idx
++
)
{
j
=
port
-
PPDeviceList
[
idx
].
userbase
;
if
(
j
<
0
)
return
1
;
switch
(
j
)
{
case
0
:
return
IO_pp_do_access
(
idx
,
PPRDATA
,
res
);
case
1
:
return
IO_pp_do_access
(
idx
,
PPRSTATUS
,
res
);
case
2
:
return
IO_pp_do_access
(
idx
,
PPRCONTROL
,
res
);
case
0x400
:
case
0x402
:
case
3
:
case
4
:
case
0x401
:
FIXME
(
"Port 0x%x not accessible for reading with ppdev
\n
"
,
port
);
FIXME
(
"If this is causing problems, try direct port access
\n
"
);
return
1
;
default:
break
;
}
}
return
1
;
}
/* IO_pp_outp
*
* Check if we can satisfy the INP command with some of the configured PPDEV deviced
* Return NULL on success
*/
BOOL
IO_pp_outp
(
int
port
,
DWORD
*
res
)
{
int
idx
,
j
=
0
;
for
(
idx
=
0
;
idx
<
PPDeviceNum
;
idx
++
)
{
j
=
port
-
PPDeviceList
[
idx
].
userbase
;
if
(
j
<
0
)
return
1
;
switch
(
j
)
{
case
0
:
return
IO_pp_do_access
(
idx
,
PPWDATA
,
res
);
case
2
:
return
IO_pp_do_access
(
idx
,
PPWCONTROL
,
res
);
case
1
:
case
0x400
:
case
0x402
:
case
3
:
case
4
:
case
0x401
:
FIXME
(
"Port %d not accessible for writing with ppdev
\n
"
,
port
);
FIXME
(
"If this is causing problems, try direct port access
\n
"
);
return
1
;
default:
break
;
}
}
return
TRUE
;
}
#else
/* HAVE_PPDEV */
char
IO_pp_init
(
void
)
{
return
1
;
}
int
IO_pp_inp
(
int
port
,
DWORD
*
res
)
{
return
1
;
}
BOOL
IO_pp_outp
(
int
port
,
DWORD
*
res
)
{
return
TRUE
;
}
#endif
/* HAVE_PPDEV */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment