kopia lustrzana https://gitlab.com/sane-project/backends
Updated snapscan backend to version 1.2 (from
Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>). Henning Meier-Geinitz <henning@meier-geinitz.de>DEVEL_2_0_BRANCH-1
rodzic
d7f2982cdc
commit
73f193944d
|
@ -1,8 +1,9 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
|
||||
Copyright (C) 1997, 1998, 2001 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson
|
||||
and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -51,8 +52,7 @@
|
|||
|
||||
/* scanner scsi commands */
|
||||
|
||||
/* Remove comment from following line to use USB instead of SCSI */
|
||||
/* #include "snapscan-usb.h" */
|
||||
#include "snapscan-usb.h"
|
||||
|
||||
/* a sensible sense handler, courtesy of Franck;
|
||||
the last argument is expected to be a pointer to the associated
|
||||
|
@ -65,12 +65,8 @@ static SANE_Status sense_handler (int scsi_fd, u_char * result, void *arg)
|
|||
char *sense_str = NULL, *as_str = NULL;
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
|
||||
DBG (DL_CALL_TRACE,
|
||||
"%s(%ld, %p, %p)\n",
|
||||
me,
|
||||
(long) scsi_fd,
|
||||
(void *) result,
|
||||
(void *) arg);
|
||||
DBG (DL_CALL_TRACE, "%s(%ld, %p, %p)\n", me, (long) scsi_fd,
|
||||
(void *) result, (void *) arg);
|
||||
|
||||
sense = result[2] & 0x0f;
|
||||
asc = result[12];
|
||||
|
@ -158,10 +154,16 @@ static SANE_Status open_scanner (SnapScan_Scanner *pss)
|
|||
DBG (DL_CALL_TRACE, "open_scanner\n");
|
||||
if (!pss->opens)
|
||||
{
|
||||
status = sanei_scsi_open (pss->devname,
|
||||
&(pss->fd),
|
||||
sense_handler,
|
||||
(void *) pss);
|
||||
if(pss->pdev->bus == SCSI)
|
||||
{
|
||||
status = sanei_scsi_open (pss->devname, &(pss->fd),
|
||||
sense_handler, (void *) pss);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = snapscani_usb_open (pss->devname, &(pss->fd),
|
||||
sense_handler, (void *) pss);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -177,11 +179,36 @@ static void close_scanner (SnapScan_Scanner *pss)
|
|||
{
|
||||
DBG (DL_CALL_TRACE, "close_scanner\n");
|
||||
if (pss->opens)
|
||||
{
|
||||
{
|
||||
pss->opens--;
|
||||
if (!pss->opens)
|
||||
sanei_scsi_close (pss->fd);
|
||||
{
|
||||
if(pss->pdev->bus == SCSI)
|
||||
{
|
||||
sanei_scsi_close (pss->fd);
|
||||
}
|
||||
else if(pss->pdev->bus == USB)
|
||||
{
|
||||
snapscani_usb_close (pss->fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SANE_Status snapscan_cmd(SnapScan_Bus bus, int fd, const void *src,
|
||||
size_t src_size, void *dst, size_t * dst_size)
|
||||
{
|
||||
SANE_Status status;
|
||||
DBG (DL_CALL_TRACE, "snapscan_cmd\n");
|
||||
if(bus == USB)
|
||||
{
|
||||
status = snapscani_usb_cmd(fd, src, src_size, dst, dst_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = sanei_scsi_cmd(fd, src, src_size, dst, dst_size);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* SCSI commands */
|
||||
|
@ -197,7 +224,6 @@ static void close_scanner (SnapScan_Scanner *pss)
|
|||
#define SEND_DIAGNOSTIC 0x1D
|
||||
#define GET_DATA_BUFFER_STATUS 0x34
|
||||
|
||||
|
||||
#define SCAN_LEN 6
|
||||
#define READ_LEN 10
|
||||
|
||||
|
@ -294,7 +320,7 @@ static void check_range (int *v, SANE_Range r)
|
|||
must point to character buffers of size at least 8 and 17
|
||||
respectively */
|
||||
|
||||
static SANE_Status mini_inquiry (int fd, char *vendor, char *model)
|
||||
static SANE_Status mini_inquiry (SnapScan_Bus bus, int fd, char *vendor, char *model)
|
||||
{
|
||||
static const char *me = "mini_inquiry";
|
||||
size_t read_bytes;
|
||||
|
@ -305,8 +331,8 @@ static SANE_Status mini_inquiry (int fd, char *vendor, char *model)
|
|||
read_bytes = 36;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), data, &read_bytes);
|
||||
CHECK_STATUS (status, me, "sanei_scsi_cmd");
|
||||
status = snapscan_cmd (bus, fd, cmd, sizeof (cmd), data, &read_bytes);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
|
||||
memcpy (vendor, data + 8, 7);
|
||||
vendor[7] = 0;
|
||||
|
@ -331,12 +357,13 @@ static SANE_Status inquiry (SnapScan_Scanner *pss)
|
|||
pss->cmd[4] = INQUIRY_RET_LEN;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
status = sanei_scsi_cmd (pss->fd,
|
||||
pss->cmd,
|
||||
INQUIRY_LEN,
|
||||
pss->buf,
|
||||
&pss->read_bytes);
|
||||
CHECK_STATUS (status, me, "sanei_scsi_cmd");
|
||||
status = snapscan_cmd (pss->pdev->bus,
|
||||
pss->fd,
|
||||
pss->cmd,
|
||||
INQUIRY_LEN,
|
||||
pss->buf,
|
||||
&pss->read_bytes);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
|
||||
/* record current parameters */
|
||||
|
||||
|
@ -370,6 +397,8 @@ static SANE_Status inquiry (SnapScan_Scanner *pss)
|
|||
case SNAPSCAN310:
|
||||
case SNAPSCAN600:
|
||||
case SNAPSCAN1236S:
|
||||
case SNAPSCAN1212U:
|
||||
case SNAPSCANE50:
|
||||
case VUEGO310S: /* WG changed */
|
||||
case VUEGO610S: /* SJU changed */
|
||||
case PRISA620S: /* GP added */
|
||||
|
@ -432,14 +461,8 @@ static SANE_Status test_unit_ready (SnapScan_Scanner *pss)
|
|||
SANE_Status status;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: scsi command error: %s\n",
|
||||
me,
|
||||
sane_strstatus (status));
|
||||
}
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -450,7 +473,7 @@ static void reserve_unit (SnapScan_Scanner *pss)
|
|||
SANE_Status status;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
|
@ -467,7 +490,7 @@ static void release_unit (SnapScan_Scanner *pss)
|
|||
SANE_Status status;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
|
@ -480,6 +503,7 @@ static void release_unit (SnapScan_Scanner *pss)
|
|||
#define DTC_HALFTONE 0x02
|
||||
#define DTC_GAMMA 0x03
|
||||
#define DTC_SPEED 0x81
|
||||
#define DTC_CALIBRATION 0x82
|
||||
#define DTCQ_HALFTONE_BW8 0x00
|
||||
#define DTCQ_HALFTONE_COLOR8 0x01
|
||||
#define DTCQ_HALFTONE_BW16 0x80
|
||||
|
@ -550,6 +574,9 @@ static SANE_Status send (SnapScan_Scanner *pss, u_char dtc, u_char dtcq)
|
|||
case DTC_SPEED: /* static transfer speed */
|
||||
tl = 2;
|
||||
break;
|
||||
case DTC_CALIBRATION:
|
||||
tl = calibration_line_length(pss);
|
||||
break;
|
||||
default:
|
||||
DBG (DL_MAJOR_ERROR, "%s: unsupported data type code 0x%x\n",
|
||||
me, (unsigned) dtc);
|
||||
|
@ -562,9 +589,9 @@ static SANE_Status send (SnapScan_Scanner *pss, u_char dtc, u_char dtcq)
|
|||
pss->buf[7] = (tl >> 8) & 0xff;
|
||||
pss->buf[8] = tl & 0xff;
|
||||
|
||||
status = sanei_scsi_cmd (pss->fd, pss->buf, SEND_LENGTH + tl,
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->buf, SEND_LENGTH + tl,
|
||||
NULL, NULL);
|
||||
CHECK_STATUS (status, me, "sane_scsi_cmd");
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -636,15 +663,15 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
check_range(&(pss->brx), pss->pdev->x_range);
|
||||
check_range(&(pss->bry), pss->pdev->y_range);
|
||||
{
|
||||
unsigned tlxp =
|
||||
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tlx));
|
||||
unsigned tlyp =
|
||||
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tly));
|
||||
unsigned brxp =
|
||||
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->brx));
|
||||
unsigned bryp =
|
||||
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->bry));
|
||||
unsigned tmp;
|
||||
int tlxp =
|
||||
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tlx));
|
||||
int tlyp =
|
||||
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tly));
|
||||
int brxp =
|
||||
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->brx));
|
||||
int bryp =
|
||||
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->bry));
|
||||
int tmp;
|
||||
|
||||
/* we don't guard against brx < tlx and bry < tly in the options */
|
||||
if (brxp < tlxp)
|
||||
|
@ -667,16 +694,10 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
u_int_to_u_char4p (MAX (((unsigned) (bryp - tlyp)), 75),
|
||||
pc + SET_WINDOW_P_LENGTH);
|
||||
}
|
||||
#ifdef INOPERATIVE
|
||||
pc[SET_WINDOW_P_BRIGHTNESS] =
|
||||
(u_char) (255.0*((pss->bright + 100) / 200.0));
|
||||
#endif
|
||||
pc[SET_WINDOW_P_BRIGHTNESS] = 128;
|
||||
pc[SET_WINDOW_P_THRESHOLD] =
|
||||
(u_char) (255.0*(pss->threshold / 100.0));
|
||||
#ifdef INOPERATIVE
|
||||
pc[SET_WINDOW_P_CONTRAST] =
|
||||
(u_char) (255.0*((pss->contrast + 100) / 200.0));
|
||||
#endif
|
||||
pc[SET_WINDOW_P_CONTRAST] = 128;
|
||||
{
|
||||
SnapScan_Mode mode = pss->mode;
|
||||
u_char bpp;
|
||||
|
@ -725,8 +746,21 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
u_short_to_u_charp (0x0000, pc + SET_WINDOW_P_BIT_ORDERING); /* used? */
|
||||
pc[SET_WINDOW_P_COMPRESSION_TYPE] = 0; /* none */
|
||||
pc[SET_WINDOW_P_COMPRESSION_ARG] = 0; /* none applicable */
|
||||
pc[SET_WINDOW_P_DEBUG_MODE] = 2; /* use full 128k buffer */
|
||||
pc[SET_WINDOW_P_GAMMA_NO] = 0x01; /* downloaded table */
|
||||
if(pss->pdev->model != ACER300F
|
||||
&&
|
||||
pss->pdev->model != SNAPSCAN310
|
||||
&&
|
||||
pss->pdev->model != SNAPSCAN1236S
|
||||
&&
|
||||
pss->pdev->model != SNAPSCANE50
|
||||
&&
|
||||
pss->pdev->model != VUEGO310S
|
||||
&&
|
||||
pss->pdev->model != VUEGO610S)
|
||||
{
|
||||
pc[SET_WINDOW_P_DEBUG_MODE] = 2; /* use full 128k buffer */
|
||||
pc[SET_WINDOW_P_GAMMA_NO] = 0x01; /* downloaded table */
|
||||
}
|
||||
source = 0x20;
|
||||
if (pss->preview)
|
||||
source |= 0x40;
|
||||
|
@ -738,12 +772,9 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
|
|||
pc[SET_WINDOW_P_GREEN_UNDER_COLOR] = 0xff;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
|
||||
status = sanei_scsi_cmd (pss->fd,
|
||||
pss->cmd,
|
||||
SET_WINDOW_TOTAL_LEN,
|
||||
NULL, NULL);
|
||||
CHECK_STATUS (status, me, "sanei_scsi_cmd");
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd,
|
||||
SET_WINDOW_TOTAL_LEN, NULL, NULL);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -755,11 +786,8 @@ static SANE_Status scan (SnapScan_Scanner *pss)
|
|||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
zero_buf (pss->cmd, MAX_SCSI_CMD_LEN);
|
||||
pss->cmd[0] = SCAN;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
|
||||
status = sanei_scsi_cmd (pss->fd, pss->cmd, SCAN_LEN, NULL, NULL);
|
||||
CHECK_STATUS (status, me, "sanei_scsi_cmd");
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd, SCAN_LEN, NULL, NULL);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -782,12 +810,9 @@ static SANE_Status scsi_read (SnapScan_Scanner *pss, u_char read_type)
|
|||
|
||||
pss->read_bytes = pss->expected_read_bytes;
|
||||
|
||||
status = sanei_scsi_cmd (pss->fd,
|
||||
pss->cmd,
|
||||
READ_LEN,
|
||||
pss->buf,
|
||||
&pss->read_bytes);
|
||||
CHECK_STATUS (status, me, "sanei_scsi_cmd");
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd,
|
||||
READ_LEN, pss->buf, &pss->read_bytes);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -802,13 +827,12 @@ static SANE_Status request_sense (SnapScan_Scanner *pss)
|
|||
read_bytes = 20;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), data, &read_bytes);
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd),
|
||||
data, &read_bytes);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: scsi command error: %s\n",
|
||||
me,
|
||||
sane_strstatus (status));
|
||||
DBG (DL_MAJOR_ERROR, "%s: scsi command error: %s\n",
|
||||
me, sane_strstatus (status));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -817,7 +841,6 @@ static SANE_Status request_sense (SnapScan_Scanner *pss)
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status send_diagnostic (SnapScan_Scanner *pss)
|
||||
{
|
||||
static const char *me = "send_diagnostic";
|
||||
|
@ -832,14 +855,8 @@ static SANE_Status send_diagnostic (SnapScan_Scanner *pss)
|
|||
}
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
|
||||
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: scsi command error: %s\n",
|
||||
me,
|
||||
sane_strstatus (status));
|
||||
}
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -870,12 +887,12 @@ static SANE_Status get_data_buffer_status (SnapScan_Scanner *pss, int wait)
|
|||
pss->cmd[1] = 0x01;
|
||||
u_short_to_u_charp (DESCRIPTOR_LENGTH, pss->cmd + 7);
|
||||
|
||||
status = sanei_scsi_cmd (pss->fd,
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd,
|
||||
pss->cmd,
|
||||
GET_DATA_BUFFER_STATUS_LEN,
|
||||
pss->buf,
|
||||
&pss->read_bytes);
|
||||
CHECK_STATUS (status, me, "sanei_scsi_cmd");
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -905,8 +922,7 @@ static SANE_Status wait_scanner_ready (SnapScan_Scanner *pss)
|
|||
int delay = pss->asi1 + 1;
|
||||
DBG (DL_INFO,
|
||||
"%s: scanner warming up. Waiting %ld seconds.\n",
|
||||
me,
|
||||
(long) delay);
|
||||
me, (long) delay);
|
||||
sleep (delay);
|
||||
}
|
||||
break;
|
||||
|
@ -926,8 +942,127 @@ static SANE_Status wait_scanner_ready (SnapScan_Scanner *pss)
|
|||
return status;
|
||||
}
|
||||
|
||||
#define READ_CALIBRATION 0x82
|
||||
#define NUM_CALIBRATION_LINES 16
|
||||
|
||||
static SANE_Status read_calibration_data (SnapScan_Scanner *pss, void *buf, u_char num_lines)
|
||||
{
|
||||
static const char *me = "read_calibration_data";
|
||||
SANE_Status status;
|
||||
size_t expected_read_bytes = num_lines * calibration_line_length(pss);
|
||||
size_t read_bytes;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
zero_buf (pss->cmd, MAX_SCSI_CMD_LEN);
|
||||
pss->cmd[0] = READ;
|
||||
pss->cmd[2] = READ_CALIBRATION;
|
||||
pss->cmd[5] = num_lines;
|
||||
u_int_to_u_char3p (expected_read_bytes, pss->cmd + 6);
|
||||
read_bytes = expected_read_bytes;
|
||||
|
||||
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd,
|
||||
READ_LEN, buf, &read_bytes);
|
||||
CHECK_STATUS (status, me, "snapscan_cmd");
|
||||
|
||||
if(read_bytes != expected_read_bytes) {
|
||||
DBG (DL_MAJOR_ERROR, "%s: read %d of %d calibration data\n", me, read_bytes, expected_read_bytes);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status calibrate (SnapScan_Scanner *pss)
|
||||
{
|
||||
int r;
|
||||
int c;
|
||||
u_char *buf;
|
||||
static const char *me = "calibrate";
|
||||
SANE_Status status;
|
||||
int line_length = calibration_line_length(pss);
|
||||
|
||||
buf = (u_char *) malloc(NUM_CALIBRATION_LINES * line_length);
|
||||
if (!buf)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR, "%s: out of memory allocating calibration, %d bytes.", me, NUM_CALIBRATION_LINES * line_length);
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
DBG (DL_MAJOR_ERROR, "%s: reading calibration data\n", me);
|
||||
status = read_calibration_data(pss, buf, NUM_CALIBRATION_LINES);
|
||||
CHECK_STATUS(status, me, "read_calibration_data");
|
||||
|
||||
/* status = test_unit_ready (pss);
|
||||
CHECK_STATUS(status, me, "test unit ready");*/
|
||||
|
||||
for(c=0; c < line_length; c++) {
|
||||
u_int sum = 0;
|
||||
for(r=0; r < NUM_CALIBRATION_LINES; r++) {
|
||||
sum += buf[c + r * line_length];
|
||||
}
|
||||
pss->buf[c + SEND_LENGTH] = sum / NUM_CALIBRATION_LINES;
|
||||
}
|
||||
|
||||
status = send (pss, DTC_CALIBRATION, 1);
|
||||
CHECK_STATUS(status, me, "send calibration");
|
||||
|
||||
/* status = test_unit_ready (pss);
|
||||
CHECK_STATUS(status, me, "test unit ready");*/
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.4 2001/05/26 12:47:30 hmg
|
||||
* Updated snapscan backend to version 1.2 (from
|
||||
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
|
||||
* Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
*
|
||||
* Revision 1.12 2001/04/10 13:00:31 sable
|
||||
* Moving sanei_usb_* to snapscani_usb*
|
||||
*
|
||||
* Revision 1.11 2001/04/10 11:04:31 sable
|
||||
* Adding support for snapscan e40 an e50 thanks to Giuseppe Tanzilli
|
||||
*
|
||||
* Revision 1.10 2001/03/17 22:53:21 sable
|
||||
* Applying Mikael Magnusson patch concerning Gamma correction
|
||||
* Support for 1212U_2
|
||||
*
|
||||
* Revision 1.3 2001/03/04 16:37:57 mikael
|
||||
* Remove brightness and contrast settings in window.
|
||||
*
|
||||
* Revision 1.2 2001/02/16 18:32:28 mikael
|
||||
* impl calibration, signed position, increased buffer size
|
||||
*
|
||||
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
|
||||
* Imported from snapscan-11282000.tar.gz
|
||||
*
|
||||
* Revision 1.9 2000/11/10 01:01:59 sable
|
||||
* USB (kind of) autodetection
|
||||
*
|
||||
* Revision 1.8 2000/11/01 01:26:43 sable
|
||||
* Support for 1212U
|
||||
*
|
||||
* Revision 1.7 2000/10/30 22:32:20 sable
|
||||
* Support for vuego310s vuego610s and 1236s
|
||||
*
|
||||
* Revision 1.6 2000/10/29 22:44:55 sable
|
||||
* Bug correction for 1236s
|
||||
*
|
||||
* Revision 1.5 2000/10/28 14:16:10 sable
|
||||
* Bug correction for SnapScan310
|
||||
*
|
||||
* Revision 1.4 2000/10/28 14:06:35 sable
|
||||
* Add support for Acer300f
|
||||
*
|
||||
* Revision 1.3 2000/10/15 19:52:06 cbagwell
|
||||
* Changed USB support to a 1 line modification instead of multi-file
|
||||
* changes.
|
||||
*
|
||||
* Revision 1.2 2000/10/13 03:50:27 cbagwell
|
||||
* Updating to source from SANE 1.0.3. Calling this versin 1.1
|
||||
*
|
||||
* Revision 1.3 2000/08/12 15:09:34 pere
|
||||
* Merge devel (v1.0.3) into head branch.
|
||||
*
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -116,6 +116,8 @@ static SANE_Status SCSISource_get (Source *pself,
|
|||
SCSISource *ps = (SCSISource *) pself;
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Int remaining = *plen;
|
||||
static SANE_Int warned_expected_bytes = 0;
|
||||
|
||||
while (remaining > 0
|
||||
&&
|
||||
pself->remaining(pself) > 0
|
||||
|
@ -137,6 +139,37 @@ static SANE_Status SCSISource_get (Source *pself,
|
|||
+ (ps->time.tv_usec - oldtime.tv_usec)/1000.0;
|
||||
ps->pss->expected_read_bytes =
|
||||
((int) (msecs/ps->pss->ms_per_line))*ps->pss->bytes_per_line;
|
||||
|
||||
if(ps->pss->pdev->model == ACER300F
|
||||
||
|
||||
ps->pss->pdev->model == SNAPSCAN310
|
||||
||
|
||||
ps->pss->pdev->model == PRISA620S
|
||||
||
|
||||
ps->pss->pdev->model == SNAPSCAN1212U
|
||||
||
|
||||
ps->pss->pdev->model == SNAPSCAN1236S
|
||||
||
|
||||
ps->pss->pdev->model == SNAPSCANE50
|
||||
||
|
||||
ps->pss->pdev->model == VUEGO310S
|
||||
||
|
||||
ps->pss->pdev->model == VUEGO610S)
|
||||
{
|
||||
ps->pss->expected_read_bytes = (size_t) ps->absolute_max;
|
||||
}
|
||||
if (ps->pss->expected_read_bytes == 0)
|
||||
{
|
||||
if (!warned_expected_bytes)
|
||||
{
|
||||
warned_expected_bytes++;
|
||||
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: Hung up because expected bytes is 0. Please report!",
|
||||
__FUNCTION__);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -306,6 +339,7 @@ static SANE_Status BufSource_get (Source *pself,
|
|||
BufSource *ps = (BufSource *) pself;
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Int to_move = MIN(*plen, pself->remaining(pself));
|
||||
|
||||
if (to_move == 0)
|
||||
{
|
||||
status = SANE_STATUS_EOF;
|
||||
|
@ -653,9 +687,32 @@ typedef struct
|
|||
static SANE_Int RGBRouter_remaining (Source *pself)
|
||||
{
|
||||
RGBRouter *ps = (RGBRouter *) pself;
|
||||
SANE_Int remaining;
|
||||
|
||||
if (ps->cb_start < 0)
|
||||
return (TxSource_remaining(pself) - ps->cb_size + ps->cb_line_size);
|
||||
return (TxSource_remaining(pself) + ps->cb_line_size - ps->pos);
|
||||
remaining = (TxSource_remaining(pself) - ps->cb_size + ps->cb_line_size);
|
||||
else
|
||||
remaining = (TxSource_remaining(pself) + ps->cb_line_size - ps->pos);
|
||||
|
||||
if (remaining < 0)
|
||||
{
|
||||
/* We are in big trouble. Someone is using the RBGRouter routines
|
||||
* to find out how much is remaining. There is a case were not
|
||||
* enough data has been read yet to fill the circular buffer.
|
||||
* Until it is filled then no one should be accessing it or
|
||||
* checking how much is remaining (in current implemntation).
|
||||
* FIXME: For now, there is some code (measure_transfer_rate) that
|
||||
* will do this at times and setting remaining = 1 allows some
|
||||
* scans to squeak by.
|
||||
*/
|
||||
remaining = 1;
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: Computed a negative size for circular buffer! Forcing to size of 1 to keep going\n",
|
||||
__FUNCTION__);
|
||||
|
||||
}
|
||||
|
||||
return (remaining);
|
||||
}
|
||||
|
||||
static SANE_Status RGBRouter_get (Source *pself,
|
||||
|
@ -676,7 +733,7 @@ static SANE_Status RGBRouter_get (Source *pself,
|
|||
if (ps->pos >= ps->cb_line_size)
|
||||
{
|
||||
/* Try to get more data */
|
||||
SANE_Int ndata = (ps->cb_start < 0) ? ps->cb_size : ps->cb_line_size;
|
||||
SANE_Int ndata = (ps->cb_start < 0) ? ps->cb_size : (ps->cb_line_size - ps->cb_start%ps->cb_line_size);
|
||||
SANE_Int start = (ps->cb_start < 0) ? 0 : ps->cb_start;
|
||||
SANE_Int ndata2;
|
||||
SANE_Int ndata3;
|
||||
|
@ -688,6 +745,10 @@ static SANE_Status RGBRouter_get (Source *pself,
|
|||
status = TxSource_get (pself, ps->cbuf + start + ndata3, &ndata2);
|
||||
if (status != SANE_STATUS_GOOD || ndata2 == 0)
|
||||
{
|
||||
DBG (DL_MINOR_ERROR,
|
||||
"TxSource_get failed status:%d, ndata:%d, ndata2:%d ndata3:%d\n", status, ndata, ndata2, ndata3);
|
||||
ps->cb_start = (start + ndata3)%ps->cb_size;
|
||||
|
||||
*plen -= remaining;
|
||||
return status;
|
||||
}
|
||||
|
@ -904,6 +965,58 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss,
|
|||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.4 2001/05/26 12:47:31 hmg
|
||||
* Updated snapscan backend to version 1.2 (from
|
||||
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
|
||||
* Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
*
|
||||
* Revision 1.11 2001/04/13 13:12:18 oliverschwartz
|
||||
* use absolute_max as expected_read_bytes for PRISA620S
|
||||
*
|
||||
* Revision 1.10 2001/04/10 11:04:31 sable
|
||||
* Adding support for snapscan e40 an e50 thanks to Giuseppe Tanzilli
|
||||
*
|
||||
* Revision 1.9 2001/03/17 22:53:21 sable
|
||||
* Applying Mikael Magnusson patch concerning Gamma correction
|
||||
* Support for 1212U_2
|
||||
*
|
||||
* Revision 1.3 2001/03/04 16:53:21 mikael
|
||||
* Reading absolute max from SNAPSCAN 1212U
|
||||
*
|
||||
* Revision 1.2 2001/02/16 18:32:28 mikael
|
||||
* impl calibration, signed position, increased buffer size
|
||||
*
|
||||
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
|
||||
* Imported from snapscan-11282000.tar.gz
|
||||
*
|
||||
* Revision 1.8 2000/11/28 03:55:07 cbagwell
|
||||
* Reverting a fix to RGBRouter_remaining to original fix. This allows
|
||||
* most scanners to scan at 600 dpi by ignoring insufficent data in
|
||||
* the RGB circular buffer and always returning size = 1 in those cases.
|
||||
* This should probably be fixed at a higher level.
|
||||
*
|
||||
* Revision 1.7 2000/11/20 01:02:42 cbagwell
|
||||
* Updates so that USB will continue reading when it receives an EAGAIN error.
|
||||
* Also, changed RGBRouter_remaining to not be able to return a negative
|
||||
* value.
|
||||
*
|
||||
* Revision 1.6 2000/11/04 01:53:58 cbagwell
|
||||
* Commiting some needed USB updates. Added extra test logic to detect
|
||||
* bad bytes_expected values. Just to help debug faster on scanners
|
||||
* that tickle the bug.
|
||||
*
|
||||
* Revision 1.5 2000/10/30 22:32:20 sable
|
||||
* Support for vuego310s vuego610s and 1236s
|
||||
*
|
||||
* Revision 1.4 2000/10/28 14:16:10 sable
|
||||
* Bug correction for SnapScan310
|
||||
*
|
||||
* Revision 1.3 2000/10/28 14:06:35 sable
|
||||
* Add support for Acer300f
|
||||
*
|
||||
* Revision 1.2 2000/10/13 03:50:27 cbagwell
|
||||
* Updating to source from SANE 1.0.3. Calling this versin 1.1
|
||||
*
|
||||
* Revision 1.3 2000/08/12 15:09:35 pere
|
||||
* Merge devel (v1.0.3) into head branch.
|
||||
*
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -87,6 +87,21 @@ static SANE_Status Source_init (Source *pself,
|
|||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.3 2001/05/26 12:47:31 hmg
|
||||
* Updated snapscan backend to version 1.2 (from
|
||||
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
|
||||
* Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
*
|
||||
* Revision 1.3 2001/03/17 22:53:21 sable
|
||||
* Applying Mikael Magnusson patch concerning Gamma correction
|
||||
* Support for 1212U_2
|
||||
*
|
||||
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
|
||||
* Imported from snapscan-11282000.tar.gz
|
||||
*
|
||||
* Revision 1.2 2000/10/13 03:50:27 cbagwell
|
||||
* Updating to source from SANE 1.0.3. Calling this versin 1.1
|
||||
*
|
||||
* Revision 1.2 2000/08/12 15:09:35 pere
|
||||
* Merge devel (v1.0.3) into head branch.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
Snapscan 1212U modifications for the Snapscan SANE backend
|
||||
|
||||
Copyright (C) 2000 Henrik Johansson
|
||||
|
||||
Henrik Johansson (henrikjo@post.urfors.se)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
This file implements USB equivalents to the SCSI routines used by the Snapscan
|
||||
backend.
|
||||
|
||||
History
|
||||
|
||||
0.1 2000-02-01
|
||||
|
||||
First version released
|
||||
|
||||
0.2 2000-02-12
|
||||
|
||||
The Send Diagnostics SCSI command seems to hang some 1212U scanners.
|
||||
Bypassing this command fixes the problem. This bug was reported by
|
||||
Dmitri (dmitri@advantrix.com).
|
||||
|
||||
0.3 2000-02-13
|
||||
|
||||
The "Set window" command returns with status "Device busy" when the
|
||||
scanner is busy. One consequence is that some frontends exits with an
|
||||
error message if it's started when the scanner is warming up.
|
||||
A solution was suggested by Dmitri (dmitri@advantrix.com)
|
||||
The idea is that a SCSI command which returns "device busy" is stored
|
||||
in a "TODO" queue. The send command function is modified to first send
|
||||
commands in the queue before the intended command.
|
||||
So far this strategy has worked flawlessly. Thanks Dmitri!
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
#include "snapscan-usb.h"
|
||||
|
||||
/* Global variables */
|
||||
|
||||
static int sem_id;
|
||||
static struct sembuf sem_wait = { 0, -1, 0 };
|
||||
static struct sembuf sem_signal = { 0, 1, 0 };
|
||||
|
||||
static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size,
|
||||
void *dst, size_t * dst_size)
|
||||
{
|
||||
static const char me[] = "snapscani_usb_cmd";
|
||||
int status;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me,
|
||||
fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
|
||||
|
||||
while(bqhead) {
|
||||
status = atomic_usb_cmd(fd, bqhead->src, bqhead->src_size, NULL, NULL);
|
||||
if(status == SANE_STATUS_DEVICE_BUSY) {
|
||||
if(is_queueable(src)) {
|
||||
enqueue_bq(fd,src,src_size);
|
||||
return SANE_STATUS_GOOD;
|
||||
} else {
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
dequeue_bq();
|
||||
}
|
||||
|
||||
status = atomic_usb_cmd(fd,src,src_size,dst,dst_size);
|
||||
|
||||
if((status == SANE_STATUS_DEVICE_BUSY) && is_queueable(src) ) {
|
||||
enqueue_bq(fd,src,src_size);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size,
|
||||
void *dst, size_t * dst_size)
|
||||
{
|
||||
static const char me[] = "atomic_usb_cmd";
|
||||
|
||||
int status;
|
||||
sigset_t all,oldset;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me,
|
||||
fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
|
||||
|
||||
/* Prevent the calling process from being killed */
|
||||
sigfillset(&all);
|
||||
sigprocmask(SIG_BLOCK, &all, &oldset);
|
||||
|
||||
/* Make sure we are alone */
|
||||
semop(sem_id, &sem_wait, 1);
|
||||
|
||||
status = usb_cmd(fd,src,src_size,dst,dst_size);
|
||||
|
||||
semop(sem_id, &sem_signal, 1);
|
||||
|
||||
/* Now it is ok to be killed */
|
||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
static SANE_Status snapscani_usb_open(const char *dev, int *fdp,
|
||||
SANEI_SCSI_Sense_Handler handler, void *handler_arg)
|
||||
{
|
||||
return usb_open(dev,fdp,handler,handler_arg);
|
||||
}
|
||||
|
||||
|
||||
static void snapscani_usb_close(int fd) {
|
||||
usb_close(fd);
|
||||
}
|
||||
|
||||
|
||||
static int usb_cmdlen(int cmd)
|
||||
{
|
||||
switch(cmd) {
|
||||
case TEST_UNIT_READY:
|
||||
case INQUIRY:
|
||||
case SCAN:
|
||||
case REQUEST_SENSE:
|
||||
case RESERVE_UNIT:
|
||||
case RELEASE_UNIT:
|
||||
case SEND_DIAGNOSTIC:
|
||||
return 6;
|
||||
case SEND:
|
||||
case SET_WINDOW:
|
||||
case READ:
|
||||
case GET_DATA_BUFFER_STATUS:
|
||||
return 10;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *usb_debug_data(char *str,const char *data, int len) {
|
||||
char tmpstr[10];
|
||||
int i;
|
||||
|
||||
str[0]=0;
|
||||
for(i=0; i < (len < 10 ? len : 10); i++) {
|
||||
sprintf(tmpstr," 0x%02x",((int)data[i]) & 0xff);
|
||||
if(i%16 == 0 && i != 0)
|
||||
strcat(str,"\n");
|
||||
strcat(str,tmpstr);
|
||||
}
|
||||
if(i < len)
|
||||
strcat(str," ...");
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status usb_open(const char *dev, int *fdp,
|
||||
SANEI_SCSI_Sense_Handler handler, void *handler_arg)
|
||||
{
|
||||
static const char me[] = "usb_open";
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%s)\n", me, dev);
|
||||
|
||||
if((sem_id = semget( ftok(dev,0x1234), 1, IPC_CREAT | 0660 )) == -1) {
|
||||
DBG (DL_MAJOR_ERROR, "%s: Can't get semaphore\n", me);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
semop(sem_id, &sem_signal, 1);
|
||||
|
||||
*fdp = open(dev, O_RDWR);
|
||||
if( *fdp < 0)
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static void usb_close(int fd) {
|
||||
static const char me[] = "usb_close";
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%d)\n", me, fd);
|
||||
semctl(sem_id, 0, IPC_RMID, 0);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
static int usb_status(char *status_buf) {
|
||||
int status;
|
||||
|
||||
status = (status_buf[1] & STATUS_MASK) >> 1;
|
||||
|
||||
switch(status) {
|
||||
case GOOD:
|
||||
return SANE_STATUS_GOOD;
|
||||
case CHECK_CONDITION:
|
||||
case BUSY:
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
default:
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#define RETURN_ON_FAILURE(x) if((status = x) != SANE_STATUS_GOOD) return status;
|
||||
|
||||
static SANE_Status usb_write(int fd, const void *buf, int n) {
|
||||
char dbgmsg[16384];
|
||||
int r;
|
||||
|
||||
static const char me[] = "usb_write";
|
||||
DBG(DL_DATA_TRACE, "%s: writing: %s\n",me,usb_debug_data(dbgmsg,buf,n));
|
||||
|
||||
if((r=write(fd,buf,n)) != n) {
|
||||
DBG (DL_MAJOR_ERROR, "%s Only %d bytes written\n",me,r);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status usb_read(int fd, void *buf, int n) {
|
||||
char dbgmsg[16384];
|
||||
int r;
|
||||
|
||||
static const char me[] = "usb_read";
|
||||
|
||||
/* USB driver appears to block in all cases when asking for data
|
||||
* except if the device says its not ready. In this case, we
|
||||
* attempt to block ourselves to act like the sane SCSI driver.
|
||||
* This relies on the USB driver to eventually report something
|
||||
* besides EAGAIN if there is a serious problem.
|
||||
*/
|
||||
do
|
||||
{
|
||||
if((r=read(fd,buf,n)) != n && !(r == -1 && errno == EAGAIN)) {
|
||||
DBG (DL_MAJOR_ERROR, "%s Only %d bytes read\n",me,r);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
if (r == -1 && errno == EAGAIN)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR, "%s: Got an EAGAIN\n",me);
|
||||
usleep(10000);
|
||||
}
|
||||
} while (r == -1 && errno == EAGAIN);
|
||||
|
||||
DBG(DL_DATA_TRACE, "%s: reading: %s\n",me,usb_debug_data(dbgmsg,buf,n));
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static SANE_Status usb_read_status(int fd, int *scsistatus, int *transaction_status)
|
||||
{
|
||||
unsigned char status_buf[8];
|
||||
int scsistat;
|
||||
int status;
|
||||
|
||||
RETURN_ON_FAILURE(usb_read(fd,status_buf,8));
|
||||
|
||||
if(transaction_status)
|
||||
*transaction_status = status_buf[0];
|
||||
|
||||
scsistat = (status_buf[1] & STATUS_MASK) >> 1;
|
||||
|
||||
if(scsistatus)
|
||||
*scsistatus = scsistat;
|
||||
|
||||
switch(scsistat) {
|
||||
case GOOD:
|
||||
return SANE_STATUS_GOOD;
|
||||
case CHECK_CONDITION:
|
||||
case BUSY:
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
default:
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
|
||||
void *dst, size_t * dst_size)
|
||||
{
|
||||
static const char me[] = "usb_cmd";
|
||||
int status,tstatus;
|
||||
int cmdlen,datalen;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me,
|
||||
fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
|
||||
|
||||
|
||||
/* Since the "Send Diagnostic" command isn't supported by
|
||||
all Snapscan USB-scanners it's disabled .
|
||||
*/
|
||||
if(((char *)src)[0] == SEND_DIAGNOSTIC)
|
||||
return(SANE_STATUS_GOOD);
|
||||
|
||||
cmdlen = usb_cmdlen(*((char *)src));
|
||||
datalen = src_size - cmdlen;
|
||||
|
||||
DBG(DL_DATA_TRACE, "%s: cmdlen=%d, datalen=%d\n",me,cmdlen,datalen);
|
||||
|
||||
/* Send command to scanner */
|
||||
RETURN_ON_FAILURE( usb_write(fd,src,cmdlen) );
|
||||
|
||||
/* Read status */
|
||||
RETURN_ON_FAILURE( usb_read_status(fd, NULL, &tstatus) );
|
||||
|
||||
/* Send data only if the scanner is expecting it */
|
||||
if(datalen > 0 && (tstatus == TRANSACTION_WRITE)) {
|
||||
/* Send data to scanner */
|
||||
RETURN_ON_FAILURE( usb_write(fd, ((SANE_Byte *) src) + cmdlen, datalen) );
|
||||
|
||||
/* Read status */
|
||||
RETURN_ON_FAILURE( usb_read_status(fd, NULL, &tstatus) );
|
||||
}
|
||||
|
||||
/* Receive data only when new data is waiting */
|
||||
if(dst_size && *dst_size && (tstatus == TRANSACTION_READ)) {
|
||||
RETURN_ON_FAILURE( usb_read(fd,dst,*dst_size) );
|
||||
|
||||
/* Read status */
|
||||
RETURN_ON_FAILURE( usb_read_status(fd, NULL, &tstatus) );
|
||||
}
|
||||
|
||||
if(tstatus != TRANSACTION_COMPLETED) {
|
||||
if(tstatus == TRANSACTION_WRITE)
|
||||
DBG(DL_MAJOR_ERROR,
|
||||
"%s: The transaction should now be completed, but the scanner is expecting more data" ,me);
|
||||
else
|
||||
DBG(DL_MAJOR_ERROR,
|
||||
"%s: The transaction should now be completed, but the scanner has more data to send" ,me);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Busy queue data structures and function implementations*/
|
||||
|
||||
static int is_queueable(const char *src)
|
||||
{
|
||||
switch(src[0]) {
|
||||
case SEND:
|
||||
case SET_WINDOW:
|
||||
case SEND_DIAGNOSTIC:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct usb_busy_queue *bqhead=NULL,*bqtail=NULL;
|
||||
int bqelements=0;
|
||||
|
||||
static int enqueue_bq(int fd,const void *src, size_t src_size)
|
||||
{
|
||||
static const char me[] = "enqueue_bq";
|
||||
struct usb_busy_queue *bqe;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%d,%p,%d)\n", me, fd,src,src_size);
|
||||
|
||||
if((bqe = malloc(sizeof(struct usb_busy_queue))) == NULL)
|
||||
return -1;
|
||||
|
||||
if((bqe->src = malloc(src_size)) == NULL)
|
||||
return -1;
|
||||
|
||||
memcpy(bqe->src,src,src_size);
|
||||
bqe->src_size=src_size;
|
||||
|
||||
bqe->next=NULL;
|
||||
|
||||
if(bqtail) {
|
||||
bqtail->next=bqe;
|
||||
bqtail = bqe;
|
||||
} else
|
||||
bqhead = bqtail = bqe;
|
||||
|
||||
bqelements++;
|
||||
DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n",
|
||||
me,bqelements,bqhead,bqtail);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dequeue_bq()
|
||||
{
|
||||
static const char me[] = "dequeue_bq";
|
||||
struct usb_busy_queue *tbqe;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s()\n", me);
|
||||
|
||||
if(!bqhead)
|
||||
return;
|
||||
|
||||
tbqe = bqhead;
|
||||
bqhead = bqhead->next;
|
||||
if(!bqhead)
|
||||
bqtail=NULL;
|
||||
|
||||
if(tbqe->src)
|
||||
free(tbqe->src);
|
||||
free(tbqe);
|
||||
|
||||
bqelements--;
|
||||
DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n",
|
||||
me,bqelements,bqhead,bqtail);
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef snapscan_usb_h
|
||||
#define snapscan_usb_h
|
||||
|
||||
static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size,
|
||||
void *dst, size_t * dst_size);
|
||||
static SANE_Status snapscani_usb_open(const char *dev, int *fdp,
|
||||
SANEI_SCSI_Sense_Handler handler, void *handler_arg);
|
||||
static void snapscani_usb_close(int fd);
|
||||
|
||||
/*
|
||||
* USB status codes
|
||||
*/
|
||||
#define GOOD 0x00
|
||||
#define CHECK_CONDITION 0x01
|
||||
#define CONDITION_GOOD 0x02
|
||||
#define BUSY 0x04
|
||||
#define INTERMEDIATE_GOOD 0x08
|
||||
#define INTERMEDIATE_C_GOOD 0x0a
|
||||
#define RESERVATION_CONFLICT 0x0c
|
||||
#define COMMAND_TERMINATED 0x11
|
||||
#define QUEUE_FULL 0x14
|
||||
|
||||
#define STATUS_MASK 0x3e
|
||||
|
||||
/*
|
||||
* USB transaction status
|
||||
*/
|
||||
#define TRANSACTION_COMPLETED 0xfb /* Scanner considers the transaction done */
|
||||
#define TRANSACTION_READ 0xf9 /* Scanner has data to deliver */
|
||||
#define TRANSACTION_WRITE 0xf8 /* Scanner is expecting more data */
|
||||
|
||||
/*
|
||||
* Busy queue data structure and prototypes
|
||||
*/
|
||||
struct usb_busy_queue {
|
||||
int fd;
|
||||
void *src;
|
||||
size_t src_size;
|
||||
struct usb_busy_queue *next;
|
||||
};
|
||||
|
||||
static struct usb_busy_queue *bqhead,*bqtail;
|
||||
extern int bqelements;
|
||||
static int enqueue_bq(int fd,const void *src, size_t src_size);
|
||||
static void dequeue_bq(void);
|
||||
static int is_queueable(const char *src);
|
||||
|
||||
static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size,
|
||||
void *dst, size_t * dst_size);
|
||||
static SANE_Status usb_open(const char *dev, int *fdp,
|
||||
SANEI_SCSI_Sense_Handler handler, void *handler_arg);
|
||||
|
||||
static void usb_close(int fd);
|
||||
|
||||
static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
|
||||
void *dst, size_t * dst_size);
|
||||
|
||||
#endif
|
Plik diff jest za duży
Load Diff
|
@ -1,4 +1,9 @@
|
|||
scsi AGFA
|
||||
scsi COLOR
|
||||
scsi ACERPERI
|
||||
|
||||
# If not automatically found from above, then you may manually specify
|
||||
# a device name.
|
||||
/dev/scanner
|
||||
/dev/sga
|
||||
#/dev/usbscanner
|
||||
#/dev/sga
|
||||
|
|
|
@ -10,56 +10,94 @@
|
|||
; All other information is optional (but what good is the file without it?).
|
||||
;
|
||||
|
||||
:backend "SnapScan" ; name of backend
|
||||
:version "0.7" ; version of backend
|
||||
:status :alpha ; :alpha, :beta, :stable, :new
|
||||
:manpage "sane-snapscan" ; name of manpage (if it exists)
|
||||
:url "http://snapscan.sourceforge.net" ; backend's web page
|
||||
:backend "SnapScan" ; name of backend
|
||||
:version "1.2" ; version of backend
|
||||
:status :alpha ; :alpha, :beta, :stable, :new
|
||||
:manpage "sane-snapscan" ; name of manpage (if it exists)
|
||||
:url "http://snapscan.sourceforge.net/" ; backend's web page
|
||||
|
||||
:devicetype :scanner ; start of a list of devices....
|
||||
; other types: :stillcam, :vidcam,
|
||||
; :meta, :api
|
||||
:devicetype :scanner ; start of a list of devices....
|
||||
; other types: :stillcam, :vidcam,
|
||||
; :meta, :api
|
||||
|
||||
:mfg "AGFA" ; name a manufacturer
|
||||
:mfg "AGFA" ; name a manufacturer
|
||||
:url "http://www.agfa.com/"
|
||||
:model "SnapScan 300" ; name models for above-specified mfg.
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
:model "SnapScan 300" ; name models for above-specified mfg.
|
||||
:interface "SCSI"
|
||||
:comment "Only 8 bits/sample at present."
|
||||
|
||||
:model "SnapScan 310"
|
||||
:interface "SCSI"
|
||||
:comment "Ditto"
|
||||
|
||||
:model "SnapScan 600"
|
||||
:interface "SCSI"
|
||||
:comment "Ditto"
|
||||
|
||||
:model "SnapScan 1236s"
|
||||
:interface "SCSI"
|
||||
:comment "Ditto. Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan 1212u"
|
||||
:interface "USB"
|
||||
:comment "Ditto. Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan e40"
|
||||
:interface "USB"
|
||||
:comment "Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan e50"
|
||||
:interface "USB"
|
||||
:comment "Have no specific programming info yet."
|
||||
|
||||
:mfg "Vuego"
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
:model "310s"
|
||||
:interface "SCSI"
|
||||
:comment "Close SnapScan 310 compatible."
|
||||
|
||||
:mfg "Acer"
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
:model "300f"
|
||||
:interface "SCSI"
|
||||
|
||||
:model "310s"
|
||||
:interface "SCSI"
|
||||
:comment "Same thing as the Vuego 310s."
|
||||
|
||||
:model "610s"
|
||||
:interface "SCSI"
|
||||
|
||||
:model "610plus"
|
||||
:interface "SCSI"
|
||||
:comment "Seems to be a close SnapScan 310/600 compatible."
|
||||
|
||||
:model "Prisa 620s"
|
||||
:interface "SCSI"
|
||||
:comment "Seems to be a close SnapScan 310/600 compatible."
|
||||
|
||||
:model "Prisa 620u"
|
||||
:interface "USB"
|
||||
:comment "Seems to be a close SnapScan 310/600 compatible."
|
||||
|
||||
:model "Prisa 640u"
|
||||
:interface "USB"
|
||||
:comment "Seems to be a close SnapScan 310/600 compatible."
|
||||
|
||||
:model "Prisa 640bu"
|
||||
:interface "USB"
|
||||
:comment "Seems to be a close SnapScan 310/600 compatible."
|
||||
|
||||
:mfg "Guillemot International"
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
:model "Maxi Scan A4 Deluxe (SCSI)"
|
||||
:interface "SCSI"
|
||||
:comment "May be a repackaged Vuego 310s or SnapScan 310s."
|
||||
;:devicetype :api ; specify a different type
|
||||
;:desc "Interface to FrObYz API" ; describe a non-hardware device
|
||||
|
||||
; :comment and :url specifiers are optional after :mfg, :model, :desc,
|
||||
; and at the top-level.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 1997, 1998, 1999 Franck Schnefra, Michel Roelofs,
|
||||
Copyright (C) 1997, 1998, 1999, 2001 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson
|
||||
and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
|
@ -65,6 +66,13 @@
|
|||
#define G_CHAN 1
|
||||
#define B_CHAN 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNKNOWN_BUS,
|
||||
SCSI,
|
||||
USB
|
||||
} SnapScan_Bus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNKNOWN,
|
||||
|
@ -72,6 +80,9 @@ typedef enum
|
|||
SNAPSCAN310, /* the SnapScan 310 */
|
||||
SNAPSCAN600, /* the SnapScan 600 */
|
||||
SNAPSCAN1236S, /* the SnapScan 1236s */
|
||||
SNAPSCAN1212U,
|
||||
SNAPSCANE50, /* SnapScan e20/e40/e50 */
|
||||
ACER300F,
|
||||
VUEGO310S, /* Vuego-Version of SnapScan 310 WG changed */
|
||||
VUEGO610S, /* Vuego 610S and 610plus SJU changed */
|
||||
PRISA620S /* Prisa-Version of SnapScan 600 GP added */
|
||||
|
@ -90,10 +101,19 @@ static struct SnapScan_Model_desc scanners[] =
|
|||
{"FlatbedScanner_9", PRISA620S},
|
||||
{"FlatbedScanner13", PRISA620S},
|
||||
{"FlatbedScanner16", PRISA620S},
|
||||
{"FlatbedScanner18", PRISA620S},
|
||||
{"FlatbedScanner19", PRISA620S}, /* Acer ScanPrisa 1240UT */
|
||||
{"FlatbedScanner20", PRISA620S},
|
||||
{"SNAPSCAN 1212U", SNAPSCAN1212U},
|
||||
{"SNAPSCAN 1212U_2", SNAPSCAN1212U},
|
||||
{"SNAPSCAN e20", SNAPSCANE50},
|
||||
{"SNAPSCAN e50", SNAPSCANE50},
|
||||
{"SNAPSCAN e40", SNAPSCANE50},
|
||||
{"SNAPSCAN 1236", SNAPSCAN1236S},
|
||||
{"SNAPSCAN 310", SNAPSCAN310},
|
||||
{"SNAPSCAN 600", SNAPSCAN600},
|
||||
{"SnapScan", SNAPSCAN300},
|
||||
{"ACERSCAN_A4____1", ACER300F},
|
||||
};
|
||||
#define known_scanners ((int) (sizeof(scanners)/sizeof(scanners[0])))
|
||||
|
||||
|
@ -101,35 +121,45 @@ static char *vendors[] =
|
|||
{
|
||||
/* SCSI Vendor name */
|
||||
"AGFA",
|
||||
"COLOR"
|
||||
"COLOR",
|
||||
"ACERPER"
|
||||
};
|
||||
#define known_vendors ((int) (sizeof(vendors)/sizeof(vendors[0])))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OPT_COUNT = 0, /* option count */
|
||||
OPT_MODE_GROUP, /* scan mode group */
|
||||
OPT_SCANRES, /* scan resolution */
|
||||
OPT_PREVIEW, /* preview mode toggle */
|
||||
OPT_MODE, /* scan mode */
|
||||
OPT_PREVIEW_MODE, /* preview mode */
|
||||
OPT_SOURCE, /* scan source (flatbed / TPO) */
|
||||
OPT_GEOMETRY_GROUP, /* geometry group */
|
||||
OPT_TLX, /* top left x */
|
||||
OPT_TLY, /* top left y */
|
||||
OPT_BRX, /* bottom right x */
|
||||
OPT_BRY, /* bottom right y */
|
||||
OPT_PREDEF_WINDOW, /* predefined window configuration */
|
||||
OPT_ENHANCEMENT_GROUP, /* enhancement group */
|
||||
OPT_QUALITY_CAL, /* quality calibration */
|
||||
OPT_HALFTONE, /* halftone flag */
|
||||
OPT_HALFTONE_PATTERN, /* halftone matrix */
|
||||
OPT_CUSTOM_GAMMA, /* use custom gamma tables */
|
||||
OPT_GAMMA_BIND,
|
||||
OPT_GAMMA_GS, /* gamma correction (greyscale) */
|
||||
OPT_GAMMA_R, /* gamma correction (red) */
|
||||
OPT_GAMMA_G, /* gamma correction (green) */
|
||||
OPT_GAMMA_B, /* gamma correction (blue) */
|
||||
OPT_GAMMA_VECTOR_GS, /* gamma correction vector (greyscale) */
|
||||
OPT_GAMMA_VECTOR_R, /* gamma correction vector (red) */
|
||||
OPT_GAMMA_VECTOR_G, /* gamma correction vector (green) */
|
||||
OPT_GAMMA_VECTOR_B, /* gamma correction vector (blue) */
|
||||
OPT_NEGATIVE, /* swap black and white */
|
||||
OPT_THRESHOLD, /* threshold for line art */
|
||||
#ifdef INOPERATIVE
|
||||
OPT_BRIGHTNESS, /* brightness */
|
||||
OPT_CONTRAST, /* contrast */
|
||||
#endif
|
||||
OPT_ADVANCED_GROUP, /* advanced group */
|
||||
OPT_RGB_LPR, /* lines per scsi read (RGB) */
|
||||
OPT_GS_LPR, /* lines per scsi read (GS) */
|
||||
OPT_SCSI_CMDS, /* a group */
|
||||
|
@ -140,6 +170,15 @@ typedef enum
|
|||
NUM_OPTS /* dummy (gives number of options) */
|
||||
} SnapScan_Options;
|
||||
|
||||
typedef union
|
||||
{
|
||||
SANE_Bool b;
|
||||
SANE_Word w;
|
||||
SANE_Word *wa; /* word array */
|
||||
SANE_String s;
|
||||
}
|
||||
Option_Value;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MD_COLOUR = 0, /* full colour */
|
||||
|
@ -169,6 +208,7 @@ typedef struct snapscan_device
|
|||
SANE_Range x_range; /* x dimension of scan area */
|
||||
SANE_Range y_range; /* y dimension of scan area */
|
||||
SnapScan_Model model; /* type of scanner */
|
||||
SnapScan_Bus bus; /* bus of the device usb/scsi */
|
||||
u_char *depths; /* bit depth table */
|
||||
struct snapscan_device *pnext;
|
||||
}
|
||||
|
@ -218,6 +258,7 @@ struct snapscan_scanner
|
|||
|
||||
SANE_Option_Descriptor
|
||||
options[NUM_OPTS]; /* the option descriptors */
|
||||
Option_Value val[NUM_OPTS];
|
||||
/* the options themselves... */
|
||||
SANE_Int res; /* resolution */
|
||||
SANE_Bool preview; /* preview mode toggle */
|
||||
|
@ -228,15 +269,19 @@ struct snapscan_scanner
|
|||
SANE_Fixed tly; /* window top left y */
|
||||
SANE_Fixed brx; /* window bottom right x */
|
||||
SANE_Fixed bry; /* window bottom right y */
|
||||
#ifdef INOPERATIVE
|
||||
int bright; /* brightness */
|
||||
int contrast; /* contrast */
|
||||
#endif
|
||||
SANE_String predef_window; /* predefined window name */
|
||||
SANE_Fixed gamma_gs; /* gamma correction value (greyscale) */
|
||||
SANE_Fixed gamma_r; /* gamma correction value (red) */
|
||||
SANE_Fixed gamma_g; /* gamma correction value (green) */
|
||||
SANE_Fixed gamma_b; /* gamma correction value (blue) */
|
||||
SANE_Int *gamma_tables; /* gamma correction vectors */
|
||||
SANE_Int *gamma_table_gs; /* gamma correction vector (greyscale) */
|
||||
SANE_Int *gamma_table_r; /* gamma correction vector (red) */
|
||||
SANE_Int *gamma_table_g; /* gamma correction vector (green) */
|
||||
SANE_Int *gamma_table_b; /* gamma correction vector (blue) */
|
||||
int gamma_length; /* length of gamma vectors */
|
||||
SANE_Bool halftone; /* halftone toggle */
|
||||
SANE_String dither_matrix; /* the halftone dither matrix */
|
||||
SANE_Bool negative; /* swap black and white */
|
||||
|
@ -249,6 +294,45 @@ struct snapscan_scanner
|
|||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.4 2001/05/26 12:47:34 hmg
|
||||
* Updated snapscan backend to version 1.2 (from
|
||||
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
|
||||
* Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
*
|
||||
* Revision 1.11 2001/04/10 12:38:21 sable
|
||||
* Adding e20 support thanks to Steffen Hübner
|
||||
*
|
||||
* Revision 1.10 2001/04/10 11:04:31 sable
|
||||
* Adding support for snapscan e40 an e50 thanks to Giuseppe Tanzilli
|
||||
*
|
||||
* Revision 1.9 2001/03/17 22:53:21 sable
|
||||
* Applying Mikael Magnusson patch concerning Gamma correction
|
||||
* Support for 1212U_2
|
||||
*
|
||||
* Revision 1.3 2001/03/04 16:51:29 mikael
|
||||
* Added Scan Mode, Geometry, Enhancement and Advanced groups. Added Quality Calibration, Analog Gamma Bind, Custom Gamma and Gamma Vector GS,R,G,B options. Added SNAPSCAN 1212U_2.
|
||||
*
|
||||
* Revision 1.2 2001/02/16 18:32:28 mikael
|
||||
* impl calibration, signed position, increased buffer size
|
||||
*
|
||||
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
|
||||
* Imported from snapscan-11282000.tar.gz
|
||||
*
|
||||
* Revision 1.8 2000/11/10 01:01:59 sable
|
||||
* USB (kind of) autodetection
|
||||
*
|
||||
* Revision 1.7 2000/11/01 01:26:43 sable
|
||||
* Support for 1212U
|
||||
*
|
||||
* Revision 1.6 2000/10/28 14:06:35 sable
|
||||
* Add support for Acer300f
|
||||
*
|
||||
* Revision 1.5 2000/10/15 17:54:58 cbagwell
|
||||
* Adding USB files for optional USB compiles.
|
||||
*
|
||||
* Revision 1.4 2000/10/13 03:50:27 cbagwell
|
||||
* Updating to source from SANE 1.0.3. Calling this versin 1.1
|
||||
*
|
||||
* Revision 1.3 2000/08/12 15:09:37 pere
|
||||
* Merge devel (v1.0.3) into head branch.
|
||||
*
|
||||
|
|
Ładowanie…
Reference in New Issue