piuspatch
v0.1
USB addition to PIE backend
|
00001 /* ----------------------------------------------------------------------------- */ 00002 00003 /* sane - Scanner Access Now Easy. 00004 00005 pie-scsidef.h: scsi-definiton header file for PIE scanner driver. 00006 00007 Copyright (C) 2000 Simon Munton, based on the umax-scsidef.h by Oliver Rauch & Michael Johnson 00008 Copyright (C) 2012 Michael Rickmann <mrickma@gwdg.de> 00009 for initial USB additions 00010 00011 This file is part of the SANE package. 00012 00013 This program is free software; you can redistribute it and/or 00014 modify it under the terms of the GNU General Public License as 00015 published by the Free Software Foundation; either version 2 of the 00016 License, or (at your option) any later version. 00017 00018 This program is distributed in the hope that it will be useful, but 00019 WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 General Public License for more details. 00022 00023 You should have received a copy of the GNU General Public License 00024 along with this program; if not, write to the Free Software 00025 Foundation, Inc., 59 Temple Place - Suite 330, Boston, 00026 MA 02111-1307, USA. 00027 00028 As a special exception, the authors of SANE give permission for 00029 additional uses of the libraries contained in this release of SANE. 00030 00031 The exception is that, if you link a SANE library with other files 00032 to produce an executable, this does not by itself cause the 00033 resulting executable to be covered by the GNU General Public 00034 License. Your use of that executable is in no way restricted on 00035 account of linking the SANE library code into it. 00036 00037 This exception does not, however, invalidate any other reasons why 00038 the executable file might be covered by the GNU General Public 00039 License. 00040 00041 If you submit changes to SANE to the maintainers to be included in 00042 a subsequent release, you agree by submitting the changes that 00043 those changes may be distributed with this exception intact. 00044 00045 If you write modifications of your own for SANE, it is your choice 00046 whether to permit this exception to apply to your modifications. 00047 If you do not wish that, delete this exception notice. 00048 */ 00049 00050 /* --------------------------------------------------------------------------------------------------------- */ 00051 00052 00053 #ifndef PIE_SCSIDEF_H 00054 #define PIE_SCSIDEF_H 00055 00056 00057 00058 /* --------------------------------------------------------------------------------------------------------- */ 00059 00060 /* I'm using functions derived from Eric Youngdale's scsiinfo 00061 * program here for dealing with parts of SCSI commands. 00062 */ 00063 00064 static inline void 00065 setbitfield (unsigned char *pageaddr, int mask, int shift, int val) 00066 { 00067 *pageaddr = (*pageaddr & ~(mask << shift)) | ((val & mask) << shift); 00068 } 00069 00070 static inline void 00071 resetbitfield (unsigned char *pageaddr, int mask, int shift, int val) 00072 { 00073 *pageaddr = (*pageaddr & ~(mask << shift)) | (((!val) & mask) << shift); 00074 } 00075 00076 static inline int 00077 getbitfield (unsigned char *pageaddr, int mask, int shift) 00078 { 00079 return ((*pageaddr >> shift) & mask); 00080 } 00081 00082 /* ------------------------------------------------------------------------- */ 00083 00084 static inline int 00085 getnbyte (unsigned char *pnt, int nbytes) 00086 { 00087 unsigned int result = 0; 00088 int i; 00089 00090 for (i = 0; i < nbytes; i++) 00091 result = (result << 8) | (pnt[i] & 0xff); 00092 return result; 00093 } 00094 00095 /* ------------------------------------------------------------------------- */ 00096 00097 static inline int 00098 getnbyte1 (unsigned char *pnt, int nbytes) 00099 { 00100 unsigned int result = 0; 00101 int i; 00102 00103 for (i = nbytes - 1; i >= 0; i--) 00104 result = (result << 8) | (pnt[i] & 0xff); 00105 return result; 00106 } 00107 00108 /* ------------------------------------------------------------------------- */ 00109 00110 static inline void 00111 putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes) 00112 { 00113 int i; 00114 00115 for (i = nbytes - 1; i >= 0; i--) 00116 { 00117 pnt[i] = value & 0xff; 00118 value = value >> 8; 00119 } 00120 } 00121 00122 00123 /* ------------------------------------------------------------------------- */ 00124 00125 static inline void 00126 putnbyte1 (unsigned char *pnt, unsigned int value, unsigned int nbytes) 00127 { 00128 unsigned int i; 00129 00130 for (i = 0; i < nbytes; i++) 00131 { 00132 pnt[i] = value & 0xff; 00133 value = value >> 8; 00134 } 00135 } 00136 00137 00138 /* --------------------------------------------------------------------------------------------------------- */ 00139 00140 00141 /* Not all of these are defined in scsi.h, so we'll make sure 00142 * we agree about them here... 00143 */ 00144 #define TEST_UNIT_READY 0x00 00145 #define REQUEST_SENSE 0x03 00146 #define INQUIRY 0x12 00147 #define RESERVE_UNIT 0x16 00148 #define RELEASE_UNIT 0x17 00149 #define SCAN 0x1B 00150 #define READ 0x08 00151 #define WRITE 0x0A 00152 #define PARAM 0x0F 00153 #define MODE 0x15 00154 00155 /* --------------------------------------------------------------------------------------------------------- */ 00156 00157 00158 #define STD_WDB_LEN 0x28 /* wdb_len if nothing is set by inquiry */ 00159 00160 00161 /* --------------------------------------------------------------------------------------------------------- */ 00162 00163 00164 /* SCSI commands */ 00165 00166 typedef struct 00167 { 00168 unsigned char *cmd; 00169 size_t size; 00170 } scsiblk; 00171 00172 00173 /* --------------------------------------------------------------------------------------------------------- */ 00174 00175 00176 #define set_inquiry_return_size(icb,val) icb[0x04]=val 00177 static unsigned char inquiryC[] = { INQUIRY, 0x00, 0x00, 0x00, 0x7c, 0x00 }; 00178 static scsiblk inquiry = { inquiryC, sizeof (inquiryC) }; 00179 00180 00181 /* --------------------------------------------------------------------------------------------------------- */ 00182 00183 00184 #define get_inquiry_periph_qual(in) getbitfield(in, 0x07, 5) 00185 # define IN_periph_qual_lun 0x00 00186 # define IN_periph_qual_nolun 0x03 00187 #define get_inquiry_periph_devtype(in) getbitfield(in, 0x1f, 0) 00188 # define IN_periph_devtype_scanner 0x06 00189 # define IN_periph_devtype_unknown 0x1f 00190 00191 #define get_inquiry_rmb(in) getbitfield(in + 0x01, 0x01, 7) 00192 #define get_inquiry_0x01_bit6(in) getbitfield(in + 0x01, 0x01, 6) 00193 #define get_inquiry_0x01_bit5(in) getbitfield(in + 0x01, 0x01, 5) 00194 00195 #define get_inquiry_iso_version(in) getbitfield(in + 0x02, 0x03, 6) 00196 #define get_inquiry_ecma_version(in) getbitfield(in + 0x02, 0x07, 3) 00197 #define get_inquiry_ansi_version(in) getbitfield(in + 0x02, 0x07, 0) 00198 00199 #define get_inquiry_aenc(in) getbitfield(in + 0x03, 0x01, 7) 00200 #define get_inquiry_tmiop(in) getbitfield(in + 0x03, 0x01, 6) 00201 #define get_inquiry_0x03_bit5(in) getbitfield(in + 0x03, 0x01, 5) 00202 #define get_inquiry_0x03_bit4(in) getbitfield(in + 0x03, 0x01, 4) 00203 #define get_inquiry_response_format(in) getbitfield(in + 0x03, 0x0f, 0) 00204 # define IN_recognized 0x02 00205 00206 #define get_inquiry_additional_length(in) in[0x04] 00207 #define set_inquiry_length(out,n) out[0x04]=n-5 00208 00209 #define get_inquiry_vendor(in, buf) strncpy(buf, in + 0x08, 0x08) 00210 #define get_inquiry_product(in, buf) strncpy(buf, in + 0x10, 0x010) 00211 #define get_inquiry_version(in, buf) strncpy(buf, in + 0x20, 0x04) 00212 #define dup_inquiry_vendor(in) strndup(in + 0x08, 0x08) 00213 #define dup_inquiry_product(in) strndup(in + 0x10, 0x010) 00214 #define dup_inquiry_version(in) strndup(in + 0x20, 0x04) 00215 00216 #define get_inquiry_max_x_res(in) getnbyte1(in + 0x24, 2) 00217 #define get_inquiry_max_y_res(in) getnbyte1(in + 0x26, 2) 00218 #define get_inquiry_fb_max_scan_width(in) getnbyte1(in + 0x28, 2) 00219 #define get_inquiry_fb_max_scan_length(in) getnbyte1(in + 0x2a, 2) 00220 #define get_inquiry_filters(in) in[0x2c] 00221 #define get_inquiry_color_depths(in) in[0x2d] 00222 #define get_inquiry_color_format(in) in[0x2e] 00223 #define get_inquiry_image_format(in) in[0x30] 00224 #define get_inquiry_scan_capability(in) in[0x31] 00225 #define get_inquiry_optional_devices(in) in[0x32] 00226 #define get_inquiry_enhancements(in) in[0x33] 00227 #define get_inquiry_gamma_bits(in) in[0x34] 00228 #define get_inquiry_last_filter(in) in[0x35] 00229 #define get_inquiry_fast_preview_res(in) getnbyte1(in + 0x36, 2) 00230 #define get_inquiry_halftones(in) in[0x60] 00231 #define get_inquiry_halftone_max_width(in) in[0x61] 00232 #define get_inquiry_halftone_max_heighgt(in) in[0x62] 00233 #define get_inquiry_max_windows(in) in[0x63] 00234 #define get_inquiry_min_highlight(in) in[0x65] 00235 #define get_inquiry_max_shadow(in) in[0x66] 00236 #define get_inquiry_cal_eqn(in) in[0x67] 00237 #define get_inquiry_max_exp(in) getnbyte1(in + 0x68, 2) 00238 #define get_inquiry_min_exp(in) getnbyte1(in + 0x6a, 2) 00239 #define get_inquiry_trans_x1(in) getnbyte1(in + 0x6c, 2) 00240 #define get_inquiry_trans_y1(in) getnbyte1(in + 0x6e, 2) 00241 #define get_inquiry_trans_x2(in) getnbyte1(in + 0x70, 2) 00242 #define get_inquiry_trans_y2(in) getnbyte1(in + 0x72, 2) 00243 #define get_inquiry_model(in) in[0x74] 00244 00245 #define INQ_ONE_PASS_COLOR 0x80 00246 #define INQ_FILTER_IRED 0x10 00247 #define INQ_FILTER_BLUE 0x08 00248 #define INQ_FILTER_GREEN 0x04 00249 #define INQ_FILTER_RED 0x02 00250 #define INQ_FILTER_NEUTRAL 0x01 00251 00252 #define INQ_COLOR_DEPTH_16 0x20 00253 #define INQ_COLOR_DEPTH_12 0x10 00254 #define INQ_COLOR_DEPTH_10 0x08 00255 #define INQ_COLOR_DEPTH_8 0x04 00256 #define INQ_COLOR_DEPTH_4 0x02 00257 #define INQ_COLOR_DEPTH_1 0x01 00258 00259 #define INQ_COLOR_FORMAT_INDEX 0x04 00260 #define INQ_COLOR_FORMAT_LINE 0x02 00261 #define INQ_COLOR_FORMAT_PIXEL 0x01 00262 00263 #define INQ_IMG_FMT_OKLINE 0x08 00264 #define INQ_IMG_FMT_BLK_ONE 0x04 00265 #define INQ_IMG_FMT_MOTOROLA 0x02 00266 #define INQ_IMG_FMT_INTEL 0x01 00267 00268 #define INQ_CAP_PWRSAV 0x80 00269 #define INQ_CAP_EXT_CAL 0x40 00270 #define INQ_CAP_FAST_PREVIEW 0x10 00271 #define INQ_CAP_DISABLE_CAL 0x08 00272 #define INQ_CAP_SPEEDS 0x07 00273 00274 #define INQ_OPT_DEV_MPCL 0x80 00275 #define INQ_OPT_DEV_TP1 0x04 00276 #define INQ_OPT_DEV_TP 0x02 00277 #define INQ_OPT_DEV_ADF 0x01 00278 00279 #define INQ_ENHANCE_EDGE 0x02 00280 00281 #define INQ_LAST_FILTER_BLUE 0x08 00282 #define INQ_LAST_FILTER_GREEN 0x04 00283 #define INQ_LAST_FILTER_RED 0x02 00284 #define INQ_LAST_FILTER_NEUTRAL 0x01 00285 00286 #define INQ_DWNLD_HALFTONE 0x80 00287 #define INQ_NUM_HALFTONES 0x7f 00288 00289 00290 /* --------------------------------------------------------------------------------------------------------- */ 00291 00292 00293 static unsigned char test_unit_readyC[] = 00294 { TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00295 00296 static scsiblk test_unit_ready = 00297 { test_unit_readyC, sizeof (test_unit_readyC) }; 00298 00299 00300 /* --------------------------------------------------------------------------------------------------------- */ 00301 00302 00303 static unsigned char reserve_unitC[] = 00304 { RESERVE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00305 00306 static scsiblk reserve_unit = { reserve_unitC, sizeof (reserve_unitC) }; 00307 00308 00309 /* --------------------------------------------------------------------------------------------------------- */ 00310 00311 00312 static unsigned char release_unitC[] = 00313 { RELEASE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00314 00315 static scsiblk release_unit = { release_unitC, sizeof (release_unitC) }; 00316 00317 00318 /* --------------------------------------------------------------------------------------------------------- */ 00319 00320 00321 static unsigned char paramC[] = { PARAM, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00322 00323 static scsiblk param = { paramC, sizeof (paramC) }; 00324 00325 #define set_param_length(in, l) putnbyte(in + 3, (l), 2) 00326 00327 #define get_param_scan_width(b) getnbyte1(b, 2) 00328 #define get_param_scan_lines(b) getnbyte1(b + 2, 2) 00329 #define get_param_scan_bytes(b) getnbyte1(b + 4, 2) 00330 #define get_param_scan_filter_offset1(b) b[6] 00331 #define get_param_scan_filter_offset2(b) b[7] 00332 #define get_param_scan_period(b) getnbyte1(b + 8, 4) 00333 #define get_param_scsi_xfer_rate(b) getnbyte1(b + 12, 2) 00334 #define get_param_scan_available_lines(b) getnbyte1(b + 14, 2) 00335 00336 /* --------------------------------------------------------------------------------------------------------- */ 00337 00338 00339 static unsigned char writeC[] = { WRITE, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00340 00341 static scsiblk swrite = { writeC, sizeof (writeC) }; 00342 00343 #define set_write_length(in, l) putnbyte(in + 2, (l), 3) 00344 00345 00346 /* --------------------------------------------------------------------------------------------------------- */ 00347 00348 00349 static unsigned char modeC[] = { MODE, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00350 00351 static scsiblk smode = { modeC, sizeof (modeC) }; 00352 00353 #define set_mode_length(in, l) putnbyte(in + 3, (l), 2) 00354 00355 /* --------------------------------------------------------------------------------------------------------- */ 00356 00357 00358 static unsigned char scanC[] = { SCAN, 0x00, 0x00, 0x00, 0x01, 0x00 }; 00359 00360 static scsiblk scan = { scanC, sizeof (scanC) }; 00361 00362 #define set_scan_cmd(in, l) in[4] = l 00363 00364 /* --------------------------------------------------------------------------------------------------------- */ 00365 00366 00367 /* sread instead of read because read is a libc primitive */ 00368 static unsigned char sreadC[] = { READ, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00369 00370 static scsiblk sread = { sreadC, sizeof (sreadC) }; 00371 00372 #define set_read_length(in, l) putnbyte(in + 2, (l), 3) 00373 00374 /* --------------------------------------------------------------------------------------------------------- */ 00375 00376 static unsigned char request_senseC[] = 00377 { REQUEST_SENSE, 0x00, 0x00, 0x00, 0x00, 0x00 }; 00378 #define set_RS_allocation_length(sb,val) sb[0x04]=val 00379 #if 0 00380 #define set_RS_LUN(sb,val) setbitfield(sb + 0x01, 7, 5) /* ??? */ 00381 00382 static scsiblk request_sense = { request_senseC, sizeof (request_senseC) }; 00383 #endif 00384 00385 /* defines for request sense return block */ 00386 #define get_RS_information_valid(b) getbitfield(b + 0x00, 1, 7) 00387 #define get_RS_error_code(b) getbitfield(b + 0x00, 0x7f, 0) 00388 #define get_RS_filemark(b) getbitfield(b + 0x02, 1, 7) 00389 #define get_RS_EOM(b) getbitfield(b + 0x02, 1, 6) 00390 #define get_RS_ILI(b) getbitfield(b + 0x02, 1, 5) 00391 #define get_RS_sense_key(b) getbitfield(b + 0x02, 0x0f, 0) 00392 #define get_RS_information(b) getnbyte(b+0x03, 4) 00393 #define get_RS_additional_length(b) b[0x07] 00394 #define get_RS_ASC(b) b[0x0c] 00395 #define get_RS_ASCQ(b) b[0x0d] 00396 #define get_RS_SKSV(b) getbitfield(b+0x0f,1,7) /* valid */ 00397 #define get_RS_CD(b) getbitfield(b+0x0f,1,6) /* 1=CDB */ 00398 #define get_RS_field_pointer(b) getnbyte(b+0x10, 2) 00399 00400 #define get_RS_additional_sense(b) getnbyte(b+0x12, 2) 00401 00402 #define rs_return_block_size 0x1f 00403 00404 00405 /* --------------------------------------------------------------------------------------------------------- */ 00406 00407 00408 static char *sense_str[] = { "NO SENSE", 00409 "RECOVERED ERROR", 00410 "NOT READY", 00411 "MEDIUM ERROR", 00412 "HARDWARE ERROR", 00413 "ILLEGAL REQUEST", 00414 "UNIT ATTENTION", 00415 "DATA PROTECT", 00416 "BLANK CHECK", 00417 "VENDOR SPECIFIC", 00418 "COPY ABORTED", 00419 "ABORTED COMMAND", 00420 "EQUAL", 00421 "VOLUME OVERFLOW", 00422 "MISCOMPARE", 00423 "??? - SENSE 0FH" 00424 }; 00425 00426 /* --------------------------------------------------------------------------------------------------------- */ 00427 00428 /* command codes used in the data part of a SCSI write command */ 00429 00430 #define SET_POWER_SAVE_CONTROL 0x01 00431 #define DWNLD_GAMMA_TABLE 0x10 00432 #define DWNLD_HALFTONE 0x11 00433 #define SET_SCAN_FRAME 0x12 00434 #define SET_EXP_TIME 0x13 00435 #define SET_HIGHLIGHT_SHADOW 0x14 00436 #define SEND_CAL_DATA 0x16 00437 00438 #define READ_POWER_SAVE_CONTROL 0x81 00439 #define READ_GAMMA_TABLE 0x90 00440 #define READ_HALFTONE 0x91 00441 #define READ_SCAN_FRAME 0x92 00442 #define READ_EXP_TIME 0x93 00443 #define READ_HIGHLIGHT_SHADOW 0x94 00444 #define READ_CAL_INFO 0x95 00445 00446 00447 #define set_command(in, cmd) putnbyte1(in, cmd, 2) 00448 #define set_data_length(in, len) putnbyte1(in + 2, len, 2) 00449 #define set_data(in, ofs, val, num) putnbyte1(in + ofs, val, num) 00450 00451 00452 00453 #define FILTER_BLUE 0x08 00454 #define FILTER_GREEN 0x04 00455 #define FILTER_RED 0x02 00456 #define FILTER_NEUTRAL 0x01 00457 00458 /* --------------------------------------------------------------------------------------------------------- */ 00459 00460 /* apparently PIE specific extensions used for USB scanners */ 00461 00462 /* additional command codes and their representation */ 00463 00464 #define PIE_COPY 0x18 /* reads a block of 0x70 or 0x00s before image aquisition */ 00465 #define PIE_RELEASE_SCANNER 0xd2 /* written after image read, flush ? */ 00466 #define PIE_READ_CALIBRATION 0xd7 /* used before image aquisition, calibration */ 00467 #define PIE_WRITE_CALIBRATION 0xdc /* used before image aquisition, calibration */ 00468 #define PIE_READ_STATUS 0xdd /* read 11 bytes of status, e.g. button */ 00469 00470 00471 static unsigned char pie_copyC[] = { PIE_COPY, 0x00, 0x00, 0x14, 0xdc, 0x00 }; 00472 static unsigned char release_scanC[] = 00473 { PIE_RELEASE_SCANNER, 0x00, 0x00, 0x00, 0x04, 0x00 }; 00474 static unsigned char read_calibrationC[] = 00475 { PIE_READ_CALIBRATION, 0x00, 0x00, 0x00, 0x67, 0x00 }; 00476 static unsigned char write_calibrationC[] = 00477 { PIE_WRITE_CALIBRATION, 0x00, 0x00, 0x00, 0x17, 0x00 }; 00478 static unsigned char read_statusC[] = 00479 { PIE_READ_STATUS, 0x00, 0x00, 0x00, 0x0b, 0x00 }; 00480 00481 #endif 00482