📄 ppntddkgenportinit.c
字号:
/*****************************************************************************//* * ppntddkgenportinit.c -- Parport direct access with NTDDK genport.sys (init routines). * * Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Please note that the GPL allows you to use the driver, NOT the radio. * In order to use the radio, you need a license from the communications * authority of your country. * *//*****************************************************************************/#include <windows.h>#include "parport.h"/* ---------------------------------------------------------------------- */#define DEVNAME "\\\\.\\GpdDev"/* ---------------------------------------------------------------------- *//* LPT registers *//* ECP specific registers */#define LPTREG_ECONTROL 0x402#define LPTREG_CONFIGB 0x401#define LPTREG_CONFIGA 0x400#define LPTREG_TFIFO 0x400#define LPTREG_DFIFO 0x400#define LPTREG_AFIFO 0x000#define LPTREG_DSR 0x001#define LPTREG_DCR 0x002/* EPP specific registers */#define LPTREG_EPPDATA 0x004#define LPTREG_EPPADDR 0x003/* standard registers */#define LPTREG_CONTROL 0x002#define LPTREG_STATUS 0x001#define LPTREG_DATA 0x000/* ECP config A */#define LPTCFGA_INTRISALEVEL 0x80#define LPTCFGA_IMPIDMASK 0x70#define LPTCFGA_IMPID16BIT 0x00#define LPTCFGA_IMPID8BIT 0x10#define LPTCFGA_IMPID32BIT 0x20#define LPTCFGA_NOPIPELINE 0x04#define LPTCFGA_PWORDCOUNT 0x03/* ECP config B */#define LPTCFGB_COMPRESS 0x80#define LPTCFGB_INTRVALUE 0x40#define LPTCFGB_IRQMASK 0x38#define LPTCFGB_IRQ5 0x38#define LPTCFGB_IRQ15 0x30#define LPTCFGB_IRQ14 0x28#define LPTCFGB_IRQ11 0x20#define LPTCFGB_IRQ10 0x18#define LPTCFGB_IRQ9 0x10#define LPTCFGB_IRQ7 0x08#define LPTCFGB_IRQJUMPER 0x00#define LPTCFGB_DMAMASK 0x07#define LPTCFGB_DMA7 0x07#define LPTCFGB_DMA6 0x06#define LPTCFGB_DMA5 0x05#define LPTCFGB_DMAJUMPER16 0x04#define LPTCFGB_DMA3 0x03#define LPTCFGB_DMA2 0x02#define LPTCFGB_DMA1 0x01#define LPTCFGB_DMAJUMPER8 0x00/* ECP ECR */#define LPTECR_MODEMASK 0xe0#define LPTECR_MODESPP 0x00#define LPTECR_MODEPS2 0x20#define LPTECR_MODESPPFIFO 0x40#define LPTECR_MODEECP 0x60#define LPTECR_MODEECPEPP 0x80#define LPTECR_MODETEST 0xc0#define LPTECR_MODECFG 0xe0#define LPTECR_NERRINTRDIS 0x10#define LPTECR_DMAEN 0x08#define LPTECR_SERVICEINTR 0x04#define LPTECR_FIFOFULL 0x02#define LPTECR_FIFOEMPTY 0x01/* ---------------------------------------------------------------------- */extern HANDLE pp_ntddkgenport_handle;extern unsigned int pp_ntddkgenport_flags;extern const struct parport_ops parport_ntddkgenport_ops, parport_ntddkgenport_emul_ops;extern unsigned char pp_ntddkgenport_inb(unsigned int port);extern void pp_ntddkgenport_outb(unsigned char val, unsigned int port);extern int pp_ntddkgenport_epp_clear_timeout(void);#define FLAGS_PCSPP (1<<0)#define FLAGS_PCPS2 (1<<1)#define FLAGS_PCEPP (1<<2)#define FLAGS_PCECR (1<<3) /* ECR Register Exists */#define FLAGS_PCECP (1<<4)#define FLAGS_PCECPEPP (1<<5)#define FLAGS_PCECPPS2 (1<<6)/* ---------------------------------------------------------------------- */static int parport_spp(void){ pp_ntddkgenport_epp_clear_timeout(); /* prevent lockup of some SMSC IC's */ /* this routine is mostly copied from Linux Kernel parport */ pp_ntddkgenport_outb(0xc, LPTREG_ECONTROL); pp_ntddkgenport_outb(0xc, LPTREG_CONTROL); pp_ntddkgenport_outb(0xaa, LPTREG_DATA); if (pp_ntddkgenport_inb(LPTREG_DATA) != 0xaa) return 0; pp_ntddkgenport_outb(0x55, LPTREG_DATA); if (pp_ntddkgenport_inb(LPTREG_DATA) != 0x55) return 0; return PARPORT_MODE_PCSPP;}/* Check for ECP * * Old style XT ports alias io ports every 0x400, hence accessing ECR * on these cards actually accesses the CTR. * * Modern cards don't do this but reading from ECR will return 0xff * regardless of what is written here if the card does NOT support * ECP. * * We will write 0x2c to ECR and 0xcc to CTR since both of these * values are "safe" on the CTR since bits 6-7 of CTR are unused. */static int parport_ecr(void){ unsigned char r = 0xc; pp_ntddkgenport_outb(r, LPTREG_CONTROL); if ((pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x3) == (r & 0x3)) { pp_ntddkgenport_outb(r ^ 0x2, LPTREG_CONTROL); /* Toggle bit 1 */ r = pp_ntddkgenport_inb(LPTREG_CONTROL); if ((pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x2) == (r & 0x2)) goto no_reg; /* Sure that no ECR register exists */ } if ((pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x3 ) != 0x1) goto no_reg; pp_ntddkgenport_outb(0x34, LPTREG_ECONTROL); if (pp_ntddkgenport_inb(LPTREG_ECONTROL) != 0x35) goto no_reg; pp_ntddkgenport_outb(0xc, LPTREG_CONTROL); /* Go to mode 000 */ pp_ntddkgenport_outb(pp_ntddkgenport_inb(LPTREG_ECONTROL) & ~0xe0, LPTREG_ECONTROL); return PARPORT_MODE_PCECR; no_reg: pp_ntddkgenport_outb(0xc, LPTREG_CONTROL); return 0; }static int parport_ecp(void){ int i; int config; int pword; int fifo_depth, writeIntrThreshold, readIntrThreshold; /* Find out FIFO depth */ pp_ntddkgenport_outb(0x00, LPTREG_ECONTROL); /* Reset FIFO */ pp_ntddkgenport_outb(0xc0, LPTREG_ECONTROL); /* TEST FIFO */ for (i=0; i < 1024 && !(pp_ntddkgenport_inb(LPTREG_ECONTROL) & 0x02); i++) pp_ntddkgenport_outb(0xaa, LPTREG_TFIFO); /* * Using LGS chipset it uses ECR register, but * it doesn't support ECP or FIFO MODE */ if (i == 1024) { pp_ntddkgenport_outb(0x00, LPTREG_ECONTROL); return 0; } fifo_depth = i; lprintf(3, "ECP: FIFO depth is %d bytes\n", fifo_depth); /* Find out writeIntrThreshold */ pp_ntddkgenport_outb(pp_ntddkgenport_inb(LPTREG_ECONTROL) | (1<<2), LPTREG_ECONTROL); pp_ntddkgenport_outb(pp_ntddkgenport_inb(LPTREG_ECONTROL) & ~(1<<2) , LPTREG_ECONTROL); for (i = 1; i <= fifo_depth; i++) { pp_ntddkgenport_inb(LPTREG_TFIFO); usleep(50); if (pp_ntddkgenport_inb(LPTREG_ECONTROL) & (1<<2)) break; } if (i <= fifo_depth) lprintf(3, "ECP: writeIntrThreshold is %d\n", i); else /* Number of bytes we know we can write if we get an interrupt. */ i = 0; writeIntrThreshold = i; /* Find out readIntrThreshold */ pp_ntddkgenport_outb((pp_ntddkgenport_inb(LPTREG_ECONTROL) & ~0xe0) | 0x20, LPTREG_ECONTROL); /* Reset FIFO, PS2 */ pp_ntddkgenport_outb(pp_ntddkgenport_inb(LPTREG_CONTROL) | PARPORT_CONTROL_DIRECTION, LPTREG_CONTROL); pp_ntddkgenport_outb((pp_ntddkgenport_inb(LPTREG_ECONTROL) & ~0xe0) | 0xc0, LPTREG_ECONTROL); /* Test FIFO */ pp_ntddkgenport_outb(pp_ntddkgenport_inb(LPTREG_ECONTROL) | (1<<2), LPTREG_ECONTROL); pp_ntddkgenport_outb(pp_ntddkgenport_inb(LPTREG_ECONTROL) & ~(1<<2) , LPTREG_ECONTROL); for (i = 1; i <= fifo_depth; i++) { pp_ntddkgenport_outb(0xaa, LPTREG_TFIFO); if (pp_ntddkgenport_inb(LPTREG_ECONTROL) & (1<<2)) break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -