here goes nothing- release updated backend. lets see who screams :)

merge-requests/1/head
m. allan noah 2006-05-14 15:29:08 +00:00
rodzic 97b8366fc3
commit 4cf409d452
6 zmienionych plików z 4409 dodań i 7788 usunięć

Wyświetl plik

@ -1,3 +1,8 @@
2006-05-14 m. allan noah <anoah AT pfeiffer DOT edu>
* backend/fujitsu*: rewritten backend, supports many more scanners
with much better usb support and less model-specific code.
* doc/sane-fujitsu.man: updated to match new backend.
2006-05-12 m. allan noah <anoah AT pfeiffer DOT edu>
* doc/descriptions/fujitsu.desc: updated with all known scanners
by fujitsu. Most now supported as 'basic'.

Wyświetl plik

@ -9,6 +9,16 @@
/****************************************************/
#define USB_COMMAND_CODE 0x43
#define USB_COMMAND_LEN 0x1F
#define USB_COMMAND_OFFSET 0x13
#define USB_COMMAND_TIME 1000
#define USB_DATA_TIME 1000
#define USB_STATUS_CODE 0x53
#define USB_STATUS_LEN 0x0D
#define USB_STATUS_OFFSET 0x09
#define USB_STATUS_TIME 3000
/*static inline void */
static void
setbitfield (unsigned char *pageaddr, int mask, int shift, int val)
@ -99,7 +109,7 @@ scsiblk;
#define SCAN 0x1b
#define IMPRINTER 0xc1
#define HW_STATUS 0xc2
#define RESET_UNIT 0xf1
#define SCANNER_CONTROL 0xf1
/* ==================================================================== */
@ -116,9 +126,16 @@ static scsiblk release_unitB = { release_unitC, sizeof (release_unitC) };
/* ==================================================================== */
static unsigned char reset_unitC[] =
{ RESET_UNIT, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static scsiblk reset_unitB = { reset_unitC, sizeof (reset_unitC) };
static unsigned char scanner_controlC[] =
{ SCANNER_CONTROL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static scsiblk scanner_controlB = { scanner_controlC, sizeof (scanner_controlC) };
#define set_SC_function(icb, val) setbitfield(icb + 1, 7, 0, val)
#define SC_function_cancel 0x04
#define SC_function_lamp_on 0x05
#define SC_function_lamp_off 0x03
#define SC_function_lamp_normal 0x06
#define SC_function_lamp_saving 0x07
/* ==================================================================== */
@ -143,9 +160,12 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
#define get_IN_product(in, buf) strncpy(buf, in + 0x10, 0x010)
#define get_IN_version(in, buf) strncpy(buf, in + 0x20, 0x04)
#define get_IN_raster(in) getnbyte (in+0x2A, 2) /* offset between colors */
#define get_IN_frontback(in) getnbyte (in+0x2E, 2) /* offset between front and back for duplex */
#define get_IN_duplex_3091(in) getnbyte (in+0x2D, 1) /* duplex available */
/* these two only in some scanners */
#define get_IN_duplex_3091(in) getnbyte (in+0x2D, 1) /* duplex available */
#define get_IN_frontback(in) getnbyte (in+0x2E, 2) /* offset between front and back for duplex */
/* the VPD response */
#define get_IN_page_length(in) getnbyte(in + 0x04, 1)
#define get_IN_basic_x_res(in) getnbyte(in + 0x05, 2)
#define get_IN_basic_y_res(in) getnbyte(in + 0x07, 2)
@ -180,23 +200,37 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
#define get_IN_monochrome_rgb(in) getbitfield(in+0x1c, 1, 5)
#define get_IN_half_tone_rgb(in) getbitfield(in+0x1c, 1, 6)
#define get_IN_multilevel_rgb(in) getbitfield(in+0x1c, 1, 7)
/* vendor unique section */
#define get_IN_operator_panel(in) getbitfield(in+0x20, 1, 1)
#define get_IN_barcode(in) getbitfield(in+0x20, 1, 2)
#define get_IN_endorser(in) getbitfield(in+0x20, 1, 3)
#define get_IN_imprinter(in) getbitfield(in+0x20, 1, 3)
#define get_IN_duplex(in) getbitfield(in+0x20, 1, 4)
#define get_IN_trancepareny(in) getbitfield(in+0x20, 1, 5)
#define get_IN_transparency(in) getbitfield(in+0x20, 1, 5)
#define get_IN_flatbed(in) getbitfield(in+0x20, 1, 6)
#define get_IN_adf(in) getbitfield(in+0x20, 1, 7)
#define get_IN_adbits(in) getbitfield(in+0x21, 0x0f, 0)
#define get_IN_buffer_bytes(in) getnbyte(in + 0x22, 4)
#define get_IN_has_set_subwindow(in) (getnbyte(in+0x2a, 2)) & 1
#define get_IN_has_imprinter(in) (getnbyte(in+0x2a, 2)) & 2
#define get_IN_has_hw_status(in) (getnbyte(in+0x2a, 2)) & 4
/* more stuff here (std supported commands) */
#define get_IN_has_subwindow(in) getbitfield(in+0x2b, 1, 0)
#define get_IN_has_endorser(in) getbitfield(in+0x2b, 1, 1)
#define get_IN_has_hw_status(in) getbitfield(in+0x2b, 1, 2)
#define get_IN_has_scanner_ctl(in) getbitfield(in+0x31, 1, 1)
#define get_IN_brightness_steps(in) getnbyte(in+0x52, 1)
#define get_IN_threshold_steps(in) getnbyte(in+0x53, 1)
#define get_IN_contrast_steps(in) getnbyte(in+0x54, 1)
#define get_IN_num_gamma(in) getbitfield(in+0x57, 15, 4)
#define get_IN_num_dither_internal(in) getbitfield(in+0x56, 15, 4)
#define get_IN_num_dither_download(in) getbitfield(in+0x56, 15, 0)
#define get_IN_num_gamma_internal(in) getbitfield(in+0x57, 15, 4)
#define get_IN_num_gamma_download(in) getbitfield(in+0x57, 15, 0)
#define get_IN_ipc_bw_reverse(in) getbitfield(in+0x58, 1, 7)
#define get_IN_ipc_bw_rif(in) getbitfield(in+0x58, 1, 7)
#define get_IN_ipc_auto1(in) getbitfield(in+0x58, 1, 6)
#define get_IN_ipc_auto2(in) getbitfield(in+0x58, 1, 5)
#define get_IN_ipc_outline_extraction(in) getbitfield(in+0x58, 1, 4)
@ -204,8 +238,10 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
#define get_IN_ipc_auto_separation(in) getbitfield(in+0x58, 1, 2)
#define get_IN_ipc_mirroring(in) getbitfield(in+0x58, 1, 1)
#define get_IN_ipc_white_level_follow(in) getbitfield(in+0x58, 1, 0)
#define get_IN_ipc_subwindow(in) getbitfield(in+0x59, 1, 7)
#define get_IN_ipc_error_diffusion(in) getbitfield(in+0x59, 1, 6)
#define get_IN_compression_MH(in) getbitfield(in+0x5a, 1, 7)
#define get_IN_compression_MR(in) getbitfield(in+0x5a, 1, 6)
#define get_IN_compression_MMR(in) getbitfield(in+0x5a, 1, 5)
@ -213,9 +249,10 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
#define get_IN_compression_JPG_BASE(in) getbitfield(in+0x5a, 1, 3)
#define get_IN_compression_JPG_EXT(in) getbitfield(in+0x5a, 1, 2)
#define get_IN_compression_JPG_INDEP(in) getbitfield(in+0x5a, 1, 1)
#define get_IN_imprinter(in) getbitfield(in+0x5c, 1, 7)
#define get_IN_imprinter_stamp(in) getbitfield(in+0x5c, 1, 6)
#define get_IN_imprinter_electrical(in) getbitfield(in+0x5c, 1, 5)
#define get_IN_imprinter2(in) getbitfield(in+0x5c, 1, 7)
#define get_IN_imprinter2_stamp(in) getbitfield(in+0x5c, 1, 6)
#define get_IN_imprinter2_electrical(in) getbitfield(in+0x5c, 1, 5)
/* ==================================================================== */
@ -230,16 +267,6 @@ static unsigned char set_windowC[] =
{ SET_WINDOW, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
/* opcode, lun, _____4 X reserved____, transfer length, control byte */
static scsiblk set_windowB = { set_windowC, sizeof (set_windowC) };
#define set_SW_xferlen(sb, len) putnbyte(sb + 0x06, len, 3)
/* With the fi-series scanners, we have to use a 12-byte command
* instead of a 10-byte command when communicating via USB. This
* may be a firmware bug. */
static unsigned char set_usb_windowC[] =
{ SET_WINDOW, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00 };
/* opcode, lun, _____4 X reserved____, transfer length, control byte */
static scsiblk set_usb_windowB = { set_usb_windowC, sizeof (set_usb_windowC) };
#define set_SW_xferlen(sb, len) putnbyte(sb + 0x06, len, 3)
/* ==================================================================== */
@ -252,7 +279,7 @@ static scsiblk object_positionB =
#define set_OP_autofeed(b,val) setbitfield(b+0x01, 0x07, 0, val)
#define OP_Discharge 0x00
#define OP_Feed 0x01
#define OP_Feed 0x01
/* ==================================================================== */
@ -381,75 +408,107 @@ static scsiblk mode_selectB = { mode_selectC, sizeof (mode_selectC) };
#define set_MSEL_xfer_length(sb, val) sb[0x04] = (unsigned char)val
static unsigned char mode_select_headerC[] = {
0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_headerB = {
mode_select_headerC, sizeof (mode_select_headerC)
};
/* With the fi-series scanners, we have to use a 10-byte header
* instead of a 4-byte header when communicating via USB. This
* may be a firmware bug. */
static unsigned char mode_select_usb_headerC[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_usb_headerB = {
mode_select_usb_headerC, sizeof (mode_select_usb_headerC)
};
static unsigned char mode_select_parameter_blockC[] = {
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00
};
static scsiblk mode_select_parameter_blockB =
{ mode_select_parameter_blockC, sizeof (mode_select_parameter_blockC) };
#define set_MSEL_len(sb, len) putnbyte(sb + 0x01, len, 1)
/*
* PageCode:
/* combined 4 byte header and 8 byte page
* PageCodes: (most scanners know a few of these)
* 0x34 = Sleep mode
* 0x35 = ADF duplex reading transfer mode
* 0x36 = All sorts of device controls switching
* 0x37 = Backing switch control
* 0x38 = Double feed detection
* 0x39 = Drop out color
* 0x3c = Paper width, paper length detection, deskew
* 0x3c = Auto paper size detection
* 0x3d = Lamp light timer set
* 0x3e = Special-purpose paper detection mode
* 0x3e = Detect job separation sheet
* there is also possibly a 'descriptor block'
* and a 'vendor-specific block'
* fujitsu's seem not to use these two
*/
#define set_MSEL_pagecode(sb, val) setbitfield(sb, 0x3f, 0, val)
#define MSEL_sleep 0x34
#define MSEL_transfer_mode 0x35
#define MSEL_dropout_color 0x39
static unsigned char mode_select_sleepC[] = {
0x00, 0x00, 0x00, 0x00,
0x34, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_sleepB = {
mode_select_sleepC, sizeof (mode_select_sleepC)
};
/* time until the device internal power supply switches to Sleep Mode
* 0 = Default (15 min)
* 1 = 1 min
* 2 = 2 min
* 0x3c ..0xff = 60 min
*/
#define set_MSEL_sleep_mode(sb, val) setbitfield(sb + 0x02, 0x0f, 0, val)
#define set_MSEL_sleep_mode(sb, val) sb[0x06]=val
static unsigned char mode_select_duplexC[] = {
0x00, 0x00, 0x00, 0x00,
0x35, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_duplexB = {
mode_select_duplexC, sizeof (mode_select_duplexC)
};
/* adf duplex reading transfer method
* 0 = front side - back side sequential transfer
* 1 = front side - back side alternate transfer
*/
#define set_MSEL_transfer_mode(sb, val) setbitfield(sb + 0x02, 0x01, 0, val)
#define set_MSEL_dropout_front(sb, val) setbitfield(sb + 0x02, 0x0f, 0, val)
#define set_MSEL_dropout_back(sb, val) setbitfield(sb + 0x02, 0x0f, 4, val)
static unsigned char mode_select_randC[] = {
0x00, 0x00, 0x00, 0x00,
0x36, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_randB = {
mode_select_randC, sizeof (mode_select_randC)
};
static unsigned char mode_select_backingC[] = {
0x00, 0x00, 0x00, 0x00,
0x37, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_backingB = {
mode_select_backingC, sizeof (mode_select_backingC)
};
/*byte 0x06 is bitmask controlling double feed detection*/
static unsigned char mode_select_dfeedC[] = {
0x00, 0x00, 0x00, 0x00,
0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_dfeedB = {
mode_select_dfeedC, sizeof (mode_select_dfeedC)
};
/*byte 0x06 is bitmask controlling monochrome color*/
static unsigned char mode_select_dropoutC[] = {
0x00, 0x00, 0x00, 0x00,
0x39, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_dropoutB = {
mode_select_dropoutC, sizeof (mode_select_dropoutC)
};
#define set_MSEL_dropout_front(sb, val) setbitfield(sb + 0x06, 0x0f, 0, val)
#define set_MSEL_dropout_back(sb, val) setbitfield(sb + 0x06, 0x0f, 4, val)
#define MSEL_dropout_DEFAULT 0
#define MSEL_dropout_GREEN 8
#define MSEL_dropout_RED 9
#define MSEL_dropout_BLUE 11
#define MSEL_dropout_CUSTOM 12
/* ==================================================================== */
/*bytes 0x06-07 and 0x09 control paper size detection*/
static unsigned char mode_select_autoC[] = {
0x00, 0x00, 0x00, 0x00,
0x3C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_autoB = {
mode_select_autoC, sizeof (mode_select_autoC)
};
static unsigned char mode_select_lampC[] = {
0x00, 0x00, 0x00, 0x00,
0x3D, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static scsiblk mode_select_lampB= {
mode_select_lampC, sizeof (mode_select_lampC)
};
/* ==================================================================== */
#if 0
@ -478,37 +537,44 @@ static scsiblk hw_statusB = { hw_statusC, sizeof (hw_statusC) };
#define set_HW_allocation_length(sb, len) putnbyte(sb + 0x07, len, 2)
#define get_HW_B5_present(in) getbitfield(in+0x02, 1, 0)
#define get_HW_A4_present(in) getbitfield(in+0x02, 1, 1)
#define get_HW_B4_present(in) getbitfield(in+0x02, 1, 2)
#define get_HW_A3_present(in) getbitfield(in+0x02, 1, 3)
#define get_HW_adf_empty(in) getbitfield(in+0x03, 1, 7)
#define get_HW_omr(in) getbitfield(in+0x03, 1, 6)
#define get_HW_adfc_open(in) getbitfield(in+0x03, 1, 5)
#define get_HW_sleep(in) getbitfield(in+0x04, 1, 7)
#define get_HW_manual_feed(in) getbitfield(in+0x04, 1, 1)
#define get_HW_start_button(in) getbitfield(in+0x04, 1, 0)
#define get_HW_ink_empty(in) getbitfield(in+0x06, 1, 7)
#define get_HW_dfeed_detected(in) getbitfield(in+0x06, 1, 0)
#define get_HW_skew_angle(in) getnbyte(in+0x08, 2)
#define get_HW_top(in) getbitfield(in+0x02, 1, 7)
#define get_HW_A3(in) getbitfield(in+0x02, 1, 3)
#define get_HW_B4(in) getbitfield(in+0x02, 1, 2)
#define get_HW_A4(in) getbitfield(in+0x02, 1, 1)
#define get_HW_B5(in) getbitfield(in+0x02, 1, 0)
#define get_HW_hopper(in) !getbitfield(in+0x03, 1, 7)
#define get_HW_omr(in) getbitfield(in+0x03, 1, 6)
#define get_HW_adf_open(in) getbitfield(in+0x03, 1, 5)
#define get_HW_sleep(in) getbitfield(in+0x04, 1, 7)
#define get_HW_send_sw(in) getbitfield(in+0x04, 1, 2)
#define get_HW_manual_feed(in) getbitfield(in+0x04, 1, 1)
#define get_HW_scan_sw(in) getbitfield(in+0x04, 1, 0)
#define get_HW_function(in) getbitfield(in+0x05, 0x0f, 0)
#define get_HW_ink_empty(in) getbitfield(in+0x06, 1, 7)
#define get_HW_double_feed(in) getbitfield(in+0x06, 1, 0)
#define get_HW_error_code(in) in[0x07]
#define get_HW_skew_angle(in) getnbyte(in+0x08, 2)
#define get_HW_ink_remain(in) in[0x0a]
/* ==================================================================== */
/* We use the same structure for both SET WINDOW and GET WINDOW. */
static unsigned char window_parameter_data_blockC[] = {
static unsigned char window_descriptor_headerC[] = {
0x00, 0x00, 0x00,
0x00, 0x00, 0x00, /* reserved */
0x00, 0x00, /* Window Descriptor Length */
};
static scsiblk window_parameter_data_blockB =
{ window_parameter_data_blockC, sizeof (window_parameter_data_blockC) };
static scsiblk window_descriptor_headerB=
{ window_descriptor_headerC, sizeof (window_descriptor_headerC) };
#define set_WPDB_wdblen(sb, len) putnbyte(sb + 0x06, len, 2)
#define used_WDB_size 0x60
#define max_WDB_size 0xff
/* ==================================================================== */
static unsigned char window_descriptor_blockC[] = {
@ -617,7 +683,9 @@ static unsigned char window_descriptor_blockC[] = {
#define WD_comp_LA 0
#define WD_comp_HT 1
#define WD_comp_GS 2
#define WD_comp_RC 5
#define WD_comp_CL 3
#define WD_comp_CH 4
#define WD_comp_CG 5
/* 0x1a - Depth
* 3091 - use 0x01 for b/w or 0x08 for gray/color
@ -694,7 +762,7 @@ static unsigned char window_descriptor_blockC[] = {
* 3091 - use 0xc0
* 3096 - use 0xc0
*/
0xC0,
0x00,
#define set_WD_vendor_id_code(sb, val) sb[0x28] = val
#define get_WD_vendor_id_code(sb) sb[0x28]
@ -757,10 +825,10 @@ static unsigned char window_descriptor_blockC[] = {
#define get_WD_mirroring(sb) getbitfield(sb + 0x2d, 1, 7)
#define set_WD_lamp_color(sb, val) sb[0x2d] = val
#define get_WD_lamp_color(sb) sb[0x2d]
#define LAMP_DEFAULT 0x00
#define LAMP_BLUE 0x01
#define LAMP_RED 0x02
#define LAMP_GREEN 0x04
#define WD_LAMP_DEFAULT 0x00
#define WD_LAMP_BLUE 0x01
#define WD_LAMP_RED 0x02
#define WD_LAMP_GREEN 0x04
/* 0x2e - variance/bit padding
* 3091 - unsupported, use 0x00
@ -828,13 +896,27 @@ static unsigned char window_descriptor_blockC[] = {
#define set_WD_subwindow_list(sb, val) putnbyte(sb + 0x33, val, 2)
#define get_WD_subwindow_list(sb) getnbyte(sb + 0x33, 2)
/* 0x35 - paper size
/* 0x35 - paper size
* 3091 unsupported, always use 0xc0
* 3096 if bits 6-7 both set, custom paper size enabled,
* bytes 0x36-0x3d used. Otherwise, a number of
* valid fixed values denote common paper formats.
*/
0xC0,
#define set_WD_paper_selection(sb, val) setbitfield(sb + 0x35, 3, 6, val)
#define WD_paper_SEL_UNDEFINED 0
#define WD_paper_SEL_NON_STANDARD 3
/* we no longer use these, custom size (0xc0) overrides,
and more recent scanners only use custom size anyway
#define get_WD_paper_selection(sb) getbitfield(sb + 0x35, 3, 6)
#define WD_paper_SEL_STANDARD 2
#define set_WD_paper_orientation(sb, val) setbitfield(sb + 0x35, 1, 4, val)
#define get_WD_paper_orientation(sb) getbitfield(sb + 0x35, 1, 4)
#define WD_paper_PORTRAIT 0
#define WD_paper_LANDSCAPE 1
#define set_WD_paper_size(sb, val) setbitfield(sb + 0x35, 0x0f, 0, val)
#define get_WD_paper_size(sb) getbitfield(sb + 0x35, 0x0f, 0)
#define WD_paper_UNDEFINED 0
@ -847,15 +929,7 @@ static unsigned char window_descriptor_blockC[] = {
#define WD_paper_B5 13
#define WD_paper_LEGAL 15
#define WD_paper_CUSTOM 14
#define set_WD_paper_orientation(sb, val) setbitfield(sb + 0x35, 1, 4, val)
#define get_WD_paper_orientation(sb) getbitfield(sb + 0x35, 1, 4)
#define WD_paper_PORTRAIT 0
#define WD_paper_LANDSCAPE 1
#define set_WD_paper_selection(sb, val) setbitfield(sb + 0x35, 3, 6, val)
#define get_WD_paper_selection(sb) getbitfield(sb + 0x35, 3, 6)
#define WD_paper_SEL_UNDEFINED 0
#define WD_paper_SEL_STANDARD 2
#define WD_paper_SEL_NON_STANDARD 3
*/
/* 0x36-0x39 - custom paper width
* 3091 0<w<=10200
@ -905,28 +979,18 @@ static unsigned char window_descriptor_blockC[] = {
0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5c reserved */
0x00, 0x00, 0x00 /* 0x5d - 0x5f reserved */
};
static scsiblk window_descriptor_blockB =
{ window_descriptor_blockC, sizeof (window_descriptor_blockC) };
#define max_WDB_size 0xc8
/* ==================================================================== */
/*#define set_WDB_length(length) (window_descriptor_block.size = (length)) */
#define WPDB_OFF(b) (b + set_window.size)
#define WDB_OFF(b, n) (b + set_window.size + \
window_parameter_data_block.size + \
( window_descriptor_block.size * (n - 1) ) )
#define set_WPDB_wdbnum(sb,n) set_WPDB_wdblen(sb,window_descriptor_block.size*n)
#define RS_return_size 0x12
/* ==================================================================== */
static unsigned char request_senseC[] =
{REQUEST_SENSE, 0x00, 0x00, 0x00, RS_return_size, 0x00};
static scsiblk request_senseB = {request_senseC, sizeof (request_senseC)};
static unsigned char request_senseC[] =
{REQUEST_SENSE, 0x00, 0x00, 0x00, 0x12, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static scsiblk request_senseB =
{request_senseC, sizeof (request_senseC)};
#define set_RS_allocation_length(sb,val) sb[0x04] = (unsigned char)val
/* defines for request sense return block */
#define get_RS_information_valid(b) getbitfield(b + 0x00, 1, 7)
#define get_RS_error_code(b) getbitfield(b + 0x00, 0x7f, 0)
@ -938,12 +1002,24 @@ static scsiblk window_descriptor_blockB =
#define get_RS_additional_length(b) b[0x07] /* always 10 */
#define get_RS_ASC(b) b[0x0c]
#define get_RS_ASCQ(b) b[0x0d]
#define get_RS_SKSV(b) getbitfield(b+0x0f,1,7) /* valid, always 0 */
#define get_RS_SKSV(b) getbitfield(b+0x0f,1,7) /* valid=0 */
#define get_RS_SKSB(b) getnbyte(b+0x0f, 3)
/* when RS is 0x05/0x26 bad bytes listed in sksb */
#define get_RS_offending_byte(b) getnbyte(b+0x10, 2)
#define rs_return_block_size 18 /* Says Nikon */
/* 3091 and 3092 use RS instead of ghs. RS must be 0x00/0x80 */
/* in ascq */
#define get_RS_adf_open(in) getbitfield(in+0x0d, 1, 7)
#define get_RS_send_sw(in) getbitfield(in+0x0d, 1, 5)
#define get_RS_scan_sw(in) getbitfield(in+0x0d, 1, 4)
#define get_RS_duplex_sw(in) getbitfield(in+0x0d, 1, 2)
#define get_RS_top(in) getbitfield(in+0x0d, 1, 1)
#define get_RS_hopper(in) getbitfield(in+0x0d, 1, 0)
/* ==================================================================== */
/* in sksb */
#define get_RS_function(in) getbitfield(in+0x0f, 0x0f, 3)
#define get_RS_density(in) getbitfield(in+0x0f, 0x07, 0)
/* ==================================================================== */

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,16 +1,25 @@
# NOTE: any 'option' lines must come first
# to override data buffer size, in bytes
# if unset, the backend will figure it out.
# the value ranges from 4096 - infinity
# but will likely not work above 32768
# dont use this unless you KNOW you need it
#option scsi-buffer-size 32768
# To search for all FUJITSU scsi devices
scsi FUJITSU
# To use a specific scsi device
#/dev/sg1
#scsi /dev/sg1
# For Fujitsu scanners connected via USB on a known device (kernel driver):
#usb /dev/usb/scanner0
# For Fujitsu scanners connected via USB using vendor and device ids (libusb):
#usb 0x04c5 0x1042
#usb 0x04c5 0x1041
# To force the Fujitsu backend to treat all devices it finds as a certain type:
#option force-model fi-4340Cdi
usb 0x04c5 0x1042
usb 0x04c5 0x1041
usb 0x04c5 0x1097
usb 0x04c5 0x10e0
usb 0x04c5 0x10ae

Wyświetl plik

@ -3,15 +3,9 @@
/*
* Part of SANE - Scanner Access Now Easy.
*
* Please see opening comment in fujitsu.c
*/
/* ------------------------------------------------------------------------- */
static int num_devices = 0;
static struct fujitsu *first_dev;
/* -------------------------------------------------------------------------
* This option list has to contain all options for all scanners supported by
* this driver. If a certain scanner cannot handle a certain option, there's
@ -22,410 +16,389 @@ enum fujitsu_Option
OPT_NUM_OPTS = 0,
OPT_MODE_GROUP,
OPT_SOURCE,
OPT_MODE,
OPT_DUPLEX,
OPT_X_RES,
OPT_Y_RES,
OPT_SOURCE, /*fb/adf/front/back/duplex*/
OPT_MODE, /*mono/gray/color*/
OPT_X_RES, /*a range or a list*/
OPT_Y_RES, /*a range or a list*/
OPT_GEOMETRY_GROUP,
OPT_TL_X, /* in mm/2^16 */
OPT_TL_Y, /* in mm/2^16 */
OPT_BR_X, /* in mm/2^16 */
OPT_BR_Y, /* in mm/2^16 */
OPT_TL_X,
OPT_TL_Y,
OPT_BR_X,
OPT_BR_Y,
OPT_PAGE_WIDTH,
OPT_PAGE_HEIGHT,
OPT_ENHANCEMENT_GROUP,
OPT_AVERAGING,
OPT_BRIGHTNESS,
OPT_THRESHOLD,
OPT_CONTRAST,
OPT_RIF,
OPT_COMPRESSION,
OPT_COMPRESSION_ARG,
OPT_DTC_SELECTION,
OPT_GAMMA,
OPT_OUTLINE_EXTRACTION,
OPT_EMPHASIS,
OPT_AUTOSEP,
OPT_MIRROR_IMAGE,
OPT_VARIANCE_RATE,
OPT_THRESHOLD_CURVE,
OPT_GRADATION,
OPT_SMOOTHING_MODE,
OPT_FILTERING,
OPT_BACKGROUND,
OPT_NOISE_REMOVAL,
OPT_MATRIX2X2,
OPT_MATRIX3X3,
OPT_MATRIX4X4,
OPT_MATRIX5X5,
OPT_WHITE_LEVEL_FOLLOW,
OPT_PAPER_SIZE,
OPT_PAPER_WIDTH,
OPT_PAPER_HEIGHT,
OPT_PAPER_ORIENTATION,
OPT_ADVANCED_GROUP,
OPT_DROPOUT_COLOR,
OPT_START_BUTTON,
OPT_TUNING_GROUP,
OPT_LAMP_COLOR,
OPT_SLEEP_TIME,
OPT_DUPLEX_OFFSET,
OPT_BLUE_OFFSET,
OPT_GREEN_OFFSET,
OPT_USE_SWAPFILE,
OPT_IMPRINTER_GROUP,
OPT_IMPRINTER,
OPT_IMPRINTER_DIR,
OPT_IMPRINTER_YOFFSET,
OPT_IMPRINTER_STRING,
OPT_IMPRINTER_CTR_INIT,
OPT_IMPRINTER_CTR_STEP,
OPT_IMPRINTER_CTR_DIR,
OPT_SLEEP_MODE,
OPT_SENSOR_GROUP,
OPT_TOP,
OPT_A3,
OPT_B4,
OPT_A4,
OPT_B5,
OPT_HOPPER,
OPT_OMR,
OPT_ADF_OPEN,
OPT_SLEEP,
OPT_SEND_SW,
OPT_MANUAL_FEED,
OPT_SCAN_SW,
OPT_FUNCTION,
OPT_INK_EMPTY,
OPT_DOUBLE_FEED,
OPT_ERROR_CODE,
OPT_SKEW_ANGLE,
OPT_INK_REMAIN,
OPT_DUPLEX_SW,
OPT_DENSITY_SW,
/* must come last: */
NUM_OPTIONS
};
typedef enum { /* hardware connection to the scanner */
SANE_FUJITSU_NODEV, /* default, no HW specified yet */
SANE_FUJITSU_SCSI, /* SCSI interface */
SANE_FUJITSU_PIO, /* parallel interface */
SANE_FUJITSU_USB /* USB interface */
} Fujitsu_Connection_Type;
struct fujitsu
{
/* --------------------------------------------------------------------- */
/* immutable values which are set during init of scanner. */
struct fujitsu *next;
char *device_name; /* The name of the scanner device for sane */
SANE_Option_Descriptor opt[NUM_OPTIONS];
Option_Value val[NUM_OPTIONS];
/* --------------------------------------------------------------------- */
/* immutable values which are set during reading of config file. */
int scsi_buf_size;
int connection; /* hardware interface type */
/* --------------------------------------------------------------------- */
/* immutable values which are set during inquiry probing of the scanner. */
/* members in order found in scsi data... */
SANE_Device sane;
/* Immutable values which are set during initial probing of the scanner. */
/* --------------------------------------------------------------------- */
char vendorName[9]; /* raw data as returned by SCSI inquiry. */
char productName[17]; /* raw data as returned by SCSI inquiry. */
char versionName[5]; /* raw data as returned by SCSI inquiry. */
int model; /* The scanner model. */
char *devicename; /* The name of the scanner device. */
Fujitsu_Connection_Type connection; /* hardware interface type */
int sfd; /* The scanner device file descriptor. */
char vendor_name[9]; /* raw data as returned by SCSI inquiry. */
char product_name[17]; /* raw data as returned by SCSI inquiry. */
char version_name[5]; /* raw data as returned by SCSI inquiry. */
int color_raster_offset; /* offset between r and b scan line and */
/* between b and g scan line (4 for all */
/* known models) */
int duplex_raster_offset; /* offset between front and rear page when */
/* when scanning duplex */
/* between b and g scan line (0 or 4) */
int duplex_raster_offset; /* offset between front and rear page when */
/* when scanning 3091 style duplex */
int can_read_alternate; /* duplex transfer mode front/back/front/back... */
int read_mode; /* constants READ_MODE_* and funcs convert_* */
int has_adf; /* true if an ADF has been detected. */
int has_fb;
int duplex_present; /* true if a duplex unit has been detected. */
int ipc_present; /* true if ipc2/3 option detected */
int cmp_present; /* true if cmp2 present */
int has_hw_status; /* true for M409X series */
int has_outline; /* ............ */
int has_emphasis; /* ............ */
int has_autosep; /* ............ */
int has_mirroring; /* ............ */
int has_reverse;
int has_white_level_follow; /* ............ */
int has_subwindow; /* ............ */
int has_dropout_color; /* */
/* --------------------------------------------------------------------- */
/* immutable values which are set during std VPD probing of the scanner. */
/* members in order found in scsi data... */
int basic_x_res;
int basic_y_res;
int step_x_res;
int step_y_res;
int max_x_res;
int max_y_res;
int min_x_res;
int min_y_res;
int std_res_200;
int std_res_180;
int std_res_160;
int std_res_150;
int std_res_120;
int std_res_100;
int std_res_75;
int std_res_60;
int std_res_1200;
int std_res_800;
int std_res_600;
int std_res_480;
int std_res_400;
int std_res_320;
int std_res_300;
int std_res_240;
/* max scan size in pixels comes from scanner in basic res units */
int max_x_basic;
int max_y_basic;
int can_overflow;
int can_monochrome;
int can_halftone;
int can_grayscale;
int can_color_monochrome;
int can_color_halftone;
int can_color_grayscale;
/* --------------------------------------------------------------------- */
/* immutable values which are set during vndr VPD probing of the scanner */
/* members in order found in scsi data... */
int has_operator_panel;
int has_barcode;
int has_imprinter;
int has_threshold;
int has_brightness;
int has_contrast;
int has_gamma;
int has_duplex;
int has_transparency;
int has_flatbed;
int has_adf;
int adbits;
int buffer_bytes;
/*FIXME: do we need the std cmd list? */
/*FIXME: there are more vendor cmds? */
int has_cmd_subwindow;
int has_cmd_endorser;
int has_cmd_hw_status;
int has_cmd_scanner_ctl;
/*FIXME: do we need the vendor window param list? */
int brightness_steps;
int threshold_steps;
int contrast_steps;
int num_internal_gamma;
int num_download_gamma;
int has_fixed_paper_size;
int num_internal_dither;
int num_download_dither;
SANE_Range adf_width_range;
SANE_Range adf_height_range;
SANE_Range x_range;
SANE_Range y_range;
int has_rif;
int has_auto1;
int has_auto2;
int has_outline;
int has_emphasis;
int has_autosep;
int has_mirroring;
int has_white_level_follow;
int has_subwindow;
int has_comp_MH;
int has_comp_MR;
int has_comp_MMR;
int has_comp_JBIG;
int has_comp_JPG1;
int has_comp_JPG2;
int has_comp_JPG3;
/*FIXME: endorser data? */
/*FIXME: barcode data? */
/* --------------------------------------------------------------------- */
/* immutable values which are hard coded because they are not in vpd */
/* this section replaces all the old 'switch (s->model)' code */
/* the scan size in 1/1200th inches, NOT basic_units or sane units */
int max_x;
int max_y;
int min_x;
int min_y;
int has_back; /* not all duplex scanners can do adf back side only */
int color_interlace; /* different models interlace colors differently */
int duplex_interlace; /* different models interlace sides differently */
int has_MS_dropout; /* dropout color specified in mode select data */
int has_SW_dropout; /* dropout color specified in set window data */
int window_vid; /* some models want different vendor ID in set window */
int ghs_in_rs;
int reverse_by_mode[6]; /* mode specific */
/* --------------------------------------------------------------------- */
/* changeable SANE_Option structs provide our interface to frontend. */
/* some options require lists of strings or numbers, we keep them here */
/* instead of in global vars so that they can differ for each scanner */
/* these are loaded in init_options(), but may be changed by other funcs */
/* long array of option structs */
SANE_Option_Descriptor opt[NUM_OPTIONS];
/*mode group*/
SANE_String_Const mode_list[7];
SANE_String_Const source_list[5];
SANE_Int x_res_list[17];
SANE_Int y_res_list[17];
SANE_Range x_res_range;
SANE_Range y_res_range;
SANE_Range x_grey_res_range;
SANE_Range y_grey_res_range;
SANE_String_Const vpd_mode_list[7];
SANE_String_Const compression_mode_list[9];
/*geometry group*/
SANE_Range tl_x_range;
SANE_Range tl_y_range;
SANE_Range br_x_range;
SANE_Range br_y_range;
SANE_Range paper_x_range;
SANE_Range paper_y_range;
SANE_Int x_res_list[17]; /* range of x and y resolution */
SANE_Int y_res_list[17]; /* if scanner has only fixed resolutions */
SANE_Int x_res_list_grey[17];
SANE_Int y_res_list_grey[17];
SANE_Range threshold_range;
/*enhancement group*/
SANE_Range brightness_range;
SANE_Range threshold_range;
SANE_Range contrast_range;
/* User settable values (usually mirrored in SANE options) */
/*ipc group*/
/*advanced group*/
SANE_String_Const do_color_list[5];
SANE_String_Const lamp_color_list[5];
SANE_Range sleep_time_range;
SANE_Range duplex_offset_range;
SANE_Range blue_offset_range;
SANE_Range green_offset_range;
/* --------------------------------------------------------------------- */
/* changeable vars to hold user input. modified by SANE_Options above */
int duplex_mode; /* Use DUPLEX_* constants below */
int resolution_x; /* X resolution in dpi */
int resolution_y; /* Y resolution in dpi */
int resolution_linked; /* When true, Y resolution is set whenever */
/* X resolution gets changed. true initially, */
/* becomes false if Y resolution is ever */
/* set independently */
int top_left_x; /* The desired size of the scan, in */
int top_left_y; /* mm/2^16. Notice that there's a second */
int bottom_right_x; /* group of these with the "rounded" */
int bottom_right_y; /* prefix, below. */
/*mode group*/
int mode; /*color,lineart,etc*/
int source; /*fb,adf front,adf duplex,etc*/
int resolution_x; /* X resolution in dpi */
int resolution_y; /* Y resolution in dpi */
/* A note on the scan are size (topLeft/bottomRight) values. When the
* user (the front-end) sets one of these, we change the above values
* and immediately calculate from it the scan height and width in
* 1/1200 inches (the internal scanner unit). Depending on the scan
* mode, depth, etc., other rules may be used to change the value,
* e.g. in 1bpp scans, the width is always increased until each scan
* line has a full number of bytes.
*
* The results of these calculations are the "top_margin", "left_margin",
* "scan_width", and "scan_height" values below. In addition, these
* values are now converted back into SANE units (1/2^16mm) and stored
* in roundedTopLeft... and roundedBottomRight... - when the front-end
* _sets_ the scan area size, the topLeft... and bottomRight... values
* will be set, but when the front-end _gets_ the scan area size,
* the rounded values will be returned.
*
* By keeping the original values instead of rounding them "in place",
* we can revise our rounded values later. Assume the resolution is set
* to 75dpi, and then the scan size is set - it will be rounded to
* the nearest 1/75 inch. Later the resolution is changed to 600dpi,
* making a better approximation of the original desired size possible.
*
* All these calculations are done within the "calculateDerivedValues"
* function.
*/
int page_width; /* paper width and height may influence the */
int page_height; /* way the ADF operates - in 1/1200 inch */
int output_depth; /* How many bits per pixel the user wants. */
int scanner_depth; /* How many bpp the scanner will send. */
/* A note on "depth" values. Many colour scanners require you to use
* the value "8" for depth if you're doing colour scans even if they
* deliver 24. The front-end, when it calls "sane_get_parameters", will
* expect to see the value 8 as well. However, internally, we use
* scanner_depth as the real number of bits sent per pixel, which is
* obvoiusly 24 for coulour scans.
*
* output_depth uses the same logic and normally both values would be
* identical; however it may be desirable to implement, say, a 4-bit
* grayscale mode in the backend even if the scanner only supports
* 8-bit grayscale. In that case, the backend would to the reduction
* "on the fly", and output_depth would be 4, while scanner_depth is 8.
*/
int color_mode; /* Color/Gray/..., use MODE_* constants */
int use_adf; /* Whether the ADF should be used or not. */
int use_temp_file; /* Whether to use a temp file for duplex. */
int mirror; /* Whether to mirror scan area for rear side */
int lamp_color; /* lamp color to use for monochrome scans */
int green_offset; /* color tuning - green scan line offset */
int blue_offset; /* color tuning - blue scan line offset */
/* Derived values (calculated by calculateDerivedValues from the above) */
/* --------------------------------------------------------------------- */
int rounded_top_left_x; /* Same as topLeft... and bottomRight..., */
int rounded_top_left_y; /* but "rounded" to the nearest 1/1200 */
int rounded_bottom_right_x; /* value, i.e. these are the values really */
int rounded_bottom_right_y; /* used for scanning. */
int top_margin; /* Top margin in 1/1200 inch */
int left_margin; /* Left margin in 1/1200 inch */
int scan_width; /* Width of scan in 1/1200 inch */
int scan_height; /* Height of scan in 1/1200 inch */
int scan_width_pixels; /* Pixels per scan line for this job */
int scan_height_pixels; /* Number of lines in this job */
int bytes_per_scan_line; /* Number of bytes per line in this job */
/* Operational values (contain internal status information etc.) */
/* --------------------------------------------------------------------- */
int default_pipe_r; /* Pipe between reader process and backend. */
int default_pipe_w; /* Pipe between reader process and backend. */
int duplex_pipe_r; /* Additional pipe for duplex scans. */
int duplex_pipe_w; /* Additional pipe for duplex scans. */
int reader_pid; /* Process ID of the reader process. */
int reverse; /* Whether to reverse the image. Not user */
/* settable but required internally. */
int i_transfer_length; /* needed when the scanner returns */
/* compressed data and size of return data */
/* is unknown in advance */
/* This replaced the former "scanning" flag. object_count represents the
* number of objects acquired (or being acquired) by the scanner which
* haven't been read. Thus, an object_count of != 0 means the scanner is
* busy. If the scanner is scanning the first page, it's 1; if the scanner
* is scanning the second page of a duplex scan, it's 2.
*/
int object_count;
/* This is set to "true" by sane_read when it encounters the end of a data
* stream.
*/
int eof;
unsigned char *buffer; /* Buffer used for SCSI transfers. */
unsigned int scsi_buf_size; /* Max amount of data in one SCSI call. */
/** these can be set */
/*geometry group*/
/* The desired size of the scan, all in 1/1200 inch */
int tl_x;
int tl_y;
int br_x;
int br_y;
int page_width;
int page_height;
/*enhancement group*/
int brightness;
int threshold;
int contrast;
int rif;
int bitorder;
int compress_type;
int compress_arg;
int vendor_id_code;
int gamma;
int outline;
int emphasis;
int auto_sep;
int mirroring;
int var_rate_dyn_thresh;
int white_level_follow;
int gradation;
int smoothing_mode;
int filtering;
int background;
int matrix2x2;
int matrix3x3;
int matrix4x4;
int matrix5x5;
int noise_removal;
int paper_orientation;
int paper_selection;
int paper_size;
int dtc_threshold_curve;
int dtc_selection;
int subwindow_list;
/***** end of "set window" terms *****/
/*ipc group*/
int gamma; /* not currently user settable */
/*advanced group*/
int dropout_color;
int lamp_color;
int sleep_time;
int duplex_offset;
int blue_offset;
int green_offset;
int use_temp_file;
SANE_Bool use_imprinter;
int imprinter_direction;
SANE_Word imprinter_y_offset;
SANE_Char imprinter_string[max_imprinter_string_length];
int imprinter_ctr_init;
int imprinter_ctr_step;
int imprinter_ctr_dir;
/* --------------------------------------------------------------------- */
/* values which are derived from setting the options above */
/* the user never directly modifies these */
SANE_Int sleep_time;
/* this is defined in sane spec as a struct containing:
SANE_Frame format;
SANE_Bool last_frame;
SANE_Int lines;
SANE_Int depth; ( binary=1, gray=8, color=8 (!24) )
SANE_Int pixels_per_line;
SANE_Int bytes_per_line;
*/
SANE_Parameters params;
/* --------------------------------------------------------------------- */
/* values which are set by scanning functions to keep track of pages, etc */
int started;
int img_count; /* how many 'sides' delivered */
/* how far we have read */
int bytes_rx[2];
int eof_rx[2];
/* how far we have written */
int bytes_tx[2];
int eof_tx[2];
int duplex_fd;
unsigned char *duplex_buffer;
/* --------------------------------------------------------------------- */
/* values which used by the command and data sending functions (scsi/usb)*/
int fd; /* The scanner device file descriptor. */
unsigned char *buffer;
unsigned char rs_buffer[RS_return_size];
/* --------------------------------------------------------------------- */
/* values which are used by the get hardware status command */
time_t last_ghs;
int hw_top;
int hw_A3;
int hw_B4;
int hw_A4;
int hw_B5;
int hw_hopper;
int hw_omr;
int hw_adf_open;
int hw_sleep;
int hw_send_sw;
int hw_manual_feed;
int hw_scan_sw;
int hw_function;
int hw_ink_empty;
int hw_double_feed;
int hw_error_code;
int hw_skew_angle;
int hw_ink_remain;
int hw_duplex_sw;
int hw_density_sw;
};
/** scan only front page */
#define DUPLEX_FRONT 1
/** scan only reverse page */
#define DUPLEX_BACK 2
/** scan both sides and return them in two different image acquisition operations */
#define DUPLEX_BOTH 3
#define CONNECTION_SCSI 0 /* SCSI interface */
#define CONNECTION_USB 1 /* USB interface */
#define MODEL_FORCE 0
/** Fujitsu M3091DCd (300x600dpi, color, duplex, ADF-only) */
#define MODEL_3091 1
/** Fujitsu M3096 (400x400dpi grayscale, simplex, FB and optional ADF) */
#define MODEL_3096 2
/** 3093 */
#define MODEL_3093 4
/** 4097 */
#define MODEL_4097 5
/** fi-???? */
#define MODEL_FI 6
#define MODEL_3097 7
/** Fujitsu M3092DCd (300x600dpi, color, duplex, FB and ADF) */
#define MODEL_3092 8
/** ScanPartner fi-4120 and ScanParter fi-4220 scsi/usb */
#define MODEL_FI4x20 9
#define SIDE_FRONT 0
#define SIDE_BACK 1
/* A note regarding the MODEL... constants. There's a place in
* identifyScanner() where the INQUIRY data is parsed and the model
* set accordingly. Now while there is, for example, only one 3091
* model (called M3091DCd), there may be different sub-models (e.g.
* the 1000abc and the 1000xyz).
*
* It is suggested that a new MODEL... type be introduced for these if
* there are significant differences in capability that have to be
* treated differently in the backend. For example, if the "abc" model
* has an optional ADF and the "xyz" model has the ADF built-in, we
* don't need to distinguish these models, and it's sufficient to set
* the "has_adf" variable accordingly.
*
* The same would apply if two sub-models behave in the same way but
* one of them is faster, or has some exotic extra capability that we
* don't support anyway.
*
* If, on the other hand, one model supports a different resolution,
* page size, different scan parameters and modes, and such, then it's
* probably necessary to create a new MODEL... constant.
*
* It may also be feasible to introduce a "subModel" member in the
* structure above for those cases where subtle, but important,
* differences exist - e.g. one model is 100% the same as another but
* supports twice the resolution.
*/
#define SOURCE_FLATBED 0
#define SOURCE_ADF_FRONT 1
#define SOURCE_ADF_BACK 2
#define SOURCE_ADF_DUPLEX 3
/** Black-and-White (Line Art) - depth always 1 */
#define MODE_LINEART 1
/** Black-and-White (Halftone) - depth always 1 */
#define MODE_HALFTONE 2
/** Grayscale */
#define MODE_GRAYSCALE 3
/** RGB Color */
#define MODE_COLOR 4
/** Binary RGB Color*/
#define MODE_BIN_COLOR 5
/** half-tones RGB Color*/
#define MODE_HALFTONE_COLOR 6
/* these are same as scsi data to make code easier */
#define MODE_LINEART WD_comp_LA
#define MODE_HALFTONE WD_comp_HT
#define MODE_GRAYSCALE WD_comp_GS
#define MODE_COLOR_LINEART WD_comp_CL
#define MODE_COLOR_HALFTONE WD_comp_CH
#define MODE_COLOR WD_comp_CG
/* these are same as scsi data to make code easier */
#define COLOR_DEFAULT MSEL_dropout_DEFAULT
#define COLOR_RED MSEL_dropout_RED
#define COLOR_GREEN MSEL_dropout_GREEN
#define COLOR_BLUE MSEL_dropout_BLUE
#define COLOR_INTERLACE_NONE 0
#define COLOR_INTERLACE_3091 1
#define COLOR_INTERLACE_BGR 2
#define COLOR_INTERLACE_RRGGBB 3
#define DUPLEX_INTERLACE_NONE 0
#define DUPLEX_INTERLACE_3091 1
#define GHS_TIME 1 /* seconds passed before calling GHS */
/* ------------------------------------------------------------------------- */
#define MM_PER_INCH 25.4
#define length_quant SANE_UNFIX(SANE_FIX(MM_PER_INCH / 1200.0))
#define mmToIlu(mm) ((mm) / length_quant)
#define iluToMm(ilu) ((ilu) * length_quant)
#define MM_PER_UNIT_UNFIX SANE_UNFIX(SANE_FIX(MM_PER_INCH / 1200.0))
#define MM_PER_UNIT_FIX SANE_FIX(SANE_UNFIX(SANE_FIX(MM_PER_INCH / 1200.0)))
#define SCANNER_UNIT_TO_FIXED_MM(number) SANE_FIX(number * MM_PER_UNIT_UNFIX)
#define FIXED_MM_TO_SCANNER_UNIT(number) SANE_UNFIX(number) / MM_PER_UNIT_UNFIX
#define FUJITSU_CONFIG_FILE "fujitsu.conf"
#define READ_MODE_PASS 1
#define READ_MODE_RRGGBB 2
#define READ_MODE_3091RGB 3
#define READ_MODE_BGR 4
#define FIXED_MM_TO_SCANNER_UNIT(number) SANE_UNFIX(number) * 1200 / MM_PER_INCH
#define SCANNER_UNIT_TO_FIXED_MM(number) SANE_FIX(number * MM_PER_INCH / 1200)
#ifndef PATH_MAX
# define PATH_MAX 1024
@ -441,7 +414,6 @@ struct fujitsu
/* ------------------------------------------------------------------------- */
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize);
SANE_Status sane_get_devices (const SANE_Device *** device_list,
@ -453,7 +425,7 @@ SANE_Status sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking);
SANE_Status sane_get_select_fd (SANE_Handle h, SANE_Int * fdp);
const SANE_Option_Descriptor *sane_get_option_descriptor (SANE_Handle handle,
const SANE_Option_Descriptor * sane_get_option_descriptor (SANE_Handle handle,
SANE_Int option);
SANE_Status sane_control_option (SANE_Handle handle, SANE_Int option,
@ -476,36 +448,42 @@ void sane_exit (void);
/* ------------------------------------------------------------------------- */
static void do_inquiry (struct fujitsu *s);
static SANE_Status find_scanners (void);
static SANE_Status attachScanner (const char *devicename,
struct fujitsu **devp);
static SANE_Status attach_one_scsi (const char *name);
static SANE_Status attach_one_usb (const char *name);
static SANE_Status attach_one (const char *devicename, int connType);
static SANE_Status scsi_sense_handler (int scsi_fd, u_char * result, void *arg);
static SANE_Status connect_fd (struct fujitsu *s);
static SANE_Status disconnect_fd (struct fujitsu *s);
static int identify_scanner (struct fujitsu *s);
static int
do_cmd (Fujitsu_Connection_Type connection, int fd, unsigned char *cmd,
int cmd_len, unsigned char *out, size_t req_out_len,
size_t *res_out_len);
static int do_scsi_cmd (int fd, unsigned char *cmd, int cmd_len,
unsigned char *out, size_t req_out_len,
size_t *res_out_len);
static int
do_usb_cmd (int fd, unsigned char *cmd,
int cmd_len, unsigned char *out, size_t req_out_len,
size_t *res_out_len);
static void hexdump (int level, char *comment, unsigned char *p, int l);
static SANE_Status sense_handler (int scsi_fd, u_char * result, void *arg);
static SANE_Status init_inquire (struct fujitsu *s);
static SANE_Status init_vpd (struct fujitsu *s);
static SANE_Status init_model (struct fujitsu *s);
static SANE_Status init_options (struct fujitsu *scanner);
static int grab_scanner (struct fujitsu *s);
static SANE_Status
do_cmd(struct fujitsu *s, int busyRetry, int busySleep, int runRS,
unsigned char * cmdBuff, int cmdLen, int cmdTime,
unsigned char * outBuff, int outLen, int outTime,
unsigned char * inBuff, int inLen, int inTime
);
static int free_scanner (struct fujitsu *s);
static SANE_Status
do_scsi_cmd(struct fujitsu *s, int busyRetry, int busySleep, int runRS,
unsigned char * cmdBuff, int cmdLen, int cmdTime,
unsigned char * outBuff, int outLen, int outTime,
unsigned char * inBuff, int inLen, int inTime
);
static SANE_Status
do_usb_cmd(struct fujitsu *s, int busyRetry, int busySleep, int runRS,
unsigned char * cmdBuff, int cmdLen, int cmdTime,
unsigned char * outBuff, int outLen, int outTime,
unsigned char * inBuff, int inLen, int inTime
);
static int wait_scanner (struct fujitsu *s);
@ -513,71 +491,36 @@ static int object_position (struct fujitsu *s, int i_load);
static SANE_Status do_cancel (struct fujitsu *scanner);
static SANE_Status do_reset (struct fujitsu *scanner);
static SANE_Status scanner_control (struct fujitsu *s, int function);
/*static int objectDischarge (struct fujitsu *s);*/
static SANE_Status mode_select_dropout(struct fujitsu *s);
static int fujitsu_set_sleep_mode(struct fujitsu *s);
static SANE_Status set_sleep_mode(struct fujitsu *s);
static int set_mode_params (struct fujitsu *s);
int get_current_side (struct fujitsu *s);
static int imprinter(struct fujitsu *s);
static int fujitsu_send(struct fujitsu *s);
static int setWindowParam (struct fujitsu *s);
static size_t maxStringSize (const SANE_String_Const strings[]);
static int set_window (struct fujitsu *s);
static int start_scan (struct fujitsu *s);
static int reader_process (void *scanner);
static SANE_Status read_from_scanner(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side);
static unsigned int reader3091ColorDuplex (struct fujitsu *scanner, FILE * fd,
FILE * fd2);
static unsigned int reader3091ColorSimplex (struct fujitsu *scanner,
FILE * fd);
static unsigned int reader3091GrayDuplex (struct fujitsu *scanner, FILE * fd,
FILE * fd2);
static void convert_bgr_to_rgb(struct fujitsu *scanner, unsigned char * buffptr, unsigned int length);
static SANE_Status read_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side);
static void convert_rrggbb_to_rgb(struct fujitsu *scanner, unsigned char * buffptr, unsigned int length);
static SANE_Status convert_bgr_to_rgb(struct fujitsu *s, unsigned char * buffptr, unsigned int length);
static unsigned int reader_gray_duplex_sequential (struct fujitsu *scanner,
FILE * fd, FILE * fd2);
static unsigned int reader_gray_duplex_alternate (struct fujitsu *scanner,
FILE * fd, FILE * fd2);
static SANE_Status convert_rrggbb_to_rgb(struct fujitsu *s, unsigned char * buffptr, unsigned int length);
static unsigned int reader_duplex_sequential (struct fujitsu *scanner,
FILE * fd, FILE * fd2);
static unsigned int reader_duplex_alternate (struct fujitsu *scanner,
FILE * fd, FILE * fd2);
static unsigned int reader_simplex (struct fujitsu *scanner, FILE * fd,
int i_window_id);
static unsigned int reader_generic_passthrough (struct fujitsu *scanner,
FILE * fd, int i_window_id);
static int read_large_data_block (struct fujitsu *s,
unsigned char *buffer, unsigned int length,
int i_window_id,
unsigned int *i_data_read);
static SANE_Status attachOne (const char *name);
static int modelMatch (const char *product);
static void setDefaults3091 (struct fujitsu *scanner);
static void setDefaults3096 (struct fujitsu *scanner);
static SANE_Status setMode3091 (struct fujitsu *scanner, int mode);
static SANE_Status setMode3096 (struct fujitsu *scanner, int mode);
static SANE_Status convert_3091rgb_to_rgb(struct fujitsu *s, unsigned char * buff, unsigned int length);
static void calculateDerivedValues (struct fujitsu *scanner);
static int makeTempFile (void);
static SANE_Status get_hardware_status (struct fujitsu *s);
static void fujitsu_set_standard_size (SANE_Handle handle);
static SANE_Status setup_duplex_buffer (struct fujitsu *s);
static SANE_Status get_hardware_status (struct fujitsu *s);
static void hexdump (int level, char *comment, unsigned char *p, int l);
static size_t maxStringSize (const SANE_String_Const strings[]);
#endif /* FUJITSU_H */

Wyświetl plik

@ -1,7 +1,5 @@
.TH sane-fujitsu 5 "17 Apr 2002" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.TH sane-fujitsu 5 "2006-05-12" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-fujitsu
.IX sane-fcpa
.IX sane-m3096g
.SH NAME
sane-fujitsu \- SANE backend for Fujitsu flatbed and ADF scanners
@ -10,173 +8,261 @@ sane-fujitsu \- SANE backend for Fujitsu flatbed and ADF scanners
The
.B sane-fujitsu
library implements a SANE (Scanner Access Now Easy) backend which
provides access to Fujitsu flatbed and ADF scanners.
At present, the following
scanners are known to work with this backend:
provides access to most Fujitsu flatbed and ADF scanners.
This document describes the rewritten backend versions 1.0.21 and greater.
The backend supports lineart, halftone, grayscale, and color
scanning for most scanners, depending on hardware capabilities.
Most simple scanning related features are exposed. This version
features better usb support, and less model-specific code.
This enables at least basic support for many more models.
See LIMITATIONS.
.SH HARDWARE SUPPORT
The following scanners are thought to have at least basic scanning
capability, either because they have been tested with a prior
version, or because documentation indicates they are compatible
with a tested model.
.PP
.RS
.ft CR
.nf
Vendor: Model: Rev:
-------- ---------------- -----
FUJITSU M3096Gm 02
FUJITSU M3093GX
FUJITSU M3093GD
FUJITSU M4097
FUJITSU fi-4220C
FUJITSU fi-4340C
FUJITSU M3091DCd BF21
FUJITSU M3092DCd
WORKGROUP SIZED SCANNERS:
--------------------------------------
SCSI: SCSI/USB: USB:
------------ ------------ ------------
M3091DC fi-4120C fi-5110C
M3092DC fi-4220C fi-5110EOX
SP-93GX fi-4120C2
fi-4220C2
fi-5120C
fi-5220C
.fi
.ft R
.RE
.P
The driver supports lineart, halftone, grayscale, and color
(3091 and 3092) scanning depending on hardware capabilities.
.PP
.RS
.ft CR
.nf
DEPARTMENTAL SIZED SCANNERS:
--------------------------------------
SCSI: SCSI/USB:
------------ ------------
M3093GX/DG fi-4340C
M3096G/GX fi-4530C
M3097G+/DG fi-5530C
fi-4640S
fi-4750C
.fi
.ft R
.RE
.P
.PP
.RS
.ft CR
.nf
PRODUCTION SIZED SCANNERS:
--------------------------------------
SCSI: SCSI/USB:
------------ ------------
M3099G/GH/GX fi-5650C
M4097D fi-5750C
fi-4750L fi-5900C
fi-4860C
M4099D
.fi
.ft R
.RE
.P
The following scanners are known NOT to work with this backend,
either because they have a non-fujitsu chipset, or an unsupported
interface type. Some of these scanners may be supported by another
backend.
.PP
.RS
.ft CR
.nf
UNSUPPORTED SCANNERS:
SCSI: SERIAL: USB:
------------ ------------ ------------
ScanStation M3093E/DE/EX fi-4110EOX2
ScanPartner M3096EX
SP-Jr M3097E+/DE
SP-10/10C M3099A/EH/EX
SP-15C/300C
SP-600C/620C
.fi
.ft R
.RE
.P
This backend may support scanners not listed here. The best
way to determine level of support is to test the scanner directly.
Fujitsu equipment has historically been good enough to not be
damaged by incorrect commands if the scanner is incompatible.
Please contact the author with test results, positive or negative.
The "Fujitsu" driver is a first attempt at integrating support
for all Fujitsu scanners \- previously available as different
single drivers \- in one driver. At present, the M3091DCd
is working (lineart, halftone, 8-bit grayscale and 24-bit color,
simplex and duplex), and the driver should also support the
M3096 as the M3096g driver code has been incorporated.
This driver supersedes the old "m3091"/"fujitsu" drivers and
the old "m3096g" driver.
Other scanners in these families may work.
The ScanPartner 15C seems to be a repackaging
of the ScanPartner 600C, but I don't know if it works.
Look at the sp15c backend for this scanner.
Perusal of the M3096GX/M3093GX/M3093DG manual
suggests the M3096G driver offers access to a
subset of the new scanners.
People are encouraged to try these driver with the other scanners
and to contact the author with test results.
.SH DUPLEX MODE
The M3091 driver supports duplex scanning. To the front-end, a duplex
scan looks very much like scanning two separate pages from the document
feeder, i.e. the SANE front-end receives two images instead of one.
Front-ends which are not capable of dealing with that \- e.g. the
command-line tool scanimage \- cannot be used for duplex scanning.
If you want to do duplex scans from the command line, get Tom
Martone's scanadf program from
http://www.martoneconsulting.com/sane-scanadf.html.
.SH CONFIGURATION
.SH OPTIONS
A modest effort has been made to expose the standard options to the API.
This allows frontends such as xscanimage to set scanning region,
resolution, bit-depth (and color), and enable the automatic document feeder.
.br
The "Fujitsu" driver supports the following options:
.br
This allows a frontend to set scanning region, resolution, bit-depth,
color mode, and enable the automatic document feeder. The fujitsu backend
supports the following basic options for most scanners:
.PP
source s
.RS
Selects the source for the scan. Options
may include "Flatbed", "ADF Front", "ADF Back", "ADF Duplex".
.RE
.PP
mode m
.RS
.I m
may be one of "Color", "Lineart", "Halftone", or "Gray", dependent on the
scanner model. It is advisable to specify this option first when using
command line tools, as the validity of some of the other options depends
on the mode setting.
.RE
.PP
x, y
.RS
Scan width and height
.RE
.PP
pagewidth, pageheight
.RS
Page size; when using the ADF, the driver will assume that a page of the
given width is centered
Selects the mode for the scan. Options
may include "Lineart", "Halftone", "Gray", and "Color".
.RE
.PP
resolution, y-resolution
.RS
Controls scan resolution. Permissible values dependent on model and scan mode;
setting --resolution also sets --y-resolution but not vice versa. This makes
it possible to set the 3091's maximum resolution of 300x600dpi.
Controls scan resolution. Setting --resolution also sets --y-resolution
but not vice versa. This behavior is overridden by some frontends.
.RE
.PP
brightness b
tlx, tly, brx, bry
.RS
Only supported for M3096
Sets scan area upper left and lower right coordinates. Often converted
to t, l, x, y by frontend code.
.RE
.PP
threshold t
pagewidth, pageheight
.RS
Only supported for M3096
Sets paper size. Used by scanner to determine centering of scan
coordinates when using ADF.
.RE
.PP
duplex d
Other options will be available based on the capabilities of the scanner.
Use 'scanimage --help' to get a list. Be aware that some options may
appear only when another option has been set.
.PP
.SH CONFIGURATION FILE
The configuration file "fujitsu.conf" is used to tell the backend how to look for
scanners, and provide options controlling the operation of the backend.
This file is read each time the frontend asks the backend for a list
of scanners, generally only when the frontend starts. If the configuration
file is missing, the backend will use a set of compiled defaults, which
are identical to the default configuration file shipped with SANE.
.PP
Scanners can be specified in the configuration file in 4 ways:
.PP
"scsi FUJITSU"
.RS
.I d
may be "front", "back", or "both" and denotes which sides of the page
are to be scanned (duplex scanner only for example 3091, 3093Gd).
Requests backend to search all scsi busses in the system for a device
which reports itself to be a scanner made by 'FUJITSU'.
.RE
.PP
lampcolor c
"scsi /dev/sg0" (or other scsi device file)
.RS
.I c
may be "red", "green", "blue", or "default" \- the lamp color to be used
when doing graysacale or b/w scans on the M3091.
Requests backend to open the named scsi device. Only useful if you have
multiple compatible scanners connected to your system, and need to
specify one. Probably should not be used with the other "scsi" line above.
.RE
.PP
blueoffset, greenoffset
"usb 0x04c5 0x1042" (or other vendor/product ids)
.RS
Color justification options for the M3091; anything other than +1/-1 will
probably distort the image. Should be left alone unless your scanner is
buggy.
Requests backend to search all usb busses in the system for a device
which uses that vendor and product id. The device will then be queried
to determine if it is a Fujitsu scanner.
.RE
.PP
swapfile
"usb /dev/usb/scanner0" (or other device file)
.RS
boolean option for the M3091. Only affects duplex scans. If set, a swap
file will be used for storing the rear side of a document as it is scanned;
otherwise the whole page will be kept in memory.
Some systems use a kernel driver to access usb scanners. This method is untested.
.RE
.br
You may specify the line "forceModel=xxx"
in the configuration file to make the driver treat your scanner as an
"xxx" scanner (currently supported: 3096, 3091). Use this if you have
another scanner that is not automatically detected as being compatible.
.br
The only other configuration option supported is "scsi-buf-size=xxx",
.PP
The only configuration option supported is "scsi-buf-size=xxx",
allowing you to set the SCSI buffer size to something other than the
compiled-in default. Especially with the M3091 scanner, some users
had the problem that the scanner would "hang" mid-page, and this can
often be alleviated by using "scsi-buf-size=32768".
compiled-in default. Some users report that the scanner would "hang"
mid-page, and this can often be alleviated by increasing scsi-buf-size.
.PP
Note: This option may appear multiple times in the configuration file. It only
applies to scanners discovered by "scanner" lines that follow this option, and will be updated to the new value each time it occurs.
.PP
Note: The backend does not place an upper bound on this value, as some users
required it to be quite large. Values above 32768 are not recommended,
and may crash your OS or lockup your scsi card driver. You have been
warned.
.SH ENVIRONMENT
The backend uses a single environment variable, SANE_DEBUG_FUJITSU, which
enables debugging output to stderr. Valid values are:
.PP
.RS
5 Errors
.br
10 Function trace
.br
15 Function detail
.br
20 Option commands
.br
30 Scsi/Usb packets
.RE
.SH OLDER VERSIONS
Backend versions prior to this were numbered with a two part version,
or with no version number at all. At the time this version was written,
all older versions were retroactively renumbered, 1.0.2 - 1.0.20.
.PP
The current backend may have lost support for some important feature
you were using. The last of the "old" backends, 1.0.20, is still available
as source from:
.PP
http://www2.pfeiffer.edu/~anoah/fujitsu/
.PP
If you find that you need to use the older version, please contact the
author, to try and get those features restored to a later version.
.SH KNOWN ISSUES
.PP
.RS
3091/3092 color and duplex modes are broken.
.br
All IPC and compression options are disabled.
.br
Most scanner specific 'quirks' are not accounted for, making it possible
to set some options in ways that the scanner does not support.
.br
Some flatbed options are affected by adf settings.
.br
Speed is too low, especially at higher resolutions, due to single-threading.
.RE
.SH HISTORY
m3091 backend: Frederik Ramm <frederik a t remote d o t org>
.br
m3096g backend: Randolph Bentson <bentson a t holmsjoen d o t com>
.br
(with credit to the unnamed author of the coolscan driver)
.br
merged fujitsu backend: Frederik?
.br
3092: Mario Goppold <mgoppold a t tbzpariv d o t tcc-chemnitz d o t de>
.br
3093,fi-4340C,ipc,cmp support, and long-time backend maintainer:
.br
Oliver Schirrmeister <oschirr a t abm d o t de>
.br
fi-4220C and basic USB support: Ron Cemer <ron a t roncemer d o t com>
.br
fi-4120, fi-series color support, backend re-write, current maintainer:
M. Allan Noah: <anoah a t pfeiffer d o t edu>
.SH "SEE ALSO"
sane(7),
sane-scsi(5),
sane-sp15c(5)
sane-usb(5),
.br
Fujitsu ScanPartner 15C OEM Manual, Doc. No. 250-0081-0
.br
Fujitsu M3096G OEM Manual, part number 50FH5028E-05
.br
Fujitsu M3096GX/M3093GX/M3093DG OEM Manual, part number C150-E015...03
sane-sp15c(5),
sane-avision(5)
.SH AUTHOR
3096/SP15 drivers: Randolph Bentson
<bentson@holmsjoen.com>,
with credit to the unnamed author of the coolscan driver
.br
3091 driver: Frederik Ramm <frederik@remote.org>
3093GD,fi-4340C, ipc and cmp options: Oliver Schirrmeister <oschirr@abm.de>
3092 patch: Mario Goppold <mgoppold@tbzpariv.tcc-chemnitz.de>
fi-4220C patch and USB support: Ronald B. Cemer <ron@roncemer.com>
.SH LIMITATIONS
Only tested with Linux 2.4
M. Allan Noah: <anoah a t pfeiffer d o t edu>
.SH BUGS
I'm sure there are plenty, and not too well hidden,
but I haven't seen them yet.
I don't know if the ScanPartner 15C still works, because I'm not able
to test it.
3091/3092 don't support halftone