From parag@pinhead.parag.codegen.com Thu Oct 29 10:12:19 1998 Received: from pinhead.parag.codegen.com (ppp-asfm08--172.sirius.net [205.134.241.172]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id KAA25992 for ; Thu, 29 Oct 1998 10:12:18 -0800 (PST) (envelope-from parag@pinhead.parag.codegen.com) Received: (from parag@localhost) by pinhead.parag.codegen.com (8.9.1/8.8.8) id KAA24349; Thu, 29 Oct 1998 10:12:23 -0800 (PST) (envelope-from parag) Message-Id: <199810291812.KAA24349@pinhead.parag.codegen.com> Date: Thu, 29 Oct 1998 10:12:23 -0800 (PST) From: parag@codegen.com Reply-To: parag@codegen.com To: FreeBSD-gnats-submit@freebsd.org Subject: doscmd port.c change to access real device ports X-Send-Pr-Version: 3.2 >Number: 8486 >Category: bin >Synopsis: doscmd port.c change to access real device ports >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: closed >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Oct 29 10:20:00 PST 1998 >Closed-Date: Wed Jan 20 10:57:47 MST 1999 >Last-Modified: Wed Jan 20 10:58:27 MST 1999 >Originator: Parag Patel >Release: FreeBSD 3.0-CURRENT i386 >Organization: CodeGen, Inc. >Environment: Dual SMP Pentium-II/300, 256Mb RAM, 2 IBM 4Gb SCSI disks (not that it matters) >Description: doscmd does not currently allow access to the physical device ports on the system. The relevant code in port.c has not been ported to FreeBSD. As I need it to access a Needhams EMP-10 EPROM programmer, I added the relevant code. >How-To-Repeat: This command allows access to the physical parallel port from doscmd using the patch below: rtprio 10 doscmd -x -b -i0x378:8 -o0x378:8 >Fix: I had posted a similar patch to current@freebsd.org that had a bug in it. In the original patch, iounmap() did not set the ioperm back to zero. This patch fixes that problem. Index: port.c =================================================================== RCS file: /src/freebsd/src/usr.bin/doscmd/port.c,v retrieving revision 1.1 diff -c -r1.1 port.c *** port.c 1997/08/09 01:42:54 1.1 --- port.c 1998/10/29 17:56:15 *************** *** 59,73 **** static void iomap(int port, int cnt) { ! fatal("iomap not supported"); } static void iounmap(int port, int cnt) { ! fatal("iomap not supported"); } - #else static void iomap(int port, int cnt) --- 59,88 ---- static void iomap(int port, int cnt) { ! if (port + cnt >= MAXPORT) { ! errno = ERANGE; ! goto bad; ! } ! if (i386_set_ioperm(port, cnt, 1) < 0) { ! bad: ! perror("iomap"); ! quit(1); ! } } static void iounmap(int port, int cnt) { ! if (port + cnt >= MAXPORT) { ! errno = ERANGE; ! goto bad; ! } ! if (i386_set_ioperm(port, cnt, 0) < 0) { ! bad: ! perror("iounmap"); ! quit(1); ! } } #else static void iomap(int port, int cnt) >Release-Note: >Audit-Trail: From: Parag Patel To: freebsd-gnats-submit@freebsd.org Cc: Subject: Re: bin/8486: doscmd port.c change to access real device ports Date: Wed, 18 Nov 1998 14:06:01 -0800 This is a multipart MIME message. --==_Exmh_1087615180 Content-Type: text/plain; charset=us-ascii Here are the more complete diffs for "doscmd" to map to arbitrary ports. Only the selected ports are iomapped. Ports may be specified on the command-line or in the config file. Access to the ports still requires root access. The man-page has also been updated for the new options. I've also appended my mods to doscmd's "tty.c" file. These change the meaning of backspace/delete back to what they're supposed to be. I don't run X with any keymaps so the original value of "1" does exactly the wrong thing for me. I also added a call to set the name of the window so it no longer shows up as "Untitled". The mods to tty.c may be omitted if you decide to leave it as-is. It does not affect the doscmd port access at all. -- Parag Patel --==_Exmh_1087615180 Content-Type: text/plain ; name="doscmd-diffs"; charset=us-ascii Content-Description: doscmd-diffs Content-Disposition: attachment; filename="doscmd-diffs" Index: config.c =================================================================== RCS file: /src/freebsd/src/usr.bin/doscmd/config.c,v retrieving revision 1.2 diff -c -r1.2 config.c *** config.c 1998/07/01 19:56:12 1.2 --- config.c 1998/11/01 20:46:21 *************** *** 238,243 **** --- 238,258 ---- fprintf(stderr, "Boot drive must be either A: or C:\n"); quit(1); } + } else if (!strcasecmp(av[0], "portmap")) { + int p, c; + if (ac < 2 || ac > 3 || !isdigit(av[1][0]) || + (ac == 3 && !isdigit(av[2][0]))) { + fprintf(stderr, "Usage: portmap port [count]\n"); + quit(1); + } + p = strtol(av[1], 0, 0); + c = (ac == 3) ? strtol(av[2], 0, 0) : 1; + iomap_port(p, c); + + while (c-- > 0) { + define_input_port_handler(p++, inb_port); + define_output_port_handler(p++, outb_port); + } } else if (!strcasecmp(av[0], "setver")) { int v; if (ac != 3 || !(v = strtol(av[2], 0, 0))) { Index: doscmd.1 =================================================================== RCS file: /src/freebsd/src/usr.bin/doscmd/doscmd.1,v retrieving revision 1.8 diff -c -r1.8 doscmd.1 *** doscmd.1 1998/10/13 08:57:45 1.8 --- doscmd.1 1998/11/01 20:29:25 *************** *** 187,192 **** --- 187,204 ---- .\" .\" .\" + .It Fl p Ar port Ns Xo + .Op : Ns Ar cnt + .Xc + Map the requested io + .Ar port + (with optional range up to to + .Ar port+cnt Ns No -1 ) + to the real hardware I/O port(s). + This will likely require root privs to access them. + .\" + .\" + .\" .It Fl P Enable tracing of io port calls (such as .Li inb , *************** *** 430,435 **** --- 442,460 ---- at interrupt specified by .Ar irq . This code is lightly tested and may not suit all needs. + .\" + .\" + .\" + .It Cm portmap Xo + .Ar port + .Op Ar count + .Xc + Map the requested io + .Ar port + (with optional range up to to + .Ar port+count Ns No -1 ) + to the real hardware I/O port(s). + This will likely require root privs to access them. .\" .\" .\" Index: doscmd.c =================================================================== RCS file: /src/freebsd/src/usr.bin/doscmd/doscmd.c,v retrieving revision 1.8 diff -c -r1.8 doscmd.c *** doscmd.c 1998/07/28 03:39:59 1.8 --- doscmd.c 1998/11/01 20:46:17 *************** *** 480,486 **** FILE *fp; char *col; ! while ((c = getopt (argc, argv, "234Oc:TkCIEMPRLAU:S:HDtzvVxXYfbri:o:d:")) != -1) { switch (c) { case 'd': if (fp = fopen(optarg, "w")) { --- 480,486 ---- FILE *fp; char *col; ! while ((c = getopt (argc, argv, "234Oc:TkCIEMPRLAU:S:HDtzvVxXYfbri:o:p:d:")) != -1) { switch (c) { case 'd': if (fp = fopen(optarg, "w")) { *************** *** 515,520 **** --- 515,521 ---- i = strtol(col, 0, 0); } p = strtol(optarg, 0, 0); + iomap_port(p, i); while (i-- > 0) define_input_port_handler(p++, inb_traceport); *************** *** 526,535 **** --- 527,551 ---- i = strtol(col, 0, 0); } p = strtol(optarg, 0, 0); + iomap_port(p, i); while (i-- > 0) define_output_port_handler(p++, outb_traceport); break; + case 'p': + i = 1; + if (col = strchr(optarg, ':')) { + *col++ = 0; + i = strtol(col, 0, 0); + } + p = strtol(optarg, 0, 0); + iomap_port(p, i); + + while (i-- > 0) { + define_input_port_handler(p++, inb_port); + define_output_port_handler(p++, outb_port); + } + break; case 'r': raw_kbd = 1; *************** *** 834,839 **** --- 850,858 ---- int enable; }; + /* This is commented out as it is never called. Turn it back on if needed. + */ + #if COMMENTED_OUT static void iomap_init(void) { *************** *** 844,849 **** --- 863,869 ---- { 0x1c80, 2, 1 }, /* 0x1c80 - 0x1c81 */ { 0x2c80, 2, 1 }, /* 0x2c80 - 0x2c81 */ { 0x3c80, 2, 1 }, /* 0x3c80 - 0x3c81 */ + { 0x378, 8, 1 }, /* 0x378 - 0x37F */ { 0x3c4, 2, 1 }, /* 0x3c4 - 0x3c5 */ { 0x3c5, 2, 1 }, /* 0x3ce - 0x3cf */ #else *************** *** 851,858 **** #endif { 0, 0, 0 } }; ! for (i = 0; io[i].length; i++) if (i386_set_ioperm(io[i].start, io[i].length, io[i].enable) < 0) err(1, "i386_set_ioperm"); } --- 871,891 ---- #endif { 0, 0, 0 } }; ! for (i = 0; io[i].length; i++) if (i386_set_ioperm(io[i].start, io[i].length, io[i].enable) < 0) err(1, "i386_set_ioperm"); + } + #endif + + /* This is used to map in only the specified port range, instead of all + the ports or only certain port ranges. + */ + void + iomap_port(int port, int count) + { + if (i386_set_ioperm(port, count, 1) < 0) + err(1, "i386_set_ioperm"); + + debug(D_PORT,"mapped I/O port: port=%#x count=%d\n", port, count); } Index: doscmd.h =================================================================== RCS file: /src/freebsd/src/usr.bin/doscmd/doscmd.h,v retrieving revision 1.4 diff -c -r1.4 doscmd.h *** doscmd.h 1998/07/01 19:56:15 1.4 --- doscmd.h 1998/11/01 20:29:37 *************** *** 146,152 **** extern void done(regcontext_t *REGS, int val); extern void quit(int); extern void call_on_quit(void (*)(void *), void *); ! /* signal.c */ extern struct sigframe *saved_sigframe; extern regcontext_t *saved_regcontext; --- 146,153 ---- extern void done(regcontext_t *REGS, int val); extern void quit(int); extern void call_on_quit(void (*)(void *), void *); ! extern void iomap_port(int port, int count); ! /* signal.c */ extern struct sigframe *saved_sigframe; extern regcontext_t *saved_regcontext; *************** *** 284,287 **** --- 285,290 ---- void outb_traceport(int, unsigned char); unsigned char inb_traceport(int); + void outb_port(int, unsigned char); + unsigned char inb_port(int); Index: port.c =================================================================== RCS file: /src/freebsd/src/usr.bin/doscmd/port.c,v retrieving revision 1.1 diff -c -r1.1 port.c *** port.c 1997/08/09 01:42:54 1.1 --- port.c 1998/10/30 01:59:09 *************** *** 54,74 **** asm volatile ("outb %%al,%%dx" : : "a" (data), "d" (port)) FILE *iolog = 0; ! u_long ioports[MAXPORT/32]; #ifdef __FreeBSD__ static void iomap(int port, int cnt) { ! fatal("iomap not supported"); } static void iounmap(int port, int cnt) { ! fatal("iomap not supported"); } - #else static void iomap(int port, int cnt) { --- 54,83 ---- asm volatile ("outb %%al,%%dx" : : "a" (data), "d" (port)) FILE *iolog = 0; ! #ifdef __FreeBSD__ static void iomap(int port, int cnt) { ! if (port + cnt >= MAXPORT) { ! errno = ERANGE; ! perror("iomap"); ! quit(1); ! } } static void iounmap(int port, int cnt) { ! if (port + cnt >= MAXPORT) { ! errno = ERANGE; ! perror("iomap"); ! quit(1); ! } } #else + u_long ioports[MAXPORT/32]; + static void iomap(int port, int cnt) { *************** *** 141,146 **** --- 150,170 ---- fflush(iolog); */ return(byte); + } + + /* + * Real input/output to (hopefully) iomapped port + */ + void + outb_port(int port, unsigned char byte) + { + out(port, byte); + } + + unsigned char + inb_port(int port) + { + return in(port); } /* Index: tty.c =================================================================== RCS file: /src/freebsd/src/usr.bin/doscmd/tty.c,v retrieving revision 1.4 diff -c -r1.4 tty.c *** tty.c 1998/02/22 23:36:54 1.4 --- tty.c 1998/11/07 19:54:27 *************** *** 68,74 **** static int mode = -1; #define vmem ((u_short *)0xB8000) static int blink = 1; ! int flipdelete = 1; /* Flip meaning of delete and backspace */ extern int capture_fd; static u_short break_code = 0x00; static u_short scan_code = 0x00; --- 68,74 ---- static int mode = -1; #define vmem ((u_short *)0xB8000) static int blink = 1; ! int flipdelete = 0; /* Flip meaning of delete and backspace */ extern int capture_fd; static u_short break_code = 0x00; static u_short scan_code = 0x00; *************** *** 2136,2141 **** --- 2136,2142 ---- | ButtonReleaseMask | PointerMotionMask ); } + XStoreName(dpy, win, "DOS"); XMapWindow(dpy, win); XFlush(dpy); --==_Exmh_1087615180-- State-Changed-From-To: open->closed State-Changed-By: imp State-Changed-When: Wed Jan 20 10:57:47 MST 1999 State-Changed-Why: I've included this patch. >Unformatted: