This source file includes following definitions.
- ssmatch
- ssattach
- ss_identify_scanner
- ssopen
- ssclose
- ssminphys
- ssread
- ssstrategy
- ssstart
- ssioctl
- ss_set_window
- ricoh_is410_sw
- umax_uc630_sw
- fujitsu_m3096g_sw
- get_buffer_status
- umax_compute_sizes
- calc_umax_row_len
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 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/fcntl.h>
37 #include <sys/errno.h>
38 #include <sys/ioctl.h>
39 #include <sys/malloc.h>
40 #include <sys/buf.h>
41 #include <sys/proc.h>
42 #include <sys/user.h>
43 #include <sys/device.h>
44 #include <sys/conf.h>
45 #include <sys/scanio.h>
46
47 #include <scsi/scsi_all.h>
48 #include <scsi/scsi_scanner.h>
49 #include <scsi/scsiconf.h>
50 #include <scsi/ssvar.h>
51
52 #include <scsi/ss_mustek.h>
53
54 #define SSMODE(z) ( minor(z) & 0x03)
55 #define SSUNIT(z) ((minor(z) >> 4) )
56
57
58
59
60
61
62 #define MODE_REWIND 0
63 #define MODE_NONREWIND 1
64 #define MODE_CONTROL 3
65
66 struct quirkdata {
67 char *name;
68 u_int quirks;
69 #define SS_Q_WINDOW_DESC_LEN 0x0001
70 #define SS_Q_BRIGHTNESS 0x0002
71 #define SS_Q_REV_BRIGHTNESS 0x0004
72 #define SS_Q_THRESHOLD 0x0008
73 #define SS_Q_MONO_THRESHOLD 0x0010
74
75 #define SS_Q_CONTRAST 0x0020
76 #define SS_Q_REV_CONTRAST 0x0040
77 #define SS_Q_HALFTONE 0x0080
78 #define SS_Q_SET_RIF 0x0100
79 #define SS_Q_PADDING_TYPE 0x0200
80 #define SS_Q_BIT_ORDERING 0x0400
81 long window_descriptor_length;
82 u_int8_t brightness;
83 u_int8_t threshold;
84 u_int8_t contrast;
85 u_int8_t halftone_pattern[2];
86 int pad_type;
87 long bit_ordering;
88 u_int8_t scanner_type;
89
90
91
92
93 int (*vendor_unique_sw)(struct ss_softc *, struct scan_io *,
94 struct scsi_set_window *, void *);
95
96
97
98
99 void (*special_minphys)(struct ss_softc *, struct buf *);
100
101
102
103
104 int (*compute_sizes)(void);
105 };
106
107 struct ss_quirk_inquiry_pattern {
108 struct scsi_inquiry_pattern pattern;
109 struct quirkdata quirkdata;
110 };
111
112 struct quirkdata ss_gen_quirks = {
113 "generic", 0, 0, 0, 0, 0,
114 {0, 0}, 0, 0, GENERIC_SCSI2,
115 NULL, NULL, NULL
116 };
117
118 void ssstrategy(struct buf *);
119 void ssstart(void *);
120 void ssminphys(struct buf *);
121
122 void ss_identify_scanner(struct ss_softc *, struct scsi_inquiry_data*);
123 int ss_set_window(struct ss_softc *, struct scan_io *);
124
125 int ricoh_is410_sw(struct ss_softc *, struct scan_io *,
126 struct scsi_set_window *, void *);
127 int umax_uc630_sw(struct ss_softc *, struct scan_io *,
128 struct scsi_set_window *, void *);
129 #ifdef NOTYET
130 int fujitsu_m3096g_sw(struct ss_softc *, struct scan_io *,
131 struct scsi_set_window *, void *);
132 #endif
133
134 void get_buffer_status(struct ss_softc *, struct buf *);
135
136
137
138
139
140
141
142
143
144
145 const struct ss_quirk_inquiry_pattern ss_quirk_patterns[] = {
146 {{T_SCANNER, T_FIXED,
147 "ULTIMA ", "AT3 1.60 ", " "}, {
148 "Ultima AT3",
149 SS_Q_HALFTONE |
150 SS_Q_PADDING_TYPE,
151 0, 0, 0, 0, { 3, 0 }, 0, 0,
152 ULTIMA_AT3,
153 NULL, NULL, NULL
154 }},
155 {{T_SCANNER, T_FIXED,
156 "ULTIMA ", "A6000C PLUS ", " "}, {
157 "Ultima A6000C",
158 SS_Q_HALFTONE |
159 SS_Q_PADDING_TYPE,
160 0, 0, 0, 0, { 3, 0 }, 0, 0,
161 ULTIMA_AC6000C,
162 NULL, NULL, NULL
163 }},
164 {{T_SCANNER, T_FIXED,
165 "RICOH ", "IS50 ", " "}, {
166 "Ricoh IS-50",
167 SS_Q_WINDOW_DESC_LEN |
168 SS_Q_REV_BRIGHTNESS |
169 SS_Q_THRESHOLD |
170 SS_Q_REV_CONTRAST |
171 SS_Q_HALFTONE |
172 SS_Q_BIT_ORDERING,
173 320, 0, 0, 0, { 2, 0x0a }, 0, 7,
174 RICOH_IS50,
175 ricoh_is410_sw, get_buffer_status, NULL
176 }},
177 {{T_SCANNER, T_FIXED,
178 "RICOH ", "IS410 ", " "}, {
179 "Ricoh IS-410",
180 SS_Q_WINDOW_DESC_LEN |
181 SS_Q_THRESHOLD |
182 SS_Q_HALFTONE |
183 SS_Q_BIT_ORDERING,
184 320, 0, 0, 0, { 2, 0x0a }, 0, 7,
185 RICOH_IS410,
186 ricoh_is410_sw, get_buffer_status, NULL
187 }},
188 {{T_SCANNER, T_FIXED,
189 "IBM ", "2456-001 ", " "}, {
190 "IBM 2456",
191 SS_Q_WINDOW_DESC_LEN |
192 SS_Q_THRESHOLD |
193 SS_Q_HALFTONE |
194 SS_Q_BIT_ORDERING,
195 320, 0, 0, 0, { 2, 0x0a }, 0, 7,
196 RICOH_IS410,
197 ricoh_is410_sw, get_buffer_status, NULL
198 }},
199 {{T_SCANNER, T_FIXED,
200 "UMAX ", "UC630 ", " "}, {
201 "UMAX UC-630",
202 SS_Q_WINDOW_DESC_LEN |
203 SS_Q_HALFTONE,
204 0x2e, 0, 0, 0, { 0, 1 }, 0, 0,
205 UMAX_UC630,
206 umax_uc630_sw, NULL, NULL
207 }},
208 {{T_SCANNER, T_FIXED,
209 "UMAX ", "UG630 ", " "}, {
210 "UMAX UG-630",
211 SS_Q_WINDOW_DESC_LEN |
212 SS_Q_HALFTONE,
213 0x2e, 0, 0, 0, { 0, 1 }, 0, 0,
214 UMAX_UG630,
215 umax_uc630_sw, NULL, NULL
216 }},
217 #ifdef NOTYET
218 {{T_SCANNER, T_FIXED,
219 "FUJITSU ", "M3096Gm ", " "}, {
220 "Fujitsu M3096G",
221 SS_Q_WINDOW_DESC_LEN |
222 SS_Q_BRIGHTNESS |
223 SS_Q_MONO_THRESHOLD |
224 SS_Q_HALFTONE |
225 SS_Q_SET_RIF |
226 SS_Q_PADDING_TYPE,
227 64, 0, 0, 0, { 0, 1 }, 0, 0,
228 FUJITSU_M3096G,
229 fujistsu_m3096g_sw, NULL, NULL
230 }},
231 #else
232 {{T_SCANNER, T_FIXED,
233 "FUJITSU ", "M3096Gm ", " "}, {
234 "Fujitsu M3096G",
235 SS_Q_BRIGHTNESS |
236 SS_Q_MONO_THRESHOLD |
237 SS_Q_CONTRAST |
238 SS_Q_HALFTONE |
239 SS_Q_PADDING_TYPE,
240 0, 0, 0, 0, { 0, 1 }, 0, 0,
241 FUJITSU_M3096G,
242 NULL, NULL, NULL
243 }},
244 #endif
245 };
246
247
248 int ssmatch(struct device *, void *, void *);
249 void ssattach(struct device *, struct device *, void *);
250
251 struct cfattach ss_ca = {
252 sizeof(struct ss_softc), ssmatch, ssattach
253 };
254
255 struct cfdriver ss_cd = {
256 NULL, "ss", DV_DULL
257 };
258
259 struct scsi_device ss_switch = {
260 NULL,
261 ssstart,
262 NULL,
263 NULL,
264 };
265
266 const struct scsi_inquiry_pattern ss_patterns[] = {
267 {T_SCANNER, T_FIXED,
268 "", "", ""},
269 {T_SCANNER, T_REMOV,
270 "", "", ""},
271 {T_PROCESSOR, T_FIXED,
272 "HP ", "C1750A ", ""},
273 {T_PROCESSOR, T_FIXED,
274 "HP ", "C1790A ", ""},
275 {T_PROCESSOR, T_FIXED,
276 "HP ", "C2500A ", ""},
277 {T_PROCESSOR, T_FIXED,
278 "HP ", "C2570A ", ""},
279 {T_PROCESSOR, T_FIXED,
280 "HP ", "C2520A ", ""},
281 {T_PROCESSOR, T_FIXED,
282 "HP ", "C1130A ", ""},
283 {T_PROCESSOR, T_FIXED,
284 "HP ", "C5110A ", ""},
285 {T_PROCESSOR, T_FIXED,
286 "HP ", "C6290A ", ""},
287 {T_PROCESSOR, T_FIXED,
288 "HP ", "C5190A ", ""},
289 {T_PROCESSOR, T_FIXED,
290 "HP ", "C7190A ", ""},
291 {T_PROCESSOR, T_FIXED,
292 "HP ", "C6270A ", ""},
293 {T_PROCESSOR, T_FIXED,
294 "HP ", "C7670A ", ""},
295 };
296
297 int
298 ssmatch(parent, match, aux)
299 struct device *parent;
300 void *match, *aux;
301 {
302 struct scsi_attach_args *sa = aux;
303 int priority;
304
305 (void)scsi_inqmatch(sa->sa_inqbuf,
306 ss_patterns, sizeof(ss_patterns)/sizeof(ss_patterns[0]),
307 sizeof(ss_patterns[0]), &priority);
308 return (priority);
309 }
310
311
312
313
314
315
316
317 void
318 ssattach(parent, self, aux)
319 struct device *parent, *self;
320 void *aux;
321 {
322 struct ss_softc *ss = (void *)self;
323 struct scsi_attach_args *sa = aux;
324 struct scsi_link *sc_link = sa->sa_sc_link;
325
326 SC_DEBUG(sc_link, SDEV_DB2, ("ssattach:\n"));
327
328
329
330
331 ss->sc_link = sc_link;
332 sc_link->device = &ss_switch;
333 sc_link->device_softc = ss;
334 sc_link->openings = 1;
335
336 if (!bcmp(sa->sa_inqbuf->vendor, "MUSTEK", 6))
337 mustek_attach(ss, sa);
338 else if (!bcmp(sa->sa_inqbuf->vendor, "HP ", 8))
339 scanjet_attach(ss, sa);
340 else
341 ss_identify_scanner(ss, sa->sa_inqbuf);
342
343
344
345
346 ss->sio.scan_width = 1200;
347 ss->sio.scan_height = 1200;
348 ss->sio.scan_x_resolution = 100;
349 ss->sio.scan_y_resolution = 100;
350 ss->sio.scan_x_origin = 0;
351 ss->sio.scan_y_origin = 0;
352 ss->sio.scan_brightness = 128;
353 ss->sio.scan_contrast = 128;
354 ss->sio.scan_quality = 100;
355 ss->sio.scan_image_mode = SIM_GRAYSCALE;
356
357
358
359
360
361
362
363 ss->buf_queue.b_active = 0;
364 ss->buf_queue.b_actf = 0;
365 ss->buf_queue.b_actb = &ss->buf_queue.b_actf;
366 }
367
368 void
369 ss_identify_scanner(ss, inqbuf)
370 struct ss_softc *ss;
371 struct scsi_inquiry_data *inqbuf;
372 {
373 const struct ss_quirk_inquiry_pattern *finger;
374 int priority;
375
376
377
378
379 finger = (const struct ss_quirk_inquiry_pattern *)scsi_inqmatch(inqbuf,
380 ss_quirk_patterns,
381 sizeof(ss_quirk_patterns)/sizeof(ss_quirk_patterns[0]),
382 sizeof(ss_quirk_patterns[0]), &priority);
383 if (priority != 0) {
384 ss->quirkdata = &finger->quirkdata;
385 if (ss->quirkdata->special_minphys != NULL) {
386 ss->special.minphys = ss->quirkdata->special_minphys;
387 }
388 ss->sio.scan_scanner_type = ss->quirkdata->scanner_type;
389 printf("\n%s: %s\n", ss->sc_dev.dv_xname, ss->quirkdata->name);
390 } else {
391 printf("\n%s: generic scanner\n", ss->sc_dev.dv_xname);
392 bzero(&ss_gen_quirks, sizeof(ss_gen_quirks));
393 ss->quirkdata = &ss_gen_quirks;
394 ss->sio.scan_scanner_type = GENERIC_SCSI2;
395 }
396 }
397
398
399
400
401 int
402 ssopen(dev, flag, mode, p)
403 dev_t dev;
404 int flag;
405 int mode;
406 struct proc *p;
407 {
408 int unit;
409 u_int ssmode;
410 int error = 0;
411 struct ss_softc *ss;
412 struct scsi_link *sc_link;
413
414 unit = SSUNIT(dev);
415 if (unit >= ss_cd.cd_ndevs)
416 return (ENXIO);
417 ss = ss_cd.cd_devs[unit];
418 if (!ss)
419 return (ENXIO);
420
421 ssmode = SSMODE(dev);
422 sc_link = ss->sc_link;
423
424 SC_DEBUG(sc_link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,
425 unit, ss_cd.cd_ndevs));
426
427 if (sc_link->flags & SDEV_OPEN) {
428 printf("%s: already open\n", ss->sc_dev.dv_xname);
429 return (EBUSY);
430 }
431
432
433
434
435
436
437
438
439 error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
440 SCSI_IGNORE_MEDIA_CHANGE | SCSI_IGNORE_ILLEGAL_REQUEST |
441 (ssmode == MODE_CONTROL ? SCSI_IGNORE_NOT_READY : 0));
442 if (error)
443 goto bad;
444
445 sc_link->flags |= SDEV_OPEN;
446
447
448
449
450
451
452 if (ssmode == MODE_CONTROL)
453 return (0);
454
455 SC_DEBUG(sc_link, SDEV_DB2, ("open complete\n"));
456 return (0);
457
458 bad:
459 sc_link->flags &= ~SDEV_OPEN;
460 return (error);
461 }
462
463
464
465
466
467 int
468 ssclose(dev, flag, mode, p)
469 dev_t dev;
470 int flag;
471 int mode;
472 struct proc *p;
473 {
474 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)];
475 int error;
476
477 SC_DEBUG(ss->sc_link, SDEV_DB1, ("closing\n"));
478
479 if (SSMODE(dev) == MODE_REWIND) {
480 if (ss->special.rewind_scanner) {
481
482 error = (ss->special.rewind_scanner)(ss);
483 if (error)
484 return (error);
485 } else {
486
487 }
488 ss->sio.scan_window_size = 0;
489 ss->flags &= ~SSF_TRIGGERED;
490 }
491 ss->sc_link->flags &= ~SDEV_OPEN;
492
493 return (0);
494 }
495
496
497
498
499
500
501
502 void
503 ssminphys(bp)
504 struct buf *bp;
505 {
506 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(bp->b_dev)];
507
508 (ss->sc_link->adapter->scsi_minphys)(bp);
509
510
511
512
513
514
515
516 if (ss->special.minphys)
517 (ss->special.minphys)(ss, bp);
518 }
519
520
521
522
523
524
525 int
526 ssread(dev, uio, flag)
527 dev_t dev;
528 struct uio *uio;
529 int flag;
530 {
531 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)];
532 int error;
533
534
535 if (!(ss->flags & SSF_TRIGGERED)) {
536 if (ss->special.trigger_scanner) {
537 error = (ss->special.trigger_scanner)(ss);
538 if (error)
539 return (error);
540 } else {
541 struct scsi_start_stop trigger_cmd;
542 bzero(&trigger_cmd, sizeof(trigger_cmd));
543 trigger_cmd.opcode = START_STOP;
544 trigger_cmd.how = SSS_START;
545 scsi_scsi_cmd(ss->sc_link,
546 (struct scsi_generic *)&trigger_cmd,
547 sizeof(trigger_cmd), 0, 0, 4, 5000, NULL, 0);
548 }
549 ss->flags |= SSF_TRIGGERED;
550 }
551
552 return (physio(ssstrategy, NULL, dev, B_READ, ssminphys, uio));
553 }
554
555
556
557
558
559
560 void
561 ssstrategy(bp)
562 struct buf *bp;
563 {
564 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(bp->b_dev)];
565 struct buf *dp;
566 int s;
567
568 SC_DEBUG(ss->sc_link, SDEV_DB2, ("ssstrategy: %ld bytes @ blk %d\n",
569 bp->b_bcount, bp->b_blkno));
570
571 if (bp->b_bcount > ss->sio.scan_window_size)
572 bp->b_bcount = ss->sio.scan_window_size;
573
574
575
576
577 if (bp->b_bcount == 0)
578 goto done;
579
580 s = splbio();
581
582
583
584
585
586
587 dp = &ss->buf_queue;
588 bp->b_actf = NULL;
589 bp->b_actb = dp->b_actb;
590 *dp->b_actb = bp;
591 dp->b_actb = &bp->b_actf;
592
593
594
595
596
597
598 ssstart(ss);
599
600 splx(s);
601 return;
602
603 done:
604
605
606
607 bp->b_resid = bp->b_bcount;
608 s = splbio();
609 biodone(bp);
610 splx(s);
611 }
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627 void
628 ssstart(v)
629 void *v;
630 {
631 struct ss_softc *ss = v;
632 struct scsi_link *sc_link = ss->sc_link;
633 struct buf *bp, *dp;
634 struct scsi_r_scanner read_cmd;
635 int flags;
636
637 SC_DEBUG(sc_link, SDEV_DB2, ("ssstart\n"));
638
639
640
641
642 while (sc_link->openings > 0) {
643
644 if (sc_link->flags & SDEV_WAITING) {
645 sc_link->flags &= ~SDEV_WAITING;
646 wakeup((caddr_t)sc_link);
647 return;
648 }
649
650
651
652
653 dp = &ss->buf_queue;
654 if ((bp = dp->b_actf) == NULL)
655 return;
656 if ((dp = bp->b_actf) != NULL)
657 dp->b_actb = bp->b_actb;
658 else
659 ss->buf_queue.b_actb = bp->b_actb;
660 *bp->b_actb = dp;
661
662 if (ss->special.read) {
663 (ss->special.read)(ss, bp);
664 } else {
665
666 bzero(&read_cmd, sizeof(read_cmd));
667 read_cmd.opcode = READ_BIG;
668 _lto3b(bp->b_bcount, read_cmd.len);
669 flags = SCSI_DATA_IN;
670
671
672
673 if (scsi_scsi_cmd(sc_link, (struct scsi_generic *)
674 &read_cmd, sizeof(read_cmd), (u_char *) bp->b_data,
675 bp->b_bcount, 0, 100000, bp, flags | SCSI_NOSLEEP))
676 printf("%s: not queued\n", ss->sc_dev.dv_xname);
677 }
678 }
679 }
680
681
682
683
684
685 int
686 ssioctl(dev, cmd, addr, flag, p)
687 dev_t dev;
688 u_long cmd;
689 caddr_t addr;
690 int flag;
691 struct proc *p;
692 {
693 struct ss_softc *ss = ss_cd.cd_devs[SSUNIT(dev)];
694 int error = 0;
695 struct scan_io *sio;
696
697 switch (cmd) {
698 case SCIOCGET:
699
700 if (ss->special.get_params) {
701 error = (ss->special.get_params)(ss);
702 if (error)
703 return (error);
704 }
705 bcopy(&ss->sio, addr, sizeof(struct scan_io));
706 break;
707 case SCIOCSET:
708 sio = (struct scan_io *)addr;
709
710
711 if (ss->special.set_params) {
712 error = (ss->special.set_params)(ss, sio);
713 if (error)
714 return (error);
715 } else {
716
717 ss_set_window(ss, sio);
718 }
719 break;
720 case SCIOCRESTART:
721
722 if (ss->special.rewind_scanner ) {
723 error = (ss->special.rewind_scanner)(ss);
724 if (error)
725 return (error);
726 } else
727
728 return (EOPNOTSUPP);
729 ss->flags &= ~SSF_TRIGGERED;
730 break;
731 case SCIOC_USE_ADF:
732
733 return (EOPNOTSUPP);
734 default:
735 if (SSMODE(dev) != MODE_CONTROL)
736 return (ENOTTY);
737 return (scsi_do_ioctl(ss->sc_link, dev, cmd, addr,
738 flag, p));
739 }
740 return (error);
741 }
742
743 int
744 ss_set_window(ss, sio)
745 struct ss_softc *ss;
746 struct scan_io *sio;
747 {
748 struct scsi_set_window window_cmd;
749 struct {
750 struct scsi_window_data window_data;
751
752
753
754
755 u_int8_t vendor_unique[280];
756 } wd;
757 #define window_data wd.window_data
758 #define vendor_unique wd.vendor_unique
759 struct scsi_link *sc_link = ss->sc_link;
760
761
762
763
764
765 bzero(&window_cmd, sizeof(window_cmd));
766 window_cmd.opcode = SET_WINDOW;
767 _lto3l(sizeof(window_data), window_cmd.len);
768
769 bzero(&window_data, sizeof(window_data));
770 if (ss->quirkdata->quirks & SS_Q_WINDOW_DESC_LEN)
771 _lto2l(ss->quirkdata->window_descriptor_length,
772 window_data.window_desc_len);
773 else
774 _lto2l(40L, window_data.window_desc_len);
775
776
777
778
779
780 _lto2l(sio->scan_x_resolution, window_data.x_res);
781 _lto2l(sio->scan_y_resolution, window_data.y_res);
782 _lto4l(sio->scan_x_origin, window_data.x_org);
783 _lto4l(sio->scan_y_origin, window_data.y_org);
784 _lto4l(sio->scan_width, window_data.width);
785 _lto4l(sio->scan_height, window_data.length);
786
787 if (ss->quirkdata->quirks & SS_Q_REV_BRIGHTNESS)
788 window_data.brightness = 256 - sio->scan_brightness;
789 else if (ss->quirkdata->quirks & SS_Q_BRIGHTNESS)
790 window_data.brightness = ss->quirkdata->brightness;
791 else
792 window_data.brightness = sio->scan_brightness;
793
794
795
796
797
798
799
800
801
802
803 if (ss->quirkdata->quirks & SS_Q_MONO_THRESHOLD) {
804 if (sio->scan_image_mode == SIM_BINARY_MONOCHROME ||
805 sio->scan_image_mode == SIM_DITHERED_MONOCHROME)
806 window_data.threshold = ss->quirkdata->threshold;
807 else
808 window_data.threshold = sio->scan_brightness;
809 } else if (ss->quirkdata->quirks & SS_Q_THRESHOLD)
810 window_data.threshold = ss->quirkdata->threshold;
811 else
812 window_data.threshold = sio->scan_brightness;
813
814 if (ss->quirkdata->quirks & SS_Q_REV_CONTRAST)
815 window_data.contrast = 256 - sio->scan_contrast;
816 else if (ss->quirkdata->quirks & SS_Q_CONTRAST)
817 window_data.contrast = ss->quirkdata->contrast;
818 else
819 window_data.contrast = sio->scan_contrast;
820
821 switch (sio->scan_image_mode) {
822 case SIM_RED:
823 case SIM_GREEN:
824 case SIM_BLUE:
825 window_data.image_comp = SIM_GRAYSCALE;
826 break;
827 default:
828 window_data.image_comp = sio->scan_image_mode;
829 }
830
831 window_data.bits_per_pixel = sio->scan_bits_per_pixel;
832
833 if (ss->quirkdata->quirks & SS_Q_HALFTONE) {
834 window_data.halftone_pattern[0] =
835 ss->quirkdata->halftone_pattern[0];
836 window_data.halftone_pattern[1] =
837 ss->quirkdata->halftone_pattern[1];
838 }
839
840 if (ss->quirkdata->quirks & SS_Q_SET_RIF)
841 window_data.rif = 1;
842
843 if (ss->quirkdata->quirks & SS_Q_PADDING_TYPE)
844 window_data.pad_type = ss->quirkdata->pad_type;
845 else
846 window_data.pad_type = 3;
847
848 if (ss->quirkdata->quirks & SS_Q_BIT_ORDERING)
849 _lto2l(ss->quirkdata->bit_ordering, window_data.bit_ordering);
850
851
852
853
854 #undef window_data
855
856 if (ss->quirkdata->vendor_unique_sw != NULL)
857 return ((*ss->quirkdata->vendor_unique_sw)(ss, sio,
858 &window_cmd, (void *)&wd));
859 else
860
861 return (scsi_scsi_cmd(sc_link,
862 (struct scsi_generic *)&window_cmd,
863 sizeof(window_cmd), (u_char *) &wd.window_data,
864 (ss->quirkdata->quirks & SS_Q_WINDOW_DESC_LEN) ?
865 ss->quirkdata->window_descriptor_length : 40,
866 4, 5000, NULL, SCSI_DATA_OUT));
867 }
868
869 int
870 ricoh_is410_sw(ss, sio, wcmd, vwd)
871 struct ss_softc *ss;
872 struct scan_io *sio;
873 struct scsi_set_window *wcmd;
874 void *vwd;
875 {
876 struct ricoh_is410_window_data {
877 struct scsi_window_data window_data;
878 u_int8_t res1;
879 u_int8_t res2;
880 u_int mrif:1;
881 u_int filtering:3;
882 u_int gamma_id:4;
883 } *rwd = (struct ricoh_is410_window_data*)vwd;
884 struct scsi_link *sc_link = ss->sc_link;
885
886 rwd->mrif = 1;
887
888
889 return (scsi_scsi_cmd(sc_link, (struct scsi_generic *)wcmd,
890 sizeof(struct scsi_set_window), (u_char *)rwd,
891 sizeof(struct ricoh_is410_window_data), 4, 5000, NULL,
892 SCSI_DATA_OUT));
893 }
894
895 int
896 umax_uc630_sw(ss, sio, wcmd, vwd)
897 struct ss_softc *ss;
898 struct scan_io *sio;
899 struct scsi_set_window *wcmd;
900 void *vwd;
901 {
902 struct umax_uc630_window_data {
903 struct scsi_window_data window_data;
904 u_int8_t speed;
905 u_int8_t select_color;
906 u_int8_t highlight;
907 u_int8_t shadow;
908 u_int8_t paper_length[2];
909 } *uwd = (struct umax_uc630_window_data*)vwd;
910 struct scsi_link *sc_link = ss->sc_link;
911
912 uwd->speed = 1;
913 switch (sio->scan_image_mode) {
914 case SIM_RED:
915 uwd->select_color = 0x80;
916 break;
917 case SIM_GREEN:
918 uwd->select_color = 0x40;
919 break;
920 case SIM_BLUE:
921 uwd->select_color = 0x20;
922 break;
923 }
924 uwd->highlight = 50;
925
926
927
928
929 return (scsi_scsi_cmd(sc_link, (struct scsi_generic *)wcmd,
930 sizeof(struct scsi_set_window), (u_char *)uwd,
931 sizeof(struct umax_uc630_window_data), 4, 5000, NULL,
932 SCSI_DATA_OUT));
933 }
934
935 #ifdef NOTYET
936 int
937 fujitsu_m3096g_sw(ss, sio, wcmd, vwd)
938 struct ss_softc *ss;
939 struct scan_io *sio;
940 struct scsi_set_window *wcmd;
941 void *vwd;
942 {
943 struct fujitsu_m3096g_window_data {
944 struct scsi_window_data window_data;
945 u_int8_t id;
946 u_int8_t res1;
947 u_int8_t outline;
948 u_int8_t emphasis;
949 u_int8_t mixed;
950 u_int8_t mirroring;
951 u_int8_t res2[5];
952 u_int8_t subwindow_list[2];
953 u_int paper_size_std:2;
954 u_int res3:1;
955 u_int paper_orientaton:1;
956 u_int paper_size_type:4;
957
958 #define FUJITSU_PST_A3 0x03
959 #define FUJITSU_PST_A4 0x04
960 #define FUJITSU_PST_A5 0x05
961 #define FUJITSU_PST_DOUBLE_LETTER 0x06
962 #define FUJITSU_PST_LETTER 0x07
963 #define FUJITSU_PST_B4 0x0C
964 #define FUJITSU_PST_B5 0x0D
965 #define FUJITSU_PST_LEGAL 0x0F
966 u_int8_t paper_width_x[4];
967 u_int8_t paper_width_y[4];
968 u_int8_t res4[2];
969 } *fwd = (struct fujitsu_m3096g_window_data*)vwd;
970 struct scsi_link *sc_link = ss->sc_link;
971
972
973 return (scsi_scsi_cmd(sc_link, (struct scsi_generic *)wcmd,
974 sizeof(struct scsi_set_window), (u_char *)fwd,
975 sizeof(struct fujitsu_m3096g_window_data), 4, 5000, NULL,
976 SCSI_DATA_OUT));
977 }
978 #endif
979
980 void
981 get_buffer_status(ss, bp)
982 struct ss_softc *ss;
983 struct buf *bp;
984 {
985 struct scsi_get_buffer_status gbs_cmd;
986 struct scsi_link *sc_link = ss->sc_link;
987 struct {
988 u_int8_t stat_len[3];
989 u_int8_t res1;
990 u_int8_t window_id;
991 u_int8_t res2;
992 u_int8_t tgt_accept_buf_len[3];
993 u_int8_t tgt_send_buf_len[3];
994 } buf_sz_retn;
995 int flags;
996
997 bzero(&gbs_cmd, sizeof(gbs_cmd));
998 gbs_cmd.opcode = GET_BUFFER_STATUS;
999 _lto2b(12, gbs_cmd.len);
1000 flags = SCSI_DATA_IN;
1001
1002 if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &gbs_cmd,
1003 sizeof(gbs_cmd), (u_char *) &buf_sz_retn, sizeof(buf_sz_retn),
1004 0, 100000, bp, flags | SCSI_NOSLEEP)) {
1005 printf("%s: not queued\n", ss->sc_dev.dv_xname);
1006 }
1007 bp->b_bcount = MIN(_3btol(buf_sz_retn.tgt_send_buf_len), bp->b_bcount);
1008 }
1009
1010 #ifdef NOTYET
1011 int
1012 umax_compute_sizes(ss)
1013 struct ss_softc *ss;
1014 {
1015 ss->sio.scan_lines = ;
1016 ss->sio.scan_window_size = ;
1017 }
1018
1019 int
1020 calc_umax_row_len(dpi, ww)
1021 int dpi;
1022 int ww;
1023 {
1024 int st[301];
1025 int i;
1026 int rowB = 0;
1027
1028 for (i = 1; i <= 300; i++)
1029 st[i] = 1;
1030
1031 for (i = 1; i <= 300 - dpi; i++)
1032 st[i * 300 / (300 - dpi)] = 0;
1033
1034 for (i = 1; i <= (ww % 1200) / 4; i++) {
1035 if (st[i])
1036 rowB++;
1037 }
1038
1039 return ((ww / 1200) * dpi + rowB);
1040 }
1041 #endif