piuspatch  v0.1
USB addition to PIE backend
only-pie/backend/pie-scsidef.h
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines