libieee1284.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. --- parallel.c 2015-11-29 14:28:19.000000000 +0100
  2. +++ parallel.c.libieee1284 2015-11-29 21:10:52.714562832 +0100
  3. @@ -27,6 +27,11 @@
  4. #ifdef USE_PARALLEL
  5. +#define USE_LIBIEEE1284
  6. +#if defined USE_LIBIEEE1284 && defined USE_PPDEV
  7. +#undef USE_PPDEV
  8. +#endif
  9. +
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #ifdef HAVE_UNISTD_H
  13. @@ -39,7 +44,9 @@
  14. #include <linux/ppdev.h>
  15. #include <sys/ioctl.h>
  16. #include <sys/time.h>
  17. -#elif defined __linux__ && defined __GLIBC__ // USE_PPDEV
  18. +#elif defined USE_LIBIEEE1284 // USE_PPDEV
  19. +#include <ieee1284.h>
  20. +#elif defined __linux__ && defined __GLIBC__ // USE_LIBIEEE1284
  21. #ifdef HAVE_SYS_IO_H // necessary for some Linux/PPC configs
  22. #include <sys/io.h> // ioperm() (glibc), in{b, w}(), out{b, w}()
  23. #else
  24. @@ -98,8 +105,12 @@
  25. #if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__
  26. static int parport_io_fd;
  27. -#ifdef USE_PPDEV
  28. +#endif
  29. +#if defined USE_PPDEV || defined USE_LIBIEEE1284
  30. static enum { FORWARD = 0, REVERSE } parport_io_direction;
  31. +#ifdef USE_LIBIEEE1284
  32. +static struct parport *libieee1284_port;
  33. +#else
  34. static int parport_io_mode;
  35. #endif
  36. #endif
  37. @@ -119,7 +130,7 @@
  38. #endif
  39. -#if defined _WIN32 || defined __CYGWIN__
  40. +#if (defined _WIN32 || defined __CYGWIN__) && !defined USE_LIBIEEE1284
  41. #define NODRIVER_MSG "ERROR: No (working) I/O port driver. Please see the FAQ, question 4\n"
  42. @@ -178,7 +189,7 @@
  43. static void (*output_word) (unsigned short, unsigned short) = outpw_func;
  44. #endif
  45. -#endif // _WIN32 || __CYGWIN__
  46. +#endif // (_WIN32 || __CYGWIN__) && !USE_LIBIEEE1284
  47. #if defined __i386__ || defined __x86_64__ // GCC && x86
  48. @@ -281,6 +292,43 @@
  49. exit (1);
  50. }
  51. return byte;
  52. +#elif defined USE_LIBIEEE1284
  53. + int ppreg = port - ucon64.parport;
  54. + unsigned char byte;
  55. +
  56. + switch (ppreg)
  57. + {
  58. + case 0: // data
  59. + if (parport_io_direction == FORWARD) // dir is forward?
  60. + {
  61. + parport_io_direction = REVERSE; // change it to reverse
  62. + ieee1284_data_dir (libieee1284_port, parport_io_direction);
  63. + }
  64. + byte = (unsigned char) ieee1284_read_data (libieee1284_port);
  65. + break;
  66. + case 1: // status
  67. + byte = (unsigned char) (ieee1284_read_status (libieee1284_port) ^ S1284_INVERTED);
  68. + break;
  69. + case 2: // control
  70. + byte = (unsigned char) (ieee1284_read_control (libieee1284_port) ^ C1284_INVERTED);
  71. + break;
  72. + case 3: // EPP/ECP address
  73. + ieee1284_epp_read_addr (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
  74. + break;
  75. + case 4: // EPP/ECP data
  76. + ieee1284_epp_read_data (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
  77. + break;
  78. + case 0x402: // ECP register
  79. + puts ("WARNING: Ignored read from ECP register, returning 0");
  80. + byte = 0;
  81. + break;
  82. + default:
  83. + fprintf (stderr,
  84. + "ERROR: inportb() tried to read from an unsupported port (0x%x)\n",
  85. + port);
  86. + exit (1);
  87. + }
  88. + return byte;
  89. #elif defined __BEOS__
  90. st_ioport_t temp;
  91. @@ -364,6 +412,26 @@
  92. exit (1);
  93. }
  94. return buf[0] | buf[1] << 8; // words are read in little endian format
  95. +#elif defined USE_LIBIEEE1284
  96. + int ppreg = port - ucon64.parport;
  97. + unsigned char buf[2];
  98. +
  99. + switch (ppreg)
  100. + {
  101. + case 3: // EPP/ECP address
  102. + ieee1284_epp_read_addr (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
  103. + break;
  104. + case 4: // EPP/ECP data
  105. + ieee1284_epp_read_data (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
  106. + break;
  107. + // the data, status, control and ECP registers should only be accessed in "8-bit mode"
  108. + default:
  109. + fprintf (stderr,
  110. + "ERROR: inportw() tried to read from an unsupported port (0x%x)\n",
  111. + port);
  112. + exit (1);
  113. + }
  114. + return buf[0] | buf[1] << 8; // words are read in little endian format
  115. #elif defined __BEOS__
  116. st_ioport_t temp;
  117. @@ -440,6 +508,37 @@
  118. port);
  119. exit (1);
  120. }
  121. +#elif defined USE_LIBIEEE1284
  122. + int ppreg = port - ucon64.parport;
  123. +
  124. + switch (ppreg)
  125. + {
  126. + case 0: // data
  127. + if (parport_io_direction == REVERSE) // dir is reverse?
  128. + {
  129. + parport_io_direction = FORWARD; // change it to forward
  130. + ieee1284_data_dir (libieee1284_port, parport_io_direction);
  131. + }
  132. + ieee1284_write_data (libieee1284_port, byte);
  133. + break;
  134. + case 2: // control
  135. + ieee1284_write_control (libieee1284_port, (unsigned char) (byte ^ C1284_INVERTED));
  136. + break;
  137. + case 3: // EPP/ECP address
  138. + ieee1284_epp_write_addr (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
  139. + break;
  140. + case 4: // EPP/ECP data
  141. + ieee1284_epp_write_data (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
  142. + break;
  143. + case 0x402: // ECP register
  144. + puts ("WARNING: Ignored write to ECP register");
  145. + break;
  146. + default:
  147. + fprintf (stderr,
  148. + "ERROR: outportb() tried to write to an unsupported port (0x%x)\n",
  149. + port);
  150. + exit (1);
  151. + }
  152. #elif defined __BEOS__
  153. st_ioport_t temp;
  154. @@ -505,6 +604,28 @@
  155. port);
  156. exit (1);
  157. }
  158. +#elif defined USE_LIBIEEE1284
  159. + int ppreg = port - ucon64.parport;
  160. + unsigned char buf[2];
  161. +
  162. + // words are written in little endian format
  163. + buf[0] = (unsigned char) word;
  164. + buf[1] = word >> 8;
  165. + switch (ppreg)
  166. + {
  167. + case 3: // EPP/ECP address
  168. + ieee1284_epp_write_addr (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
  169. + break;
  170. + case 4: // EPP/ECP data
  171. + ieee1284_epp_write_data (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
  172. + break;
  173. + // the data, control and ECP registers should only be accessed in "8-bit mode"
  174. + default:
  175. + fprintf (stderr,
  176. + "ERROR: outportw() tried to write to an unsupported port (0x%x)\n",
  177. + port);
  178. + exit (1);
  179. + }
  180. #elif defined __BEOS__
  181. st_ioport_t temp;
  182. @@ -535,7 +656,7 @@
  183. }
  184. -#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV
  185. +#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
  186. #define DETECT_MAX_CNT 1000
  187. static int
  188. parport_probe (unsigned short port)
  189. @@ -563,6 +684,7 @@
  190. #endif
  191. +#ifndef USE_LIBIEEE1284
  192. #ifdef _WIN32
  193. static LONG
  194. new_exception_filter (LPEXCEPTION_POINTERS exception_pointers)
  195. @@ -590,6 +712,7 @@
  196. return EXCEPTION_CONTINUE_SEARCH;
  197. }
  198. #endif
  199. +#endif
  200. unsigned short
  201. @@ -649,6 +772,48 @@
  202. parport_io_direction = FORWARD; // set forward direction as default
  203. ioctl (parport_io_fd, PPDATADIR, &parport_io_direction);
  204. +#elif defined USE_LIBIEEE1284
  205. + struct parport_list list;
  206. + int capabilities, ucon64_parport;
  207. +
  208. + if (port == PARPORT_UNKNOWN)
  209. + port = 0;
  210. +
  211. + if (ieee1284_find_ports (&list, 0) != E1284_OK)
  212. + {
  213. + fputs ("ERROR: Could not get port list\n", stderr);
  214. + exit (1);
  215. + }
  216. +
  217. + if (port < list.portc)
  218. + libieee1284_port = list.portv[port];
  219. + else
  220. + {
  221. + fprintf (stderr, "ERROR: libieee1284 port %d not available\n", port);
  222. + exit (1);
  223. + }
  224. +
  225. + if (ieee1284_open (libieee1284_port, F1284_EXCL, &capabilities) != E1284_OK)
  226. + {
  227. + fprintf (stderr, "ERROR: Could not open libieee1284 port %d\n", port);
  228. + exit (1);
  229. + }
  230. + // TODO: Handle ECP mode correctly
  231. + if (ucon64.parport_mode == UCON64_EPP || ucon64.parport_mode == UCON64_ECP)
  232. + if ((capabilities & (CAP1284_EPP | CAP1284_ECP)) == 0)
  233. + puts ("WARNING: EPP or ECP mode was requested, but not available");
  234. +
  235. + ieee1284_free_ports (&list);
  236. +
  237. + if (ieee1284_claim (libieee1284_port) != E1284_OK)
  238. + {
  239. + fprintf (stderr, "ERROR: Could not claim libieee1284 port %d\n", port);
  240. + ieee1284_close (libieee1284_port);
  241. + exit (1);
  242. + }
  243. +
  244. + parport_io_direction = FORWARD;
  245. + ieee1284_data_dir (libieee1284_port, parport_io_direction);
  246. #elif defined __BEOS__
  247. parport_io_fd = open ("/dev/misc/ioport", O_RDWR | O_NONBLOCK);
  248. if (parport_io_fd == -1)
  249. @@ -711,7 +876,7 @@
  250. }
  251. #endif
  252. -#if defined __linux__ && (defined __i386__ || defined __x86_64__) && !defined USE_PPDEV
  253. +#if defined __linux__ && (defined __i386__ || defined __x86_64__) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
  254. /*
  255. Some code needs us to switch to the real uid and gid. However, other code
  256. needs access to I/O ports other than the standard printer port registers.
  257. @@ -731,7 +896,7 @@
  258. stderr);
  259. exit (1); // Don't return, if iopl() fails port access
  260. } // causes core dump
  261. -#endif // __linux__ && (__i386__ || __x86_64__) && !USE_PPDEV
  262. +#endif // __linux__ && (__i386__ || __x86_64__) && !USE_PPDEV && !USE_LIBIEEE1284
  263. #ifdef __OpenBSD__ // || defined __NetBSD__, add after feature request ;-)
  264. // We use i386_iopl() on OpenBSD for the same reasons we use iopl() on Linux
  265. @@ -745,7 +910,7 @@
  266. }
  267. #endif
  268. -#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV
  269. +#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
  270. #if defined _WIN32 || defined __CYGWIN__
  271. /*
  272. @@ -922,16 +1087,16 @@
  273. exit (1);
  274. }
  275. }
  276. -#endif // (__i386__ || __x86_64__ || _WIN32) && !USE_PPDEV
  277. +#endif // (__i386__ || __x86_64__ || _WIN32) && !USE_PPDEV && !USE_LIBIEEE1284
  278. -#ifdef USE_PPDEV
  279. +#if defined USE_PPDEV || defined USE_LIBIEEE1284
  280. // the following two calls need a valid value for ucon64.parport
  281. ucon64_parport = ucon64.parport;
  282. ucon64.parport = port;
  283. #endif
  284. outportb (port + PARPORT_CONTROL, inportb (port + PARPORT_CONTROL) & 0x0f);
  285. // bit 4 = 0 => IRQ disable for ACK, bit 5-7 unused
  286. -#ifdef USE_PPDEV
  287. +#if defined USE_PPDEV || defined USE_LIBIEEE1284
  288. ucon64.parport = ucon64_parport;
  289. #endif
  290. @@ -949,6 +1114,9 @@
  291. ioctl (parport_io_fd, PPNEGOT, &parport_io_mode);
  292. ioctl (parport_io_fd, PPRELEASE);
  293. close (parport_io_fd);
  294. +#elif defined USE_LIBIEEE1284
  295. + ieee1284_release (libieee1284_port);
  296. + ieee1284_close (libieee1284_port);
  297. #elif defined __BEOS__ || defined __FreeBSD__
  298. close (parport_io_fd);
  299. #elif defined AMIGA
  300. @@ -970,6 +1138,9 @@
  301. {
  302. #ifdef USE_PPDEV
  303. printf ("Using parallel port device: %s\n", ucon64.parport_dev);
  304. +#elif defined USE_LIBIEEE1284
  305. + printf ("Using parallel port device: %s, base address 0x%lx\n",
  306. + libieee1284_port->filename, libieee1284_port->base_addr); // ->name
  307. #elif defined AMIGA
  308. printf ("Using parallel port device: %s, port %d\n", ucon64.parport_dev, ucon64.parport);
  309. #else