• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* ------------------------------------------------------------------------- */
3 
4 /* coolscan-scsidef.h: scsi-definiton header file for COOLSCAN scanner driver.
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <https://www.gnu.org/licenses/>.
18 
19    As a special exception, the authors of SANE give permission for
20    additional uses of the libraries contained in this release of SANE.
21 
22    The exception is that, if you link a SANE library with other files
23    to produce an executable, this does not by itself cause the
24    resulting executable to be covered by the GNU General Public
25    License.  Your use of that executable is in no way restricted on
26    account of linking the SANE library code into it.
27 
28    This exception does not, however, invalidate any other reasons why
29    the executable file might be covered by the GNU General Public
30    License.
31 
32    If you submit changes to SANE to the maintainers to be included in
33    a subsequent release, you agree by submitting the changes that
34    those changes may be distributed with this exception intact.
35 
36    If you write modifications of your own for SANE, it is your choice
37    whether to permit this exception to apply to your modifications.
38    If you do not wish that, delete this exception notice.
39  */
40 
41 /* ------------------------------------------------------------------------- */
42 
43 #ifndef COOLSCAN_SCSIDEF_H
44 #define COOLSCAN_SCSIDEF_H
45 
46 /* ========================================================================= */
47 
48 /* I'm using functions derived from Eric Youngdale's scsiinfo
49  * program here for dealing with parts of SCSI commands.
50  */
51 
52 static inline void
setbitfield(unsigned char * pageaddr,int mask,int shift,int val)53 setbitfield (unsigned char *pageaddr, int mask, int shift, int val) \
54 {
55   *pageaddr = (*pageaddr & ~(mask << shift)) | ((val & mask) << shift);
56 }
57 
58 /* ------------------------------------------------------------------------- */
59 
60 static inline void
resetbitfield(unsigned char * pageaddr,int mask,int shift,int val)61 resetbitfield (unsigned char *pageaddr, int mask, int shift, int val) \
62 {
63   *pageaddr = (*pageaddr & ~(mask << shift)) | (((!val) & mask) << shift);
64 }
65 
66 /* ------------------------------------------------------------------------- */
67 
68 static inline int
getbitfield(unsigned char * pageaddr,int mask,int shift)69 getbitfield (unsigned char *pageaddr, int mask, int shift) \
70 {
71   return ((*pageaddr >> shift) & mask);
72 }
73 
74 /* ------------------------------------------------------------------------- */
75 
76 static inline int
getnbyte(unsigned char * pnt,int nbytes)77 getnbyte (unsigned char *pnt, int nbytes) \
78 {
79   unsigned int result = 0;
80   int i;
81 
82 #ifdef DEBUG
83   assert (nbytes < 5);
84 #endif
85   for (i = 0; i < nbytes; i++)
86     result = (result << 8) | (pnt[i] & 0xff);
87   return result;
88 }
89 
90 /* ------------------------------------------------------------------------- */
91 
92 static inline void
putnbyte(unsigned char * pnt,unsigned int value,unsigned int nbytes)93 putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes) \
94 {
95   int i;
96 
97 #ifdef DEBUG
98   assert (nbytes < 5);
99 #endif
100   for (i = nbytes - 1; i >= 0; i--)
101     \
102     {
103       pnt[i] = value & 0xff;
104       value = value >> 8;
105     }
106 }
107 
108 
109 /* ==================================================================== */
110 
111 /* Not all of these are defined in scsi.h, so we'll make sure
112  * we agree about them here...
113  */
114 #undef  WRITE_BUFFER		/* correct size write_buffer for scanner */
115 #define TEST_UNIT_READY         0x00
116 #define REQUEST_SENSE           0x03
117 #define INQUIRY                 0x12
118 #define MODE_SELECT		0x15
119 #define RESERVE_UNIT            0x16
120 #define RELEASE_UNIT            0x17
121 #define MODE_SENSE		0x1a
122 #define SCAN                    0x1b
123 #define SEND_DIAGNOSTIC		0x1d
124 #define SET_WINDOW              0x24
125 #define GET_WINDOW              0x25
126 #define READ                    0x28
127 #define SEND                    0x2a
128 #define OBJECT_POSITION         0x31
129 #define WRITE_BUFFER            0x3b
130 #define READ_BUFFER	        0x3c
131 #define SABORT			0xc0
132 #define COMMAND_C1		0xc1
133 #define AUTO_FOCUS		0xc2
134 #define UNIT_MOVE		0xe0
135 
136 
137 /* ==================================================================== */
138 
139 /* wdb_len if nothing is set by inquiry */
140 #define STD_WDB_LEN 0x28
141 
142 /* ==================================================================== */
143 /* SCSI commands */
144 
145 typedef struct
146 {
147   unsigned char *cmd;
148   int size;
149 }
150 scsiblk;
151 
152 /* ==================================================================== */
153 
154 #define set_inquiry_return_size(icb,val)             icb[0x04]=val
155 static unsigned char inquiryC[] =
156 {INQUIRY, 0x00, 0x00, 0x00, 0x1f, 0x00};
157 static scsiblk inquiry =
158 {inquiryC, sizeof (inquiryC)};
159 
160 #define get_inquiry_periph_qual(in)             getbitfield(in, 0x07, 5)
161 #define IN_periph_qual_lun                    0x00
162 #define IN_periph_qual_nolun                  0x03
163 #define get_inquiry_periph_devtype(in)          getbitfield(in, 0x1f, 0)
164 #define IN_periph_devtype_scanner             0x06
165 #define IN_periph_devtype_unknown             0x1f
166 #define get_inquiry_response_format(in)         getbitfield(in + 0x03, 0x07, 0)
167 #define IN_recognized                         0x02
168 #define get_inquiry_additional_length(in)       in[0x04]
169 #define get_inquiry_length(in)                  in[0x03]
170 #define set_inquiry_length(out,n)               out[0x04]=n-5
171 
172 #define get_inquiry_vendor(in, buf)             strncpy(buf, in + 0x08, 0x08)
173 #define get_inquiry_product(in, buf)            strncpy(buf, in + 0x10, 0x010)
174 #define get_inquiry_version(in, buf)            strncpy(buf, in + 0x20, 0x04)
175 
176 
177 /* ==================================================================== */
178 /*
179    static unsigned char mode_selectC[] = {
180    MODE_SELECT, 0x10, 0x00, 0x00, 0x00, 0x00
181 
182    static scsiblk mode_select = { mode_selectC,sizeof(mode_selectC) };
183  */
184 /* ==================================================================== */
185 
186 static unsigned char test_unit_readyC[] =
187 {
188   TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00
189 };
190 
191 static scsiblk test_unit_ready =
192 {test_unit_readyC, sizeof (test_unit_readyC)};
193 
194 /* ==================================================================== */
195 
196 static unsigned char reserve_unitC[] =
197 {
198   RESERVE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00
199 };
200 
201 static scsiblk reserve_unit =
202 {reserve_unitC, sizeof (reserve_unitC)};
203 
204 /* ==================================================================== */
205 
206 static unsigned char release_unitC[] =
207 {
208   RELEASE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00
209 };
210 
211 static scsiblk release_unit =
212 {release_unitC, sizeof (release_unitC)};
213 
214 /* ==================================================================== */
215 
216 static unsigned char mode_senseC[] =
217 {
218   MODE_SENSE, 0x18, 0x03, 0x00, 0x00, 0x00,	/* PF set, page type 03 */
219 };
220 #define set_MS_DBD(b, val)  setbitfield(b, 0x01, 3, (val?1:0))
221 #define set_MS_len(b, val)	putnbyte(b+0x04, val, 1)
222 #define get_MS_MUD(b)		getnbyte(b+(0x04+((int)*(b+0x3)))+0x4,2)
223 
224 static scsiblk mode_sense =
225 {mode_senseC, sizeof (mode_senseC)};
226 
227 /* ==================================================================== */
228 
229 static unsigned char set_windowC[] =
230 {
231   SET_WINDOW, 0x00,		/* opcode, lun */
232   0x00, 0x00, 0x00, 0x00,	/* reserved */
233   0x00, 0x00, 0x00,		/* transfer length; needs to be set */
234   0x00,				/* control byte */
235 };
236 #define set_SW_xferlen(sb, len) putnbyte(sb + 0x06, len, 3)
237 
238 static scsiblk set_window =
239 {set_windowC, sizeof (set_windowC)};
240 
241 /* ==================================================================== */
242 
243 static unsigned char get_windowC[] =
244 {
245   GET_WINDOW, 0x01,		/* opcode, lun, misc (should be 0x01? */
246   0x00, 0x00, 0x00,		/* reserved */
247   0x00,				/* Window identifier */
248   0x00, 0x00, 0x00,		/* transfer length; needs to be get */
249   0x00,				/* control byte */
250 };
251 #define set_GW_xferlen(sb, len) putnbyte(sb + 0x06, len, 3)
252 #define set_WindowID_wid(sb, val) sb[5] = val
253 
254 static scsiblk get_window =
255 {get_windowC, sizeof (get_windowC)};
256 
257 /* ==================================================================== */
258 
259 /* We use the same structure for both SET WINDOW and GET WINDOW. */
260 static unsigned char window_parameter_data_blockC[] =
261 {
262   0x00, 0x00,			/* window data length, in case of get, or 0 in case of set */
263   0x00, 0x00, 0x00, 0x00,	/* reserved */
264   0x00, 0x00,			/* Window Descriptor Length, value must be
265 				   set by SHORT_WDB define */
266 };
267 #define set_WPDB_wdblen(sb, len) putnbyte(sb + 0x06, len, 2)
268 
269 
270 static scsiblk window_parameter_data_block =
271 {
272   window_parameter_data_blockC, sizeof (window_parameter_data_blockC)
273 };
274 
275 
276 /* ==================================================================== */
277 
278 static unsigned char window_descriptor_blockC[] =
279 {
280 /* Any field marked with 'R' (e.g. R0x55) indicate a field provided for
281  * development. In normal operation, 0 is set here. If any other value is set,
282  * operationis not guaranteed! */
283 
284 #define max_WDB_size 0xff
285 #define used_WDB_size 0x75
286 
287   0x00,				/* 0x00 */
288 				/* Window Identifier */
289 #define set_WD_wid(sb, val) sb[0] = val
290 #define WD_wid_all 0x00		/* Only one supported */
291   0x00,				/* 0x01 */
292 				/* reserved, AUTO */
293 #define set_WD_auto(sb, val) setbitfield(sb + 0x01, 1, 0, val)
294 #define get_WD_auto(sb)	getbitfield(sb + 0x01, 1, 0)
295   0x00, 0x00,			/* 0x02 */
296 				/* X Resolution in dpi */
297 #define set_WD_Xres(sb, val) putnbyte(sb + 0x02, val, 2)
298 #define get_WD_Xres(sb)	getnbyte(sb + 0x02, 2)
299   0x00, 0x00,			/* 0x04 */
300 				/* Y Resolution in dpi */
301 #define set_WD_Yres(sb, val) putnbyte(sb + 0x04, val, 2)
302 #define get_WD_Yres(sb)	getnbyte(sb + 0x04, 2)
303   0x00, 0x00, 0x00, 0x00,	/* 0x06 */
304   /* Upper Left X in 1200|2700pt/inch */
305 #define set_WD_ULX(sb, val) putnbyte(sb + 0x06, val, 4)
306 #define get_WD_ULX(sb) getnbyte(sb + 0x06, 4)
307   0x00, 0x00, 0x00, 0x00,	/* 0x0a */
308   /* Upper Left Y in 1200|2700pt/inch */
309 #define set_WD_ULY(sb, val) putnbyte(sb + 0x0a, val, 4)
310 #define get_WD_ULY(sb) getnbyte(sb + 0x0a, 4)
311   0x00, 0x00, 0x00, 0x00,	/* 0x0e */
312   /* Width 1200pt/inch */
313 #define set_WD_width(sb, val) putnbyte(sb + 0x0e, val, 4)
314 #define get_WD_width(sb) getnbyte(sb + 0x0e, 4)
315   0x00, 0x00, 0x00, 0x00,	/* 0x12 */
316   /* Length 1200pt/inch */
317 #define set_WD_length(sb, val) putnbyte(sb + 0x12, val, 4)
318 #define get_WD_length(sb) getnbyte(sb + 0x12, 4)
319   0x00,				/* 0x16 */
320   /* Brightness */
321 #define set_WD_brightness(sb, val) sb[0x16] = val
322 #define get_WD_brightness(sb)  sb[0x16]
323   0x00,				/* 0x17 */
324 				/* Reserved */
325   0x00,				/* 0x18 */
326 				/* Contrast */
327 #define set_WD_contrast(sb, val) sb[0x18] = val
328 #define get_WD_contrast(sb) sb[0x18]
329   0x05,				/* 0x19 */
330 				/* Image Mode */
331 #define set_WD_composition(sb, val)  sb[0x19] = val
332 #define get_WD_composition(sb) sb[0x19]
333 #define     WD_comp_grey          0x02
334 #define     WD_comp_gray          0x02
335 #define     WD_comp_rgb_full      0x05
336   0x08,				/* 0x1a */				/* Bits/Pixel */
337 #define set_WD_bitsperpixel(sb, val) sb[0x1a] = val
338 #define get_WD_bitsperpixel(sb)	sb[0x1a]
339 #define WD_bits_8    0x08
340   0, 0, 0, 0, 0,		/* 0x1b */
341    /* Reserved */
342   0, 0, 0, 0, 0, 0, 0, 0,
343   0, 0, 0, 0,			/* 0x28 */
344    /* X-axis pixel count (1-2592 */
345 #define get_WD_xpixels(sb) getnbyte(sb + 0x28, 4)
346   0, 0, 0, 0,			/* 0x2c */
347  /* Y-axis pixel count (1-3888) */
348 #define get_WD_ypixels(sb) getnbyte(sb + 0x2c, 4)
349   0x01,				/* 0x30 */
350 				/* Reserved, negative/positive
351 				 * reserved, drop-out color
352 				 * (Green) */
353 #define set_WD_negative(sb, val) setbitfield(sb + 0x30, 0x1, 4, (val?1:0))
354 #define get_WD_negative(sb) getbitfield(sb + 0x30, 0x1, 4)
355 #define WD_Negative 0x01
356 #define WD_Positive 0x00
357 #define set_WD_dropoutcolor(sb, val) setbitfield(sb + 0x30, 0x3, 0, val)
358 #define get_WD_dropoutcolor(sb)	getbitfield(sb + 0x30, 0x3, 0)
359 #define WD_Dropout_Red 0x00
360 #define WD_Dropout_Green 0x01
361 #define WD_Dropout_Blue 0x02
362   0x00,				/* 0x31 */
363   /* scan mode */
364 #define set_WD_scanmode(sb, val) setbitfield(sb + 0x31, 0x3, 4, val)
365 #define get_WD_scanmode(sb) getbitfield(sb + 0x31, 0x3, 4)
366 #define WD_Scan 0x00
367 #define WD_Prescan 0x01
368   0x40,				/* 0x32 */
369 				/* Data transfer mode */
370 #define set_WD_transfermode(sb, val) setbitfield(sb + 0x32, 0x3, 6, val)
371 #define get_WD_transfermode(sb)	getbitfield(sb + 0x32, 0x3, 6)
372 #define WD_LineSequence	0x2
373 #define WD_DotSequence	0x1
374   0x02,				/* 0x33 */
375 				/* Gamma selection */
376 #define set_WD_gammaselection(sb, val)	putnbyte(sb + 0x33, val, 1)
377 #define get_WD_gammaselection(sb) getnbyte(sb + 0x33, 1)
378 #define WD_Linear	0x2
379 #define WD_Monitor	0x3
380   0,				/* 0x34 */
381    /* Reserved */
382   0x40,				/* 0x35 */
383    /* Reserved, shading, analog gamma, averaging */
384 #define set_WD_shading(sb, val)	setbitfield(sb + 0x35, 0x1, 6, val)
385 #define get_WD_shading(sb) getbitfield(sb + 0x35, 0x1, 6)
386 #define WD_Shading_ON	0x0
387 #define WD_Shading_OFF	0x1
388 #define set_WD_analog_gamma_R(sb, val) setbitfield(sb + 0x35, 0x1, 5, val)
389 #define set_WD_analog_gamma_G(sb, val) setbitfield(sb + 0x35, 0x1, 4, val)
390 #define set_WD_analog_gamma_B(sb, val) setbitfield(sb + 0x35, 0x1, 3, val)
391 #define get_WD_analog_gamma_R(sb) getbitfield(sb + 0x35, 0x1, 5)
392 #define get_WD_analog_gamma_G(sb) getbitfield(sb + 0x35, 0x1, 4)
393 #define get_WD_analog_gamma_B(sb) getbitfield(sb + 0x35, 0x1, 3)
394 #define WD_Analog_Gamma_ON	0x0
395 #define WD_Analog_Gamma_OFF	0x1
396 #define set_WD_averaging(sb, val) setbitfield(sb + 0x35, 0x7, 0, (val?7:0))
397 #define get_WD_averaging(sb) getbitfield(sb + 0x35, 0x7, 0)
398 #define WD_Averaging_ON	0x0
399 #define WD_Averaging_OFF	0x1
400 
401   0,				/* 0x36 */
402   /* reserved */
403   0,				/* 0x37 */
404   /* R brightness */
405 #define set_WD_brightness_R(b, val)  putnbyte(b + 0x37, val, 1)
406 #define get_WD_brightness_R(b)  getnbyte(b + 0x37, 1)
407   0,				/* 0x38 */
408 				/* G brightness */
409 #define set_WD_brightness_G(b, val)  putnbyte(b + 0x38, val, 1)
410 #define get_WD_brightness_G(b)  getnbyte(b + 0x38, 1)
411   0,				/* 0x39 */
412 				/* B brightness */
413 #define set_WD_brightness_B(b, val)  putnbyte(b + 0x39, val, 1)
414 #define get_WD_brightness_B(b)  getnbyte(b + 0x39, 1)
415   0,				/* 0x3a */
416 				/* R contrast */
417 #define set_WD_contrast_R(b, val) putnbyte(b + 0x3a, val, 1)
418 #define get_WD_contrast_R(b) getnbyte(b + 0x3a, 1)
419   0,				/* 0x3b */
420   /* G contrast */
421 #define set_WD_contrast_G(b, val) putnbyte(b + 0x3b, val, 1)
422 #define get_WD_contrast_G(b) getnbyte(b + 0x3b, 1)
423   0,				/* 0x3c */
424   /* B contrast */
425 #define set_WD_contrast_B(b, val) putnbyte(b + 0x3c, val, 1)
426 #define get_WD_contrast_B(b) getnbyte(b + 0x3c, 1)
427   0, 0, 0, 0,			/* 0x3d */
428 					/* Reserved */
429   0, 0, 0, 0, 0, 0, 0, 0,
430   0,				/* 0x49 */
431   /* R exposure time adjustment [0, 12-200] */
432 #define set_WD_exposure_R(b, val) putnbyte(b + 0x49, val, 1)
433 #define get_WD_exposure_R(b) getnbyte(b + 0x49, 1)
434   0,				/* 0x4a */
435   /* G exposure time adjustment [0, 12-200] */
436 #define set_WD_exposure_G(b, val) putnbyte(b + 0x4a, val, 1)
437 #define get_WD_exposure_G(b) getnbyte(b + 0x4a, 1)
438   0,				/* 0x4b */
439   /* B exposure time adjustment [0, 12-200] */
440 #define set_WD_exposure_B(b, val) putnbyte(b + 0x4b, val, 1)
441 #define get_WD_exposure_B(b) getnbyte(b + 0x4b, 1)
442   0, 0, 0, 0,			/* 0x4c */
443   /* Reserved */
444   0, 0,
445   0,				/* 0x52 */
446   /* Amount of R shift [0, 128+-15] */
447 #define set_WD_shift_R(b, val)	putnbyte(b + 0x52, val, 1)
448 #define get_WD_shift_R(b) getnbyte(b + 0x52, 1)
449   0,				/* 0x53 */
450 				/* Amount of G shift [0, 128+-15] */
451 #define set_WD_shift_G(b, val) putnbyte(b + 0x53, val, 1)
452 #define get_WD_shift_G(b) getnbyte(b + 0x53, 1)
453   0,				/* 0x54 */
454 				/* Amount of B shift [0, 128+-15] */
455 #define set_WD_shift_B(b, val) putnbyte(b + 0x54, val, 1)
456 #define get_WD_shift_B(b) getnbyte(b + 0x54, 1)
457   0,				/* R0x55 */
458 				/* Amount of R offset [0-255] */
459   0,				/* R0x56 */
460 				/* Amount of G offset [0-255] */
461   0,				/* R0x57 */
462 				/* Amount of B offset [0-255] */
463   0, 0,				/* 0x58 */
464   /* Maximum resolution (for GET WINDOW: [2700]) */
465 #define get_WD_maxres(b) getnbyte(b + 0x58, 2)
466   0, 0,				/* 0x5a */
467 				/* Reserved */
468   0,				/* 0x5c */
469 				/* LUT-R, LUT-G */
470 #define set_WD_LUT_R(b, val) setbitfield(b + 0x5c, 0x0f, 4, val)
471 #define set_WD_LUT_G(b, val) setbitfield(b + 0x5c, 0x0f, 0, val)
472 #define get_WD_LUT_R(b)	getbitfield(b + 0x5c, 0x0f, 4)
473 #define get_WD_LUT_G(b)	getbitfield(b + 0x5c, 0x0f, 0)
474   0,				/* 0x5d */
475 				/* LUT-B, reserved */
476 #define set_WD_LUT_B(b, val) setbitfield(b + 0x5d, 0x0f, 4, val)
477 #define get_WD_LUT_B(b)	getbitfield(b + 0x5d, 0x0f, 4)
478   0,				/* R0x5e */
479   /* LS-1000: reserved. LS-20: R B/W reference point */
480   0,				/* R0x5f */
481   /* LS-1000: reserved. LS-20: G B/W reference point */
482   0,				/* R0x60 */
483   /* LS-1000: reserved. LS-20: B B/W reference point */
484   0,				/* R0x61 */
485   /* R exposure time unit [0-7] (LS-1000); [0, 2-1] (LS-20) */
486   0,				/* R0x62 */
487   /* G exposure time unit [0-7] (LS-1000); [0, 2-1] (LS-20) */
488   0,				/* R0x63 */
489   /* B exposure time unit [0-7] (LS-1000); [0, 2-1] (LS-20) */
490   0,				/* 0x64 */
491   /* Reserved */
492   0,				/* 0x65 */
493     /* Reserved, stop */
494 #define set_WD_stop(b, val) setbitfield(b+0x65, 0x01, 0, val)
495 #define get_WD_stop(b)	getbitfield(b+0x65, 0x01, 0)
496   0,				/* R0x66 */
497   /* R gain [0-4] (LS-1000), [0-255] (LS-20) */
498   0,				/* R0x67 */
499   /* G gain [0-4] (LS-1000), [0-255] (LS-20) */
500   0,				/* R0x68 */
501   /* B gain [0-4] (LS-1000), [0-255] (LS-20) */
502   0, 0, 0, 0,			/* R0x69 */
503   /* R exposure time variable [0, 64-65535] */
504   0, 0, 0, 0,			/* R0x6d */
505   /* G exposure time variable [0, 64-65535] */
506   0, 0, 0, 0,			/* R0x71 */
507     /* B exposure time variable [0, 64-65535] */
508   /* 0x75 (last) */
509 
510 };
511 
512 static scsiblk window_descriptor_block =
513 {
514   window_descriptor_blockC, sizeof (window_descriptor_blockC)
515 };
516 
517 
518 
519 /* LS-30 has different window-descriptor !
520  */
521 
522 static unsigned char window_descriptor_blockC_LS30[] =
523 {
524 
525 #define used_WDB_size_LS30 0x32
526 
527   0x00,				/* 0x00 */
528 				/* Window Identifier */
529 #define WD_wid_0 0x00		/* Only one supported */
530 #define WD_wid_1 0x01
531 #define WD_wid_2 0x02
532 #define WD_wid_3 0x03
533 #define WD_wid_4 0x04
534 #define WD_wid_9 0x09
535   0x00,			        /* reserved, AUTO */
536 
537   0x00, 0x00,			/* 0x02 */
538 				/* X Resolution in dpi */
539 
540   0x00, 0x00,			/* 0x04 */
541 				/* Y Resolution in dpi */
542 
543   0x00, 0x00, 0x00, 0x00,	/* 0x06 */
544   /* Upper Left X in 2700pt/inch */
545   0x00, 0x00, 0x00, 0x00,	/* 0x0a */
546   /* Upper Left Y in 2700pt/inch */
547   0x00, 0x00, 0x00, 0x00,	/* 0x0e */
548   /* Width 1200pt/inch */
549   0x00, 0x00, 0x00, 0x00,	/* 0x12 */
550   /* Length 1200pt/inch */
551   0x00,				/* 0x16 */
552   /* Brightness */
553   0x00,				/* 0x17 */
554 				/* Reserved */
555   0x00,				/* 0x18 */
556 				/* Contrast */
557   0x05,				/* 0x19 */
558 				/* Image Mode */
559   0x08,				/* 0x1a */
560 				/* Bits/Pixel */
561 #define WD_bits_10    0x0a
562   0, 0, 0, 0, 0,		/* 0x1b */
563    /* Reserved */
564   0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x20 */
565   0,  		               	/* 0x29 */
566    /* Negative/positive prevue/scan */
567 #define set_WD_negative_LS30(sb, val) setbitfield(sb + 0x29, 0x1, 0, (val?0:1))
568 #define get_WD_negative_LS30(sb) getbitfield(sb + 0x29, 0x1, 0)
569   /* scan mode */
570 #define set_WD_scanmode_LS30(sb, val) setbitfield(sb + 0x29, 0x3, 0, val)
571 #define get_WD_scanmode_LS30(sb) getbitfield(sb + 0x29, 0x3, 0)
572 
573   0x04,                          /* 0x2a */
574   0x02,                          /* 0x2b */
575   0x01,                          /* 0x2c */
576   0xff,                          /* 0x2d */
577   0,0,                           /* 0x2e */
578   0,0,                           /* 0x30 */
579 #define set_gain_LS30(sb, val) putnbyte(sb + 0x2e, val, 4)
580 #define get_gain_LS30(sb) getnbyte(sb + 0x2e, 4)
581 };
582 
583 
584 static scsiblk window_descriptor_block_LS30 =
585 {
586   window_descriptor_blockC, sizeof (window_descriptor_blockC_LS30)
587 };
588 
589 /* ==================================================================== */
590 
591 /*#define set_WDB_length(length)   (window_descriptor_block.size = (length)) */
592 #define WPDB_OFF(b)              (b + set_window.size)
593 #define WDB_OFF(b, n)            (b + set_window.size + \
594 		                 window_parameter_data_block.size + \
595 		                 ( window_descriptor_block.size * (n - 1) ) )
596 #define set_WPDB_wdbnum(sb,n) set_WPDB_wdblen(sb,window_descriptor_block.size*n)
597 
598 
599 
600 /* ==================================================================== */
601 
602 static unsigned char scanC[] =
603 {
604   SCAN, 0x00, 0x00, 0x00, 0x00, 0x00
605 };
606 
607 static scsiblk scan =
608 {scanC, sizeof (scanC)};
609 #define set_SC_xfer_length(sb, val) sb[0x04] = (unsigned char)val
610 
611 /* ==================================================================== */
612 /*
613    static unsigned char send_diagnosticC[] = {
614    SEND_DIAGNOSTIC, 0x04, 0x00, 0x00, 0x00, 0x00
615    };
616 
617    static scsiblk send_diagnostic = { send_diagnosticC, sizeof(send_diagnosticC) }; */
618 
619 /* ==================================================================== */
620 
621 /* sread instead of read because read is a libc primitive */
622 static unsigned char sreadC[] =
623 {
624   READ, 0x00,
625   0x00,				/* Data Type Code */
626   0x00,				/* reserved */
627   0x00, 0x00,			/* data type qualifier */
628   0x00, 0x00, 0x00,		/* transfer length */
629   0x00				/* control */
630 };
631 
632 static scsiblk sread =
633 {sreadC, sizeof (sreadC)};
634 #define set_R_data1_code(sb, val) sb[0x01] = val
635 #define set_R_datatype_code(sb, val) sb[0x02] = val
636 #define R_datatype_imagedata		0x00
637 #define R_EX_datatype_LUT		0x01	/* Experiment code */
638 #define R_image_positions		0x88
639 #define R_EX_datatype_shading_data	0xa0	/* Experiment code */
640 #define R_user_reg_gamma		0xc0
641 #define R_device_internal_info		0xe0
642 #define set_R_datatype_qual_upper(sb, val) sb[0x04] = val
643 #define set_R_datatype_qual_lower(sb, val) sb[0x05] = val
644 #define R_DQ_none	0x00
645 #define R_DQ_Rcomp	0x06
646 #define R_DQ_Gcomp	0x07
647 #define R_DQ_Bcomp	0x08
648 #define R_DQ_Reg1	0x01
649 #define R_DQ_Reg2	0x02
650 #define R_DQ_Reg3	0x03
651 #define set_R_xfer_length(sb, val)    putnbyte(sb + 0x06, val, 3)
652 
653 /* ==================================================================== */
654 
655 /* Length of internal info structure */
656 #define DI_length 256
657 /* Functions for picking out data from the internal info structure */
658 #define get_DI_ADbits(b)	   getnbyte(b + 0x00, 1)
659 #define get_DI_Outputbits(b)	   getnbyte(b + 0x01, 1)
660 #define get_DI_MaxResolution(b)	   getnbyte(b + 0x02, 2)
661 #define get_DI_Xmax(b)		   getnbyte(b + 0x04, 2)
662 #define get_DI_Ymax(b)		   getnbyte(b + 0x06, 2)
663 #define get_DI_Xmaxpixel(b)	   getnbyte(b + 0x08, 2)
664 #define get_DI_Ymaxpixel(b)	   getnbyte(b + 0x0a, 2)
665 #define get_DI_currentY(b)	   getnbyte(b + 0x10, 2)
666 #define get_DI_currentFocus(b)	   getnbyte(b + 0x12, 2)
667 #define get_DI_currentscanpitch(b) getnbyte(b + 0x14, 1)
668 #define get_DI_autofeeder(b)	   getnbyte(b + 0x1e, 1)
669 #define get_DI_analoggamma(b)	   getnbyte(b + 0x1f, 1)
670 #define get_DI_deviceerror0(b)	   getnbyte(b + 0x40, 1)
671 #define get_DI_deviceerror1(b)	   getnbyte(b + 0x41, 1)
672 #define get_DI_deviceerror2(b)	   getnbyte(b + 0x42, 1)
673 #define get_DI_deviceerror3(b)	   getnbyte(b + 0x43, 1)
674 #define get_DI_deviceerror4(b)	   getnbyte(b + 0x44, 1)
675 #define get_DI_deviceerror5(b)	   getnbyte(b + 0x45, 1)
676 #define get_DI_deviceerror6(b)	   getnbyte(b + 0x46, 1)
677 #define get_DI_deviceerror7(b)	   getnbyte(b + 0x47, 1)
678 #define get_DI_WBETR_R(b)	   getnbyte(b + 0x80, 2)	/* White balance exposure time variable R */
679 #define get_DI_WBETR_G(b)	    getnbyte(b + 0x82, 2)
680 #define get_DI_WBETR_B(b)	    getnbyte(b + 0x84, 2)
681 #define get_DI_PRETV_R(b)	    getnbyte(b + 0x88, 2)	/* Prescan result exposure tim4e variable R */
682 #define get_DI_PRETV_G(b)	    getnbyte(b + 0x8a, 2)
683 #define get_DI_PRETV_B(b)	    getnbyte(b + 0x8c, 2)
684 #define get_DI_CETV_R(b)	    getnbyte(b + 0x90, 2)	/* Current exposure time variable R */
685 #define get_DI_CETV_G(b)	    getnbyte(b + 0x92, 2)
686 #define get_DI_CETV_B(b)	    getnbyte(b + 0x94, 2)
687 #define get_DI_IETU_R(b)	    getnbyte(b + 0x98, 1)	/* Internal exposure time unit R */
688 #define get_DI_IETU_G(b)	    getnbyte(b + 0x99, 1)
689 #define get_DI_IETU_B(b)	    getnbyte(b + 0x9a, 1)
690 #define get_DI_limitcondition(b)    getnbyte(b + 0xa0, 1)
691 #define get_DI_offsetdata_R(b)	    getnbyte(b + 0xa1, 1)
692 #define get_DI_offsetdata_G(b)	    getnbyte(b + 0xa2, 1)
693 #define get_DI_offsetdata_B(b)	    getnbyte(b + 0xa3, 1)
694 #define get_DI_poweron_errors(b,to) memcpy(to, (b + 0xa8), 8)
695 
696 /* ==================================================================== */
697 
698 static unsigned char sendC[] =
699 {
700   SEND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
701 };
702 static scsiblk send =
703 {sendC, sizeof (sendC)};
704 
705 #define set_S_datatype_code(sb, val) sb[0x02] = (unsigned char)val
706 #define S_datatype_imagedatai		0x00
707 #define S_EX_datatype_LUT			0x01	/* Experiment code */
708 #define S_EX_datatype_shading_data	0xa0	/* Experiment code */
709 #define S_user_reg_gamma			0xc0
710 #define S_device_internal_info		0x03
711 #define set_S_datatype_qual_upper(sb, val) sb[0x04] = (unsigned char)val
712 #define S_DQ_none	0x00
713 #define S_DQ_Rcomp	0x06
714 #define S_DQ_Gcomp	0x07
715 #define S_DQ_Bcomp	0x08
716 #define S_DQ_Reg1	0x01
717 #define S_DQ_Reg2	0x02
718 #define S_DQ_Reg3	0x03
719 #define S_DQ_Reg9	0x09
720 #define set_S_xfer_length(sb, val)    putnbyte(sb + 0x06, val, 3)
721 
722 /*
723    static unsigned char gamma_user_LUT_LS1K[512] = { 0x00 };
724    static scsiblk gamma_user_LUT_LS1K_LS1K = {
725    gamma_user_LUT_LS1K, sizeof(gamma_user_LUT_LS1K)
726    };
727  */
728 
729 /* ==================================================================== */
730 
731 static unsigned char object_positionC[] =
732 {
733   OBJECT_POSITION,
734   0x00,				/* Auto feeder function */
735   0x00, 0x00, 0x00,		/* Count */
736   0x00, 0x00, 0x00, 0x00,	/* Reserved */
737   0x00				/* Control byte */
738 };
739 #define set_OP_autofeed(b,val) setbitfield(b+0x01, 0x07, 0, val)
740 #define OP_Discharge		0x00
741 #define OP_Feed			0x01
742 #define OP_Absolute		0x02	/* For development only */
743 
744 static scsiblk object_position =
745 {
746   object_positionC, sizeof (object_positionC)
747 };
748 /* ==================================================================== */
749 static unsigned char autofocusC[] =
750 {
751   AUTO_FOCUS, 0x00, 0x00, 0x00,
752   0x00,				/* transfer length (0|8) */
753   0x00				/* Control byte */
754 };
755 #define set_AF_transferlength(b, val)  b[0x04] = (unsigned char)val
756 #define get_AF_transferlength(b)  ((int)b[0x04] & 0xff)
757 #define set_AF_XPoint(b, val) putnbyte(b+0x06, val, 4)
758 #define set_AF_YPoint(b, val) putnbyte(b+0x0a, val, 4)
759 #define AF_Point_length		8
760 
761 static scsiblk autofocus =
762 {autofocusC, sizeof (autofocusC)};
763 
764 /* ==================================================================== */
765 
766 static unsigned char command_c1_C[] =
767 {
768   0xc1, 0x00, 0x00, 0x00,
769   0x00, 0x00, 0x00, 0x00,	       /*  */
770   0x00, 0x00			       /* transfer length*/
771 };
772 static scsiblk command_c1 =
773 {command_c1_C, sizeof (command_c1_C)};
774 /* ==================================================================== */
775 
776 static unsigned char autofocusLS30C[] =
777 {
778   0xe0, 0x00, 0xa0, 0x00,
779   0x00, 0x00, 0x00, 0x00,	       /*  */
780   0x09, 0x00			       /* transfer length*/
781 };
782 
783 static unsigned char autofocuspos[] =
784 {
785   0x00,
786   0x00, 0x00, 0x05, 0x10,              /* x-position */
787   0x00, 0x00, 0x07, 0x9b,	       /* y-position */
788 };
789 
790 #define set_AF_transferlength(b, val)  b[0x04] = (unsigned char)val
791 #define get_AF_transferlength(b)  ((int)b[0x04] & 0xff)
792 #define set_AF_XPoint(b, val) putnbyte(b+0x06, val, 4)
793 #define set_AF_YPoint(b, val) putnbyte(b+0x0a, val, 4)
794 #define AF_Point_length		8
795 
796 static scsiblk autofocusLS30 =
797 {autofocusLS30C, sizeof (autofocusLS30C)};
798 /* ==================================================================== */
799 
800 static unsigned char commande1C[] =
801 {
802   0xe1, 0x00, 0xc1, 0x00,
803   0x00, 0x00, 0x00, 0x00,	       /*  */
804   0x0d, 0x00			       /* transfer length*/
805 };
806 static scsiblk commande1 =
807 {commande1C, sizeof (commande1C)};
808 
809 /* ==================================================================== */
810 /*
811 static unsigned char request_senseC[] =
812 {
813   REQUEST_SENSE, 0x00, 0x00, 0x00, 0x00, 0x00
814 #define set_RS_allocation_length(sb,val) sb[0x04] = (unsigned char)val
815 };
816 
817 static scsiblk request_sense =
818 {
819   request_senseC, sizeof (request_senseC)
820 };
821 */
822 /* defines for request sense return block */
823 #define get_RS_information_valid(b)       getbitfield(b + 0x00, 1, 7)
824 #define get_RS_error_code(b)              getbitfield(b + 0x00, 0x7f, 0)
825 #define get_RS_filemark(b)                getbitfield(b + 0x02, 1, 7)
826 #define get_RS_EOM(b)                     getbitfield(b + 0x02, 1, 6)
827 #define get_RS_ILI(b)                     getbitfield(b + 0x02, 1, 5)
828 #define get_RS_sense_key(b)               getbitfield(b + 0x02, 0x0f, 0)
829 #define get_RS_information(b)             getnbyte(b+0x03, 4)	/* normally 0 */
830 #define get_RS_additional_length(b)       b[0x07]	/* always 10 */
831 #define get_RS_ASC(b)                     b[0x0c]
832 #define get_RS_ASCQ(b)                    b[0x0d]
833 #define get_RS_SKSV(b)                    getbitfield(b+0x0f,1,7)	/* valid, always 0 */
834 
835 #define rs_return_block_size              18	/* Says Nikon */
836 
837 #endif
838