📄 ppntinit.c
字号:
static int parport_epp(void){ /* If EPP timeout bit clear then EPP available */ if (!pp_nt_epp_clear_timeout()) return 0; /* No way to clear timeout */ /* * Theory: * Write two values to the EPP address register and * read them back. When the transfer times out, the state of * the EPP register is undefined in some cases (EPP 1.9?) but * in others (EPP 1.7, ECPEPP?) it is possible to read back * its value. */ pp_nt_epp_clear_timeout(); usleep(30); /* Wait for possible EPP timeout */ parport_nt_write_eppaddr(0x55); pp_nt_epp_clear_timeout(); usleep(30); /* Wait for possible EPP timeout */ if (parport_nt_read_eppaddr() == 0x55) { parport_nt_write_eppaddr(0xaa); pp_nt_epp_clear_timeout(); usleep(30); /* Wait for possible EPP timeout */ if (parport_nt_read_eppaddr() == 0xaa) { pp_nt_epp_clear_timeout(); return PARPORT_MODE_PCEPP; } } /* * Theory: * Bit 0 of STR is the EPP timeout bit, this bit is 0 * when EPP is possible and is set high when an EPP timeout * occurs (EPP uses the HALT line to stop the CPU while it does * the byte transfer, an EPP timeout occurs if the attached * device fails to respond after 10 micro seconds). * * This bit is cleared by either reading it (National Semi) * or writing a 1 to the bit (SMC, UMC, WinBond), others ??? * This bit is always high in non EPP modes. */ parport_nt_frob_control(0x20, 0x20); parport_nt_frob_control(0x10, 0x10); pp_nt_epp_clear_timeout(); parport_nt_read_eppdata(); usleep(30); /* Wait for possible EPP timeout */ if (parport_nt_read_status() & 0x01) { pp_nt_epp_clear_timeout(); return PARPORT_MODE_PCEPP; } return 0;}static int parport_ecpepp(void){ int mode; unsigned char oecr; oecr = parport_nt_read_econtrol(); /* Search for SMC style EPP+ECP mode */ parport_nt_write_econtrol(0x80); mode = parport_epp(); parport_nt_write_econtrol(oecr); return mode ? PARPORT_MODE_PCECPEPP : 0;}/* Detect PS/2 support. * * Bit 5 (0x20) sets the PS/2 data direction; setting this high * allows us to read data from the data lines. In theory we would get back * 0xff but any peripheral attached to the port may drag some or all of the * lines down to zero. So if we get back anything that isn't the contents * of the data register we deem PS/2 support to be present. * * Some SPP ports have "half PS/2" ability - you can't turn off the line * drivers, but an external peripheral with sufficiently beefy drivers of * its own can overpower them and assert its own levels onto the bus, from * where they can then be read back as normal. Ports with this property * and the right type of device attached are likely to fail the SPP test, * (as they will appear to have stuck bits) and so the fact that they might * be misdetected here is rather academic. */static int parport_ps2(void){ int ok = 0; unsigned char octr = parport_nt_read_control(); pp_nt_epp_clear_timeout(); parport_nt_write_control(octr | 0x20); /* try to tri-state the buffer */ parport_nt_write_data(0x55); if (parport_nt_read_data() != 0x55) ok++; parport_nt_write_data(0xaa); if (parport_nt_read_data() != 0xaa) ok++; parport_nt_write_control(octr); /* cancel input mode */ return ok ? PARPORT_MODE_PCPS2 : 0;}static int parport_ecpps2(void){ int mode; unsigned char oecr; oecr = parport_nt_read_econtrol(); parport_nt_write_econtrol(0x20); mode = parport_ps2(); parport_nt_write_econtrol(oecr); return mode ? PARPORT_MODE_PCECPPS2 : 0;}/* ---------------------------------------------------------------------- */#define SERVICENAME "eppflex"#define SERVICEDISPLAYNAME "Baycom EPPFLEX"//#define SERVICEBINARY "\"\\??\\g:\\nteppflex\\eppflex.sys\""#define SERVICEBINARY "System32\\drivers\\eppflex.sys"static int start_service(void){ int ret = -1; SC_HANDLE hscm, hserv; hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (!hscm) { lprintf(5, "Cannot open SC manager, error 0x%08lx\n", GetLastError()); return -1; } hserv = CreateService(hscm, SERVICENAME, SERVICEDISPLAYNAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, SERVICEBINARY, NULL, NULL, NULL, NULL, NULL); if (!hserv) { lprintf(5, "Cannot create service, error 0x%08lx\n", GetLastError()); hserv = OpenService(hscm, SERVICENAME, SERVICE_ALL_ACCESS); if (!hserv) { lprintf(5, "Cannot open service, error 0x%08lx\n", GetLastError()); goto closescm; } } if (!StartService(hserv, 0, NULL)) { lprintf(5, "Cannot start service, error 0x%08lx\n", GetLastError()); goto closeserv; } lprintf(1, "Service %s started successfully\n", SERVICENAME); ret = 0; closeserv: if (!CloseServiceHandle(hserv)) lprintf(5, "Cannot close service handle, error 0x%08lx\n", GetLastError()); closescm: if (!CloseServiceHandle(hscm)) lprintf(5, "Cannot close service manager handle, error 0x%08lx\n", GetLastError()); return ret;}static int stop_service(void){ int ret = -1; SC_HANDLE hscm, hserv; SERVICE_STATUS sstat; hscm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (!hscm) { lprintf(5, "Cannot open SC manager, error 0x%08lx\n", GetLastError()); return -1; } hserv = OpenService(hscm, SERVICENAME, SERVICE_ALL_ACCESS); if (!hserv) { lprintf(5, "Cannot open service, error 0x%08lx\n", GetLastError()); goto closescm; } ret = 0; if (!ControlService(hserv, SERVICE_CONTROL_STOP, &sstat)) { lprintf(5, "Cannot delete service, error 0x%08lx\n", GetLastError()); ret = -1; } if (!DeleteService(hserv)) { lprintf(5, "Cannot delete service, error 0x%08lx\n", GetLastError()); ret = -1; } if (!ret) lprintf(1, "Service %s stopped successfully\n", SERVICENAME); if (!CloseServiceHandle(hserv)) lprintf(5, "Cannot close service handle, error 0x%08lx\n", GetLastError()); closescm: if (!CloseServiceHandle(hscm)) lprintf(5, "Cannot close service manager handle, error 0x%08lx\n", GetLastError()); return ret;}/* ---------------------------------------------------------------------- */void parport_stop_nt(void){ if (pp_nt_handle != INVALID_HANDLE_VALUE) CloseHandle(pp_nt_handle); pp_nt_handle = INVALID_HANDLE_VALUE; stop_service();}/* ---------------------------------------------------------------------- */int parport_init_nt_flags(unsigned int portnr, unsigned int flags){ char buf[32]; if (pp_nt_handle != INVALID_HANDLE_VALUE) CloseHandle(pp_nt_handle); start_service(); snprintf(buf, sizeof(buf), "\\\\.\\eppflex\\%u", portnr); pp_nt_handle = CreateFile(buf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (pp_nt_handle == INVALID_HANDLE_VALUE) { lprintf(0, "Cannot open eppflex.sys driver, error 0x%08lx\n", GetLastError()); goto err; } pp_nt_flags = FLAGS_PCSPP; if (!parport_spp()) { lprintf(0, "No parport present\n"); goto err; } if (parport_ecr()) { pp_nt_flags |= FLAGS_PCECR; pp_nt_flags |= parport_ecp(); pp_nt_flags |= parport_ecpps2(); pp_nt_flags |= parport_ecpepp(); if ((flags & PPFLAG_FORCEHWEPP) && (pp_nt_flags & (FLAGS_PCPS2|FLAGS_PCECPPS2)) && !(pp_nt_flags & (FLAGS_PCEPP|FLAGS_PCECPEPP))) pp_nt_flags |= FLAGS_PCECPEPP; else flags &= ~PPFLAG_FORCEHWEPP; } else { pp_nt_flags |= parport_ps2(); pp_nt_flags |= parport_epp(); if ((flags & PPFLAG_FORCEHWEPP) && (pp_nt_flags & (FLAGS_PCPS2|FLAGS_PCECPPS2)) && !(pp_nt_flags & (FLAGS_PCEPP|FLAGS_PCECPEPP))) pp_nt_flags |= FLAGS_PCEPP; else flags &= ~PPFLAG_FORCEHWEPP; } lprintf(0, "Parport capabilities: SPP%s%s%s%s%s%s\n", (pp_nt_flags & FLAGS_PCPS2) ? ", PS2" : "", (pp_nt_flags & FLAGS_PCEPP) ? ((flags & PPFLAG_FORCEHWEPP) ? ", EPP (forced)" : ", EPP") : "", (pp_nt_flags & FLAGS_PCECR) ? ", ECR" : "", (pp_nt_flags & FLAGS_PCECP) ? ", ECP" : "", (pp_nt_flags & FLAGS_PCECPEPP) ? ((flags & PPFLAG_FORCEHWEPP) ? ", ECPEPP (forced)" : ", ECPEPP") : "", (pp_nt_flags & FLAGS_PCECPPS2) ? ", ECPPS2" : ""); if (!(pp_nt_flags & (FLAGS_PCPS2 | FLAGS_PCECPPS2))) { lprintf(0, "Parport does not even support PS/2 mode, cannot use it\n"); goto err; } lprintf(0, "Parport using NT eppflex.sys hardware access"); if (pp_nt_flags & FLAGS_PCECR) parport_nt_write_econtrol(0x30); /* PS/2 mode */ parport_ops = parport_nt_ops; if ((flags & PPFLAG_SWEMULECP) || !(pp_nt_flags & FLAGS_PCECP)) { parport_ops.parport_ecp_write_data = parport_nt_emul_ops.parport_ecp_write_data; parport_ops.parport_ecp_read_data = parport_nt_emul_ops.parport_ecp_read_data; parport_ops.parport_ecp_write_addr = parport_nt_emul_ops.parport_ecp_write_addr; lprintf(0, ", emulating ECP"); } if ((flags & PPFLAG_SWEMULEPP) || !(pp_nt_flags & (FLAGS_PCEPP | FLAGS_PCECPEPP))) { parport_ops.parport_epp_write_data = parport_nt_emul_ops.parport_epp_write_data; parport_ops.parport_epp_read_data = parport_nt_emul_ops.parport_epp_read_data; parport_ops.parport_epp_write_addr = parport_nt_emul_ops.parport_epp_write_addr; parport_ops.parport_epp_read_addr = parport_nt_emul_ops.parport_epp_read_addr; lprintf(0, ", emulating EPP"); } lprintf(0, "\n"); return 0; err: parport_stop_nt(); return -1;}int parport_init_nt(unsigned int portnr){ return parport_init_nt_flags(portnr, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -