1 /* sane - Scanner Access Now Easy.
2    Copyright (C) 2007 Jeremy Johnson
3    This file is part of a SANE backend for Ricoh IS450
4    and IS420 family of HS2P Scanners using the SCSI controller.
5 
6    This file is part of the SANE package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 
21    As a special exception, the authors of SANE give permission for
22    additional uses of the libraries contained in this release of SANE.
23 
24    The exception is that, if you link a SANE library with other files
25    to produce an executable, this does not by itself cause the
26    resulting executable to be covered by the GNU General Public
27    License.  Your use of that executable is in no way restricted on
28    account of linking the SANE library code into it.
29 
30    This exception does not, however, invalidate any other reasons why
31    the executable file might be covered by the GNU General Public
32    License.
33 
34    If you submit changes to SANE to the maintainers to be included in
35    a subsequent release, you agree by submitting the changes that
36    those changes may be distributed with this exception intact.
37 
38    If you write modifications of your own for SANE, it is your choice
39    whether to permit this exception to apply to your modifications.
40    If you do not wish that, delete this exception notice. */
41 
42 #include <time.h>
43 #include "../include/sane/sane.h"
44 #include "../include/sane/saneopts.h"
45 #include "../include/sane/sanei_scsi.h"
46 #include "../include/sane/sanei_config.h"
47 #include "../include/sane/sanei_thread.h"
48 
49 /* 1-2 SCSI STATUS BYTE KEYS                      */
50 #define HS2P_SCSI_STATUS_GOOD			0x00
51 #define HS2P_SCSI_STATUS_CHECK			0x02
52 #define HS2P_SCSI_STATUS_BUSY			0x08
53 #define HS2P_SCSI_STATUS_RESERVATION CONFLICT	0x18
54 /* All other status byte keys are reserved        */
55 
56 /*
57  * SCSI Command List for Command Descriptor Block
58  * All reserved bit and fields in the CDB must be zero
59  * Values in the CDB described as "Reserved" must no be specified
60  * The FLAG and LINK bits in the CONTROL byte must be zero
61  * Any values in the Vendor Unique field are ignored
62  * The Logical Unit Number in the CDB must always be zero
63  * All Reserved bit and fields in the data fields must be zero
64  * Values of parameters in the data fields described as
65  *   "Reserved" or "Not supported" must not be specified
66 */
67 
68 /* 1-3 SCSI COMMANDS				  */
69 #define HS2P_SCSI_TEST_UNIT_READY       	0x00
70 #define HS2P_SCSI_REQUEST_SENSE         	0x03
71 #define HS2P_SCSI_INQUIRY               	0x12
72 #define HS2P_SCSI_MODE_SELECT           	0x15
73 #define HS2P_SCSI_RESERVE_UNIT          	0x16
74 #define HS2P_SCSI_RELEASE_UNIT          	0x17
75 #define HS2P_SCSI_MODE_SENSE            	0x1a
76 #define HS2P_SCSI_START_SCAN            	0x1b
77 #define HS2P_SCSI_RECEIVE_DIAGNOSTICS   	0x1c
78 #define HS2P_SCSI_SEND_DIAGNOSTICS      	0x1d
79 #define HS2P_SCSI_SET_WINDOW            	0x24
80 #define HS2P_SCSI_GET_WINDOW            	0x25
81 #define HS2P_SCSI_READ_DATA             	0x28
82 #define HS2P_SCSI_SEND_DATA             	0x2a
83 #define HS2P_SCSI_OBJECT_POSITION       	0x31
84 #define HS2P_SCSI_GET_BUFFER_STATUS     	0x34
85 
86 /* Sense Key Defines                      */
87 #define HS2P_SK_NO_SENSE		0x00
88 #define HS2P_SK_RECOVERED_ERROR		0x01
89 #define HS2P_SK_NOT_READY		0x02
90 #define HS2P_SK_MEDIUM_ERROR		0x03
91 #define HS2P_SK_HARDWARE_ERROR		0x04
92 #define HS2P_SK_ILLEGAL_REQUEST		0x05
93 #define HS2P_SK_UNIT_ATTENTION		0x06
94 #define HS2P_SK_DATA_PROJECT		0x07
95 #define HS2P_SK_BLANK_CHECK		0x08
96 #define HS2P_SK_VENDOR_UNIQUE		0x09
97 #define HS2P_SK_COPY_ABORTED		0x0a
98 #define HS2P_SK_ABORTED_COMMAND		0x0b
99 #define HS2P_SK_EQUAL			0x0c
100 #define HS2P_SK_VOLUME_OVERFLOW		0x0d
101 #define HS2P_SK_MISCOMPARE		0x0e
102 #define HS2P_SK_RESERVED		0x0f
103 
104 struct sense_key
105 {
106   int key;
107   char *meaning;
108   char *description;
109 };
110 static struct sense_key sensekey_errmsg[16] = {
111   {0x00, "NO SENSE", "Indicates that there is no Sense Key information"},
112   {0x01, "RECOVERED ERROR", "Invalid"},
113   {0x02, "NOT READY",
114    "Indicates that the scanner is not ready, e.g. ADF cover not closed"},
115   {0x03, "MEDIUM ERROR", "Error regarding document such as paper jam"},
116   {0x04, "HARDWARE ERROR",
117    "Error relating to hardware, e.g. CCD line clock error"},
118   {0x05, "ILLEGAL REQUEST",
119    "Used such as when illegal parameter exists in data or command"},
120   {0x06, "UNIT ATTENTION",
121    "Used when power on, BUS DEVICE RESET message or hardware reset"},
122   {0x07, "DATA PROJECT", "Invalid"},
123   {0x08, "BLANK CHECK", "Invalid"},
124   {0x09, "VENDOR UNIQUE", "Invalid"},
125   {0x0a, "COPY ABORTED", "Invalid"},
126   {0x0b, "ABORTED COMMAND", "Used when scanner aborts a command execution"},
127   {0x0c, "EQUAL", "Invalid"},
128   {0x0d, "VOLUME OVERFLOW", "Invalid"},
129   {0x0e, "MISCOMPARE", "Invalid"},
130   {0x0f, "RESERVED", "Invalid"}
131 };
132 
133 /* When Error_Code = 0x70 more detailed information is available:
134  * code, qualifier, description
135 */
136 struct ASCQ
137 {				/* ADDITIONAL SENSE CODE QUALIFIER */
138   unsigned int codequalifier;
139   char *description;
140 };
141 static struct ASCQ ascq_errmsg[74] = {
142   {0x0000, "No additional sense information"},
143   {0x0002, "End of Medium detected"},
144   {0x0005, "End of Data detected"},
145   {0x0400, "Logical unit not ready. Don't know why."},
146   {0x0401, "Logical unit is in process of becoming ready."},
147   {0x0403, "Logical unit not ready. Manual intervention required."},
148   {0x0500, "Logical unit does not respond to selection."},
149   {0x0700, "Multiple peripheral devices selected."},
150   {0x1100, "Unrecovered read error."},
151   {0x1101, "Read retries exhausted."},
152   {0x1501, "Mechanical positioning error."},
153   {0x1a00, "Parameter list length error."},
154   {0x2000, "Invalid command operation mode."},
155   {0x2400, "Invalid field in CDB (check field pointer)."},
156   {0x2500, "Logical unit not supported."},
157   {0x2600, "Invalid field in parameter list (check field pointer)."},
158   {0x2900, "Power on, reset, or BUS DEVICE RESET occurred."},
159   {0x2a01, "(MODE parameter changed.)"},
160   {0x2c00, "Command sequence error."},
161   {0x2c01, "(Too many windows specified."},
162   {0x2c02, "(Invalid combination of windows specified."},
163   {0x3700, "(Rounded parameter.)"},
164   {0x3900, "(Saving parameters not supported.)"},
165   {0x3a00, "Medium not present."},
166   {0x3b09, "(Read past end of medium.)"},
167   {0x3b0b, "(Position past end of medium.)"},
168   {0x3d00, "Invalid bits in IDENTIFY message."},
169   {0x4300, "Message error."},
170   {0x4500, "Select/Reselect failure."},
171   {0x4700, "(SCSI parity error)"},
172   {0x4800, "Initiator detected error message received."},
173   {0x4900, "Invalid message error."},
174   {0x4a00, "Command phase error."},
175   {0x4b00, "Data phase error."},
176   {0x5300, "(Media Load/Eject failed)"},
177   {0x6000, "Lamp failure"},
178   {0x6001, "(Shading Error)"},
179   {0x6002, "White adjustment error"},
180   {0x6010, "Reverse Side Lamp Failure"},
181   {0x6200, "Scan head positioning error"},
182   {0x6300, "Document Waiting Cancel"},
183   {0x8000, "(PSU overheat)"},
184   {0x8001, "(PSU 24V fuse down)"},
185   {0x8002, "(ADF 24V fuse down)"},
186   {0x8003, "(5V fuse down)"},
187   {0x8004, "(-12V fuse down)"},
188   {0x8100, "(ADF 24V power off)"},
189   {0x8101, "(Base 12V power off)"},
190   {0x8102, "(SCSI 5V power off)"},
191   {0x8103, "Lamp cover open (Lamp 24V power off)"},
192   {0x8104, "(-12V power off)"},
193   {0x8105, "(Endorser 6V power off)"},
194   {0x8106, "SCU 3.3V power down error"},
195   {0x8107, "RCU 3.3V power down error"},
196   {0x8108, "OIPU 3.3V power down error"},
197   {0x8200, "Memory Error (Bus error)"},
198   {0x8210, "Reverse-side memory error (Bus error)"},
199   {0x8300, "(Image data processing LSI error)"},
200   {0x8301, "(Interfac LSI error)"},
201   {0x8302, "(SCSI controller error)"},
202   {0x8303, "(Compression unit error)"},
203   {0x8304, "(Marker detect unit error)"},
204   {0x8400, "Endorser error"},
205   {0x8500, "(Origin Positioning error)"},
206   {0x8600, "Mechanical Time Out error (Pick Up Roller error)"},
207   {0x8700, "(Heater error)"},
208   {0x8800, "(Thermistor error)"},
209   {0x8900, "ADF cover open"},
210   {0x8901, "(ADF lift up)"},
211   {0x8902, "Document jam error for ADF"},
212   {0x8903, "Document misfeed for ADF"},
213   {0x8a00, "(Interlock open)"},
214   {0x8b00, "(Not enough memory)"},
215   {0x8c00, "Size detection failed"}
216 };
217 
218 typedef struct sense_data
219 {				/* HS2P_REQUEST_SENSE_DATA  */
220   /* bit7:valid is 1 if information byte is valid,
221      bits6:0 error_code */
222   SANE_Byte error_code;
223 
224   /* not used, set to 0 */
225   SANE_Byte segment_number;
226 
227   /* bit7 file-mark (unused, set to 0),
228      bit6 EOM is 1 if end of document detected before completing scan
229      bit5 ILI (incorrect length indicator) is 1 when data length mismatch occurs on READ
230      bits3:0 sense_key indicates error conditions.  */
231   SANE_Byte sense_key;
232 
233   SANE_Byte information[4];
234 
235   /* fixed at 6 */
236   SANE_Byte sense_length;
237 
238   /* not used and set to 0 */
239   SANE_Byte command_specific_information[4];
240   SANE_Byte sense_code;
241   SANE_Byte sense_code_qualifier;
242 } SENSE_DATA;
243 
244 /* page codes used with HS2P_SCSI_INQUIRY */
245 #define HS2P_INQUIRY_STANDARD_PAGE_CODE 0x00
246 #define HS2P_INQUIRY_VPD_PAGE_CODE      0xC0
247 #define HS2P_INQUIRY_JIS_PAGE_CODE      0xF0
248 
249 /*
250  * The EVPD and Page Code are used in pair. When the EVPD bit is 0, INQUIRY data
251  * in the standard format is returned to the initiator. When the EVPD bit is 1,
252  * the EVPD information specified by each Page Code is returned in each Page Code
253  * data format.
254  *
255  * EVPD=0x00, Page_Code=0x00      => Standard Data Format
256  *
257  * EVPD=0x01, PAGE_CODE=0x00      => Return list of supported Page Codes
258  * EVPD=0x01, PAGE_CODE=0x01~0x7F => Not Supported
259  * EVPD=0x01, PAGE_CODE=0x80~0x82 => Not Supported
260  * EVPD=0x01, PAGE_CODE=0x83~0xBF => Reserved
261  * EVPD=0x01, PAGE_CODE=0xC0      => RICOH Scanner VPD information
262  * EVPD=0x01, PAGE_CODE=0xF0      => JIS Version VPD information
263 */
264 struct inquiry_standard_data
265 {
266   /* bits7-5 peripheral qualifier
267    * bits4-0 peripheral device
268    * Peripheral Qualifier and Peripheral Devide Type are not supported on logical unit
269    * Therefore LUN=0 and this field indicates scanner and is set to 0x06
270    * When LUN!=0 this field becomes 0x1F and means undefined data
271    */
272   SANE_Byte devtype;		/* must be 0x06 */
273 
274   /* bit7: repaceable media bit is set to 0
275    * bits6-1: reserved
276    * bit0: EVPD
277    */
278   SANE_Byte rmb_evpd;
279 
280   /* bits7-6: ISO Version  is set to 0
281    * bits5-3: ECMA Version is set to 0
282    * bits2-0: ANSI Version is set to 2
283    */
284   SANE_Byte version;
285 
286   /* bit7: AENC (asynchronous event notification capability) is set to 0
287    * bit6: TrmIOP (terminate I/O process) is set to 0
288    * bits5-4: reserved
289    * bits3-0: Response Data Format is set to 2
290    */
291   SANE_Byte response_data_format;
292 
293   /* Additional Length indicate number of bytes which follows, set to 31
294    */
295   SANE_Byte length;
296 
297   SANE_Byte reserved[2];
298 
299   /* bit7: RelAdr (relative addressing) is set to 0
300    * bit6: Wbus32 is set to 0
301    * bit5: Wbus16 is set to 0
302    * bit4: Sync   is set to 0
303    * bit3: Linked is set to 0
304    * bit2: reserved
305    * bit1: CmdQue is set to 0
306    * bit0: SftRe  is set to 0
307    * Sync is set to 1 with this scanner to support synchronous data transfer
308    * When DIPSW2 is on, Sync is set to 0 for asynchronous data transfer
309    */
310   SANE_Byte byte7;
311 
312   SANE_Byte vendor[8];		/* vendor_id="RICOH   " */
313   SANE_Byte product[16];	/* product_id="IS450           " */
314   SANE_Byte revision[4];	/* product_revision_level="xRxx" where x indicate firmware version number */
315 };
316 
317 /* VPD Information [EVPD=0x01, PageCode=0xC0] */
318 struct inquiry_vpd_data
319 {
320   SANE_Byte devtype;		/* bits7-5: Peripheral Qualifier
321 				 * bits4-0: Peripheral Device Type */
322   SANE_Byte pagecode;		/* Page Code  => 0xC0 */
323   SANE_Byte byte2;		/* Reserved */
324   SANE_Byte pagelength;		/* Page Length => 12 (0x0C) */
325   SANE_Byte adf_id;		/* ADF Identification
326 				 * 0: No ADF is mounted
327 				 * 1: Single sided ADF is mounted
328 				 * 2: Double sided ADF is mounted
329 				 * 3: ARDF is mounted. (Reverse double side scanning available)
330 				 * 4: Reserved
331 				 * It should be 1 or 2 with this scanner.
332 				 */
333   SANE_Byte end_id;		/* Endorser Identification
334 				 * 0: No endorser
335 				 * 1: Endorser mounted
336 				 * 2: Reserved
337 				 * It should be 0 or 1 with this scanner
338 				 */
339   SANE_Byte ipu_id;		/* Image Processing Unit Identification
340 				 * bits 7:2   Reserved
341 				 * bit 1    0:Extended board not mounted
342 				 *          1:Extended board is mounted
343 				 * bit 0    0:IPU is not mounted
344 				 *          1:IPU is mounted
345 				 * It should always be 0 with this scanner
346 				 */
347   SANE_Byte imagecomposition;	/* indicates supported image data type.
348 				 * This is set to 0x37
349 				 * bit0 => Line art          supported ? 1:0
350 				 * bit1 => Dither            supported ? 1:0
351 				 * bit2 => Error Diffusion   supported ? 1:0
352 				 * bit3 => Color             supported ? 1:0
353 				 * bit4 => 4bits gray scale  supported ? 1:0
354 				 * bit5 => 5-8bit gray scale supported ? 1:0
355 				 * bit6 => 5-8bit gray scale supported ? 1:0
356 				 * bit7 => Reserved
357 				 */
358   SANE_Byte imagedataprocessing[2];	/* Image Data Processing Method
359 					 * IPU installed ? 0x18 : 0x00
360 					 * Byte8  => White Framing   ? 1:0
361 					 * Byte9  => Black Framing   ? 1:0
362 					 * Byte10 => Edge Extraction ? 1:0
363 					 * Byte11 => Noise Removal   ? 1:0
364 					 * Byte12 => Smoothing       ? 1:0
365 					 * Byte13 => Line Bolding    ? 0:1
366 					 * Byte14 => Reserved
367 					 * Byte15 => Reserved
368 					 */
369   SANE_Byte compression;	/* Compression Method is set to 0x00
370 				 * bit0 => MH                 supported ? 1:0
371 				 * bit1 => MR                 supported ? 1:0
372 				 * bit2 => MMR                supported ? 1:0
373 				 * bit3 => MH (byte boundary) supported ? 1:0
374 				 * bit4 => Reserved
375 				 */
376   SANE_Byte markerrecognition;	/* Marker Recognition Method is set to 0x00
377 				 * bit0    => Marker Recognition supported ? 1:0
378 				 * bits1-7 => Reserved
379 				 */
380   SANE_Byte sizerecognition;	/* Size Detection
381 				 * bit0    => Size Detection Supported ? 1:0
382 				 * bits1-7 => Reserved
383 				 */
384   SANE_Byte byte13;		/* Reserved */
385   SANE_Byte xmaxoutputpixels[2];	/* X Maximum Output Pixel is set to 4960 (0x1360)
386 					 * indicates maximum number of pixels in the main
387 					 * scanning direction that can be output by scanner
388 					 */
389 
390 };
391 
392 struct inquiry_jis_data
393 {				/* JIS INFORMATION  VPD_IDENTIFIER_F0H */
394   SANE_Byte devtype;		/* 7-5: peripheral qualifier, 4-0: peripheral device type */
395   SANE_Byte pagecode;
396   SANE_Byte jisversion;
397   SANE_Byte reserved1;
398   SANE_Byte alloclen;		/* page length: Set to 25 (19H)  */
399   struct
400   {
401     SANE_Byte x[2];		/* Basic X Resolution: Set to 400 (01H,90H) */
402     SANE_Byte y[2];		/* Basic Y Resolution: Set to 400 (01H,90H) */
403   } BasicRes;
404   SANE_Byte resolutionstep;	/* 7-4: xstep, 3-0 ystep: Both set to 1 (11H) */
405   struct
406   {
407     SANE_Byte x[2];		/* Maximum X resolution: Set to 800 (03H,20H) */
408     SANE_Byte y[2];		/* Maximum Y resolution: Set to 800 (03H,20H) */
409   } MaxRes;
410   struct
411   {
412     SANE_Byte x[2];		/* Minimum X resolution: Set to 100 (00H,64H) */
413     SANE_Byte y[2];		/* Minimum Y resolution */
414   } MinRes;
415   SANE_Byte standardres[2];	/* Standard Resolution: bits 7-0:
416 				 * byte18:  60, 75,100,120,150,160,180, 200
417 				 * byte19: 240,300,320,400,480,600,800,1200
418 				 */
419   struct
420   {
421     SANE_Byte width[4];		/* in pixels based on basic resolution. Set to 4787 (12B3H) */
422     SANE_Byte length[4];	/* maximum number of scan lines based on basic resolution. Set to 6803 (1A93H) */
423   } Window;
424   SANE_Byte functions;		/* This is set to 0EH: 0001110
425 				 * bit0:    data overflow possible
426 				 * bit1:    line art support
427 				 * bit2:    dither support
428 				 * bit3:    gray scale support
429 				 * bits7-4: reserved
430 				 */
431   SANE_Byte reserved2;
432 };
433 
434 
435 
436 #define SMS_SP  0x01		/* Mask for Bit0                                       */
437 #define SMS_PF  0x10		/* Mask for Bit4                                       */
438 typedef struct scsi_mode_select_cmd
439 {
440   SANE_Byte opcode;		/* 15H                                                 */
441   SANE_Byte byte1;		/* 7-5:LUN; 4:PF; 2:Reserved; 1:SP
442 				 * Save Page Bit must be 0 since pages cannot be saved
443 				 * Page Format Bit must be 1                           */
444   SANE_Byte reserved[2];
445   SANE_Byte len;		/* Parameter List Length                               */
446   SANE_Byte control;		/* 7-6:Vendor Unique; 5-2:Reserved; 1:Flag; 0:Link     */
447 } SELECT;
448 
449 /* MODE SELECT PARAMETERS:
450  * 0-n Mode Parameter Header
451  * 0-n mode Block Descriptor (not used)
452  * 0-n mode Page
453 */
454 typedef struct scsi_mode_parameter_header
455 {
456   SANE_Byte data_len;		/* Mode Data Length          NOT USED so must be 0 */
457   SANE_Byte medium_type;	/* Medium Type               NOT USED so must be 0 */
458   SANE_Byte dev_spec;		/* Device Specific Parameter NOT USED so must be 0 */
459   SANE_Byte blk_desc_len;	/* Block Descriptor Length             is set to 0 */
460 } MPHdr;
461 
462 typedef struct page
463 {
464   SANE_Byte code;		/* 7:PS; 6:Reserved; 5-0:Page Code            */
465   SANE_Byte len;		/* set to 14 when MPC=02H and 6 otherwise     */
466   SANE_Byte parameter[14];	/* either 14 or 6, so let's allow room for 14 */
467 } MPP;				/* Mode Page Parameters */
468 typedef struct mode_pages
469 {
470   MPHdr hdr;			/* Mode Page Header      */
471   MPP page;			/* Mode Page Parameters  */
472 } MP;
473 					     /* MODE PAGE CODES  (MPC)                    */
474 					     /* 00H Reserved (Vendor Unique)              */
475 					     /* 01H Reserved                              */
476 #define PAGE_CODE_CONNECTION            0x02	/* 02H Disconnect/Reconnect Parameters       */
477 #define PAGE_CODE_SCANNING_MEASUREMENTS 0x03	/* 03H Scanning Measurement Parameters       */
478 					     /* 04H-08H Reserved                          */
479 					     /* 09H-0AH Reserved (Not supported)          */
480 					     /* 0BH-1FH Reserved                          */
481 #define PAGE_CODE_WHITE_BALANCE        0x20	/* 20H White Balance                         */
482 					     /* 21H Reserved (Vendor Unique)              */
483 #define PAGE_CODE_LAMP_TIMER_SET       0x22	/* 22H Lamp Timer Set                        */
484 #define PAGE_CODE_SCANNING_SPEED       0x23	/* 23H Reserved (Scanning speed select)      */
485 					     /* 24H Reserved (Vendor Unique)              */
486 					     /* 25H Reserved (Vendor Unique)              */
487 #define PAGE_CODE_ADF_CONTROL          0x26	/* 26H ADF Control                           */
488 #define PAGE_CODE_ENDORSER_CONTROL     0x27	/* 27H Endorser Control                      */
489 					     /* 28H Reserved (Marker Area Data Processing) */
490 					     /* 29H-2AH Reserved (Vendor Unique)          */
491 #define PAGE_CODE_SCAN_WAIT_MODE       0x2B	/* 2BH Scan Wait Mode (Medium Wait Mode)     */
492 					     /* 2CH-3DH Reserved (Vendor Unique)          */
493 #define PAGE_CODE_SERVICE_MODE_SELECT  0x3E	/* 3EH Service Mode Select                   */
494 					     /* 3FH Reserved (Not Supported)              */
495 
496 typedef struct mode_page_connect
497 {
498   MPHdr hdr;			/* Mode Page Header: 4 bytes            */
499   SANE_Byte code;		/* 7-6:Reserved; 5-0: 02H  */
500   SANE_Byte len;		/* Parameter Length 0EH    */
501   SANE_Byte buffer_full_ratio;	/* Ignored                 */
502   SANE_Byte buffer_empty_ratio;	/* Ignored                 */
503   SANE_Byte bus_inactive_limit[2];	/* Ignored                 */
504   SANE_Byte disconnect_time_limit[2];	/* indicates minimum time to disconnect SCSI bus until reconnection.
505 					 * It is expressed in 100msec increments; i.e. "1" for 100msec, "2" for 200msec
506 					 * The maximum time is 2sec */
507   SANE_Byte connect_time_limit[2];	/* Ignored                  */
508   SANE_Byte maximum_burst_size[2];	/* expressed in 512 increments, i.e. "1" for 512 bytes, "2" for 1024 bytes
509 					 * "0" indicates unlimited amount of data */
510   SANE_Byte dtdc;		/* 7-2:Reserved; 1-0:DTDC indicates limitations of disconnection (bit1,bit0):
511 				 * 00 (DEFAULT) Controlled by the other field in this page
512 				 * 01 Once the command data transfer starts, the target never disconnects until
513 				 *    the whole data transfer completes
514 				 * 10 Reserved
515 				 * 11 Once the command data transfer starts, the target never disconnects until
516 				 *    the completion of the command
517 				 */
518   SANE_Byte reserved[3];
519 } MP_CXN;
520 
521 /* 1 inch = 6 picas = 72 points = 25.4 mm */
522 #define DEFAULT_MUD 1200	/* WHY ? */
523 /* BASIC MEASUREMENT UNIT
524  * 00H INCH
525  * 01H MILLIMETER
526  * 02H POINT
527  * 03H-FFH Reserved
528 */
529 enum BMU
530 { INCHES = 0, MILLIMETERS, POINTS };	/* Basic Measurement Unit */
531 
532 typedef struct mode_page_scanning_measurement
533 {
534   MPHdr hdr;			/* Mode Page Header: 4 bytes         */
535   SANE_Byte code;		/* 7-6:Reserved; 5-0:Page Code (03H) */
536   SANE_Byte len;		/* Parameter Length (06H)            */
537   SANE_Byte bmu;		/* Basic Measurement Unit            */
538   SANE_Byte reserved0;
539   SANE_Byte mud[2];		/* Measurement Unit Divisor
540 				 * produces an error if 0
541 				 * mud is fixed to 1 for millimeter or point
542 				 * point is default when scanner powers on */
543   SANE_Byte reserved1[2];
544 } MP_SMU;			/* Scanning Measurement Units */
545 
546 typedef struct mode_page_white_balance
547 {
548   MPHdr hdr;			/* Mode Page Header: 4 bytes         */
549   SANE_Byte code;		/* 7-6:Reserved; 5-0:Page Code (03H) */
550   SANE_Byte len;		/* Parameter Length (06H)            */
551   SANE_Byte white_balance;	/* "0" selects relative white mode (DEFAULT when power on)
552 				 * "1" selects absolute white mode */
553   SANE_Byte reserved[5];
554 } MP_WhiteBal;			/* White Balance */
555 
556 typedef struct mode_page_lamp_timer_set
557 {
558   MPHdr hdr;			/* Mode Page Header: 4 bytes            */
559   SANE_Byte code;		/* 7-6:Reserved; 5-0:Page Code (22H)    */
560   SANE_Byte len;		/* Parameter Length (06H)               */
561   SANE_Byte time_on;		/* indicates the time of lamp turned on */
562   SANE_Byte ignored[5];
563 } MP_LampTimer;			/* Lamp Timer Set (Not supported ) */
564 
565 typedef struct mode_page_adf_control
566 {
567   MPHdr hdr;			/* Mode Page Header: 4 bytes            */
568   SANE_Byte code;		/* 7-6:Reserved; 5-0:Page Code (26H)    */
569   SANE_Byte len;		/* Parameter Length (06H)               */
570   SANE_Byte adf_control;	/* 7-2:Reserved; 1-0:ADF selection:
571 				 * 00H Book Mode (DEFAULT when power on)
572 				 * 01H Simplex ADF
573 				 * 02H Duplex ADF
574 				 * 03H-FFH Reserved                     */
575   SANE_Byte adf_mode_control;	/* 7-3:Reserved; 2:Prefeed Mode Validity 1-0:Ignored
576 				 * Prefeed Mode "0" means invalid, "1" means valid */
577   SANE_Byte medium_wait_timer;	/* indicates time for scanner to wait for media. Scanner
578 				 * will send CHECK on timeout. NOT SUPPORTED */
579   SANE_Byte ignored[3];
580 } MP_ADF;			/* ADF Control */
581 
582 typedef struct mode_page_endorser_control
583 {
584   MPHdr hdr;			/* Mode Page Header: 4 bytes            */
585   SANE_Byte code;		/* 7-6:Reserved; 5-0:Page Code (27H)    */
586   SANE_Byte len;		/* Parameter Length (06H)               */
587   SANE_Byte endorser_control;	/* 7-3:Reserved; 2-0:Endorser Control:
588 				 * 0H Disable Endorser (DEFAULT)
589 				 * 1H Enable Endorser
590 				 * 3H-7H Reserved                       */
591   SANE_Byte ignored[5];
592 } MP_EndCtrl;			/* Endorser Control */
593 
594 typedef struct mode_page_scan_wait
595 {
596   MPHdr hdr;			/* Mode Page Header: 4 bytes            */
597   SANE_Byte code;		/* 7-6:Reserved; 5-0:Page Code (2BH)    */
598   SANE_Byte len;		/* Parameter Length (06H)               */
599   SANE_Byte swm;		/* 7-1:Reserved; 0:Scan Wait Mode
600 				 * 0H Disable Medium wait mode
601 				 * 1H Enable  Medium wait mode
602 				 * In Medium wait mode, when SCAN, READ, or LOAD (in ADF mode) is issued,
603 				 * the scanner waits until start button is pressed on operation panel
604 				 * When abort button is pressed, the command is cancelled
605 				 * In ADF mode, when there are no originals on ADF, CHECK condition is
606 				 * not given unless start button is pressed. */
607   SANE_Byte ignored[5];
608 } MP_SWM;			/* Scan Wait */
609 
610 typedef struct mode_page_service
611 {				/* Selectable when Send Diagnostic command is performed */
612   MPHdr hdr;			/* Mode Page Header: 4 bytes            */
613   SANE_Byte code;		/* 7-6:Reserved; 5-0:Page Code (3EH)    */
614   SANE_Byte len;		/* Parameter Length (06H)               */
615   SANE_Byte service;		/* 7-1:Reserved; 0:Service Mode
616 				 * "0" selects Self Diagnostics mode (DEFAULT when power on )
617 				 * "1" selects Optical Adjustment mode  */
618   SANE_Byte ignored[5];
619 } MP_SRV;			/* Service */
620 
621 typedef struct scsi_mode_sense_cmd
622 {
623   SANE_Byte opcode;		/* 1AH */
624   SANE_Byte dbd;		/* 7-5:LUN; 4:Reserved; 3:DBD (Disable Block Description) set to "0"; 2-0:Reserved */
625   SANE_Byte pc;			/* 7-6:PC; 5-0:Page Code
626 				 * PC field indicates the type of data to be returned (bit7,bit6):
627 				 * 00 Current Value   (THIS IS THE ONLY VALUE WHICH WORKS!)
628 				 * 01 Changeable Value
629 				 * 10 Default Value
630 				 * 11 Saved Value
631 				 *
632 				 * Page Code indicates requested page. (See PAGE_CODE defines) */
633   SANE_Byte reserved;
634   SANE_Byte len;		/* Allocation length */
635   SANE_Byte control;		/* 7-6:Vendor Unique; 5-2:Reserved; 1:Flag; 0:Link */
636 } SENSE;
637 /* MODE SENSE DATA FORMAT --
638  * The format of Sense Data to be returned is Mode Parameter Header + Page
639  * see struct scsi_mode_parameter_header
640  *     struct mode_pages
641 */
642 
643 /* 1-3-8 SCAN command */
644 typedef struct scsi_start_scan_cmd
645 {
646   SANE_Byte opcode;		/* 1BH                   */
647   SANE_Byte byte1;		/* 7-5:LUN; 4-0:Reserved */
648   SANE_Byte page_code;
649   SANE_Byte reserved;
650   SANE_Byte len;		/* Transfer Length
651 				 * Length of Window List in bytes
652 				 * Since scanner supports up to 2 windows, len is 1 or 2
653 				 */
654   SANE_Byte control;		/* 7-6:Vendor Unique; 5-2:Reserved; 1:Flag; 0:Link */
655 } START_SCAN;
656 
657 /* 1-3-9 RECEIVE DIAGNOSTIC
658  * 1-3-10 SEND DIAGNOSTIC */
659 
660 /* BinaryFilter Byte
661  * bit7: Noise Removal '1':removal
662  * bit6: Smoothing     '1':smoothing
663  * bits5-2: ignored
664  * bits1-0: Noise Removal Matrix
665  * 00:3x3    01:4x4
666  * 10:5x5    11:Reserved
667 */
668 struct val_id
669 {
670   SANE_Byte val;
671   SANE_Byte id;
672 };
673 static SANE_String_Const noisematrix_list[] = {
674   "None", "3x3", "4x4", "5x5", NULL
675 };
676 struct val_id noisematrix[] = {
677   {0x03, 0},			/* dummy <reserved> value for "None" */
678   {0x00, 1},
679   {0x01, 2},
680   {0x02, 3}
681 };
682 static SANE_String_Const grayfilter_list[] = {
683   "none", "averaging", "MTF correction", NULL
684 };
685 struct val_id grayfilter[] = {
686   {0x00, 0},
687   {0x01, 1},
688   {0x03, 2}
689 };
690 
691 static SANE_String_Const paddingtype_list[] = {
692   "Pad with 0's to byte boundary",
693   "Pad with 1's to byte boundary",
694   "Truncate to byte boundary",
695   NULL
696 };
697 enum paddingtypes
698 { PAD_WITH_ZEROS = 0x01, PAD_WITH_ONES, TRUNCATE };
699 struct val_id paddingtype[] = {
700   {PAD_WITH_ZEROS, 0},
701   {PAD_WITH_ONES, 1},
702   {TRUNCATE, 2}
703 };
704 
705 #define NPADDINGTYPES 3
706 #define PADDINGTYPE_DEFAULT 2
707 static SANE_String_Const auto_separation_list[] = {
708   "Off", "On", "User", NULL
709 };
710 struct val_id auto_separation[] = {
711   {0x00, 0},
712   {0x01, 1},
713   {0x80, 2}
714 };
715 static SANE_String_Const auto_binarization_list[] = {
716   "Off",
717   "On",
718   "Enhancement of light characters",
719   "Removal of background color",
720   "User",
721   NULL
722 };
723 struct val_id auto_binarization[] = {
724   {0x00, 0},
725   {0x01, 1},
726   {0x02, 2},
727   {0x03, 3},
728   {0x80, 4}
729 };
730 enum imagecomposition
731 { LINEART = 0x00, HALFTONE, GRAYSCALE };
732 enum halftonecode
733 { DITHER = 0x02, ERROR_DIFFUSION };
734 static SANE_String_Const halftone_code[] = {
735   "Dither", "Error Diffusion", NULL
736 };
737 static SANE_String_Const halftone_pattern_list[] = {
738   "8x4, 45 degree",
739   "6x6, 90 degree",
740   "4x4, spiral",
741   "8x8, 90 degree",
742   "70 lines",
743   "95 lines",
744   "180 lines",
745   "16x8, 45 degree",
746   "16x16, 90 degree",
747   "8x8, Bayer",
748   "User #1",
749   "User #2",
750   NULL
751 };
752 struct val_id halftone[] = {
753   {0x01, 1},
754   {0x02, 2},
755   {0x03, 3},
756   {0x04, 4},
757   {0x05, 5},
758   {0x06, 6},
759   {0x07, 7},
760   {0x08, 9},
761   {0x09, 9},
762   {0x0A, 10},
763   {0x80, 11},
764   {0x81, 12}
765 };
766 
767 #if 0
768 static struct
769 {
770   SANE_Byte code;
771   char *type;
772 } compression_types[] =
773 {
774   {
775   0x00, "No compression"},
776   {
777   0x01, "CCITT G3, 1-dimensional (MH)"},
778   {
779   0x02, "CCITT G3, 2-dimensional (MR)"},
780   {
781   0x03, "CCITT G4, 2-dimensional (MMR)"},
782     /* 04H-0FH Reserved
783      * 10H Reserved (not supported)
784      * 11H-7FH Reserved
785      */
786   {
787   0x80, "CCITT G3, 1-dimensional (MH) Padding with 0's to byte boundary"}
788   /* 80H-FFH Reserved (Vendor Unique) */
789 };
790 static struct
791 {
792   SANE_Byte code;
793   char *argument;
794 } compression_argument[] =
795 {
796   /* 00H Reserved */
797   /* 01H Reserved */
798   {
799   0x02, "K factor-0~255"}
800   /* 03H Reserved */
801   /* 04H-0FH Reserved */
802   /* 10H Reserved */
803   /* 11H-7FH Reserved */
804   /* 80H Reserved */
805   /* 80H-FFH Reserved */
806 };
807 #endif
808 #define GAMMA_NORMAL  0x00
809 #define GAMMA_SOFT    0x01
810 #define GAMMA_SHARP   0x02
811 #define GAMMA_LINEAR  0x03
812 #define GAMMA_USER    0x08
813 /* 04H-07H Reserved */
814 /* 09H-0FH Reserved */
815 static SANE_String gamma_list[6] = {
816   "Normal", "Soft", "Sharp", "Linear", "User", NULL
817 };
818 
819 /* 1-3-11 SET WINDOW command */
820 
821 struct window_section
822 {				/* 32 bytes */
823   SANE_Byte sef;		/*byte1 7-2:ignored 1:SEF '0'-invalid section; '1'-valid section */
824   SANE_Byte ignored0;
825   SANE_Byte ulx[4];
826   SANE_Byte uly[4];
827   SANE_Byte width[4];
828   SANE_Byte length[4];
829   SANE_Byte binary_filtering;
830   SANE_Byte ignored1;
831   SANE_Byte threshold;
832   SANE_Byte ignored2;
833   SANE_Byte image_composition;
834   SANE_Byte halftone_id;
835   SANE_Byte halftone_code;
836   SANE_Byte ignored3[7];
837 };
838 /* 1-3-11 SET WINDOW COMMAND
839  * Byte0: 24H
840  * Byte1: 7-5: LUN; 4-0: Reserved
841  * Byte2-5: Reserved
842  * Byte6-8: Transfer Length
843  * Byte9: 7-6: Vendor Unique; 5-2: Reserved; 1: Flag; 0: Link
844  *
845  * Transfer length indicates the byte length of Window Parameters (Set Window Data Header +
846  * Window Descriptor Bytes transferred from the initiator in the DATA OUT PHASE
847  * The scanner supports 2 windows, so Transfer Length is 648 bytes:
848  * Set Window Header 8 bytes + Window Descriptor Bytes 640 (320*2) bytes).
849  * If data length is longer than 648 bytes only the first 648 bytes are valid, The remainng data is ignored.
850  * If data length is shorter than 648 only the specified byte length is valid data.
851  *
852  *
853  * WINDOW DATA HEADER
854  * Byte0-5: Reserved
855  * Byte6-7: Window Descriptor Length (WDL)
856  *          WDL indicates the number of bytes of one Window Descriptor Bytes which follows.
857  *          In this scanner, this value is 640 since it supports 2 windows.
858  *
859  * WINDOW DESCRIPTOR BYTES
860 */
861 #define HS2P_WINDOW_DATA_SIZE 640
862 struct hs2p_window_data
863 {				/* HS2P_WINDOW_DATA_FORMAT       */
864   SANE_Byte window_id;		/*     0: Window Identifier      */
865   SANE_Byte auto_bit;		/*     1: 1-1:Reserved; 0:Auto   */
866   SANE_Byte xres[2];		/*   2-3: X-Axis Resolution      100-800dpi in 1dpi steps */
867   SANE_Byte yres[2];		/*   4-5: Y-Axis Resolution      100-800dpi in 1dpi steps */
868   SANE_Byte ulx[4];		/*   6-9: X-Axis Upper Left      */
869   SANE_Byte uly[4];		/* 10-13: Y-Axis Upper Left      */
870   SANE_Byte width[4];		/* 14-17: Window Width           */
871   SANE_Byte length[4];		/* 18-21: Window Length          */
872   SANE_Byte brightness;		/*    22: Brightness  [0-255] dark-light 0 means default value of 128 */
873   SANE_Byte threshold;		/*    23: Threshold   [0-255] 0 means default value of 128            */
874   SANE_Byte contrast;		/*    24: Contrast    [0-255] low-high   0 means default value of 128 */
875   SANE_Byte image_composition;	/*    25: Image Composition
876 				 *        00H Lineart
877 				 *        01H Dithered Halftone
878 				 *        02H Gray scale
879 				 */
880   SANE_Byte bpp;		/*    26: Bits Per Pixel         */
881   SANE_Byte halftone_code;	/*    27: Halftone Code
882 				 *        00H-01H Reserved
883 				 *        02H Dither (partial Dot)
884 				 *        03H Error Diffusion
885 				 *        04H-07H Reserved
886 				 */
887   SANE_Byte halftone_id;	/*    28: Halftone ID
888 				 *        00H Reserved
889 				 *        01H 8x4, 45 degree
890 				 *        02H 6x6, 90 degree
891 				 *        03H 4x4, Spiral
892 				 *        04H 8x8, 90 degree
893 				 *        05H 70 lines
894 				 *        06H 95 lines
895 				 *        07H 180 lines
896 				 *        08H 16x8, 45 degree
897 				 *        09H 16x16, 90 degree
898 				 *        0AH 8x8, Bayer
899 				 *        0Bh-7FH Reserved
900 				 *        80H Download #1
901 				 *        81H Download #2
902 				 *        82H-FFH Reserved
903 				 */
904   SANE_Byte byte29;		/*    29:   7: RIF (Reverse Image Format) bit inversion
905 				 *             Image Composition field must be lineart or dithered halftone
906 				 *             RIF=0: White=0 Black=1
907 				 *             RIF=1: White=1 Black=0
908 				 *        6-3: Reserved;
909 				 *        2-0: Padding Type:
910 				 *             00H Reserved
911 				 *             01H Pad with 0's to byte boundary
912 				 *             02H Pad with 1's to byte boundary
913 				 *             03H Truncate to byte boundary
914 				 *             04H-FFH Reserved
915 				 */
916   SANE_Byte bit_ordering[2];	/* 30-31: Bit Ordering: Default 0xF8
917 				 *        0: 0=>output from bit0 of each byte; 1=>output from bit7
918 				 *        1: 0=>output from LSB; 1=>output from MSB
919 				 *        2: 0=>unpacked 4 bits gray; 1=>Packed 4 bits gray
920 				 *        3: 1=>Bits arrangement from LSB in grayscale; 0=>from MSB
921 				 *      4-6: reserved
922 				 *        7: 1=>Mirroring; 0=>Normal output
923 				 *     8-15: reserved
924 				 */
925   SANE_Byte compression_type;	/*    32: Compression Type:     Unsupported in IS450   */
926   SANE_Byte compression_arg;	/*    33: Compression Argument: Unsupported in IS450   */
927   SANE_Byte reserved2[6];	/* 34-39: Reserved               */
928   SANE_Byte ignored1;		/*    40: Ignored                */
929   SANE_Byte ignored2;		/*    41: Ignored                */
930   SANE_Byte byte42;		/*    42:   7: MRIF: Grayscale Reverse Image Format
931 				 *             MRIF=0: White=0 Black=1
932 				 *             MRIF=1: White=1 Black=0
933 				 *        6-4: Filtering: for Grayscale
934 				 *             000 No filter
935 				 *             001 Averaging
936 				 *             010 Reserved
937 				 *             011 MTF Correction
938 				 *             100 Reserved
939 				 *             110 Reserved
940 				 *             111 Reserved
941 				 *        3-0: Gamma ID
942 				 *             00H Normal
943 				 *             01H Soft
944 				 *             02H Sharp
945 				 *             03H Linear
946 				 *             04H-07H Reserved
947 				 *             08H Download table
948 				 *             09H-0FH Reserved
949 				 */
950   SANE_Byte ignored3;		/*    43: Ignored                */
951   SANE_Byte ignored4;		/*    44: Ignored                */
952   SANE_Byte binary_filtering;	/*    45: Binary Filtering
953 				 *        0-1: Noise Removal Matrix:
954 				 *             00: 3x3
955 				 *             01: 4x4
956 				 *             10: 5x5
957 				 *             11: Reserved
958 				 *        5-2: Ignored
959 				 *          6: Smoothing Flag
960 				 *          7: Noise Removal Flag
961 				 *
962 				 *          Smoothing and Noise removal can be set when option IPU is installed
963 				 *          Setting is ignored for reverse side because optional IPU is not valid
964 				 *          for reverse side scanning
965 				 */
966   /*
967    *  The following is only available when IPU is installed:
968    *  SECTION, Automatic Separation, Automatic Binarization
969    *  46-319 is ignored for Window 2
970    */
971   SANE_Byte ignored5;		/*    46: Ignored                       */
972   SANE_Byte ignored6;		/*    47: Ignored                       */
973   SANE_Byte automatic_separation;	/*    48: Automatic Separation
974 					 *            00H OFF
975 					 *            01H Default
976 					 *        02H-7FH Reserved
977 					 *            80H Download table
978 					 *        91H-FFH Reserved
979 					 */
980   SANE_Byte ignored7;		/*    49: Ignored                       */
981   SANE_Byte automatic_binarization;	/*    50: Automatic Binarization
982 					 *            00H OFF
983 					 *            01H Default
984 					 *            02H Enhancement of light characters
985 					 *            03H Removal of background color
986 					 *        04H-7FH Reserved
987 					 *            80H Download table
988 					 *        81H-FFH Reserved
989 					 */
990   SANE_Byte ignored8[13];	/* 51-63: Ignored                       */
991   struct window_section sec[8];	/* Each window can have multiple sections, each of 32 bytes long
992 				 * 53-319: = 256 bytes = 8 sections of 32 bytes
993 				 * IS450 supports up to 4 sections,
994 				 * IS420 supports up to 6 sections
995 				 */
996 };
997 struct set_window_cmd
998 {
999   SANE_Byte opcode;		/* 24H */
1000   SANE_Byte byte2;		/* 7-5:LUN 4-0:Reserve */
1001   SANE_Byte reserved[4];	/* Reserved */
1002   SANE_Byte len[3];		/* Transfer Length */
1003   SANE_Byte control;		/* 76543210
1004 				 * XX       Vendor Unique
1005 				 *   XXXX   Reserved
1006 				 *       X  Flag
1007 				 *        X Link
1008 				 */
1009 };
1010 struct set_window_data_hdr
1011 {
1012   SANE_Byte reserved[6];
1013   SANE_Byte len[2];
1014 };
1015 typedef struct set_window_data
1016 {
1017   struct set_window_data_hdr hdr;
1018   struct hs2p_window_data data[2];
1019 } SWD;
1020 
1021 /* 1-3-12 GET WINDOW command */
1022 struct get_window_cmd
1023 {
1024   SANE_Byte opcode;
1025   SANE_Byte byte1;		/* 7-5: LUN; * 4-1:Reserved; *   0:Single bit is 0 */
1026   SANE_Byte reserved[3];
1027   SANE_Byte win_id;		/* Window ID is either 0 or 1 */
1028   SANE_Byte len[3];		/* Transfer Length */
1029   SANE_Byte control;		/* 7-6:Vendor Unique; 5-2:Reserved; 1:Flag; 0:Link */
1030 };
1031 /* The data format to be returned is Get Window Data header + Window Descriptor Bytes
1032  * The format of Window Descriptor Bytes is the same as that for SET WINDOW
1033 */
1034 struct get_window_data_hdr
1035 {
1036   SANE_Byte data_len[2];	/* Window Data Length indicates byte len of data which follows less its own 2 bytes */
1037   SANE_Byte reserved[4];
1038   SANE_Byte desc_len[2];	/* Window Descriptor Length indicates byte length of one Window Descriptor which is 640 */
1039 };
1040 typedef struct get_window_data
1041 {
1042   struct get_window_data_hdr hdr;
1043   struct hs2p_window_data data[2];
1044 } GWD;
1045 
1046 /* READ/SEND DATA TYPE CODES  */
1047 /* DATA TYPE CODES (DTC):                       */
1048 #define DATA_TYPE_IMAGE                      0x00
1049 /* 01H Reserved (Vendor Unique)                 */
1050 #define DATA_TYPE_HALFTONE                   0x02
1051 #define DATA_TYPE_GAMMA                      0x03
1052 /*04H-7FH Reserved                              */
1053 #define DATA_TYPE_ENDORSER                   0x80
1054 #define DATA_TYPE_SIZE                       0x81
1055 /* 82H Reserved                                 */
1056 /* 83H Reserved (Vendor Unique)                 */
1057 #define DATA_TYPE_PAGE_LEN                   0x84
1058 #define DATA_TYPE_MAINTENANCE                0x85
1059 #define DATA_TYPE_ADF_STATUS                 0x86
1060 /* 87H Reserved (Skew Data)                     */
1061 /* 88H-91H Reserved (Vendor Unique)             */
1062 /* 92H Reserved (Scanner Extension I/O Access)  */
1063 /* 93H Reserved (Vendor Unique)                 */
1064 /* 94H-FFH Reserved (Vendor Unique)             */
1065 #define DATA_TYPE_EOL			     -1	/* va_end */
1066 
1067 /* DATA TYPE QUALIFIER CODES when DTC=93H       */
1068 #define DTQ				     0x00	/* ignored */
1069 #define DTQ_AUTO_PHOTOLETTER                 0x00	/* default */
1070 #define DTQ_DYNAMIC_THRESHOLDING             0x01	/* default */
1071 #define DTQ_LIGHT_CHARS_ENHANCEMENT          0x02
1072 #define DTQ_BACKGROUND_REMOVAL               0x03
1073 /* 04H-7FH Reserved                             */
1074 #define DTQ_AUTO_PHOTOLETTER_DOWNLOAD_TABLE  0x80
1075 #define DTQ_DYNAMIC_THRESHOLD_DOWNLOAD_TABLE 0x81
1076 /* 82H-FFH Reserved                             */
1077 
1078 /* 1-3-13 READ command */
1079 /* 1-3-14 SEND command */
1080 struct scsi_rs_scanner_cmd
1081 {
1082   SANE_Byte opcode;		/* READ=28H  SEND=2AH                    */
1083   SANE_Byte byte1;		/* 7-5:LUN; 4-0:Reserved                 */
1084   SANE_Byte dtc;		/* Data Type Code: See DTC DEFINES above */
1085   SANE_Byte reserved;
1086   SANE_Byte dtq[2];		/* Data Type Qualifier valid only for DTC 02H,03H,93H */
1087   SANE_Byte len[3];		/* Transfer Length */
1088   SANE_Byte control;		/* 7-6:Vendor Unique; 5-2:Reserved; 1:Flag; 0:Link */
1089 };
1090 /*
1091  * Data Format for Image Data
1092  * Non-compressed: {first_line, second_line, ... nth_line}
1093  * MH/MR Compression: {EOL, 1st_line_compressed, EOL, 2nd_line_compressed,..., EOL, last_line_compressed, EOL,EOL,EOL,EOL,EOL,EOL
1094  *       where EOL = 000000000001
1095  * MMR Compression: = {1st_line_compressed, 2nd_line_compressed,...,last_line_compressed, EOL,EOL}
1096  *
1097  * Normal Binary Output: MSB-LSB 1stbytes,2nd,3rd...Last
1098  * Mirror Binary Output: MSB-LSB Last,...2nd,1st
1099  *
1100  * Normal Gray Output MSB-LSB: 1st,2nd,3rd...Last
1101  *       4 bit/pixel gray: [32103210]
1102  *       8 bit/pixel gray: [76543210]
1103  * Mirror Gray Output MSB-LSB Last,...2nd,1st
1104  *
1105  *
1106  * HALFTONE MASK DATA: 1byte(row,col) ={2,3,4,6,8,16}
1107  *   (r0,c0), (r0,c1), (r0,c2)...(r1,c0),(r1,c2)...(rn,cn)
1108  *
1109  * GAMMA FUNCTION TABLE Output (D) vs. Input (I)(0,0)=(Black,Black) (255,255)=(White,White)
1110  * The number of gray scale M = 8
1111  * 2^8 = 256 total table data
1112  * D0 = D(I=0), D1=D(I=1)...D255=D(I=255)
1113  * DATA= [1st byte ID],[2nd byte M],[D0],[D1],...[D255]
1114  *
1115  * ENDORSER DATA: 1st_char, 2nd_char,...last_char
1116  *
1117  * SIZE DATA: 1byte: 4bits-Start Position; 4bits-Width Info
1118  *
1119  * PAGE LENGTH: 5bytes: 1st byte is MSB, Last byte is LSB
1120 */
1121 
1122 typedef struct maintenance_data
1123 {
1124   SANE_Byte nregx_adf;		/* number of registers of main-scanning in ADF mode */
1125   SANE_Byte nregy_adf;		/* number of registers of sub-scanning  in ADF mode */
1126   SANE_Byte nregx_book;		/* number of registers of main-scanning in Book mode */
1127   SANE_Byte nregy_book;		/* number of registers of sub-scanning  in Book mode */
1128   SANE_Byte nscans_adf[4];	/* Number of scanned pages in ADF mode */
1129   SANE_Byte nscans_book[4];	/* Number of scanned pages in Book mode */
1130   SANE_Byte lamp_time[4];	/* Lamp Time */
1131   SANE_Byte eo_odd;		/* Adjustment data of E/O balance in black level (ODD) */
1132   SANE_Byte eo_even;		/* Adjustment data of E/O balance in black level (EVEN) */
1133   SANE_Byte black_level_odd;	/* The adjustment data in black level (ODD) */
1134   SANE_Byte black_level_even;	/* The adjustment data in black level (EVEN) */
1135   SANE_Byte white_level_odd[2];	/* The adjustment data in white level (ODD) */
1136   SANE_Byte white_level_even[2];	/* The adjustment data in white level (EVEN) */
1137   SANE_Byte first_adj_white_odd[2];	/* First adjustment data in white level (ODD) */
1138   SANE_Byte first_adj_white_even[2];	/* First adjustment data in white level (EVEN) */
1139   SANE_Byte density_adj;	/* Density adjustment */
1140   SANE_Byte nregx_reverse;	/* The number of registers of main-scanning of the reverse-side ADF */
1141   SANE_Byte nregy_reverse;	/* The number of registers of sub-scanning of the reverse-side ADF */
1142   SANE_Byte nscans_reverse_adf[4];	/* Number of scanned pages of the reverse side ADF */
1143   SANE_Byte reverse_time[4];	/* The period of lamp turn on of the reverse side */
1144   SANE_Byte nchars[4];		/* The number of endorser characters */
1145   SANE_Byte reserved0;
1146   SANE_Byte reserved1;
1147   SANE_Byte reserved2;
1148   SANE_Byte zero[2];		/* All set as 0 */
1149 } MAINTENANCE_DATA;
1150 /* ADF status 1byte:
1151  * 7-3:Reserved;
1152  *   2:Reserved;
1153  *   1: '0'-ADF cover closed; '1'-ADF cover open
1154  *   0: '0'-Document on ADF; '1'-No document on ADF
1155  *
1156 */
1157 
1158 struct IPU
1159 {
1160   SANE_Byte byte0;		/* 7-4:Reserved; 3:White mode; 2:Reserved; 1-0: Gamma Table Select */
1161   SANE_Byte byte1;		/* 7-2:Reserved; 1-0: MTF Filter Select */
1162 };
1163 struct IPU_Auto_PhotoLetter
1164 {
1165   /* Halftone Separations for each level
1166    * 256 steps of relative value with 0 the sharpest and 255 the softest
1167    * The relation of strength is Strength2 > Strength3 > Strength4 ...
1168    */
1169   struct
1170   {
1171     SANE_Byte level[6];
1172   } halftone_separation[2];
1173 
1174   /* 7-2:Reversed 1-0:Halftone
1175    * 00 Default
1176    * 01 Peak Detection Soft
1177    * 10 Peak Detection Sharp
1178    * 11 Don't Use
1179    */
1180   SANE_Byte byte12;
1181 
1182   SANE_Byte black_correction;	/* Black correction strength: 0-255 sharpest-softest */
1183   SANE_Byte edge_sep[4];	/* Edge Separation strengths: 0-255 sharpest-softest 1-4 */
1184   SANE_Byte white_background_sep_strength;	/* 0-255 sharpest-softest */
1185   SANE_Byte byte19;		/* 7-1:Reversed; 0:White mode    '0'-Default;    '1'-Sharp */
1186   SANE_Byte byte20;		/* 7-1:Reversed; 0:Halftone mode '0'-widen dots; '1'-Default */
1187   SANE_Byte halftone_sep_levela;
1188   SANE_Byte halftone_sep_levelb;
1189   SANE_Byte byte23;		/* 7-4:Reversed; 3-0:Adjustment of separation level: usually fixed to 0 */
1190 
1191   /* 7-4:Reversed; 3-0:Judge Conditions Select
1192    *  0XXX Black Correction OFF      1XXX Black Correction ON
1193    *  X0XX Halftone Separation OFF   X1XX Halftone Separation ON
1194    *  XX0X White Separation OFF      XX1X White Separation ON
1195    *  XXX0 Edge Separation OFF       XXX1 Edge Separation ON
1196    */
1197   SANE_Byte byte24;
1198 
1199   /* 7-4:Filter A; 3-0:Filter B
1200    *  FilterA: 16 types are valid from 0000 to 1111
1201    *  FilterB: 0000 to 1110 are valid; 1111 is not valid
1202    */
1203   SANE_Byte MTF_correction;
1204 
1205   /* 7-4:Filter A; 3-0:Filter B
1206    *  0000(soft) to 0111(sharp) are valid; 1000 to 1111 are invalid
1207    */
1208   SANE_Byte MTF_strength;
1209 
1210   /* 7-4:Filter A; 3-0:Filter B
1211    * slightly adjusts the strength of the filters
1212    */
1213   SANE_Byte MTF_adjustment;
1214 
1215   /* 7-4:Reserved; 3-0: smoothing filter select
1216    * 14 kinds are valid from 0000 to 1101; 1110 to 1111 are invalid
1217    */
1218   SANE_Byte smoothing;
1219 
1220   /* 7-2:Reversed; 1-0: Filter Select
1221    *  10 MTF Correction Select
1222    *  11 Smoothing Select
1223    *  from 00 to 01 are not valid and basically it is set as 10
1224    */
1225   SANE_Byte byte29;
1226 
1227   /* 7-4:Reserved; 3-0: MTF Correction Filter C
1228    * 16 kinds are valid from 0000 to 1111
1229    */
1230   SANE_Byte MTF_correction_c;
1231 
1232   /* 7-3:Reserved; 2-0: MTF Correction Filter strength C
1233    *  000(soft) to 111(sharp) are valid
1234    */
1235   SANE_Byte MTF_strength_c;
1236 };
1237 /*
1238 struct IPU_Dynamic {
1239   to be implemented
1240 };
1241 sensor data
1242 */
1243 
1244 /* for object_position command */
1245 #define OBJECT_POSITION_UNLOAD 0
1246 #define OBJECT_POSITION_LOAD   1
1247 
1248 /* 1-3-15 OBJECT POSITION */
1249 typedef struct scsi_object_position_cmd
1250 {
1251   SANE_Byte opcode;		/* 31H */
1252   SANE_Byte position_func;	/* 7-5:LUN; 4-3:Reserved; 2-0:Position Function (bit2,bit1,bit0):
1253 				 * 000 Unload Object  (NO CHECK ERROR even though no document on ADF)
1254 				 * 001 Load Object    (NO CHECK ERROR even though document already fed to start position)
1255 				 * 010 Absolute Positioning in Y-axis. Not Supported in this scanner
1256 				 * 3H-7H Reserved */
1257   SANE_Byte count[3];		/* Reserved */
1258   SANE_Byte reserved[4];
1259   SANE_Byte control;		/* 7-6:Vendor Unique; 5-2:Reserved; 1:Flag; 0:Link */
1260 } POSITION;
1261 
1262 /* 1-3-16 GET DATA BUFFER STATUS */
1263 typedef struct scsi_get_data_buffer_status_cmd
1264 {
1265   SANE_Byte opcode;		/* 34H */
1266   SANE_Byte wait;		/* 7-5:LUN; 4-1:Reserved; 0: Wait bit is "0" */
1267   SANE_Byte reserved[5];
1268   SANE_Byte len[2];		/* Allocation Length */
1269   SANE_Byte control;		/* 7-6:Vendor Unique; 5-2:Reserved; 1:Flag; 0:Link */
1270 } GET_DBS_CMD;
1271 typedef struct scsi_status_hdr
1272 {
1273   SANE_Byte len[3];		/* Data Buffer Status Length */
1274   SANE_Byte block;		/* 7-1:Reserved; 0:Block bit is 0 */
1275 } STATUS_HDR;
1276 typedef struct scsi_status_data
1277 {
1278   SANE_Byte wid;		/* window identifier is 0 or 1 */
1279   SANE_Byte reserved;
1280   SANE_Byte free[3];		/* Available Space Data `Buffer */
1281   SANE_Byte filled[3];		/* Scan Data Available (Filled Data Bufferj) */
1282 } STATUS_DATA;
1283 /* BUFFER STATUS DATA FORMAT */
1284 typedef struct scsi_buffer_status
1285 {
1286   STATUS_HDR hdr;
1287   STATUS_DATA data;
1288 } STATUS_BUFFER;
1289