From c72f813a4c6a1339db01d28275648eb307ae19ec Mon Sep 17 00:00:00 2001 From: robijn Date: Fri, 4 Apr 2003 22:53:16 +0000 Subject: [PATCH] Changed things around port.h a bit: - port_access_full is now called port_access_multiple and has a count parameter (LPT port stuff should be in lpt-port.h) - Updated calling source files too - Added support for ports in higher range, so that PCI LPT cards will work too (but I can't test this myself...) - Enhanced formatting of in-file documentation a bit - Updated docs of port.h in lcdproc-dev --- configure.in | 1 + docs/lcdproc-dev/make-driver.docbook | 15 ++- server/drivers/hd44780-4bit.c | 4 +- server/drivers/hd44780-ext8bit.c | 4 +- server/drivers/hd44780-serialLpt.c | 4 +- server/drivers/hd44780-winamp.c | 4 +- server/drivers/port.h | 183 ++++++++++++++++----------- server/drivers/t6963.c | 4 +- 8 files changed, 127 insertions(+), 92 deletions(-) diff --git a/configure.in b/configure.in index e185df9..2d59a55 100644 --- a/configure.in +++ b/configure.in @@ -113,6 +113,7 @@ AC_CHECK_LIB(i386, i386_get_ioperm, [])] ) +AC_CHECK_FUNCS(iopl) AC_CHECK_FUNCS(ioperm) AC_CHECK_HEADERS(sys/io.h) diff --git a/docs/lcdproc-dev/make-driver.docbook b/docs/lcdproc-dev/make-driver.docbook index 8805b36..c00f81a 100644 --- a/docs/lcdproc-dev/make-driver.docbook +++ b/docs/lcdproc-dev/make-driver.docbook @@ -87,26 +87,27 @@ Of course, these functions will only work if the computer where LCDproc runs has - -Get access to three sequential ports + +Get access to multiple sequential ports -/* port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ static inline int port_access_full unsigned short int port + unsigned short int count Returns 0 if successful, -1 if failed. - -Close access to three sequential ports + +Close access to multiple sequential ports static inline int port_deny_full unsigned short int port + unsigned short int count Returns 0 if successful, -1 if failed. @@ -123,7 +124,7 @@ Of course, these functions will only work if the computer where LCDproc runs has 0x379 (STATUS) and 0x37A (DATA) */ -if ( -1 == port_access_full(0x378) ) { +if ( -1 == port_access_multiple(0x378,3) ) { /* Access denied, do something */ } @@ -134,7 +135,7 @@ ort_out(0x378, 'A'); char status = port_in(0x379); /* Close the 3 ports */ -port_deny_full(0x378); +port_deny_multiple(0x378,3); diff --git a/server/drivers/hd44780-4bit.c b/server/drivers/hd44780-4bit.c index a8eba30..3679989 100644 --- a/server/drivers/hd44780-4bit.c +++ b/server/drivers/hd44780-4bit.c @@ -102,9 +102,7 @@ hd_init_4bit (Driver *drvthis) int enableLines = EN1 | EN2; // Reserve the port registers - port_access(p->port); - port_access(p->port+1); - port_access(p->port+2); + port_access_multiple(p->port,3); hd44780_functions->senddata = lcdstat_HD44780_senddata; hd44780_functions->backlight = lcdstat_HD44780_backlight; diff --git a/server/drivers/hd44780-ext8bit.c b/server/drivers/hd44780-ext8bit.c index 23caadb..084fa77 100644 --- a/server/drivers/hd44780-ext8bit.c +++ b/server/drivers/hd44780-ext8bit.c @@ -90,9 +90,7 @@ hd_init_ext8bit (Driver *drvthis) semid = sem_get (); // Reserve the port registers - port_access(p->port); - port_access(p->port+1); - port_access(p->port+2); + port_access_multiple(p->port,3); hd44780_functions->senddata = lcdtime_HD44780_senddata; hd44780_functions->backlight = lcdtime_HD44780_backlight; diff --git a/server/drivers/hd44780-serialLpt.c b/server/drivers/hd44780-serialLpt.c index d3792f0..d791aa7 100644 --- a/server/drivers/hd44780-serialLpt.c +++ b/server/drivers/hd44780-serialLpt.c @@ -81,9 +81,7 @@ hd_init_serialLpt (Driver *drvthis) unsigned char enableLines = EN1 | EN2; // Reserve the port registers - port_access(p->port); - port_access(p->port+1); - port_access(p->port+2); + port_access_multiple(p->port,3); hd44780_functions->senddata = lcdserLpt_HD44780_senddata; hd44780_functions->backlight = lcdserLpt_HD44780_backlight; diff --git a/server/drivers/hd44780-winamp.c b/server/drivers/hd44780-winamp.c index c916cfd..1235107 100644 --- a/server/drivers/hd44780-winamp.c +++ b/server/drivers/hd44780-winamp.c @@ -98,9 +98,7 @@ hd_init_winamp (Driver *drvthis) HD44780_functions *hd44780_functions = p->hd44780_functions; // Reserve the port registers - port_access(p->port); - port_access(p->port+1); - port_access(p->port+2); + port_access_multiple(p->port,3); hd44780_functions->senddata = lcdwinamp_HD44780_senddata; hd44780_functions->backlight = lcdwinamp_HD44780_backlight; diff --git a/server/drivers/port.h b/server/drivers/port.h index fd9a179..1e579ff 100644 --- a/server/drivers/port.h +++ b/server/drivers/port.h @@ -12,34 +12,40 @@ * (Better) FreeBSD port by Guillaume Filion, copyright 05/2002 * * Improved support for old Linux (glibc1 and libc5) by Guillaume Filion, 12/2002 + * + * Access to ports over 0x3FF by Joris Robijn, 04/2003 + * */ /* This file defines 6 static inline functions for port I/O: -Read a byte from port - static inline int port_in (unsigned short int port); -Returns the content of the byte. +static inline int port_in (unsigned short port); + Read a byte from port + Returns the content of the byte. -Write a char(byte) 'val' to port. - static inline void port_out (unsigned short int port, unsigned char val); -Returns nothing. +static inline void port_out (unsigned short port, unsigned char val); + Write a char(byte) 'val' to port. + Returns nothing. -Get access to a specific port - static inline int port_access (unsigned short int port); -Returns 0 if successful, -1 if failed +static inline int port_access (unsigned short port); + Get access to a specific port + Returns 0 if successful, -1 if failed -Close access to a specific port - static inline int port_deny (unsigned short int port); -Returns 0 if successful, -1 if failed +static inline int port_deny (unsigned short port); + Close access to a specific port + Returns 0 if successful, -1 if failed -Get access 3 to ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) - static inline int port_access_full (unsigned short int port); -Returns 0 if successful, -1 if failed +static inline int port_access_multiple (unsigned short port, unsigned short count) + Get access multiple to ports at once. + Returns 0 if successful, -1 if failed -Close access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) - static inline int port_deny_full (unsigned short int port); -Returns 0 if successful, -1 if failed +static inline int port_deny_multiple (unsigned short port, unsigned short count) + Close access to multiple ports at once. + Returns 0 if successful, -1 if failed + +If you make modifications to this file: References to the LPT port should +not be in this file but in lpt-port.h ... */ #ifndef PORT_H @@ -53,6 +59,7 @@ Returns 0 if successful, -1 if failed /* ------------------------------------------------------------- */ /* Use ioperm, inb and outb in (Linux) */ +/* And iopl for higher addresses of PCI LPT cards */ #if defined HAVE_IOPERM /* Glibc2 and Glibc1 */ @@ -66,33 +73,63 @@ Returns 0 if successful, -1 if failed # endif /* Read a byte from port */ -static inline int port_in (unsigned short int port) { +static inline int port_in (unsigned short port) { return inb(port); } /* Write a byte 'val' to port */ -static inline void port_out (unsigned short int port, unsigned char val) { +static inline void port_out (unsigned short port, unsigned char val) { outb(val, port); } /* Get access to a specific port */ -static inline int port_access (unsigned short int port) { - return ioperm(port, 1, 255); +static inline int port_access (unsigned short port) { + if (port <= 0x3FF) { + return ioperm(port, 1, 255); + } else { +#ifdef HAVE_IOPL + /* Is there a better way to do this ? */ + static short int iopl_done = 0; + if (iopl_done) return 0; + iopl_done = 1; + return iopl(1); +#else + return -1; /* Error, can't access the requested port */ +#endif + } } /* Close access to a specific port */ -static inline int port_deny (unsigned short int port) { - return ioperm(port, 1, 0); +static inline int port_deny (unsigned short port) { + if (port <= 0x3FF) { + return ioperm(port, 1, 0); + } + /* We can't simply close access acquired with iopl */ + return 0; } -/* Get access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ -static inline int port_access_full (unsigned short int port) { - return ioperm(port, 3, 255); +/* Get access to multiple ports at once */ +static inline int port_access_multiple (unsigned short port, int count) { + if (port+count-1 <= 0x3FF) { + return ioperm(port, count, 255); + } else { +#ifdef HAVE_IOPL + return port_access(port+count); + /* to use the iopl part there... */ +#else + return -1; +#endif + } + return 0; } -/* Close access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ -static inline int port_deny_full (unsigned short int port) { - return ioperm(port, 3, 0); +/* Close access to multiple ports at once */ +static inline int port_deny_multiple (unsigned short port, int count) { + if (port+count-1 <= 0x3FF) { + return ioperm(port, count, 0); + } + /* We can't simply close access acquired with iopl */ + return 0; } /* ------------------------------------------------------------- */ @@ -103,12 +140,12 @@ static inline int port_deny_full (unsigned short int port) { #include /* Read a byte from port */ -static inline int port_in (unsigned short int port) { +static inline int port_in (unsigned short port) { return inb(port); } /* Write a byte 'val' to port */ -static inline void port_out (unsigned short int port, unsigned char val) { +static inline void port_out (unsigned short port, unsigned char val) { outb(port, val); } @@ -128,7 +165,7 @@ static inline void setaccess(u_long * map, u_int bit, int allow) { } /* Get access to a specific port */ -static inline int port_access (unsigned short int port) { +static inline int port_access (unsigned short port) { u_long iomap[32]; if (i386_get_ioperm(iomap) == -1) return -1; @@ -141,7 +178,7 @@ static inline int port_access (unsigned short int port) { } /* Close access to a specific port */ -static inline int port_deny (unsigned short int port) { +static inline int port_deny (unsigned short port) { u_long iomap[32]; if (i386_get_ioperm(iomap) == -1) return -1; @@ -153,30 +190,32 @@ static inline int port_deny (unsigned short int port) { return 0; } -/* Get access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ -static inline int port_access_full (unsigned short int port) { +/* Get access to multiple ports at once */ +static inline int port_access_multiple (unsigned short port, unsigned short count) { u_long iomap[32]; + unsigned short i; if (i386_get_ioperm(iomap) == -1) return -1; - setaccess(iomap, port , 1); - setaccess(iomap, port+1, 1); - setaccess(iomap, port+2, 1); + for (i=0; i and inb and outb f #include /* Read a byte from port */ -static inline int port_in (unsigned short int port) { +static inline int port_in (unsigned short port) { return inb(port); } /* Write a byte 'val' to port */ -static inline void port_out (unsigned short int port, unsigned char val) { +static inline void port_out (unsigned short port, unsigned char val) { outb(port,val); } /* Get access to a specific port */ -static inline int port_access (unsigned short int port) { +static inline int port_access (unsigned short port) { return i386_set_ioperm(port, 1, 1); } -/* Get access 3 to ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ -static inline int port_access_full (unsigned short int port) { - return i386_set_ioperm(port, 3, 1); +/* Get access to multiple ports at once */ +static inline int port_access_multiple (unsigned short port, unsigned short count) { + return i386_set_ioperm(port, count, 1); } /* Close access to a specific port */ -static inline int port_deny (unsigned short int port) { +static inline int port_deny (unsigned short port) { return i386_set_ioperm(port, 1, 0); } -/* Close access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ -static inline int port_deny_full (unsigned short int port) { - return i386_set_ioperm(port, 3, 0); +/* Close access to multiple ports at once */ +static inline int port_deny_multiple (unsigned short port, unsigned short count) { + return i386_set_ioperm(port, count, 0); } +#else /* ------------------------------------------------------------- */ /* Last chance! Use /dev/io and i386 ASM code (BSD4.3 ?) */ -#else /* Read a byte from port */ -static inline int port_in (unsigned short int port) { +static inline int port_in (unsigned short port) { unsigned char value; __asm__ volatile ("inb %1,%0":"=a" (value) :"d" ((unsigned short) port)); @@ -234,13 +273,13 @@ static inline int port_in (unsigned short int port) { } /* Write a byte 'val' to port */ -static inline void port_out (unsigned short int port, unsigned char val) { +static inline void port_out (unsigned short port, unsigned char val) { __asm__ volatile ("outb %0,%1\n"::"a" (val), "d" (port) ); } -/* Get access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ -static inline int port_access_full (unsigned short int port) { +/* Get access to a specific port */ +static inline int port_access (unsigned short port) { static FILE * port_access_handle = NULL ; if( port_access_handle @@ -253,19 +292,21 @@ static inline int port_access_full (unsigned short int port) { return -1; } -/* Get access to a specific port */ -static inline int port_access (unsigned short int port) { - return port_access_full(port); /* /dev/io gives you access to all ports. */ -} - -/* Close access to 3 ports: port (CONTROL), port+1 (STATUS) and port+2 (DATA) */ -static inline int port_deny_full (unsigned short int port) { - /* Can't close /dev/io... */ -} - -/* Close access to a specific port */ -static inline int port_deny (unsigned short int port) { +/* Close access to a specific port */ +static inline int port_deny (unsigned short port) { /* Can't close /dev/io... */ + return 0; +} + +/* Get access to multiple ports at once */ +static inline int port_access_multiple (unsigned short port, unsigned short count) { + return port_access (port); /* /dev/io gives you access to all ports. */ +} + +/* Close access to multiple ports at once */ +static inline int port_deny_multiple (unsigned short port, unsigned short count) { + /* Can't close /dev/io... */ + return 0; } #endif diff --git a/server/drivers/t6963.c b/server/drivers/t6963.c index fbd4afa..c03796a 100644 --- a/server/drivers/t6963.c +++ b/server/drivers/t6963.c @@ -113,7 +113,7 @@ t6963_init (Driver *drvthis, char *args) debug (RPT_DEBUG, "T6963: Getting permission to parallel port %d...", t6963_out_port); - if( port_access_full(t6963_out_port) ) { //ioperm(t6963_out_port, 3, 1)) { + if( port_access_multiple(t6963_out_port,3) ) { //ioperm(t6963_out_port, 3, 1)) { report (RPT_ERR, "T6963_init: no permission to port %d: (%s)\n", t6963_out_port, strerror (errno)); return -1; } @@ -226,7 +226,7 @@ t6963_close (Driver *drvthis) debug (RPT_INFO, "Shutting down!\n"); t6963_low_disable_mode (BLINK_ON); - port_deny_full(t6963_out_port); + port_deny_multiple(t6963_out_port,3); if (framebuf != NULL) free (framebuf);