Ключевые слова:io, raw, example, device, (найти похожие документы) From : Valentin Davydov 2:5020/400 03 Mar 01 18:56:14
Subj : пpямое пpогpаммиpование поpтов вода-вывода в FreeBSD
-------------------------------------------------------------------------------
* Forwarded from area 'RU.UNIX.BSD'
>Столкнyлся с пpоблемой пpямого пpогpаммиpования поpтов вода-вывода в FreeBSD.
>Почитав этy эхy нашел что юто делается чеpе /dev/io, но ни написааное в эхе,
>ни написанное в man, ничего pезyльтатов непpинесло. Максимyм сего добился, так
>это чтобы пpогpамма не выпадала в коpy. Покажите на конкpетном пpимеpе как это
>делается. Hе дайте погибнyть.
Вот что у меня сейчас работает на лаптопе:
/* T P D U A L S C A N . C
Author: Michael Steiner
<[email protected]> <[email protected]>
http://www.zurich.ibm.com/pub/sti/www/info.html
Ported to FreeBSD: Valentin Davydov
<[email protected]>
This program allows you to set videoram for IBM ThinkPads with dualscan
LCD screen (at least for the 750Cs and 5538-VWD but probably also for
others) to allow running XFree86 without patching it (normally you got
all twice if the upper 512K of videoram are not disabled).
Usage:
a) you run on the built-in monitor:
(1) run 'tpdualscan -d' as root
(2) start X (e.g with startx)
b) you run on an external monitor:
(1) run 'tpdualscan -e' as root
(2) start X (e.g with startx)
*/
#define PROGNAME "tpdualscan"
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <machine/cpufunc.h>
#include <fcntl.h>
char usage[] = "usage: "PROGNAME"(-d(isable) | -e(nable) | -s(tatus))";
void main (int argc, char *argv[]) {
unsigned long vgaIOBase;
int colorEmulation, dualScan, devIOHandle;
enum {enable, disable, status} mode = status;
unsigned char registr;
/* parse command line */
if ((argc > 2) || ((argc == 2) && (argv[1][0] != '-'))){
fprintf(stderr, "%s\n", usage); exit(1);
}
if (argc == 2) {
switch (argv[1][1]) {
case 'h':
printf("%s\ndisable/enable upper 512K of VRAM for dual-scan
thinkpads\n", usage); exit(0);
case 'd': /* disable */
mode = disable; break;
case 'e': /* enable */
mode = enable; break;
case 's': /* status */
mode = status; break;
default:
fprintf(stderr, "invalid option %c\n%s\n", argv[1][1], usage);
exit(1);
}
}
/* enable direct ports I/O */
devIOHandle = open("/dev/io", O_RDONLY);
if (devIOHandle == -1){
fprintf(stderr, "%s: Can not get IO permission (%s)",
PROGNAME, strerror(errno));
exit(1);};
/* set vga IO base depend from color mode */
colorEmulation = inb(0x3CC) & 0x01;
if (!colorEmulation) {
fprintf(stderr, "you are not running a dual scan thinkpad \n");
exit(1);
}
vgaIOBase = (colorEmulation) ? 0x3D0 : 0x3B0;
/* unlock flat panel registers PR18, PR19, PR!a, PR36-PR41 and PR44 */
outb(vgaIOBase + 4, 0x34); /* PR1B */
registr = inb(vgaIOBase + 5);
outb(vgaIOBase + 5, ((registr & 0x1F) | 0xA0)); /* set bits 5-7 to 101 */
/* check if we have a dual-scan LCD */
outb(vgaIOBase + 4, 0x31);
dualScan = ((inb(vgaIOBase + 5) & 0xB) == 0); /* dual scan ==
(PR18[bit:3,1,0] = 0) */
if (!dualScan) {
fprintf(stderr, "you are not running a dual scan thinkpad \n");
exit(1);
}
/* clear bit 6 to disable upper 512k The remaining 512Kbytes
of video memory are not disabled by clearing the bit, but it
is actually used as a shadow of first 512Kbyte */
outb(0x3CE, 0x0B);
registr = inb(0x3CF); /* PR1 */
if (mode == disable) {
printf("setting vramsize to 512K\n");
outb(0x3CE, 0x0B); outb(0x3CF, registr & 0xBF); /* enable 512 */
} else if (mode == enable) {
printf("setting vramsize to 1024K\n");
outb(0x3CE, 0x0B); outb(0x3CF, registr | 0xC0); /* enable 1024 */
} else {
printf("current vramsize is %dK\n", ( (registr & 0x40) ? 1024 : 512));
}
/* cleanup */
/* lock flat panel registers PR18, PR19, PR!a, PR36-PR41 and PR44 */
outb(vgaIOBase + 4, 0x34); /* PR1B */
registr = inb(vgaIOBase + 5);
outb(vgaIOBase + 5, (registr & 0x1F)); /* set bits 5-7 to other than 101 */
/* disable direct ports I/O */
close(devIOHandle);
}
--- ifmail v.2.15dev5 * Origin: Demos online service (2:5020/400)