]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/hwinfo/src/hd/parallel.c
Kleiner netter neuer Versuch.
[people/pmueller/ipfire-2.x.git] / src / hwinfo / src / hd / parallel.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8
9 #include "hd.h"
10 #include "hd_int.h"
11 #include "parallel.h"
12
13 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
14 * parallel port device info
15 *
16 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
17 */
18
19 #ifndef LIBHD_TINY
20
21 static void do_lp(hd_data_t *hd_data);
22 static void do_zip(hd_data_t *hd_data);
23 static void dump_parallel_data(hd_data_t *hd_data, str_list_t *sl);
24
25 void hd_scan_parallel(hd_data_t *hd_data)
26 {
27 if(!hd_probe_feature(hd_data, pr_parallel)) return;
28
29 hd_data->module = mod_parallel;
30
31 /* some clean-up */
32 remove_hd_entries(hd_data);
33
34 if(hd_probe_feature(hd_data, pr_parallel_lp)) do_lp(hd_data);
35
36 if(hd_probe_feature(hd_data, pr_parallel_zip)) do_zip(hd_data);
37 }
38
39 void do_lp(hd_data_t *hd_data)
40 {
41 hd_t *hd, *hd_i;
42 str_list_t *sl, *sl0;
43 hd_res_t *res;
44 char *pp = NULL, buf[256], unix_dev[] = "/dev/lp0", *s = NULL;
45 char *base_class, *device, *vendor, *cmd_set;
46 int i, j, port;
47 str_list_t *log = NULL;
48
49 PROGRESS(1, 0, "pp mod");
50
51 for(hd = hd_data->hd; hd; hd = hd->next) {
52 if(hd->base_class.id == bc_comm && hd->sub_class.id == sc_com_par) break;
53 }
54
55 /* ... if there seems to be a parallel interface, try to load it */
56 if(hd || 1) { /* always load it */
57 if(hd_data->kernel_version == KERNEL_22) {
58 unload_module(hd_data, "parport_probe");
59 probe_module(hd_data, "parport_probe");
60 } else {
61 unload_module(hd_data, "lp");
62 unload_module(hd_data, "parport_pc");
63 probe_module(hd_data, "parport_pc");
64 }
65 }
66
67 for(i = 0; i < 3; i++, unix_dev[sizeof unix_dev - 2]++) {
68 PROGRESS(2, 1 + i, "lp read info");
69
70 port = 0;
71 // ##### read modes as well? (e.g: SPP,ECP,ECPEPP,ECPPS2)
72 if(hd_data->kernel_version == KERNEL_22)
73 str_printf(&pp, 0, PROC_PARPORT_22 "%d/hardware", i);
74 else
75 str_printf(&pp, 0, PROC_PARPORT_24 "%d/base-addr", i);
76 sl0 = read_file(pp, 0, 0);
77 if(!sl0) continue; /* file doesn't exist -> no parport entry */
78 str_printf(&s, 0, "%s\n", pp);
79 add_str_list(&log, s);
80 for(sl = sl0; sl; sl = sl->next) {
81 str_printf(&s, 0, " %s", sl->str);
82 add_str_list(&log, s);
83 if(hd_data->kernel_version == KERNEL_22) {
84 if(sscanf(sl->str, "base: %i", &j) == 1) port = j;
85 } else {
86 if(sscanf(sl->str, "%i", &j) == 1) port = j;
87 }
88 }
89 free_str_list(sl0);
90
91 if(hd_data->kernel_version == KERNEL_22)
92 str_printf(&pp, 0, PROC_PARPORT_22 "%d/autoprobe", i);
93 else
94 str_printf(&pp, 0, PROC_PARPORT_24 "%d/autoprobe", i);
95 sl0 = read_file(pp, 0, 0);
96 str_printf(&s, 0, "%s\n", pp);
97 add_str_list(&log, s);
98 base_class = device = vendor = cmd_set = NULL;
99 for(sl = sl0; sl; sl = sl->next) {
100 str_printf(&s, 0, " %s", sl->str);
101 add_str_list(&log, s);
102 // fprintf(stderr, "str = \"%s\"\n", sl->str);
103 if(sscanf(sl->str, "CLASS: %255[^\n;]", buf) == 1) base_class = new_str(buf);
104 if(sscanf(sl->str, "MODEL: %255[^\n;]", buf) == 1) device = new_str(buf);
105 if(sscanf(sl->str, "MANUFACTURER: %255[^\n;]", buf) == 1) vendor = new_str(buf);
106 if(sscanf(sl->str, "COMMAND SET: %255[^\n;]", buf) == 1) cmd_set = new_str(buf);
107 }
108 free_str_list(sl0);
109
110 /* default to printer */
111 if(!base_class && vendor && device) base_class = new_str("printer");
112
113 s = free_mem(s);
114
115 // fprintf(stderr, "port <0x%x\n", port);
116 // fprintf(stderr, "class <%s>\n", base_class);
117 // fprintf(stderr, "device <%s>\n", device);
118 // fprintf(stderr, "vendor <%s>\n", vendor);
119 // fprintf(stderr, "cmds <%s>\n", cmd_set);
120
121 for(hd = hd_data->hd; hd; hd = hd->next) {
122 if(
123 hd->base_class.id == bc_comm &&
124 hd->sub_class.id == sc_com_par &&
125 hd->unix_dev_name &&
126 !strcmp(hd->unix_dev_name, unix_dev)
127 ) break;
128 }
129
130 if(!hd) {
131 /* no entry ??? */
132 hd = add_hd_entry(hd_data, __LINE__, 0);
133 hd->base_class.id = bc_comm;
134 hd->sub_class.id = sc_com_par;
135 hd->unix_dev_name = new_str(unix_dev);
136 if(port) {
137 res = add_res_entry(&hd->res, new_mem(sizeof *res));
138 res->io.type = res_io;
139 res->io.enabled = 1;
140 res->io.base = port;
141 res->io.access = acc_rw;
142 }
143 }
144
145 // ##### check if ports match?
146
147 if(
148 base_class ||
149 (device && strcmp(device, "Unknown device")) ||
150 (vendor && strcmp(vendor, "Unknown vendor"))
151 ) {
152 hd_i = hd;
153 hd = add_hd_entry(hd_data, __LINE__, 0);
154 hd->attached_to = hd_i->idx;
155 hd->unix_dev_name = new_str(hd_i->unix_dev_name);
156 hd->base_class.id = bc_none;
157 if(base_class && !strcasecmp(base_class, "printer")) hd->base_class.id = bc_printer;
158 hd->bus.id = bus_parallel;
159
160 hd->vendor.name = new_str(vendor);
161 hd->device.name = new_str(device);
162 }
163
164 free_mem(base_class);
165 free_mem(device);
166 free_mem(vendor);
167 free_mem(cmd_set);
168 }
169
170 pp = free_mem(pp);
171
172 if((hd_data->debug & HD_DEB_PARALLEL)) dump_parallel_data(hd_data, log);
173
174 free_str_list(log);
175
176 }
177
178 void do_zip(hd_data_t *hd_data)
179 {
180 hd_t *hd, *hd_i;
181 int i, j, port, is_imm, is_ppa, is_imm0, is_ppa0;
182 char *pp = NULL, *s = NULL, *unix_dev = NULL;
183 str_list_t *log = NULL, *sl, *sl0;
184 int do_imm = hd_probe_feature(hd_data, pr_parallel_imm);
185
186 is_imm = is_imm0 = hd_module_is_active(hd_data, "imm");
187 is_ppa = is_ppa0 = hd_module_is_active(hd_data, "ppa");
188
189 if(!(is_imm || is_ppa)) {
190 for(hd = hd_data->hd; hd; hd = hd->next) {
191 if(hd->base_class.id == bc_comm && hd->sub_class.id == sc_com_par) break;
192 }
193 /* ... if there seems to be a parallel interface, try to load it */
194 if(hd) {
195 if(do_imm) {
196 PROGRESS(5, 0, "imm mod");
197 load_module(hd_data, "imm");
198 }
199 PROGRESS(5, 0, "ppa mod");
200 load_module(hd_data, "ppa");
201 is_imm = hd_module_is_active(hd_data, "imm");
202 is_ppa = hd_module_is_active(hd_data, "ppa");
203 if(do_imm && !is_imm) {
204 int fd;
205 char flush[2] = { 4, 12 };
206
207 fd = open("/dev/lp0", O_NONBLOCK | O_WRONLY);
208 if(fd != -1) {
209 write(fd, flush, sizeof flush);
210 close(fd);
211 }
212 }
213 }
214 }
215
216 if(!(is_imm || is_ppa)) return;
217
218 PROGRESS(6, 0, "zip read info");
219
220 for(i = 0; i < 16; i++) {
221 str_printf(&pp, 0, PROC_SCSI "/%s/%d", (i % 2) ? "ppa" : "imm", i / 2);
222 sl0 = read_file(pp, 0, 0);
223 if(!sl0) continue;
224 str_printf(&s, 0, "%s\n", pp);
225 add_str_list(&log, s);
226 port = -1;
227 for(sl = sl0; sl; sl = sl->next) {
228 str_printf(&s, 0, " %s", sl->str);
229 add_str_list(&log, s);
230 if(sscanf(sl->str, "Parport : parport%d", &j) == 1) port = j;
231 }
232 free_str_list(sl0);
233 pp = free_mem(pp);
234 s = free_mem(s);
235
236 unix_dev = free_mem(unix_dev);
237 if(port >= 0) {
238 str_printf(&unix_dev, 0, "/dev/lp%d", port);
239 }
240
241 hd = NULL;
242 if(unix_dev) {
243 for(hd = hd_data->hd; hd; hd = hd->next) {
244 if(
245 hd->base_class.id == bc_comm &&
246 hd->sub_class.id == sc_com_par &&
247 hd->unix_dev_name &&
248 !strcmp(hd->unix_dev_name, unix_dev)
249 ) break;
250 }
251
252 if(!hd) {
253 /* no entry ??? */
254 hd = add_hd_entry(hd_data, __LINE__, 0);
255 hd->base_class.id = bc_comm;
256 hd->sub_class.id = sc_com_par;
257 hd->unix_dev_name = new_str(unix_dev);
258 }
259 }
260
261 hd_i = hd;
262 hd = add_hd_entry(hd_data, __LINE__, 0);
263 if(hd_i) {
264 hd->attached_to = hd_i->idx;
265 hd->unix_dev_name = new_str(hd_i->unix_dev_name);
266 }
267 hd->base_class.id = bc_storage;
268 hd->sub_class.id = sc_sto_scsi;
269 hd->bus.id = bus_parallel;
270 hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x1800);
271 hd->device.id = MAKE_ID(TAG_SPECIAL, (i % 2) ? 2 : 1);
272 }
273
274 if(!is_imm0) unload_module(hd_data, "imm");
275 if(!is_ppa0) unload_module(hd_data, "ppa");
276
277 if((hd_data->debug & HD_DEB_PARALLEL)) dump_parallel_data(hd_data, log);
278
279 free_mem(unix_dev);
280
281 free_str_list(log);
282
283 }
284
285 void dump_parallel_data(hd_data_t *hd_data, str_list_t *sl)
286 {
287 ADD2LOG("----- parallel info -----\n");
288 for(; sl; sl = sl->next) {
289 ADD2LOG("%s", sl->str);
290 }
291 ADD2LOG("----- parallel info end -----\n");
292 }
293
294 #endif /* ifndef LIBHD_TINY */
295