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