1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
From: Jonas Genannt <jonas.genannt@capi2name.de>
Subject: setserial pcmcia.c patch
diff -Naurp setserial-2.17.orig/pcmcia.c setserial-2.17/pcmcia.c
--- setserial-2.17.orig/pcmcia.c 1970-01-01 00:00:00.000000000 +0000
+++ setserial-2.17/pcmcia.c 2008-09-26 21:59:26.000000000 +0000
@@ -0,0 +1,159 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* This file contains the modifications needed to check for pcmcia conflicts
+ * between a normal port and a pcmcia serial-based port. Setserial should never
+ * be permitted to control a pcmcia-based device... leave it to pcmcia-cs.
+ *
+ * Note that the checking is a bit of an overkill, in that I suspect that
+ * checking stab is probably enough. However, far too many bugs have been
+ * reported on this topic for me to cut corners, so all checks are in...
+ *
+ * - Gordon Russell <gor@debian.org>
+ */
+
+/* ...but I don't have a pcmcia system. I use some routines in a sub-directory
+ * in the build directory to allow me to do some testing...
+ */
+
+extern char *progname;
+
+#undef DEBUGPCMCIA
+/* #define DEBUGPCMCIA */
+
+#ifdef DEBUGPCMCIA
+#define STABFILE {"pcmcia/var_run_stab",NULL}
+#define CARDCTL "./pcmcia/cardctl"
+#else
+#define STABFILE {"/var/run/stab","/var/state/pcmcia/stab","/var/lib/pcmcia/stab",NULL}
+#define CARDCTL "/sbin/cardctl"
+#endif
+
+/*
+ * Just a check to make sure the device exists
+ */
+int safety_check(char *devname)
+{
+ if (access(devname,F_OK)) {
+ fprintf(stderr," %s: device is not found\n",devname);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * check if the i/o address supplied for the port currently belongs to a
+ * pcmcia i/o window using cardctl
+ */
+int pcmcia_check_cardctl(char *devname,int devport)
+{
+int filedes[2],pid; /* [0] is reading, [1] writing */
+char *buffer;
+char *i;
+ssize_t sz;
+int w,f,t,status;
+int willreturn;
+ willreturn=1;
+ if (access(CARDCTL,F_OK)) return 1;
+ if (pipe(filedes)==0) {
+ switch(pid = fork()) {
+ case -1 : fprintf(stderr," setserial: unable to check cardctl (fork)\n");
+ return 1;
+ case 0 : /* child */
+ close(0); close(1); close(2);
+ close(filedes[0]);
+ dup2(filedes[1],1);
+ dup2(filedes[1],2);
+ execl(CARDCTL,CARDCTL,"config",NULL);
+ /* printf("unable to execute %s\n",CARDCTL); */
+ exit(127);
+ default : /* parent */
+ close(filedes[1]);
+ /* I need a buffer, but how big? Lets play safe... */
+ buffer = malloc(sizeof(char)*50000);
+ while ((sz = read(filedes[0],buffer,50000))) {
+ i = buffer;
+ while (i = strstr(i,"I/O window ")) {
+ if (sscanf(i,"I/O window %d: %x to %x,",&w,&f,&t)!=0) {
+ /* printf("%d 0x0%x 0x0%x\n",w,f,t); */
+ if ((devport>=f)&&(devport<=t)) {
+ fprintf(stderr," %s: port 0x0%x lies in pcmcia i/o window\n",devname,devport);
+ willreturn=0;
+ }
+ }
+ i++;
+ }
+ }
+ free(buffer);
+ close(filedes[0]);
+ }
+ if (waitpid(pid, &status, 0) == -1) {
+ if (status != 0) {
+ fprintf(stderr," setserial: strange response during cardctl command\n");
+ }
+ }
+ return willreturn;
+ } else {
+ fprintf(stderr," setserial: unable to check cardctl (pipe)\n");
+ return 1;
+ }
+}
+
+/*
+ * check that the device name specified is not being controlled by a
+ * pcmcia manager as specified in the stab file
+ */
+int pcmcia_check_stab(char *devname)
+{
+char *i,**s,buffer[1024],dev[128];
+int j;
+FILE *stab;
+char *stabs[] = STABFILE;
+
+ for (s = stabs; *s; s++) {
+ /* printf("Scanning %s\n",*s); */
+ if (!access(*s,F_OK))
+ if ((stab = fopen(*s,"r"))!=NULL) {
+ while (!feof(stab))
+ if(fgets(buffer,1023,stab)) {
+ i = strtok(buffer,"\t");
+ for (j=0; (j<4)&&i; j++) i = strtok(NULL,"\t");
+ if (i) {
+ strcpy(dev,"/dev/");
+ strcat(dev,i);
+ /* Not perfect, since devname may not I suppose begin with a /dev */
+ if (strcmp(dev,devname)==0) {
+ fprintf(stderr," %s: pcmcia controlled device (%s)\n",
+ devname,*s);
+ return 0;
+ }
+ }
+ }
+ fclose(stab);
+ }
+ }
+ return 1;
+}
+
+const char *pcmcia_check(char *devname, int devport)
+{
+int len;
+char *cname;
+ if (safety_check(devname)) {
+ if (pcmcia_check_stab(devname))
+ if (pcmcia_check_cardctl(devname,devport))
+ return "";
+ return " pcmcia";
+ }
+ return "";
+}
+
+/*
+main()
+{
+ pcmcia_check("/dev/ttyS0",0xa1f);
+}
+*/
|