This source file includes following definitions.
- scanjet_attach
- scanjet_set_params
- scanjet_trigger_scanner
- scanjet_read
- scanjet_ctl_write
- scanjet_ctl_read
- show_es
- scanjet_set_window
- atoi
- scanjet_compute_sizes
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 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/fcntl.h>
41 #include <sys/errno.h>
42 #include <sys/ioctl.h>
43 #include <sys/malloc.h>
44 #include <sys/buf.h>
45 #include <sys/proc.h>
46 #include <sys/user.h>
47 #include <sys/device.h>
48 #include <sys/conf.h>
49 #include <sys/scanio.h>
50
51 #include <scsi/scsi_all.h>
52 #include <scsi/scsi_scanner.h>
53 #include <scsi/scsiconf.h>
54 #include <scsi/ssvar.h>
55
56 #define SCANJET_RETRIES 4
57
58 int scanjet_set_params(struct ss_softc *, struct scan_io *);
59 int scanjet_trigger_scanner(struct ss_softc *);
60 int scanjet_read(struct ss_softc *, struct buf *);
61
62
63 int scanjet_ctl_write(struct ss_softc *, char *, u_int, int);
64 int scanjet_ctl_read(struct ss_softc *, char *, u_int, int);
65 int scanjet_set_window(struct ss_softc *, int);
66 int scanjet_compute_sizes(struct ss_softc *, int);
67
68 #define atoi local_atoi
69 __inline static int atoi(const char *);
70
71
72
73
74
75 struct ss_special scanjet_special = {
76 scanjet_set_params,
77 scanjet_trigger_scanner,
78 NULL,
79 NULL,
80 scanjet_read,
81 NULL,
82 NULL,
83 NULL
84 };
85
86
87
88
89 void
90 scanjet_attach(ss, sa)
91 struct ss_softc *ss;
92 struct scsi_attach_args *sa;
93 {
94 #ifdef SCSIDEBUG
95 struct scsi_link *sc_link = sa->sa_sc_link;
96 #endif
97 int error;
98
99 SC_DEBUG(sc_link, SDEV_DB1, ("scanjet_attach: start\n"));
100 ss->sio.scan_scanner_type = 0;
101
102 printf("\n%s: ", ss->sc_dev.dv_xname);
103
104
105
106 if (!bcmp(sa->sa_inqbuf->product, "C1750A", 6)) {
107 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
108 printf("HP ScanJet IIc");
109 }
110
111 if (!bcmp(sa->sa_inqbuf->product, "C1790A", 6)) {
112 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
113 printf("HP ScanJet IIp");
114 }
115 if (!bcmp(sa->sa_inqbuf->product, "C2500A", 6)) {
116 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
117 printf("HP ScanJet IIcx");
118 }
119
120 if (!bcmp(sa->sa_inqbuf->product, "C2570A", 6)) {
121 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
122 printf("HP ScanJet 3p");
123 }
124
125 if (!bcmp(sa->sa_inqbuf->product, "C2520A", 6)) {
126 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
127 printf("HP ScanJet 3c/4c/6100C");
128 }
129 if (!bcmp(sa->sa_inqbuf->product, "C1130A", 6)) {
130 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
131 printf("HP ScanJet 4p");
132 }
133 if (!bcmp(sa->sa_inqbuf->product, "C5110A", 6)) {
134 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
135 printf("HP ScanJet 5p");
136 }
137 if (!bcmp(sa->sa_inqbuf->product, "C6290A", 6)) {
138 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
139 printf("HP ScanJet 4100C");
140 }
141 if (!bcmp(sa->sa_inqbuf->product, "C5190A", 6)) {
142 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
143 printf("HP ScanJet 5100C");
144 }
145 if (!bcmp(sa->sa_inqbuf->product, "C7190A", 6)) {
146 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
147 printf("HP ScanJet 5200C");
148 }
149 if (!bcmp(sa->sa_inqbuf->product, "C6270A", 6)) {
150 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
151 printf("HP ScanJet 6200C");
152 }
153 if (!bcmp(sa->sa_inqbuf->product, "C7670A", 6)) {
154 ss->sio.scan_scanner_type = HP_SCANJET_IIC;
155 printf("HP ScanJet 6300C");
156 }
157
158 SC_DEBUG(sc_link, SDEV_DB1, ("scanjet_attach: scanner_type = %d\n",
159 ss->sio.scan_scanner_type));
160
161
162 ss->special = scanjet_special;
163
164
165
166
167
168 error = scanjet_set_window(ss, SCSI_POLL);
169 if (error) {
170 printf(" set_window failed\n");
171 return;
172 }
173
174 error = scanjet_compute_sizes(ss, SCSI_POLL);
175 if (error) {
176 printf(" compute_sizes failed\n");
177 return;
178 }
179
180 printf("\n");
181 }
182
183
184
185
186
187
188 int
189 scanjet_set_params(ss, sio)
190 struct ss_softc *ss;
191 struct scan_io *sio;
192 {
193 int error;
194
195 #if 0
196
197
198
199 if (ss->flags & SSF_TRIGGERED) {
200 error = scanjet_rewind_scanner(ss);
201 if (error)
202 return (error);
203 }
204 #endif
205
206
207 if (sio->scan_width == 0 ||
208 sio->scan_x_origin + sio->scan_width > 10200 ||
209 sio->scan_height == 0 ||
210 sio->scan_y_origin + sio->scan_height > 16800)
211 return (EINVAL);
212
213
214 if (sio->scan_x_resolution < 100 ||
215 sio->scan_x_resolution > 400 ||
216 sio->scan_y_resolution < 100 ||
217 sio->scan_y_resolution > 400)
218 return (EINVAL);
219
220 switch (sio->scan_image_mode) {
221 case SIM_BINARY_MONOCHROME:
222 case SIM_DITHERED_MONOCHROME:
223 case SIM_GRAYSCALE:
224 case SIM_COLOR:
225 break;
226 default:
227 return (EINVAL);
228 }
229
230
231 sio->scan_scanner_type = ss->sio.scan_scanner_type;
232 bcopy(sio, &ss->sio, sizeof(struct scan_io));
233
234 error = scanjet_set_window(ss, 0);
235 if (error) {
236 uprintf("%s: set_window failed\n", ss->sc_dev.dv_xname);
237 return (error);
238 }
239 error = scanjet_compute_sizes(ss, 0);
240 if (error) {
241 uprintf("%s: compute_sizes failed\n", ss->sc_dev.dv_xname);
242 return (error);
243 }
244
245 return (0);
246 }
247
248
249
250
251
252
253 int
254 scanjet_trigger_scanner(ss)
255 struct ss_softc *ss;
256 {
257 static char *escape_codes = "\033*f0S";
258 int error;
259
260 error = scanjet_set_window(ss, 0);
261 if (error) {
262 uprintf("%s: set_window failed\n", ss->sc_dev.dv_xname);
263 return (error);
264 }
265 error = scanjet_compute_sizes(ss, 0);
266 if (error) {
267 uprintf("%s: compute_sizes failed\n", ss->sc_dev.dv_xname);
268 return (error);
269 }
270
271
272 error = scanjet_ctl_write(ss, escape_codes, strlen(escape_codes), 0);
273 if (error) {
274 uprintf("%s: trigger_scanner failed\n", ss->sc_dev.dv_xname);
275 return (error);
276 }
277
278 return (0);
279 }
280
281 int
282 scanjet_read(ss, bp)
283 struct ss_softc *ss;
284 struct buf *bp;
285 {
286 struct scsi_rw_scanner cmd;
287 struct scsi_link *sc_link = ss->sc_link;
288
289
290
291
292 bzero(&cmd, sizeof(cmd));
293 cmd.opcode = READ;
294
295
296
297
298
299 _lto3b(bp->b_bcount, cmd.len);
300
301
302
303
304 if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd, sizeof(cmd),
305 (u_char *) bp->b_data, bp->b_bcount, SCANJET_RETRIES, 100000, bp,
306 SCSI_NOSLEEP | SCSI_DATA_IN) != SUCCESSFULLY_QUEUED)
307 printf("%s: not queued\n", ss->sc_dev.dv_xname);
308 else {
309 if (bp->b_bcount >= ss->sio.scan_window_size)
310 ss->sio.scan_window_size = 0;
311 else
312 ss->sio.scan_window_size -= bp->b_bcount;
313 }
314
315 return (0);
316 }
317
318
319
320
321
322 int
323 scanjet_ctl_write(ss, buf, size, flags)
324 struct ss_softc *ss;
325 char *buf;
326 u_int size;
327 int flags;
328 {
329 struct scsi_rw_scanner cmd;
330
331 bzero(&cmd, sizeof(cmd));
332 cmd.opcode = WRITE;
333 _lto3b(size, cmd.len);
334 return (scsi_scsi_cmd(ss->sc_link, (struct scsi_generic *) &cmd,
335 sizeof(cmd), (u_char *) buf, size, 0, 100000, NULL,
336 flags | SCSI_DATA_OUT));
337 }
338
339
340
341
342
343 int
344 scanjet_ctl_read(ss, buf, size, flags)
345 struct ss_softc *ss;
346 char *buf;
347 u_int size;
348 int flags;
349 {
350 struct scsi_rw_scanner cmd;
351
352 bzero(&cmd, sizeof(cmd));
353 cmd.opcode = READ;
354 _lto3b(size, cmd.len);
355 return (scsi_scsi_cmd(ss->sc_link, (struct scsi_generic *) &cmd,
356 sizeof(cmd), (u_char *) buf, size, 0, 100000, NULL,
357 flags | SCSI_DATA_IN));
358 }
359
360
361 #ifdef SCANJETDEBUG
362 static void show_es(char *es)
363 {
364 char *p = es;
365
366 while (*p) {
367 if (*p == '\033')
368 printf("[Esc]");
369 else
370 printf("%c", *p);
371 ++p;
372 }
373 printf("\n");
374 }
375 #endif
376
377
378
379
380 int
381 scanjet_set_window(ss, flags)
382 struct ss_softc *ss;
383 int flags;
384 {
385 char escape_codes[128];
386 size_t len;
387 int n;
388
389 snprintf(escape_codes, sizeof escape_codes,
390 "\033*f%ldP\033*f%ldQ\033*f%ldX\033*f%ldY\033*a%dR\033*a%dS",
391 ss->sio.scan_width / 4,
392 ss->sio.scan_height / 4,
393 ss->sio.scan_x_origin / 4,
394 ss->sio.scan_y_origin / 4,
395 ss->sio.scan_x_resolution,
396 ss->sio.scan_y_resolution);
397
398 switch (ss->sio.scan_image_mode) {
399 case SIM_BINARY_MONOCHROME:
400 ss->sio.scan_bits_per_pixel = 1;
401
402
403
404
405 strlcat(escape_codes, "\033*a0T\033*a0I", sizeof escape_codes);
406 break;
407 case SIM_DITHERED_MONOCHROME:
408 ss->sio.scan_bits_per_pixel = 1;
409
410
411
412
413 strlcat(escape_codes, "\033*a3T\033*a0I", sizeof escape_codes);
414 break;
415 case SIM_GRAYSCALE:
416 ss->sio.scan_bits_per_pixel = 8;
417
418
419
420
421 strlcat(escape_codes, "\033*a4T\033*a1I", sizeof escape_codes);
422 break;
423 case SIM_COLOR:
424 ss->sio.scan_bits_per_pixel = 24;
425
426
427
428
429
430 strlcat(escape_codes, "\033*a5T\033*a1I\033*u2T",
431 sizeof escape_codes);
432 break;
433 }
434
435
436
437
438
439
440 len = strlen(escape_codes);
441 n = snprintf(escape_codes + len, sizeof escape_codes - len,
442 "\033*a%dG\033*a%dL\033*a%dK",
443 ss->sio.scan_bits_per_pixel,
444 (int)(ss->sio.scan_brightness) - 128,
445 (int)(ss->sio.scan_contrast) - 128);
446
447 if (n >= sizeof escape_codes - len)
448 return (ENOMEM);
449 len += n;
450
451 return (scanjet_ctl_write(ss, escape_codes, len, flags));
452 }
453
454
455
456
457 __inline static int
458 atoi(cp)
459 const char *cp;
460 {
461 int n;
462
463 for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
464 n = n * 10 + *cp - '0';
465
466 return (n);
467 }
468
469 int
470 scanjet_compute_sizes(ss, flags)
471 struct ss_softc *ss;
472 int flags;
473 {
474 int error;
475 static char *wfail = "%s: interrogate write failed\n";
476 static char *rfail = "%s: interrogate read failed\n";
477 static char *dfail = "%s: bad data returned\n";
478 static char *mono = "\033*s1025E";
479 static char *color = "\033*s1024E";
480 static char *high = "\033*s1026E";
481 char response[20];
482 char *p;
483
484
485
486
487
488
489 ss->sio.scan_width = (ss->sio.scan_width + 3) & 0xfffffffc;
490 ss->sio.scan_height = (ss->sio.scan_height + 3) & 0xfffffffc;
491
492 switch (ss->sio.scan_image_mode) {
493 case SIM_BINARY_MONOCHROME:
494 case SIM_DITHERED_MONOCHROME:
495 error = scanjet_ctl_write(ss, mono, strlen(mono), flags);
496 break;
497 case SIM_GRAYSCALE:
498 case SIM_COLOR:
499 error = scanjet_ctl_write(ss, color, strlen(color), flags);
500 break;
501 default:
502 error = EIO;
503 break;
504 }
505 if (error) {
506 uprintf(wfail, ss->sc_dev.dv_xname);
507 return (error);
508 }
509 error = scanjet_ctl_read(ss, response, 20, flags);
510 if (error) {
511 uprintf(rfail, ss->sc_dev.dv_xname);
512 return (error);
513 }
514 p = strchr(response, 'd');
515 if (p == NULL) {
516 uprintf(dfail, ss->sc_dev.dv_xname);
517 return (EIO);
518 }
519 ss->sio.scan_pixels_per_line = atoi(p + 1);
520 if (ss->sio.scan_image_mode < SIM_GRAYSCALE)
521 ss->sio.scan_pixels_per_line *= 8;
522
523 error = scanjet_ctl_write(ss, high, strlen(high), flags);
524 if (error) {
525 uprintf(wfail, ss->sc_dev.dv_xname);
526 return (error);
527 }
528 error = scanjet_ctl_read(ss, response, 20, flags);
529 if (error) {
530 uprintf(rfail, ss->sc_dev.dv_xname);
531 return (error);
532 }
533 p = strchr(response, 'd');
534 if (p == NULL) {
535 uprintf(dfail, ss->sc_dev.dv_xname);
536 return (EIO);
537 }
538 ss->sio.scan_lines = atoi(p + 1);
539
540 ss->sio.scan_window_size = ss->sio.scan_lines *
541 ((ss->sio.scan_pixels_per_line * ss->sio.scan_bits_per_pixel) / 8);
542
543 return (0);
544 }