1 /* ----------------------------------------------------------------------------- */
2
3 /* sane - Scanner Access Now Easy.
4
5 pie-scsidef.h: scsi-definiton header file for PIE scanner driver.
6
7 Copyright (C) 2000 Simon Munton, based on the umax-scsidef.h by Oliver Rauch & Michael Johnson
8
9 This file is part of the SANE package.
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2 of the
14 License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <https://www.gnu.org/licenses/>.
23
24 As a special exception, the authors of SANE give permission for
25 additional uses of the libraries contained in this release of SANE.
26
27 The exception is that, if you link a SANE library with other files
28 to produce an executable, this does not by itself cause the
29 resulting executable to be covered by the GNU General Public
30 License. Your use of that executable is in no way restricted on
31 account of linking the SANE library code into it.
32
33 This exception does not, however, invalidate any other reasons why
34 the executable file might be covered by the GNU General Public
35 License.
36
37 If you submit changes to SANE to the maintainers to be included in
38 a subsequent release, you agree by submitting the changes that
39 those changes may be distributed with this exception intact.
40
41 If you write modifications of your own for SANE, it is your choice
42 whether to permit this exception to apply to your modifications.
43 If you do not wish that, delete this exception notice.
44 */
45
46 /* --------------------------------------------------------------------------------------------------------- */
47
48
49 #ifndef PIE_SCSIDEF_H
50 #define PIE_SCSIDEF_H
51
52
53
54 /* --------------------------------------------------------------------------------------------------------- */
55
56 /* I'm using functions derived from Eric Youngdale's scsiinfo
57 * program here for dealing with parts of SCSI commands.
58 */
59
setbitfield(unsigned char * pageaddr, int mask, int shift, int val)60 static inline void setbitfield(unsigned char * pageaddr, int mask, int shift, int val)
61 { *pageaddr = (*pageaddr & ~(mask << shift)) | ((val & mask) << shift); }
62
resetbitfield(unsigned char * pageaddr, int mask, int shift, int val)63 static inline void resetbitfield(unsigned char * pageaddr, int mask, int shift, int val)
64 { *pageaddr = (*pageaddr & ~(mask << shift)) | (((!val) & mask) << shift); }
65
getbitfield(unsigned char * pageaddr, int mask, int shift)66 static inline int getbitfield(unsigned char * pageaddr, int mask, int shift)
67 { return ((*pageaddr >> shift) & mask); }
68
69 /* ------------------------------------------------------------------------- */
70
getnbyte(unsigned char * pnt, int nbytes)71 static inline int getnbyte(unsigned char * pnt, int nbytes)
72 {
73 unsigned int result = 0;
74 int i;
75
76 for(i=0; i<nbytes; i++)
77 result = (result << 8) | (pnt[i] & 0xff);
78 return result;
79 }
80
81 /* ------------------------------------------------------------------------- */
82
getnbyte1(unsigned char * pnt, int nbytes)83 static inline int getnbyte1(unsigned char * pnt, int nbytes)
84 {
85 unsigned int result = 0;
86 int i;
87
88 for(i=nbytes-1; i >= 0; i--)
89 result = (result << 8) | (pnt[i] & 0xff);
90 return result;
91 }
92
93 /* ------------------------------------------------------------------------- */
94
putnbyte(unsigned char * pnt, unsigned int value, unsigned int nbytes)95 static inline void putnbyte(unsigned char * pnt, unsigned int value, unsigned int nbytes)
96 {
97 int i;
98
99 for(i=nbytes-1; i>= 0; i--)
100 {
101 pnt[i] = value & 0xff;
102 value = value >> 8;
103 }
104 }
105
106
107 /* ------------------------------------------------------------------------- */
108
putnbyte1(unsigned char * pnt, unsigned int value, unsigned int nbytes)109 static inline void putnbyte1(unsigned char * pnt, unsigned int value, unsigned int nbytes)
110 {
111 unsigned int i;
112
113 for(i=0; i< nbytes; i++)
114 {
115 pnt[i] = value & 0xff;
116 value = value >> 8;
117 }
118 }
119
120
121 /* --------------------------------------------------------------------------------------------------------- */
122
123
124 /* Not all of these are defined in scsi.h, so we'll make sure
125 * we agree about them here...
126 */
127 #define TEST_UNIT_READY 0x00
128 #define REQUEST_SENSE 0x03
129 #define INQUIRY 0x12
130 #define RESERVE_UNIT 0x16
131 #define RELEASE_UNIT 0x17
132 #define SCAN 0x1B
133 #define READ 0x08
134 #define WRITE 0x0A
135 #define PARAM 0x0F
136 #define MODE 0x15
137
138 /* --------------------------------------------------------------------------------------------------------- */
139
140
141 #define STD_WDB_LEN 0x28 /* wdb_len if nothing is set by inquiry */
142
143
144 /* --------------------------------------------------------------------------------------------------------- */
145
146
147 /* SCSI commands */
148
149 typedef struct
150 {
151 unsigned char *cmd;
152 size_t size;
153 } scsiblk;
154
155
156 /* --------------------------------------------------------------------------------------------------------- */
157
158
159 #define set_inquiry_return_size(icb,val) icb[0x04]=val
160 static unsigned char inquiryC[] = { INQUIRY, 0x00, 0x00, 0x00, 0x7c, 0x00 };
161 static scsiblk inquiry = { inquiryC, sizeof(inquiryC) };
162
163
164 /* --------------------------------------------------------------------------------------------------------- */
165
166
167 #define get_inquiry_periph_qual(in) getbitfield(in, 0x07, 5)
168 # define IN_periph_qual_lun 0x00
169 # define IN_periph_qual_nolun 0x03
170 #define get_inquiry_periph_devtype(in) getbitfield(in, 0x1f, 0)
171 # define IN_periph_devtype_scanner 0x06
172 # define IN_periph_devtype_unknown 0x1f
173
174 #define get_inquiry_rmb(in) getbitfield(in + 0x01, 0x01, 7)
175 #define get_inquiry_0x01_bit6(in) getbitfield(in + 0x01, 0x01, 6)
176 #define get_inquiry_0x01_bit5(in) getbitfield(in + 0x01, 0x01, 5)
177
178 #define get_inquiry_iso_version(in) getbitfield(in + 0x02, 0x03, 6)
179 #define get_inquiry_ecma_version(in) getbitfield(in + 0x02, 0x07, 3)
180 #define get_inquiry_ansi_version(in) getbitfield(in + 0x02, 0x07, 0)
181
182 #define get_inquiry_aenc(in) getbitfield(in + 0x03, 0x01, 7)
183 #define get_inquiry_tmiop(in) getbitfield(in + 0x03, 0x01, 6)
184 #define get_inquiry_0x03_bit5(in) getbitfield(in + 0x03, 0x01, 5)
185 #define get_inquiry_0x03_bit4(in) getbitfield(in + 0x03, 0x01, 4)
186 #define get_inquiry_response_format(in) getbitfield(in + 0x03, 0x0f, 0)
187 # define IN_recognized 0x02
188
189 #define get_inquiry_additional_length(in) in[0x04]
190 #define set_inquiry_length(out,n) out[0x04]=n-5
191
192 #define get_inquiry_vendor(in, buf) snprintf(buf, 0x08 + 1, "%.*s", \
193 0x08, in + 0x08)
194 #define get_inquiry_product(in, buf) snprintf(buf, 0x10 + 1, "%.*s", \
195 0x10, in + 0x10)
196 #define get_inquiry_version(in, buf) snprintf(buf, 0x04 + 1, "%.*s", \
197 0x04, in + 0x20)
198
199 #define get_inquiry_max_x_res(in) getnbyte1(in + 0x24, 2)
200 #define get_inquiry_max_y_res(in) getnbyte1(in + 0x26, 2)
201 #define get_inquiry_fb_max_scan_width(in) getnbyte1(in + 0x28, 2)
202 #define get_inquiry_fb_max_scan_length(in) getnbyte1(in + 0x2a, 2)
203 #define get_inquiry_filters(in) in[0x2c]
204 #define get_inquiry_color_depths(in) in[0x2d]
205 #define get_inquiry_color_format(in) in[0x2e]
206 #define get_inquiry_image_format(in) in[0x30]
207 #define get_inquiry_scan_capability(in) in[0x31]
208 #define get_inquiry_optional_devices(in) in[0x32]
209 #define get_inquiry_enhancements(in) in[0x33]
210 #define get_inquiry_gamma_bits(in) in[0x34]
211 #define get_inquiry_last_filter(in) in[0x35]
212 #define get_inquiry_fast_preview_res(in) getnbyte1(in + 0x36, 2)
213 #define get_inquiry_halftones(in) in[0x60]
214 #define get_inquiry_halftone_max_width(in) in[0x61]
215 #define get_inquiry_halftone_max_heighgt(in) in[0x62]
216 #define get_inquiry_max_windows(in) in[0x63]
217 #define get_inquiry_min_highlight(in) in[0x65]
218 #define get_inquiry_max_shadow(in) in[0x66]
219 #define get_inquiry_cal_eqn(in) in[0x67]
220 #define get_inquiry_max_exp(in) getnbyte1(in + 0x68, 2)
221 #define get_inquiry_min_exp(in) getnbyte1(in + 0x6a, 2)
222 #define get_inquiry_trans_x1(in) getnbyte1(in + 0x6c, 2)
223 #define get_inquiry_trans_y1(in) getnbyte1(in + 0x6e, 2)
224 #define get_inquiry_trans_x2(in) getnbyte1(in + 0x70, 2)
225 #define get_inquiry_trans_y2(in) getnbyte1(in + 0x72, 2)
226
227 #define INQ_ONE_PASS_COLOR 0x80
228 #define INQ_FILTER_BLUE 0x08
229 #define INQ_FILTER_GREEN 0x04
230 #define INQ_FILTER_RED 0x02
231 #define INQ_FILTER_NEUTRAL 0x01
232
233 #define INQ_COLOR_DEPTH_16 0x20
234 #define INQ_COLOR_DEPTH_12 0x10
235 #define INQ_COLOR_DEPTH_10 0x08
236 #define INQ_COLOR_DEPTH_8 0x04
237 #define INQ_COLOR_DEPTH_4 0x02
238 #define INQ_COLOR_DEPTH_1 0x01
239
240 #define INQ_COLOR_FORMAT_INDEX 0x04
241 #define INQ_COLOR_FORMAT_LINE 0x02
242 #define INQ_COLOR_FORMAT_PIXEL 0x01
243
244 #define INQ_IMG_FMT_OKLINE 0x08
245 #define INQ_IMG_FMT_BLK_ONE 0x04
246 #define INQ_IMG_FMT_MOTOROLA 0x02
247 #define INQ_IMG_FMT_INTEL 0x01
248
249 #define INQ_CAP_PWRSAV 0x80
250 #define INQ_CAP_EXT_CAL 0x40
251 #define INQ_CAP_FAST_PREVIEW 0x10
252 #define INQ_CAP_DISABLE_CAL 0x08
253 #define INQ_CAP_SPEEDS 0x07
254
255 #define INQ_OPT_DEV_MPCL 0x80
256 #define INQ_OPT_DEV_TP1 0x04
257 #define INQ_OPT_DEV_TP 0x02
258 #define INQ_OPT_DEV_ADF 0x01
259
260 #define INQ_ENHANCE_EDGE 0x02
261
262 #define INQ_LAST_FILTER_BLUE 0x08
263 #define INQ_LAST_FILTER_GREEN 0x04
264 #define INQ_LAST_FILTER_RED 0x02
265 #define INQ_LAST_FILTER_NEUTRAL 0x01
266
267 #define INQ_DWNLD_HALFTONE 0x80
268 #define INQ_NUM_HALFTONES 0x7f
269
270
271 /* --------------------------------------------------------------------------------------------------------- */
272
273
274 static unsigned char test_unit_readyC[] = { TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00 };
275
276 static scsiblk test_unit_ready = { test_unit_readyC,sizeof(test_unit_readyC) };
277
278
279 /* --------------------------------------------------------------------------------------------------------- */
280
281
282 static unsigned char reserve_unitC[] = { RESERVE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00 };
283
284 static scsiblk reserve_unit = { reserve_unitC, sizeof(reserve_unitC) };
285
286
287 /* --------------------------------------------------------------------------------------------------------- */
288
289
290 static unsigned char release_unitC[] = { RELEASE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00 };
291
292 static scsiblk release_unit = { release_unitC, sizeof(release_unitC) };
293
294
295 /* --------------------------------------------------------------------------------------------------------- */
296
297
298 static unsigned char paramC[] = { PARAM, 0x00, 0x00, 0x00, 0x00, 0x00 };
299
300 static scsiblk param = { paramC, sizeof(paramC) };
301
302 #define set_param_length(in, l) putnbyte(in + 3, (l), 2)
303
304 #define get_param_scan_width(b) getnbyte1(b, 2)
305 #define get_param_scan_lines(b) getnbyte1(b + 2, 2)
306 #define get_param_scan_bytes(b) getnbyte1(b + 4, 2)
307 #define get_param_scan_filter_offset1(b) b[6]
308 #define get_param_scan_filter_offset2(b) b[7]
309 #define get_param_scan_period(b) getnbyte1(b + 8, 4)
310 #define get_param_scsi_xfer_rate(b) getnbyte1(b + 12, 2)
311 #define get_param_scan_available_lines(b) getnbyte1(b + 14, 2)
312
313 /* --------------------------------------------------------------------------------------------------------- */
314
315
316 static unsigned char writeC[] = { WRITE, 0x00, 0x00, 0x00, 0x00, 0x00 };
317
318 static scsiblk swrite = { writeC, sizeof(writeC) };
319
320 #define set_write_length(in, l) putnbyte(in + 2, (l), 3)
321
322
323 /* --------------------------------------------------------------------------------------------------------- */
324
325
326 static unsigned char modeC[] = { MODE, 0x00, 0x00, 0x00, 0x00, 0x00 };
327
328 static scsiblk smode = { modeC, sizeof(modeC) };
329
330 #define set_mode_length(in, l) putnbyte(in + 3, (l), 2)
331
332 /* --------------------------------------------------------------------------------------------------------- */
333
334
335 static unsigned char scanC[] = { SCAN, 0x00, 0x00, 0x00, 0x01, 0x00 };
336
337 static scsiblk scan = { scanC, sizeof(scanC) };
338
339 #define set_scan_cmd(in, l) in[4] = l
340
341 /* --------------------------------------------------------------------------------------------------------- */
342
343
344 /* sread instead of read because read is a libc primitive */
345 static unsigned char sreadC[] = { READ, 0x00, 0x00, 0x00, 0x00, 0x00 };
346
347 static scsiblk sread = { sreadC, sizeof(sreadC) };
348
349 #define set_read_length(in, l) putnbyte(in + 2, (l), 3)
350
351 /* --------------------------------------------------------------------------------------------------------- */
352
353 #if 0
354 static unsigned char request_senseC[] = { REQUEST_SENSE, 0x00, 0x00, 0x00, 0x00, 0x00 };
355 #define set_RS_allocation_length(sb,val) sb[0x04]=val
356 #define set_RS_LUN(sb,val) setbitfield(sb + 0x01, 7, 5) /* ??? */
357
358 static scsiblk request_sense = { request_senseC, sizeof(request_senseC) };
359 #endif
360
361 /* defines for request sense return block */
362 #define get_RS_information_valid(b) getbitfield(b + 0x00, 1, 7)
363 #define get_RS_error_code(b) getbitfield(b + 0x00, 0x7f, 0)
364 #define get_RS_filemark(b) getbitfield(b + 0x02, 1, 7)
365 #define get_RS_EOM(b) getbitfield(b + 0x02, 1, 6)
366 #define get_RS_ILI(b) getbitfield(b + 0x02, 1, 5)
367 #define get_RS_sense_key(b) getbitfield(b + 0x02, 0x0f, 0)
368 #define get_RS_information(b) getnbyte(b+0x03, 4)
369 #define get_RS_additional_length(b) b[0x07]
370 #define get_RS_ASC(b) b[0x0c]
371 #define get_RS_ASCQ(b) b[0x0d]
372 #define get_RS_SKSV(b) getbitfield(b+0x0f,1,7) /* valid */
373 #define get_RS_CD(b) getbitfield(b+0x0f,1,6) /* 1=CDB */
374 #define get_RS_field_pointer(b) getnbyte(b+0x10, 2)
375
376 #define get_RS_additional_sense(b) getnbyte(b+0x12, 2)
377
378 #define rs_return_block_size 0x1f
379
380
381 /* --------------------------------------------------------------------------------------------------------- */
382
383
384 static char *sense_str[] = {"NO SENSE",
385 "RECOVERED ERROR",
386 "NOT READY",
387 "MEDIUM ERROR",
388 "HARDWARE ERROR",
389 "ILLEGAL REQUEST",
390 "UNIT ATTENTION",
391 "DATA PROTECT",
392 "BLANK CHECK",
393 "VENDOR SPECIFIC",
394 "COPY ABORTED",
395 "ABORTED COMMAND",
396 "EQUAL",
397 "VOLUME OVERFLOW",
398 "MISCOMPARE",
399 "??? - SENSE 0FH" };
400
401 /* --------------------------------------------------------------------------------------------------------- */
402
403 /* command codes used in the data part of a SCSI write command */
404
405 #define SET_POWER_SAVE_CONTROL 0x01
406 #define DWNLD_GAMMA_TABLE 0x10
407 #define DWNLD_HALFTONE 0x11
408 #define SET_SCAN_FRAME 0x12
409 #define SET_EXP_TIME 0x13
410 #define SET_HIGHLIGHT_SHADOW 0x14
411 #define SEND_CAL_DATA 0x16
412
413 #define READ_POWER_SAVE_CONTROL 0x81
414 #define READ_GAMMA_TABLE 0x90
415 #define READ_HALFTONE 0x91
416 #define READ_SCAN_FRAME 0x92
417 #define READ_EXP_TIME 0x93
418 #define READ_HIGHLIGHT_SHADOW 0x94
419 #define READ_CAL_INFO 0x95
420
421
422 #define set_command(in, cmd) putnbyte1(in, cmd, 2)
423 #define set_data_length(in, len) putnbyte1(in + 2, len, 2)
424 #define set_data(in, ofs, val, num) putnbyte1(in + ofs, val, num)
425
426
427
428 #define FILTER_BLUE 0x08
429 #define FILTER_GREEN 0x04
430 #define FILTER_RED 0x02
431 #define FILTER_NEUTRAL 0x01
432
433
434 #endif
435